aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorJay Fenlason <fenlason@redhat.com>2008-10-22 15:59:42 -0400
committerStefan Richter <stefanr@s5r6.in-berlin.de>2008-10-26 05:27:00 -0400
commita55709ba9d27053471f9fca8ee76b41ecefc14cd (patch)
treee338976917e3926a292c67fcadc59968504d7fcc
parent77e557191701afa55ae7320d42ad6458a2ad292e (diff)
firewire: fw-ohci: don't leak dma memory on module removal
The transmit and receive context dma memory was not being freed on module removal. Neither was the config rom memory. Fix that. The ab->next assignment is pure paranoia. Signed-off-by: Jay Fenlason <fenlason@redhat.com> Signed-off-by: Stefan Richter <stefanr@s5r6.in-berlin.de>
-rw-r--r--drivers/firewire/fw-ohci.c27
1 files changed, 27 insertions, 0 deletions
diff --git a/drivers/firewire/fw-ohci.c b/drivers/firewire/fw-ohci.c
index 251416f2148f..5a5685f8f5f7 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
500static 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))
@@ -2491,8 +2507,19 @@ static void pci_remove(struct pci_dev *dev)
2491 2507
2492 software_reset(ohci); 2508 software_reset(ohci);
2493 free_irq(dev->irq, ohci); 2509 free_irq(dev->irq, ohci);
2510
2511 if (ohci->next_config_rom && ohci->next_config_rom != ohci->config_rom)
2512 dma_free_coherent(ohci->card.device, CONFIG_ROM_SIZE,
2513 ohci->next_config_rom, ohci->next_config_rom_bus);
2514 if (ohci->config_rom)
2515 dma_free_coherent(ohci->card.device, CONFIG_ROM_SIZE,
2516 ohci->config_rom, ohci->config_rom_bus);
2494 dma_free_coherent(ohci->card.device, SELF_ID_BUF_SIZE, 2517 dma_free_coherent(ohci->card.device, SELF_ID_BUF_SIZE,
2495 ohci->self_id_cpu, ohci->self_id_bus); 2518 ohci->self_id_cpu, ohci->self_id_bus);
2519 ar_context_release(&ohci->ar_request_ctx);
2520 ar_context_release(&ohci->ar_response_ctx);
2521 context_release(&ohci->at_request_ctx);
2522 context_release(&ohci->at_response_ctx);
2496 kfree(ohci->it_context_list); 2523 kfree(ohci->it_context_list);
2497 kfree(ohci->ir_context_list); 2524 kfree(ohci->ir_context_list);
2498 pci_iounmap(dev, ohci->registers); 2525 pci_iounmap(dev, ohci->registers);