diff options
| author | David Brownell <david-b@pacbell.net> | 2008-04-10 17:21:06 -0400 |
|---|---|---|
| committer | Greg Kroah-Hartman <gregkh@suse.de> | 2008-04-25 00:16:50 -0400 |
| commit | a082b5c7882bdbd8a86ace8470ca2ecda796d5a7 (patch) | |
| tree | dd5f519ad7caa417363d256f7e572c02a43927f5 | |
| parent | 6427f7995338387ddded92f98adec19ddbf0ae5e (diff) | |
USB: ehci: qh/qtd cleanup comments
Provide better comments about qh_completions() and QTD handling.
That code can be *VERY* confusing, since it's evolved over a few
years to cope with both hardware races and silicon quirks.
Remove two unlikely() annotations that match the GCC defaults
(and are thus pointless); add an "else" to highlight code flow.
This patch doesn't change driver behavior.
Signed-off-by: David Brownell <dbrownell@users.sourceforge.net>
Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de>
| -rw-r--r-- | drivers/usb/host/ehci-q.c | 50 |
1 files changed, 40 insertions, 10 deletions
diff --git a/drivers/usb/host/ehci-q.c b/drivers/usb/host/ehci-q.c index c0e752cffc68..64942ec584c2 100644 --- a/drivers/usb/host/ehci-q.c +++ b/drivers/usb/host/ehci-q.c | |||
| @@ -336,11 +336,20 @@ qh_completions (struct ehci_hcd *ehci, struct ehci_qh *qh) | |||
| 336 | /* always clean up qtds the hc de-activated */ | 336 | /* always clean up qtds the hc de-activated */ |
| 337 | if ((token & QTD_STS_ACTIVE) == 0) { | 337 | if ((token & QTD_STS_ACTIVE) == 0) { |
| 338 | 338 | ||
| 339 | /* on STALL, error, and short reads this urb must | ||
| 340 | * complete and all its qtds must be recycled. | ||
| 341 | */ | ||
| 339 | if ((token & QTD_STS_HALT) != 0) { | 342 | if ((token & QTD_STS_HALT) != 0) { |
| 340 | stopped = 1; | 343 | stopped = 1; |
| 341 | 344 | ||
| 342 | /* magic dummy for some short reads; qh won't advance. | 345 | /* magic dummy for some short reads; qh won't advance. |
| 343 | * that silicon quirk can kick in with this dummy too. | 346 | * that silicon quirk can kick in with this dummy too. |
| 347 | * | ||
| 348 | * other short reads won't stop the queue, including | ||
| 349 | * control transfers (status stage handles that) or | ||
| 350 | * most other single-qtd reads ... the queue stops if | ||
| 351 | * URB_SHORT_NOT_OK was set so the driver submitting | ||
| 352 | * the urbs could clean it up. | ||
| 344 | */ | 353 | */ |
| 345 | } else if (IS_SHORT_READ (token) | 354 | } else if (IS_SHORT_READ (token) |
| 346 | && !(qtd->hw_alt_next | 355 | && !(qtd->hw_alt_next |
| @@ -354,18 +363,18 @@ qh_completions (struct ehci_hcd *ehci, struct ehci_qh *qh) | |||
| 354 | && HC_IS_RUNNING (ehci_to_hcd(ehci)->state))) { | 363 | && HC_IS_RUNNING (ehci_to_hcd(ehci)->state))) { |
| 355 | break; | 364 | break; |
| 356 | 365 | ||
| 366 | /* scan the whole queue for unlinks whenever it stops */ | ||
| 357 | } else { | 367 | } else { |
| 358 | stopped = 1; | 368 | stopped = 1; |
| 359 | 369 | ||
| 360 | if (unlikely (!HC_IS_RUNNING (ehci_to_hcd(ehci)->state))) | 370 | /* cancel everything if we halt, suspend, etc */ |
| 371 | if (!HC_IS_RUNNING(ehci_to_hcd(ehci)->state)) | ||
| 361 | last_status = -ESHUTDOWN; | 372 | last_status = -ESHUTDOWN; |
| 362 | 373 | ||
| 363 | /* ignore active urbs unless some previous qtd | 374 | /* this qtd is active; skip it unless a previous qtd |
| 364 | * for the urb faulted (including short read) or | 375 | * for its urb faulted, or its urb was canceled. |
| 365 | * its urb was canceled. we may patch qh or qtds. | ||
| 366 | */ | 376 | */ |
| 367 | if (likely(last_status == -EINPROGRESS && | 377 | else if (last_status == -EINPROGRESS && !urb->unlinked) |
| 368 | !urb->unlinked)) | ||
| 369 | continue; | 378 | continue; |
| 370 | 379 | ||
| 371 | /* issue status after short control reads */ | 380 | /* issue status after short control reads */ |
| @@ -375,7 +384,7 @@ qh_completions (struct ehci_hcd *ehci, struct ehci_qh *qh) | |||
| 375 | continue; | 384 | continue; |
| 376 | } | 385 | } |
| 377 | 386 | ||
| 378 | /* token in overlay may be most current */ | 387 | /* qh unlinked; token in overlay may be most current */ |
| 379 | if (state == QH_STATE_IDLE | 388 | if (state == QH_STATE_IDLE |
| 380 | && cpu_to_hc32(ehci, qtd->qtd_dma) | 389 | && cpu_to_hc32(ehci, qtd->qtd_dma) |
| 381 | == qh->hw_current) | 390 | == qh->hw_current) |
| @@ -402,11 +411,16 @@ halt: | |||
| 402 | if (likely(last_status == -EINPROGRESS)) | 411 | if (likely(last_status == -EINPROGRESS)) |
| 403 | last_status = qtd_status; | 412 | last_status = qtd_status; |
| 404 | 413 | ||
| 414 | /* if we're removing something not at the queue head, | ||
| 415 | * patch the hardware queue pointer. | ||
| 416 | */ | ||
| 405 | if (stopped && qtd->qtd_list.prev != &qh->qtd_list) { | 417 | if (stopped && qtd->qtd_list.prev != &qh->qtd_list) { |
| 406 | last = list_entry (qtd->qtd_list.prev, | 418 | last = list_entry (qtd->qtd_list.prev, |
| 407 | struct ehci_qtd, qtd_list); | 419 | struct ehci_qtd, qtd_list); |
| 408 | last->hw_next = qtd->hw_next; | 420 | last->hw_next = qtd->hw_next; |
| 409 | } | 421 | } |
| 422 | |||
| 423 | /* remove qtd; it's recycled after possible urb completion */ | ||
| 410 | list_del (&qtd->qtd_list); | 424 | list_del (&qtd->qtd_list); |
| 411 | last = qtd; | 425 | last = qtd; |
| 412 | } | 426 | } |
| @@ -431,7 +445,15 @@ halt: | |||
| 431 | qh_refresh(ehci, qh); | 445 | qh_refresh(ehci, qh); |
| 432 | break; | 446 | break; |
| 433 | case QH_STATE_LINKED: | 447 | case QH_STATE_LINKED: |
| 434 | /* should be rare for periodic transfers, | 448 | /* We won't refresh a QH that's linked (after the HC |
| 449 | * stopped the queue). That avoids a race: | ||
| 450 | * - HC reads first part of QH; | ||
| 451 | * - CPU updates that first part and the token; | ||
| 452 | * - HC reads rest of that QH, including token | ||
| 453 | * Result: HC gets an inconsistent image, and then | ||
| 454 | * DMAs to/from the wrong memory (corrupting it). | ||
| 455 | * | ||
| 456 | * That should be rare for interrupt transfers, | ||
| 435 | * except maybe high bandwidth ... | 457 | * except maybe high bandwidth ... |
| 436 | */ | 458 | */ |
| 437 | if ((cpu_to_hc32(ehci, QH_SMASK) | 459 | if ((cpu_to_hc32(ehci, QH_SMASK) |
| @@ -549,6 +571,12 @@ qh_urb_transaction ( | |||
| 549 | this_qtd_len = qtd_fill(ehci, qtd, buf, len, token, maxpacket); | 571 | this_qtd_len = qtd_fill(ehci, qtd, buf, len, token, maxpacket); |
| 550 | len -= this_qtd_len; | 572 | len -= this_qtd_len; |
| 551 | buf += this_qtd_len; | 573 | buf += this_qtd_len; |
| 574 | |||
| 575 | /* | ||
| 576 | * short reads advance to a "magic" dummy instead of the next | ||
| 577 | * qtd ... that forces the queue to stop, for manual cleanup. | ||
| 578 | * (this will usually be overridden later.) | ||
| 579 | */ | ||
| 552 | if (is_input) | 580 | if (is_input) |
| 553 | qtd->hw_alt_next = ehci->async->hw_alt_next; | 581 | qtd->hw_alt_next = ehci->async->hw_alt_next; |
| 554 | 582 | ||
| @@ -568,8 +596,10 @@ qh_urb_transaction ( | |||
| 568 | list_add_tail (&qtd->qtd_list, head); | 596 | list_add_tail (&qtd->qtd_list, head); |
| 569 | } | 597 | } |
| 570 | 598 | ||
| 571 | /* unless the bulk/interrupt caller wants a chance to clean | 599 | /* |
| 572 | * up after short reads, hc should advance qh past this urb | 600 | * unless the caller requires manual cleanup after short reads, |
| 601 | * have the alt_next mechanism keep the queue running after the | ||
| 602 | * last data qtd (the only one, for control and most other cases). | ||
| 573 | */ | 603 | */ |
| 574 | if (likely ((urb->transfer_flags & URB_SHORT_NOT_OK) == 0 | 604 | if (likely ((urb->transfer_flags & URB_SHORT_NOT_OK) == 0 |
| 575 | || usb_pipecontrol (urb->pipe))) | 605 | || usb_pipecontrol (urb->pipe))) |
