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