aboutsummaryrefslogtreecommitdiff
path: root/sys/dev/ata/ata-chipset.c
diff options
context:
space:
mode:
Diffstat (limited to 'sys/dev/ata/ata-chipset.c')
-rw-r--r--sys/dev/ata/ata-chipset.c32
1 files changed, 29 insertions, 3 deletions
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);