tech-kern archive

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index][Old Index]

Re: Merging ugen into the usb stack



Hi,

with the attached diffs I'm able to attach my debug board like this:

ugen0 at uhub5 port 1 configuration 1 interface 0
ugen0: OpenMoko (0x1457) Debug Board for Neo1973 (0x5118), rev 2.00/5.00, addr 3
uftdi0 at uhub5 port 1 configuration 1 interface 1
uftdi0: OpenMoko (0x1457) Debug Board for Neo1973 (0x5118), rev 2.00/5.00, addr 3
ucom0 at uftdi0 portno 2

(Actually, not, as the codes for my debug board are missing in usbdevs.)

Note that you have to be careful when using this ugen. There
is no restriction to interface 0, you can change configuration
and interfere with the ucom driver attached to interface 1.

The only configuration line needed for this (apart from including
usbdevices.config) is something like

ugen*           at uhub? interface 0 flags 1

or, if you want to restrict this to some specific board:

ugen*           at uhub? vendor 0x1457 product 0x5118 interface 0 flags 1

No need for the previously mentioned "no uftdi*", as the ugen
(due to the "flags 1") will attach with a higher priority.

Ciao,
Wolfgang
--
Wolfgang%Solfrank.net@localhost				Wolfgang Solfrank
Index: files.usb
===================================================================
RCS file: /cvsroot/src/sys/dev/usb/files.usb,v
retrieving revision 1.148
diff -u -r1.148 files.usb
--- files.usb	10 Dec 2017 17:03:07 -0000	1.148
+++ files.usb	8 Feb 2018 16:15:11 -0000
@@ -138,6 +138,7 @@
 # Generic devices
 device	ugen
 attach	ugen at usbdevif
+attach	ugen at usbifif with ugenif
 file	dev/usb/ugen.c			ugen			needs-flag
 
 
@@ -387,7 +388,7 @@
 
 # FTDI serial driver
 device	uftdi: ucombus
-attach	uftdi at usbdevif
+attach	uftdi at usbifif
 file	dev/usb/uftdi.c			uftdi
 
 # Prolific PL2303 serial driver
Index: uftdi.c
===================================================================
RCS file: /cvsroot/src/sys/dev/usb/uftdi.c,v
retrieving revision 1.66
diff -u -r1.66 uftdi.c
--- uftdi.c	22 Dec 2017 14:18:29 -0000	1.66
+++ uftdi.c	8 Feb 2018 16:15:11 -0000
@@ -62,9 +62,7 @@
 #define DPRINTFN(n,x)
 #endif
 
-#define UFTDI_CONFIG_INDEX	0
-#define UFTDI_IFACE_INDEX	0
-#define UFTDI_MAX_PORTS		4
+#define UFTDI_CONFIG_NO		1
 
 /*
  * These are the default number of bytes transferred per frame if the
@@ -83,17 +81,17 @@
 struct uftdi_softc {
 	device_t		sc_dev;		/* base device */
 	struct usbd_device *	sc_udev;	/* device */
-	struct usbd_interface *	sc_iface[UFTDI_MAX_PORTS];	/* interface */
+	struct usbd_interface *	sc_iface;	/* interface */
+	int			sc_iface_no;
 
 	enum uftdi_type		sc_type;
 	u_int			sc_hdrlen;
-	u_int			sc_numports;
 	u_int			sc_chiptype;
 
 	u_char			sc_msr;
 	u_char			sc_lsr;
 
-	device_t		sc_subdev[UFTDI_MAX_PORTS];
+	device_t		sc_subdev;
 
 	u_char			sc_dying;
 
@@ -190,29 +188,30 @@
 int
 uftdi_match(device_t parent, cfdata_t match, void *aux)
 {
-	struct usb_attach_arg *uaa = aux;
+	struct usbif_attach_arg *uiaa = aux;
 
 	DPRINTFN(20,("uftdi: vendor=0x%x, product=0x%x\n",
-		     uaa->uaa_vendor, uaa->uaa_product));
+		     uiaa->uiaa_vendor, uiaa->uiaa_product));
 
-	return uftdi_lookup(uaa->uaa_vendor, uaa->uaa_product) != NULL ?
-		UMATCH_VENDOR_PRODUCT : UMATCH_NONE;
+	if (uiaa->uiaa_configno != UFTDI_CONFIG_NO)
+		return UMATCH_NONE;
+
+	return uftdi_lookup(uiaa->uiaa_vendor, uiaa->uiaa_product) != NULL ?
+		UMATCH_VENDOR_PRODUCT_CONF_IFACE : UMATCH_NONE;
 }
 
 void
 uftdi_attach(device_t parent, device_t self, void *aux)
 {
 	struct uftdi_softc *sc = device_private(self);
-	struct usb_attach_arg *uaa = aux;
-	struct usbd_device *dev = uaa->uaa_device;
-	struct usbd_interface *iface;
+	struct usbif_attach_arg *uiaa = aux;
+	struct usbd_device *dev = uiaa->uiaa_device;
+	struct usbd_interface *iface = uiaa->uiaa_iface;
 	usb_device_descriptor_t *ddesc;
 	usb_interface_descriptor_t *id;
 	usb_endpoint_descriptor_t *ed;
 	char *devinfop;
-	const char *devname = device_xname(self);
-	int i,idx;
-	usbd_status err;
+	int i;
 	struct ucom_attach_args ucaa;
 
 	DPRINTFN(10,("\nuftdi_attach: sc=%p\n", sc));
@@ -224,122 +223,86 @@
 	aprint_normal_dev(self, "%s\n", devinfop);
 	usbd_devinfo_free(devinfop);
 
-	/* Move the device into the configured state. */
-	err = usbd_set_config_index(dev, UFTDI_CONFIG_INDEX, 1);
-	if (err) {
-		aprint_error("\n%s: failed to set configuration, err=%s\n",
-		       devname, usbd_errstr(err));
-		goto bad;
-	}
-
 	sc->sc_dev = self;
 	sc->sc_udev = dev;
-	sc->sc_numports = 1;
+	sc->sc_iface_no = uiaa->uiaa_ifaceno;
 	sc->sc_type = UFTDI_TYPE_8U232AM; /* most devices are post-8U232AM */
 	sc->sc_hdrlen = 0;
-	if (uaa->uaa_vendor == USB_VENDOR_FTDI
-	    && uaa->uaa_product == USB_PRODUCT_FTDI_SERIAL_8U100AX) {
+	if (uiaa->uiaa_vendor == USB_VENDOR_FTDI
+	    && uiaa->uiaa_product == USB_PRODUCT_FTDI_SERIAL_8U100AX) {
 		sc->sc_type = UFTDI_TYPE_SIO;
 		sc->sc_hdrlen = 1;
 	}
 
 	ddesc = usbd_get_device_descriptor(dev);
 	sc->sc_chiptype = UGETW(ddesc->bcdDevice);
-	switch (sc->sc_chiptype) {
-	case 0x500: /* 2232D */
-	case 0x700: /* 2232H */
-		sc->sc_numports = 2;
-		break;
-	case 0x800: /* 4232H */
-		sc->sc_numports = 4;
-		break;
-	case 0x200: /* 232/245AM */
-	case 0x400: /* 232/245BL */
-	case 0x600: /* 232/245R */
-	default:
-		break;
-	}
-
-	for (idx = UFTDI_IFACE_INDEX; idx < sc->sc_numports; idx++) {
-		err = usbd_device2interface_handle(dev, idx, &iface);
-		if (err) {
-			aprint_error(
-			    "\n%s: failed to get interface idx=%d, err=%s\n",
-			    devname, idx, usbd_errstr(err));
-			goto bad;
-		}
 
-		id = usbd_get_interface_descriptor(iface);
+	id = usbd_get_interface_descriptor(iface);
 
-		sc->sc_iface[idx] = iface;
+	sc->sc_iface = iface;
 
-		ucaa.ucaa_bulkin = ucaa.ucaa_bulkout = -1;
-		ucaa.ucaa_ibufsize = ucaa.ucaa_obufsize = 0;
-		for (i = 0; i < id->bNumEndpoints; i++) {
-			int addr, dir, attr;
-			ed = usbd_interface2endpoint_descriptor(iface, i);
-			if (ed == NULL) {
-				aprint_error_dev(self,
-				    "could not read endpoint descriptor: %s\n",
-				    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) {
-				ucaa.ucaa_bulkin = addr;
-				ucaa.ucaa_ibufsize = UGETW(ed->wMaxPacketSize);
-				if (ucaa.ucaa_ibufsize >= UFTDI_MAX_IBUFSIZE)
-					ucaa.ucaa_ibufsize = UFTDI_MAX_IBUFSIZE;
-			} else if (dir == UE_DIR_OUT && attr == UE_BULK) {
-				ucaa.ucaa_bulkout = addr;
-				ucaa.ucaa_obufsize = UGETW(ed->wMaxPacketSize)
-				    - sc->sc_hdrlen;
-				if (ucaa.ucaa_obufsize >= UFTDI_MAX_OBUFSIZE)
-					ucaa.ucaa_obufsize = UFTDI_MAX_OBUFSIZE;
-				/* Limit length if we have a 6-bit header.  */
-				if ((sc->sc_hdrlen > 0) &&
-				    (ucaa.ucaa_obufsize > UFTDIOBUFSIZE))
-					ucaa.ucaa_obufsize = UFTDIOBUFSIZE;
-			} else {
-				aprint_error_dev(self,
-				    "unexpected endpoint\n");
-				goto bad;
-			}
-		}
-		if (ucaa.ucaa_bulkin == -1) {
+	ucaa.ucaa_bulkin = ucaa.ucaa_bulkout = -1;
+	ucaa.ucaa_ibufsize = ucaa.ucaa_obufsize = 0;
+	for (i = 0; i < id->bNumEndpoints; i++) {
+		int addr, dir, attr;
+		ed = usbd_interface2endpoint_descriptor(iface, i);
+		if (ed == NULL) {
 			aprint_error_dev(self,
-			    "Could not find data bulk in\n");
+			    "could not read endpoint descriptor\n");
 			goto bad;
 		}
-		if (ucaa.ucaa_bulkout == -1) {
-			aprint_error_dev(self,
-			    "Could not find data bulk out\n");
+
+		addr = ed->bEndpointAddress;
+		dir = UE_GET_DIR(ed->bEndpointAddress);
+		attr = ed->bmAttributes & UE_XFERTYPE;
+		if (dir == UE_DIR_IN && attr == UE_BULK) {
+			ucaa.ucaa_bulkin = addr;
+			ucaa.ucaa_ibufsize = UGETW(ed->wMaxPacketSize);
+			if (ucaa.ucaa_ibufsize >= UFTDI_MAX_IBUFSIZE)
+				ucaa.ucaa_ibufsize = UFTDI_MAX_IBUFSIZE;
+		} else if (dir == UE_DIR_OUT && attr == UE_BULK) {
+			ucaa.ucaa_bulkout = addr;
+			ucaa.ucaa_obufsize = UGETW(ed->wMaxPacketSize)
+			    - sc->sc_hdrlen;
+			if (ucaa.ucaa_obufsize >= UFTDI_MAX_OBUFSIZE)
+				ucaa.ucaa_obufsize = UFTDI_MAX_OBUFSIZE;
+			/* Limit length if we have a 6-bit header.  */
+			if ((sc->sc_hdrlen > 0) &&
+			    (ucaa.ucaa_obufsize > UFTDIOBUFSIZE))
+				ucaa.ucaa_obufsize = UFTDIOBUFSIZE;
+		} else {
+			aprint_error_dev(self, "unexpected endpoint\n");
 			goto bad;
 		}
-
-		ucaa.ucaa_portno = FTDI_PIT_SIOA + idx;
-		/* ucaa_bulkin, ucaa_bulkout set above */
-		if (ucaa.ucaa_ibufsize == 0)
-			ucaa.ucaa_ibufsize = UFTDIIBUFSIZE;
-		ucaa.ucaa_ibufsizepad = ucaa.ucaa_ibufsize;
-		if (ucaa.ucaa_obufsize == 0)
-			ucaa.ucaa_obufsize = UFTDIOBUFSIZE - sc->sc_hdrlen;
-		ucaa.ucaa_opkthdrlen = sc->sc_hdrlen;
-		ucaa.ucaa_device = dev;
-		ucaa.ucaa_iface = iface;
-		ucaa.ucaa_methods = &uftdi_methods;
-		ucaa.ucaa_arg = sc;
-		ucaa.ucaa_info = NULL;
-
-		DPRINTF(("uftdi: in=0x%x out=0x%x isize=0x%x osize=0x%x\n",
-			ucaa.ucaa_bulkin, ucaa.ucaa_bulkout,
-			ucaa.ucaa_ibufsize, ucaa.ucaa_obufsize));
-		sc->sc_subdev[idx] = config_found_sm_loc(self, "ucombus", NULL,
-		    &ucaa, ucomprint, ucomsubmatch);
 	}
+	if (ucaa.ucaa_bulkin == -1) {
+		aprint_error_dev(self, "Could not find data bulk in\n");
+		goto bad;
+	}
+	if (ucaa.ucaa_bulkout == -1) {
+		aprint_error_dev(self, "Could not find data bulk out\n");
+		goto bad;
+	}
+
+	ucaa.ucaa_portno = FTDI_PIT_SIOA + sc->sc_iface_no;
+	/* ucaa_bulkin, ucaa_bulkout set above */
+	if (ucaa.ucaa_ibufsize == 0)
+		ucaa.ucaa_ibufsize = UFTDIIBUFSIZE;
+	ucaa.ucaa_ibufsizepad = ucaa.ucaa_ibufsize;
+	if (ucaa.ucaa_obufsize == 0)
+		ucaa.ucaa_obufsize = UFTDIOBUFSIZE - sc->sc_hdrlen;
+	ucaa.ucaa_opkthdrlen = sc->sc_hdrlen;
+	ucaa.ucaa_device = dev;
+	ucaa.ucaa_iface = iface;
+	ucaa.ucaa_methods = &uftdi_methods;
+	ucaa.ucaa_arg = sc;
+	ucaa.ucaa_info = NULL;
+
+	DPRINTF(("uftdi: in=0x%x out=0x%x isize=0x%x osize=0x%x\n",
+		ucaa.ucaa_bulkin, ucaa.ucaa_bulkout,
+		ucaa.ucaa_ibufsize, ucaa.ucaa_obufsize));
+	sc->sc_subdev = config_found_sm_loc(self, "ucombus", NULL,
+	    &ucaa, ucomprint, ucomsubmatch);
 
 	usbd_add_drv_event(USB_EVENT_DRIVER_ATTACH, sc->sc_udev, sc->sc_dev);
 
@@ -371,29 +334,21 @@
 void
 uftdi_childdet(device_t self, device_t child)
 {
-	int i;
 	struct uftdi_softc *sc = device_private(self);
 
-	for (i = 0; i < sc->sc_numports; i++) {
-		if (sc->sc_subdev[i] == child)
-			break;
-	}
-	KASSERT(i < sc->sc_numports);
-	sc->sc_subdev[i] = NULL;
+	KASSERT(child == sc->sc_subdev);
+	sc->sc_subdev = NULL;
 }
 
 int
 uftdi_detach(device_t self, int flags)
 {
 	struct uftdi_softc *sc = device_private(self);
-	int i;
 
 	DPRINTF(("uftdi_detach: sc=%p flags=%d\n", sc, flags));
 	sc->sc_dying = 1;
-	for (i=0; i < sc->sc_numports; i++) {
-		if (sc->sc_subdev[i] != NULL)
-			config_detach(sc->sc_subdev[i], flags);
-	}
+	if (sc->sc_subdev != NULL)
+		config_detach(sc->sc_subdev, flags);
 
 	usbd_add_drv_event(USB_EVENT_DRIVER_DETACH, sc->sc_udev, sc->sc_dev);
 
@@ -466,7 +421,7 @@
 			 lsr, sc->sc_lsr));
 		sc->sc_msr = msr;
 		sc->sc_lsr = lsr;
-		ucom_status_change(device_private(sc->sc_subdev[portno-1]));
+		ucom_status_change(device_private(sc->sc_subdev));
 	}
 
 	/* Adjust buffer pointer to skip status prefix */
Index: ugen.c
===================================================================
RCS file: /cvsroot/src/sys/dev/usb/ugen.c,v
retrieving revision 1.137
diff -u -r1.137 ugen.c
--- ugen.c	21 Jan 2018 13:57:12 -0000	1.137
+++ ugen.c	8 Feb 2018 16:15:11 -0000
@@ -183,15 +183,51 @@
 
 int	ugen_match(device_t, cfdata_t, void *);
 void	ugen_attach(device_t, device_t, void *);
+int	ugenif_match(device_t, cfdata_t, void *);
+void	ugenif_attach(device_t, device_t, void *);
 int	ugen_detach(device_t, int);
 int	ugen_activate(device_t, enum devact);
 extern struct cfdriver ugen_cd;
-CFATTACH_DECL_NEW(ugen, sizeof(struct ugen_softc), ugen_match, ugen_attach,
-    ugen_detach, ugen_activate);
+CFATTACH_DECL_NEW(ugen, sizeof(struct ugen_softc), ugen_match,
+    ugen_attach, ugen_detach, ugen_activate);
+CFATTACH_DECL_NEW(ugenif, sizeof(struct ugen_softc), ugenif_match,
+    ugenif_attach, ugen_detach, ugen_activate);
 
 /* toggle to control attach priority. -1 means "let autoconf decide" */
 int ugen_override = -1;
 
+static void
+ugenif_aux(struct usbif_attach_arg *uiaa, struct usb_attach_arg *uaa)
+{
+	memset(uaa, 0, sizeof *uaa);
+	uaa->uaa_port = uiaa->uiaa_port;
+	uaa->uaa_vendor = uiaa->uiaa_vendor;
+	uaa->uaa_product = uiaa->uiaa_product;
+	uaa->uaa_release = uiaa->uiaa_release;
+	uaa->uaa_device = uiaa->uiaa_device;
+	uaa->uaa_usegeneric = 1;
+}
+
+int
+ugenif_match(device_t parent, cfdata_t match, void *aux)
+{
+	struct usbif_attach_arg *uiaa = aux;
+	struct usb_attach_arg uaa;
+
+	ugenif_aux(uiaa, &uaa);
+	return ugen_match(parent, match, &uaa);
+}
+
+void
+ugenif_attach(device_t parent, device_t self, void *aux)
+{
+	struct usbif_attach_arg *uiaa = aux;
+	struct usb_attach_arg uaa;
+
+	ugenif_aux(uiaa, &uaa);
+	return ugen_attach(parent, self, &uaa);
+}
+
 int
 ugen_match(device_t parent, cfdata_t match, void *aux)
 {


Home | Main Index | Thread Index | Old Index