[libata] ATAPI pad allocation fixes/cleanup
authorJeff Garzik <jgarzik@pobox.com>
Sat, 5 Nov 2005 03:08:00 +0000 (22:08 -0500)
committerJeff Garzik <jgarzik@pobox.com>
Sat, 5 Nov 2005 03:08:00 +0000 (22:08 -0500)
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.

drivers/scsi/ahci.c
drivers/scsi/libata-core.c
drivers/scsi/sata_mv.c
drivers/scsi/sata_sil24.c
include/linux/libata.h

index 8420204c2eaa50b7e999f657a1d6dadd59165e34..4612312c0c2d9832d4ab0967df3481f8d404afdd 100644 (file)
@@ -307,21 +307,22 @@ static int ahci_port_start(struct ata_port *ap)
        void __iomem *port_mmio = ahci_port_base(mmio, ap->port_no);
        void *mem;
        dma_addr_t mem_dma;
+       int rc;
 
        pp = kmalloc(sizeof(*pp), GFP_KERNEL);
        if (!pp)
                return -ENOMEM;
        memset(pp, 0, sizeof(*pp));
 
-       ap->pad = dma_alloc_coherent(dev, ATA_DMA_PAD_BUF_SZ, &ap->pad_dma, GFP_KERNEL);
-       if (!ap->pad) {
+       rc = ata_pad_alloc(ap, dev);
+       if (rc) {
                kfree(pp);
-               return -ENOMEM;
+               return rc;
        }
 
        mem = dma_alloc_coherent(dev, AHCI_PORT_PRIV_DMA_SZ, &mem_dma, GFP_KERNEL);
        if (!mem) {
-               dma_free_coherent(dev, ATA_DMA_PAD_BUF_SZ, ap->pad, ap->pad_dma);
+               ata_pad_free(ap, dev);
                kfree(pp);
                return -ENOMEM;
        }
@@ -397,7 +398,7 @@ static void ahci_port_stop(struct ata_port *ap)
        ap->private_data = NULL;
        dma_free_coherent(dev, AHCI_PORT_PRIV_DMA_SZ,
                          pp->cmd_slot, pp->cmd_slot_dma);
-       dma_free_coherent(dev, ATA_DMA_PAD_BUF_SZ, ap->pad, ap->pad_dma);
+       ata_pad_free(ap, dev);
        kfree(pp);
 }
 
index ae2475e4291cb5ce69a1ea889b9586f4c446bc73..e1346cddd37fa140335bd3c59c70680ab8b71146 100644 (file)
@@ -4091,15 +4091,16 @@ err_out:
 int ata_port_start (struct ata_port *ap)
 {
        struct device *dev = ap->host_set->dev;
+       int rc;
 
        ap->prd = dma_alloc_coherent(dev, ATA_PRD_TBL_SZ, &ap->prd_dma, GFP_KERNEL);
        if (!ap->prd)
                return -ENOMEM;
 
-       ap->pad = dma_alloc_coherent(dev, ATA_DMA_PAD_BUF_SZ, &ap->pad_dma, GFP_KERNEL);
-       if (!ap->pad) {
+       rc = ata_pad_alloc(ap, dev);
+       if (rc) {
                dma_free_coherent(dev, ATA_PRD_TBL_SZ, ap->prd, ap->prd_dma);
-               return -ENOMEM;
+               return rc;
        }
 
        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)
        struct device *dev = ap->host_set->dev;
 
        dma_free_coherent(dev, ATA_PRD_TBL_SZ, ap->prd, ap->prd_dma);
-       dma_free_coherent(dev, ATA_DMA_PAD_BUF_SZ, ap->pad, ap->pad_dma);
+       ata_pad_free(ap, dev);
 }
 
 void ata_host_stop (struct ata_host_set *host_set)
index 64af334e71f49daaad0622a384fc20e11e6015ef..0f469e3dabe2e5e8fd0d21ced1f9b7e743c396b4 100644 (file)
@@ -670,6 +670,11 @@ static void mv_host_stop(struct ata_host_set *host_set)
        ata_host_stop(host_set);
 }
 
+static inline void mv_priv_free(struct mv_port_priv *pp, struct device *dev)
+{
+       dma_free_coherent(dev, MV_PORT_PRIV_DMA_SZ, pp->crpb, pp->crpb_dma);
+}
+
 /**
  *      mv_port_start - Port specific init/start routine.
  *      @ap: ATA channel to manipulate
@@ -687,21 +692,23 @@ static int mv_port_start(struct ata_port *ap)
        void __iomem *port_mmio = mv_ap_base(ap);
        void *mem;
        dma_addr_t mem_dma;
+       int rc = -ENOMEM;
 
        pp = kmalloc(sizeof(*pp), GFP_KERNEL);
-       if (!pp) {
-               return -ENOMEM;
-       }
+       if (!pp)
+               goto err_out;
        memset(pp, 0, sizeof(*pp));
 
        mem = dma_alloc_coherent(dev, MV_PORT_PRIV_DMA_SZ, &mem_dma, 
                                 GFP_KERNEL);
-       if (!mem) {
-               kfree(pp);
-               return -ENOMEM;
-       }
+       if (!mem)
+               goto err_out_pp;
        memset(mem, 0, MV_PORT_PRIV_DMA_SZ);
 
+       rc = ata_pad_alloc(ap, dev);
+       if (rc)
+               goto err_out_priv;
+
        /* First item in chunk of DMA memory: 
         * 32-slot command request table (CRQB), 32 bytes each in size
         */
@@ -746,6 +753,13 @@ static int mv_port_start(struct ata_port *ap)
         */
        ap->private_data = pp;
        return 0;
+
+err_out_priv:
+       mv_priv_free(pp, dev);
+err_out_pp:
+       kfree(pp);
+err_out:
+       return rc;
 }
 
 /**
@@ -768,7 +782,8 @@ static void mv_port_stop(struct ata_port *ap)
        spin_unlock_irqrestore(&ap->host_set->lock, flags);
 
        ap->private_data = NULL;
-       dma_free_coherent(dev, MV_PORT_PRIV_DMA_SZ, pp->crpb, pp->crpb_dma);
+       ata_pad_free(ap, dev);
+       mv_priv_free(pp, dev);
        kfree(pp);
 }
 
index 211ec7eebc9c864ef2b0470cbd8d48d08b07d548..e6c8e89c226f5a4d24ef3d85873af02d38e35d42 100644 (file)
@@ -635,6 +635,13 @@ static irqreturn_t sil24_interrupt(int irq, void *dev_instance, struct pt_regs *
        return IRQ_RETVAL(handled);
 }
 
+static inline void sil24_cblk_free(struct sil24_port_priv *pp, struct device *dev)
+{
+       const size_t cb_size = sizeof(*pp->cmd_block);
+
+       dma_free_coherent(dev, cb_size, pp->cmd_block, pp->cmd_block_dma);
+}
+
 static int sil24_port_start(struct ata_port *ap)
 {
        struct device *dev = ap->host_set->dev;
@@ -642,36 +649,44 @@ static int sil24_port_start(struct ata_port *ap)
        struct sil24_cmd_block *cb;
        size_t cb_size = sizeof(*cb);
        dma_addr_t cb_dma;
+       int rc = -ENOMEM;
 
-       pp = kmalloc(sizeof(*pp), GFP_KERNEL);
+       pp = kzalloc(sizeof(*pp), GFP_KERNEL);
        if (!pp)
-               return -ENOMEM;
-       memset(pp, 0, sizeof(*pp));
+               goto err_out;
 
        pp->tf.command = ATA_DRDY;
 
        cb = dma_alloc_coherent(dev, cb_size, &cb_dma, GFP_KERNEL);
-       if (!cb) {
-               kfree(pp);
-               return -ENOMEM;
-       }
+       if (!cb)
+               goto err_out_pp;
        memset(cb, 0, cb_size);
 
+       rc = ata_pad_alloc(ap, dev);
+       if (rc)
+               goto err_out_pad;
+
        pp->cmd_block = cb;
        pp->cmd_block_dma = cb_dma;
 
        ap->private_data = pp;
 
        return 0;
+
+err_out_pad:
+       sil24_cblk_free(pp, dev);
+err_out_pp:
+       kfree(pp);
+err_out:
+       return rc;
 }
 
 static void sil24_port_stop(struct ata_port *ap)
 {
        struct device *dev = ap->host_set->dev;
        struct sil24_port_priv *pp = ap->private_data;
-       size_t cb_size = sizeof(*pp->cmd_block);
 
-       dma_free_coherent(dev, cb_size, pp->cmd_block, pp->cmd_block_dma);
+       sil24_cblk_free(pp, dev);
        kfree(pp);
 }
 
index 6225b78fa65b30dffdc76d674a014ce0595441df..dcd17e7458ab602684db8cc965006267969e028f 100644 (file)
@@ -777,4 +777,17 @@ static inline unsigned int __ac_err_mask(u8 status)
        return mask;
 }
 
+static inline int ata_pad_alloc(struct ata_port *ap, struct device *dev)
+{
+       ap->pad_dma = 0;
+       ap->pad = dma_alloc_coherent(dev, ATA_DMA_PAD_BUF_SZ,
+                                    &ap->pad_dma, GFP_KERNEL);
+       return (ap->pad == NULL) ? -ENOMEM : 0;
+}
+
+static inline void ata_pad_free(struct ata_port *ap, struct device *dev)
+{
+       dma_free_coherent(dev, ATA_DMA_PAD_BUF_SZ, ap->pad, ap->pad_dma);
+}
+
 #endif /* __LINUX_LIBATA_H__ */