Re: Sony Clie PEG-TJ37 vs. FreeBSD CURRENT (long)

From: Brian Fundakowski Feldman <green_at_freebsd.org>
Date: Thu, 1 Jul 2004 12:45:23 -0400
On Thu, Jul 01, 2004 at 08:44:29AM -0700, Bruce A. Mah wrote:
> Hi--
> 
> Has anyone gotten a Sony Clie PEG-TJ37 (PalmOS 5.2.1-based PDA) to
> establish a PPP connection with a 5-CURRENT/i386 machine over USB?
> (If anyone has a TJ25 or TJ35, that's pretty close and I'd like to
> hear from you too.)
> 
> I've been trying for awhile now without much success.  I'm generally
> following the instructions from:
> 
> http://gja.space4me.com/things/Palm_TungstenC_Freebsd.html
> 
> I had to apply the following patches to allow the uvisor driver to
> recognize the TJ37's USB ID:
> [...]

Heya, Bruce; I happened to be screwing with the uvisor driver a lot
yesterday to try to get my phone working (which it still doesn't...
no real explanation why...).  Try also merging in these diffs; you
should at least be able to adjust the part where it's choosing which
"port" to attach to the ucom device so that it chooses whichever you
are supposed to be able to do PPP over (right now, it's at the
HotSync port, but it's also untested :)

You might want to add some printf()s to print out the uDWord
(uint8_t[4], probably not a string?) for each port type on your
card.  At the least we can provide some way to attach whichever
individual port is the one you want, but I don't really see why
it is that we can't also port over the multiple-ucom-attachment
support so that the Palm gets correctly attached as the whole
slew of ucom devices... not enough device driver infrastructure?

cvs diff: Diffing .
Index: uvisor.c
===================================================================
RCS file: /usr/ncvs/src/sys/dev/usb/uvisor.c,v
retrieving revision 1.22
diff -u -r1.22 uvisor.c
--- uvisor.c	27 Jun 2004 12:41:44 -0000	1.22
+++ uvisor.c	1 Jul 2004 03:51:44 -0000
_at__at_ -142,8 +142,24 _at__at_
  * 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];
+};
+
+union connection_info {
+	struct uvisor_connection_info ci_visor;
+	struct uvisor_palm_connection_info ci_palm;
+};
 
 /*
  * Crank down UVISORBUFSIZE from 1024 to 64 to avoid a problem where
_at__at_ -163,9 +179,7 _at__at_
 	u_int16_t		sc_flags;
 };
 
-Static usbd_status uvisor_init(struct uvisor_softc *);
-
-Static usbd_status clie_3_5_init(struct uvisor_softc *);
+Static usbd_status uvisor_init(struct uvisor_softc *, union connection_info *);
 
 Static void uvisor_close(void *, int);
 
_at__at_ -207,9 +221,10 _at__at_
 	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_HANDSPRING, USB_PRODUCT_HANDSPRING_TREO600 }, PALM4 },
 	{{ USB_VENDOR_PALM, USB_PRODUCT_PALM_M500 }, PALM4 },
_at__at_ -222,7 +237,7 _at__at_
 	{{ USB_VENDOR_PALM, USB_PRODUCT_PALM_TUNGSTEN_T }, PALM4 },
 	{{ USB_VENDOR_PALM, USB_PRODUCT_PALM_ZIRE }, PALM4 },
 	{{ USB_VENDOR_PALM, USB_PRODUCT_PALM_ZIRE31 }, PALM4 },
-	{{ USB_VENDOR_SONY, USB_PRODUCT_SONY_CLIE_40 }, 0 },
+	{{ USB_VENDOR_SONY, USB_PRODUCT_SONY_CLIE_40 }, PALM4 },
 	{{ 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 },
_at__at_ -252,6 +267,7 _at__at_
 	usbd_device_handle dev = uaa->device;
 	usbd_interface_handle iface;
 	usb_interface_descriptor_t *id;
+	union connection_info coninfo;
 	usb_endpoint_descriptor_t *ed;
 	char *devinfo;
 	const char *devname;
_at__at_ -295,65 +311,97 _at__at_
 
 	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 not visor/palm\n", 
+		    devname);
+		goto bad;
+	}
+
 	id = usbd_get_interface_descriptor(iface);
 
 	ucom->sc_udev = dev;
 	ucom->sc_iface = iface;
 
 	ucom->sc_bulkin_no = ucom->sc_bulkout_no = -1;
-	for (i = 0; i < id->bNumEndpoints; i++) {
-		int addr, dir, attr;
-		ed = usbd_interface2endpoint_descriptor(iface, i);
-		if (ed == NULL) {
-			printf("%s: could not read endpoint descriptor"
-			       ": %s\n", devname, usbd_errstr(err));
-			goto bad;
-		}
-
-		addr = ed->bEndpointAddress;
-		dir = UE_GET_DIR(ed->bEndpointAddress);
-		attr = ed->bmAttributes & UE_XFERTYPE;
-		if (dir == UE_DIR_IN && attr == UE_BULK)
-			ucom->sc_bulkin_no = addr;
-		else if (dir == UE_DIR_OUT && attr == UE_BULK)
-			ucom->sc_bulkout_no = addr;
-		else {
-			printf("%s: unexpected endpoint\n", devname);
-			goto bad;
-		}
-	}
-	if (ucom->sc_bulkin_no == -1) {
-		printf("%s: Could not find data bulk in\n",
-		       USBDEVNAME(ucom->sc_dev));
-		goto bad;
-	}
-	if (ucom->sc_bulkout_no == -1) {
-		printf("%s: Could not find data bulk out\n",
-		       USBDEVNAME(ucom->sc_dev));
-		goto bad;
-	}
-
 	ucom->sc_parent = sc;
 	ucom->sc_portno = UCOM_UNK_PORTNO;
-	/* bulkin, bulkout set above */
 	ucom->sc_ibufsize = UVISORIBUFSIZE;
 	ucom->sc_obufsize = UVISOROBUFSIZE;
 	ucom->sc_ibufsizepad = UVISORIBUFSIZE;
 	ucom->sc_opkthdrlen = 0;
 	ucom->sc_callback = &uvisor_callback;
 
-	if (uaa->vendor == USB_VENDOR_SONY &&
-	    uaa->product == USB_PRODUCT_SONY_CLIE_35)
-		err = clie_3_5_init(sc);
-	else
-		err = uvisor_init(sc);
-
+	err = uvisor_init(sc, &coninfo);
 	if (err) {
 		printf("%s: init failed, %s\n", USBDEVNAME(ucom->sc_dev),
 		       usbd_errstr(err));
 		goto bad;
 	}
 
+	if (sc->sc_flags & VISOR) {
+		for (i = 0; i < id->bNumEndpoints; i++) {
+			int addr, dir, attr;
+			ed = usbd_interface2endpoint_descriptor(iface, i);
+			if (ed == NULL) {
+				printf("%s: could not read endpoint descriptor"
+				       ": %s\n", devname, usbd_errstr(err));
+				goto bad;
+			}
+
+			addr = ed->bEndpointAddress;
+			dir = UE_GET_DIR(ed->bEndpointAddress);
+			attr = ed->bmAttributes & UE_XFERTYPE;
+			if (dir == UE_DIR_IN && attr == UE_BULK)
+				ucom->sc_bulkin_no = addr;
+			else if (dir == UE_DIR_OUT && attr == UE_BULK)
+				ucom->sc_bulkout_no = addr;
+			else {
+				printf("%s: unexpected endpoint\n", devname);
+				goto bad;
+			}
+		}
+	} else {
+		int nc = coninfo.ci_palm.num_ports;
+		int port;
+
+		if (nc > UVISOR_MAX_CONN)
+			nc = UVISOR_MAX_CONN;
+
+		/* XXX Should attach a ucom for each connection. */
+		for (i = 0; i < nc; ++i)
+			if (coninfo.ci_palm.connections[i].port_function_id[0]
+			    == UVISOR_FUNCTION_HOTSYNC)
+				break;
+		if (i == nc)
+			i = nc - 1;
+		ucom->sc_portno = 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.
+		 */
+		if (coninfo.ci_palm.endpoint_numbers_different) {
+			port = coninfo.ci_palm.connections[i].end_point_info;
+			ucom->sc_bulkin_no = (port >> 4) | UE_DIR_IN;
+			ucom->sc_bulkout_no = (port & 0xf) | UE_DIR_OUT;
+		} else {
+			port = coninfo.ci_palm.connections[i].port;
+			ucom->sc_bulkin_no = port | UE_DIR_IN;
+			ucom->sc_bulkout_no = port | UE_DIR_OUT;
+		}
+	}
+
+	if (ucom->sc_bulkin_no == -1) {
+		printf("%s: Could not find data bulk in\n",
+		       USBDEVNAME(ucom->sc_dev));
+		goto bad;
+	}
+	if (ucom->sc_bulkout_no == -1) {
+		printf("%s: Could not find data bulk out\n",
+		       USBDEVNAME(ucom->sc_dev));
+		goto bad;
+	}
+
 	usbd_add_drv_event(USB_EVENT_DRIVER_ATTACH, ucom->sc_udev,
 			   USBDEV(ucom->sc_dev));
 
_at__at_ -408,36 +456,41 _at__at_
 }
 
 usbd_status
-uvisor_init(struct uvisor_softc *sc)
+uvisor_init(struct uvisor_softc *sc, union connection_info *ci)
 {
 	usbd_status err;
 	usb_device_request_t req;
-	struct uvisor_connection_info coninfo;
 	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_ucom.sc_udev, &req, &coninfo,
-				    USBD_SHORT_XFER_OK, &actlen,
-				    USBD_DEFAULT_TIMEOUT);
-	if (err)
-		return (err);
 
+	/*
+	 * XXX
+	 * For Visor, we should be attaching every port, or at least what
+	 * we know is the HotSync port.
+	 */
+	if (sc->sc_flags & VISOR) {
 #ifdef USB_DEBUG
-	{
 		int i, np;
 		char *string;
+#endif
 
-		np = UGETW(coninfo.num_ports);
+		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_ucom.sc_udev, &req,
+		    &ci->ci_visor, USBD_SHORT_XFER_OK, &actlen,
+		    USBD_DEFAULT_TIMEOUT);
+		if (err)
+			return (err);
+#ifdef USB_DEBUG
+		np = UGETW(ci->ci_visor.num_ports);
 		printf("%s: Number of ports: %d\n", USBDEVNAME(sc->sc_ucom.sc_dev), np);
 		for (i = 0; i < np; ++i) {
-			switch (coninfo.connections[i].port_function_id) {
+			switch (ci->ci_visor.connections[i].port_function_id) {
 			case UVISOR_FUNCTION_GENERIC:
 				string = "Generic";
 				break;
_at__at_ -455,28 +508,19 _at__at_
 				break;
 			}
 			printf("%s: port %d, is for %s\n",
-			    USBDEVNAME(sc->sc_ucom.sc_dev), coninfo.connections[i].port,
+			    USBDEVNAME(sc->sc_ucom.sc_dev), ci->ci_visor.connections[i].port,
 			    string);
 		}
-	}
 #endif
-
-	if (sc->sc_flags & PALM4) {
-		/* Palm OS 4.0 Hack */
-		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_ucom.sc_udev, &req, buffer);
-		if (err)
-			return (err);
+	} else {
 		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_ucom.sc_udev, &req, buffer);
+		err = usbd_do_request_flags(sc->sc_ucom.sc_udev, &req,
+		    &ci->ci_palm, USBD_SHORT_XFER_OK, &actlen,
+		    USBD_DEFAULT_TIMEOUT);
 		if (err)
 			return (err);
 	}
_at__at_ -496,76 +540,6 _at__at_
 	return (err);
 }
 
-usbd_status
-clie_3_5_init(struct uvisor_softc *sc)
-{
-	usbd_status err;
-	usb_device_request_t req;
-	char buffer[256];
-
-	/*
-	 * Note that PEG-300 series devices expect the following two calls.
-	 */
-
-	/* get the config number */
-	DPRINTF(("clie_3_5_init: getting config info\n"));
-	req.bmRequestType = UT_READ;
-	req.bRequest = UR_GET_CONFIG;
-	USETW(req.wValue, 0);
-	USETW(req.wIndex, 0);
-	USETW(req.wLength, 1);
-	err = usbd_do_request(sc->sc_ucom.sc_udev, &req, buffer);
-	if (err)
-		return (err);
-
-	/* get the interface number */
-	DPRINTF(("clie_3_5_init: get the interface number\n"));
-	req.bmRequestType = UT_READ_DEVICE;
-	req.bRequest = UR_GET_INTERFACE;
-	USETW(req.wValue, 0);
-	USETW(req.wIndex, 0);
-	USETW(req.wLength, 1);
-	err = usbd_do_request(sc->sc_ucom.sc_udev, &req, buffer);
-	if (err)
-		return (err);
-
-#ifdef USB_DEBUG
-	{
-		struct uvisor_connection_info coninfo;
-		int i, np;
-		char *string;
-
-		np = UGETW(coninfo.num_ports);
-		DPRINTF(("%s: Number of ports: %d\n", USBDEVNAME(sc->sc_ucom.sc_dev), np));
-		for (i = 0; i < np; ++i) {
-			switch (coninfo.connections[i].port_function_id) {
-			case UVISOR_FUNCTION_GENERIC:
-				string = "Generic";
-				break;
-			case UVISOR_FUNCTION_DEBUGGER:
-				string = "Debugger";
-				break;
-			case UVISOR_FUNCTION_HOTSYNC:
-				string = "HotSync";
-				break;
-			case UVISOR_FUNCTION_REMOTE_FILE_SYS:
-				string = "Remote File System";
-				break;
-			default:
-				string = "unknown";
-				break;	
-			}
-			DPRINTF(("%s: port %d, is for %s\n",
-			    USBDEVNAME(sc->sc_ucom.sc_dev), coninfo.connections[i].port,
-			    string));
-		}
-	}
-#endif
-
-	DPRINTF(("clie_3_5_init: done\n"));
-	return (err);
-}
-
 void
 uvisor_close(void *addr, int portno)
 {

-- 
Brian Fundakowski Feldman                           \'[ FreeBSD ]''''''''''\
  <> green_at_FreeBSD.org                               \  The Power to Serve! \
 Opinions expressed are my own.                       \,,,,,,,,,,,,,,,,,,,,,,\
Received on Thu Jul 01 2004 - 14:45:25 UTC

This archive was generated by hypermail 2.4.0 : Wed May 19 2021 - 11:37:59 UTC