Changeset 4ab89e5 in mainline
- Timestamp:
- 2011-04-02T14:32:48Z (14 years ago)
- Branches:
- lfn, master, serial, ticket/834-toolchain-update, topic/msim-upgrade, topic/simplify-dev-export
- Children:
- a1313b8c
- Parents:
- 857edac
- Location:
- uspace/lib/usb
- Files:
-
- 2 edited
Legend:
- Unmodified
- Added
- Removed
-
uspace/lib/usb/include/usb/host/bandwidth.h
r857edac r4ab89e5 44 44 #include <usb/usb.h> 45 45 46 #define BANDWIDTH_TOTAL_USB11 12000000 47 #define BANDWIDTH_AVAILABLE_USB11 ((BANDWIDTH_TOTAL_USB11 / 10) * 9) 48 46 49 typedef struct bandwidth { 47 50 hash_table_t reserved; 48 51 fibril_mutex_t guard; 49 52 size_t free; 53 size_t (*usage_fnc)(usb_speed_t, usb_transfer_type_t, size_t, size_t); 50 54 } bandwidth_t; 51 55 52 int bandwidth_init(bandwidth_t *instance); 56 size_t bandwidth_count_usb11(usb_speed_t speed, usb_transfer_type_t type, 57 size_t size, size_t max_packet_size); 58 59 int bandwidth_init(bandwidth_t *instance, size_t bandwidth, 60 size_t (*usage_fnc)(usb_speed_t, usb_transfer_type_t, size_t, size_t)); 53 61 54 62 void bandwidth_destroy(bandwidth_t *instance); -
uspace/lib/usb/src/host/bandwidth.c
r857edac r4ab89e5 58 58 } 59 59 /*----------------------------------------------------------------------------*/ 60 static int trans_compare(unsigned long key[], hash_count_t keys, link_t *item) 60 static int transfer_compare( 61 unsigned long key[], hash_count_t keys, link_t *item) 61 62 { 62 63 assert(item); … … 68 69 } 69 70 /*----------------------------------------------------------------------------*/ 70 static void dummy(link_t *item) {} 71 static void transfer_remove(link_t *item) 72 { 73 assert(item); 74 transfer_status_t *status = 75 hash_table_get_instance(item, transfer_status_t, link); 76 assert(status); 77 free(status); 78 } 71 79 /*----------------------------------------------------------------------------*/ 72 80 hash_table_operations_t op = { 73 81 .hash = transfer_hash, 74 .compare = trans _compare,75 .remove_callback = dummy,82 .compare = transfer_compare, 83 .remove_callback = transfer_remove, 76 84 }; 77 85 /*----------------------------------------------------------------------------*/ 78 int bandwidth_init(bandwidth_t *instance) 86 size_t bandwidth_count_usb11(usb_speed_t speed, usb_transfer_type_t type, 87 size_t size, size_t max_packet_size) 88 { 89 const unsigned packet_count = 90 (size + max_packet_size - 1) / max_packet_size; 91 /* TODO: It may be that ISO and INT transfers use only one data packet 92 * per transaction, but I did not find text in UB spec that confirms 93 * this */ 94 /* NOTE: All data packets will be considered to be max_packet_size */ 95 switch (speed) 96 { 97 case USB_SPEED_LOW: 98 assert(type == USB_TRANSFER_INTERRUPT); 99 /* Protocol overhead 13B 100 * (3 SYNC bytes, 3 PID bytes, 2 Endpoint + CRC bytes, 2 101 * CRC bytes, and a 3-byte interpacket delay) 102 * see USB spec page 45-46. */ 103 /* Speed penalty 8: low speed is 8-times slower*/ 104 return packet_count * (13 + max_packet_size) * 8; 105 case USB_SPEED_FULL: 106 /* Interrupt transfer overhead see above 107 * or page 45 of USB spec */ 108 if (type == USB_TRANSFER_INTERRUPT) 109 return packet_count * (13 + max_packet_size); 110 111 assert(type == USB_TRANSFER_ISOCHRONOUS); 112 /* Protocol overhead 9B 113 * (2 SYNC bytes, 2 PID bytes, 2 Endpoint + CRC bytes, 2 CRC 114 * bytes, and a 1-byte interpacket delay) 115 * see USB spec page 42 */ 116 return packet_count * (9 + max_packet_size); 117 default: 118 return 0; 119 } 120 } 121 /*----------------------------------------------------------------------------*/ 122 int bandwidth_init(bandwidth_t *instance, size_t bandwidth, 123 size_t (*usage_fnc)(usb_speed_t, usb_transfer_type_t, size_t, size_t)) 79 124 { 80 125 assert(instance); 81 126 fibril_mutex_initialize(&instance->guard); 127 instance->free = bandwidth; 128 instance->usage_fnc = usage_fnc; 82 129 return 83 130 hash_table_create(&instance->reserved, BUCKET_COUNT, MAX_KEYS, &op); … … 94 141 unsigned interval) 95 142 { 96 assert(instance); 97 transfer_t trans = { 98 .address = address, 99 .endpoint = endpoint, 100 .direction = direction, 101 }; 102 fibril_mutex_lock(&instance->guard); 143 if (transfer_type != USB_TRANSFER_ISOCHRONOUS && 144 transfer_type != USB_TRANSFER_INTERRUPT) { 145 return ENOTSUP; 146 } 147 148 assert(instance); 149 assert(instance->usage_fnc); 150 151 transfer_t trans = { 152 .address = address, 153 .endpoint = endpoint, 154 .direction = direction, 155 }; 156 fibril_mutex_lock(&instance->guard); 157 const size_t required = 158 instance->usage_fnc(speed, transfer_type, size, max_packet_size); 159 160 if (required > instance->free) { 161 fibril_mutex_unlock(&instance->guard); 162 return ENOSPC; 163 } 164 103 165 link_t *item = 104 166 hash_table_find(&instance->reserved, (unsigned long*)&trans); … … 115 177 116 178 status->transfer = trans; 117 status->required = 0;179 status->required = required; 118 180 status->used = false; 119 181 link_initialize(&status->link); … … 121 183 hash_table_insert(&instance->reserved, 122 184 (unsigned long*)&status->transfer, &status->link); 185 instance->free -= required; 123 186 fibril_mutex_unlock(&instance->guard); 124 187 return EOK; … … 142 205 return EINVAL; 143 206 } 207 208 transfer_status_t *status = 209 hash_table_get_instance(item, transfer_status_t, link); 210 211 instance->free += status->required; 144 212 145 213 hash_table_remove(&instance->reserved,
Note:
See TracChangeset
for help on using the changeset viewer.