diff options
Diffstat (limited to 'drivers/usb/host/ohci-pci.c')
-rw-r--r-- | drivers/usb/host/ohci-pci.c | 219 |
1 files changed, 136 insertions, 83 deletions
diff --git a/drivers/usb/host/ohci-pci.c b/drivers/usb/host/ohci-pci.c index 596e0b41e606..b331ac4d0d62 100644 --- a/drivers/usb/host/ohci-pci.c +++ b/drivers/usb/host/ohci-pci.c | |||
@@ -20,79 +20,154 @@ | |||
20 | 20 | ||
21 | /*-------------------------------------------------------------------------*/ | 21 | /*-------------------------------------------------------------------------*/ |
22 | 22 | ||
23 | static int | 23 | /* AMD 756, for most chips (early revs), corrupts register |
24 | ohci_pci_reset (struct usb_hcd *hcd) | 24 | * values on read ... so enable the vendor workaround. |
25 | */ | ||
26 | static int __devinit ohci_quirk_amd756(struct usb_hcd *hcd) | ||
25 | { | 27 | { |
26 | struct ohci_hcd *ohci = hcd_to_ohci (hcd); | 28 | struct ohci_hcd *ohci = hcd_to_ohci (hcd); |
27 | 29 | ||
28 | ohci_hcd_init (ohci); | 30 | ohci->flags = OHCI_QUIRK_AMD756; |
29 | return ohci_init (ohci); | 31 | ohci_dbg (ohci, "AMD756 erratum 4 workaround\n"); |
32 | |||
33 | /* also erratum 10 (suspend/resume issues) */ | ||
34 | device_init_wakeup(&hcd->self.root_hub->dev, 0); | ||
35 | |||
36 | return 0; | ||
30 | } | 37 | } |
31 | 38 | ||
32 | static int __devinit | 39 | /* Apple's OHCI driver has a lot of bizarre workarounds |
33 | ohci_pci_start (struct usb_hcd *hcd) | 40 | * for this chip. Evidently control and bulk lists |
41 | * can get confused. (B&W G3 models, and ...) | ||
42 | */ | ||
43 | static int __devinit ohci_quirk_opti(struct usb_hcd *hcd) | ||
34 | { | 44 | { |
35 | struct ohci_hcd *ohci = hcd_to_ohci (hcd); | 45 | struct ohci_hcd *ohci = hcd_to_ohci (hcd); |
36 | int ret; | ||
37 | 46 | ||
38 | /* REVISIT this whole block should move to reset(), which handles | 47 | ohci_dbg (ohci, "WARNING: OPTi workarounds unavailable\n"); |
39 | * all the other one-time init. | 48 | |
49 | return 0; | ||
50 | } | ||
51 | |||
52 | /* Check for NSC87560. We have to look at the bridge (fn1) to | ||
53 | * identify the USB (fn2). This quirk might apply to more or | ||
54 | * even all NSC stuff. | ||
55 | */ | ||
56 | static int __devinit ohci_quirk_ns(struct usb_hcd *hcd) | ||
57 | { | ||
58 | struct pci_dev *pdev = to_pci_dev(hcd->self.controller); | ||
59 | struct pci_dev *b; | ||
60 | |||
61 | b = pci_get_slot (pdev->bus, PCI_DEVFN (PCI_SLOT (pdev->devfn), 1)); | ||
62 | if (b && b->device == PCI_DEVICE_ID_NS_87560_LIO | ||
63 | && b->vendor == PCI_VENDOR_ID_NS) { | ||
64 | struct ohci_hcd *ohci = hcd_to_ohci (hcd); | ||
65 | |||
66 | ohci->flags |= OHCI_QUIRK_SUPERIO; | ||
67 | ohci_dbg (ohci, "Using NSC SuperIO setup\n"); | ||
68 | } | ||
69 | pci_dev_put(b); | ||
70 | |||
71 | return 0; | ||
72 | } | ||
73 | |||
74 | /* Check for Compaq's ZFMicro chipset, which needs short | ||
75 | * delays before control or bulk queues get re-activated | ||
76 | * in finish_unlinks() | ||
77 | */ | ||
78 | static int __devinit ohci_quirk_zfmicro(struct usb_hcd *hcd) | ||
79 | { | ||
80 | struct ohci_hcd *ohci = hcd_to_ohci (hcd); | ||
81 | |||
82 | ohci->flags |= OHCI_QUIRK_ZFMICRO; | ||
83 | ohci_dbg (ohci, "enabled Compaq ZFMicro chipset quirk\n"); | ||
84 | |||
85 | return 0; | ||
86 | } | ||
87 | |||
88 | /* Check for Toshiba SCC OHCI which has big endian registers | ||
89 | * and little endian in memory data structures | ||
90 | */ | ||
91 | static int __devinit ohci_quirk_toshiba_scc(struct usb_hcd *hcd) | ||
92 | { | ||
93 | struct ohci_hcd *ohci = hcd_to_ohci (hcd); | ||
94 | |||
95 | /* That chip is only present in the southbridge of some | ||
96 | * cell based platforms which are supposed to select | ||
97 | * CONFIG_USB_OHCI_BIG_ENDIAN_MMIO. We verify here if | ||
98 | * that was the case though. | ||
99 | */ | ||
100 | #ifdef CONFIG_USB_OHCI_BIG_ENDIAN_MMIO | ||
101 | ohci->flags |= OHCI_QUIRK_BE_MMIO; | ||
102 | ohci_dbg (ohci, "enabled big endian Toshiba quirk\n"); | ||
103 | return 0; | ||
104 | #else | ||
105 | ohci_err (ohci, "unsupported big endian Toshiba quirk\n"); | ||
106 | return -ENXIO; | ||
107 | #endif | ||
108 | } | ||
109 | |||
110 | /* List of quirks for OHCI */ | ||
111 | static const struct pci_device_id ohci_pci_quirks[] = { | ||
112 | { | ||
113 | PCI_DEVICE(PCI_VENDOR_ID_AMD, 0x740c), | ||
114 | .driver_data = (unsigned long)ohci_quirk_amd756, | ||
115 | }, | ||
116 | { | ||
117 | PCI_DEVICE(PCI_VENDOR_ID_OPTI, 0xc861), | ||
118 | .driver_data = (unsigned long)ohci_quirk_opti, | ||
119 | }, | ||
120 | { | ||
121 | PCI_DEVICE(PCI_VENDOR_ID_NS, PCI_ANY_ID), | ||
122 | .driver_data = (unsigned long)ohci_quirk_ns, | ||
123 | }, | ||
124 | { | ||
125 | PCI_DEVICE(PCI_VENDOR_ID_COMPAQ, 0xa0f8), | ||
126 | .driver_data = (unsigned long)ohci_quirk_zfmicro, | ||
127 | }, | ||
128 | { | ||
129 | PCI_DEVICE(PCI_VENDOR_ID_TOSHIBA_2, 0x01b6), | ||
130 | .driver_data = (unsigned long)ohci_quirk_toshiba_scc, | ||
131 | }, | ||
132 | /* FIXME for some of the early AMD 760 southbridges, OHCI | ||
133 | * won't work at all. blacklist them. | ||
40 | */ | 134 | */ |
135 | |||
136 | {}, | ||
137 | }; | ||
138 | |||
139 | static int ohci_pci_reset (struct usb_hcd *hcd) | ||
140 | { | ||
141 | struct ohci_hcd *ohci = hcd_to_ohci (hcd); | ||
142 | int ret = 0; | ||
143 | |||
41 | if (hcd->self.controller) { | 144 | if (hcd->self.controller) { |
42 | struct pci_dev *pdev = to_pci_dev(hcd->self.controller); | 145 | struct pci_dev *pdev = to_pci_dev(hcd->self.controller); |
146 | const struct pci_device_id *quirk_id; | ||
43 | 147 | ||
44 | /* AMD 756, for most chips (early revs), corrupts register | 148 | quirk_id = pci_match_id(ohci_pci_quirks, pdev); |
45 | * values on read ... so enable the vendor workaround. | 149 | if (quirk_id != NULL) { |
46 | */ | 150 | int (*quirk)(struct usb_hcd *ohci); |
47 | if (pdev->vendor == PCI_VENDOR_ID_AMD | 151 | quirk = (void *)quirk_id->driver_data; |
48 | && pdev->device == 0x740c) { | 152 | ret = quirk(hcd); |
49 | ohci->flags = OHCI_QUIRK_AMD756; | ||
50 | ohci_dbg (ohci, "AMD756 erratum 4 workaround\n"); | ||
51 | /* also erratum 10 (suspend/resume issues) */ | ||
52 | device_init_wakeup(&hcd->self.root_hub->dev, 0); | ||
53 | } | 153 | } |
154 | } | ||
155 | if (ret == 0) { | ||
156 | ohci_hcd_init (ohci); | ||
157 | return ohci_init (ohci); | ||
158 | } | ||
159 | return ret; | ||
160 | } | ||
54 | 161 | ||
55 | /* FIXME for some of the early AMD 760 southbridges, OHCI | ||
56 | * won't work at all. blacklist them. | ||
57 | */ | ||
58 | |||
59 | /* Apple's OHCI driver has a lot of bizarre workarounds | ||
60 | * for this chip. Evidently control and bulk lists | ||
61 | * can get confused. (B&W G3 models, and ...) | ||
62 | */ | ||
63 | else if (pdev->vendor == PCI_VENDOR_ID_OPTI | ||
64 | && pdev->device == 0xc861) { | ||
65 | ohci_dbg (ohci, | ||
66 | "WARNING: OPTi workarounds unavailable\n"); | ||
67 | } | ||
68 | 162 | ||
69 | /* Check for NSC87560. We have to look at the bridge (fn1) to | 163 | static int __devinit ohci_pci_start (struct usb_hcd *hcd) |
70 | * identify the USB (fn2). This quirk might apply to more or | 164 | { |
71 | * even all NSC stuff. | 165 | struct ohci_hcd *ohci = hcd_to_ohci (hcd); |
72 | */ | 166 | int ret; |
73 | else if (pdev->vendor == PCI_VENDOR_ID_NS) { | ||
74 | struct pci_dev *b; | ||
75 | |||
76 | b = pci_get_slot (pdev->bus, | ||
77 | PCI_DEVFN (PCI_SLOT (pdev->devfn), 1)); | ||
78 | if (b && b->device == PCI_DEVICE_ID_NS_87560_LIO | ||
79 | && b->vendor == PCI_VENDOR_ID_NS) { | ||
80 | ohci->flags |= OHCI_QUIRK_SUPERIO; | ||
81 | ohci_dbg (ohci, "Using NSC SuperIO setup\n"); | ||
82 | } | ||
83 | pci_dev_put(b); | ||
84 | } | ||
85 | 167 | ||
86 | /* Check for Compaq's ZFMicro chipset, which needs short | 168 | #ifdef CONFIG_PM /* avoid warnings about unused pdev */ |
87 | * delays before control or bulk queues get re-activated | 169 | if (hcd->self.controller) { |
88 | * in finish_unlinks() | 170 | struct pci_dev *pdev = to_pci_dev(hcd->self.controller); |
89 | */ | ||
90 | else if (pdev->vendor == PCI_VENDOR_ID_COMPAQ | ||
91 | && pdev->device == 0xa0f8) { | ||
92 | ohci->flags |= OHCI_QUIRK_ZFMICRO; | ||
93 | ohci_dbg (ohci, | ||
94 | "enabled Compaq ZFMicro chipset quirk\n"); | ||
95 | } | ||
96 | 171 | ||
97 | /* RWC may not be set for add-in PCI cards, since boot | 172 | /* RWC may not be set for add-in PCI cards, since boot |
98 | * firmware probably ignored them. This transfers PCI | 173 | * firmware probably ignored them. This transfers PCI |
@@ -101,16 +176,14 @@ ohci_pci_start (struct usb_hcd *hcd) | |||
101 | if (device_may_wakeup(&pdev->dev)) | 176 | if (device_may_wakeup(&pdev->dev)) |
102 | ohci->hc_control |= OHCI_CTRL_RWC; | 177 | ohci->hc_control |= OHCI_CTRL_RWC; |
103 | } | 178 | } |
179 | #endif /* CONFIG_PM */ | ||
104 | 180 | ||
105 | /* NOTE: there may have already been a first reset, to | 181 | ret = ohci_run (ohci); |
106 | * keep bios/smm irqs from making trouble | 182 | if (ret < 0) { |
107 | */ | ||
108 | if ((ret = ohci_run (ohci)) < 0) { | ||
109 | ohci_err (ohci, "can't start\n"); | 183 | ohci_err (ohci, "can't start\n"); |
110 | ohci_stop (hcd); | 184 | ohci_stop (hcd); |
111 | return ret; | ||
112 | } | 185 | } |
113 | return 0; | 186 | return ret; |
114 | } | 187 | } |
115 | 188 | ||
116 | #ifdef CONFIG_PM | 189 | #ifdef CONFIG_PM |
@@ -238,23 +311,3 @@ static struct pci_driver ohci_pci_driver = { | |||
238 | .shutdown = usb_hcd_pci_shutdown, | 311 | .shutdown = usb_hcd_pci_shutdown, |
239 | }; | 312 | }; |
240 | 313 | ||
241 | |||
242 | static int __init ohci_hcd_pci_init (void) | ||
243 | { | ||
244 | printk (KERN_DEBUG "%s: " DRIVER_INFO " (PCI)\n", hcd_name); | ||
245 | if (usb_disabled()) | ||
246 | return -ENODEV; | ||
247 | |||
248 | pr_debug ("%s: block sizes: ed %Zd td %Zd\n", hcd_name, | ||
249 | sizeof (struct ed), sizeof (struct td)); | ||
250 | return pci_register_driver (&ohci_pci_driver); | ||
251 | } | ||
252 | module_init (ohci_hcd_pci_init); | ||
253 | |||
254 | /*-------------------------------------------------------------------------*/ | ||
255 | |||
256 | static void __exit ohci_hcd_pci_cleanup (void) | ||
257 | { | ||
258 | pci_unregister_driver (&ohci_pci_driver); | ||
259 | } | ||
260 | module_exit (ohci_hcd_pci_cleanup); | ||