aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--drivers/firewire/ohci.c35
1 files changed, 21 insertions, 14 deletions
diff --git a/drivers/firewire/ohci.c b/drivers/firewire/ohci.c
index 5826ae333b19..7570b71a2453 100644
--- a/drivers/firewire/ohci.c
+++ b/drivers/firewire/ohci.c
@@ -750,20 +750,19 @@ static void ar_context_tasklet(unsigned long data)
750 */ 750 */
751 751
752 offset = offsetof(struct ar_buffer, data); 752 offset = offsetof(struct ar_buffer, data);
753 start = buffer = ab; 753 start = ab;
754 start_bus = le32_to_cpu(ab->descriptor.data_address) - offset; 754 start_bus = le32_to_cpu(ab->descriptor.data_address) - offset;
755 buffer = ab->data;
755 756
756 ab = ab->next; 757 ab = ab->next;
757 d = &ab->descriptor; 758 d = &ab->descriptor;
758 size = buffer + PAGE_SIZE - ctx->pointer; 759 size = start + PAGE_SIZE - ctx->pointer;
759 /* valid buffer data in the next page */ 760 /* valid buffer data in the next page */
760 rest = le16_to_cpu(d->req_count) - le16_to_cpu(d->res_count); 761 rest = le16_to_cpu(d->req_count) - le16_to_cpu(d->res_count);
761 /* what actually fits in this page */ 762 /* what actually fits in this page */
762 size2 = min(rest, (size_t)PAGE_SIZE - size); 763 size2 = min(rest, (size_t)PAGE_SIZE - offset - size);
763 memmove(buffer, ctx->pointer, size); 764 memmove(buffer, ctx->pointer, size);
764 memcpy(buffer + size, ab->data, size2); 765 memcpy(buffer + size, ab->data, size2);
765 ctx->current_buffer = ab;
766 ctx->pointer = (void *) ab->data + rest;
767 766
768 while (size > 0) { 767 while (size > 0) {
769 void *next = handle_ar_packet(ctx, buffer); 768 void *next = handle_ar_packet(ctx, buffer);
@@ -782,22 +781,30 @@ static void ar_context_tasklet(unsigned long data)
782 size -= pktsize; 781 size -= pktsize;
783 /* fill up this page again */ 782 /* fill up this page again */
784 size3 = min(rest - size2, 783 size3 = min(rest - size2,
785 (size_t)PAGE_SIZE - size - size2); 784 (size_t)PAGE_SIZE - offset - size - size2);
786 memcpy(buffer + size + size2, 785 memcpy(buffer + size + size2,
787 (void *) ab->data + size2, size3); 786 (void *) ab->data + size2, size3);
788 size2 += size3; 787 size2 += size3;
789 } 788 }
790 789
791 /* handle the packets that are fully in the next page */ 790 if (rest > 0) {
792 buffer = (void *) ab->data + (buffer - (start + size)); 791 /* handle the packets that are fully in the next page */
793 end = (void *) ab->data + rest; 792 buffer = (void *) ab->data +
793 (buffer - (start + offset + size));
794 end = (void *) ab->data + rest;
794 795
795 while (buffer < end) 796 while (buffer < end)
796 buffer = handle_ar_packet(ctx, buffer); 797 buffer = handle_ar_packet(ctx, buffer);
798
799 ctx->current_buffer = ab;
800 ctx->pointer = end;
797 801
798 dma_free_coherent(ohci->card.device, PAGE_SIZE, 802 dma_free_coherent(ohci->card.device, PAGE_SIZE,
799 start, start_bus); 803 start, start_bus);
800 ar_context_add_page(ctx); 804 ar_context_add_page(ctx);
805 } else {
806 ctx->pointer = start + PAGE_SIZE;
807 }
801 } else { 808 } else {
802 buffer = ctx->pointer; 809 buffer = ctx->pointer;
803 ctx->pointer = end = 810 ctx->pointer = end =