diff options
Diffstat (limited to 'drivers/usb/atm/cxacru.c')
| -rw-r--r-- | drivers/usb/atm/cxacru.c | 122 |
1 files changed, 73 insertions, 49 deletions
diff --git a/drivers/usb/atm/cxacru.c b/drivers/usb/atm/cxacru.c index c89990f5e01..813d4d3a51c 100644 --- a/drivers/usb/atm/cxacru.c +++ b/drivers/usb/atm/cxacru.c @@ -35,7 +35,6 @@ #include <linux/timer.h> #include <linux/errno.h> #include <linux/slab.h> -#include <linux/init.h> #include <linux/device.h> #include <linux/firmware.h> #include <linux/mutex.h> @@ -564,7 +563,7 @@ static void cxacru_timeout_kill(unsigned long data) } static int cxacru_start_wait_urb(struct urb *urb, struct completion *done, - int* actual_length) + int *actual_length) { struct timer_list timer; @@ -674,7 +673,7 @@ static int cxacru_cm(struct cxacru_data *instance, enum cxacru_cm_request cm, } ret = offd; - dbg("cm %#x", cm); + usb_dbg(instance->usbatm, "cm %#x\n", cm); fail: mutex_unlock(&instance->cm_serialize); err: @@ -686,7 +685,8 @@ static int cxacru_cm_get_array(struct cxacru_data *instance, enum cxacru_cm_requ { int ret, len; __le32 *buf; - int offb, offd; + int offb; + unsigned int offd; const int stride = CMD_PACKET_SIZE / (4 * 2) - 1; int buflen = ((size - 1) / stride + 1 + size * 2) * 4; @@ -733,7 +733,7 @@ static int cxacru_card_status(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); + usb_dbg(instance->usbatm, "cxacru_adsl_start: CARD_GET_STATUS returned %d\n", ret); return ret; } return 0; @@ -758,7 +758,7 @@ static int cxacru_atm_start(struct usbatm_data *usbatm_instance, int ret; int start_polling = 1; - dbg("cxacru_atm_start"); + dev_dbg(&intf->dev, "%s\n", __func__); /* Read MAC address */ ret = cxacru_cm(instance, CM_REQUEST_CARD_GET_MAC_ADDRESS, NULL, 0, @@ -866,50 +866,50 @@ static void cxacru_poll_status(struct work_struct *work) instance->line_status = buf[CXINF_LINE_STATUS]; switch (instance->line_status) { case 0: - atm_dev->signal = ATM_PHY_SIG_LOST; + atm_dev_signal_change(atm_dev, ATM_PHY_SIG_LOST); atm_info(usbatm, "ADSL line: down\n"); break; case 1: - atm_dev->signal = ATM_PHY_SIG_LOST; + atm_dev_signal_change(atm_dev, ATM_PHY_SIG_LOST); atm_info(usbatm, "ADSL line: attempting to activate\n"); break; case 2: - atm_dev->signal = ATM_PHY_SIG_LOST; + atm_dev_signal_change(atm_dev, ATM_PHY_SIG_LOST); atm_info(usbatm, "ADSL line: training\n"); break; case 3: - atm_dev->signal = ATM_PHY_SIG_LOST; + atm_dev_signal_change(atm_dev, ATM_PHY_SIG_LOST); atm_info(usbatm, "ADSL line: channel analysis\n"); break; case 4: - atm_dev->signal = ATM_PHY_SIG_LOST; + atm_dev_signal_change(atm_dev, ATM_PHY_SIG_LOST); atm_info(usbatm, "ADSL line: exchange\n"); break; case 5: atm_dev->link_rate = buf[CXINF_DOWNSTREAM_RATE] * 1000 / 424; - atm_dev->signal = ATM_PHY_SIG_FOUND; + atm_dev_signal_change(atm_dev, ATM_PHY_SIG_FOUND); atm_info(usbatm, "ADSL line: up (%d kb/s down | %d kb/s up)\n", buf[CXINF_DOWNSTREAM_RATE], buf[CXINF_UPSTREAM_RATE]); break; case 6: - atm_dev->signal = ATM_PHY_SIG_LOST; + atm_dev_signal_change(atm_dev, ATM_PHY_SIG_LOST); atm_info(usbatm, "ADSL line: waiting\n"); break; case 7: - atm_dev->signal = ATM_PHY_SIG_LOST; + atm_dev_signal_change(atm_dev, ATM_PHY_SIG_LOST); atm_info(usbatm, "ADSL line: initializing\n"); break; default: - atm_dev->signal = ATM_PHY_SIG_UNKNOWN; + atm_dev_signal_change(atm_dev, ATM_PHY_SIG_UNKNOWN); atm_info(usbatm, "Unknown line state %02x\n", instance->line_status); break; } @@ -952,7 +952,7 @@ static int cxacru_fw(struct usb_device *usb_dev, enum cxacru_fw_request fw, put_unaligned(cpu_to_le32(addr), (__le32 *)(buf + offb)); offb += 4; addr += l; - if(l) + if (l) memcpy(buf + offb, data + offd, l); if (l < stride) memset(buf + offb + l, 0, stride - l); @@ -962,13 +962,13 @@ static int cxacru_fw(struct usb_device *usb_dev, enum cxacru_fw_request fw, ret = usb_bulk_msg(usb_dev, usb_sndbulkpipe(usb_dev, CXACRU_EP_CMD), buf, offb, NULL, CMD_TIMEOUT); if (ret < 0) { - dbg("sending fw %#x failed", fw); + dev_dbg(&usb_dev->dev, "sending fw %#x failed\n", fw); goto cleanup; } offb = 0; } - } while(offd < size); - dbg("sent fw %#x", fw); + } while (offd < size); + dev_dbg(&usb_dev->dev, "sent fw %#x\n", fw); ret = 0; @@ -988,7 +988,7 @@ static void cxacru_upload_firmware(struct cxacru_data *instance, usb_dev->descriptor.idProduct }; __le32 val; - dbg("cxacru_upload_firmware"); + usb_dbg(usbatm, "%s\n", __func__); /* FirmwarePllFClkValue */ val = cpu_to_le32(instance->modem_type->pll_f_clk); @@ -1043,8 +1043,7 @@ static void cxacru_upload_firmware(struct cxacru_data *instance, if (instance->modem_type->boot_rom_patch) { val = cpu_to_le32(BR_ADDR); ret = cxacru_fw(usb_dev, FW_WRITE_MEM, 0x2, 0x0, BR_STACK_ADDR, (u8 *) &val, 4); - } - else { + } else { ret = cxacru_fw(usb_dev, FW_GOTO_MEM, 0x0, 0x0, FW_ADDR, NULL, 0); } if (ret) { @@ -1068,14 +1067,14 @@ static void cxacru_upload_firmware(struct cxacru_data *instance, } static int cxacru_find_firmware(struct cxacru_data *instance, - char* phase, const struct firmware **fw_p) + char *phase, const struct firmware **fw_p) { struct usbatm_data *usbatm = instance->usbatm; struct device *dev = &usbatm->usb_intf->dev; char buf[16]; sprintf(buf, "cxacru-%s.bin", phase); - dbg("cxacru_find_firmware: looking for %s", buf); + usb_dbg(usbatm, "cxacru_find_firmware: looking for %s\n", buf); if (request_firmware(fw_p, buf, dev)) { usb_dbg(usbatm, "no stage %s firmware found\n", phase); @@ -1116,9 +1115,9 @@ static int cxacru_heavy_init(struct usbatm_data *usbatm_instance, ret = cxacru_card_status(instance); if (ret) - dbg("modem initialisation failed"); + usb_dbg(usbatm_instance, "modem initialisation failed\n"); else - dbg("done setting up the modem"); + usb_dbg(usbatm_instance, "done setting up the modem\n"); return ret; } @@ -1128,12 +1127,13 @@ static int cxacru_bind(struct usbatm_data *usbatm_instance, { struct cxacru_data *instance; struct usb_device *usb_dev = interface_to_usbdev(intf); + struct usb_host_endpoint *cmd_ep = usb_dev->ep_in[CXACRU_EP_CMD]; int ret; /* instance init */ instance = kzalloc(sizeof(*instance), GFP_KERNEL); if (!instance) { - dbg("cxacru_bind: no memory for instance data"); + usb_dbg(usbatm_instance, "cxacru_bind: no memory for instance data\n"); return -ENOMEM; } @@ -1149,38 +1149,57 @@ static int cxacru_bind(struct usbatm_data *usbatm_instance, instance->rcv_buf = (u8 *) __get_free_page(GFP_KERNEL); if (!instance->rcv_buf) { - dbg("cxacru_bind: no memory for rcv_buf"); + usb_dbg(usbatm_instance, "cxacru_bind: no memory for rcv_buf\n"); ret = -ENOMEM; goto fail; } instance->snd_buf = (u8 *) __get_free_page(GFP_KERNEL); if (!instance->snd_buf) { - dbg("cxacru_bind: no memory for snd_buf"); + usb_dbg(usbatm_instance, "cxacru_bind: no memory for snd_buf\n"); ret = -ENOMEM; goto fail; } instance->rcv_urb = usb_alloc_urb(0, GFP_KERNEL); if (!instance->rcv_urb) { - dbg("cxacru_bind: no memory for rcv_urb"); + usb_dbg(usbatm_instance, "cxacru_bind: no memory for rcv_urb\n"); ret = -ENOMEM; goto fail; } instance->snd_urb = usb_alloc_urb(0, GFP_KERNEL); if (!instance->snd_urb) { - dbg("cxacru_bind: no memory for snd_urb"); + usb_dbg(usbatm_instance, "cxacru_bind: no memory for snd_urb\n"); ret = -ENOMEM; goto fail; } - usb_fill_int_urb(instance->rcv_urb, + if (!cmd_ep) { + usb_dbg(usbatm_instance, "cxacru_bind: no command endpoint\n"); + ret = -ENODEV; + goto fail; + } + + if ((cmd_ep->desc.bmAttributes & USB_ENDPOINT_XFERTYPE_MASK) + == USB_ENDPOINT_XFER_INT) { + 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); - usb_fill_int_urb(instance->snd_urb, + 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); + } else { + usb_fill_bulk_urb(instance->rcv_urb, + usb_dev, usb_rcvbulkpipe(usb_dev, CXACRU_EP_CMD), + instance->rcv_buf, PAGE_SIZE, + cxacru_blocking_completion, &instance->rcv_done); + + usb_fill_bulk_urb(instance->snd_urb, + usb_dev, usb_sndbulkpipe(usb_dev, CXACRU_EP_CMD), + instance->snd_buf, PAGE_SIZE, + cxacru_blocking_completion, &instance->snd_done); + } mutex_init(&instance->cm_serialize); @@ -1208,10 +1227,10 @@ static void cxacru_unbind(struct usbatm_data *usbatm_instance, struct cxacru_data *instance = usbatm_instance->driver_data; int is_polling = 1; - dbg("cxacru_unbind entered"); + usb_dbg(usbatm_instance, "cxacru_unbind entered\n"); if (!instance) { - dbg("cxacru_unbind: NULL instance!"); + usb_dbg(usbatm_instance, "cxacru_unbind: NULL instance!\n"); return; } @@ -1228,7 +1247,7 @@ static void cxacru_unbind(struct usbatm_data *usbatm_instance, mutex_unlock(&instance->poll_state_serialize); if (is_polling) - cancel_rearming_delayed_work(&instance->poll_work); + cancel_delayed_work_sync(&instance->poll_work); usb_kill_urb(instance->snd_urb); usb_kill_urb(instance->rcv_urb); @@ -1325,8 +1344,24 @@ static struct usbatm_driver cxacru_driver = { .tx_padding = 11, }; -static int cxacru_usb_probe(struct usb_interface *intf, const struct usb_device_id *id) +static int cxacru_usb_probe(struct usb_interface *intf, + const struct usb_device_id *id) { + struct usb_device *usb_dev = interface_to_usbdev(intf); + char buf[15]; + + /* Avoid ADSL routers (cx82310_eth). + * Abort if bDeviceClass is 0xff and iProduct is "USB NET CARD". + */ + if (usb_dev->descriptor.bDeviceClass == USB_CLASS_VENDOR_SPEC + && usb_string(usb_dev, usb_dev->descriptor.iProduct, + buf, sizeof(buf)) > 0) { + if (!strcmp(buf, "USB NET CARD")) { + dev_info(&intf->dev, "ignoring cx82310_eth device\n"); + return -ENODEV; + } + } + return usbatm_usb_probe(intf, id, &cxacru_driver); } @@ -1337,18 +1372,7 @@ static struct usb_driver cxacru_usb_driver = { .id_table = cxacru_usb_ids }; -static int __init cxacru_init(void) -{ - return usb_register(&cxacru_usb_driver); -} - -static void __exit cxacru_cleanup(void) -{ - usb_deregister(&cxacru_usb_driver); -} - -module_init(cxacru_init); -module_exit(cxacru_cleanup); +module_usb_driver(cxacru_usb_driver); MODULE_AUTHOR(DRIVER_AUTHOR); MODULE_DESCRIPTION(DRIVER_DESC); |
