linux/drivers/usb/fotg210/fotg210-hcd.c

// SPDX-License-Identifier: GPL-2.0+
/* Faraday FOTG210 EHCI-like driver
 *
 * Copyright (c) 2013 Faraday Technology Corporation
 *
 * Author: Yuan-Hsin Chen <[email protected]>
 *	   Feng-Hsin Chiang <[email protected]>
 *	   Po-Yu Chuang <[email protected]>
 *
 * Most of code borrowed from the Linux-3.7 EHCI driver
 */
#include <linux/module.h>
#include <linux/of.h>
#include <linux/device.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/moduleparam.h>
#include <linux/dma-mapping.h>
#include <linux/debugfs.h>
#include <linux/slab.h>
#include <linux/uaccess.h>
#include <linux/platform_device.h>
#include <linux/io.h>
#include <linux/iopoll.h>

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

#include "fotg210.h"

static const char hcd_name[] =;

#undef FOTG210_URB_TRACE
#define FOTG210_STATS

/* magic numbers that can affect system performance */
#define FOTG210_TUNE_CERR
#define FOTG210_TUNE_RL_HS
#define FOTG210_TUNE_RL_TT
#define FOTG210_TUNE_MULT_HS
#define FOTG210_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 FOTG210_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 link power management(LPM) feature */
static unsigned int hird;
module_param(hird, int, S_IRUGO);
MODULE_PARM_DESC();

#define INTR_MASK

#include "fotg210-hcd.h"

#define fotg210_dbg(fotg210, fmt, args...)
#define fotg210_err(fotg210, fmt, args...)
#define fotg210_info(fotg210, fmt, args...)
#define fotg210_warn(fotg210, fmt, args...)

/* check the values in the HCSPARAMS register (host controller _Structural_
 * parameters) see EHCI spec, Table 2-4 for each value
 */
static void dbg_hcs_params(struct fotg210_hcd *fotg210, char *label)
{}

/* check the values in the HCCPARAMS register (host controller _Capability_
 * parameters) see EHCI Spec, Table 2-5 for each value
 */
static void dbg_hcc_params(struct fotg210_hcd *fotg210, char *label)
{}

static void __maybe_unused
dbg_qtd(const char *label, struct fotg210_hcd *fotg210, struct fotg210_qtd *qtd)
{}

static void __maybe_unused
dbg_qh(const char *label, struct fotg210_hcd *fotg210, struct fotg210_qh *qh)
{}

static void __maybe_unused
dbg_itd(const char *label, struct fotg210_hcd *fotg210, struct fotg210_itd *itd)
{}

static int __maybe_unused
dbg_status_buf(char *buf, unsigned len, const char *label, u32 status)
{}

static int __maybe_unused
dbg_intr_buf(char *buf, unsigned len, const char *label, u32 enable)
{}

static const char *const fls_strings[] =;

static int dbg_command_buf(char *buf, unsigned len, const char *label,
		u32 command)
{}

static char *dbg_port_buf(char *buf, unsigned len, const char *label, int port,
		u32 status)
{}

/* functions have the "wrong" filename when they're output... */
#define dbg_status(fotg210, label, status)

#define dbg_cmd(fotg210, label, command)

#define dbg_port(fotg210, label, port, status)

/* troubleshooting help: expose state in debugfs */
static int debug_async_open(struct inode *, struct file *);
static int debug_periodic_open(struct inode *, struct file *);
static int debug_registers_open(struct inode *, struct file *);
static int debug_async_open(struct inode *, struct file *);

static ssize_t debug_output(struct file*, char __user*, size_t, loff_t*);
static int debug_close(struct inode *, struct file *);

static const struct file_operations debug_async_fops =;
static const struct file_operations debug_periodic_fops =;
static const struct file_operations debug_registers_fops =;

static struct dentry *fotg210_debug_root;

struct debug_buffer {};

static inline char speed_char(u32 scratch)
{}

static inline char token_mark(struct fotg210_hcd *fotg210, __hc32 token)
{}

static void qh_lines(struct fotg210_hcd *fotg210, struct fotg210_qh *qh,
		char **nextp, unsigned *sizep)
{}

static ssize_t fill_async_buffer(struct debug_buffer *buf)
{}

/* count tds, get ep direction */
static unsigned output_buf_tds_dir(char *buf, struct fotg210_hcd *fotg210,
		struct fotg210_qh_hw *hw, struct fotg210_qh *qh, unsigned size)
{}

#define DBG_SCHED_LIMIT
static ssize_t fill_periodic_buffer(struct debug_buffer *buf)
{}
#undef DBG_SCHED_LIMIT

static const char *rh_state_string(struct fotg210_hcd *fotg210)
{}

static ssize_t fill_registers_buffer(struct debug_buffer *buf)
{}

static struct debug_buffer
*alloc_buffer(struct usb_bus *bus, ssize_t (*fill_func)(struct debug_buffer *))
{}

static int fill_buffer(struct debug_buffer *buf)
{}

static ssize_t debug_output(struct file *file, char __user *user_buf,
		size_t len, loff_t *offset)
{}

static int debug_close(struct inode *inode, struct file *file)
{}
static int debug_async_open(struct inode *inode, struct file *file)
{}

static int debug_periodic_open(struct inode *inode, struct file *file)
{}

static int debug_registers_open(struct inode *inode, struct file *file)
{}

static inline void create_debug_files(struct fotg210_hcd *fotg210)
{}

static inline void remove_debug_files(struct fotg210_hcd *fotg210)
{}

/* 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.
 */
static int handshake(struct fotg210_hcd *fotg210, void __iomem *ptr,
		u32 mask, u32 done, int usec)
{}

/* 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 fotg210_halt(struct fotg210_hcd *fotg210)
{}

/* Reset a non-running (STS_HALT == 1) controller.
 * Must be called with interrupts enabled and the lock not held.
 */
static int fotg210_reset(struct fotg210_hcd *fotg210)
{}

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

static void end_unlink_async(struct fotg210_hcd *fotg210);
static void unlink_empty_async(struct fotg210_hcd *fotg210);
static void fotg210_work(struct fotg210_hcd *fotg210);
static void start_unlink_intr(struct fotg210_hcd *fotg210,
			      struct fotg210_qh *qh);
static void end_unlink_intr(struct fotg210_hcd *fotg210, struct fotg210_qh *qh);

/* Set a bit in the USBCMD register */
static void fotg210_set_command_bit(struct fotg210_hcd *fotg210, u32 bit)
{}

/* Clear a bit in the USBCMD register */
static void fotg210_clear_command_bit(struct fotg210_hcd *fotg210, u32 bit)
{}

/* EHCI timer support...  Now using hrtimers.
 *
 * Lots of different events are triggered from fotg210->hrtimer.  Whenever
 * the timer routine runs, it checks each possible event; events that are
 * currently enabled and whose expiration time has passed get handled.
 * The set of enabled events is stored as a collection of bitflags in
 * fotg210->enabled_hrtimer_events, and they are numbered in order of
 * increasing delay values (ranging between 1 ms and 100 ms).
 *
 * Rather than implementing a sorted list or tree of all pending events,
 * we keep track only of the lowest-numbered pending event, in
 * fotg210->next_hrtimer_event.  Whenever fotg210->hrtimer gets restarted, its
 * expiration time is set to the timeout value for this event.
 *
 * As a result, events might not get handled right away; the actual delay
 * could be anywhere up to twice the requested delay.  This doesn't
 * matter, because none of the events are especially time-critical.  The
 * ones that matter most all have a delay of 1 ms, so they will be
 * handled after 2 ms at most, which is okay.  In addition to this, we
 * allow for an expiration range of 1 ms.
 */

/* Delay lengths for the hrtimer event types.
 * Keep this list sorted by delay length, in the same order as
 * the event types indexed by enum fotg210_hrtimer_event in fotg210.h.
 */
static unsigned event_delays_ns[] =;

/* Enable a pending hrtimer event */
static void fotg210_enable_event(struct fotg210_hcd *fotg210, unsigned event,
		bool resched)
{}


/* Poll the STS_ASS status bit; see when it agrees with CMD_ASE */
static void fotg210_poll_ASS(struct fotg210_hcd *fotg210)
{}

/* Turn off the async schedule after a brief delay */
static void fotg210_disable_ASE(struct fotg210_hcd *fotg210)
{}


/* Poll the STS_PSS status bit; see when it agrees with CMD_PSE */
static void fotg210_poll_PSS(struct fotg210_hcd *fotg210)
{}

/* Turn off the periodic schedule after a brief delay */
static void fotg210_disable_PSE(struct fotg210_hcd *fotg210)
{}


/* Poll the STS_HALT status bit; see when a dead controller stops */
static void fotg210_handle_controller_death(struct fotg210_hcd *fotg210)
{}


/* Handle unlinked interrupt QHs once they are gone from the hardware */
static void fotg210_handle_intr_unlinks(struct fotg210_hcd *fotg210)
{}


/* Start another free-iTDs/siTDs cycle */
static void start_free_itds(struct fotg210_hcd *fotg210)
{}

/* Wait for controller to stop using old iTDs and siTDs */
static void end_free_itds(struct fotg210_hcd *fotg210)
{}


/* Handle lost (or very late) IAA interrupts */
static void fotg210_iaa_watchdog(struct fotg210_hcd *fotg210)
{}


/* Enable the I/O watchdog, if appropriate */
static void turn_on_io_watchdog(struct fotg210_hcd *fotg210)
{}


/* Handler functions for the hrtimer event types.
 * Keep this array in the same order as the event types indexed by
 * enum fotg210_hrtimer_event in fotg210.h.
 */
static void (*event_handlers[])(struct fotg210_hcd *) =;

static enum hrtimer_restart fotg210_hrtimer_func(struct hrtimer *t)
{}

#define fotg210_bus_suspend
#define fotg210_bus_resume

static int check_reset_complete(struct fotg210_hcd *fotg210, int index,
		u32 __iomem *status_reg, int port_status)
{}


/* build "status change" packet (one or two bytes) from HC registers */

static int fotg210_hub_status_data(struct usb_hcd *hcd, char *buf)
{}

static void fotg210_hub_descriptor(struct fotg210_hcd *fotg210,
		struct usb_hub_descriptor *desc)
{}

static int fotg210_hub_control(struct usb_hcd *hcd, u16 typeReq, u16 wValue,
		u16 wIndex, char *buf, u16 wLength)
{}

static void __maybe_unused fotg210_relinquish_port(struct usb_hcd *hcd,
		int portnum)
{}

static int __maybe_unused fotg210_port_handed_over(struct usb_hcd *hcd,
		int portnum)
{}

/* There's basically three types of memory:
 *	- data used only by the HCD ... kmalloc is fine
 *	- async and periodic schedules, shared by HC and HCD ... these
 *	  need to use dma_pool or dma_alloc_coherent
 *	- driver buffers, read/written by HC ... single shot DMA mapped
 *
 * There's also "register" data (e.g. PCI or SOC), which is memory mapped.
 * No memory seen by this driver is pageable.
 */

/* Allocate the key transfer structures from the previously allocated pool */
static inline void fotg210_qtd_init(struct fotg210_hcd *fotg210,
		struct fotg210_qtd *qtd, dma_addr_t dma)
{}

static struct fotg210_qtd *fotg210_qtd_alloc(struct fotg210_hcd *fotg210,
		gfp_t flags)
{}

static inline void fotg210_qtd_free(struct fotg210_hcd *fotg210,
		struct fotg210_qtd *qtd)
{}


static void qh_destroy(struct fotg210_hcd *fotg210, struct fotg210_qh *qh)
{}

static struct fotg210_qh *fotg210_qh_alloc(struct fotg210_hcd *fotg210,
		gfp_t flags)
{}

/* The queue heads and transfer descriptors are managed from pools tied
 * to each of the "per device" structures.
 * This is the initialisation and cleanup code.
 */

static void fotg210_mem_cleanup(struct fotg210_hcd *fotg210)
{}

/* remember to add cleanup code (above) if you add anything here */
static int fotg210_mem_init(struct fotg210_hcd *fotg210, gfp_t flags)
{}
/* EHCI hardware queue manipulation ... the core.  QH/QTD manipulation.
 *
 * Control, bulk, and interrupt traffic all use "qh" lists.  They list "qtd"
 * entries describing USB transactions, max 16-20kB/entry (with 4kB-aligned
 * buffers needed for the larger number).  We use one QH per endpoint, queue
 * multiple urbs (all three types) per endpoint.  URBs may need several qtds.
 *
 * ISO traffic uses "ISO TD" (itd) records, and (along with
 * interrupts) needs careful scheduling.  Performance improvements can be
 * an ongoing challenge.  That's in "ehci-sched.c".
 *
 * USB 1.1 devices are handled (a) by "companion" OHCI or UHCI root hubs,
 * or otherwise through transaction translators (TTs) in USB 2.0 hubs using
 * (b) special fields in qh entries or (c) split iso entries.  TTs will
 * buffer low/full speed data so the host collects it at high speed.
 */

/* fill a qtd, returning how much of the buffer we were able to queue up */
static int qtd_fill(struct fotg210_hcd *fotg210, struct fotg210_qtd *qtd,
		dma_addr_t buf, size_t len, int token, int maxpacket)
{}

static inline void qh_update(struct fotg210_hcd *fotg210,
		struct fotg210_qh *qh, struct fotg210_qtd *qtd)
{}

/* if it weren't for a common silicon quirk (writing the dummy into the qh
 * overlay, so qh->hw_token wrongly becomes inactive/halted), only fault
 * recovery (including urb dequeue) would need software changes to a QH...
 */
static void qh_refresh(struct fotg210_hcd *fotg210, struct fotg210_qh *qh)
{}

static void qh_link_async(struct fotg210_hcd *fotg210, struct fotg210_qh *qh);

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

static void fotg210_clear_tt_buffer(struct fotg210_hcd *fotg210,
		struct fotg210_qh *qh, struct urb *urb, u32 token)
{}

static int qtd_copy_status(struct fotg210_hcd *fotg210, struct urb *urb,
		size_t length, u32 token)
{}

static void fotg210_urb_done(struct fotg210_hcd *fotg210, struct urb *urb,
		int status)
__releases(fotg210->lock)
__acquires(fotg210->lock)
{}

static int qh_schedule(struct fotg210_hcd *fotg210, struct fotg210_qh *qh);

/* Process and free completed qtds for a qh, returning URBs to drivers.
 * Chases up to qh->hw_current.  Returns number of completions called,
 * indicating how much "real" work we did.
 */
static unsigned qh_completions(struct fotg210_hcd *fotg210,
		struct fotg210_qh *qh)
{}

/* reverse of qh_urb_transaction:  free a list of TDs.
 * used for cleanup after errors, before HC sees an URB's TDs.
 */
static void qtd_list_free(struct fotg210_hcd *fotg210, struct urb *urb,
		struct list_head *head)
{}

/* create a list of filled qtds for this URB; won't link into qh.
 */
static struct list_head *qh_urb_transaction(struct fotg210_hcd *fotg210,
		struct urb *urb, struct list_head *head, gfp_t flags)
{}

/* Would be best to create all qh's from config descriptors,
 * when each interface/altsetting is established.  Unlink
 * any previous qh and cancel its urbs first; endpoints are
 * implicitly reset then (data toggle too).
 * That'd mean updating how usbcore talks to HCDs. (2.7?)
 */


/* Each QH holds a qtd list; a QH is used for everything except iso.
 *
 * For interrupt urbs, the scheduler must set the microframe scheduling
 * mask(s) each time the QH gets scheduled.  For highspeed, that's
 * just one microframe in the s-mask.  For split interrupt transactions
 * there are additional complications: c-mask, maybe FSTNs.
 */
static struct fotg210_qh *qh_make(struct fotg210_hcd *fotg210, struct urb *urb,
		gfp_t flags)
{}

static void enable_async(struct fotg210_hcd *fotg210)
{}

static void disable_async(struct fotg210_hcd *fotg210)
{}

/* move qh (and its qtds) onto async queue; maybe enable queue.  */

static void qh_link_async(struct fotg210_hcd *fotg210, struct fotg210_qh *qh)
{}

/* For control/bulk/interrupt, return QH with these TDs appended.
 * Allocates and initializes the QH if necessary.
 * Returns null if it can't allocate a QH it needs to.
 * If the QH has TDs (urbs) already, that's great.
 */
static struct fotg210_qh *qh_append_tds(struct fotg210_hcd *fotg210,
		struct urb *urb, struct list_head *qtd_list,
		int epnum, void **ptr)
{}

static int submit_async(struct fotg210_hcd *fotg210, struct urb *urb,
		struct list_head *qtd_list, gfp_t mem_flags)
{}

static void single_unlink_async(struct fotg210_hcd *fotg210,
		struct fotg210_qh *qh)
{}

static void start_iaa_cycle(struct fotg210_hcd *fotg210, bool nested)
{}

/* the async qh for the qtds being unlinked are now gone from the HC */

static void end_unlink_async(struct fotg210_hcd *fotg210)
{}

static void unlink_empty_async(struct fotg210_hcd *fotg210)
{}

/* makes sure the async qh will become idle */
/* caller must own fotg210->lock */

static void start_unlink_async(struct fotg210_hcd *fotg210,
		struct fotg210_qh *qh)
{}

static void scan_async(struct fotg210_hcd *fotg210)
{}
/* EHCI scheduled transaction support:  interrupt, iso, split iso
 * These are called "periodic" transactions in the EHCI spec.
 *
 * Note that for interrupt transfers, the QH/QTD manipulation is shared
 * with the "asynchronous" transaction support (control/bulk transfers).
 * The only real difference is in how interrupt transfers are scheduled.
 *
 * For ISO, we make an "iso_stream" head to serve the same role as a QH.
 * It keeps track of every ITD (or SITD) that's linked, and holds enough
 * pre-calculated schedule data to make appending to the queue be quick.
 */
static int fotg210_get_frame(struct usb_hcd *hcd);

/* periodic_next_shadow - return "next" pointer on shadow list
 * @periodic: host pointer to qh/itd
 * @tag: hardware tag for type of this record
 */
static union fotg210_shadow *periodic_next_shadow(struct fotg210_hcd *fotg210,
		union fotg210_shadow *periodic, __hc32 tag)
{}

static __hc32 *shadow_next_periodic(struct fotg210_hcd *fotg210,
		union fotg210_shadow *periodic, __hc32 tag)
{}

/* caller must hold fotg210->lock */
static void periodic_unlink(struct fotg210_hcd *fotg210, unsigned frame,
		void *ptr)
{}

/* how many of the uframe's 125 usecs are allocated? */
static unsigned short periodic_usecs(struct fotg210_hcd *fotg210,
		unsigned frame, unsigned uframe)
{}

static int same_tt(struct usb_device *dev1, struct usb_device *dev2)
{}

/* return true iff the device's transaction translator is available
 * for a periodic transfer starting at the specified frame, using
 * all the uframes in the mask.
 */
static int tt_no_collision(struct fotg210_hcd *fotg210, unsigned period,
		struct usb_device *dev, unsigned frame, u32 uf_mask)
{}

static void enable_periodic(struct fotg210_hcd *fotg210)
{}

static void disable_periodic(struct fotg210_hcd *fotg210)
{}

/* periodic schedule slots have iso tds (normal or split) first, then a
 * sparse tree for active interrupt transfers.
 *
 * this just links in a qh; caller guarantees uframe masks are set right.
 * no FSTN support (yet; fotg210 0.96+)
 */
static void qh_link_periodic(struct fotg210_hcd *fotg210, struct fotg210_qh *qh)
{}

static void qh_unlink_periodic(struct fotg210_hcd *fotg210,
		struct fotg210_qh *qh)
{}

static void start_unlink_intr(struct fotg210_hcd *fotg210,
		struct fotg210_qh *qh)
{}

static void end_unlink_intr(struct fotg210_hcd *fotg210, struct fotg210_qh *qh)
{}

static int check_period(struct fotg210_hcd *fotg210, unsigned frame,
		unsigned uframe, unsigned period, unsigned usecs)
{}

static int check_intr_schedule(struct fotg210_hcd *fotg210, unsigned frame,
		unsigned uframe, const struct fotg210_qh *qh, __hc32 *c_maskp)
{}

/* "first fit" scheduling policy used the first time through,
 * or when the previous schedule slot can't be re-used.
 */
static int qh_schedule(struct fotg210_hcd *fotg210, struct fotg210_qh *qh)
{}

static int intr_submit(struct fotg210_hcd *fotg210, struct urb *urb,
		struct list_head *qtd_list, gfp_t mem_flags)
{}

static void scan_intr(struct fotg210_hcd *fotg210)
{}

/* fotg210_iso_stream ops work with both ITD and SITD */

static struct fotg210_iso_stream *iso_stream_alloc(gfp_t mem_flags)
{}

static void iso_stream_init(struct fotg210_hcd *fotg210,
		struct fotg210_iso_stream *stream, struct usb_device *dev,
		int pipe, unsigned interval)
{}

static struct fotg210_iso_stream *iso_stream_find(struct fotg210_hcd *fotg210,
		struct urb *urb)
{}

/* fotg210_iso_sched ops can be ITD-only or SITD-only */

static struct fotg210_iso_sched *iso_sched_alloc(unsigned packets,
		gfp_t mem_flags)
{}

static inline void itd_sched_init(struct fotg210_hcd *fotg210,
		struct fotg210_iso_sched *iso_sched,
		struct fotg210_iso_stream *stream, struct urb *urb)
{}

static void iso_sched_free(struct fotg210_iso_stream *stream,
		struct fotg210_iso_sched *iso_sched)
{}

static int itd_urb_transaction(struct fotg210_iso_stream *stream,
		struct fotg210_hcd *fotg210, struct urb *urb, gfp_t mem_flags)
{}

static inline int itd_slot_ok(struct fotg210_hcd *fotg210, u32 mod, u32 uframe,
		u8 usecs, u32 period)
{}

/* This scheduler plans almost as far into the future as it has actual
 * periodic schedule slots.  (Affected by TUNE_FLS, which defaults to
 * "as small as possible" to be cache-friendlier.)  That limits the size
 * transfers you can stream reliably; avoid more than 64 msec per urb.
 * Also avoid queue depths of less than fotg210's worst irq latency (affected
 * by the per-urb URB_NO_INTERRUPT hint, the log2_irq_thresh module parameter,
 * and other factors); or more than about 230 msec total (for portability,
 * given FOTG210_TUNE_FLS and the slop).  Or, write a smarter scheduler!
 */

#define SCHEDULE_SLOP

static int iso_stream_schedule(struct fotg210_hcd *fotg210, struct urb *urb,
		struct fotg210_iso_stream *stream)
{}

static inline void itd_init(struct fotg210_hcd *fotg210,
		struct fotg210_iso_stream *stream, struct fotg210_itd *itd)
{}

static inline void itd_patch(struct fotg210_hcd *fotg210,
		struct fotg210_itd *itd, struct fotg210_iso_sched *iso_sched,
		unsigned index, u16 uframe)
{}

static inline void itd_link(struct fotg210_hcd *fotg210, unsigned frame,
		struct fotg210_itd *itd)
{}

/* fit urb's itds into the selected schedule slot; activate as needed */
static void itd_link_urb(struct fotg210_hcd *fotg210, struct urb *urb,
		unsigned mod, struct fotg210_iso_stream *stream)
{}

#define ISO_ERRS

/* Process and recycle a completed ITD.  Return true iff its urb completed,
 * and hence its completion callback probably added things to the hardware
 * schedule.
 *
 * Note that we carefully avoid recycling this descriptor until after any
 * completion callback runs, so that it won't be reused quickly.  That is,
 * assuming (a) no more than two urbs per frame on this endpoint, and also
 * (b) only this endpoint's completions submit URBs.  It seems some silicon
 * corrupts things if you reuse completed descriptors very quickly...
 */
static bool itd_complete(struct fotg210_hcd *fotg210, struct fotg210_itd *itd)
{}

static int itd_submit(struct fotg210_hcd *fotg210, struct urb *urb,
		gfp_t mem_flags)
{}

static inline int scan_frame_queue(struct fotg210_hcd *fotg210, unsigned frame,
		unsigned now_frame, bool live)
{}

static void scan_isoc(struct fotg210_hcd *fotg210)
{}

/* Display / Set uframe_periodic_max
 */
static ssize_t uframe_periodic_max_show(struct device *dev,
		struct device_attribute *attr, char *buf)
{}

static ssize_t uframe_periodic_max_store(struct device *dev,
		struct device_attribute *attr, const char *buf, size_t count)
{}

static DEVICE_ATTR_RW(uframe_periodic_max);

static inline int create_sysfs_files(struct fotg210_hcd *fotg210)
{}

static inline void remove_sysfs_files(struct fotg210_hcd *fotg210)
{}
/* 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 fotg210_turn_off_all_ports(struct fotg210_hcd *fotg210)
{}

/* 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 fotg210_silence_controller(struct fotg210_hcd *fotg210)
{}

/* fotg210_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 fotg210_shutdown(struct usb_hcd *hcd)
{}

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

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

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

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

static int fotg210_setup(struct usb_hcd *hcd)
{}

static irqreturn_t fotg210_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 fotg210_urb_enqueue(struct usb_hcd *hcd, struct urb *urb,
		gfp_t mem_flags)
{}

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

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

/* bulk qh holds the data toggle */

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

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

static int fotg210_get_frame(struct usb_hcd *hcd)
{}

/* The EHCI in ChipIdea HDRC cannot be a separate module or device,
 * because its registers (and irq) are shared between host/gadget/otg
 * functions  and in order to facilitate role switching we cannot
 * give the fotg210 driver exclusive access to those.
 */

static const struct hc_driver fotg210_fotg210_hc_driver =;

static void fotg210_init(struct fotg210_hcd *fotg210)
{}

/*
 * fotg210_hcd_probe - initialize faraday FOTG210 HCDs
 *
 * Allocates basic resources for this USB host controller, and
 * then invokes the start() method for the HCD associated with it
 * through the hotplug entry's driver_data.
 */
int fotg210_hcd_probe(struct platform_device *pdev, struct fotg210 *fotg)
{}

/*
 * fotg210_hcd_remove - shutdown processing for EHCI HCDs
 * @dev: USB Host Controller being removed
 *
 */
int fotg210_hcd_remove(struct platform_device *pdev)
{}

int __init fotg210_hcd_init(void)
{}

void __exit fotg210_hcd_cleanup(void)
{}