/* * Initialize a controller that was newly discovered or has just been * resumed. In either case we can't be sure of its previous state. */ static void check_and_reset_hc(struct uhci_hcd *uhci) { u16 legsup; unsigned int cmd, intr; /* * When restarting a suspended controller, we expect all the * settings to be the same as we left them: * * PIRQ and SMI disabled, no R/W bits set in USBLEGSUP; * Controller is stopped and configured with EGSM set; * No interrupts enabled except possibly Resume Detect. * * If any of these conditions are violated we do a complete reset. */ pci_read_config_word(to_pci_dev(uhci_dev(uhci)), USBLEGSUP, &legsup); if (legsup & ~(USBLEGSUP_RO | USBLEGSUP_RWC)) { dev_dbg(uhci_dev(uhci), "%s: legsup = 0x%04x\n", __FUNCTION__, legsup); goto reset_needed; } cmd = inw(uhci->io_addr + USBCMD); if ((cmd & USBCMD_RS) || !(cmd & USBCMD_CF) || !(cmd & USBCMD_EGSM)) { dev_dbg(uhci_dev(uhci), "%s: cmd = 0x%04x\n", __FUNCTION__, cmd); goto reset_needed; } intr = inw(uhci->io_addr + USBINTR); if (intr & (~USBINTR_RESUME)) { dev_dbg(uhci_dev(uhci), "%s: intr = 0x%04x\n", __FUNCTION__, intr); goto reset_needed; } return; reset_needed: dev_dbg(uhci_dev(uhci), "Performing full reset\n"); reset_hc(uhci); }
/* * Last rites for a defunct/nonfunctional controller * or one we don't want to use any more. */ static void hc_died(struct uhci_hcd *uhci) { reset_hc(uhci); uhci->hc_inaccessible = 1; del_timer(&uhci->stall_timer); }
/* * Last rites for a defunct/nonfunctional controller * or one we don't want to use any more. */ static void hc_died(struct uhci_hcd *uhci) { reset_hc(uhci); uhci->hc_inaccessible = 1; }