Skip site navigation (1)Skip section navigation (2)
Date:      Sun, 30 Dec 2007 13:51:14 GMT
From:      Hans Petter Selasky <hselasky@FreeBSD.org>
To:        Perforce Change Reviews <perforce@FreeBSD.org>
Subject:   PERFORCE change 132094 for review
Message-ID:  <200712301351.lBUDpExO072471@repoman.freebsd.org>

next in thread | raw e-mail | index | archive | help
http://perforce.freebsd.org/chv.cgi?CH=132094

Change 132094 by hselasky@hselasky_laptop001 on 2007/12/30 13:50:55

	
	Getting the uchcom probe and attach routines right.
	Some code borrowed from uplcom.

Affected files ...

.. //depot/projects/usb/src/sys/dev/usb/uchcom.c#4 edit

Differences ...

==== //depot/projects/usb/src/sys/dev/usb/uchcom.c#4 (text+ko) ====

@@ -147,26 +147,23 @@
 #define UCHCOM_INTR_STAT2	0x03
 #define UCHCOM_INTR_LEAST	4
 
-#define UCHCOMIBUFSIZE 256
-#define UCHCOMOBUFSIZE 256
+#define	UCHCOM_BULK_BUF_SIZE 1024 /* bytes */
+#define	UCHCOM_N_TRANSFER 6 /* units */
+
+struct uchcom_softc {
+	struct ucom_super_softc sc_super_ucom;
+	struct ucom_softc sc_ucom;
 
-struct uchcom_softc
-{
-	struct ucom_softc	sc_ucom;
+	struct usbd_xfer *sc_xfer[UCHCOM_N_TRANSFER];
+	struct usbd_device *sc_udev;
 
-	/* */
-	int			sc_intr_endpoint;
-	int			sc_intr_size;
-	usbd_pipe_handle	sc_intr_pipe;
-	u_char			*sc_intr_buf;
-	/* */
-	uint8_t			sc_version;
-	int			sc_dtr;
-	int			sc_rts;
-	u_char			sc_lsr;
-	u_char			sc_msr;
-	int			sc_lcr1;
-	int			sc_lcr2;
+	uint8_t		sc_version;
+	uint8_t		sc_msr;
+	uint8_t		sc_lsr;			/* local status register */
+	uint8_t		sc_flag;
+#define	UCHCOM_FLAG_INTR_STALL  0x01
+#define	UCHCOM_FLAG_READ_STALL  0x02
+#define	UCHCOM_FLAG_WRITE_STALL 0x04
 };
 
 struct uchcom_endpoints
@@ -213,19 +210,78 @@
 static int	uchcom_param(void *, int, struct termios *);
 static int	uchcom_open(void *, int);
 static void	uchcom_close(void *, int);
-static void	uchcom_intr(usbd_xfer_handle, usbd_private_handle,
-			    usbd_status);
-
-static int	uchcom_set_config(device_t );
-static int	uchcom_find_ifaces(struct uchcom_softc *, usbd_interface_handle *);
-static int	uchcom_find_endpoints(struct uchcom_softc *,
-			       struct uchcom_endpoints *);
-static void	uchcom_close_intr_pipe(struct uchcom_softc *);
 
 static device_probe_t uchcom_probe;
 static device_attach_t uchcom_attach;
 static device_detach_t uchcom_detach;
 
+static usbd_callback_t uchcom_intr_callback;
+static usbd_callback_t uchcom_intr_clear_stall_callback;
+static usbd_callback_t uchcom_write_callback;
+static usbd_callback_t uchcom_write_clear_stall_callback;
+static usbd_callback_t uchcom_read_callback;
+static usbd_callback_t uchcom_read_clear_stall_callback;
+
+static const struct usbd_config uchcom_config_data[UCHCOM_N_TRANSFER] = {
+
+	[0] = {
+		.type = UE_BULK,
+		.endpoint = UE_ADDR_ANY,
+		.direction = UE_DIR_OUT,
+		.bufsize = UCHCOM_BULK_BUF_SIZE,
+		.mh.flags = {.pipe_bof = 1,.force_short_xfer = 1,},
+		.mh.callback = &uchcom_write_callback,
+	},
+
+	[1] = {
+		.type = UE_BULK,
+		.endpoint = UE_ADDR_ANY,
+		.direction = UE_DIR_IN,
+		.bufsize = UCHCOM_BULK_BUF_SIZE,
+		.mh.flags = {.pipe_bof = 1,.short_xfer_ok = 1,},
+		.mh.callback = &uchcom_read_callback,
+	},
+
+	[2] = {
+		.type = UE_CONTROL,
+		.endpoint = 0x00,	/* Control pipe */
+		.direction = UE_DIR_ANY,
+		.bufsize = sizeof(usb_device_request_t),
+		.mh.callback = &uchcom_write_clear_stall_callback,
+		.mh.timeout = 1000,	/* 1 second */
+		.interval = 50,		/* 50ms */
+	},
+
+	[3] = {
+		.type = UE_CONTROL,
+		.endpoint = 0x00,	/* Control pipe */
+		.direction = UE_DIR_ANY,
+		.bufsize = sizeof(usb_device_request_t),
+		.mh.callback = &uchcom_read_clear_stall_callback,
+		.mh.timeout = 1000,	/* 1 second */
+		.interval = 50,		/* 50ms */
+	},
+
+	[4] = {
+		.type = UE_INTERRUPT,
+		.endpoint = UE_ADDR_ANY,
+		.direction = UE_DIR_IN,
+		.mh.flags = {.pipe_bof = 1,.short_xfer_ok = 1,},
+		.bufsize = 0,		/* use wMaxPacketSize */
+		.mh.callback = &uchcom_intr_callback,
+	},
+
+	[5] = {
+		.type = UE_CONTROL,
+		.endpoint = 0x00,	/* Control pipe */
+		.direction = UE_DIR_ANY,
+		.bufsize = sizeof(usb_device_request_t),
+		.mh.callback = &uchcom_intr_clear_stall_callback,
+		.mh.timeout = 1000,	/* 1 second */
+		.interval = 50,		/* 50ms */
+	},
+};
+
 struct	ucom_callback uchcom_callback = {
 	.ucom_get_status	= uchcom_get_status,
 	.ucom_set		= uchcom_set,
@@ -238,190 +294,106 @@
 };
 
 
-
-
 /* ----------------------------------------------------------------------
  * driver entry points
  */
 
-static int uchcom_probe(device_t self)
+static int
+uchcom_probe(device_t dev)
 {
-	struct usb_attach_arg *uaa = device_get_ivars(self);
+	struct usb_attach_arg *uaa = device_get_ivars(dev);
+
+	DPRINTF(10, "\n");
+
+	if (uaa->usb_mode != USB_MODE_HOST) {
+		return (UMATCH_NONE);
+	}
+
+	if (uaa->iface) {
+		return (UMATCH_NONE);
+	}
 
 	return (uchcom_lookup(uaa->vendor, uaa->product) != NULL ?
 		UMATCH_VENDOR_PRODUCT : UMATCH_NONE);
 }
 
-static int uchcom_attach(device_t self)
+static int
+uchcom_attach(device_t dev)
 {
-	struct uchcom_softc *sc = device_get_softc(self);
-	struct usb_attach_arg *uaa = device_get_ivars(self);
-	usbd_device_handle dev = uaa->device;
+	struct uchcom_softc *sc = device_get_softc(dev);
+	struct usb_attach_arg *uaa = device_get_ivars(dev);
+	int error;
+	uint8_t iface_index;
+
+	DPRINTF(10, "\n");
 
-	struct uchcom_endpoints endpoints;
-	struct ucom_softc *ucom = &sc->sc_ucom;
+	if (sc == NULL) {
+		return (ENOMEM);
+	}
+	usbd_set_device_desc(dev);
 
-	ucom->sc_dev = self;
-	ucom->sc_udev = dev;
+	sc->sc_udev = uaa->device;
 
-	ucom->sc_dying = 0;
-	sc->sc_dtr = sc->sc_rts = -1;
-	sc->sc_lsr = sc->sc_msr = 0;
+	/* configure the chip */
 
-	DPRINTF(("\n\nuchcom attach: sc=%p\n", sc));
+	error = usbd_set_config_index(uaa->device, UCHCOM_CONFIG_INDEX, 1);
 
-	if (uchcom_set_config(self))
-		goto failed;
+	if (error) {
+		device_printf(dev, "failed to set configuration, "
+		    "error=%s\n", usbd_errstr(error));
+		goto detach;
+	}
 
 	switch (uaa->release) {
 	case UCHCOM_REV_CH340:
-		device_printf(self, "CH340 detected\n");
+		device_printf(dev, "CH340 detected\n");
 		break;
 	default:
-		device_printf(self, "CH341 detected\n");
+		device_printf(dev, "CH341 detected\n");
 		break;
 	}
 
-	if (uchcom_find_ifaces(sc, &ucom->sc_iface))
-		goto failed;
+	iface_index = UCHCOM_IFACE_INDEX;
+	error = usbd_transfer_setup(uaa->device,
+	    &iface_index, sc->sc_xfer, uchcom_config_data,
+	    UCHCOM_N_TRANSFER, sc, &Giant);
 
-	if (uchcom_find_endpoints(sc, &endpoints))
-		goto failed;
+	if (error) {
+		DPRINTF(0, "one or more missing USB endpoints, "
+		    "error=%s\n", usbd_errstr(error));
+		goto detach;
+	}
 
-	sc->sc_intr_endpoint = endpoints.ep_intr;
-	sc->sc_intr_size = endpoints.ep_intr_size;
+	/* clear stall at first run */
+	sc->sc_flag |= (UCHCOM_FLAG_READ_STALL |
+	    UCHCOM_FLAG_WRITE_STALL);
 
-	/* setup ucom layer */
-	ucom->sc_portno = UCOM_UNK_PORTNO;
-	ucom->sc_bulkin_no = endpoints.ep_bulkin;
-	ucom->sc_bulkout_no = endpoints.ep_bulkout;
-	ucom->sc_ibufsize = UCHCOMIBUFSIZE;
-	ucom->sc_obufsize = UCHCOMOBUFSIZE;
-	ucom->sc_ibufsizepad = UCHCOMIBUFSIZE;
-	ucom->sc_opkthdrlen = 0;
-	ucom->sc_parent = sc;
-
-	ucom->sc_callback = &uchcom_callback;
-
-	ucom_attach(&sc->sc_ucom);
-	
+	error = ucom_attach(&(sc->sc_super_ucom), &(sc->sc_ucom), 1, sc,
+	    &uchcom_callback, &Giant);
+	if (error) {
+		goto detach;
+	}
 	return 0;
 
-failed:
-	ucom->sc_dying = 1;
-	return ENXIO;
+detach:
+	uchcom_detach(dev);
+	return (ENXIO);
 }
 
-static int uchcom_detach(device_t self)
-{
-	struct uchcom_softc *sc = device_get_softc(self);
-	struct ucom_softc *ucom = &sc->sc_ucom ;
-	int rv = 0;
-
-	DPRINTF(("uchcom_detach: sc=%p flags=%d\n", sc, flags));
-
-	uchcom_close_intr_pipe(sc);
-
-	ucom->sc_dying = 1;
-
-	rv = ucom_detach(ucom);
-
-	return rv;
-}
 static int
-uchcom_set_config(device_t dev)
+uchcom_detach(device_t dev)
 {
 	struct uchcom_softc *sc = device_get_softc(dev);
-	struct ucom_softc *ucom = &sc->sc_ucom;
-	usbd_status err;
-	
-	err = usbd_set_config_index(ucom->sc_udev, UCHCOM_CONFIG_INDEX, 1);
-	if (err) {
-		device_printf(dev, "failed to set configuration: %s\n",
-			      usbd_errstr(err));
-		return -1;
-	}
 
-	return 0;
-}
+	DPRINTF(10, "\n");
 
-static int
-uchcom_find_ifaces(struct uchcom_softc *sc, usbd_interface_handle *riface)
-{
-	usbd_status err;
-	struct ucom_softc *ucom = &sc->sc_ucom;
+	ucom_detach(&(sc->sc_super_ucom), &(sc->sc_ucom), 1);
 
-	err = usbd_device2interface_handle(ucom->sc_udev, UCHCOM_IFACE_INDEX,
-					   riface);
-	if (err) {
-		device_printf(ucom->sc_dev, "failed to get interface: %s\n",
-			      usbd_errstr(err));
-		return -1;
-	}
+	usbd_transfer_unsetup(sc->sc_xfer, UCHCOM_N_TRANSFER);
 
-	return 0;
-}
-
-static int
-uchcom_find_endpoints(struct uchcom_softc *sc, struct uchcom_endpoints *endpoints)
-{
-	struct ucom_softc *ucom= &sc->sc_ucom;
-	int i, bin=-1, bout=-1, intr=-1, isize=0;
-	usb_interface_descriptor_t *id;
-	usb_endpoint_descriptor_t *ed;
-
-	id = usbd_get_interface_descriptor(ucom->sc_iface);
-
-	for (i = 0; i < id->bNumEndpoints; i++) {
-		ed = usbd_interface2endpoint_descriptor(ucom->sc_iface, i);
-		if (ed == NULL) {
-			device_printf(ucom->sc_dev, "no endpoint descriptor for %d\n", i);
-			return -1;
-		}
-
-		if (UE_GET_DIR(ed->bEndpointAddress) == UE_DIR_IN &&
-		    UE_GET_XFERTYPE(ed->bmAttributes) == UE_INTERRUPT) {
-			intr = ed->bEndpointAddress;
-			isize = UGETW(ed->wMaxPacketSize);
-		} else if (UE_GET_DIR(ed->bEndpointAddress) == UE_DIR_IN &&
-			   UE_GET_XFERTYPE(ed->bmAttributes) == UE_BULK) {
-			bin = ed->bEndpointAddress;
-		} else if (UE_GET_DIR(ed->bEndpointAddress) == UE_DIR_OUT &&
-			   UE_GET_XFERTYPE(ed->bmAttributes) == UE_BULK) {
-			bout = ed->bEndpointAddress;
-		}
-	}
-
-	if (intr == -1 || bin == -1 || bout == -1) {
-		if (intr == -1) {
-			device_printf(ucom->sc_dev, "no interrupt end point\n");
-		}
-		if (bin == -1) {
-			device_printf(ucom->sc_dev, "no data bulk in end point\n");
-
-		}
-		if (bout == -1) {
-			device_printf(ucom->sc_dev, "no data bulk out end point\n");
-		}
-		return -1;
-	}
-	if (isize < UCHCOM_INTR_LEAST) {
-		device_printf(ucom->sc_dev, "intr pipe is too short");
-		return -1;
-	}
-
-	DPRINTF(("%s: bulkin=%d, bulkout=%d, intr=%d, isize=%d\n",
-		 USBDEVNAME(sc->sc_dev), bin, bout, intr, isize));
-
-	endpoints->ep_intr = intr;
-	endpoints->ep_intr_size = isize;
-	endpoints->ep_bulkin = bin;
-	endpoints->ep_bulkout = bout;
-
-	return 0;
+	return (0);
 }
 
-
 /* ----------------------------------------------------------------------
  * low level i/o
  */



Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?200712301351.lBUDpExO072471>