diff options
author | Jeremy Erickson <jerickso@cs.unc.edu> | 2014-04-11 13:24:45 -0400 |
---|---|---|
committer | Jeremy Erickson <jerickso@cs.unc.edu> | 2014-04-11 13:24:45 -0400 |
commit | 438145c7ef5c9445f25bb8fc4d52e2c9d11fdc7c (patch) | |
tree | 76941991e36f4a32bf1be0db3854959053f24619 /drivers/firewire | |
parent | 9ddd1b8ad8abd321964b8add5581910de6d67c2a (diff) |
Update from 2.6.36 to 2.6.36.4wip-dissipation-jerickso
Diffstat (limited to 'drivers/firewire')
-rw-r--r-- | drivers/firewire/core-card.c | 11 | ||||
-rw-r--r-- | drivers/firewire/ohci.c | 107 |
2 files changed, 90 insertions, 28 deletions
diff --git a/drivers/firewire/core-card.c b/drivers/firewire/core-card.c index be0492398ef9..24ff35511e2b 100644 --- a/drivers/firewire/core-card.c +++ b/drivers/firewire/core-card.c | |||
@@ -75,6 +75,8 @@ static size_t config_rom_length = 1 + 4 + 1 + 1; | |||
75 | #define BIB_IRMC ((1) << 31) | 75 | #define BIB_IRMC ((1) << 31) |
76 | #define NODE_CAPABILITIES 0x0c0083c0 /* per IEEE 1394 clause 8.3.2.6.5.2 */ | 76 | #define NODE_CAPABILITIES 0x0c0083c0 /* per IEEE 1394 clause 8.3.2.6.5.2 */ |
77 | 77 | ||
78 | #define CANON_OUI 0x000085 | ||
79 | |||
78 | static void generate_config_rom(struct fw_card *card, __be32 *config_rom) | 80 | static void generate_config_rom(struct fw_card *card, __be32 *config_rom) |
79 | { | 81 | { |
80 | struct fw_descriptor *desc; | 82 | struct fw_descriptor *desc; |
@@ -284,6 +286,7 @@ static void bm_work(struct work_struct *work) | |||
284 | bool root_device_is_running; | 286 | bool root_device_is_running; |
285 | bool root_device_is_cmc; | 287 | bool root_device_is_cmc; |
286 | bool irm_is_1394_1995_only; | 288 | bool irm_is_1394_1995_only; |
289 | bool keep_this_irm; | ||
287 | 290 | ||
288 | spin_lock_irq(&card->lock); | 291 | spin_lock_irq(&card->lock); |
289 | 292 | ||
@@ -305,6 +308,10 @@ static void bm_work(struct work_struct *work) | |||
305 | irm_is_1394_1995_only = irm_device && irm_device->config_rom && | 308 | irm_is_1394_1995_only = irm_device && irm_device->config_rom && |
306 | (irm_device->config_rom[2] & 0x000000f0) == 0; | 309 | (irm_device->config_rom[2] & 0x000000f0) == 0; |
307 | 310 | ||
311 | /* Canon MV5i works unreliably if it is not root node. */ | ||
312 | keep_this_irm = irm_device && irm_device->config_rom && | ||
313 | irm_device->config_rom[3] >> 8 == CANON_OUI; | ||
314 | |||
308 | root_id = root_node->node_id; | 315 | root_id = root_node->node_id; |
309 | irm_id = card->irm_node->node_id; | 316 | irm_id = card->irm_node->node_id; |
310 | local_id = card->local_node->node_id; | 317 | local_id = card->local_node->node_id; |
@@ -333,7 +340,7 @@ static void bm_work(struct work_struct *work) | |||
333 | goto pick_me; | 340 | goto pick_me; |
334 | } | 341 | } |
335 | 342 | ||
336 | if (irm_is_1394_1995_only) { | 343 | if (irm_is_1394_1995_only && !keep_this_irm) { |
337 | new_root_id = local_id; | 344 | new_root_id = local_id; |
338 | fw_notify("%s, making local node (%02x) root.\n", | 345 | fw_notify("%s, making local node (%02x) root.\n", |
339 | "IRM is not 1394a compliant", new_root_id); | 346 | "IRM is not 1394a compliant", new_root_id); |
@@ -382,7 +389,7 @@ static void bm_work(struct work_struct *work) | |||
382 | 389 | ||
383 | spin_lock_irq(&card->lock); | 390 | spin_lock_irq(&card->lock); |
384 | 391 | ||
385 | if (rcode != RCODE_COMPLETE) { | 392 | if (rcode != RCODE_COMPLETE && !keep_this_irm) { |
386 | /* | 393 | /* |
387 | * The lock request failed, maybe the IRM | 394 | * The lock request failed, maybe the IRM |
388 | * isn't really IRM capable after all. Let's | 395 | * isn't really IRM capable after all. Let's |
diff --git a/drivers/firewire/ohci.c b/drivers/firewire/ohci.c index 9dcb17d51aee..a03cb6acaeda 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 | ||
243 | static char ohci_driver_name[] = KBUILD_MODNAME; | 243 | static 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. */ |
255 | static const struct { | 256 | static 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[]. */ |
@@ -739,7 +756,7 @@ static void ar_context_tasklet(unsigned long data) | |||
739 | d = &ab->descriptor; | 756 | d = &ab->descriptor; |
740 | 757 | ||
741 | if (d->res_count == 0) { | 758 | if (d->res_count == 0) { |
742 | size_t size, rest, offset; | 759 | size_t size, size2, rest, pktsize, size3, offset; |
743 | dma_addr_t start_bus; | 760 | dma_addr_t start_bus; |
744 | void *start; | 761 | void *start; |
745 | 762 | ||
@@ -750,25 +767,61 @@ static void ar_context_tasklet(unsigned long data) | |||
750 | */ | 767 | */ |
751 | 768 | ||
752 | offset = offsetof(struct ar_buffer, data); | 769 | offset = offsetof(struct ar_buffer, data); |
753 | start = buffer = ab; | 770 | start = ab; |
754 | start_bus = le32_to_cpu(ab->descriptor.data_address) - offset; | 771 | start_bus = le32_to_cpu(ab->descriptor.data_address) - offset; |
772 | buffer = ab->data; | ||
755 | 773 | ||
756 | ab = ab->next; | 774 | ab = ab->next; |
757 | d = &ab->descriptor; | 775 | d = &ab->descriptor; |
758 | size = buffer + PAGE_SIZE - ctx->pointer; | 776 | size = start + PAGE_SIZE - ctx->pointer; |
777 | /* valid buffer data in the next page */ | ||
759 | rest = le16_to_cpu(d->req_count) - le16_to_cpu(d->res_count); | 778 | rest = le16_to_cpu(d->req_count) - le16_to_cpu(d->res_count); |
779 | /* what actually fits in this page */ | ||
780 | size2 = min(rest, (size_t)PAGE_SIZE - offset - size); | ||
760 | memmove(buffer, ctx->pointer, size); | 781 | memmove(buffer, ctx->pointer, size); |
761 | memcpy(buffer + size, ab->data, rest); | 782 | memcpy(buffer + size, ab->data, size2); |
762 | ctx->current_buffer = ab; | 783 | |
763 | ctx->pointer = (void *) ab->data + rest; | 784 | while (size > 0) { |
764 | end = buffer + size + rest; | 785 | void *next = handle_ar_packet(ctx, buffer); |
786 | pktsize = next - buffer; | ||
787 | if (pktsize >= size) { | ||
788 | /* | ||
789 | * We have handled all the data that was | ||
790 | * originally in this page, so we can now | ||
791 | * continue in the next page. | ||
792 | */ | ||
793 | buffer = next; | ||
794 | break; | ||
795 | } | ||
796 | /* move the next packet to the start of the buffer */ | ||
797 | memmove(buffer, next, size + size2 - pktsize); | ||
798 | size -= pktsize; | ||
799 | /* fill up this page again */ | ||
800 | size3 = min(rest - size2, | ||
801 | (size_t)PAGE_SIZE - offset - size - size2); | ||
802 | memcpy(buffer + size + size2, | ||
803 | (void *) ab->data + size2, size3); | ||
804 | size2 += size3; | ||
805 | } | ||
765 | 806 | ||
766 | while (buffer < end) | 807 | if (rest > 0) { |
767 | buffer = handle_ar_packet(ctx, buffer); | 808 | /* handle the packets that are fully in the next page */ |
809 | buffer = (void *) ab->data + | ||
810 | (buffer - (start + offset + size)); | ||
811 | end = (void *) ab->data + rest; | ||
812 | |||
813 | while (buffer < end) | ||
814 | buffer = handle_ar_packet(ctx, buffer); | ||
768 | 815 | ||
769 | dma_free_coherent(ohci->card.device, PAGE_SIZE, | 816 | ctx->current_buffer = ab; |
770 | start, start_bus); | 817 | ctx->pointer = end; |
771 | ar_context_add_page(ctx); | 818 | |
819 | dma_free_coherent(ohci->card.device, PAGE_SIZE, | ||
820 | start, start_bus); | ||
821 | ar_context_add_page(ctx); | ||
822 | } else { | ||
823 | ctx->pointer = start + PAGE_SIZE; | ||
824 | } | ||
772 | } else { | 825 | } else { |
773 | buffer = ctx->pointer; | 826 | buffer = ctx->pointer; |
774 | ctx->pointer = end = | 827 | ctx->pointer = end = |
@@ -2885,9 +2938,11 @@ static int __devinit pci_probe(struct pci_dev *dev, | |||
2885 | } | 2938 | } |
2886 | 2939 | ||
2887 | for (i = 0; i < ARRAY_SIZE(ohci_quirks); i++) | 2940 | for (i = 0; i < ARRAY_SIZE(ohci_quirks); i++) |
2888 | if (ohci_quirks[i].vendor == dev->vendor && | 2941 | if ((ohci_quirks[i].vendor == dev->vendor) && |
2889 | (ohci_quirks[i].device == dev->device || | 2942 | (ohci_quirks[i].device == (unsigned short)PCI_ANY_ID || |
2890 | ohci_quirks[i].device == (unsigned short)PCI_ANY_ID)) { | 2943 | ohci_quirks[i].device == dev->device) && |
2944 | (ohci_quirks[i].revision == (unsigned short)PCI_ANY_ID || | ||
2945 | ohci_quirks[i].revision >= dev->revision)) { | ||
2891 | ohci->quirks = ohci_quirks[i].flags; | 2946 | ohci->quirks = ohci_quirks[i].flags; |
2892 | break; | 2947 | break; |
2893 | } | 2948 | } |