speedtch cxacru.c, 1.35, 1.36 speedtch.c, 1.65, 1.66 usbatm.c, 1.48, 1.49 usbatm.h, 1.20, 1.21 xusbatm.c, 1.13, 1.14

Duncan Sands duncan at infradead.org
Mon Sep 26 16:19:44 EDT 2005


Update of /home/cvs/speedtch
In directory phoenix.infradead.org:/tmp/cvs-serv9202

Modified Files:
	cxacru.c speedtch.c usbatm.c usbatm.h xusbatm.c 
Log Message:
Work in progress: support for isochronous urbs (plus some other small changes
while I was there).  Isochronous stuff works for small packets (eg: when doing
a ping), but not with larger ones - bullshit vpi/vci values.  Maybe things are
being read in reverse order?


Index: cxacru.c
===================================================================
RCS file: /home/cvs/speedtch/cxacru.c,v
retrieving revision 1.35
retrieving revision 1.36
diff -u -r1.35 -r1.36
--- cxacru.c	12 Sep 2005 13:00:50 -0000	1.35
+++ cxacru.c	26 Sep 2005 20:19:40 -0000	1.36
@@ -667,21 +667,19 @@
 
 static int cxacru_bind(struct usbatm_data *usbatm_instance,
 		       struct usb_interface *intf, const struct usb_device_id *id,
-		       int *need_heavy_init)
+		       int *need_heavy_init, int *use_isoc)
 {
 	struct cxacru_data *instance;
 	struct usb_device *usb_dev = interface_to_usbdev(intf);
 	int ret;
 
 	/* instance init */
-	instance = kmalloc(sizeof(*instance), GFP_KERNEL);
+	instance = kzalloc(sizeof(*instance), GFP_KERNEL);
 	if (!instance) {
 		dbg("cxacru_bind: no memory for instance data");
 		return -ENOMEM;
 	}
 
-	memset(instance, 0, sizeof(*instance));
-
 	instance->usbatm = usbatm_instance;
 	instance->modem_type = (struct cxacru_modem_type *) id->driver_info;
 
@@ -837,8 +835,8 @@
 	.heavy_init	= cxacru_heavy_init,
 	.unbind		= cxacru_unbind,
 	.atm_start	= cxacru_atm_start,
-	.in		= CXACRU_EP_DATA,
-	.out		= CXACRU_EP_DATA,
+	.bulk_in	= CXACRU_EP_DATA,
+	.bulk_out	= CXACRU_EP_DATA,
 	.rx_padding	= 3,
 	.tx_padding	= 11,
 };

Index: speedtch.c
===================================================================
RCS file: /home/cvs/speedtch/speedtch.c,v
retrieving revision 1.65
retrieving revision 1.66
diff -u -r1.65 -r1.66
--- speedtch.c	9 Sep 2005 13:41:31 -0000	1.65
+++ speedtch.c	26 Sep 2005 20:19:41 -0000	1.66
@@ -35,6 +35,8 @@
 #include <linux/slab.h>
 #include <linux/stat.h>
 #include <linux/timer.h>
+#include <linux/types.h>
+#include <linux/usb_ch9.h>
 #include <linux/workqueue.h>
 
 #include "usbatm.h"
@@ -66,31 +68,41 @@
 
 #define RESUBMIT_DELAY		1000	/* milliseconds */
 
-#define DEFAULT_ALTSETTING	1
+#define DEFAULT_BULK_ALTSETTING	1
+#define DEFAULT_ISOC_ALTSETTING	2
 #define DEFAULT_DL_512_FIRST	0
+#define DEFAULT_ENABLE_ISOC	0
 #define DEFAULT_SW_BUFFERING	0
 
-static int altsetting = DEFAULT_ALTSETTING;
+static int altsetting = 0; // zero means to use the default
 static int dl_512_first = DEFAULT_DL_512_FIRST;
+static int enable_isoc = DEFAULT_ENABLE_ISOC;
 static int sw_buffering = DEFAULT_SW_BUFFERING;
 
 module_param(altsetting, int, S_IRUGO | S_IWUSR);
 MODULE_PARM_DESC(altsetting,
-		 "Alternative setting for data interface (default: "
-		 __MODULE_STRING(DEFAULT_ALTSETTING) ")");
+		 "Alternative setting for data interface (bulk_default: "
+		 __MODULE_STRING(DEFAULT_BULK_ALTSETTING) "; isoc_default: "
+		 __MODULE_STRING(DEFAULT_ISOC_ALTSETTING) ")");
 
 module_param(dl_512_first, bool, S_IRUGO | S_IWUSR);
 MODULE_PARM_DESC(dl_512_first,
 		 "Read 512 bytes before sending firmware (default: "
 		 __MODULE_STRING(DEFAULT_DL_512_FIRST) ")");
 
+module_param(enable_isoc, bool, S_IRUGO | S_IWUSR);
+MODULE_PARM_DESC(enable_isoc,
+		 "Use isochronous transfers if available (default: "
+		 __MODULE_STRING(DEFAULT_ENABLE_ISOC) ")");
+
 module_param(sw_buffering, bool, S_IRUGO | S_IWUSR);
 MODULE_PARM_DESC(sw_buffering,
 		 "Enable software buffering (default: "
 		 __MODULE_STRING(DEFAULT_SW_BUFFERING) ")");
 
 #define ENDPOINT_INT		0x81
-#define ENDPOINT_DATA		0x07
+#define ENDPOINT_BULK_DATA	0x07
+#define ENDPOINT_ISOC_DATA	0x07
 #define ENDPOINT_FIRMWARE	0x05
 
 #define hex2int(c) ( (c >= '0') && (c <= '9') ? (c - '0') : ((c & 0xf) + 9) )
@@ -98,6 +110,8 @@
 struct speedtch_instance_data {
 	struct usbatm_data *usbatm;
 
+	int altsetting;
+
 	struct work_struct status_checker;
 
 	unsigned char last_status;
@@ -270,6 +284,11 @@
 	   because we're in our own kernel thread anyway. */
 	msleep_interruptible(1000);
 
+	if ((ret = usb_set_interface(usb_dev, 1, instance->altsetting)) < 0) {
+		usb_err(usbatm, "%s: setting interface to %d failed (%d)!\n", __func__, instance->altsetting, ret);
+		goto out_free;
+	}
+
 	/* Enable software buffering, if requested */
 	if (sw_buffering)
 		speedtch_set_swbuff(instance, 1);
@@ -306,7 +325,7 @@
 			usb_dbg(usbatm, "%s: looking for %s\n", __func__, buf);
 
 			if (request_firmware(fw_p, buf, dev)) {
-				usb_err(usbatm, "no stage %d firmware found!\n", phase);
+				usb_err(usbatm, "%s: no stage %d firmware found!\n", __func__, phase);
 				return -ENOENT;
 			}
 		}
@@ -584,11 +603,6 @@
 
 	atm_dbg(usbatm, "%s entered\n", __func__);
 
-	if ((ret = usb_set_interface(usb_dev, 1, altsetting)) < 0) {
-		atm_dbg(usbatm, "%s: usb_set_interface returned %d!\n", __func__, ret);
-		return ret;
-	}
-
 	/* Set MAC address, it is stored in the serial number */
 	memset(atm_dev->esi, 0, sizeof(atm_dev->esi));
 	if (usb_string(usb_dev, usb_dev->descriptor.iSerialNumber, mac_str, sizeof(mac_str)) == 12) {
@@ -681,7 +695,7 @@
 static int speedtch_bind(struct usbatm_data *usbatm,
 			 struct usb_interface *intf,
 			 const struct usb_device_id *id,
-			 int *need_heavy_init)
+			 int *need_heavy_init, int *use_isoc)
 {
 	struct usb_device *usb_dev = interface_to_usbdev(intf);
 	struct usb_interface *cur_intf;
@@ -706,25 +720,67 @@
 			ret = usb_driver_claim_interface(&speedtch_usb_driver, cur_intf, usbatm);
 
 			if (ret < 0) {
-				usb_dbg(usbatm, "%s: failed to claim interface %d (%d)\n", __func__, i, ret);
+				usb_err(usbatm, "%s: failed to claim interface %d (%d)!\n", __func__, i, ret);
 				speedtch_release_interfaces(usb_dev, i);
 				return ret;
 			}
 		}
 	}
 
-	instance = kmalloc(sizeof(*instance), GFP_KERNEL);
+	instance = kzalloc(sizeof(*instance), GFP_KERNEL);
 
 	if (!instance) {
-		usb_dbg(usbatm, "%s: no memory for instance data!\n", __func__);
+		usb_err(usbatm, "%s: no memory for instance data!\n", __func__);
 		ret = -ENOMEM;
 		goto fail_release;
 	}
 
-	memset(instance, 0, sizeof(struct speedtch_instance_data));
-
 	instance->usbatm = usbatm;
 
+	/* altsetting and enable_isoc may change at any moment, so take a snapshot */
+	instance->altsetting = altsetting;
+	*use_isoc = enable_isoc;
+
+	if (instance->altsetting)
+		if ((ret = usb_set_interface(usb_dev, 1, instance->altsetting)) < 0) {
+			usb_err(usbatm, "%s: setting interface to %d failed (%d)!\n", __func__, instance->altsetting, ret);
+			instance->altsetting = 0; /* fall back to default */
+		}
+
+	if (!instance->altsetting && *use_isoc)
+		if ((ret = usb_set_interface(usb_dev, 1, DEFAULT_ISOC_ALTSETTING)) < 0) {
+			usb_dbg(usbatm, "%s: usb_set_interface %d failed (%d)!\n", __func__, DEFAULT_ISOC_ALTSETTING, ret);
+			*use_isoc = 0; /* fall back to bulk */
+		}
+
+	if (*use_isoc) {
+		const struct usb_host_interface *desc = intf->cur_altsetting;
+		const __u8 target_address = USB_DIR_IN | usbatm->driver->isoc_in;
+		int i;
+
+		for (i=0; i<desc->desc.bNumEndpoints; i++) {
+			const struct usb_endpoint_descriptor *endpoint_desc = &desc->endpoint[i].desc;
+
+			if ((endpoint_desc->bEndpointAddress == target_address)) {
+				*use_isoc = (endpoint_desc->bmAttributes & USB_ENDPOINT_XFERTYPE_MASK) ==
+					USB_ENDPOINT_XFER_ISOC;
+				break;
+			}
+		}
+
+		if (!*use_isoc)
+			usb_info(usbatm, "%s: isochronous transfer not supported - using bulk instead!\n", __func__);
+	}
+
+	if (!*use_isoc && !instance->altsetting)
+		if ((ret = usb_set_interface(usb_dev, 1, DEFAULT_BULK_ALTSETTING)) < 0) {
+			usb_err(usbatm, "%s: setting interface to %d failed (%d)!\n", __func__, DEFAULT_BULK_ALTSETTING, ret);
+			goto fail_free;
+		}
+
+	if (!instance->altsetting)
+		instance->altsetting = *use_isoc ? DEFAULT_ISOC_ALTSETTING : DEFAULT_BULK_ALTSETTING;
+
 	INIT_WORK(&instance->status_checker, (void *)speedtch_check_status, instance);
 
 	instance->status_checker.timer.function = speedtch_status_poll;
@@ -756,8 +812,10 @@
 	usb_dbg(usbatm, "%s: firmware %s loaded\n", __func__, need_heavy_init ? "not" : "already");
 
 	if (*need_heavy_init)
-		if ((ret = usb_reset_device(usb_dev)) < 0)
+		if ((ret = usb_reset_device(usb_dev)) < 0) {
+			usb_err(usbatm, "%s: device reset failed (%d)!\n", __func__, ret);
 			goto fail_free;
+		}
 
         usbatm->driver_data = instance;
 
@@ -796,8 +854,9 @@
 	.unbind		= speedtch_unbind,
 	.atm_start	= speedtch_atm_start,
 	.atm_stop	= speedtch_atm_stop,
-	.in		= ENDPOINT_DATA,
-	.out		= ENDPOINT_DATA
+	.bulk_in	= ENDPOINT_BULK_DATA,
+	.bulk_out	= ENDPOINT_BULK_DATA,
+	.isoc_in	= ENDPOINT_ISOC_DATA
 };
 
 static int speedtch_usb_probe(struct usb_interface *intf, const struct usb_device_id *id)

Index: usbatm.c
===================================================================
RCS file: /home/cvs/speedtch/usbatm.c,v
retrieving revision 1.48
retrieving revision 1.49
diff -u -r1.48 -r1.49
--- usbatm.c	9 Sep 2005 13:56:22 -0000	1.48
+++ usbatm.c	26 Sep 2005 20:19:41 -0000	1.49
@@ -749,13 +749,12 @@
 		goto fail;
 	}
 
-	if (!(new = kmalloc(sizeof(struct usbatm_vcc_data), GFP_KERNEL))) {
+	if (!(new = kzalloc(sizeof(struct usbatm_vcc_data), GFP_KERNEL))) {
 		atm_dbg(instance, "%s: no memory for vcc_data!\n", __func__);
 		ret = -ENOMEM;
 		goto fail;
 	}
 
-	memset(new, 0, sizeof(struct usbatm_vcc_data));
 	new->vcc = vcc;
 	new->vpi = vpi;
 	new->vci = vci;
@@ -951,7 +950,7 @@
 	char *buf;
 	int error = -ENOMEM;
 	int i, length;
-	int need_heavy;
+	int need_heavy, use_isoc;
 
 	dev_dbg(dev, "%s: trying driver %s with vendor=0x%x, product=0x%x, ifnum %d\n",
 			__func__, driver->driver_name,
@@ -960,7 +959,7 @@
 			intf->altsetting->desc.bInterfaceNumber);
 
 	/* instance init */
-	instance = kcalloc(1, sizeof(*instance) + sizeof(struct urb *) * (num_rcv_urbs + num_snd_urbs), GFP_KERNEL);
+	instance = kzalloc(sizeof(*instance) + sizeof(struct urb *) * (num_rcv_urbs + num_snd_urbs), GFP_KERNEL);
 	if (!instance) {
 		dev_err(dev, "%s: no memory for instance data!\n", __func__);
 		return -ENOMEM;
@@ -997,8 +996,9 @@
 
  bind:
 	need_heavy = 1;
-	if (driver->bind && (error = driver->bind(instance, intf, id, &need_heavy)) < 0) {
-			dev_dbg(dev, "%s: bind failed: %d!\n", __func__, error);
+	use_isoc = 0;
+	if (driver->bind && (error = driver->bind(instance, intf, id, &need_heavy, &use_isoc)) < 0) {
+			dev_err(dev, "%s: bind failed: %d!\n", __func__, error);
 			goto fail_free;
 	}
 
@@ -1017,14 +1017,19 @@
 	usbatm_init_channel(&instance->tx_channel);
 	tasklet_init(&instance->rx_channel.tasklet, usbatm_rx_process, (unsigned long)instance);
 	tasklet_init(&instance->tx_channel.tasklet, usbatm_tx_process, (unsigned long)instance);
-	instance->rx_channel.endpoint = usb_rcvbulkpipe(usb_dev, driver->in);
-	instance->tx_channel.endpoint = usb_sndbulkpipe(usb_dev, driver->out);
 	instance->rx_channel.stride = ATM_CELL_SIZE + driver->rx_padding;
 	instance->tx_channel.stride = ATM_CELL_SIZE + driver->tx_padding;
 	instance->rx_channel.buf_size = rcv_buf_size * instance->rx_channel.stride;
 	instance->tx_channel.buf_size = snd_buf_size * instance->tx_channel.stride;
 	instance->rx_channel.usbatm = instance->tx_channel.usbatm = instance;
 
+	if (use_isoc && driver->isoc_in)
+		instance->rx_channel.endpoint = usb_rcvisocpipe(usb_dev, driver->isoc_in);
+	else
+		instance->rx_channel.endpoint = usb_rcvbulkpipe(usb_dev, driver->bulk_in);
+
+	instance->tx_channel.endpoint = usb_sndbulkpipe(usb_dev, driver->bulk_out);
+
 	skb_queue_head_init(&instance->sndqueue);
 
 	for (i = 0; i < num_rcv_urbs + num_snd_urbs; i++) {
@@ -1038,8 +1043,10 @@
 			/* don't expect iso out endpoints */
 			iso_size = usb_maxpacket(instance->usb_dev, channel->endpoint, 0);
 			iso_size -= iso_size % channel->stride;	/* alignment */
-			BUG_ON(!iso_size);
-			iso_packets = (channel->buf_size - 1) / iso_size + 1;
+			BUG_ON(!iso_size);//QQ no - return failure code
+			iso_packets = channel->buf_size / iso_size;
+			if (iso_packets)
+				channel->buf_size = iso_packets * iso_size;//QQ maybe not needed if use usb_fill_iso_urb below
 		}
 
 		urb = usb_alloc_urb(iso_packets, GFP_KERNEL);
@@ -1050,15 +1057,14 @@
 
 		instance->urbs[i] = urb;
 
-		buffer = kmalloc(channel->buf_size, GFP_KERNEL);
+		buffer = kzalloc(channel->buf_size, GFP_KERNEL);
 		if (!buffer) {
 			dev_err(dev, "%s: no memory for buffer %d!\n", __func__, i);
 			goto fail_unbind;
 		}
-		memset(buffer, 0, channel->buf_size);
 
 		usb_fill_bulk_urb(urb, instance->usb_dev, channel->endpoint,
-				  buffer, channel->buf_size, usbatm_complete, channel);
+				  buffer, channel->buf_size, usbatm_complete, channel);//QQ is this OK for iso urbs; also - looks like should use iso_size * iso_packets rather than channel->buf_size
 		if (iso_packets) {
 			int j;
 			urb->interval = 1;

Index: usbatm.h
===================================================================
RCS file: /home/cvs/speedtch/usbatm.h,v
retrieving revision 1.20
retrieving revision 1.21
diff -u -r1.20 -r1.21
--- usbatm.h	9 Sep 2005 13:41:31 -0000	1.20
+++ usbatm.h	26 Sep 2005 20:19:41 -0000	1.21
@@ -104,7 +104,7 @@
 	*  method can avoid having it called by setting need_heavy_init to zero.
 	*/
         int (*bind) (struct usbatm_data *, struct usb_interface *,
-		     const struct usb_device_id *id, int *need_heavy_init);
+		     const struct usb_device_id *id, int *need_heavy_init, int *use_isoc);
 
 	/* additional device initialization that is too slow to be done in probe() */
         int (*heavy_init) (struct usbatm_data *, struct usb_interface *);
@@ -118,8 +118,9 @@
 	/* cleanup ATM device ... can sleep, but can't fail */
 	void (*atm_stop) (struct usbatm_data *, struct atm_dev *);
 
-        int in;		/* rx endpoint */
-        int out;	/* tx endpoint */
+        int bulk_in;	/* bulk rx endpoint */
+        int isoc_in;	/* isochronous rx endpoint */
+        int bulk_out;	/* bulk tx endpoint */
 
 	unsigned rx_padding;
 	unsigned tx_padding;

Index: xusbatm.c
===================================================================
RCS file: /home/cvs/speedtch/xusbatm.c,v
retrieving revision 1.13
retrieving revision 1.14
diff -u -r1.13 -r1.14
--- xusbatm.c	9 Sep 2005 12:49:12 -0000	1.13
+++ xusbatm.c	26 Sep 2005 20:19:41 -0000	1.14
@@ -63,7 +63,7 @@
 
 static int xusbatm_bind(struct usbatm_data *usbatm_instance,
 			struct usb_interface *intf, const struct usb_device_id *id,
-			int *need_heavy_init)
+			int *need_heavy_init, int *use_isoc)
 {
 	struct usb_device *usb_dev = interface_to_usbdev(intf);
 	int drv_ix = id - xusbatm_usb_ids;
@@ -172,8 +172,8 @@
 		xusbatm_drivers[i].bind		= xusbatm_bind;
 		xusbatm_drivers[i].unbind	= xusbatm_unbind;
 		xusbatm_drivers[i].atm_start	= xusbatm_atm_start;
-		xusbatm_drivers[i].in		= rx_endpoint[i];
-		xusbatm_drivers[i].out		= tx_endpoint[i];
+		xusbatm_drivers[i].bulk_in	= rx_endpoint[i];
+		xusbatm_drivers[i].bulk_out	= tx_endpoint[i];
 		xusbatm_drivers[i].rx_padding	= rx_padding[i];
 		xusbatm_drivers[i].tx_padding	= tx_padding[i];
 	}




More information about the Usbatm-commits mailing list