aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorJeff Garzik <jgarzik@pobox.com>2005-11-04 22:08:00 -0500
committerJeff Garzik <jgarzik@pobox.com>2005-11-04 22:08:00 -0500
commit6037d6bbdff65eb5a84fe35e140f4da4f7cc103a (patch)
tree67b86d8559935c04a0918afd3274eef778017d57
parentc2cc87ca9561ddfe744d446789cc10f507e87db9 (diff)
[libata] ATAPI pad allocation fixes/cleanup
Use ata_pad_{alloc,free} in two drivers, to factor out common code. Add ata_pad_{alloc,free} to two other drivers, which needed the padding but had not been updated.
-rw-r--r--drivers/scsi/ahci.c11
-rw-r--r--drivers/scsi/libata-core.c9
-rw-r--r--drivers/scsi/sata_mv.c31
-rw-r--r--drivers/scsi/sata_sil24.c33
-rw-r--r--include/linux/libata.h13
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:
4091int ata_port_start (struct ata_port *ap) 4091int 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
4131void ata_host_stop (struct ata_host_set *host_set) 4132void 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
673static 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
757err_out_priv:
758 mv_priv_free(pp, dev);
759err_out_pp:
760 kfree(pp);
761err_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
638static 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
638static int sil24_port_start(struct ata_port *ap) 645static 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
676err_out_pad:
677 sil24_cblk_free(pp, dev);
678err_out_pp:
679 kfree(pp);
680err_out:
681 return rc;
666} 682}
667 683
668static void sil24_port_stop(struct ata_port *ap) 684static 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
780static 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
788static 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__ */