linux-kernel.vger.kernel.org archive mirror
 help / color / mirror / Atom feed
* Re: [PATCH] Merge the changes from siimage 2.4.22-pre9 to 2.6.0-test2
  2003-07-31 17:49 [PATCH] Merge the changes from siimage 2.4.22-pre9 to 2.6.0-test2 Marcelo Penna Guerra
@ 2003-07-31 15:25 ` Bartlomiej Zolnierkiewicz
  2003-07-31 19:32   ` Marcelo Penna Guerra
  2003-08-02  8:29   ` Andre Hedrick
  2003-07-31 15:58 ` Alan Cox
  1 sibling, 2 replies; 11+ messages in thread
From: Bartlomiej Zolnierkiewicz @ 2003-07-31 15:25 UTC (permalink / raw)
  To: Marcelo Penna Guerra; +Cc: Andre Hedrick, linux-kernel


On Thu, 31 Jul 2003, Marcelo Penna Guerra wrote:

> Hi,

Hi,

> I don't know if anyone is working on this, but I merged the changes from
> siimage 1.06 present in 2.4.x to 2.6.0-test2. I'm really not very familiar
> with the IDE code, so it's probably a good idea if someone could take a look
> at it. All I can tell is it's working with the SiI3112A present in my
> motherboard and it's a lot more stable than before.

Thanks, I'll take a look.

What do you mean by "a lot more stable than before"?

> I also added the suggestion from Andre to make the driver not care about cable
> detection and found a possible bug in the 2.4.x code.

Can you separate your changes from forward-port?

> In 2.4.22-pre9:
>
> if (!is_sata(hwif))
>        hwif->atapi_dma = 1;
>
> and DMA is not enabled by default.

This means that if this is a SATA controller DMA shouldn't be
enabled on ATAPI devices.  There are probably some reasons to do this.

> I think it should be:
>
> if (is_sata(hwif))
>        hwif->atapi_dma = 1;
>
> With this DMA is enabled by default on my board and works great.

Are you aware of side effect?
[ Disabling DMA on ATAPI devices on SiI680. ]

Please consult this change with Alan :-).

> Marcelo Penna Guerra

Regards,
--
Bartlomiej



^ permalink raw reply	[flat|nested] 11+ messages in thread

* Re: [PATCH] Merge the changes from siimage 2.4.22-pre9 to 2.6.0-test2
  2003-07-31 17:49 [PATCH] Merge the changes from siimage 2.4.22-pre9 to 2.6.0-test2 Marcelo Penna Guerra
  2003-07-31 15:25 ` Bartlomiej Zolnierkiewicz
@ 2003-07-31 15:58 ` Alan Cox
  1 sibling, 0 replies; 11+ messages in thread
From: Alan Cox @ 2003-07-31 15:58 UTC (permalink / raw)
  To: Marcelo Penna Guerra; +Cc: lkml, Andre Hedrick

On Iau, 2003-07-31 at 18:49, Marcelo Penna Guerra wrote:
> if (!is_sata(hwif)) 
>        hwif->atapi_dma = 1;
> 
> and DMA is not enabled by default.
> 
> I think it should be:
> 
> if (is_sata(hwif)) 
>        hwif->atapi_dma = 1;
> 
> With this DMA is enabled by default on my board and works great.

You've accidentally worked around a different bug


^ permalink raw reply	[flat|nested] 11+ messages in thread

* Re: [PATCH] Merge the changes from siimage 2.4.22-pre9 to 2.6.0-test2
  2003-07-31 19:32   ` Marcelo Penna Guerra
@ 2003-07-31 17:19     ` Alan Cox
  2003-07-31 17:24     ` Bartlomiej Zolnierkiewicz
  1 sibling, 0 replies; 11+ messages in thread
From: Alan Cox @ 2003-07-31 17:19 UTC (permalink / raw)
  To: Marcelo Penna Guerra
  Cc: Bartlomiej Zolnierkiewicz, Andre Hedrick, Linux Kernel Mailing List

On Iau, 2003-07-31 at 20:32, Marcelo Penna Guerra wrote:
> I mean it doesn't crash the system during intensive read/write operations. It 
> has something to do with limiting the max bk per request to 7.5 (hwif-
> >rqsize=15).

Already handled in 2.4.22pre-ac

> 	if(is_sata(hwif))
> 	{
> +		drive->id->hw_config |= 0x6000;
> 		if(strstr(drive->id->model, "Maxtor"))
> 			return 3;
> 		return 4;
>  	}

We never check the cable bits for SATA so this is a no-op



^ permalink raw reply	[flat|nested] 11+ messages in thread

* Re: [PATCH] Merge the changes from siimage 2.4.22-pre9 to 2.6.0-test2
  2003-07-31 19:32   ` Marcelo Penna Guerra
  2003-07-31 17:19     ` Alan Cox
@ 2003-07-31 17:24     ` Bartlomiej Zolnierkiewicz
  1 sibling, 0 replies; 11+ messages in thread
From: Bartlomiej Zolnierkiewicz @ 2003-07-31 17:24 UTC (permalink / raw)
  To: Marcelo Penna Guerra; +Cc: Alan Cox, Andre Hedrick, linux-kernel


On Thu, 31 Jul 2003, Marcelo Penna Guerra wrote:

> > Are you aware of side effect?
> > [ Disabling DMA on ATAPI devices on SiI680. ]
> >
> > Please consult this change with Alan :-).
>
> No, I'm not. Sorry. I'm look for more information. But dma is working with
> my SiI3112A, everything is stable, so maybe it should be enabled by default
> for this chipset.

Real bug is in siimage_config_drive_for_dma():

		if (!(hwif->atapi_dma))
			goto fast_ata_pio;

Remove these two lines and DMA should be auto-enabled.

BTW unfortunately "it works for me" approach doesn't work in IDE ;-).
--
Bartlomiej


^ permalink raw reply	[flat|nested] 11+ messages in thread

* [PATCH] Merge the changes from siimage 2.4.22-pre9 to 2.6.0-test2
@ 2003-07-31 17:49 Marcelo Penna Guerra
  2003-07-31 15:25 ` Bartlomiej Zolnierkiewicz
  2003-07-31 15:58 ` Alan Cox
  0 siblings, 2 replies; 11+ messages in thread
From: Marcelo Penna Guerra @ 2003-07-31 17:49 UTC (permalink / raw)
  To: lkml; +Cc: Andre Hedrick

[-- Attachment #1: Type: text/plain, Size: 780 bytes --]

Hi,

I don't know if anyone is working on this, but I merged the changes from 
siimage 1.06 present in 2.4.x to 2.6.0-test2. I'm really not very familiar 
with the IDE code, so it's probably a good idea if someone could take a look 
at it. All I can tell is it's working with the SiI3112A present in my 
motherboard and it's a lot more stable than before.

I also added the suggestion from Andre to make the driver not care about cable 
detection and found a possible bug in the 2.4.x code.

In 2.4.22-pre9:

if (!is_sata(hwif)) 
       hwif->atapi_dma = 1;

and DMA is not enabled by default.

I think it should be:

if (is_sata(hwif)) 
       hwif->atapi_dma = 1;

With this DMA is enabled by default on my board and works great.

Marcelo Penna Guerra

[-- Attachment #2: siimage-1.06.diff --]
[-- Type: text/x-diff, Size: 31997 bytes --]

--- siimage.c	2003-07-31 14:38:41.622747984 -0300
+++ siimage.c.novo	2003-07-31 14:38:34.102891176 -0300
@@ -1,7 +1,24 @@
 /*
- * linux/drivers/ide/pci/siimage.c		Version 1.02	Jan 30, 2003
+ * linux/drivers/ide/pci/siimage.c             Version 1.06    June 11, 2003
  *
  * Copyright (C) 2001-2002	Andre Hedrick <andre@linux-ide.org>
+ * Copyright (C) 2003          Red Hat <alan@redhat.com>
+ *
+ *  May be copied or modified under the terms of the GNU General Public License
+ *
+ *  Documentation available under NDA only
+ *
+ *
+ *  FAQ Items:
+ *     If you are using Marvell SATA-IDE adapters with Maxtor drives
+ *     ensure the system is set up for ATA100/UDMA5 not UDMA6.
+ *
+ *     If you are using WD drives with SATA bridges you must set the
+ *     drive to "Single". "Master" will hang
+ *
+ *     If you have strange problems with nVidia chipset systems please
+ *     see the SI support documentation and update your system BIOS
+ *     if neccessary
  */
 
 #include <linux/config.h>
@@ -27,12 +44,101 @@
 static struct pci_dev *siimage_devs[SIIMAGE_MAX_DEVS];
 static int n_siimage_devs;
 
+/**
+ *     pdev_is_sata            -       check if device is SATA
+ *     @pdev:  PCI device to check
+ *
+ *     Returns true if this is a SATA controller
+ */
+
+static int pdev_is_sata(struct pci_dev *pdev)
+{
+	switch(pdev->device)
+	{
+		case PCI_DEVICE_ID_SII_3112:
+		case PCI_DEVICE_ID_SII_1210SA:
+			return 1;
+		case PCI_DEVICE_ID_SII_680:
+			return 0;
+	}
+	BUG();
+}
+
+/**
+ *     is_sata                 -       check if hwif is SATA
+ *     @hwif:  interface to check
+ *
+ *     Returns true if this is a SATA controller
+ */
+
+static inline int is_sata(ide_hwif_t *hwif)
+{
+	return pdev_is_sata(hwif->pci_dev);
+}
+
+/**
+ *     siimage_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 siimage_selreg(ide_hwif_t *hwif, int r)
+{
+	unsigned long base = (unsigned long)hwif->hwif_data;
+	base += 0xA0 + r;
+	if(hwif->mmio)
+		base += (hwif->channel << 6);
+	else
+		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 either
+ *     PCI space or MMIO 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        = HWIF(drive);
+	unsigned long base = (unsigned long)hwif->hwif_data;
+	base += 0xA0 + r;
+	if(hwif->mmio)
+		base += (hwif->channel << 6);
+	else
+		base += (hwif->channel << 4);
+	base |= drive->select.b.unit << drive->select.b.unit;
+	return base;
+}
+
+/**
+ *     print_siimage_get_info  -       print minimal proc information
+ *     @buf: buffer to write into (kernel space)
+ *     @dev: PCI device we are describing
+ *     @index: Controller number
+ *
+ *     Print the basic information for the state of the CMD680/SI3112
+ *     channel. We don't actually dump a lot of information out for
+ *     this controller although we could expand it if we needed.
+ */
+
 static char * print_siimage_get_info (char *buf, struct pci_dev *dev, int index)
 {
 	char *p		= buf;
 	u8 mmio		= (pci_get_drvdata(dev) != NULL) ? 1 : 0;
-	unsigned long bmdma	= (mmio) ? ((unsigned long) pci_get_drvdata(dev)) :
-				    (pci_resource_start(dev, 4));
+	unsigned long bmdma = pci_resource_start(dev, 4);
+        if(mmio)
+                bmdma = pci_resource_start(dev, 5);
 
 	p += sprintf(p, "\nController: %d\n", index);
 	p += sprintf(p, "SiI%x Chipset.\n", dev->device);
@@ -41,17 +147,20 @@
 	p += sprintf(p, "%s-DMA Base 0x%lx\n", (mmio)?"MMIO":"BM", bmdma);
 	p += sprintf(p, "%s-DMA Base 0x%lx\n", (mmio)?"MMIO":"BM", bmdma+8);
 
-	p += sprintf(p, "--------------- Primary Channel "
-			"---------------- Secondary Channel "
-			"-------------\n");
-	p += sprintf(p, "--------------- drive0 --------- drive1 "
-			"-------- drive0 ---------- drive1 ------\n");
-	p += sprintf(p, "PIO Mode:       %s                %s"
-			"               %s                 %s\n",
-			"?", "?", "?", "?");
 	return (char *)p;
 }
 
+/**
+ *     siimage_get_info        -       proc callback
+ *     @buffer: kernel buffer to complete
+ *     @addr: written with base of data to return
+ *     offset: seek offset
+ *     count: bytes to fill in
+ *
+ *     Called when the user reads data from the virtual file for this
+ *     controller from /proc
+ */
+
 static int siimage_get_info (char *buffer, char **addr, off_t offset, int count)
 {
 	char *p = buffer;
@@ -77,41 +186,56 @@
 	ide_hwif_t *hwif	= HWIF(drive);
 	u8 mode	= 0, scsc = 0;
 
+	unsigned long base = (unsigned long) hwif->hwif_data;
+
 	if (hwif->mmio)
-		scsc = hwif->INB(HWIFADDR(0x4A));
+		scsc = hwif->INB(base + 0x4A);
 	else
 		pci_read_config_byte(hwif->pci_dev, 0x8A, &scsc);
 
-	switch(hwif->pci_dev->device) {
-		case PCI_DEVICE_ID_SII_3112:
-			return 4;
-		case PCI_DEVICE_ID_SII_680:
-			if ((scsc & 0x10) == 0x10)	/* 133 */
-				mode = 4;
-			else if ((scsc & 0x30) == 0x00)	/* 100 */
-				mode = 3;
-			else if ((scsc & 0x20) == 0x20)	/* 66 eek */
-				BUG();	// mode = 2;
-			break;
-		default:	return 0;
+	if(is_sata(hwif))
+	{
+		drive->id->hw_config |= 0x6000;
+		if(strstr(drive->id->model, "Maxtor"))
+			return 3;
+		return 4;
 	}
+
+	if ((scsc & 0x30) == 0x10)      /* 133 */
+		mode = 4;
+	else if ((scsc & 0x30) == 0x20) /* 2xPCI */
+		mode = 4;
+	else if ((scsc & 0x30) == 0x00) /* 100 */
+		mode = 3;
+	else    /* Disabled ? */
+		BUG();
+
 	if (!eighty_ninty_three(drive))
 		mode = min(mode, (u8)1);
 	return mode;
 }
 
+/**
+ *     siimage_taskfile_timing -       turn timing data to a mode
+ *     @hwif: interface to query
+ *
+ *     Read the timing data for the interface and return the
+ *     mode that is being used.
+ */
+
 static byte siimage_taskfile_timing (ide_hwif_t *hwif)
 {
 	u16 timing	= 0x328a;
-
+	unsigned long addr = siimage_selreg(hwif, 2);
 	if (hwif->mmio)
-		timing = hwif->INW(SELADDR(2));
+		timing = hwif->INW(addr);
 	else
-		pci_read_config_word(hwif->pci_dev, SELREG(2), &timing);
+		pci_read_config_word(hwif->pci_dev, addr, &timing);
 
 	switch (timing) {
 		case 0x10c1:	return 4;
 		case 0x10c3:	return 3;
+		case 0x1104:
 		case 0x1281:	return 2;
 		case 0x2283:	return 1;
 		case 0x328a:
@@ -122,31 +246,75 @@
 static void siimage_tuneproc (ide_drive_t *drive, byte mode_wanted)
 {
 	ide_hwif_t *hwif	= HWIF(drive);
-	struct pci_dev *dev	= hwif->pci_dev;
-	u16 speedt		= 0;
-	u8 unit			= drive->select.b.unit;
-
-	if (hwif->mmio)
-		speedt = hwif->INW(SELADDR(0x04|(unit<<unit)));
-	else
-		pci_read_config_word(dev, SELADDR(0x04|(unit<<unit)), &speedt);
+	u32 speedt              = 0;
+	u16 speedp              = 0;
+	unsigned long addr      = siimage_seldev(drive, 0x04);
+	unsigned long tfaddr    = siimage_selreg(hwif, 0x02);
 
 	/* cheat for now and use the docs */
-//	switch(siimage_taskfile_timing(hwif)) {
 	switch(mode_wanted) {
-		case 4:		speedt = 0x10c1; break;
-		case 3:		speedt = 0x10C3; break;
-		case 2:		speedt = 0x1104; break;
-		case 1:		speedt = 0x2283; break;
+		case 4:
+			speedp = 0x10c1;
+			speedt = 0x10c1;
+			break;
+		case 3:
+			speedp = 0x10C3;
+			speedt = 0x10C3;
+			break;
+		case 2:
+			speedp = 0x1104;
+			speedt = 0x1281;
+			break;
+		case 1:
+			speedp = 0x2283;
+			speedt = 0x1281;
+			break;
 		case 0:
-		default:	speedt = 0x328A; break;
+		default:
+			speedp = 0x328A;
+			speedt = 0x328A;
+			break;
 	}
 	if (hwif->mmio)
-		hwif->OUTW(speedt, SELADDR(0x04|(unit<<unit)));
+	{
+		hwif->OUTW(speedt, addr);
+		hwif->OUTW(speedp, tfaddr);
+		/* Now set up IORDY */
+		if(mode_wanted == 3 || mode_wanted == 4)
+			hwif->OUTW(hwif->INW(tfaddr-2)|0x200, tfaddr-2);
+		else
+			hwif->OUTW(hwif->INW(tfaddr-2)&~0x200, tfaddr-2);
+	}
 	else
-		pci_write_config_word(dev, SELADDR(0x04|(unit<<unit)), speedt);
+	{
+		pci_write_config_word(hwif->pci_dev, addr, speedp);
+		pci_write_config_word(hwif->pci_dev, tfaddr, speedt);
+		pci_read_config_word(hwif->pci_dev, tfaddr-2, &speedp);
+		speedp &= ~0x200;
+		/* Set IORDY for mode 3 or 4 */
+		if(mode_wanted == 3 || mode_wanted == 4)
+			speedp |= 0x200;
+		pci_write_config_word(hwif->pci_dev, tfaddr-2, speedp);
+	}
 }
 
+/**
+ *     config_siimage_chipset_for_pio  -       set drive timings
+ *     @drive: drive to tune
+ *     @speed we want
+ *
+ *     Compute the best pio mode we can for a given device. Also honour
+ *     the timings for the driver when dealing with mixed devices. Some
+ *     of this is ugly but its all wrapped up here
+ *
+ *     The SI680 can also do VDMA - we need to start using that
+ *
+ *     FIXME: we use the BIOS channel timings to avoid driving the task
+ *     files too fast at the disk. We need to compute the master/slave
+ *     drive PIO mode properly so that we can up the speed on a hotplug
+ *     system.
+ */
+
 static void config_siimage_chipset_for_pio (ide_drive_t *drive, byte set_speed)
 {
 	u8 channel_timings	= siimage_taskfile_timing(HWIF(drive));
@@ -167,6 +335,16 @@
 	config_siimage_chipset_for_pio(drive, set_speed);
 }
 
+/**
+ *     siimage_tune_chipset    -       set controller timings
+ *     @drive: Drive to set up
+ *     @xferspeed: speed we want to achieve
+ *
+ *     Tune the SII chipset for the desired mode. If we can't achieve
+ *     the desired mode then tune for a lower one, but ultimately
+ *     make the thing work.
+ */
+
 static int siimage_tune_chipset (ide_drive_t *drive, byte xferspeed)
 {
 	u8 ultra6[]		= { 0x0F, 0x0B, 0x07, 0x05, 0x03, 0x02, 0x01 };
@@ -176,30 +354,32 @@
 	ide_hwif_t *hwif	= HWIF(drive);
 	u16 ultra = 0, multi	= 0;
 	u8 mode = 0, unit	= drive->select.b.unit;
-	u8 speed	= ide_rate_filter(siimage_ratemask(drive), xferspeed);
+	u8 speed		= ide_rate_filter(siimage_ratemask(drive), xferspeed);
+	unsigned long base	= (unsigned long)hwif->hwif_data;
 	u8 scsc = 0, addr_mask	= ((hwif->channel) ?
 				    ((hwif->mmio) ? 0xF4 : 0x84) :
 				    ((hwif->mmio) ? 0xB4 : 0x80));
 
+	unsigned long ma        = siimage_seldev(drive, 0x08);
+	unsigned long ua        = siimage_seldev(drive, 0x0C);
+
 	if (hwif->mmio) {
-		scsc = hwif->INB(HWIFADDR(0x4A));
-		mode = hwif->INB(HWIFADDR(addr_mask));
-		multi = hwif->INW(SELADDR(0x08|(unit<<unit)));
-		ultra = hwif->INW(SELADDR(0x0C|(unit<<unit)));
+		scsc = hwif->INB(base + 0x4A);
+		mode = hwif->INB(base + addr_mask);
+		multi = hwif->INW(ma);
+		ultra = hwif->INW(ua);
 	} else {
 		pci_read_config_byte(hwif->pci_dev, HWIFADDR(0x8A), &scsc);
 		pci_read_config_byte(hwif->pci_dev, addr_mask, &mode);
-		pci_read_config_word(hwif->pci_dev,
-				SELREG(0x08|(unit<<unit)), &multi);
-		pci_read_config_word(hwif->pci_dev,
-				SELREG(0x0C|(unit<<unit)), &ultra);
+		pci_read_config_word(hwif->pci_dev, ma, &multi);
+		pci_read_config_word(hwif->pci_dev, ua, &ultra);
 	}
 
 	mode &= ~((unit) ? 0x30 : 0x03);
 	ultra &= ~0x3F;
 	scsc = ((scsc & 0x30) == 0x00) ? 0 : 1;
 
-	scsc = (hwif->pci_dev->device == PCI_DEVICE_ID_SII_3112) ? 1 : scsc;
+	scsc = is_sata(hwif) ? 1 : scsc;
 
 	switch(speed) {
 		case XFER_PIO_4:
@@ -235,20 +415,27 @@
 	}
 
 	if (hwif->mmio) {
-		hwif->OUTB(mode, HWIFADDR(addr_mask));
-		hwif->OUTW(multi, SELADDR(0x08|(unit<<unit)));
-		hwif->OUTW(ultra, SELADDR(0x0C|(unit<<unit)));
+		hwif->OUTB(mode, base + addr_mask);
+		hwif->OUTW(multi, ma);
+		hwif->OUTW(ultra, ua);
 	} else {
 		pci_write_config_byte(hwif->pci_dev, addr_mask, mode);
-		pci_write_config_word(hwif->pci_dev,
-				SELREG(0x08|(unit<<unit)), multi);
-		pci_write_config_word(hwif->pci_dev,
-				SELREG(0x0C|(unit<<unit)), ultra);
+		pci_write_config_word(hwif->pci_dev, ma, multi);
+		pci_write_config_word(hwif->pci_dev, ua, ultra);
 	}
 
 	return (ide_config_drive_speed(drive, speed));
 }
 
+/**
+ *     config_chipset_for_dma  -       configure for DMA
+ *     @drive: drive to configure
+ *
+ *     Called by the IDE layer when it wants the timings set up.
+ *     For the CMD680 we also need to set up the PIO timings and
+ *     enable DMA.
+ */
+
 static int config_chipset_for_dma (ide_drive_t *drive)
 {
 	u8 speed	= ide_dma_speed(drive, siimage_ratemask(drive));
@@ -267,6 +454,16 @@
 	return ide_dma_enable(drive);
 }
 
+/**
+ *     siimage_configure_drive_for_dma -       set up for DMA transfers
+ *     @drive: drive we are going to set up
+ *
+ *     Set up the drive for DMA, tune the controller and drive as
+ *     required. If the drive isn't suitable for DMA or we hit
+ *     other problems then we will drop down to PIO and set up
+ *     PIO appropriately
+ */
+
 static int siimage_config_drive_for_dma (ide_drive_t *drive)
 {
 	ide_hwif_t *hwif	= HWIF(drive);
@@ -316,18 +513,28 @@
 {
 	ide_hwif_t *hwif	= HWIF(drive);
 	u8 dma_altstat		= 0;
+	unsigned long addr	= siimage_selreg(hwif, 1);
 
 	/* return 1 if INTR asserted */
 	if ((hwif->INB(hwif->dma_status) & 4) == 4)
 		return 1;
 
 	/* return 1 if Device INTR asserted */
-	pci_read_config_byte(hwif->pci_dev, SELREG(1), &dma_altstat);
+	pci_read_config_byte(hwif->pci_dev, addr, &dma_altstat);
 	if (dma_altstat & 8)
 		return 0;	//return 1;
 	return 0;
 }
 
+/**
+ *     siimage_mmio_ide_dma_count      -       DMA bytes done
+ *     @drive
+ *
+ *     If we are doing VDMA the CMD680 requires a little bit
+ *     of more careful handling and we have to read the counts
+ *     off ourselves. For non VDMA life is normal.
+ */
+
 static int siimage_mmio_ide_dma_count (ide_drive_t *drive)
 {
 #ifdef SIIMAGE_VIRTUAL_DMAPIO
@@ -335,9 +542,10 @@
 	ide_hwif_t *hwif	= HWIF(drive);
 	u32 count		= (rq->nr_sectors * SECTOR_SIZE);
 	u32 rcount		= 0;
+	unsigned long addr	= siimage_selreg(hwif, 0x1C);
 
-	hwif->OUTL(count, SELADDR(0x1C));
-	rcount = hwif->INL(SELADDR(0x1C));
+	hwif->OUTL(count, addr);
+	rcount = hwif->INL(addr);
 
 	printk("\n%s: count = %d, rcount = %d, nr_sectors = %lu\n",
 		drive->name, count, rcount, rq->nr_sectors);
@@ -346,13 +554,22 @@
 	return __ide_dma_count(drive);
 }
 
-/* returns 1 if dma irq issued, 0 otherwise */
+/**
+ *     siimage_mmio_ide_dma_test_irq   -       check we caused an IRQ
+ *     @drive: drive we are testing
+ *
+ *     Check if we caused an IDE DMA interrupt. We may also have caused
+ *     SATA status interrupts, if so we clean them up and continue.
+ */
+
 static int siimage_mmio_ide_dma_test_irq (ide_drive_t *drive)
 {
 	ide_hwif_t *hwif	= HWIF(drive);
+	unsigned long base      = (unsigned long)hwif->hwif_data;
+	unsigned long addr      = siimage_selreg(hwif, 0x1);
 
 	if (SATA_ERROR_REG) {
-		u32 ext_stat = hwif->INL(HWIFADDR(0x10));
+		u32 ext_stat = hwif->INL(base + 0x10);
 		u8 watchdog = 0;
 		if (ext_stat & ((hwif->channel) ? 0x40 : 0x10)) {
 			u32 sata_error = hwif->INL(SATA_ERROR_REG);
@@ -379,7 +596,7 @@
 		return 1;
 
 	/* return 1 if Device INTR asserted */
-	if ((hwif->INB(SELADDR(1)) & 8) == 8)
+	if ((hwif->INB(addr) & 8) == 8)
 		return 0;	//return 1;
 
 	return 0;
@@ -388,9 +605,6 @@
 static int siimage_mmio_ide_dma_verbose (ide_drive_t *drive)
 {
 	int temp = __ide_dma_verbose(drive);
-#if 0
-	drive->using_dma = 0;
-#endif
 	return temp;
 }
 
@@ -398,11 +612,12 @@
 {
 	ide_hwif_t *hwif	= HWIF(drive);
 	u32 stat_config		= 0;
+	unsigned long addr      = siimage_selreg(hwif, 0);
 
 	if (hwif->mmio) {
-		stat_config = hwif->INL(SELADDR(0));
+		stat_config = hwif->INL(addr);
 	} else
-		pci_read_config_dword(hwif->pci_dev, SELREG(0), &stat_config);
+		pci_read_config_dword(hwif->pci_dev, addr, &stat_config);
 
 	switch (state) {
 		case BUSSTATE_ON:
@@ -424,6 +639,14 @@
 	return 0;
 }
 
+/**
+ *     siimage_reset_poll      -       wait for sata reset
+ *     @drive: drive we are resetting
+ *
+ *     Poll the SATA phy and see whether it has come back from the dead
+ *     yet.
+ */
+
 static int siimage_reset_poll (ide_drive_t *drive)
 {
 	if (SATA_STATUS_REG) {
@@ -452,7 +675,8 @@
 	if (drive->media != ide_disk)
 		return;
 
-	if (HWIF(drive)->pci_dev->device == PCI_DEVICE_ID_SII_3112) {
+	if (is_sata(HWIF(drive)))
+	{
 		drive->special.b.set_geometry = 0;
 		drive->special.b.recalibrate = 0;
 	}
@@ -462,19 +686,21 @@
 {
 	ide_hwif_t *hwif	= HWIF(drive);
 	u8 reset		= 0;
+	unsigned long addr      = siimage_selreg(hwif, 0);
 
 	if (hwif->mmio) {
-		reset = hwif->INB(SELADDR(0));
-		hwif->OUTB((reset|0x03), SELADDR(0));
+		reset = hwif->INB(addr);
+		hwif->OUTB((reset|0x03), addr);
+		/* FIXME:posting */
 		udelay(25);
-		hwif->OUTB(reset, SELADDR(0));
-		(void) hwif->INB(SELADDR(0));
+		hwif->OUTB(reset, addr);
+		(void) hwif->INB(addr);
 	} else {
-		pci_read_config_byte(hwif->pci_dev, SELREG(0), &reset);
-		pci_write_config_byte(hwif->pci_dev, SELREG(0), reset|0x03);
+		pci_read_config_byte(hwif->pci_dev, addr, &reset);
+		pci_write_config_byte(hwif->pci_dev, addr, reset|0x03);
 		udelay(25);
-		pci_write_config_byte(hwif->pci_dev, SELREG(0), reset);
-		pci_read_config_byte(hwif->pci_dev, SELREG(0), &reset);
+		pci_write_config_byte(hwif->pci_dev, addr, reset);
+		pci_read_config_byte(hwif->pci_dev, addr, &reset);
 	}
 
 	if (SATA_STATUS_REG) {
@@ -492,11 +718,11 @@
 
 static void proc_reports_siimage (struct pci_dev *dev, u8 clocking, const char *name)
 {
-	if (dev->device == PCI_DEVICE_ID_SII_3112)
+	if(pdev_is_sata(dev))
 		goto sata_skip;
 
 	printk(KERN_INFO "%s: BASE CLOCK ", name);
-	clocking &= ~0x0C;
+	clocking &= 0x03;
 	switch(clocking) {
 		case 0x03: printk("DISABLED !\n"); break;
 		case 0x02: printk("== 2X PCI \n"); break;
@@ -518,15 +744,25 @@
 #endif /* DISPLAY_SIIMAGE_TIMINGS && CONFIG_PROC_FS */
 }
 
+/**
+ *     setup_mmio_siimage      -       switch an SI controller into MMIO
+ *     @dev: PCI device we are configuring
+ *     @name: device name
+ *
+ *     Attempt to put the device into mmio mode. There are some slight
+ *     complications here with certain systems where the mmio bar isnt
+ *     mapped so we have to be sure we can fall back to I/O.
+ */
+
 static unsigned int setup_mmio_siimage (struct pci_dev *dev, const char *name)
 {
 	unsigned long bar5	= pci_resource_start(dev, 5);
-	unsigned long end5	= pci_resource_end(dev, 5);
+	unsigned long barsize	= pci_resource_len(dev, 5);
 	u8 tmpbyte	= 0;
 	unsigned long addr;
 	void *ioaddr;
 
-	ioaddr = ioremap_nocache(bar5, (end5 - bar5));
+	ioaddr = ioremap(bar5, barsize);
 
 	if (ioaddr == NULL)
 		return 0;
@@ -535,24 +771,23 @@
 	pci_set_drvdata(dev, ioaddr);
 	addr = (unsigned long) ioaddr;
 
-	if (dev->device == PCI_DEVICE_ID_SII_3112) {
-		writel(0, DEVADDR(0x148));
-		writel(0, DEVADDR(0x1C8));
+	if (pdev_is_sata(dev)) {
+		writel(0, addr + 0x148);
+		writel(0, addr + 0x1C8);
 	}
 
-	writeb(0, DEVADDR(0xB4));
-	writeb(0, DEVADDR(0xF4));
-	tmpbyte = readb(DEVADDR(0x4A));
+	writeb(0, addr + 0xB4);
+	writeb(0, addr + 0xF4);
+	tmpbyte = readb(addr + 0x4A);
 
 	switch(tmpbyte) {
 		case 0x01:
-			writeb(tmpbyte|0x10, DEVADDR(0x4A));
-			tmpbyte = readb(DEVADDR(0x4A));
+			/* In 100 MHz clocking, try and switch to 133 */
+			writeb(tmpbyte|0x10, addr + 0x4A);
 		case 0x31:
 			/* if clocking is disabled */
 			/* 133 clock attempt to force it on */
-			writeb(tmpbyte & ~0x20, DEVADDR(0x4A));
-			tmpbyte = readb(DEVADDR(0x4A));
+			writeb(tmpbyte & ~0x20, addr + 0x4A);
 		case 0x11:
 		case 0x21:
 			break;
@@ -562,31 +797,40 @@
 			writeb(tmpbyte, DEVADDR(0x4A));
 			break;
 	}
-	
-	writeb(0x72, DEVADDR(0xA1));
-	writew(0x328A, DEVADDR(0xA2));
-	writel(0x62DD62DD, DEVADDR(0xA4));
-	writel(0x43924392, DEVADDR(0xA8));
-	writel(0x40094009, DEVADDR(0xAC));
-	writeb(0x72, DEVADDR(0xE1));
-	writew(0x328A, DEVADDR(0xE2));
-	writel(0x62DD62DD, DEVADDR(0xE4));
-	writel(0x43924392, DEVADDR(0xE8));
-	writel(0x40094009, DEVADDR(0xEC));
-
-	if (dev->device == PCI_DEVICE_ID_SII_3112) {
-		writel(0xFFFF0000, DEVADDR(0x108));
-		writel(0xFFFF0000, DEVADDR(0x188));
-		writel(0x00680000, DEVADDR(0x148));
-		writel(0x00680000, DEVADDR(0x1C8));
+
+	writeb(      0x72, addr + 0xA1);
+	writew(    0x328A, addr + 0xA2);
+	writel(0x62DD62DD, addr + 0xA4);
+	writel(0x43924392, addr + 0xA8);
+	writel(0x40094009, addr + 0xAC);
+	writeb(      0x72, addr + 0xE1);
+	writew(    0x328A, addr + 0xE2);
+	writel(0x62DD62DD, addr + 0xE4);
+	writel(0x43924392, addr + 0xE8);
+	writel(0x40094009, addr + 0xEC);
+
+	if (pdev_is_sata(dev)) {
+		writel(0xFFFF0000, addr + 0x108);
+		writel(0xFFFF0000, addr + 0x188);
+		writel(0x00680000, addr + 0x148);
+		writel(0x00680000, addr + 0x1C8);
 	}
 
-	tmpbyte = readb(DEVADDR(0x4A));
+	tmpbyte = readb(addr + 0x4A);
 
-	proc_reports_siimage(dev, (tmpbyte>>=4), name);
+	proc_reports_siimage(dev, (tmpbyte>>4), name);
 	return 1;
 }
 
+/**
+ *     init_chipset_siimage    -       set up an SI device
+ *     @dev: PCI device
+ *     @name: device name
+ *
+ *     Perform the initial PCI set up for this device. Attempt to switch
+ *     to 133MHz clocking if the system isn't already set up to do it.
+ */
+
 static unsigned int __init init_chipset_siimage (struct pci_dev *dev, const char *name)
 {
 	u32 class_rev	= 0;
@@ -631,115 +875,133 @@
 			break;
 	}
 
-	pci_read_config_byte(dev, 0x8A, &tmpbyte);
-	pci_write_config_byte(dev, 0xA1, 0x72);
-	pci_write_config_word(dev, 0xA2, 0x328A);
+	pci_read_config_byte(dev,   0x8A, &tmpbyte);
+
+	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_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);
 
 	pci_read_config_byte(dev, 0x8A, &tmpbyte);
-	proc_reports_siimage(dev, (tmpbyte>>=4), name);
+	proc_reports_siimage(dev, (tmpbyte>>4), name);
 	return 0;
 }
 
+/**
+ *     init_mmio_iops_siimage  -       set up the iops for MMIO
+ *     @hwif: interface to set up
+ *
+ *     The basic setup here is fairly simple, we can use standard MMIO
+ *     operations. However we do have to set the taskfile register offsets
+ *     by hand as there isnt a standard defined layout for them this
+ *     time.
+ *
+ *     The hardware supports buffered taskfiles and also some rather nice
+ *     extended PRD tables. Unfortunately right now we don't.
+ */
+
 static void __init init_mmio_iops_siimage (ide_hwif_t *hwif)
 {
 	struct pci_dev *dev	= hwif->pci_dev;
-	unsigned long addr	= (unsigned long) pci_get_drvdata(hwif->pci_dev);
+	void *addr		= pci_get_drvdata(dev);
 	u8 ch			= hwif->channel;
-//	u16 i			= 0;
-	hw_regs_t hw;
+	hw_regs_t		hw;
+	unsigned long		base;
+
+	/*
+	 *      Fill in the basic HWIF bits
+	 */
 
 	default_hwif_mmiops(hwif);
+	hwif->hwif_data			= addr;
+
+	/*
+	 *      Now set up the hw. We have to do this ourselves as
+	 *      the MMIO layout isnt the same as the the standard port
+	 *      based I/O
+	 */
+
 	memset(&hw, 0, sizeof(hw_regs_t));
+	hw.priv				= addr;
 
-#if 1
-#ifdef SIIMAGE_BUFFERED_TASKFILE
-	hw.io_ports[IDE_DATA_OFFSET]	= DEVADDR((ch) ? 0xD0 : 0x90);
-	hw.io_ports[IDE_ERROR_OFFSET]	= DEVADDR((ch) ? 0xD1 : 0x91);
-	hw.io_ports[IDE_NSECTOR_OFFSET]	= DEVADDR((ch) ? 0xD2 : 0x92);
-	hw.io_ports[IDE_SECTOR_OFFSET]	= DEVADDR((ch) ? 0xD3 : 0x93);
-	hw.io_ports[IDE_LCYL_OFFSET]	= DEVADDR((ch) ? 0xD4 : 0x94);
-	hw.io_ports[IDE_HCYL_OFFSET]	= DEVADDR((ch) ? 0xD5 : 0x95);
-	hw.io_ports[IDE_SELECT_OFFSET]	= DEVADDR((ch) ? 0xD6 : 0x96);
-	hw.io_ports[IDE_STATUS_OFFSET]	= DEVADDR((ch) ? 0xD7 : 0x97);
-	hw.io_ports[IDE_CONTROL_OFFSET]	= DEVADDR((ch) ? 0xDA : 0x9A);
-#else /* ! SIIMAGE_BUFFERED_TASKFILE */
-	hw.io_ports[IDE_DATA_OFFSET]	= DEVADDR((ch) ? 0xC0 : 0x80);
-	hw.io_ports[IDE_ERROR_OFFSET]	= DEVADDR((ch) ? 0xC1 : 0x81);
-	hw.io_ports[IDE_NSECTOR_OFFSET]	= DEVADDR((ch) ? 0xC2 : 0x82);
-	hw.io_ports[IDE_SECTOR_OFFSET]	= DEVADDR((ch) ? 0xC3 : 0x83);
-	hw.io_ports[IDE_LCYL_OFFSET]	= DEVADDR((ch) ? 0xC4 : 0x84);
-	hw.io_ports[IDE_HCYL_OFFSET]	= DEVADDR((ch) ? 0xC5 : 0x85);
-	hw.io_ports[IDE_SELECT_OFFSET]	= DEVADDR((ch) ? 0xC6 : 0x86);
-	hw.io_ports[IDE_STATUS_OFFSET]	= DEVADDR((ch) ? 0xC7 : 0x87);
-	hw.io_ports[IDE_CONTROL_OFFSET]	= DEVADDR((ch) ? 0xCA : 0x8A);
-#endif /* SIIMAGE_BUFFERED_TASKFILE */
-#else
-#ifdef SIIMAGE_BUFFERED_TASKFILE
-	for (i = IDE_DATA_OFFSET; i <= IDE_STATUS_OFFSET; i++)
-		hw.io_ports[i] = DEVADDR((ch) ? 0xD0 : 0x90)|(i);
-	hw.io_ports[IDE_CONTROL_OFFSET] = DEVADDR((ch) ? 0xDA : 0x9A);
-#else /* ! SIIMAGE_BUFFERED_TASKFILE */
-	for (i = IDE_DATA_OFFSET; i <= IDE_STATUS_OFFSET; i++)
-		hw.io_ports[i] = DEVADDR((ch) ? 0xC0 : 0x80)|(i);
-	hw.io_ports[IDE_CONTROL_OFFSET] = DEVADDR((ch) ? 0xCA : 0x8A);
-#endif /* SIIMAGE_BUFFERED_TASKFILE */
-#endif
+	base				= (unsigned long)addr;
+	if(ch)
+		base += 0xC0;
+	else
+		base += 0x80;
 
-#if 0
-	printk(KERN_DEBUG "%s: ", hwif->name);
-	for (i = IDE_DATA_OFFSET; i <= IDE_STATUS_OFFSET; i++)
-		printk("0x%08x ", DEVADDR((ch) ? 0xC0 : 0x80)|(i));
-	printk("0x%08x ", DEVADDR((ch) ? 0xCA : 0x8A)|(i));
-#endif
+	/*
+	 *      The buffered task file doesn't have status/control
+	 *      so we can't currently use it sanely since we want to
+	 *      use LBA48 mode.
+	 */
+//	base += 0x10;
+//	hwif->addressing = 1;
+
+	hw.io_ports[IDE_DATA_OFFSET]    = base;
+	hw.io_ports[IDE_ERROR_OFFSET]   = base + 1;
+	hw.io_ports[IDE_NSECTOR_OFFSET] = base + 2;
+	hw.io_ports[IDE_SECTOR_OFFSET]  = base + 3;
+	hw.io_ports[IDE_LCYL_OFFSET]    = base + 4;
+	hw.io_ports[IDE_HCYL_OFFSET]    = base + 5;
+	hw.io_ports[IDE_SELECT_OFFSET]  = base + 6;
+	hw.io_ports[IDE_STATUS_OFFSET]  = base + 7;
+	hw.io_ports[IDE_CONTROL_OFFSET] = base + 10;
 
 	hw.io_ports[IDE_IRQ_OFFSET]	= 0;
 
-        if (dev->device == PCI_DEVICE_ID_SII_3112) {
-		hw.sata_scr[SATA_STATUS_OFFSET]	= DEVADDR((ch) ? 0x184 : 0x104);
-		hw.sata_scr[SATA_ERROR_OFFSET]	= DEVADDR((ch) ? 0x188 : 0x108);
-		hw.sata_scr[SATA_CONTROL_OFFSET]= DEVADDR((ch) ? 0x180 : 0x100);
-		hw.sata_misc[SATA_MISC_OFFSET]	= DEVADDR((ch) ? 0x1C0 : 0x140);
-		hw.sata_misc[SATA_PHY_OFFSET]	= DEVADDR((ch) ? 0x1C4 : 0x144);
-		hw.sata_misc[SATA_IEN_OFFSET]	= DEVADDR((ch) ? 0x1C8 : 0x148);
+	if (pdev_is_sata(dev)) {
+		base = (unsigned long) addr;
+		if(ch)
+			base += 0x80;
+		hw.sata_scr[SATA_STATUS_OFFSET] = base + 0x104;
+		hw.sata_scr[SATA_ERROR_OFFSET]  = base + 0x108;
+		hw.sata_scr[SATA_CONTROL_OFFSET]= base + 0x100;
+		hw.sata_misc[SATA_MISC_OFFSET]  = base + 0x140;
+		hw.sata_misc[SATA_PHY_OFFSET]   = base + 0x144;
+		hw.sata_misc[SATA_IEN_OFFSET]   = base + 0x148;
 	}
 
-	hw.priv				= (void *) addr;
-//	hw.priv				= pci_get_drvdata(hwif->pci_dev);
 	hw.irq				= hwif->pci_dev->irq;
 
 	memcpy(&hwif->hw, &hw, sizeof(hw));
 	memcpy(hwif->io_ports, hwif->hw.io_ports, sizeof(hwif->hw.io_ports));
 
-	if (hwif->pci_dev->device == PCI_DEVICE_ID_SII_3112) {
+	if (is_sata(hwif)) {
 		memcpy(hwif->sata_scr, hwif->hw.sata_scr, sizeof(hwif->hw.sata_scr));
 		memcpy(hwif->sata_misc, hwif->hw.sata_misc, sizeof(hwif->hw.sata_misc));
 	}
 
-#ifdef SIIMAGE_BUFFERED_TASKFILE
-        hwif->addressing = 1;
-#endif /* SIIMAGE_BUFFERED_TASKFILE */
-	hwif->irq			= hw.irq;
-	hwif->hwif_data			= pci_get_drvdata(hwif->pci_dev);
+	base = (unsigned long) addr;
 
 #ifdef SIIMAGE_LARGE_DMA
-	hwif->dma_base			= DEVADDR((ch) ? 0x18 : 0x10);
-	hwif->dma_base2			= DEVADDR((ch) ? 0x08 : 0x00);
-	hwif->dma_prdtable		= (hwif->dma_base2 + 4);
+/* Watch the brackets - even Ken and Dennis get some language design wrong */
+	hwif->dma_base                  = base + (ch ? 0x18 : 0x10);
+	hwif->dma_base2                 = base + (ch ? 0x08 : 0x00);
+	hwif->dma_prdtable              = hwif->dma_base2 + 4;
 #else /* ! SIIMAGE_LARGE_DMA */
-	hwif->dma_base			= DEVADDR((ch) ? 0x08 : 0x00);
-	hwif->dma_base2			= DEVADDR((ch) ? 0x18 : 0x10);
+	hwif->dma_base                  = base + (ch ? 0x08 : 0x00);
+	hwif->dma_base2                 = base + (ch ? 0x18 : 0x10);
 #endif /* SIIMAGE_LARGE_DMA */
-	hwif->mmio			= 1;
+	hwif->mmio			= 2;
 }
 
+/**
+ *     init_iops_siimage       -       set up iops
+ *     @hwif: interface to set up
+ *
+ *     Do the basic setup for the SIIMAGE hardware interface
+ *     and then do the MMIO setup if we can. This is the first
+ *     look in we get for setting up the hwif so that we
+ *     can get the iops right before using them.
+ */
+
 static void __init init_iops_siimage (ide_hwif_t *hwif)
 {
 	struct pci_dev *dev	= hwif->pci_dev;
@@ -748,26 +1010,46 @@
 	pci_read_config_dword(dev, PCI_CLASS_REVISION, &class_rev);
 	class_rev &= 0xff;
 
+	hwif->hwif_data = 0;
+
 	hwif->rqsize = 128;
-	if ((dev->device == PCI_DEVICE_ID_SII_3112) && (!(class_rev)))
-		hwif->rqsize = 16;
+	if (is_sata(hwif))
+		hwif->rqsize = 15;
 
 	if (pci_get_drvdata(dev) == NULL)
 		return;
 	init_mmio_iops_siimage(hwif);
 }
 
+/**
+ *     ata66_siimage   -       check for 80 pin cable
+ *     @hwif: interface to check
+ *
+ *     Check for the presence of an ATA66 capable cable on the
+ *     interface.
+ */
+
 static unsigned int __init ata66_siimage (ide_hwif_t *hwif)
 {
+	unsigned long addr = siimage_selreg(hwif, 0);
 	if (pci_get_drvdata(hwif->pci_dev) == NULL) {
 		u8 ata66 = 0;
-		pci_read_config_byte(hwif->pci_dev, SELREG(0), &ata66);
+		pci_read_config_byte(hwif->pci_dev, addr, &ata66);
 		return (ata66 & 0x01) ? 1 : 0;
 	}
 
-	return (hwif->INB(SELADDR(0)) & 0x01) ? 1 : 0;
+	return (hwif->INB(addr) & 0x01) ? 1 : 0;
 }
 
+/**
+ *     init_hwif_siimage       -       set up hwif structs
+ *     @hwif: interface to set up
+ *
+ *     We do the basic set up of the interface structure. The SIIMAGE
+ *     requires several custom handlers so we override the default
+ *     ide DMA handlers appropriately
+ */
+
 static void __init init_hwif_siimage (ide_hwif_t *hwif)
 {
 	hwif->autodma = 0;
@@ -788,7 +1070,7 @@
 	hwif->mwdma_mask = 0x07;
 	hwif->swdma_mask = 0x07;
 
-	if (hwif->pci_dev->device != PCI_DEVICE_ID_SII_3112)
+	if(is_sata(hwif))
 		hwif->atapi_dma = 1;
 
 	hwif->ide_dma_check = &siimage_config_drive_for_dma;
@@ -802,12 +1084,25 @@
 	} else {
 		hwif->ide_dma_test_irq = & siimage_io_ide_dma_test_irq;
 	}
-	if (!noautodma)
-		hwif->autodma = 1;
+	/*
+	 *      The BIOS often doesn't set up DMA on this controller
+	 *      so we always do it.
+	 */
+
+	hwif->autodma = 1;
 	hwif->drives[0].autodma = hwif->autodma;
 	hwif->drives[1].autodma = hwif->autodma;
 }
 
+/**
+ *     init_dma_siimage        -       set up IDE DMA
+ *     @hwif: interface
+ *     @dmabase: DMA base address to use
+ *
+ *     For the SI chips this requires no special set up so we can just
+ *     let the IDE DMA core do the usual work.
+ */
+
 static void __init init_dma_siimage (ide_hwif_t *hwif, unsigned long dmabase)
 {
 	ide_setup_dma(hwif, dmabase, 8);
@@ -815,6 +1110,14 @@
 
 extern void ide_setup_pci_device(struct pci_dev *, ide_pci_device_t *);
 
+/**
+ *     siimage_init_one        -       pci layer discovery entry
+ *     @dev: PCI device
+ *     @id: ident table entry
+ *
+ *     Called by the PCI code when it finds an SI680 or SI3112 controller.
+ *     We then use the IDE PCI generic helper to do most of the work.
+ */
 
 static int __devinit siimage_init_one(struct pci_dev *dev, const struct pci_device_id *id)
 {
@@ -829,6 +1132,7 @@
 static struct pci_device_id siimage_pci_tbl[] __devinitdata = {
 	{ PCI_VENDOR_ID_CMD, PCI_DEVICE_ID_SII_680,  PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0},
 	{ PCI_VENDOR_ID_CMD, PCI_DEVICE_ID_SII_3112, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 1},
+	{ PCI_VENDOR_ID_CMD, PCI_DEVICE_ID_SII_1210SA, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 2},
 	{ 0, },
 };
 

^ permalink raw reply	[flat|nested] 11+ messages in thread

* Re: [PATCH] Merge the changes from siimage 2.4.22-pre9 to 2.6.0-test2
  2003-07-31 15:25 ` Bartlomiej Zolnierkiewicz
@ 2003-07-31 19:32   ` Marcelo Penna Guerra
  2003-07-31 17:19     ` Alan Cox
  2003-07-31 17:24     ` Bartlomiej Zolnierkiewicz
  2003-08-02  8:29   ` Andre Hedrick
  1 sibling, 2 replies; 11+ messages in thread
From: Marcelo Penna Guerra @ 2003-07-31 19:32 UTC (permalink / raw)
  To: Bartlomiej Zolnierkiewicz; +Cc: Andre Hedrick, linux-kernel

On Thursday 31 July 2003 12:25, Bartlomiej Zolnierkiewicz wrote:
> What do you mean by "a lot more stable than before"?

I mean it doesn't crash the system during intensive read/write operations. It 
has something to do with limiting the max bk per request to 7.5 (hwif-
>rqsize=15).

> Can you separate your changes from forward-port?

They are really small changes. It's the one I mentioned on the first e-mail 
and this one, that was suggested by Andre Hedrick on another post:

	if(is_sata(hwif))
	{
+		drive->id->hw_config |= 0x6000;
		if(strstr(drive->id->model, "Maxtor"))
			return 3;
		return 4;
 	}

> Are you aware of side effect?
> [ Disabling DMA on ATAPI devices on SiI680. ]
>
> Please consult this change with Alan :-).

No, I'm not. Sorry. I'm look for more information. But dma is working with my 
SiI3112A, everything is stable, so maybe it should be enabled by default for 
this chipset.

Also, there's a change missing in this patch. The PCI id for SiI1210SA is 
missing in 2.6.x.

#define PCI_DEVICE_ID_SII_680      0x0680 
+#define PCI_DEVICE_ID_SII_1210SA   0x0240 
#define PCI_DEVICE_ID_SII_3112      0x3112

Anyway, thank you for taking a look at this.

Marcelo Penna Guerra

^ permalink raw reply	[flat|nested] 11+ messages in thread

* Re: [PATCH] Merge the changes from siimage 2.4.22-pre9 to 2.6.0-test2
  2003-07-31 15:25 ` Bartlomiej Zolnierkiewicz
  2003-07-31 19:32   ` Marcelo Penna Guerra
@ 2003-08-02  8:29   ` Andre Hedrick
  1 sibling, 0 replies; 11+ messages in thread
From: Andre Hedrick @ 2003-08-02  8:29 UTC (permalink / raw)
  To: Bartlomiej Zolnierkiewicz; +Cc: Marcelo Penna Guerra, linux-kernel


There is a future proposal to deal with SATAPI devices.
It has to do with the features register having a bit set to define
direction of IO for the PHY.

Expect a proposal to be public in 2-6 months, my best guess.

Obviously I am talking about things that do not exist today again, sorry.

-a


On Thu, 31 Jul 2003, Bartlomiej Zolnierkiewicz wrote:

> 
> On Thu, 31 Jul 2003, Marcelo Penna Guerra wrote:
> 
> > Hi,
> 
> Hi,
> 
> > I don't know if anyone is working on this, but I merged the changes from
> > siimage 1.06 present in 2.4.x to 2.6.0-test2. I'm really not very familiar
> > with the IDE code, so it's probably a good idea if someone could take a look
> > at it. All I can tell is it's working with the SiI3112A present in my
> > motherboard and it's a lot more stable than before.
> 
> Thanks, I'll take a look.
> 
> What do you mean by "a lot more stable than before"?
> 
> > I also added the suggestion from Andre to make the driver not care about cable
> > detection and found a possible bug in the 2.4.x code.
> 
> Can you separate your changes from forward-port?
> 
> > In 2.4.22-pre9:
> >
> > if (!is_sata(hwif))
> >        hwif->atapi_dma = 1;
> >
> > and DMA is not enabled by default.
> 
> This means that if this is a SATA controller DMA shouldn't be
> enabled on ATAPI devices.  There are probably some reasons to do this.
> 
> > I think it should be:
> >
> > if (is_sata(hwif))
> >        hwif->atapi_dma = 1;
> >
> > With this DMA is enabled by default on my board and works great.
> 
> Are you aware of side effect?
> [ Disabling DMA on ATAPI devices on SiI680. ]
> 
> Please consult this change with Alan :-).
> 
> > Marcelo Penna Guerra
> 
> Regards,
> --
> Bartlomiej
> 
> 
> -
> To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
> the body of a message to majordomo@vger.kernel.org
> More majordomo info at  http://vger.kernel.org/majordomo-info.html
> Please read the FAQ at  http://www.tux.org/lkml/
> 


^ permalink raw reply	[flat|nested] 11+ messages in thread

* Re: [PATCH] Merge the changes from siimage 2.4.22-pre9 to 2.6.0-test2
  2003-08-07 13:35   ` Bartlomiej Zolnierkiewicz
@ 2003-08-07 15:53     ` Alan Cox
  0 siblings, 0 replies; 11+ messages in thread
From: Alan Cox @ 2003-08-07 15:53 UTC (permalink / raw)
  To: Bartlomiej Zolnierkiewicz; +Cc: casino_e, Linux Kernel Mailing List

On Iau, 2003-08-07 at 14:35, Bartlomiej Zolnierkiewicz wrote:
> > Then the bug is that ide_ata66_check is getting called at all in the
> > SATA controller case
> 
> drive->sata ?

drive->sata or hwif->sata. Something like that appears to be needed, or
making ata66_check a HWIF() function so it can be overriden just like
the cable detect half is ?

-- 
Alan Cox <alan@lxorguk.ukuu.org.uk>

^ permalink raw reply	[flat|nested] 11+ messages in thread

* Re: [PATCH] Merge the changes from siimage 2.4.22-pre9 to 2.6.0-test2
  2003-08-07 12:29 ` Alan Cox
@ 2003-08-07 13:35   ` Bartlomiej Zolnierkiewicz
  2003-08-07 15:53     ` Alan Cox
  0 siblings, 1 reply; 11+ messages in thread
From: Bartlomiej Zolnierkiewicz @ 2003-08-07 13:35 UTC (permalink / raw)
  To: Alan Cox; +Cc: casino_e, Linux Kernel Mailing List


On 7 Aug 2003, Alan Cox wrote:

> On Iau, 2003-08-07 at 10:49, CASINO_E wrote:
> > > We never check the cable bits for SATA so this is a no-op
> >
> > Alan,
> >
> > Without this, in 2.4.22-pre10-ac1, ide_ata66_check() in ide-iops.c
> > returns 1. This causes, for example, that hdparm -i shows only udma
> > modes 0 to 2 (although the drive has been set to udma6) and refuses to
> > set any value above udma2 with an ugly "Speed warnings UDMA 3/4/5 is
> > not functional".
>
> Then the bug is that ide_ata66_check is getting called at all in the
> SATA controller case

drive->sata ?


^ permalink raw reply	[flat|nested] 11+ messages in thread

* Re: [PATCH] Merge the changes from siimage 2.4.22-pre9 to 2.6.0-test2
  2003-08-07  9:49 CASINO_E
@ 2003-08-07 12:29 ` Alan Cox
  2003-08-07 13:35   ` Bartlomiej Zolnierkiewicz
  0 siblings, 1 reply; 11+ messages in thread
From: Alan Cox @ 2003-08-07 12:29 UTC (permalink / raw)
  To: casino_e; +Cc: Linux Kernel Mailing List

On Iau, 2003-08-07 at 10:49, CASINO_E wrote:
> > We never check the cable bits for SATA so this is a no-op
> 
> Alan,
> 
> Without this, in 2.4.22-pre10-ac1, ide_ata66_check() in ide-iops.c
> returns 1. This causes, for example, that hdparm -i shows only udma
> modes 0 to 2 (although the drive has been set to udma6) and refuses to
> set any value above udma2 with an ugly "Speed warnings UDMA 3/4/5 is
> not functional".

Then the bug is that ide_ata66_check is getting called at all in the
SATA controller case


^ permalink raw reply	[flat|nested] 11+ messages in thread

* Re: [PATCH] Merge the changes from siimage 2.4.22-pre9 to 2.6.0-test2
@ 2003-08-07  9:49 CASINO_E
  2003-08-07 12:29 ` Alan Cox
  0 siblings, 1 reply; 11+ messages in thread
From: CASINO_E @ 2003-08-07  9:49 UTC (permalink / raw)
  To: linux-kernel

Alan Cox <alan@lxorguk.ukuu.org.uk> wrote...
> > 	if(is_sata(hwif))
> > 	{
> > +		drive->id->hw_config |= 0x6000;
> > 		if(strstr(drive->id->model, "Maxtor"))
> > 			return 3;
> > 		return 4;
> >  	}
> 
> We never check the cable bits for SATA so this is a no-op

Alan,

Without this, in 2.4.22-pre10-ac1, ide_ata66_check() in ide-iops.c
returns 1. This causes, for example, that hdparm -i shows only udma
modes 0 to 2 (although the drive has been set to udma6) and refuses to
set any value above udma2 with an ugly "Speed warnings UDMA 3/4/5 is
not functional".

I do not understand the ide subsystem enough (I should say "at all"),
but maybe there are other implications...

Eduardo.




^ permalink raw reply	[flat|nested] 11+ messages in thread

end of thread, other threads:[~2003-08-07 16:01 UTC | newest]

Thread overview: 11+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2003-07-31 17:49 [PATCH] Merge the changes from siimage 2.4.22-pre9 to 2.6.0-test2 Marcelo Penna Guerra
2003-07-31 15:25 ` Bartlomiej Zolnierkiewicz
2003-07-31 19:32   ` Marcelo Penna Guerra
2003-07-31 17:19     ` Alan Cox
2003-07-31 17:24     ` Bartlomiej Zolnierkiewicz
2003-08-02  8:29   ` Andre Hedrick
2003-07-31 15:58 ` Alan Cox
2003-08-07  9:49 CASINO_E
2003-08-07 12:29 ` Alan Cox
2003-08-07 13:35   ` Bartlomiej Zolnierkiewicz
2003-08-07 15:53     ` Alan Cox

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).