xref: /linux/drivers/usb/host/xhci-sideband.c (revision d30c1683aaecb93d2ab95685dc4300a33d3cea7a)
1 // SPDX-License-Identifier: GPL-2.0
2 
3 /*
4  * xHCI host controller sideband support
5  *
6  * Copyright (c) 2023-2025, Intel Corporation.
7  *
8  * Author: Mathias Nyman
9  */
10 
11 #include <linux/usb/xhci-sideband.h>
12 #include <linux/dma-direct.h>
13 
14 #include "xhci.h"
15 
16 /* sideband internal helpers */
17 static struct sg_table *
18 xhci_ring_to_sgtable(struct xhci_sideband *sb, struct xhci_ring *ring)
19 {
20 	struct xhci_segment *seg;
21 	struct sg_table	*sgt;
22 	unsigned int n_pages;
23 	struct page **pages;
24 	struct device *dev;
25 	size_t sz;
26 	int i;
27 
28 	dev = xhci_to_hcd(sb->xhci)->self.sysdev;
29 	sz = ring->num_segs * TRB_SEGMENT_SIZE;
30 	n_pages = PAGE_ALIGN(sz) >> PAGE_SHIFT;
31 	pages = kvmalloc_array(n_pages, sizeof(struct page *), GFP_KERNEL);
32 	if (!pages)
33 		return NULL;
34 
35 	sgt = kzalloc(sizeof(*sgt), GFP_KERNEL);
36 	if (!sgt) {
37 		kvfree(pages);
38 		return NULL;
39 	}
40 
41 	seg = ring->first_seg;
42 	if (!seg)
43 		goto err;
44 	/*
45 	 * Rings can potentially have multiple segments, create an array that
46 	 * carries page references to allocated segments.  Utilize the
47 	 * sg_alloc_table_from_pages() to create the sg table, and to ensure
48 	 * that page links are created.
49 	 */
50 	for (i = 0; i < ring->num_segs; i++) {
51 		dma_get_sgtable(dev, sgt, seg->trbs, seg->dma,
52 				TRB_SEGMENT_SIZE);
53 		pages[i] = sg_page(sgt->sgl);
54 		sg_free_table(sgt);
55 		seg = seg->next;
56 	}
57 
58 	if (sg_alloc_table_from_pages(sgt, pages, n_pages, 0, sz, GFP_KERNEL))
59 		goto err;
60 
61 	/*
62 	 * Save first segment dma address to sg dma_address field for the sideband
63 	 * client to have access to the IOVA of the ring.
64 	 */
65 	sg_dma_address(sgt->sgl) = ring->first_seg->dma;
66 
67 	return sgt;
68 
69 err:
70 	kvfree(pages);
71 	kfree(sgt);
72 
73 	return NULL;
74 }
75 
76 /* Caller must hold sb->mutex */
77 static void
78 __xhci_sideband_remove_endpoint(struct xhci_sideband *sb, struct xhci_virt_ep *ep)
79 {
80 	lockdep_assert_held(&sb->mutex);
81 
82 	/*
83 	 * Issue a stop endpoint command when an endpoint is removed.
84 	 * The stop ep cmd handler will handle the ring cleanup.
85 	 */
86 	xhci_stop_endpoint_sync(sb->xhci, ep, 0, GFP_KERNEL);
87 
88 	ep->sideband = NULL;
89 	sb->eps[ep->ep_index] = NULL;
90 }
91 
92 /* Caller must hold sb->mutex */
93 static void
94 __xhci_sideband_remove_interrupter(struct xhci_sideband *sb)
95 {
96 	struct usb_device *udev;
97 
98 	lockdep_assert_held(&sb->mutex);
99 
100 	if (!sb->ir)
101 		return;
102 
103 	xhci_remove_secondary_interrupter(xhci_to_hcd(sb->xhci), sb->ir);
104 	sb->ir = NULL;
105 	udev = sb->vdev->udev;
106 
107 	if (udev->state != USB_STATE_NOTATTACHED)
108 		usb_offload_put(udev);
109 }
110 
111 /* sideband api functions */
112 
113 /**
114  * xhci_sideband_notify_ep_ring_free - notify client of xfer ring free
115  * @sb: sideband instance for this usb device
116  * @ep_index: usb endpoint index
117  *
118  * Notifies the xHCI sideband client driver of a xHCI transfer ring free
119  * routine.  This will allow for the client to ensure that all transfers
120  * are completed.
121  *
122  * The callback should be synchronous, as the ring free happens after.
123  */
124 void xhci_sideband_notify_ep_ring_free(struct xhci_sideband *sb,
125 				       unsigned int ep_index)
126 {
127 	struct xhci_sideband_event evt;
128 
129 	evt.type = XHCI_SIDEBAND_XFER_RING_FREE;
130 	evt.evt_data = &ep_index;
131 
132 	if (sb->notify_client)
133 		sb->notify_client(sb->intf, &evt);
134 }
135 EXPORT_SYMBOL_GPL(xhci_sideband_notify_ep_ring_free);
136 
137 /**
138  * xhci_sideband_add_endpoint - add endpoint to sideband access list
139  * @sb: sideband instance for this usb device
140  * @host_ep: usb host endpoint
141  *
142  * Adds an endpoint to the list of sideband accessed endpoints for this usb
143  * device.
144  * After an endpoint is added the sideband client can get the endpoint transfer
145  * ring buffer by calling xhci_sideband_endpoint_buffer()
146  *
147  * Return: 0 on success, negative error otherwise.
148  */
149 int
150 xhci_sideband_add_endpoint(struct xhci_sideband *sb,
151 			   struct usb_host_endpoint *host_ep)
152 {
153 	struct xhci_virt_ep *ep;
154 	unsigned int ep_index;
155 
156 	guard(mutex)(&sb->mutex);
157 
158 	if (!sb->vdev)
159 		return -ENODEV;
160 
161 	ep_index = xhci_get_endpoint_index(&host_ep->desc);
162 	ep = &sb->vdev->eps[ep_index];
163 
164 	if (ep->ep_state & EP_HAS_STREAMS)
165 		return -EINVAL;
166 
167 	/*
168 	 * Note, we don't know the DMA mask of the audio DSP device, if its
169 	 * smaller than for xhci it won't be able to access the endpoint ring
170 	 * buffer. This could be solved by not allowing the audio class driver
171 	 * to add the endpoint the normal way, but instead offload it immediately,
172 	 * and let this function add the endpoint and allocate the ring buffer
173 	 * with the smallest common DMA mask
174 	 */
175 	if (sb->eps[ep_index] || ep->sideband)
176 		return -EBUSY;
177 
178 	ep->sideband = sb;
179 	sb->eps[ep_index] = ep;
180 
181 	return 0;
182 }
183 EXPORT_SYMBOL_GPL(xhci_sideband_add_endpoint);
184 
185 /**
186  * xhci_sideband_remove_endpoint - remove endpoint from sideband access list
187  * @sb: sideband instance for this usb device
188  * @host_ep: usb host endpoint
189  *
190  * Removes an endpoint from the list of sideband accessed endpoints for this usb
191  * device.
192  * sideband client should no longer touch the endpoint transfer buffer after
193  * calling this.
194  *
195  * Return: 0 on success, negative error otherwise.
196  */
197 int
198 xhci_sideband_remove_endpoint(struct xhci_sideband *sb,
199 			      struct usb_host_endpoint *host_ep)
200 {
201 	struct xhci_virt_ep *ep;
202 	unsigned int ep_index;
203 
204 	guard(mutex)(&sb->mutex);
205 
206 	ep_index = xhci_get_endpoint_index(&host_ep->desc);
207 	ep = sb->eps[ep_index];
208 
209 	if (!ep || !ep->sideband || ep->sideband != sb)
210 		return -ENODEV;
211 
212 	__xhci_sideband_remove_endpoint(sb, ep);
213 
214 	return 0;
215 }
216 EXPORT_SYMBOL_GPL(xhci_sideband_remove_endpoint);
217 
218 int
219 xhci_sideband_stop_endpoint(struct xhci_sideband *sb,
220 			    struct usb_host_endpoint *host_ep)
221 {
222 	struct xhci_virt_ep *ep;
223 	unsigned int ep_index;
224 
225 	ep_index = xhci_get_endpoint_index(&host_ep->desc);
226 	ep = sb->eps[ep_index];
227 
228 	if (!ep || !ep->sideband || ep->sideband != sb)
229 		return -EINVAL;
230 
231 	return xhci_stop_endpoint_sync(sb->xhci, ep, 0, GFP_KERNEL);
232 }
233 EXPORT_SYMBOL_GPL(xhci_sideband_stop_endpoint);
234 
235 /**
236  * xhci_sideband_get_endpoint_buffer - gets the endpoint transfer buffer address
237  * @sb: sideband instance for this usb device
238  * @host_ep: usb host endpoint
239  *
240  * Returns the address of the endpoint buffer where xHC controller reads queued
241  * transfer TRBs from. This is the starting address of the ringbuffer where the
242  * sideband client should write TRBs to.
243  *
244  * Caller needs to free the returned sg_table
245  *
246  * Return: struct sg_table * if successful. NULL otherwise.
247  */
248 struct sg_table *
249 xhci_sideband_get_endpoint_buffer(struct xhci_sideband *sb,
250 				  struct usb_host_endpoint *host_ep)
251 {
252 	struct xhci_virt_ep *ep;
253 	unsigned int ep_index;
254 
255 	ep_index = xhci_get_endpoint_index(&host_ep->desc);
256 	ep = sb->eps[ep_index];
257 
258 	if (!ep || !ep->ring || !ep->sideband || ep->sideband != sb)
259 		return NULL;
260 
261 	return xhci_ring_to_sgtable(sb, ep->ring);
262 }
263 EXPORT_SYMBOL_GPL(xhci_sideband_get_endpoint_buffer);
264 
265 /**
266  * xhci_sideband_get_event_buffer - return the event buffer for this device
267  * @sb: sideband instance for this usb device
268  *
269  * If a secondary xhci interupter is set up for this usb device then this
270  * function returns the address of the event buffer where xHC writes
271  * the transfer completion events.
272  *
273  * Caller needs to free the returned sg_table
274  *
275  * Return: struct sg_table * if successful. NULL otherwise.
276  */
277 struct sg_table *
278 xhci_sideband_get_event_buffer(struct xhci_sideband *sb)
279 {
280 	if (!sb || !sb->ir)
281 		return NULL;
282 
283 	return xhci_ring_to_sgtable(sb, sb->ir->event_ring);
284 }
285 EXPORT_SYMBOL_GPL(xhci_sideband_get_event_buffer);
286 
287 /**
288  * xhci_sideband_check - check the existence of active sidebands
289  * @hcd: the host controller driver associated with the target host controller
290  *
291  * Allow other drivers, such as usb controller driver, to check if there are
292  * any sideband activity on the host controller. This information could be used
293  * for power management or other forms of resource management. The caller should
294  * ensure downstream usb devices are all either suspended or marked as
295  * "offload_at_suspend" to ensure the correctness of the return value.
296  *
297  * Returns true on any active sideband existence, false otherwise.
298  */
299 bool xhci_sideband_check(struct usb_hcd *hcd)
300 {
301 	struct usb_device *udev = hcd->self.root_hub;
302 	bool active;
303 
304 	usb_lock_device(udev);
305 	active = usb_offload_check(udev);
306 	usb_unlock_device(udev);
307 
308 	return active;
309 }
310 EXPORT_SYMBOL_GPL(xhci_sideband_check);
311 
312 /**
313  * xhci_sideband_create_interrupter - creates a new interrupter for this sideband
314  * @sb: sideband instance for this usb device
315  * @num_seg: number of event ring segments to allocate
316  * @ip_autoclear: IP autoclearing support such as MSI implemented
317  *
318  * Sets up a xhci interrupter that can be used for this sideband accessed usb
319  * device. Transfer events for this device can be routed to this interrupters
320  * event ring by setting the 'Interrupter Target' field correctly when queueing
321  * the transfer TRBs.
322  * Once this interrupter is created the interrupter target ID can be obtained
323  * by calling xhci_sideband_interrupter_id()
324  *
325  * Returns 0 on success, negative error otherwise
326  */
327 int
328 xhci_sideband_create_interrupter(struct xhci_sideband *sb, int num_seg,
329 				 bool ip_autoclear, u32 imod_interval, int intr_num)
330 {
331 	int ret = 0;
332 	struct usb_device *udev;
333 
334 	if (!sb || !sb->xhci)
335 		return -ENODEV;
336 
337 	guard(mutex)(&sb->mutex);
338 
339 	if (!sb->vdev)
340 		return -ENODEV;
341 
342 	if (sb->ir)
343 		return -EBUSY;
344 
345 	sb->ir = xhci_create_secondary_interrupter(xhci_to_hcd(sb->xhci),
346 						   num_seg, imod_interval,
347 						   intr_num);
348 	if (!sb->ir)
349 		return -ENOMEM;
350 
351 	udev = sb->vdev->udev;
352 	ret = usb_offload_get(udev);
353 
354 	sb->ir->ip_autoclear = ip_autoclear;
355 
356 	return ret;
357 }
358 EXPORT_SYMBOL_GPL(xhci_sideband_create_interrupter);
359 
360 /**
361  * xhci_sideband_remove_interrupter - remove the interrupter from a sideband
362  * @sb: sideband instance for this usb device
363  *
364  * Removes a registered interrupt for a sideband.  This would allow for other
365  * sideband users to utilize this interrupter.
366  */
367 void
368 xhci_sideband_remove_interrupter(struct xhci_sideband *sb)
369 {
370 	if (!sb)
371 		return;
372 
373 	guard(mutex)(&sb->mutex);
374 
375 	__xhci_sideband_remove_interrupter(sb);
376 }
377 EXPORT_SYMBOL_GPL(xhci_sideband_remove_interrupter);
378 
379 /**
380  * xhci_sideband_interrupter_id - return the interrupter target id
381  * @sb: sideband instance for this usb device
382  *
383  * If a secondary xhci interrupter is set up for this usb device then this
384  * function returns the ID used by the interrupter. The sideband client
385  * needs to write this ID to the 'Interrupter Target' field of the transfer TRBs
386  * it queues on the endpoints transfer ring to ensure transfer completion event
387  * are written by xHC to the correct interrupter event ring.
388  *
389  * Returns interrupter id on success, negative error othgerwise
390  */
391 int
392 xhci_sideband_interrupter_id(struct xhci_sideband *sb)
393 {
394 	if (!sb || !sb->ir)
395 		return -ENODEV;
396 
397 	return sb->ir->intr_num;
398 }
399 EXPORT_SYMBOL_GPL(xhci_sideband_interrupter_id);
400 
401 /**
402  * xhci_sideband_register - register a sideband for a usb device
403  * @intf: usb interface associated with the sideband device
404  *
405  * Allows for clients to utilize XHCI interrupters and fetch transfer and event
406  * ring parameters for executing data transfers.
407  *
408  * Return: pointer to a new xhci_sideband instance if successful. NULL otherwise.
409  */
410 struct xhci_sideband *
411 xhci_sideband_register(struct usb_interface *intf, enum xhci_sideband_type type,
412 		       int (*notify_client)(struct usb_interface *intf,
413 				    struct xhci_sideband_event *evt))
414 {
415 	struct usb_device *udev = interface_to_usbdev(intf);
416 	struct usb_hcd *hcd = bus_to_hcd(udev->bus);
417 	struct xhci_hcd *xhci = hcd_to_xhci(hcd);
418 	struct xhci_virt_device *vdev;
419 	struct xhci_sideband *sb;
420 
421 	/*
422 	 * Make sure the usb device is connected to a xhci controller.  Fail
423 	 * registration if the type is anything other than  XHCI_SIDEBAND_VENDOR,
424 	 * as this is the only type that is currently supported by xhci-sideband.
425 	 */
426 	if (!udev->slot_id || type != XHCI_SIDEBAND_VENDOR)
427 		return NULL;
428 
429 	sb = kzalloc_node(sizeof(*sb), GFP_KERNEL, dev_to_node(hcd->self.sysdev));
430 	if (!sb)
431 		return NULL;
432 
433 	mutex_init(&sb->mutex);
434 
435 	/* check this device isn't already controlled via sideband */
436 	spin_lock_irq(&xhci->lock);
437 
438 	vdev = xhci->devs[udev->slot_id];
439 
440 	if (!vdev || vdev->sideband) {
441 		xhci_warn(xhci, "XHCI sideband for slot %d already in use\n",
442 			  udev->slot_id);
443 		spin_unlock_irq(&xhci->lock);
444 		kfree(sb);
445 		return NULL;
446 	}
447 
448 	sb->xhci = xhci;
449 	sb->vdev = vdev;
450 	sb->intf = intf;
451 	sb->type = type;
452 	sb->notify_client = notify_client;
453 	vdev->sideband = sb;
454 
455 	spin_unlock_irq(&xhci->lock);
456 
457 	return sb;
458 }
459 EXPORT_SYMBOL_GPL(xhci_sideband_register);
460 
461 /**
462  * xhci_sideband_unregister - unregister sideband access to a usb device
463  * @sb: sideband instance to be unregistered
464  *
465  * Unregisters sideband access to a usb device and frees the sideband
466  * instance.
467  * After this the endpoint and interrupter event buffers should no longer
468  * be accessed via sideband. The xhci driver can now take over handling
469  * the buffers.
470  */
471 void
472 xhci_sideband_unregister(struct xhci_sideband *sb)
473 {
474 	struct xhci_virt_device *vdev;
475 	struct xhci_hcd *xhci;
476 	int i;
477 
478 	if (!sb)
479 		return;
480 
481 	xhci = sb->xhci;
482 
483 	scoped_guard(mutex, &sb->mutex) {
484 		vdev = sb->vdev;
485 		if (!vdev)
486 			return;
487 
488 		for (i = 0; i < EP_CTX_PER_DEV; i++)
489 			if (sb->eps[i])
490 				__xhci_sideband_remove_endpoint(sb, sb->eps[i]);
491 
492 		__xhci_sideband_remove_interrupter(sb);
493 
494 		sb->vdev = NULL;
495 	}
496 
497 	spin_lock_irq(&xhci->lock);
498 	sb->xhci = NULL;
499 	vdev->sideband = NULL;
500 	spin_unlock_irq(&xhci->lock);
501 
502 	kfree(sb);
503 }
504 EXPORT_SYMBOL_GPL(xhci_sideband_unregister);
505 MODULE_DESCRIPTION("xHCI sideband driver for secondary interrupter management");
506 MODULE_LICENSE("GPL");
507