aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/usb/host/ohci-pci.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/usb/host/ohci-pci.c')
-rw-r--r--drivers/usb/host/ohci-pci.c219
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
23static int 23/* AMD 756, for most chips (early revs), corrupts register
24ohci_pci_reset (struct usb_hcd *hcd) 24 * values on read ... so enable the vendor workaround.
25 */
26static 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
32static int __devinit 39/* Apple's OHCI driver has a lot of bizarre workarounds
33ohci_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 */
43static 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 */
56static 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 */
78static 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 */
91static 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 */
111static 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
139static 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 163static 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
242static 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}
252module_init (ohci_hcd_pci_init);
253
254/*-------------------------------------------------------------------------*/
255
256static void __exit ohci_hcd_pci_cleanup (void)
257{
258 pci_unregister_driver (&ohci_pci_driver);
259}
260module_exit (ohci_hcd_pci_cleanup);