Changeset 96e01fbc in mainline for uspace/drv/bus/usb
- Timestamp:
- 2012-08-31T17:30:29Z (13 years ago)
- Branches:
- lfn, master, serial, ticket/834-toolchain-update, topic/msim-upgrade, topic/simplify-dev-export
- Children:
- 2be2506a
- Parents:
- e0d5bc5 (diff), 0d57c3e (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/drv/bus/usb
- Files:
-
- 1 added
- 63 edited
Legend:
- Unmodified
- Added
- Removed
-
uspace/drv/bus/usb/ehci/main.c
re0d5bc5 r96e01fbc 49 49 50 50 static int ehci_dev_add(ddf_dev_t *device); 51 /*----------------------------------------------------------------------------*/ 51 52 52 static driver_ops_t ehci_driver_ops = { 53 53 .dev_add = ehci_dev_add, 54 54 }; 55 /*----------------------------------------------------------------------------*/ 55 56 56 static driver_t ehci_driver = { 57 57 .name = NAME, … … 62 62 }; 63 63 64 /*----------------------------------------------------------------------------*/ 64 65 65 /** Initializes a new ddf driver instance of EHCI hcd. 66 66 * … … 84 84 CHECK_RET_RETURN(ret, 85 85 "Failed to get memory addresses for %" PRIun ": %s.\n", 86 d evice->handle, str_error(ret));86 ddf_dev_get_handle(device), str_error(ret)); 87 87 usb_log_info("Memory mapped regs at 0x%" PRIxn " (size %zu), IRQ %d.\n", 88 88 reg_base, reg_size, irq); … … 104 104 /* High Speed, no bandwidth */ 105 105 hcd_init(ehci_hc, USB_SPEED_HIGH, 0, NULL); 106 hc_fun->ops = &hc_ops;106 ddf_fun_set_ops(hc_fun, &hc_ops); 107 107 108 108 ret = ddf_fun_bind(hc_fun); … … 116 116 117 117 usb_log_info("Controlling new EHCI device `%s' (handle %" PRIun ").\n", 118 d evice->name, device->handle);118 ddf_dev_get_name(device), ddf_dev_get_handle(device)); 119 119 120 120 return EOK; 121 121 #undef CHECK_RET_RETURN 122 122 } 123 /*----------------------------------------------------------------------------*/ 123 124 124 /** Initializes global driver structures (NONE). 125 125 * -
uspace/drv/bus/usb/ehci/res.c
re0d5bc5 r96e01fbc 76 76 * @return Error code. 77 77 */ 78 int get_my_registers( constddf_dev_t *dev,78 int get_my_registers(ddf_dev_t *dev, 79 79 uintptr_t *mem_reg_address, size_t *mem_reg_size, int *irq_no) 80 80 { … … 82 82 83 83 async_sess_t *parent_sess = devman_parent_device_connect( 84 EXCHANGE_SERIALIZE, d ev->handle, IPC_FLAG_BLOCKING);84 EXCHANGE_SERIALIZE, ddf_dev_get_handle(dev), IPC_FLAG_BLOCKING); 85 85 if (!parent_sess) 86 86 return ENOMEM; … … 115 115 * @return Error code. 116 116 */ 117 int enable_interrupts( constddf_dev_t *device)117 int enable_interrupts(ddf_dev_t *device) 118 118 { 119 119 async_sess_t *parent_sess = devman_parent_device_connect( 120 EXCHANGE_SERIALIZE, d evice->handle, IPC_FLAG_BLOCKING);120 EXCHANGE_SERIALIZE, ddf_dev_get_handle(device), IPC_FLAG_BLOCKING); 121 121 if (!parent_sess) 122 122 return ENOMEM; … … 134 134 * @return Error code. 135 135 */ 136 static int disable_extended_caps( constddf_dev_t *device, unsigned eecp)136 static int disable_extended_caps(ddf_dev_t *device, unsigned eecp) 137 137 { 138 138 /* nothing to do */ … … 141 141 142 142 async_sess_t *parent_sess = devman_parent_device_connect( 143 EXCHANGE_SERIALIZE, d evice->handle, IPC_FLAG_BLOCKING);143 EXCHANGE_SERIALIZE, ddf_dev_get_handle(device), IPC_FLAG_BLOCKING); 144 144 if (!parent_sess) 145 145 return ENOMEM; … … 234 234 } 235 235 236 int disable_legacy( constddf_dev_t *device, uintptr_t reg_base, size_t reg_size)236 int disable_legacy(ddf_dev_t *device, uintptr_t reg_base, size_t reg_size) 237 237 { 238 238 assert(device); -
uspace/drv/bus/usb/ehci/res.h
re0d5bc5 r96e01fbc 38 38 #include <ddf/driver.h> 39 39 40 int get_my_registers( constddf_dev_t *, uintptr_t *, size_t *, int *);41 int enable_interrupts( constddf_dev_t *);42 int disable_legacy( constddf_dev_t *, uintptr_t, size_t);40 int get_my_registers(ddf_dev_t *, uintptr_t *, size_t *, int *); 41 int enable_interrupts(ddf_dev_t *); 42 int disable_legacy(ddf_dev_t *, uintptr_t, size_t); 43 43 44 44 #endif -
uspace/drv/bus/usb/ohci/endpoint_list.c
re0d5bc5 r96e01fbc 65 65 return EOK; 66 66 } 67 /*----------------------------------------------------------------------------*/ 67 68 68 /** Set the next list in transfer list chain. 69 69 * … … 80 80 ed_append_ed(instance->list_head, next->list_head); 81 81 } 82 /*----------------------------------------------------------------------------*/ 82 83 83 /** Add endpoint to the list and queue. 84 84 * … … 132 132 fibril_mutex_unlock(&instance->guard); 133 133 } 134 /*----------------------------------------------------------------------------*/ 134 135 135 /** Remove endpoint from the list and queue. 136 136 * … … 162 162 qpos = "NOT FIRST"; 163 163 } 164 assert( (prev_ed->next & ED_NEXT_PTR_MASK) == addr_to_phys(ep->ed));164 assert(ed_next(prev_ed) == addr_to_phys(ep->ed)); 165 165 prev_ed->next = ep->ed->next; 166 166 /* Make sure ED is updated */ -
uspace/drv/bus/usb/ohci/hc.c
re0d5bc5 r96e01fbc 26 26 * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 27 27 */ 28 28 29 /** @addtogroup drvusbohcihc 29 30 * @{ … … 32 33 * @brief OHCI Host controller driver routines 33 34 */ 35 34 36 #include <errno.h> 35 37 #include <str_error.h> … … 49 51 static const irq_pio_range_t ohci_pio_ranges[] = { 50 52 { 51 .base = 0, /* filled later */53 .base = 0, 52 54 .size = sizeof(ohci_regs_t) 53 55 } … … 55 57 56 58 static const irq_cmd_t ohci_irq_commands[] = { 57 { .cmd = CMD_PIO_READ_32, .dstarg = 1, .addr = NULL /* filled later */ }, 58 { .cmd = CMD_BTEST, .srcarg = 1, .dstarg = 2, .value = OHCI_USED_INTERRUPTS }, 59 { .cmd = CMD_PREDICATE, .srcarg = 2, .value = 2 }, 60 { .cmd = CMD_PIO_WRITE_A_32, .srcarg = 1, .addr = NULL /* filled later */ }, 61 { .cmd = CMD_ACCEPT }, 59 { 60 .cmd = CMD_PIO_READ_32, 61 .dstarg = 1, 62 .addr = NULL 63 }, 64 { 65 .cmd = CMD_AND, 66 .srcarg = 1, 67 .dstarg = 2, 68 .value = 0 69 }, 70 { 71 .cmd = CMD_PREDICATE, 72 .srcarg = 2, 73 .value = 2 74 }, 75 { 76 .cmd = CMD_PIO_WRITE_A_32, 77 .srcarg = 1, 78 .addr = NULL 79 }, 80 { 81 .cmd = CMD_ACCEPT 82 } 62 83 }; 63 84 … … 68 89 static int interrupt_emulator(hc_t *instance); 69 90 static int hc_schedule(hcd_t *hcd, usb_transfer_batch_t *batch); 70 /*----------------------------------------------------------------------------*/ 91 71 92 /** Get number of PIO ranges used in IRQ code. 72 93 * @return Number of ranges. … … 76 97 return sizeof(ohci_pio_ranges) / sizeof(irq_pio_range_t); 77 98 } 78 /*----------------------------------------------------------------------------*/ 79 /*----------------------------------------------------------------------------*/ 99 80 100 /** Get number of commands used in IRQ code. 81 101 * @return Number of commands. … … 85 105 return sizeof(ohci_irq_commands) / sizeof(irq_cmd_t); 86 106 } 87 /*----------------------------------------------------------------------------*/ 107 88 108 /** Generate IRQ code. 89 109 * @param[out] ranges PIO ranges buffer. … … 112 132 cmds[0].addr = (void *) ®isters->interrupt_status; 113 133 cmds[3].addr = (void *) ®isters->interrupt_status; 134 OHCI_WR(cmds[1].value, OHCI_USED_INTERRUPTS); 114 135 115 136 return EOK; 116 137 } 117 /*----------------------------------------------------------------------------*/ 138 118 139 /** Announce OHCI root hub to the DDF 119 140 * … … 166 187 167 188 ret = usb_device_manager_bind_address(&instance->generic.dev_manager, 168 instance->rh.address, hub_fun->handle);189 instance->rh.address, ddf_fun_get_handle(hub_fun)); 169 190 if (ret != EOK) 170 191 usb_log_warning("Failed to bind root hub address: %s.\n", … … 174 195 #undef CHECK_RET_RELEASE 175 196 } 176 /*----------------------------------------------------------------------------*/ 197 177 198 /** Initialize OHCI hc driver structure 178 199 * … … 227 248 return EOK; 228 249 } 229 /*----------------------------------------------------------------------------*/ 250 230 251 void hc_enqueue_endpoint(hc_t *instance, const endpoint_t *ep) 231 252 { … … 241 262 switch (ep->transfer_type) { 242 263 case USB_TRANSFER_CONTROL: 243 instance->registers->control &= ~C_CLE;264 OHCI_CLR(instance->registers->control, C_CLE); 244 265 endpoint_list_add_ep(list, ohci_ep); 245 instance->registers->control_current = 0;246 instance->registers->control |= C_CLE;266 OHCI_WR(instance->registers->control_current, 0); 267 OHCI_SET(instance->registers->control, C_CLE); 247 268 break; 248 269 case USB_TRANSFER_BULK: 249 instance->registers->control &= ~C_BLE;270 OHCI_CLR(instance->registers->control, C_BLE); 250 271 endpoint_list_add_ep(list, ohci_ep); 251 instance->registers->control |= C_BLE; 272 OHCI_WR(instance->registers->bulk_current, 0); 273 OHCI_SET(instance->registers->control, C_BLE); 252 274 break; 253 275 case USB_TRANSFER_ISOCHRONOUS: 254 276 case USB_TRANSFER_INTERRUPT: 255 instance->registers->control &= (~C_PLE & ~C_IE);277 OHCI_CLR(instance->registers->control, C_PLE | C_IE); 256 278 endpoint_list_add_ep(list, ohci_ep); 257 instance->registers->control |= C_PLE | C_IE;258 break; 259 } 260 } 261 /*----------------------------------------------------------------------------*/ 279 OHCI_SET(instance->registers->control, C_PLE | C_IE); 280 break; 281 } 282 } 283 262 284 void hc_dequeue_endpoint(hc_t *instance, const endpoint_t *ep) 263 285 { … … 273 295 switch (ep->transfer_type) { 274 296 case USB_TRANSFER_CONTROL: 275 instance->registers->control &= ~C_CLE;297 OHCI_CLR(instance->registers->control, C_CLE); 276 298 endpoint_list_remove_ep(list, ohci_ep); 277 instance->registers->control_current = 0;278 instance->registers->control |= C_CLE;299 OHCI_WR(instance->registers->control_current, 0); 300 OHCI_SET(instance->registers->control, C_CLE); 279 301 break; 280 302 case USB_TRANSFER_BULK: 281 instance->registers->control &= ~C_BLE;303 OHCI_CLR(instance->registers->control, C_BLE); 282 304 endpoint_list_remove_ep(list, ohci_ep); 283 instance->registers->control |= C_BLE; 305 OHCI_WR(instance->registers->bulk_current, 0); 306 OHCI_SET(instance->registers->control, C_BLE); 284 307 break; 285 308 case USB_TRANSFER_ISOCHRONOUS: 286 309 case USB_TRANSFER_INTERRUPT: 287 instance->registers->control &= (~C_PLE & ~C_IE);310 OHCI_CLR(instance->registers->control, C_PLE | C_IE); 288 311 endpoint_list_remove_ep(list, ohci_ep); 289 instance->registers->control |= C_PLE | C_IE;312 OHCI_SET(instance->registers->control, C_PLE | C_IE); 290 313 break; 291 314 default: … … 293 316 } 294 317 } 295 /*----------------------------------------------------------------------------*/ 318 296 319 /** Add USB transfer to the schedule. 297 320 * … … 308 331 /* Check for root hub communication */ 309 332 if (batch->ep->address == instance->rh.address) { 333 usb_log_debug("OHCI root hub request.\n"); 310 334 rh_request(&instance->rh, batch); 311 335 return EOK; … … 323 347 { 324 348 case USB_TRANSFER_CONTROL: 325 instance->registers->command_status |= CS_CLF;349 OHCI_SET(instance->registers->command_status, CS_CLF); 326 350 break; 327 351 case USB_TRANSFER_BULK: 328 instance->registers->command_status |= CS_BLF;352 OHCI_SET(instance->registers->command_status, CS_BLF); 329 353 break; 330 354 default: … … 334 358 return EOK; 335 359 } 336 /*----------------------------------------------------------------------------*/ 360 337 361 /** Interrupt handling routine 338 362 * … … 342 366 void hc_interrupt(hc_t *instance, uint32_t status) 343 367 { 368 status = OHCI_RD(status); 344 369 assert(instance); 345 370 if ((status & ~I_SF) == 0) /* ignore sof status */ … … 352 377 fibril_mutex_lock(&instance->guard); 353 378 usb_log_debug2("HCCA: %p-%#" PRIx32 " (%p).\n", instance->hcca, 354 instance->registers->hcca,379 OHCI_RD(instance->registers->hcca), 355 380 (void *) addr_to_phys(instance->hcca)); 356 381 usb_log_debug2("Periodic current: %#" PRIx32 ".\n", 357 instance->registers->periodic_current);382 OHCI_RD(instance->registers->periodic_current)); 358 383 359 384 link_t *current = list_first(&instance->pending_batches); … … 379 404 380 405 } 381 /*----------------------------------------------------------------------------*/ 406 382 407 /** Check status register regularly 383 408 * … … 397 422 return EOK; 398 423 } 399 /*----------------------------------------------------------------------------*/ 424 400 425 /** Turn off any (BIOS)driver that might be in control of the device. 401 426 * … … 410 435 411 436 usb_log_debug("Requesting OHCI control.\n"); 412 if ( instance->registers->revision& R_LEGACY_FLAG) {437 if (OHCI_RD(instance->registers->revision) & R_LEGACY_FLAG) { 413 438 /* Turn off legacy emulation, it should be enough to zero 414 439 * the lowest bit, but it caused problems. Thus clear all … … 419 444 (uint32_t*)((char*)instance->registers + LEGACY_REGS_OFFSET); 420 445 usb_log_debug("OHCI legacy register %p: %x.\n", 421 ohci_emulation_reg, *ohci_emulation_reg);446 ohci_emulation_reg, OHCI_RD(*ohci_emulation_reg)); 422 447 /* Zero everything but A20State */ 423 *ohci_emulation_reg &= 0x100;448 OHCI_CLR(*ohci_emulation_reg, ~0x100); 424 449 usb_log_debug( 425 450 "OHCI legacy register (should be 0 or 0x100) %p: %x.\n", 426 ohci_emulation_reg, *ohci_emulation_reg);451 ohci_emulation_reg, OHCI_RD(*ohci_emulation_reg)); 427 452 } 428 453 429 454 /* Interrupt routing enabled => smm driver is active */ 430 if ( instance->registers->control& C_IR) {455 if (OHCI_RD(instance->registers->control) & C_IR) { 431 456 usb_log_debug("SMM driver: request ownership change.\n"); 432 instance->registers->command_status |= CS_OCR;457 OHCI_SET(instance->registers->command_status, CS_OCR); 433 458 /* Hope that SMM actually knows its stuff or we can hang here */ 434 while ( instance->registers->control & C_IR) {459 while (OHCI_RD(instance->registers->control & C_IR)) { 435 460 async_usleep(1000); 436 461 } … … 449 474 return; 450 475 } 451 /* HC is suspended assert resume for 20ms ,*/476 /* HC is suspended assert resume for 20ms */ 452 477 C_HCFS_SET(instance->registers->control, C_HCFS_RESUME); 453 478 async_usleep(20000); … … 461 486 async_usleep(50000); 462 487 } 463 /*----------------------------------------------------------------------------*/ 488 464 489 /** OHCI hw initialization routine. 465 490 * … … 473 498 474 499 /* Save contents of fm_interval register */ 475 const uint32_t fm_interval = instance->registers->fm_interval;500 const uint32_t fm_interval = OHCI_RD(instance->registers->fm_interval); 476 501 usb_log_debug2("Old value of HcFmInterval: %x.\n", fm_interval); 477 502 … … 479 504 usb_log_debug2("HC reset.\n"); 480 505 size_t time = 0; 481 instance->registers->command_status = CS_HCR;482 while ( instance->registers->command_status& CS_HCR) {506 OHCI_WR(instance->registers->command_status, CS_HCR); 507 while (OHCI_RD(instance->registers->command_status) & CS_HCR) { 483 508 async_usleep(10); 484 509 time += 10; … … 487 512 488 513 /* Restore fm_interval */ 489 instance->registers->fm_interval = fm_interval;490 assert(( instance->registers->command_status& CS_HCR) == 0);514 OHCI_WR(instance->registers->fm_interval, fm_interval); 515 assert((OHCI_RD(instance->registers->command_status) & CS_HCR) == 0); 491 516 492 517 /* hc is now in suspend state */ 493 518 usb_log_debug2("HC should be in suspend state(%x).\n", 494 instance->registers->control);519 OHCI_RD(instance->registers->control)); 495 520 496 521 /* Use HCCA */ 497 instance->registers->hcca = addr_to_phys(instance->hcca);522 OHCI_WR(instance->registers->hcca, addr_to_phys(instance->hcca)); 498 523 499 524 /* Use queues */ 500 instance->registers->bulk_head =501 instance->lists[USB_TRANSFER_BULK].list_head_pa ;525 OHCI_WR(instance->registers->bulk_head, 526 instance->lists[USB_TRANSFER_BULK].list_head_pa); 502 527 usb_log_debug2("Bulk HEAD set to: %p (%#" PRIx32 ").\n", 503 528 instance->lists[USB_TRANSFER_BULK].list_head, 504 529 instance->lists[USB_TRANSFER_BULK].list_head_pa); 505 530 506 instance->registers->control_head =507 instance->lists[USB_TRANSFER_CONTROL].list_head_pa ;531 OHCI_WR(instance->registers->control_head, 532 instance->lists[USB_TRANSFER_CONTROL].list_head_pa); 508 533 usb_log_debug2("Control HEAD set to: %p (%#" PRIx32 ").\n", 509 534 instance->lists[USB_TRANSFER_CONTROL].list_head, … … 511 536 512 537 /* Enable queues */ 513 instance->registers->control |= (C_PLE | C_IE | C_CLE | C_BLE);514 usb_log_debug 2("All queues enabled(%x).\n",515 instance->registers->control);538 OHCI_SET(instance->registers->control, (C_PLE | C_IE | C_CLE | C_BLE)); 539 usb_log_debug("Queues enabled(%x).\n", 540 OHCI_RD(instance->registers->control)); 516 541 517 542 /* Enable interrupts */ 518 instance->registers->interrupt_enable = OHCI_USED_INTERRUPTS;519 usb_log_debug 2("Enabled interrupts: %x.\n",520 instance->registers->interrupt_enable);521 instance->registers->interrupt_enable = I_MI;543 OHCI_WR(instance->registers->interrupt_enable, OHCI_USED_INTERRUPTS); 544 usb_log_debug("Enabled interrupts: %x.\n", 545 OHCI_RD(instance->registers->interrupt_enable)); 546 OHCI_WR(instance->registers->interrupt_enable, I_MI); 522 547 523 548 /* Set periodic start to 90% */ 524 uint32_t frame_length = ((fm_interval >> FMI_FI_SHIFT) & FMI_FI_MASK); 525 instance->registers->periodic_start = (frame_length / 10) * 9; 549 const uint32_t frame_length = 550 (fm_interval >> FMI_FI_SHIFT) & FMI_FI_MASK; 551 OHCI_WR(instance->registers->periodic_start, 552 ((frame_length / 10) * 9) & PS_MASK << PS_SHIFT); 526 553 usb_log_debug2("All periodic start set to: %x(%u - 90%% of %d).\n", 527 instance->registers->periodic_start, 528 instance->registers->periodic_start, frame_length); 529 554 OHCI_RD(instance->registers->periodic_start), 555 OHCI_RD(instance->registers->periodic_start), frame_length); 530 556 C_HCFS_SET(instance->registers->control, C_HCFS_OPERATIONAL); 531 557 usb_log_debug("OHCI HC up and running (ctl_reg=0x%x).\n", 532 instance->registers->control);533 } 534 /*----------------------------------------------------------------------------*/ 558 OHCI_RD(instance->registers->control)); 559 } 560 535 561 /** Initialize schedule queues 536 562 * … … 566 592 return EOK; 567 593 } 568 /*----------------------------------------------------------------------------*/ 594 569 595 /** Initialize memory structures used by the OHCI hcd. 570 596 * … … 587 613 if (instance->hcca == NULL) 588 614 return ENOMEM; 589 bzero(instance->hcca, sizeof(hcca_t));590 615 usb_log_debug2("OHCI HCCA initialized at %p.\n", instance->hcca); 591 616 592 for (unsigned i = 0; i < 32; ++i) {593 instance->hcca->int_ep[i] =594 instance->lists[USB_TRANSFER_INTERRUPT].list_head_pa ;617 for (unsigned i = 0; i < HCCA_INT_EP_COUNT; ++i) { 618 hcca_set_int_ep(instance->hcca, i, 619 instance->lists[USB_TRANSFER_INTERRUPT].list_head_pa); 595 620 } 596 621 usb_log_debug2("Interrupt HEADs set to: %p (%#" PRIx32 ").\n", -
uspace/drv/bus/usb/ohci/hw_struct/endpoint_descriptor.c
re0d5bc5 r96e01fbc 58 58 /* Mark as dead, used for dummy EDs at the beginning of 59 59 * endpoint lists. */ 60 instance->status = ED_STATUS_K_FLAG;60 OHCI_MEM32_WR(instance->status, ED_STATUS_K_FLAG); 61 61 return; 62 62 } … … 65 65 66 66 /* Status: address, endpoint nr, direction mask and max packet size. */ 67 instance->status = 068 |((ep->address & ED_STATUS_FA_MASK) << ED_STATUS_FA_SHIFT)67 OHCI_MEM32_WR(instance->status, 68 ((ep->address & ED_STATUS_FA_MASK) << ED_STATUS_FA_SHIFT) 69 69 | ((ep->endpoint & ED_STATUS_EN_MASK) << ED_STATUS_EN_SHIFT) 70 70 | ((dir[ep->direction] & ED_STATUS_D_MASK) << ED_STATUS_D_SHIFT) 71 71 | ((ep->max_packet_size & ED_STATUS_MPS_MASK) 72 << ED_STATUS_MPS_SHIFT) ;72 << ED_STATUS_MPS_SHIFT)); 73 73 74 74 /* Low speed flag */ 75 75 if (ep->speed == USB_SPEED_LOW) 76 instance->status |= ED_STATUS_S_FLAG;76 OHCI_MEM32_SET(instance->status, ED_STATUS_S_FLAG); 77 77 78 78 /* Isochronous format flag */ 79 79 if (ep->transfer_type == USB_TRANSFER_ISOCHRONOUS) 80 instance->status |= ED_STATUS_F_FLAG;80 OHCI_MEM32_SET(instance->status, ED_STATUS_F_FLAG); 81 81 82 82 /* Set TD to the list */ 83 83 const uintptr_t pa = addr_to_phys(td); 84 instance->td_head = pa & ED_TDHEAD_PTR_MASK;85 instance->td_tail = pa & ED_TDTAIL_PTR_MASK;84 OHCI_MEM32_WR(instance->td_head, pa & ED_TDHEAD_PTR_MASK); 85 OHCI_MEM32_WR(instance->td_tail, pa & ED_TDTAIL_PTR_MASK); 86 86 87 87 /* Set toggle bit */ 88 88 if (ep->toggle) 89 instance->td_head |= ED_TDHEAD_TOGGLE_CARRY;89 OHCI_MEM32_SET(instance->td_head, ED_TDHEAD_TOGGLE_CARRY); 90 90 91 91 } -
uspace/drv/bus/usb/ohci/hw_struct/endpoint_descriptor.h
re0d5bc5 r96e01fbc 44 44 45 45 #include "completion_codes.h" 46 #include "mem_access.h" 46 47 47 48 /** … … 116 117 { 117 118 assert(instance); 118 return (instance->td_head & ED_TDHEAD_HALTED_FLAG) 119 || (instance->status & ED_STATUS_K_FLAG); 119 return (OHCI_MEM32_RD(instance->td_head) & ED_TDHEAD_HALTED_FLAG) 120 || (OHCI_MEM32_RD(instance->status) & ED_STATUS_K_FLAG); 121 } 122 123 static inline void ed_clear_halt(ed_t *instance) 124 { 125 assert(instance); 126 OHCI_MEM32_CLR(instance->td_head, ED_TDHEAD_HALTED_FLAG); 120 127 } 121 128 … … 128 135 { 129 136 assert(instance); 130 return ( instance->td_head& ED_TDHEAD_PTR_MASK)131 != ( instance->td_tail& ED_TDTAIL_PTR_MASK);137 return (OHCI_MEM32_RD(instance->td_head) & ED_TDHEAD_PTR_MASK) 138 != (OHCI_MEM32_RD(instance->td_tail) & ED_TDTAIL_PTR_MASK); 132 139 } 133 140 … … 141 148 assert(instance); 142 149 const uintptr_t pa = addr_to_phys(td); 143 instance->td_tail = pa & ED_TDTAIL_PTR_MASK; 150 OHCI_MEM32_WR(instance->td_tail, pa & ED_TDTAIL_PTR_MASK); 151 } 152 153 static inline uint32_t ed_tail_td(const ed_t *instance) 154 { 155 assert(instance); 156 return OHCI_MEM32_RD(instance->td_tail) & ED_TDTAIL_PTR_MASK; 157 } 158 159 static inline uint32_t ed_head_td(const ed_t *instance) 160 { 161 assert(instance); 162 return OHCI_MEM32_RD(instance->td_head) & ED_TDHEAD_PTR_MASK; 144 163 } 145 164 … … 155 174 const uint32_t pa = addr_to_phys(next); 156 175 assert((pa & ED_NEXT_PTR_MASK) << ED_NEXT_PTR_SHIFT == pa); 157 instance->next = pa; 176 OHCI_MEM32_WR(instance->next, pa); 177 } 178 179 static inline uint32_t ed_next(const ed_t *instance) 180 { 181 assert(instance); 182 return OHCI_MEM32_RD(instance->next) & ED_NEXT_PTR_MASK; 158 183 } 159 184 … … 166 191 { 167 192 assert(instance); 168 return ( instance->td_head& ED_TDHEAD_TOGGLE_CARRY) ? 1 : 0;193 return (OHCI_MEM32_RD(instance->td_head) & ED_TDHEAD_TOGGLE_CARRY) ? 1 : 0; 169 194 } 170 195 … … 178 203 assert(instance); 179 204 if (toggle) { 180 instance->td_head |= ED_TDHEAD_TOGGLE_CARRY;205 OHCI_MEM32_SET(instance->td_head, ED_TDHEAD_TOGGLE_CARRY); 181 206 } else { 182 207 /* Clear halted flag when reseting toggle TODO: Why? */ 183 instance->td_head &= ~ED_TDHEAD_TOGGLE_CARRY;184 instance->td_head &= ~ED_TDHEAD_HALTED_FLAG;208 OHCI_MEM32_CLR(instance->td_head, ED_TDHEAD_TOGGLE_CARRY); 209 OHCI_MEM32_CLR(instance->td_head, ED_TDHEAD_HALTED_FLAG); 185 210 } 186 211 } -
uspace/drv/bus/usb/ohci/hw_struct/hcca.h
re0d5bc5 r96e01fbc 38 38 #include <malloc.h> 39 39 40 #include "mem_access.h" 41 42 #define HCCA_INT_EP_COUNT 32 43 40 44 /** Host controller communication area. 41 45 * Shared memory used for communication between the controller and the driver. 42 46 */ 43 47 typedef struct hcca { 44 uint32_t int_ep[32]; 48 /** Interrupt endpoints */ 49 uint32_t int_ep[HCCA_INT_EP_COUNT]; 50 /** Frame number. */ 45 51 uint16_t frame_number; 46 52 uint16_t pad1; 53 /** Pointer to the last completed TD. (useless) */ 47 54 uint32_t done_head; 55 /** Padding to make the size 256B */ 48 56 uint32_t reserved[30]; 49 57 } hcca_t; 50 58 51 static inline void * hcca_get(void) 59 /** Allocate properly aligned structure. 60 * 61 * The returned structure is zeroed upon allocation. 62 * 63 * @return Usable HCCA memory structure. 64 */ 65 static inline hcca_t * hcca_get(void) 52 66 { 53 67 assert(sizeof(hcca_t) == 256); 54 return memalign(256, sizeof(hcca_t)); 68 hcca_t *hcca = memalign(256, sizeof(hcca_t)); 69 if (hcca) 70 bzero(hcca, sizeof(hcca_t)); 71 return hcca; 72 } 73 74 /** Set HCCA interrupt endpoint pointer table entry. 75 * @param hcca HCCA memory structure. 76 * @param index table index. 77 * @param pa Physical address. 78 */ 79 static inline void hcca_set_int_ep(hcca_t *hcca, unsigned index, uintptr_t pa) 80 { 81 assert(hcca); 82 assert(index < HCCA_INT_EP_COUNT); 83 OHCI_MEM32_WR(hcca->int_ep[index], pa); 84 55 85 } 56 86 #endif -
uspace/drv/bus/usb/ohci/hw_struct/transfer_descriptor.c
re0d5bc5 r96e01fbc 33 33 */ 34 34 #include <usb/usb.h> 35 #include <mem.h> 36 #include "../utils/malloc32.h" 35 37 #include "transfer_descriptor.h" 36 38 … … 58 60 bzero(instance, sizeof(td_t)); 59 61 /* Set PID and Error code */ 60 instance->status = 061 |((dir[direction] & TD_STATUS_DP_MASK) << TD_STATUS_DP_SHIFT)62 | ((CC_NOACCESS2 & TD_STATUS_CC_MASK) << TD_STATUS_CC_SHIFT) ;62 OHCI_MEM32_WR(instance->status, 63 ((dir[direction] & TD_STATUS_DP_MASK) << TD_STATUS_DP_SHIFT) 64 | ((CC_NOACCESS2 & TD_STATUS_CC_MASK) << TD_STATUS_CC_SHIFT)); 63 65 64 66 if (toggle == 0 || toggle == 1) { 65 67 /* Set explicit toggle bit */ 66 instance->status |= TD_STATUS_T_USE_TD_FLAG;67 instance->status |= toggle ? TD_STATUS_T_FLAG : 0;68 OHCI_MEM32_SET(instance->status, TD_STATUS_T_USE_TD_FLAG); 69 OHCI_MEM32_SET(instance->status, toggle ? TD_STATUS_T_FLAG : 0); 68 70 } 69 71 70 72 /* Alow less data on input. */ 71 73 if (dir == USB_DIRECTION_IN) { 72 instance->status |= TD_STATUS_ROUND_FLAG;74 OHCI_MEM32_SET(instance->status, TD_STATUS_ROUND_FLAG); 73 75 } 74 76 75 77 if (buffer != NULL) { 76 78 assert(size != 0); 77 instance->cbp = addr_to_phys(buffer);78 instance->be = addr_to_phys(buffer + size - 1);79 OHCI_MEM32_WR(instance->cbp, addr_to_phys(buffer)); 80 OHCI_MEM32_WR(instance->be, addr_to_phys(buffer + size - 1)); 79 81 } 80 82 81 instance->next = addr_to_phys(next) & TD_NEXT_PTR_MASK;83 OHCI_MEM32_WR(instance->next, addr_to_phys(next) & TD_NEXT_PTR_MASK); 82 84 83 85 } -
uspace/drv/bus/usb/ohci/hw_struct/transfer_descriptor.h
re0d5bc5 r96e01fbc 38 38 #include <stdint.h> 39 39 40 #include " ../utils/malloc32.h"40 #include "mem_access.h" 41 41 #include "completion_codes.h" 42 42 … … 100 100 { 101 101 assert(instance); 102 const int cc = 103 (instance->status>> TD_STATUS_CC_SHIFT) & TD_STATUS_CC_MASK;102 const int cc =(OHCI_MEM32_RD(instance->status) 103 >> TD_STATUS_CC_SHIFT) & TD_STATUS_CC_MASK; 104 104 /* This value is changed on transfer completion, 105 105 * either to CC_NOERROR or and error code. … … 119 119 { 120 120 assert(instance); 121 const int cc = 122 (instance->status>> TD_STATUS_CC_SHIFT) & TD_STATUS_CC_MASK;121 const int cc = (OHCI_MEM32_RD(instance->status) 122 >> TD_STATUS_CC_SHIFT) & TD_STATUS_CC_MASK; 123 123 return cc_to_rc(cc); 124 124 } … … 136 136 return 0; 137 137 /* Buffer end points to the last byte of transfer buffer, so add 1 */ 138 return instance->be - instance->cbp+ 1;138 return OHCI_MEM32_RD(instance->be) - OHCI_MEM32_RD(instance->cbp) + 1; 139 139 } 140 140 #endif -
uspace/drv/bus/usb/ohci/main.c
re0d5bc5 r96e01fbc 59 59 return ret; 60 60 } 61 usb_log_info("Controlling new OHCI device '%s'.\n", d evice->name);61 usb_log_info("Controlling new OHCI device '%s'.\n", ddf_dev_get_name(device)); 62 62 63 63 return EOK; 64 64 } 65 /*----------------------------------------------------------------------------*/ 65 66 66 static driver_ops_t ohci_driver_ops = { 67 67 .dev_add = ohci_dev_add, 68 68 }; 69 /*----------------------------------------------------------------------------*/ 69 70 70 static driver_t ohci_driver = { 71 71 .name = NAME, 72 72 .driver_ops = &ohci_driver_ops 73 73 }; 74 /*----------------------------------------------------------------------------*/ 74 75 75 /** Initializes global driver structures (NONE). 76 76 * -
uspace/drv/bus/usb/ohci/ohci.c
re0d5bc5 r96e01fbc 33 33 * @brief OHCI driver 34 34 */ 35 36 /* XXX Fix this */ 37 #define _DDF_DATA_IMPLANT 38 35 39 #include <errno.h> 36 40 #include <str_error.h> … … 52 56 } ohci_t; 53 57 54 static inline ohci_t * dev_to_ohci(ddf_dev_t *dev) 55 { 56 assert(dev); 57 return dev->driver_data; 58 static inline ohci_t *dev_to_ohci(ddf_dev_t *dev) 59 { 60 return ddf_dev_data_get(dev); 58 61 } 59 62 /** IRQ handling callback, identifies device … … 75 78 hc_interrupt(&ohci->hc, status); 76 79 } 77 /*----------------------------------------------------------------------------*/ 80 78 81 /** Get USB address assigned to root hub. 79 82 * … … 87 90 88 91 if (address != NULL) { 89 *address = dev_to_ohci( fun->dev)->hc.rh.address;92 *address = dev_to_ohci(ddf_fun_get_dev(fun))->hc.rh.address; 90 93 } 91 94 92 95 return EOK; 93 96 } 94 /*----------------------------------------------------------------------------*/ 97 95 98 /** Gets handle of the respective hc (this device, hc function). 96 99 * … … 103 106 { 104 107 assert(fun); 105 ddf_fun_t *hc_fun = dev_to_ohci( fun->dev)->hc_fun;108 ddf_fun_t *hc_fun = dev_to_ohci(ddf_fun_get_dev(fun))->hc_fun; 106 109 assert(hc_fun); 107 110 108 111 if (handle != NULL) 109 *handle = hc_fun->handle;112 *handle = ddf_fun_get_handle(hc_fun); 110 113 return EOK; 111 114 } 112 /*----------------------------------------------------------------------------*/ 115 113 116 /** Root hub USB interface */ 114 117 static usb_iface_t usb_iface = { … … 116 119 .get_my_address = rh_get_my_address, 117 120 }; 118 /*----------------------------------------------------------------------------*/ 121 119 122 /** Standard USB HC options (HC interface) */ 120 123 static ddf_dev_ops_t hc_ops = { 121 124 .interfaces[USBHC_DEV_IFACE] = &hcd_iface, 122 125 }; 123 /*----------------------------------------------------------------------------*/ 126 124 127 /** Standard USB RH options (RH interface) */ 125 128 static ddf_dev_ops_t rh_ops = { 126 129 .interfaces[USB_DEV_IFACE] = &usb_iface, 127 130 }; 128 /*----------------------------------------------------------------------------*/ 131 129 132 /** Initialize hc and rh ddf structures and their respective drivers. 130 133 * … … 152 155 if (ret != EOK) { \ 153 156 if (instance->hc_fun) { \ 154 instance->hc_fun->driver_data = NULL; \155 157 ddf_fun_destroy(instance->hc_fun); \ 156 158 } \ 157 159 if (instance->rh_fun) { \ 158 instance->rh_fun->driver_data = NULL; \159 160 ddf_fun_destroy(instance->rh_fun); \ 160 161 } \ … … 167 168 CHECK_RET_DEST_FREE_RETURN(ret, 168 169 "Failed to create OHCI HC function: %s.\n", str_error(ret)); 169 instance->hc_fun->ops = &hc_ops;170 instance->hc_fun->driver_data = &instance->hc;170 ddf_fun_set_ops(instance->hc_fun, &hc_ops); 171 ddf_fun_data_implant(instance->hc_fun, &instance->hc); 171 172 172 173 instance->rh_fun = ddf_fun_create(device, fun_inner, "ohci_rh"); … … 174 175 CHECK_RET_DEST_FREE_RETURN(ret, 175 176 "Failed to create OHCI RH function: %s.\n", str_error(ret)); 176 instance->rh_fun->ops = &rh_ops;177 ddf_fun_set_ops(instance->rh_fun, &rh_ops); 177 178 178 179 uintptr_t reg_base = 0; … … 183 184 CHECK_RET_DEST_FREE_RETURN(ret, 184 185 "Failed to get register memory addresses for %" PRIun ": %s.\n", 185 d evice->handle, str_error(ret));186 ddf_dev_get_handle(device), str_error(ret)); 186 187 usb_log_debug("Memory mapped regs at %p (size %zu), IRQ %d.\n", 187 188 (void *) reg_base, reg_size, irq); -
uspace/drv/bus/usb/ohci/ohci_batch.c
re0d5bc5 r96e01fbc 44 44 45 45 static void (*const batch_setup[])(ohci_transfer_batch_t*, usb_direction_t); 46 /*----------------------------------------------------------------------------*/ 46 47 47 /** Safely destructs ohci_transfer_batch_t structure 48 48 * … … 67 67 free(ohci_batch); 68 68 } 69 /*----------------------------------------------------------------------------*/ 69 70 70 /** Finishes usb_transfer_batch and destroys the structure. 71 71 * … … 80 80 ohci_transfer_batch_dispose(ohci_batch); 81 81 } 82 /*----------------------------------------------------------------------------*/ 82 83 83 /** Allocate memory and initialize internal data structure. 84 84 * … … 158 158 #undef CHECK_NULL_DISPOSE_RET 159 159 } 160 /*----------------------------------------------------------------------------*/ 160 161 161 /** Check batch TDs' status. 162 162 * … … 199 199 ohci_batch->tds[i]->next, ohci_batch->tds[i]->be); 200 200 201 /* If the TD got all its data through, it will report 0 bytes202 * remain, the sole exception is INPUT with data rounding flag203 * (short), i.e. every INPUT. Nice thing is that short packets204 * will correctly report remaining data, thus making205 * this computation correct (short packets need to be produced206 * by the last TD)207 * NOTE: This also works for CONTROL transfer as208 * the first TD will return 0 remain.209 * NOTE: Short packets don't break the assumption that210 * we leave the very last(unused) TD behind.211 */212 ohci_batch->usb_batch->transfered_size213 -= td_remain_size(ohci_batch->tds[i]);214 215 201 ohci_batch->usb_batch->error = td_error(ohci_batch->tds[i]); 216 if (ohci_batch->usb_batch->error != EOK) { 202 if (ohci_batch->usb_batch->error == EOK) { 203 /* If the TD got all its data through, it will report 204 * 0 bytes remain, the sole exception is INPUT with 205 * data rounding flag (short), i.e. every INPUT. 206 * Nice thing is that short packets will correctly 207 * report remaining data, thus making this computation 208 * correct (short packets need to be produced by the 209 * last TD) 210 * NOTE: This also works for CONTROL transfer as 211 * the first TD will return 0 remain. 212 * NOTE: Short packets don't break the assumption that 213 * we leave the very last(unused) TD behind. 214 */ 215 ohci_batch->usb_batch->transfered_size 216 -= td_remain_size(ohci_batch->tds[i]); 217 } else { 217 218 usb_log_debug("Batch %p found error TD(%zu):%08x.\n", 218 219 ohci_batch->usb_batch, i, … … 231 232 232 233 /* Check TD assumption */ 233 const uint32_t pa = 234 addr_to_phys(ohci_batch->tds[leave_td]); 235 assert((ohci_batch->ed->td_head & ED_TDHEAD_PTR_MASK) 236 == pa); 237 234 assert(ed_head_td(ohci_batch->ed) == 235 addr_to_phys(ohci_batch->tds[leave_td])); 236 237 /* Set tail to the same TD */ 238 238 ed_set_tail_td(ohci_batch->ed, 239 239 ohci_batch->tds[leave_td]); 240 240 241 241 /* Clear possible ED HALT */ 242 ohci_batch->ed->td_head &= ~ED_TDHEAD_HALTED_FLAG;242 ed_clear_halt(ohci_batch->ed); 243 243 break; 244 244 } … … 253 253 254 254 /* Make sure that we are leaving the right TD behind */ 255 const uint32_t pa = addr_to_phys(ohci_ep->td); 256 assert(pa == (ohci_batch->ed->td_head & ED_TDHEAD_PTR_MASK)); 257 assert(pa == (ohci_batch->ed->td_tail & ED_TDTAIL_PTR_MASK)); 255 assert(addr_to_phys(ohci_ep->td) == ed_head_td(ohci_batch->ed)); 256 assert(addr_to_phys(ohci_ep->td) == ed_tail_td(ohci_batch->ed)); 258 257 259 258 return true; 260 259 } 261 /*----------------------------------------------------------------------------*/ 260 262 261 /** Starts execution of the TD list 263 262 * … … 269 268 ed_set_tail_td(ohci_batch->ed, ohci_batch->tds[ohci_batch->td_count]); 270 269 } 271 /*----------------------------------------------------------------------------*/ 270 272 271 /** Prepare generic control transfer 273 272 * … … 345 344 USB_TRANSFER_BATCH_ARGS(*ohci_batch->usb_batch)); 346 345 } 347 /*----------------------------------------------------------------------------*/ 346 348 347 /** Prepare generic data transfer 349 348 * … … 392 391 USB_TRANSFER_BATCH_ARGS(*ohci_batch->usb_batch)); 393 392 } 394 /*----------------------------------------------------------------------------*/ 393 395 394 /** Transfer setup table. */ 396 395 static void (*const batch_setup[])(ohci_transfer_batch_t*, usb_direction_t) = -
uspace/drv/bus/usb/ohci/ohci_batch.h
re0d5bc5 r96e01fbc 63 63 void ohci_transfer_batch_commit(const ohci_transfer_batch_t *batch); 64 64 void ohci_transfer_batch_finish_dispose(ohci_transfer_batch_t *batch); 65 /*----------------------------------------------------------------------------*/ 65 66 66 static inline ohci_transfer_batch_t *ohci_transfer_batch_from_link(link_t *l) 67 67 { -
uspace/drv/bus/usb/ohci/ohci_endpoint.c
re0d5bc5 r96e01fbc 48 48 ed_toggle_set(instance->ed, toggle); 49 49 } 50 /*----------------------------------------------------------------------------*/ 50 51 51 /** Callback to get value of toggle bit. 52 52 * … … 61 61 return ed_toggle_get(instance->ed); 62 62 } 63 /*----------------------------------------------------------------------------*/ 63 64 64 /** Creates new hcd endpoint representation. 65 65 * … … 93 93 return EOK; 94 94 } 95 /*----------------------------------------------------------------------------*/ 95 96 96 /** Disposes hcd endpoint structure 97 97 * -
uspace/drv/bus/usb/ohci/ohci_regs.h
re0d5bc5 r96e01fbc 35 35 #define DRV_OHCI_OHCI_REGS_H 36 36 #include <sys/types.h> 37 #include <byteorder.h> 38 39 #define OHCI_WR(reg, val) reg = host2uint32_t_le(val) 40 #define OHCI_RD(reg) uint32_t_le2host(reg) 41 #define OHCI_SET(reg, val) reg |= host2uint32_t_le(val) 42 #define OHCI_CLR(reg, val) reg &= host2uint32_t_le(~val) 43 37 44 38 45 #define LEGACY_REGS_OFFSET 0x100 … … 42 49 const ioport32_t revision; 43 50 #define R_REVISION_MASK (0x3f) 44 #define R_REVISION_SHIFT (0)45 51 #define R_LEGACY_FLAG (0x80) 46 52 47 53 ioport32_t control; 48 #define C_CBSR_MASK (0x3)/* Control-bulk service ratio */54 /* Control-bulk service ratio */ 49 55 #define C_CBSR_1_1 (0x0) 50 56 #define C_CBSR_1_2 (0x1) 51 57 #define C_CBSR_1_3 (0x2) 52 58 #define C_CBSR_1_4 (0x3) 53 #define C_CBSR_SHIFT (0) 59 #define C_CBSR_MASK (0x3) 60 #define C_CBSR_SHIFT 0 54 61 55 62 #define C_PLE (1 << 2) /* Periodic list enable */ … … 58 65 #define C_BLE (1 << 5) /* Bulk list enable */ 59 66 60 #define C_HCFS_MASK (0x3)/* Host controller functional state */67 /* Host controller functional state */ 61 68 #define C_HCFS_RESET (0x0) 62 69 #define C_HCFS_RESUME (0x1) 63 70 #define C_HCFS_OPERATIONAL (0x2) 64 71 #define C_HCFS_SUSPEND (0x3) 65 #define C_HCFS_SHIFT (6) 66 67 #define C_HCFS_GET(reg) \ 68 ((reg >> C_HCFS_SHIFT) & C_HCFS_MASK) 69 #define C_HCFS_SET(reg, hcfs_state) \ 72 #define C_HCFS_GET(reg) ((OHCI_RD(reg) >> 6) & 0x3) 73 #define C_HCFS_SET(reg, value) \ 70 74 do { \ 71 reg = (reg & ~(C_HCFS_MASK << C_HCFS_SHIFT)) \ 72 | ((hcfs_state & C_HCFS_MASK) << C_HCFS_SHIFT); \ 75 uint32_t r = OHCI_RD(reg); \ 76 r &= ~(0x3 << 6); \ 77 r |= (value & 0x3) << 6; \ 78 OHCI_WR(reg, r); \ 73 79 } while (0) 74 80 75 76 #define C_IR (1 << 8) /* Interrupt routing, make sure it's 0 */ 77 #define C_RWC (1 << 9) /* Remote wakeup connected, host specific */ 81 #define C_IR (1 << 8) /* Interrupt routing, make sure it's 0 */ 82 #define C_RWC (1 << 9) /* Remote wakeup connected, host specific */ 78 83 #define C_RWE (1 << 10) /* Remote wakeup enable */ 79 84 … … 83 88 #define CS_BLF (1 << 2) /* Bulk list filled */ 84 89 #define CS_OCR (1 << 3) /* Ownership change request */ 90 #if 0 85 91 #define CS_SOC_MASK (0x3) /* Scheduling overrun count */ 86 92 #define CS_SOC_SHIFT (16) 93 #endif 87 94 88 95 /** Interupt enable/disable/status, … … 101 108 #define I_RHSC (1 << 6) /* Root hub status change */ 102 109 #define I_OC (1 << 30) /* Ownership change */ 103 #define I_MI (1 << 31) /* Master interrupt (a ll/any interrupts) */110 #define I_MI (1 << 31) /* Master interrupt (any/all) */ 104 111 105 112 /** HCCA pointer (see hw_struct hcca.h) */ … … 145 152 /** Remaining bit time in frame to start periodic transfers */ 146 153 ioport32_t periodic_start; 147 #define PS_PS_MASK (0x3fff) /* bit time when periodic get priority (0x3e67) */ 154 #define PS_MASK 0x3fff 155 #define PS_SHIFT 0 148 156 149 157 /** Threshold for starting LS transaction */ … … 153 161 /** The first root hub control register */ 154 162 ioport32_t rh_desc_a; 155 #define RHDA_NDS_MASK (0xff) /* Number of downstream ports, max 15 */ 156 #define RHDA_NDS_SHIFT (0) 157 #define RHDA_PSM_FLAG (1 << 8) /* Power switching mode: 0-global, 1-per port*/ 158 #define RHDA_NPS_FLAG (1 << 9) /* No power switch: 1-power on, 0-use PSM*/ 159 #define RHDA_DT_FLAG (1 << 10) /* 1-Compound device, must be 0 */ 160 #define RHDA_OCPM_FLAG (1 << 11) /* Over-current mode: 0-global, 1-per port */ 161 #define RHDA_NOCP_FLAG (1 << 12) /* OC control: 0-use OCPM, 1-OC off */ 162 #define RHDA_POTPGT_MASK (0xff) /* Power on to power good time */ 163 #define RHDA_POTPGT_SHIFT (24) 163 /** Number of downstream ports, max 15 */ 164 #define RHDA_NDS_MASK (0xff) 165 /** Power switching mode: 0-global, 1-per port*/ 166 #define RHDA_PSM_FLAG (1 << 8) 167 /** No power switch: 1-power on, 0-use PSM*/ 168 #define RHDA_NPS_FLAG (1 << 9) 169 /** 1-Compound device, must be 0 */ 170 #define RHDA_DT_FLAG (1 << 10) 171 /** Over-current mode: 0-global, 1-per port */ 172 #define RHDA_OCPM_FLAG (1 << 11) 173 /** OC control: 0-use OCPM, 1-OC off */ 174 #define RHDA_NOCP_FLAG (1 << 12) 175 /** Power on to power good time */ 176 #define RHDA_POTPGT_SHIFT 24 164 177 165 178 /** The other root hub control register */ 166 179 ioport32_t rh_desc_b; 167 #define RHDB_DR_MASK (0xffff) /* Device removable mask */ 168 #define RHDB_DR_SHIFT (0) 169 #define RHDB_PCC_MASK (0xffff) /* Power control mask */ 170 #define RHDB_PCC_SHIFT (16) 171 172 /* Port device removable status */ 173 #define RHDB_DR_FLAG(port) (((1 << port) & RHDB_DR_MASK) << RHDB_DR_SHIFT) 174 /* Port power control status: 1-per port power control, 0-global power switch */ 175 #define RHDB_PPC_FLAG(port) (((1 << port) & RHDB_DR_MASK) << RHDB_DR_SHIFT) 180 /** Device removable mask */ 181 #define RHDB_DR_SHIFT 0 182 #define RHDB_DR_MASK 0xffff 183 /** Power control mask */ 184 #define RHDB_PCC_MASK (0xffff) 185 #define RHDB_PCC_SHIFT 16 176 186 177 187 /** Root hub status register */ 178 188 ioport32_t rh_status; 179 #define RHS_LPS_FLAG (1 << 0)/* read: 0, 180 * write: 0-no effect, 181 * 1-turn off port power for ports 182 * specified in PPCM(RHDB), or all ports, 183 * if power is set globally */ 189 /* read: 0, 190 * write: 0-no effect, 191 * 1-turn off port power for ports 192 * specified in PPCM(RHDB), or all ports, 193 * if power is set globally */ 194 #define RHS_LPS_FLAG (1 << 0) 184 195 #define RHS_CLEAR_GLOBAL_POWER RHS_LPS_FLAG /* synonym for the above */ 185 #define RHS_OCI_FLAG (1 << 1)/* Over-current indicator, if per-port: 0 */ 186 #define RHS_DRWE_FLAG (1 << 15)/* read: 0-connect status change does not wake HC 187 * 1-connect status change wakes HC 188 * write: 1-set DRWE, 0-no effect */ 196 /** Over-current indicator, if per-port: 0 */ 197 #define RHS_OCI_FLAG (1 << 1) 198 199 /* read: 0-connect status change does not wake HC 200 * 1-connect status change wakes HC 201 * write: 1-set DRWE, 0-no effect */ 202 #define RHS_DRWE_FLAG (1 << 15) 189 203 #define RHS_SET_DRWE RHS_DRWE_FLAG 190 #define RHS_LPSC_FLAG (1 << 16)/* read: 0, 191 * write: 0-no effect 192 * 1-turn on port power for ports 193 * specified in PPCM(RHDB), or all ports, 194 * if power is set globally */ 204 /* read: 0, 205 * write: 0-no effect 206 * 1-turn on port power for ports 207 * specified in PPCM(RHDB), or all ports, 208 * if power is set globally */ 209 #define RHS_LPSC_FLAG (1 << 16) 195 210 #define RHS_SET_GLOBAL_POWER RHS_LPSC_FLAG /* synonym for the above */ 196 #define RHS_OCIC_FLAG (1 << 17)/* Over-current indicator change */ 211 /** Over-current change indicator*/ 212 #define RHS_OCIC_FLAG (1 << 17) 197 213 #define RHS_CLEAR_DRWE (1 << 31) 198 214 … … 200 216 ioport32_t rh_port_status[]; 201 217 #define RHPS_CCS_FLAG (1 << 0) /* r: current connect status, 202 * w: 1-clear port enable, 0-nothing*/218 * w: 1-clear port enable, 0-N/S*/ 203 219 #define RHPS_CLEAR_PORT_ENABLE RHPS_CCS_FLAG 204 220 #define RHPS_PES_FLAG (1 << 1) /* r: port enable status 205 * w: 1-set port enable, 0-nothing*/221 * w: 1-set port enable, 0-N/S */ 206 222 #define RHPS_SET_PORT_ENABLE RHPS_PES_FLAG 207 223 #define RHPS_PSS_FLAG (1 << 2) /* r: port suspend status 208 * w: 1-set port suspend, 0-nothing*/224 * w: 1-set port suspend, 0-N/S */ 209 225 #define RHPS_SET_PORT_SUSPEND RHPS_PSS_FLAG 210 #define RHPS_POCI_FLAG (1 << 3) /* r: port over-current (if reports are per-port 211 * w: 1-clear port suspend (start resume 212 * if suspened) 213 * 0-nothing */ 226 #define RHPS_POCI_FLAG (1 << 3) /* r: port over-current 227 * (if reports are per-port 228 * w: 1-clear port suspend 229 * (start resume if suspened) 230 * 0-nothing */ 214 231 #define RHPS_CLEAR_PORT_SUSPEND RHPS_POCI_FLAG 215 232 #define RHPS_PRS_FLAG (1 << 4) /* r: port reset status 216 * w: 1-set port reset, 0-nothing*/233 * w: 1-set port reset, 0-N/S */ 217 234 #define RHPS_SET_PORT_RESET RHPS_PRS_FLAG 218 235 #define RHPS_PPS_FLAG (1 << 8) /* r: port power status 219 * w: 1-set port power, 0-nothing*/236 * w: 1-set port power, 0-N/S */ 220 237 #define RHPS_SET_PORT_POWER RHPS_PPS_FLAG 221 238 #define RHPS_LSDA_FLAG (1 << 9) /* r: low speed device attached 222 * w: 1-clear port power, 0-nothing*/239 * w: 1-clear port power, 0-N/S*/ 223 240 #define RHPS_CLEAR_PORT_POWER RHPS_LSDA_FLAG 224 #define RHPS_CSC_FLAG (1 << 16) /* connect status change W rite-Clean*/241 #define RHPS_CSC_FLAG (1 << 16) /* connect status change WC */ 225 242 #define RHPS_PESC_FLAG (1 << 17) /* port enable status change WC */ 226 243 #define RHPS_PSSC_FLAG (1 << 18) /* port suspend status change WC */ 227 244 #define RHPS_OCIC_FLAG (1 << 19) /* port over-current change WC */ 228 245 #define RHPS_PRSC_FLAG (1 << 20) /* port reset status change WC */ 229 #define RHPS_CHANGE_WC_MASK 0x1f0000246 #define RHPS_CHANGE_WC_MASK (0x1f0000) 230 247 } ohci_regs_t; 231 248 #endif -
uspace/drv/bus/usb/ohci/res.c
re0d5bc5 r96e01fbc 53 53 * @return Error code. 54 54 */ 55 int get_my_registers( constddf_dev_t *dev,55 int get_my_registers(ddf_dev_t *dev, 56 56 uintptr_t *mem_reg_address, size_t *mem_reg_size, int *irq_no) 57 57 { … … 59 59 60 60 async_sess_t *parent_sess = 61 devman_parent_device_connect(EXCHANGE_SERIALIZE, dev->handle,62 IPC_FLAG_BLOCKING);61 devman_parent_device_connect(EXCHANGE_SERIALIZE, 62 ddf_dev_get_handle(dev), IPC_FLAG_BLOCKING); 63 63 if (!parent_sess) 64 64 return ENOMEM; … … 94 94 * @return Error code. 95 95 */ 96 int enable_interrupts( constddf_dev_t *device)96 int enable_interrupts(ddf_dev_t *device) 97 97 { 98 98 async_sess_t *parent_sess = 99 devman_parent_device_connect(EXCHANGE_SERIALIZE, device->handle,100 IPC_FLAG_BLOCKING);99 devman_parent_device_connect(EXCHANGE_SERIALIZE, 100 ddf_dev_get_handle(device), IPC_FLAG_BLOCKING); 101 101 if (!parent_sess) 102 102 return ENOMEM; -
uspace/drv/bus/usb/ohci/res.h
re0d5bc5 r96e01fbc 37 37 #include <ddf/driver.h> 38 38 39 int get_my_registers( constddf_dev_t *, uintptr_t *, size_t *, int *);40 int enable_interrupts( constddf_dev_t *);39 int get_my_registers(ddf_dev_t *, uintptr_t *, size_t *, int *); 40 int enable_interrupts(ddf_dev_t *); 41 41 42 42 #endif -
uspace/drv/bus/usb/ohci/root_hub.c
re0d5bc5 r96e01fbc 33 33 */ 34 34 #include <assert.h> 35 #include <byteorder.h> 35 36 #include <errno.h> 36 37 #include <str_error.h> 37 38 #include <fibril_synch.h> 38 39 40 #include <usb/usb.h> 39 41 #include <usb/debug.h> 40 42 #include <usb/dev/request.h> 41 43 #include <usb/classes/hub.h> 42 44 43 #include "root_hub.h"44 45 #include <usb/classes/classes.h> 45 46 #include <usb/classes/hub.h> 46 47 #include <usb/dev/driver.h> 47 48 #include "ohci_regs.h" 49 #include "root_hub.h" 48 50 49 51 /** … … 122 124 { 123 125 assert(request); 126 usb_log_debug("Sending interrupt vector(%zu) %hhx:%hhx.\n", 127 size, ((uint8_t*)&mask)[0], ((uint8_t*)&mask)[1]); 124 128 usb_transfer_batch_finish_error(request, &mask, size, EOK); 125 129 usb_transfer_batch_destroy(request); … … 150 154 151 155 instance->registers = regs; 152 instance->port_count = 153 (instance->registers->rh_desc_a >> RHDA_NDS_SHIFT) & RHDA_NDS_MASK;156 instance->port_count = OHCI_RD(regs->rh_desc_a) & RHDA_NDS_MASK; 157 usb_log_debug2("rh_desc_a: %x.\n", OHCI_RD(regs->rh_desc_a)); 154 158 if (instance->port_count > 15) { 155 159 usb_log_warning("OHCI specification does not allow more than 15" … … 163 167 164 168 #if defined OHCI_POWER_SWITCH_no 169 usb_log_debug("OHCI rh: Set power mode to no power switching.\n"); 165 170 /* Set port power mode to no power-switching. (always on) */ 166 instance->registers->rh_desc_a |= RHDA_NPS_FLAG;171 OHCI_SET(regs->rh_desc_a, RHDA_NPS_FLAG); 167 172 168 173 /* Set to no over-current reporting */ 169 instance->registers->rh_desc_a |= RHDA_NOCP_FLAG;174 OHCI_SET(regs->rh_desc_a, RHDA_NOCP_FLAG); 170 175 171 176 #elif defined OHCI_POWER_SWITCH_ganged 172 /* Set port power mode to no ganged power-switching. */ 173 instance->registers->rh_desc_a &= ~RHDA_NPS_FLAG; 174 instance->registers->rh_desc_a &= ~RHDA_PSM_FLAG; 175 instance->registers->rh_status = RHS_CLEAR_GLOBAL_POWER; 177 usb_log_debug("OHCI rh: Set power mode to ganged power switching.\n"); 178 /* Set port power mode to ganged power-switching. */ 179 OHCI_CLR(regs->rh_desc_a, RHDA_NPS_FLAG); 180 OHCI_CLR(regs->rh_desc_a, RHDA_PSM_FLAG); 181 182 /* Turn off power (hub driver will turn this back on)*/ 183 OHCI_WR(regs->rh_status, RHS_CLEAR_GLOBAL_POWER); 176 184 177 185 /* Set to global over-current */ 178 instance->registers->rh_desc_a &= ~RHDA_NOCP_FLAG;179 instance->registers->rh_desc_a &= ~RHDA_OCPM_FLAG;186 OHCI_CLR(regs->rh_desc_a, RHDA_NOCP_FLAG); 187 OHCI_CLR(regs->rh_desc_a, RHDA_OCPM_FLAG); 180 188 #else 181 /* Set port power mode to no per port power-switching. */ 182 instance->registers->rh_desc_a &= ~RHDA_NPS_FLAG; 183 instance->registers->rh_desc_a |= RHDA_PSM_FLAG; 189 usb_log_debug("OHCI rh: Set power mode to per-port power switching.\n"); 190 /* Set port power mode to per port power-switching. */ 191 OHCI_CLR(regs->rh_desc_a, RHDA_NPS_FLAG); 192 OHCI_SET(regs->rh_desc_a, RHDA_PSM_FLAG); 184 193 185 194 /* Control all ports by global switch and turn them off */ 186 instance->registers->rh_desc_b &= (RHDB_PCC_MASK << RHDB_PCC_SHIFT);187 instance->registers->rh_status = RHS_CLEAR_GLOBAL_POWER;195 OHCI_CLR(regs->rh_desc_b, RHDB_PCC_MASK << RHDB_PCC_SHIFT); 196 OHCI_WR(regs->rh_status, RHS_CLEAR_GLOBAL_POWER); 188 197 189 198 /* Return control to per port state */ 190 instance->registers->rh_desc_b |= 191 ((1 << (instance->port_count + 1)) - 1) << RHDB_PCC_SHIFT; 199 OHCI_SET(regs->rh_desc_b, RHDB_PCC_MASK << RHDB_PCC_SHIFT); 192 200 193 201 /* Set per port over-current */ 194 instance->registers->rh_desc_a &= ~RHDA_NOCP_FLAG;195 instance->registers->rh_desc_a |= RHDA_OCPM_FLAG;202 OHCI_CLR(regs->rh_desc_a, RHDA_NOCP_FLAG); 203 OHCI_SET(regs->rh_desc_a, RHDA_OCPM_FLAG); 196 204 #endif 197 205 … … 202 210 instance->port_count); 203 211 } 204 /*----------------------------------------------------------------------------*/ 212 205 213 /** 206 214 * Process root hub request. … … 226 234 fibril_mutex_lock(&instance->guard); 227 235 assert(instance->unfinished_interrupt_transfer == NULL); 228 uint16_t mask = create_interrupt_mask(instance);236 const uint16_t mask = create_interrupt_mask(instance); 229 237 if (mask == 0) { 230 usb_log_debug("No changes ...\n");238 usb_log_debug("No changes(%hx)...\n", mask); 231 239 instance->unfinished_interrupt_transfer = request; 232 240 } else { … … 243 251 } 244 252 } 245 /*----------------------------------------------------------------------------*/ 253 246 254 /** 247 255 * Process interrupt on a hub device. … … 257 265 if (instance->unfinished_interrupt_transfer) { 258 266 usb_log_debug("Finalizing interrupt transfer\n"); 259 uint16_t mask = create_interrupt_mask(instance);267 const uint16_t mask = create_interrupt_mask(instance); 260 268 interrupt_request(instance->unfinished_interrupt_transfer, 261 269 mask, instance->interrupt_mask_size); … … 264 272 fibril_mutex_unlock(&instance->guard); 265 273 } 266 /*----------------------------------------------------------------------------*/ 274 267 275 /** 268 276 * Create hub descriptor. … … 282 290 instance->hub_descriptor_size = size; 283 291 284 uint32_t hub_desc = instance->registers->rh_desc_a;285 uint32_t port_desc = instance->registers->rh_desc_b;292 const uint32_t hub_desc = OHCI_RD(instance->registers->rh_desc_a); 293 const uint32_t port_desc = OHCI_RD(instance->registers->rh_desc_b); 286 294 287 295 /* bDescLength */ … … 305 313 instance->descriptors.hub[4] = 0; 306 314 /* bPwrOn2PwrGood */ 307 instance->descriptors.hub[5] = 308 (hub_desc >> RHDA_POTPGT_SHIFT) & RHDA_POTPGT_MASK; 315 instance->descriptors.hub[5] = hub_desc >> RHDA_POTPGT_SHIFT; 309 316 /* bHubContrCurrent, root hubs don't need no power. */ 310 317 instance->descriptors.hub[6] = 0; 311 318 312 319 /* Device Removable and some legacy 1.0 stuff*/ 313 instance->descriptors.hub[7] = 314 (port_desc >> RHDB_DR_SHIFT) & RHDB_DR_MASK & 0xff; 320 instance->descriptors.hub[7] = (port_desc >> RHDB_DR_SHIFT) & 0xff; 315 321 instance->descriptors.hub[8] = 0xff; 316 322 if (instance->interrupt_mask_size == 2) { 317 323 instance->descriptors.hub[8] = 318 (port_desc >> RHDB_DR_SHIFT) & RHDB_DR_MASK>> 8;324 (port_desc >> RHDB_DR_SHIFT) >> 8; 319 325 instance->descriptors.hub[9] = 0xff; 320 326 instance->descriptors.hub[10] = 0xff; 321 327 } 322 328 } 323 /*----------------------------------------------------------------------------*/ 329 324 330 /** Initialize hub descriptors. 325 331 * … … 341 347 instance->interrupt_mask_size; 342 348 343 instance->descriptors.configuration.total_length = 349 instance->descriptors.configuration.total_length = uint16_host2usb( 344 350 sizeof(usb_standard_configuration_descriptor_t) + 345 351 sizeof(usb_standard_endpoint_descriptor_t) + 346 352 sizeof(usb_standard_interface_descriptor_t) + 347 instance->hub_descriptor_size ;348 } 349 /*----------------------------------------------------------------------------*/ 353 instance->hub_descriptor_size); 354 } 355 350 356 /** 351 357 * Create bitmap of changes to answer status interrupt. … … 364 370 365 371 /* Only local power source change and over-current change can happen */ 366 if (instance->registers->rh_status & (RHS_LPSC_FLAG | RHS_OCIC_FLAG)) { 372 if (OHCI_RD(instance->registers->rh_status) 373 & (RHS_LPSC_FLAG | RHS_OCIC_FLAG)) { 367 374 mask |= 1; 368 375 } 369 376 for (size_t port = 1; port <= instance->port_count; ++port) { 370 377 /* Write-clean bits are those that indicate change */ 371 if (RHPS_CHANGE_WC_MASK 372 & instance->registers->rh_port_status[port - 1]) { 373 378 if (OHCI_RD(instance->registers->rh_port_status[port - 1]) 379 & RHPS_CHANGE_WC_MASK) { 374 380 mask |= (1 << port); 375 381 } 376 382 } 377 /* USB is little endian */378 return host2uint32_t_le(mask);379 } 380 /*----------------------------------------------------------------------------*/ 383 usb_log_debug2("OHCI root hub interrupt mask: %hx.\n", mask); 384 return uint16_host2usb(mask); 385 } 386 381 387 /** 382 388 * Create answer to status request. … … 396 402 usb_device_request_setup_packet_t *request_packet = 397 403 (usb_device_request_setup_packet_t*)request->setup_buffer; 404 405 const uint16_t index = uint16_usb2host(request_packet->index); 398 406 399 407 switch (request_packet->request_type) … … 406 414 TRANSFER_END(request, EOVERFLOW); 407 415 } else { 408 uint32_t data = instance->registers->rh_status & 409 (RHS_LPS_FLAG | RHS_LPSC_FLAG 410 | RHS_OCI_FLAG | RHS_OCIC_FLAG); 416 const uint32_t data = 417 OHCI_RD(instance->registers->rh_status) & 418 (RHS_LPS_FLAG | RHS_LPSC_FLAG 419 | RHS_OCI_FLAG | RHS_OCIC_FLAG); 411 420 TRANSFER_END_DATA(request, &data, sizeof(data)); 412 421 } … … 420 429 TRANSFER_END(request, EOVERFLOW); 421 430 } else { 422 unsigned port = request_packet->index;431 const unsigned port = index; 423 432 if (port < 1 || port > instance->port_count) 424 433 TRANSFER_END(request, EINVAL); 425 426 uint32_t data = 427 instance->registers->rh_port_status[port - 1]; 434 /* Register format matches the format of port status 435 * field */ 436 const uint32_t data = uint32_host2usb(OHCI_RD( 437 instance->registers->rh_port_status[port - 1])); 428 438 TRANSFER_END_DATA(request, &data, sizeof(data)); 429 439 } … … 434 444 TRANSFER_END(request, EOVERFLOW); 435 445 } else { 436 uint16_t data =446 const uint16_t data = 437 447 uint16_host2usb(USB_DEVICE_STATUS_SELF_POWERED); 438 448 TRANSFER_END_DATA(request, &data, sizeof(data)); … … 441 451 case SETUP_REQUEST_TO_HOST(USB_REQUEST_TYPE_STANDARD, USB_REQUEST_RECIPIENT_INTERFACE): 442 452 /* Hubs are allowed to have only one interface */ 443 if ( request_packet->index != 0)453 if (index != 0) 444 454 TRANSFER_END(request, EINVAL); 445 455 /* Fall through, as the answer will be the same: 0x0000 */ 446 456 case SETUP_REQUEST_TO_HOST(USB_REQUEST_TYPE_STANDARD, USB_REQUEST_RECIPIENT_ENDPOINT): 447 457 /* Endpoint 0 (default control) and 1 (interrupt) */ 448 if ( request_packet->index >= 2)458 if (index >= 2) 449 459 TRANSFER_END(request, EINVAL); 450 460 … … 455 465 } else { 456 466 /* Endpoints are OK. (We don't halt) */ 457 uint16_t data = 0;467 const uint16_t data = 0; 458 468 TRANSFER_END_DATA(request, &data, sizeof(data)); 459 469 } … … 465 475 466 476 } 467 /*----------------------------------------------------------------------------*/ 477 468 478 /** 469 479 * Create answer to a descriptor request. … … 482 492 usb_device_request_setup_packet_t *setup_request = 483 493 (usb_device_request_setup_packet_t *) request->setup_buffer; 484 uint16_t setup_request_value = setup_request->value_high; 485 switch (setup_request_value) 494 /* "The wValue field specifies the descriptor type in the high byte 495 * and the descriptor index in the low byte (refer to Table 9-5)." */ 496 const int desc_type = uint16_usb2host(setup_request->value) >> 8; 497 switch (desc_type) 486 498 { 487 499 case USB_DESCTYPE_HUB: … … 530 542 setup_request->value, 531 543 setup_request->request_type, setup_request->request, 532 setup_request_value, setup_request->index,544 desc_type, setup_request->index, 533 545 setup_request->length); 534 546 TRANSFER_END(request, EINVAL); … … 537 549 TRANSFER_END(request, ENOTSUP); 538 550 } 539 /*----------------------------------------------------------------------------*/ 551 540 552 /** 541 553 * process feature-enabling request on hub … … 554 566 return EINVAL; 555 567 556 switch (feature) 557 { 558 case USB_HUB_FEATURE_PORT_POWER: //8 559 /* No power switching */ 560 if (instance->registers->rh_desc_a & RHDA_NPS_FLAG) 561 return EOK; 562 /* Ganged power switching */ 563 if (!(instance->registers->rh_desc_a & RHDA_PSM_FLAG)) { 564 instance->registers->rh_status = RHS_SET_GLOBAL_POWER; 565 return EOK; 568 switch (feature) { 569 case USB_HUB_FEATURE_PORT_POWER: /*8*/ 570 { 571 const uint32_t rhda = 572 OHCI_RD(instance->registers->rh_desc_a); 573 /* No power switching */ 574 if (rhda & RHDA_NPS_FLAG) 575 return EOK; 576 /* Ganged power switching, one port powers all */ 577 if (!(rhda & RHDA_PSM_FLAG)) { 578 OHCI_WR(instance->registers->rh_status, 579 RHS_SET_GLOBAL_POWER); 580 return EOK; 581 } 566 582 } 567 case USB_HUB_FEATURE_PORT_ENABLE: //1 568 case USB_HUB_FEATURE_PORT_SUSPEND: //2 569 case USB_HUB_FEATURE_PORT_RESET: //4 570 /* Nice thing is that these shifts correspond to the position 571 * of control bits in register */ 572 instance->registers->rh_port_status[port - 1] = (1 << feature); 583 /* Fall through */ 584 case USB_HUB_FEATURE_PORT_ENABLE: /*1*/ 585 case USB_HUB_FEATURE_PORT_SUSPEND: /*2*/ 586 case USB_HUB_FEATURE_PORT_RESET: /*4*/ 587 usb_log_debug2("Setting port POWER, ENABLE, SUSPEND or RESET " 588 "on port %"PRIu16".\n", port); 589 OHCI_WR(instance->registers->rh_port_status[port - 1], 590 1 << feature); 573 591 return EOK; 574 592 default: … … 576 594 } 577 595 } 578 /*----------------------------------------------------------------------------*/ 596 579 597 /** 580 598 * Process feature clear request. … … 596 614 switch (feature) 597 615 { 598 case USB_HUB_FEATURE_PORT_POWER: //8 599 /* No power switching */ 600 if (instance->registers->rh_desc_a & RHDA_NPS_FLAG) 601 return ENOTSUP; 602 /* Ganged power switching */ 603 if (!(instance->registers->rh_desc_a & RHDA_PSM_FLAG)) { 604 instance->registers->rh_status = RHS_CLEAR_GLOBAL_POWER; 616 case USB_HUB_FEATURE_PORT_POWER: /*8*/ 617 { 618 const uint32_t rhda = 619 OHCI_RD(instance->registers->rh_desc_a); 620 /* No power switching */ 621 if (rhda & RHDA_NPS_FLAG) 622 return ENOTSUP; 623 /* Ganged power switching, one port powers all */ 624 if (!(rhda & RHDA_PSM_FLAG)) { 625 OHCI_WR(instance->registers->rh_status, 626 RHS_CLEAR_GLOBAL_POWER); 627 return EOK; 628 } 629 OHCI_WR(instance->registers->rh_port_status[port - 1], 630 RHPS_CLEAR_PORT_POWER); 605 631 return EOK; 606 632 } 607 instance->registers->rh_port_status[port - 1] = 608 RHPS_CLEAR_PORT_POWER; 633 634 case USB_HUB_FEATURE_PORT_ENABLE: /*1*/ 635 OHCI_WR(instance->registers->rh_port_status[port - 1], 636 RHPS_CLEAR_PORT_ENABLE); 609 637 return EOK; 610 638 611 case USB_HUB_FEATURE_PORT_ ENABLE: //1612 instance->registers->rh_port_status[port - 1] =613 RHPS_CLEAR_PORT_ENABLE;639 case USB_HUB_FEATURE_PORT_SUSPEND: /*2*/ 640 OHCI_WR(instance->registers->rh_port_status[port - 1], 641 RHPS_CLEAR_PORT_SUSPEND); 614 642 return EOK; 615 643 616 case USB_HUB_FEATURE_PORT_SUSPEND: //2 617 instance->registers->rh_port_status[port - 1] = 618 RHPS_CLEAR_PORT_SUSPEND; 619 return EOK; 620 621 case USB_HUB_FEATURE_C_PORT_CONNECTION: //16 622 case USB_HUB_FEATURE_C_PORT_ENABLE: //17 623 case USB_HUB_FEATURE_C_PORT_SUSPEND: //18 624 case USB_HUB_FEATURE_C_PORT_OVER_CURRENT: //19 625 case USB_HUB_FEATURE_C_PORT_RESET: //20 626 /* Nice thing is that these shifts correspond to the position 627 * of control bits in register */ 628 instance->registers->rh_port_status[port - 1] = (1 << feature); 644 case USB_HUB_FEATURE_C_PORT_CONNECTION: /*16*/ 645 case USB_HUB_FEATURE_C_PORT_ENABLE: /*17*/ 646 case USB_HUB_FEATURE_C_PORT_SUSPEND: /*18*/ 647 case USB_HUB_FEATURE_C_PORT_OVER_CURRENT: /*19*/ 648 case USB_HUB_FEATURE_C_PORT_RESET: /*20*/ 649 usb_log_debug2("Clearing port C_CONNECTION, C_ENABLE, " 650 "C_SUSPEND, C_OC or C_RESET on port %"PRIu16".\n", port); 651 /* Bit offsets correspond to the feature number */ 652 OHCI_WR(instance->registers->rh_port_status[port - 1], 653 1 << feature); 629 654 return EOK; 630 655 … … 633 658 } 634 659 } 635 /*----------------------------------------------------------------------------*/ 660 636 661 /** 637 662 * process one of requests that do not request nor carry additional data … … 654 679 case USB_HUB_REQ_TYPE_SET_PORT_FEATURE: 655 680 usb_log_debug("USB_HUB_REQ_TYPE_SET_PORT_FEATURE\n"); 656 int ret = set_feature_port(instance,681 const int ret = set_feature_port(instance, 657 682 setup_request->value, setup_request->index); 658 683 TRANSFER_END(request, ret); … … 671 696 } 672 697 } 673 /*----------------------------------------------------------------------------*/ 698 674 699 /** 675 700 * process one of requests that do not request nor carry additional data … … 693 718 case USB_HUB_REQ_TYPE_CLEAR_PORT_FEATURE: 694 719 usb_log_debug("USB_HUB_REQ_TYPE_CLEAR_PORT_FEATURE\n"); 695 int ret = clear_feature_port(instance,720 const int ret = clear_feature_port(instance, 696 721 setup_request->value, setup_request->index); 697 722 TRANSFER_END(request, ret); … … 706 731 * as root hubs do not support local power status feature. 707 732 * (OHCI pg. 127) */ 708 if (setup_request->value == USB_HUB_FEATURE_C_HUB_OVER_CURRENT) { 709 instance->registers->rh_status = RHS_OCIC_FLAG; 733 if (uint16_usb2host(setup_request->value) 734 == USB_HUB_FEATURE_C_HUB_OVER_CURRENT) { 735 OHCI_WR(instance->registers->rh_status, RHS_OCIC_FLAG); 710 736 TRANSFER_END(request, EOK); 711 737 } … … 717 743 } 718 744 } 719 /*----------------------------------------------------------------------------*/ 745 720 746 /** 721 747 * Process hub control request. … … 771 797 if (request->buffer_size == 0) 772 798 TRANSFER_END(request, EOVERFLOW); 773 uint8_t config = 1;799 const uint8_t config = 1; 774 800 TRANSFER_END_DATA(request, &config, sizeof(config)); 775 801 … … 790 816 TRANSFER_END(request, EINVAL); 791 817 792 instance->address = setup_request->value;818 instance->address = uint16_usb2host(setup_request->value); 793 819 TRANSFER_END(request, EOK); 794 820 795 821 case USB_DEVREQ_SET_CONFIGURATION: 796 822 usb_log_debug("USB_DEVREQ_SET_CONFIGURATION: %u\n", 797 setup_request->value);823 uint16_usb2host(setup_request->value)); 798 824 /* We have only one configuration, it's number is 1 */ 799 825 if (uint16_usb2host(setup_request->value) != 1) -
uspace/drv/bus/usb/ohci/utils/malloc32.h
re0d5bc5 r96e01fbc 63 63 return result; 64 64 } 65 /*----------------------------------------------------------------------------*/ 65 66 66 /** Physical mallocator simulator 67 67 * … … 71 71 static inline void * malloc32(size_t size) 72 72 { return memalign(OHCI_ALIGN, size); } 73 /*----------------------------------------------------------------------------*/ 73 74 74 /** Physical mallocator simulator 75 75 * -
uspace/drv/bus/usb/uhci/hc.c
re0d5bc5 r96e01fbc 50 50 static const irq_pio_range_t uhci_irq_pio_ranges[] = { 51 51 { 52 .base = 0, /* filled later */52 .base = 0, 53 53 .size = sizeof(uhci_regs_t) 54 54 } … … 56 56 57 57 static const irq_cmd_t uhci_irq_commands[] = { 58 { .cmd = CMD_PIO_READ_16, .dstarg = 1, .addr = NULL/*filled later*/}, 59 { .cmd = CMD_BTEST, .srcarg = 1, .dstarg = 2, 60 .value = UHCI_STATUS_USED_INTERRUPTS | UHCI_STATUS_NM_INTERRUPTS }, 61 { .cmd = CMD_PREDICATE, .srcarg = 2, .value = 2 }, 62 { .cmd = CMD_PIO_WRITE_A_16, .srcarg = 1, .addr = NULL/*filled later*/}, 63 { .cmd = CMD_ACCEPT }, 58 { 59 .cmd = CMD_PIO_READ_16, 60 .dstarg = 1, 61 .addr = NULL 62 }, 63 { 64 .cmd = CMD_AND, 65 .srcarg = 1, 66 .dstarg = 2, 67 .value = UHCI_STATUS_USED_INTERRUPTS | UHCI_STATUS_NM_INTERRUPTS 68 }, 69 { 70 .cmd = CMD_PREDICATE, 71 .srcarg = 2, 72 .value = 2 73 }, 74 { 75 .cmd = CMD_PIO_WRITE_A_16, 76 .srcarg = 1, 77 .addr = NULL 78 }, 79 { 80 .cmd = CMD_ACCEPT 81 } 64 82 }; 65 83 … … 72 90 static int hc_debug_checker(void *arg); 73 91 74 /*----------------------------------------------------------------------------*/ 92 75 93 /** Get number of PIO ranges used in IRQ code. 76 94 * @return Number of ranges. … … 80 98 return sizeof(uhci_irq_pio_ranges) / sizeof(irq_pio_range_t); 81 99 } 82 /*----------------------------------------------------------------------------*/ 100 83 101 /** Get number of commands used in IRQ code. 84 102 * @return Number of commands. … … 88 106 return sizeof(uhci_irq_commands) / sizeof(irq_cmd_t); 89 107 } 90 /*----------------------------------------------------------------------------*/ 108 91 109 /** Generate IRQ code. 92 110 * @param[out] ranges PIO ranges buffer. … … 118 136 return EOK; 119 137 } 120 /*----------------------------------------------------------------------------*/ 138 121 139 /** Take action based on the interrupt cause. 122 140 * … … 175 193 } 176 194 } 177 /*----------------------------------------------------------------------------*/ 195 178 196 /** Initialize UHCI hc driver structure 179 197 * … … 235 253 return EOK; 236 254 } 237 /*----------------------------------------------------------------------------*/ 255 238 256 /** Initialize UHCI hc hw resources. 239 257 * … … 277 295 UHCI_CMD_RUN_STOP | UHCI_CMD_MAX_PACKET | UHCI_CMD_CONFIGURE); 278 296 } 279 /*----------------------------------------------------------------------------*/ 297 280 298 /** Initialize UHCI hc memory structures. 281 299 * … … 319 337 return EOK; 320 338 } 321 /*----------------------------------------------------------------------------*/ 339 322 340 /** Initialize UHCI hc transfer lists. 323 341 * … … 381 399 #undef CHECK_RET_CLEAR_RETURN 382 400 } 383 /*----------------------------------------------------------------------------*/ 401 384 402 /** Schedule batch for execution. 385 403 * … … 409 427 return EOK; 410 428 } 411 /*----------------------------------------------------------------------------*/ 429 412 430 /** Polling function, emulates interrupts. 413 431 * … … 432 450 return EOK; 433 451 } 434 /*----------------------------------------------------------------------------*/ 452 435 453 /** Debug function, checks consistency of memory structures. 436 454 * -
uspace/drv/bus/usb/uhci/hw_struct/queue_head.h
re0d5bc5 r96e01fbc 47 47 volatile link_pointer_t element; 48 48 } __attribute__((packed)) qh_t; 49 /*----------------------------------------------------------------------------*/ 49 50 50 /** Initialize queue head structure 51 51 * … … 61 61 instance->next = LINK_POINTER_TERM; 62 62 } 63 /*----------------------------------------------------------------------------*/ 63 64 64 /** Set queue head next pointer 65 65 * … … 81 81 } 82 82 } 83 /*----------------------------------------------------------------------------*/ 83 84 84 /** Set queue head element pointer 85 85 * -
uspace/drv/bus/usb/uhci/hw_struct/transfer_descriptor.c
re0d5bc5 r96e01fbc 107 107 } 108 108 } 109 /*----------------------------------------------------------------------------*/ 109 110 110 /** Convert TD status into standard error code 111 111 * … … 145 145 return EOK; 146 146 } 147 /*----------------------------------------------------------------------------*/ 147 148 148 /** Print values in status field (dw1) in a human readable way. 149 149 * -
uspace/drv/bus/usb/uhci/hw_struct/transfer_descriptor.h
re0d5bc5 r96e01fbc 100 100 101 101 void td_print_status(const td_t *instance); 102 /*----------------------------------------------------------------------------*/ 102 103 103 /** Helper function for parsing actual size out of TD. 104 104 * … … 113 113 return ((s >> TD_STATUS_ACTLEN_POS) + 1) & TD_STATUS_ACTLEN_MASK; 114 114 } 115 /*----------------------------------------------------------------------------*/ 115 116 116 /** Check whether less than max data were received on SPD marked transfer. 117 117 * … … 129 129 (instance->status | TD_STATUS_SPD_FLAG) && act_size < max_size; 130 130 } 131 /*----------------------------------------------------------------------------*/ 131 132 132 /** Helper function for parsing value of toggle bit. 133 133 * … … 140 140 return (instance->device & TD_DEVICE_DATA_TOGGLE_ONE_FLAG) ? 1 : 0; 141 141 } 142 /*----------------------------------------------------------------------------*/ 142 143 143 /** Helper function for parsing value of active bit 144 144 * … … 151 151 return (instance->status & TD_STATUS_ERROR_ACTIVE) != 0; 152 152 } 153 /*----------------------------------------------------------------------------*/ 153 154 154 /** Helper function for setting IOC bit. 155 155 * … … 161 161 instance->status |= TD_STATUS_IOC_FLAG; 162 162 } 163 /*----------------------------------------------------------------------------*/ 163 164 164 #endif 165 165 /** -
uspace/drv/bus/usb/uhci/main.c
re0d5bc5 r96e01fbc 44 44 45 45 static int uhci_dev_add(ddf_dev_t *device); 46 /*----------------------------------------------------------------------------*/ 46 47 47 static driver_ops_t uhci_driver_ops = { 48 48 .dev_add = uhci_dev_add, 49 49 }; 50 /*----------------------------------------------------------------------------*/ 50 51 51 static driver_t uhci_driver = { 52 52 .name = NAME, 53 53 .driver_ops = &uhci_driver_ops 54 54 }; 55 /*----------------------------------------------------------------------------*/ 55 56 56 /** Initialize a new ddf driver instance for uhci hc and hub. 57 57 * … … 70 70 } else { 71 71 usb_log_info("Controlling new UHCI device '%s'.\n", 72 d evice->name);72 ddf_dev_get_name(device)); 73 73 } 74 74 75 75 return ret; 76 76 } 77 /*----------------------------------------------------------------------------*/ 77 78 78 /** Initialize global driver structures (NONE). 79 79 * -
uspace/drv/bus/usb/uhci/res.c
re0d5bc5 r96e01fbc 51 51 * @return Error code. 52 52 */ 53 int get_my_registers( constddf_dev_t *dev,53 int get_my_registers(ddf_dev_t *dev, 54 54 uintptr_t *io_reg_address, size_t *io_reg_size, int *irq_no) 55 55 { … … 57 57 58 58 async_sess_t *parent_sess = 59 devman_parent_device_connect(EXCHANGE_SERIALIZE, dev->handle,60 IPC_FLAG_BLOCKING);59 devman_parent_device_connect(EXCHANGE_SERIALIZE, 60 ddf_dev_get_handle(dev), IPC_FLAG_BLOCKING); 61 61 if (!parent_sess) 62 62 return ENOMEM; … … 92 92 * @return Error code. 93 93 */ 94 int enable_interrupts( constddf_dev_t *device)94 int enable_interrupts(ddf_dev_t *device) 95 95 { 96 96 async_sess_t *parent_sess = 97 devman_parent_device_connect(EXCHANGE_SERIALIZE, device->handle,98 IPC_FLAG_BLOCKING);97 devman_parent_device_connect(EXCHANGE_SERIALIZE, 98 ddf_dev_get_handle(device), IPC_FLAG_BLOCKING); 99 99 if (!parent_sess) 100 100 return ENOMEM; … … 111 111 * @return Error code. 112 112 */ 113 int disable_legacy( constddf_dev_t *device)113 int disable_legacy(ddf_dev_t *device) 114 114 { 115 115 assert(device); 116 116 117 117 async_sess_t *parent_sess = devman_parent_device_connect( 118 EXCHANGE_SERIALIZE, d evice->handle, IPC_FLAG_BLOCKING);118 EXCHANGE_SERIALIZE, ddf_dev_get_handle(device), IPC_FLAG_BLOCKING); 119 119 if (!parent_sess) 120 120 return ENOMEM; -
uspace/drv/bus/usb/uhci/res.h
re0d5bc5 r96e01fbc 38 38 #include <ddf/driver.h> 39 39 40 int get_my_registers( constddf_dev_t *, uintptr_t *, size_t *, int *);41 int enable_interrupts( constddf_dev_t *);42 int disable_legacy( constddf_dev_t *);40 int get_my_registers(ddf_dev_t *, uintptr_t *, size_t *, int *); 41 int enable_interrupts(ddf_dev_t *); 42 int disable_legacy(ddf_dev_t *); 43 43 44 44 #endif -
uspace/drv/bus/usb/uhci/transfer_list.c
re0d5bc5 r96e01fbc 42 42 static void transfer_list_remove_batch( 43 43 transfer_list_t *instance, uhci_transfer_batch_t *uhci_batch); 44 /*----------------------------------------------------------------------------*/ 44 45 45 /** Initialize transfer list structures. 46 46 * … … 69 69 return EOK; 70 70 } 71 /*----------------------------------------------------------------------------*/ 71 72 72 /** Dispose transfer list structures. 73 73 * … … 97 97 qh_set_next_qh(instance->queue_head, next->queue_head); 98 98 } 99 /*----------------------------------------------------------------------------*/ 99 100 100 /** Add transfer batch to the list and queue. 101 101 * … … 144 144 fibril_mutex_unlock(&instance->guard); 145 145 } 146 /*----------------------------------------------------------------------------*/ 146 147 147 /** Add completed batches to the provided list. 148 148 * … … 171 171 fibril_mutex_unlock(&instance->guard); 172 172 } 173 /*----------------------------------------------------------------------------*/ 173 174 174 /** Walk the list and finish all batches with EINTR. 175 175 * … … 188 188 fibril_mutex_unlock(&instance->guard); 189 189 } 190 /*----------------------------------------------------------------------------*/ 190 191 191 /** Remove a transfer batch from the list and queue. 192 192 * -
uspace/drv/bus/usb/uhci/uhci.c
re0d5bc5 r96e01fbc 33 33 * @brief UHCI driver 34 34 */ 35 36 /* XXX Fix this */ 37 #define _DDF_DATA_IMPLANT 38 35 39 #include <errno.h> 36 40 #include <str_error.h> … … 60 64 } uhci_t; 61 65 62 static inline uhci_t * dev_to_uhci(const ddf_dev_t *dev) 63 { 64 assert(dev); 65 return dev->driver_data; 66 } 67 /*----------------------------------------------------------------------------*/ 66 static inline uhci_t *dev_to_uhci(ddf_dev_t *dev) 67 { 68 return ddf_dev_data_get(dev); 69 } 70 68 71 /** IRQ handling callback, forward status from call to diver structure. 69 72 * … … 83 86 hc_interrupt(&uhci->hc, status); 84 87 } 85 /*----------------------------------------------------------------------------*/ 88 86 89 /** Operations supported by the HC driver */ 87 90 static ddf_dev_ops_t hc_ops = { 88 91 .interfaces[USBHC_DEV_IFACE] = &hcd_iface, /* see iface.h/c */ 89 92 }; 90 /*----------------------------------------------------------------------------*/ 93 91 94 /** Gets handle of the respective hc. 92 95 * … … 97 100 static int usb_iface_get_hc_handle(ddf_fun_t *fun, devman_handle_t *handle) 98 101 { 99 assert(fun); 100 ddf_fun_t *hc_fun = dev_to_uhci(fun->dev)->hc_fun; 102 ddf_fun_t *hc_fun = dev_to_uhci(ddf_fun_get_dev(fun))->hc_fun; 101 103 assert(hc_fun); 102 104 103 105 if (handle != NULL) 104 *handle = hc_fun->handle;106 *handle = ddf_fun_get_handle(hc_fun); 105 107 return EOK; 106 108 } 107 /*----------------------------------------------------------------------------*/ 109 108 110 /** USB interface implementation used by RH */ 109 111 static usb_iface_t usb_iface = { 110 112 .get_hc_handle = usb_iface_get_hc_handle, 111 113 }; 112 /*----------------------------------------------------------------------------*/ 114 113 115 /** Get root hub hw resources (I/O registers). 114 116 * … … 118 120 static hw_resource_list_t *get_resource_list(ddf_fun_t *fun) 119 121 { 120 assert(fun); 121 rh_t *rh = fun->driver_data; 122 rh_t *rh = ddf_fun_data_get(fun); 122 123 assert(rh); 123 124 return &rh->resource_list; 124 125 } 125 /*----------------------------------------------------------------------------*/ 126 126 127 /** Interface to provide the root hub driver with hw info */ 127 128 static hw_res_ops_t hw_res_iface = { … … 129 130 .enable_interrupt = NULL, 130 131 }; 131 /*----------------------------------------------------------------------------*/ 132 132 133 /** RH function support for uhci_rhd */ 133 134 static ddf_dev_ops_t rh_ops = { … … 135 136 .interfaces[HW_RES_DEV_IFACE] = &hw_res_iface 136 137 }; 137 /*----------------------------------------------------------------------------*/ 138 138 139 /** Initialize hc and rh DDF structures and their respective drivers. 139 140 * … … 160 161 if (ret != EOK) { \ 161 162 if (instance->hc_fun) \ 162 instance->hc_fun->driver_data = NULL; \163 163 ddf_fun_destroy(instance->hc_fun); \ 164 164 if (instance->rh_fun) {\ 165 instance->rh_fun->driver_data = NULL; \166 165 ddf_fun_destroy(instance->rh_fun); \ 167 166 } \ … … 174 173 int ret = (instance->hc_fun == NULL) ? ENOMEM : EOK; 175 174 CHECK_RET_DEST_FREE_RETURN(ret, "Failed to create UHCI HC function.\n"); 176 instance->hc_fun->ops = &hc_ops;177 instance->hc_fun->driver_data = &instance->hc.generic;175 ddf_fun_set_ops(instance->hc_fun, &hc_ops); 176 ddf_fun_data_implant(instance->hc_fun, &instance->hc.generic); 178 177 179 178 instance->rh_fun = ddf_fun_create(device, fun_inner, "uhci_rh"); 180 179 ret = (instance->rh_fun == NULL) ? ENOMEM : EOK; 181 180 CHECK_RET_DEST_FREE_RETURN(ret, "Failed to create UHCI RH function.\n"); 182 instance->rh_fun->ops = &rh_ops;183 instance->rh_fun->driver_data = &instance->rh;181 ddf_fun_set_ops(instance->rh_fun, &rh_ops); 182 ddf_fun_data_implant(instance->rh_fun, &instance->rh); 184 183 185 184 uintptr_t reg_base = 0; … … 190 189 CHECK_RET_DEST_FREE_RETURN(ret, 191 190 "Failed to get I/O addresses for %" PRIun ": %s.\n", 192 d evice->handle, str_error(ret));191 ddf_dev_get_handle(device), str_error(ret)); 193 192 usb_log_debug("I/O regs at 0x%p (size %zu), IRQ %d.\n", 194 193 (void *) reg_base, reg_size, irq); -
uspace/drv/bus/usb/uhci/uhci_batch.c
re0d5bc5 r96e01fbc 58 58 } 59 59 } 60 /*----------------------------------------------------------------------------*/ 60 61 61 /** Finishes usb_transfer_batch and destroys the structure. 62 62 * … … 71 71 uhci_transfer_batch_dispose(uhci_batch); 72 72 } 73 /*----------------------------------------------------------------------------*/ 73 74 74 /** Transfer batch setup table. */ 75 75 static void (*const batch_setup[])(uhci_transfer_batch_t*, usb_direction_t); 76 /*----------------------------------------------------------------------------*/ 76 77 77 /** Allocate memory and initialize internal data structure. 78 78 * … … 143 143 return uhci_batch; 144 144 } 145 /*----------------------------------------------------------------------------*/ 145 146 146 /** Check batch TDs for activity. 147 147 * … … 196 196 return true; 197 197 } 198 /*----------------------------------------------------------------------------*/ 198 199 199 /** Direction to pid conversion table */ 200 200 static const usb_packet_id direction_pids[] = { … … 202 202 [USB_DIRECTION_OUT] = USB_PID_OUT, 203 203 }; 204 /*----------------------------------------------------------------------------*/ 204 205 205 /** Prepare generic data transfer 206 206 * … … 259 259 USB_TRANSFER_BATCH_ARGS(*uhci_batch->usb_batch)); 260 260 } 261 /*----------------------------------------------------------------------------*/ 261 262 262 /** Prepare generic control transfer 263 263 * … … 331 331 uhci_batch->tds[td].status); 332 332 } 333 /*----------------------------------------------------------------------------*/ 333 334 334 static void (*const batch_setup[])(uhci_transfer_batch_t*, usb_direction_t) = 335 335 { -
uspace/drv/bus/usb/uhci/uhci_batch.h
re0d5bc5 r96e01fbc 76 76 uhci_batch->td_count * sizeof(td_t); 77 77 } 78 /*----------------------------------------------------------------------------*/ 78 79 79 /** Get offset to data buffer accessible to the HC hw. 80 80 * @param uhci_batch UHCI batch structure. … … 89 89 uhci_batch->usb_batch->setup_size; 90 90 } 91 /*----------------------------------------------------------------------------*/ 91 92 92 /** Aborts the batch. 93 93 * Sets error to EINTR and size off transferd data to 0, before finishing the … … 103 103 uhci_transfer_batch_finish_dispose(uhci_batch); 104 104 } 105 /*----------------------------------------------------------------------------*/ 105 106 106 /** Linked list conversion wrapper. 107 107 * @param l Linked list link. -
uspace/drv/bus/usb/uhci/utils/malloc32.h
re0d5bc5 r96e01fbc 35 35 #define DRV_UHCI_UTILS_MALLOC32_H 36 36 37 #include <as.h> 37 38 #include <assert.h> 38 #include < unistd.h>39 #include <ddi.h> 39 40 #include <errno.h> 40 41 #include <malloc.h> 41 42 #include <mem.h> 42 #include < as.h>43 #include <unistd.h> 43 44 44 45 #define UHCI_STRCUTURES_ALIGNMENT 16 … … 63 64 return result; 64 65 } 65 /*----------------------------------------------------------------------------*/ 66 66 67 /** DMA malloc simulator 67 68 * … … 85 86 return memalign(alignment, size); 86 87 } 87 /*----------------------------------------------------------------------------*/ 88 88 89 /** DMA malloc simulator 89 90 * … … 92 93 static inline void free32(void *addr) 93 94 { free(addr); } 94 /*----------------------------------------------------------------------------*/ 95 95 96 /** Create 4KB page mapping 96 97 * … … 99 100 static inline void * get_page(void) 100 101 { 101 void *address = as_area_create(AS_AREA_ANY, UHCI_REQUIRED_PAGE_SIZE, 102 AS_AREA_READ | AS_AREA_WRITE); 103 if (address == AS_MAP_FAILED) 104 return NULL; 105 106 return address; 102 void *address, *phys; 103 const int ret = dmamem_map_anonymous(UHCI_REQUIRED_PAGE_SIZE, 104 AS_AREA_READ | AS_AREA_WRITE, 0, &phys, &address); 105 return ret == EOK ? address : NULL; 107 106 } 108 /*----------------------------------------------------------------------------*/ 107 109 108 static inline void return_page(void *page) 110 109 { 111 if (page) 112 as_area_destroy(page); 110 dmamem_unmap_anonymous(page); 113 111 } 114 112 -
uspace/drv/bus/usb/uhcirh/main.c
re0d5bc5 r96e01fbc 48 48 #define NAME "uhcirh" 49 49 50 static int hc_get_my_registers( constddf_dev_t *dev,50 static int hc_get_my_registers(ddf_dev_t *dev, 51 51 uintptr_t *io_reg_address, size_t *io_reg_size); 52 52 … … 88 88 89 89 usb_log_debug2("uhci_rh_dev_add(handle=%" PRIun ")\n", 90 d evice->handle);90 ddf_dev_get_handle(device)); 91 91 92 92 uintptr_t io_regs = 0; … … 98 98 if (ret != EOK) { \ 99 99 usb_log_error(message); \ 100 if (rh) \101 free(rh); \102 100 return ret; \ 103 101 } else (void)0 … … 109 107 (void *) io_regs, io_size); 110 108 111 rh = malloc(sizeof(uhci_root_hub_t));109 rh = ddf_dev_data_alloc(device, sizeof(uhci_root_hub_t)); 112 110 ret = (rh == NULL) ? ENOMEM : EOK; 113 111 CHECK_RET_FREE_RH_RETURN(ret, … … 119 117 ret, str_error(ret)); 120 118 121 device->driver_data = rh;122 119 usb_log_info("Controlling root hub '%s' (%" PRIun ").\n", 123 d evice->name, device->handle);120 ddf_dev_get_name(device), ddf_dev_get_handle(device)); 124 121 return EOK; 125 122 } … … 133 130 */ 134 131 int hc_get_my_registers( 135 constddf_dev_t *dev, uintptr_t *io_reg_address, size_t *io_reg_size)132 ddf_dev_t *dev, uintptr_t *io_reg_address, size_t *io_reg_size) 136 133 { 137 assert(dev);138 139 134 async_sess_t *parent_sess = 140 devman_parent_device_connect(EXCHANGE_SERIALIZE, dev->handle,141 IPC_FLAG_BLOCKING);135 devman_parent_device_connect(EXCHANGE_SERIALIZE, 136 ddf_dev_get_handle(dev), IPC_FLAG_BLOCKING); 142 137 if (!parent_sess) 143 138 return ENOMEM; -
uspace/drv/bus/usb/uhcirh/port.c
re0d5bc5 r96e01fbc 63 63 return pio_read_16(port->address); 64 64 } 65 /*----------------------------------------------------------------------------*/ 65 66 66 /** Register writing helper function. 67 67 * … … 75 75 pio_write_16(port->address, val); 76 76 } 77 /*----------------------------------------------------------------------------*/ 77 78 78 /** Initialize UHCI root hub port instance. 79 79 * … … 127 127 return EOK; 128 128 } 129 /*----------------------------------------------------------------------------*/ 129 130 130 /** Cleanup UHCI root hub port instance. 131 131 * … … 141 141 return; 142 142 } 143 /*----------------------------------------------------------------------------*/ 143 144 144 /** Periodically checks port status and reports new devices. 145 145 * … … 210 210 return EOK; 211 211 } 212 /*----------------------------------------------------------------------------*/ 212 213 213 /** Callback for enabling port during adding a new device. 214 214 * … … 247 247 return EOK; 248 248 } 249 /*----------------------------------------------------------------------------*/ 249 250 250 /** Initialize and report connected device. 251 251 * … … 279 279 usb_log_info("%s: New device, address %d (handle %" PRIun ").\n", 280 280 port->id_string, port->attached_device.address, 281 port->attached_device.fun->handle);282 return EOK; 283 } 284 /*----------------------------------------------------------------------------*/ 281 ddf_fun_get_handle(port->attached_device.fun)); 282 return EOK; 283 } 284 285 285 /** Remove device. 286 286 * … … 324 324 return EOK; 325 325 } 326 /*----------------------------------------------------------------------------*/ 326 327 327 /** Enable or disable root hub port. 328 328 * … … 358 358 return EOK; 359 359 } 360 /*----------------------------------------------------------------------------*/ 360 361 361 /** Print the port status value in a human friendly way 362 362 * -
uspace/drv/bus/usb/uhcirh/root_hub.c
re0d5bc5 r96e01fbc 79 79 return EOK; 80 80 } 81 /*----------------------------------------------------------------------------*/ 81 82 82 /** Cleanup UHCI root hub instance. 83 83 * … … 92 92 } 93 93 } 94 /*----------------------------------------------------------------------------*/ 94 95 95 /** 96 96 * @} -
uspace/drv/bus/usb/usbflbk/main.c
re0d5bc5 r96e01fbc 69 69 " (node `%s', handle %" PRIun ").\n", 70 70 dev->interface_no < 0 ? "device" : "interface", 71 d ev->ddf_dev->name, fun_name, dev->ddf_dev->handle);71 ddf_dev_get_name(dev->ddf_dev), fun_name, ddf_dev_get_handle(dev->ddf_dev)); 72 72 73 73 return EOK; … … 85 85 const int ret = ddf_fun_unbind(ctl_fun); 86 86 if (ret != EOK) { 87 usb_log_error("Failed to unbind %s.\n", ctl_fun->name);87 usb_log_error("Failed to unbind %s.\n", ddf_fun_get_name(ctl_fun)); 88 88 return ret; 89 89 } -
uspace/drv/bus/usb/usbhid/generic/hiddev.c
re0d5bc5 r96e01fbc 35 35 */ 36 36 37 /* XXX Fix this */ 38 #define _DDF_DATA_IMPLANT 39 37 40 #include <usb/debug.h> 38 41 #include <usb/classes/classes.h> … … 46 49 #include "usbhid.h" 47 50 48 /*----------------------------------------------------------------------------*/ 51 49 52 50 53 const usb_endpoint_description_t usb_hid_generic_poll_endpoint_description = { … … 60 63 const char *HID_GENERIC_CLASS_NAME = "hid"; 61 64 62 /*----------------------------------------------------------------------------*/ 65 63 66 static size_t usb_generic_hid_get_event_length(ddf_fun_t *fun); 64 67 static int usb_generic_hid_get_event(ddf_fun_t *fun, uint8_t *buffer, … … 68 71 static int usb_generic_get_report_descriptor(ddf_fun_t *fun, uint8_t *desc, 69 72 size_t size, size_t *actual_size); 70 /*----------------------------------------------------------------------------*/ 73 71 74 static usbhid_iface_t usb_generic_iface = { 72 75 .get_event = usb_generic_hid_get_event, … … 75 78 .get_report_descriptor = usb_generic_get_report_descriptor 76 79 }; 77 /*----------------------------------------------------------------------------*/ 80 78 81 static ddf_dev_ops_t usb_generic_hid_ops = { 79 82 .interfaces[USBHID_DEV_IFACE] = &usb_generic_iface, 80 83 .open = usb_generic_hid_client_connected 81 84 }; 82 /*----------------------------------------------------------------------------*/ 85 86 /** Return hid_dev_t * for generic HID function node. 87 * 88 * For the generic HID subdriver the 'hid' function has usb_hid_gen_fun_t 89 * as soft state. Through that we can get to the usb_hid_dev_t. 90 */ 91 static usb_hid_dev_t *fun_hid_dev(ddf_fun_t *fun) 92 { 93 return ((usb_hid_gen_fun_t *)ddf_fun_data_get(fun))->hid_dev; 94 } 95 83 96 static size_t usb_generic_hid_get_event_length(ddf_fun_t *fun) 84 97 { 85 98 usb_log_debug2("Generic HID: Get event length (fun: %p, " 86 "fun->driver_data: %p.\n", fun, fun->driver_data); 87 88 if (fun == NULL || fun->driver_data == NULL) { 89 return 0; 90 } 91 92 const usb_hid_dev_t *hid_dev = fun->driver_data; 99 "fun->driver_data: %p.\n", fun, ddf_fun_data_get(fun)); 100 101 const usb_hid_dev_t *hid_dev = fun_hid_dev(fun); 93 102 94 103 usb_log_debug2("hid_dev: %p, Max input report size (%zu).\n", … … 97 106 return hid_dev->max_input_report_size; 98 107 } 99 /*----------------------------------------------------------------------------*/ 108 100 109 static int usb_generic_hid_get_event(ddf_fun_t *fun, uint8_t *buffer, 101 110 size_t size, size_t *act_size, int *event_nr, unsigned int flags) … … 103 112 usb_log_debug2("Generic HID: Get event.\n"); 104 113 105 if (fun == NULL || fun->driver_data == NULL || buffer == NULL 106 || act_size == NULL || event_nr == NULL) { 114 if (buffer == NULL || act_size == NULL || event_nr == NULL) { 107 115 usb_log_debug("No function"); 108 116 return EINVAL; 109 117 } 110 118 111 const usb_hid_dev_t *hid_dev = (usb_hid_dev_t *)fun->driver_data;119 const usb_hid_dev_t *hid_dev = fun_hid_dev(fun); 112 120 113 121 if (hid_dev->input_report_size > size) { … … 127 135 return EOK; 128 136 } 129 /*----------------------------------------------------------------------------*/ 137 130 138 static size_t usb_generic_get_report_descriptor_length(ddf_fun_t *fun) 131 139 { 132 140 usb_log_debug("Generic HID: Get report descriptor length.\n"); 133 141 134 if (fun == NULL || fun->driver_data == NULL) { 135 usb_log_debug("No function"); 136 return EINVAL; 137 } 138 139 const usb_hid_dev_t *hid_dev = fun->driver_data; 142 const usb_hid_dev_t *hid_dev = fun_hid_dev(fun); 140 143 141 144 usb_log_debug2("hid_dev->report_desc_size = %zu\n", … … 144 147 return hid_dev->report_desc_size; 145 148 } 146 /*----------------------------------------------------------------------------*/ 149 147 150 static int usb_generic_get_report_descriptor(ddf_fun_t *fun, uint8_t *desc, 148 151 size_t size, size_t *actual_size) … … 150 153 usb_log_debug2("Generic HID: Get report descriptor.\n"); 151 154 152 if (fun == NULL || fun->driver_data == NULL) { 153 usb_log_debug("No function"); 154 return EINVAL; 155 } 156 157 const usb_hid_dev_t *hid_dev = fun->driver_data; 155 const usb_hid_dev_t *hid_dev = fun_hid_dev(fun); 158 156 159 157 if (hid_dev->report_desc_size > size) { … … 166 164 return EOK; 167 165 } 168 /*----------------------------------------------------------------------------*/ 166 169 167 static int usb_generic_hid_client_connected(ddf_fun_t *fun) 170 168 { … … 172 170 return EOK; 173 171 } 174 /*----------------------------------------------------------------------------*/ 172 175 173 void usb_generic_hid_deinit(usb_hid_dev_t *hid_dev, void *data) 176 174 { … … 183 181 return; 184 182 } 185 usb_log_debug2("%s unbound.\n", fun->name); 186 /* We did not allocate this, so leave this alone 187 * the device would take care of it */ 188 fun->driver_data = NULL; 183 usb_log_debug2("%s unbound.\n", ddf_fun_get_name(fun)); 189 184 ddf_fun_destroy(fun); 190 185 } 191 /*----------------------------------------------------------------------------*/ 186 192 187 int usb_generic_hid_init(usb_hid_dev_t *hid_dev, void **data) 193 188 { 189 usb_hid_gen_fun_t *hid_fun; 190 194 191 if (hid_dev == NULL) { 195 192 return EINVAL; … … 205 202 } 206 203 207 /* This is nasty, both device and this function have the same208 * driver data, thus destruction causes to double free */209 fun->driver_data= hid_dev;210 fun->ops = &usb_generic_hid_ops;204 /* Create softstate */ 205 hid_fun = ddf_fun_data_alloc(fun, sizeof(usb_hid_gen_fun_t)); 206 hid_fun->hid_dev = hid_dev; 207 ddf_fun_set_ops(fun, &usb_generic_hid_ops); 211 208 212 209 int rc = ddf_fun_bind(fun); … … 214 211 usb_log_error("Could not bind DDF function: %s.\n", 215 212 str_error(rc)); 216 fun->driver_data = NULL;217 213 ddf_fun_destroy(fun); 218 214 return rc; 219 215 } 220 216 221 usb_log_debug("HID function created. Handle: %" PRIun "\n", fun->handle); 217 usb_log_debug("HID function created. Handle: %" PRIun "\n", 218 ddf_fun_get_handle(fun)); 222 219 *data = fun; 223 220 224 221 return EOK; 225 222 } 226 /*----------------------------------------------------------------------------*/ 223 227 224 bool usb_generic_hid_polling_callback(usb_hid_dev_t *hid_dev, void *data) 228 225 { -
uspace/drv/bus/usb/usbhid/generic/hiddev.h
re0d5bc5 r96e01fbc 47 47 const char *HID_GENERIC_CLASS_NAME; 48 48 49 /*----------------------------------------------------------------------------*/ 49 /** The USB HID generic 'hid' function softstate */ 50 typedef struct { 51 struct usb_hid_dev *hid_dev; 52 } usb_hid_gen_fun_t; 50 53 51 54 int usb_generic_hid_init(struct usb_hid_dev *hid_dev, void **data); -
uspace/drv/bus/usb/usbhid/kbd/kbddev.c
re0d5bc5 r96e01fbc 34 34 * USB HID keyboard device structure and API. 35 35 */ 36 37 /* XXX Fix this */ 38 #define _DDF_DATA_IMPLANT 36 39 37 40 #include <errno.h> … … 71 74 #include "../usbhid.h" 72 75 73 /*----------------------------------------------------------------------------*/ 76 static void default_connection_handler(ddf_fun_t *, ipc_callid_t, ipc_call_t *); 77 static ddf_dev_ops_t kbdops = { .default_handler = default_connection_handler }; 78 74 79 75 80 static const unsigned DEFAULT_ACTIVE_MODS = KM_NUM_LOCK; … … 86 91 static const unsigned int DEFAULT_REPEAT_DELAY = 50 * 1000; 87 92 88 /*----------------------------------------------------------------------------*/ 93 89 94 /** Keyboard polling endpoint description for boot protocol class. */ 90 95 const usb_endpoint_description_t usb_hid_kbd_poll_endpoint_description = { … … 101 106 102 107 static void usb_kbd_set_led(usb_hid_dev_t *hid_dev, usb_kbd_t *kbd_dev); 103 /*----------------------------------------------------------------------------*/ 108 104 109 static const uint8_t USB_KBD_BOOT_REPORT_DESCRIPTOR[] = { 105 110 0x05, 0x01, /* Usage Page (Generic Desktop), */ … … 136 141 0xC0 /* End Collection */ 137 142 }; 138 /*----------------------------------------------------------------------------*/ 143 139 144 typedef enum usb_kbd_flags { 140 145 USB_KBD_STATUS_UNINITIALIZED = 0, … … 142 147 USB_KBD_STATUS_TO_DESTROY = -1 143 148 } usb_kbd_flags; 144 /*----------------------------------------------------------------------------*/ 149 145 150 /* IPC method handler */ 146 /*----------------------------------------------------------------------------*/ 151 147 152 /** 148 153 * Default handler for IPC methods not handled by DDF. … … 160 165 ipc_callid_t icallid, ipc_call_t *icall) 161 166 { 162 if (fun == NULL || fun->driver_data == NULL) {163 usb_log_error("%s: Missing parameter.\n", __FUNCTION__);164 async_answer_0(icallid, EINVAL);165 return;166 }167 168 167 const sysarg_t method = IPC_GET_IMETHOD(*icall); 169 usb_kbd_t *kbd_dev = fun->driver_data;168 usb_kbd_t *kbd_dev = ddf_fun_data_get(fun); 170 169 171 170 switch (method) { … … 187 186 break; 188 187 } 189 if (kbd_dev->c onsole_sess == NULL) {190 kbd_dev->c onsole_sess = sess;188 if (kbd_dev->client_sess == NULL) { 189 kbd_dev->client_sess = sess; 191 190 usb_log_debug("%s: OK\n", __FUNCTION__); 192 191 async_answer_0(icallid, EOK); … … 206 205 207 206 } 208 /*----------------------------------------------------------------------------*/ 207 209 208 /* Key processing functions */ 210 /*----------------------------------------------------------------------------*/ 209 211 210 /** 212 211 * Handles turning of LED lights on and off. … … 281 280 } 282 281 } 283 /*----------------------------------------------------------------------------*/ 282 284 283 /** Send key event. 285 284 * … … 292 291 { 293 292 usb_log_debug2("Sending kbdev event %d/%d to the console\n", type, key); 294 if (kbd_dev->c onsole_sess == NULL) {293 if (kbd_dev->client_sess == NULL) { 295 294 usb_log_warning( 296 295 "Connection to console not ready, key discarded.\n"); … … 298 297 } 299 298 300 async_exch_t *exch = async_exchange_begin(kbd_dev->c onsole_sess);299 async_exch_t *exch = async_exchange_begin(kbd_dev->client_sess); 301 300 if (exch != NULL) { 302 301 async_msg_2(exch, KBDEV_EVENT, type, key); … … 306 305 } 307 306 } 308 /*----------------------------------------------------------------------------*/ 307 309 308 static inline int usb_kbd_is_lock(unsigned int key_code) 310 309 { … … 313 312 || key_code == KC_CAPS_LOCK); 314 313 } 315 /*----------------------------------------------------------------------------*/ 314 316 315 static size_t find_in_array_int32(int32_t val, int32_t *arr, size_t arr_size) 317 316 { … … 324 323 return (size_t) -1; 325 324 } 326 /*----------------------------------------------------------------------------*/ 325 327 326 /** 328 327 * Checks if some keys were pressed or released and generates key events. … … 407 406 usb_log_debug2("Stored keys %s.\n", key_buffer); 408 407 } 409 /*----------------------------------------------------------------------------*/ 408 410 409 /* General kbd functions */ 411 /*----------------------------------------------------------------------------*/ 410 412 411 /** 413 412 * Processes data received from the device in form of report. … … 479 478 usb_kbd_check_key_changes(hid_dev, kbd_dev); 480 479 } 481 /*----------------------------------------------------------------------------*/ 480 482 481 /* HID/KBD structure manipulation */ 483 /*----------------------------------------------------------------------------*/ 482 484 483 static int usb_kbd_create_function(usb_kbd_t *kbd_dev) 485 484 { … … 499 498 /* Store the initialized HID device and HID ops 500 499 * to the DDF function. */ 501 fun->ops = &kbd_dev->ops;502 fun->driver_data = kbd_dev;500 ddf_fun_set_ops(fun, &kbdops); 501 ddf_fun_data_implant(fun, kbd_dev); 503 502 504 503 int rc = ddf_fun_bind(fun); … … 506 505 usb_log_error("Could not bind DDF function: %s.\n", 507 506 str_error(rc)); 508 fun->driver_data = NULL; /* We did not allocate this. */509 507 ddf_fun_destroy(fun); 510 508 return rc; … … 512 510 513 511 usb_log_debug("%s function created. Handle: %" PRIun "\n", 514 HID_KBD_FUN_NAME, fun->handle);512 HID_KBD_FUN_NAME, ddf_fun_get_handle(fun)); 515 513 516 514 usb_log_debug("Adding DDF function to category %s...\n", … … 522 520 HID_KBD_CLASS_NAME, str_error(rc)); 523 521 if (ddf_fun_unbind(fun) == EOK) { 524 fun->driver_data = NULL; /* We did not allocate this. */525 522 ddf_fun_destroy(fun); 526 523 } else { 527 524 usb_log_error( 528 525 "Failed to unbind `%s', will not destroy.\n", 529 fun->name);526 ddf_fun_get_name(fun)); 530 527 } 531 528 return rc; … … 535 532 return EOK; 536 533 } 537 /*----------------------------------------------------------------------------*/ 534 538 535 /* API functions */ 539 /*----------------------------------------------------------------------------*/ 536 540 537 /** 541 538 * Initialization of the USB/HID keyboard structure. … … 576 573 fibril_mutex_initialize(&kbd_dev->repeat_mtx); 577 574 kbd_dev->initialized = USB_KBD_STATUS_UNINITIALIZED; 578 kbd_dev->ops.default_handler = default_connection_handler;579 575 580 576 /* Store link to HID device */ … … 700 696 return EOK; 701 697 } 702 /*----------------------------------------------------------------------------*/ 698 703 699 bool usb_kbd_polling_callback(usb_hid_dev_t *hid_dev, void *data) 704 700 { … … 714 710 return true; 715 711 } 716 /*----------------------------------------------------------------------------*/ 712 717 713 int usb_kbd_is_initialized(const usb_kbd_t *kbd_dev) 718 714 { 719 715 return (kbd_dev->initialized == USB_KBD_STATUS_INITIALIZED); 720 716 } 721 /*----------------------------------------------------------------------------*/ 717 722 718 int usb_kbd_is_ready_to_destroy(const usb_kbd_t *kbd_dev) 723 719 { 724 720 return (kbd_dev->initialized == USB_KBD_STATUS_TO_DESTROY); 725 721 } 726 /*----------------------------------------------------------------------------*/ 722 727 723 /** 728 724 * Properly destroys the USB/HID keyboard structure. … … 737 733 738 734 /* Hangup session to the console. */ 739 if (kbd_dev->c onsole_sess)740 async_hangup(kbd_dev->c onsole_sess);735 if (kbd_dev->client_sess) 736 async_hangup(kbd_dev->client_sess); 741 737 742 738 //assert(!fibril_mutex_is_locked((*kbd_dev)->repeat_mtx)); … … 756 752 if (ddf_fun_unbind(kbd_dev->fun) != EOK) { 757 753 usb_log_warning("Failed to unbind %s.\n", 758 kbd_dev->fun->name);754 ddf_fun_get_name(kbd_dev->fun)); 759 755 } else { 760 usb_log_debug2("%s unbound.\n", kbd_dev->fun->name);761 kbd_dev->fun->driver_data = NULL;756 usb_log_debug2("%s unbound.\n", 757 ddf_fun_get_name(kbd_dev->fun)); 762 758 ddf_fun_destroy(kbd_dev->fun); 763 759 } 764 760 } 765 free(kbd_dev); 766 } 767 /*----------------------------------------------------------------------------*/ 761 } 762 768 763 void usb_kbd_deinit(usb_hid_dev_t *hid_dev, void *data) 769 764 { … … 778 773 } 779 774 } 780 /*----------------------------------------------------------------------------*/ 775 781 776 int usb_kbd_set_boot_protocol(usb_hid_dev_t *hid_dev) 782 777 { -
uspace/drv/bus/usb/usbhid/kbd/kbddev.h
re0d5bc5 r96e01fbc 50 50 struct usb_hid_dev; 51 51 52 /*----------------------------------------------------------------------------*/ 52 53 53 /** 54 54 * USB/HID keyboard device type. … … 82 82 unsigned lock_keys; 83 83 84 /** IPC session to the console device (for sending key events). */ 85 async_sess_t *console_sess; 86 87 /** @todo What is this actually? */ 88 ddf_dev_ops_t ops; 84 /** IPC session to client (for sending key events). */ 85 async_sess_t *client_sess; 89 86 90 87 /** Information for auto-repeat of keys. */ … … 116 113 } usb_kbd_t; 117 114 118 /*----------------------------------------------------------------------------*/ 115 119 116 120 117 extern const usb_endpoint_description_t usb_hid_kbd_poll_endpoint_description; … … 123 120 const char *HID_KBD_CLASS_NAME; 124 121 125 /*----------------------------------------------------------------------------*/ 122 126 123 127 124 int usb_kbd_init(struct usb_hid_dev *hid_dev, void **data); -
uspace/drv/bus/usb/usbhid/kbd/kbdrepeat.c
re0d5bc5 r96e01fbc 105 105 } 106 106 } 107 /*----------------------------------------------------------------------------*/ 107 108 108 /** 109 109 * Main routine to be executed by a fibril for handling auto-repeat. … … 132 132 return EOK; 133 133 } 134 /*----------------------------------------------------------------------------*/ 134 135 135 /** 136 136 * Start repeating particular key. … … 149 149 fibril_mutex_unlock(&kbd->repeat_mtx); 150 150 } 151 /*----------------------------------------------------------------------------*/ 151 152 152 /** 153 153 * Stop repeating particular key. -
uspace/drv/bus/usb/usbhid/kbd/kbdrepeat.h
re0d5bc5 r96e01fbc 42 42 struct usb_kbd_t; 43 43 44 /*----------------------------------------------------------------------------*/ 44 45 45 /** 46 46 * Structure for keeping information needed for auto-repeat of keys. … … 57 57 } usb_kbd_repeat_t; 58 58 59 /*----------------------------------------------------------------------------*/ 59 60 60 61 61 int usb_kbd_repeat_fibril(void *arg); -
uspace/drv/bus/usb/usbhid/main.c
re0d5bc5 r96e01fbc 103 103 if (rc != EOK) { 104 104 usb_log_error("Failed to start polling fibril for `%s'.\n", 105 d ev->ddf_dev->name);105 ddf_dev_get_name(dev->ddf_dev)); 106 106 usb_hid_deinit(hid_dev); 107 107 return rc; … … 109 109 hid_dev->running = true; 110 110 111 usb_log_info("HID device `%s' ready to use.\n", dev->ddf_dev->name); 111 usb_log_info("HID device `%s' ready to use.\n", 112 ddf_dev_get_name(dev->ddf_dev)); 112 113 113 114 return EOK; 114 115 } 115 /*----------------------------------------------------------------------------*/ 116 116 117 /** 117 118 * Callback for a device about to be removed from the driver. … … 126 127 return ENOTSUP; 127 128 } 128 /*----------------------------------------------------------------------------*/ 129 129 130 /** 130 131 * Callback for removing a device from the driver. … … 149 150 150 151 usb_hid_deinit(hid_dev); 151 usb_log_debug2("%s destruction complete.\n", d ev->ddf_dev->name);152 usb_log_debug2("%s destruction complete.\n", ddf_dev_get_name(dev->ddf_dev)); 152 153 return EOK; 153 154 } 154 /*----------------------------------------------------------------------------*/ 155 155 156 /** USB generic driver callbacks */ 156 157 static const usb_driver_ops_t usb_hid_driver_ops = { … … 159 160 .device_gone = usb_hid_device_gone, 160 161 }; 161 /*----------------------------------------------------------------------------*/ 162 162 163 /** The driver itself. */ 163 164 static const usb_driver_t usb_hid_driver = { … … 166 167 .endpoints = usb_hid_endpoints 167 168 }; 168 /*----------------------------------------------------------------------------*/ 169 169 170 int main(int argc, char *argv[]) 170 171 { -
uspace/drv/bus/usb/usbhid/mouse/mousedev.c
re0d5bc5 r96e01fbc 35 35 */ 36 36 37 /* XXX Fix this */ 38 #define _DDF_DATA_IMPLANT 39 37 40 #include <usb/debug.h> 38 41 #include <usb/classes/classes.h> … … 54 57 #define NAME "mouse" 55 58 56 /*----------------------------------------------------------------------------*/ 59 static void default_connection_handler(ddf_fun_t *, ipc_callid_t, ipc_call_t *); 60 61 static ddf_dev_ops_t ops = { .default_handler = default_connection_handler }; 62 57 63 58 64 const usb_endpoint_description_t usb_hid_mouse_poll_endpoint_description = { … … 71 77 static const uint8_t IDLE_RATE = 0; 72 78 73 /*----------------------------------------------------------------------------*/ 79 74 80 static const uint8_t USB_MOUSE_BOOT_REPORT_DESCRIPTOR[] = { 75 81 0x05, 0x01, // USAGE_PAGE (Generic Desktop) … … 101 107 }; 102 108 103 /*----------------------------------------------------------------------------*/ 109 104 110 105 111 /** Default handler for IPC methods not handled by DDF. … … 112 118 ipc_callid_t icallid, ipc_call_t *icall) 113 119 { 114 usb_mouse_t *mouse_dev = fun->driver_data;120 usb_mouse_t *mouse_dev = ddf_fun_data_get(fun); 115 121 116 122 if (mouse_dev == NULL) { … … 120 126 } 121 127 122 usb_log_debug("%s: fun->name: %s\n", __FUNCTION__, fun->name);128 usb_log_debug("%s: fun->name: %s\n", __FUNCTION__, ddf_fun_get_name(fun)); 123 129 usb_log_debug("%s: mouse_sess: %p\n", 124 130 __FUNCTION__, mouse_dev->mouse_sess); … … 130 136 mouse_dev->mouse_sess = sess; 131 137 usb_log_debug("Console session to %s set ok (%p).\n", 132 fun->name, sess);138 ddf_fun_get_name(fun), sess); 133 139 async_answer_0(icallid, EOK); 134 140 } else { 135 141 usb_log_error("Console session to %s already set.\n", 136 fun->name);142 ddf_fun_get_name(fun)); 137 143 async_answer_0(icallid, ELIMIT); 138 144 async_hangup(sess); … … 143 149 } 144 150 } 145 /*----------------------------------------------------------------------------*/ 151 146 152 static int get_mouse_axis_move_value(uint8_t rid, usb_hid_report_t *report, 147 153 int32_t usage) … … 221 227 assert(index < mouse_dev->buttons_count); 222 228 223 if (mouse_dev->buttons[index] == 0 && field->value != 0) {229 if (mouse_dev->buttons[index] != field->value) { 224 230 async_exch_t *exch = 225 231 async_exchange_begin(mouse_dev->mouse_sess); 226 232 if (exch != NULL) { 227 233 async_req_2_0(exch, MOUSEEV_BUTTON_EVENT, 228 field->usage, 1); 229 async_exchange_end(exch); 230 mouse_dev->buttons[index] = field->value; 231 } 232 233 } else if (mouse_dev->buttons[index] != 0 && field->value == 0) { 234 async_exch_t *exch = 235 async_exchange_begin(mouse_dev->mouse_sess); 236 if (exch != NULL) { 237 async_req_2_0(exch, MOUSEEV_BUTTON_EVENT, 238 field->usage, 0); 234 field->usage, (field->value != 0) ? 1 : 0); 239 235 async_exchange_end(exch); 240 236 mouse_dev->buttons[index] = field->value; … … 252 248 return true; 253 249 } 254 /*----------------------------------------------------------------------------*/ 250 255 251 #define FUN_UNBIND_DESTROY(fun) \ 256 252 if (fun) { \ 257 253 if (ddf_fun_unbind((fun)) == EOK) { \ 258 (fun)->driver_data = NULL; \259 254 ddf_fun_destroy((fun)); \ 260 255 } else { \ 261 256 usb_log_error("Could not unbind function `%s', it " \ 262 "will not be destroyed.\n", (fun)->name); \257 "will not be destroyed.\n", ddf_fun_get_name(fun)); \ 263 258 } \ 264 259 } else (void)0 265 /*----------------------------------------------------------------------------*/ 260 266 261 static int usb_mouse_create_function(usb_hid_dev_t *hid_dev, usb_mouse_t *mouse) 267 262 { … … 279 274 } 280 275 281 fun->ops = &mouse->ops;282 fun->driver_data = mouse;276 ddf_fun_set_ops(fun, &ops); 277 ddf_fun_data_implant(fun, mouse); 283 278 284 279 int rc = ddf_fun_bind(fun); 285 280 if (rc != EOK) { 286 281 usb_log_error("Could not bind DDF function `%s': %s.\n", 287 fun->name, str_error(rc)); 288 fun->driver_data = NULL; 282 ddf_fun_get_name(fun), str_error(rc)); 289 283 ddf_fun_destroy(fun); 290 284 return rc; … … 292 286 293 287 usb_log_debug("Adding DDF function `%s' to category %s...\n", 294 fun->name, HID_MOUSE_CATEGORY);288 ddf_fun_get_name(fun), HID_MOUSE_CATEGORY); 295 289 rc = ddf_fun_add_to_category(fun, HID_MOUSE_CATEGORY); 296 290 if (rc != EOK) { … … 302 296 } 303 297 mouse->mouse_fun = fun; 304 305 298 return EOK; 306 299 } … … 345 338 return highest_button; 346 339 } 347 /*----------------------------------------------------------------------------*/ 340 348 341 int usb_mouse_init(usb_hid_dev_t *hid_dev, void **data) 349 342 { … … 379 372 } 380 373 381 // set handler for incoming calls382 mouse_dev->ops.default_handler = default_connection_handler;383 384 374 // TODO: how to know if the device supports the request??? 385 375 usbhid_req_set_idle(&hid_dev->usb_dev->ctrl_pipe, … … 398 388 return EOK; 399 389 } 400 /*----------------------------------------------------------------------------*/ 390 401 391 bool usb_mouse_polling_callback(usb_hid_dev_t *hid_dev, void *data) 402 392 { … … 411 401 return usb_mouse_process_report(hid_dev, mouse_dev); 412 402 } 413 /*----------------------------------------------------------------------------*/ 403 414 404 void usb_mouse_deinit(usb_hid_dev_t *hid_dev, void *data) 415 405 { … … 430 420 431 421 free(mouse_dev->buttons); 432 free(mouse_dev); 433 } 434 /*----------------------------------------------------------------------------*/ 422 } 423 435 424 int usb_mouse_set_boot_protocol(usb_hid_dev_t *hid_dev) 436 425 { -
uspace/drv/bus/usb/usbhid/mouse/mousedev.h
re0d5bc5 r96e01fbc 42 42 struct usb_hid_dev; 43 43 44 /*----------------------------------------------------------------------------*/ 44 45 45 46 46 /** Container for USB mouse device. */ 47 47 typedef struct { 48 /** IPC session to cons ole (consumer). */48 /** IPC session to consumer. */ 49 49 async_sess_t *mouse_sess; 50 50 … … 53 53 size_t buttons_count; 54 54 55 ddf_dev_ops_t ops;56 55 /* DDF mouse function */ 57 56 ddf_fun_t *mouse_fun; 58 57 } usb_mouse_t; 59 58 60 /*----------------------------------------------------------------------------*/ 59 61 60 62 61 extern const usb_endpoint_description_t usb_hid_mouse_poll_endpoint_description; … … 65 64 const char *HID_MOUSE_CATEGORY; 66 65 67 /*----------------------------------------------------------------------------*/ 66 68 67 69 68 int usb_mouse_init(struct usb_hid_dev *hid_dev, void **data); … … 75 74 int usb_mouse_set_boot_protocol(struct usb_hid_dev *hid_dev); 76 75 77 /*----------------------------------------------------------------------------*/ 76 78 77 79 78 #endif // USB_HID_MOUSEDEV_H_ -
uspace/drv/bus/usb/usbhid/multimedia/multimedia.c
re0d5bc5 r96e01fbc 54 54 #define NAME "multimedia-keys" 55 55 56 /*----------------------------------------------------------------------------*/ 56 57 57 /** 58 58 * Logitech UltraX device type. … … 70 70 71 71 72 /*----------------------------------------------------------------------------*/ 72 73 73 /** 74 74 * Default handler for IPC methods not handled by DDF. … … 86 86 { 87 87 usb_log_debug(NAME " default_connection_handler()\n"); 88 if (fun == NULL || fun->driver_data == NULL) { 89 async_answer_0(icallid, EINVAL); 90 return; 91 } 92 93 usb_multimedia_t *multim_dev = fun->driver_data; 88 89 usb_multimedia_t *multim_dev = ddf_fun_data_get(fun); 94 90 95 91 async_sess_t *sess = … … 106 102 async_answer_0(icallid, EINVAL); 107 103 } 108 /*----------------------------------------------------------------------------*/ 104 109 105 static ddf_dev_ops_t multimedia_ops = { 110 106 .default_handler = default_connection_handler 111 107 }; 112 /*----------------------------------------------------------------------------*/ 108 113 109 /** 114 110 * Processes key events. … … 155 151 } 156 152 } 157 /*----------------------------------------------------------------------------*/ 153 158 154 int usb_multimedia_init(struct usb_hid_dev *hid_dev, void **data) 159 155 { … … 172 168 } 173 169 174 fun->ops = &multimedia_ops;170 ddf_fun_set_ops(fun, &multimedia_ops); 175 171 176 172 usb_multimedia_t *multim_dev = … … 194 190 195 191 usb_log_debug(NAME " function created (handle: %" PRIun ").\n", 196 fun->handle);192 ddf_fun_get_handle(fun)); 197 193 198 194 rc = ddf_fun_add_to_category(fun, "keyboard"); … … 203 199 if (ddf_fun_unbind(fun) != EOK) { 204 200 usb_log_error("Failed to unbind %s, won't destroy.\n", 205 fun->name);201 ddf_fun_get_name(fun)); 206 202 } else { 207 203 ddf_fun_destroy(fun); … … 216 212 return EOK; 217 213 } 218 /*----------------------------------------------------------------------------*/ 214 219 215 void usb_multimedia_deinit(struct usb_hid_dev *hid_dev, void *data) 220 216 { 221 217 ddf_fun_t *fun = data; 222 if (fun != NULL && fun->driver_data != NULL) { 223 usb_multimedia_t *multim_dev = fun->driver_data; 224 /* Hangup session to the console */ 225 if (multim_dev->console_sess) 226 async_hangup(multim_dev->console_sess); 227 if (ddf_fun_unbind(fun) != EOK) { 228 usb_log_error("Failed to unbind %s, won't destroy.\n", 229 fun->name); 230 } else { 231 usb_log_debug2("%s unbound.\n", fun->name); 232 /* This frees multim_dev too as it was stored in 233 * fun->data */ 234 ddf_fun_destroy(fun); 235 } 218 219 usb_multimedia_t *multim_dev = ddf_fun_data_get(fun); 220 221 /* Hangup session to the console */ 222 if (multim_dev->console_sess) 223 async_hangup(multim_dev->console_sess); 224 if (ddf_fun_unbind(fun) != EOK) { 225 usb_log_error("Failed to unbind %s, won't destroy.\n", 226 ddf_fun_get_name(fun)); 236 227 } else { 237 usb_log_error( 238 "Failed to deinit multimedia subdriver, data missing.\n"); 239 } 240 } 241 /*----------------------------------------------------------------------------*/ 228 usb_log_debug2("%s unbound.\n", ddf_fun_get_name(fun)); 229 /* This frees multim_dev too as it was stored in 230 * fun->data */ 231 ddf_fun_destroy(fun); 232 } 233 } 234 242 235 bool usb_multimedia_polling_callback(struct usb_hid_dev *hid_dev, void *data) 243 236 { 244 237 // TODO: checks 245 238 ddf_fun_t *fun = data; 246 if (hid_dev == NULL || fun == NULL || fun->driver_data == NULL) {239 if (hid_dev == NULL) { 247 240 return false; 248 241 } 249 242 250 usb_multimedia_t *multim_dev = fun->driver_data;243 usb_multimedia_t *multim_dev = ddf_fun_data_get(fun); 251 244 252 245 usb_hid_report_path_t *path = usb_hid_report_path(); -
uspace/drv/bus/usb/usbhid/multimedia/multimedia.h
re0d5bc5 r96e01fbc 41 41 struct usb_hid_dev; 42 42 43 /*----------------------------------------------------------------------------*/ 43 44 44 45 45 int usb_multimedia_init(struct usb_hid_dev *hid_dev, void **data); … … 49 49 bool usb_multimedia_polling_callback(struct usb_hid_dev *hid_dev, void *data); 50 50 51 /*----------------------------------------------------------------------------*/ 51 52 52 53 53 #endif // USB_HID_MULTIMEDIA_H_ -
uspace/drv/bus/usb/usbhid/subdrivers.h
re0d5bc5 r96e01fbc 40 40 #include "kbd/kbddev.h" 41 41 42 /*----------------------------------------------------------------------------*/ 42 43 43 44 44 typedef struct usb_hid_subdriver_usage { … … 47 47 } usb_hid_subdriver_usage_t; 48 48 49 /*----------------------------------------------------------------------------*/ 49 50 50 51 51 /** Structure representing the mapping between device requirements and the … … 81 81 } usb_hid_subdriver_mapping_t; 82 82 83 /*----------------------------------------------------------------------------*/ 83 84 84 85 85 extern const usb_hid_subdriver_mapping_t usb_hid_subdrivers[]; 86 86 extern const size_t USB_HID_MAX_SUBDRIVERS; 87 87 88 /*----------------------------------------------------------------------------*/ 88 89 89 90 90 #endif /* USB_HID_SUBDRIVERS_H_ */ -
uspace/drv/bus/usb/usbhid/usbhid.c
re0d5bc5 r96e01fbc 58 58 NULL 59 59 }; 60 /*----------------------------------------------------------------------------*/ 60 61 61 static int usb_hid_set_boot_kbd_subdriver(usb_hid_dev_t *hid_dev) 62 62 { … … 74 74 return EOK; 75 75 } 76 /*----------------------------------------------------------------------------*/ 76 77 77 static int usb_hid_set_boot_mouse_subdriver(usb_hid_dev_t *hid_dev) 78 78 { … … 90 90 return EOK; 91 91 } 92 /*----------------------------------------------------------------------------*/ 92 93 93 static int usb_hid_set_generic_hid_subdriver(usb_hid_dev_t *hid_dev) 94 94 { … … 110 110 return EOK; 111 111 } 112 /*----------------------------------------------------------------------------*/ 112 113 113 static bool usb_hid_ids_match(const usb_hid_dev_t *hid_dev, 114 114 const usb_hid_subdriver_mapping_t *mapping) … … 122 122 == mapping->product_id); 123 123 } 124 /*----------------------------------------------------------------------------*/ 124 125 125 static bool usb_hid_path_matches(usb_hid_dev_t *hid_dev, 126 126 const usb_hid_subdriver_mapping_t *mapping) … … 178 178 return matches; 179 179 } 180 /*----------------------------------------------------------------------------*/ 180 181 181 static int usb_hid_save_subdrivers(usb_hid_dev_t *hid_dev, 182 182 const usb_hid_subdriver_t **subdrivers, unsigned count) … … 211 211 return EOK; 212 212 } 213 /*----------------------------------------------------------------------------*/ 213 214 214 static int usb_hid_find_subdrivers(usb_hid_dev_t *hid_dev) 215 215 { … … 263 263 return usb_hid_save_subdrivers(hid_dev, subdrivers, count); 264 264 } 265 /*----------------------------------------------------------------------------*/ 265 266 266 static int usb_hid_check_pipes(usb_hid_dev_t *hid_dev, const usb_device_t *dev) 267 267 { … … 290 290 return ENOTSUP; 291 291 } 292 /*----------------------------------------------------------------------------*/ 292 293 293 static int usb_hid_init_report(usb_hid_dev_t *hid_dev) 294 294 { … … 322 322 return EOK; 323 323 } 324 /*----------------------------------------------------------------------------*/ 324 325 325 /* 326 326 * This functions initializes required structures from the device's descriptors … … 458 458 return rc; 459 459 } 460 /*----------------------------------------------------------------------------*/ 460 461 461 bool usb_hid_polling_callback(usb_device_t *dev, uint8_t *buffer, 462 462 size_t buffer_size, void *arg) … … 500 500 return cont; 501 501 } 502 /*----------------------------------------------------------------------------*/ 502 503 503 void usb_hid_polling_ended_callback(usb_device_t *dev, bool reason, void *arg) 504 504 { … … 517 517 hid_dev->running = false; 518 518 } 519 /*----------------------------------------------------------------------------*/ 519 520 520 void usb_hid_new_report(usb_hid_dev_t *hid_dev) 521 521 { 522 522 ++hid_dev->report_nr; 523 523 } 524 /*----------------------------------------------------------------------------*/ 524 525 525 int usb_hid_report_number(const usb_hid_dev_t *hid_dev) 526 526 { 527 527 return hid_dev->report_nr; 528 528 } 529 /*----------------------------------------------------------------------------*/ 529 530 530 void usb_hid_deinit(usb_hid_dev_t *hid_dev) 531 531 { -
uspace/drv/bus/usb/usbhid/usbhid.h
re0d5bc5 r96e01fbc 95 95 }; 96 96 97 /*----------------------------------------------------------------------------*/ 97 98 98 /** 99 99 * Structure for holding general HID device data. … … 132 132 }; 133 133 134 /*----------------------------------------------------------------------------*/ 134 135 135 136 136 enum { … … 143 143 extern const usb_endpoint_description_t *usb_hid_endpoints[]; 144 144 145 /*----------------------------------------------------------------------------*/ 145 146 146 147 147 int usb_hid_init(usb_hid_dev_t *hid_dev, usb_device_t *dev); -
uspace/drv/bus/usb/usbhub/port.c
re0d5bc5 r96e01fbc 70 70 return EOK; 71 71 } 72 /*----------------------------------------------------------------------------*/ 72 73 73 /** 74 74 * Clear feature on hub port. … … 92 92 sizeof(clear_request), NULL, 0); 93 93 } 94 /*----------------------------------------------------------------------------*/ 94 95 95 /** 96 96 * Set feature on hub port. … … 114 114 sizeof(clear_request), NULL, 0); 115 115 } 116 /*----------------------------------------------------------------------------*/ 116 117 117 /** 118 118 * Mark reset process as failed due to external reasons … … 129 129 fibril_mutex_unlock(&port->mutex); 130 130 } 131 /*----------------------------------------------------------------------------*/ 131 132 132 /** 133 133 * Process interrupts on given port … … 245 245 port->port_number, status); 246 246 } 247 /*----------------------------------------------------------------------------*/ 247 248 248 /** 249 249 * routine called when a device on port has been removed … … 299 299 return EOK; 300 300 } 301 /*----------------------------------------------------------------------------*/ 301 302 302 /** 303 303 * Process port reset change … … 335 335 } 336 336 } 337 /*----------------------------------------------------------------------------*/ 337 338 338 /** Retrieve port status. 339 339 * … … 352 352 .request = USB_HUB_REQUEST_GET_STATUS, 353 353 .value = 0, 354 .index = port->port_number,354 .index = uint16_host2usb(port->port_number), 355 355 .length = sizeof(usb_port_status_t), 356 356 }; … … 375 375 return EOK; 376 376 } 377 /*----------------------------------------------------------------------------*/ 377 378 378 /** Callback for enabling a specific port. 379 379 * … … 407 407 return port->reset_okay ? EOK : ESTALL; 408 408 } 409 /*----------------------------------------------------------------------------*/ 409 410 410 /** Fibril for adding a new device. 411 411 * … … 436 436 usb_log_info("Detected new device on `%s' (port %zu), " 437 437 "address %d (handle %" PRIun ").\n", 438 data->hub->usb_device->ddf_dev->name, 439 data->port->port_number, new_address, child_fun->handle); 438 ddf_dev_get_name(data->hub->usb_device->ddf_dev), 439 data->port->port_number, new_address, 440 ddf_fun_get_handle(child_fun)); 440 441 } else { 441 442 usb_log_error("Failed registering device on port %zu: %s.\n", … … 454 455 return rc; 455 456 } 456 /*----------------------------------------------------------------------------*/ 457 457 458 /** Start device adding when connection change is detected. 458 459 * -
uspace/drv/bus/usb/usbhub/status.h
re0d5bc5 r96e01fbc 42 42 * should not be accessed directly, use supplied getter/setter methods. 43 43 * 44 * For more information refer to table 11-15 in 45 * "Universal Serial Bus Specification Revision 1.1" 44 * For more information refer to tables 11-15 and 11-16 in 45 * "Universal Serial Bus Specification Revision 1.1" pages 274 and 277 46 * (290 and 293 in pdf) 46 47 * 47 48 */ -
uspace/drv/bus/usb/usbhub/usbhub.c
re0d5bc5 r96e01fbc 160 160 hub_dev->running = true; 161 161 usb_log_info("Controlling hub '%s' (%zu ports).\n", 162 hub_dev->usb_device->ddf_dev->name, hub_dev->port_count);162 ddf_dev_get_name(hub_dev->usb_device->ddf_dev), hub_dev->port_count); 163 163 164 164 usb_pipe_end_long_transfer(&usb_dev->ctrl_pipe); 165 165 return EOK; 166 166 } 167 /*----------------------------------------------------------------------------*/ 167 168 168 /** 169 169 * Turn off power to all ports. … … 176 176 return ENOTSUP; 177 177 } 178 /*----------------------------------------------------------------------------*/ 178 179 179 /** 180 180 * Remove all attached devices … … 219 219 return EOK; 220 220 } 221 /*----------------------------------------------------------------------------*/ 221 222 222 /** Callback for polling hub for changes. 223 223 * … … 256 256 return true; 257 257 } 258 /*----------------------------------------------------------------------------*/ 258 259 259 /** 260 260 * Load hub-specific information into hub_dev structure and process if needed … … 331 331 return EOK; 332 332 } 333 /*----------------------------------------------------------------------------*/ 333 334 334 /** 335 335 * Set configuration of and USB device … … 378 378 return opResult; 379 379 } 380 /*----------------------------------------------------------------------------*/ 380 381 381 /** 382 382 * Process hub over current change … … 416 416 417 417 } 418 /*----------------------------------------------------------------------------*/ 418 419 419 /** 420 420 * Process hub interrupts. … … 485 485 } 486 486 } 487 /*----------------------------------------------------------------------------*/ 487 488 488 /** 489 489 * callback called from hub polling fibril when the fibril terminates -
uspace/drv/bus/usb/usbmast/main.c
re0d5bc5 r96e01fbc 37 37 #include <as.h> 38 38 #include <async.h> 39 #include < ipc/bd.h>39 #include <bd_srv.h> 40 40 #include <macros.h> 41 41 #include <usb/dev/driver.h> … … 82 82 void *arg); 83 83 84 static int usbmast_bd_open(bd_srvs_t *, bd_srv_t *); 85 static int usbmast_bd_close(bd_srv_t *); 86 static int usbmast_bd_read_blocks(bd_srv_t *, aoff64_t, size_t, void *, size_t); 87 static int usbmast_bd_write_blocks(bd_srv_t *, aoff64_t, size_t, const void *, size_t); 88 static int usbmast_bd_get_block_size(bd_srv_t *, size_t *); 89 static int usbmast_bd_get_num_blocks(bd_srv_t *, aoff64_t *); 90 91 static bd_ops_t usbmast_bd_ops = { 92 .open = usbmast_bd_open, 93 .close = usbmast_bd_close, 94 .read_blocks = usbmast_bd_read_blocks, 95 .write_blocks = usbmast_bd_write_blocks, 96 .get_block_size = usbmast_bd_get_block_size, 97 .get_num_blocks = usbmast_bd_get_num_blocks 98 }; 99 100 static usbmast_fun_t *bd_srv_usbmast(bd_srv_t *bd) 101 { 102 return (usbmast_fun_t *) bd->srvs->sarg; 103 } 104 84 105 /** Callback when a device is removed from the system. 85 106 * … … 139 160 mdev->usb_dev = dev; 140 161 141 usb_log_info("Initializing mass storage `%s'.\n", d ev->ddf_dev->name);162 usb_log_info("Initializing mass storage `%s'.\n", ddf_dev_get_name(dev->ddf_dev)); 142 163 usb_log_debug("Bulk in endpoint: %d [%zuB].\n", 143 164 dev->pipes[BULK_IN_EP].pipe.endpoint_no, … … 219 240 mfun->lun = lun; 220 241 242 bd_srvs_init(&mfun->bds); 243 mfun->bds.ops = &usbmast_bd_ops; 244 mfun->bds.sarg = mfun; 245 221 246 /* Set up a connection handler. */ 222 fun->conn_handler = usbmast_bd_connection;247 ddf_fun_set_conn_handler(fun, usbmast_bd_connection); 223 248 224 249 usb_log_debug("Inquire...\n"); … … 227 252 if (rc != EOK) { 228 253 usb_log_warning("Failed to inquire device `%s': %s.\n", 229 mdev->ddf_dev->name, str_error(rc));254 ddf_dev_get_name(mdev->ddf_dev), str_error(rc)); 230 255 rc = EIO; 231 256 goto error; … … 234 259 usb_log_info("Mass storage `%s' LUN %u: " \ 235 260 "%s by %s rev. %s is %s (%s).\n", 236 mdev->ddf_dev->name,261 ddf_dev_get_name(mdev->ddf_dev), 237 262 lun, 238 263 inquiry.product, … … 247 272 if (rc != EOK) { 248 273 usb_log_warning("Failed to read capacity, device `%s': %s.\n", 249 mdev->ddf_dev->name, str_error(rc));274 ddf_dev_get_name(mdev->ddf_dev), str_error(rc)); 250 275 rc = EIO; 251 276 goto error; … … 284 309 { 285 310 usbmast_fun_t *mfun; 286 void *comm_buf = NULL; 287 size_t comm_size; 288 ipc_callid_t callid; 289 ipc_call_t call; 290 unsigned int flags; 291 sysarg_t method; 292 uint64_t ba; 293 size_t cnt; 294 int retval; 295 296 async_answer_0(iid, EOK); 297 298 if (!async_share_out_receive(&callid, &comm_size, &flags)) { 299 async_answer_0(callid, EHANGUP); 300 return; 301 } 302 303 (void) async_share_out_finalize(callid, &comm_buf); 304 if (comm_buf == AS_MAP_FAILED) { 305 async_answer_0(callid, EHANGUP); 306 return; 307 } 308 309 mfun = (usbmast_fun_t *) ((ddf_fun_t *)arg)->driver_data; 310 311 while (true) { 312 callid = async_get_call(&call); 313 method = IPC_GET_IMETHOD(call); 314 315 if (!method) { 316 /* The other side hung up. */ 317 async_answer_0(callid, EOK); 318 return; 319 } 320 321 switch (method) { 322 case BD_GET_BLOCK_SIZE: 323 async_answer_1(callid, EOK, mfun->block_size); 324 break; 325 case BD_GET_NUM_BLOCKS: 326 async_answer_2(callid, EOK, LOWER32(mfun->nblocks), 327 UPPER32(mfun->nblocks)); 328 break; 329 case BD_READ_BLOCKS: 330 ba = MERGE_LOUP32(IPC_GET_ARG1(call), IPC_GET_ARG2(call)); 331 cnt = IPC_GET_ARG3(call); 332 retval = usbmast_read(mfun, ba, cnt, comm_buf); 333 async_answer_0(callid, retval); 334 break; 335 case BD_WRITE_BLOCKS: 336 ba = MERGE_LOUP32(IPC_GET_ARG1(call), IPC_GET_ARG2(call)); 337 cnt = IPC_GET_ARG3(call); 338 retval = usbmast_write(mfun, ba, cnt, comm_buf); 339 async_answer_0(callid, retval); 340 break; 341 default: 342 async_answer_0(callid, EINVAL); 343 } 344 } 345 } 311 312 mfun = (usbmast_fun_t *) ddf_fun_data_get((ddf_fun_t *)arg); 313 bd_conn(iid, icall, &mfun->bds); 314 } 315 316 /** Open device. */ 317 static int usbmast_bd_open(bd_srvs_t *bds, bd_srv_t *bd) 318 { 319 return EOK; 320 } 321 322 /** Close device. */ 323 static int usbmast_bd_close(bd_srv_t *bd) 324 { 325 return EOK; 326 } 327 328 /** Read blocks from the device. */ 329 static int usbmast_bd_read_blocks(bd_srv_t *bd, uint64_t ba, size_t cnt, void *buf, 330 size_t size) 331 { 332 usbmast_fun_t *mfun = bd_srv_usbmast(bd); 333 334 if (size < cnt * mfun->block_size) 335 return EINVAL; 336 337 return usbmast_read(mfun, ba, cnt, buf); 338 } 339 340 /** Write blocks to the device. */ 341 static int usbmast_bd_write_blocks(bd_srv_t *bd, uint64_t ba, size_t cnt, 342 const void *buf, size_t size) 343 { 344 usbmast_fun_t *mfun = bd_srv_usbmast(bd); 345 346 if (size < cnt * mfun->block_size) 347 return EINVAL; 348 349 return usbmast_write(mfun, ba, cnt, buf); 350 } 351 352 /** Get device block size. */ 353 static int usbmast_bd_get_block_size(bd_srv_t *bd, size_t *rsize) 354 { 355 usbmast_fun_t *mfun = bd_srv_usbmast(bd); 356 *rsize = mfun->block_size; 357 return EOK; 358 } 359 360 /** Get number of blocks on device. */ 361 static int usbmast_bd_get_num_blocks(bd_srv_t *bd, aoff64_t *rnb) 362 { 363 usbmast_fun_t *mfun = bd_srv_usbmast(bd); 364 *rnb = mfun->nblocks; 365 return EOK; 366 } 367 346 368 347 369 /** USB mass storage driver ops. */ -
uspace/drv/bus/usb/usbmast/scsi_ms.c
re0d5bc5 r96e01fbc 88 88 if (rc != EOK) { 89 89 usb_log_error("Inquiry transport failed, device %s: %s.\n", 90 mfun->mdev->ddf_dev->name, str_error(rc));90 ddf_dev_get_name(mfun->mdev->ddf_dev), str_error(rc)); 91 91 return rc; 92 92 } … … 96 96 97 97 usb_log_error("SCSI command failed, device %s.\n", 98 mfun->mdev->ddf_dev->name);98 ddf_dev_get_name(mfun->mdev->ddf_dev)); 99 99 100 100 rc = usbmast_request_sense(mfun, &sense_buf, sizeof(sense_buf)); … … 147 147 if (rc != EOK) { 148 148 usb_log_error("Inquiry transport failed, device %s: %s.\n", 149 mfun->mdev->ddf_dev->name, str_error(rc));149 ddf_dev_get_name(mfun->mdev->ddf_dev), str_error(rc)); 150 150 return rc; 151 151 } … … 153 153 if (cmd.status != CMDS_GOOD) { 154 154 usb_log_error("Inquiry command failed, device %s.\n", 155 mfun->mdev->ddf_dev->name);155 ddf_dev_get_name(mfun->mdev->ddf_dev)); 156 156 return EIO; 157 157 } … … 215 215 if (rc != EOK || cmd.status != CMDS_GOOD) { 216 216 usb_log_error("Request Sense failed, device %s: %s.\n", 217 mfun->mdev->ddf_dev->name, str_error(rc));217 ddf_dev_get_name(mfun->mdev->ddf_dev), str_error(rc)); 218 218 return rc; 219 219 } … … 257 257 if (rc != EOK) { 258 258 usb_log_error("Read Capacity (10) transport failed, device %s: %s.\n", 259 mfun->mdev->ddf_dev->name, str_error(rc));259 ddf_dev_get_name(mfun->mdev->ddf_dev), str_error(rc)); 260 260 return rc; 261 261 } … … 263 263 if (cmd.status != CMDS_GOOD) { 264 264 usb_log_error("Read Capacity (10) command failed, device %s.\n", 265 mfun->mdev->ddf_dev->name);265 ddf_dev_get_name(mfun->mdev->ddf_dev)); 266 266 return EIO; 267 267 } … … 314 314 if (rc != EOK) { 315 315 usb_log_error("Read (10) transport failed, device %s: %s.\n", 316 mfun->mdev->ddf_dev->name, str_error(rc));316 ddf_dev_get_name(mfun->mdev->ddf_dev), str_error(rc)); 317 317 return rc; 318 318 } … … 320 320 if (cmd.status != CMDS_GOOD) { 321 321 usb_log_error("Read (10) command failed, device %s.\n", 322 mfun->mdev->ddf_dev->name);322 ddf_dev_get_name(mfun->mdev->ddf_dev)); 323 323 return EIO; 324 324 } … … 370 370 if (rc != EOK) { 371 371 usb_log_error("Write (10) transport failed, device %s: %s.\n", 372 mfun->mdev->ddf_dev->name, str_error(rc));372 ddf_dev_get_name(mfun->mdev->ddf_dev), str_error(rc)); 373 373 return rc; 374 374 } … … 376 376 if (cmd.status != CMDS_GOOD) { 377 377 usb_log_error("Write (10) command failed, device %s.\n", 378 mfun->mdev->ddf_dev->name);378 ddf_dev_get_name(mfun->mdev->ddf_dev)); 379 379 return EIO; 380 380 } -
uspace/drv/bus/usb/usbmast/usbmast.h
re0d5bc5 r96e01fbc 37 37 #define USBMAST_H_ 38 38 39 #include <bd_srv.h> 39 40 #include <sys/types.h> 40 41 #include <usb/usb.h> … … 68 69 /** Block size in bytes */ 69 70 size_t block_size; 71 /** Block device service structure */ 72 bd_srvs_t bds; 70 73 } usbmast_fun_t; 71 74 -
uspace/drv/bus/usb/usbmid/explore.c
re0d5bc5 r96e01fbc 172 172 return false; 173 173 } 174 usb_mid->ctl_fun->ops = &mid_device_ops;174 ddf_fun_set_ops(usb_mid->ctl_fun, &mid_device_ops); 175 175 176 176 /* Bind control function. */ -
uspace/drv/bus/usb/usbmid/main.c
re0d5bc5 r96e01fbc 51 51 static int usbmid_device_add(usb_device_t *dev) 52 52 { 53 usb_log_info("Taking care of new MID `%s'.\n", d ev->ddf_dev->name);53 usb_log_info("Taking care of new MID `%s'.\n", ddf_dev_get_name(dev->ddf_dev)); 54 54 55 55 const bool accept = usbmid_explore_device(dev); … … 61 61 return EOK; 62 62 } 63 /*----------------------------------------------------------------------------*/ 63 64 64 /** Callback when a MID device is about to be removed from the host. 65 65 * … … 115 115 return ret; 116 116 } 117 /*----------------------------------------------------------------------------*/ 117 118 118 /** Callback when a MID device was removed from the host. 119 119 * … … 127 127 assert(usb_mid); 128 128 129 usb_log_info("USB MID gone: `%s'.\n", d ev->ddf_dev->name);129 usb_log_info("USB MID gone: `%s'.\n", ddf_dev_get_name(dev->ddf_dev)); 130 130 131 131 /* Remove ctl function */ -
uspace/drv/bus/usb/usbmid/usbmid.c
re0d5bc5 r96e01fbc 30 30 * @{ 31 31 */ 32 33 /* XXX Fix this */ 34 #define _DDF_DATA_IMPLANT 35 32 36 /** 33 37 * @file … … 47 51 static int usb_iface_get_interface_impl(ddf_fun_t *fun, int *iface_no) 48 52 { 49 assert(fun); 50 51 usbmid_interface_t *iface = fun->driver_data; 53 usbmid_interface_t *iface = ddf_fun_data_get(fun); 52 54 assert(iface); 53 55 … … 123 125 } 124 126 127 match_id_list_t match_ids; 128 init_match_ids(&match_ids); 129 125 130 rc = usb_device_create_match_ids_from_interface(device_descriptor, 126 interface_descriptor, & child->match_ids);131 interface_descriptor, &match_ids); 127 132 if (rc != EOK) { 128 133 ddf_fun_destroy(child); 129 134 return rc; 130 135 } 136 137 list_foreach(match_ids.ids, link) { 138 match_id_t *match_id = list_get_instance(link, match_id_t, link); 139 rc = ddf_fun_add_match_id(child, match_id->id, match_id->score); 140 if (rc != EOK) { 141 clean_match_ids(&match_ids); 142 ddf_fun_destroy(child); 143 return rc; 144 } 145 } 146 clean_match_ids(&match_ids); 131 147 132 148 rc = ddf_fun_bind(child); … … 138 154 139 155 iface->fun = child; 140 child->driver_data = iface;141 child->ops = &child_device_ops;156 ddf_fun_data_implant(child, iface); 157 ddf_fun_set_ops(child, &child_device_ops); 142 158 143 159 return EOK; -
uspace/drv/bus/usb/vhc/conndev.c
re0d5bc5 r96e01fbc 94 94 ipc_call_t *icall) 95 95 { 96 vhc_data_t *vhc = fun->dev->driver_data;96 vhc_data_t *vhc = ddf_dev_data_get(ddf_fun_get_dev(fun)); 97 97 98 98 async_sess_t *callback = … … 125 125 void on_client_close(ddf_fun_t *fun) 126 126 { 127 vhc_data_t *vhc = fun->dev->driver_data;127 vhc_data_t *vhc = ddf_dev_data_get(ddf_fun_get_dev(fun)); 128 128 129 129 if (plugged_device_handle != 0) { -
uspace/drv/bus/usb/vhc/connhost.c
re0d5bc5 r96e01fbc 42 42 43 43 #define GET_VHC_DATA(fun) \ 44 ((vhc_data_t *) fun->dev->driver_data)44 ((vhc_data_t *)ddf_dev_data_get(ddf_fun_get_dev(fun))) 45 45 #define VHC_DATA(vhc, fun) \ 46 46 vhc_data_t *vhc = GET_VHC_DATA(fun); assert(vhc->magic == 0xdeadbeef) … … 483 483 VHC_DATA(vhc, root_hub_fun); 484 484 485 *handle = vhc->hc_fun->handle;485 *handle = ddf_fun_get_handle(vhc->hc_fun); 486 486 487 487 return EOK; … … 492 492 VHC_DATA(vhc, root_hub_fun); 493 493 494 devman_handle_t handle = root_hub_fun->handle;494 devman_handle_t handle = ddf_fun_get_handle(root_hub_fun); 495 495 496 496 usb_log_debug("tell_address_rh(handle=%" PRIun ")\n", handle); -
uspace/drv/bus/usb/vhc/hub.c
re0d5bc5 r96e01fbc 100 100 async_sess_t *sess; 101 101 do { 102 sess = devman_device_connect(EXCHANGE_SERIALIZE, hc_dev->handle, 0); 102 sess = devman_device_connect(EXCHANGE_SERIALIZE, 103 ddf_fun_get_handle(hc_dev), 0); 103 104 } while (!sess); 104 105 async_hangup(sess); … … 107 108 108 109 usb_hc_connection_t hc_conn; 109 usb_hc_connection_initialize(&hc_conn, hc_dev->handle);110 usb_hc_connection_initialize(&hc_conn, ddf_fun_get_handle(hc_dev)); 110 111 111 112 rc = usb_hc_connection_open(&hc_conn); … … 113 114 114 115 ddf_fun_t *hub_dev; 115 rc = usb_hc_new_device_wrapper( hc_dev->dev, &hc_conn, USB_SPEED_FULL,116 rc = usb_hc_new_device_wrapper(ddf_fun_get_dev(hc_dev), &hc_conn, USB_SPEED_FULL, 116 117 pretend_port_rest, NULL, NULL, &rh_ops, hc_dev, &hub_dev); 117 118 if (rc != EOK) { … … 123 124 124 125 usb_log_info("Created root hub function (handle %zu).\n", 125 (size_t) hub_dev->handle);126 (size_t) ddf_fun_get_handle(hub_dev)); 126 127 127 128 return 0; -
uspace/drv/bus/usb/vhc/main.c
re0d5bc5 r96e01fbc 67 67 } 68 68 69 vhc_data_t *data = malloc(sizeof(vhc_data_t));69 vhc_data_t *data = ddf_dev_data_alloc(dev, sizeof(vhc_data_t)); 70 70 if (data == NULL) { 71 71 usb_log_fatal("Failed to allocate memory.\n"); … … 89 89 } 90 90 91 hc->ops = &vhc_ops;91 ddf_fun_set_ops(hc, &vhc_ops); 92 92 list_initialize(&data->devices); 93 93 fibril_mutex_initialize(&data->guard); 94 94 data->hub = &virtual_hub_device; 95 95 data->hc_fun = hc; 96 97 dev->driver_data = data;98 96 99 97 rc = ddf_fun_bind(hc); … … 116 114 117 115 usb_log_info("Virtual USB host controller ready (dev %zu, hc %zu).\n", 118 (size_t) dev->handle, (size_t) hc->handle); 119 120 116 (size_t) ddf_dev_get_handle(dev), (size_t) ddf_fun_get_handle(hc)); 121 117 122 118 rc = vhc_virtdev_plug_hub(data, data->hub, NULL);
Note:
See TracChangeset
for help on using the changeset viewer.