Commit 871af1210f13966ab911ed2166e4ab2ce775b99d

Authored by Alan Cox
Committed by Jeff Garzik
1 parent e427fe042c

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: Alan Cox <alan@redhat.com>
Signed-off-by: Jeff Garzik <jgarzik@redhat.com>

Showing 7 changed files with 66 additions and 9 deletions Side-by-side Diff

drivers/ata/ata_piix.c
... ... @@ -310,7 +310,7 @@
310 310 };
311 311  
312 312 static struct ata_port_operations piix_pata_ops = {
313   - .inherits = &ata_bmdma_port_ops,
  313 + .inherits = &ata_bmdma32_port_ops,
314 314 .cable_detect = ata_cable_40wire,
315 315 .set_piomode = piix_set_piomode,
316 316 .set_dmamode = piix_set_dmamode,
drivers/ata/libata-sff.c
... ... @@ -78,6 +78,13 @@
78 78 .bmdma_status = ata_bmdma_status,
79 79 };
80 80  
  81 +const struct ata_port_operations ata_bmdma32_port_ops = {
  82 + .inherits = &ata_bmdma_port_ops,
  83 +
  84 + .sff_data_xfer = ata_sff_data_xfer32,
  85 +};
  86 +EXPORT_SYMBOL_GPL(ata_bmdma32_port_ops);
  87 +
81 88 /**
82 89 * ata_fill_sg - Fill PCI IDE PRD table
83 90 * @qc: Metadata associated with taskfile to be transferred
... ... @@ -717,6 +724,52 @@
717 724  
718 725 return words << 1;
719 726 }
  727 +
  728 +/**
  729 + * ata_sff_data_xfer32 - Transfer data by PIO
  730 + * @dev: device to target
  731 + * @buf: data buffer
  732 + * @buflen: buffer length
  733 + * @rw: read/write
  734 + *
  735 + * Transfer data from/to the device data register by PIO using 32bit
  736 + * I/O operations.
  737 + *
  738 + * LOCKING:
  739 + * Inherited from caller.
  740 + *
  741 + * RETURNS:
  742 + * Bytes consumed.
  743 + */
  744 +
  745 +unsigned int ata_sff_data_xfer32(struct ata_device *dev, unsigned char *buf,
  746 + unsigned int buflen, int rw)
  747 +{
  748 + struct ata_port *ap = dev->link->ap;
  749 + void __iomem *data_addr = ap->ioaddr.data_addr;
  750 + unsigned int words = buflen >> 2;
  751 + int slop = buflen & 3;
  752 +
  753 + /* Transfer multiple of 4 bytes */
  754 + if (rw == READ)
  755 + ioread32_rep(data_addr, buf, words);
  756 + else
  757 + iowrite32_rep(data_addr, buf, words);
  758 +
  759 + if (unlikely(slop)) {
  760 + __le32 pad;
  761 + if (rw == READ) {
  762 + pad = cpu_to_le32(ioread32(ap->ioaddr.data_addr));
  763 + memcpy(buf + buflen - slop, &pad, slop);
  764 + } else {
  765 + memcpy(&pad, buf + buflen - slop, slop);
  766 + iowrite32(le32_to_cpu(pad), ap->ioaddr.data_addr);
  767 + }
  768 + words++;
  769 + }
  770 + return words << 2;
  771 +}
  772 +EXPORT_SYMBOL_GPL(ata_sff_data_xfer32);
720 773  
721 774 /**
722 775 * ata_sff_data_xfer_noirq - Transfer data by PIO
drivers/ata/pata_ali.c
... ... @@ -151,8 +151,7 @@
151 151  
152 152 pci_read_config_byte(pdev, pio_fifo, &fifo);
153 153 fifo &= ~(0x0F << shift);
154   - if (on)
155   - fifo |= (on << shift);
  154 + fifo |= (on << shift);
156 155 pci_write_config_byte(pdev, pio_fifo, fifo);
157 156 }
158 157  
159 158  
... ... @@ -370,10 +369,11 @@
370 369 .inherits = &ata_sff_port_ops,
371 370 .cable_detect = ata_cable_40wire,
372 371 .set_piomode = ali_set_piomode,
  372 + .sff_data_xfer = ata_sff_data_xfer32,
373 373 };
374 374  
375 375 static const struct ata_port_operations ali_dma_base_ops = {
376   - .inherits = &ata_bmdma_port_ops,
  376 + .inherits = &ata_bmdma32_port_ops,
377 377 .set_piomode = ali_set_piomode,
378 378 .set_dmamode = ali_set_dmamode,
379 379 };
drivers/ata/pata_amd.c
... ... @@ -24,7 +24,7 @@
24 24 #include <linux/libata.h>
25 25  
26 26 #define DRV_NAME "pata_amd"
27   -#define DRV_VERSION "0.3.10"
  27 +#define DRV_VERSION "0.3.11"
28 28  
29 29 /**
30 30 * timing_setup - shared timing computation and load
... ... @@ -345,7 +345,7 @@
345 345 };
346 346  
347 347 static const struct ata_port_operations amd_base_port_ops = {
348   - .inherits = &ata_bmdma_port_ops,
  348 + .inherits = &ata_bmdma32_port_ops,
349 349 .prereset = amd_pre_reset,
350 350 };
351 351  
drivers/ata/pata_mpiix.c
... ... @@ -35,7 +35,7 @@
35 35 #include <linux/libata.h>
36 36  
37 37 #define DRV_NAME "pata_mpiix"
38   -#define DRV_VERSION "0.7.6"
  38 +#define DRV_VERSION "0.7.7"
39 39  
40 40 enum {
41 41 IDETIM = 0x6C, /* IDE control register */
... ... @@ -146,6 +146,7 @@
146 146 .cable_detect = ata_cable_40wire,
147 147 .set_piomode = mpiix_set_piomode,
148 148 .prereset = mpiix_pre_reset,
  149 + .sff_data_xfer = ata_sff_data_xfer32,
149 150 };
150 151  
151 152 static int mpiix_init_one(struct pci_dev *dev, const struct pci_device_id *id)
drivers/ata/pata_sil680.c
... ... @@ -32,7 +32,7 @@
32 32 #include <linux/libata.h>
33 33  
34 34 #define DRV_NAME "pata_sil680"
35   -#define DRV_VERSION "0.4.8"
  35 +#define DRV_VERSION "0.4.9"
36 36  
37 37 #define SIL680_MMIO_BAR 5
38 38  
... ... @@ -195,7 +195,7 @@
195 195 };
196 196  
197 197 static struct ata_port_operations sil680_port_ops = {
198   - .inherits = &ata_bmdma_port_ops,
  198 + .inherits = &ata_bmdma32_port_ops,
199 199 .cable_detect = sil680_cable_detect,
200 200 .set_piomode = sil680_set_piomode,
201 201 .set_dmamode = sil680_set_dmamode,
include/linux/libata.h
... ... @@ -1518,6 +1518,7 @@
1518 1518  
1519 1519 extern const struct ata_port_operations ata_sff_port_ops;
1520 1520 extern const struct ata_port_operations ata_bmdma_port_ops;
  1521 +extern const struct ata_port_operations ata_bmdma32_port_ops;
1521 1522  
1522 1523 /* PIO only, sg_tablesize and dma_boundary limits can be removed */
1523 1524 #define ATA_PIO_SHT(drv_name) \
... ... @@ -1544,6 +1545,8 @@
1544 1545 extern void ata_sff_exec_command(struct ata_port *ap,
1545 1546 const struct ata_taskfile *tf);
1546 1547 extern unsigned int ata_sff_data_xfer(struct ata_device *dev,
  1548 + unsigned char *buf, unsigned int buflen, int rw);
  1549 +extern unsigned int ata_sff_data_xfer32(struct ata_device *dev,
1547 1550 unsigned char *buf, unsigned int buflen, int rw);
1548 1551 extern unsigned int ata_sff_data_xfer_noirq(struct ata_device *dev,
1549 1552 unsigned char *buf, unsigned int buflen, int rw);