aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/firewire/ohci.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/firewire/ohci.c')
-rw-r--r--drivers/firewire/ohci.c135
1 files changed, 98 insertions, 37 deletions
diff --git a/drivers/firewire/ohci.c b/drivers/firewire/ohci.c
index 9dcb17d51aee..e3c8b60bd86b 100644
--- a/drivers/firewire/ohci.c
+++ b/drivers/firewire/ohci.c
@@ -242,6 +242,7 @@ static inline struct fw_ohci *fw_ohci(struct fw_card *card)
242 242
243static char ohci_driver_name[] = KBUILD_MODNAME; 243static char ohci_driver_name[] = KBUILD_MODNAME;
244 244
245#define PCI_DEVICE_ID_AGERE_FW643 0x5901
245#define PCI_DEVICE_ID_JMICRON_JMB38X_FW 0x2380 246#define PCI_DEVICE_ID_JMICRON_JMB38X_FW 0x2380
246#define PCI_DEVICE_ID_TI_TSB12LV22 0x8009 247#define PCI_DEVICE_ID_TI_TSB12LV22 0x8009
247 248
@@ -253,18 +254,34 @@ static char ohci_driver_name[] = KBUILD_MODNAME;
253 254
254/* In case of multiple matches in ohci_quirks[], only the first one is used. */ 255/* In case of multiple matches in ohci_quirks[], only the first one is used. */
255static const struct { 256static const struct {
256 unsigned short vendor, device, flags; 257 unsigned short vendor, device, revision, flags;
257} ohci_quirks[] = { 258} ohci_quirks[] = {
258 {PCI_VENDOR_ID_TI, PCI_DEVICE_ID_TI_TSB12LV22, QUIRK_CYCLE_TIMER | 259 {PCI_VENDOR_ID_AL, PCI_ANY_ID, PCI_ANY_ID,
259 QUIRK_RESET_PACKET | 260 QUIRK_CYCLE_TIMER},
260 QUIRK_NO_1394A}, 261
261 {PCI_VENDOR_ID_TI, PCI_ANY_ID, QUIRK_RESET_PACKET}, 262 {PCI_VENDOR_ID_APPLE, PCI_DEVICE_ID_APPLE_UNI_N_FW, PCI_ANY_ID,
262 {PCI_VENDOR_ID_AL, PCI_ANY_ID, QUIRK_CYCLE_TIMER}, 263 QUIRK_BE_HEADERS},
263 {PCI_VENDOR_ID_JMICRON, PCI_DEVICE_ID_JMICRON_JMB38X_FW, QUIRK_NO_MSI}, 264
264 {PCI_VENDOR_ID_NEC, PCI_ANY_ID, QUIRK_CYCLE_TIMER}, 265 {PCI_VENDOR_ID_ATT, PCI_DEVICE_ID_AGERE_FW643, 6,
265 {PCI_VENDOR_ID_VIA, PCI_ANY_ID, QUIRK_CYCLE_TIMER}, 266 QUIRK_NO_MSI},
266 {PCI_VENDOR_ID_RICOH, PCI_ANY_ID, QUIRK_CYCLE_TIMER}, 267
267 {PCI_VENDOR_ID_APPLE, PCI_DEVICE_ID_APPLE_UNI_N_FW, QUIRK_BE_HEADERS}, 268 {PCI_VENDOR_ID_JMICRON, PCI_DEVICE_ID_JMICRON_JMB38X_FW, PCI_ANY_ID,
269 QUIRK_NO_MSI},
270
271 {PCI_VENDOR_ID_NEC, PCI_ANY_ID, PCI_ANY_ID,
272 QUIRK_CYCLE_TIMER},
273
274 {PCI_VENDOR_ID_RICOH, PCI_ANY_ID, PCI_ANY_ID,
275 QUIRK_CYCLE_TIMER},
276
277 {PCI_VENDOR_ID_TI, PCI_DEVICE_ID_TI_TSB12LV22, PCI_ANY_ID,
278 QUIRK_CYCLE_TIMER | QUIRK_RESET_PACKET | QUIRK_NO_1394A},
279
280 {PCI_VENDOR_ID_TI, PCI_ANY_ID, PCI_ANY_ID,
281 QUIRK_RESET_PACKET},
282
283 {PCI_VENDOR_ID_VIA, PCI_ANY_ID, PCI_ANY_ID,
284 QUIRK_CYCLE_TIMER | QUIRK_NO_MSI},
268}; 285};
269 286
270/* This overrides anything that was found in ohci_quirks[]. */ 287/* This overrides anything that was found in ohci_quirks[]. */
@@ -577,17 +594,11 @@ static int ohci_update_phy_reg(struct fw_card *card, int addr,
577 return ret; 594 return ret;
578} 595}
579 596
580static int ar_context_add_page(struct ar_context *ctx) 597static void ar_context_link_page(struct ar_context *ctx,
598 struct ar_buffer *ab, dma_addr_t ab_bus)
581{ 599{
582 struct device *dev = ctx->ohci->card.device;
583 struct ar_buffer *ab;
584 dma_addr_t uninitialized_var(ab_bus);
585 size_t offset; 600 size_t offset;
586 601
587 ab = dma_alloc_coherent(dev, PAGE_SIZE, &ab_bus, GFP_ATOMIC);
588 if (ab == NULL)
589 return -ENOMEM;
590
591 ab->next = NULL; 602 ab->next = NULL;
592 memset(&ab->descriptor, 0, sizeof(ab->descriptor)); 603 memset(&ab->descriptor, 0, sizeof(ab->descriptor));
593 ab->descriptor.control = cpu_to_le16(DESCRIPTOR_INPUT_MORE | 604 ab->descriptor.control = cpu_to_le16(DESCRIPTOR_INPUT_MORE |
@@ -606,6 +617,19 @@ static int ar_context_add_page(struct ar_context *ctx)
606 617
607 reg_write(ctx->ohci, CONTROL_SET(ctx->regs), CONTEXT_WAKE); 618 reg_write(ctx->ohci, CONTROL_SET(ctx->regs), CONTEXT_WAKE);
608 flush_writes(ctx->ohci); 619 flush_writes(ctx->ohci);
620}
621
622static int ar_context_add_page(struct ar_context *ctx)
623{
624 struct device *dev = ctx->ohci->card.device;
625 struct ar_buffer *ab;
626 dma_addr_t uninitialized_var(ab_bus);
627
628 ab = dma_alloc_coherent(dev, PAGE_SIZE, &ab_bus, GFP_ATOMIC);
629 if (ab == NULL)
630 return -ENOMEM;
631
632 ar_context_link_page(ctx, ab, ab_bus);
609 633
610 return 0; 634 return 0;
611} 635}
@@ -730,16 +754,17 @@ static __le32 *handle_ar_packet(struct ar_context *ctx, __le32 *buffer)
730static void ar_context_tasklet(unsigned long data) 754static void ar_context_tasklet(unsigned long data)
731{ 755{
732 struct ar_context *ctx = (struct ar_context *)data; 756 struct ar_context *ctx = (struct ar_context *)data;
733 struct fw_ohci *ohci = ctx->ohci;
734 struct ar_buffer *ab; 757 struct ar_buffer *ab;
735 struct descriptor *d; 758 struct descriptor *d;
736 void *buffer, *end; 759 void *buffer, *end;
760 __le16 res_count;
737 761
738 ab = ctx->current_buffer; 762 ab = ctx->current_buffer;
739 d = &ab->descriptor; 763 d = &ab->descriptor;
740 764
741 if (d->res_count == 0) { 765 res_count = ACCESS_ONCE(d->res_count);
742 size_t size, rest, offset; 766 if (res_count == 0) {
767 size_t size, size2, rest, pktsize, size3, offset;
743 dma_addr_t start_bus; 768 dma_addr_t start_bus;
744 void *start; 769 void *start;
745 770
@@ -750,29 +775,63 @@ static void ar_context_tasklet(unsigned long data)
750 */ 775 */
751 776
752 offset = offsetof(struct ar_buffer, data); 777 offset = offsetof(struct ar_buffer, data);
753 start = buffer = ab; 778 start = ab;
754 start_bus = le32_to_cpu(ab->descriptor.data_address) - offset; 779 start_bus = le32_to_cpu(ab->descriptor.data_address) - offset;
780 buffer = ab->data;
755 781
756 ab = ab->next; 782 ab = ab->next;
757 d = &ab->descriptor; 783 d = &ab->descriptor;
758 size = buffer + PAGE_SIZE - ctx->pointer; 784 size = start + PAGE_SIZE - ctx->pointer;
785 /* valid buffer data in the next page */
759 rest = le16_to_cpu(d->req_count) - le16_to_cpu(d->res_count); 786 rest = le16_to_cpu(d->req_count) - le16_to_cpu(d->res_count);
787 /* what actually fits in this page */
788 size2 = min(rest, (size_t)PAGE_SIZE - offset - size);
760 memmove(buffer, ctx->pointer, size); 789 memmove(buffer, ctx->pointer, size);
761 memcpy(buffer + size, ab->data, rest); 790 memcpy(buffer + size, ab->data, size2);
762 ctx->current_buffer = ab; 791
763 ctx->pointer = (void *) ab->data + rest; 792 while (size > 0) {
764 end = buffer + size + rest; 793 void *next = handle_ar_packet(ctx, buffer);
794 pktsize = next - buffer;
795 if (pktsize >= size) {
796 /*
797 * We have handled all the data that was
798 * originally in this page, so we can now
799 * continue in the next page.
800 */
801 buffer = next;
802 break;
803 }
804 /* move the next packet to the start of the buffer */
805 memmove(buffer, next, size + size2 - pktsize);
806 size -= pktsize;
807 /* fill up this page again */
808 size3 = min(rest - size2,
809 (size_t)PAGE_SIZE - offset - size - size2);
810 memcpy(buffer + size + size2,
811 (void *) ab->data + size2, size3);
812 size2 += size3;
813 }
765 814
766 while (buffer < end) 815 if (rest > 0) {
767 buffer = handle_ar_packet(ctx, buffer); 816 /* handle the packets that are fully in the next page */
817 buffer = (void *) ab->data +
818 (buffer - (start + offset + size));
819 end = (void *) ab->data + rest;
768 820
769 dma_free_coherent(ohci->card.device, PAGE_SIZE, 821 while (buffer < end)
770 start, start_bus); 822 buffer = handle_ar_packet(ctx, buffer);
771 ar_context_add_page(ctx); 823
824 ctx->current_buffer = ab;
825 ctx->pointer = end;
826
827 ar_context_link_page(ctx, start, start_bus);
828 } else {
829 ctx->pointer = start + PAGE_SIZE;
830 }
772 } else { 831 } else {
773 buffer = ctx->pointer; 832 buffer = ctx->pointer;
774 ctx->pointer = end = 833 ctx->pointer = end =
775 (void *) ab + PAGE_SIZE - le16_to_cpu(d->res_count); 834 (void *) ab + PAGE_SIZE - le16_to_cpu(res_count);
776 835
777 while (buffer < end) 836 while (buffer < end)
778 buffer = handle_ar_packet(ctx, buffer); 837 buffer = handle_ar_packet(ctx, buffer);
@@ -2885,9 +2944,11 @@ static int __devinit pci_probe(struct pci_dev *dev,
2885 } 2944 }
2886 2945
2887 for (i = 0; i < ARRAY_SIZE(ohci_quirks); i++) 2946 for (i = 0; i < ARRAY_SIZE(ohci_quirks); i++)
2888 if (ohci_quirks[i].vendor == dev->vendor && 2947 if ((ohci_quirks[i].vendor == dev->vendor) &&
2889 (ohci_quirks[i].device == dev->device || 2948 (ohci_quirks[i].device == (unsigned short)PCI_ANY_ID ||
2890 ohci_quirks[i].device == (unsigned short)PCI_ANY_ID)) { 2949 ohci_quirks[i].device == dev->device) &&
2950 (ohci_quirks[i].revision == (unsigned short)PCI_ANY_ID ||
2951 ohci_quirks[i].revision >= dev->revision)) {
2891 ohci->quirks = ohci_quirks[i].flags; 2952 ohci->quirks = ohci_quirks[i].flags;
2892 break; 2953 break;
2893 } 2954 }