*** uvisor.c.orig	Wed Jan  1 00:09:21 1997
--- uvisor.c	Fri Nov 28 19:25:14 2003
***************
*** 1,5 ****
  /*	$NetBSD: uvisor.c,v 1.9 2001/01/23 14:04:14 augustss Exp $	*/
! /*      $FreeBSD: src/sys/dev/usb/uvisor.c,v 1.7.2.6 2003/09/02 14:35:17 joe Exp $	*/
  
  /* This version of uvisor is heavily based upon the version in NetBSD
   * but is missing the following patches:
--- 1,5 ----
  /*	$NetBSD: uvisor.c,v 1.9 2001/01/23 14:04:14 augustss Exp $	*/
! /*      $FreeBSD: src/sys/dev/usb/uvisor.c,v 1.7.2.7 2003/11/12 00:19:50 joe Exp $	*/
  
  /* This version of uvisor is heavily based upon the version in NetBSD
   * but is missing the following patches:
***************
*** 140,147 ****
   * Unknown PalmOS stuff.
   */
  #define UVISOR_GET_PALM_INFORMATION		0x04
! #define UVISOR_GET_PALM_INFORMATION_LEN		0x14
  
  
  /*
   * Crank down UVISORBUFSIZE from 1024 to 64 to avoid a problem where
--- 140,158 ----
   * Unknown PalmOS stuff.
   */
  #define UVISOR_GET_PALM_INFORMATION		0x04
! #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];
+ };
  
  /*
   * Crank down UVISORBUFSIZE from 1024 to 64 to avoid a problem where
***************
*** 203,211 ****
  	struct usb_devno	uv_dev;
  	u_int16_t		uv_flags;
  #define PALM4	0x0001
  };
  static const struct uvisor_type uvisor_devs[] = {
! 	{{ USB_VENDOR_HANDSPRING, USB_PRODUCT_HANDSPRING_VISOR }, 0 },
  	{{ USB_VENDOR_HANDSPRING, USB_PRODUCT_HANDSPRING_TREO }, PALM4 },
  	{{ USB_VENDOR_PALM, USB_PRODUCT_PALM_M500 }, PALM4 },
  	{{ USB_VENDOR_PALM, USB_PRODUCT_PALM_M505 }, PALM4 },
--- 214,223 ----
  	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 }, 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 },
***************
*** 216,222 ****
  	{{ USB_VENDOR_PALM, USB_PRODUCT_PALM_TUNGSTEN_Z }, PALM4 },
  	{{ 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_S360 }, PALM4 },
  	{{ USB_VENDOR_SONY, USB_PRODUCT_SONY_CLIE_NX60 }, PALM4 },
--- 228,234 ----
  	{{ USB_VENDOR_PALM, USB_PRODUCT_PALM_TUNGSTEN_Z }, PALM4 },
  	{{ 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 }, 0 },
  	{{ USB_VENDOR_SONY, USB_PRODUCT_SONY_CLIE_41 }, 0 },
  	{{ USB_VENDOR_SONY, USB_PRODUCT_SONY_CLIE_S360 }, PALM4 },
  	{{ USB_VENDOR_SONY, USB_PRODUCT_SONY_CLIE_NX60 }, PALM4 },
***************
*** 284,290 ****
  		goto bad;
  	}
  
! 	printf("%s: %s\n", devname, devinfo);
  
  	sc->sc_flags = uvisor_lookup(uaa->vendor, uaa->product)->uv_flags;
  
--- 296,302 ----
  		goto bad;
  	}
  
! /*	printf("%s: %s\n", devname, devinfo);*/
  
  	sc->sc_flags = uvisor_lookup(uaa->vendor, uaa->product)->uv_flags;
  
***************
*** 395,415 ****
  	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);
! 	if (err)
! 		return (err);
! 
  #ifdef USB_DEBUG
  	{
  		int i, np;
--- 407,429 ----
  	usbd_status err;
  	usb_device_request_t req;
  	struct uvisor_connection_info coninfo;
+ 	struct uvisor_palm_connection_info pconinfo;
  	int actlen;
  	uWord avail;
  	char buffer[256];
  
! 	if (sc->sc_flags & VISOR) { 
! 		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);
! 		if (err)
! 			return (err);
! 	}
  #ifdef USB_DEBUG
  	{
  		int i, np;
***************
*** 443,457 ****
  #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);
  		req.bmRequestType = UT_READ_VENDOR_ENDPOINT;
  		req.bRequest = UVISOR_GET_PALM_INFORMATION;
  		USETW(req.wValue, 0);
--- 457,490 ----
  #endif
  
  	if (sc->sc_flags & PALM4) {
+ 	        int port;
  		/* 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_flags(sc->sc_ucom.sc_udev, &req, &pconinfo,
! 					    USBD_SHORT_XFER_OK, &actlen);
  		if (err)
  			return (err);
+ 
+ 	  /*
+ 		printf("pconinfo.num_ports=%d\n",pconinfo.num_ports);
+ 		printf("pconinfo.endpoint_numbers_different=%d\n",pconinfo.endpoint_numbers_different);
+ 	   */
+ 
+ 		if (pconinfo.endpoint_numbers_different) {
+ 			port = pconinfo.connections[0].end_point_info;
+ 			sc->sc_ucom.sc_bulkin_no = (port >> 4) | UE_DIR_IN;
+ 			sc->sc_ucom.sc_bulkout_no = (port & 0xf) | UE_DIR_OUT;
+ 		} else {
+ 			port = pconinfo.connections[0].port;
+ 			sc->sc_ucom.sc_bulkin_no = port | UE_DIR_IN;
+ 			sc->sc_ucom.sc_bulkout_no = port | UE_DIR_OUT;
+ 		}
+ #if 0
  		req.bmRequestType = UT_READ_VENDOR_ENDPOINT;
  		req.bRequest = UVISOR_GET_PALM_INFORMATION;
  		USETW(req.wValue, 0);
***************
*** 460,465 ****
--- 493,499 ----
  		err = usbd_do_request(sc->sc_ucom.sc_udev, &req, buffer);
  		if (err)
  			return (err);
+ #endif
  	}
  
  	DPRINTF(("uvisor_init: getting available bytes\n"));
