Changeset df6ded8 in mainline for uspace/lib/usbhost/include
- Timestamp:
- 2018-02-28T16:37:50Z (8 years ago)
- Branches:
- lfn, master, serial, ticket/834-toolchain-update, topic/msim-upgrade, topic/simplify-dev-export
- Children:
- 1b20da0
- Parents:
- f5e5f73 (diff), b2dca8de (diff)
Note: this is a merge changeset, the changes displayed below correspond to the merge itself.
Use the(diff)links above to see all the changes relative to each parent. - git-author:
- Jakub Jermar <jakub@…> (2018-02-28 16:06:42)
- git-committer:
- Jakub Jermar <jakub@…> (2018-02-28 16:37:50)
- Location:
- uspace/lib/usbhost/include/usb/host
- Files:
-
- 4 added
- 1 deleted
- 4 edited
-
bandwidth.h (added)
-
bus.h (added)
-
ddf_helpers.h (modified) (2 diffs)
-
endpoint.h (modified) (3 diffs)
-
hcd.h (modified) (2 diffs)
-
usb2_bus.h (added)
-
usb_bus.h (deleted)
-
usb_transfer_batch.h (modified) (3 diffs)
-
utility.h (added)
Legend:
- Unmodified
- Added
- Removed
-
uspace/lib/usbhost/include/usb/host/ddf_helpers.h
rf5e5f73 rdf6ded8 1 1 /* 2 2 * Copyright (c) 2012 Jan Vesely 3 * Copyright (c) 2018 Ondrej Hlavaty 3 4 * All rights reserved. 4 5 * … … 37 38 #define LIBUSBHOST_HOST_DDF_HELPERS_H 38 39 39 #include < usb/host/hcd.h>40 #include < usb/host/usb_bus.h>40 #include <ddf/driver.h> 41 #include <ddf/interrupt.h> 41 42 #include <usb/usb.h> 42 43 43 #include <ddf/driver.h> 44 #include <ddf/interrupt.h> 45 #include <device/hw_res_parsed.h> 44 #include <usb/host/hcd.h> 45 #include <usb/descriptor.h> 46 46 47 typedef errno_t (*driver_init_t)(hcd_t *, const hw_res_list_parsed_t *, bool);48 typedef void (*driver_fini_t)(hcd_t *);49 typedef errno_t (*claim_t)(ddf_dev_t *);50 typedef errno_t (*irq_code_gen_t)(irq_code_t *, const hw_res_list_parsed_t *, int *);51 47 52 typedef struct { 53 hcd_ops_t ops; 54 claim_t claim; 55 usb_speed_t hc_speed; 56 driver_init_t init; 57 driver_fini_t fini; 58 interrupt_handler_t *irq_handler; 59 irq_code_gen_t irq_code_gen; 60 const char *name; 61 } ddf_hc_driver_t; 48 errno_t hcd_ddf_setup_hc(ddf_dev_t *, size_t); 49 void hcd_ddf_clean_hc(hc_device_t *); 62 50 63 errno_t hcd_ddf_add_hc(ddf_dev_t *device, const ddf_hc_driver_t *driver);64 51 65 errno_t hcd_ddf_setup_hc(ddf_dev_t *device, usb_speed_t max_speed, 66 size_t bw, bw_count_func_t bw_count); 67 void hcd_ddf_clean_hc(ddf_dev_t *device); 68 errno_t hcd_ddf_setup_root_hub(ddf_dev_t *device); 52 device_t *hcd_ddf_fun_create(hc_device_t *, usb_speed_t); 53 void hcd_ddf_fun_destroy(device_t *); 69 54 70 hcd_t *dev_to_hcd(ddf_dev_t *dev);55 errno_t hcd_ddf_setup_match_ids(device_t *, usb_standard_device_descriptor_t *); 71 56 72 errno_t hcd_ddf_enable_interrupt(ddf_dev_t *device, int); 73 errno_t hcd_ddf_get_registers(ddf_dev_t *device, hw_res_list_parsed_t *hw_res); 74 errno_t hcd_ddf_setup_interrupts(ddf_dev_t *device, 75 const hw_res_list_parsed_t *hw_res, 76 interrupt_handler_t handler, 77 errno_t (*gen_irq_code)(irq_code_t *, const hw_res_list_parsed_t *, int *), 78 cap_handle_t *handle); 79 void ddf_hcd_gen_irq_handler(ipc_call_t *call, ddf_dev_t *dev); 57 errno_t hcd_ddf_enable_interrupt(hc_device_t *hcd, int); 58 errno_t hcd_ddf_get_registers(hc_device_t *hcd, hw_res_list_parsed_t *hw_res); 59 60 void hcd_ddf_gen_irq_handler(ipc_callid_t iid, ipc_call_t *call, ddf_dev_t *dev); 80 61 81 62 #endif -
uspace/lib/usbhost/include/usb/host/endpoint.h
rf5e5f73 rdf6ded8 1 1 /* 2 2 * Copyright (c) 2011 Jan Vesely 3 * Copyright (c) 2018 Ondrej Hlavaty 3 4 * All rights reserved. 4 5 * … … 32 33 /** @file 33 34 * 35 * Endpoint structure is tightly coupled to the bus. The bus controls the 36 * life-cycle of endpoint. In order to keep endpoints lightweight, operations 37 * on endpoints are part of the bus structure. 38 * 34 39 */ 35 40 #ifndef LIBUSBHOST_HOST_ENDPOINT_H 36 41 #define LIBUSBHOST_HOST_ENDPOINT_H 37 42 43 #include <adt/list.h> 44 #include <atomic.h> 45 #include <fibril_synch.h> 38 46 #include <stdbool.h> 39 #include <adt/list.h> 40 #include <fibril_synch.h> 47 #include <sys/time.h> 41 48 #include <usb/usb.h> 42 #include <atomic.h> 49 #include <usb/host/bus.h> 50 #include <usbhc_iface.h> 43 51 44 /** Host controller side endpoint structure. */ 52 typedef struct bus bus_t; 53 typedef struct device device_t; 54 typedef struct transfer_request transfer_request_t; 55 typedef struct usb_transfer_batch usb_transfer_batch_t; 56 57 /** 58 * Host controller side endpoint structure. 59 * 60 * This structure, though reference-counted, is very fragile. It is responsible 61 * for synchronizing transfer batch scheduling and completion. 62 * 63 * To avoid situations, in which two locks must be obtained to schedule/finish 64 * a transfer, the endpoint inherits a lock from the outside. Because the 65 * concrete instance of mutex can be unknown at the time of initialization, 66 * the HC shall pass the right lock at the time of onlining the endpoint. 67 * 68 * The fields used for scheduling (online, active_batch) are to be used only 69 * under that guard and by functions designed for this purpose. The driver can 70 * also completely avoid using this mechanism, in which case it is on its own in 71 * question of transfer aborting. 72 * 73 * Relevant information can be found in the documentation of HelenOS xHCI 74 * project. 75 */ 45 76 typedef struct endpoint { 77 /** USB device */ 78 device_t *device; 46 79 /** Reference count. */ 47 atomic_t refcnt; 48 /** Part of linked list. */ 49 link_t link; 50 /** USB address. */ 51 usb_address_t address; 52 /** USB endpoint number. */ 80 atomic_t refcnt; 81 82 /** An inherited guard */ 83 fibril_mutex_t *guard; 84 /** Whether it's allowed to schedule on this endpoint */ 85 bool online; 86 /** The currently active transfer batch. */ 87 usb_transfer_batch_t *active_batch; 88 /** Signals change of active status. */ 89 fibril_condvar_t avail; 90 91 /** Endpoint number */ 53 92 usb_endpoint_t endpoint; 54 93 /** Communication direction. */ … … 56 95 /** USB transfer type. */ 57 96 usb_transfer_type_t transfer_type; 58 /** Communication speed. */ 59 usb_speed_t speed; 60 /** Maximum size of data packets. */ 97 /** Maximum size of one packet */ 61 98 size_t max_packet_size; 62 /** Additional opportunities per uframe */ 63 unsigned packets; 64 /** Necessary bandwidth. */ 65 size_t bandwidth; 66 /** Value of the toggle bit. */ 67 unsigned toggle:1; 68 /** True if there is a batch using this scheduled for this endpoint. */ 69 volatile bool active; 70 /** Protects resources and active status changes. */ 71 fibril_mutex_t guard; 72 /** Signals change of active status. */ 73 fibril_condvar_t avail; 74 /** High speed TT data */ 75 struct { 76 usb_address_t address; 77 unsigned port; 78 } tt; 79 /** Optional device specific data. */ 80 struct { 81 /** Device specific data. */ 82 void *data; 83 /** Callback to get the value of toggle bit. */ 84 int (*toggle_get)(void *); 85 /** Callback to set the value of toggle bit. */ 86 void (*toggle_set)(void *, int); 87 } hc_data; 99 100 /** Maximum size of one transfer */ 101 size_t max_transfer_size; 102 103 /* Policies for transfer buffers */ 104 /** A hint for optimal performance. */ 105 dma_policy_t transfer_buffer_policy; 106 /** Enforced by the library. */ 107 dma_policy_t required_transfer_buffer_policy; 108 109 /** 110 * Number of packets that can be sent in one service interval 111 * (not necessarily uframe, despite its name) 112 */ 113 unsigned packets_per_uframe; 114 115 /* This structure is meant to be extended by overriding. */ 88 116 } endpoint_t; 89 117 90 extern endpoint_t *endpoint_create(usb_address_t, usb_endpoint_t, 91 usb_direction_t, usb_transfer_type_t, usb_speed_t, size_t, unsigned int, 92 size_t, usb_address_t, unsigned int); 93 extern void endpoint_destroy(endpoint_t *); 118 extern void endpoint_init(endpoint_t *, device_t *, 119 const usb_endpoint_descriptors_t *); 94 120 95 121 extern void endpoint_add_ref(endpoint_t *); 96 122 extern void endpoint_del_ref(endpoint_t *); 97 123 98 extern void endpoint_set_hc_data(endpoint_t *, void *, int (*)(void *), 99 void (*)(void *, int)); 100 extern void endpoint_clear_hc_data(endpoint_t *); 124 extern void endpoint_set_online(endpoint_t *, fibril_mutex_t *); 125 extern void endpoint_set_offline_locked(endpoint_t *); 101 126 102 extern void endpoint_use(endpoint_t *); 103 extern void endpoint_release(endpoint_t *); 127 extern void endpoint_wait_timeout_locked(endpoint_t *ep, suseconds_t); 128 extern int endpoint_activate_locked(endpoint_t *, usb_transfer_batch_t *); 129 extern void endpoint_deactivate_locked(endpoint_t *); 104 130 105 extern int endpoint_toggle_get(endpoint_t *); 106 extern void endpoint_toggle_set(endpoint_t *, int); 131 int endpoint_send_batch(endpoint_t *, const transfer_request_t *); 107 132 108 /** list_get_instance wrapper. 109 * 110 * @param item Pointer to link member. 111 * 112 * @return Pointer to endpoint_t structure. 113 * 114 */ 115 static inline endpoint_t * endpoint_get_instance(link_t *item) 133 static inline bus_t *endpoint_get_bus(endpoint_t *ep) 116 134 { 117 return item ? list_get_instance(item, endpoint_t, link) : NULL; 135 device_t * const device = ep->device; 136 return device ? device->bus : NULL; 118 137 } 138 119 139 #endif 120 140 -
uspace/lib/usbhost/include/usb/host/hcd.h
rf5e5f73 rdf6ded8 1 1 /* 2 2 * Copyright (c) 2011 Jan Vesely 3 * Copyright (c) 2018 Ondrej Hlavaty 3 4 * All rights reserved. 4 5 * … … 37 38 #define LIBUSBHOST_HOST_HCD_H 38 39 39 #include <usb/host/endpoint.h> 40 #include <usb/host/usb_bus.h> 41 #include <usb/host/usb_transfer_batch.h> 42 #include <usb/usb.h> 40 #include <ddf/driver.h> 41 #include <usb/request.h> 43 42 44 #include <assert.h> 45 #include <usbhc_iface.h> 46 #include <stddef.h> 47 #include <stdint.h> 43 typedef struct hw_resource_list_parsed hw_res_list_parsed_t; 44 typedef struct bus bus_t; 45 typedef struct device device_t; 48 46 49 typedef struct hcd hcd_t; 47 /* Treat this header as read-only in driver code. 48 * It could be opaque, but why to complicate matters. 49 */ 50 typedef struct hc_device { 51 /* Bus instance */ 52 bus_t *bus; 50 53 51 typedef errno_t (*schedule_hook_t)(hcd_t *, usb_transfer_batch_t *); 52 typedef errno_t (*ep_add_hook_t)(hcd_t *, endpoint_t *); 53 typedef void (*ep_remove_hook_t)(hcd_t *, endpoint_t *); 54 typedef void (*interrupt_hook_t)(hcd_t *, uint32_t); 55 typedef errno_t (*status_hook_t)(hcd_t *, uint32_t *); 54 /* Managed DDF device */ 55 ddf_dev_t *ddf_dev; 56 56 57 typedef struct { 58 /** Transfer scheduling, implement in device driver. */ 59 schedule_hook_t schedule; 60 /** Hook called upon registering new endpoint. */ 61 ep_add_hook_t ep_add_hook; 62 /** Hook called upon removing of an endpoint. */ 63 ep_remove_hook_t ep_remove_hook; 64 /** Hook to be called on device interrupt, passes ARG1 */ 65 interrupt_hook_t irq_hook; 66 /** Periodic polling hook */ 67 status_hook_t status_hook; 68 } hcd_ops_t; 57 /* Control function */ 58 ddf_fun_t *ctl_fun; 69 59 70 /** Generic host controller driver structure. */ 71 struct hcd { 72 /** Endpoint manager. */ 73 usb_bus_t bus; 60 /* Result of enabling HW IRQs */ 61 int irq_cap; 74 62 75 63 /** Interrupt replacement fibril */ 76 64 fid_t polling_fibril; 77 65 78 /** Driver implementation */ 79 hcd_ops_t ops; 80 /** Device specific driver data. */ 81 void * driver_data; 82 }; 66 /* This structure is meant to be extended by driver code. */ 67 } hc_device_t; 83 68 84 extern void hcd_init(hcd_t *, usb_speed_t, size_t, bw_count_func_t); 69 typedef struct hc_driver { 70 const char *name; 85 71 86 static inline void hcd_set_implementation(hcd_t *hcd, void *data, 87 const hcd_ops_t *ops) 72 /** Size of the device data to be allocated, and passed as the 73 * hc_device_t. */ 74 size_t hc_device_size; 75 76 /** Initialize device structures. */ 77 int (*hc_add)(hc_device_t *, const hw_res_list_parsed_t *); 78 79 /** Generate IRQ code to handle interrupts. */ 80 int (*irq_code_gen)(irq_code_t *, hc_device_t *, 81 const hw_res_list_parsed_t *, int *); 82 83 /** Claim device from BIOS. */ 84 int (*claim)(hc_device_t *); 85 86 /** Start the host controller. */ 87 int (*start)(hc_device_t *); 88 89 /** Setup the virtual roothub. */ 90 int (*setup_root_hub)(hc_device_t *); 91 92 /** Stop the host controller (after start has been called) */ 93 int (*stop)(hc_device_t *); 94 95 /** HC was asked to be removed (after hc_add has been called) */ 96 int (*hc_remove)(hc_device_t *); 97 98 /** HC is gone. */ 99 int (*hc_gone)(hc_device_t *); 100 } hc_driver_t; 101 102 /* Drivers should call this before leaving hc_add */ 103 static inline void hc_device_setup(hc_device_t *hcd, bus_t *bus) 88 104 { 89 assert(hcd); 90 if (ops) { 91 hcd->driver_data = data; 92 hcd->ops = *ops; 93 } else { 94 memset(&hcd->ops, 0, sizeof(hcd->ops)); 95 } 105 hcd->bus = bus; 96 106 } 97 107 98 static inline void * hcd_get_driver_data(hcd_t *hcd)108 static inline hc_device_t *dev_to_hcd(ddf_dev_t *dev) 99 109 { 100 assert(hcd); 101 return hcd->driver_data; 110 return ddf_dev_data_get(dev); 102 111 } 103 112 104 extern errno_t hcd_request_address(hcd_t *, usb_speed_t, usb_address_t *); 105 106 extern errno_t hcd_release_address(hcd_t *, usb_address_t); 107 108 extern errno_t hcd_reserve_default_address(hcd_t *, usb_speed_t); 109 110 static inline errno_t hcd_release_default_address(hcd_t *hcd) 111 { 112 return hcd_release_address(hcd, USB_ADDRESS_DEFAULT); 113 } 114 115 extern errno_t hcd_add_ep(hcd_t *, usb_target_t, usb_direction_t, 116 usb_transfer_type_t, size_t, unsigned int, size_t, usb_address_t, 117 unsigned int); 118 119 extern errno_t hcd_remove_ep(hcd_t *, usb_target_t, usb_direction_t); 120 121 extern errno_t hcd_send_batch(hcd_t *, usb_target_t, usb_direction_t, void *, 122 size_t, uint64_t, usbhc_iface_transfer_in_callback_t, 123 usbhc_iface_transfer_out_callback_t, void *, const char *); 124 125 extern errno_t hcd_send_batch_sync(hcd_t *, usb_target_t, usb_direction_t, 126 void *, size_t, uint64_t, const char *, size_t *); 113 extern errno_t hc_driver_main(const hc_driver_t *); 127 114 128 115 #endif -
uspace/lib/usbhost/include/usb/host/usb_transfer_batch.h
rf5e5f73 rdf6ded8 1 1 /* 2 2 * Copyright (c) 2011 Jan Vesely 3 * Copyright (c) 2018 Ondrej Hlavaty 3 4 * All rights reserved. 4 5 * … … 37 38 #define LIBUSBHOST_HOST_USB_TRANSFER_BATCH_H 38 39 39 #include <usb/host/endpoint.h> 40 #include <usb/usb.h> 41 42 #include <assert.h> 40 #include <atomic.h> 41 #include <errno.h> 43 42 #include <stddef.h> 44 43 #include <stdint.h> 44 #include <usb/dma_buffer.h> 45 #include <usb/request.h> 46 #include <usb/usb.h> 45 47 #include <usbhc_iface.h> 46 48 47 #define USB_SETUP_PACKET_SIZE 8 49 #include <usb/host/hcd.h> 50 #include <usb/host/endpoint.h> 51 #include <usb/host/bus.h> 52 53 typedef struct endpoint endpoint_t; 54 typedef struct bus bus_t; 48 55 49 56 /** Structure stores additional data needed for communication with EP */ 50 57 typedef struct usb_transfer_batch { 58 /** Target for communication */ 59 usb_target_t target; 60 /** Direction of the transfer */ 61 usb_direction_t dir; 62 51 63 /** Endpoint used for communication */ 52 64 endpoint_t *ep; 53 /** Function called on completion (IN version) */ 54 usbhc_iface_transfer_in_callback_t callback_in; 55 /** Function called on completion (OUT version) */ 56 usbhc_iface_transfer_out_callback_t callback_out; 57 /** Argument to pass to the completion function */ 58 void *arg; 59 /** Place for data to send/receive */ 60 char *buffer; 61 /** Size of memory pointed to by buffer member */ 62 size_t buffer_size; 65 63 66 /** Place to store SETUP data needed by control transfers */ 64 char setup_buffer[USB_SETUP_PACKET_SIZE]; 65 /** Used portion of setup_buffer member 66 * 67 * SETUP buffer must be 8 bytes for control transfers and is left 68 * unused for all other transfers. Thus, this field is either 0 or 8. 67 union { 68 char buffer [USB_SETUP_PACKET_SIZE]; 69 usb_device_request_setup_packet_t packet; 70 uint64_t packed; 71 } setup; 72 73 /** DMA buffer with enforced policy */ 74 dma_buffer_t dma_buffer; 75 /** Size of memory buffer */ 76 size_t offset, size; 77 78 /** 79 * In case a bounce buffer is allocated, the original buffer must to be 80 * stored to be filled after the IN transaction is finished. 69 81 */ 70 size_t setup_size; 82 char *original_buffer; 83 bool is_bounced; 71 84 72 /** Actually used portion of the buffer 73 * This member is never accessed by functions provided in this header, 74 * with the exception of usb_transfer_batch_finish. For external use. 75 */ 76 size_t transfered_size; 77 /** Indicates success/failure of the communication 78 * This member is never accessed by functions provided in this header, 79 * with the exception of usb_transfer_batch_finish. For external use. 80 */ 85 /** Indicates success/failure of the communication */ 81 86 errno_t error; 87 /** Actually used portion of the buffer */ 88 size_t transferred_size; 89 90 /** Function called on completion */ 91 usbhc_iface_transfer_callback_t on_complete; 92 /** Arbitrary data for the handler */ 93 void *on_complete_data; 82 94 } usb_transfer_batch_t; 83 95 84 /** Printf formatting string for dumping usb_transfer_batch_t. */ 96 /** 97 * Printf formatting string for dumping usb_transfer_batch_t. 98 * [address:endpoint speed transfer_type-direction buffer_sizeB/max_packet_size] 99 * */ 85 100 #define USB_TRANSFER_BATCH_FMT "[%d:%d %s %s-%s %zuB/%zu]" 86 101 … … 89 104 */ 90 105 #define USB_TRANSFER_BATCH_ARGS(batch) \ 91 ( batch).ep->address, (batch).ep->endpoint, \92 usb_str_speed((batch).ep-> speed), \106 ((batch).ep->device->address), ((batch).ep->endpoint), \ 107 usb_str_speed((batch).ep->device->speed), \ 93 108 usb_str_transfer_type_short((batch).ep->transfer_type), \ 94 usb_str_direction((batch). ep->direction), \95 (batch). buffer_size, (batch).ep->max_packet_size109 usb_str_direction((batch).dir), \ 110 (batch).size, (batch).ep->max_packet_size 96 111 112 /** Wrapper for bus operation. */ 113 usb_transfer_batch_t *usb_transfer_batch_create(endpoint_t *); 97 114 98 usb_transfer_batch_t * usb_transfer_batch_create( 99 endpoint_t *ep, 100 char *buffer, 101 size_t buffer_size, 102 uint64_t setup_buffer, 103 usbhc_iface_transfer_in_callback_t func_in, 104 usbhc_iface_transfer_out_callback_t func_out, 105 void *arg 106 ); 107 void usb_transfer_batch_destroy(usb_transfer_batch_t *instance); 115 /** Batch initializer. */ 116 void usb_transfer_batch_init(usb_transfer_batch_t *, endpoint_t *); 108 117 109 void usb_transfer_batch_finish_error(const usb_transfer_batch_t *instance, 110 const void* data, size_t size, errno_t error); 118 /** Buffer handling */ 119 bool usb_transfer_batch_bounce_required(usb_transfer_batch_t *); 120 errno_t usb_transfer_batch_bounce(usb_transfer_batch_t *); 111 121 112 /** Finish batch using stored error value and transferred size. 113 * 114 * @param[in] instance Batch structure to use. 115 * @param[in] data Data to copy to the output buffer. 122 /** Batch finalization. */ 123 void usb_transfer_batch_finish(usb_transfer_batch_t *); 124 125 /** To be called from outside only when the transfer is not going to be finished 126 * (i.o.w. until successfuly scheduling) 116 127 */ 117 static inline void usb_transfer_batch_finish( 118 const usb_transfer_batch_t *instance, const void* data) 119 { 120 assert(instance); 121 usb_transfer_batch_finish_error( 122 instance, data, instance->transfered_size, instance->error); 123 } 124 125 /** Determine batch direction based on the callbacks present 126 * @param[in] instance Batch structure to use, non-null. 127 * @return USB_DIRECTION_IN, or USB_DIRECTION_OUT. 128 */ 129 static inline usb_direction_t usb_transfer_batch_direction( 130 const usb_transfer_batch_t *instance) 131 { 132 assert(instance); 133 if (instance->callback_in) { 134 assert(instance->callback_out == NULL); 135 assert(instance->ep == NULL 136 || instance->ep->transfer_type == USB_TRANSFER_CONTROL 137 || instance->ep->direction == USB_DIRECTION_IN); 138 return USB_DIRECTION_IN; 139 } 140 if (instance->callback_out) { 141 assert(instance->callback_in == NULL); 142 assert(instance->ep == NULL 143 || instance->ep->transfer_type == USB_TRANSFER_CONTROL 144 || instance->ep->direction == USB_DIRECTION_OUT); 145 return USB_DIRECTION_OUT; 146 } 147 assert(false); 148 } 128 void usb_transfer_batch_destroy(usb_transfer_batch_t *); 149 129 150 130 #endif
Note:
See TracChangeset
for help on using the changeset viewer.
