KolibriOS kernel
usb_pipe Struct Reference

Pipe descriptor. An USB pipe is described by two structures, for hardware and for software. This is the software part. The hardware part is defined in a driver of the corresponding controller. The hardware part is located immediately before usb_pipe, both are allocated at once by controller-specific code (it knows the total length, which depends on the hardware part). More...

Public Attributes

dd Controller
 
dd NextVirt
 
dd PrevVirt
 
dd BaseList
 
dd LastTD
 
dd NextSibling
 
dd PrevSibling
 
dd NextWait
 
MUTEX Lock
 
db Type
 
db Flags
 
dd DeviceData
 

Detailed Description

Pipe descriptor. An USB pipe is described by two structures, for hardware and for software. This is the software part. The hardware part is defined in a driver of the corresponding controller. The hardware part is located immediately before usb_pipe, both are allocated at once by controller-specific code (it knows the total length, which depends on the hardware part).

Source
bus/usb/common.inc:268

Member Data Documentation

◆ BaseList

dd usb_pipe::BaseList

Previous endpoint in the processing list. See also NextVirt field and the description before NextVirt field.

◆ Controller

dd usb_pipe::Controller

◆ DeviceData

dd usb_pipe::DeviceData

◆ Flags

db usb_pipe::Flags

Type of pipe, one of {CONTROL,ISOCHRONOUS,BULK,INTERRUPT}_PIPE.

◆ LastTD

dd usb_pipe::LastTD

Pointer to head of the processing list.

Every pipe has the associated transfer queue, that is, the double-linked list of Transfer Descriptors aka TD. For Control, Bulk and Interrupt endpoints this list consists of usb_gtd structures (GTD = General Transfer Descriptors), for Isochronous endpoints this list consists of usb_itd structures, which are not developed yet. The pipe needs to know only the last TD; the first TD can be obtained as [[pipe.LastTD].NextVirt].

◆ Lock

MUTEX usb_pipe::Lock

◆ NextSibling

dd usb_pipe::NextSibling

Last TD in the transfer queue.

All opened pipes corresponding to the same physical device are organized in the double-linked list using .NextSibling and .PrevSibling fields. The head of this list is kept in usb_device_data structure (OpenedPipeList). This list is used when the device is disconnected and all pipes for the device should be closed. Also, all pipes closed due to disconnect must remain valid at least until driver-provided disconnect function returns; all should-be-freed-but-not-now pipes for one device are organized in another double-linked list with the head in usb_device_data.ClosedPipeList; this list uses the same link fields, one pipe can never be in both lists.

◆ NextVirt

dd usb_pipe::NextVirt

Pointer to usb_controller structure corresponding to this pipe. Must be the first dword after hardware part, see *hci_new_device.

Every endpoint is included into one of processing lists: Bulk list contains all Bulk endpoints. Control list contains all Control endpoints. Several Periodic lists serve Interrupt endpoints with different interval.

  • There are N=2^n "leaf" periodic lists for N ms interval, one is processed in the frames 0,N,2N,..., another is processed in the frames 1,1+N,1+2N,... and so on. The hardware starts processing of periodic endpoints in every frame from the list identified by lower n bits of the frame number; the addresses of these N lists are written to the controller data area during the initialization.
  • We assume that n=5, N=32 to simplify the code and compact the data. OHCI works in this way. UHCI and EHCI actually have n=10, N=1024, but this is an overkill for interrupt endpoints; the large value of N is useful only for isochronous transfers in UHCI and EHCI. UHCI/EHCI code initializes "leaf" lists k,k+32,k+64,...,k+(1024-32) to the same value, giving essentially N=32. This restriction means that the actual maximum interval of polling any interrupt endpoint is 32ms, which seems to be a reasonable value.
  • Similarly, there are 16 lists for 16-ms interval, 8 lists for 8-ms interval and so on. Finally, there is one list for 1ms interval. Their addresses are not directly known to the controller.
  • The hardware serves endpoints following a physical link from the hardware part.
  • The hardware links are organized as follows. If the list item is not the last, it's hardware link points to the next item. The hardware link of the last item points to the first item of the "next" list.
  • The "next" list for k-th and (k+M)-th periodic lists for interval 2M ms is the k-th periodic list for interval M ms, M >= 1. In this scheme, if two "previous" lists are served in the frames k,k+2M,k+4M,... and k+M,k+3M,k+5M,... correspondingly, the "next" list is served in the frames k,k+M,k+2M,k+3M,k+4M,k+5M,..., which is exactly what we want.
  • The links between Periodic, Control, Bulk lists and the processing of Isochronous endpoints are controller-specific. The head of every processing list is a static entry which does not correspond to any real pipe. It is described by usb_static_ep structure, not usb_pipe. For OHCI and UHCI, sizeof.usb_static_ep plus sizeof hardware part is 20h, the total number of lists is 32+16+8+4+2+1+1+1 = 65, so all these structures fit in one page, leaving space for other data. This is another reason for 32ms limit. Static endpoint descriptors are kept in *hci_controller structure. All items in every processing list, including the static head, are organized in a double-linked list using .NextVirt and .PrevVirt fields. [[item.NextVirt].PrevVirt] = [[item.PrevVirt].NextVirt] for all items.

◆ NextWait

dd usb_pipe::NextWait

Previous pipe for the physical device.

When hardware part of pipe is changed, some time is needed before further actions so that hardware reacts on this change. During that time, all changed pipes are organized in single-linked list with the head usb_controller.WaitPipeList* and link field NextWait. Currently there are two possible reasons to change: change of address/packet size in initial configuration, close of the pipe. They are distinguished by USB_FLAG_CLOSED.

◆ PrevSibling

dd usb_pipe::PrevSibling

Next pipe for the physical device.

◆ PrevVirt

dd usb_pipe::PrevVirt

Next endpoint in the processing list. See also PrevVirt field and the description before NextVirt field.

◆ Type

db usb_pipe::Type

Mutex that guards operations with transfer queue for this pipe.


The documentation for this struct was generated from the following file: