diff options
author | Mikael Pettersson <mikpe@it.uu.se> | 2007-01-09 04:50:27 -0500 |
---|---|---|
committer | Jeff Garzik <jeff@garzik.org> | 2007-02-09 17:39:29 -0500 |
commit | 870ae337d568e8633ec30ca6f6afb7b58a558ba3 (patch) | |
tree | e846c14922310b6a30b491bdc07cf3810376eeb1 /drivers/ata/sata_promise.c | |
parent | 7a44e910f43cbb5186e7242f4c32b3a5d2fb6666 (diff) |
sata_promise: TX2plus PATA support
This patch implements a simple way of setting up per-port
flags on the SATA+PATA Promise TX2plus chips, which is a
prerequisite for supporting the PATA port on those chips.
It is based on the observation that ap->flags isn't really
used until after ->port_start() has been invoked. So it
places the "exceptional" per-port flags array in the driver's
private host structure, and uses it in ->port_start() to
finalise the port's flags.
This patch obsoletes the #promise-sata-pata branch included
in the #all branch.
Signed-off-by: Mikael Pettersson <mikpe@it.uu.se>
Signed-off-by: Jeff Garzik <jeff@garzik.org>
Diffstat (limited to 'drivers/ata/sata_promise.c')
-rw-r--r-- | drivers/ata/sata_promise.c | 27 |
1 files changed, 22 insertions, 5 deletions
diff --git a/drivers/ata/sata_promise.c b/drivers/ata/sata_promise.c index f055874a6ec5..6ab057417386 100644 --- a/drivers/ata/sata_promise.c +++ b/drivers/ata/sata_promise.c | |||
@@ -92,6 +92,7 @@ struct pdc_port_priv { | |||
92 | 92 | ||
93 | struct pdc_host_priv { | 93 | struct pdc_host_priv { |
94 | unsigned long flags; | 94 | unsigned long flags; |
95 | unsigned long port_flags[ATA_MAX_PORTS]; | ||
95 | }; | 96 | }; |
96 | 97 | ||
97 | static u32 pdc_sata_scr_read (struct ata_port *ap, unsigned int sc_reg); | 98 | static u32 pdc_sata_scr_read (struct ata_port *ap, unsigned int sc_reg); |
@@ -183,7 +184,7 @@ static const struct ata_port_info pdc_port_info[] = { | |||
183 | /* board_2037x */ | 184 | /* board_2037x */ |
184 | { | 185 | { |
185 | .sht = &pdc_ata_sht, | 186 | .sht = &pdc_ata_sht, |
186 | .flags = PDC_COMMON_FLAGS | ATA_FLAG_SATA, | 187 | .flags = PDC_COMMON_FLAGS, |
187 | .pio_mask = 0x1f, /* pio0-4 */ | 188 | .pio_mask = 0x1f, /* pio0-4 */ |
188 | .mwdma_mask = 0x07, /* mwdma0-2 */ | 189 | .mwdma_mask = 0x07, /* mwdma0-2 */ |
189 | .udma_mask = 0x7f, /* udma0-6 ; FIXME */ | 190 | .udma_mask = 0x7f, /* udma0-6 ; FIXME */ |
@@ -213,7 +214,7 @@ static const struct ata_port_info pdc_port_info[] = { | |||
213 | /* board_2057x */ | 214 | /* board_2057x */ |
214 | { | 215 | { |
215 | .sht = &pdc_ata_sht, | 216 | .sht = &pdc_ata_sht, |
216 | .flags = PDC_COMMON_FLAGS | ATA_FLAG_SATA, | 217 | .flags = PDC_COMMON_FLAGS, |
217 | .pio_mask = 0x1f, /* pio0-4 */ | 218 | .pio_mask = 0x1f, /* pio0-4 */ |
218 | .mwdma_mask = 0x07, /* mwdma0-2 */ | 219 | .mwdma_mask = 0x07, /* mwdma0-2 */ |
219 | .udma_mask = 0x7f, /* udma0-6 ; FIXME */ | 220 | .udma_mask = 0x7f, /* udma0-6 ; FIXME */ |
@@ -271,6 +272,11 @@ static int pdc_port_start(struct ata_port *ap) | |||
271 | struct pdc_port_priv *pp; | 272 | struct pdc_port_priv *pp; |
272 | int rc; | 273 | int rc; |
273 | 274 | ||
275 | /* fix up port flags and cable type for SATA+PATA chips */ | ||
276 | ap->flags |= hp->port_flags[ap->port_no]; | ||
277 | if (ap->flags & ATA_FLAG_SATA) | ||
278 | ap->cbl = ATA_CBL_SATA; | ||
279 | |||
274 | rc = ata_port_start(ap); | 280 | rc = ata_port_start(ap); |
275 | if (rc) | 281 | if (rc) |
276 | return rc; | 282 | return rc; |
@@ -377,7 +383,7 @@ static void pdc_pata_phy_reset(struct ata_port *ap) | |||
377 | 383 | ||
378 | static u32 pdc_sata_scr_read (struct ata_port *ap, unsigned int sc_reg) | 384 | static u32 pdc_sata_scr_read (struct ata_port *ap, unsigned int sc_reg) |
379 | { | 385 | { |
380 | if (sc_reg > SCR_CONTROL) | 386 | if (sc_reg > SCR_CONTROL || ap->cbl != ATA_CBL_SATA) |
381 | return 0xffffffffU; | 387 | return 0xffffffffU; |
382 | return readl((void __iomem *) ap->ioaddr.scr_addr + (sc_reg * 4)); | 388 | return readl((void __iomem *) ap->ioaddr.scr_addr + (sc_reg * 4)); |
383 | } | 389 | } |
@@ -386,7 +392,7 @@ static u32 pdc_sata_scr_read (struct ata_port *ap, unsigned int sc_reg) | |||
386 | static void pdc_sata_scr_write (struct ata_port *ap, unsigned int sc_reg, | 392 | static void pdc_sata_scr_write (struct ata_port *ap, unsigned int sc_reg, |
387 | u32 val) | 393 | u32 val) |
388 | { | 394 | { |
389 | if (sc_reg > SCR_CONTROL) | 395 | if (sc_reg > SCR_CONTROL || ap->cbl != ATA_CBL_SATA) |
390 | return; | 396 | return; |
391 | writel(val, (void __iomem *) ap->ioaddr.scr_addr + (sc_reg * 4)); | 397 | writel(val, (void __iomem *) ap->ioaddr.scr_addr + (sc_reg * 4)); |
392 | } | 398 | } |
@@ -740,6 +746,7 @@ static int pdc_ata_init_one (struct pci_dev *pdev, const struct pci_device_id *e | |||
740 | unsigned int board_idx = (unsigned int) ent->driver_data; | 746 | unsigned int board_idx = (unsigned int) ent->driver_data; |
741 | int pci_dev_busy = 0; | 747 | int pci_dev_busy = 0; |
742 | int rc; | 748 | int rc; |
749 | u8 tmp; | ||
743 | 750 | ||
744 | if (!printed_version++) | 751 | if (!printed_version++) |
745 | dev_printk(KERN_DEBUG, &pdev->dev, "version " DRV_VERSION "\n"); | 752 | dev_printk(KERN_DEBUG, &pdev->dev, "version " DRV_VERSION "\n"); |
@@ -820,7 +827,17 @@ static int pdc_ata_init_one (struct pci_dev *pdev, const struct pci_device_id *e | |||
820 | hp->flags |= PDC_FLAG_GEN_II; | 827 | hp->flags |= PDC_FLAG_GEN_II; |
821 | /* Fall through */ | 828 | /* Fall through */ |
822 | case board_2037x: | 829 | case board_2037x: |
823 | probe_ent->n_ports = 2; | 830 | /* TX2plus boards also have a PATA port */ |
831 | tmp = readb(mmio_base + PDC_FLASH_CTL+1); | ||
832 | if (!(tmp & 0x80)) { | ||
833 | probe_ent->n_ports = 3; | ||
834 | pdc_ata_setup_port(&probe_ent->port[2], base + 0x300); | ||
835 | hp->port_flags[2] = ATA_FLAG_SLAVE_POSS; | ||
836 | printk(KERN_INFO DRV_NAME " PATA port found\n"); | ||
837 | } else | ||
838 | probe_ent->n_ports = 2; | ||
839 | hp->port_flags[0] = ATA_FLAG_SATA; | ||
840 | hp->port_flags[1] = ATA_FLAG_SATA; | ||
824 | break; | 841 | break; |
825 | case board_20619: | 842 | case board_20619: |
826 | probe_ent->n_ports = 4; | 843 | probe_ent->n_ports = 4; |