Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

firewire: ohci: release buffer for AR req/resp contexts when managed resource is released

The 1394 OHCI driver allocates several non-coherent DMA buffers for AR
request and response contexts. The buffers are mapped to kernel virtual
address (VMA) so that the first page locates after the last page. Even
when large payload of packet is handled crossing the boundary of buffers,
the driver operates continuously on VMA.

No kernel API is provided for this kind of mapping, while it is possible
to release the buffer when PCI device is going to be released.

This commit moves the call of release helper function to the callback
function of release resources.

Link: https://lore.kernel.org/r/20230604054451.161076-10-o-takashi@sakamocchi.jp
Signed-off-by: Takashi Sakamoto <o-takashi@sakamocchi.jp>

+14 -17
+14 -17
drivers/firewire/ohci.c
··· 677 677 struct device *dev = ctx->ohci->card.device; 678 678 unsigned int i; 679 679 680 + if (!ctx->buffer) 681 + return; 682 + 680 683 vunmap(ctx->buffer); 681 684 682 685 for (i = 0; i < AR_BUFFERS; i++) { ··· 3559 3556 static void release_ohci(struct device *dev, void *data) 3560 3557 { 3561 3558 struct pci_dev *pdev = to_pci_dev(dev); 3559 + struct fw_ohci *ohci = pci_get_drvdata(pdev); 3562 3560 3563 3561 pmac_ohci_off(pdev); 3562 + 3563 + ar_context_release(&ohci->ar_response_ctx); 3564 + ar_context_release(&ohci->ar_request_ctx); 3564 3565 3565 3566 dev_notice(dev, "removed fw-ohci device\n"); 3566 3567 } ··· 3650 3643 err = ar_context_init(&ohci->ar_response_ctx, ohci, PAGE_SIZE/4, 3651 3644 OHCI1394_AsRspRcvContextControlSet); 3652 3645 if (err < 0) 3653 - goto fail_arreq_ctx; 3646 + return err; 3654 3647 3655 3648 err = context_init(&ohci->at_request_ctx, ohci, 3656 3649 OHCI1394_AsReqTrContextControlSet, handle_at_packet); 3657 3650 if (err < 0) 3658 - goto fail_arrsp_ctx; 3651 + return err; 3659 3652 3660 3653 err = context_init(&ohci->at_response_ctx, ohci, 3661 3654 OHCI1394_AsRspTrContextControlSet, handle_at_packet); 3662 3655 if (err < 0) 3663 - goto fail_arrsp_ctx; 3656 + return err; 3664 3657 3665 3658 reg_write(ohci, OHCI1394_IsoRecvIntMaskSet, ~0); 3666 3659 ohci->ir_context_channels = ~0ULL; ··· 3670 3663 ohci->n_ir = hweight32(ohci->ir_context_mask); 3671 3664 size = sizeof(struct iso_context) * ohci->n_ir; 3672 3665 ohci->ir_context_list = devm_kzalloc(&dev->dev, size, GFP_KERNEL); 3673 - if (!ohci->ir_context_list) { 3674 - err = -ENOMEM; 3675 - goto fail_arrsp_ctx; 3676 - } 3666 + if (!ohci->ir_context_list) 3667 + return -ENOMEM; 3677 3668 3678 3669 reg_write(ohci, OHCI1394_IsoXmitIntMaskSet, ~0); 3679 3670 ohci->it_context_support = reg_read(ohci, OHCI1394_IsoXmitIntMaskSet); ··· 3685 3680 ohci->n_it = hweight32(ohci->it_context_mask); 3686 3681 size = sizeof(struct iso_context) * ohci->n_it; 3687 3682 ohci->it_context_list = devm_kzalloc(&dev->dev, size, GFP_KERNEL); 3688 - if (!ohci->it_context_list) { 3689 - err = -ENOMEM; 3690 - goto fail_arrsp_ctx; 3691 - } 3683 + if (!ohci->it_context_list) 3684 + return -ENOMEM; 3692 3685 3693 3686 ohci->self_id = ohci->misc_buffer + PAGE_SIZE/2; 3694 3687 ohci->self_id_bus = ohci->misc_buffer_bus + PAGE_SIZE/2; ··· 3723 3720 3724 3721 fail_msi: 3725 3722 pci_disable_msi(dev); 3726 - fail_arrsp_ctx: 3727 - ar_context_release(&ohci->ar_response_ctx); 3728 - fail_arreq_ctx: 3729 - ar_context_release(&ohci->ar_request_ctx); 3730 3723 3731 3724 return err; 3732 3725 } ··· 3749 3750 3750 3751 software_reset(ohci); 3751 3752 3752 - ar_context_release(&ohci->ar_request_ctx); 3753 - ar_context_release(&ohci->ar_response_ctx); 3754 3753 pci_disable_msi(dev); 3755 3754 3756 3755 dev_notice(&dev->dev, "removing fw-ohci device\n");