[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.
diff --git a/drivers/scsi/ahci.c b/drivers/scsi/ahci.c
index 8420204..4612312 100644
--- a/drivers/scsi/ahci.c
+++ b/drivers/scsi/ahci.c
@@ -307,21 +307,22 @@
 	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 @@
 	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);
 }
 
diff --git a/drivers/scsi/libata-core.c b/drivers/scsi/libata-core.c
index ae2475e..e1346cd 100644
--- a/drivers/scsi/libata-core.c
+++ b/drivers/scsi/libata-core.c
@@ -4091,15 +4091,16 @@
 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 @@
 	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)
diff --git a/drivers/scsi/sata_mv.c b/drivers/scsi/sata_mv.c
index 64af334..0f469e3 100644
--- a/drivers/scsi/sata_mv.c
+++ b/drivers/scsi/sata_mv.c
@@ -670,6 +670,11 @@
 	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 @@
 	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 @@
 	 */
 	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 @@
 	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);
 }
 
diff --git a/drivers/scsi/sata_sil24.c b/drivers/scsi/sata_sil24.c
index 211ec7e..e6c8e89 100644
--- a/drivers/scsi/sata_sil24.c
+++ b/drivers/scsi/sata_sil24.c
@@ -635,6 +635,13 @@
 	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 @@
 	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);
 }
 
diff --git a/include/linux/libata.h b/include/linux/libata.h
index 6225b78..dcd17e7 100644
--- a/include/linux/libata.h
+++ b/include/linux/libata.h
@@ -777,4 +777,17 @@
 	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__ */