4.3. Pipes

4.3.1. Control pipes

A pipe is a communication channel between a driver and a specified endpoint on a device.

It is established by calling usb_pipe_open (USB_PipeOpen (SWI&5538B)) with the endpoint the driver wishes to attach the pipe to. The pipe can either be opened exclusively which is the default behaviour or may be shared (more than one pipe per endpoint may be opened).

A pipe should be closed when the driver no longer wishes to perform transactions through it. This is achieved using usb_pipe_close (USB_PipeClose (SWI&5538C)) with the specified pipe.

A pipe may be cleared, i.e. all transactions removed, using usb_pipe_clear (USB_PipeClear (SWI&5538D)) with the specified pipe.

A pipe may become halted from either an error condition from a failed transaction or by calling usb_pipe_halt(USB_PipeHalt (SWI&5538E)) with the specified pipe. Once a pipe is in the halted state a driver should resolve the error condition and clear the pipe which will return the pipe to the active state and allow transactions to be processed once more.

4.3.1. Control pipes

A control pipe has several special properties that differentiate it from a normal pipe, including it's bi-directionality and that in normal operation it cannot be halted.

A pipe on the control endpoint should always be opened shared to allow other drivers access to the configuration and control information of a device.

A halt condition from a transaction on a control pipe means that the transaction was not understood or not supported by the device but does not halt the pipe.

Example 4.1. Obtaining a control pipe

This example shows how to obtain a default pipe given a controller name and device number. These are typically obtained from the information in a new device message, usually obtained when the device is found using usb_devmgr_find_free(USBLib_DevMgrFindFree (SWI &5635A)) see Chapter 3, Driver Initialisation for more details.

This example is identical in function to the one show in Example 3.2, “Using USBLib_GetDefaultPipe”.


static usb_pipe_t*
get_default_pipe(const char *controller_name,
                 unsigned long device_number)
{
    int result;
    void *hc_ref;
    struct usb_device_s* dev_ref;
    struct usb_endpoint_s* control_ep;
    usb_pipe_t* control_pipe;

    hc_ref = usb_find_object(NULL, (unsigned long)controller_name,
                             USB_REFERENCE_CONTROLLER,
                             0, NULL, &result);

    if (result != USB_RESULT_OK) {
	printf("failed to find host-controller %s\n", dev->controller_name);
	return NULL;
    }

    dev_ref = usb_find_device_ref(device_number,
				  hc_ref);

    if (dev_ref == NULL) {
	fprintf(stderr, "failed to find device reference\n");
	return NULL;
    }

    /* obtain control pipe */
    control_pipe = usb_get_default_pipe(dev_ref,
                                        dev_ref->hostcontroller,
                                        &control_ep);

    if (control_pipe == NULL) {
	fprintf(stderr, "failed to open default pipe\n");
    }

    return control_pipe;
}