USB_PIPE_INTR_XFER(9F)  Kernel Functions for Drivers  USB_PIPE_INTR_XFER(9F)
NAME
       usb_pipe_intr_xfer, usb_pipe_stop_intr_polling - USB interrupt
       transfer and polling functions
SYNOPSIS
       #include <sys/usb/usba.h>       
int usb_pipe_intr_xfer(
usb_pipe_handle_t pipe_handle, 
usb_intr_req_t *request,            
usb_flags_t flags);       
void usb_pipe_stop_intr_polling(
usb_pipe_handle_t pipe_handle, 
usb__flags_t flags);
INTERFACE LEVEL
       illumos DDI specific (illumos DDI)
PARAMETERS
       For 
usb_pipe_intr_xfer():       
pipe_handle                      Interrupt pipe handle on which request is made.       
request                      Pointer to interrupt transfer request.       
flags                      USB_FLAGS_SLEEP is the only flag recognized. Wait for
                      needed resources if unavailable. For requests
                      specifying the USB_ATTRS_ONE_XFER attribute, wait for
                      the request to complete.
       For 
usb_pipe_stop_intr_polling():       
pipe_handle                      Interrupt pipe handle on which to stop polling for
                      data.       
flags                      USB_FLAGS_SLEEP is the only flag recognized. Wait for
                      polling to stop.
DESCRIPTION
       The 
usb_pipe_intr_xfer() function requests the USBA framework to
       perform a transfer through a USB interrupt pipe. The request is
       passed to the host controller driver (HCD), which performs the
       necessary transactions to complete the request.
       There are three categories of interrupt transfers: periodic or polled
       interrupt-IN, single-transfer interrupt-IN, and (single-transfer)
       interrupt-OUT.   
Periodic Interrupt-IN Transfers       Periodic or polled interrupt-IN transfers execute on input requests
       which do not have the USB_ATTRS_ONE_XFER attribute set. One request
       enables repetitive transfers at a periodic rate set by the endpoint's
       bInterval. There can be only one interrupt-IN request submitted at a
       time.
       Periodic interrupt-IN transfers are always asynchronous. Client
       driver notification of new data is always via a callback. The
       USB_FLAGS_SLEEP flag is only to wait for resources to become
       available. Callbacks must always be in place to receive transfer
       completion notification. Please see 
usb_callback_flags(9S) for
       details on USB callbacks.
       Calls made to 
usb_pipe_intr_xfer() for starting input polling need
       allocate only one request. The USBA framework allocates a new request
       each time polling has new data to return.  (Note that each request
       returned must be freed via 
usb_free_intr_req(9F). Specify a zero
       length when calling 
usb_alloc_intr_req() to allocate the original
       request, since it will not be used to return data.  Set the intr_len
       in the request to specify how much data can be returned per polling
       interval.
       The original request passed to 
usb_pipe_intr_xfer() is used to return
       status when polling is terminated, or on an error condition when the
       USB_ATTRS_AUTOCLEARING attribute is set for the request. If
       autoclearing is not set, the current (non-original) request is
       returned on error. Call 
usb_pipe_reset(9F) to reset the pipe and get
       back the original request in this case. The USB_CR_STOPPED_POLLING
       flag is always set for callbacks where the original request is
       returned.   
Single-transfer Interrupt-IN Transfers       Interrupt-IN requests which have the USB_ATTRS_ONE_XFER attribute
       perform a single transfer. Such requests are synchronous when the
       USB_FLAGS_SLEEP flag is specified. Calls for synchronous requests do
       not return until their transaction is complete, and their callbacks
       are optional. The request is returned to the client through the
       normal or the exception completion callback to signal either normal
       completion or an error condition.   
Interrupt-OUT Transfers       Interrupt-OUT requests always set up for a single transfer. However,
       multiple requests can be queued and execute in periodic fashion until
       depleted.
       Interrupt-OUT transfers are synchronous when the USB_FLAGS_SLEEP flag
       is set in the request's flags. Calls for synchronous transfers will
       not return until their transaction has completed. Calls for
       asynchronous transfers notify the client driver of transaction
       completion via a normal callback, or error completion via an
       exception callback.
       The 
usb_pipe_stop_intr_polling() function terminates polling on
       interrupt-IN pipes and does the following:
         1. Cease polling.
         2. Allow any requests-in-progress to complete and be returned to
         the client driver through the normal callback mechanism.
         3. Idle the pipe.
         4. Return the original polling request to the client driver through
         an exception callback with a completion reason of
         USB_CR_STOPPED_POLLING.
       The client driver may restart polling from an exception callback only
       if the callback corresponds to an original request. The callback
       handler checks for the following completion reasons to ensure that a
       callback corresponds to an original request:
                 USB_CR_STOPPED_POLLING,
                 USB_CR_PIPE_RESET,
                 USB_CR_PIPE_CLOSING,
                 USB_CR_NOT_SUPPORTED
       The callback handler also checks the request's intr_data field to
       mark original polling requests, when the requests are created with a
       zero 
len argument.  In this case, a NULL intr_data field
       distinguishes a returned original request from a request allocated by
       the framework during polling.
       Mblks for data for interrupt-OUT requests are allocated when a
       request is allocated via 
usb_alloc_intr_req(9F) by passing a non-
       negative value for the 
len argument.
RETURN VALUES
       For 
usb_pipe_intr_xfer()       USB_SUCCESS                                Transfer was successful.       
USB_INVALID_ARGS                                Request is 
NULL.       
USB_INVALID_CONTEXT                                Called from interrupt context with the
                                USB_FLAGS_SLEEP flag set.       
USB_INVALID_REQUEST                                The request has been freed or otherwise
                                invalidated.
                                A set of conflicting attributes was
                                specified. See 
usb_intr_request(9S).
                                The normal and/or  exception callback was
                                NULL, USB_FLAGS_SLEEP was not set and
                                USB_ATTRS_ONE_XFER was not set.
                                An interrupt request was  specified with a
                                NULL data and a non-zero intr_len value.
                                An IN interrupt request was specified with
                                both polling (USB_ATTRS_ONE_XFER clear in
                                attributes) and non-zero timeout specified.
                                An IN interrupt request was specified with a
                                non-NULL data argument.
                                An OUT interrupt request was specified with
                                a NULL data argument.       
USB_INVALID_PIPE                                Pipe handle is NULL or invalid.
                                Pipe is closing or closed.       
USB_PIPE_ERROR                                Pipe handle refers to a pipe which is in the
                                USB_PIPE_STATE_ERROR state.       
USB_NO_RESOURCES                                Memory, descriptors or other resources
                                unavailable.       
USB_HC_HARDWARE_ERROR                                Host controller is in error state.       
USB_FAILURE                                An asynchronous transfer failed or an
                                internal error occurred.
                                An intr polling request is made while
                                polling is already in progress.
                                The pipe is in an unsuitable state (error,
                                busy, not ready).
                                Additional status information may be
                                available in the intr_completion_reason and
                                intr_cb_flags fields of the request. Please
                                see 
usb_completion_reason(9S) and                                
usb_callback_flags(9S) for more information.
       For 
usb_pipe_stop_intr_polling()       None, but fails if called with USB_FLAGS_SLEEP specified from
       interrupt context, pipe handle is invalid, NULL or pertains to a
       closing or closed pipe, or the pipe is in an error state. Error
       messages are logged to the console logfile.
       Exception handlers' queued requests which are flushed by these
       commands before execution are returned with completion reason of
       USB_CR_FLUSHED.
CONTEXT
       Both of these functions can be called from kernel or user context
       without regard to arguments, and may be called from interrupt context
       only when the USB_FLAGS_SLEEP flag is clear.
EXAMPLES
          /* Start polling on interrupt-IN pipe. */
          usb_intr_req_t intr_req;
          void intr_pipe_callback(usb_pipe_handle_t, usb_intr_req_t*);
          void intr_pipe_exception_callback(
              usb_pipe_handle_t, usb_intr_req_t*);
          usb_ep_descr_t *ep_descr;
          ep_descr = ...;
          intr_req = usb_alloc_intr_req(dip, 0, USB_FLAGS_SLEEP);
          ...
          ...
          intr_req->intr_attributes   = USB_ATTRS_SHORT_XFER_OK;
          intr_req->intr_len          = ep_descr->wMaxPacketSize;
          ...
          ...
          intr_req->intr_cb           = intr_pipe_callback;
          intr_req->intr_exc_cb       = intr_pipe_exception_callback;
          if ((rval = usb_pipe_intr_xfer(pipe, intr_req, USB_FLAGS_NOSLEEP))
              != USB_SUCCESS) {
                cmn_err (CE_WARN, "%s%d: Error starting interrupt pipe polling.",
                    ddi_driver_name(dip), ddi_get_instance(dip));
          }
          -------
          /* Stop polling before setting device idle.  Wait for polling to stop. */
          usb_pipe_stop_intr_polling(pipe, USB_FLAGS_SLEEP);
          (void) pm_idle_component(dip, 0);
          -------
          /* Allocate, initialize and issue a synchronous intr-OUT request. */
          usb_intr_req_t intr_req;
          mblk_t *mblk;
          usb_ep_descr_t *ep_descr;
          ep_descr = ...;
          intr_req =
            usb_alloc_intr_req(dip, ep_descr->wMaxPacketSize, USB_FLAGS_SLEEP);
          intr_req->intr_attributes   = USB_ATTRS_AUTOCLEARING;
          mblk = intr_req->intr_data;
          bcopy(buffer, mblk->b_wptr, ep_descr->wMaxPacketSize);
          mblk->b_wptr += ep_descr->wMaxPacketSize;
          if ((rval = usb_pipe_intr_xfer(pipe, intr_req, USB_FLAGS_SLEEP))
              != USB_SUCCESS) {
                  cmn_err (CE_WARN, "%s%d: Error writing intr data.",
                      ddi_driver_name(dip), ddi_get_instance(dip));
          }
ATTRIBUTES
       See 
attributes(7) for descriptions of the following attributes:
       +--------------------+-------------------+
       |  ATTRIBUTE TYPE    |  ATTRIBUTE VALUE  |
       +--------------------+-------------------+
       |Architecture        | PCI-based systems |
       +--------------------+-------------------+
       |Interface stability | Evolving          |
       +--------------------+-------------------+
SEE ALSO
       attributes(7), 
usb_alloc_request(9F), 
usb_get_cfg(9F),       
usb_get_status(9F), 
usb_pipe_bulk_xfer(9F), 
usb_pipe_ctrl_xfer(9F),       
usb_pipe_get_state(9F), 
usb_pipe_isoc_xfer(9F), 
usb_pipe_reset(9F),       
usb_pipe_xopen(9F), 
usb_bulk_request(9S), 
usb_callback_flags(9S),       
usb_completion_reason(9S), 
usb_ctrl_request(9S), 
usb_ep_descr(9S),       
usb_intr_request(9S), 
usb_isoc_request(9S)                             September 16, 2016       USB_PIPE_INTR_XFER(9F)