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