diff options
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 da17d409a244..33f8421c71cc 100644 --- a/drivers/firewire/net.c +++ b/drivers/firewire/net.c | |||
| @@ -579,7 +579,7 @@ static int fwnet_finish_incoming_packet(struct net_device *net, | |||
| 579 | if (!peer) { | 579 | if (!peer) { |
| 580 | fw_notify("No peer for ARP packet from %016llx\n", | 580 | fw_notify("No peer for ARP packet from %016llx\n", |
| 581 | (unsigned long long)peer_guid); | 581 | (unsigned long long)peer_guid); |
| 582 | goto failed_proto; | 582 | goto no_peer; |
| 583 | } | 583 | } |
| 584 | 584 | ||
| 585 | /* | 585 | /* |
| @@ -656,7 +656,7 @@ static int fwnet_finish_incoming_packet(struct net_device *net, | |||
| 656 | 656 | ||
| 657 | return 0; | 657 | return 0; |
| 658 | 658 | ||
| 659 | failed_proto: | 659 | no_peer: |
| 660 | net->stats.rx_errors++; | 660 | net->stats.rx_errors++; |
| 661 | net->stats.rx_dropped++; | 661 | net->stats.rx_dropped++; |
| 662 | 662 | ||
| @@ -664,7 +664,7 @@ static int fwnet_finish_incoming_packet(struct net_device *net, | |||
| 664 | if (netif_queue_stopped(net)) | 664 | if (netif_queue_stopped(net)) |
| 665 | netif_wake_queue(net); | 665 | netif_wake_queue(net); |
| 666 | 666 | ||
| 667 | return 0; | 667 | return -ENOENT; |
| 668 | } | 668 | } |
| 669 | 669 | ||
| 670 | static int fwnet_incoming_packet(struct fwnet_device *dev, __be32 *buf, int len, | 670 | static int fwnet_incoming_packet(struct fwnet_device *dev, __be32 *buf, int len, |
| @@ -701,7 +701,7 @@ static int fwnet_incoming_packet(struct fwnet_device *dev, __be32 *buf, int len, | |||
| 701 | fw_error("out of memory\n"); | 701 | fw_error("out of memory\n"); |
| 702 | net->stats.rx_dropped++; | 702 | net->stats.rx_dropped++; |
| 703 | 703 | ||
| 704 | return -1; | 704 | return -ENOMEM; |
| 705 | } | 705 | } |
| 706 | skb_reserve(skb, (net->hard_header_len + 15) & ~15); | 706 | skb_reserve(skb, (net->hard_header_len + 15) & ~15); |
| 707 | memcpy(skb_put(skb, len), buf, len); | 707 | memcpy(skb_put(skb, len), buf, len); |
| @@ -726,8 +726,10 @@ static int fwnet_incoming_packet(struct fwnet_device *dev, __be32 *buf, int len, | |||
| 726 | spin_lock_irqsave(&dev->lock, flags); | 726 | spin_lock_irqsave(&dev->lock, flags); |
| 727 | 727 | ||
| 728 | peer = fwnet_peer_find_by_node_id(dev, source_node_id, generation); | 728 | peer = fwnet_peer_find_by_node_id(dev, source_node_id, generation); |
| 729 | if (!peer) | 729 | if (!peer) { |
| 730 | goto bad_proto; | 730 | retval = -ENOENT; |
| 731 | goto fail; | ||
| 732 | } | ||
| 731 | 733 | ||
| 732 | pd = fwnet_pd_find(peer, datagram_label); | 734 | pd = fwnet_pd_find(peer, datagram_label); |
| 733 | if (pd == NULL) { | 735 | if (pd == NULL) { |
| @@ -741,7 +743,7 @@ static int fwnet_incoming_packet(struct fwnet_device *dev, __be32 *buf, int len, | |||
| 741 | dg_size, buf, fg_off, len); | 743 | dg_size, buf, fg_off, len); |
| 742 | if (pd == NULL) { | 744 | if (pd == NULL) { |
| 743 | retval = -ENOMEM; | 745 | retval = -ENOMEM; |
| 744 | goto bad_proto; | 746 | goto fail; |
| 745 | } | 747 | } |
| 746 | peer->pdg_size++; | 748 | peer->pdg_size++; |
| 747 | } else { | 749 | } else { |
| @@ -755,9 +757,9 @@ static int fwnet_incoming_packet(struct fwnet_device *dev, __be32 *buf, int len, | |||
| 755 | pd = fwnet_pd_new(net, peer, datagram_label, | 757 | pd = fwnet_pd_new(net, peer, datagram_label, |
| 756 | dg_size, buf, fg_off, len); | 758 | dg_size, buf, fg_off, len); |
| 757 | if (pd == NULL) { | 759 | if (pd == NULL) { |
| 758 | retval = -ENOMEM; | ||
| 759 | peer->pdg_size--; | 760 | peer->pdg_size--; |
| 760 | goto bad_proto; | 761 | retval = -ENOMEM; |
| 762 | goto fail; | ||
| 761 | } | 763 | } |
| 762 | } else { | 764 | } else { |
| 763 | if (!fwnet_pd_update(peer, pd, buf, fg_off, len)) { | 765 | if (!fwnet_pd_update(peer, pd, buf, fg_off, len)) { |
| @@ -768,7 +770,8 @@ static int fwnet_incoming_packet(struct fwnet_device *dev, __be32 *buf, int len, | |||
| 768 | */ | 770 | */ |
| 769 | fwnet_pd_delete(pd); | 771 | fwnet_pd_delete(pd); |
| 770 | peer->pdg_size--; | 772 | peer->pdg_size--; |
| 771 | goto bad_proto; | 773 | retval = -ENOMEM; |
| 774 | goto fail; | ||
| 772 | } | 775 | } |
| 773 | } | 776 | } |
| 774 | } /* new datagram or add to existing one */ | 777 | } /* new datagram or add to existing one */ |
| @@ -794,14 +797,13 @@ static int fwnet_incoming_packet(struct fwnet_device *dev, __be32 *buf, int len, | |||
| 794 | spin_unlock_irqrestore(&dev->lock, flags); | 797 | spin_unlock_irqrestore(&dev->lock, flags); |
| 795 | 798 | ||
| 796 | return 0; | 799 | return 0; |
| 797 | 800 | fail: | |
| 798 | bad_proto: | ||
| 799 | spin_unlock_irqrestore(&dev->lock, flags); | 801 | spin_unlock_irqrestore(&dev->lock, flags); |
| 800 | 802 | ||
| 801 | if (netif_queue_stopped(net)) | 803 | if (netif_queue_stopped(net)) |
| 802 | netif_wake_queue(net); | 804 | netif_wake_queue(net); |
| 803 | 805 | ||
| 804 | return 0; | 806 | return retval; |
| 805 | } | 807 | } |
| 806 | 808 | ||
| 807 | static void fwnet_receive_packet(struct fw_card *card, struct fw_request *r, | 809 | 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; |
