Skip to content

Commit

Permalink
---
Browse files Browse the repository at this point in the history
yaml
---
r: 3662
b: refs/heads/master
c: c074b41
h: refs/heads/master
v: v3
  • Loading branch information
Alan Stern authored and Greg Kroah-Hartman committed Jun 27, 2005
1 parent c2a53a1 commit 9311e11
Show file tree
Hide file tree
Showing 2 changed files with 41 additions and 30 deletions.
2 changes: 1 addition & 1 deletion [refs]
Original file line number Diff line number Diff line change
@@ -1,2 +1,2 @@
---
refs/heads/master: 6c1b445c226dd82d0961725dec8051b95003723a
refs/heads/master: c074b416b94c0aa4a371f24bf6cc13d8cf1fab59
69 changes: 40 additions & 29 deletions trunk/drivers/usb/host/uhci-hcd.c
Original file line number Diff line number Diff line change
Expand Up @@ -112,6 +112,8 @@ static inline void restart_timer(struct uhci_hcd *uhci)
*/
static void reset_hc(struct uhci_hcd *uhci)
{
int port;

/* Turn off PIRQ enable and SMI enable. (This also turns off the
* BIOS's USB Legacy Support.) Turn off all the R/WC bits too.
*/
Expand All @@ -135,6 +137,13 @@ static void reset_hc(struct uhci_hcd *uhci)
outw(0, uhci->io_addr + USBINTR);
outw(0, uhci->io_addr + USBCMD);

/* HCRESET doesn't affect the Suspend, Reset, and Resume Detect
* bits in the port status and control registers.
* We have to clear them by hand.
*/
for (port = 0; port < uhci->rh_numports; ++port)
outw(0, uhci->io_addr + USBPORTSC1 + (port * 2));

uhci->port_c_suspend = uhci->suspended_ports =
uhci->resuming_ports = 0;
uhci->rh_state = UHCI_RH_RESET;
Expand Down Expand Up @@ -166,14 +175,14 @@ static void check_and_reset_hc(struct uhci_hcd *uhci)
* When restarting a suspended controller, we expect all the
* settings to be the same as we left them:
*
* PIRQ and SMI disabled, no R/WC bits set in USBLEGSUP;
* 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) {
if (legsup & ~(USBLEGSUP_RO | USBLEGSUP_RWC)) {
dev_dbg(uhci_dev(uhci), "%s: legsup = 0x%04x\n",
__FUNCTION__, legsup);
goto reset_needed;
Expand Down Expand Up @@ -478,9 +487,37 @@ static void release_uhci(struct uhci_hcd *uhci)
static int uhci_reset(struct usb_hcd *hcd)
{
struct uhci_hcd *uhci = hcd_to_uhci(hcd);
unsigned io_size = (unsigned) hcd->rsrc_len;
int port;

uhci->io_addr = (unsigned long) hcd->rsrc_start;

/* The UHCI spec says devices must have 2 ports, and goes on to say
* they may have more but gives no way to determine how many there
* are. However, according to the UHCI spec, Bit 7 of the port
* status and control register is always set to 1. So we try to
* use this to our advantage.
*/
for (port = 0; port < (io_size - USBPORTSC1) / 2; port++) {
unsigned int portstatus;

portstatus = inw(uhci->io_addr + USBPORTSC1 + (port * 2));
if (!(portstatus & 0x0080))
break;
}
if (debug)
dev_info(uhci_dev(uhci), "detected %d ports\n", port);

/* Anything less than 2 or greater than 7 is weird,
* so we'll ignore it.
*/
if (port < 2 || port > UHCI_RH_MAXCHILD) {
dev_info(uhci_dev(uhci), "port count misdetected? "
"forcing to 2 ports\n");
port = 2;
}
uhci->rh_numports = port;

/* Kick BIOS off this hardware and reset if the controller
* isn't already safely quiescent.
*/
Expand Down Expand Up @@ -508,13 +545,11 @@ static int uhci_start(struct usb_hcd *hcd)
{
struct uhci_hcd *uhci = hcd_to_uhci(hcd);
int retval = -EBUSY;
int i, port;
unsigned io_size;
int i;
dma_addr_t dma_handle;
struct usb_device *udev;
struct dentry *dentry;

io_size = (unsigned) hcd->rsrc_len;
hcd->uses_new_polling = 1;
if (pci_find_capability(to_pci_dev(uhci_dev(uhci)), PCI_CAP_ID_PM))
hcd->can_wakeup = 1; /* Assume it supports PME# */
Expand Down Expand Up @@ -578,30 +613,6 @@ static int uhci_start(struct usb_hcd *hcd)

/* Initialize the root hub */

/* UHCI specs says devices must have 2 ports, but goes on to say */
/* they may have more but give no way to determine how many they */
/* have. However, according to the UHCI spec, Bit 7 is always set */
/* to 1. So we try to use this to our advantage */
for (port = 0; port < (io_size - 0x10) / 2; port++) {
unsigned int portstatus;

portstatus = inw(uhci->io_addr + 0x10 + (port * 2));
if (!(portstatus & 0x0080))
break;
}
if (debug)
dev_info(uhci_dev(uhci), "detected %d ports\n", port);

/* This is experimental so anything less than 2 or greater than 8 is */
/* something weird and we'll ignore it */
if (port < 2 || port > UHCI_RH_MAXCHILD) {
dev_info(uhci_dev(uhci), "port count misdetected? "
"forcing to 2 ports\n");
port = 2;
}

uhci->rh_numports = port;

udev = usb_alloc_dev(NULL, &hcd->self, 0);
if (!udev) {
dev_err(uhci_dev(uhci), "unable to allocate root hub\n");
Expand Down

0 comments on commit 9311e11

Please sign in to comment.