xref: /linux/include/linux/usb/xhci-sideband.h (revision c6006b8ca14dcc604567be99fc4863e6e11ab6e3)
1 /* SPDX-License-Identifier: GPL-2.0 */
2 /*
3  * xHCI host controller sideband support
4  *
5  * Copyright (c) 2023-2025, Intel Corporation.
6  *
7  * Author: Mathias Nyman <mathias.nyman@linux.intel.com>
8  */
9 #ifndef __LINUX_XHCI_SIDEBAND_H
10 #define __LINUX_XHCI_SIDEBAND_H
11 
12 #include <linux/scatterlist.h>
13 #include <linux/usb.h>
14 #include <linux/usb/hcd.h>
15 
16 #define	EP_CTX_PER_DEV		31	/* FIXME defined twice, from xhci.h */
17 
18 struct xhci_sideband;
19 
20 enum xhci_sideband_type {
21 	XHCI_SIDEBAND_AUDIO,
22 	XHCI_SIDEBAND_VENDOR,
23 };
24 
25 enum xhci_sideband_notify_type {
26 	XHCI_SIDEBAND_XFER_RING_FREE,
27 };
28 
29 /**
30  * struct xhci_sideband_event - sideband event
31  * @type: notifier type
32  * @evt_data: event data
33  */
34 struct xhci_sideband_event {
35 	enum xhci_sideband_notify_type type;
36 	void *evt_data;
37 };
38 
39 /**
40  * struct xhci_sideband - representation of a sideband accessed usb device.
41  * @xhci: The xhci host controller the usb device is connected to
42  * @vdev: the usb device accessed via sideband
43  * @eps: array of endpoints controlled via sideband
44  * @ir: event handling and buffer for sideband accessed device
45  * @type: xHCI sideband type
46  * @mutex: mutex for sideband operations
47  * @intf: USB sideband client interface
48  * @notify_client: callback for xHCI sideband sequences
49  *
50  * FIXME usb device accessed via sideband Keeping track of sideband accessed usb devices.
51  */
52 struct xhci_sideband {
53 	struct xhci_hcd                 *xhci;
54 	struct xhci_virt_device         *vdev;
55 	struct xhci_virt_ep             *eps[EP_CTX_PER_DEV];
56 	struct xhci_interrupter         *ir;
57 	enum xhci_sideband_type		type;
58 
59 	/* Synchronizing xHCI sideband operations with client drivers operations */
60 	struct mutex			mutex;
61 
62 	struct usb_interface		*intf;
63 	int (*notify_client)(struct usb_interface *intf,
64 			     struct xhci_sideband_event *evt);
65 };
66 
67 struct xhci_sideband *
68 xhci_sideband_register(struct usb_interface *intf, enum xhci_sideband_type type,
69 		       int (*notify_client)(struct usb_interface *intf,
70 				    struct xhci_sideband_event *evt));
71 void
72 xhci_sideband_unregister(struct xhci_sideband *sb);
73 int
74 xhci_sideband_add_endpoint(struct xhci_sideband *sb,
75 			   struct usb_host_endpoint *host_ep);
76 int
77 xhci_sideband_remove_endpoint(struct xhci_sideband *sb,
78 			      struct usb_host_endpoint *host_ep);
79 int
80 xhci_sideband_stop_endpoint(struct xhci_sideband *sb,
81 			    struct usb_host_endpoint *host_ep);
82 struct sg_table *
83 xhci_sideband_get_endpoint_buffer(struct xhci_sideband *sb,
84 				  struct usb_host_endpoint *host_ep);
85 struct sg_table *
86 xhci_sideband_get_event_buffer(struct xhci_sideband *sb);
87 
88 #if IS_ENABLED(CONFIG_USB_XHCI_SIDEBAND)
89 bool xhci_sideband_check(struct usb_hcd *hcd);
90 #else
91 static inline bool xhci_sideband_check(struct usb_hcd *hcd)
92 { return false; }
93 #endif /* IS_ENABLED(CONFIG_USB_XHCI_SIDEBAND) */
94 
95 int
96 xhci_sideband_create_interrupter(struct xhci_sideband *sb, int num_seg,
97 				 bool ip_autoclear, u32 imod_interval, int intr_num);
98 void
99 xhci_sideband_remove_interrupter(struct xhci_sideband *sb);
100 int
101 xhci_sideband_interrupter_id(struct xhci_sideband *sb);
102 
103 #if IS_ENABLED(CONFIG_USB_XHCI_SIDEBAND)
104 void xhci_sideband_notify_ep_ring_free(struct xhci_sideband *sb,
105 				       unsigned int ep_index);
106 #else
107 static inline void xhci_sideband_notify_ep_ring_free(struct xhci_sideband *sb,
108 						     unsigned int ep_index)
109 { }
110 #endif /* IS_ENABLED(CONFIG_USB_XHCI_SIDEBAND) */
111 #endif /* __LINUX_XHCI_SIDEBAND_H */
112