aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/usb
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/usb')
-rw-r--r--drivers/usb/host/u132-hcd.c92
-rw-r--r--drivers/usb/misc/ftdi-elan.c592
2 files changed, 425 insertions, 259 deletions
diff --git a/drivers/usb/host/u132-hcd.c b/drivers/usb/host/u132-hcd.c
index a9d7119e3176..a7fa0d75567d 100644
--- a/drivers/usb/host/u132-hcd.c
+++ b/drivers/usb/host/u132-hcd.c
@@ -40,6 +40,7 @@
40#include <linux/moduleparam.h> 40#include <linux/moduleparam.h>
41#include <linux/delay.h> 41#include <linux/delay.h>
42#include <linux/ioport.h> 42#include <linux/ioport.h>
43#include <linux/pci_ids.h>
43#include <linux/sched.h> 44#include <linux/sched.h>
44#include <linux/slab.h> 45#include <linux/slab.h>
45#include <linux/smp_lock.h> 46#include <linux/smp_lock.h>
@@ -210,15 +211,16 @@ struct u132 {
210* these cannot be inlines because we need the structure offset!! 211* these cannot be inlines because we need the structure offset!!
211* Does anyone have a better way????? 212* Does anyone have a better way?????
212*/ 213*/
214#define ftdi_read_pcimem(pdev, member, data) usb_ftdi_elan_read_pcimem(pdev, \
215 offsetof(struct ohci_regs, member), 0, data);
216#define ftdi_write_pcimem(pdev, member, data) usb_ftdi_elan_write_pcimem(pdev, \
217 offsetof(struct ohci_regs, member), 0, data);
213#define u132_read_pcimem(u132, member, data) \ 218#define u132_read_pcimem(u132, member, data) \
214 usb_ftdi_elan_read_pcimem(u132->platform_dev, offsetof(struct \ 219 usb_ftdi_elan_read_pcimem(u132->platform_dev, offsetof(struct \
215 ohci_regs, member), 0, data); 220 ohci_regs, member), 0, data);
216#define u132_write_pcimem(u132, member, data) \ 221#define u132_write_pcimem(u132, member, data) \
217 usb_ftdi_elan_write_pcimem(u132->platform_dev, offsetof(struct \ 222 usb_ftdi_elan_write_pcimem(u132->platform_dev, offsetof(struct \
218 ohci_regs, member), 0, data); 223 ohci_regs, member), 0, data);
219#define u132_write_pcimem_byte(u132, member, data) \
220 usb_ftdi_elan_write_pcimem(u132->platform_dev, offsetof(struct \
221 ohci_regs, member), 0x0e, data);
222static inline struct u132 *udev_to_u132(struct u132_udev *udev) 224static inline struct u132 *udev_to_u132(struct u132_udev *udev)
223{ 225{
224 u8 udev_number = udev->udev_number; 226 u8 udev_number = udev->udev_number;
@@ -1574,59 +1576,12 @@ static char *hcfs2string(int state)
1574 return "?"; 1576 return "?";
1575} 1577}
1576 1578
1577static int u132_usb_reset(struct u132 *u132)
1578{
1579 int retval;
1580 retval = u132_read_pcimem(u132, control, &u132->hc_control);
1581 if (retval)
1582 return retval;
1583 u132->hc_control &= OHCI_CTRL_RWC;
1584 retval = u132_write_pcimem(u132, control, u132->hc_control);
1585 if (retval)
1586 return retval;
1587 return 0;
1588}
1589
1590static int u132_init(struct u132 *u132) 1579static int u132_init(struct u132 *u132)
1591{ 1580{
1592 int retval; 1581 int retval;
1593 u32 control; 1582 u32 control;
1594 u132_disable(u132); 1583 u132_disable(u132);
1595 u132->next_statechange = 1584 u132->next_statechange = jiffies;
1596 jiffies; /* SMM owns the HC? not for long! */ {
1597 u32 control;
1598 retval = u132_read_pcimem(u132, control, &control);
1599 if (retval)
1600 return retval;
1601 if (control & OHCI_CTRL_IR) {
1602 u32 temp = 50;
1603 retval = u132_write_pcimem(u132, intrenable,
1604 OHCI_INTR_OC);
1605 if (retval)
1606 return retval;
1607 retval = u132_write_pcimem_byte(u132, cmdstatus,
1608 OHCI_OCR);
1609 if (retval)
1610 return retval;
1611 check:{
1612 retval = u132_read_pcimem(u132, control,
1613 &control);
1614 if (retval)
1615 return retval;
1616 }
1617 if (control & OHCI_CTRL_IR) {
1618 msleep(10);
1619 if (--temp == 0) {
1620 dev_err(&u132->platform_dev->dev, "USB "
1621 "HC takeover failed!(BIOS/SMM b"
1622 "ug) control=%08X\n", control);
1623 return -EBUSY;
1624 }
1625 goto check;
1626 }
1627 u132_usb_reset(u132);
1628 }
1629 }
1630 retval = u132_write_pcimem(u132, intrdisable, OHCI_INTR_MIE); 1585 retval = u132_write_pcimem(u132, intrdisable, OHCI_INTR_MIE);
1631 if (retval) 1586 if (retval)
1632 return retval; 1587 return retval;
@@ -1725,7 +1680,7 @@ static int u132_run(struct u132 *u132)
1725 retry:retval = u132_read_pcimem(u132, cmdstatus, &status); 1680 retry:retval = u132_read_pcimem(u132, cmdstatus, &status);
1726 if (retval) 1681 if (retval)
1727 return retval; 1682 return retval;
1728 retval = u132_write_pcimem_byte(u132, cmdstatus, OHCI_HCR); 1683 retval = u132_write_pcimem(u132, cmdstatus, OHCI_HCR);
1729 if (retval) 1684 if (retval)
1730 return retval; 1685 return retval;
1731 extra:{ 1686 extra:{
@@ -1782,7 +1737,7 @@ static int u132_run(struct u132 *u132)
1782 retval = u132_write_pcimem(u132, control, u132->hc_control); 1737 retval = u132_write_pcimem(u132, control, u132->hc_control);
1783 if (retval) 1738 if (retval)
1784 return retval; 1739 return retval;
1785 retval = u132_write_pcimem_byte(u132, cmdstatus, OHCI_BLF); 1740 retval = u132_write_pcimem(u132, cmdstatus, OHCI_BLF);
1786 if (retval) 1741 if (retval)
1787 return retval; 1742 return retval;
1788 retval = u132_read_pcimem(u132, cmdstatus, &cmdstatus); 1743 retval = u132_read_pcimem(u132, cmdstatus, &cmdstatus);
@@ -1839,8 +1794,8 @@ static void u132_hcd_stop(struct usb_hcd *hcd)
1839{ 1794{
1840 struct u132 *u132 = hcd_to_u132(hcd); 1795 struct u132 *u132 = hcd_to_u132(hcd);
1841 if (u132->going > 1) { 1796 if (u132->going > 1) {
1842 dev_err(&u132->platform_dev->dev, "device has been removed %d\n" 1797 dev_err(&u132->platform_dev->dev, "u132 device %p(hcd=%p) has b"
1843 , u132->going); 1798 "een removed %d\n", u132, hcd, u132->going);
1844 } else if (u132->going > 0) { 1799 } else if (u132->going > 0) {
1845 dev_err(&u132->platform_dev->dev, "device hcd=%p is being remov" 1800 dev_err(&u132->platform_dev->dev, "device hcd=%p is being remov"
1846 "ed\n", hcd); 1801 "ed\n", hcd);
@@ -2545,8 +2500,9 @@ static void u132_endpoint_disable(struct usb_hcd *hcd,
2545{ 2500{
2546 struct u132 *u132 = hcd_to_u132(hcd); 2501 struct u132 *u132 = hcd_to_u132(hcd);
2547 if (u132->going > 2) { 2502 if (u132->going > 2) {
2548 dev_err(&u132->platform_dev->dev, "device has been removed %d\n" 2503 dev_err(&u132->platform_dev->dev, "u132 device %p(hcd=%p hep=%p"
2549 , u132->going); 2504 ") has been removed %d\n", u132, hcd, hep,
2505 u132->going);
2550 } else { 2506 } else {
2551 struct u132_endp *endp = hep->hcpriv; 2507 struct u132_endp *endp = hep->hcpriv;
2552 if (endp) 2508 if (endp)
@@ -2790,7 +2746,6 @@ static int u132_hub_status_data(struct usb_hcd *hcd, char *buf)
2790 } else if (u132->going > 0) { 2746 } else if (u132->going > 0) {
2791 dev_err(&u132->platform_dev->dev, "device hcd=%p is being remov" 2747 dev_err(&u132->platform_dev->dev, "device hcd=%p is being remov"
2792 "ed\n", hcd); 2748 "ed\n", hcd);
2793 dump_stack();
2794 return -ESHUTDOWN; 2749 return -ESHUTDOWN;
2795 } else { 2750 } else {
2796 int i, changed = 0, length = 1; 2751 int i, changed = 0, length = 1;
@@ -3034,12 +2989,15 @@ static int __devexit u132_remove(struct platform_device *pdev)
3034 struct usb_hcd *hcd = platform_get_drvdata(pdev); 2989 struct usb_hcd *hcd = platform_get_drvdata(pdev);
3035 if (hcd) { 2990 if (hcd) {
3036 struct u132 *u132 = hcd_to_u132(hcd); 2991 struct u132 *u132 = hcd_to_u132(hcd);
3037 dump_stack();
3038 if (u132->going++ > 1) { 2992 if (u132->going++ > 1) {
2993 dev_err(&u132->platform_dev->dev, "already being remove"
2994 "d\n");
3039 return -ENODEV; 2995 return -ENODEV;
3040 } else { 2996 } else {
3041 int rings = MAX_U132_RINGS; 2997 int rings = MAX_U132_RINGS;
3042 int endps = MAX_U132_ENDPS; 2998 int endps = MAX_U132_ENDPS;
2999 dev_err(&u132->platform_dev->dev, "removing device u132"
3000 ".%d\n", u132->sequence_num);
3043 msleep(100); 3001 msleep(100);
3044 down(&u132->sw_lock); 3002 down(&u132->sw_lock);
3045 u132_monitor_cancel_work(u132); 3003 u132_monitor_cancel_work(u132);
@@ -3121,10 +3079,24 @@ static void u132_initialise(struct u132 *u132, struct platform_device *pdev)
3121static int __devinit u132_probe(struct platform_device *pdev) 3079static int __devinit u132_probe(struct platform_device *pdev)
3122{ 3080{
3123 struct usb_hcd *hcd; 3081 struct usb_hcd *hcd;
3082 int retval;
3083 u32 control;
3084 u32 rh_a = -1;
3085 u32 num_ports;
3124 msleep(100); 3086 msleep(100);
3125 if (u132_exiting > 0) { 3087 if (u132_exiting > 0) {
3126 return -ENODEV; 3088 return -ENODEV;
3127 } /* refuse to confuse usbcore */ 3089 }
3090 retval = ftdi_write_pcimem(pdev, intrdisable, OHCI_INTR_MIE);
3091 if (retval)
3092 return retval;
3093 retval = ftdi_read_pcimem(pdev, control, &control);
3094 if (retval)
3095 return retval;
3096 retval = ftdi_read_pcimem(pdev, roothub.a, &rh_a);
3097 if (retval)
3098 return retval;
3099 num_ports = rh_a & RH_A_NDP; /* refuse to confuse usbcore */
3128 if (pdev->dev.dma_mask) { 3100 if (pdev->dev.dma_mask) {
3129 return -EINVAL; 3101 return -EINVAL;
3130 } 3102 }
diff --git a/drivers/usb/misc/ftdi-elan.c b/drivers/usb/misc/ftdi-elan.c
index 18b1925032a8..41c0161abdb9 100644
--- a/drivers/usb/misc/ftdi-elan.c
+++ b/drivers/usb/misc/ftdi-elan.c
@@ -40,6 +40,7 @@
40#include <linux/init.h> 40#include <linux/init.h>
41#include <linux/list.h> 41#include <linux/list.h>
42#include <linux/ioctl.h> 42#include <linux/ioctl.h>
43#include <linux/pci_ids.h>
43#include <linux/slab.h> 44#include <linux/slab.h>
44#include <linux/module.h> 45#include <linux/module.h>
45#include <linux/kref.h> 46#include <linux/kref.h>
@@ -51,6 +52,10 @@ MODULE_AUTHOR("Tony Olech");
51MODULE_DESCRIPTION("FTDI ELAN driver"); 52MODULE_DESCRIPTION("FTDI ELAN driver");
52MODULE_LICENSE("GPL"); 53MODULE_LICENSE("GPL");
53#define INT_MODULE_PARM(n, v) static int n = v;module_param(n, int, 0444) 54#define INT_MODULE_PARM(n, v) static int n = v;module_param(n, int, 0444)
55static int distrust_firmware = 1;
56module_param(distrust_firmware, bool, 0);
57MODULE_PARM_DESC(distrust_firmware, "true to distrust firmware power/overcurren"
58 "t setup");
54extern struct platform_driver u132_platform_driver; 59extern struct platform_driver u132_platform_driver;
55static struct workqueue_struct *status_queue; 60static struct workqueue_struct *status_queue;
56static struct workqueue_struct *command_queue; 61static struct workqueue_struct *command_queue;
@@ -66,7 +71,9 @@ static struct list_head ftdi_static_list;
66* end of the global variables protected by ftdi_module_lock 71* end of the global variables protected by ftdi_module_lock
67*/ 72*/
68#include "usb_u132.h" 73#include "usb_u132.h"
69#define TD_DEVNOTRESP 5 74#include <asm/io.h>
75#include "../core/hcd.h"
76#include "../host/ohci.h"
70/* Define these values to match your devices*/ 77/* Define these values to match your devices*/
71#define USB_FTDI_ELAN_VENDOR_ID 0x0403 78#define USB_FTDI_ELAN_VENDOR_ID 0x0403
72#define USB_FTDI_ELAN_PRODUCT_ID 0xd6ea 79#define USB_FTDI_ELAN_PRODUCT_ID 0xd6ea
@@ -551,7 +558,7 @@ static void ftdi_elan_status_work(struct work_struct *work)
551 } else { 558 } else {
552 dev_err(&ftdi->udev->dev, "initialized failed - trying " 559 dev_err(&ftdi->udev->dev, "initialized failed - trying "
553 "again in 10 seconds\n"); 560 "again in 10 seconds\n");
554 work_delay_in_msec = 10 *1000; 561 work_delay_in_msec = 1 *1000;
555 } 562 }
556 } else if (ftdi->registered == 0) { 563 } else if (ftdi->registered == 0) {
557 work_delay_in_msec = 10; 564 work_delay_in_msec = 10;
@@ -2288,82 +2295,288 @@ static int ftdi_elan_checkingPCI(struct usb_ftdi *ftdi)
2288 } 2295 }
2289} 2296}
2290 2297
2291static int ftdi_elan_enumeratePCI(struct usb_ftdi *ftdi) 2298
2299#define ftdi_read_pcimem(ftdi, member, data) ftdi_elan_read_pcimem(ftdi, \
2300 offsetof(struct ohci_regs, member), 0, data);
2301#define ftdi_write_pcimem(ftdi, member, data) ftdi_elan_write_pcimem(ftdi, \
2302 offsetof(struct ohci_regs, member), 0, data);
2303#define OHCI_QUIRK_AMD756 0x01
2304#define OHCI_QUIRK_SUPERIO 0x02
2305#define OHCI_QUIRK_INITRESET 0x04
2306#define OHCI_BIG_ENDIAN 0x08
2307#define OHCI_QUIRK_ZFMICRO 0x10
2308#define OHCI_CONTROL_INIT OHCI_CTRL_CBSR
2309#define OHCI_INTR_INIT (OHCI_INTR_MIE | OHCI_INTR_UE | OHCI_INTR_RD | \
2310 OHCI_INTR_WDH)
2311static int ftdi_elan_check_controller(struct usb_ftdi *ftdi, int quirk)
2312{
2313 int devices = 0;
2314 int retval;
2315 u32 hc_control;
2316 int num_ports;
2317 u32 control;
2318 u32 rh_a = -1;
2319 u32 status;
2320 u32 fminterval;
2321 u32 hc_fminterval;
2322 u32 periodicstart;
2323 u32 cmdstatus;
2324 u32 roothub_a;
2325 int mask = OHCI_INTR_INIT;
2326 int sleep_time = 0;
2327 int reset_timeout = 30; /* ... allow extra time */
2328 int temp;
2329 retval = ftdi_write_pcimem(ftdi, intrdisable, OHCI_INTR_MIE);
2330 if (retval)
2331 return retval;
2332 retval = ftdi_read_pcimem(ftdi, control, &control);
2333 if (retval)
2334 return retval;
2335 retval = ftdi_read_pcimem(ftdi, roothub.a, &rh_a);
2336 if (retval)
2337 return retval;
2338 num_ports = rh_a & RH_A_NDP;
2339 retval = ftdi_read_pcimem(ftdi, fminterval, &hc_fminterval);
2340 if (retval)
2341 return retval;
2342 hc_fminterval &= 0x3fff;
2343 if (hc_fminterval != FI) {
2344 }
2345 hc_fminterval |= FSMP(hc_fminterval) << 16;
2346 retval = ftdi_read_pcimem(ftdi, control, &hc_control);
2347 if (retval)
2348 return retval;
2349 switch (hc_control & OHCI_CTRL_HCFS) {
2350 case OHCI_USB_OPER:
2351 sleep_time = 0;
2352 break;
2353 case OHCI_USB_SUSPEND:
2354 case OHCI_USB_RESUME:
2355 hc_control &= OHCI_CTRL_RWC;
2356 hc_control |= OHCI_USB_RESUME;
2357 sleep_time = 10;
2358 break;
2359 default:
2360 hc_control &= OHCI_CTRL_RWC;
2361 hc_control |= OHCI_USB_RESET;
2362 sleep_time = 50;
2363 break;
2364 }
2365 retval = ftdi_write_pcimem(ftdi, control, hc_control);
2366 if (retval)
2367 return retval;
2368 retval = ftdi_read_pcimem(ftdi, control, &control);
2369 if (retval)
2370 return retval;
2371 msleep(sleep_time);
2372 retval = ftdi_read_pcimem(ftdi, roothub.a, &roothub_a);
2373 if (retval)
2374 return retval;
2375 if (!(roothub_a & RH_A_NPS)) { /* power down each port */
2376 for (temp = 0; temp < num_ports; temp++) {
2377 retval = ftdi_write_pcimem(ftdi,
2378 roothub.portstatus[temp], RH_PS_LSDA);
2379 if (retval)
2380 return retval;
2381 }
2382 }
2383 retval = ftdi_read_pcimem(ftdi, control, &control);
2384 if (retval)
2385 return retval;
2386 retry:retval = ftdi_read_pcimem(ftdi, cmdstatus, &status);
2387 if (retval)
2388 return retval;
2389 retval = ftdi_write_pcimem(ftdi, cmdstatus, OHCI_HCR);
2390 if (retval)
2391 return retval;
2392 extra:{
2393 retval = ftdi_read_pcimem(ftdi, cmdstatus, &status);
2394 if (retval)
2395 return retval;
2396 if (0 != (status & OHCI_HCR)) {
2397 if (--reset_timeout == 0) {
2398 dev_err(&ftdi->udev->dev, "USB HC reset timed o"
2399 "ut!\n");
2400 return -ENODEV;
2401 } else {
2402 msleep(5);
2403 goto extra;
2404 }
2405 }
2406 }
2407 if (quirk & OHCI_QUIRK_INITRESET) {
2408 retval = ftdi_write_pcimem(ftdi, control, hc_control);
2409 if (retval)
2410 return retval;
2411 retval = ftdi_read_pcimem(ftdi, control, &control);
2412 if (retval)
2413 return retval;
2414 }
2415 retval = ftdi_write_pcimem(ftdi, ed_controlhead, 0x00000000);
2416 if (retval)
2417 return retval;
2418 retval = ftdi_write_pcimem(ftdi, ed_bulkhead, 0x11000000);
2419 if (retval)
2420 return retval;
2421 retval = ftdi_write_pcimem(ftdi, hcca, 0x00000000);
2422 if (retval)
2423 return retval;
2424 retval = ftdi_read_pcimem(ftdi, fminterval, &fminterval);
2425 if (retval)
2426 return retval;
2427 retval = ftdi_write_pcimem(ftdi, fminterval,
2428 ((fminterval & FIT) ^ FIT) | hc_fminterval);
2429 if (retval)
2430 return retval;
2431 retval = ftdi_write_pcimem(ftdi, periodicstart,
2432 ((9 *hc_fminterval) / 10) & 0x3fff);
2433 if (retval)
2434 return retval;
2435 retval = ftdi_read_pcimem(ftdi, fminterval, &fminterval);
2436 if (retval)
2437 return retval;
2438 retval = ftdi_read_pcimem(ftdi, periodicstart, &periodicstart);
2439 if (retval)
2440 return retval;
2441 if (0 == (fminterval & 0x3fff0000) || 0 == periodicstart) {
2442 if (!(quirk & OHCI_QUIRK_INITRESET)) {
2443 quirk |= OHCI_QUIRK_INITRESET;
2444 goto retry;
2445 } else
2446 dev_err(&ftdi->udev->dev, "init err(%08x %04x)\n",
2447 fminterval, periodicstart);
2448 } /* start controller operations */
2449 hc_control &= OHCI_CTRL_RWC;
2450 hc_control |= OHCI_CONTROL_INIT | OHCI_CTRL_BLE | OHCI_USB_OPER;
2451 retval = ftdi_write_pcimem(ftdi, control, hc_control);
2452 if (retval)
2453 return retval;
2454 retval = ftdi_write_pcimem(ftdi, cmdstatus, OHCI_BLF);
2455 if (retval)
2456 return retval;
2457 retval = ftdi_read_pcimem(ftdi, cmdstatus, &cmdstatus);
2458 if (retval)
2459 return retval;
2460 retval = ftdi_read_pcimem(ftdi, control, &control);
2461 if (retval)
2462 return retval;
2463 retval = ftdi_write_pcimem(ftdi, roothub.status, RH_HS_DRWE);
2464 if (retval)
2465 return retval;
2466 retval = ftdi_write_pcimem(ftdi, intrstatus, mask);
2467 if (retval)
2468 return retval;
2469 retval = ftdi_write_pcimem(ftdi, intrdisable,
2470 OHCI_INTR_MIE | OHCI_INTR_OC | OHCI_INTR_RHSC | OHCI_INTR_FNO |
2471 OHCI_INTR_UE | OHCI_INTR_RD | OHCI_INTR_SF | OHCI_INTR_WDH |
2472 OHCI_INTR_SO);
2473 if (retval)
2474 return retval; /* handle root hub init quirks ... */
2475 retval = ftdi_read_pcimem(ftdi, roothub.a, &roothub_a);
2476 if (retval)
2477 return retval;
2478 roothub_a &= ~(RH_A_PSM | RH_A_OCPM);
2479 if (quirk & OHCI_QUIRK_SUPERIO) {
2480 roothub_a |= RH_A_NOCP;
2481 roothub_a &= ~(RH_A_POTPGT | RH_A_NPS);
2482 retval = ftdi_write_pcimem(ftdi, roothub.a, roothub_a);
2483 if (retval)
2484 return retval;
2485 } else if ((quirk & OHCI_QUIRK_AMD756) || distrust_firmware) {
2486 roothub_a |= RH_A_NPS;
2487 retval = ftdi_write_pcimem(ftdi, roothub.a, roothub_a);
2488 if (retval)
2489 return retval;
2490 }
2491 retval = ftdi_write_pcimem(ftdi, roothub.status, RH_HS_LPSC);
2492 if (retval)
2493 return retval;
2494 retval = ftdi_write_pcimem(ftdi, roothub.b,
2495 (roothub_a & RH_A_NPS) ? 0 : RH_B_PPCM);
2496 if (retval)
2497 return retval;
2498 retval = ftdi_read_pcimem(ftdi, control, &control);
2499 if (retval)
2500 return retval;
2501 mdelay((roothub_a >> 23) & 0x1fe);
2502 for (temp = 0; temp < num_ports; temp++) {
2503 u32 portstatus;
2504 retval = ftdi_read_pcimem(ftdi, roothub.portstatus[temp],
2505 &portstatus);
2506 if (retval)
2507 return retval;
2508 if (1 & portstatus)
2509 devices += 1;
2510 }
2511 return devices;
2512}
2513
2514static int ftdi_elan_setup_controller(struct usb_ftdi *ftdi, int fn)
2292{ 2515{
2293 u32 latence_timer; 2516 u32 latence_timer;
2294 u32 controlreg;
2295 int UxxxStatus; 2517 int UxxxStatus;
2296 u32 pcidata; 2518 u32 pcidata;
2297 int reg = 0; 2519 int reg = 0;
2298 int foundOHCI = 0; 2520 int activePCIfn = fn << 8;
2299 u8 fn; 2521 UxxxStatus = ftdi_elan_write_reg(ftdi, 0x0000025FL | 0x2800);
2300 int activePCIfn = 0;
2301 u32 pciVID = 0;
2302 u32 pciPID = 0;
2303 UxxxStatus = ftdi_elan_read_reg(ftdi, &controlreg);
2304 if (UxxxStatus)
2305 return UxxxStatus;
2306 UxxxStatus = ftdi_elan_write_reg(ftdi, 0x00000000L);
2307 if (UxxxStatus)
2308 return UxxxStatus;
2309 msleep(750);
2310 UxxxStatus = ftdi_elan_write_reg(ftdi, 0x00000200L | 0x100);
2311 if (UxxxStatus) 2522 if (UxxxStatus)
2312 return UxxxStatus; 2523 return UxxxStatus;
2313 UxxxStatus = ftdi_elan_write_reg(ftdi, 0x00000200L | 0x500); 2524 reg = 16;
2525 UxxxStatus = ftdi_elan_write_config(ftdi, activePCIfn | reg, 0,
2526 0xFFFFFFFF);
2314 if (UxxxStatus) 2527 if (UxxxStatus)
2315 return UxxxStatus; 2528 return UxxxStatus;
2316 UxxxStatus = ftdi_elan_read_reg(ftdi, &controlreg); 2529 UxxxStatus = ftdi_elan_read_config(ftdi, activePCIfn | reg, 0,
2530 &pcidata);
2317 if (UxxxStatus) 2531 if (UxxxStatus)
2318 return UxxxStatus; 2532 return UxxxStatus;
2319 UxxxStatus = ftdi_elan_write_reg(ftdi, 0x0000020CL | 0x000); 2533 UxxxStatus = ftdi_elan_write_config(ftdi, activePCIfn | reg, 0,
2534 0xF0000000);
2320 if (UxxxStatus) 2535 if (UxxxStatus)
2321 return UxxxStatus; 2536 return UxxxStatus;
2322 UxxxStatus = ftdi_elan_write_reg(ftdi, 0x0000020DL | 0x000); 2537 UxxxStatus = ftdi_elan_read_config(ftdi, activePCIfn | reg, 0,
2538 &pcidata);
2323 if (UxxxStatus) 2539 if (UxxxStatus)
2324 return UxxxStatus; 2540 return UxxxStatus;
2325 msleep(250); 2541 reg = 12;
2326 UxxxStatus = ftdi_elan_write_reg(ftdi, 0x0000020FL | 0x000); 2542 UxxxStatus = ftdi_elan_read_config(ftdi, activePCIfn | reg, 0,
2543 &latence_timer);
2327 if (UxxxStatus) 2544 if (UxxxStatus)
2328 return UxxxStatus; 2545 return UxxxStatus;
2329 UxxxStatus = ftdi_elan_read_reg(ftdi, &controlreg); 2546 latence_timer &= 0xFFFF00FF;
2547 latence_timer |= 0x00001600;
2548 UxxxStatus = ftdi_elan_write_config(ftdi, activePCIfn | reg, 0x00,
2549 latence_timer);
2330 if (UxxxStatus) 2550 if (UxxxStatus)
2331 return UxxxStatus; 2551 return UxxxStatus;
2332 UxxxStatus = ftdi_elan_write_reg(ftdi, 0x0000025FL | 0x800); 2552 UxxxStatus = ftdi_elan_read_config(ftdi, activePCIfn | reg, 0,
2553 &pcidata);
2333 if (UxxxStatus) 2554 if (UxxxStatus)
2334 return UxxxStatus; 2555 return UxxxStatus;
2335 UxxxStatus = ftdi_elan_read_reg(ftdi, &controlreg); 2556 reg = 4;
2557 UxxxStatus = ftdi_elan_write_config(ftdi, activePCIfn | reg, 0x00,
2558 0x06);
2336 if (UxxxStatus) 2559 if (UxxxStatus)
2337 return UxxxStatus; 2560 return UxxxStatus;
2338 UxxxStatus = ftdi_elan_read_reg(ftdi, &controlreg); 2561 UxxxStatus = ftdi_elan_read_config(ftdi, activePCIfn | reg, 0,
2562 &pcidata);
2339 if (UxxxStatus) 2563 if (UxxxStatus)
2340 return UxxxStatus; 2564 return UxxxStatus;
2341 msleep(1000); 2565 for (reg = 0; reg <= 0x54; reg += 4) {
2342 for (fn = 0; (fn < 4) && (!foundOHCI); fn++) { 2566 UxxxStatus = ftdi_elan_read_pcimem(ftdi, reg, 0, &pcidata);
2343 activePCIfn = fn << 8;
2344 ftdi->function = fn + 1;
2345 UxxxStatus = ftdi_elan_read_config(ftdi, activePCIfn | reg, 0,
2346 &pcidata);
2347 if (UxxxStatus) 2567 if (UxxxStatus)
2348 return UxxxStatus; 2568 return UxxxStatus;
2349 pciVID = pcidata & 0xFFFF;
2350 pciPID = (pcidata >> 16) & 0xFFFF;
2351 if ((pciVID == 0x1045) && (pciPID == 0xc861)) {
2352 foundOHCI = 1;
2353 } else if ((pciVID == 0x1033) && (pciPID == 0x0035)) {
2354 foundOHCI = 1;
2355 } else if ((pciVID == 0x10b9) && (pciPID == 0x5237)) {
2356 foundOHCI = 1;
2357 } else if ((pciVID == 0x11c1) && (pciPID == 0x5802)) {
2358 foundOHCI = 1;
2359 } else if ((pciVID == 0x11AB) && (pciPID == 0x1FA6)) {
2360 }
2361 }
2362 if (foundOHCI == 0) {
2363 return -ENXIO;
2364 } 2569 }
2365 ftdi->platform_data.vendor = pciVID; 2570 return 0;
2366 ftdi->platform_data.device = pciPID; 2571}
2572
2573static int ftdi_elan_close_controller(struct usb_ftdi *ftdi, int fn)
2574{
2575 u32 latence_timer;
2576 int UxxxStatus;
2577 u32 pcidata;
2578 int reg = 0;
2579 int activePCIfn = fn << 8;
2367 UxxxStatus = ftdi_elan_write_reg(ftdi, 0x0000025FL | 0x2800); 2580 UxxxStatus = ftdi_elan_write_reg(ftdi, 0x0000025FL | 0x2800);
2368 if (UxxxStatus) 2581 if (UxxxStatus)
2369 return UxxxStatus; 2582 return UxxxStatus;
@@ -2377,7 +2590,7 @@ static int ftdi_elan_enumeratePCI(struct usb_ftdi *ftdi)
2377 if (UxxxStatus) 2590 if (UxxxStatus)
2378 return UxxxStatus; 2591 return UxxxStatus;
2379 UxxxStatus = ftdi_elan_write_config(ftdi, activePCIfn | reg, 0, 2592 UxxxStatus = ftdi_elan_write_config(ftdi, activePCIfn | reg, 0,
2380 0xF0000000); 2593 0x00000000);
2381 if (UxxxStatus) 2594 if (UxxxStatus)
2382 return UxxxStatus; 2595 return UxxxStatus;
2383 UxxxStatus = ftdi_elan_read_config(ftdi, activePCIfn | reg, 0, 2596 UxxxStatus = ftdi_elan_read_config(ftdi, activePCIfn | reg, 0,
@@ -2401,7 +2614,7 @@ static int ftdi_elan_enumeratePCI(struct usb_ftdi *ftdi)
2401 return UxxxStatus; 2614 return UxxxStatus;
2402 reg = 4; 2615 reg = 4;
2403 UxxxStatus = ftdi_elan_write_config(ftdi, activePCIfn | reg, 0x00, 2616 UxxxStatus = ftdi_elan_write_config(ftdi, activePCIfn | reg, 0x00,
2404 0x06); 2617 0x00);
2405 if (UxxxStatus) 2618 if (UxxxStatus)
2406 return UxxxStatus; 2619 return UxxxStatus;
2407 UxxxStatus = ftdi_elan_read_config(ftdi, activePCIfn | reg, 0, 2620 UxxxStatus = ftdi_elan_read_config(ftdi, activePCIfn | reg, 0,
@@ -2411,159 +2624,139 @@ static int ftdi_elan_enumeratePCI(struct usb_ftdi *ftdi)
2411 return 0; 2624 return 0;
2412} 2625}
2413 2626
2627static int ftdi_elan_found_controller(struct usb_ftdi *ftdi, int fn, int quirk)
2628{
2629 int result;
2630 int UxxxStatus;
2631 UxxxStatus = ftdi_elan_setup_controller(ftdi, fn);
2632 if (UxxxStatus)
2633 return UxxxStatus;
2634 result = ftdi_elan_check_controller(ftdi, quirk);
2635 UxxxStatus = ftdi_elan_close_controller(ftdi, fn);
2636 if (UxxxStatus)
2637 return UxxxStatus;
2638 return result;
2639}
2640
2641static int ftdi_elan_enumeratePCI(struct usb_ftdi *ftdi)
2642{
2643 u32 controlreg;
2644 u8 sensebits;
2645 int UxxxStatus;
2646 UxxxStatus = ftdi_elan_read_reg(ftdi, &controlreg);
2647 if (UxxxStatus)
2648 return UxxxStatus;
2649 UxxxStatus = ftdi_elan_write_reg(ftdi, 0x00000000L);
2650 if (UxxxStatus)
2651 return UxxxStatus;
2652 msleep(750);
2653 UxxxStatus = ftdi_elan_write_reg(ftdi, 0x00000200L | 0x100);
2654 if (UxxxStatus)
2655 return UxxxStatus;
2656 UxxxStatus = ftdi_elan_write_reg(ftdi, 0x00000200L | 0x500);
2657 if (UxxxStatus)
2658 return UxxxStatus;
2659 UxxxStatus = ftdi_elan_read_reg(ftdi, &controlreg);
2660 if (UxxxStatus)
2661 return UxxxStatus;
2662 UxxxStatus = ftdi_elan_write_reg(ftdi, 0x0000020CL | 0x000);
2663 if (UxxxStatus)
2664 return UxxxStatus;
2665 UxxxStatus = ftdi_elan_write_reg(ftdi, 0x0000020DL | 0x000);
2666 if (UxxxStatus)
2667 return UxxxStatus;
2668 msleep(250);
2669 UxxxStatus = ftdi_elan_write_reg(ftdi, 0x0000020FL | 0x000);
2670 if (UxxxStatus)
2671 return UxxxStatus;
2672 UxxxStatus = ftdi_elan_read_reg(ftdi, &controlreg);
2673 if (UxxxStatus)
2674 return UxxxStatus;
2675 UxxxStatus = ftdi_elan_write_reg(ftdi, 0x0000025FL | 0x800);
2676 if (UxxxStatus)
2677 return UxxxStatus;
2678 UxxxStatus = ftdi_elan_read_reg(ftdi, &controlreg);
2679 if (UxxxStatus)
2680 return UxxxStatus;
2681 UxxxStatus = ftdi_elan_read_reg(ftdi, &controlreg);
2682 if (UxxxStatus)
2683 return UxxxStatus;
2684 msleep(1000);
2685 sensebits = (controlreg >> 16) & 0x000F;
2686 if (0x0D == sensebits)
2687 return 0;
2688 else
2689 return - ENXIO;
2690}
2691
2414static int ftdi_elan_setupOHCI(struct usb_ftdi *ftdi) 2692static int ftdi_elan_setupOHCI(struct usb_ftdi *ftdi)
2415{ 2693{
2694 int UxxxStatus;
2416 u32 pcidata; 2695 u32 pcidata;
2417 int U132Status; 2696 int reg = 0;
2418 int reg; 2697 u8 fn;
2419 int reset_repeat = 0; 2698 int activePCIfn = 0;
2420 do_reset:reg = 8; 2699 int max_devices = 0;
2421 U132Status = ftdi_elan_write_pcimem(ftdi, reg, 0x0e, 0x01); 2700 int controllers = 0;
2422 if (U132Status) 2701 int unrecognized = 0;
2423 return U132Status; 2702 ftdi->function = 0;
2424 reset_check:{ 2703 for (fn = 0; (fn < 4); fn++) {
2425 U132Status = ftdi_elan_read_pcimem(ftdi, reg, 0, &pcidata); 2704 u32 pciVID = 0;
2426 if (U132Status) 2705 u32 pciPID = 0;
2427 return U132Status; 2706 int devices = 0;
2428 if (pcidata & 1) { 2707 activePCIfn = fn << 8;
2429 msleep(500); 2708 UxxxStatus = ftdi_elan_read_config(ftdi, activePCIfn | reg, 0,
2430 if (reset_repeat++ > 100) { 2709 &pcidata);
2431 reset_repeat = 0; 2710 if (UxxxStatus)
2432 goto do_reset; 2711 return UxxxStatus;
2433 } else 2712 pciVID = pcidata & 0xFFFF;
2434 goto reset_check; 2713 pciPID = (pcidata >> 16) & 0xFFFF;
2714 if ((pciVID == PCI_VENDOR_ID_OPTI) && (pciPID == 0xc861)) {
2715 devices = ftdi_elan_found_controller(ftdi, fn, 0);
2716 controllers += 1;
2717 } else if ((pciVID == PCI_VENDOR_ID_NEC) && (pciPID == 0x0035))
2718 {
2719 devices = ftdi_elan_found_controller(ftdi, fn, 0);
2720 controllers += 1;
2721 } else if ((pciVID == PCI_VENDOR_ID_AL) && (pciPID == 0x5237)) {
2722 devices = ftdi_elan_found_controller(ftdi, fn, 0);
2723 controllers += 1;
2724 } else if ((pciVID == PCI_VENDOR_ID_ATT) && (pciPID == 0x5802))
2725 {
2726 devices = ftdi_elan_found_controller(ftdi, fn, 0);
2727 controllers += 1;
2728 } else if (pciVID == PCI_VENDOR_ID_AMD && pciPID == 0x740c) {
2729 devices = ftdi_elan_found_controller(ftdi, fn,
2730 OHCI_QUIRK_AMD756);
2731 controllers += 1;
2732 } else if (pciVID == PCI_VENDOR_ID_COMPAQ && pciPID == 0xa0f8) {
2733 devices = ftdi_elan_found_controller(ftdi, fn,
2734 OHCI_QUIRK_ZFMICRO);
2735 controllers += 1;
2736 } else if (0 == pcidata) {
2737 } else
2738 unrecognized += 1;
2739 if (devices > max_devices) {
2740 max_devices = devices;
2741 ftdi->function = fn + 1;
2742 ftdi->platform_data.vendor = pciVID;
2743 ftdi->platform_data.device = pciPID;
2435 } 2744 }
2436 } 2745 }
2437 goto dump_regs; 2746 if (ftdi->function > 0) {
2438 msleep(500); 2747 UxxxStatus = ftdi_elan_setup_controller(ftdi,
2439 reg = 0x28; 2748 ftdi->function - 1);
2440 U132Status = ftdi_elan_write_pcimem(ftdi, reg, 0x00, 0x11000000); 2749 if (UxxxStatus)
2441 if (U132Status) 2750 return UxxxStatus;
2442 return U132Status; 2751 return 0;
2443 U132Status = ftdi_elan_read_pcimem(ftdi, reg, 0, &pcidata); 2752 } else if (controllers > 0) {
2444 if (U132Status) 2753 return -ENXIO;
2445 return U132Status; 2754 } else if (unrecognized > 0) {
2446 reg = 0x40; 2755 return -ENXIO;
2447 U132Status = ftdi_elan_write_pcimem(ftdi, reg, 0x00, 0x2edf); 2756 } else {
2448 if (U132Status) 2757 ftdi->enumerated = 0;
2449 return U132Status; 2758 return -ENXIO;
2450 U132Status = ftdi_elan_read_pcimem(ftdi, reg, 0, &pcidata);
2451 if (U132Status)
2452 return U132Status;
2453 reg = 0x34;
2454 U132Status = ftdi_elan_write_pcimem(ftdi, reg, 0x00, 0x2edf2edf);
2455 if (U132Status)
2456 return U132Status;
2457 U132Status = ftdi_elan_read_pcimem(ftdi, reg, 0, &pcidata);
2458 if (U132Status)
2459 return U132Status;
2460 reg = 4;
2461 U132Status = ftdi_elan_write_pcimem(ftdi, reg, 0x00, 0xA0);
2462 if (U132Status)
2463 return U132Status;
2464 U132Status = ftdi_elan_read_pcimem(ftdi, reg, 0, &pcidata);
2465 if (U132Status)
2466 return U132Status;
2467 msleep(250);
2468 reg = 8;
2469 U132Status = ftdi_elan_write_pcimem(ftdi, reg, 0x0e, 0x04);
2470 if (U132Status)
2471 return U132Status;
2472 U132Status = ftdi_elan_read_pcimem(ftdi, reg, 0, &pcidata);
2473 if (U132Status)
2474 return U132Status;
2475 reg = 0x28;
2476 U132Status = ftdi_elan_read_pcimem(ftdi, reg, 0, &pcidata);
2477 if (U132Status)
2478 return U132Status;
2479 reg = 8;
2480 U132Status = ftdi_elan_read_pcimem(ftdi, reg, 0, &pcidata);
2481 if (U132Status)
2482 return U132Status;
2483 reg = 0x48;
2484 U132Status = ftdi_elan_write_pcimem(ftdi, reg, 0x00, 0x00001200);
2485 if (U132Status)
2486 return U132Status;
2487 U132Status = ftdi_elan_read_pcimem(ftdi, reg, 0, &pcidata);
2488 if (U132Status)
2489 return U132Status;
2490 reg = 0x54;
2491 U132Status = ftdi_elan_read_pcimem(ftdi, reg, 0, &pcidata);
2492 if (U132Status)
2493 return U132Status;
2494 reg = 0x58;
2495 U132Status = ftdi_elan_read_pcimem(ftdi, reg, 0, &pcidata);
2496 if (U132Status)
2497 return U132Status;
2498 reg = 0x34;
2499 U132Status = ftdi_elan_write_pcimem(ftdi, reg, 0x00, 0x28002edf);
2500 if (U132Status)
2501 return U132Status;
2502 U132Status = ftdi_elan_read_pcimem(ftdi, reg, 0, &pcidata);
2503 if (U132Status)
2504 return U132Status;
2505 msleep(100);
2506 reg = 0x50;
2507 U132Status = ftdi_elan_write_pcimem(ftdi, reg, 0x00, 0x10000);
2508 if (U132Status)
2509 return U132Status;
2510 reg = 0x54;
2511 power_check:U132Status = ftdi_elan_read_pcimem(ftdi, reg, 0, &pcidata);
2512 if (U132Status)
2513 return U132Status;
2514 if (!(pcidata & 1)) {
2515 msleep(500);
2516 goto power_check;
2517 }
2518 msleep(3000);
2519 reg = 0x54;
2520 U132Status = ftdi_elan_read_pcimem(ftdi, reg, 0, &pcidata);
2521 if (U132Status)
2522 return U132Status;
2523 reg = 0x58;
2524 U132Status = ftdi_elan_read_pcimem(ftdi, reg, 0, &pcidata);
2525 if (U132Status)
2526 return U132Status;
2527 reg = 0x54;
2528 U132Status = ftdi_elan_write_pcimem(ftdi, reg, 0x00, 0x02);
2529 if (U132Status)
2530 return U132Status;
2531 U132Status = ftdi_elan_read_pcimem(ftdi, reg, 0, &pcidata);
2532 if (U132Status)
2533 return U132Status;
2534 reg = 0x54;
2535 U132Status = ftdi_elan_write_pcimem(ftdi, reg, 0x00, 0x10);
2536 if (U132Status)
2537 return U132Status;
2538 U132Status = ftdi_elan_read_pcimem(ftdi, reg, 0, &pcidata);
2539 if (U132Status)
2540 return U132Status;
2541 msleep(750);
2542 reg = 0x54;
2543 if (0) {
2544 U132Status = ftdi_elan_write_pcimem(ftdi, reg, 0x00, 0x02);
2545 if (U132Status)
2546 return U132Status;
2547 }
2548 if (0) {
2549 U132Status = ftdi_elan_read_pcimem(ftdi, reg, 0, &pcidata);
2550 if (U132Status)
2551 return U132Status;
2552 }
2553 reg = 0x54;
2554 U132Status = ftdi_elan_read_pcimem(ftdi, reg, 0, &pcidata);
2555 if (U132Status)
2556 return U132Status;
2557 reg = 0x58;
2558 U132Status = ftdi_elan_read_pcimem(ftdi, reg, 0, &pcidata);
2559 if (U132Status)
2560 return U132Status;
2561 dump_regs:for (reg = 0; reg <= 0x54; reg += 4) {
2562 U132Status = ftdi_elan_read_pcimem(ftdi, reg, 0, &pcidata);
2563 if (U132Status)
2564 return U132Status;
2565 } 2759 }
2566 return 0;
2567} 2760}
2568 2761
2569 2762
@@ -2688,6 +2881,7 @@ static void ftdi_elan_disconnect(struct usb_interface *interface)
2688 platform_device_unregister(&ftdi->platform_dev); 2881 platform_device_unregister(&ftdi->platform_dev);
2689 ftdi->synchronized = 0; 2882 ftdi->synchronized = 0;
2690 ftdi->enumerated = 0; 2883 ftdi->enumerated = 0;
2884 ftdi->initialized = 0;
2691 ftdi->registered = 0; 2885 ftdi->registered = 0;
2692 } 2886 }
2693 flush_workqueue(status_queue); 2887 flush_workqueue(status_queue);