From owner-svn-src-all@FreeBSD.ORG Sat Feb 5 21:34:27 2011 Return-Path: Delivered-To: svn-src-all@freebsd.org Received: from mx1.freebsd.org (mx1.freebsd.org [IPv6:2001:4f8:fff6::34]) by hub.freebsd.org (Postfix) with ESMTP id 4555A1065675; Sat, 5 Feb 2011 21:34:27 +0000 (UTC) (envelope-from mav@FreeBSD.org) Received: from svn.freebsd.org (svn.freebsd.org [IPv6:2001:4f8:fff6::2c]) by mx1.freebsd.org (Postfix) with ESMTP id 2FFD48FC08; Sat, 5 Feb 2011 21:34:27 +0000 (UTC) Received: from svn.freebsd.org (localhost [127.0.0.1]) by svn.freebsd.org (8.14.3/8.14.3) with ESMTP id p15LYR13041697; Sat, 5 Feb 2011 21:34:27 GMT (envelope-from mav@svn.freebsd.org) Received: (from mav@localhost) by svn.freebsd.org (8.14.3/8.14.3/Submit) id p15LYRmw041695; Sat, 5 Feb 2011 21:34:27 GMT (envelope-from mav@svn.freebsd.org) Message-Id: <201102052134.p15LYRmw041695@svn.freebsd.org> From: Alexander Motin Date: Sat, 5 Feb 2011 21:34:27 +0000 (UTC) To: src-committers@freebsd.org, svn-src-all@freebsd.org, svn-src-stable@freebsd.org, svn-src-stable-8@freebsd.org X-SVN-Group: stable-8 MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Cc: Subject: svn commit: r218347 - stable/8/sys/dev/ata/chipsets X-BeenThere: svn-src-all@freebsd.org X-Mailman-Version: 2.1.5 Precedence: list List-Id: "SVN commit messages for the entire src tree \(except for " user" and " projects" \)" List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Sat, 05 Feb 2011 21:34:27 -0000 Author: mav Date: Sat Feb 5 21:34:26 2011 New Revision: 218347 URL: http://svn.freebsd.org/changeset/base/218347 Log: MFC r217774: ICH7 SATA controller in legacy mode can provide access to SATA registers via AHCI-like memory resource at BAR(5). Use it if BIOS was so kind to allocate memory for that BAR. This allows hot-plug support and connection speed reporting. Modified: stable/8/sys/dev/ata/chipsets/ata-intel.c Directory Properties: stable/8/sys/ (props changed) stable/8/sys/amd64/include/xen/ (props changed) stable/8/sys/cddl/contrib/opensolaris/ (props changed) stable/8/sys/contrib/dev/acpica/ (props changed) stable/8/sys/contrib/pf/ (props changed) Modified: stable/8/sys/dev/ata/chipsets/ata-intel.c ============================================================================== --- stable/8/sys/dev/ata/chipsets/ata-intel.c Sat Feb 5 21:24:37 2011 (r218346) +++ stable/8/sys/dev/ata/chipsets/ata-intel.c Sat Feb 5 21:34:26 2011 (r218347) @@ -60,10 +60,14 @@ static int ata_intel_new_setmode(device_ static int ata_intel_sch_setmode(device_t dev, int target, int mode); static int ata_intel_sata_getrev(device_t dev, int target); static int ata_intel_sata_status(device_t dev); +static int ata_intel_sata_ahci_read(device_t dev, int port, + int reg, u_int32_t *result); static int ata_intel_sata_cscr_read(device_t dev, int port, int reg, u_int32_t *result); static int ata_intel_sata_sidpr_read(device_t dev, int port, int reg, u_int32_t *result); +static int ata_intel_sata_ahci_write(device_t dev, int port, + int reg, u_int32_t result); static int ata_intel_sata_cscr_write(device_t dev, int port, int reg, u_int32_t result); static int ata_intel_sata_sidpr_write(device_t dev, int port, @@ -79,6 +83,7 @@ static void ata_intel_31244_reset(device #define INTEL_ICH5 2 #define INTEL_6CH 4 #define INTEL_6CH2 8 +#define INTEL_ICH7 16 /* * Intel chipset support functions @@ -113,11 +118,11 @@ ata_intel_probe(device_t dev) { ATA_I82801FB_R1, 0, INTEL_AHCI, 0, ATA_SA150, "ICH6" }, { ATA_I82801FBM, 0, INTEL_AHCI, 0, ATA_SA150, "ICH6M" }, { ATA_I82801GB, 0, 0, 1, ATA_UDMA5, "ICH7" }, - { ATA_I82801GB_S1, 0, 0, 0, ATA_SA300, "ICH7" }, - { ATA_I82801GB_R1, 0, 0, 0, ATA_SA300, "ICH7" }, + { ATA_I82801GB_S1, 0, INTEL_ICH7, 0, ATA_SA300, "ICH7" }, + { ATA_I82801GB_R1, 0, INTEL_AHCI, 0, ATA_SA300, "ICH7" }, { ATA_I82801GB_AH, 0, INTEL_AHCI, 0, ATA_SA300, "ICH7" }, - { ATA_I82801GBM_S1, 0, 0, 0, ATA_SA150, "ICH7M" }, - { ATA_I82801GBM_R1, 0, 0, 0, ATA_SA150, "ICH7M" }, + { ATA_I82801GBM_S1, 0, INTEL_ICH7, 0, ATA_SA150, "ICH7M" }, + { ATA_I82801GBM_R1, 0, INTEL_AHCI, 0, ATA_SA150, "ICH7M" }, { ATA_I82801GBM_AH, 0, INTEL_AHCI, 0, ATA_SA150, "ICH7M" }, { ATA_I63XXESB2, 0, 0, 1, ATA_UDMA5, "63XXESB2" }, { ATA_I63XXESB2_S1, 0, 0, 0, ATA_SA300, "63XXESB2" }, @@ -250,14 +255,30 @@ ata_intel_chipinit(device_t dev) (pci_read_config(dev, 0x90, 1) & 0xc0) && (ata_ahci_chipinit(dev) != ENXIO)) return 0; - - /* if BAR(5) is IO it should point to SATA interface registers */ - ctlr->r_type2 = SYS_RES_IOPORT; - ctlr->r_rid2 = PCIR_BAR(5); - if ((ctlr->r_res2 = bus_alloc_resource_any(dev, ctlr->r_type2, - &ctlr->r_rid2, RF_ACTIVE)) - || (ctlr->chip->cfg1 & INTEL_ICH5)) - ctlr->getrev = ata_intel_sata_getrev; + + /* BAR(5) may point to SATA interface registers */ + if ((ctlr->chip->cfg1 & INTEL_ICH7)) { + ctlr->r_type2 = SYS_RES_MEMORY; + ctlr->r_rid2 = PCIR_BAR(5); + ctlr->r_res2 = bus_alloc_resource_any(dev, ctlr->r_type2, + &ctlr->r_rid2, RF_ACTIVE); + if (ctlr->r_res2 != NULL) { + /* Set SCRAE bit to enable registers access. */ + pci_write_config(dev, 0x94, + pci_read_config(dev, 0x94, 4) | (1 << 9), 4); + /* Set Ports Implemented register bits. */ + ATA_OUTL(ctlr->r_res2, 0x0C, + ATA_INL(ctlr->r_res2, 0x0C) | 0xf); + } + } else { + ctlr->r_type2 = SYS_RES_IOPORT; + ctlr->r_rid2 = PCIR_BAR(5); + ctlr->r_res2 = bus_alloc_resource_any(dev, ctlr->r_type2, + &ctlr->r_rid2, RF_ACTIVE); + } + if (ctlr->r_res2 != NULL || + (ctlr->chip->cfg1 & INTEL_ICH5)) + ctlr->getrev = ata_intel_sata_getrev; ctlr->setmode = ata_sata_setmode; } return 0; @@ -336,8 +357,13 @@ ata_intel_ch_attach(device_t dev) } else if (ctlr->r_res2) { ch->flags |= ATA_PERIODIC_POLL; ch->hw.status = ata_intel_sata_status; - ch->hw.pm_read = ata_intel_sata_sidpr_read; - ch->hw.pm_write = ata_intel_sata_sidpr_write; + if ((ctlr->chip->cfg1 & INTEL_ICH7)) { + ch->hw.pm_read = ata_intel_sata_ahci_read; + ch->hw.pm_write = ata_intel_sata_ahci_write; + } else { + ch->hw.pm_read = ata_intel_sata_sidpr_read; + ch->hw.pm_write = ata_intel_sata_sidpr_write; + }; } if (ch->hw.pm_write != NULL) { ata_sata_scr_write(ch, 0, @@ -537,6 +563,38 @@ ata_intel_sata_status(device_t dev) } static int +ata_intel_sata_ahci_read(device_t dev, int port, int reg, u_int32_t *result) +{ + struct ata_pci_controller *ctlr; + struct ata_channel *ch; + device_t parent; + u_char *smap; + int offset; + + parent = device_get_parent(dev); + ctlr = device_get_softc(parent); + ch = device_get_softc(dev); + port = (port == 1) ? 1 : 0; + smap = (u_char *)&ctlr->chipset_data + ch->unit * 2; + offset = 0x100 + smap[port] * 0x80; + switch (reg) { + case ATA_SSTATUS: + reg = 0x28; + break; + case ATA_SCONTROL: + reg = 0x2c; + break; + case ATA_SERROR: + reg = 0x30; + break; + default: + return (EINVAL); + } + *result = ATA_INL(ctlr->r_res2, offset + reg); + return (0); +} + +static int ata_intel_sata_cscr_read(device_t dev, int port, int reg, u_int32_t *result) { struct ata_pci_controller *ctlr; @@ -598,6 +656,38 @@ ata_intel_sata_sidpr_read(device_t dev, } static int +ata_intel_sata_ahci_write(device_t dev, int port, int reg, u_int32_t value) +{ + struct ata_pci_controller *ctlr; + struct ata_channel *ch; + device_t parent; + u_char *smap; + int offset; + + parent = device_get_parent(dev); + ctlr = device_get_softc(parent); + ch = device_get_softc(dev); + port = (port == 1) ? 1 : 0; + smap = (u_char *)&ctlr->chipset_data + ch->unit * 2; + offset = 0x100 + smap[port] * 0x80; + switch (reg) { + case ATA_SSTATUS: + reg = 0x28; + break; + case ATA_SCONTROL: + reg = 0x2c; + break; + case ATA_SERROR: + reg = 0x30; + break; + default: + return (EINVAL); + } + ATA_OUTL(ctlr->r_res2, offset + reg, value); + return (0); +} + +static int ata_intel_sata_cscr_write(device_t dev, int port, int reg, u_int32_t value) { struct ata_pci_controller *ctlr;