diff options
author | David S. Miller <davem@davemloft.net> | 2010-09-10 01:27:33 -0400 |
---|---|---|
committer | David S. Miller <davem@davemloft.net> | 2010-09-10 01:27:33 -0400 |
commit | e548833df83c3554229eff0672900bfe958b45fd (patch) | |
tree | 85efc4a76dc356593d6d394776aeb845dc580fb6 /drivers/firewire | |
parent | cbd9da7be869f676afc204e1a664163778c770bd (diff) | |
parent | 053d8f6622701f849fda2ca2c9ae596c13599ba9 (diff) |
Merge branch 'master' of master.kernel.org:/pub/scm/linux/kernel/git/davem/net-2.6
Conflicts:
net/mac80211/main.c
Diffstat (limited to 'drivers/firewire')
-rw-r--r-- | drivers/firewire/core-transaction.c | 13 | ||||
-rw-r--r-- | drivers/firewire/net.c | 28 | ||||
-rw-r--r-- | drivers/firewire/ohci.c | 10 | ||||
-rw-r--r-- | drivers/firewire/sbp2.c | 23 |
4 files changed, 49 insertions, 25 deletions
diff --git a/drivers/firewire/core-transaction.c b/drivers/firewire/core-transaction.c index ca7ca56661e0..b42a0bde8494 100644 --- a/drivers/firewire/core-transaction.c +++ b/drivers/firewire/core-transaction.c | |||
@@ -81,6 +81,10 @@ static int close_transaction(struct fw_transaction *transaction, | |||
81 | spin_lock_irqsave(&card->lock, flags); | 81 | spin_lock_irqsave(&card->lock, flags); |
82 | list_for_each_entry(t, &card->transaction_list, link) { | 82 | list_for_each_entry(t, &card->transaction_list, link) { |
83 | if (t == transaction) { | 83 | if (t == transaction) { |
84 | if (!del_timer(&t->split_timeout_timer)) { | ||
85 | spin_unlock_irqrestore(&card->lock, flags); | ||
86 | goto timed_out; | ||
87 | } | ||
84 | list_del_init(&t->link); | 88 | list_del_init(&t->link); |
85 | card->tlabel_mask &= ~(1ULL << t->tlabel); | 89 | card->tlabel_mask &= ~(1ULL << t->tlabel); |
86 | break; | 90 | break; |
@@ -89,11 +93,11 @@ static int close_transaction(struct fw_transaction *transaction, | |||
89 | spin_unlock_irqrestore(&card->lock, flags); | 93 | spin_unlock_irqrestore(&card->lock, flags); |
90 | 94 | ||
91 | if (&t->link != &card->transaction_list) { | 95 | if (&t->link != &card->transaction_list) { |
92 | del_timer_sync(&t->split_timeout_timer); | ||
93 | t->callback(card, rcode, NULL, 0, t->callback_data); | 96 | t->callback(card, rcode, NULL, 0, t->callback_data); |
94 | return 0; | 97 | return 0; |
95 | } | 98 | } |
96 | 99 | ||
100 | timed_out: | ||
97 | return -ENOENT; | 101 | return -ENOENT; |
98 | } | 102 | } |
99 | 103 | ||
@@ -921,6 +925,10 @@ void fw_core_handle_response(struct fw_card *card, struct fw_packet *p) | |||
921 | spin_lock_irqsave(&card->lock, flags); | 925 | spin_lock_irqsave(&card->lock, flags); |
922 | list_for_each_entry(t, &card->transaction_list, link) { | 926 | list_for_each_entry(t, &card->transaction_list, link) { |
923 | if (t->node_id == source && t->tlabel == tlabel) { | 927 | if (t->node_id == source && t->tlabel == tlabel) { |
928 | if (!del_timer(&t->split_timeout_timer)) { | ||
929 | spin_unlock_irqrestore(&card->lock, flags); | ||
930 | goto timed_out; | ||
931 | } | ||
924 | list_del_init(&t->link); | 932 | list_del_init(&t->link); |
925 | card->tlabel_mask &= ~(1ULL << t->tlabel); | 933 | card->tlabel_mask &= ~(1ULL << t->tlabel); |
926 | break; | 934 | break; |
@@ -929,6 +937,7 @@ void fw_core_handle_response(struct fw_card *card, struct fw_packet *p) | |||
929 | spin_unlock_irqrestore(&card->lock, flags); | 937 | spin_unlock_irqrestore(&card->lock, flags); |
930 | 938 | ||
931 | if (&t->link == &card->transaction_list) { | 939 | if (&t->link == &card->transaction_list) { |
940 | timed_out: | ||
932 | fw_notify("Unsolicited response (source %x, tlabel %x)\n", | 941 | fw_notify("Unsolicited response (source %x, tlabel %x)\n", |
933 | source, tlabel); | 942 | source, tlabel); |
934 | return; | 943 | return; |
@@ -963,8 +972,6 @@ void fw_core_handle_response(struct fw_card *card, struct fw_packet *p) | |||
963 | break; | 972 | break; |
964 | } | 973 | } |
965 | 974 | ||
966 | del_timer_sync(&t->split_timeout_timer); | ||
967 | |||
968 | /* | 975 | /* |
969 | * The response handler may be executed while the request handler | 976 | * The response handler may be executed while the request handler |
970 | * is still pending. Cancel the request handler. | 977 | * is still pending. Cancel the request handler. |
diff --git a/drivers/firewire/net.c b/drivers/firewire/net.c index 51e8a35ebd7e..18fdd9703b48 100644 --- a/drivers/firewire/net.c +++ b/drivers/firewire/net.c | |||
@@ -578,7 +578,7 @@ static int fwnet_finish_incoming_packet(struct net_device *net, | |||
578 | if (!peer) { | 578 | if (!peer) { |
579 | fw_notify("No peer for ARP packet from %016llx\n", | 579 | fw_notify("No peer for ARP packet from %016llx\n", |
580 | (unsigned long long)peer_guid); | 580 | (unsigned long long)peer_guid); |
581 | goto failed_proto; | 581 | goto no_peer; |
582 | } | 582 | } |
583 | 583 | ||
584 | /* | 584 | /* |
@@ -655,7 +655,7 @@ static int fwnet_finish_incoming_packet(struct net_device *net, | |||
655 | 655 | ||
656 | return 0; | 656 | return 0; |
657 | 657 | ||
658 | failed_proto: | 658 | no_peer: |
659 | net->stats.rx_errors++; | 659 | net->stats.rx_errors++; |
660 | net->stats.rx_dropped++; | 660 | net->stats.rx_dropped++; |
661 | 661 | ||
@@ -663,7 +663,7 @@ static int fwnet_finish_incoming_packet(struct net_device *net, | |||
663 | if (netif_queue_stopped(net)) | 663 | if (netif_queue_stopped(net)) |
664 | netif_wake_queue(net); | 664 | netif_wake_queue(net); |
665 | 665 | ||
666 | return 0; | 666 | return -ENOENT; |
667 | } | 667 | } |
668 | 668 | ||
669 | static int fwnet_incoming_packet(struct fwnet_device *dev, __be32 *buf, int len, | 669 | static int fwnet_incoming_packet(struct fwnet_device *dev, __be32 *buf, int len, |
@@ -700,7 +700,7 @@ static int fwnet_incoming_packet(struct fwnet_device *dev, __be32 *buf, int len, | |||
700 | fw_error("out of memory\n"); | 700 | fw_error("out of memory\n"); |
701 | net->stats.rx_dropped++; | 701 | net->stats.rx_dropped++; |
702 | 702 | ||
703 | return -1; | 703 | return -ENOMEM; |
704 | } | 704 | } |
705 | skb_reserve(skb, (net->hard_header_len + 15) & ~15); | 705 | skb_reserve(skb, (net->hard_header_len + 15) & ~15); |
706 | memcpy(skb_put(skb, len), buf, len); | 706 | memcpy(skb_put(skb, len), buf, len); |
@@ -725,8 +725,10 @@ static int fwnet_incoming_packet(struct fwnet_device *dev, __be32 *buf, int len, | |||
725 | spin_lock_irqsave(&dev->lock, flags); | 725 | spin_lock_irqsave(&dev->lock, flags); |
726 | 726 | ||
727 | peer = fwnet_peer_find_by_node_id(dev, source_node_id, generation); | 727 | peer = fwnet_peer_find_by_node_id(dev, source_node_id, generation); |
728 | if (!peer) | 728 | if (!peer) { |
729 | goto bad_proto; | 729 | retval = -ENOENT; |
730 | goto fail; | ||
731 | } | ||
730 | 732 | ||
731 | pd = fwnet_pd_find(peer, datagram_label); | 733 | pd = fwnet_pd_find(peer, datagram_label); |
732 | if (pd == NULL) { | 734 | if (pd == NULL) { |
@@ -740,7 +742,7 @@ static int fwnet_incoming_packet(struct fwnet_device *dev, __be32 *buf, int len, | |||
740 | dg_size, buf, fg_off, len); | 742 | dg_size, buf, fg_off, len); |
741 | if (pd == NULL) { | 743 | if (pd == NULL) { |
742 | retval = -ENOMEM; | 744 | retval = -ENOMEM; |
743 | goto bad_proto; | 745 | goto fail; |
744 | } | 746 | } |
745 | peer->pdg_size++; | 747 | peer->pdg_size++; |
746 | } else { | 748 | } else { |
@@ -754,9 +756,9 @@ static int fwnet_incoming_packet(struct fwnet_device *dev, __be32 *buf, int len, | |||
754 | pd = fwnet_pd_new(net, peer, datagram_label, | 756 | pd = fwnet_pd_new(net, peer, datagram_label, |
755 | dg_size, buf, fg_off, len); | 757 | dg_size, buf, fg_off, len); |
756 | if (pd == NULL) { | 758 | if (pd == NULL) { |
757 | retval = -ENOMEM; | ||
758 | peer->pdg_size--; | 759 | peer->pdg_size--; |
759 | goto bad_proto; | 760 | retval = -ENOMEM; |
761 | goto fail; | ||
760 | } | 762 | } |
761 | } else { | 763 | } else { |
762 | if (!fwnet_pd_update(peer, pd, buf, fg_off, len)) { | 764 | if (!fwnet_pd_update(peer, pd, buf, fg_off, len)) { |
@@ -767,7 +769,8 @@ static int fwnet_incoming_packet(struct fwnet_device *dev, __be32 *buf, int len, | |||
767 | */ | 769 | */ |
768 | fwnet_pd_delete(pd); | 770 | fwnet_pd_delete(pd); |
769 | peer->pdg_size--; | 771 | peer->pdg_size--; |
770 | goto bad_proto; | 772 | retval = -ENOMEM; |
773 | goto fail; | ||
771 | } | 774 | } |
772 | } | 775 | } |
773 | } /* new datagram or add to existing one */ | 776 | } /* new datagram or add to existing one */ |
@@ -793,14 +796,13 @@ static int fwnet_incoming_packet(struct fwnet_device *dev, __be32 *buf, int len, | |||
793 | spin_unlock_irqrestore(&dev->lock, flags); | 796 | spin_unlock_irqrestore(&dev->lock, flags); |
794 | 797 | ||
795 | return 0; | 798 | return 0; |
796 | 799 | fail: | |
797 | bad_proto: | ||
798 | spin_unlock_irqrestore(&dev->lock, flags); | 800 | spin_unlock_irqrestore(&dev->lock, flags); |
799 | 801 | ||
800 | if (netif_queue_stopped(net)) | 802 | if (netif_queue_stopped(net)) |
801 | netif_wake_queue(net); | 803 | netif_wake_queue(net); |
802 | 804 | ||
803 | return 0; | 805 | return retval; |
804 | } | 806 | } |
805 | 807 | ||
806 | static void fwnet_receive_packet(struct fw_card *card, struct fw_request *r, | 808 | static void fwnet_receive_packet(struct fw_card *card, struct fw_request *r, |
diff --git a/drivers/firewire/ohci.c b/drivers/firewire/ohci.c index 7f03540cabe8..be29b0bb2471 100644 --- a/drivers/firewire/ohci.c +++ b/drivers/firewire/ohci.c | |||
@@ -694,7 +694,15 @@ static __le32 *handle_ar_packet(struct ar_context *ctx, __le32 *buffer) | |||
694 | log_ar_at_event('R', p.speed, p.header, evt); | 694 | log_ar_at_event('R', p.speed, p.header, evt); |
695 | 695 | ||
696 | /* | 696 | /* |
697 | * The OHCI bus reset handler synthesizes a phy packet with | 697 | * Several controllers, notably from NEC and VIA, forget to |
698 | * write ack_complete status at PHY packet reception. | ||
699 | */ | ||
700 | if (evt == OHCI1394_evt_no_status && | ||
701 | (p.header[0] & 0xff) == (OHCI1394_phy_tcode << 4)) | ||
702 | p.ack = ACK_COMPLETE; | ||
703 | |||
704 | /* | ||
705 | * The OHCI bus reset handler synthesizes a PHY packet with | ||
698 | * the new generation number when a bus reset happens (see | 706 | * the new generation number when a bus reset happens (see |
699 | * section 8.4.2.3). This helps us determine when a request | 707 | * section 8.4.2.3). This helps us determine when a request |
700 | * was received and make sure we send the response in the same | 708 | * was received and make sure we send the response in the same |
diff --git a/drivers/firewire/sbp2.c b/drivers/firewire/sbp2.c index 9f76171717e5..bfae4b309791 100644 --- a/drivers/firewire/sbp2.c +++ b/drivers/firewire/sbp2.c | |||
@@ -450,7 +450,7 @@ static void sbp2_status_write(struct fw_card *card, struct fw_request *request, | |||
450 | 450 | ||
451 | if (&orb->link != &lu->orb_list) { | 451 | if (&orb->link != &lu->orb_list) { |
452 | orb->callback(orb, &status); | 452 | orb->callback(orb, &status); |
453 | kref_put(&orb->kref, free_orb); | 453 | kref_put(&orb->kref, free_orb); /* orb callback reference */ |
454 | } else { | 454 | } else { |
455 | fw_error("status write for unknown orb\n"); | 455 | fw_error("status write for unknown orb\n"); |
456 | } | 456 | } |
@@ -472,20 +472,28 @@ static void complete_transaction(struct fw_card *card, int rcode, | |||
472 | * So this callback only sets the rcode if it hasn't already | 472 | * So this callback only sets the rcode if it hasn't already |
473 | * been set and only does the cleanup if the transaction | 473 | * been set and only does the cleanup if the transaction |
474 | * failed and we didn't already get a status write. | 474 | * failed and we didn't already get a status write. |
475 | * | ||
476 | * Here we treat RCODE_CANCELLED like RCODE_COMPLETE because some | ||
477 | * OXUF936QSE firmwares occasionally respond after Split_Timeout and | ||
478 | * complete the ORB just fine. Note, we also get RCODE_CANCELLED | ||
479 | * from sbp2_cancel_orbs() if fw_cancel_transaction() == 0. | ||
475 | */ | 480 | */ |
476 | spin_lock_irqsave(&card->lock, flags); | 481 | spin_lock_irqsave(&card->lock, flags); |
477 | 482 | ||
478 | if (orb->rcode == -1) | 483 | if (orb->rcode == -1) |
479 | orb->rcode = rcode; | 484 | orb->rcode = rcode; |
480 | if (orb->rcode != RCODE_COMPLETE) { | 485 | |
486 | if (orb->rcode != RCODE_COMPLETE && orb->rcode != RCODE_CANCELLED) { | ||
481 | list_del(&orb->link); | 487 | list_del(&orb->link); |
482 | spin_unlock_irqrestore(&card->lock, flags); | 488 | spin_unlock_irqrestore(&card->lock, flags); |
489 | |||
483 | orb->callback(orb, NULL); | 490 | orb->callback(orb, NULL); |
491 | kref_put(&orb->kref, free_orb); /* orb callback reference */ | ||
484 | } else { | 492 | } else { |
485 | spin_unlock_irqrestore(&card->lock, flags); | 493 | spin_unlock_irqrestore(&card->lock, flags); |
486 | } | 494 | } |
487 | 495 | ||
488 | kref_put(&orb->kref, free_orb); | 496 | kref_put(&orb->kref, free_orb); /* transaction callback reference */ |
489 | } | 497 | } |
490 | 498 | ||
491 | static void sbp2_send_orb(struct sbp2_orb *orb, struct sbp2_logical_unit *lu, | 499 | static void sbp2_send_orb(struct sbp2_orb *orb, struct sbp2_logical_unit *lu, |
@@ -501,9 +509,8 @@ static void sbp2_send_orb(struct sbp2_orb *orb, struct sbp2_logical_unit *lu, | |||
501 | list_add_tail(&orb->link, &lu->orb_list); | 509 | list_add_tail(&orb->link, &lu->orb_list); |
502 | spin_unlock_irqrestore(&device->card->lock, flags); | 510 | spin_unlock_irqrestore(&device->card->lock, flags); |
503 | 511 | ||
504 | /* Take a ref for the orb list and for the transaction callback. */ | 512 | kref_get(&orb->kref); /* transaction callback reference */ |
505 | kref_get(&orb->kref); | 513 | kref_get(&orb->kref); /* orb callback reference */ |
506 | kref_get(&orb->kref); | ||
507 | 514 | ||
508 | fw_send_request(device->card, &orb->t, TCODE_WRITE_BLOCK_REQUEST, | 515 | fw_send_request(device->card, &orb->t, TCODE_WRITE_BLOCK_REQUEST, |
509 | node_id, generation, device->max_speed, offset, | 516 | node_id, generation, device->max_speed, offset, |
@@ -525,11 +532,11 @@ static int sbp2_cancel_orbs(struct sbp2_logical_unit *lu) | |||
525 | 532 | ||
526 | list_for_each_entry_safe(orb, next, &list, link) { | 533 | list_for_each_entry_safe(orb, next, &list, link) { |
527 | retval = 0; | 534 | retval = 0; |
528 | if (fw_cancel_transaction(device->card, &orb->t) == 0) | 535 | fw_cancel_transaction(device->card, &orb->t); |
529 | continue; | ||
530 | 536 | ||
531 | orb->rcode = RCODE_CANCELLED; | 537 | orb->rcode = RCODE_CANCELLED; |
532 | orb->callback(orb, NULL); | 538 | orb->callback(orb, NULL); |
539 | kref_put(&orb->kref, free_orb); /* orb callback reference */ | ||
533 | } | 540 | } |
534 | 541 | ||
535 | return retval; | 542 | return retval; |