diff options
Diffstat (limited to 'drivers/firewire/fw-ohci.c')
-rw-r--r-- | drivers/firewire/fw-ohci.c | 39 |
1 files changed, 25 insertions, 14 deletions
diff --git a/drivers/firewire/fw-ohci.c b/drivers/firewire/fw-ohci.c index 333b12544dd1..251416f2148f 100644 --- a/drivers/firewire/fw-ohci.c +++ b/drivers/firewire/fw-ohci.c | |||
@@ -171,7 +171,6 @@ struct iso_context { | |||
171 | struct fw_ohci { | 171 | struct fw_ohci { |
172 | struct fw_card card; | 172 | struct fw_card card; |
173 | 173 | ||
174 | u32 version; | ||
175 | __iomem char *registers; | 174 | __iomem char *registers; |
176 | dma_addr_t self_id_bus; | 175 | dma_addr_t self_id_bus; |
177 | __le32 *self_id_cpu; | 176 | __le32 *self_id_cpu; |
@@ -180,6 +179,8 @@ struct fw_ohci { | |||
180 | int generation; | 179 | int generation; |
181 | int request_generation; /* for timestamping incoming requests */ | 180 | int request_generation; /* for timestamping incoming requests */ |
182 | u32 bus_seconds; | 181 | u32 bus_seconds; |
182 | |||
183 | bool use_dualbuffer; | ||
183 | bool old_uninorth; | 184 | bool old_uninorth; |
184 | bool bus_reset_packet_quirk; | 185 | bool bus_reset_packet_quirk; |
185 | 186 | ||
@@ -953,7 +954,7 @@ at_context_queue_packet(struct context *ctx, struct fw_packet *packet) | |||
953 | payload_bus = | 954 | payload_bus = |
954 | dma_map_single(ohci->card.device, packet->payload, | 955 | dma_map_single(ohci->card.device, packet->payload, |
955 | packet->payload_length, DMA_TO_DEVICE); | 956 | packet->payload_length, DMA_TO_DEVICE); |
956 | if (dma_mapping_error(payload_bus)) { | 957 | if (dma_mapping_error(ohci->card.device, payload_bus)) { |
957 | packet->ack = RCODE_SEND_ERROR; | 958 | packet->ack = RCODE_SEND_ERROR; |
958 | return -1; | 959 | return -1; |
959 | } | 960 | } |
@@ -1885,7 +1886,7 @@ ohci_allocate_iso_context(struct fw_card *card, int type, size_t header_size) | |||
1885 | } else { | 1886 | } else { |
1886 | mask = &ohci->ir_context_mask; | 1887 | mask = &ohci->ir_context_mask; |
1887 | list = ohci->ir_context_list; | 1888 | list = ohci->ir_context_list; |
1888 | if (ohci->version >= OHCI_VERSION_1_1) | 1889 | if (ohci->use_dualbuffer) |
1889 | callback = handle_ir_dualbuffer_packet; | 1890 | callback = handle_ir_dualbuffer_packet; |
1890 | else | 1891 | else |
1891 | callback = handle_ir_packet_per_buffer; | 1892 | callback = handle_ir_packet_per_buffer; |
@@ -1949,7 +1950,7 @@ static int ohci_start_iso(struct fw_iso_context *base, | |||
1949 | } else { | 1950 | } else { |
1950 | index = ctx - ohci->ir_context_list; | 1951 | index = ctx - ohci->ir_context_list; |
1951 | control = IR_CONTEXT_ISOCH_HEADER; | 1952 | control = IR_CONTEXT_ISOCH_HEADER; |
1952 | if (ohci->version >= OHCI_VERSION_1_1) | 1953 | if (ohci->use_dualbuffer) |
1953 | control |= IR_CONTEXT_DUAL_BUFFER_MODE; | 1954 | control |= IR_CONTEXT_DUAL_BUFFER_MODE; |
1954 | match = (tags << 28) | (sync << 8) | ctx->base.channel; | 1955 | match = (tags << 28) | (sync << 8) | ctx->base.channel; |
1955 | if (cycle >= 0) { | 1956 | if (cycle >= 0) { |
@@ -2279,7 +2280,7 @@ ohci_queue_iso(struct fw_iso_context *base, | |||
2279 | spin_lock_irqsave(&ctx->context.ohci->lock, flags); | 2280 | spin_lock_irqsave(&ctx->context.ohci->lock, flags); |
2280 | if (base->type == FW_ISO_CONTEXT_TRANSMIT) | 2281 | if (base->type == FW_ISO_CONTEXT_TRANSMIT) |
2281 | retval = ohci_queue_iso_transmit(base, packet, buffer, payload); | 2282 | retval = ohci_queue_iso_transmit(base, packet, buffer, payload); |
2282 | else if (ctx->context.ohci->version >= OHCI_VERSION_1_1) | 2283 | else if (ctx->context.ohci->use_dualbuffer) |
2283 | retval = ohci_queue_iso_receive_dualbuffer(base, packet, | 2284 | retval = ohci_queue_iso_receive_dualbuffer(base, packet, |
2284 | buffer, payload); | 2285 | buffer, payload); |
2285 | else | 2286 | else |
@@ -2341,7 +2342,7 @@ static int __devinit | |||
2341 | pci_probe(struct pci_dev *dev, const struct pci_device_id *ent) | 2342 | pci_probe(struct pci_dev *dev, const struct pci_device_id *ent) |
2342 | { | 2343 | { |
2343 | struct fw_ohci *ohci; | 2344 | struct fw_ohci *ohci; |
2344 | u32 bus_options, max_receive, link_speed; | 2345 | u32 bus_options, max_receive, link_speed, version; |
2345 | u64 guid; | 2346 | u64 guid; |
2346 | int err; | 2347 | int err; |
2347 | size_t size; | 2348 | size_t size; |
@@ -2366,12 +2367,6 @@ pci_probe(struct pci_dev *dev, const struct pci_device_id *ent) | |||
2366 | pci_write_config_dword(dev, OHCI1394_PCI_HCI_Control, 0); | 2367 | pci_write_config_dword(dev, OHCI1394_PCI_HCI_Control, 0); |
2367 | pci_set_drvdata(dev, ohci); | 2368 | pci_set_drvdata(dev, ohci); |
2368 | 2369 | ||
2369 | #if defined(CONFIG_PPC_PMAC) && defined(CONFIG_PPC32) | ||
2370 | ohci->old_uninorth = dev->vendor == PCI_VENDOR_ID_APPLE && | ||
2371 | dev->device == PCI_DEVICE_ID_APPLE_UNI_N_FW; | ||
2372 | #endif | ||
2373 | ohci->bus_reset_packet_quirk = dev->vendor == PCI_VENDOR_ID_TI; | ||
2374 | |||
2375 | spin_lock_init(&ohci->lock); | 2370 | spin_lock_init(&ohci->lock); |
2376 | 2371 | ||
2377 | tasklet_init(&ohci->bus_reset_tasklet, | 2372 | tasklet_init(&ohci->bus_reset_tasklet, |
@@ -2390,6 +2385,23 @@ pci_probe(struct pci_dev *dev, const struct pci_device_id *ent) | |||
2390 | goto fail_iomem; | 2385 | goto fail_iomem; |
2391 | } | 2386 | } |
2392 | 2387 | ||
2388 | version = reg_read(ohci, OHCI1394_Version) & 0x00ff00ff; | ||
2389 | ohci->use_dualbuffer = version >= OHCI_VERSION_1_1; | ||
2390 | |||
2391 | /* x86-32 currently doesn't use highmem for dma_alloc_coherent */ | ||
2392 | #if !defined(CONFIG_X86_32) | ||
2393 | /* dual-buffer mode is broken with descriptor addresses above 2G */ | ||
2394 | if (dev->vendor == PCI_VENDOR_ID_TI && | ||
2395 | dev->device == PCI_DEVICE_ID_TI_TSB43AB22) | ||
2396 | ohci->use_dualbuffer = false; | ||
2397 | #endif | ||
2398 | |||
2399 | #if defined(CONFIG_PPC_PMAC) && defined(CONFIG_PPC32) | ||
2400 | ohci->old_uninorth = dev->vendor == PCI_VENDOR_ID_APPLE && | ||
2401 | dev->device == PCI_DEVICE_ID_APPLE_UNI_N_FW; | ||
2402 | #endif | ||
2403 | ohci->bus_reset_packet_quirk = dev->vendor == PCI_VENDOR_ID_TI; | ||
2404 | |||
2393 | ar_context_init(&ohci->ar_request_ctx, ohci, | 2405 | ar_context_init(&ohci->ar_request_ctx, ohci, |
2394 | OHCI1394_AsReqRcvContextControlSet); | 2406 | OHCI1394_AsReqRcvContextControlSet); |
2395 | 2407 | ||
@@ -2441,9 +2453,8 @@ pci_probe(struct pci_dev *dev, const struct pci_device_id *ent) | |||
2441 | if (err < 0) | 2453 | if (err < 0) |
2442 | goto fail_self_id; | 2454 | goto fail_self_id; |
2443 | 2455 | ||
2444 | ohci->version = reg_read(ohci, OHCI1394_Version) & 0x00ff00ff; | ||
2445 | fw_notify("Added fw-ohci device %s, OHCI version %x.%x\n", | 2456 | fw_notify("Added fw-ohci device %s, OHCI version %x.%x\n", |
2446 | dev->dev.bus_id, ohci->version >> 16, ohci->version & 0xff); | 2457 | dev->dev.bus_id, version >> 16, version & 0xff); |
2447 | return 0; | 2458 | return 0; |
2448 | 2459 | ||
2449 | fail_self_id: | 2460 | fail_self_id: |