Changeset f11c288 in mainline
- Timestamp:
- 2011-04-09T22:20:02Z (13 years ago)
- Branches:
- lfn, master, serial, ticket/834-toolchain-update, topic/msim-upgrade, topic/simplify-dev-export
- Children:
- 0748854, d32ed36
- Parents:
- 709e868 (diff), a19a2d7 (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
- Files:
-
- 14 edited
Legend:
- Unmodified
- Added
- Removed
-
uspace/drv/ohci/batch.c
r709e868 rf11c288 227 227 ed_init(data->ed, instance->ep); 228 228 ed_add_tds(data->ed, &data->tds[0], &data->tds[data->td_count - 1]); 229 usb_log_debug("Created ED: %x:%x:%x:%x.\n", data->ed->status, 230 data->ed->td_tail, data->ed->td_head, data->ed->next); 229 usb_log_debug("Created ED(%p): %x:%x:%x:%x.\n", data->ed, 230 data->ed->status, data->ed->td_tail, data->ed->td_head, 231 data->ed->next); 231 232 int toggle = 0; 232 233 /* setup stage */ -
uspace/drv/ohci/hc.c
r709e868 rf11c288 108 108 ret, str_error(ret)); 109 109 110 hc_gain_control(instance); 111 ret = hc_init_memory(instance); 112 CHECK_RET_RETURN(ret, "Failed to create OHCI memory structures:%s.\n", 113 ret, str_error(ret)); 114 hc_init_hw(instance); 115 116 rh_init(&instance->rh, dev, instance->registers); 117 110 118 if (!interrupts) { 111 119 instance->interrupt_emulator = … … 114 122 } 115 123 116 hc_gain_control(instance);117 118 rh_init(&instance->rh, dev, instance->registers);119 120 hc_init_memory(instance);121 hc_init_hw(instance);122 123 /* TODO: implement */124 124 return EOK; 125 125 } … … 140 140 switch (batch->transfer_type) { 141 141 case USB_TRANSFER_CONTROL: 142 instance->registers->control &= ~C_CLE; 142 143 instance->registers->command_status |= CS_CLF; 144 usb_log_debug2("Set control transfer filled: %x.\n", 145 instance->registers->command_status); 146 instance->registers->control |= C_CLE; 143 147 break; 144 148 case USB_TRANSFER_BULK: 145 149 instance->registers->command_status |= CS_BLF; 150 usb_log_debug2("Set bulk transfer filled: %x.\n", 151 instance->registers->command_status); 146 152 break; 147 153 default: … … 154 160 { 155 161 assert(instance); 156 if ( status == 0)162 if ((status & ~IS_SF) == 0) /* ignore sof status */ 157 163 return; 158 164 if (status & IS_RHSC) … … 160 166 161 167 usb_log_info("OHCI interrupt: %x.\n", status); 168 162 169 163 170 LIST_INITIALIZE(done); … … 192 199 { 193 200 assert(instance); 201 /* Turn off legacy emulation */ 202 volatile uint32_t *ohci_emulation_reg = 203 (uint32_t*)((char*)instance->registers + 0x100); 204 usb_log_debug("OHCI legacy register %p: %x.\n", 205 ohci_emulation_reg, *ohci_emulation_reg); 206 *ohci_emulation_reg = 0; 207 194 208 /* Interrupt routing enabled => smm driver is active */ 195 209 if (instance->registers->control & C_IR) { 196 usb_log_ info("Found SMM driver requestingownership change.\n");210 usb_log_debug("SMM driver: request ownership change.\n"); 197 211 instance->registers->command_status |= CS_OCR; 198 212 while (instance->registers->control & C_IR) { 199 213 async_usleep(1000); 200 214 } 201 usb_log_info(" Ownership taken from SMM driver.\n");215 usb_log_info("SMM driver: Ownership taken.\n"); 202 216 return; 203 217 } … … 207 221 /* Interrupt routing disabled && status != USB_RESET => BIOS active */ 208 222 if (hc_status != C_HCFS_RESET) { 209 usb_log_ info("Found BIOS driver.\n");223 usb_log_debug("BIOS driver found.\n"); 210 224 if (hc_status == C_HCFS_OPERATIONAL) { 211 usb_log_info(" HC operational(BIOS).\n");225 usb_log_info("BIOS driver: HC operational.\n"); 212 226 return; 213 227 } … … 215 229 instance->registers->control &= (C_HCFS_RESUME << C_HCFS_SHIFT); 216 230 async_usleep(20000); 231 usb_log_info("BIOS driver: HC resumed.\n"); 217 232 return; 218 233 } … … 220 235 /* HC is in reset (hw startup) => no other driver 221 236 * maintain reset for at least the time specified in USB spec (50 ms)*/ 237 usb_log_info("HC found in reset.\n"); 222 238 async_usleep(50000); 223 224 /* turn off legacy emulation */225 volatile uint32_t *ohci_emulation_reg =226 (uint32_t*)((char*)instance->registers + 0x100);227 usb_log_info("OHCI legacy register status %p: %x.\n",228 ohci_emulation_reg, *ohci_emulation_reg);229 *ohci_emulation_reg = 0;230 231 239 } 232 240 /*----------------------------------------------------------------------------*/ 233 241 void hc_init_hw(hc_t *instance) 234 242 { 235 assert(instance); 243 /* OHCI guide page 42 */ 244 assert(instance); 245 usb_log_debug2("Started hc initialization routine.\n"); 246 247 /* Save contents of fm_interval register */ 236 248 const uint32_t fm_interval = instance->registers->fm_interval; 237 238 /* reset hc */ 249 usb_log_debug2("Old value of HcFmInterval: %x.\n", fm_interval); 250 251 /* Reset hc */ 252 usb_log_debug2("HC reset.\n"); 253 size_t time = 0; 239 254 instance->registers->command_status = CS_HCR; 240 async_usleep(10); 241 242 /* restore fm_interval */ 255 while (instance->registers->command_status & CS_HCR) { 256 async_usleep(10); 257 time += 10; 258 } 259 usb_log_debug2("HC reset complete in %zu us.\n", time); 260 261 /* Restore fm_interval */ 243 262 instance->registers->fm_interval = fm_interval; 244 263 assert((instance->registers->command_status & CS_HCR) == 0); 245 264 246 265 /* hc is now in suspend state */ 247 248 /* enable queues */ 266 usb_log_debug2("HC should be in suspend state(%x).\n", 267 instance->registers->control); 268 269 /* Enable queues */ 249 270 instance->registers->control |= (C_PLE | C_IE | C_CLE | C_BLE); 250 /* TODO: enable interrupts */ 251 /* set periodic start to 90% */ 252 instance->registers->periodic_start = (fm_interval / 10) * 9; 271 usb_log_debug2("All queues enabled(%x).\n", 272 instance->registers->control); 273 274 /* Disable interrupts */ 275 instance->registers->interrupt_disable = I_SF | I_OC; 276 usb_log_debug2("Disabling interrupts: %x.\n", 277 instance->registers->interrupt_disable); 278 instance->registers->interrupt_disable = I_MI; 279 usb_log_debug2("Enabled interrupts: %x.\n", 280 instance->registers->interrupt_enable); 281 282 /* Set periodic start to 90% */ 283 uint32_t frame_length = ((fm_interval >> FMI_FI_SHIFT) & FMI_FI_MASK); 284 instance->registers->periodic_start = (frame_length / 10) * 9; 285 usb_log_debug2("All periodic start set to: %x(%u - 90%% of %d).\n", 286 instance->registers->periodic_start, 287 instance->registers->periodic_start, frame_length); 253 288 254 289 instance->registers->control &= (C_HCFS_OPERATIONAL << C_HCFS_SHIFT); 255 usb_log_info("OHCI HC up and running.\n"); 290 usb_log_info("OHCI HC up and running(%x).\n", 291 instance->registers->control); 256 292 } 257 293 /*----------------------------------------------------------------------------*/ … … 298 334 { 299 335 assert(instance); 300 /* init queues */336 /* Init queues */ 301 337 hc_init_transfer_lists(instance); 302 338 303 /* init HCCA */339 /*Init HCCA */ 304 340 instance->hcca = malloc32(sizeof(hcca_t)); 305 341 if (instance->hcca == NULL) … … 307 343 bzero(instance->hcca, sizeof(hcca_t)); 308 344 instance->registers->hcca = addr_to_phys(instance->hcca); 309 310 /* use queues */ 345 usb_log_debug2("OHCI HCCA initialized at %p(%p).\n", 346 instance->hcca, instance->registers->hcca); 347 348 /* Use queues */ 311 349 instance->registers->bulk_head = instance->transfers_bulk.list_head_pa; 350 usb_log_debug2("Bulk HEAD set to: %p(%p).\n", 351 instance->transfers_bulk.list_head, 352 instance->transfers_bulk.list_head_pa); 353 312 354 instance->registers->control_head = 313 355 instance->transfers_control.list_head_pa; 356 usb_log_debug2("Control HEAD set to: %p(%p).\n", 357 instance->transfers_control.list_head, 358 instance->transfers_control.list_head_pa); 314 359 315 360 unsigned i = 0; … … 318 363 instance->transfers_interrupt.list_head_pa; 319 364 } 365 usb_log_debug2("Interrupt HEADs set to: %p(%p).\n", 366 instance->transfers_interrupt.list_head, 367 instance->transfers_interrupt.list_head_pa); 320 368 321 369 return EOK; -
uspace/drv/ohci/hw_struct/endpoint_descriptor.c
r709e868 rf11c288 42 42 bzero(instance, sizeof(ed_t)); 43 43 if (ep == NULL) { 44 instance->status |= ED_STATUS_K_FLAG;44 instance->status = ED_STATUS_K_FLAG; 45 45 return; 46 46 } … … 57 57 if (ep->transfer_type == USB_TRANSFER_ISOCHRONOUS) 58 58 instance->status |= ED_STATUS_F_FLAG; 59 60 59 } 61 62 60 /** 63 61 * @} -
uspace/drv/ohci/iface.c
r709e868 rf11c288 74 74 name, target.address, target.endpoint, size, ep->max_packet_size); 75 75 76 assert(ep->speed == 77 usb_device_keeper_get_speed(&(*hc)->manager, target.address)); 78 // assert(ep->max_packet_size == max_packet_size); 79 // assert(ep->transfer_type == USB_TRANSFER_CONTROL); 80 81 *batch = 82 batch_get(fun, ep, data, size, setup_data, setup_size, 83 in, out, arg); 84 if (!batch) 76 *batch = batch_get( 77 fun, ep, data, size, setup_data, setup_size, in, out, arg); 78 if (!*batch) 85 79 return ENOMEM; 86 return EOK;87 }88 89 90 /** Reserve default address interface function91 *92 * @param[in] fun DDF function that was called.93 * @param[in] speed Speed to associate with the new default address.94 * @return Error code.95 */96 static int reserve_default_address(ddf_fun_t *fun, usb_speed_t speed)97 {98 assert(fun);99 hc_t *hc = fun_to_hc(fun);100 assert(hc);101 usb_log_debug("Default address request with speed %d.\n", speed);102 usb_device_keeper_reserve_default_address(&hc->manager, speed);103 return EOK;104 #if 0105 endpoint_t *ep = malloc(sizeof(endpoint_t));106 if (ep == NULL)107 return ENOMEM;108 const size_t max_packet_size = speed == USB_SPEED_LOW ? 8 : 64;109 endpoint_init(ep, USB_TRANSFER_CONTROL, speed, max_packet_size);110 int ret;111 try_retgister:112 ret = usb_endpoint_manager_register_ep(&hc->ep_manager,113 USB_ADDRESS_DEFAULT, 0, USB_DIRECTION_BOTH, ep, endpoint_destroy, 0);114 if (ret == EEXISTS) {115 async_usleep(1000);116 goto try_retgister;117 }118 if (ret != EOK) {119 endpoint_destroy(ep);120 }121 return ret;122 #endif123 }124 /*----------------------------------------------------------------------------*/125 /** Release default address interface function126 *127 * @param[in] fun DDF function that was called.128 * @return Error code.129 */130 static int release_default_address(ddf_fun_t *fun)131 {132 assert(fun);133 hc_t *hc = fun_to_hc(fun);134 assert(hc);135 usb_log_debug("Default address release.\n");136 // return usb_endpoint_manager_unregister_ep(&hc->ep_manager,137 // USB_ADDRESS_DEFAULT, 0, USB_DIRECTION_BOTH);138 usb_device_keeper_release_default_address(&hc->manager);139 80 return EOK; 140 81 } … … 245 186 if (ret != EOK) { 246 187 endpoint_destroy(ep); 247 } else {248 usb_device_keeper_add_ep(&hc->manager, address, ep);249 188 } 250 189 return ret; … … 259 198 usb_log_debug("Unregister endpoint %d:%d %d.\n", 260 199 address, endpoint, direction); 261 endpoint_t *ep = usb_endpoint_manager_get_ep(&hc->ep_manager,262 address, endpoint, direction, NULL);263 if (ep != NULL) {264 usb_device_keeper_del_ep(&hc->manager, address, ep);265 }266 200 return usb_endpoint_manager_unregister_ep(&hc->ep_manager, address, 267 201 endpoint, direction); … … 435 369 if (ret != EOK) 436 370 return ret; 437 usb_ device_keeper_reset_if_need(&hc->manager, target, setup_data);371 usb_endpoint_manager_reset_if_need(&hc->ep_manager, target, setup_data); 438 372 batch_control_write(batch); 439 373 ret = hc_schedule(hc, batch); … … 484 418 /*----------------------------------------------------------------------------*/ 485 419 usbhc_iface_t hc_iface = { 486 .reserve_default_address = reserve_default_address,487 .release_default_address = release_default_address,488 420 .request_address = request_address, 489 421 .bind_address = bind_address, -
uspace/drv/ohci/ohci_regs.h
r709e868 rf11c288 84 84 /** Interupt enable/disable, reads give the same value, writing causes 85 85 * enable/disable */ 86 volatile uint32_t inter upt_enable;86 volatile uint32_t interrupt_enable; 87 87 volatile uint32_t interrupt_disable; 88 88 #define I_SO (1 << 0) /* Scheduling overrun */ … … 120 120 /** Frame time and max packet size for all transfers */ 121 121 volatile uint32_t fm_interval; 122 #define FMI_FI_MASK (0x 1fff) /* Frame interval in bit times (should be 11999)*/122 #define FMI_FI_MASK (0x3fff) /* Frame interval in bit times (should be 11999)*/ 123 123 #define FMI_FI_SHIFT (0) 124 124 #define FMI_FSMPS_MASK (0x7fff) /* Full speed max packet size */ … … 138 138 /** Remaining bit time in frame to start periodic transfers */ 139 139 volatile uint32_t periodic_start; 140 #define PS_PS_MASK (0x 1fff) /* bit time when periodic get priority (0x3e67) */140 #define PS_PS_MASK (0x3fff) /* bit time when periodic get priority (0x3e67) */ 141 141 142 142 /** Threshold for starting LS transaction */ -
uspace/drv/ohci/root_hub.c
r709e868 rf11c288 210 210 instance->registers = regs; 211 211 instance->device = dev; 212 instance->port_count = instance->registers->rh_desc_a & 0xff; 212 instance->port_count = 213 (instance->registers->rh_desc_a >> RHDA_NDS_SHIFT) & RHDA_NDS_MASK; 213 214 rh_init_descriptors(instance); 214 215 // set port power mode to no-power-switching -
uspace/drv/ohci/transfer_list.c
r709e868 rf11c288 122 122 usb_transfer_batch_t *first = list_get_instance( 123 123 instance->batch_list.next, usb_transfer_batch_t, link); 124 usb_log_debug("Batch(%p) added to queue %s, first is %p.\n", 125 batch, instance->name, first); 124 usb_log_debug("Batch(%p) added to list %s, first is %p(%p).\n", 125 batch, instance->name, first, batch_ed(first)); 126 if (last_ed == instance->list_head) { 127 usb_log_debug2("%s head ED: %x:%x:%x:%x.\n", instance->name, 128 last_ed->status, last_ed->td_tail, last_ed->td_head, 129 last_ed->next); 130 } 126 131 fibril_mutex_unlock(&instance->guard); 127 132 } -
uspace/drv/uhci-hcd/iface.c
r709e868 rf11c288 74 74 name, target.address, target.endpoint, size, ep->max_packet_size); 75 75 76 // assert(ep->speed == 77 // usb_device_keeper_get_speed(&(*hc)->manager, target.address)); 78 // assert(ep->max_packet_size == max_packet_size); 79 // assert(ep->transfer_type == USB_TRANSFER_CONTROL); 80 81 *batch = 82 batch_get(fun, ep, data, size, setup_data, setup_size, 83 in, out, arg); 84 if (!batch) 76 *batch = batch_get( 77 fun, ep, data, size, setup_data, setup_size, in, out, arg); 78 if (!*batch) 85 79 return ENOMEM; 86 return EOK;87 }88 89 90 /** Reserve default address interface function91 *92 * @param[in] fun DDF function that was called.93 * @param[in] speed Speed to associate with the new default address.94 * @return Error code.95 */96 static int reserve_default_address(ddf_fun_t *fun, usb_speed_t speed)97 {98 assert(fun);99 hc_t *hc = fun_to_hc(fun);100 assert(hc);101 usb_log_debug("Default address request with speed %d.\n", speed);102 usb_device_keeper_reserve_default_address(&hc->manager, speed);103 return EOK;104 #if 0105 endpoint_t *ep = malloc(sizeof(endpoint_t));106 if (ep == NULL)107 return ENOMEM;108 const size_t max_packet_size = speed == USB_SPEED_LOW ? 8 : 64;109 endpoint_init(ep, USB_TRANSFER_CONTROL, speed, max_packet_size);110 int ret;111 try_retgister:112 ret = usb_endpoint_manager_register_ep(&hc->ep_manager,113 USB_ADDRESS_DEFAULT, 0, USB_DIRECTION_BOTH, ep, endpoint_destroy, 0);114 if (ret == EEXISTS) {115 async_usleep(1000);116 goto try_retgister;117 }118 if (ret != EOK) {119 endpoint_destroy(ep);120 }121 return ret;122 #endif123 }124 /*----------------------------------------------------------------------------*/125 /** Release default address interface function126 *127 * @param[in] fun DDF function that was called.128 * @return Error code.129 */130 static int release_default_address(ddf_fun_t *fun)131 {132 assert(fun);133 hc_t *hc = fun_to_hc(fun);134 assert(hc);135 usb_log_debug("Default address release.\n");136 // return usb_endpoint_manager_unregister_ep(&hc->ep_manager,137 // USB_ADDRESS_DEFAULT, 0, USB_DIRECTION_BOTH);138 usb_device_keeper_release_default_address(&hc->manager);139 80 return EOK; 140 81 } … … 232 173 if (ret != EOK) { 233 174 endpoint_destroy(ep); 234 } else {235 usb_device_keeper_add_ep(&hc->manager, address, ep);236 175 } 237 176 return ret; … … 246 185 usb_log_debug("Unregister endpoint %d:%d %d.\n", 247 186 address, endpoint, direction); 248 endpoint_t *ep = usb_endpoint_manager_get_ep(&hc->ep_manager,249 address, endpoint, direction, NULL);250 if (ep != NULL) {251 usb_device_keeper_del_ep(&hc->manager, address, ep);252 }253 187 return usb_endpoint_manager_unregister_ep(&hc->ep_manager, address, 254 188 endpoint, direction); … … 391 325 if (ret != EOK) 392 326 return ret; 393 usb_ device_keeper_reset_if_need(&hc->manager, target, setup_data);327 usb_endpoint_manager_reset_if_need(&hc->ep_manager, target, setup_data); 394 328 batch_control_write(batch); 395 329 ret = hc_schedule(hc, batch); … … 433 367 /*----------------------------------------------------------------------------*/ 434 368 usbhc_iface_t hc_iface = { 435 .reserve_default_address = reserve_default_address,436 .release_default_address = release_default_address,437 369 .request_address = request_address, 438 370 .bind_address = bind_address, -
uspace/lib/usb/include/usb/host/device_keeper.h
r709e868 rf11c288 71 71 void usb_device_keeper_init(usb_device_keeper_t *instance); 72 72 73 void usb_device_keeper_add_ep(74 usb_device_keeper_t *instance, usb_address_t address, endpoint_t *ep);75 void usb_device_keeper_del_ep(76 usb_device_keeper_t *instance, usb_address_t address, endpoint_t *ep);77 78 73 void usb_device_keeper_reserve_default_address( 79 74 usb_device_keeper_t *instance, usb_speed_t speed); -
uspace/lib/usb/include/usb/host/endpoint.h
r709e868 rf11c288 54 54 fibril_condvar_t avail; 55 55 volatile bool active; 56 link_t same_device_eps;57 56 } endpoint_t; 58 57 … … 71 70 void endpoint_toggle_set(endpoint_t *instance, int toggle); 72 71 73 void endpoint_toggle_reset(link_t *ep); 74 75 void endpoint_toggle_reset_filtered(link_t *ep, usb_endpoint_t epn); 76 72 void endpoint_toggle_reset_filtered(endpoint_t *instance, usb_target_t target); 77 73 #endif 78 74 /** -
uspace/lib/usb/include/usb/host/usb_endpoint_manager.h
r709e868 rf11c288 78 78 size_t *bw); 79 79 80 void usb_endpoint_manager_reset_if_need( 81 usb_endpoint_manager_t *instance, usb_target_t target, const uint8_t *data); 80 82 #endif 81 83 /** -
uspace/lib/usb/src/host/device_keeper.c
r709e868 rf11c288 54 54 for (; i < USB_ADDRESS_COUNT; ++i) { 55 55 instance->devices[i].occupied = false; 56 instance->devices[i].control_used = 0;57 56 instance->devices[i].handle = 0; 58 57 instance->devices[i].speed = USB_SPEED_MAX; 59 list_initialize(&instance->devices[i].endpoints);60 58 } 61 59 // TODO: is this hack enough? 62 60 // (it is needed to allow smooth registration at default address) 63 61 instance->devices[0].occupied = true; 64 }65 /*----------------------------------------------------------------------------*/66 void usb_device_keeper_add_ep(67 usb_device_keeper_t *instance, usb_address_t address, endpoint_t *ep)68 {69 assert(instance);70 fibril_mutex_lock(&instance->guard);71 assert(instance->devices[address].occupied);72 list_append(&ep->same_device_eps, &instance->devices[address].endpoints);73 fibril_mutex_unlock(&instance->guard);74 }75 /*----------------------------------------------------------------------------*/76 void usb_device_keeper_del_ep(77 usb_device_keeper_t *instance, usb_address_t address, endpoint_t *ep)78 {79 assert(instance);80 fibril_mutex_lock(&instance->guard);81 assert(instance->devices[address].occupied);82 list_remove(&ep->same_device_eps);83 list_initialize(&ep->same_device_eps);84 fibril_mutex_unlock(&instance->guard);85 62 } 86 63 /*----------------------------------------------------------------------------*/ … … 117 94 } 118 95 /*----------------------------------------------------------------------------*/ 119 /** Check setup packet data for signs of toggle reset.120 *121 * @param[in] instance Device keeper structure to use.122 * @param[in] target Device to receive setup packet.123 * @param[in] data Setup packet data.124 *125 * Really ugly one.126 */127 void usb_device_keeper_reset_if_need(128 usb_device_keeper_t *instance, usb_target_t target, const uint8_t *data)129 {130 assert(instance);131 fibril_mutex_lock(&instance->guard);132 if (target.endpoint > 15 || target.endpoint < 0133 || target.address >= USB_ADDRESS_COUNT || target.address < 0134 || !instance->devices[target.address].occupied) {135 fibril_mutex_unlock(&instance->guard);136 usb_log_error("Invalid data when checking for toggle reset.\n");137 return;138 }139 140 switch (data[1])141 {142 case 0x01: /*clear feature*/143 /* recipient is endpoint, value is zero (ENDPOINT_STALL) */144 if (((data[0] & 0xf) == 1) && ((data[2] | data[3]) == 0)) {145 link_t *current =146 instance->devices[target.address].endpoints.next;147 while (current !=148 &instance->devices[target.address].endpoints)149 {150 /* endpoint number is < 16, thus first byte is enough */151 endpoint_toggle_reset_filtered(152 current, data[4]);153 current = current->next;154 }155 }156 break;157 158 case 0x9: /* set configuration */159 case 0x11: /* set interface */160 /* target must be device */161 if ((data[0] & 0xf) == 0) {162 link_t *current =163 instance->devices[target.address].endpoints.next;164 while (current !=165 &instance->devices[target.address].endpoints)166 {167 endpoint_toggle_reset(current);168 current = current->next;169 }170 }171 break;172 }173 fibril_mutex_unlock(&instance->guard);174 }175 96 /*----------------------------------------------------------------------------*/ 176 97 /** Get a free USB address -
uspace/lib/usb/src/host/endpoint.c
r709e868 rf11c288 53 53 fibril_mutex_initialize(&instance->guard); 54 54 fibril_condvar_initialize(&instance->avail); 55 link_initialize(&instance->same_device_eps);56 55 return EOK; 57 56 } … … 61 60 assert(instance); 62 61 assert(!instance->active); 63 list_remove(&instance->same_device_eps);64 62 free(instance); 65 63 } … … 97 95 } 98 96 /*----------------------------------------------------------------------------*/ 99 void endpoint_toggle_reset (link_t *ep)97 void endpoint_toggle_reset_filtered(endpoint_t *instance, usb_target_t target) 100 98 { 101 endpoint_t *instance =102 list_get_instance(ep, endpoint_t, same_device_eps);103 99 assert(instance); 104 instance->toggle = 0; 105 } 106 /*----------------------------------------------------------------------------*/ 107 void endpoint_toggle_reset_filtered(link_t *ep, usb_endpoint_t epn) 108 { 109 endpoint_t *instance = 110 list_get_instance(ep, endpoint_t, same_device_eps); 111 assert(instance); 112 if (instance->endpoint == epn) 100 if (instance->address == target.address && 101 instance->endpoint == target.endpoint) 113 102 instance->toggle = 0; 114 103 } -
uspace/lib/usb/src/host/usb_endpoint_manager.c
r709e868 rf11c288 31 31 #include <errno.h> 32 32 33 #include <usb/debug.h> 33 34 #include <usb/host/usb_endpoint_manager.h> 34 35 … … 80 81 endpoint_destroy(node->ep); 81 82 free(node); 83 } 84 /*----------------------------------------------------------------------------*/ 85 static void node_toggle_reset_filtered(link_t *item, void *arg) 86 { 87 assert(item); 88 node_t *node = hash_table_get_instance(item, node_t, link); 89 usb_target_t *target = arg; 90 endpoint_toggle_reset_filtered(node->ep, *target); 82 91 } 83 92 /*----------------------------------------------------------------------------*/ … … 230 239 return node->ep; 231 240 } 241 /*----------------------------------------------------------------------------*/ 242 /** Check setup packet data for signs of toggle reset. 243 * 244 * @param[in] instance Device keeper structure to use. 245 * @param[in] target Device to receive setup packet. 246 * @param[in] data Setup packet data. 247 * 248 * Really ugly one. 249 */ 250 void usb_endpoint_manager_reset_if_need( 251 usb_endpoint_manager_t *instance, usb_target_t target, const uint8_t *data) 252 { 253 assert(instance); 254 if (target.endpoint > 15 || target.endpoint < 0 255 || target.address >= USB11_ADDRESS_MAX || target.address < 0) { 256 usb_log_error("Invalid data when checking for toggle reset.\n"); 257 return; 258 } 259 260 switch (data[1]) 261 { 262 case 0x01: /*clear feature*/ 263 /* recipient is endpoint, value is zero (ENDPOINT_STALL) */ 264 if (((data[0] & 0xf) == 1) && ((data[2] | data[3]) == 0)) { 265 /* endpoint number is < 16, thus first byte is enough */ 266 usb_target_t reset_target = 267 { .address = target.address, data[4] }; 268 fibril_mutex_lock(&instance->guard); 269 hash_table_apply(&instance->ep_table, 270 node_toggle_reset_filtered, &reset_target); 271 fibril_mutex_unlock(&instance->guard); 272 } 273 break; 274 275 case 0x9: /* set configuration */ 276 case 0x11: /* set interface */ 277 /* target must be device */ 278 if ((data[0] & 0xf) == 0) { 279 usb_target_t reset_target = 280 { .address = target.address, 0 }; 281 fibril_mutex_lock(&instance->guard); 282 hash_table_apply(&instance->ep_table, 283 node_toggle_reset_filtered, &reset_target); 284 fibril_mutex_unlock(&instance->guard); 285 } 286 break; 287 } 288 }
Note:
See TracChangeset
for help on using the changeset viewer.