[PATCH 31/68] pata_ali: move code to be re-used by ide2libata to pata_ali.h

From: Bartlomiej Zolnierkiewicz
Date: Fri Jan 29 2010 - 11:17:09 EST


From: Bartlomiej Zolnierkiewicz <bzolnier@xxxxxxxxx>
Subject: [PATCH] pata_ali: move code to be re-used by ide2libata to pata_ali.h

Signed-off-by: Bartlomiej Zolnierkiewicz <bzolnier@xxxxxxxxx>
---
drivers/ata/pata_ali.c | 240 ------------------------------------------------
drivers/ata/pata_ali.h | 241 +++++++++++++++++++++++++++++++++++++++++++++++++
2 files changed, 241 insertions(+), 240 deletions(-)

Index: b/drivers/ata/pata_ali.c
===================================================================
--- a/drivers/ata/pata_ali.c
+++ b/drivers/ata/pata_ali.c
@@ -45,33 +45,6 @@ static struct pci_dev *ali_isa_bridge;
#include "pata_ali.h"

/**
- * ali_c2_cable_detect - cable detection
- * @ap: ATA port
- *
- * Perform cable detection for C2 and later revisions
- */
-
-static int ali_c2_cable_detect(struct ata_port *ap)
-{
- struct pci_dev *pdev = to_pci_dev(ap->host->dev);
- u8 ata66;
-
- /* Certain laptops use short but suitable cables and don't
- implement the detect logic */
-
- if (ali_cable_override(pdev))
- return ATA_CBL_PATA40_SHORT;
-
- /* Host view cable detect 0x4A bit 0 primary bit 1 secondary
- Bit set for 40 pin */
- pci_read_config_byte(pdev, 0x4A, &ata66);
- if (ata66 & (1 << ap->port_no))
- return ATA_CBL_PATA40;
- else
- return ATA_CBL_PATA80;
-}
-
-/**
* ali_20_filter - filter for earlier ALI DMA
* @ap: ALi ATA port
* @adev: attached device
@@ -93,156 +66,6 @@ static unsigned long ali_20_filter(struc
}

/**
- * ali_fifo_control - FIFO manager
- * @ap: ALi channel to control
- * @adev: device for FIFO control
- * @on: 0 for off 1 for on
- *
- * Enable or disable the FIFO on a given device. Because of the way the
- * ALi FIFO works it provides a boost on ATA disk but can be confused by
- * ATAPI and we must therefore manage it.
- */
-
-static void ali_fifo_control(struct ata_port *ap, struct ata_device *adev, int on)
-{
- struct pci_dev *pdev = to_pci_dev(ap->host->dev);
- int pio_fifo = 0x54 + ap->port_no;
- u8 fifo;
- int shift = 4 * adev->devno;
-
- /* ATA - FIFO on set nibble to 0x05, ATAPI - FIFO off, set nibble to
- 0x00. Not all the docs agree but the behaviour we now use is the
- one stated in the BIOS Programming Guide */
-
- pci_read_config_byte(pdev, pio_fifo, &fifo);
- fifo &= ~(0x0F << shift);
- fifo |= (on << shift);
- pci_write_config_byte(pdev, pio_fifo, fifo);
-}
-
-/**
- * ali_program_modes - load mode registers
- * @ap: ALi channel to load
- * @adev: Device the timing is for
- * @t: timing data
- * @ultra: UDMA timing or zero for off
- *
- * Loads the timing registers for cmd/data and disable UDMA if
- * ultra is zero. If ultra is set then load and enable the UDMA
- * timing but do not touch the command/data timing.
- */
-
-static void ali_program_modes(struct ata_port *ap, struct ata_device *adev, struct ata_timing *t, u8 ultra)
-{
- struct pci_dev *pdev = to_pci_dev(ap->host->dev);
- int cas = 0x58 + 4 * ap->port_no; /* Command timing */
- int cbt = 0x59 + 4 * ap->port_no; /* Command timing */
- int drwt = 0x5A + 4 * ap->port_no + adev->devno; /* R/W timing */
- int udmat = 0x56 + ap->port_no; /* UDMA timing */
- int shift = 4 * adev->devno;
- u8 udma;
-
- if (t != NULL) {
- t->setup = clamp_val(t->setup, 1, 8) & 7;
- t->act8b = clamp_val(t->act8b, 1, 8) & 7;
- t->rec8b = clamp_val(t->rec8b, 1, 16) & 15;
- t->active = clamp_val(t->active, 1, 8) & 7;
- t->recover = clamp_val(t->recover, 1, 16) & 15;
-
- pci_write_config_byte(pdev, cas, t->setup);
- pci_write_config_byte(pdev, cbt, (t->act8b << 4) | t->rec8b);
- pci_write_config_byte(pdev, drwt, (t->active << 4) | t->recover);
- }
-
- /* Set up the UDMA enable */
- pci_read_config_byte(pdev, udmat, &udma);
- udma &= ~(0x0F << shift);
- udma |= ultra << shift;
- pci_write_config_byte(pdev, udmat, udma);
-}
-
-/**
- * ali_set_piomode - set initial PIO mode data
- * @ap: ATA interface
- * @adev: ATA device
- *
- * Program the ALi registers for PIO mode.
- */
-
-static void ali_set_piomode(struct ata_port *ap, struct ata_device *adev)
-{
- struct ata_device *pair = ata_dev_pair(adev);
- struct ata_timing t;
- unsigned long T = 1000000000 / 33333; /* PCI clock based */
-
- ata_timing_compute(adev->id, adev->pio_mode, adev->pio_mode, &t, T, 1);
- if (pair) {
- struct ata_timing p;
-
- ata_timing_compute(pair->id, pair->pio_mode, pair->pio_mode,
- &p, T, 1);
- ata_timing_merge(&p, &t, &t, ATA_TIMING_SETUP|ATA_TIMING_8BIT);
- if (pair->dma_mode) {
- ata_timing_compute(pair->id, pair->dma_mode,
- pair->pio_mode, &p, T, 1);
- ata_timing_merge(&p, &t, &t, ATA_TIMING_SETUP|ATA_TIMING_8BIT);
- }
- }
-
- /* PIO FIFO is only permitted on ATA disk */
- ali_fifo_control(ap, adev, (adev->class == ATA_DEV_ATA) ? 0x05 : 0x00);
-
- ali_program_modes(ap, adev, &t, 0);
-}
-
-/**
- * ali_set_dmamode - set initial DMA mode data
- * @ap: ATA interface
- * @adev: ATA device
- *
- * Program the ALi registers for DMA mode.
- */
-
-static void ali_set_dmamode(struct ata_port *ap, struct ata_device *adev)
-{
- static u8 udma_timing[7] = { 0xC, 0xB, 0xA, 0x9, 0x8, 0xF, 0xD };
- struct ata_device *pair = ata_dev_pair(adev);
- struct ata_timing t;
- unsigned long T = 1000000000 / 33333; /* PCI clock based */
- struct pci_dev *pdev = to_pci_dev(ap->host->dev);
-
-
- if (adev->class == ATA_DEV_ATA)
- ali_fifo_control(ap, adev, 0x08);
-
- if (adev->dma_mode >= XFER_UDMA_0) {
- ali_program_modes(ap, adev, NULL, udma_timing[adev->dma_mode - XFER_UDMA_0]);
- if (adev->dma_mode >= XFER_UDMA_3) {
- u8 reg4b;
- pci_read_config_byte(pdev, 0x4B, &reg4b);
- reg4b |= 1;
- pci_write_config_byte(pdev, 0x4B, reg4b);
- }
- } else {
- ata_timing_compute(adev->id, adev->dma_mode, adev->pio_mode,
- &t, T, 1);
- if (pair) {
- struct ata_timing p;
-
- ata_timing_compute(pair->id, pair->pio_mode,
- pair->pio_mode, &p, T, 1);
- ata_timing_merge(&p, &t, &t, ATA_TIMING_SETUP|ATA_TIMING_8BIT);
- if (pair->dma_mode) {
- ata_timing_compute(pair->id, pair->dma_mode,
- pair->pio_mode, &p, T, 1);
- ata_timing_merge(&p, &t, &t, ATA_TIMING_SETUP|ATA_TIMING_8BIT);
- }
- }
- ali_program_modes(ap, adev, &t, 0);
- }
-}
-
-/**
* ali_warn_atapi_dma - Warn about ATAPI DMA disablement
* @adev: Device
*
@@ -388,69 +211,6 @@ static struct ata_port_operations ali_c5
.cable_detect = ali_c2_cable_detect,
};

-
-/**
- * ali_init_chipset - chip setup function
- * @dev: device of ATA controller
- *
- * Perform the setup on the device that must be done both at boot
- * and at resume time.
- */
-
-static int ali_init_chipset(struct device *dev)
-{
- struct pci_dev *pdev = to_pci_dev(dev);
- u8 tmp;
- struct pci_dev *north;
-
- /*
- * The chipset revision selects the driver operations and
- * mode data.
- */
-
- if (pdev->revision <= 0x20) {
- pci_read_config_byte(pdev, 0x53, &tmp);
- tmp |= 0x03;
- pci_write_config_byte(pdev, 0x53, tmp);
- } else {
- pci_read_config_byte(pdev, 0x4a, &tmp);
- pci_write_config_byte(pdev, 0x4a, tmp | 0x20);
- pci_read_config_byte(pdev, 0x4B, &tmp);
- if (pdev->revision < 0xC2)
- /* 1543-E/F, 1543C-C, 1543C-D, 1543C-E */
- /* Clear CD-ROM DMA write bit */
- tmp &= 0x7F;
- /* Cable and UDMA */
- if (pdev->revision >= 0xc2)
- tmp |= 0x01;
- pci_write_config_byte(pdev, 0x4B, tmp | 0x08);
- /*
- * CD_ROM DMA on (0x53 bit 0). Enable this even if we want
- * to use PIO. 0x53 bit 1 (rev 20 only) - enable FIFO control
- * via 0x54/55.
- */
- pci_read_config_byte(pdev, 0x53, &tmp);
- if (pdev->revision >= 0xc7)
- tmp |= 0x03;
- else
- tmp |= 0x01; /* CD_ROM enable for DMA */
- pci_write_config_byte(pdev, 0x53, tmp);
- }
- north = pci_get_bus_and_slot(0, PCI_DEVFN(0,0));
- if (north && north->vendor == PCI_VENDOR_ID_AL && ali_isa_bridge) {
- /* Configure the ALi bridge logic. For non ALi rely on BIOS.
- Set the south bridge enable bit */
- pci_read_config_byte(ali_isa_bridge, 0x79, &tmp);
- if (pdev->revision == 0xC2)
- pci_write_config_byte(ali_isa_bridge, 0x79, tmp | 0x04);
- else if (pdev->revision > 0xC2 && pdev->revision < 0xC5)
- pci_write_config_byte(ali_isa_bridge, 0x79, tmp | 0x02);
- }
- pci_dev_put(north);
- ata_pci_bmdma_clear_simplex(pdev);
- return 0;
-}
-
/**
* ali_init_one - discovery callback
* @pdev: PCI device ID
Index: b/drivers/ata/pata_ali.h
===================================================================
--- a/drivers/ata/pata_ali.h
+++ b/drivers/ata/pata_ali.h
@@ -38,3 +38,244 @@ static int ali_cable_override(struct pci
return 1;
return 0;
}
+
+#ifdef __LINUX_LIBATA_H__
+/**
+ * ali_c2_cable_detect - cable detection
+ * @ap: ATA port
+ *
+ * Perform cable detection for C2 and later revisions
+ */
+
+static int ali_c2_cable_detect(struct ata_port *ap)
+{
+ struct pci_dev *pdev = to_pci_dev(ap->host->dev);
+ u8 ata66;
+
+ /* Certain laptops use short but suitable cables and don't
+ implement the detect logic */
+
+ if (ali_cable_override(pdev))
+ return ATA_CBL_PATA40_SHORT;
+
+ /* Host view cable detect 0x4A bit 0 primary bit 1 secondary
+ Bit set for 40 pin */
+ pci_read_config_byte(pdev, 0x4A, &ata66);
+ if (ata66 & (1 << ap->port_no))
+ return ATA_CBL_PATA40;
+ else
+ return ATA_CBL_PATA80;
+}
+
+/**
+ * ali_fifo_control - FIFO manager
+ * @ap: ALi channel to control
+ * @adev: device for FIFO control
+ * @on: 0 for off 1 for on
+ *
+ * Enable or disable the FIFO on a given device. Because of the way the
+ * ALi FIFO works it provides a boost on ATA disk but can be confused by
+ * ATAPI and we must therefore manage it.
+ */
+
+static void ali_fifo_control(struct ata_port *ap, struct ata_device *adev, int on)
+{
+ struct pci_dev *pdev = to_pci_dev(ap->host->dev);
+ int pio_fifo = 0x54 + ap->port_no;
+ u8 fifo;
+ int shift = 4 * adev->devno;
+
+ /* ATA - FIFO on set nibble to 0x05, ATAPI - FIFO off, set nibble to
+ 0x00. Not all the docs agree but the behaviour we now use is the
+ one stated in the BIOS Programming Guide */
+
+ pci_read_config_byte(pdev, pio_fifo, &fifo);
+ fifo &= ~(0x0F << shift);
+ fifo |= (on << shift);
+ pci_write_config_byte(pdev, pio_fifo, fifo);
+}
+
+/**
+ * ali_program_modes - load mode registers
+ * @ap: ALi channel to load
+ * @adev: Device the timing is for
+ * @t: timing data
+ * @ultra: UDMA timing or zero for off
+ *
+ * Loads the timing registers for cmd/data and disable UDMA if
+ * ultra is zero. If ultra is set then load and enable the UDMA
+ * timing but do not touch the command/data timing.
+ */
+
+static void ali_program_modes(struct ata_port *ap, struct ata_device *adev, struct ata_timing *t, u8 ultra)
+{
+ struct pci_dev *pdev = to_pci_dev(ap->host->dev);
+ int cas = 0x58 + 4 * ap->port_no; /* Command timing */
+ int cbt = 0x59 + 4 * ap->port_no; /* Command timing */
+ int drwt = 0x5A + 4 * ap->port_no + adev->devno; /* R/W timing */
+ int udmat = 0x56 + ap->port_no; /* UDMA timing */
+ int shift = 4 * adev->devno;
+ u8 udma;
+
+ if (t != NULL) {
+ t->setup = clamp_val(t->setup, 1, 8) & 7;
+ t->act8b = clamp_val(t->act8b, 1, 8) & 7;
+ t->rec8b = clamp_val(t->rec8b, 1, 16) & 15;
+ t->active = clamp_val(t->active, 1, 8) & 7;
+ t->recover = clamp_val(t->recover, 1, 16) & 15;
+
+ pci_write_config_byte(pdev, cas, t->setup);
+ pci_write_config_byte(pdev, cbt, (t->act8b << 4) | t->rec8b);
+ pci_write_config_byte(pdev, drwt, (t->active << 4) | t->recover);
+ }
+
+ /* Set up the UDMA enable */
+ pci_read_config_byte(pdev, udmat, &udma);
+ udma &= ~(0x0F << shift);
+ udma |= ultra << shift;
+ pci_write_config_byte(pdev, udmat, udma);
+}
+
+/**
+ * ali_set_piomode - set initial PIO mode data
+ * @ap: ATA interface
+ * @adev: ATA device
+ *
+ * Program the ALi registers for PIO mode.
+ */
+
+static void ali_set_piomode(struct ata_port *ap, struct ata_device *adev)
+{
+ struct ata_device *pair = ata_dev_pair(adev);
+ struct ata_timing t;
+ unsigned long T = 1000000000 / 33333; /* PCI clock based */
+
+ ata_timing_compute(adev->id, adev->pio_mode, adev->pio_mode, &t, T, 1);
+ if (pair) {
+ struct ata_timing p;
+
+ ata_timing_compute(pair->id, pair->pio_mode, pair->pio_mode,
+ &p, T, 1);
+ ata_timing_merge(&p, &t, &t, ATA_TIMING_SETUP|ATA_TIMING_8BIT);
+ if (pair->dma_mode) {
+ ata_timing_compute(pair->id, pair->dma_mode,
+ pair->pio_mode, &p, T, 1);
+ ata_timing_merge(&p, &t, &t, ATA_TIMING_SETUP|ATA_TIMING_8BIT);
+ }
+ }
+
+ /* PIO FIFO is only permitted on ATA disk */
+ ali_fifo_control(ap, adev, (adev->class == ATA_DEV_ATA) ? 0x05 : 0x00);
+
+ ali_program_modes(ap, adev, &t, 0);
+}
+
+/**
+ * ali_set_dmamode - set initial DMA mode data
+ * @ap: ATA interface
+ * @adev: ATA device
+ *
+ * Program the ALi registers for DMA mode.
+ */
+
+static void ali_set_dmamode(struct ata_port *ap, struct ata_device *adev)
+{
+ static u8 udma_timing[7] = { 0xC, 0xB, 0xA, 0x9, 0x8, 0xF, 0xD };
+ struct ata_device *pair = ata_dev_pair(adev);
+ struct ata_timing t;
+ unsigned long T = 1000000000 / 33333; /* PCI clock based */
+ struct pci_dev *pdev = to_pci_dev(ap->host->dev);
+
+
+ if (adev->class == ATA_DEV_ATA)
+ ali_fifo_control(ap, adev, 0x08);
+
+ if (adev->dma_mode >= XFER_UDMA_0) {
+ ali_program_modes(ap, adev, NULL, udma_timing[adev->dma_mode - XFER_UDMA_0]);
+ if (adev->dma_mode >= XFER_UDMA_3) {
+ u8 reg4b;
+ pci_read_config_byte(pdev, 0x4B, &reg4b);
+ reg4b |= 1;
+ pci_write_config_byte(pdev, 0x4B, reg4b);
+ }
+ } else {
+ ata_timing_compute(adev->id, adev->dma_mode, adev->pio_mode,
+ &t, T, 1);
+ if (pair) {
+ struct ata_timing p;
+
+ ata_timing_compute(pair->id, pair->pio_mode,
+ pair->pio_mode, &p, T, 1);
+ ata_timing_merge(&p, &t, &t, ATA_TIMING_SETUP|ATA_TIMING_8BIT);
+ if (pair->dma_mode) {
+ ata_timing_compute(pair->id, pair->dma_mode,
+ pair->pio_mode, &p, T, 1);
+ ata_timing_merge(&p, &t, &t, ATA_TIMING_SETUP|ATA_TIMING_8BIT);
+ }
+ }
+ ali_program_modes(ap, adev, &t, 0);
+ }
+}
+
+/**
+ * ali_init_chipset - chip setup function
+ * @dev: device of ATA controller
+ *
+ * Perform the setup on the device that must be done both at boot
+ * and at resume time.
+ */
+
+static int ali_init_chipset(struct device *dev)
+{
+ struct pci_dev *pdev = to_pci_dev(dev);
+ u8 tmp;
+ struct pci_dev *north;
+
+ /*
+ * The chipset revision selects the driver operations and
+ * mode data.
+ */
+
+ if (pdev->revision <= 0x20) {
+ pci_read_config_byte(pdev, 0x53, &tmp);
+ tmp |= 0x03;
+ pci_write_config_byte(pdev, 0x53, tmp);
+ } else {
+ pci_read_config_byte(pdev, 0x4a, &tmp);
+ pci_write_config_byte(pdev, 0x4a, tmp | 0x20);
+ pci_read_config_byte(pdev, 0x4B, &tmp);
+ if (pdev->revision < 0xC2)
+ /* 1543-E/F, 1543C-C, 1543C-D, 1543C-E */
+ /* Clear CD-ROM DMA write bit */
+ tmp &= 0x7F;
+ /* Cable and UDMA */
+ if (pdev->revision >= 0xc2)
+ tmp |= 0x01;
+ pci_write_config_byte(pdev, 0x4B, tmp | 0x08);
+ /*
+ * CD_ROM DMA on (0x53 bit 0). Enable this even if we want
+ * to use PIO. 0x53 bit 1 (rev 20 only) - enable FIFO control
+ * via 0x54/55.
+ */
+ pci_read_config_byte(pdev, 0x53, &tmp);
+ if (pdev->revision >= 0xc7)
+ tmp |= 0x03;
+ else
+ tmp |= 0x01; /* CD_ROM enable for DMA */
+ pci_write_config_byte(pdev, 0x53, tmp);
+ }
+ north = pci_get_bus_and_slot(0, PCI_DEVFN(0,0));
+ if (north && north->vendor == PCI_VENDOR_ID_AL && ali_isa_bridge) {
+ /* Configure the ALi bridge logic. For non ALi rely on BIOS.
+ Set the south bridge enable bit */
+ pci_read_config_byte(ali_isa_bridge, 0x79, &tmp);
+ if (pdev->revision == 0xC2)
+ pci_write_config_byte(ali_isa_bridge, 0x79, tmp | 0x04);
+ else if (pdev->revision > 0xC2 && pdev->revision < 0xC5)
+ pci_write_config_byte(ali_isa_bridge, 0x79, tmp | 0x02);
+ }
+ pci_dev_put(north);
+ ata_pci_bmdma_clear_simplex(pdev);
+ return 0;
+}
+#endif
--
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to majordomo@xxxxxxxxxxxxxxx
More majordomo info at http://vger.kernel.org/majordomo-info.html
Please read the FAQ at http://www.tux.org/lkml/