Changeset e50cd7f in mainline for uspace/lib/usb/src/host/device_keeper.c
- Timestamp:
- 2011-04-17T19:17:55Z (14 years ago)
- Branches:
- lfn, master, serial, ticket/834-toolchain-update, topic/msim-upgrade, topic/simplify-dev-export
- Children:
- 63517c2, cfbbe1d3
- Parents:
- ef354b6 (diff), 8595577b (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/usb/src/host/device_keeper.c
ref354b6 re50cd7f 48 48 { 49 49 assert(instance); 50 fibril_mutex_initialize(&instance->guard);51 fibril_condvar_initialize(&instance->change);52 instance->last_address = 0;53 50 unsigned i = 0; 54 51 for (; i < USB_ADDRESS_COUNT; ++i) { 55 52 instance->devices[i].occupied = false; 56 instance->devices[i].control_used = 0;57 53 instance->devices[i].handle = 0; 58 list_initialize(&instance->devices[i].endpoints);54 instance->devices[i].speed = USB_SPEED_MAX; 59 55 } 60 } 61 /*----------------------------------------------------------------------------*/ 62 void usb_device_keeper_add_ep( 63 usb_device_keeper_t *instance, usb_address_t address, endpoint_t *ep) 64 { 65 assert(instance); 66 fibril_mutex_lock(&instance->guard); 67 assert(instance->devices[address].occupied); 68 list_append(&ep->same_device_eps, &instance->devices[address].endpoints); 69 fibril_mutex_unlock(&instance->guard); 70 } 71 /*----------------------------------------------------------------------------*/ 72 /** Attempt to obtain address 0, blocks. 73 * 74 * @param[in] instance Device keeper structure to use. 75 * @param[in] speed Speed of the device requesting default address. 76 */ 77 void usb_device_keeper_reserve_default_address( 78 usb_device_keeper_t *instance, usb_speed_t speed) 79 { 80 assert(instance); 81 fibril_mutex_lock(&instance->guard); 82 while (instance->devices[USB_ADDRESS_DEFAULT].occupied) { 83 fibril_condvar_wait(&instance->change, &instance->guard); 84 } 85 instance->devices[USB_ADDRESS_DEFAULT].occupied = true; 86 instance->devices[USB_ADDRESS_DEFAULT].speed = speed; 87 fibril_mutex_unlock(&instance->guard); 88 } 89 /*----------------------------------------------------------------------------*/ 90 /** Attempt to obtain address 0, blocks. 91 * 92 * @param[in] instance Device keeper structure to use. 93 * @param[in] speed Speed of the device requesting default address. 94 */ 95 void usb_device_keeper_release_default_address(usb_device_keeper_t *instance) 96 { 97 assert(instance); 98 fibril_mutex_lock(&instance->guard); 99 instance->devices[USB_ADDRESS_DEFAULT].occupied = false; 100 fibril_mutex_unlock(&instance->guard); 101 fibril_condvar_signal(&instance->change); 102 } 103 /*----------------------------------------------------------------------------*/ 104 /** Check setup packet data for signs of toggle reset. 105 * 106 * @param[in] instance Device keeper structure to use. 107 * @param[in] target Device to receive setup packet. 108 * @param[in] data Setup packet data. 109 * 110 * Really ugly one. 111 */ 112 void usb_device_keeper_reset_if_need( 113 usb_device_keeper_t *instance, usb_target_t target, const uint8_t *data) 114 { 115 assert(instance); 116 fibril_mutex_lock(&instance->guard); 117 if (target.endpoint > 15 || target.endpoint < 0 118 || target.address >= USB_ADDRESS_COUNT || target.address < 0 119 || !instance->devices[target.address].occupied) { 120 fibril_mutex_unlock(&instance->guard); 121 usb_log_error("Invalid data when checking for toggle reset.\n"); 122 return; 123 } 124 125 switch (data[1]) 126 { 127 case 0x01: /*clear feature*/ 128 /* recipient is endpoint, value is zero (ENDPOINT_STALL) */ 129 if (((data[0] & 0xf) == 1) && ((data[2] | data[3]) == 0)) { 130 link_t *current = 131 instance->devices[target.address].endpoints.next; 132 while (current != 133 &instance->devices[target.address].endpoints) 134 { 135 /* endpoint number is < 16, thus first byte is enough */ 136 endpoint_toggle_reset_filtered( 137 current, data[4]); 138 current = current->next; 139 } 140 } 141 break; 142 143 case 0x9: /* set configuration */ 144 case 0x11: /* set interface */ 145 /* target must be device */ 146 if ((data[0] & 0xf) == 0) { 147 link_t *current = 148 instance->devices[target.address].endpoints.next; 149 while (current != 150 &instance->devices[target.address].endpoints) 151 { 152 endpoint_toggle_reset(current); 153 current = current->next; 154 } 155 } 156 break; 157 } 158 fibril_mutex_unlock(&instance->guard); 56 // TODO: is this hack enough? 57 // (it is needed to allow smooth registration at default address) 58 instance->devices[0].occupied = true; 59 instance->last_address = 0; 60 fibril_mutex_initialize(&instance->guard); 159 61 } 160 62 /*----------------------------------------------------------------------------*/ … … 184 86 assert(new_address != USB_ADDRESS_DEFAULT); 185 87 assert(instance->devices[new_address].occupied == false); 88 186 89 instance->devices[new_address].occupied = true; 187 90 instance->devices[new_address].speed = speed; 188 91 instance->last_address = new_address; 92 189 93 fibril_mutex_unlock(&instance->guard); 190 94 return new_address; … … 202 106 assert(instance); 203 107 fibril_mutex_lock(&instance->guard); 108 204 109 assert(address > 0); 205 110 assert(address <= USB11_ADDRESS_MAX); 206 111 assert(instance->devices[address].occupied); 112 207 113 instance->devices[address].handle = handle; 208 114 fibril_mutex_unlock(&instance->guard); … … 223 129 fibril_mutex_lock(&instance->guard); 224 130 assert(instance->devices[address].occupied); 131 225 132 instance->devices[address].occupied = false; 226 133 fibril_mutex_unlock(&instance->guard); … … 241 148 while (address <= USB11_ADDRESS_MAX) { 242 149 if (instance->devices[address].handle == handle) { 150 assert(instance->devices[address].occupied); 243 151 fibril_mutex_unlock(&instance->guard); 244 152 return address; … … 262 170 assert(address >= 0); 263 171 assert(address <= USB11_ADDRESS_MAX); 172 264 173 return instance->devices[address].speed; 265 }266 /*----------------------------------------------------------------------------*/267 void usb_device_keeper_use_control(268 usb_device_keeper_t *instance, usb_target_t target)269 {270 assert(instance);271 const uint16_t ep = 1 << target.endpoint;272 fibril_mutex_lock(&instance->guard);273 while (instance->devices[target.address].control_used & ep) {274 fibril_condvar_wait(&instance->change, &instance->guard);275 }276 instance->devices[target.address].control_used |= ep;277 fibril_mutex_unlock(&instance->guard);278 }279 /*----------------------------------------------------------------------------*/280 void usb_device_keeper_release_control(281 usb_device_keeper_t *instance, usb_target_t target)282 {283 assert(instance);284 const uint16_t ep = 1 << target.endpoint;285 fibril_mutex_lock(&instance->guard);286 assert((instance->devices[target.address].control_used & ep) != 0);287 instance->devices[target.address].control_used &= ~ep;288 fibril_mutex_unlock(&instance->guard);289 fibril_condvar_signal(&instance->change);290 174 } 291 175 /**
Note:
See TracChangeset
for help on using the changeset viewer.