diff --git a/sys/dev/ata/ata-chipset.c b/sys/dev/ata/ata-chipset.c index a8d3d4465b25..b00229dea00d 100644 --- a/sys/dev/ata/ata-chipset.c +++ b/sys/dev/ata/ata-chipset.c @@ -3941,7 +3941,7 @@ ata_via_ident(device_t dev) static struct ata_chip_id new_ids[] = {{ ATA_VIA6410, 0x00, 0, 0x00, ATA_UDMA6, "VIA 6410" }, { ATA_VIA6420, 0x00, 7, 0x00, ATA_SA150, "VIA 6420" }, - { ATA_VIA6421, 0x00, 6, 0x00, ATA_SA150, "VIA 6421" }, + { ATA_VIA6421, 0x00, 6, VIABAR, ATA_SA150, "VIA 6421" }, { 0, 0, 0, 0, 0, 0 }}; char buffer[64]; @@ -4016,8 +4016,34 @@ ata_via_allocate(device_t dev) 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 */ - ata_pci_allocate(dev); + + /* newer SATA chips has resources in one BAR for each channel */ + if (ctlr->chip->cfg2 & VIABAR) { + struct resource *r_io; + int i, rid; + + rid = PCIR_BAR(ch->unit); + if (!(r_io = bus_alloc_resource_any(device_get_parent(dev), + SYS_RES_IOPORT, + &rid, RF_ACTIVE))) + return ENXIO; + + for (i = ATA_DATA; i <= ATA_COMMAND; i ++) { + ch->r_io[i].res = r_io; + ch->r_io[i].offset = i; + } + ch->r_io[ATA_CONTROL].res = r_io; + ch->r_io[ATA_CONTROL].offset = 2 + ATA_IOSIZE; + ch->r_io[ATA_IDX_ADDR].res = r_io; + ata_default_registers(dev); + for (i = ATA_BMCMD_PORT; i <= ATA_BMDTP_PORT; i++) { + ch->r_io[i].res = ctlr->r_res1; + ch->r_io[i].offset = i - ATA_BMCMD_PORT; + } + ata_generic_hw(dev); + } + else + ata_pci_allocate(dev); ch->r_io[ATA_SSTATUS].res = ctlr->r_res2; ch->r_io[ATA_SSTATUS].offset = (ch->unit << ctlr->chip->cfg1); diff --git a/sys/dev/ata/ata-pci.h b/sys/dev/ata/ata-pci.h index 33ccb2698ada..99a1fb10483b 100644 --- a/sys/dev/ata/ata-pci.h +++ b/sys/dev/ata/ata-pci.h @@ -355,6 +355,7 @@ struct ata_connect_task { #define NV4OFF 0x08 #define VIACLK 0x10 #define VIABUG 0x20 +#define VIABAR 0x40 /* global prototypes ata-pci.c */