diff options
Diffstat (limited to 'drivers/firewire/fw-ohci.c')
-rw-r--r-- | drivers/firewire/fw-ohci.c | 63 |
1 files changed, 49 insertions, 14 deletions
diff --git a/drivers/firewire/fw-ohci.c b/drivers/firewire/fw-ohci.c index 251416f2148f..ab9c01e462ef 100644 --- a/drivers/firewire/fw-ohci.c +++ b/drivers/firewire/fw-ohci.c | |||
@@ -476,6 +476,7 @@ static int ar_context_add_page(struct ar_context *ctx) | |||
476 | if (ab == NULL) | 476 | if (ab == NULL) |
477 | return -ENOMEM; | 477 | return -ENOMEM; |
478 | 478 | ||
479 | ab->next = NULL; | ||
479 | memset(&ab->descriptor, 0, sizeof(ab->descriptor)); | 480 | memset(&ab->descriptor, 0, sizeof(ab->descriptor)); |
480 | ab->descriptor.control = cpu_to_le16(DESCRIPTOR_INPUT_MORE | | 481 | ab->descriptor.control = cpu_to_le16(DESCRIPTOR_INPUT_MORE | |
481 | DESCRIPTOR_STATUS | | 482 | DESCRIPTOR_STATUS | |
@@ -496,6 +497,21 @@ static int ar_context_add_page(struct ar_context *ctx) | |||
496 | return 0; | 497 | return 0; |
497 | } | 498 | } |
498 | 499 | ||
500 | static void ar_context_release(struct ar_context *ctx) | ||
501 | { | ||
502 | struct ar_buffer *ab, *ab_next; | ||
503 | size_t offset; | ||
504 | dma_addr_t ab_bus; | ||
505 | |||
506 | for (ab = ctx->current_buffer; ab; ab = ab_next) { | ||
507 | ab_next = ab->next; | ||
508 | offset = offsetof(struct ar_buffer, data); | ||
509 | ab_bus = le32_to_cpu(ab->descriptor.data_address) - offset; | ||
510 | dma_free_coherent(ctx->ohci->card.device, PAGE_SIZE, | ||
511 | ab, ab_bus); | ||
512 | } | ||
513 | } | ||
514 | |||
499 | #if defined(CONFIG_PPC_PMAC) && defined(CONFIG_PPC32) | 515 | #if defined(CONFIG_PPC_PMAC) && defined(CONFIG_PPC32) |
500 | #define cond_le32_to_cpu(v) \ | 516 | #define cond_le32_to_cpu(v) \ |
501 | (ohci->old_uninorth ? (__force __u32)(v) : le32_to_cpu(v)) | 517 | (ohci->old_uninorth ? (__force __u32)(v) : le32_to_cpu(v)) |
@@ -958,6 +974,7 @@ at_context_queue_packet(struct context *ctx, struct fw_packet *packet) | |||
958 | packet->ack = RCODE_SEND_ERROR; | 974 | packet->ack = RCODE_SEND_ERROR; |
959 | return -1; | 975 | return -1; |
960 | } | 976 | } |
977 | packet->payload_bus = payload_bus; | ||
961 | 978 | ||
962 | d[2].req_count = cpu_to_le16(packet->payload_length); | 979 | d[2].req_count = cpu_to_le16(packet->payload_length); |
963 | d[2].data_address = cpu_to_le32(payload_bus); | 980 | d[2].data_address = cpu_to_le32(payload_bus); |
@@ -1009,7 +1026,6 @@ static int handle_at_packet(struct context *context, | |||
1009 | struct driver_data *driver_data; | 1026 | struct driver_data *driver_data; |
1010 | struct fw_packet *packet; | 1027 | struct fw_packet *packet; |
1011 | struct fw_ohci *ohci = context->ohci; | 1028 | struct fw_ohci *ohci = context->ohci; |
1012 | dma_addr_t payload_bus; | ||
1013 | int evt; | 1029 | int evt; |
1014 | 1030 | ||
1015 | if (last->transfer_status == 0) | 1031 | if (last->transfer_status == 0) |
@@ -1022,9 +1038,8 @@ static int handle_at_packet(struct context *context, | |||
1022 | /* This packet was cancelled, just continue. */ | 1038 | /* This packet was cancelled, just continue. */ |
1023 | return 1; | 1039 | return 1; |
1024 | 1040 | ||
1025 | payload_bus = le32_to_cpu(last->data_address); | 1041 | if (packet->payload_bus) |
1026 | if (payload_bus != 0) | 1042 | dma_unmap_single(ohci->card.device, packet->payload_bus, |
1027 | dma_unmap_single(ohci->card.device, payload_bus, | ||
1028 | packet->payload_length, DMA_TO_DEVICE); | 1043 | packet->payload_length, DMA_TO_DEVICE); |
1029 | 1044 | ||
1030 | evt = le16_to_cpu(last->transfer_status) & 0x1f; | 1045 | evt = le16_to_cpu(last->transfer_status) & 0x1f; |
@@ -1681,6 +1696,10 @@ static int ohci_cancel_packet(struct fw_card *card, struct fw_packet *packet) | |||
1681 | if (packet->ack != 0) | 1696 | if (packet->ack != 0) |
1682 | goto out; | 1697 | goto out; |
1683 | 1698 | ||
1699 | if (packet->payload_bus) | ||
1700 | dma_unmap_single(ohci->card.device, packet->payload_bus, | ||
1701 | packet->payload_length, DMA_TO_DEVICE); | ||
1702 | |||
1684 | log_ar_at_event('T', packet->speed, packet->header, 0x20); | 1703 | log_ar_at_event('T', packet->speed, packet->header, 0x20); |
1685 | driver_data->packet = NULL; | 1704 | driver_data->packet = NULL; |
1686 | packet->ack = RCODE_CANCELLED; | 1705 | packet->ack = RCODE_CANCELLED; |
@@ -2349,8 +2368,8 @@ pci_probe(struct pci_dev *dev, const struct pci_device_id *ent) | |||
2349 | 2368 | ||
2350 | ohci = kzalloc(sizeof(*ohci), GFP_KERNEL); | 2369 | ohci = kzalloc(sizeof(*ohci), GFP_KERNEL); |
2351 | if (ohci == NULL) { | 2370 | if (ohci == NULL) { |
2352 | fw_error("Could not malloc fw_ohci data.\n"); | 2371 | err = -ENOMEM; |
2353 | return -ENOMEM; | 2372 | goto fail; |
2354 | } | 2373 | } |
2355 | 2374 | ||
2356 | fw_card_initialize(&ohci->card, &ohci_driver, &dev->dev); | 2375 | fw_card_initialize(&ohci->card, &ohci_driver, &dev->dev); |
@@ -2359,7 +2378,7 @@ pci_probe(struct pci_dev *dev, const struct pci_device_id *ent) | |||
2359 | 2378 | ||
2360 | err = pci_enable_device(dev); | 2379 | err = pci_enable_device(dev); |
2361 | if (err) { | 2380 | if (err) { |
2362 | fw_error("Failed to enable OHCI hardware.\n"); | 2381 | fw_error("Failed to enable OHCI hardware\n"); |
2363 | goto fail_free; | 2382 | goto fail_free; |
2364 | } | 2383 | } |
2365 | 2384 | ||
@@ -2427,9 +2446,8 @@ pci_probe(struct pci_dev *dev, const struct pci_device_id *ent) | |||
2427 | ohci->ir_context_list = kzalloc(size, GFP_KERNEL); | 2446 | ohci->ir_context_list = kzalloc(size, GFP_KERNEL); |
2428 | 2447 | ||
2429 | if (ohci->it_context_list == NULL || ohci->ir_context_list == NULL) { | 2448 | if (ohci->it_context_list == NULL || ohci->ir_context_list == NULL) { |
2430 | fw_error("Out of memory for it/ir contexts.\n"); | ||
2431 | err = -ENOMEM; | 2449 | err = -ENOMEM; |
2432 | goto fail_registers; | 2450 | goto fail_contexts; |
2433 | } | 2451 | } |
2434 | 2452 | ||
2435 | /* self-id dma buffer allocation */ | 2453 | /* self-id dma buffer allocation */ |
@@ -2438,9 +2456,8 @@ pci_probe(struct pci_dev *dev, const struct pci_device_id *ent) | |||
2438 | &ohci->self_id_bus, | 2456 | &ohci->self_id_bus, |
2439 | GFP_KERNEL); | 2457 | GFP_KERNEL); |
2440 | if (ohci->self_id_cpu == NULL) { | 2458 | if (ohci->self_id_cpu == NULL) { |
2441 | fw_error("Out of memory for self ID buffer.\n"); | ||
2442 | err = -ENOMEM; | 2459 | err = -ENOMEM; |
2443 | goto fail_registers; | 2460 | goto fail_contexts; |
2444 | } | 2461 | } |
2445 | 2462 | ||
2446 | bus_options = reg_read(ohci, OHCI1394_BusOptions); | 2463 | bus_options = reg_read(ohci, OHCI1394_BusOptions); |
@@ -2454,15 +2471,19 @@ pci_probe(struct pci_dev *dev, const struct pci_device_id *ent) | |||
2454 | goto fail_self_id; | 2471 | goto fail_self_id; |
2455 | 2472 | ||
2456 | fw_notify("Added fw-ohci device %s, OHCI version %x.%x\n", | 2473 | fw_notify("Added fw-ohci device %s, OHCI version %x.%x\n", |
2457 | dev->dev.bus_id, version >> 16, version & 0xff); | 2474 | dev_name(&dev->dev), version >> 16, version & 0xff); |
2458 | return 0; | 2475 | return 0; |
2459 | 2476 | ||
2460 | fail_self_id: | 2477 | fail_self_id: |
2461 | dma_free_coherent(ohci->card.device, SELF_ID_BUF_SIZE, | 2478 | dma_free_coherent(ohci->card.device, SELF_ID_BUF_SIZE, |
2462 | ohci->self_id_cpu, ohci->self_id_bus); | 2479 | ohci->self_id_cpu, ohci->self_id_bus); |
2463 | fail_registers: | 2480 | fail_contexts: |
2464 | kfree(ohci->it_context_list); | ||
2465 | kfree(ohci->ir_context_list); | 2481 | kfree(ohci->ir_context_list); |
2482 | kfree(ohci->it_context_list); | ||
2483 | context_release(&ohci->at_response_ctx); | ||
2484 | context_release(&ohci->at_request_ctx); | ||
2485 | ar_context_release(&ohci->ar_response_ctx); | ||
2486 | ar_context_release(&ohci->ar_request_ctx); | ||
2466 | pci_iounmap(dev, ohci->registers); | 2487 | pci_iounmap(dev, ohci->registers); |
2467 | fail_iomem: | 2488 | fail_iomem: |
2468 | pci_release_region(dev, 0); | 2489 | pci_release_region(dev, 0); |
@@ -2471,6 +2492,9 @@ pci_probe(struct pci_dev *dev, const struct pci_device_id *ent) | |||
2471 | fail_free: | 2492 | fail_free: |
2472 | kfree(&ohci->card); | 2493 | kfree(&ohci->card); |
2473 | ohci_pmac_off(dev); | 2494 | ohci_pmac_off(dev); |
2495 | fail: | ||
2496 | if (err == -ENOMEM) | ||
2497 | fw_error("Out of memory\n"); | ||
2474 | 2498 | ||
2475 | return err; | 2499 | return err; |
2476 | } | 2500 | } |
@@ -2491,8 +2515,19 @@ static void pci_remove(struct pci_dev *dev) | |||
2491 | 2515 | ||
2492 | software_reset(ohci); | 2516 | software_reset(ohci); |
2493 | free_irq(dev->irq, ohci); | 2517 | free_irq(dev->irq, ohci); |
2518 | |||
2519 | if (ohci->next_config_rom && ohci->next_config_rom != ohci->config_rom) | ||
2520 | dma_free_coherent(ohci->card.device, CONFIG_ROM_SIZE, | ||
2521 | ohci->next_config_rom, ohci->next_config_rom_bus); | ||
2522 | if (ohci->config_rom) | ||
2523 | dma_free_coherent(ohci->card.device, CONFIG_ROM_SIZE, | ||
2524 | ohci->config_rom, ohci->config_rom_bus); | ||
2494 | dma_free_coherent(ohci->card.device, SELF_ID_BUF_SIZE, | 2525 | dma_free_coherent(ohci->card.device, SELF_ID_BUF_SIZE, |
2495 | ohci->self_id_cpu, ohci->self_id_bus); | 2526 | ohci->self_id_cpu, ohci->self_id_bus); |
2527 | ar_context_release(&ohci->ar_request_ctx); | ||
2528 | ar_context_release(&ohci->ar_response_ctx); | ||
2529 | context_release(&ohci->at_request_ctx); | ||
2530 | context_release(&ohci->at_response_ctx); | ||
2496 | kfree(ohci->it_context_list); | 2531 | kfree(ohci->it_context_list); |
2497 | kfree(ohci->ir_context_list); | 2532 | kfree(ohci->ir_context_list); |
2498 | pci_iounmap(dev, ohci->registers); | 2533 | pci_iounmap(dev, ohci->registers); |