/* SPDX-License-Identifier: GPL-2.0 */ /* * xHCI host controller sideband support * * Copyright (c) 2023-2025, Intel Corporation. * * Author: Mathias Nyman */ #ifndef __LINUX_XHCI_SIDEBAND_H #define __LINUX_XHCI_SIDEBAND_H #include #include #define EP_CTX_PER_DEV 31 /* FIXME defined twice, from xhci.h */ struct xhci_sideband; enum xhci_sideband_type { XHCI_SIDEBAND_AUDIO, XHCI_SIDEBAND_VENDOR, }; enum xhci_sideband_notify_type { XHCI_SIDEBAND_XFER_RING_FREE, }; /** * struct xhci_sideband_event - sideband event * @type: notifier type * @evt_data: event data */ struct xhci_sideband_event { enum xhci_sideband_notify_type type; void *evt_data; }; /** * struct xhci_sideband - representation of a sideband accessed usb device. * @xhci: The xhci host controller the usb device is connected to * @vdev: the usb device accessed via sideband * @eps: array of endpoints controlled via sideband * @ir: event handling and buffer for sideband accessed device * @type: xHCI sideband type * @mutex: mutex for sideband operations * @intf: USB sideband client interface * @notify_client: callback for xHCI sideband sequences * * FIXME usb device accessed via sideband Keeping track of sideband accessed usb devices. */ struct xhci_sideband { struct xhci_hcd *xhci; struct xhci_virt_device *vdev; struct xhci_virt_ep *eps[EP_CTX_PER_DEV]; struct xhci_interrupter *ir; enum xhci_sideband_type type; /* Synchronizing xHCI sideband operations with client drivers operations */ struct mutex mutex; struct usb_interface *intf; int (*notify_client)(struct usb_interface *intf, struct xhci_sideband_event *evt); }; struct xhci_sideband * xhci_sideband_register(struct usb_interface *intf, enum xhci_sideband_type type, int (*notify_client)(struct usb_interface *intf, struct xhci_sideband_event *evt)); void xhci_sideband_unregister(struct xhci_sideband *sb); int xhci_sideband_add_endpoint(struct xhci_sideband *sb, struct usb_host_endpoint *host_ep); int xhci_sideband_remove_endpoint(struct xhci_sideband *sb, struct usb_host_endpoint *host_ep); int xhci_sideband_stop_endpoint(struct xhci_sideband *sb, struct usb_host_endpoint *host_ep); struct sg_table * xhci_sideband_get_endpoint_buffer(struct xhci_sideband *sb, struct usb_host_endpoint *host_ep); struct sg_table * xhci_sideband_get_event_buffer(struct xhci_sideband *sb); int xhci_sideband_create_interrupter(struct xhci_sideband *sb, int num_seg, bool ip_autoclear, u32 imod_interval, int intr_num); void xhci_sideband_remove_interrupter(struct xhci_sideband *sb); int xhci_sideband_interrupter_id(struct xhci_sideband *sb); #if IS_ENABLED(CONFIG_USB_XHCI_SIDEBAND) void xhci_sideband_notify_ep_ring_free(struct xhci_sideband *sb, unsigned int ep_index); #else static inline void xhci_sideband_notify_ep_ring_free(struct xhci_sideband *sb, unsigned int ep_index) { } #endif /* IS_ENABLED(CONFIG_USB_XHCI_SIDEBAND) */ #endif /* __LINUX_XHCI_SIDEBAND_H */