diff options
Diffstat (limited to 'drivers/usb/atm/ueagle-atm.c')
-rw-r--r-- | drivers/usb/atm/ueagle-atm.c | 96 |
1 files changed, 55 insertions, 41 deletions
diff --git a/drivers/usb/atm/ueagle-atm.c b/drivers/usb/atm/ueagle-atm.c index 7d2a679989ed..830d2c982670 100644 --- a/drivers/usb/atm/ueagle-atm.c +++ b/drivers/usb/atm/ueagle-atm.c | |||
@@ -63,11 +63,12 @@ | |||
63 | #include <linux/ctype.h> | 63 | #include <linux/ctype.h> |
64 | #include <linux/kthread.h> | 64 | #include <linux/kthread.h> |
65 | #include <linux/version.h> | 65 | #include <linux/version.h> |
66 | #include <linux/mutex.h> | ||
66 | #include <asm/unaligned.h> | 67 | #include <asm/unaligned.h> |
67 | 68 | ||
68 | #include "usbatm.h" | 69 | #include "usbatm.h" |
69 | 70 | ||
70 | #define EAGLEUSBVERSION "ueagle 1.1" | 71 | #define EAGLEUSBVERSION "ueagle 1.2" |
71 | 72 | ||
72 | 73 | ||
73 | /* | 74 | /* |
@@ -358,16 +359,19 @@ struct intr_pkt { | |||
358 | #define INTR_PKT_SIZE 28 | 359 | #define INTR_PKT_SIZE 28 |
359 | 360 | ||
360 | static struct usb_driver uea_driver; | 361 | static struct usb_driver uea_driver; |
361 | static DECLARE_MUTEX(uea_semaphore); | 362 | static DEFINE_MUTEX(uea_mutex); |
362 | static const char *chip_name[] = {"ADI930", "Eagle I", "Eagle II", "Eagle III"}; | 363 | static const char *chip_name[] = {"ADI930", "Eagle I", "Eagle II", "Eagle III"}; |
363 | 364 | ||
364 | static int modem_index; | 365 | static int modem_index; |
365 | static unsigned int debug; | 366 | static unsigned int debug; |
367 | static int use_iso[NB_MODEM] = {[0 ... (NB_MODEM - 1)] = 1}; | ||
366 | static int sync_wait[NB_MODEM]; | 368 | static int sync_wait[NB_MODEM]; |
367 | static char *cmv_file[NB_MODEM]; | 369 | static char *cmv_file[NB_MODEM]; |
368 | 370 | ||
369 | module_param(debug, uint, 0644); | 371 | module_param(debug, uint, 0644); |
370 | MODULE_PARM_DESC(debug, "module debug level (0=off,1=on,2=verbose)"); | 372 | MODULE_PARM_DESC(debug, "module debug level (0=off,1=on,2=verbose)"); |
373 | module_param_array(use_iso, bool, NULL, 0644); | ||
374 | MODULE_PARM_DESC(use_iso, "use isochronous usb pipe for incoming traffic"); | ||
371 | module_param_array(sync_wait, bool, NULL, 0644); | 375 | module_param_array(sync_wait, bool, NULL, 0644); |
372 | MODULE_PARM_DESC(sync_wait, "wait the synchronisation before starting ATM"); | 376 | MODULE_PARM_DESC(sync_wait, "wait the synchronisation before starting ATM"); |
373 | module_param_array(cmv_file, charp, NULL, 0644); | 377 | module_param_array(cmv_file, charp, NULL, 0644); |
@@ -628,8 +632,7 @@ static int request_dsp(struct uea_softc *sc) | |||
628 | dsp_name = FW_DIR "DSPep.bin"; | 632 | dsp_name = FW_DIR "DSPep.bin"; |
629 | } | 633 | } |
630 | 634 | ||
631 | ret = request_firmware(&sc->dsp_firm, | 635 | ret = request_firmware(&sc->dsp_firm, dsp_name, &sc->usb_dev->dev); |
632 | dsp_name, &sc->usb_dev->dev); | ||
633 | if (ret < 0) { | 636 | if (ret < 0) { |
634 | uea_err(INS_TO_USBDEV(sc), | 637 | uea_err(INS_TO_USBDEV(sc), |
635 | "requesting firmware %s failed with error %d\n", | 638 | "requesting firmware %s failed with error %d\n", |
@@ -744,7 +747,6 @@ static inline int wait_cmv_ack(struct uea_softc *sc) | |||
744 | return ret; | 747 | return ret; |
745 | 748 | ||
746 | return (ret == 0) ? -ETIMEDOUT : 0; | 749 | return (ret == 0) ? -ETIMEDOUT : 0; |
747 | |||
748 | } | 750 | } |
749 | 751 | ||
750 | #define UCDC_SEND_ENCAPSULATED_COMMAND 0x00 | 752 | #define UCDC_SEND_ENCAPSULATED_COMMAND 0x00 |
@@ -935,6 +937,7 @@ static int uea_stat(struct uea_softc *sc) | |||
935 | * ADI930 don't support it (-EPIPE error). | 937 | * ADI930 don't support it (-EPIPE error). |
936 | */ | 938 | */ |
937 | if (UEA_CHIP_VERSION(sc) != ADI930 | 939 | if (UEA_CHIP_VERSION(sc) != ADI930 |
940 | && !use_iso[sc->modem_index] | ||
938 | && sc->stats.phy.dsrate != (data >> 16) * 32) { | 941 | && sc->stats.phy.dsrate != (data >> 16) * 32) { |
939 | /* Original timming from ADI(used in windows driver) | 942 | /* Original timming from ADI(used in windows driver) |
940 | * 0x20ffff>>16 * 32 = 32 * 32 = 1Mbits | 943 | * 0x20ffff>>16 * 32 = 32 * 32 = 1Mbits |
@@ -1010,7 +1013,7 @@ static int request_cmvs(struct uea_softc *sc, | |||
1010 | int ret, size; | 1013 | int ret, size; |
1011 | u8 *data; | 1014 | u8 *data; |
1012 | char *file; | 1015 | char *file; |
1013 | static char cmv_name[256] = FW_DIR; | 1016 | char cmv_name[FIRMWARE_NAME_MAX]; /* 30 bytes stack variable */ |
1014 | 1017 | ||
1015 | if (cmv_file[sc->modem_index] == NULL) { | 1018 | if (cmv_file[sc->modem_index] == NULL) { |
1016 | if (UEA_CHIP_VERSION(sc) == ADI930) | 1019 | if (UEA_CHIP_VERSION(sc) == ADI930) |
@@ -1184,8 +1187,7 @@ static int load_XILINX_firmware(struct uea_softc *sc) | |||
1184 | } | 1187 | } |
1185 | } | 1188 | } |
1186 | 1189 | ||
1187 | /* finish to send the fpga | 1190 | /* finish to send the fpga */ |
1188 | */ | ||
1189 | ret = uea_request(sc, 0xe, 1, 0, NULL); | 1191 | ret = uea_request(sc, 0xe, 1, 0, NULL); |
1190 | if (ret < 0) { | 1192 | if (ret < 0) { |
1191 | uea_err(INS_TO_USBDEV(sc), | 1193 | uea_err(INS_TO_USBDEV(sc), |
@@ -1193,9 +1195,7 @@ static int load_XILINX_firmware(struct uea_softc *sc) | |||
1193 | goto err1; | 1195 | goto err1; |
1194 | } | 1196 | } |
1195 | 1197 | ||
1196 | /* | 1198 | /* Tell the modem we finish : de-assert reset */ |
1197 | * Tell the modem we finish : de-assert reset | ||
1198 | */ | ||
1199 | value = 0; | 1199 | value = 0; |
1200 | ret = uea_send_modem_cmd(sc->usb_dev, 0xe, 1, &value); | 1200 | ret = uea_send_modem_cmd(sc->usb_dev, 0xe, 1, &value); |
1201 | if (ret < 0) | 1201 | if (ret < 0) |
@@ -1209,6 +1209,7 @@ err0: | |||
1209 | return ret; | 1209 | return ret; |
1210 | } | 1210 | } |
1211 | 1211 | ||
1212 | /* The modem send us an ack. First with check if it right */ | ||
1212 | static void uea_dispatch_cmv(struct uea_softc *sc, struct cmv* cmv) | 1213 | static void uea_dispatch_cmv(struct uea_softc *sc, struct cmv* cmv) |
1213 | { | 1214 | { |
1214 | uea_enters(INS_TO_USBDEV(sc)); | 1215 | uea_enters(INS_TO_USBDEV(sc)); |
@@ -1268,23 +1269,19 @@ bad1: | |||
1268 | */ | 1269 | */ |
1269 | static void uea_intr(struct urb *urb, struct pt_regs *regs) | 1270 | static void uea_intr(struct urb *urb, struct pt_regs *regs) |
1270 | { | 1271 | { |
1271 | struct uea_softc *sc = (struct uea_softc *)urb->context; | 1272 | struct uea_softc *sc = urb->context; |
1272 | struct intr_pkt *intr; | 1273 | struct intr_pkt *intr = urb->transfer_buffer; |
1273 | uea_enters(INS_TO_USBDEV(sc)); | 1274 | uea_enters(INS_TO_USBDEV(sc)); |
1274 | 1275 | ||
1275 | if (urb->status < 0) { | 1276 | if (unlikely(urb->status < 0)) { |
1276 | uea_err(INS_TO_USBDEV(sc), "uea_intr() failed with %d\n", | 1277 | uea_err(INS_TO_USBDEV(sc), "uea_intr() failed with %d\n", |
1277 | urb->status); | 1278 | urb->status); |
1278 | return; | 1279 | return; |
1279 | } | 1280 | } |
1280 | 1281 | ||
1281 | intr = (struct intr_pkt *) urb->transfer_buffer; | ||
1282 | |||
1283 | /* device-to-host interrupt */ | 1282 | /* device-to-host interrupt */ |
1284 | if (intr->bType != 0x08 || sc->booting) { | 1283 | if (intr->bType != 0x08 || sc->booting) { |
1285 | uea_err(INS_TO_USBDEV(sc), "wrong intr\n"); | 1284 | uea_err(INS_TO_USBDEV(sc), "wrong interrupt\n"); |
1286 | // rebooting ? | ||
1287 | // sc->reset = 1; | ||
1288 | goto resubmit; | 1285 | goto resubmit; |
1289 | } | 1286 | } |
1290 | 1287 | ||
@@ -1300,7 +1297,7 @@ static void uea_intr(struct urb *urb, struct pt_regs *regs) | |||
1300 | break; | 1297 | break; |
1301 | 1298 | ||
1302 | default: | 1299 | default: |
1303 | uea_err(INS_TO_USBDEV(sc), "unknown intr %u\n", | 1300 | uea_err(INS_TO_USBDEV(sc), "unknown interrupt %u\n", |
1304 | le16_to_cpu(intr->wInterrupt)); | 1301 | le16_to_cpu(intr->wInterrupt)); |
1305 | } | 1302 | } |
1306 | 1303 | ||
@@ -1379,7 +1376,7 @@ static void uea_stop(struct uea_softc *sc) | |||
1379 | int ret; | 1376 | int ret; |
1380 | uea_enters(INS_TO_USBDEV(sc)); | 1377 | uea_enters(INS_TO_USBDEV(sc)); |
1381 | ret = kthread_stop(sc->kthread); | 1378 | ret = kthread_stop(sc->kthread); |
1382 | uea_info(INS_TO_USBDEV(sc), "kthread finish with status %d\n", ret); | 1379 | uea_dbg(INS_TO_USBDEV(sc), "kthread finish with status %d\n", ret); |
1383 | 1380 | ||
1384 | /* stop any pending boot process */ | 1381 | /* stop any pending boot process */ |
1385 | flush_scheduled_work(); | 1382 | flush_scheduled_work(); |
@@ -1418,13 +1415,13 @@ static ssize_t read_status(struct device *dev, struct device_attribute *attr, | |||
1418 | int ret = -ENODEV; | 1415 | int ret = -ENODEV; |
1419 | struct uea_softc *sc; | 1416 | struct uea_softc *sc; |
1420 | 1417 | ||
1421 | down(&uea_semaphore); | 1418 | mutex_lock(&uea_mutex); |
1422 | sc = dev_to_uea(dev); | 1419 | sc = dev_to_uea(dev); |
1423 | if (!sc) | 1420 | if (!sc) |
1424 | goto out; | 1421 | goto out; |
1425 | ret = snprintf(buf, 10, "%08x\n", sc->stats.phy.state); | 1422 | ret = snprintf(buf, 10, "%08x\n", sc->stats.phy.state); |
1426 | out: | 1423 | out: |
1427 | up(&uea_semaphore); | 1424 | mutex_unlock(&uea_mutex); |
1428 | return ret; | 1425 | return ret; |
1429 | } | 1426 | } |
1430 | 1427 | ||
@@ -1434,14 +1431,14 @@ static ssize_t reboot(struct device *dev, struct device_attribute *attr, | |||
1434 | int ret = -ENODEV; | 1431 | int ret = -ENODEV; |
1435 | struct uea_softc *sc; | 1432 | struct uea_softc *sc; |
1436 | 1433 | ||
1437 | down(&uea_semaphore); | 1434 | mutex_lock(&uea_mutex); |
1438 | sc = dev_to_uea(dev); | 1435 | sc = dev_to_uea(dev); |
1439 | if (!sc) | 1436 | if (!sc) |
1440 | goto out; | 1437 | goto out; |
1441 | sc->reset = 1; | 1438 | sc->reset = 1; |
1442 | ret = count; | 1439 | ret = count; |
1443 | out: | 1440 | out: |
1444 | up(&uea_semaphore); | 1441 | mutex_unlock(&uea_mutex); |
1445 | return ret; | 1442 | return ret; |
1446 | } | 1443 | } |
1447 | 1444 | ||
@@ -1453,7 +1450,7 @@ static ssize_t read_human_status(struct device *dev, struct device_attribute *at | |||
1453 | int ret = -ENODEV; | 1450 | int ret = -ENODEV; |
1454 | struct uea_softc *sc; | 1451 | struct uea_softc *sc; |
1455 | 1452 | ||
1456 | down(&uea_semaphore); | 1453 | mutex_lock(&uea_mutex); |
1457 | sc = dev_to_uea(dev); | 1454 | sc = dev_to_uea(dev); |
1458 | if (!sc) | 1455 | if (!sc) |
1459 | goto out; | 1456 | goto out; |
@@ -1473,7 +1470,7 @@ static ssize_t read_human_status(struct device *dev, struct device_attribute *at | |||
1473 | break; | 1470 | break; |
1474 | } | 1471 | } |
1475 | out: | 1472 | out: |
1476 | up(&uea_semaphore); | 1473 | mutex_unlock(&uea_mutex); |
1477 | return ret; | 1474 | return ret; |
1478 | } | 1475 | } |
1479 | 1476 | ||
@@ -1485,7 +1482,7 @@ static ssize_t read_delin(struct device *dev, struct device_attribute *attr, | |||
1485 | int ret = -ENODEV; | 1482 | int ret = -ENODEV; |
1486 | struct uea_softc *sc; | 1483 | struct uea_softc *sc; |
1487 | 1484 | ||
1488 | down(&uea_semaphore); | 1485 | mutex_lock(&uea_mutex); |
1489 | sc = dev_to_uea(dev); | 1486 | sc = dev_to_uea(dev); |
1490 | if (!sc) | 1487 | if (!sc) |
1491 | goto out; | 1488 | goto out; |
@@ -1497,7 +1494,7 @@ static ssize_t read_delin(struct device *dev, struct device_attribute *attr, | |||
1497 | else | 1494 | else |
1498 | ret = sprintf(buf, "GOOD\n"); | 1495 | ret = sprintf(buf, "GOOD\n"); |
1499 | out: | 1496 | out: |
1500 | up(&uea_semaphore); | 1497 | mutex_unlock(&uea_mutex); |
1501 | return ret; | 1498 | return ret; |
1502 | } | 1499 | } |
1503 | 1500 | ||
@@ -1511,7 +1508,7 @@ static ssize_t read_##name(struct device *dev, \ | |||
1511 | int ret = -ENODEV; \ | 1508 | int ret = -ENODEV; \ |
1512 | struct uea_softc *sc; \ | 1509 | struct uea_softc *sc; \ |
1513 | \ | 1510 | \ |
1514 | down(&uea_semaphore); \ | 1511 | mutex_lock(&uea_mutex); \ |
1515 | sc = dev_to_uea(dev); \ | 1512 | sc = dev_to_uea(dev); \ |
1516 | if (!sc) \ | 1513 | if (!sc) \ |
1517 | goto out; \ | 1514 | goto out; \ |
@@ -1519,7 +1516,7 @@ static ssize_t read_##name(struct device *dev, \ | |||
1519 | if (reset) \ | 1516 | if (reset) \ |
1520 | sc->stats.phy.name = 0; \ | 1517 | sc->stats.phy.name = 0; \ |
1521 | out: \ | 1518 | out: \ |
1522 | up(&uea_semaphore); \ | 1519 | mutex_unlock(&uea_mutex); \ |
1523 | return ret; \ | 1520 | return ret; \ |
1524 | } \ | 1521 | } \ |
1525 | \ | 1522 | \ |
@@ -1617,7 +1614,7 @@ static void create_fs_entries(struct uea_softc *sc, struct usb_interface *intf) | |||
1617 | } | 1614 | } |
1618 | 1615 | ||
1619 | static int uea_bind(struct usbatm_data *usbatm, struct usb_interface *intf, | 1616 | static int uea_bind(struct usbatm_data *usbatm, struct usb_interface *intf, |
1620 | const struct usb_device_id *id, int *heavy) | 1617 | const struct usb_device_id *id) |
1621 | { | 1618 | { |
1622 | struct usb_device *usb = interface_to_usbdev(intf); | 1619 | struct usb_device *usb = interface_to_usbdev(intf); |
1623 | struct uea_softc *sc; | 1620 | struct uea_softc *sc; |
@@ -1629,16 +1626,14 @@ static int uea_bind(struct usbatm_data *usbatm, struct usb_interface *intf, | |||
1629 | if (ifnum != UEA_INTR_IFACE_NO) | 1626 | if (ifnum != UEA_INTR_IFACE_NO) |
1630 | return -ENODEV; | 1627 | return -ENODEV; |
1631 | 1628 | ||
1632 | *heavy = sync_wait[modem_index]; | 1629 | usbatm->flags = (sync_wait[modem_index] ? 0 : UDSL_SKIP_HEAVY_INIT); |
1633 | 1630 | ||
1634 | /* interface 1 is for outbound traffic */ | 1631 | /* interface 1 is for outbound traffic */ |
1635 | ret = claim_interface(usb, usbatm, UEA_US_IFACE_NO); | 1632 | ret = claim_interface(usb, usbatm, UEA_US_IFACE_NO); |
1636 | if (ret < 0) | 1633 | if (ret < 0) |
1637 | return ret; | 1634 | return ret; |
1638 | 1635 | ||
1639 | /* ADI930 has only 2 interfaces and inbound traffic | 1636 | /* ADI930 has only 2 interfaces and inbound traffic is on interface 1 */ |
1640 | * is on interface 1 | ||
1641 | */ | ||
1642 | if (UEA_CHIP_VERSION(id) != ADI930) { | 1637 | if (UEA_CHIP_VERSION(id) != ADI930) { |
1643 | /* interface 2 is for inbound traffic */ | 1638 | /* interface 2 is for inbound traffic */ |
1644 | ret = claim_interface(usb, usbatm, UEA_DS_IFACE_NO); | 1639 | ret = claim_interface(usb, usbatm, UEA_DS_IFACE_NO); |
@@ -1658,6 +1653,25 @@ static int uea_bind(struct usbatm_data *usbatm, struct usb_interface *intf, | |||
1658 | sc->modem_index = (modem_index < NB_MODEM) ? modem_index++ : 0; | 1653 | sc->modem_index = (modem_index < NB_MODEM) ? modem_index++ : 0; |
1659 | sc->driver_info = id->driver_info; | 1654 | sc->driver_info = id->driver_info; |
1660 | 1655 | ||
1656 | /* ADI930 don't support iso */ | ||
1657 | if (UEA_CHIP_VERSION(id) != ADI930 && use_iso[sc->modem_index]) { | ||
1658 | int i; | ||
1659 | |||
1660 | /* try set fastest alternate for inbound traffic interface */ | ||
1661 | for (i = FASTEST_ISO_INTF; i > 0; i--) | ||
1662 | if (usb_set_interface(usb, UEA_DS_IFACE_NO, i) == 0) | ||
1663 | break; | ||
1664 | |||
1665 | if (i > 0) { | ||
1666 | uea_dbg(usb, "set alternate %d for 2 interface\n", i); | ||
1667 | uea_info(usb, "using iso mode\n"); | ||
1668 | usbatm->flags |= UDSL_USE_ISOC | UDSL_IGNORE_EILSEQ; | ||
1669 | } else { | ||
1670 | uea_err(usb, "setting any alternate failed for " | ||
1671 | "2 interface, using bulk mode\n"); | ||
1672 | } | ||
1673 | } | ||
1674 | |||
1661 | ret = uea_boot(sc); | 1675 | ret = uea_boot(sc); |
1662 | if (ret < 0) { | 1676 | if (ret < 0) { |
1663 | kfree(sc); | 1677 | kfree(sc); |
@@ -1701,13 +1715,13 @@ static void uea_unbind(struct usbatm_data *usbatm, struct usb_interface *intf) | |||
1701 | 1715 | ||
1702 | static struct usbatm_driver uea_usbatm_driver = { | 1716 | static struct usbatm_driver uea_usbatm_driver = { |
1703 | .driver_name = "ueagle-atm", | 1717 | .driver_name = "ueagle-atm", |
1704 | .owner = THIS_MODULE, | ||
1705 | .bind = uea_bind, | 1718 | .bind = uea_bind, |
1706 | .atm_start = uea_atm_open, | 1719 | .atm_start = uea_atm_open, |
1707 | .unbind = uea_unbind, | 1720 | .unbind = uea_unbind, |
1708 | .heavy_init = uea_heavy, | 1721 | .heavy_init = uea_heavy, |
1709 | .in = UEA_BULK_DATA_PIPE, | 1722 | .bulk_in = UEA_BULK_DATA_PIPE, |
1710 | .out = UEA_BULK_DATA_PIPE, | 1723 | .bulk_out = UEA_BULK_DATA_PIPE, |
1724 | .isoc_in = UEA_ISO_DATA_PIPE, | ||
1711 | }; | 1725 | }; |
1712 | 1726 | ||
1713 | static int uea_probe(struct usb_interface *intf, const struct usb_device_id *id) | 1727 | static int uea_probe(struct usb_interface *intf, const struct usb_device_id *id) |
@@ -1738,9 +1752,9 @@ static void uea_disconnect(struct usb_interface *intf) | |||
1738 | * Pre-firmware device has one interface | 1752 | * Pre-firmware device has one interface |
1739 | */ | 1753 | */ |
1740 | if (usb->config->desc.bNumInterfaces != 1 && ifnum == 0) { | 1754 | if (usb->config->desc.bNumInterfaces != 1 && ifnum == 0) { |
1741 | down(&uea_semaphore); | 1755 | mutex_lock(&uea_mutex); |
1742 | usbatm_usb_disconnect(intf); | 1756 | usbatm_usb_disconnect(intf); |
1743 | up(&uea_semaphore); | 1757 | mutex_unlock(&uea_mutex); |
1744 | uea_info(usb, "ADSL device removed\n"); | 1758 | uea_info(usb, "ADSL device removed\n"); |
1745 | } | 1759 | } |
1746 | 1760 | ||