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
15 #define EP_CTX_PER_DEV 31 /* FIXME defined twice, from xhci.h */
16
17 struct xhci_sideband;
18
19 enum xhci_sideband_type {
20 XHCI_SIDEBAND_AUDIO,
21 XHCI_SIDEBAND_VENDOR,
22 };
23
24 enum xhci_sideband_notify_type {
25 XHCI_SIDEBAND_XFER_RING_FREE,
26 };
27
28 /**
29 * struct xhci_sideband_event - sideband event
30 * @type: notifier type
31 * @evt_data: event data
32 */
33 struct xhci_sideband_event {
34 enum xhci_sideband_notify_type type;
35 void *evt_data;
36 };
37
38 /**
39 * struct xhci_sideband - representation of a sideband accessed usb device.
40 * @xhci: The xhci host controller the usb device is connected to
41 * @vdev: the usb device accessed via sideband
42 * @eps: array of endpoints controlled via sideband
43 * @ir: event handling and buffer for sideband accessed device
44 * @type: xHCI sideband type
45 * @mutex: mutex for sideband operations
46 * @intf: USB sideband client interface
47 * @notify_client: callback for xHCI sideband sequences
48 *
49 * FIXME usb device accessed via sideband Keeping track of sideband accessed usb devices.
50 */
51 struct xhci_sideband {
52 struct xhci_hcd *xhci;
53 struct xhci_virt_device *vdev;
54 struct xhci_virt_ep *eps[EP_CTX_PER_DEV];
55 struct xhci_interrupter *ir;
56 enum xhci_sideband_type type;
57
58 /* Synchronizing xHCI sideband operations with client drivers operations */
59 struct mutex mutex;
60
61 struct usb_interface *intf;
62 int (*notify_client)(struct usb_interface *intf,
63 struct xhci_sideband_event *evt);
64 };
65
66 struct xhci_sideband *
67 xhci_sideband_register(struct usb_interface *intf, enum xhci_sideband_type type,
68 int (*notify_client)(struct usb_interface *intf,
69 struct xhci_sideband_event *evt));
70 void
71 xhci_sideband_unregister(struct xhci_sideband *sb);
72 int
73 xhci_sideband_add_endpoint(struct xhci_sideband *sb,
74 struct usb_host_endpoint *host_ep);
75 int
76 xhci_sideband_remove_endpoint(struct xhci_sideband *sb,
77 struct usb_host_endpoint *host_ep);
78 int
79 xhci_sideband_stop_endpoint(struct xhci_sideband *sb,
80 struct usb_host_endpoint *host_ep);
81 struct sg_table *
82 xhci_sideband_get_endpoint_buffer(struct xhci_sideband *sb,
83 struct usb_host_endpoint *host_ep);
84 struct sg_table *
85 xhci_sideband_get_event_buffer(struct xhci_sideband *sb);
86 int
87 xhci_sideband_create_interrupter(struct xhci_sideband *sb, int num_seg,
88 bool ip_autoclear, u32 imod_interval, int intr_num);
89 void
90 xhci_sideband_remove_interrupter(struct xhci_sideband *sb);
91 int
92 xhci_sideband_interrupter_id(struct xhci_sideband *sb);
93
94 #if IS_ENABLED(CONFIG_USB_XHCI_SIDEBAND)
95 void xhci_sideband_notify_ep_ring_free(struct xhci_sideband *sb,
96 unsigned int ep_index);
97 #else
xhci_sideband_notify_ep_ring_free(struct xhci_sideband * sb,unsigned int ep_index)98 static inline void xhci_sideband_notify_ep_ring_free(struct xhci_sideband *sb,
99 unsigned int ep_index)
100 { }
101 #endif /* IS_ENABLED(CONFIG_USB_XHCI_SIDEBAND) */
102 #endif /* __LINUX_XHCI_SIDEBAND_H */
103