Changes in / [3f3afb9:58226b4] in mainline
- Location:
- uspace
- Files:
-
- 5 deleted
- 48 edited
Legend:
- Unmodified
- Added
- Removed
-
uspace/drv/ohci/batch.c
r3f3afb9 r58226b4 51 51 static void batch_control(usb_transfer_batch_t *instance, 52 52 usb_direction_t data_dir, usb_direction_t status_dir); 53 static void batch_data(usb_transfer_batch_t *instance);54 53 static void batch_call_in_and_dispose(usb_transfer_batch_t *instance); 55 54 static void batch_call_out_and_dispose(usb_transfer_batch_t *instance); … … 135 134 assert(data); 136 135 size_t tds = data->td_count - 1; 137 usb_log_debug ("Batch(%p) checking %d td(s) for completion.\n",136 usb_log_debug2("Batch(%p) checking %d td(s) for completion.\n", 138 137 instance, tds); 139 usb_log_debug("ED: %x:%x:%x:%x.\n",140 data->ed->status, data->ed->td_head, data->ed->td_tail,141 data->ed->next);142 138 size_t i = 0; 143 139 for (; i < tds; ++i) { 144 usb_log_debug("TD %d: %x:%x:%x:%x.\n", i, 145 data->tds[i].status, data->tds[i].cbp, data->tds[i].next, 146 data->tds[i].be); 147 if (!td_is_finished(&data->tds[i])) { 140 if (!td_is_finished(&data->tds[i])) 148 141 return false; 149 }150 142 instance->error = td_error(&data->tds[i]); 151 143 /* FIXME: calculate real transfered size */ … … 185 177 assert(instance->direction == USB_DIRECTION_IN); 186 178 instance->next_step = batch_call_in_and_dispose; 187 batch_data(instance);179 /* TODO: implement */ 188 180 usb_log_debug("Batch(%p) INTERRUPT IN initialized.\n", instance); 189 181 } … … 197 189 instance->buffer_size); 198 190 instance->next_step = batch_call_out_and_dispose; 199 batch_data(instance);191 /* TODO: implement */ 200 192 usb_log_debug("Batch(%p) INTERRUPT OUT initialized.\n", instance); 201 193 } … … 206 198 instance->direction = USB_DIRECTION_IN; 207 199 instance->next_step = batch_call_in_and_dispose; 208 batch_data(instance);200 /* TODO: implement */ 209 201 usb_log_debug("Batch(%p) BULK IN initialized.\n", instance); 210 202 } … … 215 207 instance->direction = USB_DIRECTION_IN; 216 208 instance->next_step = batch_call_in_and_dispose; 217 batch_data(instance);209 /* TODO: implement */ 218 210 usb_log_debug("Batch(%p) BULK IN initialized.\n", instance); 219 211 } … … 235 227 ed_init(data->ed, instance->ep); 236 228 ed_add_tds(data->ed, &data->tds[0], &data->tds[data->td_count - 1]); 237 usb_log_debug("Created ED(%p): %x:%x:%x:%x.\n", data->ed, 238 data->ed->status, data->ed->td_tail, data->ed->td_head, 239 data->ed->next); 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); 240 231 int toggle = 0; 241 232 /* setup stage */ … … 276 267 } 277 268 /*----------------------------------------------------------------------------*/ 278 void batch_data(usb_transfer_batch_t *instance)279 {280 assert(instance);281 ohci_batch_t *data = instance->private_data;282 assert(data);283 ed_init(data->ed, instance->ep);284 ed_add_tds(data->ed, &data->tds[0], &data->tds[data->td_count - 1]);285 usb_log_debug("Created ED(%p): %x:%x:%x:%x.\n", data->ed,286 data->ed->status, data->ed->td_tail, data->ed->td_head,287 data->ed->next);288 289 /* data stage */290 size_t td_current = 0;291 size_t remain_size = instance->buffer_size;292 char *transfer_buffer = instance->transport_buffer;293 while (remain_size > 0) {294 size_t transfer_size = remain_size > OHCI_TD_MAX_TRANSFER ?295 OHCI_TD_MAX_TRANSFER : remain_size;296 297 td_init(&data->tds[td_current], instance->ep->direction,298 transfer_buffer, transfer_size, -1);299 td_set_next(&data->tds[td_current], &data->tds[td_current + 1]);300 usb_log_debug("Created DATA TD: %x:%x:%x:%x.\n",301 data->tds[td_current].status, data->tds[td_current].cbp,302 data->tds[td_current].next, data->tds[td_current].be);303 304 transfer_buffer += transfer_size;305 remain_size -= transfer_size;306 assert(td_current < data->td_count);307 ++td_current;308 }309 }310 /*----------------------------------------------------------------------------*/311 269 /** Helper function calls callback and correctly disposes of batch structure. 312 270 * -
uspace/drv/ohci/hc.c
r3f3afb9 r58226b4 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 fibril_mutex_initialize(&instance->guard);116 117 rh_init(&instance->rh, dev, instance->registers);118 119 110 if (!interrupts) { 120 111 instance->interrupt_emulator = … … 123 114 } 124 115 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 */ 125 124 return EOK; 126 125 } … … 136 135 } 137 136 138 fibril_mutex_lock(&instance->guard); 137 transfer_list_add_batch( 138 instance->transfers[batch->transfer_type], batch); 139 139 140 switch (batch->transfer_type) { 140 141 case USB_TRANSFER_CONTROL: 141 instance->registers->control &= ~C_CLE;142 transfer_list_add_batch(143 instance->transfers[batch->transfer_type], batch);144 142 instance->registers->command_status |= CS_CLF; 145 usb_log_debug2("Set CS control transfer filled: %x.\n",146 instance->registers->command_status);147 instance->registers->control_current = 0;148 instance->registers->control |= C_CLE;149 143 break; 150 144 case USB_TRANSFER_BULK: 151 instance->registers->control &= ~C_BLE;152 transfer_list_add_batch(153 instance->transfers[batch->transfer_type], batch);154 145 instance->registers->command_status |= CS_BLF; 155 usb_log_debug2("Set bulk transfer filled: %x.\n",156 instance->registers->command_status);157 instance->registers->control |= C_BLE;158 break;159 case USB_TRANSFER_INTERRUPT:160 case USB_TRANSFER_ISOCHRONOUS:161 instance->registers->control &= (~C_PLE & ~C_IE);162 transfer_list_add_batch(163 instance->transfers[batch->transfer_type], batch);164 instance->registers->control |= C_PLE | C_IE;165 usb_log_debug2("Added periodic transfer: %x.\n",166 instance->registers->periodic_current);167 146 break; 168 147 default: 169 148 break; 170 149 } 171 fibril_mutex_unlock(&instance->guard);172 150 return EOK; 173 151 } … … 176 154 { 177 155 assert(instance); 178 if ( (status & ~IS_SF) == 0) /* ignore sof status */156 if (status == 0) 179 157 return; 180 158 if (status & IS_RHSC) 181 159 rh_interrupt(&instance->rh); 182 160 183 usb_log_debug("OHCI interrupt: %x.\n", status); 184 185 if (status & IS_WDH) { 186 fibril_mutex_lock(&instance->guard); 187 usb_log_debug2("HCCA: %p-%p(%p).\n", instance->hcca, 188 instance->registers->hcca, addr_to_phys(instance->hcca)); 189 usb_log_debug2("Periodic current: %p.\n", 190 instance->registers->periodic_current); 191 LIST_INITIALIZE(done); 192 transfer_list_remove_finished( 193 &instance->transfers_interrupt, &done); 194 transfer_list_remove_finished( 195 &instance->transfers_isochronous, &done); 196 transfer_list_remove_finished( 197 &instance->transfers_control, &done); 198 transfer_list_remove_finished( 199 &instance->transfers_bulk, &done); 200 201 while (!list_empty(&done)) { 202 link_t *item = done.next; 203 list_remove(item); 204 usb_transfer_batch_t *batch = 205 list_get_instance(item, usb_transfer_batch_t, link); 206 usb_transfer_batch_finish(batch); 207 } 208 fibril_mutex_unlock(&instance->guard); 161 usb_log_info("OHCI interrupt: %x.\n", status); 162 163 LIST_INITIALIZE(done); 164 transfer_list_remove_finished(&instance->transfers_interrupt, &done); 165 transfer_list_remove_finished(&instance->transfers_isochronous, &done); 166 transfer_list_remove_finished(&instance->transfers_control, &done); 167 transfer_list_remove_finished(&instance->transfers_bulk, &done); 168 169 while (!list_empty(&done)) { 170 link_t *item = done.next; 171 list_remove(item); 172 usb_transfer_batch_t *batch = 173 list_get_instance(item, usb_transfer_batch_t, link); 174 usb_transfer_batch_finish(batch); 209 175 } 210 176 } … … 218 184 instance->registers->interrupt_status = status; 219 185 hc_interrupt(instance, status); 220 async_usleep( 50000);186 async_usleep(1000); 221 187 } 222 188 return EOK; … … 226 192 { 227 193 assert(instance); 228 /* Turn off legacy emulation */229 volatile uint32_t *ohci_emulation_reg =230 (uint32_t*)((char*)instance->registers + 0x100);231 usb_log_debug("OHCI legacy register %p: %x.\n",232 ohci_emulation_reg, *ohci_emulation_reg);233 *ohci_emulation_reg = 0;234 235 194 /* Interrupt routing enabled => smm driver is active */ 236 195 if (instance->registers->control & C_IR) { 237 usb_log_ debug("SMM driver: requestownership change.\n");196 usb_log_info("Found SMM driver requesting ownership change.\n"); 238 197 instance->registers->command_status |= CS_OCR; 239 198 while (instance->registers->control & C_IR) { 240 199 async_usleep(1000); 241 200 } 242 usb_log_info(" SMM driver: Ownership taken.\n");201 usb_log_info("Ownership taken from SMM driver.\n"); 243 202 return; 244 203 } … … 248 207 /* Interrupt routing disabled && status != USB_RESET => BIOS active */ 249 208 if (hc_status != C_HCFS_RESET) { 250 usb_log_ debug("BIOS driver found.\n");209 usb_log_info("Found BIOS driver.\n"); 251 210 if (hc_status == C_HCFS_OPERATIONAL) { 252 usb_log_info(" BIOS driver: HC operational.\n");211 usb_log_info("HC operational(BIOS).\n"); 253 212 return; 254 213 } … … 256 215 instance->registers->control &= (C_HCFS_RESUME << C_HCFS_SHIFT); 257 216 async_usleep(20000); 258 usb_log_info("BIOS driver: HC resumed.\n");259 217 return; 260 218 } … … 262 220 /* HC is in reset (hw startup) => no other driver 263 221 * maintain reset for at least the time specified in USB spec (50 ms)*/ 264 usb_log_info("HC found in reset.\n");265 222 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 266 231 } 267 232 /*----------------------------------------------------------------------------*/ 268 233 void hc_init_hw(hc_t *instance) 269 234 { 270 /* OHCI guide page 42 */ 271 assert(instance); 272 usb_log_debug2("Started hc initialization routine.\n"); 273 274 /* Save contents of fm_interval register */ 235 assert(instance); 275 236 const uint32_t fm_interval = instance->registers->fm_interval; 276 usb_log_debug2("Old value of HcFmInterval: %x.\n", fm_interval); 277 278 /* Reset hc */ 279 usb_log_debug2("HC reset.\n"); 280 size_t time = 0; 237 238 /* reset hc */ 281 239 instance->registers->command_status = CS_HCR; 282 while (instance->registers->command_status & CS_HCR) { 283 async_usleep(10); 284 time += 10; 285 } 286 usb_log_debug2("HC reset complete in %zu us.\n", time); 287 288 /* Restore fm_interval */ 240 async_usleep(10); 241 242 /* restore fm_interval */ 289 243 instance->registers->fm_interval = fm_interval; 290 244 assert((instance->registers->command_status & CS_HCR) == 0); 291 245 292 246 /* hc is now in suspend state */ 293 usb_log_debug2("HC should be in suspend state(%x).\n", 294 instance->registers->control); 295 296 /* Use HCCA */ 297 instance->registers->hcca = addr_to_phys(instance->hcca); 298 299 /* Use queues */ 300 instance->registers->bulk_head = instance->transfers_bulk.list_head_pa; 301 usb_log_debug2("Bulk HEAD set to: %p(%p).\n", 302 instance->transfers_bulk.list_head, 303 instance->transfers_bulk.list_head_pa); 304 305 instance->registers->control_head = 306 instance->transfers_control.list_head_pa; 307 usb_log_debug2("Control HEAD set to: %p(%p).\n", 308 instance->transfers_control.list_head, 309 instance->transfers_control.list_head_pa); 310 311 /* Enable queues */ 247 248 /* enable queues */ 312 249 instance->registers->control |= (C_PLE | C_IE | C_CLE | C_BLE); 313 usb_log_debug2("All queues enabled(%x).\n", 314 instance->registers->control); 315 316 /* Disable interrupts */ 317 instance->registers->interrupt_disable = I_SF | I_OC; 318 usb_log_debug2("Disabling interrupts: %x.\n", 319 instance->registers->interrupt_disable); 320 instance->registers->interrupt_disable = I_MI; 321 usb_log_debug2("Enabled interrupts: %x.\n", 322 instance->registers->interrupt_enable); 323 324 /* Set periodic start to 90% */ 325 uint32_t frame_length = ((fm_interval >> FMI_FI_SHIFT) & FMI_FI_MASK); 326 instance->registers->periodic_start = (frame_length / 10) * 9; 327 usb_log_debug2("All periodic start set to: %x(%u - 90%% of %d).\n", 328 instance->registers->periodic_start, 329 instance->registers->periodic_start, frame_length); 250 /* TODO: enable interrupts */ 251 /* set periodic start to 90% */ 252 instance->registers->periodic_start = (fm_interval / 10) * 9; 330 253 331 254 instance->registers->control &= (C_HCFS_OPERATIONAL << C_HCFS_SHIFT); 332 usb_log_info("OHCI HC up and running(%x).\n", 333 instance->registers->control); 255 usb_log_info("OHCI HC up and running.\n"); 334 256 } 335 257 /*----------------------------------------------------------------------------*/ … … 355 277 SETUP_TRANSFER_LIST(transfers_control, "CONTROL"); 356 278 SETUP_TRANSFER_LIST(transfers_bulk, "BULK"); 357 #undef SETUP_TRANSFER_LIST 279 358 280 transfer_list_set_next(&instance->transfers_interrupt, 359 281 &instance->transfers_isochronous); … … 370 292 371 293 return EOK; 294 #undef CHECK_RET_CLEAR_RETURN 372 295 } 373 296 /*----------------------------------------------------------------------------*/ … … 375 298 { 376 299 assert(instance); 377 /* Init queues */300 /* init queues */ 378 301 hc_init_transfer_lists(instance); 379 302 380 /* Init HCCA */303 /* init HCCA */ 381 304 instance->hcca = malloc32(sizeof(hcca_t)); 382 305 if (instance->hcca == NULL) 383 306 return ENOMEM; 384 307 bzero(instance->hcca, sizeof(hcca_t)); 385 usb_log_debug2("OHCI HCCA initialized at %p.\n", instance->hcca); 308 instance->registers->hcca = addr_to_phys(instance->hcca); 309 310 /* use queues */ 311 instance->registers->bulk_head = instance->transfers_bulk.list_head_pa; 312 instance->registers->control_head = 313 instance->transfers_control.list_head_pa; 386 314 387 315 unsigned i = 0; … … 390 318 instance->transfers_interrupt.list_head_pa; 391 319 } 392 usb_log_debug2("Interrupt HEADs set to: %p(%p).\n",393 instance->transfers_interrupt.list_head,394 instance->transfers_interrupt.list_head_pa);395 320 396 321 return EOK; -
uspace/drv/ohci/hc.h
r3f3afb9 r58226b4 69 69 usb_endpoint_manager_t ep_manager; 70 70 fid_t interrupt_emulator; 71 fibril_mutex_t guard;72 71 } hc_t; 73 72 -
uspace/drv/ohci/hw_struct/endpoint_descriptor.c
r3f3afb9 r58226b4 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 } … … 53 53 << ED_STATUS_MPS_SHIFT); 54 54 55 56 55 if (ep->speed == USB_SPEED_LOW) 57 56 instance->status |= ED_STATUS_S_FLAG; … … 59 58 instance->status |= ED_STATUS_F_FLAG; 60 59 61 if (ep->toggle)62 instance->td_head |= ED_TDHEAD_TOGGLE_CARRY;63 60 } 61 64 62 /** 65 63 * @} -
uspace/drv/ohci/hw_struct/endpoint_descriptor.h
r3f3afb9 r58226b4 53 53 #define ED_STATUS_D_MASK (0x3) /* direction */ 54 54 #define ED_STATUS_D_SHIFT (11) 55 #define ED_STATUS_D_ OUT(0x1)56 #define ED_STATUS_D_ IN(0x2)55 #define ED_STATUS_D_IN (0x1) 56 #define ED_STATUS_D_OUT (0x2) 57 57 #define ED_STATUS_D_TRANSFER (0x3) 58 58 … … 84 84 { 85 85 assert(instance); 86 instance->td_head = 87 ((addr_to_phys(head) & ED_TDHEAD_PTR_MASK) 88 | (instance->td_head & ~ED_TDHEAD_PTR_MASK)); 86 instance->td_head = addr_to_phys(head) & ED_TDHEAD_PTR_MASK; 89 87 instance->td_tail = addr_to_phys(tail) & ED_TDTAIL_PTR_MASK; 90 88 } … … 98 96 instance->next = pa; 99 97 } 98 100 99 #endif 101 100 /** -
uspace/drv/ohci/hw_struct/hcca.h
r3f3afb9 r58226b4 43 43 uint32_t done_head; 44 44 uint32_t reserved[29]; 45 } __attribute__((packed , aligned)) hcca_t;45 } __attribute__((packed)) hcca_t; 46 46 47 47 #endif -
uspace/drv/ohci/hw_struct/transfer_descriptor.c
r3f3afb9 r58226b4 53 53 } 54 54 if (buffer != NULL) { 55 assert(size != 0);56 55 instance->cbp = addr_to_phys(buffer); 57 56 instance->be = addr_to_phys(buffer + size - 1); -
uspace/drv/ohci/hw_struct/transfer_descriptor.h
r3f3afb9 r58226b4 50 50 #define TD_STATUS_DP_SHIFT (19) 51 51 #define TD_STATUS_DP_SETUP (0x0) 52 #define TD_STATUS_DP_ OUT(0x1)53 #define TD_STATUS_DP_ IN(0x2)52 #define TD_STATUS_DP_IN (0x1) 53 #define TD_STATUS_DP_OUT (0x2) 54 54 #define TD_STATUS_DI_MASK (0x7) /* delay interrupt, wait DI frames before int */ 55 55 #define TD_STATUS_DI_SHIFT (21) … … 86 86 int cc = (instance->status >> TD_STATUS_CC_SHIFT) & TD_STATUS_CC_MASK; 87 87 /* something went wrong, error code is set */ 88 if (cc != CC_NOACCESS1 && cc != CC_NOACCESS2 ) {88 if (cc != CC_NOACCESS1 && cc != CC_NOACCESS2 && cc != CC_NOERROR) { 89 89 return true; 90 90 } -
uspace/drv/ohci/iface.c
r3f3afb9 r58226b4 63 63 } 64 64 65 usb_log_debug("%s %d:%d %zu(%zu).\n",66 name, target.address, target.endpoint, size, ep->max_packet_size);67 68 65 const size_t bw = bandwidth_count_usb11( 69 66 ep->speed, ep->transfer_type, size, ep->max_packet_size); … … 71 68 usb_log_error("Endpoint(%d:%d) %s needs %zu bw " 72 69 "but only %zu is reserved.\n", 73 target.address, target.endpoint, name, bw, res_bw);70 name, target.address, target.endpoint, bw, res_bw); 74 71 return ENOSPC; 75 72 } 76 77 *batch = batch_get( 78 fun, ep, data, size, setup_data, setup_size, in, out, arg); 79 if (!*batch) 73 usb_log_debug("%s %d:%d %zu(%zu).\n", 74 name, target.address, target.endpoint, size, ep->max_packet_size); 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) 80 85 return ENOMEM; 86 return EOK; 87 } 88 89 90 /** Reserve default address interface function 91 * 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 0 105 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 #endif 123 } 124 /*----------------------------------------------------------------------------*/ 125 /** Release default address interface function 126 * 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); 81 139 return EOK; 82 140 } … … 158 216 hc_t *hc = fun_to_hc(fun); 159 217 assert(hc); 160 218 if (address == hc->rh.address) 219 return EOK; 161 220 usb_speed_t speed = usb_device_keeper_get_speed(&hc->manager, address); 162 221 if (speed >= USB_SPEED_MAX) { 163 222 speed = ep_speed; 164 223 } 165 const size_t size = max_packet_size; 224 const size_t size = 225 (transfer_type == USB_TRANSFER_INTERRUPT 226 || transfer_type == USB_TRANSFER_ISOCHRONOUS) ? 227 max_packet_size : 0; 166 228 int ret; 167 168 usb_log_debug("Register endpoint %d:%d %s %s(%d) %zu(%zu) %u.\n",169 address, endpoint, usb_str_transfer_type(transfer_type),170 usb_str_speed(speed), direction, size, max_packet_size, interval);171 229 172 230 endpoint_t *ep = malloc(sizeof(endpoint_t)); … … 180 238 } 181 239 240 usb_log_debug("Register endpoint %d:%d %s %s(%d) %zu(%zu) %u.\n", 241 address, endpoint, usb_str_transfer_type(transfer_type), 242 usb_str_speed(speed), direction, size, max_packet_size, interval); 243 182 244 ret = usb_endpoint_manager_register_ep(&hc->ep_manager, ep, size); 183 245 if (ret != EOK) { 184 246 endpoint_destroy(ep); 247 } else { 248 usb_device_keeper_add_ep(&hc->manager, address, ep); 185 249 } 186 250 return ret; … … 195 259 usb_log_debug("Unregister endpoint %d:%d %d.\n", 196 260 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 } 197 266 return usb_endpoint_manager_unregister_ep(&hc->ep_manager, address, 198 267 endpoint, direction); … … 366 435 if (ret != EOK) 367 436 return ret; 368 usb_ endpoint_manager_reset_if_need(&hc->ep_manager, target, setup_data);437 usb_device_keeper_reset_if_need(&hc->manager, target, setup_data); 369 438 batch_control_write(batch); 370 439 ret = hc_schedule(hc, batch); … … 415 484 /*----------------------------------------------------------------------------*/ 416 485 usbhc_iface_t hc_iface = { 486 .reserve_default_address = reserve_default_address, 487 .release_default_address = release_default_address, 417 488 .request_address = request_address, 418 489 .bind_address = bind_address, -
uspace/drv/ohci/ohci.ma
r3f3afb9 r58226b4 1 1 10 pci/ven=106b&dev=003f 2 10 pci/ven=10de&dev=0aa53 10 pci/ven=10de&dev=0aa5 -
uspace/drv/ohci/ohci_regs.h
r3f3afb9 r58226b4 84 84 /** Interupt enable/disable, reads give the same value, writing causes 85 85 * enable/disable */ 86 volatile uint32_t inter rupt_enable;86 volatile uint32_t interupt_enable; 87 87 volatile uint32_t interrupt_disable; 88 88 #define I_SO (1 << 0) /* Scheduling overrun */ … … 100 100 #define HCCA_PTR_MASK 0xffffff00 /* HCCA is 256B aligned */ 101 101 102 /** Currently executed period icendpoint */103 const volatile uint32_t period ic_current;102 /** Currently executed period endpoint */ 103 const volatile uint32_t period_current; 104 104 105 105 /** The first control endpoint */ … … 120 120 /** Frame time and max packet size for all transfers */ 121 121 volatile uint32_t fm_interval; 122 #define FMI_FI_MASK (0x 3fff) /* Frame interval in bit times (should be 11999)*/122 #define FMI_FI_MASK (0x1fff) /* 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 3fff) /* bit time when periodic get priority (0x3e67) */140 #define PS_PS_MASK (0x1fff) /* bit time when periodic get priority (0x3e67) */ 141 141 142 142 /** Threshold for starting LS transaction */ -
uspace/drv/ohci/root_hub.c
r3f3afb9 r58226b4 210 210 instance->registers = regs; 211 211 instance->device = dev; 212 instance->port_count = 213 (instance->registers->rh_desc_a >> RHDA_NDS_SHIFT) & RHDA_NDS_MASK; 212 instance->port_count = instance->registers->rh_desc_a & 0xff; 214 213 rh_init_descriptors(instance); 215 214 // set port power mode to no-power-switching -
uspace/drv/ohci/transfer_list.c
r3f3afb9 r58226b4 79 79 assert(instance); 80 80 assert(next); 81 /* Set both queue_head.next to point to the follower */ 81 82 ed_append_ed(instance->list_head, next->list_head); 82 83 } … … 121 122 usb_transfer_batch_t *first = list_get_instance( 122 123 instance->batch_list.next, usb_transfer_batch_t, link); 123 usb_log_debug("Batch(%p) added to list %s, first is %p(%p).\n", 124 batch, instance->name, first, batch_ed(first)); 125 if (last_ed == instance->list_head) { 126 usb_log_debug2("%s head ED(%p-%p): %x:%x:%x:%x.\n", 127 instance->name, last_ed, instance->list_head_pa, 128 last_ed->status, last_ed->td_tail, last_ed->td_head, 129 last_ed->next); 130 } 124 usb_log_debug("Batch(%p) added to queue %s, first is %p.\n", 125 batch, instance->name, first); 131 126 fibril_mutex_unlock(&instance->guard); 132 127 } … … 143 138 144 139 fibril_mutex_lock(&instance->guard); 145 usb_log_debug2("Checking list %s for completed batches(%d).\n",146 instance->name, list_count(&instance->batch_list));147 140 link_t *current = instance->batch_list.next; 148 141 while (current != &instance->batch_list) { -
uspace/drv/ohci/utils/malloc32.h
r3f3afb9 r58226b4 41 41 #include <as.h> 42 42 43 #define UHCI_STRCUTURES_ALIGNMENT 16 43 44 #define UHCI_REQUIRED_PAGE_SIZE 4096 44 45 … … 64 65 */ 65 66 static inline void * malloc32(size_t size) 66 { return memalign( size, size); }67 { return memalign(UHCI_STRCUTURES_ALIGNMENT, size); } 67 68 /*----------------------------------------------------------------------------*/ 68 69 /** Physical mallocator simulator -
uspace/drv/uhci-hcd/iface.c
r3f3afb9 r58226b4 63 63 } 64 64 65 usb_log_debug("%s %d:%d %zu(%zu).\n",66 name, target.address, target.endpoint, size, ep->max_packet_size);67 68 65 const size_t bw = bandwidth_count_usb11( 69 66 ep->speed, ep->transfer_type, size, ep->max_packet_size); … … 71 68 usb_log_error("Endpoint(%d:%d) %s needs %zu bw " 72 69 "but only %zu is reserved.\n", 73 target.address, target.endpoint, name, bw, res_bw);70 name, target.address, target.endpoint, bw, res_bw); 74 71 return ENOSPC; 75 72 } 76 77 *batch = batch_get( 78 fun, ep, data, size, setup_data, setup_size, in, out, arg); 79 if (!*batch) 73 usb_log_debug("%s %d:%d %zu(%zu).\n", 74 name, target.address, target.endpoint, size, ep->max_packet_size); 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) 80 85 return ENOMEM; 86 return EOK; 87 } 88 89 90 /** Reserve default address interface function 91 * 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 0 105 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 #endif 123 } 124 /*----------------------------------------------------------------------------*/ 125 /** Release default address interface function 126 * 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); 81 139 return EOK; 82 140 } … … 147 205 hc_t *hc = fun_to_hc(fun); 148 206 assert(hc); 149 const size_t size = max_packet_size;150 int ret;151 207 usb_speed_t speed = usb_device_keeper_get_speed(&hc->manager, address); 152 208 if (speed >= USB_SPEED_MAX) { 153 209 speed = ep_speed; 154 210 } 155 usb_log_debug("Register endpoint %d:%d %s %s(%d) %zu(%zu) %u.\n", 156 address, endpoint, usb_str_transfer_type(transfer_type), 157 usb_str_speed(speed), direction, size, max_packet_size, interval); 158 211 const size_t size = 212 (transfer_type == USB_TRANSFER_INTERRUPT 213 || transfer_type == USB_TRANSFER_ISOCHRONOUS) ? 214 max_packet_size : 0; 215 int ret; 159 216 160 217 endpoint_t *ep = malloc(sizeof(endpoint_t)); … … 168 225 } 169 226 227 usb_log_debug("Register endpoint %d:%d %s %s(%d) %zu(%zu) %u.\n", 228 address, endpoint, usb_str_transfer_type(transfer_type), 229 usb_str_speed(speed), direction, size, max_packet_size, interval); 230 170 231 ret = usb_endpoint_manager_register_ep(&hc->ep_manager, ep, size); 171 232 if (ret != EOK) { 172 233 endpoint_destroy(ep); 234 } else { 235 usb_device_keeper_add_ep(&hc->manager, address, ep); 173 236 } 174 237 return ret; … … 183 246 usb_log_debug("Unregister endpoint %d:%d %d.\n", 184 247 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 } 185 253 return usb_endpoint_manager_unregister_ep(&hc->ep_manager, address, 186 254 endpoint, direction); … … 323 391 if (ret != EOK) 324 392 return ret; 325 usb_ endpoint_manager_reset_if_need(&hc->ep_manager, target, setup_data);393 usb_device_keeper_reset_if_need(&hc->manager, target, setup_data); 326 394 batch_control_write(batch); 327 395 ret = hc_schedule(hc, batch); … … 365 433 /*----------------------------------------------------------------------------*/ 366 434 usbhc_iface_t hc_iface = { 435 .reserve_default_address = reserve_default_address, 436 .release_default_address = release_default_address, 367 437 .request_address = request_address, 368 438 .bind_address = bind_address, -
uspace/drv/usbhid/Makefile
r3f3afb9 r58226b4 40 40 main.c \ 41 41 usbhid.c \ 42 subdrivers.c \43 42 kbd/conv.c \ 44 43 kbd/kbddev.c \ 45 44 kbd/kbdrepeat.c \ 46 45 generic/hiddev.c \ 47 mouse/mousedev.c \48 46 $(STOLEN_LAYOUT_SOURCES) 49 47 -
uspace/drv/usbhid/generic/hiddev.c
r3f3afb9 r58226b4 39 39 40 40 #include "hiddev.h" 41 #include "usbhid.h"42 41 43 42 /*----------------------------------------------------------------------------*/ … … 55 54 /*----------------------------------------------------------------------------*/ 56 55 57 bool usb_ generic_hid_polling_callback(usb_hid_dev_t *hid_dev,58 uint8_t *buffer, size_t buffer_size)56 bool usb_hid_polling_callback(usb_device_t *dev, uint8_t *buffer, 57 size_t buffer_size, void *arg) 59 58 { 60 usb_log_debug("usb_hid_polling_callback(%p, %p, %zu)\n", 61 hid_dev, buffer, buffer_size); 59 usb_log_debug("usb_hid_polling_callback()\n"); 62 60 usb_debug_str_buffer(buffer, buffer_size, 0); 63 61 return true; -
uspace/drv/usbhid/generic/hiddev.h
r3f3afb9 r58226b4 34 34 */ 35 35 36 #ifndef USB_HID _HIDDDEV_H_37 #define USB_HID _HIDDDEV_H_36 #ifndef USB_HIDD_H_ 37 #define USB_HIDD_H_ 38 38 39 39 #include <usb/devdrv.h> 40 41 struct usb_hid_dev;42 40 43 41 usb_endpoint_description_t usb_hid_generic_poll_endpoint_description; … … 46 44 const char *HID_GENERIC_CLASS_NAME; 47 45 48 bool usb_ generic_hid_polling_callback(struct usb_hid_dev *hid_dev,49 uint8_t *buffer, size_t buffer_size);46 bool usb_hid_polling_callback(usb_device_t *dev, uint8_t *buffer, 47 size_t buffer_size, void *arg); 50 48 51 #endif // USB_HID _HIDDDEV_H_49 #endif // USB_HIDD_H_ 52 50 53 51 /** -
uspace/drv/usbhid/kbd/conv.h
r3f3afb9 r58226b4 34 34 */ 35 35 36 #ifndef USB_ HID_CONV_H_37 #define USB_ HID_CONV_H_36 #ifndef USB_KBD_CONV_H_ 37 #define USB_KBD_CONV_H_ 38 38 39 39 unsigned int usbhid_parse_scancode(int scancode); 40 40 41 #endif /* USB_ HID_CONV_H_ */41 #endif /* USB_KBD_CONV_H_ */ 42 42 43 43 /** -
uspace/drv/usbhid/kbd/kbddev.c
r3f3afb9 r58226b4 238 238 * @param icall Call data. 239 239 */ 240 staticvoid default_connection_handler(ddf_fun_t *fun,240 void default_connection_handler(ddf_fun_t *fun, 241 241 ipc_callid_t icallid, ipc_call_t *icall) 242 242 { … … 856 856 /*----------------------------------------------------------------------------*/ 857 857 858 bool usb_kbd_polling_callback(usb_ hid_dev_t *hid_dev, uint8_t *buffer,859 size_t buffer_size )860 { 861 if ( hid_dev == NULL || buffer== NULL) {858 bool usb_kbd_polling_callback(usb_device_t *dev, uint8_t *buffer, 859 size_t buffer_size, void *arg) 860 { 861 if (dev == NULL || buffer == NULL || arg == NULL) { 862 862 // do not continue polling (???) 863 863 return false; 864 864 } 865 866 usb_hid_dev_t *hid_dev = (usb_hid_dev_t *)arg; 865 867 866 868 // TODO: add return value from this function … … 914 916 /*----------------------------------------------------------------------------*/ 915 917 916 void usb_kbd_deinit( usb_hid_dev_t *hid_dev)918 void usb_kbd_deinit(struct usb_hid_dev_t *hid_dev) 917 919 { 918 920 if (hid_dev == NULL) { -
uspace/drv/usbhid/kbd/kbddev.h
r3f3afb9 r58226b4 34 34 */ 35 35 36 #ifndef USB_ HID_KBDDEV_H_37 #define USB_ HID_KBDDEV_H_36 #ifndef USB_KBDDEV_H_ 37 #define USB_KBDDEV_H_ 38 38 39 39 #include <stdint.h> … … 49 49 #include "kbdrepeat.h" 50 50 51 struct usb_hid_dev ;51 struct usb_hid_dev_t; 52 52 53 53 /*----------------------------------------------------------------------------*/ … … 65 65 */ 66 66 typedef struct usb_kbd_t { 67 /** Structure holding generic USB device information. */ 68 //usbhid_dev_t *hid_dev; 69 //usb_device_t *usb_dev; 70 67 71 /** Currently pressed keys (not translated to key codes). */ 68 72 uint8_t *keys; … … 87 91 fibril_mutex_t *repeat_mtx; 88 92 93 /** Report descriptor. */ 94 //uint8_t *report_desc; 95 96 /** Report descriptor size. */ 97 //size_t report_desc_size; 98 89 99 uint8_t *output_buffer; 90 100 … … 96 106 97 107 int32_t *led_data; 108 109 /** HID Report parser. */ 110 //usb_hid_report_parser_t *parser; 98 111 99 112 /** State of the structure (for checking before use). … … 108 121 /*----------------------------------------------------------------------------*/ 109 122 123 //enum { 124 // USB_KBD_POLL_EP_NO = 0, 125 // USB_HID_POLL_EP_NO = 1, 126 // USB_KBD_POLL_EP_COUNT = 2 127 //}; 128 129 //usb_endpoint_description_t *usb_kbd_endpoints[USB_KBD_POLL_EP_COUNT + 1]; 130 131 //ddf_dev_ops_t keyboard_ops; 132 110 133 usb_endpoint_description_t usb_hid_kbd_poll_endpoint_description; 111 134 … … 115 138 /*----------------------------------------------------------------------------*/ 116 139 117 int usb_kbd_init(struct usb_hid_dev *hid_dev);140 //usb_kbd_t *usb_kbd_new(void); 118 141 119 bool usb_kbd_polling_callback(struct usb_hid_dev *hid_dev, uint8_t *buffer, 120 size_t buffer_size); 142 int usb_kbd_init(struct usb_hid_dev_t *hid_dev); 143 144 bool usb_kbd_polling_callback(usb_device_t *dev, uint8_t *buffer, 145 size_t buffer_size, void *arg); 146 147 //void usb_kbd_polling_ended_callback(usb_device_t *dev, bool reason, 148 // void *arg); 121 149 122 150 int usb_kbd_is_initialized(const usb_kbd_t *kbd_dev); … … 126 154 void usb_kbd_free(usb_kbd_t **kbd_dev); 127 155 128 void usb_kbd_push_ev(struct usb_hid_dev *hid_dev, usb_kbd_t *kbd_dev,156 void usb_kbd_push_ev(struct usb_hid_dev_t *hid_dev, usb_kbd_t *kbd_dev, 129 157 int type, unsigned int key); 130 158 131 void usb_kbd_deinit(struct usb_hid_dev *hid_dev);132 159 133 int usb_kbd_set_boot_protocol(struct usb_hid_dev*hid_dev);160 void usb_kbd_deinit(struct usb_hid_dev_t *hid_dev); 134 161 135 #endif /* USB_HID_KBDDEV_H_ */ 162 int usb_kbd_set_boot_protocol(struct usb_hid_dev_t *hid_dev); 163 164 #endif /* USB_KBDDEV_H_ */ 136 165 137 166 /** -
uspace/drv/usbhid/kbd/kbdrepeat.h
r3f3afb9 r58226b4 34 34 */ 35 35 36 #ifndef USB_ HID_KBDREPEAT_H_37 #define USB_ HID_KBDREPEAT_H_36 #ifndef USB_KBDREPEAT_H_ 37 #define USB_KBDREPEAT_H_ 38 38 39 39 struct usb_kbd_t; … … 62 62 void usb_kbd_repeat_stop(struct usb_kbd_t *kbd, unsigned int key); 63 63 64 #endif /* USB_ HID_KBDREPEAT_H_ */64 #endif /* USB_KBDREPEAT_H_ */ 65 65 66 66 /** -
uspace/drv/usbhid/layout.h
r3f3afb9 r58226b4 36 36 */ 37 37 38 #ifndef USB_ HID_LAYOUT_H_39 #define USB_ HID_LAYOUT_H_38 #ifndef USB_KBD_LAYOUT_H_ 39 #define USB_KBD_LAYOUT_H_ 40 40 41 41 #include <sys/types.h> -
uspace/drv/usbhid/main.c
r3f3afb9 r58226b4 98 98 /* Create the function exposed under /dev/devices. */ 99 99 ddf_fun_t *hid_fun = ddf_fun_create(dev->ddf_dev, fun_exposed, 100 usb_hid_get_function_name(hid_dev ));100 usb_hid_get_function_name(hid_dev->device_type)); 101 101 if (hid_fun == NULL) { 102 102 usb_log_error("Could not create DDF function node.\n"); … … 122 122 } 123 123 124 rc = ddf_fun_add_to_class(hid_fun, usb_hid_get_class_name(hid_dev)); 124 rc = ddf_fun_add_to_class(hid_fun, 125 usb_hid_get_class_name(hid_dev->device_type)); 125 126 if (rc != EOK) { 126 127 usb_log_error( … … 141 142 hid_dev->poll_pipe_index, 142 143 /* Callback when data arrives. */ 143 usb_hid_polling_callback,144 hid_dev->poll_callback, 144 145 /* How much data to request. */ 145 146 dev->pipes[hid_dev->poll_pipe_index].pipe->max_packet_size, -
uspace/drv/usbhid/usbhid.c
r3f3afb9 r58226b4 42 42 #include <usb/classes/hidreq.h> 43 43 #include <errno.h> 44 #include <str_error.h>45 44 46 45 #include "usbhid.h" … … 48 47 #include "kbd/kbddev.h" 49 48 #include "generic/hiddev.h" 50 #include "mouse/mousedev.h" 51 #include "subdrivers.h" 52 53 /*----------------------------------------------------------------------------*/ 49 50 /*----------------------------------------------------------------------------*/ 51 52 /** Mouse polling endpoint description for boot protocol class. */ 53 static usb_endpoint_description_t usb_hid_mouse_poll_endpoint_description = { 54 .transfer_type = USB_TRANSFER_INTERRUPT, 55 .direction = USB_DIRECTION_IN, 56 .interface_class = USB_CLASS_HID, 57 .interface_subclass = USB_HID_SUBCLASS_BOOT, 58 .interface_protocol = USB_HID_PROTOCOL_MOUSE, 59 .flags = 0 60 }; 54 61 55 62 /* Array of endpoints expected on the device, NULL terminated. */ … … 61 68 }; 62 69 63 static const int USB_HID_MAX_SUBDRIVERS = 10; 64 65 /*----------------------------------------------------------------------------*/ 66 67 static int usb_hid_set_boot_kbd_subdriver(usb_hid_dev_t *hid_dev) 68 { 69 assert(hid_dev->subdriver_count == 0); 70 71 hid_dev->subdrivers = (usb_hid_subdriver_t *)malloc( 72 sizeof(usb_hid_subdriver_t)); 73 if (hid_dev->subdrivers == NULL) { 74 return ENOMEM; 75 } 76 77 // set the init callback 78 hid_dev->subdrivers[0].init = usb_kbd_init; 79 80 // set the polling callback 81 hid_dev->subdrivers[0].poll = usb_kbd_polling_callback; 82 83 // set the polling ended callback 84 hid_dev->subdrivers[0].poll_end = NULL; 85 86 // set the deinit callback 87 hid_dev->subdrivers[0].deinit = usb_kbd_deinit; 88 89 // set subdriver count 90 hid_dev->subdriver_count = 1; 91 92 return EOK; 93 } 94 95 /*----------------------------------------------------------------------------*/ 96 97 static int usb_hid_set_boot_mouse_subdriver(usb_hid_dev_t *hid_dev) 98 { 99 assert(hid_dev->subdriver_count == 0); 100 101 hid_dev->subdrivers = (usb_hid_subdriver_t *)malloc( 102 sizeof(usb_hid_subdriver_t)); 103 if (hid_dev->subdrivers == NULL) { 104 return ENOMEM; 105 } 106 107 // set the init callback 108 hid_dev->subdrivers[0].init = usb_mouse_init; 109 110 // set the polling callback 111 hid_dev->subdrivers[0].poll = usb_mouse_polling_callback; 112 113 // set the polling ended callback 114 hid_dev->subdrivers[0].poll_end = NULL; 115 116 // set the deinit callback 117 hid_dev->subdrivers[0].deinit = usb_mouse_deinit; 118 119 // set subdriver count 120 hid_dev->subdriver_count = 1; 121 122 return EOK; 123 } 124 125 /*----------------------------------------------------------------------------*/ 126 127 static int usb_hid_set_generic_hid_subdriver(usb_hid_dev_t *hid_dev) 128 { 129 assert(hid_dev->subdriver_count == 0); 130 131 hid_dev->subdrivers = (usb_hid_subdriver_t *)malloc( 132 sizeof(usb_hid_subdriver_t)); 133 if (hid_dev->subdrivers == NULL) { 134 return ENOMEM; 135 } 136 137 // set the init callback 138 hid_dev->subdrivers[0].init = NULL; 139 140 // set the polling callback 141 hid_dev->subdrivers[0].poll = usb_generic_hid_polling_callback; 142 143 // set the polling ended callback 144 hid_dev->subdrivers[0].poll_end = NULL; 145 146 // set the deinit callback 147 hid_dev->subdrivers[0].deinit = NULL; 148 149 // set subdriver count 150 hid_dev->subdriver_count = 1; 151 152 return EOK; 153 } 154 155 /*----------------------------------------------------------------------------*/ 156 157 static bool usb_hid_ids_match(usb_hid_dev_t *hid_dev, 158 const usb_hid_subdriver_mapping_t *mapping) 159 { 160 return false; 161 } 162 163 /*----------------------------------------------------------------------------*/ 164 165 static bool usb_hid_path_matches(usb_hid_dev_t *hid_dev, 166 const usb_hid_subdriver_usage_t *path, int path_size, int compare) 167 { 168 assert(hid_dev != NULL); 169 assert(path != NULL); 170 171 usb_hid_report_path_t *usage_path = usb_hid_report_path(); 172 if (usage_path == NULL) { 173 usb_log_debug("Failed to create usage path.\n"); 174 return false; 175 } 176 int i; 177 for (i = 0; i < path_size; ++i) { 178 if (usb_hid_report_path_append_item(usage_path, 179 path[i].usage_page, path[i].usage) != EOK) { 180 usb_log_debug("Failed to append to usage path.\n"); 181 usb_hid_report_path_free(usage_path); 182 return false; 183 } 184 } 185 186 assert(hid_dev->parser != NULL); 187 188 usb_log_debug("Compare flags: %d\n", compare); 189 size_t size = usb_hid_report_input_length(hid_dev->parser, usage_path, 190 compare); 191 usb_log_debug("Size of the input report: %d\n", size); 192 193 usb_hid_report_path_free(usage_path); 194 195 return (size > 0); 196 } 197 198 /*----------------------------------------------------------------------------*/ 199 200 static int usb_hid_save_subdrivers(usb_hid_dev_t *hid_dev, 201 const usb_hid_subdriver_t **subdrivers, int count) 202 { 203 int i; 204 205 if (count <= 0) { 206 hid_dev->subdriver_count = 0; 207 hid_dev->subdrivers = NULL; 208 return EOK; 209 } 210 211 hid_dev->subdrivers = (usb_hid_subdriver_t *)malloc(count * 212 sizeof(usb_hid_subdriver_t)); 213 if (hid_dev->subdrivers == NULL) { 214 return ENOMEM; 215 } 216 217 for (i = 0; i < count; ++i) { 218 hid_dev->subdrivers[i].init = subdrivers[i]->init; 219 hid_dev->subdrivers[i].deinit = subdrivers[i]->deinit; 220 hid_dev->subdrivers[i].poll = subdrivers[i]->poll; 221 hid_dev->subdrivers[i].poll_end = subdrivers[i]->poll_end; 222 } 223 224 hid_dev->subdriver_count = count; 225 226 return EOK; 227 } 228 229 /*----------------------------------------------------------------------------*/ 230 231 static int usb_hid_find_subdrivers(usb_hid_dev_t *hid_dev) 232 { 233 const usb_hid_subdriver_t *subdrivers[USB_HID_MAX_SUBDRIVERS]; 234 235 int i = 0, count = 0; 236 const usb_hid_subdriver_mapping_t *mapping = &usb_hid_subdrivers[i]; 237 238 while (count < USB_HID_MAX_SUBDRIVERS && 239 (mapping->usage_path != NULL 240 || mapping->vendor_id != NULL 241 || mapping->product_id != NULL)) { 242 // check the vendor & product ID 243 if (mapping->vendor_id != NULL && mapping->product_id == NULL) { 244 usb_log_warning("Missing Product ID for Vendor ID %s\n", 245 mapping->vendor_id); 246 return EINVAL; 247 } 248 if (mapping->product_id != NULL && mapping->vendor_id == NULL) { 249 usb_log_warning("Missing Vendor ID for Product ID %s\n", 250 mapping->product_id); 251 return EINVAL; 252 } 253 254 if (mapping->vendor_id != NULL) { 255 assert(mapping->product_id != NULL); 256 usb_log_debug("Comparing device against vendor ID %s" 257 " and product ID %s.\n", mapping->vendor_id, 258 mapping->product_id); 259 if (usb_hid_ids_match(hid_dev, mapping)) { 260 usb_log_debug("Matched.\n"); 261 subdrivers[count++] = &mapping->subdriver; 262 // skip the checking of usage path 263 goto next; 264 } 265 } 266 267 if (mapping->usage_path != NULL) { 268 usb_log_debug("Comparing device against usage path.\n"); 269 if (usb_hid_path_matches(hid_dev, 270 mapping->usage_path, mapping->path_size, 271 mapping->compare)) { 272 subdrivers[count++] = &mapping->subdriver; 273 } else { 274 usb_log_debug("Not matched.\n"); 275 } 276 } 277 next: 278 mapping = &usb_hid_subdrivers[++i]; 279 } 280 281 // we have all subdrivers determined, save them into the hid device 282 return usb_hid_save_subdrivers(hid_dev, subdrivers, count); 283 } 284 285 /*----------------------------------------------------------------------------*/ 286 287 static int usb_hid_check_pipes(usb_hid_dev_t *hid_dev, usb_device_t *dev) 288 { 289 int rc = EOK; 290 291 if (dev->pipes[USB_HID_KBD_POLL_EP_NO].present) { 292 usb_log_debug("Found keyboard endpoint.\n"); 293 // save the pipe index 294 hid_dev->poll_pipe_index = USB_HID_KBD_POLL_EP_NO; 295 } else if (dev->pipes[USB_HID_MOUSE_POLL_EP_NO].present) { 296 usb_log_debug("Found mouse endpoint.\n"); 297 // save the pipe index 298 hid_dev->poll_pipe_index = USB_HID_MOUSE_POLL_EP_NO; 299 } else if (dev->pipes[USB_HID_GENERIC_POLL_EP_NO].present) { 300 usb_log_debug("Found generic HID endpoint.\n"); 301 // save the pipe index 302 hid_dev->poll_pipe_index = USB_HID_GENERIC_POLL_EP_NO; 303 } else { 304 usb_log_error("None of supported endpoints found - probably" 305 " not a supported device.\n"); 306 rc = ENOTSUP; 307 } 308 309 return rc; 310 } 70 static const char *HID_MOUSE_FUN_NAME = "mouse"; 71 static const char *HID_MOUSE_CLASS_NAME = "mouse"; 311 72 312 73 /*----------------------------------------------------------------------------*/ … … 330 91 } 331 92 332 hid_dev->poll_pipe_index = -1;333 334 93 return hid_dev; 335 94 } … … 337 96 /*----------------------------------------------------------------------------*/ 338 97 98 static bool usb_dummy_polling_callback(usb_device_t *dev, uint8_t *buffer, 99 size_t buffer_size, void *arg) 100 { 101 usb_log_debug("Dummy polling callback.\n"); 102 return false; 103 } 104 105 /*----------------------------------------------------------------------------*/ 106 107 static int usb_hid_check_pipes(usb_hid_dev_t *hid_dev, usb_device_t *dev) 108 { 109 if (dev->pipes[USB_HID_KBD_POLL_EP_NO].present) { 110 usb_log_debug("Found keyboard endpoint.\n"); 111 112 // save the pipe index and device type 113 hid_dev->poll_pipe_index = USB_HID_KBD_POLL_EP_NO; 114 hid_dev->device_type = USB_HID_PROTOCOL_KEYBOARD; 115 116 // set the polling callback 117 hid_dev->poll_callback = usb_kbd_polling_callback; 118 119 } else if (dev->pipes[USB_HID_MOUSE_POLL_EP_NO].present) { 120 usb_log_debug("Found mouse endpoint.\n"); 121 122 // save the pipe index and device type 123 hid_dev->poll_pipe_index = USB_HID_MOUSE_POLL_EP_NO; 124 hid_dev->device_type = USB_HID_PROTOCOL_MOUSE; 125 126 // set the polling callback 127 hid_dev->poll_callback = usb_dummy_polling_callback; 128 129 } else if (dev->pipes[USB_HID_GENERIC_POLL_EP_NO].present) { 130 usb_log_debug("Found generic HID endpoint.\n"); 131 132 // save the pipe index and device type 133 hid_dev->poll_pipe_index = USB_HID_GENERIC_POLL_EP_NO; 134 hid_dev->device_type = USB_HID_PROTOCOL_NONE; 135 136 // set the polling callback 137 hid_dev->poll_callback = usb_hid_polling_callback; 138 139 } else { 140 usb_log_warning("None of supported endpoints found - probably" 141 " not a supported device.\n"); 142 return ENOTSUP; 143 } 144 145 return EOK; 146 } 147 148 /*----------------------------------------------------------------------------*/ 149 150 static int usb_hid_init_parser(usb_hid_dev_t *hid_dev) 151 { 152 /* Initialize the report parser. */ 153 int rc = usb_hid_parser_init(hid_dev->parser); 154 if (rc != EOK) { 155 usb_log_error("Failed to initialize report parser.\n"); 156 return rc; 157 } 158 159 /* Get the report descriptor and parse it. */ 160 rc = usb_hid_process_report_descriptor(hid_dev->usb_dev, 161 hid_dev->parser); 162 163 if (rc != EOK) { 164 usb_log_warning("Could not process report descriptor.\n"); 165 166 if (hid_dev->device_type == USB_HID_PROTOCOL_KEYBOARD) { 167 usb_log_warning("Falling back to boot protocol.\n"); 168 169 rc = usb_kbd_set_boot_protocol(hid_dev); 170 171 } else if (hid_dev->device_type == USB_HID_PROTOCOL_MOUSE) { 172 usb_log_warning("No boot protocol for mouse yet.\n"); 173 rc = ENOTSUP; 174 } 175 } 176 177 return rc; 178 } 179 180 /*----------------------------------------------------------------------------*/ 181 339 182 int usb_hid_init(usb_hid_dev_t *hid_dev, usb_device_t *dev) 340 183 { 341 int rc , i;184 int rc; 342 185 343 186 usb_log_debug("Initializing HID structure...\n"); … … 360 203 rc = usb_hid_check_pipes(hid_dev, dev); 361 204 if (rc != EOK) { 362 usb_hid_free(&hid_dev);363 205 return rc; 364 206 } 365 207 366 /* Initialize the report parser. */ 367 rc = usb_hid_parser_init(hid_dev->parser); 208 rc = usb_hid_init_parser(hid_dev); 368 209 if (rc != EOK) { 369 usb_log_error("Failed to initialize report parser.\n"); 370 usb_hid_free(&hid_dev); 210 usb_log_error("Failed to initialize HID parser.\n"); 371 211 return rc; 372 212 } 373 213 374 /* Get the report descriptor and parse it. */ 375 rc = usb_hid_process_report_descriptor(hid_dev->usb_dev, 376 hid_dev->parser); 377 378 bool fallback = false; 379 380 if (rc == EOK) { 381 // try to find subdrivers that may want to handle this device 382 rc = usb_hid_find_subdrivers(hid_dev); 383 if (rc != EOK || hid_dev->subdriver_count == 0) { 384 // try to fall back to the boot protocol if available 385 usb_log_info("No subdrivers found to handle this" 386 " device.\n"); 387 fallback = true; 214 switch (hid_dev->device_type) { 215 case USB_HID_PROTOCOL_KEYBOARD: 216 // initialize the keyboard structure 217 rc = usb_kbd_init(hid_dev); 218 if (rc != EOK) { 219 usb_log_warning("Failed to initialize KBD structure." 220 "\n"); 388 221 } 389 } else { 390 usb_log_error("Failed to parse Report descriptor.\n"); 391 // try to fall back to the boot protocol if available 392 fallback = true; 393 } 394 395 // TODO: remove the mouse hack 396 if (hid_dev->poll_pipe_index == USB_HID_MOUSE_POLL_EP_NO || 397 fallback) { 398 // fall back to boot protocol 399 switch (hid_dev->poll_pipe_index) { 400 case USB_HID_KBD_POLL_EP_NO: 401 usb_log_info("Falling back to kbd boot protocol.\n"); 402 rc = usb_kbd_set_boot_protocol(hid_dev); 403 if (rc == EOK) { 404 rc = usb_hid_set_boot_kbd_subdriver(hid_dev); 405 } 406 break; 407 case USB_HID_MOUSE_POLL_EP_NO: 408 usb_log_info("Falling back to mouse boot protocol.\n"); 409 rc = usb_mouse_set_boot_protocol(hid_dev); 410 if (rc == EOK) { 411 rc = usb_hid_set_boot_mouse_subdriver(hid_dev); 412 } 413 break; 414 default: 415 assert(hid_dev->poll_pipe_index 416 == USB_HID_GENERIC_POLL_EP_NO); 417 418 /* TODO: this has no meaning if the report descriptor 419 is not parsed */ 420 usb_log_info("Falling back to generic HID driver.\n"); 421 rc = usb_hid_set_generic_hid_subdriver(hid_dev); 422 } 423 } 424 425 if (rc != EOK) { 426 usb_log_error("No subdriver for handling this device could be" 427 " initialized: %s.\n", str_error(rc)); 428 usb_hid_free(&hid_dev); 429 } else { 430 bool ok = false; 431 432 usb_log_debug("Subdriver count: %d\n", 433 hid_dev->subdriver_count); 434 435 for (i = 0; i < hid_dev->subdriver_count; ++i) { 436 if (hid_dev->subdrivers[i].init != NULL) { 437 usb_log_debug("Initializing subdriver %d.\n",i); 438 rc = hid_dev->subdrivers[i].init(hid_dev); 439 if (rc != EOK) { 440 usb_log_warning("Failed to initialize" 441 " HID subdriver structure.\n"); 442 } else { 443 // at least one subdriver initialized 444 ok = true; 445 } 446 } else { 447 ok = true; 448 } 449 } 450 451 rc = (ok) ? EOK : -1; // what error to report 222 break; 223 case USB_HID_PROTOCOL_MOUSE: 224 break; 225 default: 226 // usbhid_req_set_idle(&hid_dev->usb_dev->ctrl_pipe, 227 // hid_dev->usb_dev->interface_no, 0); 228 break; 452 229 } 453 230 454 231 return rc; 455 }456 457 /*----------------------------------------------------------------------------*/458 459 bool usb_hid_polling_callback(usb_device_t *dev, uint8_t *buffer,460 size_t buffer_size, void *arg)461 {462 int i;463 464 if (dev == NULL || arg == NULL || buffer == NULL) {465 usb_log_error("Missing arguments to polling callback.\n");466 return false;467 }468 469 usb_hid_dev_t *hid_dev = (usb_hid_dev_t *)arg;470 471 bool cont = false;472 473 // continue if at least one of the subdrivers want to continue474 for (i = 0; i < hid_dev->subdriver_count; ++i) {475 if (hid_dev->subdrivers[i].poll != NULL476 && hid_dev->subdrivers[i].poll(hid_dev, buffer,477 buffer_size)) {478 cont = true;479 }480 }481 482 return cont;483 232 } 484 233 … … 488 237 void *arg) 489 238 { 490 int i;491 492 239 if (dev == NULL || arg == NULL) { 493 240 return; … … 496 243 usb_hid_dev_t *hid_dev = (usb_hid_dev_t *)arg; 497 244 498 for (i = 0; i < hid_dev->subdriver_count; ++i) {499 if (hid_dev->subdrivers[i].poll_end != NULL) {500 hid_dev->subdrivers[i].poll_end(hid_dev, reason);501 }502 }503 504 245 usb_hid_free(&hid_dev); 505 246 } … … 507 248 /*----------------------------------------------------------------------------*/ 508 249 509 const char *usb_hid_get_function_name( const usb_hid_dev_t *hid_dev)510 { 511 switch ( hid_dev->poll_pipe_index) {512 case USB_HID_ KBD_POLL_EP_NO:250 const char *usb_hid_get_function_name(usb_hid_iface_protocol_t device_type) 251 { 252 switch (device_type) { 253 case USB_HID_PROTOCOL_KEYBOARD: 513 254 return HID_KBD_FUN_NAME; 514 255 break; 515 case USB_HID_ MOUSE_POLL_EP_NO:256 case USB_HID_PROTOCOL_MOUSE: 516 257 return HID_MOUSE_FUN_NAME; 517 258 break; … … 523 264 /*----------------------------------------------------------------------------*/ 524 265 525 const char *usb_hid_get_class_name(const usb_hid_dev_t *hid_dev) 526 { 527 // this means that only boot protocol keyboards will be connected 528 // to the console; there is probably no better way to do this 529 530 switch (hid_dev->poll_pipe_index) { 531 case USB_HID_KBD_POLL_EP_NO: 266 const char *usb_hid_get_class_name(usb_hid_iface_protocol_t device_type) 267 { 268 switch (device_type) { 269 case USB_HID_PROTOCOL_KEYBOARD: 532 270 return HID_KBD_CLASS_NAME; 533 271 break; 534 case USB_HID_ MOUSE_POLL_EP_NO:272 case USB_HID_PROTOCOL_MOUSE: 535 273 return HID_MOUSE_CLASS_NAME; 536 274 break; … … 544 282 void usb_hid_free(usb_hid_dev_t **hid_dev) 545 283 { 546 int i;547 548 284 if (hid_dev == NULL || *hid_dev == NULL) { 549 285 return; 550 286 } 551 287 552 assert((*hid_dev)->subdrivers != NULL 553 || (*hid_dev)->subdriver_count == 0); 554 555 for (i = 0; i < (*hid_dev)->subdriver_count; ++i) { 556 if ((*hid_dev)->subdrivers[i].deinit != NULL) { 557 (*hid_dev)->subdrivers[i].deinit(*hid_dev); 558 } 559 } 560 561 // free the subdrivers info 562 if ((*hid_dev)->subdrivers != NULL) { 563 free((*hid_dev)->subdrivers); 288 switch ((*hid_dev)->device_type) { 289 case USB_HID_PROTOCOL_KEYBOARD: 290 usb_kbd_deinit(*hid_dev); 291 break; 292 case USB_HID_PROTOCOL_MOUSE: 293 break; 294 default: 295 break; 564 296 } 565 297 -
uspace/drv/usbhid/usbhid.h
r3f3afb9 r58226b4 34 34 */ 35 35 36 #ifndef USB_ HID_USBHID_H_37 #define USB_ HID_USBHID_H_36 #ifndef USB_USBHID_H_ 37 #define USB_USBHID_H_ 38 38 39 39 #include <stdint.h> … … 45 45 #include <usb/classes/hid.h> 46 46 47 struct usb_hid_dev;48 49 typedef int (*usb_hid_driver_init_t)(struct usb_hid_dev *);50 typedef void (*usb_hid_driver_deinit_t)(struct usb_hid_dev *);51 typedef bool (*usb_hid_driver_poll)(struct usb_hid_dev *, uint8_t *, size_t);52 typedef int (*usb_hid_driver_poll_ended)(struct usb_hid_dev *, bool reason);53 54 // TODO: add function and class name??55 typedef struct usb_hid_subdriver {56 /** Function to be called when initializing HID device. */57 usb_hid_driver_init_t init;58 /** Function to be called when destroying the HID device structure. */59 usb_hid_driver_deinit_t deinit;60 /** Function to be called when data arrives from the device. */61 usb_hid_driver_poll poll;62 /** Function to be called when polling ends. */63 usb_hid_driver_poll_ended poll_end;64 } usb_hid_subdriver_t;65 66 47 /*----------------------------------------------------------------------------*/ 67 48 /** 68 49 * Structure for holding general HID device data. 69 50 */ 70 typedef struct usb_hid_dev {51 typedef struct usb_hid_dev_t { 71 52 /** Structure holding generic USB device information. */ 72 53 usb_device_t *usb_dev; … … 78 59 int poll_pipe_index; 79 60 80 /** Subdrivers. */ 81 usb_hid_subdriver_t *subdrivers; 82 83 /** Number of subdrivers. */ 84 int subdriver_count; 61 /** Function to be called when data arrives from the device. */ 62 usb_polling_callback_t poll_callback; 85 63 86 64 /** Report descriptor. */ … … 95 73 /** Arbitrary data (e.g. a special structure for handling keyboard). */ 96 74 void *data; 75 76 /** Type of the device (keyboard, mouse, generic HID device). */ 77 usb_hid_iface_protocol_t device_type; 97 78 } usb_hid_dev_t; 98 79 … … 114 95 int usb_hid_init(usb_hid_dev_t *hid_dev, usb_device_t *dev); 115 96 116 bool usb_hid_polling_callback(usb_device_t *dev, uint8_t *buffer,117 size_t buffer_size, void *arg);118 119 97 void usb_hid_polling_ended_callback(usb_device_t *dev, bool reason, 120 98 void *arg); 121 99 122 const char *usb_hid_get_function_name( const usb_hid_dev_t *hid_dev);100 const char *usb_hid_get_function_name(usb_hid_iface_protocol_t device_type); 123 101 124 const char *usb_hid_get_class_name( const usb_hid_dev_t *hid_dev);102 const char *usb_hid_get_class_name(usb_hid_iface_protocol_t device_type); 125 103 126 104 void usb_hid_free(usb_hid_dev_t **hid_dev); 127 105 128 #endif /* USB_ HID_USBHID_H_ */106 #endif /* USB_USBHID_H_ */ 129 107 130 108 /** -
uspace/drv/usbhid/usbhid.ma
r3f3afb9 r58226b4 1 1 100 usb&interface&class=HID&subclass=0x01&protocol=0x01 2 100 0usb&interface&class=HID&subclass=0x01&protocol=0x022 100 usb&interface&class=HID&subclass=0x01&protocol=0x02 3 3 100 usb&interface&class=HID -
uspace/drv/usbhub/ports.c
r3f3afb9 r58226b4 181 181 */ 182 182 } else { 183 // TODO: is this really reason to print a warning? 184 usb_log_warning("Device removed before being registered.\n"); 185 186 /* 187 * Device was removed before port reset completed. 188 * We will announce a failed port reset to unblock the 189 * port reset callback from new device wrapper. 190 */ 191 usb_hub_port_t *the_port = hub->ports + port; 192 fibril_mutex_lock(&the_port->reset_mutex); 193 the_port->reset_completed = true; 194 the_port->reset_okay = false; 195 fibril_condvar_broadcast(&the_port->reset_cv); 196 fibril_mutex_unlock(&the_port->reset_mutex); 183 usb_log_warning("this is strange, disconnected device had " 184 "no address\n"); 185 //device was disconnected before it`s port was reset - 186 //return default address 187 usb_hub_release_default_address(hub); 197 188 } 198 189 } … … 216 207 fibril_mutex_lock(&the_port->reset_mutex); 217 208 the_port->reset_completed = true; 218 the_port->reset_okay = true;219 209 fibril_condvar_broadcast(&the_port->reset_cv); 220 210 fibril_mutex_unlock(&the_port->reset_mutex); … … 329 319 } 330 320 331 if (my_port->reset_okay) { 332 return EOK; 333 } else { 334 return ESTALL; 335 } 321 return EOK; 336 322 } 337 323 -
uspace/drv/usbhub/ports.h
r3f3afb9 r58226b4 51 51 */ 52 52 bool reset_completed; 53 /** Whether to announce the port reset as successful. */54 bool reset_okay;55 53 56 54 /** Information about attached device. */ -
uspace/drv/usbhub/usbhub.c
r3f3afb9 r58226b4 179 179 } 180 180 181 /** 182 * release default address used by given hub 183 * 184 * Also unsets hub->is_default_address_used. Convenience wrapper function. 185 * @note hub->connection MUST be open for communication 186 * @param hub hub representation 187 * @return error code 188 */ 189 int usb_hub_release_default_address(usb_hub_info_t * hub) { 190 int opResult = usb_hc_release_default_address(&hub->connection); 191 if (opResult != EOK) { 192 usb_log_error("could not release default address, errno %d\n", 193 opResult); 194 return opResult; 195 } 196 hub->is_default_address_used = false; 197 return EOK; 198 } 199 181 200 182 201 //********************************************* … … 247 266 for (port = 0; port < hub_info->port_count + 1; port++) { 248 267 usb_hub_port_init(&hub_info->ports[port]); 249 }250 for (port = 0; port < hub_info->port_count; port++) {251 268 opResult = usb_hub_set_port_feature(hub_info->control_pipe, 252 port +1, USB_HUB_FEATURE_PORT_POWER);269 port, USB_HUB_FEATURE_PORT_POWER); 253 270 if (opResult != EOK) { 254 271 usb_log_error("cannot power on port %d; %d\n", 255 port +1, opResult);272 port, opResult); 256 273 } 257 274 } -
uspace/drv/usbhub/usbhub.h
r3f3afb9 r58226b4 98 98 uint8_t *change_bitmap, size_t change_bitmap_size, void *arg); 99 99 100 int usb_hub_release_default_address(usb_hub_info_t * hub); 101 100 102 #endif 101 103 /** -
uspace/drv/vhc/connhost.c
r3f3afb9 r58226b4 324 324 } 325 325 326 static int reserve_default_address(ddf_fun_t *fun, usb_speed_t ignored) 327 { 328 usb_address_keeping_reserve_default(&addresses); 329 return EOK; 330 } 331 332 static int release_default_address(ddf_fun_t *fun) 333 { 334 usb_address_keeping_release_default(&addresses); 335 return EOK; 336 } 337 326 338 static int request_address(ddf_fun_t *fun, usb_speed_t ignored, 327 339 usb_address_t *address) … … 376 388 377 389 usbhc_iface_t vhc_iface = { 390 .reserve_default_address = reserve_default_address, 391 .release_default_address = release_default_address, 378 392 .request_address = request_address, 379 393 .bind_address = bind_address, -
uspace/lib/drv/generic/remote_usbhc.c
r3f3afb9 r58226b4 50 50 static void remote_usbhc_control_write(ddf_fun_t *, void *, ipc_callid_t, ipc_call_t *); 51 51 static void remote_usbhc_control_read(ddf_fun_t *, void *, ipc_callid_t, ipc_call_t *); 52 static void remote_usbhc_reserve_default_address(ddf_fun_t *, void *, ipc_callid_t, ipc_call_t *); 53 static void remote_usbhc_release_default_address(ddf_fun_t *, void *, ipc_callid_t, ipc_call_t *); 52 54 static void remote_usbhc_request_address(ddf_fun_t *, void *, ipc_callid_t, ipc_call_t *); 53 55 static void remote_usbhc_bind_address(ddf_fun_t *, void *, ipc_callid_t, ipc_call_t *); … … 59 61 /** Remote USB host controller interface operations. */ 60 62 static remote_iface_func_ptr_t remote_usbhc_iface_ops [] = { 63 remote_usbhc_reserve_default_address, 64 remote_usbhc_release_default_address, 65 61 66 remote_usbhc_request_address, 62 67 remote_usbhc_bind_address, … … 122 127 123 128 return trans; 129 } 130 131 void remote_usbhc_reserve_default_address(ddf_fun_t *fun, void *iface, 132 ipc_callid_t callid, ipc_call_t *call) 133 { 134 usbhc_iface_t *usb_iface = (usbhc_iface_t *) iface; 135 136 if (!usb_iface->reserve_default_address) { 137 async_answer_0(callid, ENOTSUP); 138 return; 139 } 140 141 usb_speed_t speed = DEV_IPC_GET_ARG1(*call); 142 143 int rc = usb_iface->reserve_default_address(fun, speed); 144 145 async_answer_0(callid, rc); 146 } 147 148 void remote_usbhc_release_default_address(ddf_fun_t *fun, void *iface, 149 ipc_callid_t callid, ipc_call_t *call) 150 { 151 usbhc_iface_t *usb_iface = (usbhc_iface_t *) iface; 152 153 if (!usb_iface->release_default_address) { 154 async_answer_0(callid, ENOTSUP); 155 return; 156 } 157 158 int rc = usb_iface->release_default_address(fun); 159 160 async_answer_0(callid, rc); 124 161 } 125 162 -
uspace/lib/drv/include/usbhc_iface.h
r3f3afb9 r58226b4 84 84 */ 85 85 typedef enum { 86 /** Reserve usage of default address. 87 * This call informs the host controller that the caller will be 88 * using default USB address. It is duty of the HC driver to ensure 89 * that only single entity will have it reserved. 90 * The address is returned via IPC_M_USBHC_RELEASE_DEFAULT_ADDRESS. 91 * The caller can start using the address after receiving EOK 92 * answer. 93 */ 94 IPC_M_USBHC_RESERVE_DEFAULT_ADDRESS, 95 96 /** Release usage of default address. 97 * @see IPC_M_USBHC_RESERVE_DEFAULT_ADDRESS 98 */ 99 IPC_M_USBHC_RELEASE_DEFAULT_ADDRESS, 100 86 101 /** Asks for address assignment by host controller. 87 102 * Answer: -
uspace/lib/usb/Makefile
r3f3afb9 r58226b4 34 34 SOURCES = \ 35 35 src/addrkeep.c \ 36 src/altiface.c \37 36 src/class.c \ 38 37 src/ddfiface.c \ -
uspace/lib/usb/include/usb/devdrv.h
r3f3afb9 r58226b4 174 174 usb_endpoint_mapping_t **, size_t *); 175 175 int usb_device_destroy_pipes(ddf_dev_t *, usb_endpoint_mapping_t *, size_t); 176 int usb_device_create(ddf_dev_t *, usb_endpoint_description_t **, usb_device_t **, const char **);177 176 178 177 size_t usb_interface_count_alternates(uint8_t *, size_t, uint8_t); 179 int usb_alternate_interfaces_create(uint8_t *, size_t, int,180 usb_alternate_interfaces_t **);181 178 182 179 #endif -
uspace/lib/usb/include/usb/host/device_keeper.h
r3f3afb9 r58226b4 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 73 78 void usb_device_keeper_reserve_default_address( 74 79 usb_device_keeper_t *instance, usb_speed_t speed); -
uspace/lib/usb/include/usb/host/endpoint.h
r3f3afb9 r58226b4 54 54 fibril_condvar_t avail; 55 55 volatile bool active; 56 link_t same_device_eps; 56 57 } endpoint_t; 57 58 … … 70 71 void endpoint_toggle_set(endpoint_t *instance, int toggle); 71 72 72 void endpoint_toggle_reset_filtered(endpoint_t *instance, usb_target_t target); 73 void endpoint_toggle_reset(link_t *ep); 74 75 void endpoint_toggle_reset_filtered(link_t *ep, usb_endpoint_t epn); 76 73 77 #endif 74 78 /** -
uspace/lib/usb/include/usb/host/usb_endpoint_manager.h
r3f3afb9 r58226b4 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);82 80 #endif 83 81 /** -
uspace/lib/usb/include/usb/hub.h
r3f3afb9 r58226b4 59 59 } usb_hc_attached_device_t; 60 60 61 int usb_hc_reserve_default_address(usb_hc_connection_t *, usb_speed_t); 62 int usb_hc_release_default_address(usb_hc_connection_t *); 63 61 64 usb_address_t usb_hc_request_address(usb_hc_connection_t *, usb_speed_t); 62 65 int usb_hc_register_device(usb_hc_connection_t *, -
uspace/lib/usb/include/usb/request.h
r3f3afb9 r58226b4 50 50 /** USB endpoint status - endpoint is halted (stalled). */ 51 51 #define USB_ENDPOINT_STATUS_HALTED ((uint16_t)(1 << 0)) 52 53 /** USB feature selector - endpoint halt (stall). */54 #define USB_FEATURE_SELECTOR_ENDPOINT_HALT (0)55 56 /** USB feature selector - device remote wake-up. */57 #define USB_FEATURE_SELECTOR_REMOTE_WAKEUP (1)58 52 59 53 /** Standard device request. */ … … 141 135 char **); 142 136 143 int usb_request_clear_endpoint_halt(usb_pipe_t *, uint16_t);144 145 137 #endif 146 138 /** -
uspace/lib/usb/src/devdrv.c
r3f3afb9 r58226b4 100 100 usb_device_t *dev, int alternate_setting) 101 101 { 102 if (endpoints == NULL) {103 dev->pipes = NULL;104 dev->pipes_count = 0;105 return EOK;106 }107 108 102 usb_endpoint_mapping_t *pipes; 109 103 size_t pipes_count; … … 115 109 116 110 if (rc != EOK) { 111 usb_log_error( 112 "Failed to create endpoint pipes for `%s': %s.\n", 113 dev->ddf_dev->name, str_error(rc)); 117 114 return rc; 118 115 } … … 120 117 dev->pipes = pipes; 121 118 dev->pipes_count = pipes_count; 119 120 return EOK; 121 } 122 123 /** Initialize all endpoint pipes. 124 * 125 * @param drv The driver. 126 * @param dev The device to be initialized. 127 * @return Error code. 128 */ 129 static int initialize_pipes(usb_device_t *dev) 130 { 131 int rc; 132 133 rc = usb_device_connection_initialize_from_device(&dev->wire, 134 dev->ddf_dev); 135 if (rc != EOK) { 136 usb_log_error( 137 "Failed initializing connection on device `%s'. %s.\n", 138 dev->ddf_dev->name, str_error(rc)); 139 return rc; 140 } 141 142 rc = usb_pipe_initialize_default_control(&dev->ctrl_pipe, 143 &dev->wire); 144 if (rc != EOK) { 145 usb_log_error("Failed to initialize default control pipe " \ 146 "on device `%s': %s.\n", 147 dev->ddf_dev->name, str_error(rc)); 148 return rc; 149 } 150 151 rc = usb_pipe_probe_default_control(&dev->ctrl_pipe); 152 if (rc != EOK) { 153 usb_log_error( 154 "Probing default control pipe on device `%s' failed: %s.\n", 155 dev->ddf_dev->name, str_error(rc)); 156 return rc; 157 } 158 159 /* Get our interface. */ 160 dev->interface_no = usb_device_get_assigned_interface(dev->ddf_dev); 161 162 /* 163 * We will do some querying of the device, it is worth to prepare 164 * the long transfer. 165 */ 166 rc = usb_pipe_start_long_transfer(&dev->ctrl_pipe); 167 if (rc != EOK) { 168 usb_log_error("Failed to start transfer: %s.\n", 169 str_error(rc)); 170 return rc; 171 } 172 173 /* Retrieve the descriptors. */ 174 rc = usb_device_retrieve_descriptors(&dev->ctrl_pipe, 175 &dev->descriptors); 176 if (rc != EOK) { 177 usb_log_error("Failed to retrieve standard device " \ 178 "descriptors of %s: %s.\n", 179 dev->ddf_dev->name, str_error(rc)); 180 return rc; 181 } 182 183 184 if (driver->endpoints != NULL) { 185 rc = initialize_other_pipes(driver->endpoints, dev, 0); 186 } 187 188 usb_pipe_end_long_transfer(&dev->ctrl_pipe); 189 190 /* Rollback actions. */ 191 if (rc != EOK) { 192 if (dev->descriptors.configuration != NULL) { 193 free(dev->descriptors.configuration); 194 } 195 } 196 197 return rc; 198 } 199 200 /** Count number of alternate settings of a interface. 201 * 202 * @param config_descr Full configuration descriptor. 203 * @param config_descr_size Size of @p config_descr in bytes. 204 * @param interface_no Interface number. 205 * @return Number of alternate interfaces for @p interface_no interface. 206 */ 207 size_t usb_interface_count_alternates(uint8_t *config_descr, 208 size_t config_descr_size, uint8_t interface_no) 209 { 210 assert(config_descr != NULL); 211 assert(config_descr_size > 0); 212 213 usb_dp_parser_t dp_parser = { 214 .nesting = usb_dp_standard_descriptor_nesting 215 }; 216 usb_dp_parser_data_t dp_data = { 217 .data = config_descr, 218 .size = config_descr_size, 219 .arg = NULL 220 }; 221 222 size_t alternate_count = 0; 223 224 uint8_t *iface_ptr = usb_dp_get_nested_descriptor(&dp_parser, 225 &dp_data, config_descr); 226 while (iface_ptr != NULL) { 227 usb_standard_interface_descriptor_t *iface 228 = (usb_standard_interface_descriptor_t *) iface_ptr; 229 if (iface->descriptor_type == USB_DESCTYPE_INTERFACE) { 230 if (iface->interface_number == interface_no) { 231 alternate_count++; 232 } 233 } 234 iface_ptr = usb_dp_get_sibling_descriptor(&dp_parser, &dp_data, 235 config_descr, iface_ptr); 236 } 237 238 return alternate_count; 239 } 240 241 /** Initialize structures related to alternate interfaces. 242 * 243 * @param dev Device where alternate settings shall be initialized. 244 * @return Error code. 245 */ 246 static int initialize_alternate_interfaces(usb_device_t *dev) 247 { 248 if (dev->interface_no < 0) { 249 dev->alternate_interfaces = NULL; 250 return EOK; 251 } 252 253 usb_alternate_interfaces_t *alternates 254 = malloc(sizeof(usb_alternate_interfaces_t)); 255 256 if (alternates == NULL) { 257 return ENOMEM; 258 } 259 260 alternates->alternative_count 261 = usb_interface_count_alternates(dev->descriptors.configuration, 262 dev->descriptors.configuration_size, dev->interface_no); 263 264 if (alternates->alternative_count == 0) { 265 free(alternates); 266 return ENOENT; 267 } 268 269 alternates->alternatives = malloc(alternates->alternative_count 270 * sizeof(usb_alternate_interface_descriptors_t)); 271 if (alternates->alternatives == NULL) { 272 free(alternates); 273 return ENOMEM; 274 } 275 276 alternates->current = 0; 277 278 usb_dp_parser_t dp_parser = { 279 .nesting = usb_dp_standard_descriptor_nesting 280 }; 281 usb_dp_parser_data_t dp_data = { 282 .data = dev->descriptors.configuration, 283 .size = dev->descriptors.configuration_size, 284 .arg = NULL 285 }; 286 287 usb_alternate_interface_descriptors_t *cur_alt_iface 288 = &alternates->alternatives[0]; 289 290 uint8_t *iface_ptr = usb_dp_get_nested_descriptor(&dp_parser, 291 &dp_data, dp_data.data); 292 while (iface_ptr != NULL) { 293 usb_standard_interface_descriptor_t *iface 294 = (usb_standard_interface_descriptor_t *) iface_ptr; 295 if ((iface->descriptor_type != USB_DESCTYPE_INTERFACE) 296 || (iface->interface_number != dev->interface_no)) { 297 iface_ptr = usb_dp_get_sibling_descriptor(&dp_parser, 298 &dp_data, 299 dp_data.data, iface_ptr); 300 continue; 301 } 302 303 cur_alt_iface->interface = iface; 304 cur_alt_iface->nested_descriptors = iface_ptr + sizeof(*iface); 305 306 /* Find next interface to count size of nested descriptors. */ 307 iface_ptr = usb_dp_get_sibling_descriptor(&dp_parser, &dp_data, 308 dp_data.data, iface_ptr); 309 if (iface_ptr == NULL) { 310 uint8_t *next = dp_data.data + dp_data.size; 311 cur_alt_iface->nested_descriptors_size 312 = next - cur_alt_iface->nested_descriptors; 313 } else { 314 cur_alt_iface->nested_descriptors_size 315 = iface_ptr - cur_alt_iface->nested_descriptors; 316 } 317 318 cur_alt_iface++; 319 } 320 321 dev->alternate_interfaces = alternates; 122 322 123 323 return EOK; … … 139 339 int rc; 140 340 141 usb_device_t *dev = NULL; 142 const char *err_msg = NULL; 143 rc = usb_device_create(gen_dev, driver->endpoints, &dev, &err_msg); 144 if (rc != EOK) { 145 usb_log_error("USB device `%s' creation failed (%s): %s.\n", 146 gen_dev->name, err_msg, str_error(rc)); 147 return rc; 148 } 341 usb_device_t *dev = malloc(sizeof(usb_device_t)); 342 if (dev == NULL) { 343 usb_log_error("Out of memory when adding device `%s'.\n", 344 gen_dev->name); 345 return ENOMEM; 346 } 347 348 349 dev->ddf_dev = gen_dev; 350 dev->ddf_dev->driver_data = dev; 351 dev->driver_data = NULL; 352 dev->descriptors.configuration = NULL; 353 354 dev->pipes_count = 0; 355 dev->pipes = NULL; 356 357 rc = initialize_pipes(dev); 358 if (rc != EOK) { 359 free(dev); 360 return rc; 361 } 362 363 (void) initialize_alternate_interfaces(dev); 149 364 150 365 return driver->ops->add_device(dev); … … 180 395 * with usb_pipe_initialize_from_configuration(). 181 396 * 182 * @warning This is a wrapper function that does several operations that183 * can fail and that cannot be rollbacked easily. That means that a failure184 * during the SET_INTERFACE request would result in having a device with185 * no pipes at all (except the default control one). That is because the old186 * pipes needs to be unregistered at HC first and the new ones could not187 * be created.188 *189 397 * @param dev USB device. 190 398 * @param alternate_setting Alternate setting to choose. … … 201 409 int rc; 202 410 411 /* TODO: more transactional behavior. */ 412 203 413 /* Destroy existing pipes. */ 204 414 rc = destroy_current_pipes(dev); … … 222 432 /** Retrieve basic descriptors from the device. 223 433 * 224 * @param[in] ctrl_pipe Control endpoint pipe.434 * @param[in] ctrl_pipe Control pipe with opened session. 225 435 * @param[out] descriptors Where to store the descriptors. 226 436 * @return Error code. … … 230 440 { 231 441 assert(descriptors != NULL); 442 assert(usb_pipe_is_session_started(ctrl_pipe)); 232 443 233 444 descriptors->configuration = NULL; 234 445 235 446 int rc; 236 237 /* It is worth to start a long transfer. */238 rc = usb_pipe_start_long_transfer(ctrl_pipe);239 if (rc != EOK) {240 return rc;241 }242 447 243 448 /* Get the device descriptor. */ 244 449 rc = usb_request_get_device_descriptor(ctrl_pipe, &descriptors->device); 245 450 if (rc != EOK) { 246 goto leave;451 return rc; 247 452 } 248 453 … … 251 456 ctrl_pipe, 0, (void **) &descriptors->configuration, 252 457 &descriptors->configuration_size); 253 254 leave: 255 usb_pipe_end_long_transfer(ctrl_pipe);256 257 return rc;458 if (rc != EOK) { 459 return rc; 460 } 461 462 return EOK; 258 463 } 259 464 … … 436 641 } 437 642 438 /** Initialize control pipe in a device.439 *440 * @param dev USB device in question.441 * @param errmsg Where to store error context.442 * @return443 */444 static int init_wire_and_ctrl_pipe(usb_device_t *dev, const char **errmsg)445 {446 int rc;447 448 rc = usb_device_connection_initialize_from_device(&dev->wire,449 dev->ddf_dev);450 if (rc != EOK) {451 *errmsg = "device connection initialization";452 return rc;453 }454 455 rc = usb_pipe_initialize_default_control(&dev->ctrl_pipe,456 &dev->wire);457 if (rc != EOK) {458 *errmsg = "default control pipe initialization";459 return rc;460 }461 462 return EOK;463 }464 465 466 /** Create new instance of USB device.467 *468 * @param[in] ddf_dev Generic DDF device backing the USB one.469 * @param[in] endpoints NULL terminated array of endpoints (NULL for none).470 * @param[out] dev_ptr Where to store pointer to the new device.471 * @param[out] errstr_ptr Where to store description of context472 * (in case error occurs).473 * @return Error code.474 */475 int usb_device_create(ddf_dev_t *ddf_dev,476 usb_endpoint_description_t **endpoints,477 usb_device_t **dev_ptr, const char **errstr_ptr)478 {479 assert(dev_ptr != NULL);480 assert(ddf_dev != NULL);481 482 int rc;483 484 usb_device_t *dev = malloc(sizeof(usb_device_t));485 if (dev == NULL) {486 *errstr_ptr = "structure allocation";487 return ENOMEM;488 }489 490 // FIXME: proper deallocation in case of errors491 492 dev->ddf_dev = ddf_dev;493 dev->driver_data = NULL;494 dev->descriptors.configuration = NULL;495 dev->alternate_interfaces = NULL;496 497 dev->pipes_count = 0;498 dev->pipes = NULL;499 500 /* Initialize backing wire and control pipe. */501 rc = init_wire_and_ctrl_pipe(dev, errstr_ptr);502 if (rc != EOK) {503 return rc;504 }505 506 /* Get our interface. */507 dev->interface_no = usb_device_get_assigned_interface(dev->ddf_dev);508 509 /* Retrieve standard descriptors. */510 rc = usb_device_retrieve_descriptors(&dev->ctrl_pipe,511 &dev->descriptors);512 if (rc != EOK) {513 *errstr_ptr = "descriptor retrieval";514 return rc;515 }516 517 /* Create alternate interfaces. */518 rc = usb_alternate_interfaces_create(dev->descriptors.configuration,519 dev->descriptors.configuration_size, dev->interface_no,520 &dev->alternate_interfaces);521 if (rc != EOK) {522 /* We will try to silently ignore this. */523 dev->alternate_interfaces = NULL;524 }525 526 rc = initialize_other_pipes(endpoints, dev, 0);527 if (rc != EOK) {528 *errstr_ptr = "pipes initialization";529 return rc;530 }531 532 *errstr_ptr = NULL;533 *dev_ptr = dev;534 535 return EOK;536 }537 538 643 /** 539 644 * @} -
uspace/lib/usb/src/hidparser.c
r3f3afb9 r58226b4 900 900 item->usage_page = usage_page; 901 901 902 usb_log_debug("Appending usage %d, usage page %d\n", usage, usage_page);903 904 902 list_append (&usage_path->link, &item->link); 905 903 usage_path->depth++; -
uspace/lib/usb/src/host/device_keeper.c
r3f3afb9 r58226b4 54 54 for (; i < USB_ADDRESS_COUNT; ++i) { 55 55 instance->devices[i].occupied = false; 56 instance->devices[i].control_used = 0; 56 57 instance->devices[i].handle = 0; 57 58 instance->devices[i].speed = USB_SPEED_MAX; 59 list_initialize(&instance->devices[i].endpoints); 58 60 } 59 61 // TODO: is this hack enough? … … 62 64 } 63 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 } 86 /*----------------------------------------------------------------------------*/ 64 87 /** Attempt to obtain address 0, blocks. 65 88 * … … 94 117 } 95 118 /*----------------------------------------------------------------------------*/ 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 < 0 133 || target.address >= USB_ADDRESS_COUNT || target.address < 0 134 || !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 } 96 175 /*----------------------------------------------------------------------------*/ 97 176 /** Get a free USB address -
uspace/lib/usb/src/host/endpoint.c
r3f3afb9 r58226b4 53 53 fibril_mutex_initialize(&instance->guard); 54 54 fibril_condvar_initialize(&instance->avail); 55 link_initialize(&instance->same_device_eps); 55 56 return EOK; 56 57 } … … 60 61 assert(instance); 61 62 assert(!instance->active); 63 list_remove(&instance->same_device_eps); 62 64 free(instance); 63 65 } … … 95 97 } 96 98 /*----------------------------------------------------------------------------*/ 97 void endpoint_toggle_reset _filtered(endpoint_t *instance, usb_target_t target)99 void endpoint_toggle_reset(link_t *ep) 98 100 { 101 endpoint_t *instance = 102 list_get_instance(ep, endpoint_t, same_device_eps); 99 103 assert(instance); 100 if (instance->address == target.address && 101 (instance->endpoint == target.endpoint || target.endpoint == 0)) 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) 102 113 instance->toggle = 0; 103 114 } -
uspace/lib/usb/src/host/usb_endpoint_manager.c
r3f3afb9 r58226b4 31 31 #include <errno.h> 32 32 33 #include <usb/debug.h>34 33 #include <usb/host/usb_endpoint_manager.h> 35 34 … … 81 80 endpoint_destroy(node->ep); 82 81 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);91 82 } 92 83 /*----------------------------------------------------------------------------*/ … … 239 230 return node->ep; 240 231 } 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 < 0255 || 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 } -
uspace/lib/usb/src/hub.c
r3f3afb9 r58226b4 42 42 #include <usb/debug.h> 43 43 44 /** How much time to wait between attempts to register endpoint 0:0.45 * The value is based on typical value for port reset + some overhead.46 */47 #define ENDPOINT_0_0_REGISTER_ATTEMPT_DELAY_USEC (1000 * (10 + 2))48 49 44 /** Check that HC connection is alright. 50 45 * … … 58 53 } \ 59 54 } while (false) 55 56 57 /** Tell host controller to reserve default address. 58 * @deprecated 59 * 60 * @param connection Opened connection to host controller. 61 * @param speed Speed of the device that will respond on the default address. 62 * @return Error code. 63 */ 64 int usb_hc_reserve_default_address(usb_hc_connection_t *connection, 65 usb_speed_t speed) 66 { 67 CHECK_CONNECTION(connection); 68 69 usb_log_warning("usb_hc_reserve_default_address() considered obsolete"); 70 71 return async_req_2_0(connection->hc_phone, 72 DEV_IFACE_ID(USBHC_DEV_IFACE), 73 IPC_M_USBHC_RESERVE_DEFAULT_ADDRESS, speed); 74 } 75 76 /** Tell host controller to release default address. 77 * @deprecated 78 * 79 * @param connection Opened connection to host controller. 80 * @return Error code. 81 */ 82 int usb_hc_release_default_address(usb_hc_connection_t *connection) 83 { 84 CHECK_CONNECTION(connection); 85 86 usb_log_warning("usb_hc_release_default_address() considered obsolete"); 87 88 return async_req_1_0(connection->hc_phone, 89 DEV_IFACE_ID(USBHC_DEV_IFACE), 90 IPC_M_USBHC_RELEASE_DEFAULT_ADDRESS); 91 } 60 92 61 93 /** Ask host controller for free address assignment. … … 237 269 if (rc != EOK) { 238 270 /* Do not overheat the CPU ;-). */ 239 async_usleep( ENDPOINT_0_0_REGISTER_ATTEMPT_DELAY_USEC);271 async_usleep(10); 240 272 } 241 273 } while (rc != EOK); -
uspace/lib/usb/src/request.c
r3f3afb9 r58226b4 871 871 } 872 872 873 /** Clear halt bit of an endpoint pipe (after pipe stall).874 *875 * @param pipe Control pipe.876 * @param ep_index Endpoint index (in native endianness).877 * @return Error code.878 */879 int usb_request_clear_endpoint_halt(usb_pipe_t *pipe, uint16_t ep_index)880 {881 return usb_request_clear_feature(pipe,882 USB_REQUEST_TYPE_STANDARD, USB_REQUEST_RECIPIENT_ENDPOINT,883 uint16_host2usb(USB_FEATURE_SELECTOR_ENDPOINT_HALT),884 uint16_host2usb(ep_index));885 }886 887 873 /** 888 874 * @}
Note:
See TracChangeset
for help on using the changeset viewer.