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

Commit 871af121 authored by Alan Cox's avatar Alan Cox Committed by Jeff Garzik
Browse files

libata: Add 32bit PIO support



This matters for some controllers and in one or two cases almost doubles
PIO performance. Add a bmdma32 operations set we can inherit and activate
it for some controllers

Signed-off-by: default avatarAlan Cox <alan@redhat.com>
Signed-off-by: default avatarJeff Garzik <jgarzik@redhat.com>
parent e427fe04
Loading
Loading
Loading
Loading
+1 −1
Original line number Diff line number Diff line
@@ -310,7 +310,7 @@ static struct scsi_host_template piix_sht = {
};

static struct ata_port_operations piix_pata_ops = {
	.inherits		= &ata_bmdma_port_ops,
	.inherits		= &ata_bmdma32_port_ops,
	.cable_detect		= ata_cable_40wire,
	.set_piomode		= piix_set_piomode,
	.set_dmamode		= piix_set_dmamode,
+53 −0
Original line number Diff line number Diff line
@@ -78,6 +78,13 @@ const struct ata_port_operations ata_bmdma_port_ops = {
	.bmdma_status		= ata_bmdma_status,
};

const struct ata_port_operations ata_bmdma32_port_ops = {
	.inherits		= &ata_bmdma_port_ops,

	.sff_data_xfer		= ata_sff_data_xfer32,
};
EXPORT_SYMBOL_GPL(ata_bmdma32_port_ops);

/**
 *	ata_fill_sg - Fill PCI IDE PRD table
 *	@qc: Metadata associated with taskfile to be transferred
@@ -718,6 +725,52 @@ unsigned int ata_sff_data_xfer(struct ata_device *dev, unsigned char *buf,
	return words << 1;
}

/**
 *	ata_sff_data_xfer32 - Transfer data by PIO
 *	@dev: device to target
 *	@buf: data buffer
 *	@buflen: buffer length
 *	@rw: read/write
 *
 *	Transfer data from/to the device data register by PIO using 32bit
 *	I/O operations.
 *
 *	LOCKING:
 *	Inherited from caller.
 *
 *	RETURNS:
 *	Bytes consumed.
 */

unsigned int ata_sff_data_xfer32(struct ata_device *dev, unsigned char *buf,
			       unsigned int buflen, int rw)
{
	struct ata_port *ap = dev->link->ap;
	void __iomem *data_addr = ap->ioaddr.data_addr;
	unsigned int words = buflen >> 2;
	int slop = buflen & 3;

	/* Transfer multiple of 4 bytes */
	if (rw == READ)
		ioread32_rep(data_addr, buf, words);
	else
		iowrite32_rep(data_addr, buf, words);

	if (unlikely(slop)) {
		__le32 pad;
		if (rw == READ) {
			pad = cpu_to_le32(ioread32(ap->ioaddr.data_addr));
			memcpy(buf + buflen - slop, &pad, slop);
		} else {
			memcpy(&pad, buf + buflen - slop, slop);
			iowrite32(le32_to_cpu(pad), ap->ioaddr.data_addr);
		}
		words++;
	}
	return words << 2;
}
EXPORT_SYMBOL_GPL(ata_sff_data_xfer32);

/**
 *	ata_sff_data_xfer_noirq - Transfer data by PIO
 *	@dev: device to target
+3 −3
Original line number Diff line number Diff line
@@ -151,7 +151,6 @@ static void ali_fifo_control(struct ata_port *ap, struct ata_device *adev, int o

	pci_read_config_byte(pdev, pio_fifo, &fifo);
	fifo &= ~(0x0F << shift);
	if (on)
	fifo |= (on << shift);
	pci_write_config_byte(pdev, pio_fifo, fifo);
}
@@ -370,10 +369,11 @@ static struct ata_port_operations ali_early_port_ops = {
	.inherits	= &ata_sff_port_ops,
	.cable_detect	= ata_cable_40wire,
	.set_piomode	= ali_set_piomode,
	.sff_data_xfer  = ata_sff_data_xfer32,
};

static const struct ata_port_operations ali_dma_base_ops = {
	.inherits	= &ata_bmdma_port_ops,
	.inherits	= &ata_bmdma32_port_ops,
	.set_piomode	= ali_set_piomode,
	.set_dmamode	= ali_set_dmamode,
};
+2 −2
Original line number Diff line number Diff line
@@ -24,7 +24,7 @@
#include <linux/libata.h>

#define DRV_NAME "pata_amd"
#define DRV_VERSION "0.3.10"
#define DRV_VERSION "0.3.11"

/**
 *	timing_setup		-	shared timing computation and load
@@ -345,7 +345,7 @@ static struct scsi_host_template amd_sht = {
};

static const struct ata_port_operations amd_base_port_ops = {
	.inherits	= &ata_bmdma_port_ops,
	.inherits	= &ata_bmdma32_port_ops,
	.prereset	= amd_pre_reset,
};

+2 −1
Original line number Diff line number Diff line
@@ -35,7 +35,7 @@
#include <linux/libata.h>

#define DRV_NAME "pata_mpiix"
#define DRV_VERSION "0.7.6"
#define DRV_VERSION "0.7.7"

enum {
	IDETIM = 0x6C,		/* IDE control register */
@@ -146,6 +146,7 @@ static struct ata_port_operations mpiix_port_ops = {
	.cable_detect	= ata_cable_40wire,
	.set_piomode	= mpiix_set_piomode,
	.prereset	= mpiix_pre_reset,
	.sff_data_xfer	= ata_sff_data_xfer32,
};

static int mpiix_init_one(struct pci_dev *dev, const struct pci_device_id *id)
Loading