diff options
| author | Stefan Richter <stefanr@s5r6.in-berlin.de> | 2010-07-22 05:58:05 -0400 |
|---|---|---|
| committer | Stefan Richter <stefanr@s5r6.in-berlin.de> | 2010-07-27 05:04:12 -0400 |
| commit | 269fe1023191a338736c71ba4f4db13839747772 (patch) | |
| tree | eb49afb2d44ec2e1422a105ce6f1e77f6c7256a2 | |
| parent | 468066f771032ad4bef4a906dfe0b0a55593d64d (diff) | |
tools/firewire: nosy-dump: break up a deeply nested function
Signed-off-by: Stefan Richter <stefanr@s5r6.in-berlin.de>
| -rw-r--r-- | tools/firewire/nosy-dump.c | 245 |
1 files changed, 132 insertions, 113 deletions
diff --git a/tools/firewire/nosy-dump.c b/tools/firewire/nosy-dump.c index 5d1e89233738..32c48556170b 100644 --- a/tools/firewire/nosy-dump.c +++ b/tools/firewire/nosy-dump.c | |||
| @@ -487,138 +487,157 @@ static const struct packet_info packet_info[] = { | |||
| 487 | }; | 487 | }; |
| 488 | 488 | ||
| 489 | static int | 489 | static int |
| 490 | handle_packet(uint32_t *data, size_t length) | 490 | handle_request_packet(uint32_t *data, size_t length) |
| 491 | { | 491 | { |
| 492 | if (length == 0) { | 492 | struct link_packet *p = (struct link_packet *) data; |
| 493 | printf("bus reset\r\n"); | 493 | struct subaction *sa, *prev; |
| 494 | clear_pending_transaction_list(); | 494 | struct link_transaction *t; |
| 495 | } else if (length > sizeof(struct phy_packet)) { | ||
| 496 | struct link_packet *p = (struct link_packet *) data; | ||
| 497 | struct subaction *sa, *prev; | ||
| 498 | struct link_transaction *t; | ||
| 499 | 495 | ||
| 500 | switch (packet_info[p->common.tcode].type) { | 496 | t = link_transaction_lookup(p->common.source, p->common.destination, |
| 501 | case PACKET_REQUEST: | 497 | p->common.tlabel); |
| 502 | t = link_transaction_lookup(p->common.source, p->common.destination, | 498 | sa = subaction_create(data, length); |
| 503 | p->common.tlabel); | 499 | t->request = sa; |
| 504 | sa = subaction_create(data, length); | 500 | |
| 505 | t->request = sa; | 501 | if (!list_empty(&t->request_list)) { |
| 506 | 502 | prev = list_tail(&t->request_list, | |
| 507 | if (!list_empty(&t->request_list)) { | 503 | struct subaction, link); |
| 508 | prev = list_tail(&t->request_list, | 504 | |
| 509 | struct subaction, link); | 505 | if (!ACK_BUSY(prev->ack)) { |
| 510 | 506 | /* | |
| 511 | if (!ACK_BUSY(prev->ack)) { | 507 | * error, we should only see ack_busy_* before the |
| 512 | /* | 508 | * ack_pending/ack_complete -- this is an ack_pending |
| 513 | * error, we should only see ack_busy_* before the | 509 | * instead (ack_complete would have finished the |
| 514 | * ack_pending/ack_complete -- this is an ack_pending | 510 | * transaction). |
| 515 | * instead (ack_complete would have finished the | 511 | */ |
| 516 | * transaction). | 512 | } |
| 517 | */ | ||
| 518 | } | ||
| 519 | 513 | ||
| 520 | if (prev->packet.common.tcode != sa->packet.common.tcode || | 514 | if (prev->packet.common.tcode != sa->packet.common.tcode || |
| 521 | prev->packet.common.tlabel != sa->packet.common.tlabel) { | 515 | prev->packet.common.tlabel != sa->packet.common.tlabel) { |
| 522 | /* memcmp() ? */ | 516 | /* memcmp() ? */ |
| 523 | /* error, these should match for retries. */ | 517 | /* error, these should match for retries. */ |
| 524 | } | 518 | } |
| 525 | } | 519 | } |
| 526 | 520 | ||
| 527 | list_append(&t->request_list, &sa->link); | 521 | list_append(&t->request_list, &sa->link); |
| 528 | 522 | ||
| 529 | switch (sa->ack) { | 523 | switch (sa->ack) { |
| 530 | case ACK_COMPLETE: | 524 | case ACK_COMPLETE: |
| 531 | if (p->common.tcode != TCODE_WRITE_QUADLET && | 525 | if (p->common.tcode != TCODE_WRITE_QUADLET && |
| 532 | p->common.tcode != TCODE_WRITE_BLOCK) | 526 | p->common.tcode != TCODE_WRITE_BLOCK) |
| 533 | /* error, unified transactions only allowed for write */; | 527 | /* error, unified transactions only allowed for write */; |
| 534 | list_remove(&t->link); | 528 | list_remove(&t->link); |
| 535 | handle_transaction(t); | 529 | handle_transaction(t); |
| 536 | break; | 530 | break; |
| 537 | 531 | ||
| 538 | case ACK_NO_ACK: | 532 | case ACK_NO_ACK: |
| 539 | case ACK_DATA_ERROR: | 533 | case ACK_DATA_ERROR: |
| 540 | case ACK_TYPE_ERROR: | 534 | case ACK_TYPE_ERROR: |
| 541 | list_remove(&t->link); | 535 | list_remove(&t->link); |
| 542 | handle_transaction(t); | 536 | handle_transaction(t); |
| 543 | break; | 537 | break; |
| 538 | |||
| 539 | case ACK_PENDING: | ||
| 540 | /* request subaction phase over, wait for response. */ | ||
| 541 | break; | ||
| 542 | |||
| 543 | case ACK_BUSY_X: | ||
| 544 | case ACK_BUSY_A: | ||
| 545 | case ACK_BUSY_B: | ||
| 546 | /* ok, wait for retry. */ | ||
| 547 | /* check that retry protocol is respected. */ | ||
| 548 | break; | ||
| 549 | } | ||
| 544 | 550 | ||
| 545 | case ACK_PENDING: | 551 | return 1; |
| 546 | /* request subaction phase over, wait for response. */ | 552 | } |
| 547 | break; | ||
| 548 | 553 | ||
| 549 | case ACK_BUSY_X: | 554 | static int |
| 550 | case ACK_BUSY_A: | 555 | handle_response_packet(uint32_t *data, size_t length) |
| 551 | case ACK_BUSY_B: | 556 | { |
| 552 | /* ok, wait for retry. */ | 557 | struct link_packet *p = (struct link_packet *) data; |
| 553 | /* check that retry protocol is respected. */ | 558 | struct subaction *sa, *prev; |
| 554 | break; | 559 | struct link_transaction *t; |
| 555 | } | ||
| 556 | break; | ||
| 557 | 560 | ||
| 558 | case PACKET_RESPONSE: | 561 | t = link_transaction_lookup(p->common.destination, p->common.source, |
| 559 | t = link_transaction_lookup(p->common.destination, p->common.source, | 562 | p->common.tlabel); |
| 560 | p->common.tlabel); | 563 | if (list_empty(&t->request_list)) { |
| 561 | if (list_empty(&t->request_list)) { | 564 | /* unsolicited response */ |
| 562 | /* unsolicited response */ | 565 | } |
| 563 | } | ||
| 564 | 566 | ||
| 565 | sa = subaction_create(data, length); | 567 | sa = subaction_create(data, length); |
| 566 | t->response = sa; | 568 | t->response = sa; |
| 567 | 569 | ||
| 568 | if (!list_empty(&t->response_list)) { | 570 | if (!list_empty(&t->response_list)) { |
| 569 | prev = list_tail(&t->response_list, struct subaction, link); | 571 | prev = list_tail(&t->response_list, struct subaction, link); |
| 570 | 572 | ||
| 571 | if (!ACK_BUSY(prev->ack)) { | 573 | if (!ACK_BUSY(prev->ack)) { |
| 572 | /* | 574 | /* |
| 573 | * error, we should only see ack_busy_* before the | 575 | * error, we should only see ack_busy_* before the |
| 574 | * ack_pending/ack_complete | 576 | * ack_pending/ack_complete |
| 575 | */ | 577 | */ |
| 576 | } | 578 | } |
| 577 | 579 | ||
| 578 | if (prev->packet.common.tcode != sa->packet.common.tcode || | 580 | if (prev->packet.common.tcode != sa->packet.common.tcode || |
| 579 | prev->packet.common.tlabel != sa->packet.common.tlabel) { | 581 | prev->packet.common.tlabel != sa->packet.common.tlabel) { |
| 580 | /* use memcmp() instead? */ | 582 | /* use memcmp() instead? */ |
| 581 | /* error, these should match for retries. */ | 583 | /* error, these should match for retries. */ |
| 582 | } | 584 | } |
| 583 | } else { | 585 | } else { |
| 584 | prev = list_tail(&t->request_list, struct subaction, link); | 586 | prev = list_tail(&t->request_list, struct subaction, link); |
| 585 | if (prev->ack != ACK_PENDING) { | 587 | if (prev->ack != ACK_PENDING) { |
| 586 | /* | 588 | /* |
| 587 | * error, should not get response unless last request got | 589 | * error, should not get response unless last request got |
| 588 | * ack_pending. | 590 | * ack_pending. |
| 589 | */ | 591 | */ |
| 590 | } | 592 | } |
| 591 | 593 | ||
| 592 | if (packet_info[prev->packet.common.tcode].response_tcode != | 594 | if (packet_info[prev->packet.common.tcode].response_tcode != |
| 593 | sa->packet.common.tcode) { | 595 | sa->packet.common.tcode) { |
| 594 | /* error, tcode mismatch */ | 596 | /* error, tcode mismatch */ |
| 595 | } | 597 | } |
| 596 | } | 598 | } |
| 597 | 599 | ||
| 598 | list_append(&t->response_list, &sa->link); | 600 | list_append(&t->response_list, &sa->link); |
| 599 | 601 | ||
| 600 | switch (sa->ack) { | 602 | switch (sa->ack) { |
| 601 | case ACK_COMPLETE: | 603 | case ACK_COMPLETE: |
| 602 | case ACK_NO_ACK: | 604 | case ACK_NO_ACK: |
| 603 | case ACK_DATA_ERROR: | 605 | case ACK_DATA_ERROR: |
| 604 | case ACK_TYPE_ERROR: | 606 | case ACK_TYPE_ERROR: |
| 605 | list_remove(&t->link); | 607 | list_remove(&t->link); |
| 606 | handle_transaction(t); | 608 | handle_transaction(t); |
| 607 | /* transaction complete, remove t from pending list. */ | 609 | /* transaction complete, remove t from pending list. */ |
| 608 | break; | 610 | break; |
| 611 | |||
| 612 | case ACK_PENDING: | ||
| 613 | /* error for responses. */ | ||
| 614 | break; | ||
| 615 | |||
| 616 | case ACK_BUSY_X: | ||
| 617 | case ACK_BUSY_A: | ||
| 618 | case ACK_BUSY_B: | ||
| 619 | /* no problem, wait for next retry */ | ||
| 620 | break; | ||
| 621 | } | ||
| 609 | 622 | ||
| 610 | case ACK_PENDING: | 623 | return 1; |
| 611 | /* error for responses. */ | 624 | } |
| 612 | break; | ||
| 613 | 625 | ||
| 614 | case ACK_BUSY_X: | 626 | static int |
| 615 | case ACK_BUSY_A: | 627 | handle_packet(uint32_t *data, size_t length) |
| 616 | case ACK_BUSY_B: | 628 | { |
| 617 | /* no problem, wait for next retry */ | 629 | if (length == 0) { |
| 618 | break; | 630 | printf("bus reset\r\n"); |
| 619 | } | 631 | clear_pending_transaction_list(); |
| 632 | } else if (length > sizeof(struct phy_packet)) { | ||
| 633 | struct link_packet *p = (struct link_packet *) data; | ||
| 620 | 634 | ||
| 621 | break; | 635 | switch (packet_info[p->common.tcode].type) { |
| 636 | case PACKET_REQUEST: | ||
| 637 | return handle_request_packet(data, length); | ||
| 638 | |||
| 639 | case PACKET_RESPONSE: | ||
| 640 | return handle_response_packet(data, length); | ||
| 622 | 641 | ||
| 623 | case PACKET_OTHER: | 642 | case PACKET_OTHER: |
| 624 | case PACKET_RESERVED: | 643 | case PACKET_RESERVED: |
