diff options
Diffstat (limited to 'drivers/usb/host/uhci-hcd.c')
| -rw-r--r-- | drivers/usb/host/uhci-hcd.c | 628 | 
1 files changed, 271 insertions, 357 deletions
diff --git a/drivers/usb/host/uhci-hcd.c b/drivers/usb/host/uhci-hcd.c index f52d04db28f..27f35e8f161 100644 --- a/drivers/usb/host/uhci-hcd.c +++ b/drivers/usb/host/uhci-hcd.c @@ -45,21 +45,20 @@  #include <asm/uaccess.h>  #include <asm/io.h>  #include <asm/irq.h> -#include <asm/system.h>  #include "uhci-hcd.h" -#include "pci-quirks.h"  /*   * Version Information   */ -#define DRIVER_AUTHOR "Linus 'Frodo Rabbit' Torvalds, Johannes Erdfelt, \ -Randy Dunlap, Georg Acher, Deti Fliegl, Thomas Sailer, Roman Weissgaerber, \ -Alan Stern" +#define DRIVER_AUTHOR							\ +	"Linus 'Frodo Rabbit' Torvalds, Johannes Erdfelt, "		\ +	"Randy Dunlap, Georg Acher, Deti Fliegl, Thomas Sailer, "	\ +	"Roman Weissgaerber, Alan Stern"  #define DRIVER_DESC "USB Universal Host Controller Interface driver"  /* for flakey hardware, ignore overcurrent indicators */ -static int ignore_oc; +static bool ignore_oc;  module_param(ignore_oc, bool, S_IRUGO);  MODULE_PARM_DESC(ignore_oc, "ignore hardware overcurrent indications"); @@ -70,18 +69,21 @@ MODULE_PARM_DESC(ignore_oc, "ignore hardware overcurrent indications");   *            show all queues in /sys/kernel/debug/uhci/[pci_addr]   * debug = 3, show all TDs in URBs when dumping   */ -#ifdef DEBUG -#define DEBUG_CONFIGURED	1 +#ifdef CONFIG_DYNAMIC_DEBUG +  static int debug = 1;  module_param(debug, int, S_IRUGO | S_IWUSR);  MODULE_PARM_DESC(debug, "Debug level"); +static char *errbuf;  #else -#define DEBUG_CONFIGURED	0 -#define debug			0 + +#define debug 0 +#define errbuf NULL +  #endif -static char *errbuf; +  #define ERRBUF_LEN    (32 * 1024)  static struct kmem_cache *uhci_up_cachep;	/* urb_priv */ @@ -93,7 +95,7 @@ static void uhci_get_current_frame_number(struct uhci_hcd *uhci);  /*   * Calculate the link pointer DMA value for the first Skeleton QH in a frame.   */ -static __le32 uhci_frame_skel_link(struct uhci_hcd *uhci, int frame) +static __hc32 uhci_frame_skel_link(struct uhci_hcd *uhci, int frame)  {  	int skelnum; @@ -115,7 +117,7 @@ static __le32 uhci_frame_skel_link(struct uhci_hcd *uhci, int frame)  	skelnum = 8 - (int) __ffs(frame | UHCI_NUMFRAMES);  	if (skelnum <= 1)  		skelnum = 9; -	return LINK_TO_QH(uhci->skelqh[skelnum]); +	return LINK_TO_QH(uhci, uhci->skelqh[skelnum]);  }  #include "uhci-debug.c" @@ -134,15 +136,12 @@ static void finish_reset(struct uhci_hcd *uhci)  	 * We have to clear them by hand.  	 */  	for (port = 0; port < uhci->rh_numports; ++port) -		outw(0, uhci->io_addr + USBPORTSC1 + (port * 2)); +		uhci_writew(uhci, 0, USBPORTSC1 + (port * 2));  	uhci->port_c_suspend = uhci->resuming_ports = 0;  	uhci->rh_state = UHCI_RH_RESET;  	uhci->is_stopped = UHCI_IS_STOPPED; -	uhci_to_hcd(uhci)->state = HC_STATE_HALT;  	clear_bit(HCD_FLAG_POLL_RH, &uhci_to_hcd(uhci)->flags); - -	uhci->dead = 0;		/* Full reset resurrects the controller */  }  /* @@ -152,7 +151,7 @@ static void finish_reset(struct uhci_hcd *uhci)  static void uhci_hc_died(struct uhci_hcd *uhci)  {  	uhci_get_current_frame_number(uhci); -	uhci_reset_hc(to_pci_dev(uhci_dev(uhci)), uhci->io_addr); +	uhci->reset_hc(uhci);  	finish_reset(uhci);  	uhci->dead = 1; @@ -167,97 +166,118 @@ static void uhci_hc_died(struct uhci_hcd *uhci)   */  static void check_and_reset_hc(struct uhci_hcd *uhci)  { -	if (uhci_check_and_reset_hc(to_pci_dev(uhci_dev(uhci)), uhci->io_addr)) +	if (uhci->check_and_reset_hc(uhci))  		finish_reset(uhci);  } +#if defined(CONFIG_USB_UHCI_SUPPORT_NON_PCI_HC) +/* + * The two functions below are generic reset functions that are used on systems + * that do not have keyboard and mouse legacy support. We assume that we are + * running on such a system if CONFIG_USB_UHCI_SUPPORT_NON_PCI_HC is defined. + */ + +/* + * Make sure the controller is completely inactive, unable to + * generate interrupts or do DMA. + */ +static void uhci_generic_reset_hc(struct uhci_hcd *uhci) +{ +	/* Reset the HC - this will force us to get a +	 * new notification of any already connected +	 * ports due to the virtual disconnect that it +	 * implies. +	 */ +	uhci_writew(uhci, USBCMD_HCRESET, USBCMD); +	mb(); +	udelay(5); +	if (uhci_readw(uhci, USBCMD) & USBCMD_HCRESET) +		dev_warn(uhci_dev(uhci), "HCRESET not completed yet!\n"); + +	/* Just to be safe, disable interrupt requests and +	 * make sure the controller is stopped. +	 */ +	uhci_writew(uhci, 0, USBINTR); +	uhci_writew(uhci, 0, USBCMD); +} + +/* + * Initialize a controller that was newly discovered or has just been + * resumed.  In either case we can't be sure of its previous state. + * + * Returns: 1 if the controller was reset, 0 otherwise. + */ +static int uhci_generic_check_and_reset_hc(struct uhci_hcd *uhci) +{ +	unsigned int cmd, intr; + +	/* +	 * When restarting a suspended controller, we expect all the +	 * settings to be the same as we left them: +	 * +	 *	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. +	 */ + +	cmd = uhci_readw(uhci, USBCMD); +	if ((cmd & USBCMD_RS) || !(cmd & USBCMD_CF) || !(cmd & USBCMD_EGSM)) { +		dev_dbg(uhci_dev(uhci), "%s: cmd = 0x%04x\n", +				__func__, cmd); +		goto reset_needed; +	} + +	intr = uhci_readw(uhci, USBINTR); +	if (intr & (~USBINTR_RESUME)) { +		dev_dbg(uhci_dev(uhci), "%s: intr = 0x%04x\n", +				__func__, intr); +		goto reset_needed; +	} +	return 0; + +reset_needed: +	dev_dbg(uhci_dev(uhci), "Performing full reset\n"); +	uhci_generic_reset_hc(uhci); +	return 1; +} +#endif /* CONFIG_USB_UHCI_SUPPORT_NON_PCI_HC */ +  /*   * Store the basic register settings needed by the controller.   */  static void configure_hc(struct uhci_hcd *uhci)  { -	struct pci_dev *pdev = to_pci_dev(uhci_dev(uhci)); -  	/* Set the frame length to the default: 1 ms exactly */ -	outb(USBSOF_DEFAULT, uhci->io_addr + USBSOF); +	uhci_writeb(uhci, USBSOF_DEFAULT, USBSOF);  	/* Store the frame list base address */ -	outl(uhci->frame_dma_handle, uhci->io_addr + USBFLBASEADD); +	uhci_writel(uhci, uhci->frame_dma_handle, USBFLBASEADD);  	/* Set the current frame number */ -	outw(uhci->frame_number & UHCI_MAX_SOF_NUMBER, -			uhci->io_addr + USBFRNUM); - -	/* Mark controller as not halted before we enable interrupts */ -	uhci_to_hcd(uhci)->state = HC_STATE_SUSPENDED; -	mb(); - -	/* Enable PIRQ */ -	pci_write_config_word(pdev, USBLEGSUP, USBLEGSUP_DEFAULT); +	uhci_writew(uhci, uhci->frame_number & UHCI_MAX_SOF_NUMBER, +			USBFRNUM); -	/* Disable platform-specific non-PME# wakeup */ -	if (pdev->vendor == PCI_VENDOR_ID_INTEL) -		pci_write_config_byte(pdev, USBRES_INTEL, 0); +	/* perform any arch/bus specific configuration */ +	if (uhci->configure_hc) +		uhci->configure_hc(uhci);  } -  static int resume_detect_interrupts_are_broken(struct uhci_hcd *uhci)  { -	int port; -  	/* If we have to ignore overcurrent events then almost by definition  	 * we can't depend on resume-detect interrupts. */  	if (ignore_oc)  		return 1; -	switch (to_pci_dev(uhci_dev(uhci))->vendor) { -	    default: -		break; - -	    case PCI_VENDOR_ID_GENESYS: -		/* Genesys Logic's GL880S controllers don't generate -		 * resume-detect interrupts. -		 */ -		return 1; - -	    case PCI_VENDOR_ID_INTEL: -		/* Some of Intel's USB controllers have a bug that causes -		 * resume-detect interrupts if any port has an over-current -		 * condition.  To make matters worse, some motherboards -		 * hardwire unused USB ports' over-current inputs active! -		 * To prevent problems, we will not enable resume-detect -		 * interrupts if any ports are OC. -		 */ -		for (port = 0; port < uhci->rh_numports; ++port) { -			if (inw(uhci->io_addr + USBPORTSC1 + port * 2) & -					USBPORTSC_OC) -				return 1; -		} -		break; -	} -	return 0; +	return uhci->resume_detect_interrupts_are_broken ? +		uhci->resume_detect_interrupts_are_broken(uhci) : 0;  }  static int global_suspend_mode_is_broken(struct uhci_hcd *uhci)  { -	int port; -	const char *sys_info; -	static char bad_Asus_board[] = "A7V8X"; - -	/* One of Asus's motherboards has a bug which causes it to -	 * wake up immediately from suspend-to-RAM if any of the ports -	 * are connected.  In such cases we will not set EGSM. -	 */ -	sys_info = dmi_get_system_info(DMI_BOARD_NAME); -	if (sys_info && !strcmp(sys_info, bad_Asus_board)) { -		for (port = 0; port < uhci->rh_numports; ++port) { -			if (inw(uhci->io_addr + USBPORTSC1 + port * 2) & -					USBPORTSC_CCS) -				return 1; -		} -	} - -	return 0; +	return uhci->global_suspend_mode_is_broken ? +		uhci->global_suspend_mode_is_broken(uhci) : 0;  }  static void suspend_rh(struct uhci_hcd *uhci, enum uhci_rh_state new_state) @@ -276,52 +296,52 @@ __acquires(uhci->lock)  	 * and that remote wakeups should be enabled.  	 */  	egsm_enable = USBCMD_EGSM; -	uhci->RD_enable = 1;  	int_enable = USBINTR_RESUME;  	wakeup_enable = 1; -	/* In auto-stop mode wakeups must always be detected, but -	 * Resume-Detect interrupts may be prohibited.  (In the absence -	 * of CONFIG_PM, they are always disallowed.) +	/* +	 * In auto-stop mode, we must be able to detect new connections. +	 * The user can force us to poll by disabling remote wakeup; +	 * otherwise we will use the EGSM/RD mechanism.  	 */  	if (auto_stop) {  		if (!device_may_wakeup(&rhdev->dev)) -			int_enable = 0; +			egsm_enable = int_enable = 0; +	} -	/* In bus-suspend mode wakeups may be disabled, but if they are -	 * allowed then so are Resume-Detect interrupts. -	 */ -	} else {  #ifdef CONFIG_PM +	/* +	 * In bus-suspend mode, we use the wakeup setting specified +	 * for the root hub. +	 */ +	else {  		if (!rhdev->do_remote_wakeup)  			wakeup_enable = 0; -#endif  	} +#endif -	/* EGSM causes the root hub to echo a 'K' signal (resume) out any -	 * port which requests a remote wakeup.  According to the USB spec, -	 * every hub is supposed to do this.  But if we are ignoring -	 * remote-wakeup requests anyway then there's no point to it. -	 * We also shouldn't enable EGSM if it's broken. -	 */ -	if (!wakeup_enable || global_suspend_mode_is_broken(uhci)) -		egsm_enable = 0; - -	/* If we're ignoring wakeup events then there's no reason to -	 * enable Resume-Detect interrupts.  We also shouldn't enable -	 * them if they are broken or disallowed. +	/* +	 * UHCI doesn't distinguish between wakeup requests from downstream +	 * devices and local connect/disconnect events.  There's no way to +	 * enable one without the other; both are controlled by EGSM.  Thus +	 * if wakeups are disallowed then EGSM must be turned off -- in which +	 * case remote wakeup requests from downstream during system sleep +	 * will be lost.  	 * -	 * This logic may lead us to enabling RD but not EGSM.  The UHCI -	 * spec foolishly says that RD works only when EGSM is on, but -	 * there's no harm in enabling it anyway -- perhaps some chips -	 * will implement it! +	 * In addition, if EGSM is broken then we can't use it.  Likewise, +	 * if Resume-Detect interrupts are broken then we can't use them. +	 * +	 * Finally, neither EGSM nor RD is useful by itself.  Without EGSM, +	 * the RD status bit will never get set.  Without RD, the controller +	 * won't generate interrupts to tell the system about wakeup events.  	 */ -	if (!wakeup_enable || resume_detect_interrupts_are_broken(uhci) || -			!int_enable) -		uhci->RD_enable = int_enable = 0; +	if (!wakeup_enable || global_suspend_mode_is_broken(uhci) || +			resume_detect_interrupts_are_broken(uhci)) +		egsm_enable = int_enable = 0; -	outw(int_enable, uhci->io_addr + USBINTR); -	outw(egsm_enable | USBCMD_CF, uhci->io_addr + USBCMD); +	uhci->RD_enable = !!int_enable; +	uhci_writew(uhci, int_enable, USBINTR); +	uhci_writew(uhci, egsm_enable | USBCMD_CF, USBCMD);  	mb();  	udelay(5); @@ -330,7 +350,7 @@ __acquires(uhci->lock)  	 * controller should stop after a few microseconds.  Otherwise  	 * we will give the controller one frame to stop.  	 */ -	if (!auto_stop && !(inw(uhci->io_addr + USBSTS) & USBSTS_HCH)) { +	if (!auto_stop && !(uhci_readw(uhci, USBSTS) & USBSTS_HCH)) {  		uhci->rh_state = UHCI_RH_SUSPENDING;  		spin_unlock_irq(&uhci->lock);  		msleep(1); @@ -338,7 +358,7 @@ __acquires(uhci->lock)  		if (uhci->dead)  			return;  	} -	if (!(inw(uhci->io_addr + USBSTS) & USBSTS_HCH)) +	if (!(uhci_readw(uhci, USBSTS) & USBSTS_HCH))  		dev_warn(uhci_dev(uhci), "Controller not stopped yet!\n");  	uhci_get_current_frame_number(uhci); @@ -346,10 +366,12 @@ __acquires(uhci->lock)  	uhci->rh_state = new_state;  	uhci->is_stopped = UHCI_IS_STOPPED; -	/* If interrupts don't work and remote wakeup is enabled then -	 * the suspended root hub needs to be polled. +	/* +	 * If remote wakeup is enabled but either EGSM or RD interrupts +	 * doesn't work, then we won't get an interrupt when a wakeup event +	 * occurs.  Thus the suspended root hub needs to be polled.  	 */ -	if (!int_enable && wakeup_enable) +	if (wakeup_enable && (!int_enable || !egsm_enable))  		set_bit(HCD_FLAG_POLL_RH, &uhci_to_hcd(uhci)->flags);  	else  		clear_bit(HCD_FLAG_POLL_RH, &uhci_to_hcd(uhci)->flags); @@ -360,15 +382,14 @@ __acquires(uhci->lock)  static void start_rh(struct uhci_hcd *uhci)  { -	uhci_to_hcd(uhci)->state = HC_STATE_RUNNING;  	uhci->is_stopped = 0;  	/* Mark it configured and running with a 64-byte max packet.  	 * All interrupts are enabled, even though RESUME won't do anything.  	 */ -	outw(USBCMD_RS | USBCMD_CF | USBCMD_MAXP, uhci->io_addr + USBCMD); -	outw(USBINTR_TIMEOUT | USBINTR_RESUME | USBINTR_IOC | USBINTR_SP, -			uhci->io_addr + USBINTR); +	uhci_writew(uhci, USBCMD_RS | USBCMD_CF | USBCMD_MAXP, USBCMD); +	uhci_writew(uhci, USBINTR_TIMEOUT | USBINTR_RESUME | +		USBINTR_IOC | USBINTR_SP, USBINTR);  	mb();  	uhci->rh_state = UHCI_RH_RUNNING;  	set_bit(HCD_FLAG_POLL_RH, &uhci_to_hcd(uhci)->flags); @@ -391,9 +412,9 @@ __acquires(uhci->lock)  		unsigned egsm;  		/* Keep EGSM on if it was set before */ -		egsm = inw(uhci->io_addr + USBCMD) & USBCMD_EGSM; +		egsm = uhci_readw(uhci, USBCMD) & USBCMD_EGSM;  		uhci->rh_state = UHCI_RH_RESUMING; -		outw(USBCMD_FGR | USBCMD_CF | egsm, uhci->io_addr + USBCMD); +		uhci_writew(uhci, USBCMD_FGR | USBCMD_CF | egsm, USBCMD);  		spin_unlock_irq(&uhci->lock);  		msleep(20);  		spin_lock_irq(&uhci->lock); @@ -401,10 +422,10 @@ __acquires(uhci->lock)  			return;  		/* End Global Resume and wait for EOP to be sent */ -		outw(USBCMD_CF, uhci->io_addr + USBCMD); +		uhci_writew(uhci, USBCMD_CF, USBCMD);  		mb();  		udelay(4); -		if (inw(uhci->io_addr + USBCMD) & USBCMD_FGR) +		if (uhci_readw(uhci, USBCMD) & USBCMD_FGR)  			dev_warn(uhci_dev(uhci), "FGR not stopped yet!\n");  	} @@ -424,45 +445,48 @@ static irqreturn_t uhci_irq(struct usb_hcd *hcd)  	 * interrupt cause.  Contrary to the UHCI specification, the  	 * "HC Halted" status bit is persistent: it is RO, not R/WC.  	 */ -	status = inw(uhci->io_addr + USBSTS); +	status = uhci_readw(uhci, USBSTS);  	if (!(status & ~USBSTS_HCH))	/* shared interrupt, not mine */  		return IRQ_NONE; -	outw(status, uhci->io_addr + USBSTS);		/* Clear it */ +	uhci_writew(uhci, status, USBSTS);		/* Clear it */ + +	spin_lock(&uhci->lock); +	if (unlikely(!uhci->is_initialized))	/* not yet configured */ +		goto done;  	if (status & ~(USBSTS_USBINT | USBSTS_ERROR | USBSTS_RD)) {  		if (status & USBSTS_HSE) -			dev_err(uhci_dev(uhci), "host system error, " -					"PCI problems?\n"); +			dev_err(uhci_dev(uhci), +				"host system error, PCI problems?\n");  		if (status & USBSTS_HCPE) -			dev_err(uhci_dev(uhci), "host controller process " -					"error, something bad happened!\n"); +			dev_err(uhci_dev(uhci), +				"host controller process error, something bad happened!\n");  		if (status & USBSTS_HCH) { -			spin_lock(&uhci->lock);  			if (uhci->rh_state >= UHCI_RH_RUNNING) {  				dev_err(uhci_dev(uhci), -					"host controller halted, " -					"very bad!\n"); +					"host controller halted, very bad!\n");  				if (debug > 1 && errbuf) {  					/* Print the schedule for debugging */ -					uhci_sprint_schedule(uhci, -							errbuf, ERRBUF_LEN); +					uhci_sprint_schedule(uhci, errbuf, +						ERRBUF_LEN - EXTRA_SPACE);  					lprintk(errbuf);  				}  				uhci_hc_died(uhci); +				usb_hc_died(hcd);  				/* Force a callback in case there are  				 * pending unlinks */  				mod_timer(&hcd->rh_timer, jiffies);  			} -			spin_unlock(&uhci->lock);  		}  	} -	if (status & USBSTS_RD) +	if (status & USBSTS_RD) { +		spin_unlock(&uhci->lock);  		usb_hcd_poll_rh_status(hcd); -	else { -		spin_lock(&uhci->lock); +	} else {  		uhci_scan_schedule(uhci); + done:  		spin_unlock(&uhci->lock);  	} @@ -471,7 +495,7 @@ static irqreturn_t uhci_irq(struct usb_hcd *hcd)  /*   * Store the current frame number in uhci->frame_number if the controller - * is runnning.  Expand from 11 bits (of which we use only 10) to a + * is running.  Expand from 11 bits (of which we use only 10) to a   * full-sized integer.   *   * Like many other parts of the driver, this code relies on being polled @@ -482,7 +506,7 @@ static void uhci_get_current_frame_number(struct uhci_hcd *uhci)  	if (!uhci->is_stopped) {  		unsigned delta; -		delta = (inw(uhci->io_addr + USBFRNUM) - uhci->frame_number) & +		delta = (uhci_readw(uhci, USBFRNUM) - uhci->frame_number) &  				(UHCI_NUMFRAMES - 1);  		uhci->frame_number += delta;  	} @@ -495,13 +519,12 @@ static void release_uhci(struct uhci_hcd *uhci)  {  	int i; -	if (DEBUG_CONFIGURED) { -		spin_lock_irq(&uhci->lock); -		uhci->is_initialized = 0; -		spin_unlock_irq(&uhci->lock); -		debugfs_remove(uhci->dentry); -	} +	spin_lock_irq(&uhci->lock); +	uhci->is_initialized = 0; +	spin_unlock_irq(&uhci->lock); + +	debugfs_remove(uhci->dentry);  	for (i = 0; i < UHCI_NUM_SKELQH; i++)  		uhci_free_qh(uhci, uhci->skelqh[i]); @@ -519,61 +542,6 @@ static void release_uhci(struct uhci_hcd *uhci)  			uhci->frame, uhci->frame_dma_handle);  } -static int uhci_init(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.  Another common failure mode when -	 * a nonexistent register is addressed is to return all ones, so -	 * we test for that also. -	 */ -	for (port = 0; port < (io_size - USBPORTSC1) / 2; port++) { -		unsigned int portstatus; - -		portstatus = inw(uhci->io_addr + USBPORTSC1 + (port * 2)); -		if (!(portstatus & 0x0080) || portstatus == 0xffff) -			break; -	} -	if (debug) -		dev_info(uhci_dev(uhci), "detected %d ports\n", port); - -	/* Anything greater than 7 is weird so we'll ignore it. */ -	if (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. -	 */ -	check_and_reset_hc(uhci); -	return 0; -} - -/* Make sure the controller is quiescent and that we're not using it - * any more.  This is mainly for the benefit of programs which, like kexec, - * expect the hardware to be idle: not doing DMA or generating IRQs. - * - * This routine may be called in a damaged or failing kernel.  Hence we - * do not acquire the spinlock before shutting down the controller. - */ -static void uhci_shutdown(struct pci_dev *pdev) -{ -	struct usb_hcd *hcd = (struct usb_hcd *) pci_get_drvdata(pdev); - -	uhci_hc_died(hcd_to_uhci(hcd)); -} -  /*   * Allocate a frame list, and then setup the skeleton   * @@ -600,6 +568,9 @@ static int uhci_start(struct usb_hcd *hcd)  	struct dentry __maybe_unused *dentry;  	hcd->uses_new_polling = 1; +	/* Accept arbitrarily long scatter-gather lists */ +	if (!(hcd->driver->flags & HCD_LOCAL_MEM)) +		hcd->self.sg_tablesize = ~0;  	spin_lock_init(&uhci->lock);  	setup_timer(&uhci->fsbr_timer, uhci_fsbr_timeout, @@ -622,8 +593,8 @@ static int uhci_start(struct usb_hcd *hcd)  			UHCI_NUMFRAMES * sizeof(*uhci->frame),  			&uhci->frame_dma_handle, 0);  	if (!uhci->frame) { -		dev_err(uhci_dev(uhci), "unable to allocate " -				"consistent memory for frame list\n"); +		dev_err(uhci_dev(uhci), +			"unable to allocate consistent memory for frame list\n");  		goto err_alloc_frame;  	}  	memset(uhci->frame, 0, UHCI_NUMFRAMES * sizeof(*uhci->frame)); @@ -631,8 +602,8 @@ static int uhci_start(struct usb_hcd *hcd)  	uhci->frame_cpu = kcalloc(UHCI_NUMFRAMES, sizeof(*uhci->frame_cpu),  			GFP_KERNEL);  	if (!uhci->frame_cpu) { -		dev_err(uhci_dev(uhci), "unable to allocate " -				"memory for frame pointers\n"); +		dev_err(uhci_dev(uhci), +			"unable to allocate memory for frame pointers\n");  		goto err_alloc_frame_cpu;  	} @@ -668,16 +639,16 @@ static int uhci_start(struct usb_hcd *hcd)  	 * 8 Interrupt queues; link all higher int queues to int1 = async  	 */  	for (i = SKEL_ISO + 1; i < SKEL_ASYNC; ++i) -		uhci->skelqh[i]->link = LINK_TO_QH(uhci->skel_async_qh); -	uhci->skel_async_qh->link = UHCI_PTR_TERM; -	uhci->skel_term_qh->link = LINK_TO_QH(uhci->skel_term_qh); +		uhci->skelqh[i]->link = LINK_TO_QH(uhci, uhci->skel_async_qh); +	uhci->skel_async_qh->link = UHCI_PTR_TERM(uhci); +	uhci->skel_term_qh->link = LINK_TO_QH(uhci, uhci->skel_term_qh);  	/* This dummy TD is to work around a bug in Intel PIIX controllers */ -	uhci_fill_td(uhci->term_td, 0, uhci_explen(0) | +	uhci_fill_td(uhci, uhci->term_td, 0, uhci_explen(0) |  			(0x7f << TD_TOKEN_DEVADDR_SHIFT) | USB_PID_IN, 0); -	uhci->term_td->link = UHCI_PTR_TERM; +	uhci->term_td->link = UHCI_PTR_TERM(uhci);  	uhci->skel_async_qh->element = uhci->skel_term_qh->element = -			LINK_TO_TD(uhci->term_td); +		LINK_TO_TD(uhci, uhci->term_td);  	/*  	 * Fill the frame list: make all entries point to the proper @@ -695,9 +666,9 @@ static int uhci_start(struct usb_hcd *hcd)  	 */  	mb(); +	spin_lock_irq(&uhci->lock);  	configure_hc(uhci);  	uhci->is_initialized = 1; -	spin_lock_irq(&uhci->lock);  	start_rh(uhci);  	spin_unlock_irq(&uhci->lock);  	return 0; @@ -767,8 +738,8 @@ static int uhci_rh_suspend(struct usb_hcd *hcd)  	 */  	else if (hcd->self.root_hub->do_remote_wakeup &&  			uhci->resuming_ports) { -		dev_dbg(uhci_dev(uhci), "suspend failed because a port " -				"is resuming\n"); +		dev_dbg(uhci_dev(uhci), +			"suspend failed because a port is resuming\n");  		rc = -EBUSY;  	} else  		suspend_rh(uhci, UHCI_RH_SUSPENDED); @@ -790,86 +761,6 @@ static int uhci_rh_resume(struct usb_hcd *hcd)  	return rc;  } -static int uhci_pci_suspend(struct usb_hcd *hcd, bool do_wakeup) -{ -	struct uhci_hcd *uhci = hcd_to_uhci(hcd); -	struct pci_dev *pdev = to_pci_dev(uhci_dev(uhci)); -	int rc = 0; - -	dev_dbg(uhci_dev(uhci), "%s\n", __func__); - -	spin_lock_irq(&uhci->lock); -	if (!HCD_HW_ACCESSIBLE(hcd) || uhci->dead) -		goto done_okay;		/* Already suspended or dead */ - -	if (uhci->rh_state > UHCI_RH_SUSPENDED) { -		dev_warn(uhci_dev(uhci), "Root hub isn't suspended!\n"); -		rc = -EBUSY; -		goto done; -	}; - -	/* All PCI host controllers are required to disable IRQ generation -	 * at the source, so we must turn off PIRQ. -	 */ -	pci_write_config_word(pdev, USBLEGSUP, 0); -	clear_bit(HCD_FLAG_POLL_RH, &hcd->flags); - -	/* Enable platform-specific non-PME# wakeup */ -	if (do_wakeup) { -		if (pdev->vendor == PCI_VENDOR_ID_INTEL) -			pci_write_config_byte(pdev, USBRES_INTEL, -					USBPORT1EN | USBPORT2EN); -	} - -done_okay: -	clear_bit(HCD_FLAG_HW_ACCESSIBLE, &hcd->flags); -done: -	spin_unlock_irq(&uhci->lock); -	return rc; -} - -static int uhci_pci_resume(struct usb_hcd *hcd, bool hibernated) -{ -	struct uhci_hcd *uhci = hcd_to_uhci(hcd); - -	dev_dbg(uhci_dev(uhci), "%s\n", __func__); - -	/* Since we aren't in D3 any more, it's safe to set this flag -	 * even if the controller was dead. -	 */ -	set_bit(HCD_FLAG_HW_ACCESSIBLE, &hcd->flags); - -	spin_lock_irq(&uhci->lock); - -	/* Make sure resume from hibernation re-enumerates everything */ -	if (hibernated) -		uhci_hc_died(uhci); - -	/* The firmware or a boot kernel may have changed the controller -	 * settings during a system wakeup.  Check it and reconfigure -	 * to avoid problems. -	 */ -	check_and_reset_hc(uhci); - -	/* If the controller was dead before, it's back alive now */ -	configure_hc(uhci); - -	/* Tell the core if the controller had to be reset */ -	if (uhci->rh_state == UHCI_RH_RESET) -		usb_root_hub_lost_power(hcd->self.root_hub); - -	spin_unlock_irq(&uhci->lock); - -	/* If interrupts don't work and remote wakeup is enabled then -	 * the suspended root hub needs to be polled. -	 */ -	if (!uhci->RD_enable && hcd->self.root_hub->do_remote_wakeup) -		set_bit(HCD_FLAG_POLL_RH, &hcd->flags); - -	/* Does the root hub have a port wakeup pending? */ -	usb_hcd_poll_rh_status(hcd); -	return 0; -}  #endif  /* Wait until a particular device/endpoint's QH is idle, and free it */ @@ -907,67 +798,67 @@ static int uhci_hcd_get_frame_number(struct usb_hcd *hcd)  	/* Minimize latency by avoiding the spinlock */  	frame_number = uhci->frame_number;  	barrier(); -	delta = (inw(uhci->io_addr + USBFRNUM) - frame_number) & +	delta = (uhci_readw(uhci, USBFRNUM) - frame_number) &  			(UHCI_NUMFRAMES - 1);  	return frame_number + delta;  } -static const char hcd_name[] = "uhci_hcd"; - -static const struct hc_driver uhci_driver = { -	.description =		hcd_name, -	.product_desc =		"UHCI Host Controller", -	.hcd_priv_size =	sizeof(struct uhci_hcd), - -	/* Generic hardware linkage */ -	.irq =			uhci_irq, -	.flags =		HCD_USB11, +/* Determines number of ports on controller */ +static int uhci_count_ports(struct usb_hcd *hcd) +{ +	struct uhci_hcd *uhci = hcd_to_uhci(hcd); +	unsigned io_size = (unsigned) hcd->rsrc_len; +	int port; -	/* Basic lifecycle operations */ -	.reset =		uhci_init, -	.start =		uhci_start, -#ifdef CONFIG_PM -	.pci_suspend =		uhci_pci_suspend, -	.pci_resume =		uhci_pci_resume, -	.bus_suspend =		uhci_rh_suspend, -	.bus_resume =		uhci_rh_resume, -#endif -	.stop =			uhci_stop, +	/* 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.  Another common failure mode when +	 * a nonexistent register is addressed is to return all ones, so +	 * we test for that also. +	 */ +	for (port = 0; port < (io_size - USBPORTSC1) / 2; port++) { +		unsigned int portstatus; -	.urb_enqueue =		uhci_urb_enqueue, -	.urb_dequeue =		uhci_urb_dequeue, +		portstatus = uhci_readw(uhci, USBPORTSC1 + (port * 2)); +		if (!(portstatus & 0x0080) || portstatus == 0xffff) +			break; +	} +	if (debug) +		dev_info(uhci_dev(uhci), "detected %d ports\n", port); -	.endpoint_disable =	uhci_hcd_endpoint_disable, -	.get_frame_number =	uhci_hcd_get_frame_number, +	/* Anything greater than 7 is weird so we'll ignore it. */ +	if (port > UHCI_RH_MAXCHILD) { +		dev_info(uhci_dev(uhci), +			"port count misdetected? forcing to 2 ports\n"); +		port = 2; +	} -	.hub_status_data =	uhci_hub_status_data, -	.hub_control =		uhci_hub_control, -}; +	return port; +} -static const struct pci_device_id uhci_pci_ids[] = { { -	/* handle any USB UHCI controller */ -	PCI_DEVICE_CLASS(PCI_CLASS_SERIAL_USB_UHCI, ~0), -	.driver_data =	(unsigned long) &uhci_driver, -	}, { /* end: all zeroes */ } -}; +static const char hcd_name[] = "uhci_hcd"; -MODULE_DEVICE_TABLE(pci, uhci_pci_ids); +#ifdef CONFIG_PCI +#include "uhci-pci.c" +#define	PCI_DRIVER		uhci_pci_driver +#endif -static struct pci_driver uhci_pci_driver = { -	.name =		(char *)hcd_name, -	.id_table =	uhci_pci_ids, +#ifdef CONFIG_SPARC_LEON +#include "uhci-grlib.c" +#define PLATFORM_DRIVER		uhci_grlib_driver +#endif -	.probe =	usb_hcd_pci_probe, -	.remove =	usb_hcd_pci_remove, -	.shutdown =	uhci_shutdown, +#ifdef CONFIG_USB_UHCI_PLATFORM +#include "uhci-platform.c" +#define PLATFORM_DRIVER		uhci_platform_driver +#endif -#ifdef CONFIG_PM_SLEEP -	.driver =	{ -		.pm =	&usb_hcd_pci_pm_ops -	}, +#if !defined(PCI_DRIVER) && !defined(PLATFORM_DRIVER) +#error "missing bus glue for uhci-hcd"  #endif -}; -  +  static int __init uhci_hcd_init(void)  {  	int retval = -ENOMEM; @@ -979,36 +870,52 @@ static int __init uhci_hcd_init(void)  			ignore_oc ? ", overcurrent ignored" : "");  	set_bit(USB_UHCI_LOADED, &usb_hcds_loaded); -	if (DEBUG_CONFIGURED) { -		errbuf = kmalloc(ERRBUF_LEN, GFP_KERNEL); -		if (!errbuf) -			goto errbuf_failed; -		uhci_debugfs_root = debugfs_create_dir("uhci", usb_debug_root); -		if (!uhci_debugfs_root) -			goto debug_failed; -	} +#ifdef CONFIG_DYNAMIC_DEBUG +	errbuf = kmalloc(ERRBUF_LEN, GFP_KERNEL); +	if (!errbuf) +		goto errbuf_failed; +	uhci_debugfs_root = debugfs_create_dir("uhci", usb_debug_root); +	if (!uhci_debugfs_root) +		goto debug_failed; +#endif  	uhci_up_cachep = kmem_cache_create("uhci_urb_priv",  		sizeof(struct urb_priv), 0, 0, NULL);  	if (!uhci_up_cachep)  		goto up_failed; -	retval = pci_register_driver(&uhci_pci_driver); -	if (retval) -		goto init_failed; +#ifdef PLATFORM_DRIVER +	retval = platform_driver_register(&PLATFORM_DRIVER); +	if (retval < 0) +		goto clean0; +#endif + +#ifdef PCI_DRIVER +	retval = pci_register_driver(&PCI_DRIVER); +	if (retval < 0) +		goto clean1; +#endif  	return 0; -init_failed: +#ifdef PCI_DRIVER +clean1: +#endif +#ifdef PLATFORM_DRIVER +	platform_driver_unregister(&PLATFORM_DRIVER); +clean0: +#endif  	kmem_cache_destroy(uhci_up_cachep);  up_failed: +#if defined(DEBUG) || defined(CONFIG_DYNAMIC_DEBUG)  	debugfs_remove(uhci_debugfs_root);  debug_failed:  	kfree(errbuf);  errbuf_failed: +#endif  	clear_bit(USB_UHCI_LOADED, &usb_hcds_loaded);  	return retval; @@ -1016,10 +923,17 @@ errbuf_failed:  static void __exit uhci_hcd_cleanup(void)   { -	pci_unregister_driver(&uhci_pci_driver); +#ifdef PLATFORM_DRIVER +	platform_driver_unregister(&PLATFORM_DRIVER); +#endif +#ifdef PCI_DRIVER +	pci_unregister_driver(&PCI_DRIVER); +#endif  	kmem_cache_destroy(uhci_up_cachep);  	debugfs_remove(uhci_debugfs_root); +#ifdef CONFIG_DYNAMIC_DEBUG  	kfree(errbuf); +#endif  	clear_bit(USB_UHCI_LOADED, &usb_hcds_loaded);  }  | 
