0001
0002
0003
0004
0005
0006
0007
0008
0009
0010
0011
0012
0013
0014
0015
0016
0017
0018
0019
0020
0021 #include "pci-quirks.h"
0022
0023
0024
0025
0026
0027 static void uhci_pci_reset_hc(struct uhci_hcd *uhci)
0028 {
0029 uhci_reset_hc(to_pci_dev(uhci_dev(uhci)), uhci->io_addr);
0030 }
0031
0032
0033
0034
0035
0036
0037
0038 static int uhci_pci_check_and_reset_hc(struct uhci_hcd *uhci)
0039 {
0040 return uhci_check_and_reset_hc(to_pci_dev(uhci_dev(uhci)),
0041 uhci->io_addr);
0042 }
0043
0044
0045
0046
0047
0048 static void uhci_pci_configure_hc(struct uhci_hcd *uhci)
0049 {
0050 struct pci_dev *pdev = to_pci_dev(uhci_dev(uhci));
0051
0052
0053 pci_write_config_word(pdev, USBLEGSUP, USBLEGSUP_DEFAULT);
0054
0055
0056 if (pdev->vendor == PCI_VENDOR_ID_INTEL)
0057 pci_write_config_byte(pdev, USBRES_INTEL, 0);
0058 }
0059
0060 static int uhci_pci_resume_detect_interrupts_are_broken(struct uhci_hcd *uhci)
0061 {
0062 int port;
0063
0064 switch (to_pci_dev(uhci_dev(uhci))->vendor) {
0065 default:
0066 break;
0067
0068 case PCI_VENDOR_ID_GENESYS:
0069
0070
0071
0072 return 1;
0073
0074 case PCI_VENDOR_ID_INTEL:
0075
0076
0077
0078
0079
0080
0081
0082 for (port = 0; port < uhci->rh_numports; ++port) {
0083 if (inw(uhci->io_addr + USBPORTSC1 + port * 2) &
0084 USBPORTSC_OC)
0085 return 1;
0086 }
0087 break;
0088 }
0089 return 0;
0090 }
0091
0092 static int uhci_pci_global_suspend_mode_is_broken(struct uhci_hcd *uhci)
0093 {
0094 int port;
0095 const char *sys_info;
0096 static const char bad_Asus_board[] = "A7V8X";
0097
0098
0099
0100
0101
0102 sys_info = dmi_get_system_info(DMI_BOARD_NAME);
0103 if (sys_info && !strcmp(sys_info, bad_Asus_board)) {
0104 for (port = 0; port < uhci->rh_numports; ++port) {
0105 if (inw(uhci->io_addr + USBPORTSC1 + port * 2) &
0106 USBPORTSC_CCS)
0107 return 1;
0108 }
0109 }
0110
0111 return 0;
0112 }
0113
0114 static int uhci_pci_init(struct usb_hcd *hcd)
0115 {
0116 struct uhci_hcd *uhci = hcd_to_uhci(hcd);
0117
0118 uhci->io_addr = (unsigned long) hcd->rsrc_start;
0119
0120 uhci->rh_numports = uhci_count_ports(hcd);
0121
0122
0123
0124
0125
0126 if (to_pci_dev(uhci_dev(uhci))->vendor == PCI_VENDOR_ID_VIA)
0127 uhci->oc_low = 1;
0128
0129
0130 if (to_pci_dev(uhci_dev(uhci))->vendor == PCI_VENDOR_ID_HP)
0131 uhci->wait_for_hp = 1;
0132
0133
0134 if (to_pci_dev(uhci_dev(uhci))->vendor == PCI_VENDOR_ID_INTEL)
0135 device_set_wakeup_capable(uhci_dev(uhci), true);
0136
0137
0138 uhci->reset_hc = uhci_pci_reset_hc;
0139 uhci->check_and_reset_hc = uhci_pci_check_and_reset_hc;
0140 uhci->configure_hc = uhci_pci_configure_hc;
0141 uhci->resume_detect_interrupts_are_broken =
0142 uhci_pci_resume_detect_interrupts_are_broken;
0143 uhci->global_suspend_mode_is_broken =
0144 uhci_pci_global_suspend_mode_is_broken;
0145
0146
0147
0148
0149
0150 check_and_reset_hc(uhci);
0151 return 0;
0152 }
0153
0154
0155
0156
0157
0158
0159
0160
0161 static void uhci_shutdown(struct pci_dev *pdev)
0162 {
0163 struct usb_hcd *hcd = pci_get_drvdata(pdev);
0164
0165 uhci_hc_died(hcd_to_uhci(hcd));
0166 }
0167
0168 #ifdef CONFIG_PM
0169
0170 static int uhci_pci_resume(struct usb_hcd *hcd, bool hibernated);
0171
0172 static int uhci_pci_suspend(struct usb_hcd *hcd, bool do_wakeup)
0173 {
0174 struct uhci_hcd *uhci = hcd_to_uhci(hcd);
0175 struct pci_dev *pdev = to_pci_dev(uhci_dev(uhci));
0176 int rc = 0;
0177
0178 dev_dbg(uhci_dev(uhci), "%s\n", __func__);
0179
0180 spin_lock_irq(&uhci->lock);
0181 if (!HCD_HW_ACCESSIBLE(hcd) || uhci->dead)
0182 goto done_okay;
0183
0184
0185
0186
0187 pci_write_config_word(pdev, USBLEGSUP, 0);
0188 clear_bit(HCD_FLAG_POLL_RH, &hcd->flags);
0189
0190
0191 if (do_wakeup) {
0192 if (pdev->vendor == PCI_VENDOR_ID_INTEL)
0193 pci_write_config_byte(pdev, USBRES_INTEL,
0194 USBPORT1EN | USBPORT2EN);
0195 }
0196
0197 done_okay:
0198 clear_bit(HCD_FLAG_HW_ACCESSIBLE, &hcd->flags);
0199 spin_unlock_irq(&uhci->lock);
0200
0201 synchronize_irq(hcd->irq);
0202
0203
0204 if (do_wakeup && HCD_WAKEUP_PENDING(hcd)) {
0205 uhci_pci_resume(hcd, false);
0206 rc = -EBUSY;
0207 }
0208 return rc;
0209 }
0210
0211 static int uhci_pci_resume(struct usb_hcd *hcd, bool hibernated)
0212 {
0213 struct uhci_hcd *uhci = hcd_to_uhci(hcd);
0214
0215 dev_dbg(uhci_dev(uhci), "%s\n", __func__);
0216
0217
0218
0219
0220 set_bit(HCD_FLAG_HW_ACCESSIBLE, &hcd->flags);
0221
0222 spin_lock_irq(&uhci->lock);
0223
0224
0225 if (hibernated) {
0226 uhci->reset_hc(uhci);
0227 finish_reset(uhci);
0228 }
0229
0230
0231
0232
0233 else {
0234 check_and_reset_hc(uhci);
0235 }
0236 configure_hc(uhci);
0237
0238
0239 if (uhci->rh_state == UHCI_RH_RESET)
0240 usb_root_hub_lost_power(hcd->self.root_hub);
0241
0242 spin_unlock_irq(&uhci->lock);
0243
0244
0245
0246
0247 if (!uhci->RD_enable && hcd->self.root_hub->do_remote_wakeup)
0248 set_bit(HCD_FLAG_POLL_RH, &hcd->flags);
0249
0250
0251 usb_hcd_poll_rh_status(hcd);
0252 return 0;
0253 }
0254
0255 #endif
0256
0257 static const struct hc_driver uhci_driver = {
0258 .description = hcd_name,
0259 .product_desc = "UHCI Host Controller",
0260 .hcd_priv_size = sizeof(struct uhci_hcd),
0261
0262
0263 .irq = uhci_irq,
0264 .flags = HCD_DMA | HCD_USB11,
0265
0266
0267 .reset = uhci_pci_init,
0268 .start = uhci_start,
0269 #ifdef CONFIG_PM
0270 .pci_suspend = uhci_pci_suspend,
0271 .pci_resume = uhci_pci_resume,
0272 .bus_suspend = uhci_rh_suspend,
0273 .bus_resume = uhci_rh_resume,
0274 #endif
0275 .stop = uhci_stop,
0276
0277 .urb_enqueue = uhci_urb_enqueue,
0278 .urb_dequeue = uhci_urb_dequeue,
0279
0280 .endpoint_disable = uhci_hcd_endpoint_disable,
0281 .get_frame_number = uhci_hcd_get_frame_number,
0282
0283 .hub_status_data = uhci_hub_status_data,
0284 .hub_control = uhci_hub_control,
0285 };
0286
0287 static const struct pci_device_id uhci_pci_ids[] = { {
0288
0289 PCI_DEVICE_CLASS(PCI_CLASS_SERIAL_USB_UHCI, ~0),
0290 }, { }
0291 };
0292
0293 MODULE_DEVICE_TABLE(pci, uhci_pci_ids);
0294
0295 static int uhci_pci_probe(struct pci_dev *dev, const struct pci_device_id *id)
0296 {
0297 return usb_hcd_pci_probe(dev, id, &uhci_driver);
0298 }
0299
0300 static struct pci_driver uhci_pci_driver = {
0301 .name = hcd_name,
0302 .id_table = uhci_pci_ids,
0303
0304 .probe = uhci_pci_probe,
0305 .remove = usb_hcd_pci_remove,
0306 .shutdown = uhci_shutdown,
0307
0308 #ifdef CONFIG_PM
0309 .driver = {
0310 .pm = &usb_hcd_pci_pm_ops
0311 },
0312 #endif
0313 };
0314
0315 MODULE_SOFTDEP("pre: ehci_pci");