dd support for the Promise Ultra100TX2, Promise Ultra100TX2v2 and Ultra133
IDE controllers. In part from OpenBSD via ragge, in part from FreeBSD.
This commit is contained in:
parent
3b488c3f27
commit
a9f41fe33b
|
@ -1,4 +1,4 @@
|
|||
/* $NetBSD: pciide.c,v 1.137 2001/12/13 20:57:22 bouyer Exp $ */
|
||||
/* $NetBSD: pciide.c,v 1.138 2001/12/16 23:35:52 bouyer Exp $ */
|
||||
|
||||
|
||||
/*
|
||||
|
@ -77,7 +77,7 @@
|
|||
*/
|
||||
|
||||
#include <sys/cdefs.h>
|
||||
__KERNEL_RCSID(0, "$NetBSD: pciide.c,v 1.137 2001/12/13 20:57:22 bouyer Exp $");
|
||||
__KERNEL_RCSID(0, "$NetBSD: pciide.c,v 1.138 2001/12/16 23:35:52 bouyer Exp $");
|
||||
|
||||
#ifndef WDCDEBUG
|
||||
#define WDCDEBUG
|
||||
|
@ -192,6 +192,7 @@ static int acer_isabr_match __P(( struct pci_attach_args *));
|
|||
|
||||
void pdc202xx_chip_map __P((struct pciide_softc*, struct pci_attach_args*));
|
||||
void pdc202xx_setup_channel __P((struct channel_softc*));
|
||||
void pdc20268_setup_channel __P((struct channel_softc*));
|
||||
int pdc202xx_pci_intr __P((void *));
|
||||
int pdc20265_pci_intr __P((void *));
|
||||
|
||||
|
@ -420,6 +421,21 @@ const struct pciide_product_desc pciide_promise_products[] = {
|
|||
"Promise Ultra100/ATA Bus Master IDE Accelerator",
|
||||
pdc202xx_chip_map,
|
||||
},
|
||||
{ PCI_PRODUCT_PROMISE_ULTRA100TX2,
|
||||
IDE_PCI_CLASS_OVERRIDE,
|
||||
"Promise Ultra100TX2/ATA Bus Master IDE Accelerator",
|
||||
pdc202xx_chip_map,
|
||||
},
|
||||
{ PCI_PRODUCT_PROMISE_ULTRA100TX2v2,
|
||||
IDE_PCI_CLASS_OVERRIDE,
|
||||
"Promise Ultra100TX2v2/ATA Bus Master IDE Accelerator",
|
||||
pdc202xx_chip_map,
|
||||
},
|
||||
{ PCI_PRODUCT_PROMISE_ULTRA133,
|
||||
IDE_PCI_CLASS_OVERRIDE,
|
||||
"Promise Ultra133/ATA Bus Master IDE Accelerator",
|
||||
pdc202xx_chip_map,
|
||||
},
|
||||
{ 0,
|
||||
0,
|
||||
NULL,
|
||||
|
@ -3390,10 +3406,20 @@ hpt_pci_intr(arg)
|
|||
#define PDC_IS_262(sc) \
|
||||
((sc)->sc_pp->ide_product == PCI_PRODUCT_PROMISE_ULTRA66 || \
|
||||
(sc)->sc_pp->ide_product == PCI_PRODUCT_PROMISE_ULTRA100 || \
|
||||
(sc)->sc_pp->ide_product == PCI_PRODUCT_PROMISE_ULTRA100X)
|
||||
(sc)->sc_pp->ide_product == PCI_PRODUCT_PROMISE_ULTRA100X || \
|
||||
(sc)->sc_pp->ide_product == PCI_PRODUCT_PROMISE_ULTRA100TX2 || \
|
||||
(sc)->sc_pp->ide_product == PCI_PRODUCT_PROMISE_ULTRA100TX2v2 || \
|
||||
(sc)->sc_pp->ide_product == PCI_PRODUCT_PROMISE_ULTRA133)
|
||||
#define PDC_IS_265(sc) \
|
||||
((sc)->sc_pp->ide_product == PCI_PRODUCT_PROMISE_ULTRA100 || \
|
||||
(sc)->sc_pp->ide_product == PCI_PRODUCT_PROMISE_ULTRA100X)
|
||||
(sc)->sc_pp->ide_product == PCI_PRODUCT_PROMISE_ULTRA100X || \
|
||||
(sc)->sc_pp->ide_product == PCI_PRODUCT_PROMISE_ULTRA100TX2 || \
|
||||
(sc)->sc_pp->ide_product == PCI_PRODUCT_PROMISE_ULTRA100TX2v2 || \
|
||||
(sc)->sc_pp->ide_product == PCI_PRODUCT_PROMISE_ULTRA133)
|
||||
#define PDC_IS_268(sc) \
|
||||
((sc)->sc_pp->ide_product == PCI_PRODUCT_PROMISE_ULTRA100TX2 || \
|
||||
(sc)->sc_pp->ide_product == PCI_PRODUCT_PROMISE_ULTRA100TX2v2 || \
|
||||
(sc)->sc_pp->ide_product == PCI_PRODUCT_PROMISE_ULTRA133)
|
||||
|
||||
void
|
||||
pdc202xx_chip_map(sc, pa)
|
||||
|
@ -3405,14 +3431,17 @@ pdc202xx_chip_map(sc, pa)
|
|||
pcireg_t interface, st, mode;
|
||||
bus_size_t cmdsize, ctlsize;
|
||||
|
||||
st = pci_conf_read(sc->sc_pc, sc->sc_tag, PDC2xx_STATE);
|
||||
WDCDEBUG_PRINT(("pdc202xx_setup_chip: controller state 0x%x\n", st),
|
||||
DEBUG_PROBE);
|
||||
if (!PDC_IS_268(sc)) {
|
||||
st = pci_conf_read(sc->sc_pc, sc->sc_tag, PDC2xx_STATE);
|
||||
WDCDEBUG_PRINT(("pdc202xx_setup_chip: controller state 0x%x\n",
|
||||
st), DEBUG_PROBE);
|
||||
}
|
||||
if (pciide_chipen(sc, pa) == 0)
|
||||
return;
|
||||
|
||||
/* turn off RAID mode */
|
||||
st &= ~PDC2xx_STATE_IDERAID;
|
||||
if (!PDC_IS_268(sc))
|
||||
st &= ~PDC2xx_STATE_IDERAID;
|
||||
|
||||
/*
|
||||
* can't rely on the PCI_CLASS_REG content if the chip was in raid
|
||||
|
@ -3441,63 +3470,73 @@ pdc202xx_chip_map(sc, pa)
|
|||
sc->sc_wdcdev.UDMA_cap = 4;
|
||||
else
|
||||
sc->sc_wdcdev.UDMA_cap = 2;
|
||||
sc->sc_wdcdev.set_modes = pdc202xx_setup_channel;
|
||||
sc->sc_wdcdev.set_modes = PDC_IS_268(sc) ?
|
||||
pdc20268_setup_channel : pdc202xx_setup_channel;
|
||||
sc->sc_wdcdev.channels = sc->wdc_chanarray;
|
||||
sc->sc_wdcdev.nchannels = PCIIDE_NUM_CHANNELS;
|
||||
|
||||
/* setup failsafe defaults */
|
||||
mode = 0;
|
||||
mode = PDC2xx_TIM_SET_PA(mode, pdc2xx_pa[0]);
|
||||
mode = PDC2xx_TIM_SET_PB(mode, pdc2xx_pb[0]);
|
||||
mode = PDC2xx_TIM_SET_MB(mode, pdc2xx_dma_mb[0]);
|
||||
mode = PDC2xx_TIM_SET_MC(mode, pdc2xx_dma_mc[0]);
|
||||
for (channel = 0; channel < sc->sc_wdcdev.nchannels; channel++) {
|
||||
WDCDEBUG_PRINT(("pdc202xx_setup_chip: channel %d drive 0 "
|
||||
"initial timings 0x%x, now 0x%x\n", channel,
|
||||
pci_conf_read(sc->sc_pc, sc->sc_tag,
|
||||
PDC2xx_TIM(channel, 0)), mode | PDC2xx_TIM_IORDYp),
|
||||
if (!PDC_IS_268(sc)) {
|
||||
/* setup failsafe defaults */
|
||||
mode = 0;
|
||||
mode = PDC2xx_TIM_SET_PA(mode, pdc2xx_pa[0]);
|
||||
mode = PDC2xx_TIM_SET_PB(mode, pdc2xx_pb[0]);
|
||||
mode = PDC2xx_TIM_SET_MB(mode, pdc2xx_dma_mb[0]);
|
||||
mode = PDC2xx_TIM_SET_MC(mode, pdc2xx_dma_mc[0]);
|
||||
for (channel = 0;
|
||||
channel < sc->sc_wdcdev.nchannels;
|
||||
channel++) {
|
||||
WDCDEBUG_PRINT(("pdc202xx_setup_chip: channel %d "
|
||||
"drive 0 initial timings 0x%x, now 0x%x\n",
|
||||
channel, pci_conf_read(sc->sc_pc, sc->sc_tag,
|
||||
PDC2xx_TIM(channel, 0)), mode | PDC2xx_TIM_IORDYp),
|
||||
DEBUG_PROBE);
|
||||
pci_conf_write(sc->sc_pc, sc->sc_tag,
|
||||
PDC2xx_TIM(channel, 0), mode | PDC2xx_TIM_IORDYp);
|
||||
WDCDEBUG_PRINT(("pdc202xx_setup_chip: channel %d "
|
||||
"drive 1 initial timings 0x%x, now 0x%x\n",
|
||||
channel, pci_conf_read(sc->sc_pc, sc->sc_tag,
|
||||
PDC2xx_TIM(channel, 1)), mode), DEBUG_PROBE);
|
||||
pci_conf_write(sc->sc_pc, sc->sc_tag,
|
||||
PDC2xx_TIM(channel, 1), mode);
|
||||
}
|
||||
|
||||
mode = PDC2xx_SCR_DMA;
|
||||
if (PDC_IS_262(sc)) {
|
||||
mode = PDC2xx_SCR_SET_GEN(mode, PDC262_SCR_GEN_LAT);
|
||||
} else {
|
||||
/* the BIOS set it up this way */
|
||||
mode = PDC2xx_SCR_SET_GEN(mode, 0x1);
|
||||
}
|
||||
mode = PDC2xx_SCR_SET_I2C(mode, 0x3); /* ditto */
|
||||
mode = PDC2xx_SCR_SET_POLL(mode, 0x1); /* ditto */
|
||||
WDCDEBUG_PRINT(("pdc202xx_setup_chip: initial SCR 0x%x, "
|
||||
"now 0x%x\n",
|
||||
bus_space_read_4(sc->sc_dma_iot, sc->sc_dma_ioh,
|
||||
PDC2xx_SCR),
|
||||
mode), DEBUG_PROBE);
|
||||
bus_space_write_4(sc->sc_dma_iot, sc->sc_dma_ioh,
|
||||
PDC2xx_SCR, mode);
|
||||
|
||||
/* controller initial state register is OK even without BIOS */
|
||||
/* Set DMA mode to IDE DMA compatibility */
|
||||
mode =
|
||||
bus_space_read_1(sc->sc_dma_iot, sc->sc_dma_ioh, PDC2xx_PM);
|
||||
WDCDEBUG_PRINT(("pdc202xx_setup_chip: primary mode 0x%x", mode),
|
||||
DEBUG_PROBE);
|
||||
pci_conf_write(sc->sc_pc, sc->sc_tag, PDC2xx_TIM(channel, 0),
|
||||
mode | PDC2xx_TIM_IORDYp);
|
||||
WDCDEBUG_PRINT(("pdc202xx_setup_chip: channel %d drive 1 "
|
||||
"initial timings 0x%x, now 0x%x\n", channel,
|
||||
pci_conf_read(sc->sc_pc, sc->sc_tag,
|
||||
PDC2xx_TIM(channel, 1)), mode), DEBUG_PROBE);
|
||||
pci_conf_write(sc->sc_pc, sc->sc_tag, PDC2xx_TIM(channel, 1),
|
||||
mode);
|
||||
bus_space_write_1(sc->sc_dma_iot, sc->sc_dma_ioh, PDC2xx_PM,
|
||||
mode | 0x1);
|
||||
mode =
|
||||
bus_space_read_1(sc->sc_dma_iot, sc->sc_dma_ioh, PDC2xx_SM);
|
||||
WDCDEBUG_PRINT((", secondary mode 0x%x\n", mode ), DEBUG_PROBE);
|
||||
bus_space_write_1(sc->sc_dma_iot, sc->sc_dma_ioh, PDC2xx_SM,
|
||||
mode | 0x1);
|
||||
}
|
||||
|
||||
mode = PDC2xx_SCR_DMA;
|
||||
if (PDC_IS_262(sc)) {
|
||||
mode = PDC2xx_SCR_SET_GEN(mode, PDC262_SCR_GEN_LAT);
|
||||
} else {
|
||||
/* the BIOS set it up this way */
|
||||
mode = PDC2xx_SCR_SET_GEN(mode, 0x1);
|
||||
}
|
||||
mode = PDC2xx_SCR_SET_I2C(mode, 0x3); /* ditto */
|
||||
mode = PDC2xx_SCR_SET_POLL(mode, 0x1); /* ditto */
|
||||
WDCDEBUG_PRINT(("pdc202xx_setup_chip: initial SCR 0x%x, now 0x%x\n",
|
||||
bus_space_read_4(sc->sc_dma_iot, sc->sc_dma_ioh, PDC2xx_SCR), mode),
|
||||
DEBUG_PROBE);
|
||||
bus_space_write_4(sc->sc_dma_iot, sc->sc_dma_ioh, PDC2xx_SCR, mode);
|
||||
|
||||
/* controller initial state register is OK even without BIOS */
|
||||
/* Set DMA mode to IDE DMA compatibility */
|
||||
mode = bus_space_read_1(sc->sc_dma_iot, sc->sc_dma_ioh, PDC2xx_PM);
|
||||
WDCDEBUG_PRINT(("pdc202xx_setup_chip: primary mode 0x%x", mode ),
|
||||
DEBUG_PROBE);
|
||||
bus_space_write_1(sc->sc_dma_iot, sc->sc_dma_ioh, PDC2xx_PM,
|
||||
mode | 0x1);
|
||||
mode = bus_space_read_1(sc->sc_dma_iot, sc->sc_dma_ioh, PDC2xx_SM);
|
||||
WDCDEBUG_PRINT((", secondary mode 0x%x\n", mode ), DEBUG_PROBE);
|
||||
bus_space_write_1(sc->sc_dma_iot, sc->sc_dma_ioh, PDC2xx_SM,
|
||||
mode | 0x1);
|
||||
|
||||
for (channel = 0; channel < sc->sc_wdcdev.nchannels; channel++) {
|
||||
cp = &sc->pciide_channels[channel];
|
||||
if (pciide_chansetup(sc, channel, interface) == 0)
|
||||
continue;
|
||||
if ((st & (PDC_IS_262(sc) ?
|
||||
if (!PDC_IS_268(sc) && (st & (PDC_IS_262(sc) ?
|
||||
PDC262_STATE_EN(channel):PDC246_STATE_EN(channel))) == 0) {
|
||||
printf("%s: %s channel ignored (disabled)\n",
|
||||
sc->sc_wdcdev.sc_dev.dv_xname, cp->name);
|
||||
|
@ -3511,15 +3550,17 @@ pdc202xx_chip_map(sc, pa)
|
|||
pdc202xx_pci_intr);
|
||||
if (cp->hw_ok == 0)
|
||||
continue;
|
||||
if (pciide_chan_candisable(cp))
|
||||
if (!PDC_IS_268(sc) && pciide_chan_candisable(cp))
|
||||
st &= ~(PDC_IS_262(sc) ?
|
||||
PDC262_STATE_EN(channel):PDC246_STATE_EN(channel));
|
||||
pciide_map_compat_intr(pa, cp, channel, interface);
|
||||
pdc202xx_setup_channel(&cp->wdc_channel);
|
||||
}
|
||||
WDCDEBUG_PRINT(("pdc202xx_setup_chip: new controller state 0x%x\n", st),
|
||||
DEBUG_PROBE);
|
||||
pci_conf_write(sc->sc_pc, sc->sc_tag, PDC2xx_STATE, st);
|
||||
if (!PDC_IS_268(sc)) {
|
||||
WDCDEBUG_PRINT(("pdc202xx_setup_chip: new controller state "
|
||||
"0x%x\n", st), DEBUG_PROBE);
|
||||
pci_conf_write(sc->sc_pc, sc->sc_tag, PDC2xx_STATE, st);
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
|
@ -3640,6 +3681,57 @@ pdc202xx_setup_channel(chp)
|
|||
pciide_print_modes(cp);
|
||||
}
|
||||
|
||||
void
|
||||
pdc20268_setup_channel(chp)
|
||||
struct channel_softc *chp;
|
||||
{
|
||||
struct ata_drive_datas *drvp;
|
||||
int drive;
|
||||
u_int32_t idedma_ctl;
|
||||
struct pciide_channel *cp = (struct pciide_channel*)chp;
|
||||
struct pciide_softc *sc = (struct pciide_softc *)cp->wdc_channel.wdc;
|
||||
int u100;
|
||||
|
||||
/* setup DMA if needed */
|
||||
pciide_channel_dma_setup(cp);
|
||||
|
||||
idedma_ctl = 0;
|
||||
|
||||
/* I don't know what this is for, FreeBSD does it ... */
|
||||
bus_space_write_1(sc->sc_dma_iot, sc->sc_dma_ioh,
|
||||
IDEDMA_CMD + 0x1, 0x0b);
|
||||
|
||||
/*
|
||||
* I don't know what this is for; FreeBSD checks this ... this is not
|
||||
* cable type detect.
|
||||
*/
|
||||
u100 = (bus_space_read_1(sc->sc_dma_iot, sc->sc_dma_ioh,
|
||||
IDEDMA_CMD + 0x3) & 0x04) ? 0 : 1;
|
||||
|
||||
for (drive = 0; drive < 2; drive++) {
|
||||
drvp = &chp->ch_drive[drive];
|
||||
/* If no drive, skip */
|
||||
if ((drvp->drive_flags & DRIVE) == 0)
|
||||
continue;
|
||||
if (drvp->drive_flags & DRIVE_UDMA) {
|
||||
/* use Ultra/DMA */
|
||||
drvp->drive_flags &= ~DRIVE_DMA;
|
||||
idedma_ctl |= IDEDMA_CTL_DRV_DMA(drive);
|
||||
if (drvp->UDMA_mode > 2 && u100 == 0)
|
||||
drvp->UDMA_mode = 2;
|
||||
} else if (drvp->drive_flags & DRIVE_DMA) {
|
||||
idedma_ctl |= IDEDMA_CTL_DRV_DMA(drive);
|
||||
}
|
||||
}
|
||||
/* nothing to do to setup modes, the controller snoop SET_FEATURE cmd */
|
||||
if (idedma_ctl != 0) {
|
||||
/* Add software bits in status register */
|
||||
bus_space_write_1(sc->sc_dma_iot, sc->sc_dma_ioh,
|
||||
IDEDMA_CTL, idedma_ctl);
|
||||
}
|
||||
pciide_print_modes(cp);
|
||||
}
|
||||
|
||||
int
|
||||
pdc202xx_pci_intr(arg)
|
||||
void *arg;
|
||||
|
|
Loading…
Reference in New Issue