diff options
-rw-r--r-- | drivers/scsi/ahci.c | 11 | ||||
-rw-r--r-- | drivers/scsi/libata-core.c | 9 | ||||
-rw-r--r-- | drivers/scsi/sata_mv.c | 31 | ||||
-rw-r--r-- | drivers/scsi/sata_sil24.c | 33 | ||||
-rw-r--r-- | include/linux/libata.h | 13 |
5 files changed, 71 insertions, 26 deletions
diff --git a/drivers/scsi/ahci.c b/drivers/scsi/ahci.c index 8420204c2eaa..4612312c0c2d 100644 --- a/drivers/scsi/ahci.c +++ b/drivers/scsi/ahci.c | |||
@@ -307,21 +307,22 @@ static int ahci_port_start(struct ata_port *ap) | |||
307 | void __iomem *port_mmio = ahci_port_base(mmio, ap->port_no); | 307 | void __iomem *port_mmio = ahci_port_base(mmio, ap->port_no); |
308 | void *mem; | 308 | void *mem; |
309 | dma_addr_t mem_dma; | 309 | dma_addr_t mem_dma; |
310 | int rc; | ||
310 | 311 | ||
311 | pp = kmalloc(sizeof(*pp), GFP_KERNEL); | 312 | pp = kmalloc(sizeof(*pp), GFP_KERNEL); |
312 | if (!pp) | 313 | if (!pp) |
313 | return -ENOMEM; | 314 | return -ENOMEM; |
314 | memset(pp, 0, sizeof(*pp)); | 315 | memset(pp, 0, sizeof(*pp)); |
315 | 316 | ||
316 | ap->pad = dma_alloc_coherent(dev, ATA_DMA_PAD_BUF_SZ, &ap->pad_dma, GFP_KERNEL); | 317 | rc = ata_pad_alloc(ap, dev); |
317 | if (!ap->pad) { | 318 | if (rc) { |
318 | kfree(pp); | 319 | kfree(pp); |
319 | return -ENOMEM; | 320 | return rc; |
320 | } | 321 | } |
321 | 322 | ||
322 | mem = dma_alloc_coherent(dev, AHCI_PORT_PRIV_DMA_SZ, &mem_dma, GFP_KERNEL); | 323 | mem = dma_alloc_coherent(dev, AHCI_PORT_PRIV_DMA_SZ, &mem_dma, GFP_KERNEL); |
323 | if (!mem) { | 324 | if (!mem) { |
324 | dma_free_coherent(dev, ATA_DMA_PAD_BUF_SZ, ap->pad, ap->pad_dma); | 325 | ata_pad_free(ap, dev); |
325 | kfree(pp); | 326 | kfree(pp); |
326 | return -ENOMEM; | 327 | return -ENOMEM; |
327 | } | 328 | } |
@@ -397,7 +398,7 @@ static void ahci_port_stop(struct ata_port *ap) | |||
397 | ap->private_data = NULL; | 398 | ap->private_data = NULL; |
398 | dma_free_coherent(dev, AHCI_PORT_PRIV_DMA_SZ, | 399 | dma_free_coherent(dev, AHCI_PORT_PRIV_DMA_SZ, |
399 | pp->cmd_slot, pp->cmd_slot_dma); | 400 | pp->cmd_slot, pp->cmd_slot_dma); |
400 | dma_free_coherent(dev, ATA_DMA_PAD_BUF_SZ, ap->pad, ap->pad_dma); | 401 | ata_pad_free(ap, dev); |
401 | kfree(pp); | 402 | kfree(pp); |
402 | } | 403 | } |
403 | 404 | ||
diff --git a/drivers/scsi/libata-core.c b/drivers/scsi/libata-core.c index ae2475e4291c..e1346cddd37f 100644 --- a/drivers/scsi/libata-core.c +++ b/drivers/scsi/libata-core.c | |||
@@ -4091,15 +4091,16 @@ err_out: | |||
4091 | int ata_port_start (struct ata_port *ap) | 4091 | int ata_port_start (struct ata_port *ap) |
4092 | { | 4092 | { |
4093 | struct device *dev = ap->host_set->dev; | 4093 | struct device *dev = ap->host_set->dev; |
4094 | int rc; | ||
4094 | 4095 | ||
4095 | ap->prd = dma_alloc_coherent(dev, ATA_PRD_TBL_SZ, &ap->prd_dma, GFP_KERNEL); | 4096 | ap->prd = dma_alloc_coherent(dev, ATA_PRD_TBL_SZ, &ap->prd_dma, GFP_KERNEL); |
4096 | if (!ap->prd) | 4097 | if (!ap->prd) |
4097 | return -ENOMEM; | 4098 | return -ENOMEM; |
4098 | 4099 | ||
4099 | ap->pad = dma_alloc_coherent(dev, ATA_DMA_PAD_BUF_SZ, &ap->pad_dma, GFP_KERNEL); | 4100 | rc = ata_pad_alloc(ap, dev); |
4100 | if (!ap->pad) { | 4101 | if (rc) { |
4101 | dma_free_coherent(dev, ATA_PRD_TBL_SZ, ap->prd, ap->prd_dma); | 4102 | dma_free_coherent(dev, ATA_PRD_TBL_SZ, ap->prd, ap->prd_dma); |
4102 | return -ENOMEM; | 4103 | return rc; |
4103 | } | 4104 | } |
4104 | 4105 | ||
4105 | DPRINTK("prd alloc, virt %p, dma %llx\n", ap->prd, (unsigned long long) ap->prd_dma); | 4106 | DPRINTK("prd alloc, virt %p, dma %llx\n", ap->prd, (unsigned long long) ap->prd_dma); |
@@ -4125,7 +4126,7 @@ void ata_port_stop (struct ata_port *ap) | |||
4125 | struct device *dev = ap->host_set->dev; | 4126 | struct device *dev = ap->host_set->dev; |
4126 | 4127 | ||
4127 | dma_free_coherent(dev, ATA_PRD_TBL_SZ, ap->prd, ap->prd_dma); | 4128 | dma_free_coherent(dev, ATA_PRD_TBL_SZ, ap->prd, ap->prd_dma); |
4128 | dma_free_coherent(dev, ATA_DMA_PAD_BUF_SZ, ap->pad, ap->pad_dma); | 4129 | ata_pad_free(ap, dev); |
4129 | } | 4130 | } |
4130 | 4131 | ||
4131 | void ata_host_stop (struct ata_host_set *host_set) | 4132 | void ata_host_stop (struct ata_host_set *host_set) |
diff --git a/drivers/scsi/sata_mv.c b/drivers/scsi/sata_mv.c index 64af334e71f4..0f469e3dabe2 100644 --- a/drivers/scsi/sata_mv.c +++ b/drivers/scsi/sata_mv.c | |||
@@ -670,6 +670,11 @@ static void mv_host_stop(struct ata_host_set *host_set) | |||
670 | ata_host_stop(host_set); | 670 | ata_host_stop(host_set); |
671 | } | 671 | } |
672 | 672 | ||
673 | static inline void mv_priv_free(struct mv_port_priv *pp, struct device *dev) | ||
674 | { | ||
675 | dma_free_coherent(dev, MV_PORT_PRIV_DMA_SZ, pp->crpb, pp->crpb_dma); | ||
676 | } | ||
677 | |||
673 | /** | 678 | /** |
674 | * mv_port_start - Port specific init/start routine. | 679 | * mv_port_start - Port specific init/start routine. |
675 | * @ap: ATA channel to manipulate | 680 | * @ap: ATA channel to manipulate |
@@ -687,21 +692,23 @@ static int mv_port_start(struct ata_port *ap) | |||
687 | void __iomem *port_mmio = mv_ap_base(ap); | 692 | void __iomem *port_mmio = mv_ap_base(ap); |
688 | void *mem; | 693 | void *mem; |
689 | dma_addr_t mem_dma; | 694 | dma_addr_t mem_dma; |
695 | int rc = -ENOMEM; | ||
690 | 696 | ||
691 | pp = kmalloc(sizeof(*pp), GFP_KERNEL); | 697 | pp = kmalloc(sizeof(*pp), GFP_KERNEL); |
692 | if (!pp) { | 698 | if (!pp) |
693 | return -ENOMEM; | 699 | goto err_out; |
694 | } | ||
695 | memset(pp, 0, sizeof(*pp)); | 700 | memset(pp, 0, sizeof(*pp)); |
696 | 701 | ||
697 | mem = dma_alloc_coherent(dev, MV_PORT_PRIV_DMA_SZ, &mem_dma, | 702 | mem = dma_alloc_coherent(dev, MV_PORT_PRIV_DMA_SZ, &mem_dma, |
698 | GFP_KERNEL); | 703 | GFP_KERNEL); |
699 | if (!mem) { | 704 | if (!mem) |
700 | kfree(pp); | 705 | goto err_out_pp; |
701 | return -ENOMEM; | ||
702 | } | ||
703 | memset(mem, 0, MV_PORT_PRIV_DMA_SZ); | 706 | memset(mem, 0, MV_PORT_PRIV_DMA_SZ); |
704 | 707 | ||
708 | rc = ata_pad_alloc(ap, dev); | ||
709 | if (rc) | ||
710 | goto err_out_priv; | ||
711 | |||
705 | /* First item in chunk of DMA memory: | 712 | /* First item in chunk of DMA memory: |
706 | * 32-slot command request table (CRQB), 32 bytes each in size | 713 | * 32-slot command request table (CRQB), 32 bytes each in size |
707 | */ | 714 | */ |
@@ -746,6 +753,13 @@ static int mv_port_start(struct ata_port *ap) | |||
746 | */ | 753 | */ |
747 | ap->private_data = pp; | 754 | ap->private_data = pp; |
748 | return 0; | 755 | return 0; |
756 | |||
757 | err_out_priv: | ||
758 | mv_priv_free(pp, dev); | ||
759 | err_out_pp: | ||
760 | kfree(pp); | ||
761 | err_out: | ||
762 | return rc; | ||
749 | } | 763 | } |
750 | 764 | ||
751 | /** | 765 | /** |
@@ -768,7 +782,8 @@ static void mv_port_stop(struct ata_port *ap) | |||
768 | spin_unlock_irqrestore(&ap->host_set->lock, flags); | 782 | spin_unlock_irqrestore(&ap->host_set->lock, flags); |
769 | 783 | ||
770 | ap->private_data = NULL; | 784 | ap->private_data = NULL; |
771 | dma_free_coherent(dev, MV_PORT_PRIV_DMA_SZ, pp->crpb, pp->crpb_dma); | 785 | ata_pad_free(ap, dev); |
786 | mv_priv_free(pp, dev); | ||
772 | kfree(pp); | 787 | kfree(pp); |
773 | } | 788 | } |
774 | 789 | ||
diff --git a/drivers/scsi/sata_sil24.c b/drivers/scsi/sata_sil24.c index 211ec7eebc9c..e6c8e89c226f 100644 --- a/drivers/scsi/sata_sil24.c +++ b/drivers/scsi/sata_sil24.c | |||
@@ -635,6 +635,13 @@ static irqreturn_t sil24_interrupt(int irq, void *dev_instance, struct pt_regs * | |||
635 | return IRQ_RETVAL(handled); | 635 | return IRQ_RETVAL(handled); |
636 | } | 636 | } |
637 | 637 | ||
638 | static inline void sil24_cblk_free(struct sil24_port_priv *pp, struct device *dev) | ||
639 | { | ||
640 | const size_t cb_size = sizeof(*pp->cmd_block); | ||
641 | |||
642 | dma_free_coherent(dev, cb_size, pp->cmd_block, pp->cmd_block_dma); | ||
643 | } | ||
644 | |||
638 | static int sil24_port_start(struct ata_port *ap) | 645 | static int sil24_port_start(struct ata_port *ap) |
639 | { | 646 | { |
640 | struct device *dev = ap->host_set->dev; | 647 | struct device *dev = ap->host_set->dev; |
@@ -642,36 +649,44 @@ static int sil24_port_start(struct ata_port *ap) | |||
642 | struct sil24_cmd_block *cb; | 649 | struct sil24_cmd_block *cb; |
643 | size_t cb_size = sizeof(*cb); | 650 | size_t cb_size = sizeof(*cb); |
644 | dma_addr_t cb_dma; | 651 | dma_addr_t cb_dma; |
652 | int rc = -ENOMEM; | ||
645 | 653 | ||
646 | pp = kmalloc(sizeof(*pp), GFP_KERNEL); | 654 | pp = kzalloc(sizeof(*pp), GFP_KERNEL); |
647 | if (!pp) | 655 | if (!pp) |
648 | return -ENOMEM; | 656 | goto err_out; |
649 | memset(pp, 0, sizeof(*pp)); | ||
650 | 657 | ||
651 | pp->tf.command = ATA_DRDY; | 658 | pp->tf.command = ATA_DRDY; |
652 | 659 | ||
653 | cb = dma_alloc_coherent(dev, cb_size, &cb_dma, GFP_KERNEL); | 660 | cb = dma_alloc_coherent(dev, cb_size, &cb_dma, GFP_KERNEL); |
654 | if (!cb) { | 661 | if (!cb) |
655 | kfree(pp); | 662 | goto err_out_pp; |
656 | return -ENOMEM; | ||
657 | } | ||
658 | memset(cb, 0, cb_size); | 663 | memset(cb, 0, cb_size); |
659 | 664 | ||
665 | rc = ata_pad_alloc(ap, dev); | ||
666 | if (rc) | ||
667 | goto err_out_pad; | ||
668 | |||
660 | pp->cmd_block = cb; | 669 | pp->cmd_block = cb; |
661 | pp->cmd_block_dma = cb_dma; | 670 | pp->cmd_block_dma = cb_dma; |
662 | 671 | ||
663 | ap->private_data = pp; | 672 | ap->private_data = pp; |
664 | 673 | ||
665 | return 0; | 674 | return 0; |
675 | |||
676 | err_out_pad: | ||
677 | sil24_cblk_free(pp, dev); | ||
678 | err_out_pp: | ||
679 | kfree(pp); | ||
680 | err_out: | ||
681 | return rc; | ||
666 | } | 682 | } |
667 | 683 | ||
668 | static void sil24_port_stop(struct ata_port *ap) | 684 | static void sil24_port_stop(struct ata_port *ap) |
669 | { | 685 | { |
670 | struct device *dev = ap->host_set->dev; | 686 | struct device *dev = ap->host_set->dev; |
671 | struct sil24_port_priv *pp = ap->private_data; | 687 | struct sil24_port_priv *pp = ap->private_data; |
672 | size_t cb_size = sizeof(*pp->cmd_block); | ||
673 | 688 | ||
674 | dma_free_coherent(dev, cb_size, pp->cmd_block, pp->cmd_block_dma); | 689 | sil24_cblk_free(pp, dev); |
675 | kfree(pp); | 690 | kfree(pp); |
676 | } | 691 | } |
677 | 692 | ||
diff --git a/include/linux/libata.h b/include/linux/libata.h index 6225b78fa65b..dcd17e7458ab 100644 --- a/include/linux/libata.h +++ b/include/linux/libata.h | |||
@@ -777,4 +777,17 @@ static inline unsigned int __ac_err_mask(u8 status) | |||
777 | return mask; | 777 | return mask; |
778 | } | 778 | } |
779 | 779 | ||
780 | static inline int ata_pad_alloc(struct ata_port *ap, struct device *dev) | ||
781 | { | ||
782 | ap->pad_dma = 0; | ||
783 | ap->pad = dma_alloc_coherent(dev, ATA_DMA_PAD_BUF_SZ, | ||
784 | &ap->pad_dma, GFP_KERNEL); | ||
785 | return (ap->pad == NULL) ? -ENOMEM : 0; | ||
786 | } | ||
787 | |||
788 | static inline void ata_pad_free(struct ata_port *ap, struct device *dev) | ||
789 | { | ||
790 | dma_free_coherent(dev, ATA_DMA_PAD_BUF_SZ, ap->pad, ap->pad_dma); | ||
791 | } | ||
792 | |||
780 | #endif /* __LINUX_LIBATA_H__ */ | 793 | #endif /* __LINUX_LIBATA_H__ */ |