From owner-svn-src-stable-8@FreeBSD.ORG Tue Nov 2 09:26:12 2010 Return-Path: Delivered-To: svn-src-stable-8@freebsd.org Received: from mx1.freebsd.org (mx1.freebsd.org [IPv6:2001:4f8:fff6::34]) by hub.freebsd.org (Postfix) with ESMTP id 89082106566B; Tue, 2 Nov 2010 09:26:12 +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 748388FC14; Tue, 2 Nov 2010 09:26:12 +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 oA29QCVJ032819; Tue, 2 Nov 2010 09:26:12 GMT (envelope-from mav@svn.freebsd.org) Received: (from mav@localhost) by svn.freebsd.org (8.14.3/8.14.3/Submit) id oA29QCGh032806; Tue, 2 Nov 2010 09:26:12 GMT (envelope-from mav@svn.freebsd.org) Message-Id: <201011020926.oA29QCGh032806@svn.freebsd.org> From: Alexander Motin Date: Tue, 2 Nov 2010 09:26:12 +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: r214671 - in stable/8/sys: arm/mv dev/ata dev/ata/chipsets X-BeenThere: svn-src-stable-8@freebsd.org X-Mailman-Version: 2.1.5 Precedence: list List-Id: SVN commit messages for only the 8-stable src tree List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Tue, 02 Nov 2010 09:26:12 -0000 Author: mav Date: Tue Nov 2 09:26:12 2010 New Revision: 214671 URL: http://svn.freebsd.org/changeset/base/214671 Log: MFC r214016: Set of legacy mode SATA enchancements: - Implement proper combined mode decoding for Intel controllers to properly identify SATA and PATA channels and associate ATA channels with SATA ports. This fixes wrong reporting and in some cases hard resets to wrong SATA ports. - Improve SATA registers support to handle hot-plug events and potentially interface errors. For ICH5/6300ESB chipsets these registers accessible via PCI config space. For later ones they may be accessible via PCI BAR(5). - For controllers not generating interrupts on hot-plug events, implement periodic status polling. Use it to detect hot-plug on Intel and VIA controllers. Same probably could also be used for Serverworks and SIS. Modified: stable/8/sys/arm/mv/mv_sata.c stable/8/sys/dev/ata/ata-all.c stable/8/sys/dev/ata/ata-all.h stable/8/sys/dev/ata/ata-pci.c stable/8/sys/dev/ata/ata-sata.c stable/8/sys/dev/ata/chipsets/ata-ahci.c stable/8/sys/dev/ata/chipsets/ata-intel.c stable/8/sys/dev/ata/chipsets/ata-marvell.c stable/8/sys/dev/ata/chipsets/ata-nvidia.c stable/8/sys/dev/ata/chipsets/ata-promise.c stable/8/sys/dev/ata/chipsets/ata-siliconimage.c stable/8/sys/dev/ata/chipsets/ata-via.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) stable/8/sys/dev/xen/xenpci/ (props changed) Modified: stable/8/sys/arm/mv/mv_sata.c ============================================================================== --- stable/8/sys/arm/mv/mv_sata.c Tue Nov 2 09:16:41 2010 (r214670) +++ stable/8/sys/arm/mv/mv_sata.c Tue Nov 2 09:26:12 2010 (r214671) @@ -709,7 +709,7 @@ sata_channel_status(device_t dev) if ((icr & SATA_ICR_DEV(ch->unit)) || iecr) { /* Disable EDMA before accessing SATA registers */ sata_edma_ctrl(dev, 0); - ata_sata_phy_check_events(dev); + ata_sata_phy_check_events(dev, -1); /* Ack device and error interrupt */ SATA_OUTL(sc, SATA_ICR, ~SATA_ICR_DEV(ch->unit)); Modified: stable/8/sys/dev/ata/ata-all.c ============================================================================== --- stable/8/sys/dev/ata/ata-all.c Tue Nov 2 09:16:41 2010 (r214670) +++ stable/8/sys/dev/ata/ata-all.c Tue Nov 2 09:26:12 2010 (r214671) @@ -82,6 +82,7 @@ static void bswap(int8_t *, int); static void btrim(int8_t *, int); static void bpack(int8_t *, int8_t *, int); static void ata_interrupt_locked(void *data); +static void ata_periodic_poll(void *data); /* global vars */ MALLOC_DEFINE(M_ATA, "ata_generic", "ATA driver generic layer"); @@ -172,6 +173,7 @@ ata_attach(device_t dev) ch->curr[i] = ch->user[i]; } #endif + callout_init(&ch->poll_callout, 1); /* reset the controller HW, the channel and device(s) */ while (ATA_LOCKING(dev, ATA_LF_LOCK) != ch->unit) @@ -199,6 +201,8 @@ ata_attach(device_t dev) device_printf(dev, "unable to setup interrupt\n"); return error; } + if (ch->flags & ATA_PERIODIC_POLL) + callout_reset(&ch->poll_callout, hz, ata_periodic_poll, ch); #ifndef ATA_CAM /* probe and attach devices on this channel unless we are in early boot */ @@ -245,6 +249,8 @@ err2: err1: bus_release_resource(dev, SYS_RES_IRQ, rid, ch->r_irq); mtx_unlock(&ch->state_mtx); + if (ch->flags & ATA_PERIODIC_POLL) + callout_drain(&ch->poll_callout); return (error); #endif } @@ -266,6 +272,8 @@ ata_detach(device_t dev) mtx_lock(&ch->state_mtx); ch->state |= ATA_STALL_QUEUE; mtx_unlock(&ch->state_mtx); + if (ch->flags & ATA_PERIODIC_POLL) + callout_drain(&ch->poll_callout); #ifndef ATA_CAM /* detach & delete all children */ @@ -453,6 +461,8 @@ ata_suspend(device_t dev) if (!dev || !(ch = device_get_softc(dev))) return ENXIO; + if (ch->flags & ATA_PERIODIC_POLL) + callout_drain(&ch->poll_callout); #ifdef ATA_CAM mtx_lock(&ch->state_mtx); xpt_freeze_simq(ch->sim, 1); @@ -497,6 +507,8 @@ ata_resume(device_t dev) /* kick off requests on the queue */ ata_start(dev); #endif + if (ch->flags & ATA_PERIODIC_POLL) + callout_reset(&ch->poll_callout, hz, ata_periodic_poll, ch); return error; } @@ -563,6 +575,15 @@ ata_interrupt_locked(void *data) #endif } +static void +ata_periodic_poll(void *data) +{ + struct ata_channel *ch = (struct ata_channel *)data; + + callout_reset(&ch->poll_callout, hz, ata_periodic_poll, ch); + ata_interrupt(ch); +} + void ata_print_cable(device_t dev, u_int8_t *who) { Modified: stable/8/sys/dev/ata/ata-all.h ============================================================================== --- stable/8/sys/dev/ata/ata-all.h Tue Nov 2 09:16:41 2010 (r214670) +++ stable/8/sys/dev/ata/ata-all.h Tue Nov 2 09:26:12 2010 (r214671) @@ -114,13 +114,6 @@ #define ATA_SS_IPM_PARTIAL 0x00000200 #define ATA_SS_IPM_SLUMBER 0x00000600 -#define ATA_SS_CONWELL_MASK \ - (ATA_SS_DET_MASK|ATA_SS_SPD_MASK|ATA_SS_IPM_MASK) -#define ATA_SS_CONWELL_GEN1 \ - (ATA_SS_DET_PHY_ONLINE|ATA_SS_SPD_GEN1|ATA_SS_IPM_ACTIVE) -#define ATA_SS_CONWELL_GEN2 \ - (ATA_SS_DET_PHY_ONLINE|ATA_SS_SPD_GEN2|ATA_SS_IPM_ACTIVE) - #define ATA_SERROR 14 #define ATA_SE_DATA_CORRECTED 0x00000001 #define ATA_SE_COMM_CORRECTED 0x00000002 @@ -567,6 +560,7 @@ struct ata_channel { #define ATA_DMA_BEFORE_CMD 0x100 #define ATA_KNOWN_PRESENCE 0x200 #define ATA_STATUS_IS_LONG 0x400 +#define ATA_PERIODIC_POLL 0x800 int pm_level; /* power management level */ int devices; /* what is present */ @@ -593,6 +587,7 @@ struct ata_channel { struct ata_cam_device user[16]; /* User-specified settings */ struct ata_cam_device curr[16]; /* Current settings */ #endif + struct callout poll_callout; /* Periodic status poll. */ }; /* disk bay/enclosure related */ @@ -666,7 +661,7 @@ void ata_dmainit(device_t); void ata_dmafini(device_t dev); /* ata-sata.c: */ -void ata_sata_phy_check_events(device_t dev); +void ata_sata_phy_check_events(device_t dev, int port); int ata_sata_scr_read(struct ata_channel *ch, int port, int reg, uint32_t *val); int ata_sata_scr_write(struct ata_channel *ch, int port, int reg, uint32_t val); int ata_sata_phy_reset(device_t dev, int port, int quick); Modified: stable/8/sys/dev/ata/ata-pci.c ============================================================================== --- stable/8/sys/dev/ata/ata-pci.c Tue Nov 2 09:16:41 2010 (r214670) +++ stable/8/sys/dev/ata/ata-pci.c Tue Nov 2 09:26:12 2010 (r214671) @@ -615,6 +615,7 @@ ata_pcichannel_attach(device_t dev) return (0); ch->attached = 1; + ch->dev = dev; ch->unit = (intptr_t)device_get_ivars(dev); resource_int_value(device_get_name(dev), Modified: stable/8/sys/dev/ata/ata-sata.c ============================================================================== --- stable/8/sys/dev/ata/ata-sata.c Tue Nov 2 09:16:41 2010 (r214670) +++ stable/8/sys/dev/ata/ata-sata.c Tue Nov 2 09:26:12 2010 (r214671) @@ -48,20 +48,23 @@ __FBSDID("$FreeBSD$"); #include void -ata_sata_phy_check_events(device_t dev) +ata_sata_phy_check_events(device_t dev, int port) { struct ata_channel *ch = device_get_softc(dev); - u_int32_t error = ATA_IDX_INL(ch, ATA_SERROR); + u_int32_t error, status; - /* clear error bits/interrupt */ - ATA_IDX_OUTL(ch, ATA_SERROR, error); + ata_sata_scr_read(ch, port, ATA_SERROR, &error); + /* Clear set error bits/interrupt. */ + if (error) + ata_sata_scr_write(ch, port, ATA_SERROR, error); /* if we have a connection event deal with it */ if ((error & ATA_SE_PHY_CHANGED) && (ch->pm_level == 0)) { if (bootverbose) { - u_int32_t status = ATA_IDX_INL(ch, ATA_SSTATUS); - if (((status & ATA_SS_CONWELL_MASK) == ATA_SS_CONWELL_GEN1) || - ((status & ATA_SS_CONWELL_MASK) == ATA_SS_CONWELL_GEN2)) { + ata_sata_scr_read(ch, port, ATA_SSTATUS, &status); + if (((status & ATA_SS_DET_MASK) == ATA_SS_DET_PHY_ONLINE) && + ((status & ATA_SS_SPD_MASK) != ATA_SS_SPD_NO_SPEED) && + ((status & ATA_SS_IPM_MASK) == ATA_SS_IPM_ACTIVE)) { device_printf(dev, "CONNECT requested\n"); } else device_printf(dev, "DISCONNECT requested\n"); @@ -73,69 +76,51 @@ ata_sata_phy_check_events(device_t dev) int ata_sata_scr_read(struct ata_channel *ch, int port, int reg, uint32_t *val) { - int r; - if (port < 0) { + if (ch->hw.pm_read != NULL) + return (ch->hw.pm_read(ch->dev, port, reg, val)); + if (ch->r_io[reg].res) { *val = ATA_IDX_INL(ch, reg); return (0); - } else { - switch (reg) { - case ATA_SSTATUS: - r = 0; - break; - case ATA_SERROR: - r = 1; - break; - case ATA_SCONTROL: - r = 2; - break; - default: - return (EINVAL); - } - return (ch->hw.pm_read(ch->dev, port, r, val)); } + return (-1); } int ata_sata_scr_write(struct ata_channel *ch, int port, int reg, uint32_t val) { - int r; - if (port < 0) { + if (ch->hw.pm_write != NULL) + return (ch->hw.pm_write(ch->dev, port, reg, val)); + if (ch->r_io[reg].res) { ATA_IDX_OUTL(ch, reg, val); return (0); - } else { - switch (reg) { - case ATA_SERROR: - r = 1; - break; - case ATA_SCONTROL: - r = 2; - break; - default: - return (EINVAL); - } - return (ch->hw.pm_write(ch->dev, port, r, val)); } + return (-1); } static int -ata_sata_connect(struct ata_channel *ch, int port) +ata_sata_connect(struct ata_channel *ch, int port, int quick) { u_int32_t status; - int timeout; + int timeout, t; /* wait up to 1 second for "connect well" */ - for (timeout = 0; timeout < 100 ; timeout++) { + timeout = (quick == 2) ? 0 : 100; + t = 0; + while (1) { if (ata_sata_scr_read(ch, port, ATA_SSTATUS, &status)) return (0); - if ((status & ATA_SS_CONWELL_MASK) == ATA_SS_CONWELL_GEN1 || - (status & ATA_SS_CONWELL_MASK) == ATA_SS_CONWELL_GEN2) + if (((status & ATA_SS_DET_MASK) == ATA_SS_DET_PHY_ONLINE) && + ((status & ATA_SS_SPD_MASK) != ATA_SS_SPD_NO_SPEED) && + ((status & ATA_SS_IPM_MASK) == ATA_SS_IPM_ACTIVE)) + break; + if (++t > timeout) break; ata_udelay(10000); } - if (timeout >= 100) { - if (bootverbose) { + if (bootverbose) { + if (t > timeout) { if (port < 0) { device_printf(ch->dev, "SATA connect timeout status=%08x\n", status); @@ -143,23 +128,19 @@ ata_sata_connect(struct ata_channel *ch, device_printf(ch->dev, "p%d: SATA connect timeout status=%08x\n", port, status); } - } - return 0; - } - if (bootverbose) { - if (port < 0) { + } else if (port < 0) { device_printf(ch->dev, "SATA connect time=%dms status=%08x\n", - timeout * 10, status); + t * 10, status); } else { device_printf(ch->dev, "p%d: SATA connect time=%dms status=%08x\n", - port, timeout * 10, status); + port, t * 10, status); } } /* clear SATA error register */ ata_sata_scr_write(ch, port, ATA_SERROR, 0xffffffff); - return 1; + return ((t > timeout) ? 0 : 1); } int @@ -173,7 +154,7 @@ ata_sata_phy_reset(device_t dev, int por if (ata_sata_scr_read(ch, port, ATA_SCONTROL, &val)) return (0); if ((val & ATA_SC_DET_MASK) == ATA_SC_DET_IDLE) - return ata_sata_connect(ch, port); + return ata_sata_connect(ch, port, quick); } if (bootverbose) { @@ -203,7 +184,7 @@ ata_sata_phy_reset(device_t dev, int por if (ata_sata_scr_read(ch, port, ATA_SCONTROL, &val)) return (0); if ((val & ATA_SC_DET_MASK) == 0) - return ata_sata_connect(ch, port); + return ata_sata_connect(ch, port, 0); } } return 0; Modified: stable/8/sys/dev/ata/chipsets/ata-ahci.c ============================================================================== --- stable/8/sys/dev/ata/chipsets/ata-ahci.c Tue Nov 2 09:16:41 2010 (r214670) +++ stable/8/sys/dev/ata/chipsets/ata-ahci.c Tue Nov 2 09:26:12 2010 (r214671) @@ -403,7 +403,7 @@ ata_ahci_status(device_t dev) /* do we have any PHY events ? */ if (istatus & (ATA_AHCI_P_IX_PRC | ATA_AHCI_P_IX_PC)) - ata_sata_phy_check_events(dev); + ata_sata_phy_check_events(dev, -1); /* do we have a potentially hanging engine to take care of? */ /* XXX SOS what todo on NCQ */ @@ -623,6 +623,25 @@ ata_ahci_pm_read(device_t dev, int port, (struct ata_ahci_cmd_tab *)(ch->dma.work + ATA_AHCI_CT_OFFSET); u_int8_t *fis = ch->dma.work + ATA_AHCI_FB_OFFSET + 0x40; + if (port < 0) { + *result = ATA_IDX_INL(ch, reg); + return (0); + } + if (port < ATA_PM) { + switch (reg) { + case ATA_SSTATUS: + reg = 0; + break; + case ATA_SERROR: + reg = 1; + break; + case ATA_SCONTROL: + reg = 2; + break; + default: + return (EINVAL); + } + } bzero(ctp->cfis, 64); ctp->cfis[0] = 0x27; /* host to device */ ctp->cfis[1] = 0x8f; /* command FIS to PM port */ @@ -649,6 +668,25 @@ ata_ahci_pm_write(device_t dev, int port (struct ata_ahci_cmd_tab *)(ch->dma.work + ATA_AHCI_CT_OFFSET); int offset = ch->unit << 7; + if (port < 0) { + ATA_IDX_OUTL(ch, reg, value); + return (0); + } + if (port < ATA_PM) { + switch (reg) { + case ATA_SSTATUS: + reg = 0; + break; + case ATA_SERROR: + reg = 1; + break; + case ATA_SCONTROL: + reg = 2; + break; + default: + return (EINVAL); + } + } bzero(ctp->cfis, 64); ctp->cfis[0] = 0x27; /* host to device */ ctp->cfis[1] = 0x8f; /* command FIS to PM port */ Modified: stable/8/sys/dev/ata/chipsets/ata-intel.c ============================================================================== --- stable/8/sys/dev/ata/chipsets/ata-intel.c Tue Nov 2 09:16:41 2010 (r214670) +++ stable/8/sys/dev/ata/chipsets/ata-intel.c Tue Nov 2 09:26:12 2010 (r214671) @@ -59,6 +59,15 @@ static int ata_intel_old_setmode(device_ static int ata_intel_new_setmode(device_t dev, int target, int mode); 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_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_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, + int reg, u_int32_t result); 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); @@ -67,7 +76,9 @@ static void ata_intel_31244_reset(device /* misc defines */ #define INTEL_AHCI 1 - +#define INTEL_ICH5 2 +#define INTEL_6CH 4 +#define INTEL_6CH2 8 /* * Intel chipset support functions @@ -92,74 +103,74 @@ ata_intel_probe(device_t dev) { ATA_I82801DB, 0, 0, 2, ATA_UDMA5, "ICH4" }, { ATA_I82801DB_1, 0, 0, 2, ATA_UDMA5, "ICH4" }, { ATA_I82801EB, 0, 0, 2, ATA_UDMA5, "ICH5" }, - { ATA_I82801EB_S1, 0, 0, 2, ATA_SA150, "ICH5" }, - { ATA_I82801EB_R1, 0, 0, 2, ATA_SA150, "ICH5" }, + { ATA_I82801EB_S1, 0, INTEL_ICH5, 2, ATA_SA150, "ICH5" }, + { ATA_I82801EB_R1, 0, INTEL_ICH5, 2, ATA_SA150, "ICH5" }, { ATA_I6300ESB, 0, 0, 2, ATA_UDMA5, "6300ESB" }, - { ATA_I6300ESB_S1, 0, 0, 2, ATA_SA150, "6300ESB" }, - { ATA_I6300ESB_R1, 0, 0, 2, ATA_SA150, "6300ESB" }, + { ATA_I6300ESB_S1, 0, INTEL_ICH5, 2, ATA_SA150, "6300ESB" }, + { ATA_I6300ESB_R1, 0, INTEL_ICH5, 2, ATA_SA150, "6300ESB" }, { ATA_I82801FB, 0, 0, 2, ATA_UDMA5, "ICH6" }, { ATA_I82801FB_S1, 0, INTEL_AHCI, 0, ATA_SA150, "ICH6" }, { 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, INTEL_AHCI, 0, ATA_SA300, "ICH7" }, - { ATA_I82801GB_R1, 0, INTEL_AHCI, 0, ATA_SA300, "ICH7" }, + { ATA_I82801GB_S1, 0, 0, 0, ATA_SA300, "ICH7" }, + { ATA_I82801GB_R1, 0, 0, 0, ATA_SA300, "ICH7" }, { ATA_I82801GB_AH, 0, INTEL_AHCI, 0, ATA_SA300, "ICH7" }, - { ATA_I82801GBM_S1, 0, INTEL_AHCI, 0, ATA_SA150, "ICH7M" }, - { ATA_I82801GBM_R1, 0, INTEL_AHCI, 0, ATA_SA150, "ICH7M" }, + { ATA_I82801GBM_S1, 0, 0, 0, ATA_SA150, "ICH7M" }, + { ATA_I82801GBM_R1, 0, 0, 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, INTEL_AHCI, 0, ATA_SA300, "63XXESB2" }, + { ATA_I63XXESB2_S1, 0, 0, 0, ATA_SA300, "63XXESB2" }, { ATA_I63XXESB2_S2, 0, INTEL_AHCI, 0, ATA_SA300, "63XXESB2" }, { ATA_I63XXESB2_R1, 0, INTEL_AHCI, 0, ATA_SA300, "63XXESB2" }, { ATA_I63XXESB2_R2, 0, INTEL_AHCI, 0, ATA_SA300, "63XXESB2" }, - { ATA_I82801HB_S1, 0, INTEL_AHCI, 0, ATA_SA300, "ICH8" }, - { ATA_I82801HB_S2, 0, INTEL_AHCI, 0, ATA_SA300, "ICH8" }, + { ATA_I82801HB_S1, 0, INTEL_6CH, 0, ATA_SA300, "ICH8" }, + { ATA_I82801HB_S2, 0, INTEL_6CH2, 0, ATA_SA300, "ICH8" }, { ATA_I82801HB_R1, 0, INTEL_AHCI, 0, ATA_SA300, "ICH8" }, { ATA_I82801HB_AH4, 0, INTEL_AHCI, 0, ATA_SA300, "ICH8" }, { ATA_I82801HB_AH6, 0, INTEL_AHCI, 0, ATA_SA300, "ICH8" }, { ATA_I82801HBM, 0, 0, 1, ATA_UDMA5, "ICH8M" }, - { ATA_I82801HBM_S1, 0, INTEL_AHCI, 0, ATA_SA300, "ICH8M" }, + { ATA_I82801HBM_S1, 0, INTEL_6CH, 0, ATA_SA300, "ICH8M" }, { ATA_I82801HBM_S2, 0, INTEL_AHCI, 0, ATA_SA300, "ICH8M" }, { ATA_I82801HBM_S3, 0, INTEL_AHCI, 0, ATA_SA300, "ICH8M" }, - { ATA_I82801IB_S1, 0, INTEL_AHCI, 0, ATA_SA300, "ICH9" }, - { ATA_I82801IB_S2, 0, INTEL_AHCI, 0, ATA_SA300, "ICH9" }, + { ATA_I82801IB_S1, 0, INTEL_6CH, 0, ATA_SA300, "ICH9" }, + { ATA_I82801IB_S2, 0, INTEL_6CH2, 0, ATA_SA300, "ICH9" }, { ATA_I82801IB_AH2, 0, INTEL_AHCI, 0, ATA_SA300, "ICH9" }, { ATA_I82801IB_AH4, 0, INTEL_AHCI, 0, ATA_SA300, "ICH9" }, { ATA_I82801IB_AH6, 0, INTEL_AHCI, 0, ATA_SA300, "ICH9" }, { ATA_I82801IB_R1, 0, INTEL_AHCI, 0, ATA_SA300, "ICH9" }, - { ATA_I82801JIB_S1, 0, INTEL_AHCI, 0, ATA_SA300, "ICH10" }, + { ATA_I82801JIB_S1, 0, INTEL_6CH, 0, ATA_SA300, "ICH10" }, { ATA_I82801JIB_AH, 0, INTEL_AHCI, 0, ATA_SA300, "ICH10" }, { ATA_I82801JIB_R1, 0, INTEL_AHCI, 0, ATA_SA300, "ICH10" }, - { ATA_I82801JIB_S2, 0, INTEL_AHCI, 0, ATA_SA300, "ICH10" }, - { ATA_I82801JD_S1, 0, INTEL_AHCI, 0, ATA_SA300, "ICH10" }, + { ATA_I82801JIB_S2, 0, INTEL_6CH2, 0, ATA_SA300, "ICH10" }, + { ATA_I82801JD_S1, 0, INTEL_6CH, 0, ATA_SA300, "ICH10" }, { ATA_I82801JD_AH, 0, INTEL_AHCI, 0, ATA_SA300, "ICH10" }, { ATA_I82801JD_R1, 0, INTEL_AHCI, 0, ATA_SA300, "ICH10" }, - { ATA_I82801JD_S2, 0, INTEL_AHCI, 0, ATA_SA300, "ICH10" }, - { ATA_I82801JI_S1, 0, INTEL_AHCI, 0, ATA_SA300, "ICH10" }, + { ATA_I82801JD_S2, 0, INTEL_6CH2, 0, ATA_SA300, "ICH10" }, + { ATA_I82801JI_S1, 0, INTEL_6CH, 0, ATA_SA300, "ICH10" }, { ATA_I82801JI_AH, 0, INTEL_AHCI, 0, ATA_SA300, "ICH10" }, { ATA_I82801JI_R1, 0, INTEL_AHCI, 0, ATA_SA300, "ICH10" }, - { ATA_I82801JI_S2, 0, INTEL_AHCI, 0, ATA_SA300, "ICH10" }, - { ATA_5Series_S1, 0, INTEL_AHCI, 0, ATA_SA300, "5 Series/3400 Series PCH" }, - { ATA_5Series_S2, 0, INTEL_AHCI, 0, ATA_SA300, "5 Series/3400 Series PCH" }, + { ATA_I82801JI_S2, 0, INTEL_6CH2, 0, ATA_SA300, "ICH10" }, + { ATA_5Series_S1, 0, INTEL_6CH, 0, ATA_SA300, "5 Series/3400 Series PCH" }, + { ATA_5Series_S2, 0, INTEL_6CH2, 0, ATA_SA300, "5 Series/3400 Series PCH" }, { ATA_5Series_AH1, 0, INTEL_AHCI, 0, ATA_SA300, "5 Series/3400 Series PCH" }, { ATA_5Series_AH2, 0, INTEL_AHCI, 0, ATA_SA300, "5 Series/3400 Series PCH" }, { ATA_5Series_R1, 0, INTEL_AHCI, 0, ATA_SA300, "5 Series/3400 Series PCH" }, - { ATA_5Series_S3, 0, INTEL_AHCI, 0, ATA_SA300, "5 Series/3400 Series PCH" }, - { ATA_5Series_S4, 0, INTEL_AHCI, 0, ATA_SA300, "5 Series/3400 Series PCH" }, + { ATA_5Series_S3, 0, INTEL_6CH2, 0, ATA_SA300, "5 Series/3400 Series PCH" }, + { ATA_5Series_S4, 0, INTEL_6CH, 0, ATA_SA300, "5 Series/3400 Series PCH" }, { ATA_5Series_AH3, 0, INTEL_AHCI, 0, ATA_SA300, "5 Series/3400 Series PCH" }, { ATA_5Series_R2, 0, INTEL_AHCI, 0, ATA_SA300, "5 Series/3400 Series PCH" }, - { ATA_5Series_S5, 0, INTEL_AHCI, 0, ATA_SA300, "5 Series/3400 Series PCH" }, - { ATA_5Series_S6, 0, INTEL_AHCI, 0, ATA_SA300, "5 Series/3400 Series PCH" }, + { ATA_5Series_S5, 0, INTEL_6CH2, 0, ATA_SA300, "5 Series/3400 Series PCH" }, + { ATA_5Series_S6, 0, INTEL_6CH, 0, ATA_SA300, "5 Series/3400 Series PCH" }, { ATA_5Series_AH4, 0, INTEL_AHCI, 0, ATA_SA300, "5 Series/3400 Series PCH" }, - { ATA_CPT_S1, 0, INTEL_AHCI, 0, ATA_SA300, "Cougar Point" }, - { ATA_CPT_S2, 0, INTEL_AHCI, 0, ATA_SA300, "Cougar Point" }, + { ATA_CPT_S1, 0, INTEL_6CH, 0, ATA_SA300, "Cougar Point" }, + { ATA_CPT_S2, 0, INTEL_6CH, 0, ATA_SA300, "Cougar Point" }, { ATA_CPT_AH1, 0, INTEL_AHCI, 0, ATA_SA300, "Cougar Point" }, { ATA_CPT_AH2, 0, INTEL_AHCI, 0, ATA_SA300, "Cougar Point" }, { ATA_CPT_R1, 0, INTEL_AHCI, 0, ATA_SA300, "Cougar Point" }, { ATA_CPT_R2, 0, INTEL_AHCI, 0, ATA_SA300, "Cougar Point" }, - { ATA_CPT_S3, 0, INTEL_AHCI, 0, ATA_SA300, "Cougar Point" }, - { ATA_CPT_S4, 0, INTEL_AHCI, 0, ATA_SA300, "Cougar Point" }, + { ATA_CPT_S3, 0, INTEL_6CH2, 0, ATA_SA300, "Cougar Point" }, + { ATA_CPT_S4, 0, INTEL_6CH2, 0, ATA_SA300, "Cougar Point" }, { ATA_I31244, 0, 0, 2, ATA_SA150, "31244" }, { ATA_ISCH, 0, 0, 1, ATA_UDMA5, "SCH" }, { 0, 0, 0, 0, 0, 0}}; @@ -183,6 +194,8 @@ ata_intel_chipinit(device_t dev) if (ata_setup_interrupt(dev, ata_generic_intr)) return ENXIO; + ctlr->chipset_data = NULL; + /* good old PIIX needs special treatment (not implemented) */ if (ctlr->chip->chipid == ATA_I82371FB) { ctlr->setmode = ata_intel_old_setmode; @@ -233,7 +246,7 @@ ata_intel_chipinit(device_t dev) * if we have AHCI capability and AHCI or RAID mode enabled * in BIOS we try for AHCI mode */ - if ((ctlr->chip->cfg1 == INTEL_AHCI) && + if ((ctlr->chip->cfg1 & INTEL_AHCI) && (pci_read_config(dev, 0x90, 1) & 0xc0) && (ata_ahci_chipinit(dev) != ENXIO)) return 0; @@ -242,7 +255,8 @@ ata_intel_chipinit(device_t dev) 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->r_rid2, RF_ACTIVE)) + || (ctlr->chip->cfg1 & INTEL_ICH5)) ctlr->getrev = ata_intel_sata_getrev; ctlr->setmode = ata_sata_setmode; } @@ -252,63 +266,142 @@ ata_intel_chipinit(device_t dev) static int ata_intel_ch_attach(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 */ - if (ata_pci_ch_attach(dev)) - return ENXIO; - - /* if r_res2 is valid it points to SATA interface registers */ - if (ctlr->r_res2) { - ch->r_io[ATA_IDX_ADDR].res = ctlr->r_res2; - ch->r_io[ATA_IDX_ADDR].offset = 0x00; - ch->r_io[ATA_IDX_DATA].res = ctlr->r_res2; - ch->r_io[ATA_IDX_DATA].offset = 0x04; - } + struct ata_pci_controller *ctlr; + struct ata_channel *ch; + u_char *smap; + u_int map; + + /* setup the usual register normal pci style */ + if (ata_pci_ch_attach(dev)) + return (ENXIO); + + ctlr = device_get_softc(device_get_parent(dev)); + ch = device_get_softc(dev); + + /* if r_res2 is valid it points to SATA interface registers */ + if (ctlr->r_res2) { + ch->r_io[ATA_IDX_ADDR].res = ctlr->r_res2; + ch->r_io[ATA_IDX_ADDR].offset = 0x00; + ch->r_io[ATA_IDX_DATA].res = ctlr->r_res2; + ch->r_io[ATA_IDX_DATA].offset = 0x04; + } - 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 if (ctlr->chip->chipid != ATA_ISCH) - ch->flags |= ATA_CHECKS_CABLE; - return 0; + ch->flags |= ATA_ALWAYS_DMASTAT; + if (ctlr->chip->max_dma >= ATA_SA150) { + smap = (u_char *)&ctlr->chipset_data + ch->unit * 2; + map = pci_read_config(device_get_parent(dev), 0x90, 1); + if (ctlr->chip->cfg1 & INTEL_ICH5) { + map &= 0x07; + if ((map & 0x04) == 0) { + ch->flags |= ATA_SATA; + ch->flags |= ATA_NO_SLAVE; + smap[0] = (map & 0x01) ^ ch->unit; + smap[1] = 0; + } else if ((map & 0x02) == 0 && ch->unit == 0) { + ch->flags |= ATA_SATA; + smap[0] = (map & 0x01) ? 1 : 0; + smap[1] = (map & 0x01) ? 0 : 1; + } else if ((map & 0x02) != 0 && ch->unit == 1) { + ch->flags |= ATA_SATA; + smap[0] = (map & 0x01) ? 1 : 0; + smap[1] = (map & 0x01) ? 0 : 1; + } + } else if (ctlr->chip->cfg1 & INTEL_6CH2) { + ch->flags |= ATA_SATA; + ch->flags |= ATA_NO_SLAVE; + smap[0] = (ch->unit == 0) ? 4 : 5; + smap[1] = 0; + } else { + map &= 0x03; + if (map == 0x00) { + ch->flags |= ATA_SATA; + smap[ch->unit] = (ch->unit == 0) ? 0x20 : 0x31; + smap[0] = (ch->unit == 0) ? 0 : 1; + smap[1] = (ch->unit == 0) ? 2 : 3; + } else if (map == 0x02 && ch->unit == 0) { + ch->flags |= ATA_SATA; + smap[0] = 0; + smap[1] = 2; + } else if (map == 0x01 && ch->unit == 1) { + ch->flags |= ATA_SATA; + smap[0] = 1; + smap[1] = 3; + } + } + if (ch->flags & ATA_SATA) { + if ((ctlr->chip->cfg1 & INTEL_ICH5)) { + ch->flags |= ATA_PERIODIC_POLL; + ch->hw.status = ata_intel_sata_status; + ch->hw.pm_read = ata_intel_sata_cscr_read; + ch->hw.pm_write = ata_intel_sata_cscr_write; + } 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 (ch->hw.pm_write != NULL) { + ata_sata_scr_write(ch, 0, + ATA_SERROR, 0xffffffff); + if ((ch->flags & ATA_NO_SLAVE) == 0) { + ata_sata_scr_write(ch, 1, + ATA_SERROR, 0xffffffff); + } + } + } else + ctlr->setmode = ata_intel_new_setmode; + } else if (ctlr->chip->chipid != ATA_ISCH) + ch->flags |= ATA_CHECKS_CABLE; + return (0); } static void ata_intel_reset(device_t 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); - int mask, timeout; + 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 mask, pmask, timeout, devs; + u_char *smap; - /* ICH6 & ICH7 in compat mode has 4 SATA ports as master/slave on 2 ch's */ - if (ctlr->chip->cfg1) { - mask = (0x0005 << ch->unit); - } - else { - /* ICH5 in compat mode has SATA ports as master/slave on 1 channel */ - if (pci_read_config(parent, 0x90, 1) & 0x04) - mask = 0x0003; + /* In combined mode, skip SATA stuff for PATA channel. */ + if ((ch->flags & ATA_SATA) == 0) + return (ata_generic_reset(dev)); + + /* Do hard-reset on respective SATA ports. */ + smap = (u_char *)&ctlr->chipset_data + ch->unit * 2; + mask = 1 << smap[0]; + if ((ch->flags & ATA_NO_SLAVE) == 0) + mask |= (1 << smap[1]); + pci_write_config(parent, 0x92, + pci_read_config(parent, 0x92, 2) & ~mask, 2); + DELAY(10); + pci_write_config(parent, 0x92, + pci_read_config(parent, 0x92, 2) | mask, 2); + + /* Wait up to 1 sec for "connect well". */ + if (ctlr->chip->cfg1 & (INTEL_6CH | INTEL_6CH2)) + pmask = mask << 8; else - mask = (0x0001 << ch->unit); - } - pci_write_config(parent, 0x92, pci_read_config(parent, 0x92, 2) & ~mask, 2); - DELAY(10); - pci_write_config(parent, 0x92, pci_read_config(parent, 0x92, 2) | mask, 2); - - /* wait up to 1 sec for "connect well" */ - for (timeout = 0; timeout < 100 ; timeout++) { - if (((pci_read_config(parent, 0x92, 2) & (mask << 4)) == (mask << 4)) && - (ATA_IDX_INB(ch, ATA_STATUS) != 0xff)) - break; - ata_udelay(10000); - } - ata_generic_reset(dev); + pmask = mask << 4; + for (timeout = 0; timeout < 100 ; timeout++) { + if (((pci_read_config(parent, 0x92, 2) & pmask) == pmask) && + (ATA_IDX_INB(ch, ATA_STATUS) != 0xff)) + break; + ata_udelay(10000); + } + + /* If any device found, do soft-reset. */ + if (ch->hw.pm_read != NULL) { + devs = ata_sata_phy_reset(dev, 0, 2); + if ((ch->flags & ATA_NO_SLAVE) == 0) + devs += ata_sata_phy_reset(dev, 1, 2); + } else + devs = 1; + if (devs) + ata_generic_reset(dev); + else + ch->devices = 0; } static int @@ -339,6 +432,10 @@ ata_intel_new_setmode(device_t dev, int u_int8_t timings[] = { 0x00, 0x00, 0x10, 0x21, 0x23, 0x00, 0x21, 0x23 }; u_int8_t utimings[] = { 0x00, 0x01, 0x02, 0x01, 0x02, 0x01, 0x02 }; + /* In combined mode, skip PATA stuff for SATA channel. */ + if (ch->flags & ATA_SATA) + return (ata_sata_setmode(dev, target, mode)); + mode = min(mode, ctlr->chip->max_dma); if (ata_dma_check_80pin && mode > ATA_UDMA2 && !(reg54 & (0x10 << devno))) { @@ -421,12 +518,145 @@ static int ata_intel_sata_getrev(device_t dev, int target) { struct ata_channel *ch = device_get_softc(dev); - int devno = (ch->unit << 1) + target; + uint32_t status; + + if (ata_sata_scr_read(ch, target, ATA_SSTATUS, &status) == 0) + return ((status & 0x0f0) >> 4); + return (0xff); +} + +static int +ata_intel_sata_status(device_t dev) +{ + struct ata_channel *ch = device_get_softc(dev); + + ata_sata_phy_check_events(dev, 0); + if ((ch->flags & ATA_NO_SLAVE) == 0) + ata_sata_phy_check_events(dev, 1); - /* set ATA_SSTATUS register offset */ - ATA_IDX_OUTL(ch, ATA_IDX_ADDR, devno * 0x100); - /* query SATA STATUS for the speed */ - return ((ATA_IDX_INL(ch, ATA_IDX_DATA) & 0x0f0) >> 4); + return ata_pci_status(dev); +} + +static int +ata_intel_sata_cscr_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; + + parent = device_get_parent(dev); + ctlr = device_get_softc(parent); + ch = device_get_softc(dev); + smap = (u_char *)&ctlr->chipset_data + ch->unit * 2; + port = (port == 1) ? 1 : 0; + switch (reg) { + case ATA_SSTATUS: + reg = 0; + break; + case ATA_SERROR: + reg = 1; + break; + case ATA_SCONTROL: + reg = 2; + break; + default: + return (EINVAL); + } + pci_write_config(parent, 0xa0, + 0x50 + smap[port] * 0x10 + reg * 4, 4); + *result = pci_read_config(parent, 0xa4, 4); + return (0); +} + +static int +ata_intel_sata_sidpr_read(device_t dev, int port, int reg, u_int32_t *result) +{ + struct ata_pci_controller *ctlr; + struct ata_channel *ch; + device_t parent; + + parent = device_get_parent(dev); + ctlr = device_get_softc(parent); + ch = device_get_softc(dev); + port = (port == 1) ? 1 : 0; + switch (reg) { + case ATA_SSTATUS: + reg = 0; + break; + case ATA_SCONTROL: + reg = 1; + break; + case ATA_SERROR: + reg = 2; + break; + default: + return (EINVAL); + } + ATA_IDX_OUTL(ch, ATA_IDX_ADDR, ((ch->unit * 2 + port) << 8) + reg); + *result = ATA_IDX_INL(ch, ATA_IDX_DATA); + 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; + struct ata_channel *ch; + device_t parent; + u_char *smap; + + parent = device_get_parent(dev); + ctlr = device_get_softc(parent); + ch = device_get_softc(dev); + smap = (u_char *)&ctlr->chipset_data + ch->unit * 2; + port = (port == 1) ? 1 : 0; + switch (reg) { + case ATA_SSTATUS: + reg = 0; + break; + case ATA_SERROR: + reg = 1; + break; + case ATA_SCONTROL: + reg = 2; + break; + default: + return (EINVAL); + } + pci_write_config(parent, 0xa0, + 0x50 + smap[port] * 0x10 + reg * 4, 4); + pci_write_config(parent, 0xa4, value, 4); + return (0); +} + +static int +ata_intel_sata_sidpr_write(device_t dev, int port, int reg, u_int32_t value) +{ + struct ata_pci_controller *ctlr; + struct ata_channel *ch; + device_t parent; + + parent = device_get_parent(dev); + ctlr = device_get_softc(parent); + ch = device_get_softc(dev); + port = (port == 1) ? 1 : 0; + switch (reg) { + case ATA_SSTATUS: + reg = 0; + break; + case ATA_SCONTROL: + reg = 1; + break; + case ATA_SERROR: + reg = 2; + break; + default: + return (EINVAL); + } + ATA_IDX_OUTL(ch, ATA_IDX_ADDR, ((ch->unit * 2 + port) << 8) + reg); + ATA_IDX_OUTL(ch, ATA_IDX_DATA, value); + return (0); } static int @@ -492,7 +722,7 @@ static int ata_intel_31244_status(device_t dev) { /* do we have any PHY events ? */ - ata_sata_phy_check_events(dev); + ata_sata_phy_check_events(dev, -1); /* any drive action to take care of ? */ return ata_pci_status(dev); Modified: stable/8/sys/dev/ata/chipsets/ata-marvell.c ============================================================================== --- stable/8/sys/dev/ata/chipsets/ata-marvell.c Tue Nov 2 09:16:41 2010 (r214670) +++ stable/8/sys/dev/ata/chipsets/ata-marvell.c Tue Nov 2 09:26:12 2010 (r214671) @@ -374,7 +374,7 @@ ata_marvell_edma_status(device_t dev) ATA_OUTL(ctlr->r_res1, 0x02008 + ATA_MV_EDMA_BASE(ch), 0x0); /* do we have any PHY events ? */ - ata_sata_phy_check_events(dev); + ata_sata_phy_check_events(dev, -1); } /* do we have any device action ? */ Modified: stable/8/sys/dev/ata/chipsets/ata-nvidia.c ============================================================================== --- stable/8/sys/dev/ata/chipsets/ata-nvidia.c Tue Nov 2 09:16:41 2010 (r214670) +++ stable/8/sys/dev/ata/chipsets/ata-nvidia.c Tue Nov 2 09:26:12 2010 (r214671) @@ -281,7 +281,7 @@ ata_nvidia_status(device_t dev) /* do we have any PHY events ? */ if (istatus & (0x0c << shift)) - ata_sata_phy_check_events(dev); + ata_sata_phy_check_events(dev, -1); /* clear interrupt(s) */ if (ctlr->chip->cfg1 & NVQ) Modified: stable/8/sys/dev/ata/chipsets/ata-promise.c ============================================================================== --- stable/8/sys/dev/ata/chipsets/ata-promise.c Tue Nov 2 09:16:41 2010 (r214670) +++ stable/8/sys/dev/ata/chipsets/ata-promise.c Tue Nov 2 09:26:12 2010 (r214671) @@ -830,6 +830,25 @@ ata_promise_mio_pm_read(device_t dev, in struct ata_channel *ch = device_get_softc(dev); int timeout = 0; + if (port < 0) { + *result = ATA_IDX_INL(ch, reg); + return (0); + } + if (port < ATA_PM) { + switch (reg) { + case ATA_SSTATUS: + reg = 0; + break; + case ATA_SERROR: + reg = 1; + break; + case ATA_SCONTROL: + reg = 2; + break; + default: + return (EINVAL); + } + } /* set portmultiplier port */ ATA_OUTB(ctlr->r_res2, 0x4e8 + (ch->unit << 8), 0x0f); @@ -862,6 +881,25 @@ ata_promise_mio_pm_write(device_t dev, i struct ata_channel *ch = device_get_softc(dev); int timeout = 0; + if (port < 0) { + ATA_IDX_OUTL(ch, reg, value); + return (0); + } + if (port < ATA_PM) { + switch (reg) { + case ATA_SSTATUS: + reg = 0; + break; + case ATA_SERROR: + reg = 1; + break; + case ATA_SCONTROL: + reg = 2; + break; + default: + return (EINVAL); + } + } /* set portmultiplier port */ ATA_OUTB(ctlr->r_res2, 0x4e8 + (ch->unit << 8), 0x0f); Modified: stable/8/sys/dev/ata/chipsets/ata-siliconimage.c ============================================================================== --- stable/8/sys/dev/ata/chipsets/ata-siliconimage.c Tue Nov 2 09:16:41 2010 (r214670) +++ stable/8/sys/dev/ata/chipsets/ata-siliconimage.c Tue Nov 2 09:26:12 2010 (r214671) @@ -354,7 +354,7 @@ ata_sii_status(device_t dev) /* do we have any PHY events ? */ if (ctlr->chip->max_dma >= ATA_SA150 && (ATA_INL(ctlr->r_res2, 0x10 + offset0) & 0x00000010)) - ata_sata_phy_check_events(dev); + ata_sata_phy_check_events(dev, -1); if (ATA_INL(ctlr->r_res2, 0xa0 + offset1) & 0x00000800) return ata_pci_status(dev); @@ -510,7 +510,7 @@ ata_siiprb_status(device_t dev) u_int32_t istatus = ATA_INL(ctlr->r_res2, 0x1008 + offset); /* do we have any PHY events ? */ - ata_sata_phy_check_events(dev); + ata_sata_phy_check_events(dev, -1); /* clear interrupt(s) */ ATA_OUTL(ctlr->r_res2, 0x1008 + offset, istatus); @@ -700,6 +700,25 @@ ata_siiprb_pm_read(device_t dev, int por struct ata_siiprb_command *prb = (struct ata_siiprb_command *)ch->dma.work; int offset = ch->unit * 0x2000; + if (port < 0) { + *result = ATA_IDX_INL(ch, reg); *** DIFF OUTPUT TRUNCATED AT 1000 LINES ***