Subject: [PATCH 0/9] few more ide2libata patches


On top of atang-v4.0:
- pata_cs5536 fixes (forward ported from cs5536)
- siimage cleanup
- cs5536 & siimage ported over ide2libata (400 LOC gone)


The following changes since commit 02a4edce515b374e01068be6c954c7f90dfac861:
Bartlomiej Zolnierkiewicz (1):
via82cxxx: convert to ide2libata

are available in the git repository at:

git://git.kernel.org/pub/scm/linux/kernel/git/bart/misc.git atang-v4.1

Bartlomiej Zolnierkiewicz (9):
pata_cs5536: forward port changes from cs5536
pata_sil680: CodingStyle fixes
siimage: cleanup I/O helpers
piix: move documentation to ata_piix.h
ide2libata: add missing credits
pata_cs5536: move code to be re-used by ide2libata to pata_cs5536.h
cs5536: convert to ide2libata
pata_sil680: move code to be re-used by ide2libata to pata_sil680.h
siimage: convert to ide2libata

drivers/ata/ata_piix.c | 45 ------
drivers/ata/ata_piix.h | 46 ++++++
drivers/ata/pata_cs5536.c | 191 +-------------------------
drivers/ata/pata_cs5536.h | 195 ++++++++++++++++++++++++++
drivers/ata/pata_sil680.c | 228 +------------------------------
drivers/ata/pata_sil680.h | 284 +++++++++++++++++++++++++++++++++++++
drivers/ide/aec62xx.c | 4 +-
drivers/ide/atiixp.c | 4 +-
drivers/ide/cs5520.c | 3 +-
drivers/ide/cs5530.c | 4 +-
drivers/ide/cs5535.c | 4 +-
drivers/ide/cs5536.c | 189 +------------------------
drivers/ide/it8213.c | 4 +-
drivers/ide/it821x.c | 4 +-
drivers/ide/piix.c | 40 +-----
drivers/ide/sc1200.c | 4 +-
drivers/ide/siimage.c | 342 +++------------------------------------------
drivers/ide/sl82c105.c | 2 +-
drivers/ide/slc90e66.c | 3 +-
drivers/ide/triflex.c | 4 +-
20 files changed, 578 insertions(+), 1022 deletions(-)
create mode 100644 drivers/ata/pata_cs5536.h
create mode 100644 drivers/ata/pata_sil680.h


Subject: [PATCH 4/9] [ata_]piix: move documentation to ata_piix.h

From: Bartlomiej Zolnierkiewicz <[email protected]>
Subject: [PATCH] [ata_]piix: move documentation to ata_piix.h

Signed-off-by: Bartlomiej Zolnierkiewicz <[email protected]>
---
drivers/ata/ata_piix.c | 45 ---------------------------------------------
drivers/ata/ata_piix.h | 46 ++++++++++++++++++++++++++++++++++++++++++++++
drivers/ide/piix.c | 37 -------------------------------------
3 files changed, 46 insertions(+), 82 deletions(-)

Index: b/drivers/ata/ata_piix.c
===================================================================
--- a/drivers/ata/ata_piix.c
+++ b/drivers/ata/ata_piix.c
@@ -36,51 +36,6 @@
* as Documentation/DocBook/libata.*
*
* Hardware documentation available at http://developer.intel.com/
- *
- * Documentation
- * Publically available from Intel web site. Errata documentation
- * is also publically available. As an aide to anyone hacking on this
- * driver the list of errata that are relevant is below, going back to
- * PIIX4. Older device documentation is now a bit tricky to find.
- *
- * The chipsets all follow very much the same design. The orginal Triton
- * series chipsets do _not_ support independant device timings, but this
- * is fixed in Triton II. With the odd mobile exception the chips then
- * change little except in gaining more modes until SATA arrives. This
- * driver supports only the chips with independant timing (that is those
- * with SITRE and the 0x44 timing register). See pata_oldpiix and pata_mpiix
- * for the early chip drivers.
- *
- * Errata of note:
- *
- * Unfixable
- * PIIX4 errata #9 - Only on ultra obscure hw
- * ICH3 errata #13 - Not observed to affect real hw
- * by Intel
- *
- * Things we must deal with
- * PIIX4 errata #10 - BM IDE hang with non UDMA
- * (must stop/start dma to recover)
- * 440MX errata #15 - As PIIX4 errata #10
- * PIIX4 errata #15 - Must not read control registers
- * during a PIO transfer
- * 440MX errata #13 - As PIIX4 errata #15
- * ICH2 errata #21 - DMA mode 0 doesn't work right
- * ICH0/1 errata #55 - As ICH2 errata #21
- * ICH2 spec c #9 - Extra operations needed to handle
- * drive hotswap [NOT YET SUPPORTED]
- * ICH2 spec c #20 - IDE PRD must not cross a 64K boundary
- * and must be dword aligned
- * ICH2 spec c #24 - UDMA mode 4,5 t85/86 should be 6ns not 3.3
- * ICH7 errata #16 - MWDMA1 timings are incorrect
- *
- * Should have been BIOS fixed:
- * 450NX: errata #19 - DMA hangs on old 450NX
- * 450NX: errata #20 - DMA hangs on old 450NX
- * 450NX: errata #25 - Corruption with DMA on old 450NX
- * ICH3 errata #15 - IDE deadlock under high load
- * (BIOS must set dev 31 fn 0 bit 23)
- * ICH3 errata #18 - Don't use native mode
*/

#include <linux/kernel.h>
Index: b/drivers/ata/ata_piix.h
===================================================================
--- a/drivers/ata/ata_piix.h
+++ b/drivers/ata/ata_piix.h
@@ -1,3 +1,49 @@
+/*
+ * Documentation:
+ * Publically available from Intel web site. Errata documentation
+ * is also publically available. As an aide to anyone hacking on this
+ * driver the list of errata that are relevant is below, going back to
+ * PIIX4. Older device documentation is now a bit tricky to find.
+ *
+ * The chipsets all follow very much the same design. The orginal Triton
+ * series chipsets do _not_ support independant device timings, but this
+ * is fixed in Triton II. With the odd mobile exception the chips then
+ * change little except in gaining more modes until SATA arrives. This
+ * driver supports only the chips with independant timing (that is those
+ * with SITRE and the 0x44 timing register). See pata_oldpiix and pata_mpiix
+ * for the early chip drivers.
+ *
+ * Errata of note:
+ *
+ * Unfixable
+ * PIIX4 errata #9 - Only on ultra obscure hw
+ * ICH3 errata #13 - Not observed to affect real hw
+ * by Intel
+ *
+ * Things we must deal with
+ * PIIX4 errata #10 - BM IDE hang with non UDMA
+ * (must stop/start dma to recover)
+ * 440MX errata #15 - As PIIX4 errata #10
+ * PIIX4 errata #15 - Must not read control registers
+ * during a PIO transfer
+ * 440MX errata #13 - As PIIX4 errata #15
+ * ICH2 errata #21 - DMA mode 0 doesn't work right
+ * ICH0/1 errata #55 - As ICH2 errata #21
+ * ICH2 spec c #9 - Extra operations needed to handle
+ * drive hotswap [NOT YET SUPPORTED]
+ * ICH2 spec c #20 - IDE PRD must not cross a 64K boundary
+ * and must be dword aligned
+ * ICH2 spec c #24 - UDMA mode 4,5 t85/86 should be 6ns not 3.3
+ * ICH7 errata #16 - MWDMA1 timings are incorrect
+ *
+ * Should have been BIOS fixed:
+ * 450NX: errata #19 - DMA hangs on old 450NX
+ * 450NX: errata #20 - DMA hangs on old 450NX
+ * 450NX: errata #25 - Corruption with DMA on old 450NX
+ * ICH3 errata #15 - IDE deadlock under high load
+ * (BIOS must set dev 31 fn 0 bit 23)
+ * ICH3 errata #18 - Don't use native mode
+ */

struct ich_laptop {
u16 device;
Index: b/drivers/ide/piix.c
===================================================================
--- a/drivers/ide/piix.c
+++ b/drivers/ide/piix.c
@@ -5,43 +5,6 @@
* Copyright (C) 2006-2007 MontaVista Software, Inc. <[email protected]>
*
* May be copied or modified under the terms of the GNU General Public License
- *
- * Documentation:
- *
- * Publically available from Intel web site. Errata documentation
- * is also publically available. As an aide to anyone hacking on this
- * driver the list of errata that are relevant is below.going back to
- * PIIX4. Older device documentation is now a bit tricky to find.
- *
- * Errata of note:
- *
- * Unfixable
- * PIIX4 errata #9 - Only on ultra obscure hw
- * ICH3 errata #13 - Not observed to affect real hw
- * by Intel
- *
- * Things we must deal with
- * PIIX4 errata #10 - BM IDE hang with non UDMA
- * (must stop/start dma to recover)
- * 440MX errata #15 - As PIIX4 errata #10
- * PIIX4 errata #15 - Must not read control registers
- * during a PIO transfer
- * 440MX errata #13 - As PIIX4 errata #15
- * ICH2 errata #21 - DMA mode 0 doesn't work right
- * ICH0/1 errata #55 - As ICH2 errata #21
- * ICH2 spec c #9 - Extra operations needed to handle
- * drive hotswap [NOT YET SUPPORTED]
- * ICH2 spec c #20 - IDE PRD must not cross a 64K boundary
- * and must be dword aligned
- * ICH2 spec c #24 - UDMA mode 4,5 t85/86 should be 6ns not 3.3
- *
- * Should have been BIOS fixed:
- * 450NX: errata #19 - DMA hangs on old 450NX
- * 450NX: errata #20 - DMA hangs on old 450NX
- * 450NX: errata #25 - Corruption with DMA on old 450NX
- * ICH3 errata #15 - IDE deadlock under high load
- * (BIOS must set dev 31 fn 0 bit 23)
- * ICH3 errata #18 - Don't use native mode
*/

#include <linux/types.h>

Subject: [PATCH 1/9] pata_cs5536: forward port changes from cs5536

From: Bartlomiej Zolnierkiewicz <[email protected]>
Subject: [PATCH] pata_cs5536: forward port changes from cs5536

* Fix cable detection to also account for the slave device cable bit.

* Disable UDMA when programming MWDMA in cs5536_set_dmamode().

* Don't change UDMA settings in cs5536_set_piomode().

* Add cs5536_program_dtc() helper.

* Cleanup and uninline cs5536_[read,write]() methods.

Signed-off-by: Bartlomiej Zolnierkiewicz <[email protected]>
---
drivers/ata/pata_cs5536.c | 99 +++++++++++++++++++---------------------------
1 file changed, 42 insertions(+), 57 deletions(-)

Index: b/drivers/ata/pata_cs5536.c
===================================================================
--- a/drivers/ata/pata_cs5536.c
+++ b/drivers/ata/pata_cs5536.c
@@ -1,6 +1,7 @@
/*
* pata_cs5536.c - CS5536 PATA for new ATA layer
* (C) 2007 Martin K. Petersen <[email protected]>
+ * (C) 2010 Bartlomiej Zolnierkiewicz
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License version 2 as
@@ -43,24 +44,16 @@
#define DRV_VERSION "0.0.7"

enum {
- CFG = 0,
- DTC = 1,
- CAST = 2,
- ETC = 3,
-
- MSR_IDE_BASE = 0x51300000,
- MSR_IDE_CFG = (MSR_IDE_BASE + 0x10),
- MSR_IDE_DTC = (MSR_IDE_BASE + 0x12),
- MSR_IDE_CAST = (MSR_IDE_BASE + 0x13),
- MSR_IDE_ETC = (MSR_IDE_BASE + 0x14),
-
+ MSR_IDE_CFG = 0x51300010,
PCI_IDE_CFG = 0x40,
- PCI_IDE_DTC = 0x48,
- PCI_IDE_CAST = 0x4c,
- PCI_IDE_ETC = 0x50,

- IDE_CFG_CHANEN = 0x2,
- IDE_CFG_CABLE = 0x10000,
+ CFG = 0,
+ DTC = 2,
+ CAST = 3,
+ ETC = 4,
+
+ IDE_CFG_CHANEN = (1 << 1),
+ IDE_CFG_CABLE = (1 << 17) | (1 << 16),

IDE_D0_SHIFT = 24,
IDE_D1_SHIFT = 16,
@@ -72,47 +65,52 @@ enum {
IDE_CAST_CMD_MASK = 0xff,
IDE_CAST_CMD_SHIFT = 24,

- IDE_ETC_NODMA = 0x03,
+ IDE_ETC_UDMA_MASK = 0xc0,
};

static int use_msr;

-static const u32 msr_reg[4] = {
- MSR_IDE_CFG, MSR_IDE_DTC, MSR_IDE_CAST, MSR_IDE_ETC,
-};
-
-static const u8 pci_reg[4] = {
- PCI_IDE_CFG, PCI_IDE_DTC, PCI_IDE_CAST, PCI_IDE_ETC,
-};
-
-static inline int cs5536_read(struct pci_dev *pdev, int reg, u32 *val)
+static int cs5536_read(struct pci_dev *pdev, int reg, u32 *val)
{
if (unlikely(use_msr)) {
u32 dummy;

- rdmsr(msr_reg[reg], *val, dummy);
+ rdmsr(MSR_IDE_CFG + reg, *val, dummy);
return 0;
}

- return pci_read_config_dword(pdev, pci_reg[reg], val);
+ return pci_read_config_dword(pdev, PCI_IDE_CFG + reg * 4, val);
}

-static inline int cs5536_write(struct pci_dev *pdev, int reg, int val)
+static int cs5536_write(struct pci_dev *pdev, int reg, int val)
{
if (unlikely(use_msr)) {
- wrmsr(msr_reg[reg], val, 0);
+ wrmsr(MSR_IDE_CFG + reg, val, 0);
return 0;
}

- return pci_write_config_dword(pdev, pci_reg[reg], val);
+ return pci_write_config_dword(pdev, PCI_IDE_CFG + reg * 4, val);
+}
+
+static void cs5536_program_dtc(struct ata_device *adev, u8 tim)
+{
+ struct pci_dev *pdev = to_pci_dev(adev->link->ap->host->dev);
+ int dshift = adev->devno ? IDE_D1_SHIFT : IDE_D0_SHIFT;
+ u32 dtc;
+
+ cs5536_read(pdev, DTC, &dtc);
+ dtc &= ~(IDE_DRV_MASK << dshift);
+ dtc |= tim << dshift;
+ cs5536_write(pdev, DTC, dtc);
}

/**
* cs5536_cable_detect - detect cable type
* @ap: Port to detect on
*
- * Perform cable detection for ATA66 capable cable. Return a libata
- * cable type.
+ * Perform cable detection for ATA66 capable cable.
+ *
+ * Returns a cable type.
*/

static int cs5536_cable_detect(struct ata_port *ap)
@@ -122,7 +120,7 @@ static int cs5536_cable_detect(struct at

cs5536_read(pdev, CFG, &cfg);

- if (cfg & (IDE_CFG_CABLE << ap->port_no))
+ if (cfg & IDE_CFG_CABLE)
return ATA_CBL_PATA80;
else
return ATA_CBL_PATA40;
@@ -152,19 +150,15 @@ static void cs5536_set_piomode(struct at
struct ata_device *pair = ata_dev_pair(adev);
int mode = adev->pio_mode - XFER_PIO_0;
int cmdmode = mode;
- int dshift = adev->devno ? IDE_D1_SHIFT : IDE_D0_SHIFT;
int cshift = adev->devno ? IDE_CAST_D1_SHIFT : IDE_CAST_D0_SHIFT;
- u32 dtc, cast, etc;
+ u32 cast;

if (pair)
cmdmode = min(mode, pair->pio_mode - XFER_PIO_0);

- cs5536_read(pdev, DTC, &dtc);
- cs5536_read(pdev, CAST, &cast);
- cs5536_read(pdev, ETC, &etc);
+ cs5536_program_dtc(adev, drv_timings[mode]);

- dtc &= ~(IDE_DRV_MASK << dshift);
- dtc |= drv_timings[mode] << dshift;
+ cs5536_read(pdev, CAST, &cast);

cast &= ~(IDE_CAST_DRV_MASK << cshift);
cast |= addr_timings[mode] << cshift;
@@ -172,12 +166,7 @@ static void cs5536_set_piomode(struct at
cast &= ~(IDE_CAST_CMD_MASK << IDE_CAST_CMD_SHIFT);
cast |= cmd_timings[cmdmode] << IDE_CAST_CMD_SHIFT;

- etc &= ~(IDE_DRV_MASK << dshift);
- etc |= IDE_ETC_NODMA << dshift;
-
- cs5536_write(pdev, DTC, dtc);
cs5536_write(pdev, CAST, cast);
- cs5536_write(pdev, ETC, etc);
}

/**
@@ -198,25 +187,21 @@ static void cs5536_set_dmamode(struct at
};

struct pci_dev *pdev = to_pci_dev(ap->host->dev);
- u32 dtc, etc;
+ u32 etc;
int mode = adev->dma_mode;
int dshift = adev->devno ? IDE_D1_SHIFT : IDE_D0_SHIFT;

- if (mode >= XFER_UDMA_0) {
- cs5536_read(pdev, ETC, &etc);
+ cs5536_read(pdev, ETC, &etc);

+ if (mode >= XFER_UDMA_0) {
etc &= ~(IDE_DRV_MASK << dshift);
etc |= udma_timings[mode - XFER_UDMA_0] << dshift;
-
- cs5536_write(pdev, ETC, etc);
} else { /* MWDMA */
- cs5536_read(pdev, DTC, &dtc);
-
- dtc &= ~(IDE_DRV_MASK << dshift);
- dtc |= mwdma_timings[mode - XFER_MW_DMA_0] << dshift;
-
- cs5536_write(pdev, DTC, dtc);
+ etc &= ~(IDE_ETC_UDMA_MASK << dshift);
+ cs5536_program_dtc(adev, mwdma_timings[mode - XFER_MW_DMA_0]);
}
+
+ cs5536_write(pdev, ETC, etc);
}

static struct scsi_host_template cs5536_sht = {

Subject: [PATCH 2/9] pata_sil680: CodingStyle fixes

From: Bartlomiej Zolnierkiewicz <[email protected]>
Subject: [PATCH] pata_sil680: CodingStyle fixes

Signed-off-by: Bartlomiej Zolnierkiewicz <[email protected]>
---
drivers/ata/pata_sil680.c | 58 ++++++++++++++++++++++++++--------------------
1 file changed, 33 insertions(+), 25 deletions(-)

Index: b/drivers/ata/pata_sil680.c
===================================================================
--- a/drivers/ata/pata_sil680.c
+++ b/drivers/ata/pata_sil680.c
@@ -81,7 +81,8 @@ static unsigned long sil680_seldev(struc
* space for us.
*/

-static int sil680_cable_detect(struct ata_port *ap) {
+static int sil680_cable_detect(struct ata_port *ap)
+{
struct pci_dev *pdev = to_pci_dev(ap->host->dev);
unsigned long addr = sil680_selreg(ap, 0);
u8 ata66;
@@ -175,7 +176,7 @@ static void sil680_set_dmamode(struct at
mode &= ~(0x03 << port_shift);

/* Extract scsc */
- scsc = (scsc & 0x30) ? 1: 0;
+ scsc = (scsc & 0x30) ? 1 : 0;

if (adev->dma_mode >= XFER_UDMA_0) {
multi = 0x10C1;
@@ -214,7 +215,7 @@ static u8 sil680_init_chip(struct pci_de
{
u8 tmpbyte = 0;

- /* FIXME: double check */
+ /* FIXME: double check */
pci_write_config_byte(pdev, PCI_CACHE_LINE_SIZE,
pdev->revision ? 1 : 255);

@@ -232,22 +233,22 @@ static u8 sil680_init_chip(struct pci_de
*try_mmio = (tmpbyte & 1) || pci_resource_start(pdev, 5);
#endif

- switch(tmpbyte & 0x30) {
- case 0x00:
- /* 133 clock attempt to force it on */
- pci_write_config_byte(pdev, 0x8A, tmpbyte|0x10);
- break;
- case 0x30:
- /* if clocking is disabled */
- /* 133 clock attempt to force it on */
- pci_write_config_byte(pdev, 0x8A, tmpbyte & ~0x20);
- break;
- case 0x10:
- /* 133 already */
- break;
- case 0x20:
- /* BIOS set PCI x2 clocking */
- break;
+ switch (tmpbyte & 0x30) {
+ case 0x00:
+ /* 133 clock attempt to force it on */
+ pci_write_config_byte(pdev, 0x8A, tmpbyte|0x10);
+ break;
+ case 0x30:
+ /* if clocking is disabled */
+ /* 133 clock attempt to force it on */
+ pci_write_config_byte(pdev, 0x8A, tmpbyte & ~0x20);
+ break;
+ case 0x10:
+ /* 133 already */
+ break;
+ case 0x20:
+ /* BIOS set PCI x2 clocking */
+ break;
}

pci_read_config_byte(pdev, 0x8A, &tmpbyte);
@@ -265,12 +266,19 @@ static u8 sil680_init_chip(struct pci_de
pci_write_config_dword(pdev, 0xB8, 0x43924392);
pci_write_config_dword(pdev, 0xBC, 0x40094009);

- switch(tmpbyte & 0x30) {
- case 0x00: printk(KERN_INFO "sil680: 100MHz clock.\n");break;
- case 0x10: printk(KERN_INFO "sil680: 133MHz clock.\n");break;
- case 0x20: printk(KERN_INFO "sil680: Using PCI clock.\n");break;
- /* This last case is _NOT_ ok */
- case 0x30: printk(KERN_ERR "sil680: Clock disabled ?\n");
+ switch (tmpbyte & 0x30) {
+ case 0x00:
+ printk(KERN_INFO "sil680: 100MHz clock.\n");
+ break;
+ case 0x10:
+ printk(KERN_INFO "sil680: 133MHz clock.\n");
+ break;
+ case 0x20:
+ printk(KERN_INFO "sil680: Using PCI clock.\n");
+ break;
+ /* This last case is _NOT_ ok */
+ case 0x30:
+ printk(KERN_ERR "sil680: Clock disabled ?\n");
}
return tmpbyte & 0x30;
}

Subject: [PATCH 3/9] siimage: cleanup I/O helpers

From: Bartlomiej Zolnierkiewicz <[email protected]>
Subject: [PATCH] siimage: cleanup I/O helpers

No users of sil_io*()/siimage_sel[reg,dev]() helpers except ->test_irq
method are performance critical so convert ->test_irq to use MMIO space
directly if needed and switch the rest to just use PCI space.

Signed-off-by: Bartlomiej Zolnierkiewicz <[email protected]>
---
drivers/ide/siimage.c | 178 ++++++++++++++++----------------------------------
1 file changed, 58 insertions(+), 120 deletions(-)

Index: b/drivers/ide/siimage.c
===================================================================
--- a/drivers/ide/siimage.c
+++ b/drivers/ide/siimage.c
@@ -2,7 +2,7 @@
* Copyright (C) 2001-2002 Andre Hedrick <[email protected]>
* Copyright (C) 2003 Red Hat
* Copyright (C) 2007-2008 MontaVista Software, Inc.
- * Copyright (C) 2007-2008 Bartlomiej Zolnierkiewicz
+ * Copyright (C) 2007-2010 Bartlomiej Zolnierkiewicz
*
* May be copied or modified under the terms of the GNU General Public License
*
@@ -83,21 +83,18 @@ static inline int is_sata(ide_hwif_t *hw
* @hwif: interface
* @r: config offset
*
- * Turn a config register offset into the right address in either
- * PCI space or MMIO space to access the control register in question
+ * Turn a config register offset into the right address in PCI space
+ * to access the control register in question.
+ *
* Thankfully this is a configuration operation, so isn't performance
* critical.
*/

static unsigned long siimage_selreg(ide_hwif_t *hwif, int r)
{
- unsigned long base = (unsigned long)hwif->hwif_data;
+ unsigned long base = 0xA0 + r;

- base += 0xA0 + r;
- if (hwif->host_flags & IDE_HFLAG_MMIO)
- base += hwif->channel << 6;
- else
- base += hwif->channel << 4;
+ base += hwif->channel << 4;
return base;
}

@@ -106,82 +103,22 @@ static unsigned long siimage_selreg(ide_
* @hwif: interface
* @r: config offset
*
- * Turn a config register offset into the right address in either
- * PCI space or MMIO space to access the control register in question
- * including accounting for the unit shift.
+ * Turn a config register offset into the right address in PCI space
+ * to access the control register in question including accounting for
+ * the unit shift.
*/

static inline unsigned long siimage_seldev(ide_drive_t *drive, int r)
{
ide_hwif_t *hwif = drive->hwif;
- unsigned long base = (unsigned long)hwif->hwif_data;
+ unsigned long base = 0xA0 + r;
u8 unit = drive->dn & 1;

- base += 0xA0 + r;
- if (hwif->host_flags & IDE_HFLAG_MMIO)
- base += hwif->channel << 6;
- else
- base += hwif->channel << 4;
+ base += hwif->channel << 4;
base |= unit << unit;
return base;
}

-static u8 sil_ioread8(struct pci_dev *dev, unsigned long addr)
-{
- struct ide_host *host = pci_get_drvdata(dev);
- u8 tmp = 0;
-
- if (host->host_priv)
- tmp = readb((void __iomem *)addr);
- else
- pci_read_config_byte(dev, addr, &tmp);
-
- return tmp;
-}
-
-static u16 sil_ioread16(struct pci_dev *dev, unsigned long addr)
-{
- struct ide_host *host = pci_get_drvdata(dev);
- u16 tmp = 0;
-
- if (host->host_priv)
- tmp = readw((void __iomem *)addr);
- else
- pci_read_config_word(dev, addr, &tmp);
-
- return tmp;
-}
-
-static void sil_iowrite8(struct pci_dev *dev, u8 val, unsigned long addr)
-{
- struct ide_host *host = pci_get_drvdata(dev);
-
- if (host->host_priv)
- writeb(val, (void __iomem *)addr);
- else
- pci_write_config_byte(dev, addr, val);
-}
-
-static void sil_iowrite16(struct pci_dev *dev, u16 val, unsigned long addr)
-{
- struct ide_host *host = pci_get_drvdata(dev);
-
- if (host->host_priv)
- writew(val, (void __iomem *)addr);
- else
- pci_write_config_word(dev, addr, val);
-}
-
-static void sil_iowrite32(struct pci_dev *dev, u32 val, unsigned long addr)
-{
- struct ide_host *host = pci_get_drvdata(dev);
-
- if (host->host_priv)
- writel(val, (void __iomem *)addr);
- else
- pci_write_config_dword(dev, addr, val);
-}
-
/**
* sil_udma_filter - compute UDMA mask
* @drive: IDE device
@@ -196,12 +133,9 @@ static u8 sil_pata_udma_filter(ide_drive
{
ide_hwif_t *hwif = drive->hwif;
struct pci_dev *dev = to_pci_dev(hwif->dev);
- unsigned long base = (unsigned long)hwif->hwif_data;
u8 scsc, mask = 0;

- base += (hwif->host_flags & IDE_HFLAG_MMIO) ? 0x4A : 0x8A;
-
- scsc = sil_ioread8(dev, base);
+ pci_read_config_byte(dev, 0x8A, &scsc);

switch (scsc & 0x30) {
case 0x10: /* 133 */
@@ -247,12 +181,9 @@ static void sil_set_pio_mode(ide_hwif_t
u16 speedp = 0;
unsigned long addr = siimage_seldev(drive, 0x04);
unsigned long tfaddr = siimage_selreg(hwif, 0x02);
- unsigned long base = (unsigned long)hwif->hwif_data;
const u8 pio = drive->pio_mode - XFER_PIO_0;
u8 tf_pio = pio;
- u8 mmio = (hwif->host_flags & IDE_HFLAG_MMIO) ? 1 : 0;
- u8 addr_mask = hwif->channel ? (mmio ? 0xF4 : 0x84)
- : (mmio ? 0xB4 : 0x80);
+ u8 addr_mask = hwif->channel ? 0x84 : 0x80;
u8 mode = 0;
u8 unit = drive->dn & 1;

@@ -268,14 +199,14 @@ static void sil_set_pio_mode(ide_hwif_t
speedp = data_speed[pio];
speedt = tf_speed[tf_pio];

- sil_iowrite16(dev, speedp, addr);
- sil_iowrite16(dev, speedt, tfaddr);
+ pci_write_config_word(dev, addr, speedp);
+ pci_write_config_word(dev, tfaddr, speedt);

/* now set up IORDY */
- speedp = sil_ioread16(dev, tfaddr - 2);
+ pci_read_config_word(dev, tfaddr - 2, &speedp);
speedp &= ~0x200;

- mode = sil_ioread8(dev, base + addr_mask);
+ pci_read_config_byte(dev, addr_mask, &mode);
mode &= ~(unit ? 0x30 : 0x03);

if (ide_pio_need_iordy(drive, pio)) {
@@ -283,8 +214,8 @@ static void sil_set_pio_mode(ide_hwif_t
mode |= unit ? 0x10 : 0x01;
}

- sil_iowrite16(dev, speedp, tfaddr - 2);
- sil_iowrite8(dev, mode, base + addr_mask);
+ pci_write_config_word(dev, tfaddr - 2, speedp);
+ pci_write_config_byte(dev, addr_mask, mode);
}

/**
@@ -302,20 +233,17 @@ static void sil_set_dma_mode(ide_hwif_t
static const u16 dma[] = { 0x2208, 0x10C2, 0x10C1 };

struct pci_dev *dev = to_pci_dev(hwif->dev);
- unsigned long base = (unsigned long)hwif->hwif_data;
u16 ultra = 0, multi = 0;
u8 mode = 0, unit = drive->dn & 1;
- u8 mmio = (hwif->host_flags & IDE_HFLAG_MMIO) ? 1 : 0;
- u8 scsc = 0, addr_mask = hwif->channel ? (mmio ? 0xF4 : 0x84)
- : (mmio ? 0xB4 : 0x80);
+ u8 scsc = 0, addr_mask = hwif->channel ? 0x84 : 0x80;
unsigned long ma = siimage_seldev(drive, 0x08);
unsigned long ua = siimage_seldev(drive, 0x0C);
const u8 speed = drive->dma_mode;

- scsc = sil_ioread8 (dev, base + (mmio ? 0x4A : 0x8A));
- mode = sil_ioread8 (dev, base + addr_mask);
- multi = sil_ioread16(dev, ma);
- ultra = sil_ioread16(dev, ua);
+ pci_read_config_byte(dev, 0x8A, &scsc);
+ pci_read_config_byte(dev, addr_mask, &mode);
+ pci_read_config_word(dev, ma, &multi);
+ pci_read_config_word(dev, ua, &ultra);

mode &= ~(unit ? 0x30 : 0x03);
ultra &= ~0x3F;
@@ -333,16 +261,25 @@ static void sil_set_dma_mode(ide_hwif_t
mode |= unit ? 0x20 : 0x02;
}

- sil_iowrite8 (dev, mode, base + addr_mask);
- sil_iowrite16(dev, multi, ma);
- sil_iowrite16(dev, ultra, ua);
+ pci_write_config_byte(dev, addr_mask, mode);
+ pci_write_config_word(dev, ma, multi);
+ pci_write_config_word(dev, ua, ultra);
}

static int sil_test_irq(ide_hwif_t *hwif)
{
struct pci_dev *dev = to_pci_dev(hwif->dev);
- unsigned long addr = siimage_selreg(hwif, 1);
- u8 val = sil_ioread8(dev, addr);
+ unsigned long addr;
+ u8 val;
+
+ if (hwif->host->host_priv) {
+ addr = (unsigned long)hwif->hwif_data;
+ addr += 0xA0 + 1 + (hwif->channel << 6);
+ val = readb((void __iomem *)addr);
+ } else {
+ addr = siimage_selreg(hwif, 1);
+ pci_read_config_byte(dev, addr, &val);
+ }

/* Return 1 if INTRQ asserted */
return (val & 8) ? 1 : 0;
@@ -454,7 +391,7 @@ static int init_chipset_siimage(struct p
{
struct ide_host *host = pci_get_drvdata(dev);
void __iomem *ioaddr = host->host_priv;
- unsigned long base, scsc_addr;
+ unsigned long base;
u8 rev = dev->revision, tmp;

pci_write_config_byte(dev, PCI_CACHE_LINE_SIZE, rev ? 1 : 255);
@@ -479,20 +416,19 @@ static int init_chipset_siimage(struct p
writel(0, ioaddr + 0x1C8);
}

- sil_iowrite8(dev, 0, base ? (base + 0xB4) : 0x80);
- sil_iowrite8(dev, 0, base ? (base + 0xF4) : 0x84);
+ pci_write_config_byte(dev, 0x80, 0x00);
+ pci_write_config_byte(dev, 0x84, 0x00);

- scsc_addr = base ? (base + 0x4A) : 0x8A;
- tmp = sil_ioread8(dev, scsc_addr);
+ pci_read_config_byte(dev, 0x8A, &tmp);

switch (tmp & 0x30) {
case 0x00:
/* On 100 MHz clocking, try and switch to 133 MHz */
- sil_iowrite8(dev, tmp | 0x10, scsc_addr);
+ pci_write_config_byte(dev, 0x8A, tmp | 0x10);
break;
case 0x30:
/* Clocking is disabled, attempt to force 133MHz clocking. */
- sil_iowrite8(dev, tmp & ~0x20, scsc_addr);
+ pci_write_config_byte(dev, 0x8A, tmp & ~0x20);
case 0x10:
/* On 133Mhz clocking. */
break;
@@ -501,18 +437,18 @@ static int init_chipset_siimage(struct p
break;
}

- tmp = sil_ioread8(dev, scsc_addr);
+ pci_read_config_byte(dev, 0x8A, &tmp);

- sil_iowrite8 (dev, 0x72, base + 0xA1);
- sil_iowrite16(dev, 0x328A, base + 0xA2);
- sil_iowrite32(dev, 0x62DD62DD, base + 0xA4);
- sil_iowrite32(dev, 0x43924392, base + 0xA8);
- sil_iowrite32(dev, 0x40094009, base + 0xAC);
- sil_iowrite8 (dev, 0x72, base ? (base + 0xE1) : 0xB1);
- sil_iowrite16(dev, 0x328A, base ? (base + 0xE2) : 0xB2);
- sil_iowrite32(dev, 0x62DD62DD, base ? (base + 0xE4) : 0xB4);
- sil_iowrite32(dev, 0x43924392, base ? (base + 0xE8) : 0xB8);
- sil_iowrite32(dev, 0x40094009, base ? (base + 0xEC) : 0xBC);
+ pci_write_config_byte(dev, 0xA1, 0x72);
+ pci_write_config_word(dev, 0xA2, 0x328A);
+ pci_write_config_dword(dev, 0xA4, 0x62DD62DD);
+ pci_write_config_dword(dev, 0xA8, 0x43924392);
+ pci_write_config_dword(dev, 0xAC, 0x40094009);
+ pci_write_config_byte(dev, 0xB1, 0x72);
+ pci_write_config_word(dev, 0xB2, 0x328A);
+ pci_write_config_dword(dev, 0xB4, 0x62DD62DD);
+ pci_write_config_dword(dev, 0xB8, 0x43924392);
+ pci_write_config_dword(dev, 0xBC, 0x40094009);

if (base && pdev_is_sata(dev)) {
writel(0xFFFF0000, ioaddr + 0x108);
@@ -671,7 +607,9 @@ static int sil_cable_detect(ide_hwif_t *
{
struct pci_dev *dev = to_pci_dev(hwif->dev);
unsigned long addr = siimage_selreg(hwif, 0);
- u8 ata66 = sil_ioread8(dev, addr);
+ u8 ata66;
+
+ pci_read_config_byte(dev, addr, &ata66);

return (ata66 & 0x01) ? ATA_CBL_PATA80 : ATA_CBL_PATA40;
}

Subject: [PATCH 5/9] ide2libata: add missing credits

From: Bartlomiej Zolnierkiewicz <[email protected]>
Subject: [PATCH] ide2libata: add missing credits

I forgot to credit myself. :)

Signed-off-by: Bartlomiej Zolnierkiewicz <[email protected]>
---
drivers/ide/aec62xx.c | 4 ++--
drivers/ide/atiixp.c | 4 ++--
drivers/ide/cs5520.c | 3 ++-
drivers/ide/cs5530.c | 4 ++--
drivers/ide/cs5535.c | 4 ++--
drivers/ide/it8213.c | 4 ++--
drivers/ide/it821x.c | 4 ++--
drivers/ide/piix.c | 3 ++-
drivers/ide/sc1200.c | 4 ++--
drivers/ide/sl82c105.c | 2 +-
drivers/ide/slc90e66.c | 3 ++-
drivers/ide/triflex.c | 4 +++-
12 files changed, 24 insertions(+), 19 deletions(-)

Index: b/drivers/ide/aec62xx.c
===================================================================
--- a/drivers/ide/aec62xx.c
+++ b/drivers/ide/aec62xx.c
@@ -1,7 +1,7 @@
/*
* Copyright (C) 1999-2002 Andre Hedrick <[email protected]>
* Copyright (C) 2007 MontaVista Software, Inc. <[email protected]>
- *
+ * Copyright (C) 2007-2010 Bartlomiej Zolnierkiewicz
*/

#include <linux/module.h>
@@ -173,6 +173,6 @@ static void __exit aec62xx_ide_exit(void
module_init(aec62xx_ide_init);
module_exit(aec62xx_ide_exit);

-MODULE_AUTHOR("Andre Hedrick");
+MODULE_AUTHOR("Andre Hedrick, Bartlomiej Zolnierkiewicz");
MODULE_DESCRIPTION("PCI driver module for ARTOP AEC62xx IDE");
MODULE_LICENSE("GPL");
Index: b/drivers/ide/atiixp.c
===================================================================
--- a/drivers/ide/atiixp.c
+++ b/drivers/ide/atiixp.c
@@ -1,6 +1,6 @@
/*
* Copyright (C) 2003 ATI Inc. <[email protected]>
- * Copyright (C) 2004,2007 Bartlomiej Zolnierkiewicz
+ * Copyright (C) 2004,2007-2010 Bartlomiej Zolnierkiewicz
*/

#include <linux/types.h>
@@ -88,6 +88,6 @@ static void __exit atiixp_ide_exit(void)
module_init(atiixp_ide_init);
module_exit(atiixp_ide_exit);

-MODULE_AUTHOR("HUI YU");
+MODULE_AUTHOR("HUI YU, Bartlomiej Zolnierkiewicz");
MODULE_DESCRIPTION("PCI driver module for ATI IXP IDE");
MODULE_LICENSE("GPL");
Index: b/drivers/ide/cs5520.c
===================================================================
--- a/drivers/ide/cs5520.c
+++ b/drivers/ide/cs5520.c
@@ -13,6 +13,7 @@
* *** This driver is strictly experimental ***
*
* (c) Copyright Red Hat Inc 2002
+ * (c) Copyright Bartlomiej Zolnierkiewicz 2010
*
* This program is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License as published by the
@@ -127,6 +128,6 @@ static int __init cs5520_ide_init(void)

module_init(cs5520_ide_init);

-MODULE_AUTHOR("Alan Cox");
+MODULE_AUTHOR("Alan Cox, Bartlomiej Zolnierkiewicz");
MODULE_DESCRIPTION("PCI driver module for Cyrix 5510/5520 IDE");
MODULE_LICENSE("GPL");
Index: b/drivers/ide/cs5530.c
===================================================================
--- a/drivers/ide/cs5530.c
+++ b/drivers/ide/cs5530.c
@@ -1,7 +1,7 @@
/*
* Copyright (C) 2000 Andre Hedrick <[email protected]>
* Copyright (C) 2000 Mark Lord <[email protected]>
- * Copyright (C) 2007 Bartlomiej Zolnierkiewicz
+ * Copyright (C) 2007-2010 Bartlomiej Zolnierkiewicz
*
* May be copied or modified under the terms of the GNU General Public License
*
@@ -173,6 +173,6 @@ static void __exit cs5530_ide_exit(void)
module_init(cs5530_ide_init);
module_exit(cs5530_ide_exit);

-MODULE_AUTHOR("Mark Lord");
+MODULE_AUTHOR("Mark Lord, Bartlomiej Zolnierkiewicz");
MODULE_DESCRIPTION("PCI driver module for Cyrix/NS 5530 IDE");
MODULE_LICENSE("GPL");
Index: b/drivers/ide/cs5535.c
===================================================================
--- a/drivers/ide/cs5535.c
+++ b/drivers/ide/cs5535.c
@@ -1,6 +1,6 @@
/*
* Copyright (C) 2004-2005 Advanced Micro Devices, Inc.
- * Copyright (C) 2007 Bartlomiej Zolnierkiewicz
+ * Copyright (C) 2007-2010 Bartlomiej Zolnierkiewicz
*
* History:
* 09/20/2005 - Jaya Kumar <[email protected]>
@@ -82,6 +82,6 @@ static void __exit cs5535_ide_exit(void)
module_init(cs5535_ide_init);
module_exit(cs5535_ide_exit);

-MODULE_AUTHOR("AMD");
+MODULE_AUTHOR("AMD, Bartlomiej Zolnierkiewicz");
MODULE_DESCRIPTION("PCI driver module for AMD/NS CS5535 IDE");
MODULE_LICENSE("GPL");
Index: b/drivers/ide/it8213.c
===================================================================
--- a/drivers/ide/it8213.c
+++ b/drivers/ide/it8213.c
@@ -3,7 +3,7 @@
*
* Copyright (C) 2006 Jack Lee
* Copyright (C) 2006 Alan Cox
- * Copyright (C) 2007 Bartlomiej Zolnierkiewicz
+ * Copyright (C) 2007-2010 Bartlomiej Zolnierkiewicz
*/

#include <linux/kernel.h>
@@ -79,6 +79,6 @@ static void __exit it8213_ide_exit(void)
module_init(it8213_ide_init);
module_exit(it8213_ide_exit);

-MODULE_AUTHOR("Jack Lee, Alan Cox");
+MODULE_AUTHOR("Jack Lee, Alan Cox, Bartlomiej Zolnierkiewicz");
MODULE_DESCRIPTION("PCI driver module for the ITE 8213");
MODULE_LICENSE("GPL");
Index: b/drivers/ide/it821x.c
===================================================================
--- a/drivers/ide/it821x.c
+++ b/drivers/ide/it821x.c
@@ -1,6 +1,6 @@
/*
* Copyright (C) 2004 Red Hat
- * Copyright (C) 2007 Bartlomiej Zolnierkiewicz
+ * Copyright (C) 2007-2010 Bartlomiej Zolnierkiewicz
*
* May be copied or modified under the terms of the GNU General Public License
* Based in part on the ITE vendor provided SCSI driver.
@@ -352,6 +352,6 @@ module_exit(it821x_ide_exit);
module_param_named(noraid, it8212_noraid, int, S_IRUGO);
MODULE_PARM_DESC(noraid, "Force card into bypass mode");

-MODULE_AUTHOR("Alan Cox");
+MODULE_AUTHOR("Alan Cox, Bartlomiej Zolnierkiewicz");
MODULE_DESCRIPTION("PCI driver module for the ITE 821x");
MODULE_LICENSE("GPL");
Index: b/drivers/ide/piix.c
===================================================================
--- a/drivers/ide/piix.c
+++ b/drivers/ide/piix.c
@@ -3,6 +3,7 @@
* Copyright (C) 1998-2000 Andre Hedrick <[email protected]>
* Copyright (C) 2003 Red Hat
* Copyright (C) 2006-2007 MontaVista Software, Inc. <[email protected]>
+ * Copyright (C) 2007-2010 Bartlomiej Zolnierkiewicz
*
* May be copied or modified under the terms of the GNU General Public License
*/
@@ -230,6 +231,6 @@ static void __exit piix_ide_exit(void)
module_init(piix_ide_init);
module_exit(piix_ide_exit);

-MODULE_AUTHOR("Andre Hedrick, Andrzej Krzysztofowicz");
+MODULE_AUTHOR("Andre Hedrick, Andrzej Krzysztofowicz, Bartlomiej Zolnierkiewicz");
MODULE_DESCRIPTION("PCI driver module for Intel PIIX IDE");
MODULE_LICENSE("GPL");
Index: b/drivers/ide/sc1200.c
===================================================================
--- a/drivers/ide/sc1200.c
+++ b/drivers/ide/sc1200.c
@@ -1,6 +1,6 @@
/*
* Copyright (C) 2000-2002 Mark Lord <[email protected]>
- * Copyright (C) 2007 Bartlomiej Zolnierkiewicz
+ * Copyright (C) 2007-2010 Bartlomiej Zolnierkiewicz
*
* May be copied or modified under the terms of the GNU General Public License
*
@@ -244,6 +244,6 @@ static void __exit sc1200_ide_exit(void)
module_init(sc1200_ide_init);
module_exit(sc1200_ide_exit);

-MODULE_AUTHOR("Mark Lord");
+MODULE_AUTHOR("Mark Lord, Bartlomiej Zolnierkiewicz");
MODULE_DESCRIPTION("PCI driver module for NS SC1200 IDE");
MODULE_LICENSE("GPL");
Index: b/drivers/ide/sl82c105.c
===================================================================
--- a/drivers/ide/sl82c105.c
+++ b/drivers/ide/sl82c105.c
@@ -11,7 +11,7 @@
* -- Benjamin Herrenschmidt (01/11/03) [email protected]
*
* Copyright (C) 2006-2007,2009 MontaVista Software, Inc. <[email protected]>
- * Copyright (C) 2007 Bartlomiej Zolnierkiewicz
+ * Copyright (C) 2007-2010 Bartlomiej Zolnierkiewicz
*/

#include <linux/types.h>
Index: b/drivers/ide/slc90e66.c
===================================================================
--- a/drivers/ide/slc90e66.c
+++ b/drivers/ide/slc90e66.c
@@ -1,6 +1,7 @@
/*
* Copyright (C) 2000-2002 Andre Hedrick <[email protected]>
* Copyright (C) 2006-2007 MontaVista Software, Inc. <[email protected]>
+ * Copyright (C) 2007-2010 Bartlomiej Zolnierkiewicz
*
* This is a look-alike variation of the ICH0 PIIX4 Ultra-66,
* but this keeps the ISA-Bridge and slots alive.
@@ -68,6 +69,6 @@ static void __exit slc90e66_ide_exit(voi
module_init(slc90e66_ide_init);
module_exit(slc90e66_ide_exit);

-MODULE_AUTHOR("Andre Hedrick");
+MODULE_AUTHOR("Andre Hedrick, Bartlomiej Zolnierkiewicz");
MODULE_DESCRIPTION("PCI driver module for SLC90E66 IDE");
MODULE_LICENSE("GPL");
Index: b/drivers/ide/triflex.c
===================================================================
--- a/drivers/ide/triflex.c
+++ b/drivers/ide/triflex.c
@@ -6,6 +6,8 @@
* Copyright (C) 2002 Hewlett-Packard Development Group, L.P.
* Author: Torben Mathiasen <[email protected]>
*
+ * Copyright (C) 2007-2010 Bartlomiej Zolnierkiewicz
+ *
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License version 2 as
* published by the Free Software Foundation.
@@ -90,7 +92,7 @@ static void __exit triflex_ide_exit(void
module_init(triflex_ide_init);
module_exit(triflex_ide_exit);

-MODULE_AUTHOR("Torben Mathiasen");
+MODULE_AUTHOR("Torben Mathiasen, Bartlomiej Zolnierkiewicz");
MODULE_DESCRIPTION("PCI driver module for Compaq Triflex IDE");
MODULE_LICENSE("GPL");

Subject: [PATCH 9/9] siimage: convert to ide2libata

From: Bartlomiej Zolnierkiewicz <[email protected]>
Subject: [PATCH] siimage: convert to ide2libata

While at it:
- fix documentation for sil680_sel[reg,dev]() and sil680_set_[pio,dma]mode()
- constify tables in sil680_set_[pio,dma]mode()

Signed-off-by: Bartlomiej Zolnierkiewicz <[email protected]>
---
drivers/ata/pata_sil680.h | 85 +++++++++++----
drivers/ide/siimage.c | 260 +---------------------------------------------
2 files changed, 78 insertions(+), 267 deletions(-)

Index: b/drivers/ata/pata_sil680.h
===================================================================
--- a/drivers/ata/pata_sil680.h
+++ b/drivers/ata/pata_sil680.h
@@ -3,8 +3,9 @@
* @hwif: interface
* @r: config offset
*
- * Turn a config register offset into the right address in either
- * PCI space or MMIO space to access the control register in question
+ * Turn a config register offset into the right address in PCI space
+ * MMIO space to access the control register in question.
+ *
* Thankfully this is a configuration operation so isnt performance
* criticial.
*/
@@ -21,9 +22,9 @@ static unsigned long sil680_selreg(struc
* @hwif: interface
* @r: config offset
*
- * Turn a config register offset into the right address in either
- * PCI space or MMIO space to access the control register in question
- * including accounting for the unit shift.
+ * Turn a config register offset into the right address in PCI space
+ * to access the control register in question including accounting for
+ * the unit shift.
*/

static unsigned long sil680_seldev(struct ata_port *ap, struct ata_device *adev, int r)
@@ -56,7 +57,7 @@ static int sil680_cable_detect(struct at
}

/**
- * sil680_set_piomode - set initial PIO mode data
+ * sil680_set_piomode - set PIO mode data
* @ap: ATA interface
* @adev: ATA device
*
@@ -67,8 +68,8 @@ static int sil680_cable_detect(struct at

static void sil680_set_piomode(struct ata_port *ap, struct ata_device *adev)
{
- static u16 speed_p[5] = { 0x328A, 0x2283, 0x1104, 0x10C3, 0x10C1 };
- static u16 speed_t[5] = { 0x328A, 0x2283, 0x1281, 0x10C3, 0x10C1 };
+ static const u16 speed_p[5] = { 0x328A, 0x2283, 0x1104, 0x10C3, 0x10C1 };
+ static const u16 speed_t[5] = { 0x328A, 0x2283, 0x1281, 0x10C3, 0x10C1 };

unsigned long tfaddr = sil680_selreg(ap, 0x02);
unsigned long addr = sil680_seldev(ap, adev, 0x04);
@@ -103,22 +104,23 @@ static void sil680_set_piomode(struct at
}

/**
- * sil680_set_dmamode - set initial DMA mode data
+ * sil680_set_dmamode - set DMA mode data
* @ap: ATA interface
* @adev: ATA device
*
- * Program the MWDMA/UDMA modes for the sil680 k
- * chipset. The MWDMA mode values are pulled from a lookup table
+ * Program the MWDMA/UDMA modes for the sil680 chipset.
+ *
+ * The MWDMA mode values are pulled from a lookup table
* while the chipset uses mode number for UDMA.
*/

static void sil680_set_dmamode(struct ata_port *ap, struct ata_device *adev)
{
- static u8 ultra_table[2][7] = {
+ static const u8 ultra_table[2][7] = {
{ 0x0C, 0x07, 0x05, 0x04, 0x02, 0x01, 0xFF }, /* 100MHz */
{ 0x0F, 0x0B, 0x07, 0x05, 0x03, 0x02, 0x01 }, /* 133Mhz */
};
- static u16 dma_table[3] = { 0x2208, 0x10C2, 0x10C1 };
+ static const u16 dma_table[3] = { 0x2208, 0x10C2, 0x10C1 };

struct pci_dev *pdev = to_pci_dev(ap->host->dev);
unsigned long ma = sil680_seldev(ap, adev, 0x08);
@@ -139,7 +141,9 @@ static void sil680_set_dmamode(struct at

/* Extract scsc */
scsc = (scsc & 0x30) ? 1 : 0;
-
+#ifdef __IDE2LIBATA
+ scsc = is_sata(ap) ? 1 : scsc;
+#endif
if (adev->dma_mode >= XFER_UDMA_0) {
multi = 0x10C1;
ultra |= ultra_table[scsc][adev->dma_mode - XFER_UDMA_0];
@@ -164,17 +168,42 @@ static void sil680_set_dmamode(struct at

static u8 sil680_init_chip(struct pci_dev *pdev, int *try_mmio)
{
+#ifdef __IDE2LIBATA
+ struct ide_host *host = pci_get_drvdata(pdev);
+ void __iomem *ioaddr = host->host_priv;
+ unsigned long base;
+#endif
u8 tmpbyte = 0;

/* FIXME: double check */
pci_write_config_byte(pdev, PCI_CACHE_LINE_SIZE,
pdev->revision ? 1 : 255);
-
+#ifdef __IDE2LIBATA
+ if (ioaddr)
+ pci_set_master(pdev);
+
+ base = (unsigned long)ioaddr;
+
+ if (ioaddr && pdev_is_sata(pdev)) {
+ u32 tmp32, irq_mask;
+
+ /* make sure IDE0/1 interrupts are not masked */
+ irq_mask = (1 << 22) | (1 << 23);
+ tmp32 = readl(ioaddr + 0x48);
+ if (tmp32 & irq_mask) {
+ tmp32 &= ~irq_mask;
+ writel(tmp32, ioaddr + 0x48);
+ readl(ioaddr + 0x48); /* flush */
+ }
+ writel(0, ioaddr + 0x148);
+ writel(0, ioaddr + 0x1C8);
+ }
+#endif
pci_write_config_byte(pdev, 0x80, 0x00);
pci_write_config_byte(pdev, 0x84, 0x00);

pci_read_config_byte(pdev, 0x8A, &tmpbyte);
-
+#ifndef __IDE2LIBATA
dev_dbg(&pdev->dev, "sil680: BA5_EN = %d clock = %02X\n",
tmpbyte & 1, tmpbyte & 0x30);

@@ -183,7 +212,7 @@ static u8 sil680_init_chip(struct pci_de
if (machine_is(cell))
*try_mmio = (tmpbyte & 1) || pci_resource_start(pdev, 5);
#endif
-
+#endif
switch (tmpbyte & 0x30) {
case 0x00:
/* 133 clock attempt to force it on */
@@ -203,9 +232,10 @@ static u8 sil680_init_chip(struct pci_de
}

pci_read_config_byte(pdev, 0x8A, &tmpbyte);
+#ifndef __IDE2LIBATA
dev_dbg(&pdev->dev, "sil680: BA5_EN = %d clock = %02X\n",
tmpbyte & 1, tmpbyte & 0x30);
-
+#endif
pci_write_config_byte(pdev, 0xA1, 0x72);
pci_write_config_word(pdev, 0xA2, 0x328A);
pci_write_config_dword(pdev, 0xA4, 0x62DD62DD);
@@ -217,6 +247,7 @@ static u8 sil680_init_chip(struct pci_de
pci_write_config_dword(pdev, 0xB8, 0x43924392);
pci_write_config_dword(pdev, 0xBC, 0x40094009);

+#ifndef __IDE2LIBATA
switch (tmpbyte & 0x30) {
case 0x00:
printk(KERN_INFO "sil680: 100MHz clock.\n");
@@ -231,5 +262,23 @@ static u8 sil680_init_chip(struct pci_de
case 0x30:
printk(KERN_ERR "sil680: Clock disabled ?\n");
}
+#else
+ if (base && pdev_is_sata(pdev)) {
+ writel(0xFFFF0000, ioaddr + 0x108);
+ writel(0xFFFF0000, ioaddr + 0x188);
+ writel(0x00680000, ioaddr + 0x148);
+ writel(0x00680000, ioaddr + 0x1C8);
+ }
+
+ /* report the clocking mode of the controller */
+ if (!pdev_is_sata(pdev)) {
+ static const char *clk_str[]
+ = { "== 100", "== 133", "== 2X PCI", "DISABLED!" };
+
+ tmpbyte >>= 4;
+ printk(KERN_INFO DRV_NAME " %s: BASE CLOCK %s\n",
+ pci_name(pdev), clk_str[tmpbyte & 3]);
+ }
+#endif
return tmpbyte & 0x30;
}
Index: b/drivers/ide/siimage.c
===================================================================
--- a/drivers/ide/siimage.c
+++ b/drivers/ide/siimage.c
@@ -79,47 +79,6 @@ static inline int is_sata(ide_hwif_t *hw
}

/**
- * siimage_selreg - return register base
- * @hwif: interface
- * @r: config offset
- *
- * Turn a config register offset into the right address in PCI space
- * to access the control register in question.
- *
- * Thankfully this is a configuration operation, so isn't performance
- * critical.
- */
-
-static unsigned long siimage_selreg(ide_hwif_t *hwif, int r)
-{
- unsigned long base = 0xA0 + r;
-
- base += hwif->channel << 4;
- return base;
-}
-
-/**
- * siimage_seldev - return register base
- * @hwif: interface
- * @r: config offset
- *
- * Turn a config register offset into the right address in PCI space
- * to access the control register in question including accounting for
- * the unit shift.
- */
-
-static inline unsigned long siimage_seldev(ide_drive_t *drive, int r)
-{
- ide_hwif_t *hwif = drive->hwif;
- unsigned long base = 0xA0 + r;
- u8 unit = drive->dn & 1;
-
- base += hwif->channel << 4;
- base |= unit << unit;
- return base;
-}
-
-/**
* sil_udma_filter - compute UDMA mask
* @drive: IDE device
*
@@ -161,110 +120,8 @@ static u8 sil_sata_udma_filter(ide_drive
return strstr(m, "Maxtor") ? ATA_UDMA5 : ATA_UDMA6;
}

-/**
- * sil_set_pio_mode - set host controller for PIO mode
- * @hwif: port
- * @drive: drive
- *
- * Load the timing settings for this device mode into the
- * controller.
- */
-
-static void sil_set_pio_mode(ide_hwif_t *hwif, ide_drive_t *drive)
-{
- static const u16 tf_speed[] = { 0x328a, 0x2283, 0x1281, 0x10c3, 0x10c1 };
- static const u16 data_speed[] = { 0x328a, 0x2283, 0x1104, 0x10c3, 0x10c1 };
-
- struct pci_dev *dev = to_pci_dev(hwif->dev);
- ide_drive_t *pair = ide_get_pair_dev(drive);
- u32 speedt = 0;
- u16 speedp = 0;
- unsigned long addr = siimage_seldev(drive, 0x04);
- unsigned long tfaddr = siimage_selreg(hwif, 0x02);
- const u8 pio = drive->pio_mode - XFER_PIO_0;
- u8 tf_pio = pio;
- u8 addr_mask = hwif->channel ? 0x84 : 0x80;
- u8 mode = 0;
- u8 unit = drive->dn & 1;
-
- /* trim *taskfile* PIO to the slowest of the master/slave */
- if (pair) {
- u8 pair_pio = pair->pio_mode - XFER_PIO_0;
-
- if (pair_pio < tf_pio)
- tf_pio = pair_pio;
- }
-
- /* cheat for now and use the docs */
- speedp = data_speed[pio];
- speedt = tf_speed[tf_pio];
-
- pci_write_config_word(dev, addr, speedp);
- pci_write_config_word(dev, tfaddr, speedt);
-
- /* now set up IORDY */
- pci_read_config_word(dev, tfaddr - 2, &speedp);
- speedp &= ~0x200;
-
- pci_read_config_byte(dev, addr_mask, &mode);
- mode &= ~(unit ? 0x30 : 0x03);
-
- if (ide_pio_need_iordy(drive, pio)) {
- speedp |= 0x200;
- mode |= unit ? 0x10 : 0x01;
- }
-
- pci_write_config_word(dev, tfaddr - 2, speedp);
- pci_write_config_byte(dev, addr_mask, mode);
-}
-
-/**
- * sil_set_dma_mode - set host controller for DMA mode
- * @hwif: port
- * @drive: drive
- *
- * Tune the SiI chipset for the desired DMA mode.
- */
-
-static void sil_set_dma_mode(ide_hwif_t *hwif, ide_drive_t *drive)
-{
- static const u8 ultra6[] = { 0x0F, 0x0B, 0x07, 0x05, 0x03, 0x02, 0x01 };
- static const u8 ultra5[] = { 0x0C, 0x07, 0x05, 0x04, 0x02, 0x01 };
- static const u16 dma[] = { 0x2208, 0x10C2, 0x10C1 };
-
- struct pci_dev *dev = to_pci_dev(hwif->dev);
- u16 ultra = 0, multi = 0;
- u8 mode = 0, unit = drive->dn & 1;
- u8 scsc = 0, addr_mask = hwif->channel ? 0x84 : 0x80;
- unsigned long ma = siimage_seldev(drive, 0x08);
- unsigned long ua = siimage_seldev(drive, 0x0C);
- const u8 speed = drive->dma_mode;
-
- pci_read_config_byte(dev, 0x8A, &scsc);
- pci_read_config_byte(dev, addr_mask, &mode);
- pci_read_config_word(dev, ma, &multi);
- pci_read_config_word(dev, ua, &ultra);
-
- mode &= ~(unit ? 0x30 : 0x03);
- ultra &= ~0x3F;
- scsc = ((scsc & 0x30) == 0x00) ? 0 : 1;
-
- scsc = is_sata(hwif) ? 1 : scsc;
-
- if (speed >= XFER_UDMA_0) {
- multi = dma[2];
- ultra |= scsc ? ultra6[speed - XFER_UDMA_0] :
- ultra5[speed - XFER_UDMA_0];
- mode |= unit ? 0x30 : 0x03;
- } else {
- multi = dma[speed - XFER_MW_DMA_0];
- mode |= unit ? 0x20 : 0x02;
- }
-
- pci_write_config_byte(dev, addr_mask, mode);
- pci_write_config_word(dev, ma, multi);
- pci_write_config_word(dev, ua, ultra);
-}
+#include <linux/ide2libata.h>
+#include "../ata/pata_sil680.h"

static int sil_test_irq(ide_hwif_t *hwif)
{
@@ -277,7 +134,7 @@ static int sil_test_irq(ide_hwif_t *hwif
addr += 0xA0 + 1 + (hwif->channel << 6);
val = readb((void __iomem *)addr);
} else {
- addr = siimage_selreg(hwif, 1);
+ addr = sil680_selreg(hwif, 1);
pci_read_config_byte(dev, addr, &val);
}

@@ -389,84 +246,7 @@ static void sil_sata_pre_reset(ide_drive

static int init_chipset_siimage(struct pci_dev *dev)
{
- struct ide_host *host = pci_get_drvdata(dev);
- void __iomem *ioaddr = host->host_priv;
- unsigned long base;
- u8 rev = dev->revision, tmp;
-
- pci_write_config_byte(dev, PCI_CACHE_LINE_SIZE, rev ? 1 : 255);
-
- if (ioaddr)
- pci_set_master(dev);
-
- base = (unsigned long)ioaddr;
-
- if (ioaddr && pdev_is_sata(dev)) {
- u32 tmp32, irq_mask;
-
- /* make sure IDE0/1 interrupts are not masked */
- irq_mask = (1 << 22) | (1 << 23);
- tmp32 = readl(ioaddr + 0x48);
- if (tmp32 & irq_mask) {
- tmp32 &= ~irq_mask;
- writel(tmp32, ioaddr + 0x48);
- readl(ioaddr + 0x48); /* flush */
- }
- writel(0, ioaddr + 0x148);
- writel(0, ioaddr + 0x1C8);
- }
-
- pci_write_config_byte(dev, 0x80, 0x00);
- pci_write_config_byte(dev, 0x84, 0x00);
-
- pci_read_config_byte(dev, 0x8A, &tmp);
-
- switch (tmp & 0x30) {
- case 0x00:
- /* On 100 MHz clocking, try and switch to 133 MHz */
- pci_write_config_byte(dev, 0x8A, tmp | 0x10);
- break;
- case 0x30:
- /* Clocking is disabled, attempt to force 133MHz clocking. */
- pci_write_config_byte(dev, 0x8A, tmp & ~0x20);
- case 0x10:
- /* On 133Mhz clocking. */
- break;
- case 0x20:
- /* On PCIx2 clocking. */
- break;
- }
-
- pci_read_config_byte(dev, 0x8A, &tmp);
-
- pci_write_config_byte(dev, 0xA1, 0x72);
- pci_write_config_word(dev, 0xA2, 0x328A);
- pci_write_config_dword(dev, 0xA4, 0x62DD62DD);
- pci_write_config_dword(dev, 0xA8, 0x43924392);
- pci_write_config_dword(dev, 0xAC, 0x40094009);
- pci_write_config_byte(dev, 0xB1, 0x72);
- pci_write_config_word(dev, 0xB2, 0x328A);
- pci_write_config_dword(dev, 0xB4, 0x62DD62DD);
- pci_write_config_dword(dev, 0xB8, 0x43924392);
- pci_write_config_dword(dev, 0xBC, 0x40094009);
-
- if (base && pdev_is_sata(dev)) {
- writel(0xFFFF0000, ioaddr + 0x108);
- writel(0xFFFF0000, ioaddr + 0x188);
- writel(0x00680000, ioaddr + 0x148);
- writel(0x00680000, ioaddr + 0x1C8);
- }
-
- /* report the clocking mode of the controller */
- if (!pdev_is_sata(dev)) {
- static const char *clk_str[] =
- { "== 100", "== 133", "== 2X PCI", "DISABLED!" };
-
- tmp >>= 4;
- printk(KERN_INFO DRV_NAME " %s: BASE CLOCK %s\n",
- pci_name(dev), clk_str[tmp & 3]);
- }
-
+ (void)sil680_init_chip(dev, NULL);
return 0;
}

@@ -596,42 +376,24 @@ static void __devinit init_iops_siimage(
init_mmio_iops_siimage(hwif);
}

-/**
- * sil_cable_detect - cable detection
- * @hwif: interface to check
- *
- * Check for the presence of an ATA66 capable cable on the interface.
- */
-
-static int sil_cable_detect(ide_hwif_t *hwif)
-{
- struct pci_dev *dev = to_pci_dev(hwif->dev);
- unsigned long addr = siimage_selreg(hwif, 0);
- u8 ata66;
-
- pci_read_config_byte(dev, addr, &ata66);
-
- return (ata66 & 0x01) ? ATA_CBL_PATA80 : ATA_CBL_PATA40;
-}
-
static const struct ide_port_ops sil_pata_port_ops = {
- .set_pio_mode = sil_set_pio_mode,
- .set_dma_mode = sil_set_dma_mode,
+ .set_pio_mode = sil680_set_piomode,
+ .set_dma_mode = sil680_set_dmamode,
.quirkproc = sil_quirkproc,
.test_irq = sil_test_irq,
.udma_filter = sil_pata_udma_filter,
- .cable_detect = sil_cable_detect,
+ .cable_detect = sil680_cable_detect,
};

static const struct ide_port_ops sil_sata_port_ops = {
- .set_pio_mode = sil_set_pio_mode,
- .set_dma_mode = sil_set_dma_mode,
+ .set_pio_mode = sil680_set_piomode,
+ .set_dma_mode = sil680_set_dmamode,
.reset_poll = sil_sata_reset_poll,
.pre_reset = sil_sata_pre_reset,
.quirkproc = sil_quirkproc,
.test_irq = sil_test_irq,
.udma_filter = sil_sata_udma_filter,
- .cable_detect = sil_cable_detect,
+ .cable_detect = sil680_cable_detect,
};

static const struct ide_dma_ops sil_dma_ops = {
@@ -778,6 +540,6 @@ static void __exit siimage_ide_exit(void
module_init(siimage_ide_init);
module_exit(siimage_ide_exit);

-MODULE_AUTHOR("Andre Hedrick, Alan Cox");
+MODULE_AUTHOR("Andre Hedrick, Alan Cox, Bartlomiej Zolnierkiewicz");
MODULE_DESCRIPTION("PCI driver module for SiI IDE");
MODULE_LICENSE("GPL");

Subject: [PATCH 8/9] pata_sil680: move code to be re-used by ide2libata to pata_sil680.h

From: Bartlomiej Zolnierkiewicz <[email protected]>
Subject: [PATCH] pata_sil680: move code to be re-used by ide2libata to pata_sil680.h

Signed-off-by: Bartlomiej Zolnierkiewicz <[email protected]>
---
drivers/ata/pata_sil680.c | 236 ----------------------------------------------
drivers/ata/pata_sil680.h | 235 +++++++++++++++++++++++++++++++++++++++++++++
2 files changed, 236 insertions(+), 235 deletions(-)

Index: b/drivers/ata/pata_sil680.c
===================================================================
--- a/drivers/ata/pata_sil680.c
+++ b/drivers/ata/pata_sil680.c
@@ -36,160 +36,7 @@

#define SIL680_MMIO_BAR 5

-/**
- * sil680_selreg - return register base
- * @hwif: interface
- * @r: config offset
- *
- * Turn a config register offset into the right address in either
- * PCI space or MMIO space to access the control register in question
- * Thankfully this is a configuration operation so isnt performance
- * criticial.
- */
-
-static unsigned long sil680_selreg(struct ata_port *ap, int r)
-{
- unsigned long base = 0xA0 + r;
- base += (ap->port_no << 4);
- return base;
-}
-
-/**
- * sil680_seldev - return register base
- * @hwif: interface
- * @r: config offset
- *
- * Turn a config register offset into the right address in either
- * PCI space or MMIO space to access the control register in question
- * including accounting for the unit shift.
- */
-
-static unsigned long sil680_seldev(struct ata_port *ap, struct ata_device *adev, int r)
-{
- unsigned long base = 0xA0 + r;
- base += (ap->port_no << 4);
- base |= adev->devno ? 2 : 0;
- return base;
-}
-
-
-/**
- * sil680_cable_detect - cable detection
- * @ap: ATA port
- *
- * Perform cable detection. The SIL680 stores this in PCI config
- * space for us.
- */
-
-static int sil680_cable_detect(struct ata_port *ap)
-{
- struct pci_dev *pdev = to_pci_dev(ap->host->dev);
- unsigned long addr = sil680_selreg(ap, 0);
- u8 ata66;
- pci_read_config_byte(pdev, addr, &ata66);
- if (ata66 & 1)
- return ATA_CBL_PATA80;
- else
- return ATA_CBL_PATA40;
-}
-
-/**
- * sil680_set_piomode - set initial PIO mode data
- * @ap: ATA interface
- * @adev: ATA device
- *
- * Program the SIL680 registers for PIO mode. Note that the task speed
- * registers are shared between the devices so we must pick the lowest
- * mode for command work.
- */
-
-static void sil680_set_piomode(struct ata_port *ap, struct ata_device *adev)
-{
- static u16 speed_p[5] = { 0x328A, 0x2283, 0x1104, 0x10C3, 0x10C1 };
- static u16 speed_t[5] = { 0x328A, 0x2283, 0x1281, 0x10C3, 0x10C1 };
-
- unsigned long tfaddr = sil680_selreg(ap, 0x02);
- unsigned long addr = sil680_seldev(ap, adev, 0x04);
- unsigned long addr_mask = 0x80 + 4 * ap->port_no;
- struct pci_dev *pdev = to_pci_dev(ap->host->dev);
- int pio = adev->pio_mode - XFER_PIO_0;
- int lowest_pio = pio;
- int port_shift = 4 * adev->devno;
- u16 reg;
- u8 mode;
-
- struct ata_device *pair = ata_dev_pair(adev);
-
- if (pair != NULL && adev->pio_mode > pair->pio_mode)
- lowest_pio = pair->pio_mode - XFER_PIO_0;
-
- pci_write_config_word(pdev, addr, speed_p[pio]);
- pci_write_config_word(pdev, tfaddr, speed_t[lowest_pio]);
-
- pci_read_config_word(pdev, tfaddr-2, &reg);
- pci_read_config_byte(pdev, addr_mask, &mode);
-
- reg &= ~0x0200; /* Clear IORDY */
- mode &= ~(3 << port_shift); /* Clear IORDY and DMA bits */
-
- if (ata_pio_need_iordy(adev)) {
- reg |= 0x0200; /* Enable IORDY */
- mode |= 1 << port_shift;
- }
- pci_write_config_word(pdev, tfaddr-2, reg);
- pci_write_config_byte(pdev, addr_mask, mode);
-}
-
-/**
- * sil680_set_dmamode - set initial DMA mode data
- * @ap: ATA interface
- * @adev: ATA device
- *
- * Program the MWDMA/UDMA modes for the sil680 k
- * chipset. The MWDMA mode values are pulled from a lookup table
- * while the chipset uses mode number for UDMA.
- */
-
-static void sil680_set_dmamode(struct ata_port *ap, struct ata_device *adev)
-{
- static u8 ultra_table[2][7] = {
- { 0x0C, 0x07, 0x05, 0x04, 0x02, 0x01, 0xFF }, /* 100MHz */
- { 0x0F, 0x0B, 0x07, 0x05, 0x03, 0x02, 0x01 }, /* 133Mhz */
- };
- static u16 dma_table[3] = { 0x2208, 0x10C2, 0x10C1 };
-
- struct pci_dev *pdev = to_pci_dev(ap->host->dev);
- unsigned long ma = sil680_seldev(ap, adev, 0x08);
- unsigned long ua = sil680_seldev(ap, adev, 0x0C);
- unsigned long addr_mask = 0x80 + 4 * ap->port_no;
- int port_shift = adev->devno * 4;
- u8 scsc, mode;
- u16 multi, ultra;
-
- pci_read_config_byte(pdev, 0x8A, &scsc);
- pci_read_config_byte(pdev, addr_mask, &mode);
- pci_read_config_word(pdev, ma, &multi);
- pci_read_config_word(pdev, ua, &ultra);
-
- /* Mask timing bits */
- ultra &= ~0x3F;
- mode &= ~(0x03 << port_shift);
-
- /* Extract scsc */
- scsc = (scsc & 0x30) ? 1 : 0;
-
- if (adev->dma_mode >= XFER_UDMA_0) {
- multi = 0x10C1;
- ultra |= ultra_table[scsc][adev->dma_mode - XFER_UDMA_0];
- mode |= (0x03 << port_shift);
- } else {
- multi = dma_table[adev->dma_mode - XFER_MW_DMA_0];
- mode |= (0x02 << port_shift);
- }
- pci_write_config_byte(pdev, addr_mask, mode);
- pci_write_config_word(pdev, ma, multi);
- pci_write_config_word(pdev, ua, ultra);
-}
+#include "pata_sil680.h"

static struct scsi_host_template sil680_sht = {
ATA_BMDMA_SHT(DRV_NAME),
@@ -202,87 +49,6 @@ static struct ata_port_operations sil680
.set_dmamode = sil680_set_dmamode,
};

-/**
- * sil680_init_chip - chip setup
- * @pdev: PCI device
- *
- * Perform all the chip setup which must be done both when the device
- * is powered up on boot and when we resume in case we resumed from RAM.
- * Returns the final clock settings.
- */
-
-static u8 sil680_init_chip(struct pci_dev *pdev, int *try_mmio)
-{
- u8 tmpbyte = 0;
-
- /* FIXME: double check */
- pci_write_config_byte(pdev, PCI_CACHE_LINE_SIZE,
- pdev->revision ? 1 : 255);
-
- pci_write_config_byte(pdev, 0x80, 0x00);
- pci_write_config_byte(pdev, 0x84, 0x00);
-
- pci_read_config_byte(pdev, 0x8A, &tmpbyte);
-
- dev_dbg(&pdev->dev, "sil680: BA5_EN = %d clock = %02X\n",
- tmpbyte & 1, tmpbyte & 0x30);
-
- *try_mmio = 0;
-#ifdef CONFIG_PPC
- if (machine_is(cell))
- *try_mmio = (tmpbyte & 1) || pci_resource_start(pdev, 5);
-#endif
-
- switch (tmpbyte & 0x30) {
- case 0x00:
- /* 133 clock attempt to force it on */
- pci_write_config_byte(pdev, 0x8A, tmpbyte|0x10);
- break;
- case 0x30:
- /* if clocking is disabled */
- /* 133 clock attempt to force it on */
- pci_write_config_byte(pdev, 0x8A, tmpbyte & ~0x20);
- break;
- case 0x10:
- /* 133 already */
- break;
- case 0x20:
- /* BIOS set PCI x2 clocking */
- break;
- }
-
- pci_read_config_byte(pdev, 0x8A, &tmpbyte);
- dev_dbg(&pdev->dev, "sil680: BA5_EN = %d clock = %02X\n",
- tmpbyte & 1, tmpbyte & 0x30);
-
- pci_write_config_byte(pdev, 0xA1, 0x72);
- pci_write_config_word(pdev, 0xA2, 0x328A);
- pci_write_config_dword(pdev, 0xA4, 0x62DD62DD);
- pci_write_config_dword(pdev, 0xA8, 0x43924392);
- pci_write_config_dword(pdev, 0xAC, 0x40094009);
- pci_write_config_byte(pdev, 0xB1, 0x72);
- pci_write_config_word(pdev, 0xB2, 0x328A);
- pci_write_config_dword(pdev, 0xB4, 0x62DD62DD);
- pci_write_config_dword(pdev, 0xB8, 0x43924392);
- pci_write_config_dword(pdev, 0xBC, 0x40094009);
-
- switch (tmpbyte & 0x30) {
- case 0x00:
- printk(KERN_INFO "sil680: 100MHz clock.\n");
- break;
- case 0x10:
- printk(KERN_INFO "sil680: 133MHz clock.\n");
- break;
- case 0x20:
- printk(KERN_INFO "sil680: Using PCI clock.\n");
- break;
- /* This last case is _NOT_ ok */
- case 0x30:
- printk(KERN_ERR "sil680: Clock disabled ?\n");
- }
- return tmpbyte & 0x30;
-}
-
static int __devinit sil680_init_one(struct pci_dev *pdev,
const struct pci_device_id *id)
{
Index: b/drivers/ata/pata_sil680.h
===================================================================
--- /dev/null
+++ b/drivers/ata/pata_sil680.h
@@ -0,0 +1,235 @@
+/**
+ * sil680_selreg - return register base
+ * @hwif: interface
+ * @r: config offset
+ *
+ * Turn a config register offset into the right address in either
+ * PCI space or MMIO space to access the control register in question
+ * Thankfully this is a configuration operation so isnt performance
+ * criticial.
+ */
+
+static unsigned long sil680_selreg(struct ata_port *ap, int r)
+{
+ unsigned long base = 0xA0 + r;
+ base += (ap->port_no << 4);
+ return base;
+}
+
+/**
+ * sil680_seldev - return register base
+ * @hwif: interface
+ * @r: config offset
+ *
+ * Turn a config register offset into the right address in either
+ * PCI space or MMIO space to access the control register in question
+ * including accounting for the unit shift.
+ */
+
+static unsigned long sil680_seldev(struct ata_port *ap, struct ata_device *adev, int r)
+{
+ unsigned long base = 0xA0 + r;
+ base += (ap->port_no << 4);
+ base |= adev->devno ? 2 : 0;
+ return base;
+}
+
+
+/**
+ * sil680_cable_detect - cable detection
+ * @ap: ATA port
+ *
+ * Perform cable detection. The SIL680 stores this in PCI config
+ * space for us.
+ */
+
+static int sil680_cable_detect(struct ata_port *ap)
+{
+ struct pci_dev *pdev = to_pci_dev(ap->host->dev);
+ unsigned long addr = sil680_selreg(ap, 0);
+ u8 ata66;
+ pci_read_config_byte(pdev, addr, &ata66);
+ if (ata66 & 1)
+ return ATA_CBL_PATA80;
+ else
+ return ATA_CBL_PATA40;
+}
+
+/**
+ * sil680_set_piomode - set initial PIO mode data
+ * @ap: ATA interface
+ * @adev: ATA device
+ *
+ * Program the SIL680 registers for PIO mode. Note that the task speed
+ * registers are shared between the devices so we must pick the lowest
+ * mode for command work.
+ */
+
+static void sil680_set_piomode(struct ata_port *ap, struct ata_device *adev)
+{
+ static u16 speed_p[5] = { 0x328A, 0x2283, 0x1104, 0x10C3, 0x10C1 };
+ static u16 speed_t[5] = { 0x328A, 0x2283, 0x1281, 0x10C3, 0x10C1 };
+
+ unsigned long tfaddr = sil680_selreg(ap, 0x02);
+ unsigned long addr = sil680_seldev(ap, adev, 0x04);
+ unsigned long addr_mask = 0x80 + 4 * ap->port_no;
+ struct pci_dev *pdev = to_pci_dev(ap->host->dev);
+ int pio = adev->pio_mode - XFER_PIO_0;
+ int lowest_pio = pio;
+ int port_shift = 4 * adev->devno;
+ u16 reg;
+ u8 mode;
+
+ struct ata_device *pair = ata_dev_pair(adev);
+
+ if (pair != NULL && adev->pio_mode > pair->pio_mode)
+ lowest_pio = pair->pio_mode - XFER_PIO_0;
+
+ pci_write_config_word(pdev, addr, speed_p[pio]);
+ pci_write_config_word(pdev, tfaddr, speed_t[lowest_pio]);
+
+ pci_read_config_word(pdev, tfaddr-2, &reg);
+ pci_read_config_byte(pdev, addr_mask, &mode);
+
+ reg &= ~0x0200; /* Clear IORDY */
+ mode &= ~(3 << port_shift); /* Clear IORDY and DMA bits */
+
+ if (ata_pio_need_iordy(adev)) {
+ reg |= 0x0200; /* Enable IORDY */
+ mode |= 1 << port_shift;
+ }
+ pci_write_config_word(pdev, tfaddr-2, reg);
+ pci_write_config_byte(pdev, addr_mask, mode);
+}
+
+/**
+ * sil680_set_dmamode - set initial DMA mode data
+ * @ap: ATA interface
+ * @adev: ATA device
+ *
+ * Program the MWDMA/UDMA modes for the sil680 k
+ * chipset. The MWDMA mode values are pulled from a lookup table
+ * while the chipset uses mode number for UDMA.
+ */
+
+static void sil680_set_dmamode(struct ata_port *ap, struct ata_device *adev)
+{
+ static u8 ultra_table[2][7] = {
+ { 0x0C, 0x07, 0x05, 0x04, 0x02, 0x01, 0xFF }, /* 100MHz */
+ { 0x0F, 0x0B, 0x07, 0x05, 0x03, 0x02, 0x01 }, /* 133Mhz */
+ };
+ static u16 dma_table[3] = { 0x2208, 0x10C2, 0x10C1 };
+
+ struct pci_dev *pdev = to_pci_dev(ap->host->dev);
+ unsigned long ma = sil680_seldev(ap, adev, 0x08);
+ unsigned long ua = sil680_seldev(ap, adev, 0x0C);
+ unsigned long addr_mask = 0x80 + 4 * ap->port_no;
+ int port_shift = adev->devno * 4;
+ u8 scsc, mode;
+ u16 multi, ultra;
+
+ pci_read_config_byte(pdev, 0x8A, &scsc);
+ pci_read_config_byte(pdev, addr_mask, &mode);
+ pci_read_config_word(pdev, ma, &multi);
+ pci_read_config_word(pdev, ua, &ultra);
+
+ /* Mask timing bits */
+ ultra &= ~0x3F;
+ mode &= ~(0x03 << port_shift);
+
+ /* Extract scsc */
+ scsc = (scsc & 0x30) ? 1 : 0;
+
+ if (adev->dma_mode >= XFER_UDMA_0) {
+ multi = 0x10C1;
+ ultra |= ultra_table[scsc][adev->dma_mode - XFER_UDMA_0];
+ mode |= (0x03 << port_shift);
+ } else {
+ multi = dma_table[adev->dma_mode - XFER_MW_DMA_0];
+ mode |= (0x02 << port_shift);
+ }
+ pci_write_config_byte(pdev, addr_mask, mode);
+ pci_write_config_word(pdev, ma, multi);
+ pci_write_config_word(pdev, ua, ultra);
+}
+
+/**
+ * sil680_init_chip - chip setup
+ * @pdev: PCI device
+ *
+ * Perform all the chip setup which must be done both when the device
+ * is powered up on boot and when we resume in case we resumed from RAM.
+ * Returns the final clock settings.
+ */
+
+static u8 sil680_init_chip(struct pci_dev *pdev, int *try_mmio)
+{
+ u8 tmpbyte = 0;
+
+ /* FIXME: double check */
+ pci_write_config_byte(pdev, PCI_CACHE_LINE_SIZE,
+ pdev->revision ? 1 : 255);
+
+ pci_write_config_byte(pdev, 0x80, 0x00);
+ pci_write_config_byte(pdev, 0x84, 0x00);
+
+ pci_read_config_byte(pdev, 0x8A, &tmpbyte);
+
+ dev_dbg(&pdev->dev, "sil680: BA5_EN = %d clock = %02X\n",
+ tmpbyte & 1, tmpbyte & 0x30);
+
+ *try_mmio = 0;
+#ifdef CONFIG_PPC
+ if (machine_is(cell))
+ *try_mmio = (tmpbyte & 1) || pci_resource_start(pdev, 5);
+#endif
+
+ switch (tmpbyte & 0x30) {
+ case 0x00:
+ /* 133 clock attempt to force it on */
+ pci_write_config_byte(pdev, 0x8A, tmpbyte|0x10);
+ break;
+ case 0x30:
+ /* if clocking is disabled */
+ /* 133 clock attempt to force it on */
+ pci_write_config_byte(pdev, 0x8A, tmpbyte & ~0x20);
+ break;
+ case 0x10:
+ /* 133 already */
+ break;
+ case 0x20:
+ /* BIOS set PCI x2 clocking */
+ break;
+ }
+
+ pci_read_config_byte(pdev, 0x8A, &tmpbyte);
+ dev_dbg(&pdev->dev, "sil680: BA5_EN = %d clock = %02X\n",
+ tmpbyte & 1, tmpbyte & 0x30);
+
+ pci_write_config_byte(pdev, 0xA1, 0x72);
+ pci_write_config_word(pdev, 0xA2, 0x328A);
+ pci_write_config_dword(pdev, 0xA4, 0x62DD62DD);
+ pci_write_config_dword(pdev, 0xA8, 0x43924392);
+ pci_write_config_dword(pdev, 0xAC, 0x40094009);
+ pci_write_config_byte(pdev, 0xB1, 0x72);
+ pci_write_config_word(pdev, 0xB2, 0x328A);
+ pci_write_config_dword(pdev, 0xB4, 0x62DD62DD);
+ pci_write_config_dword(pdev, 0xB8, 0x43924392);
+ pci_write_config_dword(pdev, 0xBC, 0x40094009);
+
+ switch (tmpbyte & 0x30) {
+ case 0x00:
+ printk(KERN_INFO "sil680: 100MHz clock.\n");
+ break;
+ case 0x10:
+ printk(KERN_INFO "sil680: 133MHz clock.\n");
+ break;
+ case 0x20:
+ printk(KERN_INFO "sil680: Using PCI clock.\n");
+ break;
+ /* This last case is _NOT_ ok */
+ case 0x30:
+ printk(KERN_ERR "sil680: Clock disabled ?\n");
+ }
+ return tmpbyte & 0x30;
+}

Subject: [PATCH 6/9] pata_cs5536: move code to be re-used by ide2libata to pata_cs5536.h

From: Bartlomiej Zolnierkiewicz <[email protected]>
Subject: [PATCH] pata_cs5536: move code to be re-used by ide2libata to pata_cs5536.h

Signed-off-by: Bartlomiej Zolnierkiewicz <[email protected]>
---
drivers/ata/pata_cs5536.c | 174 ---------------------------------------------
drivers/ata/pata_cs5536.h | 175 ++++++++++++++++++++++++++++++++++++++++++++++
2 files changed, 176 insertions(+), 173 deletions(-)

Index: b/drivers/ata/pata_cs5536.c
===================================================================
--- a/drivers/ata/pata_cs5536.c
+++ b/drivers/ata/pata_cs5536.c
@@ -15,19 +15,6 @@
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
- *
- * Documentation:
- * Available from AMD web site.
- *
- * The IDE timing registers for the CS5536 live in the Geode Machine
- * Specific Register file and not PCI config space. Most BIOSes
- * virtualize the PCI registers so the chip looks like a standard IDE
- * controller. Unfortunately not all implementations get this right.
- * In particular some have problems with unaligned accesses to the
- * virtualized PCI registers. This driver always does full dword
- * writes to work around the issue. Also, in case of a bad BIOS this
- * driver can be loaded with the "msr=1" parameter which forces using
- * the Machine Specific Registers to configure the device.
*/

#include <linux/kernel.h>
@@ -43,166 +30,7 @@
#define DRV_NAME "pata_cs5536"
#define DRV_VERSION "0.0.7"

-enum {
- MSR_IDE_CFG = 0x51300010,
- PCI_IDE_CFG = 0x40,
-
- CFG = 0,
- DTC = 2,
- CAST = 3,
- ETC = 4,
-
- IDE_CFG_CHANEN = (1 << 1),
- IDE_CFG_CABLE = (1 << 17) | (1 << 16),
-
- IDE_D0_SHIFT = 24,
- IDE_D1_SHIFT = 16,
- IDE_DRV_MASK = 0xff,
-
- IDE_CAST_D0_SHIFT = 6,
- IDE_CAST_D1_SHIFT = 4,
- IDE_CAST_DRV_MASK = 0x3,
- IDE_CAST_CMD_MASK = 0xff,
- IDE_CAST_CMD_SHIFT = 24,
-
- IDE_ETC_UDMA_MASK = 0xc0,
-};
-
-static int use_msr;
-
-static int cs5536_read(struct pci_dev *pdev, int reg, u32 *val)
-{
- if (unlikely(use_msr)) {
- u32 dummy;
-
- rdmsr(MSR_IDE_CFG + reg, *val, dummy);
- return 0;
- }
-
- return pci_read_config_dword(pdev, PCI_IDE_CFG + reg * 4, val);
-}
-
-static int cs5536_write(struct pci_dev *pdev, int reg, int val)
-{
- if (unlikely(use_msr)) {
- wrmsr(MSR_IDE_CFG + reg, val, 0);
- return 0;
- }
-
- return pci_write_config_dword(pdev, PCI_IDE_CFG + reg * 4, val);
-}
-
-static void cs5536_program_dtc(struct ata_device *adev, u8 tim)
-{
- struct pci_dev *pdev = to_pci_dev(adev->link->ap->host->dev);
- int dshift = adev->devno ? IDE_D1_SHIFT : IDE_D0_SHIFT;
- u32 dtc;
-
- cs5536_read(pdev, DTC, &dtc);
- dtc &= ~(IDE_DRV_MASK << dshift);
- dtc |= tim << dshift;
- cs5536_write(pdev, DTC, dtc);
-}
-
-/**
- * cs5536_cable_detect - detect cable type
- * @ap: Port to detect on
- *
- * Perform cable detection for ATA66 capable cable.
- *
- * Returns a cable type.
- */
-
-static int cs5536_cable_detect(struct ata_port *ap)
-{
- struct pci_dev *pdev = to_pci_dev(ap->host->dev);
- u32 cfg;
-
- cs5536_read(pdev, CFG, &cfg);
-
- if (cfg & IDE_CFG_CABLE)
- return ATA_CBL_PATA80;
- else
- return ATA_CBL_PATA40;
-}
-
-/**
- * cs5536_set_piomode - PIO setup
- * @ap: ATA interface
- * @adev: device on the interface
- */
-
-static void cs5536_set_piomode(struct ata_port *ap, struct ata_device *adev)
-{
- static const u8 drv_timings[5] = {
- 0x98, 0x55, 0x32, 0x21, 0x20,
- };
-
- static const u8 addr_timings[5] = {
- 0x2, 0x1, 0x0, 0x0, 0x0,
- };
-
- static const u8 cmd_timings[5] = {
- 0x99, 0x92, 0x90, 0x22, 0x20,
- };
-
- struct pci_dev *pdev = to_pci_dev(ap->host->dev);
- struct ata_device *pair = ata_dev_pair(adev);
- int mode = adev->pio_mode - XFER_PIO_0;
- int cmdmode = mode;
- int cshift = adev->devno ? IDE_CAST_D1_SHIFT : IDE_CAST_D0_SHIFT;
- u32 cast;
-
- if (pair)
- cmdmode = min(mode, pair->pio_mode - XFER_PIO_0);
-
- cs5536_program_dtc(adev, drv_timings[mode]);
-
- cs5536_read(pdev, CAST, &cast);
-
- cast &= ~(IDE_CAST_DRV_MASK << cshift);
- cast |= addr_timings[mode] << cshift;
-
- cast &= ~(IDE_CAST_CMD_MASK << IDE_CAST_CMD_SHIFT);
- cast |= cmd_timings[cmdmode] << IDE_CAST_CMD_SHIFT;
-
- cs5536_write(pdev, CAST, cast);
-}
-
-/**
- * cs5536_set_dmamode - DMA timing setup
- * @ap: ATA interface
- * @adev: Device being configured
- *
- */
-
-static void cs5536_set_dmamode(struct ata_port *ap, struct ata_device *adev)
-{
- static const u8 udma_timings[6] = {
- 0xc2, 0xc1, 0xc0, 0xc4, 0xc5, 0xc6,
- };
-
- static const u8 mwdma_timings[3] = {
- 0x67, 0x21, 0x20,
- };
-
- struct pci_dev *pdev = to_pci_dev(ap->host->dev);
- u32 etc;
- int mode = adev->dma_mode;
- int dshift = adev->devno ? IDE_D1_SHIFT : IDE_D0_SHIFT;
-
- cs5536_read(pdev, ETC, &etc);
-
- if (mode >= XFER_UDMA_0) {
- etc &= ~(IDE_DRV_MASK << dshift);
- etc |= udma_timings[mode - XFER_UDMA_0] << dshift;
- } else { /* MWDMA */
- etc &= ~(IDE_ETC_UDMA_MASK << dshift);
- cs5536_program_dtc(adev, mwdma_timings[mode - XFER_MW_DMA_0]);
- }
-
- cs5536_write(pdev, ETC, etc);
-}
+#include "pata_cs5536.h"

static struct scsi_host_template cs5536_sht = {
ATA_BMDMA_SHT(DRV_NAME),
Index: b/drivers/ata/pata_cs5536.h
===================================================================
--- /dev/null
+++ b/drivers/ata/pata_cs5536.h
@@ -0,0 +1,175 @@
+/*
+ * Documentation:
+ * Available from AMD web site.
+ *
+ * The IDE timing registers for the CS5536 live in the Geode Machine
+ * Specific Register file and not PCI config space. Most BIOSes
+ * virtualize the PCI registers so the chip looks like a standard IDE
+ * controller. Unfortunately not all implementations get this right.
+ * In particular some have problems with unaligned accesses to the
+ * virtualized PCI registers. This driver always does full dword
+ * writes to work around the issue. Also, in case of a bad BIOS this
+ * driver can be loaded with the "msr=1" parameter which forces using
+ * the Machine Specific Registers to configure the device.
+ */
+
+enum {
+ MSR_IDE_CFG = 0x51300010,
+ PCI_IDE_CFG = 0x40,
+
+ CFG = 0,
+ DTC = 2,
+ CAST = 3,
+ ETC = 4,
+
+ IDE_CFG_CHANEN = (1 << 1),
+ IDE_CFG_CABLE = (1 << 17) | (1 << 16),
+
+ IDE_D0_SHIFT = 24,
+ IDE_D1_SHIFT = 16,
+ IDE_DRV_MASK = 0xff,
+
+ IDE_CAST_D0_SHIFT = 6,
+ IDE_CAST_D1_SHIFT = 4,
+ IDE_CAST_DRV_MASK = 0x3,
+ IDE_CAST_CMD_MASK = 0xff,
+ IDE_CAST_CMD_SHIFT = 24,
+
+ IDE_ETC_UDMA_MASK = 0xc0,
+};
+
+static int use_msr;
+
+static int cs5536_read(struct pci_dev *pdev, int reg, u32 *val)
+{
+ if (unlikely(use_msr)) {
+ u32 dummy;
+
+ rdmsr(MSR_IDE_CFG + reg, *val, dummy);
+ return 0;
+ }
+
+ return pci_read_config_dword(pdev, PCI_IDE_CFG + reg * 4, val);
+}
+
+static int cs5536_write(struct pci_dev *pdev, int reg, int val)
+{
+ if (unlikely(use_msr)) {
+ wrmsr(MSR_IDE_CFG + reg, val, 0);
+ return 0;
+ }
+
+ return pci_write_config_dword(pdev, PCI_IDE_CFG + reg * 4, val);
+}
+
+static void cs5536_program_dtc(struct ata_device *adev, u8 tim)
+{
+ struct pci_dev *pdev = to_pci_dev(adev->link->ap->host->dev);
+ int dshift = adev->devno ? IDE_D1_SHIFT : IDE_D0_SHIFT;
+ u32 dtc;
+
+ cs5536_read(pdev, DTC, &dtc);
+ dtc &= ~(IDE_DRV_MASK << dshift);
+ dtc |= tim << dshift;
+ cs5536_write(pdev, DTC, dtc);
+}
+
+/**
+ * cs5536_cable_detect - detect cable type
+ * @ap: Port to detect on
+ *
+ * Perform cable detection for ATA66 capable cable.
+ *
+ * Returns a cable type.
+ */
+
+static int cs5536_cable_detect(struct ata_port *ap)
+{
+ struct pci_dev *pdev = to_pci_dev(ap->host->dev);
+ u32 cfg;
+
+ cs5536_read(pdev, CFG, &cfg);
+
+ if (cfg & IDE_CFG_CABLE)
+ return ATA_CBL_PATA80;
+ else
+ return ATA_CBL_PATA40;
+}
+
+/**
+ * cs5536_set_piomode - PIO setup
+ * @ap: ATA interface
+ * @adev: device on the interface
+ */
+
+static void cs5536_set_piomode(struct ata_port *ap, struct ata_device *adev)
+{
+ static const u8 drv_timings[5] = {
+ 0x98, 0x55, 0x32, 0x21, 0x20,
+ };
+
+ static const u8 addr_timings[5] = {
+ 0x2, 0x1, 0x0, 0x0, 0x0,
+ };
+
+ static const u8 cmd_timings[5] = {
+ 0x99, 0x92, 0x90, 0x22, 0x20,
+ };
+
+ struct pci_dev *pdev = to_pci_dev(ap->host->dev);
+ struct ata_device *pair = ata_dev_pair(adev);
+ int mode = adev->pio_mode - XFER_PIO_0;
+ int cmdmode = mode;
+ int cshift = adev->devno ? IDE_CAST_D1_SHIFT : IDE_CAST_D0_SHIFT;
+ u32 cast;
+
+ if (pair)
+ cmdmode = min(mode, pair->pio_mode - XFER_PIO_0);
+
+ cs5536_program_dtc(adev, drv_timings[mode]);
+
+ cs5536_read(pdev, CAST, &cast);
+
+ cast &= ~(IDE_CAST_DRV_MASK << cshift);
+ cast |= addr_timings[mode] << cshift;
+
+ cast &= ~(IDE_CAST_CMD_MASK << IDE_CAST_CMD_SHIFT);
+ cast |= cmd_timings[cmdmode] << IDE_CAST_CMD_SHIFT;
+
+ cs5536_write(pdev, CAST, cast);
+}
+
+/**
+ * cs5536_set_dmamode - DMA timing setup
+ * @ap: ATA interface
+ * @adev: Device being configured
+ *
+ */
+
+static void cs5536_set_dmamode(struct ata_port *ap, struct ata_device *adev)
+{
+ static const u8 udma_timings[6] = {
+ 0xc2, 0xc1, 0xc0, 0xc4, 0xc5, 0xc6,
+ };
+
+ static const u8 mwdma_timings[3] = {
+ 0x67, 0x21, 0x20,
+ };
+
+ struct pci_dev *pdev = to_pci_dev(ap->host->dev);
+ u32 etc;
+ int mode = adev->dma_mode;
+ int dshift = adev->devno ? IDE_D1_SHIFT : IDE_D0_SHIFT;
+
+ cs5536_read(pdev, ETC, &etc);
+
+ if (mode >= XFER_UDMA_0) {
+ etc &= ~(IDE_DRV_MASK << dshift);
+ etc |= udma_timings[mode - XFER_UDMA_0] << dshift;
+ } else { /* MWDMA */
+ etc &= ~(IDE_ETC_UDMA_MASK << dshift);
+ cs5536_program_dtc(adev, mwdma_timings[mode - XFER_MW_DMA_0]);
+ }
+
+ cs5536_write(pdev, ETC, etc);
+}

Subject: [PATCH 7/9] cs5536: convert to ide2libata

From: Bartlomiej Zolnierkiewicz <[email protected]>
Subject: [PATCH] cs5536: convert to ide2libata

Signed-off-by: Bartlomiej Zolnierkiewicz <[email protected]>
---
drivers/ata/pata_cs5536.h | 22 +++++
drivers/ide/cs5536.c | 189 +---------------------------------------------
2 files changed, 26 insertions(+), 185 deletions(-)

Index: b/drivers/ata/pata_cs5536.h
===================================================================
--- a/drivers/ata/pata_cs5536.h
+++ b/drivers/ata/pata_cs5536.h
@@ -64,7 +64,11 @@ static int cs5536_write(struct pci_dev *

static void cs5536_program_dtc(struct ata_device *adev, u8 tim)
{
+#ifndef __IDE2LIBATA
struct pci_dev *pdev = to_pci_dev(adev->link->ap->host->dev);
+#else
+ struct pci_dev *pdev = to_pci_dev(adev->hwif->dev);
+#endif
int dshift = adev->devno ? IDE_D1_SHIFT : IDE_D0_SHIFT;
u32 dtc;

@@ -121,11 +125,19 @@ static void cs5536_set_piomode(struct at
int mode = adev->pio_mode - XFER_PIO_0;
int cmdmode = mode;
int cshift = adev->devno ? IDE_CAST_D1_SHIFT : IDE_CAST_D0_SHIFT;
+#ifdef __IDE2LIBATA
+ unsigned long timings = (unsigned long)ide_get_drivedata(adev);
+#endif
u32 cast;

if (pair)
cmdmode = min(mode, pair->pio_mode - XFER_PIO_0);

+#ifdef __IDE2LIBATA
+ timings &= (IDE_DRV_MASK << 8);
+ timings |= drv_timings[mode];
+ ide_set_drivedata(adev, (void *)timings);
+#endif
cs5536_program_dtc(adev, drv_timings[mode]);

cs5536_read(pdev, CAST, &cast);
@@ -160,7 +172,9 @@ static void cs5536_set_dmamode(struct at
u32 etc;
int mode = adev->dma_mode;
int dshift = adev->devno ? IDE_D1_SHIFT : IDE_D0_SHIFT;
-
+#ifdef __IDE2LIBATA
+ unsigned long timings = (unsigned long)ide_get_drivedata(adev);
+#endif
cs5536_read(pdev, ETC, &etc);

if (mode >= XFER_UDMA_0) {
@@ -168,7 +182,13 @@ static void cs5536_set_dmamode(struct at
etc |= udma_timings[mode - XFER_UDMA_0] << dshift;
} else { /* MWDMA */
etc &= ~(IDE_ETC_UDMA_MASK << dshift);
+#ifndef __IDE2LIBATA
cs5536_program_dtc(adev, mwdma_timings[mode - XFER_MW_DMA_0]);
+#else
+ timings &= IDE_DRV_MASK;
+ timings |= mwdma_timings[mode - XFER_MW_DMA_0] << 8;
+ ide_set_drivedata(adev, (void *)timings);
+#endif
}

cs5536_write(pdev, ETC, etc);
Index: b/drivers/ide/cs5536.c
===================================================================
--- a/drivers/ide/cs5536.c
+++ b/drivers/ide/cs5536.c
@@ -1,7 +1,7 @@
/*
* CS5536 PATA support
* (C) 2007 Martin K. Petersen <[email protected]>
- * (C) 2009 Bartlomiej Zolnierkiewicz
+ * (C) 2009-2010 Bartlomiej Zolnierkiewicz
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License version 2 as
@@ -15,19 +15,6 @@
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
- *
- * Documentation:
- * Available from AMD web site.
- *
- * The IDE timing registers for the CS5536 live in the Geode Machine
- * Specific Register file and not PCI config space. Most BIOSes
- * virtualize the PCI registers so the chip looks like a standard IDE
- * controller. Unfortunately not all implementations get this right.
- * In particular some have problems with unaligned accesses to the
- * virtualized PCI registers. This driver always does full dword
- * writes to work around the issue. Also, in case of a bad BIOS this
- * driver can be loaded with the "msr=1" parameter which forces using
- * the Machine Specific Registers to configure the device.
*/

#include <linux/kernel.h>
@@ -39,174 +26,8 @@

#define DRV_NAME "cs5536"

-enum {
- MSR_IDE_CFG = 0x51300010,
- PCI_IDE_CFG = 0x40,
-
- CFG = 0,
- DTC = 2,
- CAST = 3,
- ETC = 4,
-
- IDE_CFG_CHANEN = (1 << 1),
- IDE_CFG_CABLE = (1 << 17) | (1 << 16),
-
- IDE_D0_SHIFT = 24,
- IDE_D1_SHIFT = 16,
- IDE_DRV_MASK = 0xff,
-
- IDE_CAST_D0_SHIFT = 6,
- IDE_CAST_D1_SHIFT = 4,
- IDE_CAST_DRV_MASK = 0x3,
-
- IDE_CAST_CMD_SHIFT = 24,
- IDE_CAST_CMD_MASK = 0xff,
-
- IDE_ETC_UDMA_MASK = 0xc0,
-};
-
-static int use_msr;
-
-static int cs5536_read(struct pci_dev *pdev, int reg, u32 *val)
-{
- if (unlikely(use_msr)) {
- u32 dummy;
-
- rdmsr(MSR_IDE_CFG + reg, *val, dummy);
- return 0;
- }
-
- return pci_read_config_dword(pdev, PCI_IDE_CFG + reg * 4, val);
-}
-
-static int cs5536_write(struct pci_dev *pdev, int reg, int val)
-{
- if (unlikely(use_msr)) {
- wrmsr(MSR_IDE_CFG + reg, val, 0);
- return 0;
- }
-
- return pci_write_config_dword(pdev, PCI_IDE_CFG + reg * 4, val);
-}
-
-static void cs5536_program_dtc(ide_drive_t *drive, u8 tim)
-{
- struct pci_dev *pdev = to_pci_dev(drive->hwif->dev);
- int dshift = (drive->dn & 1) ? IDE_D1_SHIFT : IDE_D0_SHIFT;
- u32 dtc;
-
- cs5536_read(pdev, DTC, &dtc);
- dtc &= ~(IDE_DRV_MASK << dshift);
- dtc |= tim << dshift;
- cs5536_write(pdev, DTC, dtc);
-}
-
-/**
- * cs5536_cable_detect - detect cable type
- * @hwif: Port to detect on
- *
- * Perform cable detection for ATA66 capable cable.
- *
- * Returns a cable type.
- */
-
-static int cs5536_cable_detect(ide_hwif_t *hwif)
-{
- struct pci_dev *pdev = to_pci_dev(hwif->dev);
- u32 cfg;
-
- cs5536_read(pdev, CFG, &cfg);
-
- if (cfg & IDE_CFG_CABLE)
- return ATA_CBL_PATA80;
- else
- return ATA_CBL_PATA40;
-}
-
-/**
- * cs5536_set_pio_mode - PIO timing setup
- * @hwif: ATA port
- * @drive: ATA device
- */
-
-static void cs5536_set_pio_mode(ide_hwif_t *hwif, ide_drive_t *drive)
-{
- static const u8 drv_timings[5] = {
- 0x98, 0x55, 0x32, 0x21, 0x20,
- };
-
- static const u8 addr_timings[5] = {
- 0x2, 0x1, 0x0, 0x0, 0x0,
- };
-
- static const u8 cmd_timings[5] = {
- 0x99, 0x92, 0x90, 0x22, 0x20,
- };
-
- struct pci_dev *pdev = to_pci_dev(hwif->dev);
- ide_drive_t *pair = ide_get_pair_dev(drive);
- int cshift = (drive->dn & 1) ? IDE_CAST_D1_SHIFT : IDE_CAST_D0_SHIFT;
- unsigned long timings = (unsigned long)ide_get_drivedata(drive);
- u32 cast;
- const u8 pio = drive->pio_mode - XFER_PIO_0;
- u8 cmd_pio = pio;
-
- if (pair)
- cmd_pio = min_t(u8, pio, pair->pio_mode - XFER_PIO_0);
-
- timings &= (IDE_DRV_MASK << 8);
- timings |= drv_timings[pio];
- ide_set_drivedata(drive, (void *)timings);
-
- cs5536_program_dtc(drive, drv_timings[pio]);
-
- cs5536_read(pdev, CAST, &cast);
-
- cast &= ~(IDE_CAST_DRV_MASK << cshift);
- cast |= addr_timings[pio] << cshift;
-
- cast &= ~(IDE_CAST_CMD_MASK << IDE_CAST_CMD_SHIFT);
- cast |= cmd_timings[cmd_pio] << IDE_CAST_CMD_SHIFT;
-
- cs5536_write(pdev, CAST, cast);
-}
-
-/**
- * cs5536_set_dma_mode - DMA timing setup
- * @hwif: ATA port
- * @drive: ATA device
- */
-
-static void cs5536_set_dma_mode(ide_hwif_t *hwif, ide_drive_t *drive)
-{
- static const u8 udma_timings[6] = {
- 0xc2, 0xc1, 0xc0, 0xc4, 0xc5, 0xc6,
- };
-
- static const u8 mwdma_timings[3] = {
- 0x67, 0x21, 0x20,
- };
-
- struct pci_dev *pdev = to_pci_dev(hwif->dev);
- int dshift = (drive->dn & 1) ? IDE_D1_SHIFT : IDE_D0_SHIFT;
- unsigned long timings = (unsigned long)ide_get_drivedata(drive);
- u32 etc;
- const u8 mode = drive->dma_mode;
-
- cs5536_read(pdev, ETC, &etc);
-
- if (mode >= XFER_UDMA_0) {
- etc &= ~(IDE_DRV_MASK << dshift);
- etc |= udma_timings[mode - XFER_UDMA_0] << dshift;
- } else { /* MWDMA */
- etc &= ~(IDE_ETC_UDMA_MASK << dshift);
- timings &= IDE_DRV_MASK;
- timings |= mwdma_timings[mode - XFER_MW_DMA_0] << 8;
- ide_set_drivedata(drive, (void *)timings);
- }
-
- cs5536_write(pdev, ETC, etc);
-}
+#include <linux/ide2libata.h>
+#include "../ata/pata_cs5536.h"

static void cs5536_dma_start(ide_drive_t *drive)
{
@@ -232,8 +53,8 @@ static int cs5536_dma_end(ide_drive_t *d
}

static const struct ide_port_ops cs5536_port_ops = {
- .set_pio_mode = cs5536_set_pio_mode,
- .set_dma_mode = cs5536_set_dma_mode,
+ .set_pio_mode = cs5536_set_piomode,
+ .set_dma_mode = cs5536_set_dmamode,
.cable_detect = cs5536_cable_detect,
};

2010-01-30 21:55:51

by Jeff Garzik

[permalink] [raw]
Subject: Re: [PATCH 7/9] cs5536: convert to ide2libata

On 01/30/2010 02:50 PM, Bartlomiej Zolnierkiewicz wrote:
> From: Bartlomiej Zolnierkiewicz<[email protected]>
> Subject: [PATCH] cs5536: convert to ide2libata
>
> Signed-off-by: Bartlomiej Zolnierkiewicz<[email protected]>
> ---
> drivers/ata/pata_cs5536.h | 22 +++++
> drivers/ide/cs5536.c | 189 +---------------------------------------------
> 2 files changed, 26 insertions(+), 185 deletions(-)
>
> Index: b/drivers/ata/pata_cs5536.h
> ===================================================================
> --- a/drivers/ata/pata_cs5536.h
> +++ b/drivers/ata/pata_cs5536.h
> @@ -64,7 +64,11 @@ static int cs5536_write(struct pci_dev *
>
> static void cs5536_program_dtc(struct ata_device *adev, u8 tim)
> {
> +#ifndef __IDE2LIBATA
> struct pci_dev *pdev = to_pci_dev(adev->link->ap->host->dev);
> +#else
> + struct pci_dev *pdev = to_pci_dev(adev->hwif->dev);
> +#endif
> int dshift = adev->devno ? IDE_D1_SHIFT : IDE_D0_SHIFT;
> u32 dtc;
>
> @@ -121,11 +125,19 @@ static void cs5536_set_piomode(struct at
> int mode = adev->pio_mode - XFER_PIO_0;
> int cmdmode = mode;
> int cshift = adev->devno ? IDE_CAST_D1_SHIFT : IDE_CAST_D0_SHIFT;
> +#ifdef __IDE2LIBATA
> + unsigned long timings = (unsigned long)ide_get_drivedata(adev);
> +#endif
> u32 cast;
>
> if (pair)
> cmdmode = min(mode, pair->pio_mode - XFER_PIO_0);
>
> +#ifdef __IDE2LIBATA
> + timings&= (IDE_DRV_MASK<< 8);
> + timings |= drv_timings[mode];
> + ide_set_drivedata(adev, (void *)timings);
> +#endif
> cs5536_program_dtc(adev, drv_timings[mode]);
>
> cs5536_read(pdev, CAST,&cast);
> @@ -160,7 +172,9 @@ static void cs5536_set_dmamode(struct at
> u32 etc;
> int mode = adev->dma_mode;
> int dshift = adev->devno ? IDE_D1_SHIFT : IDE_D0_SHIFT;
> -
> +#ifdef __IDE2LIBATA
> + unsigned long timings = (unsigned long)ide_get_drivedata(adev);
> +#endif
> cs5536_read(pdev, ETC,&etc);
>
> if (mode>= XFER_UDMA_0) {
> @@ -168,7 +182,13 @@ static void cs5536_set_dmamode(struct at
> etc |= udma_timings[mode - XFER_UDMA_0]<< dshift;
> } else { /* MWDMA */
> etc&= ~(IDE_ETC_UDMA_MASK<< dshift);
> +#ifndef __IDE2LIBATA
> cs5536_program_dtc(adev, mwdma_timings[mode - XFER_MW_DMA_0]);
> +#else
> + timings&= IDE_DRV_MASK;
> + timings |= mwdma_timings[mode - XFER_MW_DMA_0]<< 8;
> + ide_set_drivedata(adev, (void *)timings);
> +#endif
> }
>
> cs5536_write(pdev, ETC, etc);

Wow, that's really turning into a rat's nest of ifdefs, isn't it?

Jeff


Subject: Re: [PATCH 7/9] cs5536: convert to ide2libata

On Saturday 30 January 2010 10:55:47 pm Jeff Garzik wrote:
> On 01/30/2010 02:50 PM, Bartlomiej Zolnierkiewicz wrote:
> > From: Bartlomiej Zolnierkiewicz<[email protected]>
> > Subject: [PATCH] cs5536: convert to ide2libata
> >
> > Signed-off-by: Bartlomiej Zolnierkiewicz<[email protected]>
> > ---
> > drivers/ata/pata_cs5536.h | 22 +++++
> > drivers/ide/cs5536.c | 189 +---------------------------------------------
> > 2 files changed, 26 insertions(+), 185 deletions(-)
> >
> > Index: b/drivers/ata/pata_cs5536.h
> > ===================================================================
> > --- a/drivers/ata/pata_cs5536.h
> > +++ b/drivers/ata/pata_cs5536.h
> > @@ -64,7 +64,11 @@ static int cs5536_write(struct pci_dev *
> >
> > static void cs5536_program_dtc(struct ata_device *adev, u8 tim)
> > {
> > +#ifndef __IDE2LIBATA
> > struct pci_dev *pdev = to_pci_dev(adev->link->ap->host->dev);
> > +#else
> > + struct pci_dev *pdev = to_pci_dev(adev->hwif->dev);
> > +#endif
> > int dshift = adev->devno ? IDE_D1_SHIFT : IDE_D0_SHIFT;
> > u32 dtc;
> >
> > @@ -121,11 +125,19 @@ static void cs5536_set_piomode(struct at
> > int mode = adev->pio_mode - XFER_PIO_0;
> > int cmdmode = mode;
> > int cshift = adev->devno ? IDE_CAST_D1_SHIFT : IDE_CAST_D0_SHIFT;
> > +#ifdef __IDE2LIBATA
> > + unsigned long timings = (unsigned long)ide_get_drivedata(adev);
> > +#endif
> > u32 cast;
> >
> > if (pair)
> > cmdmode = min(mode, pair->pio_mode - XFER_PIO_0);
> >
> > +#ifdef __IDE2LIBATA
> > + timings&= (IDE_DRV_MASK<< 8);
> > + timings |= drv_timings[mode];
> > + ide_set_drivedata(adev, (void *)timings);
> > +#endif
> > cs5536_program_dtc(adev, drv_timings[mode]);
> >
> > cs5536_read(pdev, CAST,&cast);
> > @@ -160,7 +172,9 @@ static void cs5536_set_dmamode(struct at
> > u32 etc;
> > int mode = adev->dma_mode;
> > int dshift = adev->devno ? IDE_D1_SHIFT : IDE_D0_SHIFT;
> > -
> > +#ifdef __IDE2LIBATA
> > + unsigned long timings = (unsigned long)ide_get_drivedata(adev);
> > +#endif
> > cs5536_read(pdev, ETC,&etc);
> >
> > if (mode>= XFER_UDMA_0) {
> > @@ -168,7 +182,13 @@ static void cs5536_set_dmamode(struct at
> > etc |= udma_timings[mode - XFER_UDMA_0]<< dshift;
> > } else { /* MWDMA */
> > etc&= ~(IDE_ETC_UDMA_MASK<< dshift);
> > +#ifndef __IDE2LIBATA
> > cs5536_program_dtc(adev, mwdma_timings[mode - XFER_MW_DMA_0]);
> > +#else
> > + timings&= IDE_DRV_MASK;
> > + timings |= mwdma_timings[mode - XFER_MW_DMA_0]<< 8;
> > + ide_set_drivedata(adev, (void *)timings);
> > +#endif
> > }
> >
> > cs5536_write(pdev, ETC, etc);
>
> Wow, that's really turning into a rat's nest of ifdefs, isn't it?

I'm sorry to say it but this is missing the point entirely.

With such ifdefs around I'm finally able to see some still remaining to
be fixed libata PATA issues (BTW work on ide2libata is what allowed me to
quickly do previous "PATA fixes" and "more PATA fixes" patchsets).

i.e. I can see that pata_cs5536 still needs to be fixed to handle non-matching
PIO/MWDMA timings (pata_ali.h patch is even better example of the concept).

[ As added bonus I'm cutting LOC and enabling possibility of sharing testing
efforts for much of IDE/libata low-level code ('"leave it alone" stability
promise of an old-IDE' is a wishful thinking anyway given that whole kernel
evolves, not to even mention that it is completely unnecessary as we have
much better stability promise in distributions that need it -- they are
simply using much older kernel version (i.e. RHEL). ]

In reality I'm doing a long overdue work that should have been done four yours
ago before commit 669a5db got merged without any review or integration work
being done...

--
Bartlomiej Zolnierkiewicz