Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 6037d6bb authored by Jeff Garzik's avatar Jeff Garzik
Browse files

[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.
parent c2cc87ca
Loading
Loading
Loading
Loading
+6 −5
Original line number Diff line number Diff line
@@ -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);
}

+5 −4
Original line number Diff line number Diff line
@@ -4091,15 +4091,16 @@ static void atapi_packet_task(void *_data)
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)
+23 −8
Original line number Diff line number Diff line
@@ -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);
}

+24 −9
Original line number Diff line number Diff line
@@ -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);
}

+13 −0
Original line number Diff line number Diff line
@@ -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__ */