patches for pata disks on sata promise controller

Dave Jones davej at redhat.com
Fri Jan 5 00:18:31 UTC 2007


On Thu, Jan 04, 2007 at 03:59:14PM -0700, James C. Bevier wrote:
 > Since the 2.4 kernel, I have had to patch sata_promise.c and libata.c to 
 > recognize pata disks.  When the kernel was updated to 2.6.19, all of the 
 > patches were discarded.

The 2.6.19 rebase is incomplete. This is why it isn't in updates-testing yet.
Pretty much all the stuff that had conflicts get commented out for the
time being.

 > Why were these patches not integrated upstream 
 > over the last two years?

I'll leave Jeff to answer that one.  I know I'm tired of carrying it too.

 > Now the code has been redesigned by someone 
 > (Jeff?) and the patches invalidated.  Here is a first pass at the 
 > patches for the 2.6.19 and beyond kernels.  Dave, could you review the 
 > patch and incorporate them into the next kernel rev?  They seem to work 
 > for me, but they needed to be tested with a system that has sata disks 
 > to make sure I did not screw them up.  Here is the patch and the diffs 
 > for the spec file.

Jeff, care to eyeball this?
(Same diff James sent, but with some indentation fixes)

Thanks,

		Dave




This will update the following files:

 drivers/scsi/libata-core.c
 include/linux/libata.h
 drivers/scsi/sata_promise.c

through these ChangeSets:

  o [libata sata_promise] support PATA ports on SATA controllers

diff -Nru a/drivers/scsi/libata-core.c b/drivers/scsi/libata-core.c
--- a/drivers/ata/libata-core.c	2006-12-27 13:57:22.000000000 -0700
+++ b/drivers/ata/libata-core.c	2006-12-27 12:24:36.000000000 -0700
@@ -5626,6 +5629,7 @@
 		ap->mwdma_mask = ent->mwdma_mask;
 		ap->udma_mask = ent->udma_mask;
 		ap->flags |= ent->port_flags;
+		ap->flags |= ent->pata_flags[port_no];	/* pata fix */
 		ap->ops = ent->port_ops;
 	}
 	ap->hw_sata_spd_limit = UINT_MAX;
@@ -5804,6 +5808,9 @@
 		int irq_line = ent->irq;
 
 		ap = ata_port_add(ent, host, i);
+		ap->flags |= ent->pata_flags[i];	/* pata fix */
+		ata_port_printk(ap, KERN_INFO, " ata_dev_add port %u found\n", i);	/* pata fix */
+
 		host->ports[i] = ap;
 		if (!ap)
 			goto err_out;
@@ -5832,6 +5839,7 @@
 				(ap->pio_mask << ATA_SHIFT_PIO);
 
 		/* print per-port info to dmesg */
+ata_port_printk(ap, KERN_INFO, " ata_dev_add port flags 0x%lX\n", ap->flags);	/* pata fix */
 		ata_port_printk(ap, KERN_INFO, "%cATA max %s cmd 0x%lX "
 				"ctl 0x%lX bmdma 0x%lX irq %d\n",
 				ap->flags & ATA_FLAG_SATA ? 'S' : 'P',
diff -Nru a/drivers/scsi/sata_promise.c b/drivers/scsi/sata_promise.c
--- a/drivers/ata/sata_promise.c	2006-12-27 12:32:27.000000000 -0700
+++ b/drivers/ata/sata_promise.c	2006-12-27 14:15:06.000000000 -0700
@@ -102,6 +102,8 @@
 static int pdc_port_start(struct ata_port *ap);
 static void pdc_port_stop(struct ata_port *ap);
 static void pdc_pata_phy_reset(struct ata_port *ap);
+static void pdc_sata_phy_reset(struct ata_port *ap);	/* pata fix */
+static void pdc_phy_reset(struct ata_port *ap);		/* pata fix */
 static void pdc_qc_prep(struct ata_queued_cmd *qc);
 static void pdc_tf_load_mmio(struct ata_port *ap, const struct ata_taskfile *tf);
 static void pdc_exec_command_mmio(struct ata_port *ap, const struct ata_taskfile *tf);
@@ -140,6 +142,8 @@
 	.exec_command		= pdc_exec_command_mmio,
 	.dev_select		= ata_std_dev_select,
 
+	.phy_reset		= pdc_phy_reset,	/* pata fix */
+
 	.qc_prep		= pdc_qc_prep,
 	.qc_issue		= pdc_qc_issue_prot,
 	.freeze			= pdc_freeze,
@@ -165,7 +169,8 @@
 	.exec_command		= pdc_exec_command_mmio,
 	.dev_select		= ata_std_dev_select,
 
-	.phy_reset		= pdc_pata_phy_reset,
+/*	.phy_reset		= pdc_pata_phy_reset, */	/* pata fix */
+	.phy_reset		= pdc_phy_reset,		/* pata fix */
 
 	.qc_prep		= pdc_qc_prep,
 	.qc_issue		= pdc_qc_issue_prot,
@@ -183,7 +188,7 @@
 	/* board_2037x */
 	{
 		.sht		= &pdc_ata_sht,
-		.flags		= PDC_COMMON_FLAGS | ATA_FLAG_SATA,
+		.flags		= PDC_COMMON_FLAGS /* | ATA_FLAG_SATA */,	/* pata fix */
 		.pio_mask	= 0x1f, /* pio0-4 */
 		.mwdma_mask	= 0x07, /* mwdma0-2 */
 		.udma_mask	= 0x7f, /* udma0-6 ; FIXME */
@@ -353,6 +358,22 @@
 	readl(mmio);	/* flush */
 }
 
+static void pdc_phy_reset(struct ata_port *ap)	/* pata fix */
+{							/* pata fix */
+	/* if no sata flag, test for pata drive */      /* pata fix */
+	if (ap->flags & ATA_FLAG_SATA)  /* pata fix */
+		pdc_sata_phy_reset(ap); /* pata fix */
+	else                            /* pata fix */
+		pdc_pata_phy_reset(ap); /* pata fix */
+}
+
+static void pdc_sata_phy_reset(struct ata_port *ap)	/* pata fix */
+{							/* pata fix */
+	/* if no sata flag, test for pata drive */      /* pata fix */
+	pdc_reset_port(ap);     	/* pata fix */
+	sata_phy_reset(ap);     	/* pata fix */
+}
+
 static void pdc_pata_cbl_detect(struct ata_port *ap)
 {
 	u8 tmp;
@@ -369,6 +390,12 @@
 
 static void pdc_pata_phy_reset(struct ata_port *ap)
 {
+	u8 tmp;                                         /* pata fix */
+	void *mmio = (void *) ap->ioaddr.cmd_addr + PDC_CTLSTAT + 0x03; /* pata fix */
+	tmp = readb(mmio);                              /* pata fix */
+	if (tmp & 0x01)                                 /* pata fix */
+		ap->udma_mask &= ATA_UDMA_MASK_40C;     /* pata fix */
+
 	pdc_pata_cbl_detect(ap);
 	pdc_reset_port(ap);
 	ata_port_probe(ap);
@@ -740,6 +767,7 @@
 	unsigned int board_idx = (unsigned int) ent->driver_data;
 	int pci_dev_busy = 0;
 	int rc;
+	u8 tmp;		/* pata fix */
 
 	if (!printed_version++)
 		dev_printk(KERN_DEBUG, &pdev->dev, "version " DRV_VERSION "\n");
@@ -802,6 +830,8 @@
 	probe_ent->port[0].scr_addr = base + 0x400;
 	probe_ent->port[1].scr_addr = base + 0x500;
 
+	//printk(KERN_INFO DRV_NAME " looking for PATA port\n");	/* pata fix */
+	dev_printk(KERN_INFO, &pdev->dev, "looking for PATA ports\n");
 	/* notice 4-port boards */
 	switch (board_idx) {
 	case board_40518:
@@ -820,7 +850,27 @@
 		hp->flags |= PDC_FLAG_GEN_II;
 		/* Fall through */
 	case board_2037x:
-		probe_ent->n_ports = 2;
+/*		probe_ent->n_ports = 2; */			/* pata fix */
+		/* the first two ports are always SATA */	/* pata fix */
+		probe_ent->pata_flags[0] = ATA_FLAG_SATA;	/* pata fix */
+		probe_ent->pata_flags[1] = ATA_FLAG_SATA;	/* pata fix */
+
+		/* Some boards also have PATA ports */		/* pata fix */
+		tmp = readb(mmio_base + PDC_FLASH_CTL+1);	/* pata fix */
+		if (!(tmp & 0x80))				/* pata fix */
+		{						/* pata fix */
+			probe_ent->n_ports = 3;			/* pata fix */
+			pdc_ata_setup_port(&probe_ent->port[2], base + 0x300);	/* pata fix */
+			probe_ent->pata_flags[2] = ATA_FLAG_SLAVE_POSS;		/* pata fix */
+//			printk(KERN_INFO DRV_NAME " PATA port found\n");	/* pata fix */
+			dev_printk(KERN_INFO, &pdev->dev, "PATA port found\n");
+		}						/* pata fix */
+		else						/* pata fix */
+		{
+//			printk(KERN_INFO DRV_NAME " PATA port not found\n");	/* pata fix */
+			dev_printk(KERN_INFO, &pdev->dev, "PATA port not found\n");
+       			probe_ent->n_ports = 2;			/* pata fix */
+		}
 		break;
 	case board_20619:
 		probe_ent->n_ports = 4;
diff -Nru a/include/linux/libata.h b/include/linux/libata.h
--- a/include/linux/libata.h	2006-12-27 13:58:14.000000000 -0700
+++ b/include/linux/libata.h	2006-12-27 12:12:57.000000000 -0700
@@ -383,6 +383,7 @@
 	unsigned long		irq2;
 	unsigned int		irq_flags;
 	unsigned long		port_flags;
+	unsigned long		pata_flags[ATA_MAX_PORTS];	/* pata fix */
 	unsigned long		_host_flags;
 	void __iomem		*mmio_base;
 	void			*private_data;

-- 
http://www.codemonkey.org.uk




More information about the fedora-test-list mailing list