Changeset 925a21e in mainline for uspace/lib/usbhost/src/usb_endpoint_manager.c
- Timestamp:
- 2011-09-24T14:20:29Z (13 years ago)
- Branches:
- lfn, master, serial, ticket/834-toolchain-update, topic/msim-upgrade, topic/simplify-dev-export
- Children:
- 5bf76c1
- Parents:
- 867e2555 (diff), 1ab4aca (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. - File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
uspace/lib/usbhost/src/usb_endpoint_manager.c
r867e2555 r925a21e 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 =
Note:
See TracChangeset
for help on using the changeset viewer.