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