Changeset 96e01fbc in mainline for uspace/drv/bus/usb/ohci
- 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/ohci
- Files:
-
- 1 added
- 17 edited
-
endpoint_list.c (modified) (4 diffs)
-
hc.c (modified) (31 diffs)
-
hw_struct/endpoint_descriptor.c (modified) (2 diffs)
-
hw_struct/endpoint_descriptor.h (modified) (7 diffs)
-
hw_struct/hcca.h (modified) (1 diff)
-
hw_struct/mem_access.h (added)
-
hw_struct/transfer_descriptor.c (modified) (2 diffs)
-
hw_struct/transfer_descriptor.h (modified) (4 diffs)
-
main.c (modified) (1 diff)
-
ohci.c (modified) (10 diffs)
-
ohci_batch.c (modified) (10 diffs)
-
ohci_batch.h (modified) (1 diff)
-
ohci_endpoint.c (modified) (3 diffs)
-
ohci_regs.h (modified) (8 diffs)
-
res.c (modified) (3 diffs)
-
res.h (modified) (1 diff)
-
root_hub.c (modified) (34 diffs)
-
utils/malloc32.h (modified) (2 diffs)
Legend:
- Unmodified
- Added
- Removed
-
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 *
Note:
See TracChangeset
for help on using the changeset viewer.
