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