changeset 13737:1189735fe286

2881 usbftdi needs support for the SheevaPlug JTAG adapter Reviewed by: Garrett D'Amore <garrett@damore.org> Reviewed by: Milan Jurik <milan.jurik@xylab.cz> Reviewed by: Albert Lee <trisk@nexenta.com> Approved by: Richard Lowe <richlowe@richlowe.net>
author Hans Rosenfeld <rosenfeld@grumpf.hope-2000.org>
date Tue, 19 Jun 2012 16:29:20 -0500
parents 9f1d48e1681f
children e10d315d1821
files usr/src/pkg/manifests/driver-serial-usbftdi.mf usr/src/uts/common/io/usb/clients/usbser/usbftdi/uftdi_dsd.c usr/src/uts/common/io/usb/usbdevs usr/src/uts/common/sys/usb/clients/usbser/usbftdi/uftdi_var.h
diffstat 4 files changed, 74 insertions(+), 26 deletions(-) [+]
line wrap: on
line diff
--- a/usr/src/pkg/manifests/driver-serial-usbftdi.mf	Fri Jun 22 10:17:50 2012 -0400
+++ b/usr/src/pkg/manifests/driver-serial-usbftdi.mf	Tue Jun 19 16:29:20 2012 -0500
@@ -63,7 +63,8 @@
     alias=usb7cc,0421 \
     alias=usb856,ac01 \
     alias=usb93c,0601 \
-    alias=usb93c,0701
+    alias=usb93c,0701 \
+    alias=usbif9e88,9e8f.config1.1
 file path=kernel/drv/$(ARCH64)/usbftdi group=sys
 $(i386_ONLY)file path=kernel/drv/usbftdi group=sys
 file path=kernel/drv/usbftdi.conf group=sys \
--- a/usr/src/uts/common/io/usb/clients/usbser/usbftdi/uftdi_dsd.c	Fri Jun 22 10:17:50 2012 -0400
+++ b/usr/src/uts/common/io/usb/clients/usbser/usbftdi/uftdi_dsd.c	Tue Jun 19 16:29:20 2012 -0500
@@ -95,11 +95,11 @@
 /* configuration routines */
 static void	uftdi_cleanup(uftdi_state_t *, int);
 static int	uftdi_dev_attach(uftdi_state_t *);
-static int	uftdi_open_hw_port(uftdi_state_t *, int, int);
+static int	uftdi_open_hw_port(uftdi_state_t *, int);
 
 /* hotplug */
 static int	uftdi_restore_device_state(uftdi_state_t *);
-static int	uftdi_restore_port_state(uftdi_state_t *, int);
+static int	uftdi_restore_port_state(uftdi_state_t *);
 
 /* power management */
 static int	uftdi_create_pm_components(uftdi_state_t *);
@@ -202,6 +202,8 @@
 		return (USB_FAILURE);
 	}
 
+	uf->uf_hwport = FTDI_PIT_SIOA + uf->uf_dev_data->dev_curr_if;
+
 	mutex_init(&uf->uf_lock, NULL, MUTEX_DRIVER,
 	    uf->uf_dev_data->dev_iblock_cookie);
 
@@ -281,6 +283,15 @@
 			break;
 		}
 		break;
+	case USB_VENDOR_MARVELL:
+		switch (dd->idProduct) {
+		case USB_PRODUCT_MARVELL_SHEEVAPLUG_JTAG:
+			break;
+		default:
+			recognized = B_FALSE;
+			break;
+		}
+		break;
 	default:
 		recognized = B_FALSE;
 		break;
@@ -296,8 +307,8 @@
 	}
 
 	USB_DPRINTF_L3(DPRINT_ATTACH, uf->uf_lh,
-	    "uftdi: matched vendor 0x%x product 0x%x",
-	    dd->idVendor, dd->idProduct);
+	    "uftdi: matched vendor 0x%x product 0x%x port %d",
+	    dd->idVendor, dd->idProduct, uf->uf_hwport);
 
 	uf->uf_def_ph = uf->uf_dev_data->dev_default_ph;
 
@@ -363,6 +374,8 @@
 {
 	uftdi_state_t *uf = (uftdi_state_t *)hdl;
 
+	ASSERT(portno == 0);
+
 	uf->uf_cb = *cb;
 	return (USB_SUCCESS);
 }
@@ -377,6 +390,8 @@
 {
 	uftdi_state_t *uf = (uftdi_state_t *)hdl;
 
+	ASSERT(portno == 0);
+
 	bzero(&uf->uf_cb, sizeof (uf->uf_cb));
 }
 
@@ -393,6 +408,8 @@
 
 	USB_DPRINTF_L4(DPRINT_OPEN, uf->uf_lh, "uftdi_open_port %d", portno);
 
+	ASSERT(portno == 0);
+
 	mutex_enter(&uf->uf_lock);
 	if (uf->uf_dev_state == USB_DEV_DISCONNECTED ||
 	    uf->uf_port_state != UFTDI_PORT_CLOSED) {
@@ -405,7 +422,7 @@
 		return (rval);
 
 	/* initialize hardware serial port */
-	rval = uftdi_open_hw_port(uf, portno, 0);
+	rval = uftdi_open_hw_port(uf, 0);
 
 	if (rval == USB_SUCCESS) {
 		mutex_enter(&uf->uf_lock);
@@ -435,6 +452,8 @@
 
 	USB_DPRINTF_L4(DPRINT_CLOSE, uf->uf_lh, "uftdi_close_port %d", portno);
 
+	ASSERT(portno == 0);
+
 	mutex_enter(&uf->uf_lock);
 
 	/* free resources and finalize state */
@@ -754,7 +773,7 @@
  * If there are errors, return the device to its previous state.
  */
 static int
-uftdi_setregs(uftdi_state_t *uf, uint_t portno, uftdi_regs_t *ur)
+uftdi_setregs(uftdi_state_t *uf, uftdi_regs_t *ur)
 {
 	int rval;
 	uftdi_regs_t uold;
@@ -767,10 +786,10 @@
 		ur = &uold;	/* NULL => restore previous values */
 
 	rval = uftdi_cmd_vendor_write0(uf, FTDI_SIO_SET_BAUD_RATE,
-	    ur->ur_baud, portno);
+	    ur->ur_baud, uf->uf_hwport);
 	if (rval != USB_SUCCESS) {
 		(void) uftdi_cmd_vendor_write0(uf, FTDI_SIO_SET_BAUD_RATE,
-		    uold.ur_baud, portno);
+		    uold.ur_baud, uf->uf_hwport);
 		goto out;
 	} else {
 		mutex_enter(&uf->uf_lock);
@@ -779,10 +798,10 @@
 	}
 
 	rval = uftdi_cmd_vendor_write0(uf, FTDI_SIO_SET_DATA,
-	    ur->ur_data, portno);
+	    ur->ur_data, uf->uf_hwport);
 	if (rval != USB_SUCCESS) {
 		(void) uftdi_cmd_vendor_write0(uf, FTDI_SIO_SET_DATA,
-		    uold.ur_data, portno);
+		    uold.ur_data, uf->uf_hwport);
 		goto out;
 	} else {
 		mutex_enter(&uf->uf_lock);
@@ -791,10 +810,10 @@
 	}
 
 	rval = uftdi_cmd_vendor_write0(uf, FTDI_SIO_SET_FLOW_CTRL,
-	    ur->ur_flowval, ur->ur_flowidx | portno);
+	    ur->ur_flowval, ur->ur_flowidx | uf->uf_hwport);
 	if (rval != USB_SUCCESS) {
 		(void) uftdi_cmd_vendor_write0(uf, FTDI_SIO_SET_FLOW_CTRL,
-		    uold.ur_flowval, uold.ur_flowidx | portno);
+		    uold.ur_flowval, uold.ur_flowidx | uf->uf_hwport);
 		goto out;
 	} else {
 		mutex_enter(&uf->uf_lock);
@@ -816,11 +835,13 @@
 	int rval;
 	uftdi_regs_t uregs;
 
+	ASSERT(portno == 0);
+
 	USB_DPRINTF_L4(DPRINT_CTLOP, uf->uf_lh, "uftdi_set_port_params");
 
 	rval = uftdi_param2regs(uf, tp, &uregs);
 	if (rval == USB_SUCCESS)
-		rval = uftdi_setregs(uf, portno, &uregs);
+		rval = uftdi_setregs(uf, &uregs);
 	return (rval);
 }
 
@@ -834,6 +855,8 @@
 	int rval;
 	uint16_t mctl;
 
+	ASSERT(portno == 0);
+
 	USB_DPRINTF_L4(DPRINT_CTLOP, uf->uf_lh, "uftdi_set_modem_ctl");
 
 	/*
@@ -846,7 +869,7 @@
 		    FTDI_SIO_SET_DTR_HIGH : FTDI_SIO_SET_DTR_LOW;
 
 		rval = uftdi_cmd_vendor_write0(uf,
-		    FTDI_SIO_MODEM_CTRL, mctl, portno);
+		    FTDI_SIO_MODEM_CTRL, mctl, uf->uf_hwport);
 
 		if (rval == USB_SUCCESS) {
 			mutex_enter(&uf->uf_lock);
@@ -862,7 +885,7 @@
 		    FTDI_SIO_SET_RTS_HIGH : FTDI_SIO_SET_RTS_LOW;
 
 		rval = uftdi_cmd_vendor_write0(uf,
-		    FTDI_SIO_MODEM_CTRL, mctl, portno);
+		    FTDI_SIO_MODEM_CTRL, mctl, uf->uf_hwport);
 
 		if (rval == USB_SUCCESS) {
 			mutex_enter(&uf->uf_lock);
@@ -929,6 +952,8 @@
 	uftdi_regs_t *ur = &uf->uf_softr;
 	uint16_t data;
 
+	ASSERT(portno == 0);
+
 	USB_DPRINTF_L4(DPRINT_CTLOP, uf->uf_lh, "uftdi_break_ctl");
 
 	mutex_enter(&uf->uf_lock);
@@ -936,7 +961,7 @@
 	mutex_exit(&uf->uf_lock);
 
 	return (uftdi_cmd_vendor_write0(uf, FTDI_SIO_SET_DATA,
-	    data, portno));
+	    data, uf->uf_hwport));
 }
 
 
@@ -949,6 +974,8 @@
 {
 	uftdi_state_t *uf = (uftdi_state_t *)hdl;
 
+	ASSERT(portno == 0);
+
 	USB_DPRINTF_L4(DPRINT_CTLOP, uf->uf_lh, "uftdi_tx");
 
 	ASSERT(mp != NULL && MBLKL(mp) >= 1);
@@ -972,6 +999,8 @@
 	uftdi_state_t *uf = (uftdi_state_t *)hdl;
 	mblk_t *mp;
 
+	ASSERT(portno == 0);
+
 	USB_DPRINTF_L4(DPRINT_CTLOP, uf->uf_lh, "uftdi_rx");
 
 	mutex_enter(&uf->uf_lock);
@@ -992,6 +1021,8 @@
 {
 	uftdi_state_t *uf = (uftdi_state_t *)hdl;
 
+	ASSERT(portno == 0);
+
 	USB_DPRINTF_L4(DPRINT_CTLOP, uf->uf_lh, "uftdi_stop");
 
 	if (dir & DS_TX) {
@@ -1011,6 +1042,8 @@
 {
 	uftdi_state_t *uf = (uftdi_state_t *)hdl;
 
+	ASSERT(portno == 0);
+
 	USB_DPRINTF_L4(DPRINT_CTLOP, uf->uf_lh, "uftdi_start");
 
 	if (dir & DS_TX) {
@@ -1033,6 +1066,8 @@
 {
 	uftdi_state_t *uf = (uftdi_state_t *)hdl;
 
+	ASSERT(portno == 0);
+
 	USB_DPRINTF_L4(DPRINT_CTLOP, uf->uf_lh,
 	    "uftdi_fifo_flush: dir=0x%x", dir);
 
@@ -1052,11 +1087,11 @@
 
 	if (dir & DS_TX)
 		(void) uftdi_cmd_vendor_write0(uf,
-		    FTDI_SIO_RESET, FTDI_SIO_RESET_PURGE_TX, portno);
+		    FTDI_SIO_RESET, FTDI_SIO_RESET_PURGE_TX, uf->uf_hwport);
 
 	if (dir & DS_RX)
 		(void) uftdi_cmd_vendor_write0(uf,
-		    FTDI_SIO_RESET, FTDI_SIO_RESET_PURGE_RX, portno);
+		    FTDI_SIO_RESET, FTDI_SIO_RESET_PURGE_RX, uf->uf_hwport);
 
 	return (USB_SUCCESS);
 }
@@ -1075,6 +1110,8 @@
 	const uint8_t txempty =
 	    FTDI_LSR_STATUS_TEMT | FTDI_LSR_STATUS_THRE;
 
+	ASSERT(portno == 0);
+
 	USB_DPRINTF_L4(DPRINT_CTLOP, uf->uf_lh, "uftdi_fifo_drain");
 
 	mutex_enter(&uf->uf_lock);
@@ -1194,7 +1231,7 @@
 	state = uf->uf_dev_state = USB_DEV_ONLINE;
 	mutex_exit(&uf->uf_lock);
 
-	if ((uftdi_restore_port_state(uf, 0) != USB_SUCCESS)) {
+	if ((uftdi_restore_port_state(uf) != USB_SUCCESS)) {
 		USB_DPRINTF_L2(DPRINT_HOTPLUG, uf->uf_lh,
 		    "uftdi_restore_device_state: failed");
 	}
@@ -1207,7 +1244,7 @@
  * restore ports state after CPR resume or reconnect
  */
 static int
-uftdi_restore_port_state(uftdi_state_t *uf, int portno)
+uftdi_restore_port_state(uftdi_state_t *uf)
 {
 	int rval;
 
@@ -1219,7 +1256,7 @@
 	mutex_exit(&uf->uf_lock);
 
 	/* open hardware serial port, restoring old settings */
-	if ((rval = uftdi_open_hw_port(uf, portno, 1)) != USB_SUCCESS) {
+	if ((rval = uftdi_open_hw_port(uf, 1)) != USB_SUCCESS) {
 		USB_DPRINTF_L2(DPRINT_HOTPLUG, uf->uf_lh,
 		    "uftdi_restore_port_state: failed");
 	}
@@ -1935,7 +1972,7 @@
  * initialize hardware serial port
  */
 static int
-uftdi_open_hw_port(uftdi_state_t *uf, int portno, int dorestore)
+uftdi_open_hw_port(uftdi_state_t *uf, int dorestore)
 {
 	int rval;
 
@@ -1943,7 +1980,7 @@
 	 * Perform a full reset on the device
 	 */
 	rval = uftdi_cmd_vendor_write0(uf,
-	    FTDI_SIO_RESET, FTDI_SIO_RESET_SIO, portno);
+	    FTDI_SIO_RESET, FTDI_SIO_RESET_SIO, uf->uf_hwport);
 	if (rval != USB_SUCCESS) {
 		USB_DPRINTF_L2(DPRINT_DEF_PIPE, uf->uf_lh,
 		    "uftdi_open_hw_port: failed to reset!");
@@ -1954,7 +1991,7 @@
 		/*
 		 * Restore settings from our soft copy of HW registers
 		 */
-		(void) uftdi_setregs(uf, portno, NULL);
+		(void) uftdi_setregs(uf, NULL);
 	} else {
 		/*
 		 * 9600 baud, 2 stop bits, no parity, 8-bit, h/w flow control
@@ -1979,7 +2016,7 @@
 			sizeof (ents) / sizeof (ents[0])
 		};
 
-		rval = uftdi_set_port_params(uf, portno, &params);
+		rval = uftdi_set_port_params(uf, 0, &params);
 		if (rval != USB_SUCCESS) {
 			USB_DPRINTF_L2(DPRINT_DEF_PIPE, uf->uf_lh,
 			    "uftdi_open_hw_port: failed 9600/2/n/8 rval %d",
@@ -2052,6 +2089,8 @@
 static usb_pipe_handle_t
 uftdi_out_pipe(ds_hdl_t hdl, uint_t portno)
 {
+	ASSERT(portno == 0);
+
 	return (((uftdi_state_t *)hdl)->uf_bulkout_ph);
 }
 
@@ -2059,5 +2098,7 @@
 static usb_pipe_handle_t
 uftdi_in_pipe(ds_hdl_t hdl, uint_t portno)
 {
+	ASSERT(portno == 0);
+
 	return (((uftdi_state_t *)hdl)->uf_bulkin_ph);
 }
--- a/usr/src/uts/common/io/usb/usbdevs	Fri Jun 22 10:17:50 2012 -0400
+++ b/usr/src/uts/common/io/usb/usbdevs	Tue Jun 19 16:29:20 2012 -0500
@@ -675,6 +675,7 @@
 vendor INTEL		0x8086	Intel
 vendor SITECOM2		0x9016	Sitecom
 vendor MOSCHIP		0x9710	MosChip Semiconductor
+vendor MARVELL		0x9e88	Marvell Technology Group Ltd.
 vendor 3COM3		0xa727	3Com
 vendor HP2		0xf003	Hewlett Packard
 vendor USRP		0xfffe	GNU Radio USRP
@@ -1664,6 +1665,9 @@
 /* Macally products */
 product MACALLY MOUSE1		0x0101	mouse
 
+/* Marvell Technology Group, Ltd. products */
+product MARVELL SHEEVAPLUG_JTAG	0x9e8f	SheevaPlug JTAGKey
+
 /* MCT Corp. */
 product MCT HUB0100		0x0100	Hub
 product MCT DU_H3SP_USB232	0x0200	D-Link DU-H3SP USB BAY Hub
--- a/usr/src/uts/common/sys/usb/clients/usbser/usbftdi/uftdi_var.h	Fri Jun 22 10:17:50 2012 -0400
+++ b/usr/src/uts/common/sys/usb/clients/usbser/usbftdi/uftdi_var.h	Tue Jun 19 16:29:20 2012 -0500
@@ -67,6 +67,7 @@
 	kmutex_t		uf_lock;		/* structure lock */
 	dev_info_t		*uf_dip;		/* device info */
 	int			uf_dev_flags;		/* device flags */
+	int			uf_hwport;		/* hw port number */
 	int			uf_port_state;		/* port state */
 	int			uf_port_flags;		/* port flags */
 	ds_cb_t			uf_cb;			/* DSD callbacks */
@@ -117,6 +118,7 @@
 	uf_cb
 	uf_bulkin_ph
 	uf_bulkout_ph
+	uf_hwport
 }))
 
 /* port state */