Table of Contents
All communications between the driver and the device are performed using transactions. The driver always initiates the transaction, a device cannot send unsolicited data to the host. The USB core performs all management of a transaction on behalf of the driver and notifies it once it has finished (see Chapter 7).
The transaction moves data as an uninterpreted set of bytes. The direction of the transfer is determined by the pipe being used (see Chapter 4).
Control transactions are a special case, they are formatted data and can only be used on the bi-directional control pipe. They are also the only transaction that requires two URB.
The transaction requires the following before it is started
An open pipe (see Chapter 4) which specifies the direction and endpoint on the device.
A URB in which to contain the data to be sent or received. The URB used_size field indicates how much data is in the URB to be send for host to device transactions or the maximum size of data to be read from the device to the host.
A waiting structure to specify a waiting action upon transaction commencement. This structure is considered a template as it is never actually used by the transaction, it is merely a way of passing all the waiting parameters used in a single block.
A transaction is started using usb_request_start(USB_RequestStart (SWI&5538F)) passing the details as already outlined. It returns a pointer to a new waiting structure for the transaction, it does not modify the one passed in. There is also usb_request_start2(USBLib_RequestStart2 (SWI &56340)) which allows for a transaction timeout allowing the driver to take action if the device doesn't respond within a certain time.
A control transaction takes the form of a formatted structure whose contents are defined by the USB specification (see section 9.3 "USB Device Requests) on page 183 of the USB Specification 1.1). It may also have a second buffer to transfer data appropriate for the control transaction. The direction of data transfered is specified in the control transaction structure.
A control transaction may be sent by simple use of usblib_ctrl_msg(USBLib_CtrlMsg (SWI &56340)). Using this library call reduces the driver writers work to perform control transactions to providing two URB of sufficient size.
The library call simply formats the data as required in the USB specification and starts a control transaction.
If the driver write wishes to perform the control transaction themselves they should note the following
A URB must be filled with the formated data and a call make to usb_request_start(USB_RequestStart (SWI&5538F))
Care should be taken with the order URBs are passed to the usb_request_start(USB_RequestStart (SWI&5538F)) call as the formatted structure is passed as the additional URB.
The transactions behaviour flags must contain the USB_TRANSACTION_STATUS_STAGE flag to indicate it is a control transaction.
If the control transaction is not transferring any additional data they it may either pass NULL for the data URB or a URB with zero indicated length.
Example 6.1 shows in more detain how to perform a control transaction.
The waiting structure returned by starting a transaction is dependent on the type of waiting requested. The progress of a transaction is found using usb_request_get_state(USB_RequestGetState (SWI&55390)) passing the transactions waiting structure (not the template!). Two values are returned the first is the usual result which indicates if the call was successful or not and the second shows the requests completion status (see Table A.3). For more details on waiting see Chapter 7.
Once the transaction has completed, the associated waiting structure will be used to notify the driver that the transaction has completed. If the transaction failed with an error, the pipe may have become halted and the driver will have to take action to clear the error condition and restart the pipe.
The full list of result codes can be found Table A.3. However the most common ones are listed in more detail here.
The transaction completed normally, further transactions may be attempted.
The transaction is still in progress. This indicates to a driver that the transaction has yet to complete, and another attempt to read the status should be made later.
The transaction was halted by the device. For a normal pipe, the state of the pipe is set to halted and the pending transactions cleared.
For a control transaction, this means that the device did not accept the transaction, but the pipe is not placed into the halted state. Further transactions can be attempted on this pipe.
For receives, this is generated if the size of the transaction returned from the device is not equal to the URBs used_size field if the USB_TRANSACTION_EXACT_SIZE flag is set.
For transmits, this means that the driver attempted to send too much data to the endpoint for the device to handle.