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__ */ | 
