usbatm usb_atm.c,1.12,1.13 usb_atm.h,1.4,1.5 cxacru.c,1.5,1.6
kagan at infradead.org
kagan at infradead.org
Tue Jan 25 04:36:09 EST 2005
Update of /home/cvs/usbatm
In directory phoenix.infradead.org:/tmp/cvs-serv29610
Modified Files:
usb_atm.c usb_atm.h cxacru.c
Log Message:
Redone using subdriver infrastructure registered at probe time.
Index: usb_atm.c
===================================================================
RCS file: /home/cvs/usbatm/usb_atm.c,v
retrieving revision 1.12
retrieving revision 1.13
diff -u -r1.12 -r1.13
--- usb_atm.c 29 Dec 2004 21:18:32 -0000 1.12
+++ usb_atm.c 25 Jan 2005 09:36:05 -0000 1.13
@@ -139,6 +139,9 @@
__MODULE_STRING(UDSL_MAX_SND_BUF_SIZE) ", default: "
__MODULE_STRING(UDSL_DEFAULT_SND_BUF_SIZE) ")");
+#define ATM_CELL_HEADER (ATM_CELL_SIZE - ATM_CELL_PAYLOAD)
+#define UDSL_NUM_CELLS(x) (((x) + ATM_AAL5_TRAILER + ATM_CELL_PAYLOAD - 1) / ATM_CELL_PAYLOAD)
+
/* ATM */
static void udsl_atm_dev_close(struct atm_dev *dev);
@@ -148,16 +151,6 @@
static int udsl_atm_send(struct atm_vcc *vcc, struct sk_buff *skb);
static int udsl_atm_proc_read(struct atm_dev *atm_dev, loff_t * pos, char *page);
-static struct atmdev_ops udsl_atm_devops = {
- .dev_close = udsl_atm_dev_close,
- .open = udsl_atm_open,
- .close = udsl_atm_close,
- .ioctl = udsl_atm_ioctl,
- .send = udsl_atm_send,
- .proc_read = udsl_atm_proc_read,
- .owner = THIS_MODULE,
-};
-
/***********
** misc **
***********/
@@ -174,7 +167,7 @@
** decode **
*************/
-static inline struct udsl_vcc_data *udsl_find_vcc(struct udsl_instance_data *instance,
+static inline struct udsl_vcc_data *udsl_find_vcc(struct usbatm_data *instance,
short vpi, int vci)
{
struct udsl_vcc_data *vcc;
@@ -185,7 +178,7 @@
return NULL;
}
-static void udsl_extract_cells(struct udsl_instance_data *instance,
+static void udsl_extract_cells(struct usbatm_data *instance,
unsigned char *source, unsigned int howmany)
{
struct udsl_vcc_data *cached_vcc = NULL;
@@ -200,7 +193,7 @@
short vpi;
for (i = 0; i < howmany;
- i++, source += ATM_CELL_SIZE + instance->rcv_padding) {
+ i++, source += ATM_CELL_SIZE + instance->rx_padding) {
vpi = ((source[0] & 0x0f) << 4) | (source[1] >> 4);
vci = ((source[1] & 0x0f) << 12) | (source[2] << 4) | (source[3] >> 4);
pti = (source[3] & 0x2) != 0;
@@ -339,7 +332,7 @@
ctrl->aal5_trailer[7] = crc;
}
-static unsigned int udsl_write_cells(struct udsl_instance_data *instance,
+static unsigned int udsl_write_cells(struct usbatm_data *instance,
unsigned int howmany, struct sk_buff *skb,
unsigned char **target_p)
{
@@ -357,9 +350,9 @@
target += ATM_CELL_HEADER;
memcpy(target, skb->data, ATM_CELL_PAYLOAD);
target += ATM_CELL_PAYLOAD;
- if (instance->snd_padding) {
- memset(target, 0, instance->snd_padding);
- target += instance->snd_padding;
+ if (instance->tx_padding) {
+ memset(target, 0, instance->tx_padding);
+ target += instance->tx_padding;
}
__skb_pull(skb, ATM_CELL_PAYLOAD);
}
@@ -383,9 +376,9 @@
goto out;
}
- if (instance->snd_padding) {
- memset(target, 0, instance->snd_padding);
- target += instance->snd_padding;
+ if (instance->tx_padding) {
+ memset(target, 0, instance->tx_padding);
+ target += instance->tx_padding;
}
udsl_fill_cell_header(target, ctrl->atm_data.vcc);
target += ATM_CELL_HEADER;
@@ -400,9 +393,9 @@
target += ATM_AAL5_TRAILER;
/* set pti bit in last cell */
*(target + 3 - ATM_CELL_SIZE) |= 0x2;
- if (instance->snd_padding) {
- memset(target, 0, instance->snd_padding);
- target += instance->snd_padding;
+ if (instance->tx_padding) {
+ memset(target, 0, instance->tx_padding);
+ target += instance->tx_padding;
}
out:
*target_p = target;
@@ -416,7 +409,7 @@
static void udsl_complete_receive(struct urb *urb, struct pt_regs *regs)
{
struct udsl_receive_buffer *buf;
- struct udsl_instance_data *instance;
+ struct usbatm_data *instance;
struct udsl_receiver *rcv;
unsigned long flags;
@@ -428,7 +421,7 @@
instance = rcv->instance;
buf = rcv->buffer;
- buf->filled_cells = urb->actual_length / (ATM_CELL_SIZE + instance->rcv_padding);
+ buf->filled_cells = urb->actual_length / (ATM_CELL_SIZE + instance->rx_padding);
vdbg("udsl_complete_receive: urb 0x%p, status %d, actual_length %d, filled_cells %u, rcv 0x%p, buf 0x%p", urb, urb->status, urb->actual_length, buf->filled_cells, rcv, buf);
@@ -446,7 +439,7 @@
static void udsl_process_receive(unsigned long data)
{
struct udsl_receive_buffer *buf;
- struct udsl_instance_data *instance = (struct udsl_instance_data *)data;
+ struct usbatm_data *instance = (struct usbatm_data *)data;
struct udsl_receiver *rcv;
int err;
@@ -468,10 +461,9 @@
rcv->buffer = buf;
- usb_fill_bulk_urb(rcv->urb, instance->usb_dev,
- usb_rcvbulkpipe(instance->usb_dev, instance->data_endpoint),
+ usb_fill_bulk_urb(rcv->urb, instance->usb_dev, instance->rx_pipe,
buf->base,
- rcv_buf_size * (ATM_CELL_SIZE + instance->rcv_padding),
+ rcv_buf_size * (ATM_CELL_SIZE + instance->rx_padding),
udsl_complete_receive, rcv);
vdbg("udsl_process_receive: sending urb 0x%p, rcv 0x%p, buf 0x%p",
@@ -509,7 +501,7 @@
static void udsl_complete_send(struct urb *urb, struct pt_regs *regs)
{
- struct udsl_instance_data *instance;
+ struct usbatm_data *instance;
struct udsl_sender *snd;
unsigned long flags;
@@ -532,7 +524,7 @@
static void udsl_process_send(unsigned long data)
{
struct udsl_send_buffer *buf;
- struct udsl_instance_data *instance = (struct udsl_instance_data *)data;
+ struct usbatm_data *instance = (struct usbatm_data *)data;
struct sk_buff *skb;
struct udsl_sender *snd;
int err;
@@ -556,10 +548,9 @@
spin_unlock_irq(&instance->send_lock);
snd->buffer = buf;
- usb_fill_bulk_urb(snd->urb, instance->usb_dev,
- usb_sndbulkpipe(instance->usb_dev, instance->data_endpoint),
+ usb_fill_bulk_urb(snd->urb, instance->usb_dev, instance->tx_pipe,
buf->base,
- (snd_buf_size - buf->free_cells) * (ATM_CELL_SIZE + instance->snd_padding),
+ (snd_buf_size - buf->free_cells) * (ATM_CELL_SIZE + instance->tx_padding),
udsl_complete_send, snd);
vdbg("udsl_process_send: submitting urb 0x%p (%d cells), snd 0x%p, buf 0x%p",
@@ -628,7 +619,7 @@
goto made_progress;
}
-static void udsl_cancel_send(struct udsl_instance_data *instance,
+static void udsl_cancel_send(struct usbatm_data *instance,
struct atm_vcc *vcc)
{
struct sk_buff *skb, *n;
@@ -657,7 +648,7 @@
static int udsl_atm_send(struct atm_vcc *vcc, struct sk_buff *skb)
{
- struct udsl_instance_data *instance = vcc->dev->dev_data;
+ struct usbatm_data *instance = vcc->dev->dev_data;
int err;
vdbg("udsl_atm_send called (skb 0x%p, len %u)", skb, skb->len);
@@ -700,21 +691,24 @@
static void udsl_destroy_instance(struct kref *kref)
{
- struct udsl_instance_data *instance =
- container_of(kref, struct udsl_instance_data, refcount);
+ struct usbatm_data *instance =
+ container_of(kref, struct usbatm_data, refcount);
+ struct usb_device *usb_dev = instance->usb_dev;
tasklet_kill(&instance->receive_tasklet);
tasklet_kill(&instance->send_tasklet);
- usb_put_dev(instance->usb_dev);
- kfree(instance);
+
+ mb();
+ instance->driver->cleanup(instance);
+ usb_put_dev(usb_dev);
}
-void udsl_get_instance(struct udsl_instance_data *instance)
+static void udsl_get_instance(struct usbatm_data *instance)
{
kref_get(&instance->refcount);
}
-void udsl_put_instance(struct udsl_instance_data *instance)
+static void udsl_put_instance(struct usbatm_data *instance)
{
kref_put(&instance->refcount, udsl_destroy_instance);
}
@@ -725,7 +719,7 @@
static void udsl_atm_dev_close(struct atm_dev *dev)
{
- struct udsl_instance_data *instance = dev->dev_data;
+ struct usbatm_data *instance = dev->dev_data;
dev->dev_data = NULL;
udsl_put_instance(instance);
@@ -733,7 +727,7 @@
static int udsl_atm_proc_read(struct atm_dev *atm_dev, loff_t * pos, char *page)
{
- struct udsl_instance_data *instance = atm_dev->dev_data;
+ struct usbatm_data *instance = atm_dev->dev_data;
int left = *pos;
if (!instance) {
@@ -774,14 +768,8 @@
if (instance->usb_dev->state == USB_STATE_NOTATTACHED)
strcat(page, ", disconnected\n");
- else {
- if (instance->status == UDSL_LOADED_FIRMWARE)
- strcat(page, ", firmware loaded\n");
- else if (instance->status == UDSL_LOADING_FIRMWARE)
- strcat(page, ", firmware loading\n");
- else
- strcat(page, ", no firmware\n");
- }
+ else
+ strcat(page, "\n");
return strlen(page);
}
@@ -791,12 +779,11 @@
static int udsl_atm_open(struct atm_vcc *vcc)
{
- struct udsl_instance_data *instance = vcc->dev->dev_data;
+ struct usbatm_data *instance = vcc->dev->dev_data;
struct udsl_vcc_data *new;
unsigned int max_pdu;
int vci = vcc->vci;
short vpi = vcc->vpi;
- int err;
dbg("udsl_atm_open: vpi %hd, vci %d", vpi, vci);
@@ -812,12 +799,6 @@
return -EINVAL;
}
- if (instance->firmware_wait &&
- (err = instance->firmware_wait(instance)) < 0) {
- dbg("udsl_atm_open: firmware not loaded (%d)!", err);
- return err;
- }
-
down(&instance->serialize); /* vs self, udsl_atm_close */
if (udsl_find_vcc(instance, vpi, vci)) {
@@ -867,7 +848,7 @@
static void udsl_atm_close(struct atm_vcc *vcc)
{
- struct udsl_instance_data *instance = vcc->dev->dev_data;
+ struct usbatm_data *instance = vcc->dev->dev_data;
struct udsl_vcc_data *vcc_data = vcc->dev_data;
dbg("udsl_atm_close called");
@@ -920,23 +901,27 @@
** USB **
**********/
-int udsl_instance_setup(struct usb_device *dev,
- struct udsl_instance_data *instance)
+int usbatm_init(struct usbatm_data *instance,
+ struct usbatm_driver *driver, struct usb_device *usb_dev)
{
char *buf;
int i, length;
- kref_init(&instance->refcount); /* one for USB */
- udsl_get_instance(instance); /* one for ATM */
+ kref_init(&instance->refcount); /* released in usbatm_disconnect */
init_MUTEX(&instance->serialize);
- instance->usb_dev = dev;
+ instance->driver = driver;
+ instance->usb_dev = usb_dev;
- INIT_LIST_HEAD(&instance->vcc_list);
+ /* FIXME: handle iso pipes */
+ instance->rx_pipe = usb_rcvbulkpipe(usb_dev, driver->rx_endpoint);
+ instance->tx_pipe = usb_sndbulkpipe(usb_dev, driver->tx_endpoint);
- instance->status = UDSL_NO_FIRMWARE;
- init_waitqueue_head(&instance->firmware_waiters);
+ instance->rx_padding = driver->rx_padding;
+ instance->tx_padding = driver->tx_padding;
+
+ INIT_LIST_HEAD(&instance->vcc_list);
spin_lock_init(&instance->receive_lock);
INIT_LIST_HEAD(&instance->spare_receivers);
@@ -960,7 +945,7 @@
struct udsl_receiver *rcv = &(instance->receivers[i]);
if (!(rcv->urb = usb_alloc_urb(0, GFP_KERNEL))) {
- dbg("udsl_usb_probe: no memory for receive urb %d!", i);
+ dbg("usbatm_init: no memory for receive urb %d!", i);
goto fail;
}
@@ -973,10 +958,10 @@
struct udsl_receive_buffer *buf =
&(instance->receive_buffers[i]);
- buf->base = kmalloc(rcv_buf_size * (ATM_CELL_SIZE + instance->rcv_padding),
+ buf->base = kmalloc(rcv_buf_size * (ATM_CELL_SIZE + instance->rx_padding),
GFP_KERNEL);
if (!buf->base) {
- dbg("udsl_usb_probe: no memory for receive buffer %d!", i);
+ dbg("usbatm_init: no memory for receive buffer %d!", i);
goto fail;
}
@@ -988,7 +973,7 @@
struct udsl_sender *snd = &(instance->senders[i]);
if (!(snd->urb = usb_alloc_urb(0, GFP_KERNEL))) {
- dbg("udsl_usb_probe: no memory for send urb %d!", i);
+ dbg("usbatm_init: no memory for send urb %d!", i);
goto fail;
}
@@ -1000,37 +985,24 @@
for (i = 0; i < num_snd_bufs; i++) {
struct udsl_send_buffer *buf = &(instance->send_buffers[i]);
- buf->base = kmalloc(snd_buf_size * (ATM_CELL_SIZE + instance->snd_padding),
+ buf->base = kmalloc(snd_buf_size * (ATM_CELL_SIZE + instance->tx_padding),
GFP_KERNEL);
if (!buf->base) {
- dbg("udsl_usb_probe: no memory for send buffer %d!", i);
+ dbg("usbatm_init: no memory for send buffer %d!", i);
goto fail;
}
list_add(&buf->list, &instance->spare_send_buffers);
}
- /* ATM init */
- instance->atm_dev = atm_dev_register(instance->driver_name,
- &udsl_atm_devops, -1, NULL);
- if (!instance->atm_dev) {
- dbg("udsl_usb_probe: failed to register ATM device!");
- goto fail;
- }
-
- instance->atm_dev->ci_range.vpi_bits = ATM_CI_MAX;
- instance->atm_dev->ci_range.vci_bits = ATM_CI_MAX;
- instance->atm_dev->signal = ATM_PHY_SIG_UNKNOWN;
-
- /* temp init ATM device, set to 128kbit */
- instance->atm_dev->link_rate = 128 * 1000 / 424;
+ usb_get_dev(usb_dev); /* released in udsl_destroy_instance */
/* device description */
buf = instance->description;
length = sizeof(instance->description);
- if ((i = usb_string(dev, dev->descriptor.iProduct, buf, length)) < 0)
- goto finish;
+ if ((i = usb_string(usb_dev, usb_dev->descriptor.iProduct, buf, length)) < 0)
+ return 1;
buf += i;
length -= i;
@@ -1039,22 +1011,14 @@
buf += i;
length -= i;
- if (length <= 0 || (i = usb_make_path(dev, buf, length)) < 0)
- goto finish;
+ if (length <= 0 || (i = usb_make_path(usb_dev, buf, length)) < 0)
+ return 1;
buf += i;
length -= i;
snprintf(buf, length, ")");
-
- finish:
- /* ready for ATM callbacks */
- wmb();
- instance->atm_dev->dev_data = instance;
-
- usb_get_dev(dev);
-
- return 0;
+ return 1;
fail:
for (i = 0; i < num_snd_bufs; i++)
@@ -1072,14 +1036,66 @@
return -ENOMEM;
}
-void udsl_instance_disconnect(struct udsl_instance_data *instance)
+EXPORT_SYMBOL_GPL(usbatm_init);
+
+int usbatm_atm_setup(struct usbatm_data *instance, const unsigned char *esi)
{
int i;
- dbg("udsl_instance_disconnect entered");
+ /* fill it here so that ATM stack maintains correct owner */
+ instance->atm_devops.dev_close = udsl_atm_dev_close,
+ instance->atm_devops.open = udsl_atm_open,
+ instance->atm_devops.close = udsl_atm_close,
+ instance->atm_devops.ioctl = udsl_atm_ioctl,
+ instance->atm_devops.send = udsl_atm_send,
+ instance->atm_devops.proc_read = udsl_atm_proc_read,
+ instance->atm_devops.owner = instance->driver->owner;
+
+ down(&instance->serialize);
+
+ /* ATM init */
+ instance->atm_dev = atm_dev_register(instance->driver->name,
+ &instance->atm_devops, -1, NULL);
+ if (!instance->atm_dev) {
+ dbg("usbatm_atm_setup: failed to register ATM device!");
+ up(&instance->serialize);
+ return -1;
+ }
+
+ udsl_get_instance(instance); /* released in udsl_atm_dev_close */
+
+ instance->atm_dev->ci_range.vpi_bits = ATM_CI_MAX;
+ instance->atm_dev->ci_range.vci_bits = ATM_CI_MAX;
+ instance->atm_dev->signal = ATM_PHY_SIG_UNKNOWN;
+
+ memcpy(instance->atm_dev->esi, esi, sizeof(instance->atm_dev->esi));
+ dev_info(&instance->usb_dev->dev, "%s: MAC = %02x", instance->driver->name, esi[0]);
+ for (i = 1; i < sizeof(instance->atm_dev->esi); i++)
+ printk(":%02x", esi[i]);
+ printk("\n");
+
+ /* temp init ATM device, set to 128kbit */
+ instance->atm_dev->link_rate = 128 * 1000 / 424;
+
+ /* ready for ATM callbacks */
+ wmb();
+ instance->atm_dev->dev_data = instance;
+
+ up(&instance->serialize);
+
+ return 1;
+}
+
+EXPORT_SYMBOL_GPL(usbatm_atm_setup);
+
+void usbatm_disconnect(struct usbatm_data *instance)
+{
+ int i;
+
+ dbg("usbatm_disconnect entered");
if (!instance) {
- dbg("udsl_instance_disconnect: NULL instance!");
+ dbg("usbatm_disconnect: NULL instance!");
return;
}
@@ -1121,13 +1137,55 @@
kfree(instance->send_buffers[i].base);
/* ATM finalize */
- shutdown_atm_dev(instance->atm_dev);
+ down(&instance->serialize);
+ if (instance->atm_dev) {
+ up(&instance->serialize);
+ shutdown_atm_dev(instance->atm_dev);
+ }
+ up(&instance->serialize);
+
+ udsl_put_instance(instance);
+}
+
+EXPORT_SYMBOL_GPL(usbatm_disconnect);
+
+static int usbatm_heavy_init_thread(void *arg)
+{
+ struct usbatm_data *instance = arg;
+ struct module *owner = instance->driver->owner;
+
+ daemonize("%s/init", instance->driver->name);
+
+ instance->driver->heavy_init(instance);
+
+ mb();
+ udsl_put_instance(instance);
+ module_put(owner);
+ return 0;
+}
+
+int usbatm_heavy_init(struct usbatm_data *instance)
+{
+ struct module *owner = instance->driver->owner;
+ int ret;
+
+ try_module_get(owner);
+ udsl_get_instance(instance);
+
+ ret = kernel_thread(usbatm_heavy_init_thread, instance,
+ CLONE_FS | CLONE_FILES);
+ if (ret >= 0)
+ return 1; /* OK */
+
+ dbg("cxacru_firmware_start: kernel_thread failed (%d)!", ret);
+
+ mb();
+ udsl_put_instance(instance);
+ module_put(owner);
+ return ret;
}
-EXPORT_SYMBOL_GPL(udsl_get_instance);
-EXPORT_SYMBOL_GPL(udsl_put_instance);
-EXPORT_SYMBOL_GPL(udsl_instance_setup);
-EXPORT_SYMBOL_GPL(udsl_instance_disconnect);
+EXPORT_SYMBOL_GPL(usbatm_heavy_init);
/***********
** init **
Index: usb_atm.h
===================================================================
RCS file: /home/cvs/usbatm/usb_atm.h,v
retrieving revision 1.4
retrieving revision 1.5
diff -u -r1.4 -r1.5
--- usb_atm.h 29 Dec 2004 21:18:32 -0000 1.4
+++ usb_atm.h 25 Jan 2005 09:36:05 -0000 1.5
@@ -58,8 +58,22 @@
#define UDSL_DEFAULT_RCV_BUF_SIZE 64 /* ATM cells */
#define UDSL_DEFAULT_SND_BUF_SIZE 64 /* ATM cells */
-#define ATM_CELL_HEADER (ATM_CELL_SIZE - ATM_CELL_PAYLOAD)
-#define UDSL_NUM_CELLS(x) (((x) + ATM_AAL5_TRAILER + ATM_CELL_PAYLOAD - 1) / ATM_CELL_PAYLOAD)
+struct usbatm_data;
+
+struct usbatm_driver {
+ struct module *owner;
+ const char *name;
+
+ void (*heavy_init)(struct usbatm_data *);
+ void (*cleanup)(struct usbatm_data *);
+
+ int rx_endpoint;
+ int tx_endpoint;
+
+ unsigned rx_padding;
+ unsigned tx_padding;
+};
+
/* receive */
@@ -73,7 +87,7 @@
struct list_head list;
struct udsl_receive_buffer *buffer;
struct urb *urb;
- struct udsl_instance_data *instance;
+ struct usbatm_data *instance;
};
struct udsl_vcc_data {
@@ -100,7 +114,7 @@
struct list_head list;
struct udsl_send_buffer *buffer;
struct urb *urb;
- struct udsl_instance_data *instance;
+ struct usbatm_data *instance;
};
struct udsl_control {
@@ -115,33 +129,27 @@
/* main driver data */
-enum udsl_status {
- UDSL_NO_FIRMWARE,
- UDSL_LOADING_FIRMWARE,
- UDSL_LOADED_FIRMWARE
-};
+struct usbatm_data {
+ struct atmdev_ops atm_devops;
-struct udsl_instance_data {
struct kref refcount;
struct semaphore serialize;
+ /* driver part */
+ struct usbatm_driver *driver;
+
/* USB device part */
struct usb_device *usb_dev;
+ unsigned int rx_pipe;
+ unsigned int tx_pipe;
+ int rx_padding;
+ int tx_padding;
char description[64];
- int data_endpoint;
- int snd_padding;
- int rcv_padding;
- const char *driver_name;
/* ATM device part */
struct atm_dev *atm_dev;
struct list_head vcc_list;
- /* firmware */
- int (*firmware_wait) (struct udsl_instance_data *);
- enum udsl_status status;
- wait_queue_head_t firmware_waiters;
-
/* receive */
struct udsl_receiver receivers[UDSL_MAX_RCV_URBS];
struct udsl_receive_buffer receive_buffers[UDSL_MAX_RCV_BUFS];
@@ -169,8 +177,8 @@
struct list_head filled_send_buffers;
};
-extern int udsl_instance_setup(struct usb_device *dev,
- struct udsl_instance_data *instance);
-extern void udsl_instance_disconnect(struct udsl_instance_data *instance);
-extern void udsl_get_instance(struct udsl_instance_data *instance);
-extern void udsl_put_instance(struct udsl_instance_data *instance);
+extern int usbatm_init(struct usbatm_data *instance,
+ struct usbatm_driver *driver, struct usb_device *usb_dev);
+extern int usbatm_atm_setup(struct usbatm_data *instance, const unsigned char *esi);
+extern void usbatm_disconnect(struct usbatm_data *instance);
+extern int usbatm_heavy_init(struct usbatm_data *instance);
Index: cxacru.c
===================================================================
RCS file: /home/cvs/usbatm/cxacru.c,v
retrieving revision 1.5
retrieving revision 1.6
diff -u -r1.5 -r1.6
--- cxacru.c 20 Jan 2005 18:30:36 -0000 1.5
+++ cxacru.c 25 Jan 2005 09:36:06 -0000 1.6
@@ -51,9 +51,6 @@
static const char cxacru_driver_name[] = "cxacru";
-#define UDSL_IOCTL_LINE_UP 1
-#define UDSL_IOCTL_LINE_DOWN 2
-
#define CXACRU_EP_CMD 0x01 /* Bulk/interrupt in/out */
#define CXACRU_EP_DATA 0x02 /* Bulk in/out */
@@ -159,17 +156,27 @@
CXINF_MAX = 0x1c,
};
-struct cxacru_instance_data {
- struct udsl_instance_data u;
+static void cxacru_heavy_init(struct usbatm_data *);
+static void cxacru_cleanup(struct usbatm_data *);
- struct semaphore start_serialize;
-#ifdef USE_FW_LOADER
- int firmware_start_run;
-#endif
+static struct usbatm_driver cxacru_driver = {
+ .owner = THIS_MODULE,
+ .name = cxacru_driver_name,
+ .heavy_init = cxacru_heavy_init,
+ .cleanup = cxacru_cleanup,
+ .rx_endpoint = CXACRU_EP_DATA,
+ .tx_endpoint = CXACRU_EP_DATA,
+ .rx_padding = 3,
+ .tx_padding = 11,
+};
+
+struct cxacru_data {
+ struct usbatm_data usbatm;
int line_status;
struct work_struct poll_work;
struct timer_list poll_timer;
+
/* contol handles */
struct semaphore cm_serialize;
u8 *rcv_buf;
@@ -180,6 +187,8 @@
struct completion snd_done;
};
+#define to_cxacru_data(ua) container_of(ua, struct cxacru_data, usbatm)
+
/* the following three functions are stolen from drivers/usb/core/message.c */
static void cxacru_blocking_completion(struct urb *urb, struct pt_regs *regs)
{
@@ -213,7 +222,7 @@
return status;
}
-static int cxacru_cm(struct cxacru_instance_data *instance, enum cxacru_cm_request cm,
+static int cxacru_cm(struct cxacru_data *instance, enum cxacru_cm_request cm,
u8 *wdata, int wsize, u8 *rdata, int rsize)
{
int ret, actlen;
@@ -230,6 +239,8 @@
goto fail;
}
+ dbg("cxacru_cm: cm %#x instance %p usb_dev %p",
+ cm, instance, instance->usbatm.usb_dev);
down(&instance->cm_serialize);
/* submit reading urb before the writing one */
@@ -303,7 +314,7 @@
return ret;
}
-static int cxacru_cm_get_array(struct cxacru_instance_data *instance, enum cxacru_cm_request cm,
+static int cxacru_cm_get_array(struct cxacru_data *instance, enum cxacru_cm_request cm,
u32 *data, int size)
{
int ret, len;
@@ -347,7 +358,7 @@
return ret;
}
-static void cxacru_do_timer_poll(struct cxacru_instance_data *instance)
+static void cxacru_do_timer_poll(struct cxacru_data *instance)
{
schedule_work(&instance->poll_work);
mod_timer(&instance->poll_timer, jiffies + (5 * HZ));
@@ -355,77 +366,65 @@
static void cxacru_timer_poll(unsigned long data)
{
- cxacru_do_timer_poll((struct cxacru_instance_data *)data);
+ cxacru_do_timer_poll((struct cxacru_data *)data);
}
-#ifdef USE_FW_LOADER
-static void cxacru_firmware_start(struct cxacru_instance_data *instance);
-#endif
+static int cxacru_is_up(struct cxacru_data *instance)
+{
+ int ret = cxacru_cm(instance, CM_REQUEST_CARD_GET_STATUS, NULL, 0, NULL, 0);
+ if (ret < 0) { /* firmware not loaded */
+ dbg("cxacru_adsl_start: CARD_GET_STATUS returned %d", ret);
+ return 0;
+ }
+ return 1;
+}
-static void cxacru_adsl_start(struct cxacru_instance_data *instance)
+static void cxacru_adsl_start(struct cxacru_data *instance)
{
+ struct device *dev = &instance->usbatm.usb_dev->dev;
int ret;
- u8 esi[sizeof(instance->u.atm_dev->esi)] = {};
+ u8 esi[sizeof(instance->usbatm.atm_dev->esi)] = {};
dbg("cxacru_adsl_start");
- down(&instance->start_serialize);
-
- ret = cxacru_cm(instance, CM_REQUEST_CARD_GET_STATUS, NULL, 0, NULL, 0);
- if (ret < 0) { /* firmware not loaded */
- dbg("cxacru_adsl_start: CARD_GET_STATUS returned %d", ret);
-#ifdef USE_FW_LOADER
- if (!instance->firmware_start_run) {
- instance->firmware_start_run = 1;
- cxacru_firmware_start(instance);
- }
-#endif /* USE_FW_LOADER */
- goto out;
- }
/* Read MAC address */
ret = cxacru_cm(instance, CM_REQUEST_CARD_GET_MAC_ADDRESS, NULL, 0,
esi, sizeof(esi));
if (ret < 0) {
- err("cxacru_adsl_start: CARD_GET_MAC_ADDRESS returned %d", ret);
- goto out;
+ dev_err(dev, "cxacru_adsl_start: CARD_GET_MAC_ADDRESS returned %d\n", ret);
+ return;
}
- /* FIXME: remove dev from args; should have been set in probe */
- ret = udsl_instance_setup(instance->u.usb_dev, &instance->u);
- if (ret)
- goto out;
- memcpy(instance->u.atm_dev->esi, esi, sizeof(esi));
- /* FIXME: remove */
- instance->u.status = UDSL_LOADED_FIRMWARE;
-
- dev_info(&instance->u.usb_dev->dev, "cxacru: MAC = %02x", esi[0]);
- for (ret = 1; ret < sizeof(esi); ret++)
- printk(":%02x", esi[ret]);
- printk("\n");
+ ret = usbatm_atm_setup(&instance->usbatm, esi);
+ if (ret < 0) {
+ dev_err(dev, "cxacru_adsl_start: usbatm_atm_setup returned %d\n", ret);
+ return;
+ }
/* start ADSL */
ret = cxacru_cm(instance, CM_REQUEST_CHIP_ADSL_LINE_START, NULL, 0, NULL, 0);
if (ret < 0) {
- err("cxacru_adst_start: CHIP_ADSL_LINE_START returned %d", ret);
- goto out;
+ dev_err(dev, "cxacru_adst_start: CHIP_ADSL_LINE_START returned %d\n", ret);
+ return;
}
/* Start status polling */
cxacru_do_timer_poll(instance);
- tasklet_schedule(&instance->u.receive_tasklet);
-out:
- up(&instance->start_serialize);
+ /* FIXME: is it needed here? */
+ tasklet_schedule(&instance->usbatm.receive_tasklet);
}
-static void cxacru_poll_status(struct cxacru_instance_data *instance)
+static void cxacru_poll_status(struct cxacru_data *instance)
{
u32 buf[CXINF_MAX] = {};
+ struct device *dev = &instance->usbatm.usb_dev->dev;
+ struct atm_dev *atm_dev = instance->usbatm.atm_dev;
int ret;
ret = cxacru_cm_get_array(instance, CM_REQUEST_CARD_INFO_GET, buf, CXINF_MAX);
if (ret < 0) {
- dev_warn(&instance->u.usb_dev->dev, "poll status: error %d\n", ret);
+ dev_warn(dev, "poll status: error %d\n", ret);
return;
}
@@ -435,65 +434,63 @@
instance->line_status = buf[CXINF_LINE_STATUS];
switch (instance->line_status) {
case 0:
- instance->u.atm_dev->signal = ATM_PHY_SIG_LOST;
- dev_info(&instance->u.usb_dev->dev, "ADSL line: down\n");
+ atm_dev->signal = ATM_PHY_SIG_LOST;
+ dev_info(dev, "ADSL line: down\n");
break;
case 1:
- instance->u.atm_dev->signal = ATM_PHY_SIG_LOST;
- dev_info(&instance->u.usb_dev->dev, "ADSL line: attemtping to activate\n");
+ atm_dev->signal = ATM_PHY_SIG_LOST;
+ dev_info(dev, "ADSL line: attemtping to activate\n");
break;
case 2:
- instance->u.atm_dev->signal = ATM_PHY_SIG_LOST;
- dev_info(&instance->u.usb_dev->dev, "ADSL line: training\n");
+ atm_dev->signal = ATM_PHY_SIG_LOST;
+ dev_info(dev, "ADSL line: training\n");
break;
case 3:
- instance->u.atm_dev->signal = ATM_PHY_SIG_LOST;
- dev_info(&instance->u.usb_dev->dev, "ADSL line: channel analysis\n");
+ atm_dev->signal = ATM_PHY_SIG_LOST;
+ dev_info(dev, "ADSL line: channel analysis\n");
break;
case 4:
- instance->u.atm_dev->signal = ATM_PHY_SIG_LOST;
- dev_info(&instance->u.usb_dev->dev, "ADSL line: exchange\n");
+ atm_dev->signal = ATM_PHY_SIG_LOST;
+ dev_info(dev, "ADSL line: exchange\n");
break;
case 5:
- instance->u.atm_dev->link_rate = buf[CXINF_DOWNSTREAM_RATE] * 1000 / 424;
- instance->u.atm_dev->signal = ATM_PHY_SIG_FOUND;
+ atm_dev->link_rate = buf[CXINF_DOWNSTREAM_RATE] * 1000 / 424;
+ atm_dev->signal = ATM_PHY_SIG_FOUND;
- dev_info(&instance->u.usb_dev->dev, "ADSL line: up (%d Kib/s down | %d Kib/s up)\n",
+ dev_info(dev, "ADSL line: up (%d Kib/s down | %d Kib/s up)\n",
buf[CXINF_DOWNSTREAM_RATE], buf[CXINF_UPSTREAM_RATE]);
break;
case 6:
- instance->u.atm_dev->signal = ATM_PHY_SIG_LOST;
- dev_info(&instance->u.usb_dev->dev, "ADSL line: waiting\n");
+ atm_dev->signal = ATM_PHY_SIG_LOST;
+ dev_info(dev, "ADSL line: waiting\n");
break;
case 7:
- instance->u.atm_dev->signal = ATM_PHY_SIG_LOST;
- dev_info(&instance->u.usb_dev->dev, "ADSL line: initializing\n");
+ atm_dev->signal = ATM_PHY_SIG_LOST;
+ dev_info(dev, "ADSL line: initializing\n");
break;
default:
- instance->u.atm_dev->signal = ATM_PHY_SIG_UNKNOWN;
- dev_info(&instance->u.usb_dev->dev, "Unknown line state %02x\n",
- instance->line_status);
+ atm_dev->signal = ATM_PHY_SIG_UNKNOWN;
+ dev_info(dev, "Unknown line state %02x\n", instance->line_status);
break;
}
}
#ifdef USE_FW_LOADER
-static int cxacru_fw(struct cxacru_instance_data *instance, enum cxacru_fw_request fw,
+static int cxacru_fw(struct usb_device *usb_dev, enum cxacru_fw_request fw,
u8 code1, u8 code2, u32 addr, u8 *data, int size)
{
int ret;
u8 *buf;
int offd, offb;
const int stride = CMD_PACKET_SIZE - 8;
- struct usb_device *usb_dev = instance->u.usb_dev;
buf = (u8 *) __get_free_page(GFP_KERNEL);
if (!buf)
@@ -534,77 +531,78 @@
return ret;
}
-static void cxacru_upload_firmware(struct cxacru_instance_data *instance,
+static void cxacru_upload_firmware(struct cxacru_data *instance,
const struct firmware *fw,
const struct firmware *br,
const struct firmware *cf)
{
int ret;
int off;
- struct usb_device *dev = instance->u.usb_dev;
- const u32 vid = dev->descriptor.idVendor;
- const u32 pid = dev->descriptor.idProduct;
+ struct usb_device *usb_dev = instance->usbatm.usb_dev;
+ struct device *dev = &usb_dev->dev;
+ const u32 vid = usb_dev->descriptor.idVendor;
+ const u32 pid = usb_dev->descriptor.idProduct;
u32 val;
dbg("cxacru_upload_firmware");
/* FirmwarePllFClkValue */
val = br ? PLLFCLK_OLD : PLLFCLK_NEW;
- ret = cxacru_fw(instance, FW_WRITE_MEM, 0x2, 0x0, PLLFCLK_ADDR, (u8 *) &val, 4);
+ ret = cxacru_fw(usb_dev, FW_WRITE_MEM, 0x2, 0x0, PLLFCLK_ADDR, (u8 *) &val, 4);
if (ret) {
- err("FirmwarePllFClkValue failed: %d", ret);
+ dev_err(dev, "FirmwarePllFClkValue failed: %d\n", ret);
return;
}
/* FirmwarePllBClkValue */
val = br ? PLLBCLK_OLD : PLLBCLK_NEW;
- ret = cxacru_fw(instance, FW_WRITE_MEM, 0x2, 0x0, PLLBCLK_ADDR, (u8 *) &val, 4);
+ ret = cxacru_fw(usb_dev, FW_WRITE_MEM, 0x2, 0x0, PLLBCLK_ADDR, (u8 *) &val, 4);
if (ret) {
- err("FirmwarePllBClkValue failed: %d", ret);
+ dev_err(dev, "FirmwarePllBClkValue failed: %d\n", ret);
return;
}
/* Enable SDRAM */
val = SDRAM_ENA;
- ret = cxacru_fw(instance, FW_WRITE_MEM, 0x2, 0x0, SDRAMEN_ADDR, (u8 *) &val, 4);
+ ret = cxacru_fw(usb_dev, FW_WRITE_MEM, 0x2, 0x0, SDRAMEN_ADDR, (u8 *) &val, 4);
if (ret) {
- err("Enable SDRAM failed: %d", ret);
+ dev_err(dev, "Enable SDRAM failed: %d\n", ret);
return;
}
/* Firmware */
- ret = cxacru_fw(instance, FW_WRITE_MEM, 0x2, 0x0, FW_ADDR, fw->data, fw->size);
+ ret = cxacru_fw(usb_dev, FW_WRITE_MEM, 0x2, 0x0, FW_ADDR, fw->data, fw->size);
if (ret) {
- err("Firmware upload failed: %d", ret);
+ dev_err(dev, "Firmware upload failed: %d\n", ret);
return;
}
/* Boot ROM patch */
if (br) {
- ret = cxacru_fw(instance, FW_WRITE_MEM, 0x2, 0x0, BR_ADDR, br->data, br->size);
+ ret = cxacru_fw(usb_dev, FW_WRITE_MEM, 0x2, 0x0, BR_ADDR, br->data, br->size);
if (ret) {
- err("Boot ROM patching failed: %d", ret);
+ dev_err(dev, "Boot ROM patching failed: %d\n", ret);
return;
}
}
/* Signature */
val = (pid << 16) | (vid & 0xffff);
- ret = cxacru_fw(instance, FW_WRITE_MEM, 0x2, 0x0, SIG_ADDR, (u8 *) &val, 4);
+ ret = cxacru_fw(usb_dev, FW_WRITE_MEM, 0x2, 0x0, SIG_ADDR, (u8 *) &val, 4);
if (ret) {
- err("Signature storing failed: %d", ret);
+ dev_err(dev, "Signature storing failed: %d\n", ret);
return;
}
if (br) {
val = BR_ADDR;
- ret = cxacru_fw(instance, FW_WRITE_MEM, 0x2, 0x0, BR_STACK_ADDR, (u8 *) &val, 4);
+ ret = cxacru_fw(usb_dev, FW_WRITE_MEM, 0x2, 0x0, BR_STACK_ADDR, (u8 *) &val, 4);
}
else {
- ret = cxacru_fw(instance, FW_GOTO_MEM, 0x0, 0x0, FW_ADDR, NULL, 0);
+ ret = cxacru_fw(usb_dev, FW_GOTO_MEM, 0x0, 0x0, FW_ADDR, NULL, 0);
}
if (ret) {
- err("Passing control to firmware failed: %d", ret);
+ dev_err(dev, "Passing control to firmware failed: %d\n", ret);
return;
}
@@ -612,14 +610,14 @@
because we're in our own kernel thread anyway. */
msleep(1000);
- usb_clear_halt(dev, usb_sndbulkpipe(dev, CXACRU_EP_CMD));
- usb_clear_halt(dev, usb_rcvbulkpipe(dev, CXACRU_EP_CMD));
- usb_clear_halt(dev, usb_sndbulkpipe(dev, CXACRU_EP_DATA));
- usb_clear_halt(dev, usb_rcvbulkpipe(dev, CXACRU_EP_DATA));
+ usb_clear_halt(usb_dev, usb_sndbulkpipe(usb_dev, CXACRU_EP_CMD));
+ usb_clear_halt(usb_dev, usb_rcvbulkpipe(usb_dev, CXACRU_EP_CMD));
+ usb_clear_halt(usb_dev, usb_sndbulkpipe(usb_dev, CXACRU_EP_DATA));
+ usb_clear_halt(usb_dev, usb_rcvbulkpipe(usb_dev, CXACRU_EP_DATA));
ret = cxacru_cm(instance, CM_REQUEST_CARD_GET_STATUS, NULL, 0, NULL, 0);
if (ret < 0) {
- err("modem failed to initialize: %d", ret);
+ dev_err(dev, "modem failed to initialize: %d\n", ret);
return;
}
@@ -635,88 +633,81 @@
ret = cxacru_cm(instance, CM_REQUEST_CARD_DATA_SET,
(u8 *) buf, len, NULL, 0);
if (ret < 0) {
- err("load config data failed: %d", ret);
+ dev_err(dev, "load config data failed: %d\n", ret);
return;
}
}
msleep(4000);
- dbg("done setting up the modem");
-
- cxacru_adsl_start(instance);
+ if (cxacru_is_up(instance)) {
+ dbg("done setting up the modem");
+ cxacru_adsl_start(instance);
+ }
+ else
+ dbg("modem initialisation failed");
}
-static int cxacru_find_firmware(struct cxacru_instance_data *instance,
+static int cxacru_find_firmware(struct usbatm_data *instance,
char* phase, const struct firmware **fw_p)
{
+ struct device *dev = &instance->usb_dev->dev;
char buf[16];
sprintf(buf, "cxacru-%s.bin", phase);
dbg("cxacru_find_firmware: looking for %s", buf);
- if (request_firmware(fw_p, buf, &instance->u.usb_dev->dev)) {
- dev_warn(&instance->u.usb_dev->dev, "no stage %s firmware found\n", phase);
+ if (request_firmware(fw_p, buf, dev)) {
+ dev_warn(dev, "no stage %s firmware found\n", phase);
return -ENOENT;
}
- dev_info(&instance->u.usb_dev->dev, "found firmware %s\n", buf);
+ dev_info(dev, "found firmware %s\n", buf);
return 0;
}
-static int cxacru_load_firmware(void *arg)
+static void cxacru_heavy_init(struct usbatm_data *usbatm_instance)
{
const struct firmware *fw, *bp, *cf;
- struct cxacru_instance_data *instance = arg;
-
- BUG_ON(!instance);
- daemonize("firmware/cxacru");
-
- if (!cxacru_find_firmware(instance, "fw", &fw)) {
- if (!cxacru_find_firmware(instance, "cf", &cf)) {
- if (!cxacru_find_firmware(instance, "bp", &bp))
+ if (!cxacru_find_firmware(usbatm_instance, "fw", &fw)) {
+ if (!cxacru_find_firmware(usbatm_instance, "cf", &cf)) {
+ if (!cxacru_find_firmware(usbatm_instance, "bp", &bp))
/* ok, assume it's not needed */
bp = NULL;
- cxacru_upload_firmware(instance, fw, bp, cf);
+ cxacru_upload_firmware(to_cxacru_data(usbatm_instance), fw, bp, cf);
release_firmware(cf);
}
release_firmware(fw);
}
-
- module_put(THIS_MODULE);
- return 0;
}
+#endif /* USE_FW_LOADER */
-static void cxacru_firmware_start(struct cxacru_instance_data *instance)
+static void cxacru_cleanup(struct usbatm_data *usbatm_instance)
{
- int ret;
-
- try_module_get(THIS_MODULE);
+ struct cxacru_data *instance = to_cxacru_data(usbatm_instance);
- ret = kernel_thread(cxacru_load_firmware, instance,
- CLONE_FS | CLONE_FILES);
-
- if (ret >= 0)
- return; /* OK */
+ dbg("cxacru_cleanup");
+ usb_kill_urb(instance->snd_urb);
+ usb_kill_urb(instance->rcv_urb);
+ usb_free_urb(instance->snd_urb);
+ usb_free_urb(instance->rcv_urb);
- dbg("cxacru_firmware_start: kernel_thread failed (%d)!", ret);
+ free_page((unsigned long) instance->snd_buf);
+ free_page((unsigned long) instance->rcv_buf);
- module_put(THIS_MODULE);
+ kfree(instance);
}
-#endif /* USE_FW_LOADER */
static int cxacru_usb_probe(struct usb_interface *intf,
- const struct usb_device_id *id)
+ const struct usb_device_id *id)
{
- struct usb_device *dev = interface_to_usbdev(intf);
- struct cxacru_instance_data *instance;
+ struct cxacru_data *instance;
+ struct usb_device *usb_dev = interface_to_usbdev(intf);
int ret;
- dbg("cxacru_usb_probe: trying device with vendor=0x%x, product=0x%x",
- dev->descriptor.idVendor, dev->descriptor.idProduct);
-
+ dbg("probed device: %p", usb_dev);
/* instance init */
instance = kmalloc(sizeof(*instance), GFP_KERNEL);
if (!instance) {
@@ -724,7 +715,7 @@
return -ENOMEM;
}
- memset(instance, 0, sizeof(struct cxacru_instance_data));
+ memset(instance, 0, sizeof(*instance));
instance->rcv_buf = (u8 *) __get_free_page(GFP_KERNEL);
if (!instance->rcv_buf) {
@@ -751,23 +742,24 @@
goto fail;
}
- instance->u.data_endpoint = CXACRU_EP_DATA;
- instance->u.snd_padding = 11;
- instance->u.rcv_padding = 3;
- instance->u.driver_name = cxacru_driver_name;
- instance->u.usb_dev = dev;
-
- usb_fill_int_urb(instance->rcv_urb, dev, usb_rcvintpipe(dev, CXACRU_EP_CMD),
- instance->rcv_buf, PAGE_SIZE,
- cxacru_blocking_completion, &instance->rcv_done, 1);
+ ret = usbatm_init(&instance->usbatm, &cxacru_driver, usb_dev);
+ if (ret < 0) {
+ dbg("cxacru_usb_probe: usbatm_init returned %d", ret);
+ goto fail;
+ }
+
+ usb_fill_int_urb(instance->rcv_urb,
+ usb_dev, usb_rcvintpipe(usb_dev, CXACRU_EP_CMD),
+ instance->rcv_buf, PAGE_SIZE,
+ cxacru_blocking_completion, &instance->rcv_done, 1);
instance->rcv_urb->transfer_flags |= URB_ASYNC_UNLINK;
- usb_fill_int_urb(instance->snd_urb, dev, usb_sndintpipe(dev, CXACRU_EP_CMD),
- instance->snd_buf, PAGE_SIZE,
- cxacru_blocking_completion, &instance->snd_done, 4);
+ usb_fill_int_urb(instance->snd_urb,
+ usb_dev, usb_sndintpipe(usb_dev, CXACRU_EP_CMD),
+ instance->snd_buf, PAGE_SIZE,
+ cxacru_blocking_completion, &instance->snd_done, 4);
instance->snd_urb->transfer_flags |= URB_ASYNC_UNLINK;
- init_MUTEX(&instance->start_serialize);
init_MUTEX(&instance->cm_serialize);
init_timer(&instance->poll_timer);
@@ -778,7 +770,12 @@
usb_set_intfdata(intf, instance);
- cxacru_adsl_start(instance);
+ if (cxacru_is_up(instance))
+ cxacru_adsl_start(instance);
+#ifdef USE_FW_LOADER
+ else
+ usbatm_heavy_init(&instance->usbatm);
+#endif /* USE_FW_LOADER */
return 0;
@@ -798,7 +795,7 @@
static void cxacru_usb_disconnect(struct usb_interface *intf)
{
- struct cxacru_instance_data *instance = usb_get_intfdata(intf);
+ struct cxacru_data *instance = usb_get_intfdata(intf);
dbg("cxacru_usb_disconnect entered");
@@ -811,20 +808,9 @@
wmb();
flush_scheduled_work();
- usb_kill_urb(instance->snd_urb);
- usb_kill_urb(instance->rcv_urb);
- usb_free_urb(instance->snd_urb);
- usb_free_urb(instance->rcv_urb);
-
- free_page((unsigned long) instance->snd_buf);
- free_page((unsigned long) instance->rcv_buf);
-
- udsl_instance_disconnect(&instance->u);
+ usbatm_disconnect(&instance->usbatm);
- /* clean up */
usb_set_intfdata(intf, NULL);
- /* FIXME: do we need this refcount? */
- udsl_put_instance(&instance->u);
}
static struct usb_device_id cxacru_usb_ids[] = {
More information about the Usbatm-commits
mailing list