162306a36Sopenharmony_ciUSB bulk streams 262306a36Sopenharmony_ci~~~~~~~~~~~~~~~~ 362306a36Sopenharmony_ci 462306a36Sopenharmony_ciBackground 562306a36Sopenharmony_ci========== 662306a36Sopenharmony_ci 762306a36Sopenharmony_ciBulk endpoint streams were added in the USB 3.0 specification. Streams allow a 862306a36Sopenharmony_cidevice driver to overload a bulk endpoint so that multiple transfers can be 962306a36Sopenharmony_ciqueued at once. 1062306a36Sopenharmony_ci 1162306a36Sopenharmony_ciStreams are defined in sections 4.4.6.4 and 8.12.1.4 of the Universal Serial Bus 1262306a36Sopenharmony_ci3.0 specification at https://www.usb.org/developers/docs/ The USB Attached SCSI 1362306a36Sopenharmony_ciProtocol, which uses streams to queue multiple SCSI commands, can be found on 1462306a36Sopenharmony_cithe T10 website (https://t10.org/). 1562306a36Sopenharmony_ci 1662306a36Sopenharmony_ci 1762306a36Sopenharmony_ciDevice-side implications 1862306a36Sopenharmony_ci======================== 1962306a36Sopenharmony_ci 2062306a36Sopenharmony_ciOnce a buffer has been queued to a stream ring, the device is notified (through 2162306a36Sopenharmony_cian out-of-band mechanism on another endpoint) that data is ready for that stream 2262306a36Sopenharmony_ciID. The device then tells the host which "stream" it wants to start. The host 2362306a36Sopenharmony_cican also initiate a transfer on a stream without the device asking, but the 2462306a36Sopenharmony_cidevice can refuse that transfer. Devices can switch between streams at any 2562306a36Sopenharmony_citime. 2662306a36Sopenharmony_ci 2762306a36Sopenharmony_ci 2862306a36Sopenharmony_ciDriver implications 2962306a36Sopenharmony_ci=================== 3062306a36Sopenharmony_ci 3162306a36Sopenharmony_ci:: 3262306a36Sopenharmony_ci 3362306a36Sopenharmony_ci int usb_alloc_streams(struct usb_interface *interface, 3462306a36Sopenharmony_ci struct usb_host_endpoint **eps, unsigned int num_eps, 3562306a36Sopenharmony_ci unsigned int num_streams, gfp_t mem_flags); 3662306a36Sopenharmony_ci 3762306a36Sopenharmony_ciDevice drivers will call this API to request that the host controller driver 3862306a36Sopenharmony_ciallocate memory so the driver can use up to num_streams stream IDs. They must 3962306a36Sopenharmony_cipass an array of usb_host_endpoints that need to be setup with similar stream 4062306a36Sopenharmony_ciIDs. This is to ensure that a UASP driver will be able to use the same stream 4162306a36Sopenharmony_ciID for the bulk IN and OUT endpoints used in a Bi-directional command sequence. 4262306a36Sopenharmony_ci 4362306a36Sopenharmony_ciThe return value is an error condition (if one of the endpoints doesn't support 4462306a36Sopenharmony_cistreams, or the xHCI driver ran out of memory), or the number of streams the 4562306a36Sopenharmony_cihost controller allocated for this endpoint. The xHCI host controller hardware 4662306a36Sopenharmony_cideclares how many stream IDs it can support, and each bulk endpoint on a 4762306a36Sopenharmony_ciSuperSpeed device will say how many stream IDs it can handle. Therefore, 4862306a36Sopenharmony_cidrivers should be able to deal with being allocated less stream IDs than they 4962306a36Sopenharmony_cirequested. 5062306a36Sopenharmony_ci 5162306a36Sopenharmony_ciDo NOT call this function if you have URBs enqueued for any of the endpoints 5262306a36Sopenharmony_cipassed in as arguments. Do not call this function to request less than two 5362306a36Sopenharmony_cistreams. 5462306a36Sopenharmony_ci 5562306a36Sopenharmony_ciDrivers will only be allowed to call this API once for the same endpoint 5662306a36Sopenharmony_ciwithout calling usb_free_streams(). This is a simplification for the xHCI host 5762306a36Sopenharmony_cicontroller driver, and may change in the future. 5862306a36Sopenharmony_ci 5962306a36Sopenharmony_ci 6062306a36Sopenharmony_ciPicking new Stream IDs to use 6162306a36Sopenharmony_ci============================= 6262306a36Sopenharmony_ci 6362306a36Sopenharmony_ciStream ID 0 is reserved, and should not be used to communicate with devices. If 6462306a36Sopenharmony_ciusb_alloc_streams() returns with a value of N, you may use streams 1 though N. 6562306a36Sopenharmony_ciTo queue an URB for a specific stream, set the urb->stream_id value. If the 6662306a36Sopenharmony_ciendpoint does not support streams, an error will be returned. 6762306a36Sopenharmony_ci 6862306a36Sopenharmony_ciNote that new API to choose the next stream ID will have to be added if the xHCI 6962306a36Sopenharmony_cidriver supports secondary stream IDs. 7062306a36Sopenharmony_ci 7162306a36Sopenharmony_ci 7262306a36Sopenharmony_ciClean up 7362306a36Sopenharmony_ci======== 7462306a36Sopenharmony_ci 7562306a36Sopenharmony_ciIf a driver wishes to stop using streams to communicate with the device, it 7662306a36Sopenharmony_cishould call:: 7762306a36Sopenharmony_ci 7862306a36Sopenharmony_ci void usb_free_streams(struct usb_interface *interface, 7962306a36Sopenharmony_ci struct usb_host_endpoint **eps, unsigned int num_eps, 8062306a36Sopenharmony_ci gfp_t mem_flags); 8162306a36Sopenharmony_ci 8262306a36Sopenharmony_ciAll stream IDs will be deallocated when the driver releases the interface, to 8362306a36Sopenharmony_ciensure that drivers that don't support streams will be able to use the endpoint. 84