linux/drivers/usb/host/ehci-hcd.c

// SPDX-License-Identifier: GPL-2.0+
/*
 * Enhanced Host Controller Interface (EHCI) driver for USB.
 *
 * Maintainer: Alan Stern <[email protected]>
 *
 * Copyright (c) 2000-2004 by David Brownell
 */

#include <linux/module.h>
#include <linux/pci.h>
#include <linux/dmapool.h>
#include <linux/kernel.h>
#include <linux/delay.h>
#include <linux/ioport.h>
#include <linux/sched.h>
#include <linux/vmalloc.h>
#include <linux/errno.h>
#include <linux/init.h>
#include <linux/hrtimer.h>
#include <linux/list.h>
#include <linux/interrupt.h>
#include <linux/usb.h>
#include <linux/usb/hcd.h>
#include <linux/usb/otg.h>
#include <linux/moduleparam.h>
#include <linux/dma-mapping.h>
#include <linux/debugfs.h>
#include <linux/platform_device.h>
#include <linux/slab.h>

#include <asm/byteorder.h>
#include <asm/io.h>
#include <asm/irq.h>
#include <asm/unaligned.h>

#if defined(CONFIG_PPC_PS3)
#include <asm/firmware.h>
#endif

/*-------------------------------------------------------------------------*/

/*
 * EHCI hc_driver implementation ... experimental, incomplete.
 * Based on the final 1.0 register interface specification.
 *
 * USB 2.0 shows up in upcoming www.pcmcia.org technology.
 * First was PCMCIA, like ISA; then CardBus, which is PCI.
 * Next comes "CardBay", using USB 2.0 signals.
 *
 * Contains additional contributions by Brad Hards, Rory Bolt, and others.
 * Special thanks to Intel and VIA for providing host controllers to
 * test this driver on, and Cypress (including In-System Design) for
 * providing early devices for those host controllers to talk to!
 */

#define DRIVER_AUTHOR
#define DRIVER_DESC

static const char	hcd_name [] =;


#undef EHCI_URB_TRACE

/* magic numbers that can affect system performance */
#define EHCI_TUNE_CERR
#define EHCI_TUNE_RL_HS
#define EHCI_TUNE_RL_TT
#define EHCI_TUNE_MULT_HS
#define EHCI_TUNE_MULT_TT
/*
 * Some drivers think it's safe to schedule isochronous transfers more than
 * 256 ms into the future (partly as a result of an old bug in the scheduling
 * code).  In an attempt to avoid trouble, we will use a minimum scheduling
 * length of 512 frames instead of 256.
 */
#define EHCI_TUNE_FLS

/* Initial IRQ latency:  faster than hw default */
static int log2_irq_thresh;		// 0 to 6
module_param (log2_irq_thresh, int, S_IRUGO);
MODULE_PARM_DESC();

/* initial park setting:  slower than hw default */
static unsigned park;
module_param (park, uint, S_IRUGO);
MODULE_PARM_DESC();

/* for flakey hardware, ignore overcurrent indicators */
static bool ignore_oc;
module_param (ignore_oc, bool, S_IRUGO);
MODULE_PARM_DESC();

#define INTR_MASK

/*-------------------------------------------------------------------------*/

#include "ehci.h"
#include "pci-quirks.h"

static void compute_tt_budget(u8 budget_table[EHCI_BANDWIDTH_SIZE],
		struct ehci_tt *tt);

/*
 * The MosChip MCS9990 controller updates its microframe counter
 * a little before the frame counter, and occasionally we will read
 * the invalid intermediate value.  Avoid problems by checking the
 * microframe number (the low-order 3 bits); if they are 0 then
 * re-read the register to get the correct value.
 */
static unsigned ehci_moschip_read_frame_index(struct ehci_hcd *ehci)
{}

static inline unsigned ehci_read_frame_index(struct ehci_hcd *ehci)
{}

#include "ehci-dbg.c"

/*-------------------------------------------------------------------------*/

/*
 * ehci_handshake - spin reading hc until handshake completes or fails
 * @ptr: address of hc register to be read
 * @mask: bits to look at in result of read
 * @done: value of those bits when handshake succeeds
 * @usec: timeout in microseconds
 *
 * Returns negative errno, or zero on success
 *
 * Success happens when the "mask" bits have the specified value (hardware
 * handshake done).  There are two failure modes:  "usec" have passed (major
 * hardware flakeout), or the register reads as all-ones (hardware removed).
 *
 * That last failure should_only happen in cases like physical cardbus eject
 * before driver shutdown. But it also seems to be caused by bugs in cardbus
 * bridge shutdown:  shutting down the bridge before the devices using it.
 */
int ehci_handshake(struct ehci_hcd *ehci, void __iomem *ptr,
		   u32 mask, u32 done, int usec)
{}
EXPORT_SYMBOL_GPL();

/* check TDI/ARC silicon is in host mode */
static int tdi_in_host_mode (struct ehci_hcd *ehci)
{}

/*
 * Force HC to halt state from unknown (EHCI spec section 2.3).
 * Must be called with interrupts enabled and the lock not held.
 */
static int ehci_halt (struct ehci_hcd *ehci)
{}

/* put TDI/ARC silicon into EHCI mode */
static void tdi_reset (struct ehci_hcd *ehci)
{}

/*
 * Reset a non-running (STS_HALT == 1) controller.
 * Must be called with interrupts enabled and the lock not held.
 */
int ehci_reset(struct ehci_hcd *ehci)
{}
EXPORT_SYMBOL_GPL();

/*
 * Idle the controller (turn off the schedules).
 * Must be called with interrupts enabled and the lock not held.
 */
static void ehci_quiesce (struct ehci_hcd *ehci)
{}

/*-------------------------------------------------------------------------*/

static void end_iaa_cycle(struct ehci_hcd *ehci);
static void end_unlink_async(struct ehci_hcd *ehci);
static void unlink_empty_async(struct ehci_hcd *ehci);
static void ehci_work(struct ehci_hcd *ehci);
static void start_unlink_intr(struct ehci_hcd *ehci, struct ehci_qh *qh);
static void end_unlink_intr(struct ehci_hcd *ehci, struct ehci_qh *qh);
static int ehci_port_power(struct ehci_hcd *ehci, int portnum, bool enable);

#include "ehci-timer.c"
#include "ehci-hub.c"
#include "ehci-mem.c"
#include "ehci-q.c"
#include "ehci-sched.c"
#include "ehci-sysfs.c"

/*-------------------------------------------------------------------------*/

/* On some systems, leaving remote wakeup enabled prevents system shutdown.
 * The firmware seems to think that powering off is a wakeup event!
 * This routine turns off remote wakeup and everything else, on all ports.
 */
static void ehci_turn_off_all_ports(struct ehci_hcd *ehci)
{}

/*
 * Halt HC, turn off all ports, and let the BIOS use the companion controllers.
 * Must be called with interrupts enabled and the lock not held.
 */
static void ehci_silence_controller(struct ehci_hcd *ehci)
{}

/* ehci_shutdown kick in for silicon on any bus (not just pci, etc).
 * This forcibly disables dma and IRQs, helping kexec and other cases
 * where the next system software may expect clean state.
 */
static void ehci_shutdown(struct usb_hcd *hcd)
{}

/*-------------------------------------------------------------------------*/

/*
 * ehci_work is called from some interrupts, timers, and so on.
 * it calls driver completion functions, after dropping ehci->lock.
 */
static void ehci_work (struct ehci_hcd *ehci)
{}

/*
 * Called when the ehci_hcd module is removed.
 */
static void ehci_stop (struct usb_hcd *hcd)
{}

/* one-time init, only for memory state */
static int ehci_init(struct usb_hcd *hcd)
{}

/* start HC running; it's halted, ehci_init() has been run (once) */
static int ehci_run (struct usb_hcd *hcd)
{}

int ehci_setup(struct usb_hcd *hcd)
{}
EXPORT_SYMBOL_GPL();

/*-------------------------------------------------------------------------*/

static irqreturn_t ehci_irq (struct usb_hcd *hcd)
{}

/*-------------------------------------------------------------------------*/

/*
 * non-error returns are a promise to giveback() the urb later
 * we drop ownership so next owner (or urb unlink) can get it
 *
 * urb + dev is in hcd.self.controller.urb_list
 * we're queueing TDs onto software and hardware lists
 *
 * hcd-specific init for hcpriv hasn't been done yet
 *
 * NOTE:  control, bulk, and interrupt share the same code to append TDs
 * to a (possibly active) QH, and the same QH scanning code.
 */
static int ehci_urb_enqueue (
	struct usb_hcd	*hcd,
	struct urb	*urb,
	gfp_t		mem_flags
) {}

/* remove from hardware lists
 * completions normally happen asynchronously
 */

static int ehci_urb_dequeue(struct usb_hcd *hcd, struct urb *urb, int status)
{}

/*-------------------------------------------------------------------------*/

// bulk qh holds the data toggle

static void
ehci_endpoint_disable (struct usb_hcd *hcd, struct usb_host_endpoint *ep)
{}

static void
ehci_endpoint_reset(struct usb_hcd *hcd, struct usb_host_endpoint *ep)
{}

static int ehci_get_frame (struct usb_hcd *hcd)
{}

/*-------------------------------------------------------------------------*/

/* Device addition and removal */

static void ehci_remove_device(struct usb_hcd *hcd, struct usb_device *udev)
{}

/*-------------------------------------------------------------------------*/

#ifdef	CONFIG_PM

/* Clear wakeup signal locked in zhaoxin platform when device plug in. */
static void ehci_zx_wakeup_clear(struct ehci_hcd *ehci)
{}

/* suspend/resume, section 4.3 */

/* These routines handle the generic parts of controller suspend/resume */

int ehci_suspend(struct usb_hcd *hcd, bool do_wakeup)
{}
EXPORT_SYMBOL_GPL();

/* Returns 0 if power was preserved, 1 if power was lost */
int ehci_resume(struct usb_hcd *hcd, bool force_reset)
{}
EXPORT_SYMBOL_GPL();

#endif

/*-------------------------------------------------------------------------*/

/*
 * Generic structure: This gets copied for platform drivers so that
 * individual entries can be overridden as needed.
 */

static const struct hc_driver ehci_hc_driver =;

void ehci_init_driver(struct hc_driver *drv,
		const struct ehci_driver_overrides *over)
{}
EXPORT_SYMBOL_GPL();

/*-------------------------------------------------------------------------*/

MODULE_DESCRIPTION();
MODULE_AUTHOR();
MODULE_LICENSE();

#ifdef CONFIG_USB_EHCI_SH
#include "ehci-sh.c"
#endif

#ifdef CONFIG_PPC_PS3
#include "ehci-ps3.c"
#endif

#ifdef CONFIG_USB_EHCI_HCD_PPC_OF
#include "ehci-ppc-of.c"
#endif

#ifdef CONFIG_XPS_USB_HCD_XILINX
#include "ehci-xilinx-of.c"
#endif

#ifdef CONFIG_SPARC_LEON
#include "ehci-grlib.c"
#endif

static struct platform_driver * const platform_drivers[] =;

static int __init ehci_hcd_init(void)
{}
module_init();

static void __exit ehci_hcd_cleanup(void)
{}
module_exit(ehci_hcd_cleanup);