13d0407baSopenharmony_ci// SPDX-License-Identifier: GPL-2.0+ 23d0407baSopenharmony_ci/* 33d0407baSopenharmony_ci * Copyright (c) 2001-2002 by David Brownell 43d0407baSopenharmony_ci * 53d0407baSopenharmony_ci * This program is free software; you can redistribute it and/or modify it 63d0407baSopenharmony_ci * under the terms of the GNU General Public License as published by the 73d0407baSopenharmony_ci * Free Software Foundation; either version 2 of the License, or (at your 83d0407baSopenharmony_ci * option) any later version. 93d0407baSopenharmony_ci * 103d0407baSopenharmony_ci * This program is distributed in the hope that it will be useful, but 113d0407baSopenharmony_ci * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY 123d0407baSopenharmony_ci * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License 133d0407baSopenharmony_ci * for more details. 143d0407baSopenharmony_ci * 153d0407baSopenharmony_ci * You should have received a copy of the GNU General Public License 163d0407baSopenharmony_ci * along with this program; if not, write to the Free Software Foundation, 173d0407baSopenharmony_ci * Inc., 675 Mass Ave, Cambridge, MA 02139, USA. 183d0407baSopenharmony_ci */ 193d0407baSopenharmony_ci 203d0407baSopenharmony_ci#ifndef __USB_CORE_HCD_H 213d0407baSopenharmony_ci#define __USB_CORE_HCD_H 223d0407baSopenharmony_ci 233d0407baSopenharmony_ci#ifdef __KERNEL__ 243d0407baSopenharmony_ci 253d0407baSopenharmony_ci#include <linux/rwsem.h> 263d0407baSopenharmony_ci#include <linux/interrupt.h> 273d0407baSopenharmony_ci#include <linux/idr.h> 283d0407baSopenharmony_ci#include <linux/android_kabi.h> 293d0407baSopenharmony_ci 303d0407baSopenharmony_ci#define MAX_TOPO_LEVEL 6 313d0407baSopenharmony_ci 323d0407baSopenharmony_ci/* This file contains declarations of usbcore internals that are mostly 333d0407baSopenharmony_ci * used or exposed by Host Controller Drivers. 343d0407baSopenharmony_ci */ 353d0407baSopenharmony_ci 363d0407baSopenharmony_ci/* 373d0407baSopenharmony_ci * USB Packet IDs (PIDs) 383d0407baSopenharmony_ci */ 393d0407baSopenharmony_ci#define USB_PID_EXT 0xf0 /* USB 2.0 LPM ECN */ 403d0407baSopenharmony_ci#define USB_PID_OUT 0xe1 413d0407baSopenharmony_ci#define USB_PID_ACK 0xd2 423d0407baSopenharmony_ci#define USB_PID_DATA0 0xc3 433d0407baSopenharmony_ci#define USB_PID_PING 0xb4 /* USB 2.0 */ 443d0407baSopenharmony_ci#define USB_PID_SOF 0xa5 453d0407baSopenharmony_ci#define USB_PID_NYET 0x96 /* USB 2.0 */ 463d0407baSopenharmony_ci#define USB_PID_DATA2 0x87 /* USB 2.0 */ 473d0407baSopenharmony_ci#define USB_PID_SPLIT 0x78 /* USB 2.0 */ 483d0407baSopenharmony_ci#define USB_PID_IN 0x69 493d0407baSopenharmony_ci#define USB_PID_NAK 0x5a 503d0407baSopenharmony_ci#define USB_PID_DATA1 0x4b 513d0407baSopenharmony_ci#define USB_PID_PREAMBLE 0x3c /* Token mode */ 523d0407baSopenharmony_ci#define USB_PID_ERR 0x3c /* USB 2.0: handshake mode */ 533d0407baSopenharmony_ci#define USB_PID_SETUP 0x2d 543d0407baSopenharmony_ci#define USB_PID_STALL 0x1e 553d0407baSopenharmony_ci#define USB_PID_MDATA 0x0f /* USB 2.0 */ 563d0407baSopenharmony_ci 573d0407baSopenharmony_ci/*-------------------------------------------------------------------------*/ 583d0407baSopenharmony_ci 593d0407baSopenharmony_ci/* 603d0407baSopenharmony_ci * USB Host Controller Driver (usb_hcd) framework 613d0407baSopenharmony_ci * 623d0407baSopenharmony_ci * Since "struct usb_bus" is so thin, you can't share much code in it. 633d0407baSopenharmony_ci * This framework is a layer over that, and should be more sharable. 643d0407baSopenharmony_ci */ 653d0407baSopenharmony_ci 663d0407baSopenharmony_ci/*-------------------------------------------------------------------------*/ 673d0407baSopenharmony_ci 683d0407baSopenharmony_cistruct giveback_urb_bh { 693d0407baSopenharmony_ci bool running; 703d0407baSopenharmony_ci spinlock_t lock; 713d0407baSopenharmony_ci struct list_head head; 723d0407baSopenharmony_ci struct tasklet_struct bh; 733d0407baSopenharmony_ci struct usb_host_endpoint *completing_ep; 743d0407baSopenharmony_ci}; 753d0407baSopenharmony_ci 763d0407baSopenharmony_cienum usb_dev_authorize_policy { 773d0407baSopenharmony_ci USB_DEVICE_AUTHORIZE_NONE = 0, 783d0407baSopenharmony_ci USB_DEVICE_AUTHORIZE_ALL = 1, 793d0407baSopenharmony_ci USB_DEVICE_AUTHORIZE_INTERNAL = 2, 803d0407baSopenharmony_ci}; 813d0407baSopenharmony_ci 823d0407baSopenharmony_cistruct usb_hcd { 833d0407baSopenharmony_ci 843d0407baSopenharmony_ci /* 853d0407baSopenharmony_ci * housekeeping 863d0407baSopenharmony_ci */ 873d0407baSopenharmony_ci struct usb_bus self; /* hcd is-a bus */ 883d0407baSopenharmony_ci struct kref kref; /* reference counter */ 893d0407baSopenharmony_ci 903d0407baSopenharmony_ci const char *product_desc; /* product/vendor string */ 913d0407baSopenharmony_ci int speed; /* Speed for this roothub. 923d0407baSopenharmony_ci * May be different from 933d0407baSopenharmony_ci * hcd->driver->flags & HCD_MASK 943d0407baSopenharmony_ci */ 953d0407baSopenharmony_ci char irq_descr[24]; /* driver + bus # */ 963d0407baSopenharmony_ci 973d0407baSopenharmony_ci struct timer_list rh_timer; /* drives root-hub polling */ 983d0407baSopenharmony_ci struct urb *status_urb; /* the current status urb */ 993d0407baSopenharmony_ci#ifdef CONFIG_PM 1003d0407baSopenharmony_ci struct work_struct wakeup_work; /* for remote wakeup */ 1013d0407baSopenharmony_ci#endif 1023d0407baSopenharmony_ci struct work_struct died_work; /* for when the device dies */ 1033d0407baSopenharmony_ci 1043d0407baSopenharmony_ci /* 1053d0407baSopenharmony_ci * hardware info/state 1063d0407baSopenharmony_ci */ 1073d0407baSopenharmony_ci const struct hc_driver *driver; /* hw-specific hooks */ 1083d0407baSopenharmony_ci 1093d0407baSopenharmony_ci /* 1103d0407baSopenharmony_ci * OTG and some Host controllers need software interaction with phys; 1113d0407baSopenharmony_ci * other external phys should be software-transparent 1123d0407baSopenharmony_ci */ 1133d0407baSopenharmony_ci struct usb_phy *usb_phy; 1143d0407baSopenharmony_ci struct usb_phy_roothub *phy_roothub; 1153d0407baSopenharmony_ci 1163d0407baSopenharmony_ci /* Flags that need to be manipulated atomically because they can 1173d0407baSopenharmony_ci * change while the host controller is running. Always use 1183d0407baSopenharmony_ci * set_bit() or clear_bit() to change their values. 1193d0407baSopenharmony_ci */ 1203d0407baSopenharmony_ci unsigned long flags; 1213d0407baSopenharmony_ci#define HCD_FLAG_HW_ACCESSIBLE 0 /* at full power */ 1223d0407baSopenharmony_ci#define HCD_FLAG_POLL_RH 2 /* poll for rh status? */ 1233d0407baSopenharmony_ci#define HCD_FLAG_POLL_PENDING 3 /* status has changed? */ 1243d0407baSopenharmony_ci#define HCD_FLAG_WAKEUP_PENDING 4 /* root hub is resuming? */ 1253d0407baSopenharmony_ci#define HCD_FLAG_RH_RUNNING 5 /* root hub is running? */ 1263d0407baSopenharmony_ci#define HCD_FLAG_DEAD 6 /* controller has died? */ 1273d0407baSopenharmony_ci#define HCD_FLAG_INTF_AUTHORIZED 7 /* authorize interfaces? */ 1283d0407baSopenharmony_ci 1293d0407baSopenharmony_ci /* The flags can be tested using these macros; they are likely to 1303d0407baSopenharmony_ci * be slightly faster than test_bit(). 1313d0407baSopenharmony_ci */ 1323d0407baSopenharmony_ci#define HCD_HW_ACCESSIBLE(hcd) ((hcd)->flags & (1U << HCD_FLAG_HW_ACCESSIBLE)) 1333d0407baSopenharmony_ci#define HCD_POLL_RH(hcd) ((hcd)->flags & (1U << HCD_FLAG_POLL_RH)) 1343d0407baSopenharmony_ci#define HCD_POLL_PENDING(hcd) ((hcd)->flags & (1U << HCD_FLAG_POLL_PENDING)) 1353d0407baSopenharmony_ci#define HCD_WAKEUP_PENDING(hcd) ((hcd)->flags & (1U << HCD_FLAG_WAKEUP_PENDING)) 1363d0407baSopenharmony_ci#define HCD_RH_RUNNING(hcd) ((hcd)->flags & (1U << HCD_FLAG_RH_RUNNING)) 1373d0407baSopenharmony_ci#define HCD_DEAD(hcd) ((hcd)->flags & (1U << HCD_FLAG_DEAD)) 1383d0407baSopenharmony_ci 1393d0407baSopenharmony_ci /* 1403d0407baSopenharmony_ci * Specifies if interfaces are authorized by default 1413d0407baSopenharmony_ci * or they require explicit user space authorization; this bit is 1423d0407baSopenharmony_ci * settable through /sys/class/usb_host/X/interface_authorized_default 1433d0407baSopenharmony_ci */ 1443d0407baSopenharmony_ci#define HCD_INTF_AUTHORIZED(hcd) \ 1453d0407baSopenharmony_ci ((hcd)->flags & (1U << HCD_FLAG_INTF_AUTHORIZED)) 1463d0407baSopenharmony_ci 1473d0407baSopenharmony_ci /* 1483d0407baSopenharmony_ci * Specifies if devices are authorized by default 1493d0407baSopenharmony_ci * or they require explicit user space authorization; this bit is 1503d0407baSopenharmony_ci * settable through /sys/class/usb_host/X/authorized_default 1513d0407baSopenharmony_ci */ 1523d0407baSopenharmony_ci enum usb_dev_authorize_policy dev_policy; 1533d0407baSopenharmony_ci 1543d0407baSopenharmony_ci /* Flags that get set only during HCD registration or removal. */ 1553d0407baSopenharmony_ci unsigned rh_registered:1;/* is root hub registered? */ 1563d0407baSopenharmony_ci unsigned rh_pollable:1; /* may we poll the root hub? */ 1573d0407baSopenharmony_ci unsigned msix_enabled:1; /* driver has MSI-X enabled? */ 1583d0407baSopenharmony_ci unsigned msi_enabled:1; /* driver has MSI enabled? */ 1593d0407baSopenharmony_ci /* 1603d0407baSopenharmony_ci * do not manage the PHY state in the HCD core, instead let the driver 1613d0407baSopenharmony_ci * handle this (for example if the PHY can only be turned on after a 1623d0407baSopenharmony_ci * specific event) 1633d0407baSopenharmony_ci */ 1643d0407baSopenharmony_ci unsigned skip_phy_initialization:1; 1653d0407baSopenharmony_ci 1663d0407baSopenharmony_ci /* The next flag is a stopgap, to be removed when all the HCDs 1673d0407baSopenharmony_ci * support the new root-hub polling mechanism. */ 1683d0407baSopenharmony_ci unsigned uses_new_polling:1; 1693d0407baSopenharmony_ci unsigned wireless:1; /* Wireless USB HCD */ 1703d0407baSopenharmony_ci unsigned has_tt:1; /* Integrated TT in root hub */ 1713d0407baSopenharmony_ci unsigned amd_resume_bug:1; /* AMD remote wakeup quirk */ 1723d0407baSopenharmony_ci unsigned can_do_streams:1; /* HC supports streams */ 1733d0407baSopenharmony_ci unsigned tpl_support:1; /* OTG & EH TPL support */ 1743d0407baSopenharmony_ci unsigned cant_recv_wakeups:1; 1753d0407baSopenharmony_ci /* wakeup requests from downstream aren't received */ 1763d0407baSopenharmony_ci 1773d0407baSopenharmony_ci unsigned int irq; /* irq allocated */ 1783d0407baSopenharmony_ci void __iomem *regs; /* device memory/io */ 1793d0407baSopenharmony_ci resource_size_t rsrc_start; /* memory/io resource start */ 1803d0407baSopenharmony_ci resource_size_t rsrc_len; /* memory/io resource length */ 1813d0407baSopenharmony_ci unsigned power_budget; /* in mA, 0 = no limit */ 1823d0407baSopenharmony_ci 1833d0407baSopenharmony_ci struct giveback_urb_bh high_prio_bh; 1843d0407baSopenharmony_ci struct giveback_urb_bh low_prio_bh; 1853d0407baSopenharmony_ci 1863d0407baSopenharmony_ci /* bandwidth_mutex should be taken before adding or removing 1873d0407baSopenharmony_ci * any new bus bandwidth constraints: 1883d0407baSopenharmony_ci * 1. Before adding a configuration for a new device. 1893d0407baSopenharmony_ci * 2. Before removing the configuration to put the device into 1903d0407baSopenharmony_ci * the addressed state. 1913d0407baSopenharmony_ci * 3. Before selecting a different configuration. 1923d0407baSopenharmony_ci * 4. Before selecting an alternate interface setting. 1933d0407baSopenharmony_ci * 1943d0407baSopenharmony_ci * bandwidth_mutex should be dropped after a successful control message 1953d0407baSopenharmony_ci * to the device, or resetting the bandwidth after a failed attempt. 1963d0407baSopenharmony_ci */ 1973d0407baSopenharmony_ci struct mutex *address0_mutex; 1983d0407baSopenharmony_ci struct mutex *bandwidth_mutex; 1993d0407baSopenharmony_ci struct usb_hcd *shared_hcd; 2003d0407baSopenharmony_ci struct usb_hcd *primary_hcd; 2013d0407baSopenharmony_ci 2023d0407baSopenharmony_ci 2033d0407baSopenharmony_ci#define HCD_BUFFER_POOLS 4 2043d0407baSopenharmony_ci struct dma_pool *pool[HCD_BUFFER_POOLS]; 2053d0407baSopenharmony_ci 2063d0407baSopenharmony_ci int state; 2073d0407baSopenharmony_ci# define __ACTIVE 0x01 2083d0407baSopenharmony_ci# define __SUSPEND 0x04 2093d0407baSopenharmony_ci# define __TRANSIENT 0x80 2103d0407baSopenharmony_ci 2113d0407baSopenharmony_ci# define HC_STATE_HALT 0 2123d0407baSopenharmony_ci# define HC_STATE_RUNNING (__ACTIVE) 2133d0407baSopenharmony_ci# define HC_STATE_QUIESCING (__SUSPEND|__TRANSIENT|__ACTIVE) 2143d0407baSopenharmony_ci# define HC_STATE_RESUMING (__SUSPEND|__TRANSIENT) 2153d0407baSopenharmony_ci# define HC_STATE_SUSPENDED (__SUSPEND) 2163d0407baSopenharmony_ci 2173d0407baSopenharmony_ci#define HC_IS_RUNNING(state) ((state) & __ACTIVE) 2183d0407baSopenharmony_ci#define HC_IS_SUSPENDED(state) ((state) & __SUSPEND) 2193d0407baSopenharmony_ci 2203d0407baSopenharmony_ci /* memory pool for HCs having local memory, or %NULL */ 2213d0407baSopenharmony_ci struct gen_pool *localmem_pool; 2223d0407baSopenharmony_ci 2233d0407baSopenharmony_ci /* more shared queuing code would be good; it should support 2243d0407baSopenharmony_ci * smarter scheduling, handle transaction translators, etc; 2253d0407baSopenharmony_ci * input size of periodic table to an interrupt scheduler. 2263d0407baSopenharmony_ci * (ohci 32, uhci 1024, ehci 256/512/1024). 2273d0407baSopenharmony_ci */ 2283d0407baSopenharmony_ci 2293d0407baSopenharmony_ci ANDROID_KABI_RESERVE(1); 2303d0407baSopenharmony_ci ANDROID_KABI_RESERVE(2); 2313d0407baSopenharmony_ci ANDROID_KABI_RESERVE(3); 2323d0407baSopenharmony_ci ANDROID_KABI_RESERVE(4); 2333d0407baSopenharmony_ci 2343d0407baSopenharmony_ci /* The HC driver's private data is stored at the end of 2353d0407baSopenharmony_ci * this structure. 2363d0407baSopenharmony_ci */ 2373d0407baSopenharmony_ci unsigned long hcd_priv[] 2383d0407baSopenharmony_ci __attribute__ ((aligned(sizeof(s64)))); 2393d0407baSopenharmony_ci}; 2403d0407baSopenharmony_ci 2413d0407baSopenharmony_ci/* 2.4 does this a bit differently ... */ 2423d0407baSopenharmony_cistatic inline struct usb_bus *hcd_to_bus(struct usb_hcd *hcd) 2433d0407baSopenharmony_ci{ 2443d0407baSopenharmony_ci return &hcd->self; 2453d0407baSopenharmony_ci} 2463d0407baSopenharmony_ci 2473d0407baSopenharmony_cistatic inline struct usb_hcd *bus_to_hcd(struct usb_bus *bus) 2483d0407baSopenharmony_ci{ 2493d0407baSopenharmony_ci return container_of(bus, struct usb_hcd, self); 2503d0407baSopenharmony_ci} 2513d0407baSopenharmony_ci 2523d0407baSopenharmony_ci/*-------------------------------------------------------------------------*/ 2533d0407baSopenharmony_ci 2543d0407baSopenharmony_ci 2553d0407baSopenharmony_cistruct hc_driver { 2563d0407baSopenharmony_ci const char *description; /* "ehci-hcd" etc */ 2573d0407baSopenharmony_ci const char *product_desc; /* product/vendor string */ 2583d0407baSopenharmony_ci size_t hcd_priv_size; /* size of private data */ 2593d0407baSopenharmony_ci 2603d0407baSopenharmony_ci /* irq handler */ 2613d0407baSopenharmony_ci irqreturn_t (*irq) (struct usb_hcd *hcd); 2623d0407baSopenharmony_ci 2633d0407baSopenharmony_ci int flags; 2643d0407baSopenharmony_ci#define HCD_MEMORY 0x0001 /* HC regs use memory (else I/O) */ 2653d0407baSopenharmony_ci#define HCD_DMA 0x0002 /* HC uses DMA */ 2663d0407baSopenharmony_ci#define HCD_SHARED 0x0004 /* Two (or more) usb_hcds share HW */ 2673d0407baSopenharmony_ci#define HCD_USB11 0x0010 /* USB 1.1 */ 2683d0407baSopenharmony_ci#define HCD_USB2 0x0020 /* USB 2.0 */ 2693d0407baSopenharmony_ci#define HCD_USB25 0x0030 /* Wireless USB 1.0 (USB 2.5)*/ 2703d0407baSopenharmony_ci#define HCD_USB3 0x0040 /* USB 3.0 */ 2713d0407baSopenharmony_ci#define HCD_USB31 0x0050 /* USB 3.1 */ 2723d0407baSopenharmony_ci#define HCD_USB32 0x0060 /* USB 3.2 */ 2733d0407baSopenharmony_ci#define HCD_MASK 0x0070 2743d0407baSopenharmony_ci#define HCD_BH 0x0100 /* URB complete in BH context */ 2753d0407baSopenharmony_ci 2763d0407baSopenharmony_ci /* called to init HCD and root hub */ 2773d0407baSopenharmony_ci int (*reset) (struct usb_hcd *hcd); 2783d0407baSopenharmony_ci int (*start) (struct usb_hcd *hcd); 2793d0407baSopenharmony_ci 2803d0407baSopenharmony_ci /* NOTE: these suspend/resume calls relate to the HC as 2813d0407baSopenharmony_ci * a whole, not just the root hub; they're for PCI bus glue. 2823d0407baSopenharmony_ci */ 2833d0407baSopenharmony_ci /* called after suspending the hub, before entering D3 etc */ 2843d0407baSopenharmony_ci int (*pci_suspend)(struct usb_hcd *hcd, bool do_wakeup); 2853d0407baSopenharmony_ci 2863d0407baSopenharmony_ci /* called after entering D0 (etc), before resuming the hub */ 2873d0407baSopenharmony_ci int (*pci_resume)(struct usb_hcd *hcd, bool hibernated); 2883d0407baSopenharmony_ci 2893d0407baSopenharmony_ci /* cleanly make HCD stop writing memory and doing I/O */ 2903d0407baSopenharmony_ci void (*stop) (struct usb_hcd *hcd); 2913d0407baSopenharmony_ci 2923d0407baSopenharmony_ci /* shutdown HCD */ 2933d0407baSopenharmony_ci void (*shutdown) (struct usb_hcd *hcd); 2943d0407baSopenharmony_ci 2953d0407baSopenharmony_ci /* return current frame number */ 2963d0407baSopenharmony_ci int (*get_frame_number) (struct usb_hcd *hcd); 2973d0407baSopenharmony_ci 2983d0407baSopenharmony_ci /* manage i/o requests, device state */ 2993d0407baSopenharmony_ci int (*urb_enqueue)(struct usb_hcd *hcd, 3003d0407baSopenharmony_ci struct urb *urb, gfp_t mem_flags); 3013d0407baSopenharmony_ci int (*urb_dequeue)(struct usb_hcd *hcd, 3023d0407baSopenharmony_ci struct urb *urb, int status); 3033d0407baSopenharmony_ci 3043d0407baSopenharmony_ci /* 3053d0407baSopenharmony_ci * (optional) these hooks allow an HCD to override the default DMA 3063d0407baSopenharmony_ci * mapping and unmapping routines. In general, they shouldn't be 3073d0407baSopenharmony_ci * necessary unless the host controller has special DMA requirements, 3083d0407baSopenharmony_ci * such as alignment contraints. If these are not specified, the 3093d0407baSopenharmony_ci * general usb_hcd_(un)?map_urb_for_dma functions will be used instead 3103d0407baSopenharmony_ci * (and it may be a good idea to call these functions in your HCD 3113d0407baSopenharmony_ci * implementation) 3123d0407baSopenharmony_ci */ 3133d0407baSopenharmony_ci int (*map_urb_for_dma)(struct usb_hcd *hcd, struct urb *urb, 3143d0407baSopenharmony_ci gfp_t mem_flags); 3153d0407baSopenharmony_ci void (*unmap_urb_for_dma)(struct usb_hcd *hcd, struct urb *urb); 3163d0407baSopenharmony_ci 3173d0407baSopenharmony_ci /* hw synch, freeing endpoint resources that urb_dequeue can't */ 3183d0407baSopenharmony_ci void (*endpoint_disable)(struct usb_hcd *hcd, 3193d0407baSopenharmony_ci struct usb_host_endpoint *ep); 3203d0407baSopenharmony_ci 3213d0407baSopenharmony_ci /* (optional) reset any endpoint state such as sequence number 3223d0407baSopenharmony_ci and current window */ 3233d0407baSopenharmony_ci void (*endpoint_reset)(struct usb_hcd *hcd, 3243d0407baSopenharmony_ci struct usb_host_endpoint *ep); 3253d0407baSopenharmony_ci 3263d0407baSopenharmony_ci /* root hub support */ 3273d0407baSopenharmony_ci int (*hub_status_data) (struct usb_hcd *hcd, char *buf); 3283d0407baSopenharmony_ci int (*hub_control) (struct usb_hcd *hcd, 3293d0407baSopenharmony_ci u16 typeReq, u16 wValue, u16 wIndex, 3303d0407baSopenharmony_ci char *buf, u16 wLength); 3313d0407baSopenharmony_ci int (*bus_suspend)(struct usb_hcd *); 3323d0407baSopenharmony_ci int (*bus_resume)(struct usb_hcd *); 3333d0407baSopenharmony_ci int (*start_port_reset)(struct usb_hcd *, unsigned port_num); 3343d0407baSopenharmony_ci unsigned long (*get_resuming_ports)(struct usb_hcd *); 3353d0407baSopenharmony_ci 3363d0407baSopenharmony_ci /* force handover of high-speed port to full-speed companion */ 3373d0407baSopenharmony_ci void (*relinquish_port)(struct usb_hcd *, int); 3383d0407baSopenharmony_ci /* has a port been handed over to a companion? */ 3393d0407baSopenharmony_ci int (*port_handed_over)(struct usb_hcd *, int); 3403d0407baSopenharmony_ci 3413d0407baSopenharmony_ci /* CLEAR_TT_BUFFER completion callback */ 3423d0407baSopenharmony_ci void (*clear_tt_buffer_complete)(struct usb_hcd *, 3433d0407baSopenharmony_ci struct usb_host_endpoint *); 3443d0407baSopenharmony_ci 3453d0407baSopenharmony_ci /* xHCI specific functions */ 3463d0407baSopenharmony_ci /* Called by usb_alloc_dev to alloc HC device structures */ 3473d0407baSopenharmony_ci int (*alloc_dev)(struct usb_hcd *, struct usb_device *); 3483d0407baSopenharmony_ci /* Called by usb_disconnect to free HC device structures */ 3493d0407baSopenharmony_ci void (*free_dev)(struct usb_hcd *, struct usb_device *); 3503d0407baSopenharmony_ci /* Change a group of bulk endpoints to support multiple stream IDs */ 3513d0407baSopenharmony_ci int (*alloc_streams)(struct usb_hcd *hcd, struct usb_device *udev, 3523d0407baSopenharmony_ci struct usb_host_endpoint **eps, unsigned int num_eps, 3533d0407baSopenharmony_ci unsigned int num_streams, gfp_t mem_flags); 3543d0407baSopenharmony_ci /* Reverts a group of bulk endpoints back to not using stream IDs. 3553d0407baSopenharmony_ci * Can fail if we run out of memory. 3563d0407baSopenharmony_ci */ 3573d0407baSopenharmony_ci int (*free_streams)(struct usb_hcd *hcd, struct usb_device *udev, 3583d0407baSopenharmony_ci struct usb_host_endpoint **eps, unsigned int num_eps, 3593d0407baSopenharmony_ci gfp_t mem_flags); 3603d0407baSopenharmony_ci 3613d0407baSopenharmony_ci /* Bandwidth computation functions */ 3623d0407baSopenharmony_ci /* Note that add_endpoint() can only be called once per endpoint before 3633d0407baSopenharmony_ci * check_bandwidth() or reset_bandwidth() must be called. 3643d0407baSopenharmony_ci * drop_endpoint() can only be called once per endpoint also. 3653d0407baSopenharmony_ci * A call to xhci_drop_endpoint() followed by a call to 3663d0407baSopenharmony_ci * xhci_add_endpoint() will add the endpoint to the schedule with 3673d0407baSopenharmony_ci * possibly new parameters denoted by a different endpoint descriptor 3683d0407baSopenharmony_ci * in usb_host_endpoint. A call to xhci_add_endpoint() followed by a 3693d0407baSopenharmony_ci * call to xhci_drop_endpoint() is not allowed. 3703d0407baSopenharmony_ci */ 3713d0407baSopenharmony_ci /* Allocate endpoint resources and add them to a new schedule */ 3723d0407baSopenharmony_ci int (*add_endpoint)(struct usb_hcd *, struct usb_device *, 3733d0407baSopenharmony_ci struct usb_host_endpoint *); 3743d0407baSopenharmony_ci /* Drop an endpoint from a new schedule */ 3753d0407baSopenharmony_ci int (*drop_endpoint)(struct usb_hcd *, struct usb_device *, 3763d0407baSopenharmony_ci struct usb_host_endpoint *); 3773d0407baSopenharmony_ci /* Check that a new hardware configuration, set using 3783d0407baSopenharmony_ci * endpoint_enable and endpoint_disable, does not exceed bus 3793d0407baSopenharmony_ci * bandwidth. This must be called before any set configuration 3803d0407baSopenharmony_ci * or set interface requests are sent to the device. 3813d0407baSopenharmony_ci */ 3823d0407baSopenharmony_ci int (*check_bandwidth)(struct usb_hcd *, struct usb_device *); 3833d0407baSopenharmony_ci /* Reset the device schedule to the last known good schedule, 3843d0407baSopenharmony_ci * which was set from a previous successful call to 3853d0407baSopenharmony_ci * check_bandwidth(). This reverts any add_endpoint() and 3863d0407baSopenharmony_ci * drop_endpoint() calls since that last successful call. 3873d0407baSopenharmony_ci * Used for when a check_bandwidth() call fails due to resource 3883d0407baSopenharmony_ci * or bandwidth constraints. 3893d0407baSopenharmony_ci */ 3903d0407baSopenharmony_ci void (*reset_bandwidth)(struct usb_hcd *, struct usb_device *); 3913d0407baSopenharmony_ci /* Returns the hardware-chosen device address */ 3923d0407baSopenharmony_ci int (*address_device)(struct usb_hcd *, struct usb_device *udev); 3933d0407baSopenharmony_ci /* prepares the hardware to send commands to the device */ 3943d0407baSopenharmony_ci int (*enable_device)(struct usb_hcd *, struct usb_device *udev); 3953d0407baSopenharmony_ci /* Notifies the HCD after a hub descriptor is fetched. 3963d0407baSopenharmony_ci * Will block. 3973d0407baSopenharmony_ci */ 3983d0407baSopenharmony_ci int (*update_hub_device)(struct usb_hcd *, struct usb_device *hdev, 3993d0407baSopenharmony_ci struct usb_tt *tt, gfp_t mem_flags); 4003d0407baSopenharmony_ci int (*reset_device)(struct usb_hcd *, struct usb_device *); 4013d0407baSopenharmony_ci /* Notifies the HCD after a device is connected and its 4023d0407baSopenharmony_ci * address is set 4033d0407baSopenharmony_ci */ 4043d0407baSopenharmony_ci int (*update_device)(struct usb_hcd *, struct usb_device *); 4053d0407baSopenharmony_ci int (*set_usb2_hw_lpm)(struct usb_hcd *, struct usb_device *, int); 4063d0407baSopenharmony_ci /* USB 3.0 Link Power Management */ 4073d0407baSopenharmony_ci /* Returns the USB3 hub-encoded value for the U1/U2 timeout. */ 4083d0407baSopenharmony_ci int (*enable_usb3_lpm_timeout)(struct usb_hcd *, 4093d0407baSopenharmony_ci struct usb_device *, enum usb3_link_state state); 4103d0407baSopenharmony_ci /* The xHCI host controller can still fail the command to 4113d0407baSopenharmony_ci * disable the LPM timeouts, so this can return an error code. 4123d0407baSopenharmony_ci */ 4133d0407baSopenharmony_ci int (*disable_usb3_lpm_timeout)(struct usb_hcd *, 4143d0407baSopenharmony_ci struct usb_device *, enum usb3_link_state state); 4153d0407baSopenharmony_ci int (*find_raw_port_number)(struct usb_hcd *, int); 4163d0407baSopenharmony_ci /* Call for power on/off the port if necessary */ 4173d0407baSopenharmony_ci int (*port_power)(struct usb_hcd *hcd, int portnum, bool enable); 4183d0407baSopenharmony_ci 4193d0407baSopenharmony_ci ANDROID_KABI_RESERVE(1); 4203d0407baSopenharmony_ci ANDROID_KABI_RESERVE(2); 4213d0407baSopenharmony_ci ANDROID_KABI_RESERVE(3); 4223d0407baSopenharmony_ci ANDROID_KABI_RESERVE(4); 4233d0407baSopenharmony_ci}; 4243d0407baSopenharmony_ci 4253d0407baSopenharmony_cistatic inline int hcd_giveback_urb_in_bh(struct usb_hcd *hcd) 4263d0407baSopenharmony_ci{ 4273d0407baSopenharmony_ci return hcd->driver->flags & HCD_BH; 4283d0407baSopenharmony_ci} 4293d0407baSopenharmony_ci 4303d0407baSopenharmony_cistatic inline bool hcd_periodic_completion_in_progress(struct usb_hcd *hcd, 4313d0407baSopenharmony_ci struct usb_host_endpoint *ep) 4323d0407baSopenharmony_ci{ 4333d0407baSopenharmony_ci return hcd->high_prio_bh.completing_ep == ep; 4343d0407baSopenharmony_ci} 4353d0407baSopenharmony_ci 4363d0407baSopenharmony_cistatic inline bool hcd_uses_dma(struct usb_hcd *hcd) 4373d0407baSopenharmony_ci{ 4383d0407baSopenharmony_ci return IS_ENABLED(CONFIG_HAS_DMA) && (hcd->driver->flags & HCD_DMA); 4393d0407baSopenharmony_ci} 4403d0407baSopenharmony_ci 4413d0407baSopenharmony_ciextern int usb_hcd_link_urb_to_ep(struct usb_hcd *hcd, struct urb *urb); 4423d0407baSopenharmony_ciextern int usb_hcd_check_unlink_urb(struct usb_hcd *hcd, struct urb *urb, 4433d0407baSopenharmony_ci int status); 4443d0407baSopenharmony_ciextern void usb_hcd_unlink_urb_from_ep(struct usb_hcd *hcd, struct urb *urb); 4453d0407baSopenharmony_ci 4463d0407baSopenharmony_ciextern int usb_hcd_submit_urb(struct urb *urb, gfp_t mem_flags); 4473d0407baSopenharmony_ciextern int usb_hcd_unlink_urb(struct urb *urb, int status); 4483d0407baSopenharmony_ciextern void usb_hcd_giveback_urb(struct usb_hcd *hcd, struct urb *urb, 4493d0407baSopenharmony_ci int status); 4503d0407baSopenharmony_ciextern int usb_hcd_map_urb_for_dma(struct usb_hcd *hcd, struct urb *urb, 4513d0407baSopenharmony_ci gfp_t mem_flags); 4523d0407baSopenharmony_ciextern void usb_hcd_unmap_urb_setup_for_dma(struct usb_hcd *, struct urb *); 4533d0407baSopenharmony_ciextern void usb_hcd_unmap_urb_for_dma(struct usb_hcd *, struct urb *); 4543d0407baSopenharmony_ciextern void usb_hcd_flush_endpoint(struct usb_device *udev, 4553d0407baSopenharmony_ci struct usb_host_endpoint *ep); 4563d0407baSopenharmony_ciextern void usb_hcd_disable_endpoint(struct usb_device *udev, 4573d0407baSopenharmony_ci struct usb_host_endpoint *ep); 4583d0407baSopenharmony_ciextern void usb_hcd_reset_endpoint(struct usb_device *udev, 4593d0407baSopenharmony_ci struct usb_host_endpoint *ep); 4603d0407baSopenharmony_ciextern void usb_hcd_synchronize_unlinks(struct usb_device *udev); 4613d0407baSopenharmony_ciextern int usb_hcd_alloc_bandwidth(struct usb_device *udev, 4623d0407baSopenharmony_ci struct usb_host_config *new_config, 4633d0407baSopenharmony_ci struct usb_host_interface *old_alt, 4643d0407baSopenharmony_ci struct usb_host_interface *new_alt); 4653d0407baSopenharmony_ciextern int usb_hcd_get_frame_number(struct usb_device *udev); 4663d0407baSopenharmony_ci 4673d0407baSopenharmony_cistruct usb_hcd *__usb_create_hcd(const struct hc_driver *driver, 4683d0407baSopenharmony_ci struct device *sysdev, struct device *dev, const char *bus_name, 4693d0407baSopenharmony_ci struct usb_hcd *primary_hcd); 4703d0407baSopenharmony_ciextern struct usb_hcd *usb_create_hcd(const struct hc_driver *driver, 4713d0407baSopenharmony_ci struct device *dev, const char *bus_name); 4723d0407baSopenharmony_ciextern struct usb_hcd *usb_create_shared_hcd(const struct hc_driver *driver, 4733d0407baSopenharmony_ci struct device *dev, const char *bus_name, 4743d0407baSopenharmony_ci struct usb_hcd *shared_hcd); 4753d0407baSopenharmony_ciextern struct usb_hcd *usb_get_hcd(struct usb_hcd *hcd); 4763d0407baSopenharmony_ciextern void usb_put_hcd(struct usb_hcd *hcd); 4773d0407baSopenharmony_ciextern int usb_hcd_is_primary_hcd(struct usb_hcd *hcd); 4783d0407baSopenharmony_ciextern int usb_add_hcd(struct usb_hcd *hcd, 4793d0407baSopenharmony_ci unsigned int irqnum, unsigned long irqflags); 4803d0407baSopenharmony_ciextern void usb_remove_hcd(struct usb_hcd *hcd); 4813d0407baSopenharmony_ciextern int usb_hcd_find_raw_port_number(struct usb_hcd *hcd, int port1); 4823d0407baSopenharmony_ciint usb_hcd_setup_local_mem(struct usb_hcd *hcd, phys_addr_t phys_addr, 4833d0407baSopenharmony_ci dma_addr_t dma, size_t size); 4843d0407baSopenharmony_ci 4853d0407baSopenharmony_cistruct platform_device; 4863d0407baSopenharmony_ciextern void usb_hcd_platform_shutdown(struct platform_device *dev); 4873d0407baSopenharmony_ci 4883d0407baSopenharmony_ci#ifdef CONFIG_USB_PCI 4893d0407baSopenharmony_cistruct pci_dev; 4903d0407baSopenharmony_cistruct pci_device_id; 4913d0407baSopenharmony_ciextern int usb_hcd_pci_probe(struct pci_dev *dev, 4923d0407baSopenharmony_ci const struct pci_device_id *id, 4933d0407baSopenharmony_ci const struct hc_driver *driver); 4943d0407baSopenharmony_ciextern void usb_hcd_pci_remove(struct pci_dev *dev); 4953d0407baSopenharmony_ciextern void usb_hcd_pci_shutdown(struct pci_dev *dev); 4963d0407baSopenharmony_ci 4973d0407baSopenharmony_ciextern int usb_hcd_amd_remote_wakeup_quirk(struct pci_dev *dev); 4983d0407baSopenharmony_ci 4993d0407baSopenharmony_ci#ifdef CONFIG_PM 5003d0407baSopenharmony_ciextern const struct dev_pm_ops usb_hcd_pci_pm_ops; 5013d0407baSopenharmony_ci#endif 5023d0407baSopenharmony_ci#endif /* CONFIG_USB_PCI */ 5033d0407baSopenharmony_ci 5043d0407baSopenharmony_ci/* pci-ish (pdev null is ok) buffer alloc/mapping support */ 5053d0407baSopenharmony_civoid usb_init_pool_max(void); 5063d0407baSopenharmony_ciint hcd_buffer_create(struct usb_hcd *hcd); 5073d0407baSopenharmony_civoid hcd_buffer_destroy(struct usb_hcd *hcd); 5083d0407baSopenharmony_ci 5093d0407baSopenharmony_civoid *hcd_buffer_alloc(struct usb_bus *bus, size_t size, 5103d0407baSopenharmony_ci gfp_t mem_flags, dma_addr_t *dma); 5113d0407baSopenharmony_civoid hcd_buffer_free(struct usb_bus *bus, size_t size, 5123d0407baSopenharmony_ci void *addr, dma_addr_t dma); 5133d0407baSopenharmony_ci 5143d0407baSopenharmony_ci/* generic bus glue, needed for host controllers that don't use PCI */ 5153d0407baSopenharmony_ciextern irqreturn_t usb_hcd_irq(int irq, void *__hcd); 5163d0407baSopenharmony_ci 5173d0407baSopenharmony_ciextern void usb_hc_died(struct usb_hcd *hcd); 5183d0407baSopenharmony_ciextern void usb_hcd_poll_rh_status(struct usb_hcd *hcd); 5193d0407baSopenharmony_ciextern void usb_wakeup_notification(struct usb_device *hdev, 5203d0407baSopenharmony_ci unsigned int portnum); 5213d0407baSopenharmony_ci 5223d0407baSopenharmony_ciextern void usb_hcd_start_port_resume(struct usb_bus *bus, int portnum); 5233d0407baSopenharmony_ciextern void usb_hcd_end_port_resume(struct usb_bus *bus, int portnum); 5243d0407baSopenharmony_ci 5253d0407baSopenharmony_ci/* The D0/D1 toggle bits ... USE WITH CAUTION (they're almost hcd-internal) */ 5263d0407baSopenharmony_ci#define usb_gettoggle(dev, ep, out) (((dev)->toggle[out] >> (ep)) & 1) 5273d0407baSopenharmony_ci#define usb_dotoggle(dev, ep, out) ((dev)->toggle[out] ^= (1 << (ep))) 5283d0407baSopenharmony_ci#define usb_settoggle(dev, ep, out, bit) \ 5293d0407baSopenharmony_ci ((dev)->toggle[out] = ((dev)->toggle[out] & ~(1 << (ep))) | \ 5303d0407baSopenharmony_ci ((bit) << (ep))) 5313d0407baSopenharmony_ci 5323d0407baSopenharmony_ci/* -------------------------------------------------------------------------- */ 5333d0407baSopenharmony_ci 5343d0407baSopenharmony_ci/* Enumeration is only for the hub driver, or HCD virtual root hubs */ 5353d0407baSopenharmony_ciextern struct usb_device *usb_alloc_dev(struct usb_device *parent, 5363d0407baSopenharmony_ci struct usb_bus *, unsigned port); 5373d0407baSopenharmony_ciextern int usb_new_device(struct usb_device *dev); 5383d0407baSopenharmony_ciextern void usb_disconnect(struct usb_device **); 5393d0407baSopenharmony_ci 5403d0407baSopenharmony_ciextern int usb_get_configuration(struct usb_device *dev); 5413d0407baSopenharmony_ciextern void usb_destroy_configuration(struct usb_device *dev); 5423d0407baSopenharmony_ci 5433d0407baSopenharmony_ci/*-------------------------------------------------------------------------*/ 5443d0407baSopenharmony_ci 5453d0407baSopenharmony_ci/* 5463d0407baSopenharmony_ci * HCD Root Hub support 5473d0407baSopenharmony_ci */ 5483d0407baSopenharmony_ci 5493d0407baSopenharmony_ci#include <linux/usb/ch11.h> 5503d0407baSopenharmony_ci 5513d0407baSopenharmony_ci/* 5523d0407baSopenharmony_ci * As of USB 2.0, full/low speed devices are segregated into trees. 5533d0407baSopenharmony_ci * One type grows from USB 1.1 host controllers (OHCI, UHCI etc). 5543d0407baSopenharmony_ci * The other type grows from high speed hubs when they connect to 5553d0407baSopenharmony_ci * full/low speed devices using "Transaction Translators" (TTs). 5563d0407baSopenharmony_ci * 5573d0407baSopenharmony_ci * TTs should only be known to the hub driver, and high speed bus 5583d0407baSopenharmony_ci * drivers (only EHCI for now). They affect periodic scheduling and 5593d0407baSopenharmony_ci * sometimes control/bulk error recovery. 5603d0407baSopenharmony_ci */ 5613d0407baSopenharmony_ci 5623d0407baSopenharmony_cistruct usb_device; 5633d0407baSopenharmony_ci 5643d0407baSopenharmony_cistruct usb_tt { 5653d0407baSopenharmony_ci struct usb_device *hub; /* upstream highspeed hub */ 5663d0407baSopenharmony_ci int multi; /* true means one TT per port */ 5673d0407baSopenharmony_ci unsigned think_time; /* think time in ns */ 5683d0407baSopenharmony_ci void *hcpriv; /* HCD private data */ 5693d0407baSopenharmony_ci 5703d0407baSopenharmony_ci /* for control/bulk error recovery (CLEAR_TT_BUFFER) */ 5713d0407baSopenharmony_ci spinlock_t lock; 5723d0407baSopenharmony_ci struct list_head clear_list; /* of usb_tt_clear */ 5733d0407baSopenharmony_ci struct work_struct clear_work; 5743d0407baSopenharmony_ci 5753d0407baSopenharmony_ci ANDROID_KABI_RESERVE(1); 5763d0407baSopenharmony_ci ANDROID_KABI_RESERVE(2); 5773d0407baSopenharmony_ci ANDROID_KABI_RESERVE(3); 5783d0407baSopenharmony_ci ANDROID_KABI_RESERVE(4); 5793d0407baSopenharmony_ci}; 5803d0407baSopenharmony_ci 5813d0407baSopenharmony_cistruct usb_tt_clear { 5823d0407baSopenharmony_ci struct list_head clear_list; 5833d0407baSopenharmony_ci unsigned tt; 5843d0407baSopenharmony_ci u16 devinfo; 5853d0407baSopenharmony_ci struct usb_hcd *hcd; 5863d0407baSopenharmony_ci struct usb_host_endpoint *ep; 5873d0407baSopenharmony_ci}; 5883d0407baSopenharmony_ci 5893d0407baSopenharmony_ciextern int usb_hub_clear_tt_buffer(struct urb *urb); 5903d0407baSopenharmony_ciextern void usb_ep0_reinit(struct usb_device *); 5913d0407baSopenharmony_ci 5923d0407baSopenharmony_ci/* (shifted) direction/type/recipient from the USB 2.0 spec, table 9.2 */ 5933d0407baSopenharmony_ci#define DeviceRequest \ 5943d0407baSopenharmony_ci ((USB_DIR_IN|USB_TYPE_STANDARD|USB_RECIP_DEVICE)<<8) 5953d0407baSopenharmony_ci#define DeviceOutRequest \ 5963d0407baSopenharmony_ci ((USB_DIR_OUT|USB_TYPE_STANDARD|USB_RECIP_DEVICE)<<8) 5973d0407baSopenharmony_ci 5983d0407baSopenharmony_ci#define InterfaceRequest \ 5993d0407baSopenharmony_ci ((USB_DIR_IN|USB_TYPE_STANDARD|USB_RECIP_INTERFACE)<<8) 6003d0407baSopenharmony_ci 6013d0407baSopenharmony_ci#define EndpointRequest \ 6023d0407baSopenharmony_ci ((USB_DIR_IN|USB_TYPE_STANDARD|USB_RECIP_ENDPOINT)<<8) 6033d0407baSopenharmony_ci#define EndpointOutRequest \ 6043d0407baSopenharmony_ci ((USB_DIR_OUT|USB_TYPE_STANDARD|USB_RECIP_ENDPOINT)<<8) 6053d0407baSopenharmony_ci 6063d0407baSopenharmony_ci/* class requests from the USB 2.0 hub spec, table 11-15 */ 6073d0407baSopenharmony_ci#define HUB_CLASS_REQ(dir, type, request) ((((dir) | (type)) << 8) | (request)) 6083d0407baSopenharmony_ci/* GetBusState and SetHubDescriptor are optional, omitted */ 6093d0407baSopenharmony_ci#define ClearHubFeature HUB_CLASS_REQ(USB_DIR_OUT, USB_RT_HUB, USB_REQ_CLEAR_FEATURE) 6103d0407baSopenharmony_ci#define ClearPortFeature HUB_CLASS_REQ(USB_DIR_OUT, USB_RT_PORT, USB_REQ_CLEAR_FEATURE) 6113d0407baSopenharmony_ci#define GetHubDescriptor HUB_CLASS_REQ(USB_DIR_IN, USB_RT_HUB, USB_REQ_GET_DESCRIPTOR) 6123d0407baSopenharmony_ci#define GetHubStatus HUB_CLASS_REQ(USB_DIR_IN, USB_RT_HUB, USB_REQ_GET_STATUS) 6133d0407baSopenharmony_ci#define GetPortStatus HUB_CLASS_REQ(USB_DIR_IN, USB_RT_PORT, USB_REQ_GET_STATUS) 6143d0407baSopenharmony_ci#define SetHubFeature HUB_CLASS_REQ(USB_DIR_OUT, USB_RT_HUB, USB_REQ_SET_FEATURE) 6153d0407baSopenharmony_ci#define SetPortFeature HUB_CLASS_REQ(USB_DIR_OUT, USB_RT_PORT, USB_REQ_SET_FEATURE) 6163d0407baSopenharmony_ci#define ClearTTBuffer HUB_CLASS_REQ(USB_DIR_OUT, USB_RT_PORT, HUB_CLEAR_TT_BUFFER) 6173d0407baSopenharmony_ci#define ResetTT HUB_CLASS_REQ(USB_DIR_OUT, USB_RT_PORT, HUB_RESET_TT) 6183d0407baSopenharmony_ci#define GetTTState HUB_CLASS_REQ(USB_DIR_IN, USB_RT_PORT, HUB_GET_TT_STATE) 6193d0407baSopenharmony_ci#define StopTT HUB_CLASS_REQ(USB_DIR_OUT, USB_RT_PORT, HUB_STOP_TT) 6203d0407baSopenharmony_ci 6213d0407baSopenharmony_ci 6223d0407baSopenharmony_ci/*-------------------------------------------------------------------------*/ 6233d0407baSopenharmony_ci 6243d0407baSopenharmony_ci/* class requests from USB 3.1 hub spec, table 10-7 */ 6253d0407baSopenharmony_ci#define SetHubDepth HUB_CLASS_REQ(USB_DIR_OUT, USB_RT_HUB, HUB_SET_DEPTH) 6263d0407baSopenharmony_ci#define GetPortErrorCount HUB_CLASS_REQ(USB_DIR_IN, USB_RT_PORT, HUB_GET_PORT_ERR_COUNT) 6273d0407baSopenharmony_ci 6283d0407baSopenharmony_ci/* 6293d0407baSopenharmony_ci * Generic bandwidth allocation constants/support 6303d0407baSopenharmony_ci */ 6313d0407baSopenharmony_ci#define FRAME_TIME_USECS 1000L 6323d0407baSopenharmony_ci#define BitTime(bytecount) (7 * 8 * bytecount / 6) /* with integer truncation */ 6333d0407baSopenharmony_ci /* Trying not to use worst-case bit-stuffing 6343d0407baSopenharmony_ci * of (7/6 * 8 * bytecount) = 9.33 * bytecount */ 6353d0407baSopenharmony_ci /* bytecount = data payload byte count */ 6363d0407baSopenharmony_ci 6373d0407baSopenharmony_ci#define NS_TO_US(ns) DIV_ROUND_UP(ns, 1000L) 6383d0407baSopenharmony_ci /* convert nanoseconds to microseconds, rounding up */ 6393d0407baSopenharmony_ci 6403d0407baSopenharmony_ci/* 6413d0407baSopenharmony_ci * Full/low speed bandwidth allocation constants/support. 6423d0407baSopenharmony_ci */ 6433d0407baSopenharmony_ci#define BW_HOST_DELAY 1000L /* nanoseconds */ 6443d0407baSopenharmony_ci#define BW_HUB_LS_SETUP 333L /* nanoseconds */ 6453d0407baSopenharmony_ci /* 4 full-speed bit times (est.) */ 6463d0407baSopenharmony_ci 6473d0407baSopenharmony_ci#define FRAME_TIME_BITS 12000L /* frame = 1 millisecond */ 6483d0407baSopenharmony_ci#define FRAME_TIME_MAX_BITS_ALLOC (90L * FRAME_TIME_BITS / 100L) 6493d0407baSopenharmony_ci#define FRAME_TIME_MAX_USECS_ALLOC (90L * FRAME_TIME_USECS / 100L) 6503d0407baSopenharmony_ci 6513d0407baSopenharmony_ci/* 6523d0407baSopenharmony_ci * Ceiling [nano/micro]seconds (typical) for that many bytes at high speed 6533d0407baSopenharmony_ci * ISO is a bit less, no ACK ... from USB 2.0 spec, 5.11.3 (and needed 6543d0407baSopenharmony_ci * to preallocate bandwidth) 6553d0407baSopenharmony_ci */ 6563d0407baSopenharmony_ci#define USB2_HOST_DELAY 5 /* nsec, guess */ 6573d0407baSopenharmony_ci#define HS_NSECS(bytes) (((55 * 8 * 2083) \ 6583d0407baSopenharmony_ci + (2083UL * (3 + BitTime(bytes))))/1000 \ 6593d0407baSopenharmony_ci + USB2_HOST_DELAY) 6603d0407baSopenharmony_ci#define HS_NSECS_ISO(bytes) (((38 * 8 * 2083) \ 6613d0407baSopenharmony_ci + (2083UL * (3 + BitTime(bytes))))/1000 \ 6623d0407baSopenharmony_ci + USB2_HOST_DELAY) 6633d0407baSopenharmony_ci#define HS_USECS(bytes) NS_TO_US(HS_NSECS(bytes)) 6643d0407baSopenharmony_ci#define HS_USECS_ISO(bytes) NS_TO_US(HS_NSECS_ISO(bytes)) 6653d0407baSopenharmony_ci 6663d0407baSopenharmony_ciextern long usb_calc_bus_time(int speed, int is_input, 6673d0407baSopenharmony_ci int isoc, int bytecount); 6683d0407baSopenharmony_ci 6693d0407baSopenharmony_ci/*-------------------------------------------------------------------------*/ 6703d0407baSopenharmony_ci 6713d0407baSopenharmony_ciextern void usb_set_device_state(struct usb_device *udev, 6723d0407baSopenharmony_ci enum usb_device_state new_state); 6733d0407baSopenharmony_ci 6743d0407baSopenharmony_ci/*-------------------------------------------------------------------------*/ 6753d0407baSopenharmony_ci 6763d0407baSopenharmony_ci/* exported only within usbcore */ 6773d0407baSopenharmony_ci 6783d0407baSopenharmony_ciextern struct idr usb_bus_idr; 6793d0407baSopenharmony_ciextern struct mutex usb_bus_idr_lock; 6803d0407baSopenharmony_ciextern wait_queue_head_t usb_kill_urb_queue; 6813d0407baSopenharmony_ci 6823d0407baSopenharmony_ci 6833d0407baSopenharmony_ci#define usb_endpoint_out(ep_dir) (!((ep_dir) & USB_DIR_IN)) 6843d0407baSopenharmony_ci 6853d0407baSopenharmony_ci#ifdef CONFIG_PM 6863d0407baSopenharmony_ciextern unsigned usb_wakeup_enabled_descendants(struct usb_device *udev); 6873d0407baSopenharmony_ciextern void usb_root_hub_lost_power(struct usb_device *rhdev); 6883d0407baSopenharmony_ciextern int hcd_bus_suspend(struct usb_device *rhdev, pm_message_t msg); 6893d0407baSopenharmony_ciextern int hcd_bus_resume(struct usb_device *rhdev, pm_message_t msg); 6903d0407baSopenharmony_ciextern void usb_hcd_resume_root_hub(struct usb_hcd *hcd); 6913d0407baSopenharmony_ci#else 6923d0407baSopenharmony_cistatic inline unsigned usb_wakeup_enabled_descendants(struct usb_device *udev) 6933d0407baSopenharmony_ci{ 6943d0407baSopenharmony_ci return 0; 6953d0407baSopenharmony_ci} 6963d0407baSopenharmony_cistatic inline void usb_hcd_resume_root_hub(struct usb_hcd *hcd) 6973d0407baSopenharmony_ci{ 6983d0407baSopenharmony_ci return; 6993d0407baSopenharmony_ci} 7003d0407baSopenharmony_ci#endif /* CONFIG_PM */ 7013d0407baSopenharmony_ci 7023d0407baSopenharmony_ci/*-------------------------------------------------------------------------*/ 7033d0407baSopenharmony_ci 7043d0407baSopenharmony_ci#if defined(CONFIG_USB_MON) || defined(CONFIG_USB_MON_MODULE) 7053d0407baSopenharmony_ci 7063d0407baSopenharmony_cistruct usb_mon_operations { 7073d0407baSopenharmony_ci void (*urb_submit)(struct usb_bus *bus, struct urb *urb); 7083d0407baSopenharmony_ci void (*urb_submit_error)(struct usb_bus *bus, struct urb *urb, int err); 7093d0407baSopenharmony_ci void (*urb_complete)(struct usb_bus *bus, struct urb *urb, int status); 7103d0407baSopenharmony_ci /* void (*urb_unlink)(struct usb_bus *bus, struct urb *urb); */ 7113d0407baSopenharmony_ci}; 7123d0407baSopenharmony_ci 7133d0407baSopenharmony_ciextern const struct usb_mon_operations *mon_ops; 7143d0407baSopenharmony_ci 7153d0407baSopenharmony_cistatic inline void usbmon_urb_submit(struct usb_bus *bus, struct urb *urb) 7163d0407baSopenharmony_ci{ 7173d0407baSopenharmony_ci if (bus->monitored) 7183d0407baSopenharmony_ci (*mon_ops->urb_submit)(bus, urb); 7193d0407baSopenharmony_ci} 7203d0407baSopenharmony_ci 7213d0407baSopenharmony_cistatic inline void usbmon_urb_submit_error(struct usb_bus *bus, struct urb *urb, 7223d0407baSopenharmony_ci int error) 7233d0407baSopenharmony_ci{ 7243d0407baSopenharmony_ci if (bus->monitored) 7253d0407baSopenharmony_ci (*mon_ops->urb_submit_error)(bus, urb, error); 7263d0407baSopenharmony_ci} 7273d0407baSopenharmony_ci 7283d0407baSopenharmony_cistatic inline void usbmon_urb_complete(struct usb_bus *bus, struct urb *urb, 7293d0407baSopenharmony_ci int status) 7303d0407baSopenharmony_ci{ 7313d0407baSopenharmony_ci if (bus->monitored) 7323d0407baSopenharmony_ci (*mon_ops->urb_complete)(bus, urb, status); 7333d0407baSopenharmony_ci} 7343d0407baSopenharmony_ci 7353d0407baSopenharmony_ciint usb_mon_register(const struct usb_mon_operations *ops); 7363d0407baSopenharmony_civoid usb_mon_deregister(void); 7373d0407baSopenharmony_ci 7383d0407baSopenharmony_ci#else 7393d0407baSopenharmony_ci 7403d0407baSopenharmony_cistatic inline void usbmon_urb_submit(struct usb_bus *bus, struct urb *urb) {} 7413d0407baSopenharmony_cistatic inline void usbmon_urb_submit_error(struct usb_bus *bus, struct urb *urb, 7423d0407baSopenharmony_ci int error) {} 7433d0407baSopenharmony_cistatic inline void usbmon_urb_complete(struct usb_bus *bus, struct urb *urb, 7443d0407baSopenharmony_ci int status) {} 7453d0407baSopenharmony_ci 7463d0407baSopenharmony_ci#endif /* CONFIG_USB_MON || CONFIG_USB_MON_MODULE */ 7473d0407baSopenharmony_ci 7483d0407baSopenharmony_ci/*-------------------------------------------------------------------------*/ 7493d0407baSopenharmony_ci 7503d0407baSopenharmony_ci/* random stuff */ 7513d0407baSopenharmony_ci 7523d0407baSopenharmony_ci#define RUN_CONTEXT (in_irq() ? "in_irq" \ 7533d0407baSopenharmony_ci : (in_interrupt() ? "in_interrupt" : "can sleep")) 7543d0407baSopenharmony_ci 7553d0407baSopenharmony_ci 7563d0407baSopenharmony_ci/* This rwsem is for use only by the hub driver and ehci-hcd. 7573d0407baSopenharmony_ci * Nobody else should touch it. 7583d0407baSopenharmony_ci */ 7593d0407baSopenharmony_ciextern struct rw_semaphore ehci_cf_port_reset_rwsem; 7603d0407baSopenharmony_ci 7613d0407baSopenharmony_ci/* Keep track of which host controller drivers are loaded */ 7623d0407baSopenharmony_ci#define USB_UHCI_LOADED 0 7633d0407baSopenharmony_ci#define USB_OHCI_LOADED 1 7643d0407baSopenharmony_ci#define USB_EHCI_LOADED 2 7653d0407baSopenharmony_ciextern unsigned long usb_hcds_loaded; 7663d0407baSopenharmony_ci 7673d0407baSopenharmony_ci#endif /* __KERNEL__ */ 7683d0407baSopenharmony_ci 7693d0407baSopenharmony_ci#endif /* __USB_CORE_HCD_H */ 770