/* SPDX-License-Identifier: GPL-2.0+ */ /* * Copyright (c) 2001-2002 by David Brownell */ #ifndef __LINUX_EHCI_HCD_H #define __LINUX_EHCI_HCD_H /* definitions used for the EHCI driver */ /* * __hc32 and __hc16 are "Host Controller" types, they may be equivalent to * __leXX (normally) or __beXX (given EHCI_BIG_ENDIAN_DESC), depending on * the host controller implementation. * * To facilitate the strongest possible byte-order checking from "sparse" * and so on, we use __leXX unless that's not practical. */ #ifdef CONFIG_USB_EHCI_BIG_ENDIAN_DESC typedef __u32 __bitwise __hc32; typedef __u16 __bitwise __hc16; #else #define __hc32 … #define __hc16 … #endif /* statistics can be kept for tuning/monitoring */ #ifdef CONFIG_DYNAMIC_DEBUG #define EHCI_STATS #endif struct ehci_stats { … }; /* * Scheduling and budgeting information for periodic transfers, for both * high-speed devices and full/low-speed devices lying behind a TT. */ struct ehci_per_sched { … }; #define NO_FRAME … /* ehci_hcd->lock guards shared data against other CPUs: * ehci_hcd: async, unlink, periodic (and shadow), ... * usb_host_endpoint: hcpriv * ehci_qh: qh_next, qtd_list * ehci_qtd: qtd_list * * Also, hold this lock when talking to HC registers or * when updating hw_* fields in shared qh/qtd/... structures. */ #define EHCI_MAX_ROOT_PORTS … /* * ehci_rh_state values of EHCI_RH_RUNNING or above mean that the * controller may be doing DMA. Lower values mean there's no DMA. */ enum ehci_rh_state { … }; /* * Timer events, ordered by increasing delay length. * Always update event_delays_ns[] and event_handlers[] (defined in * ehci-timer.c) in parallel with this list. */ enum ehci_hrtimer_event { … }; #define EHCI_HRTIMER_NO_EVENT … struct ehci_hcd { … }; /* convert between an HCD pointer and the corresponding EHCI_HCD */ static inline struct ehci_hcd *hcd_to_ehci(struct usb_hcd *hcd) { … } static inline struct usb_hcd *ehci_to_hcd(struct ehci_hcd *ehci) { … } /*-------------------------------------------------------------------------*/ #include <linux/usb/ehci_def.h> /*-------------------------------------------------------------------------*/ #define QTD_NEXT(ehci, dma) … /* * EHCI Specification 0.95 Section 3.5 * QTD: describe data transfer components (buffer, direction, ...) * See Fig 3-6 "Queue Element Transfer Descriptor Block Diagram". * * These are associated only with "QH" (Queue Head) structures, * used with control, bulk, and interrupt transfers. */ struct ehci_qtd { … } __aligned(…); /* PID Codes that are used here, from EHCI specification, Table 3-16. */ #define PID_CODE_OUT … #define PID_CODE_IN … #define PID_CODE_SETUP … /* mask NakCnt+T in qh->hw_alt_next */ #define QTD_MASK(ehci) … #define IS_SHORT_READ(token) … /*-------------------------------------------------------------------------*/ /* type tag from {qh,itd,sitd,fstn}->hw_next */ #define Q_NEXT_TYPE(ehci, dma) … /* * Now the following defines are not converted using the * cpu_to_le32() macro anymore, since we have to support * "dynamic" switching between be and le support, so that the driver * can be used on one system with SoC EHCI controller using big-endian * descriptors as well as a normal little-endian PCI EHCI controller. */ /* values for that type tag */ #define Q_TYPE_ITD … #define Q_TYPE_QH … #define Q_TYPE_SITD … #define Q_TYPE_FSTN … /* next async queue entry, or pointer to interrupt/periodic QH */ #define QH_NEXT(ehci, dma) … /* for periodic/async schedules and qtd lists, mark end of list */ #define EHCI_LIST_END(ehci) … /* * Entries in periodic shadow table are pointers to one of four kinds * of data structure. That's dictated by the hardware; a type tag is * encoded in the low bits of the hardware's periodic schedule. Use * Q_NEXT_TYPE to get the tag. * * For entries in the async schedule, the type tag always says "qh". */ ehci_shadow; /*-------------------------------------------------------------------------*/ /* * EHCI Specification 0.95 Section 3.6 * QH: describes control/bulk/interrupt endpoints * See Fig 3-7 "Queue Head Structure Layout". * * These appear in both the async and (for interrupt) periodic schedules. */ /* first part defined by EHCI spec */ struct ehci_qh_hw { … } __aligned(…); struct ehci_qh { … }; /*-------------------------------------------------------------------------*/ /* description of one iso transaction (up to 3 KB data if highspeed) */ struct ehci_iso_packet { … }; /* temporary schedule data for packets from iso urbs (both speeds) * each packet is one logical usb transaction to the device (not TT), * beginning at stream->next_uframe */ struct ehci_iso_sched { … }; /* * ehci_iso_stream - groups all (s)itds for this endpoint. * acts like a qh would, if EHCI had them for ISO. */ struct ehci_iso_stream { … }; /*-------------------------------------------------------------------------*/ /* * EHCI Specification 0.95 Section 3.3 * Fig 3-4 "Isochronous Transaction Descriptor (iTD)" * * Schedule records for high speed iso xfers */ struct ehci_itd { … } __aligned(…); /*-------------------------------------------------------------------------*/ /* * EHCI Specification 0.95 Section 3.4 * siTD, aka split-transaction isochronous Transfer Descriptor * ... describe full speed iso xfers through TT in hubs * see Figure 3-5 "Split-transaction Isochronous Transaction Descriptor (siTD) */ struct ehci_sitd { … } __aligned(…); /*-------------------------------------------------------------------------*/ /* * EHCI Specification 0.96 Section 3.7 * Periodic Frame Span Traversal Node (FSTN) * * Manages split interrupt transactions (using TT) that span frame boundaries * into uframes 0/1; see 4.12.2.2. In those uframes, a "save place" FSTN * makes the HC jump (back) to a QH to scan for fs/ls QH completions until * it hits a "restore" FSTN; then it returns to finish other uframe 0/1 work. */ struct ehci_fstn { … } __aligned(…); /*-------------------------------------------------------------------------*/ /* * USB-2.0 Specification Sections 11.14 and 11.18 * Scheduling and budgeting split transactions using TTs * * A hub can have a single TT for all its ports, or multiple TTs (one for each * port). The bandwidth and budgeting information for the full/low-speed bus * below each TT is self-contained and independent of the other TTs or the * high-speed bus. * * "Bandwidth" refers to the number of microseconds on the FS/LS bus allocated * to an interrupt or isochronous endpoint for each frame. "Budget" refers to * the best-case estimate of the number of full-speed bytes allocated to an * endpoint for each microframe within an allocated frame. * * Removal of an endpoint invalidates a TT's budget. Instead of trying to * keep an up-to-date record, we recompute the budget when it is needed. */ struct ehci_tt { … }; /*-------------------------------------------------------------------------*/ /* Prepare the PORTSC wakeup flags during controller suspend/resume */ #define ehci_prepare_ports_for_controller_suspend(ehci, do_wakeup) … #define ehci_prepare_ports_for_controller_resume(ehci) … /*-------------------------------------------------------------------------*/ #ifdef CONFIG_USB_EHCI_ROOT_HUB_TT /* * Some EHCI controllers have a Transaction Translator built into the * root hub. This is a non-standard feature. Each controller will need * to add code to the following inline functions, and call them as * needed (mostly in root hub code). */ #define ehci_is_TDI(e) … /* Returns the speed of a device attached to a port on the root hub. */ static inline unsigned int ehci_port_speed(struct ehci_hcd *ehci, unsigned int portsc) { … } #else #define ehci_is_TDI … #define ehci_port_speed … #endif /*-------------------------------------------------------------------------*/ #ifdef CONFIG_PPC_83xx /* Some Freescale processors have an erratum in which the TT * port number in the queue head was 0..N-1 instead of 1..N. */ #define ehci_has_fsl_portno_bug … #else #define ehci_has_fsl_portno_bug(e) … #endif #define PORTSC_FSL_PFSC … #if defined(CONFIG_PPC_85xx) /* Some Freescale processors have an erratum (USB A-005275) in which * incoming packets get corrupted in HS mode */ #define ehci_has_fsl_hs_errata … #else #define ehci_has_fsl_hs_errata(e) … #endif /* * Some Freescale/NXP processors have an erratum (USB A-005697) * in which we need to wait for 10ms for bus to enter suspend mode * after setting SUSP bit. */ #define ehci_has_fsl_susp_errata(e) … /* * Some Freescale/NXP processors using ChipIdea IP have a bug in which * disabling the port (PE is cleared) does not cause PEC to be asserted * when frame babble is detected. */ #define ehci_has_ci_pec_bug(e, portsc) … /* * While most USB host controllers implement their registers in * little-endian format, a minority (celleb companion chip) implement * them in big endian format. * * This attempts to support either format at compile time without a * runtime penalty, or both formats with the additional overhead * of checking a flag bit. * * ehci_big_endian_capbase is a special quirk for controllers that * implement the HC capability registers as separate registers and not * as fields of a 32-bit register. */ #ifdef CONFIG_USB_EHCI_BIG_ENDIAN_MMIO #define ehci_big_endian_mmio … #define ehci_big_endian_capbase … #else #define ehci_big_endian_mmio(e) … #define ehci_big_endian_capbase(e) … #endif /* * Big-endian read/write functions are arch-specific. * Other arches can be added if/when they're needed. */ #if defined(CONFIG_ARM) && defined(CONFIG_ARCH_IXP4XX) #define readl_be … #define writel_be … #endif static inline unsigned int ehci_readl(const struct ehci_hcd *ehci, __u32 __iomem *regs) { … } #ifdef CONFIG_SOC_IMX28 static inline void imx28_ehci_writel(const unsigned int val, volatile __u32 __iomem *addr) { __asm__ ("swp %0, %0, [%1]" : : "r"(val), "r"(addr)); } #else static inline void imx28_ehci_writel(const unsigned int val, volatile __u32 __iomem *addr) { … } #endif static inline void ehci_writel(const struct ehci_hcd *ehci, const unsigned int val, __u32 __iomem *regs) { … } /* * On certain ppc-44x SoC there is a HW issue, that could only worked around with * explicit suspend/operate of OHCI. This function hereby makes sense only on that arch. * Other common bits are dependent on has_amcc_usb23 quirk flag. */ #ifdef CONFIG_44x static inline void set_ohci_hcfs(struct ehci_hcd *ehci, int operational) { u32 hc_control; hc_control = (readl_be(ehci->ohci_hcctrl_reg) & ~OHCI_CTRL_HCFS); if (operational) hc_control |= OHCI_USB_OPER; else hc_control |= OHCI_USB_SUSPEND; writel_be(hc_control, ehci->ohci_hcctrl_reg); (void) readl_be(ehci->ohci_hcctrl_reg); } #else static inline void set_ohci_hcfs(struct ehci_hcd *ehci, int operational) { … } #endif /*-------------------------------------------------------------------------*/ /* * The AMCC 440EPx not only implements its EHCI registers in big-endian * format, but also its DMA data structures (descriptors). * * EHCI controllers accessed through PCI work normally (little-endian * everywhere), so we won't bother supporting a BE-only mode for now. */ #ifdef CONFIG_USB_EHCI_BIG_ENDIAN_DESC #define ehci_big_endian_desc … /* cpu to ehci */ static inline __hc32 cpu_to_hc32(const struct ehci_hcd *ehci, const u32 x) { return ehci_big_endian_desc(ehci) ? (__force __hc32)cpu_to_be32(x) : (__force __hc32)cpu_to_le32(x); } /* ehci to cpu */ static inline u32 hc32_to_cpu(const struct ehci_hcd *ehci, const __hc32 x) { return ehci_big_endian_desc(ehci) ? be32_to_cpu((__force __be32)x) : le32_to_cpu((__force __le32)x); } static inline u32 hc32_to_cpup(const struct ehci_hcd *ehci, const __hc32 *x) { return ehci_big_endian_desc(ehci) ? be32_to_cpup((__force __be32 *)x) : le32_to_cpup((__force __le32 *)x); } #else /* cpu to ehci */ static inline __hc32 cpu_to_hc32(const struct ehci_hcd *ehci, const u32 x) { … } /* ehci to cpu */ static inline u32 hc32_to_cpu(const struct ehci_hcd *ehci, const __hc32 x) { … } static inline u32 hc32_to_cpup(const struct ehci_hcd *ehci, const __hc32 *x) { … } #endif /*-------------------------------------------------------------------------*/ #define ehci_dbg(ehci, fmt, args...) … #define ehci_err(ehci, fmt, args...) … #define ehci_info(ehci, fmt, args...) … #define ehci_warn(ehci, fmt, args...) … /*-------------------------------------------------------------------------*/ /* Declarations of things exported for use by ehci platform drivers */ struct ehci_driver_overrides { … }; extern void ehci_init_driver(struct hc_driver *drv, const struct ehci_driver_overrides *over); extern int ehci_setup(struct usb_hcd *hcd); extern int ehci_handshake(struct ehci_hcd *ehci, void __iomem *ptr, u32 mask, u32 done, int usec); extern int ehci_reset(struct ehci_hcd *ehci); extern int ehci_suspend(struct usb_hcd *hcd, bool do_wakeup); extern int ehci_resume(struct usb_hcd *hcd, bool force_reset); extern void ehci_adjust_port_wakeup_flags(struct ehci_hcd *ehci, bool suspending, bool do_wakeup); extern int ehci_hub_control(struct usb_hcd *hcd, u16 typeReq, u16 wValue, u16 wIndex, char *buf, u16 wLength); #endif /* __LINUX_EHCI_HCD_H */