Skip to contentSkip to conversation

latest libata (includes Silicon Image work)

PATCH In review Jeff Garzik 2 participants 4 messages Mar 18, 2004 – Mar 19, 2004

Subsystems (2)
lore
Share & tools
lore
#0 lore raw

PATCH 1/1 latest libata (includes Silicon Image work)

Attached is the latest libata patch against 2.6.x mainline. Although not 100% of content, most of this patch resolves around getting Silicon Image into better shape. As I mentioned in my last post, this patch affects all libata users, so plenty of testing is requested.

Silicon Image-related changes:

* Only set/clear the BMDMA bits we care about (got a report last night this fixed 3114 for him)

* mask all SATA interrupts

* after determining drive speed, write that information to a special SII register Data Transfer Mode

* (style) make port base address setup a loop, shortening the code and making the code more readable

* limit SII to UDMA5 (reading info on FreeBSD lists and source code scared me about chip errata), mainly related to PATA->SATA bridges.

drivers/scsi/ata_piix.c +1 -3
diff -Nru a/drivers/scsi/ata_piix.c b/drivers/scsi/ata_piix.c
@@ -16,7 +16,7 @@
     May be copied or modified under the terms of the GNU General Public License
 
  */
-#include <linux/config.h>
+
 #include <linux/kernel.h>
 #include <linux/module.h>
 #include <linux/pci.h>
@@ -125,7 +125,6 @@
 	.exec_command		= ata_exec_command_pio,
 
 	.phy_reset		= piix_pata_phy_reset,
-	.phy_config		= pata_phy_config,
 
 	.bmdma_start		= ata_bmdma_start_pio,
 	.fill_sg		= ata_fill_sg,
@@ -148,7 +147,6 @@
 	.exec_command		= ata_exec_command_pio,
 
 	.phy_reset		= piix_sata_phy_reset,
-	.phy_config		= pata_phy_config,	/* not a typo */
 
 	.bmdma_start		= ata_bmdma_start_pio,
 	.fill_sg		= ata_fill_sg,
drivers/scsi/libata-core.c +23 -15
diff -Nru a/drivers/scsi/libata-core.c b/drivers/scsi/libata-core.c
@@ -58,6 +58,7 @@
 static void ata_host_set_udma(struct ata_port *ap);
 static void ata_dev_set_pio(struct ata_port *ap, unsigned int device);
 static void ata_dev_set_udma(struct ata_port *ap, unsigned int device);
+static void ata_set_mode(struct ata_port *ap);
 
 static unsigned int ata_unique_id = 1;
 
@@ -1031,7 +1032,7 @@
 	if ((!found) || (ap->flags & ATA_FLAG_PORT_DISABLED))
 		goto err_out_disable;
 
-	ap->ops->phy_config(ap);
+	ata_set_mode(ap);
 	if (ap->flags & ATA_FLAG_PORT_DISABLED)
 		goto err_out_disable;
 
@@ -1120,13 +1121,13 @@
 }
 
 /**
- *	pata_phy_config -
- *	@ap:
+ *	ata_set_mode - Program timings and issue SET FEATURES - XFER
+ *	@ap: port on which timings will be programmed
  *
  *	LOCKING:
  *
  */
-void pata_phy_config(struct ata_port *ap)
+static void ata_set_mode(struct ata_port *ap)
 {
 	unsigned int force_pio;
 
@@ -1158,6 +1159,8 @@
 			return;
 	}
 
+	if (ap->ops->post_set_mode)
+		ap->ops->post_set_mode(ap);
 }
 
 /**
@@ -2263,9 +2266,12 @@
 	mb();	/* make sure PRD table writes are visible to controller */
 	writel(ap->prd_dma, mmio + ATA_DMA_TABLE_OFS);
 
-	/* specify data direction */
-	/* FIXME: redundant to later start-dma command? */
-	writeb(rw ? 0 : ATA_DMA_WR, mmio + ATA_DMA_CMD);
+	/* specify data direction, triple-check start bit is clear */
+	dmactl = readb(mmio + ATA_DMA_CMD);
+	dmactl &= ~(ATA_DMA_WR | ATA_DMA_START);
+	if (!rw)
+		dmactl |= ATA_DMA_WR;
+	writeb(dmactl, mmio + ATA_DMA_CMD);
 
 	/* clear interrupt, error bits */
 	host_stat = readb(mmio + ATA_DMA_STATUS);
@@ -2275,7 +2281,6 @@
 	ap->ops->exec_command(ap, &qc->tf);
 
 	/* start host DMA transaction */
-	dmactl = readb(mmio + ATA_DMA_CMD);
 	writeb(dmactl | ATA_DMA_START, mmio + ATA_DMA_CMD);
 
 	/* Strictly, one may wish to issue a readb() here, to
@@ -2308,9 +2313,12 @@
 	/* load PRD table addr. */
 	outl(ap->prd_dma, ap->ioaddr.bmdma_addr + ATA_DMA_TABLE_OFS);
 
-	/* specify data direction */
-	/* FIXME: redundant to later start-dma command? */
-	outb(rw ? 0 : ATA_DMA_WR, ap->ioaddr.bmdma_addr + ATA_DMA_CMD);
+	/* specify data direction, triple-check start bit is clear */
+	dmactl = inb(ap->ioaddr.bmdma_addr + ATA_DMA_CMD);
+	dmactl &= ~(ATA_DMA_WR | ATA_DMA_START);
+	if (!rw)
+		dmactl |= ATA_DMA_WR;
+	outb(dmactl, ap->ioaddr.bmdma_addr + ATA_DMA_CMD);
 
 	/* clear interrupt, error bits */
 	host_stat = inb(ap->ioaddr.bmdma_addr + ATA_DMA_STATUS);
@@ -2321,7 +2329,6 @@
 	ap->ops->exec_command(ap, &qc->tf);
 
 	/* start host DMA transaction */
-	dmactl = inb(ap->ioaddr.bmdma_addr + ATA_DMA_CMD);
 	outb(dmactl | ATA_DMA_START,
 	     ap->ioaddr.bmdma_addr + ATA_DMA_CMD);
 }
@@ -2344,14 +2351,16 @@
 		void *mmio = (void *) ap->ioaddr.bmdma_addr;
 
 		/* clear start/stop bit */
-		writeb(0, mmio + ATA_DMA_CMD);
+		writeb(readb(mmio + ATA_DMA_CMD) & ~ATA_DMA_START,
+		       mmio + ATA_DMA_CMD);
 
 		/* ack intr, err bits */
 		writeb(host_stat | ATA_DMA_INTR | ATA_DMA_ERR,
 		       mmio + ATA_DMA_STATUS);
 	} else {
 		/* clear start/stop bit */
-		outb(0, ap->ioaddr.bmdma_addr + ATA_DMA_CMD);
+		outb(inb(ap->ioaddr.bmdma_addr + ATA_DMA_CMD) & ~ATA_DMA_START,
+		     ap->ioaddr.bmdma_addr + ATA_DMA_CMD);
 
 		/* ack intr, err bits */
 		outb(host_stat | ATA_DMA_INTR | ATA_DMA_ERR,
@@ -3381,7 +3390,6 @@
 EXPORT_SYMBOL_GPL(ata_bmdma_start_mmio);
 EXPORT_SYMBOL_GPL(ata_port_probe);
 EXPORT_SYMBOL_GPL(sata_phy_reset);
-EXPORT_SYMBOL_GPL(pata_phy_config);
 EXPORT_SYMBOL_GPL(ata_bus_reset);
 EXPORT_SYMBOL_GPL(ata_port_disable);
 EXPORT_SYMBOL_GPL(ata_pci_init_one);
drivers/scsi/sata_promise.c +0 -3
diff -Nru a/drivers/scsi/sata_promise.c b/drivers/scsi/sata_promise.c
@@ -21,7 +21,6 @@
  *
  */
 
-#include <linux/config.h>
 #include <linux/kernel.h>
 #include <linux/module.h>
 #include <linux/pci.h>
@@ -201,7 +200,6 @@
 	.check_status		= ata_check_status_mmio,
 	.exec_command		= pdc_exec_command_mmio,
 	.phy_reset		= sata_phy_reset,
-	.phy_config		= pata_phy_config,	/* not a typo */
 	.bmdma_start            = pdc_dma_start,
 	.fill_sg		= pdc_fill_sg,
 	.eng_timeout		= pdc_eng_timeout,
@@ -219,7 +217,6 @@
 	.check_status		= ata_check_status_mmio,
 	.exec_command		= pdc_exec_command_mmio,
 	.phy_reset		= pdc_20621_phy_reset,
-	.phy_config		= pata_phy_config,	/* not a typo */
 	.bmdma_start            = pdc20621_dma_start,
 	.fill_sg		= pdc20621_fill_sg,
 	.eng_timeout		= pdc_eng_timeout,
drivers/scsi/sata_sil.c +65 -50

182 lines not on this page · raw message

drivers/scsi/sata_svw.c +0 -1
diff -Nru a/drivers/scsi/sata_svw.c b/drivers/scsi/sata_svw.c
@@ -226,7 +226,6 @@
 	.check_status		= k2_stat_check_status,
 	.exec_command		= ata_exec_command_mmio,
 	.phy_reset		= sata_phy_reset,
-	.phy_config		= pata_phy_config,	/* not a typo */
 	.bmdma_start            = ata_bmdma_start_mmio,
 	.fill_sg		= ata_fill_sg,
 	.eng_timeout		= ata_eng_timeout,
drivers/scsi/sata_via.c +154 -74

301 lines not on this page · raw message

drivers/scsi/sata_vsc.c +2 -3
diff -Nru a/drivers/scsi/sata_vsc.c b/drivers/scsi/sata_vsc.c
@@ -207,7 +207,6 @@
 	.exec_command		= ata_exec_command_mmio,
 	.check_status		= ata_check_status_mmio,
 	.phy_reset		= sata_phy_reset,
-	.phy_config		= pata_phy_config,	/* not a typo */
 	.bmdma_start            = ata_bmdma_start_mmio,
 	.fill_sg		= ata_fill_sg,
 	.eng_timeout		= ata_eng_timeout,
@@ -268,10 +267,10 @@
 	/*
 	 * Use 32 bit DMA mask, because 64 bit address support is poor.
 	 */
-	rc = pci_set_dma_mask(pdev, 0xFFFFFFFF);
+	rc = pci_set_dma_mask(pdev, 0xFFFFFFFFULL);
 	if (rc)
 		goto err_out_regions;
-	rc = pci_set_consistent_dma_mask(pdev, 0xFFFFFFFF);
+	rc = pci_set_consistent_dma_mask(pdev, 0xFFFFFFFFULL);
 	if (rc)
 		goto err_out_regions;
 
include/linux/libata.h +1 -2
diff -Nru a/include/linux/libata.h b/include/linux/libata.h
@@ -362,7 +362,7 @@
 	u8   (*check_status)(struct ata_port *ap);
 
 	void (*phy_reset) (struct ata_port *ap);
-	void (*phy_config) (struct ata_port *ap);
+	void (*post_set_mode) (struct ata_port *ap);
 
 	void (*bmdma_start) (struct ata_queued_cmd *qc);
 	void (*fill_sg) (struct ata_queued_cmd *qc);
@@ -396,7 +396,6 @@
 };
 
 extern void ata_port_probe(struct ata_port *);
-extern void pata_phy_config(struct ata_port *ap);
 extern void sata_phy_reset(struct ata_port *ap);
 extern void ata_bus_reset(struct ata_port *ap);
 extern void ata_port_disable(struct ata_port *);
#1 lore raw
Quoted 5 lines · Jeff Garzik

Attached is the latest libata patch against 2.6.x mainline. Although not 100% of content, most of this patch resolves around getting Silicon Image into better shape. As I mentioned in my last post, this patch affects all libata users, so plenty of testing is requested.

Jeff,

After applying this to and rebuilding arjanv newest redhat kernel (2.6.4-1.275), sd_mod doesn't load when at sata_sil is loaded. It did before I patched the kernel rpm.

Signature · 5 lines
Mark Lane, CET mailto:[email protected] 
Hard Data Ltd. http://www.harddata.com 
T: 01-780-456-9771   F: 01-780-456-9772
11060 - 166 Avenue Edmonton, AB, Canada, T5X 1Y3
--> Ask me about our Excellent 1U Systems! <--
#2 lore raw
Quoted 11 lines · Mark
Quoted 5 lines · Jeff Garzik

Attached is the latest libata patch against 2.6.x mainline. Although not 100% of content, most of this patch resolves around getting Silicon Image into better shape. As I mentioned in my last post, this patch affects all libata users, so plenty of testing is requested.

Jeff,

After applying this to and rebuilding arjanv newest redhat kernel (2.6.4-1.275), sd_mod doesn't load when at sata_sil is loaded. It did before I patched the kernel rpm.

That's a configuration problem of some sort... libata doesn't change any of that.

Jeff

#3 lore raw
In reply to Jeff Garzik
Quoted 12 lines · Jeff Garzik

Attached is the latest libata patch against 2.6.x mainline. Although not 100% of content, most of this patch resolves around getting Silicon Image into better shape. As I mentioned in my last post, this patch affects all libata users, so plenty of testing is requested.

Silicon Image-related changes:

* Only set/clear the BMDMA bits we care about (got a report last night this fixed 3114 for him)

* mask all SATA interrupts

Quoted 8 lines

* after determining drive speed, write that information to a special SII register Data Transfer Mode

* (style) make port base address setup a loop, shortening the code and making the code more readable

* limit SII to UDMA5 (reading info on FreeBSD lists and source code scared me about chip errata), mainly related to PATA->SATA bridges.

This patch works pretty well. Here my results of a bonnie++ test on a 4 drive array with WD Caviar 74GB Drives on Tyan S2875S with onboard Sil3114.

Signature · 5 lines
Mark Lane, CET mailto:[email protected] 
Hard Data Ltd. http://www.harddata.com 
T: 01-780-456-9771   F: 01-780-456-9772
11060 - 166 Avenue Edmonton, AB, Canada, T5X 1Y3
--> Ask me about our Excellent 1U Systems! <--

Version 1.03 ------Sequential Output------ --Sequential Input- --Random-

                    -Per Chr- --Block-- -Rewrite- -Per Chr- --Block-- --Seeks--
Machine        Size K/sec %CP K/sec %CP K/sec %CP K/sec %CP K/sec %CP  /sec %CP
dynamic-109. 20000M 25546  69 39833  20 25538  11 36725  86 80332  19 339.8   2
                    ------Sequential Create------ --------Random Create--------
                    -Create-- --Read--- -Delete-- -Create-- --Read--- -Delete--
              files  /sec %CP  /sec %CP  /sec %CP  /sec %CP  /sec %CP  /sec %CP
                 16  1535  98 +++++ +++ 17244  95  1646  98 +++++ +++  5744  96

dynamic-109.harddata.net,20000M,25546,69,39833,20,25538,11,36725,86,80332,19,339.8,2,16,1535,98,+++++,+++,17244,95,1646,98,+++++,+++,5744,96