diff options
Diffstat (limited to 'sys/dev/ata/chipsets')
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 |