1 | // SPDX-License-Identifier: GPL-2.0 |
2 | /* |
3 | * UHCI HCD (Host Controller Driver) PCI Bus Glue. |
4 | * |
5 | * Extracted from uhci-hcd.c: |
6 | * Maintainer: Alan Stern <stern@rowland.harvard.edu> |
7 | * |
8 | * (C) Copyright 1999 Linus Torvalds |
9 | * (C) Copyright 1999-2002 Johannes Erdfelt, johannes@erdfelt.com |
10 | * (C) Copyright 1999 Randy Dunlap |
11 | * (C) Copyright 1999 Georg Acher, acher@in.tum.de |
12 | * (C) Copyright 1999 Deti Fliegl, deti@fliegl.de |
13 | * (C) Copyright 1999 Thomas Sailer, sailer@ife.ee.ethz.ch |
14 | * (C) Copyright 1999 Roman Weissgaerber, weissg@vienna.at |
15 | * (C) Copyright 2000 Yggdrasil Computing, Inc. (port of new PCI interface |
16 | * support from usb-ohci.c by Adam Richter, adam@yggdrasil.com). |
17 | * (C) Copyright 1999 Gregory P. Smith (from usb-ohci.c) |
18 | * (C) Copyright 2004-2007 Alan Stern, stern@rowland.harvard.edu |
19 | */ |
20 | |
21 | #include "pci-quirks.h" |
22 | |
23 | /* |
24 | * Make sure the controller is completely inactive, unable to |
25 | * generate interrupts or do DMA. |
26 | */ |
27 | static void uhci_pci_reset_hc(struct uhci_hcd *uhci) |
28 | { |
29 | uhci_reset_hc(to_pci_dev(uhci_dev(uhci)), base: uhci->io_addr); |
30 | } |
31 | |
32 | /* |
33 | * Initialize a controller that was newly discovered or has just been |
34 | * resumed. In either case we can't be sure of its previous state. |
35 | * |
36 | * Returns: 1 if the controller was reset, 0 otherwise. |
37 | */ |
38 | static int uhci_pci_check_and_reset_hc(struct uhci_hcd *uhci) |
39 | { |
40 | return uhci_check_and_reset_hc(to_pci_dev(uhci_dev(uhci)), |
41 | base: uhci->io_addr); |
42 | } |
43 | |
44 | /* |
45 | * Store the basic register settings needed by the controller. |
46 | * This function is called at the end of configure_hc in uhci-hcd.c. |
47 | */ |
48 | static void uhci_pci_configure_hc(struct uhci_hcd *uhci) |
49 | { |
50 | struct pci_dev *pdev = to_pci_dev(uhci_dev(uhci)); |
51 | |
52 | /* Enable PIRQ */ |
53 | pci_write_config_word(dev: pdev, USBLEGSUP, USBLEGSUP_DEFAULT); |
54 | |
55 | /* Disable platform-specific non-PME# wakeup */ |
56 | if (pdev->vendor == PCI_VENDOR_ID_INTEL) |
57 | pci_write_config_byte(dev: pdev, USBRES_INTEL, val: 0); |
58 | } |
59 | |
60 | static int uhci_pci_resume_detect_interrupts_are_broken(struct uhci_hcd *uhci) |
61 | { |
62 | int port; |
63 | |
64 | switch (to_pci_dev(uhci_dev(uhci))->vendor) { |
65 | default: |
66 | break; |
67 | |
68 | case PCI_VENDOR_ID_GENESYS: |
69 | /* Genesys Logic's GL880S controllers don't generate |
70 | * resume-detect interrupts. |
71 | */ |
72 | return 1; |
73 | |
74 | case PCI_VENDOR_ID_INTEL: |
75 | /* Some of Intel's USB controllers have a bug that causes |
76 | * resume-detect interrupts if any port has an over-current |
77 | * condition. To make matters worse, some motherboards |
78 | * hardwire unused USB ports' over-current inputs active! |
79 | * To prevent problems, we will not enable resume-detect |
80 | * interrupts if any ports are OC. |
81 | */ |
82 | for (port = 0; port < uhci->rh_numports; ++port) { |
83 | if (inw(port: uhci->io_addr + USBPORTSC1 + port * 2) & |
84 | USBPORTSC_OC) |
85 | return 1; |
86 | } |
87 | break; |
88 | } |
89 | return 0; |
90 | } |
91 | |
92 | static int uhci_pci_global_suspend_mode_is_broken(struct uhci_hcd *uhci) |
93 | { |
94 | int port; |
95 | const char *sys_info; |
96 | static const char bad_Asus_board[] = "A7V8X" ; |
97 | |
98 | /* One of Asus's motherboards has a bug which causes it to |
99 | * wake up immediately from suspend-to-RAM if any of the ports |
100 | * are connected. In such cases we will not set EGSM. |
101 | */ |
102 | sys_info = dmi_get_system_info(field: DMI_BOARD_NAME); |
103 | if (sys_info && !strcmp(sys_info, bad_Asus_board)) { |
104 | for (port = 0; port < uhci->rh_numports; ++port) { |
105 | if (inw(port: uhci->io_addr + USBPORTSC1 + port * 2) & |
106 | USBPORTSC_CCS) |
107 | return 1; |
108 | } |
109 | } |
110 | |
111 | return 0; |
112 | } |
113 | |
114 | static int uhci_pci_init(struct usb_hcd *hcd) |
115 | { |
116 | struct uhci_hcd *uhci = hcd_to_uhci(hcd); |
117 | |
118 | uhci->io_addr = (unsigned long) hcd->rsrc_start; |
119 | |
120 | uhci->rh_numports = uhci_count_ports(hcd); |
121 | |
122 | /* |
123 | * Intel controllers report the OverCurrent bit active on. VIA |
124 | * and ZHAOXIN controllers report it active off, so we'll adjust |
125 | * the bit value. (It's not standardized in the UHCI spec.) |
126 | */ |
127 | if (to_pci_dev(uhci_dev(uhci))->vendor == PCI_VENDOR_ID_VIA || |
128 | to_pci_dev(uhci_dev(uhci))->vendor == PCI_VENDOR_ID_ZHAOXIN) |
129 | uhci->oc_low = 1; |
130 | |
131 | /* HP's server management chip requires a longer port reset delay. */ |
132 | if (to_pci_dev(uhci_dev(uhci))->vendor == PCI_VENDOR_ID_HP) |
133 | uhci->wait_for_hp = 1; |
134 | |
135 | /* Intel controllers use non-PME wakeup signalling */ |
136 | if (to_pci_dev(uhci_dev(uhci))->vendor == PCI_VENDOR_ID_INTEL) |
137 | device_set_wakeup_capable(uhci_dev(uhci), capable: true); |
138 | |
139 | /* Set up pointers to PCI-specific functions */ |
140 | uhci->reset_hc = uhci_pci_reset_hc; |
141 | uhci->check_and_reset_hc = uhci_pci_check_and_reset_hc; |
142 | uhci->configure_hc = uhci_pci_configure_hc; |
143 | uhci->resume_detect_interrupts_are_broken = |
144 | uhci_pci_resume_detect_interrupts_are_broken; |
145 | uhci->global_suspend_mode_is_broken = |
146 | uhci_pci_global_suspend_mode_is_broken; |
147 | |
148 | |
149 | /* Kick BIOS off this hardware and reset if the controller |
150 | * isn't already safely quiescent. |
151 | */ |
152 | check_and_reset_hc(uhci); |
153 | return 0; |
154 | } |
155 | |
156 | /* Make sure the controller is quiescent and that we're not using it |
157 | * any more. This is mainly for the benefit of programs which, like kexec, |
158 | * expect the hardware to be idle: not doing DMA or generating IRQs. |
159 | * |
160 | * This routine may be called in a damaged or failing kernel. Hence we |
161 | * do not acquire the spinlock before shutting down the controller. |
162 | */ |
163 | static void uhci_shutdown(struct pci_dev *pdev) |
164 | { |
165 | struct usb_hcd *hcd = pci_get_drvdata(pdev); |
166 | |
167 | uhci_hc_died(uhci: hcd_to_uhci(hcd)); |
168 | } |
169 | |
170 | #ifdef CONFIG_PM |
171 | |
172 | static int uhci_pci_resume(struct usb_hcd *hcd, pm_message_t state); |
173 | |
174 | static int uhci_pci_suspend(struct usb_hcd *hcd, bool do_wakeup) |
175 | { |
176 | struct uhci_hcd *uhci = hcd_to_uhci(hcd); |
177 | struct pci_dev *pdev = to_pci_dev(uhci_dev(uhci)); |
178 | int rc = 0; |
179 | |
180 | dev_dbg(uhci_dev(uhci), "%s\n" , __func__); |
181 | |
182 | spin_lock_irq(lock: &uhci->lock); |
183 | if (!HCD_HW_ACCESSIBLE(hcd) || uhci->dead) |
184 | goto done_okay; /* Already suspended or dead */ |
185 | |
186 | /* All PCI host controllers are required to disable IRQ generation |
187 | * at the source, so we must turn off PIRQ. |
188 | */ |
189 | pci_write_config_word(dev: pdev, USBLEGSUP, val: 0); |
190 | clear_bit(HCD_FLAG_POLL_RH, addr: &hcd->flags); |
191 | |
192 | /* Enable platform-specific non-PME# wakeup */ |
193 | if (do_wakeup) { |
194 | if (pdev->vendor == PCI_VENDOR_ID_INTEL) |
195 | pci_write_config_byte(dev: pdev, USBRES_INTEL, |
196 | USBPORT1EN | USBPORT2EN); |
197 | } |
198 | |
199 | done_okay: |
200 | clear_bit(HCD_FLAG_HW_ACCESSIBLE, addr: &hcd->flags); |
201 | spin_unlock_irq(lock: &uhci->lock); |
202 | |
203 | synchronize_irq(irq: hcd->irq); |
204 | |
205 | /* Check for race with a wakeup request */ |
206 | if (do_wakeup && HCD_WAKEUP_PENDING(hcd)) { |
207 | uhci_pci_resume(hcd, PMSG_SUSPEND); |
208 | rc = -EBUSY; |
209 | } |
210 | return rc; |
211 | } |
212 | |
213 | static int uhci_pci_resume(struct usb_hcd *hcd, pm_message_t msg) |
214 | { |
215 | bool hibernated = (msg.event == PM_EVENT_RESTORE); |
216 | struct uhci_hcd *uhci = hcd_to_uhci(hcd); |
217 | |
218 | dev_dbg(uhci_dev(uhci), "%s\n" , __func__); |
219 | |
220 | /* Since we aren't in D3 any more, it's safe to set this flag |
221 | * even if the controller was dead. |
222 | */ |
223 | set_bit(HCD_FLAG_HW_ACCESSIBLE, addr: &hcd->flags); |
224 | |
225 | spin_lock_irq(lock: &uhci->lock); |
226 | |
227 | /* Make sure resume from hibernation re-enumerates everything */ |
228 | if (hibernated) { |
229 | uhci->reset_hc(uhci); |
230 | finish_reset(uhci); |
231 | } |
232 | |
233 | /* The firmware may have changed the controller settings during |
234 | * a system wakeup. Check it and reconfigure to avoid problems. |
235 | */ |
236 | else { |
237 | check_and_reset_hc(uhci); |
238 | } |
239 | configure_hc(uhci); |
240 | |
241 | /* Tell the core if the controller had to be reset */ |
242 | if (uhci->rh_state == UHCI_RH_RESET) |
243 | usb_root_hub_lost_power(rhdev: hcd->self.root_hub); |
244 | |
245 | spin_unlock_irq(lock: &uhci->lock); |
246 | |
247 | /* If interrupts don't work and remote wakeup is enabled then |
248 | * the suspended root hub needs to be polled. |
249 | */ |
250 | if (!uhci->RD_enable && hcd->self.root_hub->do_remote_wakeup) |
251 | set_bit(HCD_FLAG_POLL_RH, addr: &hcd->flags); |
252 | |
253 | /* Does the root hub have a port wakeup pending? */ |
254 | usb_hcd_poll_rh_status(hcd); |
255 | return 0; |
256 | } |
257 | |
258 | #endif |
259 | |
260 | static const struct hc_driver uhci_driver = { |
261 | .description = hcd_name, |
262 | .product_desc = "UHCI Host Controller" , |
263 | .hcd_priv_size = sizeof(struct uhci_hcd), |
264 | |
265 | /* Generic hardware linkage */ |
266 | .irq = uhci_irq, |
267 | .flags = HCD_DMA | HCD_USB11, |
268 | |
269 | /* Basic lifecycle operations */ |
270 | .reset = uhci_pci_init, |
271 | .start = uhci_start, |
272 | #ifdef CONFIG_PM |
273 | .pci_suspend = uhci_pci_suspend, |
274 | .pci_resume = uhci_pci_resume, |
275 | .bus_suspend = uhci_rh_suspend, |
276 | .bus_resume = uhci_rh_resume, |
277 | #endif |
278 | .stop = uhci_stop, |
279 | |
280 | .urb_enqueue = uhci_urb_enqueue, |
281 | .urb_dequeue = uhci_urb_dequeue, |
282 | |
283 | .endpoint_disable = uhci_hcd_endpoint_disable, |
284 | .get_frame_number = uhci_hcd_get_frame_number, |
285 | |
286 | .hub_status_data = uhci_hub_status_data, |
287 | .hub_control = uhci_hub_control, |
288 | }; |
289 | |
290 | static const struct pci_device_id uhci_pci_ids[] = { { |
291 | /* handle any USB UHCI controller */ |
292 | PCI_DEVICE_CLASS(PCI_CLASS_SERIAL_USB_UHCI, ~0), |
293 | }, { /* end: all zeroes */ } |
294 | }; |
295 | |
296 | MODULE_DEVICE_TABLE(pci, uhci_pci_ids); |
297 | |
298 | static int uhci_pci_probe(struct pci_dev *dev, const struct pci_device_id *id) |
299 | { |
300 | return usb_hcd_pci_probe(dev, driver: &uhci_driver); |
301 | } |
302 | |
303 | static struct pci_driver uhci_pci_driver = { |
304 | .name = hcd_name, |
305 | .id_table = uhci_pci_ids, |
306 | |
307 | .probe = uhci_pci_probe, |
308 | .remove = usb_hcd_pci_remove, |
309 | .shutdown = uhci_shutdown, |
310 | |
311 | #ifdef CONFIG_PM |
312 | .driver = { |
313 | .pm = &usb_hcd_pci_pm_ops |
314 | }, |
315 | #endif |
316 | }; |
317 | |
318 | MODULE_SOFTDEP("pre: ehci_pci" ); |
319 | |