Changeset fd07e526 in mainline for uspace/lib/usbhost/src
- Timestamp:
- 2011-09-16T14:50:20Z (14 years ago)
- Branches:
- lfn, master, serial, ticket/834-toolchain-update, topic/msim-upgrade, topic/simplify-dev-export
- Children:
- 432a269, d1e18573
- Parents:
- 47fecbb (diff), 82a31261 (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. - Location:
- uspace/lib/usbhost/src
- Files:
-
- 1 added
- 2 edited
- 2 moved
-
endpoint.c (modified) (3 diffs)
-
iface.c (added)
-
usb_device_manager.c (moved) (moved from uspace/lib/usbhost/src/device_keeper.c ) (8 diffs)
-
usb_endpoint_manager.c (modified) (10 diffs)
-
usb_transfer_batch.c (moved) (moved from uspace/lib/usbhost/src/batch.c ) (5 diffs)
Legend:
- Unmodified
- Added
- Removed
-
uspace/lib/usbhost/src/endpoint.c
r47fecbb rfd07e526 53 53 instance->toggle = 0; 54 54 instance->active = false; 55 instance->destroy_hook = NULL; 56 instance->hc_data.data = NULL; 57 instance->hc_data.toggle_get = NULL; 58 instance->hc_data.toggle_set = NULL; 55 59 fibril_mutex_initialize(&instance->guard); 56 60 fibril_condvar_initialize(&instance->avail); … … 64 68 assert(instance); 65 69 assert(!instance->active); 70 if (instance->hc_data.data) { 71 assert(instance->destroy_hook); 72 instance->destroy_hook(instance); 73 } 66 74 free(instance); 67 75 } 68 76 /*----------------------------------------------------------------------------*/ 69 77 void endpoint_set_hc_data(endpoint_t *instance, 70 void *data, int (*toggle_get)(void *), void (*toggle_set)(void *, int)) 78 void *data, void (*destroy_hook)(endpoint_t *), 79 int (*toggle_get)(void *), void (*toggle_set)(void *, int)) 71 80 { 72 81 assert(instance); 82 instance->destroy_hook = destroy_hook; 73 83 instance->hc_data.data = data; 74 84 instance->hc_data.toggle_get = toggle_get; … … 79 89 { 80 90 assert(instance); 91 instance->destroy_hook = NULL; 81 92 instance->hc_data.data = NULL; 82 93 instance->hc_data.toggle_get = NULL; -
uspace/lib/usbhost/src/usb_device_manager.c
r47fecbb rfd07e526 31 31 */ 32 32 /** @file 33 * Device keeper structure and functions (implementation).33 * Device manager structure and functions (implementation). 34 34 */ 35 35 #include <assert.h> 36 36 #include <errno.h> 37 37 #include <usb/debug.h> 38 #include <usb/host/ device_keeper.h>39 40 /*----------------------------------------------------------------------------*/ 41 /** Initialize device keeper structure.38 #include <usb/host/usb_device_manager.h> 39 40 /*----------------------------------------------------------------------------*/ 41 /** Initialize device manager structure. 42 42 * 43 43 * @param[in] instance Memory place to initialize. … … 45 45 * Set all values to false/0. 46 46 */ 47 void usb_device_ keeper_init(usb_device_keeper_t *instance)47 void usb_device_manager_init(usb_device_manager_t *instance) 48 48 { 49 49 assert(instance); … … 63 63 /** Get a free USB address 64 64 * 65 * @param[in] instance Device keeper structure to use.65 * @param[in] instance Device manager structure to use. 66 66 * @param[in] speed Speed of the device requiring address. 67 67 * @return Free address, or error code. 68 68 */ 69 usb_address_t device_keeper_get_free_address(70 usb_device_ keeper_t *instance, usb_speed_t speed)69 usb_address_t usb_device_manager_get_free_address( 70 usb_device_manager_t *instance, usb_speed_t speed) 71 71 { 72 72 assert(instance); … … 97 97 /** Bind USB address to devman handle. 98 98 * 99 * @param[in] instance Device keeper structure to use.99 * @param[in] instance Device manager structure to use. 100 100 * @param[in] address Device address 101 101 * @param[in] handle Devman handle of the device. 102 102 */ 103 void usb_device_ keeper_bind(usb_device_keeper_t *instance,103 void usb_device_manager_bind(usb_device_manager_t *instance, 104 104 usb_address_t address, devman_handle_t handle) 105 105 { … … 117 117 /** Release used USB address. 118 118 * 119 * @param[in] instance Device keeper structure to use.119 * @param[in] instance Device manager structure to use. 120 120 * @param[in] address Device address 121 121 */ 122 void usb_device_ keeper_release(123 usb_device_ keeper_t *instance, usb_address_t address)122 void usb_device_manager_release( 123 usb_device_manager_t *instance, usb_address_t address) 124 124 { 125 125 assert(instance); … … 136 136 /** Find USB address associated with the device 137 137 * 138 * @param[in] instance Device keeper structure to use.138 * @param[in] instance Device manager structure to use. 139 139 * @param[in] handle Devman handle of the device seeking its address. 140 140 * @return USB Address, or error code. 141 141 */ 142 usb_address_t usb_device_ keeper_find(143 usb_device_ keeper_t *instance, devman_handle_t handle)142 usb_address_t usb_device_manager_find( 143 usb_device_manager_t *instance, devman_handle_t handle) 144 144 { 145 145 assert(instance); … … 161 161 * Intentionally refuse to find handle of default address. 162 162 * 163 * @param[in] instance Device keeper structure to use.163 * @param[in] instance Device manager structure to use. 164 164 * @param[in] address Address the caller wants to find. 165 165 * @param[out] handle Where to store found handle. 166 166 * @return Whether such address is currently occupied. 167 167 */ 168 bool usb_device_ keeper_find_by_address(usb_device_keeper_t *instance,168 bool usb_device_manager_find_by_address(usb_device_manager_t *instance, 169 169 usb_address_t address, devman_handle_t *handle) 170 170 { … … 191 191 /** Get speed associated with the address 192 192 * 193 * @param[in] instance Device keeper structure to use.193 * @param[in] instance Device manager structure to use. 194 194 * @param[in] address Address of the device. 195 195 * @return USB speed. 196 196 */ 197 usb_speed_t usb_device_ keeper_get_speed(198 usb_device_ keeper_t *instance, usb_address_t address)197 usb_speed_t usb_device_manager_get_speed( 198 usb_device_manager_t *instance, usb_address_t address) 199 199 { 200 200 assert(instance); -
uspace/lib/usbhost/src/usb_endpoint_manager.c
r47fecbb rfd07e526 45 45 static hash_index_t node_hash(unsigned long key[]) 46 46 { 47 hash_index_t hash = 0; 48 unsigned i = 0; 49 for (;i < MAX_KEYS; ++i) { 50 hash ^= key[i]; 51 } 52 hash %= BUCKET_COUNT; 53 return hash; 47 /* USB endpoints use 4 bits, thus ((key[0] << 4) | key[1]) 48 * produces unique value for every address.endpoint pair */ 49 return ((key[0] << 4) | key[1]) % BUCKET_COUNT; 54 50 } 55 51 /*----------------------------------------------------------------------------*/ … … 63 59 switch (keys) { 64 60 case 3: 65 match = match && (key[2] == node->ep->direction); 61 match = match && 62 ((key[2] == node->ep->direction) 63 || (node->ep->direction == USB_DIRECTION_BOTH)); 66 64 case 2: 67 65 match = match && (key[1] == (unsigned long)node->ep->endpoint); … … 140 138 /*----------------------------------------------------------------------------*/ 141 139 int usb_endpoint_manager_init(usb_endpoint_manager_t *instance, 142 size_t available_bandwidth) 140 size_t available_bandwidth, 141 size_t (*bw_count)(usb_speed_t, usb_transfer_type_t, size_t, size_t)) 143 142 { 144 143 assert(instance); 145 144 fibril_mutex_initialize(&instance->guard); 146 fibril_condvar_initialize(&instance->change);147 145 instance->free_bw = available_bandwidth; 148 bool ht = 146 instance->bw_count = bw_count; 147 const bool ht = 149 148 hash_table_create(&instance->ep_table, BUCKET_COUNT, MAX_KEYS, &op); 150 149 return ht ? EOK : ENOMEM; … … 159 158 endpoint_t *ep, size_t data_size) 160 159 { 160 assert(instance); 161 assert(instance->bw_count); 161 162 assert(ep); 162 size_t bw = bandwidth_count_usb11(ep->speed, ep->transfer_type,163 const size_t bw = instance->bw_count(ep->speed, ep->transfer_type, 163 164 data_size, ep->max_packet_size); 164 assert(instance); 165 166 fibril_mutex_lock(&instance->guard); 167 168 if (bw > instance->free_bw) { 169 fibril_mutex_unlock(&instance->guard); 170 return ENOSPC; 171 } 165 172 166 173 unsigned long key[MAX_KEYS] = 167 174 {ep->address, ep->endpoint, ep->direction}; 168 fibril_mutex_lock(&instance->guard); 169 170 link_t *item = 175 176 const link_t *item = 171 177 hash_table_find(&instance->ep_table, key); 172 178 if (item != NULL) { 173 179 fibril_mutex_unlock(&instance->guard); 174 180 return EEXISTS; 175 }176 177 if (bw > instance->free_bw) {178 fibril_mutex_unlock(&instance->guard);179 return ENOSPC;180 181 } 181 182 … … 193 194 instance->free_bw -= bw; 194 195 fibril_mutex_unlock(&instance->guard); 195 fibril_condvar_broadcast(&instance->change);196 196 return EOK; 197 197 } … … 211 211 212 212 node_t *node = hash_table_get_instance(item, node_t, link); 213 if (node->ep->active) 213 if (node->ep->active) { 214 fibril_mutex_unlock(&instance->guard); 214 215 return EBUSY; 216 } 215 217 216 218 instance->free_bw += node->bw; … … 218 220 219 221 fibril_mutex_unlock(&instance->guard); 220 fibril_condvar_broadcast(&instance->change);221 222 return EOK; 222 223 } … … 230 231 231 232 fibril_mutex_lock(&instance->guard); 232 link_t *item = hash_table_find(&instance->ep_table, key);233 const link_t *item = hash_table_find(&instance->ep_table, key); 233 234 if (item == NULL) { 234 235 fibril_mutex_unlock(&instance->guard); 235 236 return NULL; 236 237 } 237 node_t *node = hash_table_get_instance(item, node_t, link);238 const node_t *node = hash_table_get_instance(item, node_t, link); 238 239 if (bw) 239 240 *bw = node->bw; … … 255 256 { 256 257 assert(instance); 257 if (target.endpoint > 15 || target.endpoint < 0 258 || target.address >= USB11_ADDRESS_MAX || target.address < 0) { 258 if (!usb_target_is_valid(target)) { 259 259 usb_log_error("Invalid data when checking for toggle reset.\n"); 260 260 return; 261 261 } 262 262 263 assert(data); 263 264 switch (data[1]) 264 265 { 265 case 0x01: /* clear feature*/266 /* recipient is endpoint, value is zero (ENDPOINT_STALL) */266 case 0x01: /* Clear Feature -- resets only cleared ep */ 267 /* Recipient is endpoint, value is zero (ENDPOINT_STALL) */ 267 268 if (((data[0] & 0xf) == 1) && ((data[2] | data[3]) == 0)) { 268 269 /* endpoint number is < 16, thus first byte is enough */ … … 276 277 break; 277 278 278 case 0x9: /* set configuration */279 case 0x11: /* set interface */280 /* target must be device */279 case 0x9: /* Set Configuration */ 280 case 0x11: /* Set Interface */ 281 /* Recipient must be device */ 281 282 if ((data[0] & 0xf) == 0) { 282 283 usb_target_t reset_target = -
uspace/lib/usbhost/src/usb_transfer_batch.c
r47fecbb rfd07e526 37 37 #include <usb/usb.h> 38 38 #include <usb/debug.h> 39 #include <usb/host/batch.h> 39 #include <usb/host/usb_transfer_batch.h> 40 #include <usb/host/hcd.h> 40 41 41 void usb_transfer_batch_call_in(usb_transfer_batch_t *instance); 42 void usb_transfer_batch_call_out(usb_transfer_batch_t *instance); 43 44 void usb_transfer_batch_init( 45 usb_transfer_batch_t *instance, 42 usb_transfer_batch_t * usb_transfer_batch_get( 46 43 endpoint_t *ep, 47 44 char *buffer, 48 char *data_buffer,49 45 size_t buffer_size, 50 char *setup_buffer, 51 size_t setup_size, 46 uint64_t setup_buffer, 52 47 usbhc_iface_transfer_in_callback_t func_in, 53 48 usbhc_iface_transfer_out_callback_t func_out, … … 55 50 ddf_fun_t *fun, 56 51 void *private_data, 57 void (*private_data_dtor)(void * p_data)52 void (*private_data_dtor)(void *) 58 53 ) 59 54 { 60 assert(instance); 61 link_initialize(&instance->link); 62 instance->ep = ep; 63 instance->callback_in = func_in; 64 instance->callback_out = func_out; 65 instance->arg = arg; 66 instance->buffer = buffer; 67 instance->data_buffer = data_buffer; 68 instance->buffer_size = buffer_size; 69 instance->setup_buffer = setup_buffer; 70 instance->setup_size = setup_size; 71 instance->fun = fun; 72 instance->private_data = private_data; 73 instance->private_data_dtor = private_data_dtor; 74 instance->transfered_size = 0; 75 instance->next_step = NULL; 76 instance->error = EOK; 77 endpoint_use(instance->ep); 55 usb_transfer_batch_t *instance = malloc(sizeof(usb_transfer_batch_t)); 56 if (instance) { 57 instance->ep = ep; 58 instance->callback_in = func_in; 59 instance->callback_out = func_out; 60 instance->arg = arg; 61 instance->buffer = buffer; 62 instance->buffer_size = buffer_size; 63 instance->setup_size = 0; 64 instance->fun = fun; 65 instance->private_data = private_data; 66 instance->private_data_dtor = private_data_dtor; 67 instance->transfered_size = 0; 68 instance->error = EOK; 69 if (ep && ep->transfer_type == USB_TRANSFER_CONTROL) { 70 memcpy(instance->setup_buffer, &setup_buffer, 71 USB_SETUP_PACKET_SIZE); 72 instance->setup_size = USB_SETUP_PACKET_SIZE; 73 } 74 if (instance->ep) 75 endpoint_use(instance->ep); 76 } 77 return instance; 78 78 } 79 79 /*----------------------------------------------------------------------------*/ 80 /** Helper function, calls callback and correctly destroys batch structure.80 /** Mark batch as finished and run callback. 81 81 * 82 82 * @param[in] instance Batch structure to use. 83 * @param[in] data Data to copy to the output buffer. 84 * @param[in] size Size of @p data. 83 85 */ 84 void usb_transfer_batch_call_in_and_dispose(usb_transfer_batch_t *instance) 85 { 86 assert(instance); 87 usb_transfer_batch_call_in(instance); 88 usb_transfer_batch_dispose(instance); 89 } 90 /*----------------------------------------------------------------------------*/ 91 /** Helper function calls callback and correctly destroys batch structure. 92 * 93 * @param[in] instance Batch structure to use. 94 */ 95 void usb_transfer_batch_call_out_and_dispose(usb_transfer_batch_t *instance) 96 { 97 assert(instance); 98 usb_transfer_batch_call_out(instance); 99 usb_transfer_batch_dispose(instance); 100 } 101 /*----------------------------------------------------------------------------*/ 102 /** Mark batch as finished and continue with next step. 103 * 104 * @param[in] instance Batch structure to use. 105 * 106 */ 107 void usb_transfer_batch_finish(usb_transfer_batch_t *instance) 86 void usb_transfer_batch_finish( 87 usb_transfer_batch_t *instance, const void *data, size_t size) 108 88 { 109 89 assert(instance); 110 90 assert(instance->ep); 111 assert(instance->next_step); 112 endpoint_release(instance->ep); 113 instance->next_step(instance); 91 /* we care about the data and there are some to copy */ 92 if (instance->ep->direction != USB_DIRECTION_OUT 93 && data) { 94 const size_t min_size = 95 size < instance->buffer_size ? size : instance->buffer_size; 96 memcpy(instance->buffer, data, min_size); 97 } 98 if (instance->callback_out) 99 usb_transfer_batch_call_out(instance); 100 if (instance->callback_in) 101 usb_transfer_batch_call_in(instance); 102 114 103 } 115 104 /*----------------------------------------------------------------------------*/ … … 124 113 assert(instance); 125 114 assert(instance->callback_in); 126 assert(instance->ep);127 128 /* We are data in, we need data */129 memcpy(instance->buffer, instance->data_buffer, instance->buffer_size);130 115 131 116 usb_log_debug2("Batch %p " USB_TRANSFER_BATCH_FMT " completed (%zuB): %s.\n", … … 150 135 str_error(instance->error)); 151 136 137 if (instance->ep->transfer_type == USB_TRANSFER_CONTROL 138 && instance->error == EOK) { 139 const usb_target_t target = 140 {{ instance->ep->address, instance->ep->endpoint }}; 141 reset_ep_if_need( 142 fun_to_hcd(instance->fun), target, instance->setup_buffer); 143 } 144 152 145 instance->callback_out(instance->fun, 153 146 instance->error, instance->arg); … … 160 153 void usb_transfer_batch_dispose(usb_transfer_batch_t *instance) 161 154 { 162 assert(instance); 155 if (!instance) 156 return; 163 157 usb_log_debug2("Batch %p " USB_TRANSFER_BATCH_FMT " disposing.\n", 164 158 instance, USB_TRANSFER_BATCH_ARGS(*instance)); 159 if (instance->ep) { 160 endpoint_release(instance->ep); 161 } 165 162 if (instance->private_data) { 166 163 assert(instance->private_data_dtor);
Note:
See TracChangeset
for help on using the changeset viewer.
