summaryrefslogtreecommitdiffstats
path: root/sys/dev/ata/chipsets
diff options
context:
space:
mode:
Diffstat (limited to 'sys/dev/ata/chipsets')
-rw-r--r--sys/dev/ata/chipsets/ata-acard.c94
-rw-r--r--sys/dev/ata/chipsets/ata-acerlabs.c98
-rw-r--r--sys/dev/ata/chipsets/ata-ahci.c3
-rw-r--r--sys/dev/ata/chipsets/ata-amd.c69
-rw-r--r--sys/dev/ata/chipsets/ata-ati.c93
-rw-r--r--sys/dev/ata/chipsets/ata-cenatek.c30
-rw-r--r--sys/dev/ata/chipsets/ata-cypress.c31
-rw-r--r--sys/dev/ata/chipsets/ata-cyrix.c79
-rw-r--r--sys/dev/ata/chipsets/ata-highpoint.c91
-rw-r--r--sys/dev/ata/chipsets/ata-intel.c181
-rw-r--r--sys/dev/ata/chipsets/ata-ite.c209
-rw-r--r--sys/dev/ata/chipsets/ata-jmicron.c46
-rw-r--r--sys/dev/ata/chipsets/ata-marvell.c30
-rw-r--r--sys/dev/ata/chipsets/ata-micron.c33
-rw-r--r--sys/dev/ata/chipsets/ata-national.c74
-rw-r--r--sys/dev/ata/chipsets/ata-netcell.c17
-rw-r--r--sys/dev/ata/chipsets/ata-nvidia.c56
-rw-r--r--sys/dev/ata/chipsets/ata-promise.c68
-rw-r--r--sys/dev/ata/chipsets/ata-serverworks.c99
-rw-r--r--sys/dev/ata/chipsets/ata-siliconimage.c180
-rw-r--r--sys/dev/ata/chipsets/ata-sis.c71
-rw-r--r--sys/dev/ata/chipsets/ata-via.c123
22 files changed, 778 insertions, 997 deletions
diff --git a/sys/dev/ata/chipsets/ata-acard.c b/sys/dev/ata/chipsets/ata-acard.c
index c52c2cb..bb81c48 100644
--- a/sys/dev/ata/chipsets/ata-acard.c
+++ b/sys/dev/ata/chipsets/ata-acard.c
@@ -61,8 +61,8 @@ struct ata_serialize {
static int ata_acard_chipinit(device_t dev);
static int ata_acard_ch_attach(device_t dev);
static int ata_acard_status(device_t dev);
-static void ata_acard_850_setmode(device_t dev, int mode);
-static void ata_acard_86X_setmode(device_t dev, int mode);
+static int ata_acard_850_setmode(device_t dev, int target, int mode);
+static int ata_acard_86X_setmode(device_t dev, int target, int mode);
static int ata_serialize(device_t dev, int flags);
static void ata_serialize_init(struct ata_serialize *serial);
@@ -130,6 +130,7 @@ ata_acard_ch_attach(device_t dev)
return ENXIO;
ch->hw.status = ata_acard_status;
+ ch->flags |= ATA_NO_ATAPI_DMA;
return 0;
}
@@ -162,79 +163,52 @@ ata_acard_status(device_t dev)
return 1;
}
-static void
-ata_acard_850_setmode(device_t dev, int mode)
+static int
+ata_acard_850_setmode(device_t dev, int target, int mode)
{
- device_t gparent = GRANDPARENT(dev);
- struct ata_pci_controller *ctlr = device_get_softc(gparent);
- struct ata_channel *ch = device_get_softc(device_get_parent(dev));
- struct ata_device *atadev = device_get_softc(dev);
- int devno = (ch->unit << 1) + atadev->unit;
- int error;
-
- mode = ata_limit_mode(dev, mode,
- ata_atapi(dev) ? ATA_PIO_MAX : ctlr->chip->max_dma);
+ device_t parent = device_get_parent(dev);
+ struct ata_pci_controller *ctlr = device_get_softc(parent);
+ struct ata_channel *ch = device_get_softc(dev);
+ int devno = (ch->unit << 1) + target;
+ mode = min(mode, ctlr->chip->max_dma);
/* XXX SOS missing WDMA0+1 + PIO modes */
if (mode >= ATA_WDMA2) {
- error = ata_controlcmd(dev, ATA_SETFEATURES, ATA_SF_SETXFER, 0, mode);
- if (bootverbose)
- device_printf(dev, "%ssetting %s on %s chip\n",
- (error) ? "FAILURE " : "",
- ata_mode2str(mode), ctlr->chip->text);
- if (!error) {
- u_int8_t reg54 = pci_read_config(gparent, 0x54, 1);
+ u_int8_t reg54 = pci_read_config(parent, 0x54, 1);
reg54 &= ~(0x03 << (devno << 1));
if (mode >= ATA_UDMA0)
reg54 |= (((mode & ATA_MODE_MASK) + 1) << (devno << 1));
- pci_write_config(gparent, 0x54, reg54, 1);
- pci_write_config(gparent, 0x4a, 0xa6, 1);
- pci_write_config(gparent, 0x40 + (devno << 1), 0x0301, 2);
- atadev->mode = mode;
- return;
- }
+ pci_write_config(parent, 0x54, reg54, 1);
+ pci_write_config(parent, 0x4a, 0xa6, 1);
+ pci_write_config(parent, 0x40 + (devno << 1), 0x0301, 2);
}
/* we could set PIO mode timings, but we assume the BIOS did that */
+ return (mode);
}
-static void
-ata_acard_86X_setmode(device_t dev, int mode)
+static int
+ata_acard_86X_setmode(device_t dev, int target, int mode)
{
- device_t gparent = GRANDPARENT(dev);
- struct ata_pci_controller *ctlr = device_get_softc(gparent);
- struct ata_channel *ch = device_get_softc(device_get_parent(dev));
- struct ata_device *atadev = device_get_softc(dev);
- int devno = (ch->unit << 1) + atadev->unit;
- int error;
-
-
- mode = ata_limit_mode(dev, mode,
- ata_atapi(dev) ? ATA_PIO_MAX : ctlr->chip->max_dma);
-
- mode = ata_check_80pin(dev, mode);
-
- /* XXX SOS missing WDMA0+1 + PIO modes */
- if (mode >= ATA_WDMA2) {
- error = ata_controlcmd(dev, ATA_SETFEATURES, ATA_SF_SETXFER, 0, mode);
- if (bootverbose)
- device_printf(dev, "%ssetting %s on %s chip\n",
- (error) ? "FAILURE " : "",
- ata_mode2str(mode), ctlr->chip->text);
- if (!error) {
- u_int16_t reg44 = pci_read_config(gparent, 0x44, 2);
+ device_t parent = device_get_parent(dev);
+ struct ata_pci_controller *ctlr = device_get_softc(parent);
+ struct ata_channel *ch = device_get_softc(dev);
+ int devno = (ch->unit << 1) + target;
+
+ mode = min(mode, ctlr->chip->max_dma);
+ /* XXX SOS missing WDMA0+1 + PIO modes */
+ if (mode >= ATA_WDMA2) {
+ u_int16_t reg44 = pci_read_config(parent, 0x44, 2);
- reg44 &= ~(0x000f << (devno << 2));
- if (mode >= ATA_UDMA0)
- reg44 |= (((mode & ATA_MODE_MASK) + 1) << (devno << 2));
- pci_write_config(gparent, 0x44, reg44, 2);
- pci_write_config(gparent, 0x4a, 0xa6, 1);
- pci_write_config(gparent, 0x40 + devno, 0x31, 1);
- atadev->mode = mode;
- return;
+ reg44 &= ~(0x000f << (devno << 2));
+ if (mode >= ATA_UDMA0)
+ reg44 |= (((mode & ATA_MODE_MASK) + 1) << (devno << 2));
+ pci_write_config(parent, 0x44, reg44, 2);
+ pci_write_config(parent, 0x4a, 0xa6, 1);
+ pci_write_config(parent, 0x40 + devno, 0x31, 1);
}
- }
- /* we could set PIO mode timings, but we assume the BIOS did that */
+ /* we could set PIO mode timings, but we assume the BIOS did that */
+ return (mode);
}
static void
diff --git a/sys/dev/ata/chipsets/ata-acerlabs.c b/sys/dev/ata/chipsets/ata-acerlabs.c
index cf503c5..e74b210 100644
--- a/sys/dev/ata/chipsets/ata-acerlabs.c
+++ b/sys/dev/ata/chipsets/ata-acerlabs.c
@@ -56,7 +56,7 @@ static int ata_ali_chipinit(device_t dev);
static int ata_ali_ch_attach(device_t dev);
static int ata_ali_sata_ch_attach(device_t dev);
static void ata_ali_reset(device_t dev);
-static void ata_ali_setmode(device_t dev, int mode);
+static int ata_ali_setmode(device_t dev, int target, int mode);
/* misc defines */
#define ALI_OLD 0x01
@@ -113,6 +113,7 @@ ata_ali_chipinit(device_t dev)
ctlr->ch_attach = ata_ali_sata_ch_attach;
ctlr->ch_detach = ata_pci_ch_detach;
ctlr->setmode = ata_sata_setmode;
+ ctlr->getrev = ata_sata_getrev;
/* AHCI mode is correctly supported only on the ALi 5288. */
if ((ctlr->chip->chipid == ATA_ALI_5288) &&
@@ -176,6 +177,7 @@ ata_ali_ch_attach(device_t dev)
if (ata_pci_ch_attach(dev))
return ENXIO;
+ ch->flags |= ATA_CHECKS_CABLE;
/* older chips can't do 48bit DMA transfers */
if (ctlr->chip->chiprev <= 0xc4)
ch->flags |= ATA_NO_48BIT_DMA;
@@ -218,6 +220,7 @@ ata_ali_sata_ch_attach(device_t dev)
}
}
ch->flags |= ATA_NO_SLAVE;
+ ch->flags |= ATA_SATA;
/* XXX SOS PHY handling awkward in ALI chip not supported yet */
ata_pci_hw(dev);
@@ -257,67 +260,56 @@ ata_ali_reset(device_t dev)
}
}
-static void
-ata_ali_setmode(device_t dev, int mode)
+static int
+ata_ali_setmode(device_t dev, int target, int mode)
{
- device_t gparent = GRANDPARENT(dev);
- struct ata_pci_controller *ctlr = device_get_softc(gparent);
- struct ata_channel *ch = device_get_softc(device_get_parent(dev));
- struct ata_device *atadev = device_get_softc(dev);
- int devno = (ch->unit << 1) + atadev->unit;
- int error;
-
- mode = ata_limit_mode(dev, mode, ctlr->chip->max_dma);
-
- if (ctlr->chip->cfg2 & ALI_NEW) {
- if (mode > ATA_UDMA2 &&
- pci_read_config(gparent, 0x4a, 1) & (1 << ch->unit)) {
- ata_print_cable(dev, "controller");
- mode = ATA_UDMA2;
- }
- }
- else
- mode = ata_check_80pin(dev, mode);
-
- if (ctlr->chip->cfg2 & ALI_OLD) {
- /* doesn't support ATAPI DMA on write */
- ch->flags |= ATA_ATAPI_DMA_RO;
- if (ch->devices & ATA_ATAPI_MASTER && ch->devices & ATA_ATAPI_SLAVE) {
- /* doesn't support ATAPI DMA on two ATAPI devices */
- device_printf(dev, "two atapi devices on this channel, no DMA\n");
- mode = ata_limit_mode(dev, mode, ATA_PIO_MAX);
- }
- }
+ device_t parent = device_get_parent(dev);
+ struct ata_pci_controller *ctlr = device_get_softc(parent);
+ struct ata_channel *ch = device_get_softc(dev);
+ int devno = (ch->unit << 1) + target;
+ int piomode;
+ u_int32_t piotimings[] =
+ { 0x006d0003, 0x00580002, 0x00440001, 0x00330001,
+ 0x00310001, 0x006d0003, 0x00330001, 0x00310001 };
+ u_int8_t udma[] = {0x0c, 0x0b, 0x0a, 0x09, 0x08, 0x0f, 0x0d};
+ u_int32_t word54;
- error = ata_controlcmd(dev, ATA_SETFEATURES, ATA_SF_SETXFER, 0, mode);
+ mode = min(mode, ctlr->chip->max_dma);
- if (bootverbose)
- device_printf(dev, "%ssetting %s on %s chip\n",
- (error) ? "FAILURE " : "",
- ata_mode2str(mode), ctlr->chip->text);
- if (!error) {
+ if (ctlr->chip->cfg2 & ALI_NEW) {
+ if (mode > ATA_UDMA2 &&
+ pci_read_config(parent, 0x4a, 1) & (1 << ch->unit)) {
+ ata_print_cable(dev, "controller");
+ mode = ATA_UDMA2;
+ }
+ }
+ if (ctlr->chip->cfg2 & ALI_OLD) {
+ /* doesn't support ATAPI DMA on write */
+ ch->flags |= ATA_ATAPI_DMA_RO;
+ if (ch->devices & ATA_ATAPI_MASTER &&
+ ch->devices & ATA_ATAPI_SLAVE) {
+ /* doesn't support ATAPI DMA on two ATAPI devices */
+ device_printf(dev, "two atapi devices on this channel,"
+ " no DMA\n");
+ mode = min(mode, ATA_PIO_MAX);
+ }
+ }
+ /* Set UDMA mode */
+ word54 = pci_read_config(parent, 0x54, 4);
if (mode >= ATA_UDMA0) {
- u_int8_t udma[] = {0x0c, 0x0b, 0x0a, 0x09, 0x08, 0x0f, 0x0d};
- u_int32_t word54 = pci_read_config(gparent, 0x54, 4);
-
word54 &= ~(0x000f000f << (devno << 2));
word54 |= (((udma[mode&ATA_MODE_MASK]<<16)|0x05)<<(devno<<2));
- pci_write_config(gparent, 0x54, word54, 4);
- pci_write_config(gparent, 0x58 + (ch->unit << 2),
- 0x00310001, 4);
+ piomode = ATA_PIO4;
}
else {
- u_int32_t piotimings[] =
- { 0x006d0003, 0x00580002, 0x00440001, 0x00330001,
- 0x00310001, 0x00440001, 0x00330001, 0x00310001};
-
- pci_write_config(gparent, 0x54, pci_read_config(gparent, 0x54, 4) &
- ~(0x0008000f << (devno << 2)), 4);
- pci_write_config(gparent, 0x58 + (ch->unit << 2),
- piotimings[ata_mode2idx(mode)], 4);
+ word54 &= ~(0x0008000f << (devno << 2));
+ piomode = mode;
}
- atadev->mode = mode;
- }
+ pci_write_config(parent, 0x54, word54, 4);
+ /* Set PIO/WDMA mode */
+ pci_write_config(parent, 0x58 + (ch->unit << 2),
+ piotimings[ata_mode2idx(piomode)], 4);
+ return (mode);
}
ATA_DECLARE_DRIVER(ata_ali);
diff --git a/sys/dev/ata/chipsets/ata-ahci.c b/sys/dev/ata/chipsets/ata-ahci.c
index e4a7cd1..39c5152 100644
--- a/sys/dev/ata/chipsets/ata-ahci.c
+++ b/sys/dev/ata/chipsets/ata-ahci.c
@@ -194,6 +194,7 @@ ata_ahci_chipinit(device_t dev)
ctlr->ch_suspend = ata_ahci_ch_suspend;
ctlr->ch_resume = ata_ahci_ch_resume;
ctlr->setmode = ata_sata_setmode;
+ ctlr->getrev = ata_sata_getrev;
ctlr->suspend = ata_ahci_suspend;
ctlr->resume = ata_ahci_ctlr_reset;
@@ -309,6 +310,8 @@ ata_ahci_ch_attach(device_t dev)
ch->hw.softreset = ata_ahci_softreset;
ch->hw.pm_read = ata_ahci_pm_read;
ch->hw.pm_write = ata_ahci_pm_write;
+ ch->flags |= ATA_NO_SLAVE;
+ ch->flags |= ATA_SATA;
ata_ahci_ch_resume(dev);
return 0;
diff --git a/sys/dev/ata/chipsets/ata-amd.c b/sys/dev/ata/chipsets/ata-amd.c
index 9c14e99..1cf9ac0 100644
--- a/sys/dev/ata/chipsets/ata-amd.c
+++ b/sys/dev/ata/chipsets/ata-amd.c
@@ -53,7 +53,7 @@ __FBSDID("$FreeBSD$");
/* local prototypes */
static int ata_amd_chipinit(device_t dev);
-static void ata_amd_setmode(device_t dev, int mode);
+static int ata_amd_setmode(device_t dev, int target, int mode);
/* misc defines */
#define AMD_BUG 0x01
@@ -104,46 +104,37 @@ ata_amd_chipinit(device_t dev)
return 0;
}
-static void
-ata_amd_setmode(device_t dev, int mode)
+static int
+ata_amd_setmode(device_t dev, int target, int mode)
{
- device_t gparent = GRANDPARENT(dev);
- struct ata_pci_controller *ctlr = device_get_softc(gparent);
- struct ata_channel *ch = device_get_softc(device_get_parent(dev));
- struct ata_device *atadev = device_get_softc(dev);
- u_int8_t timings[] = { 0xa8, 0x65, 0x42, 0x22, 0x20, 0x42, 0x22, 0x20,
- 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20 };
- int modes[7] = { 0xc2, 0xc1, 0xc0, 0xc4, 0xc5, 0xc6, 0xc7 };
- int devno = (ch->unit << 1) + atadev->unit;
- int reg = 0x53 - devno;
- int error;
-
- mode = ata_limit_mode(dev, mode, ctlr->chip->max_dma);
-
- if (ctlr->chip->cfg1 & AMD_CABLE) {
- if (mode > ATA_UDMA2 &&
- !(pci_read_config(gparent, 0x42, 1) & (1 << devno))) {
- ata_print_cable(dev, "controller");
- mode = ATA_UDMA2;
+ device_t parent = device_get_parent(dev);
+ struct ata_pci_controller *ctlr = device_get_softc(parent);
+ struct ata_channel *ch = device_get_softc(dev);
+ int devno = (ch->unit << 1) + target;
+ int piomode;
+ u_int8_t timings[] = { 0xa8, 0x65, 0x42, 0x22, 0x20, 0xa8, 0x22, 0x20 };
+ int modes[7] = { 0xc2, 0xc1, 0xc0, 0xc4, 0xc5, 0xc6, 0xc7 };
+ int reg = 0x53 - devno;
+
+ mode = min(mode, ctlr->chip->max_dma);
+ if (ctlr->chip->cfg1 & AMD_CABLE) {
+ if (mode > ATA_UDMA2 &&
+ !(pci_read_config(parent, 0x42, 1) & (1 << devno))) {
+ ata_print_cable(dev, "controller");
+ mode = ATA_UDMA2;
+ }
+ }
+ /* Set UDMA timings. */
+ if (mode >= ATA_UDMA0) {
+ pci_write_config(parent, reg, modes[mode & ATA_MODE_MASK], 1);
+ piomode = ATA_PIO4;
+ } else {
+ pci_write_config(parent, reg, 0x8b, 1);
+ piomode = mode;
}
- }
- else
- mode = ata_check_80pin(dev, mode);
-
-
- error = ata_controlcmd(dev, ATA_SETFEATURES, ATA_SF_SETXFER, 0, mode);
- if (bootverbose)
- device_printf(dev, "%ssetting %s on %s chip\n",
- (error) ? "FAILURE " : "", ata_mode2str(mode),
- ctlr->chip->text);
- if (!error) {
- pci_write_config(gparent, reg - 0x08, timings[ata_mode2idx(mode)], 1);
- if (mode >= ATA_UDMA0)
- pci_write_config(gparent, reg, modes[mode & ATA_MODE_MASK], 1);
- else
- pci_write_config(gparent, reg, 0x8b, 1);
- atadev->mode = mode;
- }
+ /* Set WDMA/PIO timings. */
+ pci_write_config(parent, reg - 0x08, timings[ata_mode2idx(piomode)], 1);
+ return (mode);
}
ATA_DECLARE_DRIVER(ata_amd);
diff --git a/sys/dev/ata/chipsets/ata-ati.c b/sys/dev/ata/chipsets/ata-ati.c
index 4436c7f..d464897 100644
--- a/sys/dev/ata/chipsets/ata-ati.c
+++ b/sys/dev/ata/chipsets/ata-ati.c
@@ -53,7 +53,7 @@ __FBSDID("$FreeBSD$");
/* local prototypes */
static int ata_ati_chipinit(device_t dev);
-static void ata_ati_setmode(device_t dev, int mode);
+static int ata_ati_setmode(device_t dev, int target, int mode);
/* misc defines */
#define ATI_PATA 0x01
@@ -160,68 +160,61 @@ ata_ati_chipinit(device_t dev)
return 0;
}
-static void
-ata_ati_setmode(device_t dev, int mode)
+static int
+ata_ati_setmode(device_t dev, int target, int mode)
{
- device_t gparent = GRANDPARENT(dev);
- struct ata_pci_controller *ctlr = device_get_softc(gparent);
- struct ata_channel *ch = device_get_softc(device_get_parent(dev));
- struct ata_device *atadev = device_get_softc(dev);
- int devno = (ch->unit << 1) + atadev->unit;
- int offset = (devno ^ 0x01) << 3;
- int error;
- u_int8_t piotimings[] = { 0x5d, 0x47, 0x34, 0x22, 0x20, 0x34, 0x22, 0x20,
- 0x20, 0x20, 0x20, 0x20, 0x20, 0x20 };
- u_int8_t dmatimings[] = { 0x77, 0x21, 0x20 };
-
- mode = ata_limit_mode(dev, mode, ctlr->chip->max_dma);
-
- mode = ata_check_80pin(dev, mode);
-
- error = ata_controlcmd(dev, ATA_SETFEATURES, ATA_SF_SETXFER, 0, mode);
-
- if (bootverbose)
- device_printf(dev, "%ssetting %s on %s chip\n",
- (error) ? "FAILURE " : "",
- ata_mode2str(mode), ctlr->chip->text);
- if (!error) {
+ device_t parent = device_get_parent(dev);
+ struct ata_pci_controller *ctlr = device_get_softc(parent);
+ struct ata_channel *ch = device_get_softc(dev);
+ int devno = (ch->unit << 1) + target;
+ int offset = (devno ^ 0x01) << 3;
+ int piomode;
+ u_int8_t piotimings[] = { 0x5d, 0x47, 0x34, 0x22, 0x20 };
+ u_int8_t dmatimings[] = { 0x77, 0x21, 0x20 };
+
+ mode = min(mode, ctlr->chip->max_dma);
if (mode >= ATA_UDMA0) {
- pci_write_config(gparent, 0x56,
- (pci_read_config(gparent, 0x56, 2) &
+ /* Set UDMA mode, enable UDMA, set WDMA2/PIO4 */
+ pci_write_config(parent, 0x56,
+ (pci_read_config(parent, 0x56, 2) &
~(0xf << (devno << 2))) |
((mode & ATA_MODE_MASK) << (devno << 2)), 2);
- pci_write_config(gparent, 0x54,
- pci_read_config(gparent, 0x54, 1) |
+ pci_write_config(parent, 0x54,
+ pci_read_config(parent, 0x54, 1) |
(0x01 << devno), 1);
- pci_write_config(gparent, 0x44,
- (pci_read_config(gparent, 0x44, 4) &
+ pci_write_config(parent, 0x44,
+ (pci_read_config(parent, 0x44, 4) &
~(0xff << offset)) |
(dmatimings[2] << offset), 4);
- }
- else if (mode >= ATA_WDMA0) {
- pci_write_config(gparent, 0x54,
- pci_read_config(gparent, 0x54, 1) &
+ piomode = ATA_PIO4;
+ } else if (mode >= ATA_WDMA0) {
+ /* Disable UDMA, set WDMA mode and timings, calculate PIO. */
+ pci_write_config(parent, 0x54,
+ pci_read_config(parent, 0x54, 1) &
~(0x01 << devno), 1);
- pci_write_config(gparent, 0x44,
- (pci_read_config(gparent, 0x44, 4) &
+ pci_write_config(parent, 0x44,
+ (pci_read_config(parent, 0x44, 4) &
~(0xff << offset)) |
(dmatimings[mode & ATA_MODE_MASK] << offset), 4);
- }
- else
- pci_write_config(gparent, 0x54,
- pci_read_config(gparent, 0x54, 1) &
+ piomode = (mode == ATA_WDMA0) ? ATA_PIO0 :
+ (mode == ATA_WDMA1) ? ATA_PIO3 : ATA_PIO4;
+ } else {
+ /* Disable UDMA, set requested PIO. */
+ pci_write_config(parent, 0x54,
+ pci_read_config(parent, 0x54, 1) &
~(0x01 << devno), 1);
-
- pci_write_config(gparent, 0x4a,
- (pci_read_config(gparent, 0x4a, 2) &
+ piomode = mode;
+ }
+ /* Set PIO mode and timings, calculated above. */
+ pci_write_config(parent, 0x4a,
+ (pci_read_config(parent, 0x4a, 2) &
~(0xf << (devno << 2))) |
- (((mode - ATA_PIO0) & ATA_MODE_MASK) << (devno<<2)),2);
- pci_write_config(gparent, 0x40,
- (pci_read_config(gparent, 0x40, 4) &
+ ((piomode - ATA_PIO0) << (devno<<2)),2);
+ pci_write_config(parent, 0x40,
+ (pci_read_config(parent, 0x40, 4) &
~(0xff << offset)) |
- (piotimings[ata_mode2idx(mode)] << offset), 4);
- atadev->mode = mode;
- }
+ (piotimings[ata_mode2idx(piomode)] << offset), 4);
+ return (mode);
}
ATA_DECLARE_DRIVER(ata_ati);
diff --git a/sys/dev/ata/chipsets/ata-cenatek.c b/sys/dev/ata/chipsets/ata-cenatek.c
index 8f6474c..cc54d2b 100644
--- a/sys/dev/ata/chipsets/ata-cenatek.c
+++ b/sys/dev/ata/chipsets/ata-cenatek.c
@@ -51,11 +51,6 @@ __FBSDID("$FreeBSD$");
#include <dev/ata/ata-pci.h>
#include <ata_if.h>
-/* local prototypes */
-static int ata_cenatek_chipinit(device_t dev);
-static void ata_cenatek_setmode(device_t dev, int mode);
-
-
/*
* Cenatek chipset support functions
*/
@@ -67,32 +62,9 @@ ata_cenatek_probe(device_t dev)
if (pci_get_devid(dev) != ATA_CENATEK_ROCKET)
return ENXIO;
- ctlr->chipinit = ata_cenatek_chipinit;
+ ctlr->chipinit = ata_generic_chipinit;
device_set_desc(dev, "Cenatek Rocket Drive controller");
return (BUS_PROBE_DEFAULT);
}
-static int
-ata_cenatek_chipinit(device_t dev)
-{
- struct ata_pci_controller *ctlr = device_get_softc(dev);
-
- if (ata_setup_interrupt(dev, ata_generic_intr))
- return ENXIO;
-
- ctlr->setmode = ata_cenatek_setmode;
- return 0;
-}
-
-static void
-ata_cenatek_setmode(device_t dev, int mode)
-{
- struct ata_device *atadev = device_get_softc(dev);
-
- mode = ata_limit_mode(dev, mode, ATA_UDMA2);
- mode = ata_check_80pin(dev, mode);
- if (!ata_controlcmd(dev, ATA_SETFEATURES, ATA_SF_SETXFER, 0, mode))
- atadev->mode = mode;
-}
-
ATA_DECLARE_DRIVER(ata_cenatek);
diff --git a/sys/dev/ata/chipsets/ata-cypress.c b/sys/dev/ata/chipsets/ata-cypress.c
index ffa9782..e4c1a93 100644
--- a/sys/dev/ata/chipsets/ata-cypress.c
+++ b/sys/dev/ata/chipsets/ata-cypress.c
@@ -53,7 +53,7 @@ __FBSDID("$FreeBSD$");
/* local prototypes */
static int ata_cypress_chipinit(device_t dev);
-static void ata_cypress_setmode(device_t dev, int mode);
+static int ata_cypress_setmode(device_t dev, int target, int mode);
/*
@@ -93,29 +93,20 @@ ata_cypress_chipinit(device_t dev)
return 0;
}
-static void
-ata_cypress_setmode(device_t dev, int mode)
+static int
+ata_cypress_setmode(device_t dev, int target, int mode)
{
- device_t gparent = GRANDPARENT(dev);
- struct ata_channel *ch = device_get_softc(device_get_parent(dev));
- struct ata_device *atadev = device_get_softc(dev);
- int error;
+ device_t parent = device_get_parent(dev);
+ struct ata_channel *ch = device_get_softc(dev);
- mode = ata_limit_mode(dev, mode, ATA_WDMA2);
+ mode = min(mode, ATA_WDMA2);
- /* XXX SOS missing WDMA0+1 + PIO modes */
- if (mode == ATA_WDMA2) {
- error = ata_controlcmd(dev, ATA_SETFEATURES, ATA_SF_SETXFER, 0, mode);
- if (bootverbose)
- device_printf(dev, "%ssetting WDMA2 on Cypress chip\n",
- error ? "FAILURE " : "");
- if (!error) {
- pci_write_config(gparent, ch->unit ? 0x4e : 0x4c, 0x2020, 2);
- atadev->mode = mode;
- return;
+ /* XXX SOS missing WDMA0+1 + PIO modes */
+ if (mode == ATA_WDMA2) {
+ pci_write_config(parent, ch->unit ? 0x4e : 0x4c, 0x2020, 2);
}
- }
- /* we could set PIO mode timings, but we assume the BIOS did that */
+ /* we could set PIO mode timings, but we assume the BIOS did that */
+ return (mode);
}
ATA_DECLARE_DRIVER(ata_cypress);
diff --git a/sys/dev/ata/chipsets/ata-cyrix.c b/sys/dev/ata/chipsets/ata-cyrix.c
index ddfa562..5a00856 100644
--- a/sys/dev/ata/chipsets/ata-cyrix.c
+++ b/sys/dev/ata/chipsets/ata-cyrix.c
@@ -53,7 +53,8 @@ __FBSDID("$FreeBSD$");
/* local prototypes */
static int ata_cyrix_chipinit(device_t dev);
-static void ata_cyrix_setmode(device_t dev, int mode);
+static int ata_cyrix_ch_attach(device_t dev);
+static int ata_cyrix_setmode(device_t dev, int target, int mode);
/*
@@ -79,53 +80,57 @@ ata_cyrix_chipinit(device_t dev)
if (ata_setup_interrupt(dev, ata_generic_intr))
return ENXIO;
-
+ ctlr->ch_attach = ata_cyrix_ch_attach;
ctlr->setmode = ata_cyrix_setmode;
return 0;
}
-static void
-ata_cyrix_setmode(device_t dev, int mode)
+static int
+ata_cyrix_ch_attach(device_t dev)
{
- struct ata_pci_controller *ctlr = device_get_softc(GRANDPARENT(dev));
- struct ata_channel *ch = device_get_softc(device_get_parent(dev));
- struct ata_device *atadev = device_get_softc(dev);
- int devno = (ch->unit << 1) + atadev->unit;
- u_int32_t piotiming[] =
- { 0x00009172, 0x00012171, 0x00020080, 0x00032010, 0x00040010 };
- u_int32_t dmatiming[] = { 0x00077771, 0x00012121, 0x00002020 };
- u_int32_t udmatiming[] = { 0x00921250, 0x00911140, 0x00911030 };
- int error;
-
- mode = ata_limit_mode(dev, mode, ATA_UDMA2);
-
- error = ata_controlcmd(dev, ATA_SETFEATURES, ATA_SF_SETXFER, 0, mode);
+ struct ata_channel *ch = device_get_softc(dev);
+ int error;
+
+ error = ata_pci_ch_attach(dev);
+ ch->dma.alignment = 16;
+ ch->dma.max_iosize = 64 * DEV_BSIZE;
+ return (error);
+}
- if (bootverbose)
- device_printf(dev, "%ssetting %s on Cyrix chip\n",
- (error) ? "FAILURE " : "", ata_mode2str(mode));
- if (!error) {
+static int
+ata_cyrix_setmode(device_t dev, int target, int mode)
+{
+ struct ata_pci_controller *ctlr = device_get_softc(device_get_parent(dev));
+ struct ata_channel *ch = device_get_softc(dev);
+ int devno = (ch->unit << 1) + target;
+ int piomode;
+ u_int32_t piotiming[] =
+ { 0x00009172, 0x00012171, 0x00020080, 0x00032010, 0x00040010 };
+ u_int32_t dmatiming[] = { 0x00077771, 0x00012121, 0x00002020 };
+ u_int32_t udmatiming[] = { 0x00921250, 0x00911140, 0x00911030 };
+
+ mode = min(mode, ATA_UDMA2);
/* dont try to set the mode if we dont have the resource */
if (ctlr->r_res1) {
- ch->dma.alignment = 16;
- ch->dma.max_iosize = 64 * DEV_BSIZE;
-
- if (mode >= ATA_UDMA0) {
- ATA_OUTL(ch->r_io[ATA_BMCMD_PORT].res,
- 0x24 + (devno << 3), udmatiming[mode & ATA_MODE_MASK]);
- }
- else if (mode >= ATA_WDMA0) {
+ if (mode >= ATA_UDMA0) {
+ /* Set UDMA timings, and PIO4. */
+ ATA_OUTL(ch->r_io[ATA_BMCMD_PORT].res,
+ 0x24 + (devno << 3), udmatiming[mode & ATA_MODE_MASK]);
+ piomode = ATA_PIO4;
+ } else if (mode >= ATA_WDMA0) {
+ /* Set WDMA timings, and respective PIO mode. */
+ ATA_OUTL(ch->r_io[ATA_BMCMD_PORT].res,
+ 0x24 + (devno << 3), dmatiming[mode & ATA_MODE_MASK]);
+ piomode = (mode == ATA_WDMA0) ? ATA_PIO0 :
+ (mode == ATA_WDMA1) ? ATA_PIO3 : ATA_PIO4;
+ } else
+ piomode = mode;
+ /* Set PIO mode calculated above. */
ATA_OUTL(ch->r_io[ATA_BMCMD_PORT].res,
- 0x24 + (devno << 3), dmatiming[mode & ATA_MODE_MASK]);
- }
- else {
- ATA_OUTL(ch->r_io[ATA_BMCMD_PORT].res,
- 0x20 + (devno << 3), piotiming[mode & ATA_MODE_MASK]);
- }
+ 0x20 + (devno << 3), piotiming[ata_mode2idx(piomode)]);
}
- atadev->mode = mode;
- }
+ return (mode);
}
ATA_DECLARE_DRIVER(ata_cyrix);
diff --git a/sys/dev/ata/chipsets/ata-highpoint.c b/sys/dev/ata/chipsets/ata-highpoint.c
index 101b054..511366a 100644
--- a/sys/dev/ata/chipsets/ata-highpoint.c
+++ b/sys/dev/ata/chipsets/ata-highpoint.c
@@ -54,7 +54,7 @@ __FBSDID("$FreeBSD$");
/* local prototypes */
static int ata_highpoint_chipinit(device_t dev);
static int ata_highpoint_ch_attach(device_t dev);
-static void ata_highpoint_setmode(device_t dev, int mode);
+static int ata_highpoint_setmode(device_t dev, int target, int mode);
static int ata_highpoint_check_80pin(device_t dev, int mode);
/* misc defines */
@@ -143,26 +143,27 @@ ata_highpoint_chipinit(device_t dev)
static int
ata_highpoint_ch_attach(device_t dev)
{
- struct ata_channel *ch = device_get_softc(dev);
-
- /* setup the usual register normal pci style */
- if (ata_pci_ch_attach(dev))
- return ENXIO;
-
- ch->flags |= ATA_ALWAYS_DMASTAT;
- return 0;
+ struct ata_pci_controller *ctlr = device_get_softc(device_get_parent(dev));
+ struct ata_channel *ch = device_get_softc(dev);
+
+ /* setup the usual register normal pci style */
+ if (ata_pci_ch_attach(dev))
+ return (ENXIO);
+ ch->flags |= ATA_ALWAYS_DMASTAT;
+ ch->flags |= ATA_CHECKS_CABLE;
+ if (ctlr->chip->cfg1 == HPT_366)
+ ch->flags |= ATA_NO_ATAPI_DMA;
+ return (0);
}
-static void
-ata_highpoint_setmode(device_t dev, int mode)
+static int
+ata_highpoint_setmode(device_t dev, int target, int mode)
{
- device_t gparent = GRANDPARENT(dev);
- struct ata_pci_controller *ctlr = device_get_softc(gparent);
- struct ata_channel *ch = device_get_softc(device_get_parent(dev));
- struct ata_device *atadev = device_get_softc(dev);
- int devno = (ch->unit << 1) + atadev->unit;
- int error;
- u_int32_t timings33[][4] = {
+ device_t parent = device_get_parent(dev);
+ struct ata_pci_controller *ctlr = device_get_softc(parent);
+ struct ata_channel *ch = device_get_softc(dev);
+ int devno = (ch->unit << 1) + target;
+ u_int32_t timings33[][4] = {
/* HPT366 HPT370 HPT372 HPT374 mode */
{ 0x40d0a7aa, 0x06914e57, 0x0d029d5e, 0x0ac1f48a }, /* PIO 0 */
{ 0x40d0a7a3, 0x06914e43, 0x0d029d26, 0x0ac1f465 }, /* PIO 1 */
@@ -179,51 +180,41 @@ ata_highpoint_setmode(device_t dev, int mode)
{ 0x10c9a731, 0x16454e31, 0x1c8a9c62, 0x12ac8242 }, /* UDMA 4 */
{ 0, 0x16454e31, 0x1c8a9c62, 0x12848242 }, /* UDMA 5 */
{ 0, 0, 0x1c869c62, 0x12808242 } /* UDMA 6 */
- };
-
- mode = ata_limit_mode(dev, mode, ctlr->chip->max_dma);
-
- if (ctlr->chip->cfg1 == HPT_366 && ata_atapi(dev))
- mode = ata_limit_mode(dev, mode, ATA_PIO_MAX);
-
- mode = ata_highpoint_check_80pin(dev, mode);
-
- /*
- * most if not all HPT chips cant really handle that the device is
- * running at ATA_UDMA6/ATA133 speed, so we cheat at set the device to
- * a max of ATA_UDMA5/ATA100 to guard against suboptimal performance
- */
- error = ata_controlcmd(dev, ATA_SETFEATURES, ATA_SF_SETXFER, 0,
- ata_limit_mode(dev, mode, ATA_UDMA5));
- if (bootverbose)
- device_printf(dev, "%ssetting %s on HighPoint chip\n",
- (error) ? "FAILURE " : "", ata_mode2str(mode));
- if (!error)
- pci_write_config(gparent, 0x40 + (devno << 2),
+ };
+
+ mode = min(mode, ctlr->chip->max_dma);
+ mode = ata_highpoint_check_80pin(dev, mode);
+ /*
+ * most if not all HPT chips cant really handle that the device is
+ * running at ATA_UDMA6/ATA133 speed, so we cheat at set the device to
+ * a max of ATA_UDMA5/ATA100 to guard against suboptimal performance
+ */
+ mode = min(mode, ATA_UDMA5);
+ pci_write_config(parent, 0x40 + (devno << 2),
timings33[ata_mode2idx(mode)][ctlr->chip->cfg1], 4);
- atadev->mode = mode;
+ return (mode);
}
static int
ata_highpoint_check_80pin(device_t dev, int mode)
{
- device_t gparent = GRANDPARENT(dev);
- struct ata_pci_controller *ctlr = device_get_softc(gparent);
- struct ata_channel *ch = device_get_softc(device_get_parent(dev));
+ device_t parent = device_get_parent(dev);
+ struct ata_pci_controller *ctlr = device_get_softc(parent);
+ struct ata_channel *ch = device_get_softc(dev);
u_int8_t reg, val, res;
- if (ctlr->chip->cfg1 == HPT_374 && pci_get_function(gparent) == 1) {
+ if (ctlr->chip->cfg1 == HPT_374 && pci_get_function(parent) == 1) {
reg = ch->unit ? 0x57 : 0x53;
- val = pci_read_config(gparent, reg, 1);
- pci_write_config(gparent, reg, val | 0x80, 1);
+ val = pci_read_config(parent, reg, 1);
+ pci_write_config(parent, reg, val | 0x80, 1);
}
else {
reg = 0x5b;
- val = pci_read_config(gparent, reg, 1);
- pci_write_config(gparent, reg, val & 0xfe, 1);
+ val = pci_read_config(parent, reg, 1);
+ pci_write_config(parent, reg, val & 0xfe, 1);
}
- res = pci_read_config(gparent, 0x5a, 1) & (ch->unit ? 0x1:0x2);
- pci_write_config(gparent, reg, val, 1);
+ res = pci_read_config(parent, 0x5a, 1) & (ch->unit ? 0x1:0x2);
+ pci_write_config(parent, reg, val, 1);
if (mode > ATA_UDMA2 && res) {
ata_print_cable(dev, "controller");
diff --git a/sys/dev/ata/chipsets/ata-intel.c b/sys/dev/ata/chipsets/ata-intel.c
index add18d2..95e40c1 100644
--- a/sys/dev/ata/chipsets/ata-intel.c
+++ b/sys/dev/ata/chipsets/ata-intel.c
@@ -55,9 +55,9 @@ __FBSDID("$FreeBSD$");
static int ata_intel_chipinit(device_t dev);
static int ata_intel_ch_attach(device_t dev);
static void ata_intel_reset(device_t dev);
-static void ata_intel_old_setmode(device_t dev, int mode);
-static void ata_intel_new_setmode(device_t dev, int mode);
-static void ata_intel_sata_setmode(device_t dev, int mode);
+static int ata_intel_old_setmode(device_t dev, int target, int mode);
+static int ata_intel_new_setmode(device_t dev, int target, int mode);
+static int ata_intel_sata_getrev(device_t dev, int target);
static int ata_intel_31244_ch_attach(device_t dev);
static int ata_intel_31244_ch_detach(device_t dev);
static int ata_intel_31244_status(device_t dev);
@@ -181,6 +181,7 @@ ata_intel_chipinit(device_t dev)
ctlr->reset = ata_intel_31244_reset;
}
ctlr->setmode = ata_sata_setmode;
+ ctlr->getrev = ata_sata_getrev;
}
/* non SATA intel chips goes here */
@@ -214,9 +215,8 @@ ata_intel_chipinit(device_t dev)
ctlr->r_rid2 = PCIR_BAR(5);
if ((ctlr->r_res2 = bus_alloc_resource_any(dev, ctlr->r_type2,
&ctlr->r_rid2, RF_ACTIVE)))
- ctlr->setmode = ata_intel_sata_setmode;
- else
- ctlr->setmode = ata_sata_setmode;
+ ctlr->getrev = ata_intel_sata_getrev;
+ ctlr->setmode = ata_sata_setmode;
}
return 0;
}
@@ -240,6 +240,13 @@ ata_intel_ch_attach(device_t dev)
}
ch->flags |= ATA_ALWAYS_DMASTAT;
+ if (ctlr->chip->max_dma >= ATA_SA150) {
+ if (ctlr->chip->cfg1 == 0 &&
+ (pci_read_config(device_get_parent(dev), 0x90, 1) & 0x04) == 0)
+ ch->flags |= ATA_NO_SLAVE;
+ ch->flags |= ATA_SATA;
+ } else
+ ch->flags |= ATA_CHECKS_CABLE;
return 0;
}
@@ -259,11 +266,8 @@ ata_intel_reset(device_t dev)
/* ICH5 in compat mode has SATA ports as master/slave on 1 channel */
if (pci_read_config(parent, 0x90, 1) & 0x04)
mask = 0x0003;
- else {
+ else
mask = (0x0001 << ch->unit);
- /* XXX SOS should be in intel_ch_attach if we grow it */
- ch->flags |= ATA_NO_SLAVE;
- }
}
pci_write_config(parent, 0x92, pci_read_config(parent, 0x92, 2) & ~mask, 2);
DELAY(10);
@@ -279,80 +283,70 @@ ata_intel_reset(device_t dev)
ata_generic_reset(dev);
}
-static void
-ata_intel_old_setmode(device_t dev, int mode)
+static int
+ata_intel_old_setmode(device_t dev, int target, int mode)
{
- /* NOT YET */
+ device_t parent = device_get_parent(dev);
+ struct ata_pci_controller *ctlr = device_get_softc(parent);
+
+ mode = min(mode, ctlr->chip->max_dma);
+ return (mode);
}
-static void
-ata_intel_new_setmode(device_t dev, int mode)
+static int
+ata_intel_new_setmode(device_t dev, int target, int mode)
{
- device_t gparent = GRANDPARENT(dev);
- struct ata_pci_controller *ctlr = device_get_softc(gparent);
- struct ata_channel *ch = device_get_softc(device_get_parent(dev));
- struct ata_device *atadev = device_get_softc(dev);
- int devno = (ch->unit << 1) + atadev->unit;
- u_int32_t reg40 = pci_read_config(gparent, 0x40, 4);
- u_int8_t reg44 = pci_read_config(gparent, 0x44, 1);
- u_int8_t reg48 = pci_read_config(gparent, 0x48, 1);
- u_int16_t reg4a = pci_read_config(gparent, 0x4a, 2);
- u_int16_t reg54 = pci_read_config(gparent, 0x54, 2);
- u_int32_t mask40 = 0, new40 = 0;
- u_int8_t mask44 = 0, new44 = 0;
- int error;
- u_int8_t timings[] = { 0x00, 0x00, 0x10, 0x21, 0x23, 0x00, 0x21, 0x23,
- 0x23, 0x23, 0x23, 0x23, 0x23, 0x23 };
-
- mode = ata_limit_mode(dev, mode, ctlr->chip->max_dma);
-
- if ( mode > ATA_UDMA2 && !(reg54 & (0x10 << devno))) {
- ata_print_cable(dev, "controller");
- mode = ATA_UDMA2;
- }
-
- error = ata_controlcmd(dev, ATA_SETFEATURES, ATA_SF_SETXFER, 0, mode);
-
- if (bootverbose)
- device_printf(dev, "%ssetting %s on %s chip\n",
- (error) ? "FAILURE " : "",
- ata_mode2str(mode), ctlr->chip->text);
- if (!error) {
- if (mode >= ATA_UDMA0) {
- u_int8_t utimings[] = { 0x00, 0x01, 0x02, 0x01, 0x02, 0x01, 0x02 };
-
- pci_write_config(gparent, 0x48, reg48 | (0x0001 << devno), 2);
- pci_write_config(gparent, 0x4a,
- (reg4a & ~(0x3 << (devno << 2))) |
- (utimings[mode & ATA_MODE_MASK] << (devno<<2)), 2);
+ device_t parent = device_get_parent(dev);
+ struct ata_pci_controller *ctlr = device_get_softc(parent);
+ struct ata_channel *ch = device_get_softc(dev);
+ int devno = (ch->unit << 1) + target;
+ int piomode;
+ u_int32_t reg40 = pci_read_config(parent, 0x40, 4);
+ u_int8_t reg44 = pci_read_config(parent, 0x44, 1);
+ u_int8_t reg48 = pci_read_config(parent, 0x48, 1);
+ u_int16_t reg4a = pci_read_config(parent, 0x4a, 2);
+ u_int16_t reg54 = pci_read_config(parent, 0x54, 2);
+ u_int32_t mask40 = 0, new40 = 0;
+ u_int8_t mask44 = 0, new44 = 0;
+ u_int8_t timings[] = { 0x00, 0x00, 0x10, 0x21, 0x23, 0x00, 0x21, 0x23 };
+ u_int8_t utimings[] = { 0x00, 0x01, 0x02, 0x01, 0x02, 0x01, 0x02 };
+
+ mode = min(mode, ctlr->chip->max_dma);
+ if (mode > ATA_UDMA2 && !(reg54 & (0x10 << devno))) {
+ ata_print_cable(dev, "controller");
+ mode = ATA_UDMA2;
}
- else {
- pci_write_config(gparent, 0x48, reg48 & ~(0x0001 << devno), 2);
- pci_write_config(gparent, 0x4a, (reg4a & ~(0x3 << (devno << 2))),2);
+ /* Enable/disable UDMA and set timings. */
+ if (mode >= ATA_UDMA0) {
+ pci_write_config(parent, 0x48, reg48 | (0x0001 << devno), 2);
+ pci_write_config(parent, 0x4a,
+ (reg4a & ~(0x3 << (devno << 2))) |
+ (utimings[mode & ATA_MODE_MASK] << (devno<<2)), 2);
+ piomode = ATA_PIO4;
+ } else {
+ pci_write_config(parent, 0x48, reg48 & ~(0x0001 << devno), 2);
+ pci_write_config(parent, 0x4a, (reg4a & ~(0x3 << (devno << 2))),2);
+ piomode = mode;
}
reg54 |= 0x0400;
- if (mode >= ATA_UDMA3)
- reg54 |= (0x1 << devno);
- else
- reg54 &= ~(0x1 << devno);
+ /* Set UDMA reference clock (33/66/133MHz). */
+ reg54 &= ~(0x1001 << devno);
if (mode >= ATA_UDMA5)
reg54 |= (0x1000 << devno);
- else
- reg54 &= ~(0x1000 << devno);
-
- pci_write_config(gparent, 0x54, reg54, 2);
-
+ else if (mode >= ATA_UDMA3)
+ reg54 |= (0x1 << devno);
+ pci_write_config(parent, 0x54, reg54, 2);
+ /* Allow PIO/WDMA timing controls. */
reg40 &= ~0x00ff00ff;
reg40 |= 0x40774077;
-
- if (atadev->unit == ATA_MASTER) {
+ /* Set PIO/WDMA timings. */
+ if (target == 0) {
mask40 = 0x3300;
- new40 = timings[ata_mode2idx(mode)] << 8;
- }
- else {
+ new40 = timings[ata_mode2idx(piomode)] << 8;
+ } else {
mask44 = 0x0f;
- new44 = ((timings[ata_mode2idx(mode)] & 0x30) >> 2) |
- (timings[ata_mode2idx(mode)] & 0x03);
+ new44 = ((timings[ata_mode2idx(piomode)] & 0x30) >> 2) |
+ (timings[ata_mode2idx(piomode)] & 0x03);
}
if (ch->unit) {
mask40 <<= 16;
@@ -360,43 +354,21 @@ ata_intel_new_setmode(device_t dev, int mode)
mask44 <<= 4;
new44 <<= 4;
}
- pci_write_config(gparent, 0x40, (reg40 & ~mask40) | new40, 4);
- pci_write_config(gparent, 0x44, (reg44 & ~mask44) | new44, 1);
-
- atadev->mode = mode;
- }
+ pci_write_config(parent, 0x40, (reg40 & ~mask40) | new40, 4);
+ pci_write_config(parent, 0x44, (reg44 & ~mask44) | new44, 1);
+ return (mode);
}
-static void
-ata_intel_sata_setmode(device_t dev, int mode)
+static int
+ata_intel_sata_getrev(device_t dev, int target)
{
- struct ata_device *atadev = device_get_softc(dev);
-
- if (atadev->param.satacapabilities != 0x0000 &&
- atadev->param.satacapabilities != 0xffff) {
-
- struct ata_channel *ch = device_get_softc(device_get_parent(dev));
- int devno = (ch->unit << 1) + atadev->unit;
-
- /* on some drives we need to set the transfer mode */
- ata_controlcmd(dev, ATA_SETFEATURES, ATA_SF_SETXFER, 0,
- ata_limit_mode(dev, mode, ATA_UDMA6));
+ struct ata_channel *ch = device_get_softc(dev);
+ int devno = (ch->unit << 1) + target;
/* set ATA_SSTATUS register offset */
ATA_IDX_OUTL(ch, ATA_IDX_ADDR, devno * 0x100);
-
/* query SATA STATUS for the speed */
- if ((ATA_IDX_INL(ch, ATA_IDX_DATA) & ATA_SS_CONWELL_MASK) ==
- ATA_SS_CONWELL_GEN2)
- atadev->mode = ATA_SA300;
- else
- atadev->mode = ATA_SA150;
- }
- else {
- mode = ata_limit_mode(dev, mode, ATA_UDMA5);
- if (!ata_controlcmd(dev, ATA_SETFEATURES, ATA_SF_SETXFER, 0, mode))
- atadev->mode = mode;
- }
+ return ((ATA_IDX_INL(ch, ATA_IDX_DATA) & 0x0f0) >> 4);
}
static int
@@ -439,6 +411,7 @@ ata_intel_31244_ch_attach(device_t dev)
ch->r_io[ATA_BMDTP_PORT].offset = ch_offset + 0x74;
ch->flags |= ATA_NO_SLAVE;
+ ch->flags |= ATA_SATA;
ata_pci_hw(dev);
ch->hw.status = ata_intel_31244_status;
ch->hw.tf_write = ata_intel_31244_tf_write;
@@ -471,7 +444,9 @@ static void
ata_intel_31244_tf_write(struct ata_request *request)
{
struct ata_channel *ch = device_get_softc(request->parent);
+#ifndef ATA_CAM
struct ata_device *atadev = device_get_softc(request->dev);
+#endif
if (request->flags & ATA_R_48BIT) {
ATA_IDX_OUTW(ch, ATA_FEATURE, request->u.ata.feature);
@@ -487,6 +462,7 @@ ata_intel_31244_tf_write(struct ata_request *request)
else {
ATA_IDX_OUTB(ch, ATA_FEATURE, request->u.ata.feature);
ATA_IDX_OUTB(ch, ATA_COUNT, request->u.ata.count);
+#ifndef ATA_CAM
if (atadev->flags & ATA_D_USE_CHS) {
int heads, sectors;
@@ -508,13 +484,16 @@ ata_intel_31244_tf_write(struct ata_request *request)
sectors) & 0xf));
}
else {
+#endif
ATA_IDX_OUTB(ch, ATA_SECTOR, request->u.ata.lba);
ATA_IDX_OUTB(ch, ATA_CYL_LSB, request->u.ata.lba >> 8);
ATA_IDX_OUTB(ch, ATA_CYL_MSB, request->u.ata.lba >> 16);
ATA_IDX_OUTB(ch, ATA_DRIVE,
ATA_D_IBM | ATA_D_LBA | ATA_DEV(request->unit) |
((request->u.ata.lba >> 24) & 0x0f));
+#ifndef ATA_CAM
}
+#endif
}
}
diff --git a/sys/dev/ata/chipsets/ata-ite.c b/sys/dev/ata/chipsets/ata-ite.c
index 6187917..250ca64 100644
--- a/sys/dev/ata/chipsets/ata-ite.c
+++ b/sys/dev/ata/chipsets/ata-ite.c
@@ -53,8 +53,9 @@ __FBSDID("$FreeBSD$");
/* local prototypes */
static int ata_ite_chipinit(device_t dev);
-static void ata_ite_821x_setmode(device_t dev, int mode);
-static void ata_ite_8213_setmode(device_t dev, int mode);
+static int ata_ite_ch_attach(device_t dev);
+static int ata_ite_821x_setmode(device_t dev, int target, int mode);
+static int ata_ite_8213_setmode(device_t dev, int target, int mode);
/*
@@ -105,143 +106,125 @@ ata_ite_chipinit(device_t dev)
ctlr->setmode = ata_ite_821x_setmode;
}
-
+ ctlr->ch_attach = ata_ite_ch_attach;
return 0;
}
-
-static void
-ata_ite_821x_setmode(device_t dev, int mode)
+
+static int
+ata_ite_ch_attach(device_t dev)
{
- device_t gparent = GRANDPARENT(dev);
- struct ata_channel *ch = device_get_softc(device_get_parent(dev));
- struct ata_device *atadev = device_get_softc(dev);
- int devno = (ch->unit << 1) + atadev->unit;
- int error;
+ struct ata_channel *ch = device_get_softc(dev);
+ int error;
+
+ error = ata_pci_ch_attach(dev);
+ ch->flags |= ATA_CHECKS_CABLE;
+ return (error);
+}
- /* correct the mode for what the HW supports */
- mode = ata_limit_mode(dev, mode, ATA_UDMA6);
+static int
+ata_ite_821x_setmode(device_t dev, int target, int mode)
+{
+ device_t parent = device_get_parent(dev);
+ struct ata_pci_controller *ctlr = device_get_softc(parent);
+ struct ata_channel *ch = device_get_softc(dev);
+ int devno = (ch->unit << 1) + target;
+ int piomode;
+ u_int8_t udmatiming[] =
+ { 0x44, 0x42, 0x31, 0x21, 0x11, 0xa2, 0x91 };
+ u_int8_t chtiming[] =
+ { 0xaa, 0xa3, 0xa1, 0x33, 0x31, 0x88, 0x32, 0x31 };
- /* check the CBLID bits for 80 conductor cable detection */
- if (mode > ATA_UDMA2 && (pci_read_config(gparent, 0x40, 2) &
+ mode = min(mode, ctlr->chip->max_dma);
+ /* check the CBLID bits for 80 conductor cable detection */
+ if (mode > ATA_UDMA2 && (pci_read_config(parent, 0x40, 2) &
(ch->unit ? (1<<3) : (1<<2)))) {
- ata_print_cable(dev, "controller");
- mode = ATA_UDMA2;
- }
-
- /* set the wanted mode on the device */
- error = ata_controlcmd(dev, ATA_SETFEATURES, ATA_SF_SETXFER, 0, mode);
-
- if (bootverbose)
- device_printf(dev, "%s setting %s on ITE8212F chip\n",
- (error) ? "failed" : "success", ata_mode2str(mode));
-
- /* if the device accepted the mode change, setup the HW accordingly */
- if (!error) {
+ ata_print_cable(dev, "controller");
+ mode = ATA_UDMA2;
+ }
if (mode >= ATA_UDMA0) {
- u_int8_t udmatiming[] =
- { 0x44, 0x42, 0x31, 0x21, 0x11, 0xa2, 0x91 };
-
- /* enable UDMA mode */
- pci_write_config(gparent, 0x50,
- pci_read_config(gparent, 0x50, 1) &
+ /* enable UDMA mode */
+ pci_write_config(parent, 0x50,
+ pci_read_config(parent, 0x50, 1) &
~(1 << (devno + 3)), 1);
-
- /* set UDMA timing */
- pci_write_config(gparent,
- 0x56 + (ch->unit << 2) + atadev->unit,
+ /* set UDMA timing */
+ pci_write_config(parent,
+ 0x56 + (ch->unit << 2) + target,
udmatiming[mode & ATA_MODE_MASK], 1);
- }
- else {
- u_int8_t chtiming[] =
- { 0xaa, 0xa3, 0xa1, 0x33, 0x31, 0x88, 0x32, 0x31 };
-
- /* disable UDMA mode */
- pci_write_config(gparent, 0x50,
- pci_read_config(gparent, 0x50, 1) |
+ piomode = ATA_PIO4;
+ } else {
+ /* disable UDMA mode */
+ pci_write_config(parent, 0x50,
+ pci_read_config(parent, 0x50, 1) |
(1 << (devno + 3)), 1);
-
- /* set active and recover timing (shared between master & slave) */
- if (pci_read_config(gparent, 0x54 + (ch->unit << 2), 1) <
- chtiming[ata_mode2idx(mode)])
- pci_write_config(gparent, 0x54 + (ch->unit << 2),
- chtiming[ata_mode2idx(mode)], 1);
+ piomode = mode;
}
- atadev->mode = mode;
- }
+ /* set active and recover timing (shared between master & slave) */
+ if (pci_read_config(parent, 0x54 + (ch->unit << 2), 1) <
+ chtiming[ata_mode2idx(piomode)])
+ pci_write_config(parent, 0x54 + (ch->unit << 2),
+ chtiming[ata_mode2idx(piomode)], 1);
+ return (mode);
}
-static void
-ata_ite_8213_setmode(device_t dev, int mode)
+static int
+ata_ite_8213_setmode(device_t dev, int target, int mode)
{
- device_t gparent = GRANDPARENT(dev);
- struct ata_pci_controller *ctlr = device_get_softc(gparent);
- struct ata_device *atadev = device_get_softc(dev);
- u_int16_t reg40 = pci_read_config(gparent, 0x40, 2);
- u_int8_t reg44 = pci_read_config(gparent, 0x44, 1);
- u_int8_t reg48 = pci_read_config(gparent, 0x48, 1);
- u_int16_t reg4a = pci_read_config(gparent, 0x4a, 2);
- u_int16_t reg54 = pci_read_config(gparent, 0x54, 2);
- u_int16_t mask40 = 0, new40 = 0;
- u_int8_t mask44 = 0, new44 = 0;
- int devno = atadev->unit;
- int error;
- u_int8_t timings[] = { 0x00, 0x00, 0x10, 0x21, 0x23, 0x10, 0x21, 0x23,
- 0x23, 0x23, 0x23, 0x23, 0x23, 0x23 };
-
- mode = ata_limit_mode(dev, mode, ctlr->chip->max_dma);
-
- if (mode > ATA_UDMA2 && !(reg54 & (0x10 << devno))) {
- ata_print_cable(dev, "controller");
- mode = ATA_UDMA2;
- }
-
- error = ata_controlcmd(dev, ATA_SETFEATURES, ATA_SF_SETXFER, 0, mode);
-
- if (bootverbose)
- device_printf(dev, "%ssetting %s on %s chip\n",
- (error) ? "FAILURE " : "",
- ata_mode2str(mode), ctlr->chip->text);
- if (!error) {
- if (mode >= ATA_UDMA0) {
- u_int8_t utimings[] = { 0x00, 0x01, 0x10, 0x01, 0x10, 0x01, 0x10 };
-
- pci_write_config(gparent, 0x48, reg48 | (0x0001 << devno), 2);
- pci_write_config(gparent, 0x4a,
- (reg4a & ~(0x3 << (devno << 2))) |
- (utimings[mode & ATA_MODE_MASK] << (devno<<2)), 2);
+ device_t parent = device_get_parent(dev);
+ struct ata_pci_controller *ctlr = device_get_softc(parent);
+ int piomode;
+ u_int16_t reg40 = pci_read_config(parent, 0x40, 2);
+ u_int8_t reg44 = pci_read_config(parent, 0x44, 1);
+ u_int8_t reg48 = pci_read_config(parent, 0x48, 1);
+ u_int16_t reg4a = pci_read_config(parent, 0x4a, 2);
+ u_int16_t reg54 = pci_read_config(parent, 0x54, 2);
+ u_int16_t mask40 = 0, new40 = 0;
+ u_int8_t mask44 = 0, new44 = 0;
+ u_int8_t timings[] = { 0x00, 0x00, 0x10, 0x21, 0x23, 0x00, 0x21, 0x23 };
+ u_int8_t utimings[] = { 0x00, 0x01, 0x02, 0x01, 0x02, 0x01, 0x02 };
+
+ mode = min(mode, ctlr->chip->max_dma);
+
+ if (mode > ATA_UDMA2 && !(reg54 & (0x10 << target))) {
+ ata_print_cable(dev, "controller");
+ mode = ATA_UDMA2;
}
- else {
- pci_write_config(gparent, 0x48, reg48 & ~(0x0001 << devno), 2);
- pci_write_config(gparent, 0x4a, (reg4a & ~(0x3 << (devno << 2))),2);
+ /* Enable/disable UDMA and set timings. */
+ if (mode >= ATA_UDMA0) {
+ pci_write_config(parent, 0x48, reg48 | (0x0001 << target), 2);
+ pci_write_config(parent, 0x4a,
+ (reg4a & ~(0x3 << (target << 2))) |
+ (utimings[mode & ATA_MODE_MASK] << (target<<2)), 2);
+ piomode = ATA_PIO4;
+ } else {
+ pci_write_config(parent, 0x48, reg48 & ~(0x0001 << target), 2);
+ pci_write_config(parent, 0x4a, (reg4a & ~(0x3 << (target << 2))),2);
+ piomode = mode;
}
- if (mode >= ATA_UDMA2)
- reg54 |= (0x1 << devno);
- else
- reg54 &= ~(0x1 << devno);
+ /* Set UDMA reference clock (33/66/133MHz). */
+ reg54 &= ~(0x1001 << target);
if (mode >= ATA_UDMA5)
- reg54 |= (0x1000 << devno);
- else
- reg54 &= ~(0x1000 << devno);
- pci_write_config(gparent, 0x54, reg54, 2);
-
+ reg54 |= (0x1000 << target);
+ else if (mode >= ATA_UDMA3)
+ reg54 |= (0x1 << target);
+ pci_write_config(parent, 0x54, reg54, 2);
+ /* Allow PIO/WDMA timing controls. */
reg40 &= 0xff00;
reg40 |= 0x4033;
- if (atadev->unit == ATA_MASTER) {
+ /* Set PIO/WDMA timings. */
+ if (target == 0) {
reg40 |= (ata_atapi(dev) ? 0x04 : 0x00);
mask40 = 0x3300;
- new40 = timings[ata_mode2idx(mode)] << 8;
+ new40 = timings[ata_mode2idx(piomode)] << 8;
}
else {
reg40 |= (ata_atapi(dev) ? 0x40 : 0x00);
mask44 = 0x0f;
- new44 = ((timings[ata_mode2idx(mode)] & 0x30) >> 2) |
- (timings[ata_mode2idx(mode)] & 0x03);
+ new44 = ((timings[ata_mode2idx(piomode)] & 0x30) >> 2) |
+ (timings[ata_mode2idx(piomode)] & 0x03);
}
- pci_write_config(gparent, 0x40, (reg40 & ~mask40) | new40, 4);
- pci_write_config(gparent, 0x44, (reg44 & ~mask44) | new44, 1);
-
- atadev->mode = mode;
- }
+ pci_write_config(parent, 0x40, (reg40 & ~mask40) | new40, 4);
+ pci_write_config(parent, 0x44, (reg44 & ~mask44) | new44, 1);
+ return (mode);
}
ATA_DECLARE_DRIVER(ata_ite);
diff --git a/sys/dev/ata/chipsets/ata-jmicron.c b/sys/dev/ata/chipsets/ata-jmicron.c
index 2531070..13524f1 100644
--- a/sys/dev/ata/chipsets/ata-jmicron.c
+++ b/sys/dev/ata/chipsets/ata-jmicron.c
@@ -53,7 +53,8 @@ __FBSDID("$FreeBSD$");
/* local prototypes */
static int ata_jmicron_chipinit(device_t dev);
-static void ata_jmicron_setmode(device_t dev, int mode);
+static int ata_jmicron_ch_attach(device_t dev);
+static int ata_jmicron_setmode(device_t dev, int target, int mode);
/*
* JMicron chipset support functions
@@ -79,13 +80,8 @@ ata_jmicron_probe(device_t dev)
if (!(idx = ata_match_chip(dev, ids)))
return ENXIO;
- if ((pci_read_config(dev, 0xdf, 1) & 0x40) &&
- (pci_get_function(dev) == (pci_read_config(dev, 0x40, 1) & 0x02 >> 1)))
- sprintf(buffer, "JMicron %s %s controller",
- idx->text, ata_mode2str(ATA_UDMA6));
- else
- sprintf(buffer, "JMicron %s %s controller",
- idx->text, ata_mode2str(idx->max_dma));
+ sprintf(buffer, "JMicron %s %s controller",
+ idx->text, ata_mode2str(idx->max_dma));
device_set_desc_copy(dev, buffer);
ctlr->chip = idx;
ctlr->chipinit = ata_jmicron_chipinit;
@@ -108,7 +104,7 @@ ata_jmicron_chipinit(device_t dev)
return 0;
/* otherwise we are on the PATA part */
- ctlr->ch_attach = ata_pci_ch_attach;
+ ctlr->ch_attach = ata_jmicron_ch_attach;
ctlr->ch_detach = ata_pci_ch_detach;
ctlr->reset = ata_generic_reset;
ctlr->setmode = ata_jmicron_setmode;
@@ -126,7 +122,7 @@ ata_jmicron_chipinit(device_t dev)
bus_generic_attach(dev);
}
}
- ctlr->ch_attach = ata_pci_ch_attach;
+ ctlr->ch_attach = ata_jmicron_ch_attach;
ctlr->ch_detach = ata_pci_ch_detach;
ctlr->reset = ata_generic_reset;
ctlr->setmode = ata_jmicron_setmode;
@@ -135,18 +131,30 @@ ata_jmicron_chipinit(device_t dev)
return 0;
}
-static void
-ata_jmicron_setmode(device_t dev, int mode)
+static int
+ata_jmicron_ch_attach(device_t dev)
+{
+ struct ata_channel *ch = device_get_softc(dev);
+ int error;
+
+ error = ata_pci_ch_attach(dev);
+ ch->flags |= ATA_CHECKS_CABLE;
+ return (error);
+}
+
+static int
+ata_jmicron_setmode(device_t dev, int target, int mode)
{
- struct ata_device *atadev = device_get_softc(dev);
+ struct ata_pci_controller *ctlr = device_get_softc(device_get_parent(dev));
+ mode = min(mode, ctlr->chip->max_dma);
/* check for 80pin cable present */
- if (pci_read_config(dev, 0x40, 1) & 0x08)
- mode = ata_limit_mode(dev, mode, ATA_UDMA2);
- else
- mode = ata_limit_mode(dev, mode, ATA_UDMA6);
- if (!ata_controlcmd(dev, ATA_SETFEATURES, ATA_SF_SETXFER, 0, mode))
- atadev->mode = mode;
+ if (mode > ATA_UDMA2 && pci_read_config(dev, 0x40, 1) & 0x08) {
+ ata_print_cable(dev, "controller");
+ mode = ATA_UDMA2;
+ }
+ /* Nothing to do to setup mode, the controller snoop SET_FEATURE cmd. */
+ return (mode);
}
ATA_DECLARE_DRIVER(ata_jmicron);
diff --git a/sys/dev/ata/chipsets/ata-marvell.c b/sys/dev/ata/chipsets/ata-marvell.c
index bda1a17..0d11266 100644
--- a/sys/dev/ata/chipsets/ata-marvell.c
+++ b/sys/dev/ata/chipsets/ata-marvell.c
@@ -54,7 +54,7 @@ __FBSDID("$FreeBSD$");
/* local prototypes */
static int ata_marvell_chipinit(device_t dev);
static int ata_marvell_ch_attach(device_t dev);
-static void ata_marvell_setmode(device_t dev, int mode);
+static int ata_marvell_setmode(device_t dev, int target, int mode);
static int ata_marvell_edma_ch_attach(device_t dev);
static int ata_marvell_edma_ch_detach(device_t dev);
static int ata_marvell_edma_status(device_t dev);
@@ -170,20 +170,24 @@ ata_marvell_ch_attach(device_t dev)
error = ata_pci_ch_attach(dev);
/* dont use 32 bit PIO transfers */
ch->flags |= ATA_USE_16BIT;
+ ch->flags |= ATA_CHECKS_CABLE;
return (error);
}
-static void
-ata_marvell_setmode(device_t dev, int mode)
+static int
+ata_marvell_setmode(device_t dev, int target, int mode)
{
- device_t gparent = GRANDPARENT(dev);
- struct ata_pci_controller *ctlr = device_get_softc(gparent);
- struct ata_device *atadev = device_get_softc(dev);
-
- mode = ata_limit_mode(dev, mode, ctlr->chip->max_dma);
- mode = ata_check_80pin(dev, mode);
- if (!ata_controlcmd(dev, ATA_SETFEATURES, ATA_SF_SETXFER, 0, mode))
- atadev->mode = mode;
+ struct ata_pci_controller *ctlr = device_get_softc(device_get_parent(dev));
+ struct ata_channel *ch = device_get_softc(dev);
+
+ mode = min(mode, ctlr->chip->max_dma);
+ /* Check for 80pin cable present. */
+ if (mode > ATA_UDMA2 && ATA_IDX_INB(ch, ATA_BMDEVSPEC_0) & 0x01) {
+ ata_print_cable(dev, "controller");
+ mode = ATA_UDMA2;
+ }
+ /* Nothing to do to setup mode, the controller snoop SET_FEATURE cmd. */
+ return (mode);
}
int
@@ -210,6 +214,7 @@ ata_marvell_edma_chipinit(device_t dev)
ctlr->ch_detach = ata_marvell_edma_ch_detach;
ctlr->reset = ata_marvell_edma_reset;
ctlr->setmode = ata_sata_setmode;
+ ctlr->getrev = ata_sata_getrev;
ctlr->channels = ctlr->chip->cfg1;
/* clear host controller interrupts */
@@ -281,6 +286,7 @@ ata_marvell_edma_ch_attach(device_t dev)
ch->flags |= ATA_NO_SLAVE;
ch->flags |= ATA_USE_16BIT; /* XXX SOS needed ? */
+ ch->flags |= ATA_SATA;
ata_generic_hw(dev);
ch->hw.begin_transaction = ata_marvell_edma_begin_transaction;
ch->hw.end_transaction = ata_marvell_edma_end_transaction;
@@ -601,8 +607,6 @@ ata_marvell_edma_dmainit(device_t dev)
/* chip does not reliably do 64K DMA transfers */
if (ctlr->chip->cfg2 == MV_50XX || ctlr->chip->cfg2 == MV_60XX)
ch->dma.max_iosize = 64 * DEV_BSIZE;
- else
- ch->dma.max_iosize = (ATA_DMA_ENTRIES - 1) * PAGE_SIZE;
}
ATA_DECLARE_DRIVER(ata_marvell);
diff --git a/sys/dev/ata/chipsets/ata-micron.c b/sys/dev/ata/chipsets/ata-micron.c
index ce75874..2b74a33 100644
--- a/sys/dev/ata/chipsets/ata-micron.c
+++ b/sys/dev/ata/chipsets/ata-micron.c
@@ -51,11 +51,6 @@ __FBSDID("$FreeBSD$");
#include <dev/ata/ata-pci.h>
#include <ata_if.h>
-/* local prototypes */
-static int ata_micron_chipinit(device_t dev);
-static void ata_micron_setmode(device_t dev, int mode);
-
-
/*
* Cenatek chipset support functions
*/
@@ -68,34 +63,10 @@ ata_micron_probe(device_t dev)
pci_get_devid(dev) == ATA_MICRON_RZ1001) {
device_set_desc(dev,
"RZ 100? ATA controller !WARNING! data loss/corruption risk");
- ctlr->chipinit = ata_micron_chipinit;
+ ctlr->chipinit = ata_generic_chipinit;
return (BUS_PROBE_DEFAULT);
}
- else
- return ENXIO;
-}
-
-static int
-ata_micron_chipinit(device_t dev)
-{
- struct ata_pci_controller *ctlr = device_get_softc(dev);
-
- if (ata_setup_interrupt(dev, ata_generic_intr))
- return ENXIO;
-
- ctlr->setmode = ata_micron_setmode;
- return 0;
-}
-
-static void
-ata_micron_setmode(device_t dev, int mode)
-{
- struct ata_device *atadev = device_get_softc(dev);
-
- mode = ata_limit_mode(dev, mode, ATA_UDMA2);
- mode = ata_check_80pin(dev, mode);
- if (!ata_controlcmd(dev, ATA_SETFEATURES, ATA_SF_SETXFER, 0, mode))
- atadev->mode = mode;
+ return (ENXIO);
}
ATA_DECLARE_DRIVER(ata_micron);
diff --git a/sys/dev/ata/chipsets/ata-national.c b/sys/dev/ata/chipsets/ata-national.c
index 840360a..20cafa5 100644
--- a/sys/dev/ata/chipsets/ata-national.c
+++ b/sys/dev/ata/chipsets/ata-national.c
@@ -53,8 +53,8 @@ __FBSDID("$FreeBSD$");
/* local prototypes */
static int ata_national_chipinit(device_t dev);
-static void ata_national_setmode(device_t dev, int mode);
-
+static int ata_national_ch_attach(device_t dev);
+static int ata_national_setmode(device_t dev, int target, int mode);
/*
* National chipset support functions
@@ -81,53 +81,55 @@ ata_national_chipinit(device_t dev)
if (ata_setup_interrupt(dev, ata_generic_intr))
return ENXIO;
+ ctlr->ch_attach = ata_national_ch_attach;
ctlr->setmode = ata_national_setmode;
return 0;
}
-static void
-ata_national_setmode(device_t dev, int mode)
+static int
+ata_national_ch_attach(device_t dev)
{
- device_t gparent = GRANDPARENT(dev);
- struct ata_channel *ch = device_get_softc(device_get_parent(dev));
- struct ata_device *atadev = device_get_softc(dev);
- int devno = (ch->unit << 1) + atadev->unit;
- u_int32_t piotiming[] =
- { 0x9172d132, 0x21717121, 0x00803020, 0x20102010, 0x00100010,
- 0x00803020, 0x20102010, 0x00100010,
- 0x00100010, 0x00100010, 0x00100010 };
- u_int32_t dmatiming[] = { 0x80077771, 0x80012121, 0x80002020 };
- u_int32_t udmatiming[] = { 0x80921250, 0x80911140, 0x80911030 };
- int error;
-
- ch->dma.alignment = 16;
- ch->dma.max_iosize = 64 * DEV_BSIZE;
+ struct ata_channel *ch = device_get_softc(dev);
+ int error;
+
+ error = ata_pci_ch_attach(dev);
+ ch->dma.alignment = 16;
+ ch->dma.max_iosize = 64 * DEV_BSIZE;
+ return (error);
+}
- mode = ata_limit_mode(dev, mode, ATA_UDMA2);
+static int
+ata_national_setmode(device_t dev, int target, int mode)
+{
+ device_t parent = device_get_parent(dev);
+ struct ata_channel *ch = device_get_softc(dev);
+ int devno = (ch->unit << 1) + target;
+ int piomode;
+ u_int32_t piotiming[] =
+ { 0x9172d132, 0x21717121, 0x00803020, 0x20102010, 0x00100010,
+ 0x9172d132, 0x20102010, 0x00100010 };
+ u_int32_t dmatiming[] = { 0x80077771, 0x80012121, 0x80002020 };
+ u_int32_t udmatiming[] = { 0x80921250, 0x80911140, 0x80911030 };
- error = ata_controlcmd(dev, ATA_SETFEATURES, ATA_SF_SETXFER, 0, mode);
+ mode = min(mode, ATA_UDMA2);
- if (bootverbose)
- device_printf(dev, "%s setting %s on National chip\n",
- (error) ? "failed" : "success", ata_mode2str(mode));
- if (!error) {
if (mode >= ATA_UDMA0) {
- pci_write_config(gparent, 0x44 + (devno << 3),
+ pci_write_config(parent, 0x44 + (devno << 3),
udmatiming[mode & ATA_MODE_MASK], 4);
- }
- else if (mode >= ATA_WDMA0) {
- pci_write_config(gparent, 0x44 + (devno << 3),
+ piomode = ATA_PIO4;
+ } else if (mode >= ATA_WDMA0) {
+ pci_write_config(parent, 0x44 + (devno << 3),
dmatiming[mode & ATA_MODE_MASK], 4);
- }
- else {
- pci_write_config(gparent, 0x44 + (devno << 3),
- pci_read_config(gparent, 0x44 + (devno << 3), 4) |
+ piomode = mode;
+ } else {
+ pci_write_config(parent, 0x44 + (devno << 3),
+ pci_read_config(parent, 0x44 + (devno << 3), 4) |
0x80000000, 4);
+ piomode = mode;
}
- pci_write_config(gparent, 0x40 + (devno << 3),
- piotiming[ata_mode2idx(mode)], 4);
- atadev->mode = mode;
- }
+ pci_write_config(parent, 0x40 + (devno << 3),
+ piotiming[ata_mode2idx(piomode)], 4);
+ return (mode);
}
ATA_DECLARE_DRIVER(ata_national);
diff --git a/sys/dev/ata/chipsets/ata-netcell.c b/sys/dev/ata/chipsets/ata-netcell.c
index c07df0e..f6a7545 100644
--- a/sys/dev/ata/chipsets/ata-netcell.c
+++ b/sys/dev/ata/chipsets/ata-netcell.c
@@ -54,8 +54,6 @@ __FBSDID("$FreeBSD$");
/* local prototypes */
static int ata_netcell_chipinit(device_t dev);
static int ata_netcell_ch_attach(device_t dev);
-static void ata_netcell_setmode(device_t dev, int mode);
-
/*
* NetCell chipset support functions
@@ -82,8 +80,7 @@ ata_netcell_chipinit(device_t dev)
return ENXIO;
ctlr->ch_attach = ata_netcell_ch_attach;
- ctlr->ch_detach = ata_pci_ch_detach;
- ctlr->setmode = ata_netcell_setmode;
+ ctlr->setmode = ata_generic_setmode;
return 0;
}
@@ -98,19 +95,7 @@ ata_netcell_ch_attach(device_t dev)
/* the NetCell only supports 16 bit PIO transfers */
ch->flags |= ATA_USE_16BIT;
-
return 0;
}
-static void
-ata_netcell_setmode(device_t dev, int mode)
-{
- struct ata_device *atadev = device_get_softc(dev);
-
- mode = ata_limit_mode(dev, mode, ATA_UDMA2);
- mode = ata_check_80pin(dev, mode);
- if (!ata_controlcmd(dev, ATA_SETFEATURES, ATA_SF_SETXFER, 0, mode))
- atadev->mode = mode;
-}
-
ATA_DECLARE_DRIVER(ata_netcell);
diff --git a/sys/dev/ata/chipsets/ata-nvidia.c b/sys/dev/ata/chipsets/ata-nvidia.c
index cdff825..79064f8 100644
--- a/sys/dev/ata/chipsets/ata-nvidia.c
+++ b/sys/dev/ata/chipsets/ata-nvidia.c
@@ -56,7 +56,7 @@ static int ata_nvidia_chipinit(device_t dev);
static int ata_nvidia_ch_attach(device_t dev);
static int ata_nvidia_status(device_t dev);
static void ata_nvidia_reset(device_t dev);
-static void ata_nvidia_setmode(device_t dev, int mode);
+static int ata_nvidia_setmode(device_t dev, int target, int mode);
/* misc defines */
#define NV4 0x01
@@ -231,6 +231,7 @@ ata_nvidia_chipinit(device_t dev)
}
}
ctlr->setmode = ata_sata_setmode;
+ ctlr->getrev = ata_sata_getrev;
}
else {
/* disable prefetch, postwrite */
@@ -259,7 +260,7 @@ ata_nvidia_ch_attach(device_t dev)
ch->hw.status = ata_nvidia_status;
ch->flags |= ATA_NO_SLAVE;
-
+ ch->flags |= ATA_SATA;
return 0;
}
@@ -299,36 +300,29 @@ ata_nvidia_reset(device_t dev)
ata_generic_reset(dev);
}
-static void
-ata_nvidia_setmode(device_t dev, int mode)
+static int
+ata_nvidia_setmode(device_t dev, int target, int mode)
{
- device_t gparent = GRANDPARENT(dev);
- struct ata_pci_controller *ctlr = device_get_softc(gparent);
- struct ata_channel *ch = device_get_softc(device_get_parent(dev));
- struct ata_device *atadev = device_get_softc(dev);
- u_int8_t timings[] = { 0xa8, 0x65, 0x42, 0x22, 0x20, 0x42, 0x22, 0x20,
- 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20 };
- int modes[7] = { 0xc2, 0xc1, 0xc0, 0xc4, 0xc5, 0xc6, 0xc7 };
- int devno = (ch->unit << 1) + atadev->unit;
- int reg = 0x63 - devno;
- int error;
-
- mode = ata_limit_mode(dev, mode, ctlr->chip->max_dma);
- mode = ata_check_80pin(dev, mode);
-
- error = ata_controlcmd(dev, ATA_SETFEATURES, ATA_SF_SETXFER, 0, mode);
- if (bootverbose)
- device_printf(dev, "%ssetting %s on %s chip\n",
- (error) ? "FAILURE " : "", ata_mode2str(mode),
- ctlr->chip->text);
- if (!error) {
- pci_write_config(gparent, reg - 0x08, timings[ata_mode2idx(mode)], 1);
- if (mode >= ATA_UDMA0)
- pci_write_config(gparent, reg, modes[mode & ATA_MODE_MASK], 1);
- else
- pci_write_config(gparent, reg, 0x8b, 1);
- atadev->mode = mode;
- }
+ device_t parent = device_get_parent(dev);
+ struct ata_pci_controller *ctlr = device_get_softc(parent);
+ struct ata_channel *ch = device_get_softc(dev);
+ int devno = (ch->unit << 1) + target;
+ int piomode;
+ u_int8_t timings[] = { 0xa8, 0x65, 0x42, 0x22, 0x20, 0xa8, 0x22, 0x20 };
+ int modes[7] = { 0xc2, 0xc1, 0xc0, 0xc4, 0xc5, 0xc6, 0xc7 };
+ int reg = 0x63 - devno;
+
+ mode = min(mode, ctlr->chip->max_dma);
+
+ if (mode >= ATA_UDMA0) {
+ pci_write_config(parent, reg, modes[mode & ATA_MODE_MASK], 1);
+ piomode = ATA_PIO4;
+ } else {
+ pci_write_config(parent, reg, 0x8b, 1);
+ piomode = mode;
+ }
+ pci_write_config(parent, reg - 0x08, timings[ata_mode2idx(piomode)], 1);
+ return (mode);
}
ATA_DECLARE_DRIVER(ata_nvidia);
diff --git a/sys/dev/ata/chipsets/ata-promise.c b/sys/dev/ata/chipsets/ata-promise.c
index ca3243a..2f79a46 100644
--- a/sys/dev/ata/chipsets/ata-promise.c
+++ b/sys/dev/ata/chipsets/ata-promise.c
@@ -58,7 +58,7 @@ static int ata_promise_status(device_t dev);
static int ata_promise_dmastart(struct ata_request *request);
static int ata_promise_dmastop(struct ata_request *request);
static void ata_promise_dmareset(device_t dev);
-static void ata_promise_setmode(device_t dev, int mode);
+static int ata_promise_setmode(device_t dev, int target, int mode);
static int ata_promise_tx2_ch_attach(device_t dev);
static int ata_promise_tx2_status(device_t dev);
static int ata_promise_mio_ch_attach(device_t dev);
@@ -72,7 +72,7 @@ static int ata_promise_mio_pm_write(device_t dev, int port, int reg, u_int32_t r
static u_int32_t ata_promise_mio_softreset(device_t dev, int port);
static void ata_promise_mio_dmainit(device_t dev);
static void ata_promise_mio_setprd(void *xsc, bus_dma_segment_t *segs, int nsegs, int error);
-static void ata_promise_mio_setmode(device_t dev, int mode);
+static int ata_promise_mio_setmode(device_t dev, int target, int mode);
static void ata_promise_sx4_intr(void *data);
static int ata_promise_sx4_command(struct ata_request *request);
static int ata_promise_apkt(u_int8_t *bytep, struct ata_request *request);
@@ -369,6 +369,8 @@ ata_promise_ch_attach(device_t dev)
}
ch->hw.status = ata_promise_status;
+ ch->flags |= ATA_NO_ATAPI_DMA;
+ ch->flags |= ATA_CHECKS_CABLE;
return 0;
}
@@ -438,15 +440,13 @@ ata_promise_dmareset(device_t dev)
ch->flags &= ~ATA_DMA_ACTIVE;
}
-static void
-ata_promise_setmode(device_t dev, int mode)
+static int
+ata_promise_setmode(device_t dev, int target, int mode)
{
- device_t gparent = GRANDPARENT(dev);
- struct ata_pci_controller *ctlr = device_get_softc(gparent);
- struct ata_channel *ch = device_get_softc(device_get_parent(dev));
- struct ata_device *atadev = device_get_softc(dev);
- int devno = (ch->unit << 1) + atadev->unit;
- int error;
+ device_t parent = device_get_parent(dev);
+ struct ata_pci_controller *ctlr = device_get_softc(parent);
+ struct ata_channel *ch = device_get_softc(dev);
+ int devno = (ch->unit << 1) + target;
u_int32_t timings[][2] = {
/* PR_OLD PR_NEW mode */
{ 0x004ff329, 0x004fff2f }, /* PIO 0 */
@@ -465,18 +465,16 @@ ata_promise_setmode(device_t dev, int mode)
{ 0, 0x004127f3 } /* UDMA 5 */
};
- mode = ata_limit_mode(dev, mode, ctlr->chip->max_dma);
+ mode = min(mode, ctlr->chip->max_dma);
switch (ctlr->chip->cfg1) {
case PR_OLD:
case PR_NEW:
- if (mode > ATA_UDMA2 && (pci_read_config(gparent, 0x50, 2) &
+ if (mode > ATA_UDMA2 && (pci_read_config(parent, 0x50, 2) &
(ch->unit ? 1 << 11 : 1 << 10))) {
ata_print_cable(dev, "controller");
mode = ATA_UDMA2;
}
- if (ata_atapi(dev) && mode > ATA_PIO_MAX)
- mode = ata_limit_mode(dev, mode, ATA_PIO_MAX);
break;
case PR_TX:
@@ -499,19 +497,10 @@ ata_promise_setmode(device_t dev, int mode)
break;
}
- error = ata_controlcmd(dev, ATA_SETFEATURES, ATA_SF_SETXFER, 0, mode);
-
- if (bootverbose)
- device_printf(dev, "%ssetting %s on %s chip\n",
- (error) ? "FAILURE " : "",
- ata_mode2str(mode), ctlr->chip->text);
- if (!error) {
if (ctlr->chip->cfg1 < PR_TX)
- pci_write_config(gparent, 0x60 + (devno << 2),
+ pci_write_config(parent, 0x60 + (devno << 2),
timings[ata_mode2idx(mode)][ctlr->chip->cfg1], 4);
- atadev->mode = mode;
- }
- return;
+ return (mode);
}
static int
@@ -523,6 +512,7 @@ ata_promise_tx2_ch_attach(device_t dev)
return ENXIO;
ch->hw.status = ata_promise_tx2_status;
+ ch->flags |= ATA_CHECKS_CABLE;
return 0;
}
@@ -565,8 +555,10 @@ ata_promise_mio_ch_attach(device_t dev)
ch->r_io[ATA_SCONTROL].res = ctlr->r_res2;
ch->r_io[ATA_SCONTROL].offset = 0x408 + (ch->unit << 8);
ch->flags |= ATA_NO_SLAVE;
+ ch->flags |= ATA_SATA;
}
ch->flags |= ATA_USE_16BIT;
+ ch->flags |= ATA_CHECKS_CABLE;
ata_generic_hw(dev);
if (ctlr->chip->cfg2 & PR_SX4X) {
@@ -997,20 +989,20 @@ ata_promise_mio_setprd(void *xsc, bus_dma_segment_t *segs, int nsegs, int error)
args->nsegs = nsegs;
}
-static void
-ata_promise_mio_setmode(device_t dev, int mode)
+static int
+ata_promise_mio_setmode(device_t dev, int target, int mode)
{
- device_t gparent = GRANDPARENT(dev);
- struct ata_pci_controller *ctlr = device_get_softc(gparent);
- struct ata_channel *ch = device_get_softc(device_get_parent(dev));
-
- if ( (ctlr->chip->cfg2 == PR_SATA) ||
- ((ctlr->chip->cfg2 == PR_CMBO) && (ch->unit < 2)) ||
- (ctlr->chip->cfg2 == PR_SATA2) ||
- ((ctlr->chip->cfg2 == PR_CMBO2) && (ch->unit < 2)))
- ata_sata_setmode(dev, mode);
- else
- ata_promise_setmode(dev, mode);
+ struct ata_pci_controller *ctlr = device_get_softc(device_get_parent(dev));
+ struct ata_channel *ch = device_get_softc(dev);
+
+ if ( (ctlr->chip->cfg2 == PR_SATA) ||
+ ((ctlr->chip->cfg2 == PR_CMBO) && (ch->unit < 2)) ||
+ (ctlr->chip->cfg2 == PR_SATA2) ||
+ ((ctlr->chip->cfg2 == PR_CMBO2) && (ch->unit < 2)))
+ mode = ata_sata_setmode(dev, target, mode);
+ else
+ mode = ata_promise_setmode(dev, target, mode);
+ return (mode);
}
static void
diff --git a/sys/dev/ata/chipsets/ata-serverworks.c b/sys/dev/ata/chipsets/ata-serverworks.c
index 886282e..b5a3fc2 100644
--- a/sys/dev/ata/chipsets/ata-serverworks.c
+++ b/sys/dev/ata/chipsets/ata-serverworks.c
@@ -60,7 +60,7 @@ static int ata_serverworks_ch_attach(device_t dev);
static int ata_serverworks_ch_detach(device_t dev);
static void ata_serverworks_tf_read(struct ata_request *request);
static void ata_serverworks_tf_write(struct ata_request *request);
-static void ata_serverworks_setmode(device_t dev, int mode);
+static int ata_serverworks_setmode(device_t dev, int target, int mode);
#ifdef __powerpc__
static int ata_serverworks_status(device_t dev);
#endif
@@ -147,6 +147,7 @@ ata_serverworks_chipinit(device_t dev)
ctlr->ch_attach = ata_serverworks_ch_attach;
ctlr->ch_detach = ata_serverworks_ch_detach;
ctlr->setmode = ata_sata_setmode;
+ ctlr->getrev = ata_sata_getrev;
return 0;
}
else if (ctlr->chip->cfg1 == SWKS_33) {
@@ -213,6 +214,7 @@ ata_serverworks_ch_attach(device_t dev)
ch->r_io[ATA_SCONTROL].offset = ch_offset + 0x48;
ch->flags |= ATA_NO_SLAVE;
+ ch->flags |= ATA_SATA;
ata_pci_hw(dev);
ch->hw.tf_read = ata_serverworks_tf_read;
ch->hw.tf_write = ata_serverworks_tf_write;
@@ -287,7 +289,9 @@ static void
ata_serverworks_tf_write(struct ata_request *request)
{
struct ata_channel *ch = device_get_softc(request->parent);
+#ifndef ATA_CAM
struct ata_device *atadev = device_get_softc(request->dev);
+#endif
if (request->flags & ATA_R_48BIT) {
ATA_IDX_OUTW(ch, ATA_FEATURE, request->u.ata.feature);
@@ -303,6 +307,7 @@ ata_serverworks_tf_write(struct ata_request *request)
else {
ATA_IDX_OUTW(ch, ATA_FEATURE, request->u.ata.feature);
ATA_IDX_OUTW(ch, ATA_COUNT, request->u.ata.count);
+#ifndef ATA_CAM
if (atadev->flags & ATA_D_USE_CHS) {
int heads, sectors;
@@ -324,74 +329,74 @@ ata_serverworks_tf_write(struct ata_request *request)
sectors) & 0xf));
}
else {
+#endif
ATA_IDX_OUTW(ch, ATA_SECTOR, request->u.ata.lba);
ATA_IDX_OUTW(ch, ATA_CYL_LSB, request->u.ata.lba >> 8);
ATA_IDX_OUTW(ch, ATA_CYL_MSB, request->u.ata.lba >> 16);
ATA_IDX_OUTW(ch, ATA_DRIVE,
ATA_D_IBM | ATA_D_LBA | ATA_DEV(request->unit) |
((request->u.ata.lba >> 24) & 0x0f));
+#ifndef ATA_CAM
}
+#endif
}
}
-static void
-ata_serverworks_setmode(device_t dev, int mode)
+static int
+ata_serverworks_setmode(device_t dev, int target, int mode)
{
- device_t gparent = GRANDPARENT(dev);
- struct ata_pci_controller *ctlr = device_get_softc(gparent);
- struct ata_channel *ch = device_get_softc(device_get_parent(dev));
- struct ata_device *atadev = device_get_softc(dev);
- int devno = (ch->unit << 1) + atadev->unit;
- int offset = (devno ^ 0x01) << 3;
- int error;
- u_int8_t piotimings[] = { 0x5d, 0x47, 0x34, 0x22, 0x20, 0x34, 0x22, 0x20,
- 0x20, 0x20, 0x20, 0x20, 0x20, 0x20 };
- u_int8_t dmatimings[] = { 0x77, 0x21, 0x20 };
-
- mode = ata_limit_mode(dev, mode, ctlr->chip->max_dma);
-
- mode = ata_check_80pin(dev, mode);
-
- error = ata_controlcmd(dev, ATA_SETFEATURES, ATA_SF_SETXFER, 0, mode);
-
- if (bootverbose)
- device_printf(dev, "%ssetting %s on %s chip\n",
- (error) ? "FAILURE " : "",
- ata_mode2str(mode), ctlr->chip->text);
- if (!error) {
+ device_t parent = device_get_parent(dev);
+ struct ata_pci_controller *ctlr = device_get_softc(parent);
+ struct ata_channel *ch = device_get_softc(dev);
+ int devno = (ch->unit << 1) + target;
+ int offset = (devno ^ 0x01) << 3;
+ int piomode;
+ u_int8_t piotimings[] = { 0x5d, 0x47, 0x34, 0x22, 0x20 };
+ u_int8_t dmatimings[] = { 0x77, 0x21, 0x20 };
+
+ mode = min(mode, ctlr->chip->max_dma);
if (mode >= ATA_UDMA0) {
- pci_write_config(gparent, 0x56,
- (pci_read_config(gparent, 0x56, 2) &
+ /* Set UDMA mode, enable UDMA, set WDMA2/PIO4 */
+ pci_write_config(parent, 0x56,
+ (pci_read_config(parent, 0x56, 2) &
~(0xf << (devno << 2))) |
((mode & ATA_MODE_MASK) << (devno << 2)), 2);
- pci_write_config(gparent, 0x54,
- pci_read_config(gparent, 0x54, 1) |
+ pci_write_config(parent, 0x54,
+ pci_read_config(parent, 0x54, 1) |
(0x01 << devno), 1);
- pci_write_config(gparent, 0x44,
- (pci_read_config(gparent, 0x44, 4) &
+ pci_write_config(parent, 0x44,
+ (pci_read_config(parent, 0x44, 4) &
~(0xff << offset)) |
(dmatimings[2] << offset), 4);
- }
- else if (mode >= ATA_WDMA0) {
- pci_write_config(gparent, 0x54,
- pci_read_config(gparent, 0x54, 1) &
+ piomode = ATA_PIO4;
+ } else if (mode >= ATA_WDMA0) {
+ /* Disable UDMA, set WDMA mode and timings, calculate PIO. */
+ pci_write_config(parent, 0x54,
+ pci_read_config(parent, 0x54, 1) &
~(0x01 << devno), 1);
- pci_write_config(gparent, 0x44,
- (pci_read_config(gparent, 0x44, 4) &
+ pci_write_config(parent, 0x44,
+ (pci_read_config(parent, 0x44, 4) &
~(0xff << offset)) |
(dmatimings[mode & ATA_MODE_MASK] << offset), 4);
- }
- else
- pci_write_config(gparent, 0x54,
- pci_read_config(gparent, 0x54, 1) &
+ piomode = (mode == ATA_WDMA0) ? ATA_PIO0 :
+ (mode == ATA_WDMA1) ? ATA_PIO3 : ATA_PIO4;
+ } else {
+ /* Disable UDMA, set requested PIO. */
+ pci_write_config(parent, 0x54,
+ pci_read_config(parent, 0x54, 1) &
~(0x01 << devno), 1);
-
- pci_write_config(gparent, 0x40,
- (pci_read_config(gparent, 0x40, 4) &
+ piomode = mode;
+ }
+ /* Set PIO mode and timings, calculated above. */
+ pci_write_config(parent, 0x4a,
+ (pci_read_config(parent, 0x4a, 2) &
+ ~(0xf << (devno << 2))) |
+ ((piomode - ATA_PIO0) << (devno<<2)),2);
+ pci_write_config(parent, 0x40,
+ (pci_read_config(parent, 0x40, 4) &
~(0xff << offset)) |
- (piotimings[ata_mode2idx(mode)] << offset), 4);
- atadev->mode = mode;
- }
+ (piotimings[ata_mode2idx(piomode)] << offset), 4);
+ return (mode);
}
ATA_DECLARE_DRIVER(ata_serverworks);
diff --git a/sys/dev/ata/chipsets/ata-siliconimage.c b/sys/dev/ata/chipsets/ata-siliconimage.c
index 34bd92f..066e9280 100644
--- a/sys/dev/ata/chipsets/ata-siliconimage.c
+++ b/sys/dev/ata/chipsets/ata-siliconimage.c
@@ -54,12 +54,12 @@ __FBSDID("$FreeBSD$");
/* local prototypes */
static int ata_cmd_ch_attach(device_t dev);
static int ata_cmd_status(device_t dev);
-static void ata_cmd_setmode(device_t dev, int mode);
+static int ata_cmd_setmode(device_t dev, int target, int mode);
static int ata_sii_ch_attach(device_t dev);
static int ata_sii_ch_detach(device_t dev);
static int ata_sii_status(device_t dev);
static void ata_sii_reset(device_t dev);
-static void ata_sii_setmode(device_t dev, int mode);
+static int ata_sii_setmode(device_t dev, int target, int mode);
static int ata_siiprb_ch_attach(device_t dev);
static int ata_siiprb_ch_detach(device_t dev);
static int ata_siiprb_status(device_t dev);
@@ -145,6 +145,7 @@ ata_sii_chipinit(device_t dev)
ctlr->ch_detach = ata_siiprb_ch_detach;
ctlr->reset = ata_siiprb_reset;
ctlr->setmode = ata_sata_setmode;
+ ctlr->getrev = ata_sata_getrev;
ctlr->channels = (ctlr->chip->cfg2 == SII_4CH) ? 4 : 2;
/* reset controller */
@@ -193,6 +194,7 @@ ata_sii_chipinit(device_t dev)
if (ctlr->chip->max_dma >= ATA_SA150) {
ctlr->reset = ata_sii_reset;
ctlr->setmode = ata_sata_setmode;
+ ctlr->getrev = ata_sata_getrev;
}
else
ctlr->setmode = ata_sii_setmode;
@@ -246,59 +248,37 @@ ata_cmd_status(device_t dev)
return 0;
}
-static void
-ata_cmd_setmode(device_t dev, int mode)
+static int
+ata_cmd_setmode(device_t dev, int target, int mode)
{
- device_t gparent = GRANDPARENT(dev);
- struct ata_pci_controller *ctlr = device_get_softc(gparent);
- struct ata_channel *ch = device_get_softc(device_get_parent(dev));
- struct ata_device *atadev = device_get_softc(dev);
- int devno = (ch->unit << 1) + atadev->unit;
- int error;
-
- mode = ata_limit_mode(dev, mode, ctlr->chip->max_dma);
-
- mode = ata_check_80pin(dev, mode);
-
- error = ata_controlcmd(dev, ATA_SETFEATURES, ATA_SF_SETXFER, 0, mode);
-
- if (bootverbose)
- device_printf(dev, "%ssetting %s on %s chip\n",
- (error) ? "FAILURE " : "",
- ata_mode2str(mode), ctlr->chip->text);
- if (!error) {
+ device_t parent = device_get_parent(dev);
+ struct ata_pci_controller *ctlr = device_get_softc(parent);
+ struct ata_channel *ch = device_get_softc(dev);
+ int devno = (ch->unit << 1) + target;
int treg = 0x54 + ((devno < 3) ? (devno << 1) : 7);
int ureg = ch->unit ? 0x7b : 0x73;
-
- if (mode >= ATA_UDMA0) {
- int udmatimings[][2] = { { 0x31, 0xc2 }, { 0x21, 0x82 },
+ int piomode;
+ uint8_t piotimings[] = { 0xa9, 0x57, 0x44, 0x32, 0x3f, 0x87, 0x32, 0x3f };
+ uint8_t udmatimings[][2] = { { 0x31, 0xc2 }, { 0x21, 0x82 },
{ 0x11, 0x42 }, { 0x25, 0x8a },
{ 0x15, 0x4a }, { 0x05, 0x0a } };
- u_int8_t umode = pci_read_config(gparent, ureg, 1);
-
- umode &= ~(atadev->unit == ATA_MASTER ? 0x35 : 0xca);
- umode |= udmatimings[mode & ATA_MODE_MASK][atadev->unit];
- pci_write_config(gparent, ureg, umode, 1);
- }
- else if (mode >= ATA_WDMA0) {
- int dmatimings[] = { 0x87, 0x32, 0x3f };
-
- pci_write_config(gparent, treg, dmatimings[mode & ATA_MODE_MASK],1);
- pci_write_config(gparent, ureg,
- pci_read_config(gparent, ureg, 1) &
- ~(atadev->unit == ATA_MASTER ? 0x35 : 0xca), 1);
- }
- else {
- int piotimings[] = { 0xa9, 0x57, 0x44, 0x32, 0x3f };
- pci_write_config(gparent, treg,
- piotimings[(mode & ATA_MODE_MASK) - ATA_PIO0], 1);
- pci_write_config(gparent, ureg,
- pci_read_config(gparent, ureg, 1) &
- ~(atadev->unit == ATA_MASTER ? 0x35 : 0xca), 1);
+ mode = min(mode, ctlr->chip->max_dma);
+ if (mode >= ATA_UDMA0) {
+ u_int8_t umode = pci_read_config(parent, ureg, 1);
+
+ umode &= ~(target == 0 ? 0x35 : 0xca);
+ umode |= udmatimings[mode & ATA_MODE_MASK][target];
+ pci_write_config(parent, ureg, umode, 1);
+ piomode = ATA_PIO4;
+ } else {
+ pci_write_config(parent, ureg,
+ pci_read_config(parent, ureg, 1) &
+ ~(target == 0 ? 0x35 : 0xca), 1);
+ piomode = mode;
}
- atadev->mode = mode;
- }
+ pci_write_config(parent, treg, piotimings[ata_mode2idx(piomode)], 1);
+ return (mode);
}
static int
@@ -335,12 +315,12 @@ ata_sii_ch_attach(device_t dev)
ch->r_io[ATA_SCONTROL].res = ctlr->r_res2;
ch->r_io[ATA_SCONTROL].offset = 0x100 + (unit01 << 7) + (unit10 << 8);
ch->flags |= ATA_NO_SLAVE;
+ ch->flags |= ATA_SATA;
/* enable PHY state change interrupt */
ATA_OUTL(ctlr->r_res2, 0x148 + (unit01 << 7) + (unit10 << 8),(1 << 16));
}
- ch->dma.max_iosize = (ATA_DMA_ENTRIES - 1) * PAGE_SIZE;
if (ctlr->chip->cfg2 & SII_BUG) {
/* work around errata in early chips */
ch->dma.boundary = 8192;
@@ -349,6 +329,8 @@ ata_sii_ch_attach(device_t dev)
ata_pci_hw(dev);
ch->hw.status = ata_sii_status;
+ if (ctlr->chip->cfg2 & SII_SETCLK)
+ ch->flags |= ATA_CHECKS_CABLE;
return 0;
}
@@ -386,69 +368,53 @@ ata_sii_reset(device_t dev)
ata_generic_reset(dev);
}
-static void
-ata_sii_setmode(device_t dev, int mode)
+static int
+ata_sii_setmode(device_t dev, int target, int mode)
{
- device_t gparent = GRANDPARENT(dev);
- struct ata_pci_controller *ctlr = device_get_softc(gparent);
- struct ata_channel *ch = device_get_softc(device_get_parent(dev));
- struct ata_device *atadev = device_get_softc(dev);
- int rego = (ch->unit << 4) + (atadev->unit << 1);
- int mreg = ch->unit ? 0x84 : 0x80;
- int mask = 0x03 << (atadev->unit << 2);
- int mval = pci_read_config(gparent, mreg, 1) & ~mask;
- int error;
-
- mode = ata_limit_mode(dev, mode, ctlr->chip->max_dma);
-
- if (ctlr->chip->cfg2 & SII_SETCLK) {
- if (mode > ATA_UDMA2 && (pci_read_config(gparent, 0x79, 1) &
- (ch->unit ? 0x02 : 0x01))) {
- ata_print_cable(dev, "controller");
- mode = ATA_UDMA2;
- }
- }
- else
- mode = ata_check_80pin(dev, mode);
-
- error = ata_controlcmd(dev, ATA_SETFEATURES, ATA_SF_SETXFER, 0, mode);
-
- if (bootverbose)
- device_printf(dev, "%ssetting %s on %s chip\n",
- (error) ? "FAILURE " : "",
- ata_mode2str(mode), ctlr->chip->text);
- if (error)
- return;
-
- if (mode >= ATA_UDMA0) {
- u_int8_t udmatimings[] = { 0xf, 0xb, 0x7, 0x5, 0x3, 0x2, 0x1 };
- u_int8_t ureg = 0xac + rego;
-
- pci_write_config(gparent, mreg,
- mval | (0x03 << (atadev->unit << 2)), 1);
- pci_write_config(gparent, ureg,
- (pci_read_config(gparent, ureg, 1) & ~0x3f) |
- udmatimings[mode & ATA_MODE_MASK], 1);
-
- }
- else if (mode >= ATA_WDMA0) {
+ device_t parent = device_get_parent(dev);
+ struct ata_pci_controller *ctlr = device_get_softc(parent);
+ struct ata_channel *ch = device_get_softc(dev);
+ int rego = (ch->unit << 4) + (target << 1);
+ int mreg = ch->unit ? 0x84 : 0x80;
+ int mask = 0x03 << (target << 2);
+ int mval = pci_read_config(parent, mreg, 1) & ~mask;
+ int piomode;
+ u_int8_t preg = 0xa4 + rego;
u_int8_t dreg = 0xa8 + rego;
+ u_int8_t ureg = 0xac + rego;
+ u_int16_t piotimings[] = { 0x328a, 0x2283, 0x1104, 0x10c3, 0x10c1 };
u_int16_t dmatimings[] = { 0x2208, 0x10c2, 0x10c1 };
+ u_int8_t udmatimings[] = { 0xf, 0xb, 0x7, 0x5, 0x3, 0x2, 0x1 };
- pci_write_config(gparent, mreg,
- mval | (0x02 << (atadev->unit << 2)), 1);
- pci_write_config(gparent, dreg, dmatimings[mode & ATA_MODE_MASK], 2);
-
- }
- else {
- u_int8_t preg = 0xa4 + rego;
- u_int16_t piotimings[] = { 0x328a, 0x2283, 0x1104, 0x10c3, 0x10c1 };
+ mode = min(mode, ctlr->chip->max_dma);
- pci_write_config(gparent, mreg,
- mval | (0x01 << (atadev->unit << 2)), 1);
- pci_write_config(gparent, preg, piotimings[mode & ATA_MODE_MASK], 2);
- }
- atadev->mode = mode;
+ if (ctlr->chip->cfg2 & SII_SETCLK) {
+ if (mode > ATA_UDMA2 && (pci_read_config(parent, 0x79, 1) &
+ (ch->unit ? 0x02 : 0x01))) {
+ ata_print_cable(dev, "controller");
+ mode = ATA_UDMA2;
+ }
+ }
+ if (mode >= ATA_UDMA0) {
+ pci_write_config(parent, mreg,
+ mval | (0x03 << (target << 2)), 1);
+ pci_write_config(parent, ureg,
+ (pci_read_config(parent, ureg, 1) & ~0x3f) |
+ udmatimings[mode & ATA_MODE_MASK], 1);
+ piomode = ATA_PIO4;
+ } else if (mode >= ATA_WDMA0) {
+ pci_write_config(parent, mreg,
+ mval | (0x02 << (target << 2)), 1);
+ pci_write_config(parent, dreg, dmatimings[mode & ATA_MODE_MASK], 2);
+ piomode = (mode == ATA_WDMA0) ? ATA_PIO0 :
+ (mode == ATA_WDMA1) ? ATA_PIO3 : ATA_PIO4;
+ } else {
+ pci_write_config(parent, mreg,
+ mval | (0x01 << (target << 2)), 1);
+ piomode = mode;
+ }
+ pci_write_config(parent, preg, piotimings[ata_mode2idx(piomode)], 2);
+ return (mode);
}
diff --git a/sys/dev/ata/chipsets/ata-sis.c b/sys/dev/ata/chipsets/ata-sis.c
index 5c74e56..8022505 100644
--- a/sys/dev/ata/chipsets/ata-sis.c
+++ b/sys/dev/ata/chipsets/ata-sis.c
@@ -55,7 +55,7 @@ __FBSDID("$FreeBSD$");
static int ata_sis_chipinit(device_t dev);
static int ata_sis_ch_attach(device_t dev);
static void ata_sis_reset(device_t dev);
-static void ata_sis_setmode(device_t dev, int mode);
+static int ata_sis_setmode(device_t dev, int target, int mode);
/* misc defines */
#define SIS_33 1
@@ -191,6 +191,7 @@ ata_sis_chipinit(device_t dev)
ctlr->reset = ata_sis_reset;
}
ctlr->setmode = ata_sata_setmode;
+ ctlr->getrev = ata_sata_getrev;
return 0;
default:
return ENXIO;
@@ -217,6 +218,7 @@ ata_sis_ch_attach(device_t dev)
ch->r_io[ATA_SCONTROL].res = ctlr->r_res2;
ch->r_io[ATA_SCONTROL].offset = 0x08 + offset;
ch->flags |= ATA_NO_SLAVE;
+ ch->flags |= ATA_SATA;
/* XXX SOS PHY hotplug handling missing in SiS chip ?? */
/* XXX SOS unknown how to enable PHY state change interrupt */
@@ -230,40 +232,30 @@ ata_sis_reset(device_t dev)
ata_generic_reset(dev);
}
-static void
-ata_sis_setmode(device_t dev, int mode)
+static int
+ata_sis_setmode(device_t dev, int target, int mode)
{
- device_t gparent = GRANDPARENT(dev);
- struct ata_pci_controller *ctlr = device_get_softc(gparent);
- struct ata_channel *ch = device_get_softc(device_get_parent(dev));
- struct ata_device *atadev = device_get_softc(dev);
- int devno = (ch->unit << 1) + atadev->unit;
- int error;
-
- mode = ata_limit_mode(dev, mode, ctlr->chip->max_dma);
-
- if (ctlr->chip->cfg1 == SIS_133NEW) {
- if (mode > ATA_UDMA2 &&
- pci_read_config(gparent, ch->unit ? 0x52 : 0x50,2) & 0x8000) {
- ata_print_cable(dev, "controller");
- mode = ATA_UDMA2;
- }
- }
- else {
- if (mode > ATA_UDMA2 &&
- pci_read_config(gparent, 0x48, 1)&(ch->unit ? 0x20 : 0x10)) {
- ata_print_cable(dev, "controller");
- mode = ATA_UDMA2;
- }
- }
+ device_t parent = device_get_parent(dev);
+ struct ata_pci_controller *ctlr = device_get_softc(parent);
+ struct ata_channel *ch = device_get_softc(dev);
+ int devno = (ch->unit << 1) + target;
+
+ mode = min(mode, ctlr->chip->max_dma);
+
+ if (ctlr->chip->cfg1 == SIS_133NEW) {
+ if (mode > ATA_UDMA2 &&
+ pci_read_config(parent, ch->unit ? 0x52 : 0x50,2) & 0x8000) {
+ ata_print_cable(dev, "controller");
+ mode = ATA_UDMA2;
+ }
+ } else {
+ if (mode > ATA_UDMA2 &&
+ pci_read_config(parent, 0x48, 1)&(ch->unit ? 0x20 : 0x10)) {
+ ata_print_cable(dev, "controller");
+ mode = ATA_UDMA2;
+ }
+ }
- error = ata_controlcmd(dev, ATA_SETFEATURES, ATA_SF_SETXFER, 0, mode);
-
- if (bootverbose)
- device_printf(dev, "%ssetting %s on %s chip\n",
- (error) ? "FAILURE " : "",
- ata_mode2str(mode), ctlr->chip->text);
- if (!error) {
switch (ctlr->chip->cfg1) {
case SIS_133NEW: {
u_int32_t timings[] =
@@ -272,8 +264,8 @@ ata_sis_setmode(device_t dev, int mode)
0x0509347c, 0x0509325c, 0x0509323c, 0x0509322c, 0x0509321c};
u_int32_t reg;
- reg = (pci_read_config(gparent, 0x57, 1)&0x40?0x70:0x40)+(devno<<2);
- pci_write_config(gparent, reg, timings[ata_mode2idx(mode)], 4);
+ reg = (pci_read_config(parent, 0x57, 1)&0x40?0x70:0x40)+(devno<<2);
+ pci_write_config(parent, reg, timings[ata_mode2idx(mode)], 4);
break;
}
case SIS_133OLD: {
@@ -283,7 +275,7 @@ ata_sis_setmode(device_t dev, int mode)
u_int16_t reg = 0x40 + (devno << 1);
- pci_write_config(gparent, reg, timings[ata_mode2idx(mode)], 2);
+ pci_write_config(parent, reg, timings[ata_mode2idx(mode)], 2);
break;
}
case SIS_100NEW: {
@@ -292,7 +284,7 @@ ata_sis_setmode(device_t dev, int mode)
0x0031, 0x8b31, 0x8731, 0x8531, 0x8431, 0x8231, 0x8131 };
u_int16_t reg = 0x40 + (devno << 1);
- pci_write_config(gparent, reg, timings[ata_mode2idx(mode)], 2);
+ pci_write_config(parent, reg, timings[ata_mode2idx(mode)], 2);
break;
}
case SIS_100OLD:
@@ -303,12 +295,11 @@ ata_sis_setmode(device_t dev, int mode)
0x0301, 0xf301, 0xd301, 0xb301, 0xa301, 0x9301, 0x8301 };
u_int16_t reg = 0x40 + (devno << 1);
- pci_write_config(gparent, reg, timings[ata_mode2idx(mode)], 2);
+ pci_write_config(parent, reg, timings[ata_mode2idx(mode)], 2);
break;
}
}
- atadev->mode = mode;
- }
+ return (mode);
}
ATA_DECLARE_DRIVER(ata_sis);
diff --git a/sys/dev/ata/chipsets/ata-via.c b/sys/dev/ata/chipsets/ata-via.c
index 47ebd0a..9aea45d 100644
--- a/sys/dev/ata/chipsets/ata-via.c
+++ b/sys/dev/ata/chipsets/ata-via.c
@@ -56,9 +56,9 @@ static int ata_via_chipinit(device_t dev);
static int ata_via_ch_attach(device_t dev);
static int ata_via_ch_detach(device_t dev);
static void ata_via_reset(device_t dev);
-static void ata_via_old_setmode(device_t dev, int mode);
+static int ata_via_old_setmode(device_t dev, int target, int mode);
static void ata_via_southbridge_fixup(device_t dev);
-static void ata_via_new_setmode(device_t dev, int mode);
+static int ata_via_new_setmode(device_t dev, int target, int mode);
/* misc defines */
#define VIA33 0
@@ -152,9 +152,9 @@ ata_via_chipinit(device_t dev)
if (ctlr->chip->cfg2 & VIABAR) {
ctlr->channels = 3;
ctlr->setmode = ata_via_new_setmode;
- }
- else
+ } else
ctlr->setmode = ata_sata_setmode;
+ ctlr->getrev = ata_sata_getrev;
return 0;
}
@@ -233,6 +233,7 @@ ata_via_ch_attach(device_t dev)
ch->r_io[ATA_SCONTROL].res = ctlr->r_res2;
ch->r_io[ATA_SCONTROL].offset = 0x08 + (ch->unit << ctlr->chip->cfg1);
ch->flags |= ATA_NO_SLAVE;
+ ch->flags |= ATA_SATA;
/* XXX SOS PHY hotplug handling missing in VIA chip ?? */
/* XXX SOS unknown how to enable PHY state change interrupt */
@@ -277,75 +278,63 @@ ata_via_reset(device_t dev)
ata_generic_reset(dev);
}
-static void
-ata_via_new_setmode(device_t dev, int mode)
+static int
+ata_via_new_setmode(device_t dev, int target, int mode)
{
- device_t gparent = GRANDPARENT(dev);
- struct ata_pci_controller *ctlr = device_get_softc(gparent);
- struct ata_channel *ch = device_get_softc(device_get_parent(dev));
- struct ata_device *atadev = device_get_softc(dev);
- int error;
-
- if ((ctlr->chip->cfg2 & VIABAR) && (ch->unit > 1)) {
- u_int8_t pio_timings[] = { 0xa8, 0x65, 0x65, 0x32, 0x20,
- 0x65, 0x32, 0x20,
- 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20 };
- u_int8_t dma_timings[] = { 0xee, 0xe8, 0xe6, 0xe4, 0xe2, 0xe1, 0xe0 };
-
- mode = ata_check_80pin(dev, ata_limit_mode(dev, mode, ATA_UDMA6));
- error = ata_controlcmd(dev, ATA_SETFEATURES, ATA_SF_SETXFER, 0, mode);
- if (bootverbose)
- device_printf(dev, "%ssetting %s on %s chip\n",
- (error) ? "FAILURE " : "", ata_mode2str(mode),
- ctlr->chip->text);
- if (!error) {
- pci_write_config(gparent, 0xab, pio_timings[ata_mode2idx(mode)], 1);
- if (mode >= ATA_UDMA0)
- pci_write_config(gparent, 0xb3,
+ device_t parent = device_get_parent(dev);
+ struct ata_pci_controller *ctlr = device_get_softc(parent);
+ struct ata_channel *ch = device_get_softc(dev);
+
+ if ((ctlr->chip->cfg2 & VIABAR) && (ch->unit > 1)) {
+ int piomode;
+ u_int8_t pio_timings[] = { 0xa8, 0x65, 0x65, 0x32, 0x20 };
+ u_int8_t dma_timings[] = { 0xee, 0xe8, 0xe6, 0xe4, 0xe2, 0xe1, 0xe0 };
+
+ /* This chip can't do WDMA. */
+ if (mode >= ATA_WDMA0 && mode < ATA_UDMA0)
+ mode = ATA_PIO4;
+ if (mode >= ATA_UDMA0) {
+ pci_write_config(parent, 0xb3,
dma_timings[mode & ATA_MODE_MASK], 1);
- atadev->mode = mode;
- }
- }
- else
- ata_sata_setmode(dev, mode);
+ piomode = ATA_PIO4;
+ } else
+ piomode = mode;
+ pci_write_config(parent, 0xab, pio_timings[ata_mode2idx(piomode)], 1);
+ } else
+ mode = ata_sata_setmode(dev, target, mode);
+ return (mode);
}
-static void
-ata_via_old_setmode(device_t dev, int mode)
+static int
+ata_via_old_setmode(device_t dev, int target, int mode)
{
- device_t gparent = GRANDPARENT(dev);
- struct ata_pci_controller *ctlr = device_get_softc(gparent);
- struct ata_channel *ch = device_get_softc(device_get_parent(dev));
- struct ata_device *atadev = device_get_softc(dev);
- u_int8_t timings[] = { 0xa8, 0x65, 0x42, 0x22, 0x20, 0x42, 0x22, 0x20,
- 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20 };
- int modes[][7] = {
- { 0xc2, 0xc1, 0xc0, 0x00, 0x00, 0x00, 0x00 }, /* VIA ATA33 */
- { 0xee, 0xec, 0xea, 0xe9, 0xe8, 0x00, 0x00 }, /* VIA ATA66 */
- { 0xf7, 0xf6, 0xf4, 0xf2, 0xf1, 0xf0, 0x00 }, /* VIA ATA100 */
- { 0xf7, 0xf7, 0xf6, 0xf4, 0xf2, 0xf1, 0xf0 } }; /* VIA ATA133 */
- int devno = (ch->unit << 1) + atadev->unit;
- int reg = 0x53 - devno;
- int error;
-
- mode = ata_limit_mode(dev, mode, ctlr->chip->max_dma);
- mode = ata_check_80pin(dev, mode);
-
- error = ata_controlcmd(dev, ATA_SETFEATURES, ATA_SF_SETXFER, 0, mode);
- if (bootverbose)
- device_printf(dev, "%ssetting %s on %s chip\n",
- (error) ? "FAILURE " : "", ata_mode2str(mode),
- ctlr->chip->text);
- if (!error) {
- if (ctlr->chip->cfg1 != VIA133)
- pci_write_config(gparent, reg - 0x08,timings[ata_mode2idx(mode)],1);
- if (mode >= ATA_UDMA0)
- pci_write_config(gparent, reg,
+ device_t parent = device_get_parent(dev);
+ struct ata_pci_controller *ctlr = device_get_softc(parent);
+ struct ata_channel *ch = device_get_softc(dev);
+ int devno = (ch->unit << 1) + target;
+ int reg = 0x53 - devno;
+ int piomode;
+ uint8_t timings[] = { 0xa8, 0x65, 0x42, 0x22, 0x20, 0xa8, 0x22, 0x20 };
+ uint8_t modes[][7] = {
+ { 0xc2, 0xc1, 0xc0, 0x00, 0x00, 0x00, 0x00 }, /* VIA ATA33 */
+ { 0xee, 0xec, 0xea, 0xe9, 0xe8, 0x00, 0x00 }, /* VIA ATA66 */
+ { 0xf7, 0xf6, 0xf4, 0xf2, 0xf1, 0xf0, 0x00 }, /* VIA ATA100 */
+ { 0xf7, 0xf7, 0xf6, 0xf4, 0xf2, 0xf1, 0xf0 } }; /* VIA ATA133 */
+
+ mode = min(mode, ctlr->chip->max_dma);
+ /* Set UDMA timings */
+ if (mode >= ATA_UDMA0) {
+ pci_write_config(parent, reg,
modes[ctlr->chip->cfg1][mode & ATA_MODE_MASK], 1);
- else
- pci_write_config(gparent, reg, 0x8b, 1);
- atadev->mode = mode;
- }
+ piomode = ATA_PIO4;
+ } else {
+ pci_write_config(parent, reg, 0x8b, 1);
+ piomode = mode;
+ }
+ /* Set WDMA/PIO timings */
+ if (ctlr->chip->cfg1 != VIA133)
+ pci_write_config(parent, reg - 0x08,timings[ata_mode2idx(piomode)], 1);
+ return (mode);
}
static void
OpenPOWER on IntegriCloud