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