Files | |
file | batch.c |
UHCI driver USB transfer structure. | |
file | batch.h |
UHCI driver USB tranfer helper functions. | |
file | endpoint.c |
UHCI host controller driver structure. | |
file | hc.c |
UHCI Host controller driver routines. | |
file | hc.h |
UHCI host controller driver structure. | |
file | iface.c |
UHCI driver hc interface implementation. | |
file | iface.h |
UHCI driver iface. | |
file | link_pointer.h |
UHCI driver. | |
file | main.c |
UHCI driver initialization. | |
file | pci.c |
PCI related functions needed by the UHCI driver. | |
file | pci.h |
UHCI driver PCI helper functions. | |
file | queue_head.h |
UHCI driver. | |
file | transfer_descriptor.c |
UHCI driver. | |
file | transfer_descriptor.h |
UHCI driver. | |
file | transfer_list.c |
UHCI driver transfer list implementation. | |
file | transfer_list.h |
UHCI driver transfer list structure. | |
Data Structures | |
struct | hc |
Main OHCI drier structure. More... | |
struct | queue_head |
This structure is defined in UHCI design guide p. More... | |
struct | transfer_descriptor |
Transfer Descriptor, defined in UHCI design guide p. More... | |
struct | transfer_list |
Structure maintaining both hw queue and software list of currently executed transfers. More... | |
struct | uhci_regs |
UHCI I/O registers layout. More... | |
struct | uhci_transfer_batch |
UHCI specific data required for USB transfer. More... | |
Defines | |
#define | DEFAULT_ERROR_COUNT 3 |
#define | LINK_POINTER_ADDRESS_MASK 0xfffffff0 |
#define | LINK_POINTER_QH(address) ((address & LINK_POINTER_ADDRESS_MASK) | LINK_POINTER_QUEUE_HEAD_FLAG) |
#define | LINK_POINTER_QUEUE_HEAD_FLAG (1 << 1) |
#define | LINK_POINTER_RESERVED_FLAG (1 << 3) |
#define | LINK_POINTER_TD(address) (address & LINK_POINTER_ADDRESS_MASK) |
#define | LINK_POINTER_TERM ((link_pointer_t)LINK_POINTER_TERMINATE_FLAG) |
#define | LINK_POINTER_TERMINATE_FLAG (1 << 0) |
#define | LINK_POINTER_VERTICAL_FLAG (1 << 2) |
#define | LINK_POINTER_ZERO_BIT_FLAG (1 << 2) |
#define | NAME "uhci-hcd" |
#define | UHCI_ALLOWED_HW_FAIL 5 |
#define | UHCI_DEBUGER_TIMEOUT 5000000 |
#define | UHCI_FRAME_LIST_COUNT 1024 |
#define | UHCI_INT_EMULATOR_TIMEOUT 10000 |
#define | UHCI_INTR_ALLOW_INTERRUPTS (UHCI_INTR_CRC | UHCI_INTR_COMPLETE | UHCI_INTR_SHORT_PACKET) |
#define | UHCI_NEEDED_IRQ_COMMANDS 5 |
#define | UHCI_STATUS_USED_INTERRUPTS (UHCI_STATUS_INTERRUPT | UHCI_STATUS_ERROR_INTERRUPT) |
Typedefs | |
typedef hc | hc_t |
Main UHCI driver structure. | |
typedef uint32_t | link_pointer_t |
typedef queue_head | qh_t |
This structure is defined in UHCI design guide p. | |
typedef uhci_regs | regs_t |
UHCI I/O registers layout. | |
typedef transfer_descriptor | td_t |
Transfer Descriptor, defined in UHCI design guide p. | |
typedef transfer_list | transfer_list_t |
Structure maintaining both hw queue and software list of currently executed transfers. | |
typedef uhci_transfer_batch | uhci_transfer_batch_t |
UHCI specific data required for USB transfer. | |
Functions | |
void | batch_bulk_in (usb_transfer_batch_t *instance) |
Prepare bulk in transfer. | |
void | batch_bulk_out (usb_transfer_batch_t *instance) |
Prepare bulk out transfer. | |
static void | batch_control (usb_transfer_batch_t *instance, usb_packet_id data_stage, usb_packet_id status_stage) |
Prepare generic control transfer. | |
void | batch_control_read (usb_transfer_batch_t *instance) |
Prepares control read transfer. | |
void | batch_control_write (usb_transfer_batch_t *instance) |
Prepares control write transfer. | |
static void | batch_data (usb_transfer_batch_t *instance, usb_packet_id pid) |
Prepare generic data transfer. | |
usb_transfer_batch_t * | batch_get (ddf_fun_t *fun, endpoint_t *ep, char *buffer, size_t buffer_size, const char *setup_buffer, size_t setup_size, usbhc_iface_transfer_in_callback_t func_in, usbhc_iface_transfer_out_callback_t func_out, void *arg) |
Allocate memory and initialize internal data structure. | |
void | batch_interrupt_in (usb_transfer_batch_t *instance) |
Prepare interrupt in transfer. | |
void | batch_interrupt_out (usb_transfer_batch_t *instance) |
Prepare interrupt out transfer. | |
bool | batch_is_complete (usb_transfer_batch_t *instance) |
Check batch TDs for activity. | |
qh_t * | batch_qh (usb_transfer_batch_t *instance) |
Provides access to QH data structure. | |
static int | bind_address (ddf_fun_t *fun, usb_address_t address, devman_handle_t handle) |
Bind address interface function. | |
static int | bulk_in (ddf_fun_t *fun, usb_target_t target, void *data, size_t size, usbhc_iface_transfer_in_callback_t callback, void *arg) |
Bulk in transaction interface function. | |
static int | bulk_out (ddf_fun_t *fun, usb_target_t target, void *data, size_t size, usbhc_iface_transfer_out_callback_t callback, void *arg) |
Bulk out transaction interface function. | |
static int | control_read (ddf_fun_t *fun, usb_target_t target, void *setup_data, size_t setup_size, void *data, size_t size, usbhc_iface_transfer_in_callback_t callback, void *arg) |
Control read transaction interface function. | |
static int | control_write (ddf_fun_t *fun, usb_target_t target, void *setup_data, size_t setup_size, void *data, size_t size, usbhc_iface_transfer_out_callback_t callback, void *arg) |
Control write transaction interface function. | |
void | endpoint_clear_hc_data (endpoint_t *instance) |
void | endpoint_destroy (endpoint_t *instance) |
int | endpoint_init (endpoint_t *instance, usb_address_t address, usb_endpoint_t endpoint, usb_direction_t direction, usb_transfer_type_t type, usb_speed_t speed, size_t max_packet_size) |
void | endpoint_release (endpoint_t *instance) |
void | endpoint_set_hc_data (endpoint_t *instance, void *data, int(*toggle_get)(void *), void(*toggle_set)(void *, int)) |
int | endpoint_toggle_get (endpoint_t *instance) |
void | endpoint_toggle_reset_filtered (endpoint_t *instance, usb_target_t target) |
void | endpoint_toggle_set (endpoint_t *instance, int toggle) |
void | endpoint_use (endpoint_t *instance) |
static int | find_by_address (ddf_fun_t *fun, usb_address_t address, devman_handle_t *handle) |
Find device handle by address interface function. | |
static hc_t * | fun_to_hc (ddf_fun_t *fun) |
Get and cast pointer to the driver data. | |
static int | hc_debug_checker (void *arg) |
Debug function, checks consistency of memory structures. | |
static void | hc_fini (hc_t *instance) |
Safely dispose host controller internal structures. | |
int | hc_init (hc_t *instance, void *regs, size_t reg_size, bool interrupts) |
Initialize UHCI hc driver structure. | |
static void | hc_init_hw (hc_t *instance) |
Initialize UHCI hc hw resources. | |
static int | hc_init_mem_structures (hc_t *instance) |
Initialize UHCI hc memory structures. | |
static int | hc_init_transfer_lists (hc_t *instance) |
Initialize UHCI hc transfer lists. | |
void | hc_interrupt (hc_t *instance, uint16_t status) |
Take action based on the interrupt cause. | |
static int | hc_interrupt_emulator (void *arg) |
Polling function, emulates interrupts. | |
int | hc_schedule (hc_t *instance, usb_transfer_batch_t *batch) |
Add USB transfer to the schedule. | |
static int | interrupt_in (ddf_fun_t *fun, usb_target_t target, void *data, size_t size, usbhc_iface_transfer_in_callback_t callback, void *arg) |
Interrupt in transaction interface function. | |
static int | interrupt_out (ddf_fun_t *fun, usb_target_t target, void *data, size_t size, usbhc_iface_transfer_out_callback_t callback, void *arg) |
Interrupt out transaction interface function. | |
int | main (int argc, char *argv[]) |
Main entry point. | |
int | pci_disable_legacy (const ddf_dev_t *device) |
Call the PCI driver with a request to clear legacy support register. | |
int | pci_enable_interrupts (const ddf_dev_t *device) |
Call the PCI driver with a request to enable interrupts. | |
int | pci_get_my_registers (const ddf_dev_t *dev, uintptr_t *io_reg_address, size_t *io_reg_size, int *irq_no) |
Get I/O address of registers and IRQ for given device. | |
static void | qh_init (qh_t *instance) |
Initialize queue head structure. | |
static void | qh_set_element_td (qh_t *instance, td_t *td) |
Set queue head element pointer. | |
static void | qh_set_next_qh (qh_t *instance, qh_t *next) |
Set queue head next pointer. | |
static int | register_endpoint (ddf_fun_t *fun, usb_address_t address, usb_speed_t ep_speed, usb_endpoint_t endpoint, usb_transfer_type_t transfer_type, usb_direction_t direction, size_t max_packet_size, unsigned int interval) |
static int | release_address (ddf_fun_t *fun, usb_address_t address) |
Release address interface function. | |
static int | request_address (ddf_fun_t *fun, usb_speed_t speed, usb_address_t *address) |
Request address interface function. | |
static int | setup_batch (ddf_fun_t *fun, usb_target_t target, usb_direction_t direction, void *data, size_t size, void *setup_data, size_t setup_size, usbhc_iface_transfer_in_callback_t in, usbhc_iface_transfer_out_callback_t out, void *arg, const char *name, hc_t **hc, usb_transfer_batch_t **batch) |
static size_t | td_act_size (td_t *instance) |
Helper function for parsing actual size out of TD. | |
void | td_init (td_t *instance, int err_count, size_t size, bool toggle, bool iso, bool low_speed, usb_target_t target, usb_packet_id pid, void *buffer, td_t *next) |
Initialize Transfer Descriptor. | |
static bool | td_is_active (td_t *instance) |
Helper function for parsing value of active bit. | |
static bool | td_is_short (td_t *instance) |
Check whether less than max data were received on SPD marked transfer. | |
void | td_print_status (td_t *instance) |
Print values in status field (dw1) in a human readable way. | |
static void | td_set_ioc (td_t *instance) |
Helper function for setting IOC bit. | |
int | td_status (td_t *instance) |
Convert TD status into standard error code. | |
static int | td_toggle (td_t *instance) |
Helper function for parsing value of toggle bit. | |
void | transfer_list_abort_all (transfer_list_t *instance) |
Walk the list and finish all batches with EINTR. | |
void | transfer_list_add_batch (transfer_list_t *instance, usb_transfer_batch_t *batch) |
Add transfer batch to the list and queue. | |
void | transfer_list_fini (transfer_list_t *instance) |
Dispose transfer list structures. | |
int | transfer_list_init (transfer_list_t *instance, const char *name) |
Initialize transfer list structures. | |
static void | transfer_list_remove_batch (transfer_list_t *instance, usb_transfer_batch_t *batch) |
Remove a transfer batch from the list and queue. | |
void | transfer_list_remove_finished (transfer_list_t *instance, link_t *done) |
Add completed bantches to the provided list. | |
void | transfer_list_set_next (transfer_list_t *instance, transfer_list_t *next) |
Set the next list in transfer list chain. | |
static int | uhci_add_device (ddf_dev_t *device) |
Initialize a new ddf driver instance for uhci hc and hub. | |
static void | uhci_transfer_batch_dispose (void *uhci_batch) |
Safely destructs uhci_transfer_batch_t structure. | |
static int | unregister_endpoint (ddf_fun_t *fun, usb_address_t address, usb_endpoint_t endpoint, usb_direction_t direction) |
Variables | |
usbhc_iface_t | hc_iface |
usbhc_iface_t | hc_iface |
static driver_t | uhci_driver |
static driver_ops_t | uhci_driver_ops |
typedef struct queue_head qh_t |
This structure is defined in UHCI design guide p.
31
typedef struct transfer_descriptor td_t |
Transfer Descriptor, defined in UHCI design guide p.
26
void batch_bulk_in | ( | usb_transfer_batch_t * | instance | ) |
void batch_bulk_out | ( | usb_transfer_batch_t * | instance | ) |
void batch_control | ( | usb_transfer_batch_t * | instance, | |
usb_packet_id | data_stage, | |||
usb_packet_id | status_stage | |||
) | [static] |
Prepare generic control transfer.
[in] | instance | Batch structure to use. |
[in] | data_stage | Pid to use for data tds. |
[in] | status_stage | Pid to use for data tds. |
void batch_control_read | ( | usb_transfer_batch_t * | instance | ) |
void batch_control_write | ( | usb_transfer_batch_t * | instance | ) |
void batch_data | ( | usb_transfer_batch_t * | instance, | |
usb_packet_id | pid | |||
) | [static] |
usb_transfer_batch_t* batch_get | ( | ddf_fun_t * | fun, | |
endpoint_t * | ep, | |||
char * | buffer, | |||
size_t | buffer_size, | |||
const char * | setup_buffer, | |||
size_t | setup_size, | |||
usbhc_iface_transfer_in_callback_t | func_in, | |||
usbhc_iface_transfer_out_callback_t | func_out, | |||
void * | arg | |||
) |
Allocate memory and initialize internal data structure.
[in] | fun | DDF function to pass to callback. |
[in] | ep | Communication target |
[in] | buffer | Data source/destination. |
[in] | buffer_size | Size of the buffer. |
[in] | setup_buffer | Setup data source (if not NULL) |
[in] | setup_size | Size of setup_buffer (should be always 8) |
[in] | func_in | function to call on inbound transfer completion |
[in] | func_out | function to call on outbound transfer completion |
[in] | arg | additional parameter to func_in or func_out |
void batch_interrupt_in | ( | usb_transfer_batch_t * | instance | ) |
void batch_interrupt_out | ( | usb_transfer_batch_t * | instance | ) |
bool batch_is_complete | ( | usb_transfer_batch_t * | instance | ) |
Check batch TDs for activity.
[in] | instance | Batch structure to use. |
qh_t * batch_qh | ( | usb_transfer_batch_t * | instance | ) |
static int bind_address | ( | ddf_fun_t * | fun, | |
usb_address_t | address, | |||
devman_handle_t | handle | |||
) | [static] |
static int bulk_in | ( | ddf_fun_t * | fun, | |
usb_target_t | target, | |||
void * | data, | |||
size_t | size, | |||
usbhc_iface_transfer_in_callback_t | callback, | |||
void * | arg | |||
) | [static] |
Bulk in transaction interface function.
[in] | fun | DDF function that was called. |
[in] | target | USB device to write to. |
[out] | data | Data destination. |
[in] | size | Size of data source. |
[in] | callback | Function to call on transaction completion |
[in] | arg | Additional for callback function. |
static int bulk_out | ( | ddf_fun_t * | fun, | |
usb_target_t | target, | |||
void * | data, | |||
size_t | size, | |||
usbhc_iface_transfer_out_callback_t | callback, | |||
void * | arg | |||
) | [static] |
Bulk out transaction interface function.
[in] | fun | DDF function that was called. |
[in] | target | USB device to write to. |
[in] | data | Source of data. |
[in] | size | Size of data source. |
[in] | callback | Function to call on transaction completion |
[in] | arg | Additional for callback function. |
static int control_read | ( | ddf_fun_t * | fun, | |
usb_target_t | target, | |||
void * | setup_data, | |||
size_t | setup_size, | |||
void * | data, | |||
size_t | size, | |||
usbhc_iface_transfer_in_callback_t | callback, | |||
void * | arg | |||
) | [static] |
Control read transaction interface function.
[in] | fun | DDF function that was called. |
[in] | target | USB device to write to. |
[in] | setup_data | Data to send with SETUP packet. |
[in] | setup_size | Size of data to send with SETUP packet (should be 8B). |
[out] | data | Source of data. |
[in] | size | Size of data source. |
[in] | callback | Function to call on transaction completion. |
[in] | arg | Additional for callback function. |
static int control_write | ( | ddf_fun_t * | fun, | |
usb_target_t | target, | |||
void * | setup_data, | |||
size_t | setup_size, | |||
void * | data, | |||
size_t | size, | |||
usbhc_iface_transfer_out_callback_t | callback, | |||
void * | arg | |||
) | [static] |
Control write transaction interface function.
[in] | fun | DDF function that was called. |
[in] | target | USB device to write to. |
[in] | setup_data | Data to send with SETUP transfer. |
[in] | setup_size | Size of data to send with SETUP transfer (always 8B). |
[in] | data | Source of data. |
[in] | size | Size of data source. |
[in] | callback | Function to call on transaction completion. |
[in] | arg | Additional for callback function. |
static int find_by_address | ( | ddf_fun_t * | fun, | |
usb_address_t | address, | |||
devman_handle_t * | handle | |||
) | [static] |
int hc_debug_checker | ( | void * | arg | ) | [static] |
static void hc_fini | ( | hc_t * | instance | ) | [inline, static] |
Initialize UHCI hc driver structure.
[in] | instance | Memory place to initialize. |
[in] | regs | Address of I/O control registers. |
[in] | reg_size | Size of I/O control registers. |
[in] | interrupts | True if hw interrupts should be used. |
void hc_init_hw | ( | hc_t * | instance | ) | [static] |
int hc_init_mem_structures | ( | hc_t * | instance | ) | [static] |
Initialize UHCI hc memory structures.
[in] | instance | UHCI structure to use. |
int hc_init_transfer_lists | ( | hc_t * | instance | ) | [static] |
Initialize UHCI hc transfer lists.
[in] | instance | UHCI structure to use. |
void hc_interrupt | ( | hc_t * | instance, | |
uint16_t | status | |||
) |
Take action based on the interrupt cause.
[in] | instance | UHCI structure to use. |
[in] | status | Value of the status register at the time of interrupt. |
int hc_interrupt_emulator | ( | void * | arg | ) | [static] |
int hc_schedule | ( | hc_t * | instance, | |
usb_transfer_batch_t * | batch | |||
) |
static int interrupt_in | ( | ddf_fun_t * | fun, | |
usb_target_t | target, | |||
void * | data, | |||
size_t | size, | |||
usbhc_iface_transfer_in_callback_t | callback, | |||
void * | arg | |||
) | [static] |
Interrupt in transaction interface function.
[in] | fun | DDF function that was called. |
[in] | target | USB device to write to. |
[out] | data | Data destination. |
[in] | size | Size of data source. |
[in] | callback | Function to call on transaction completion |
[in] | arg | Additional for callback function. |
static int interrupt_out | ( | ddf_fun_t * | fun, | |
usb_target_t | target, | |||
void * | data, | |||
size_t | size, | |||
usbhc_iface_transfer_out_callback_t | callback, | |||
void * | arg | |||
) | [static] |
Interrupt out transaction interface function.
[in] | fun | DDF function that was called. |
[in] | target | USB device to write to. |
[in] | data | Source of data. |
[in] | size | Size of data source. |
[in] | callback | Function to call on transaction completion |
[in] | arg | Additional for callback function. |
int main | ( | int | argc, | |
char * | argv[] | |||
) |
int pci_disable_legacy | ( | const ddf_dev_t * | device | ) |
int pci_enable_interrupts | ( | const ddf_dev_t * | device | ) |
static void qh_init | ( | qh_t * | instance | ) | [inline, static] |
Initialize queue head structure.
[in] | instance | qh_t structure to initialize. |
Definition at line 56 of file queue_head.h.
Set queue head element pointer.
[in] | instance | qh_t structure to use. |
[in] | td | Transfer descriptor to set as the first element. |
Definition at line 88 of file queue_head.h.
Set queue head next pointer.
[in] | instance | qh_t structure to use. |
[in] | next | Address of the next queue. |
Definition at line 71 of file queue_head.h.
static int release_address | ( | ddf_fun_t * | fun, | |
usb_address_t | address | |||
) | [static] |
static int request_address | ( | ddf_fun_t * | fun, | |
usb_speed_t | speed, | |||
usb_address_t * | address | |||
) | [static] |
Helper function for parsing actual size out of TD.
[in] | instance | TD structure to use. |
Definition at line 108 of file transfer_descriptor.h.
void td_init | ( | td_t * | instance, | |
int | err_count, | |||
size_t | size, | |||
bool | toggle, | |||
bool | iso, | |||
bool | low_speed, | |||
usb_target_t | target, | |||
usb_packet_id | pid, | |||
void * | buffer, | |||
td_t * | next | |||
) |
Initialize Transfer Descriptor.
[in] | instance | Memory place to initialize. |
[in] | err_count | Number of retries hc should attempt. |
[in] | size | Size of data source. |
[in] | toggle | Value of toggle bit. |
[in] | iso | True if TD represents Isochronous transfer. |
[in] | low_speed | Target device's speed. |
[in] | target | Address and endpoint receiving the transfer. |
[in] | pid | Packet identification (SETUP, IN or OUT). |
[in] | buffer | Source of data. |
[in] | next | Net TD in transaction. |
Dumps 8 bytes of buffer if PID_SETUP is used.
Definition at line 62 of file transfer_descriptor.c.
Helper function for parsing value of active bit.
[in] | instance | TD structure to use. |
Definition at line 147 of file transfer_descriptor.h.
Check whether less than max data were received on SPD marked transfer.
[in] | instance | TD structure to use. |
Definition at line 121 of file transfer_descriptor.h.
void td_print_status | ( | td_t * | instance | ) |
Print values in status field (dw1) in a human readable way.
[in] | instance | TD structure to use. |
Definition at line 152 of file transfer_descriptor.c.
static void td_set_ioc | ( | td_t * | instance | ) | [inline, static] |
Helper function for setting IOC bit.
[in] | instance | TD structure to use. |
Definition at line 157 of file transfer_descriptor.h.
int td_status | ( | td_t * | instance | ) |
Convert TD status into standard error code.
[in] | instance | TD structure to use. |
Definition at line 115 of file transfer_descriptor.c.
static int td_toggle | ( | td_t * | instance | ) | [inline, static] |
Helper function for parsing value of toggle bit.
[in] | instance | TD structure to use. |
Definition at line 136 of file transfer_descriptor.h.
void transfer_list_abort_all | ( | transfer_list_t * | instance | ) |
Walk the list and finish all batches with EINTR.
[in] | instance | List to use. |
Definition at line 181 of file transfer_list.c.
void transfer_list_add_batch | ( | transfer_list_t * | instance, | |
usb_transfer_batch_t * | batch | |||
) |
Add transfer batch to the list and queue.
[in] | instance | List to use. |
[in] | batch | Transfer batch to submit. |
Definition at line 107 of file transfer_list.c.
void transfer_list_fini | ( | transfer_list_t * | instance | ) |
Dispose transfer list structures.
[in] | instance | Memory place to use. |
Definition at line 78 of file transfer_list.c.
int transfer_list_init | ( | transfer_list_t * | instance, | |
const char * | name | |||
) |
Initialize transfer list structures.
[in] | instance | Memory place to use. |
[in] | name | Name of the new list. |
Definition at line 53 of file transfer_list.c.
void transfer_list_remove_batch | ( | transfer_list_t * | instance, | |
usb_transfer_batch_t * | batch | |||
) | [static] |
Remove a transfer batch from the list and queue.
[in] | instance | List to use. |
[in] | batch | Transfer batch to remove. |
Definition at line 201 of file transfer_list.c.
void transfer_list_remove_finished | ( | transfer_list_t * | instance, | |
link_t * | done | |||
) |
Add completed bantches to the provided list.
[in] | instance | List to use. |
[in] | done | list to fill |
Definition at line 155 of file transfer_list.c.
void transfer_list_set_next | ( | transfer_list_t * | instance, | |
transfer_list_t * | next | |||
) |
Set the next list in transfer list chain.
[in] | instance | List to lead. |
[in] | next | List to append. |
Definition at line 91 of file transfer_list.c.
int uhci_add_device | ( | ddf_dev_t * | device | ) | [static] |
static void uhci_transfer_batch_dispose | ( | void * | uhci_batch | ) | [static] |