Changeset 548c123 in mainline
- Timestamp:
- 2017-09-29T21:46:08Z (7 years ago)
- Branches:
- lfn, master, serial, ticket/834-toolchain-update, topic/msim-upgrade, topic/simplify-dev-export
- Children:
- cc9ac7c
- Parents:
- ab5a0830
- Location:
- uspace/drv/bus/usb/xhci
- Files:
-
- 5 edited
Legend:
- Unmodified
- Added
- Removed
-
uspace/drv/bus/usb/xhci/commands.c
rab5a0830 r548c123 55 55 */ 56 56 #define TRB_SET_DEQUEUE_PTR(trb, dptr) (trb).parameter |= host2xhci(64, (dptr)) 57 #define TRB_SET_ICTX(trb, phys) (trb).parameter |= host2xhci( 32, phys_addr & (~0xF))57 #define TRB_SET_ICTX(trb, phys) (trb).parameter |= host2xhci(64, phys_addr & (~0xF)) 58 58 59 59 #define TRB_GET_CODE(trb) XHCI_DWORD_EXTRACT((trb).status, 31, 24) … … 108 108 */ 109 109 cmd->has_owner = true; 110 cmd->owns_trb = false;111 110 112 111 return cmd; … … 119 118 if (cmd->ictx) 120 119 free32(cmd->ictx); 121 if (cmd->owns_trb && cmd->trb)122 free32(cmd->trb);123 120 124 121 free32(cmd); … … 128 125 { 129 126 link_t *cmd_link = list_first(&hc->commands); 127 128 129 usb_log_debug2("Searching TRB %lu...", phys); 130 130 131 131 while (cmd_link != NULL) { 132 132 xhci_cmd_t *cmd = list_get_instance(cmd_link, xhci_cmd_t, link); 133 133 134 if ( addr_to_phys(cmd->trb)== phys)134 if (cmd->trb_phys == phys) 135 135 break; 136 136 … … 155 155 } 156 156 157 static inline int enqueue_trb(xhci_hc_t *hc, xhci_trb_t *trb, 158 unsigned doorbell, unsigned target) 159 { 160 assert(hc); 161 assert(trb); 162 163 xhci_trb_ring_enqueue(&hc->command_ring, trb); 157 static inline int enqueue_command(xhci_hc_t *hc, xhci_cmd_t *cmd, unsigned doorbell, unsigned target) 158 { 159 assert(hc); 160 assert(cmd); 161 162 list_append(&cmd->link, &hc->commands); 163 164 xhci_trb_ring_enqueue(&hc->command_ring, &cmd->trb, &cmd->trb_phys); 164 165 ring_doorbell(hc, doorbell, target); 165 166 166 xhci_dump_trb(trb);167 usb_log_debug2("HC(%p): Sent TRB", hc);167 usb_log_debug2("HC(%p): Sent command:", hc); 168 xhci_dump_trb(&cmd->trb); 168 169 169 170 return EOK; 170 }171 172 static inline void add_cmd(xhci_hc_t *hc, xhci_cmd_t *cmd)173 {174 assert(cmd);175 176 list_append(&cmd->link, &hc->commands);177 cmd->trb = hc->command_ring.enqueue_trb;178 171 } 179 172 … … 263 256 assert(hc); 264 257 265 xhci_trb_t trb; 266 memset(&trb, 0, sizeof(trb)); 267 268 TRB_SET_TYPE(trb, XHCI_TRB_TYPE_NO_OP_CMD); 269 270 add_cmd(hc, cmd); 271 272 return enqueue_trb(hc, &trb, 0, 0); 258 xhci_trb_clean(&cmd->trb); 259 260 TRB_SET_TYPE(cmd->trb, XHCI_TRB_TYPE_NO_OP_CMD); 261 262 return enqueue_command(hc, cmd, 0, 0); 273 263 } 274 264 … … 277 267 assert(hc); 278 268 279 xhci_trb_t trb; 280 memset(&trb, 0, sizeof(trb)); 281 282 TRB_SET_TYPE(trb, XHCI_TRB_TYPE_ENABLE_SLOT_CMD); 283 trb.control |= host2xhci(32, XHCI_REG_RD(hc->xecp, XHCI_EC_SP_SLOT_TYPE) << 16); 284 285 add_cmd(hc, cmd); 286 287 return enqueue_trb(hc, &trb, 0, 0); 269 xhci_trb_clean(&cmd->trb); 270 271 TRB_SET_TYPE(cmd->trb, XHCI_TRB_TYPE_ENABLE_SLOT_CMD); 272 cmd->trb.control |= host2xhci(32, XHCI_REG_RD(hc->xecp, XHCI_EC_SP_SLOT_TYPE) << 16); 273 274 return enqueue_command(hc, cmd, 0, 0); 288 275 } 289 276 … … 293 280 assert(cmd); 294 281 295 xhci_trb_t trb; 296 memset(&trb, 0, sizeof(trb)); 297 298 TRB_SET_TYPE(trb, XHCI_TRB_TYPE_DISABLE_SLOT_CMD); 299 TRB_SET_SLOT(trb, cmd->slot_id); 300 301 add_cmd(hc, cmd); 302 303 return enqueue_trb(hc, &trb, 0, 0); 282 xhci_trb_clean(&cmd->trb); 283 284 TRB_SET_TYPE(cmd->trb, XHCI_TRB_TYPE_DISABLE_SLOT_CMD); 285 TRB_SET_SLOT(cmd->trb, cmd->slot_id); 286 287 return enqueue_command(hc, cmd, 0, 0); 304 288 } 305 289 … … 316 300 * other should be ignored at this point (see section 4.6.5). 317 301 */ 318 xhci_trb_t trb; 319 memset(&trb, 0, sizeof(trb)); 302 xhci_trb_clean(&cmd->trb); 320 303 321 304 uint64_t phys_addr = (uint64_t) addr_to_phys(cmd->ictx); 322 TRB_SET_ICTX( trb, phys_addr);305 TRB_SET_ICTX(cmd->trb, phys_addr); 323 306 324 307 /** … … 329 312 * that require their device descriptor to be read before such request. 330 313 */ 331 TRB_SET_TYPE(trb, XHCI_TRB_TYPE_ADDRESS_DEVICE_CMD); 332 TRB_SET_SLOT(trb, cmd->slot_id); 333 334 add_cmd(hc, cmd); 335 336 return enqueue_trb(hc, &trb, 0, 0); 314 TRB_SET_TYPE(cmd->trb, XHCI_TRB_TYPE_ADDRESS_DEVICE_CMD); 315 TRB_SET_SLOT(cmd->trb, cmd->slot_id); 316 317 return enqueue_command(hc, cmd, 0, 0); 337 318 } 338 319 … … 343 324 assert(cmd->ictx); 344 325 345 xhci_trb_t trb; 346 memset(&trb, 0, sizeof(trb)); 326 xhci_trb_clean(&cmd->trb); 347 327 348 328 uint64_t phys_addr = (uint64_t) addr_to_phys(cmd->ictx); 349 TRB_SET_ICTX(trb, phys_addr); 350 351 TRB_SET_TYPE(trb, XHCI_TRB_TYPE_CONFIGURE_ENDPOINT_CMD); 352 TRB_SET_SLOT(trb, cmd->slot_id); 353 354 add_cmd(hc, cmd); 355 356 return enqueue_trb(hc, &trb, 0, 0); 329 TRB_SET_ICTX(cmd->trb, phys_addr); 330 331 TRB_SET_TYPE(cmd->trb, XHCI_TRB_TYPE_CONFIGURE_ENDPOINT_CMD); 332 TRB_SET_SLOT(cmd->trb, cmd->slot_id); 333 334 return enqueue_command(hc, cmd, 0, 0); 357 335 } 358 336 … … 369 347 * Refer to sections 6.2.2.3 and 6.3.3.3 for further info. 370 348 */ 371 xhci_trb_t trb; 372 memset(&trb, 0, sizeof(trb)); 349 xhci_trb_clean(&cmd->trb); 373 350 374 351 uint64_t phys_addr = (uint64_t) addr_to_phys(cmd->ictx); 375 TRB_SET_ICTX(trb, phys_addr); 376 377 TRB_SET_TYPE(trb, XHCI_TRB_TYPE_EVALUATE_CONTEXT_CMD); 378 TRB_SET_SLOT(trb, cmd->slot_id); 379 380 add_cmd(hc, cmd); 381 382 return enqueue_trb(hc, &trb, 0, 0); 352 TRB_SET_ICTX(cmd->trb, phys_addr); 353 354 TRB_SET_TYPE(cmd->trb, XHCI_TRB_TYPE_EVALUATE_CONTEXT_CMD); 355 TRB_SET_SLOT(cmd->trb, cmd->slot_id); 356 357 return enqueue_command(hc, cmd, 0, 0); 383 358 } 384 359 … … 392 367 * information about this flag. 393 368 */ 394 xhci_trb_t trb; 395 memset(&trb, 0, sizeof(trb)); 396 397 TRB_SET_TYPE(trb, XHCI_TRB_TYPE_RESET_ENDPOINT_CMD); 398 TRB_SET_TCS(trb, tcs); 399 TRB_SET_EP(trb, ep_id); 400 TRB_SET_SLOT(trb, cmd->slot_id); 401 402 add_cmd(hc, cmd); 403 404 return enqueue_trb(hc, &trb, 0, 0); 369 xhci_trb_clean(&cmd->trb); 370 371 TRB_SET_TYPE(cmd->trb, XHCI_TRB_TYPE_RESET_ENDPOINT_CMD); 372 TRB_SET_TCS(cmd->trb, tcs); 373 TRB_SET_EP(cmd->trb, ep_id); 374 TRB_SET_SLOT(cmd->trb, cmd->slot_id); 375 376 return enqueue_command(hc, cmd, 0, 0); 405 377 } 406 378 … … 410 382 assert(cmd); 411 383 412 xhci_trb_t trb; 413 memset(&trb, 0, sizeof(trb)); 414 415 TRB_SET_TYPE(trb, XHCI_TRB_TYPE_STOP_ENDPOINT_CMD); 416 TRB_SET_EP(trb, ep_id); 417 TRB_SET_SUSP(trb, susp); 418 TRB_SET_SLOT(trb, cmd->slot_id); 419 420 add_cmd(hc, cmd); 421 422 return enqueue_trb(hc, &trb, 0, 0); 384 xhci_trb_clean(&cmd->trb); 385 386 TRB_SET_TYPE(cmd->trb, XHCI_TRB_TYPE_STOP_ENDPOINT_CMD); 387 TRB_SET_EP(cmd->trb, ep_id); 388 TRB_SET_SUSP(cmd->trb, susp); 389 TRB_SET_SLOT(cmd->trb, cmd->slot_id); 390 391 return enqueue_command(hc, cmd, 0, 0); 423 392 } 424 393 … … 430 399 assert(cmd); 431 400 432 xhci_trb_t trb; 433 memset(&trb, 0, sizeof(trb)); 434 435 TRB_SET_TYPE(trb, XHCI_TRB_TYPE_SET_TR_DEQUEUE_POINTER_CMD); 436 TRB_SET_EP(trb, ep_id); 437 TRB_SET_STREAM(trb, stream_id); 438 TRB_SET_SLOT(trb, cmd->slot_id); 439 TRB_SET_DEQUEUE_PTR(trb, dequeue_ptr); 401 xhci_trb_clean(&cmd->trb); 402 403 TRB_SET_TYPE(cmd->trb, XHCI_TRB_TYPE_SET_TR_DEQUEUE_POINTER_CMD); 404 TRB_SET_EP(cmd->trb, ep_id); 405 TRB_SET_STREAM(cmd->trb, stream_id); 406 TRB_SET_SLOT(cmd->trb, cmd->slot_id); 407 TRB_SET_DEQUEUE_PTR(cmd->trb, dequeue_ptr); 440 408 441 409 /** … … 443 411 */ 444 412 445 add_cmd(hc, cmd); 446 447 return enqueue_trb(hc, &trb, 0, 0); 413 return enqueue_command(hc, cmd, 0, 0); 448 414 } 449 415 … … 453 419 assert(cmd); 454 420 455 xhci_trb_t trb; 456 memset(&trb, 0, sizeof(trb)); 457 458 TRB_SET_TYPE(trb, XHCI_TRB_TYPE_RESET_DEVICE_CMD); 459 TRB_SET_SLOT(trb, cmd->slot_id); 460 461 add_cmd(hc, cmd); 462 463 return enqueue_trb(hc, &trb, 0, 0); 421 xhci_trb_clean(&cmd->trb); 422 423 TRB_SET_TYPE(cmd->trb, XHCI_TRB_TYPE_RESET_DEVICE_CMD); 424 TRB_SET_SLOT(cmd->trb, cmd->slot_id); 425 426 return enqueue_command(hc, cmd, 0, 0); 464 427 } 465 428 … … 475 438 uint64_t phys; 476 439 xhci_cmd_t *command; 477 xhci_trb_t *command_trb;478 440 479 441 code = TRB_GET_CODE(*trb); … … 490 452 } 491 453 492 command_trb = command->trb;493 454 command->status = code; 494 455 command->slot_id = TRB_GET_SLOT(*trb); 495 456 496 usb_log_debug2("Completed command trb: %s", xhci_trb_str_type(TRB_TYPE( *command_trb)));497 if (TRB_TYPE( *command_trb) != XHCI_TRB_TYPE_NO_OP_CMD) {457 usb_log_debug2("Completed command trb: %s", xhci_trb_str_type(TRB_TYPE(command->trb))); 458 if (TRB_TYPE(command->trb) != XHCI_TRB_TYPE_NO_OP_CMD) { 498 459 if (code != XHCI_TRBC_SUCCESS) { 499 460 report_error(code); 500 xhci_dump_trb( command_trb);461 xhci_dump_trb(&command->trb); 501 462 } 502 463 } 503 464 504 switch (TRB_TYPE( *command_trb)) {465 switch (TRB_TYPE(command->trb)) { 505 466 case XHCI_TRB_TYPE_NO_OP_CMD: 506 467 assert(code == XHCI_TRBC_TRB_ERROR); … … 526 487 break; 527 488 default: 528 usb_log_debug2("Unsupported command trb: %s", xhci_trb_str_type(TRB_TYPE( *command_trb)));489 usb_log_debug2("Unsupported command trb: %s", xhci_trb_str_type(TRB_TYPE(command->trb))); 529 490 530 491 command->completed = true; … … 536 497 if (!command->has_owner) { 537 498 usb_log_debug2("Command has no owner, deallocating."); 538 command->trb = NULL; // It was statically allocated.539 499 xhci_free_command(command); 540 500 } else { 541 501 usb_log_debug2("Command has owner, don't forget to deallocate!"); 542 /* Copy the trb for later use so that we can free space on the cmd ring. */543 command->trb = malloc32(sizeof(xhci_trb_t));544 xhci_trb_copy(command->trb, command_trb);545 command->owns_trb = true;546 502 } 547 503 -
uspace/drv/bus/usb/xhci/commands.h
rab5a0830 r548c123 39 39 #include <adt/list.h> 40 40 #include <stdbool.h> 41 #include "hw_struct/trb.h" 41 42 42 43 typedef struct xhci_hc xhci_hc_t; 43 typedef struct xhci_trb xhci_trb_t;44 44 typedef struct xhci_input_ctx xhci_input_ctx_t; 45 45 … … 47 47 link_t link; 48 48 49 xhci_trb_t *trb; 49 xhci_trb_t trb; 50 uintptr_t trb_phys; 50 51 xhci_input_ctx_t *ictx; 51 52 uint32_t slot_id; -
uspace/drv/bus/usb/xhci/hw_struct/trb.h
rab5a0830 r548c123 138 138 dst->status = src->status; 139 139 dst->control = src->control; 140 } 141 142 static inline void xhci_trb_clean(xhci_trb_t *trb) 143 { 144 memset(trb, 0, sizeof(*trb)); 140 145 } 141 146 -
uspace/drv/bus/usb/xhci/trb_ring.c
rab5a0830 r548c123 164 164 * 165 165 * @param td the first TRB of TD 166 * @param phys returns address of the first TRB enqueued 166 167 * @return EOK on success, 167 168 * EAGAIN when the ring is too full to fit all TRBs (temporary) 168 169 */ 169 int xhci_trb_ring_enqueue(xhci_trb_ring_t *ring, xhci_trb_t *td )170 int xhci_trb_ring_enqueue(xhci_trb_ring_t *ring, xhci_trb_t *td, uintptr_t *phys) 170 171 { 171 172 xhci_trb_t * const saved_enqueue_trb = ring->enqueue_trb; 172 173 trb_segment_t * const saved_enqueue_segment = ring->enqueue_segment; 174 if (phys) 175 *phys = NULL; 173 176 174 177 /* … … 189 192 ring->enqueue_segment = saved_enqueue_segment; 190 193 ring->enqueue_trb = saved_enqueue_trb; 194 if (phys) 195 *phys = trb_ring_enqueue_phys(ring); 191 196 192 197 /* -
uspace/drv/bus/usb/xhci/trb_ring.h
rab5a0830 r548c123 72 72 int xhci_trb_ring_init(xhci_trb_ring_t *, xhci_hc_t *); 73 73 int xhci_trb_ring_fini(xhci_trb_ring_t *); 74 int xhci_trb_ring_enqueue(xhci_trb_ring_t *, xhci_trb_t * );74 int xhci_trb_ring_enqueue(xhci_trb_ring_t *, xhci_trb_t *, uintptr_t *); 75 75 76 76 /**
Note:
See TracChangeset
for help on using the changeset viewer.