From owner-freebsd-current@FreeBSD.ORG Wed Apr 22 18:49:22 2009 Return-Path: Delivered-To: freebsd-current@FreeBSD.org Received: from [127.0.0.1] (freefall.freebsd.org [IPv6:2001:4f8:fff6::28]) by hub.freebsd.org (Postfix) with ESMTP id 24EC4106568D; Wed, 22 Apr 2009 18:49:22 +0000 (UTC) (envelope-from jkim@FreeBSD.org) From: Jung-uk Kim To: freebsd-current@FreeBSD.org Date: Wed, 22 Apr 2009 14:49:10 -0400 User-Agent: KMail/1.6.2 References: <83e5fb980904220858g4b009527w315425b72c536d3a@mail.gmail.com> In-Reply-To: <83e5fb980904220858g4b009527w315425b72c536d3a@mail.gmail.com> MIME-Version: 1.0 Content-Disposition: inline Content-Type: Multipart/Mixed; boundary="Boundary-00=_oa27J69VBdrMQvQ" Message-Id: <200904221449.12678.jkim@FreeBSD.org> Cc: Ian Freislich , Diego Depaoli Subject: Re: SATA DVD drive no longer works X-BeenThere: freebsd-current@freebsd.org X-Mailman-Version: 2.1.5 Precedence: list List-Id: Discussions about the use of FreeBSD-current List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Wed, 22 Apr 2009 18:49:28 -0000 --Boundary-00=_oa27J69VBdrMQvQ Content-Type: text/plain; charset="utf-8" Content-Transfer-Encoding: 8bit Content-Disposition: inline On Wednesday 22 April 2009 11:58 am, Diego Depaoli wrote: > 2009/4/22 Ian Freislich : > > I have a DVD drive that was in the past detected as: > > > > > > > > It's been a long time since I tried to use it because it's only > > been able to play about 1/10 of my DVD colloction.  It's now > > with a recent (>4 days old CURRENT) not even detected. > > > > My ATA hardware is detected as follows: > > > > atapci1: port > > 0xc480-0xc487,0xc400-0xc403,0xc080-0xc087,0xc000-0xc003,0xbc00-0x > >bc0f mem 0xfe9f6000-0xfe9f7fff irq 22 at device 9.0 on pci0 > > atapci1: [ITHREAD] > > atapci1: AHCI Version 01.10 controller with 4 ports PM supported > > ata2: on atapci1 > > If I 'atacontrol reinit ata2' (where the drive is connected) it > > takes much less time than the other controlers which have nothing > > on them, but it still turns up no hardware: > > > > [brane] /var/db/pkg # time atacontrol reinit ata2 > > Master:      no device present > > Slave:       no device present > > same here with AMD780G chipset. I don't think ATI/AMD SB700 issue is related to the nVidia problem. Please try the attached patch for ATI/AMD south bridge. It is not a complete patch yet but you should be able to use "combined mode" for SB700, I think. ;-) Jung-uk Kim --Boundary-00=_oa27J69VBdrMQvQ Content-Type: text/plain; charset="utf-8"; name="ata-ati.diff" Content-Transfer-Encoding: 7bit Content-Disposition: attachment; filename="ata-ati.diff" --- sys/dev/ata/ata-pci.h 30 Mar 2009 22:18:38 -0000 1.104 +++ sys/dev/ata/ata-pci.h 22 Apr 2009 18:44:04 -0000 @@ -108,6 +108,11 @@ #define ATA_ATI_IXP600_S1 0x43801002 #define ATA_ATI_IXP700 0x439c1002 #define ATA_ATI_IXP700_S1 0x43901002 +#define ATA_ATI_IXP700_S2 0x43911002 +#define ATA_ATI_IXP700_S3 0x43921002 +#define ATA_ATI_IXP700_S4 0x43931002 +#define ATA_ATI_IXP700_S5 0x43941002 +#define ATA_ATI_IXP700_S6 0x43951002 #define ATA_CENATEK_ID 0x16ca #define ATA_CENATEK_ROCKET 0x000116ca @@ -458,6 +463,7 @@ int ata_ahci_ch_detach(device_t dev); int ata_ahci_ch_suspend(device_t dev); int ata_ahci_ch_resume(device_t dev); +int ata_ahci_ctlr_reset(device_t dev); void ata_ahci_reset(device_t dev); int ata_marvell_edma_chipinit(device_t); int ata_sii_chipinit(device_t); --- sys/dev/ata/chipsets/ata-ahci.c 30 Mar 2009 22:18:38 -0000 1.20 +++ sys/dev/ata/chipsets/ata-ahci.c 22 Apr 2009 18:44:04 -0000 @@ -52,7 +52,6 @@ #include /* local prototypes */ -static int ata_ahci_ctlr_reset(device_t dev); static int ata_ahci_suspend(device_t dev); static int ata_ahci_status(device_t dev); static int ata_ahci_begin_transaction(struct ata_request *request); @@ -155,7 +154,7 @@ return 0; } -static int +int ata_ahci_ctlr_reset(device_t dev) { struct ata_pci_controller *ctlr = device_get_softc(dev); --- sys/dev/ata/chipsets/ata-ati.c 9 Oct 2008 12:56:57 -0000 1.1 +++ sys/dev/ata/chipsets/ata-ati.c 22 Apr 2009 18:44:04 -0000 @@ -44,6 +44,7 @@ #include #include #include +#include #include #include #include @@ -54,14 +55,26 @@ /* local prototypes */ static int ata_ati_chipinit(device_t dev); static void ata_ati_setmode(device_t dev, int mode); +static int ata_ati_ahci_chipinit(device_t dev); +static int ata_ati_ahci_resume(device_t dev); +static void ata_ati_ahci_fixup(device_t dev); /* misc defines */ #define ATI_PATA 0x01 #define ATI_SATA 0x02 #define ATI_AHCI 0x04 #define SII_MEMIO 1 +#define ATI_FORCE_AHCI 0x01 +#define ATI_INTx_BUG 0x02 #define SII_BUG 0x04 +#define ATI_SMBUS_DEV 0x4385 +/* Misc Control Register */ +#define ATI_PCI_MISC_CTRL 0x40 +#define ATI_PCI_MISCCTRL_ENABLE_WR 0x00000001 + +/* MSI Control Register */ +#define ATI_PCI_MSI_CTRL 0x50 /* * ATI chipset support functions @@ -81,7 +94,16 @@ { ATA_ATI_IXP600_S1, 0x00, ATI_AHCI, 0, ATA_SA300, "IXP600" }, { ATA_ATI_IXP700, 0x00, ATI_PATA, 0, ATA_UDMA6, "IXP700" }, { ATA_ATI_IXP700_S1, 0x00, ATI_AHCI, 0, ATA_SA300, "IXP700" }, + { ATA_ATI_IXP700_S2, 0x00, ATI_AHCI, 0, ATA_SA300, "IXP700" }, + { ATA_ATI_IXP700_S3, 0x00, ATI_AHCI, 0, ATA_SA300, "IXP700" }, + { ATA_ATI_IXP700_S4, 0x00, ATI_AHCI, 0, ATA_SA300, "IXP700" }, + { ATA_ATI_IXP700_S5, 0x00, ATI_AHCI, 0, ATA_SA300, "IXP700" }, + { ATA_ATI_IXP700_S6, 0x00, ATI_AHCI, 0, ATA_SA300, "IXP700" }, { 0, 0, 0, 0, 0, 0}}; + struct pci_devinfo *dinfo; + pcicfgregs *cfg; + device_t smbdev; + uint8_t revid; if (pci_get_vendor(dev) != ATA_ATI_ID) return ENXIO; @@ -105,7 +127,43 @@ ctlr->chipinit = ata_sii_chipinit; break; case ATI_AHCI: - ctlr->chipinit = ata_ahci_chipinit; + /* Force AHCI mode on SATA controllers if IDE mode is set. */ + if ((ctlr->chip->chipid == ATA_ATI_IXP600_S1 || + ctlr->chip->chipid == ATA_ATI_IXP700_S1) && + pci_get_subclass(dev) == PCIS_STORAGE_IDE) { + ctlr->chip->cfg2 = ATI_FORCE_AHCI; + dinfo = device_get_ivars(dev); + cfg = &dinfo->cfg; + cfg->subclass = PCIS_STORAGE_SATA; + cfg->progif = PCIP_STORAGE_SATA_AHCI_1_0; + if (cfg->msi.msi_location == 0) { + cfg->msi.msi_location = ATI_PCI_MSI_CTRL; + cfg->msi.msi_ctrl = pci_read_config(dev, + ATI_PCI_MSI_CTRL + PCIR_MSI_CTRL, 2) & + ~PCIM_MSICTRL_MME_MASK; + cfg->msi.msi_msgnum = + 1 << ((cfg->msi.msi_ctrl & PCIM_MSICTRL_MMC_MASK) >> 1); + cfg->msi.msi_ctrl |= cfg->msi.msi_msgnum << 4; + } + } + /* + * Some IXP700 revisions require INTx even with MSI. + * XXX Chip revision must be obtained from SMBUS device. + */ + if ((ctlr->chip->chipid == ATA_ATI_IXP700_S1 || + ctlr->chip->chipid == ATA_ATI_IXP700_S2 || + ctlr->chip->chipid == ATA_ATI_IXP700_S3 || + ctlr->chip->chipid == ATA_ATI_IXP700_S4 || + ctlr->chip->chipid == ATA_ATI_IXP700_S5) && + (smbdev = pci_find_device(ATA_ATI_ID, ATI_SMBUS_DEV)) != NULL) { + revid = pci_get_revid(smbdev); + if (revid >= 0x30 && revid < 0x3b) + ctlr->chip->cfg2 |= ATI_INTx_BUG; + } + if (ctlr->chip->cfg2 != 0) + ctlr->chipinit = ata_ati_ahci_chipinit; + else + ctlr->chipinit = ata_ahci_chipinit; break; } return 0; @@ -119,9 +177,8 @@ if (ata_setup_interrupt(dev, ata_generic_intr)) return ENXIO; - /* IXP600 & IXP700 only have 1 PATA channel */ - if ((ctlr->chip->chipid == ATA_ATI_IXP600) || - (ctlr->chip->chipid == ATA_ATI_IXP700)) + /* IXP600 only has 1 PATA channel */ + if (ctlr->chip->chipid == ATA_ATI_IXP600) ctlr->channels = 1; ctlr->setmode = ata_ati_setmode; @@ -192,6 +249,49 @@ } } +static int +ata_ati_ahci_chipinit(device_t dev) +{ + struct ata_pci_controller *ctlr = device_get_softc(dev); + int error; + + ata_ati_ahci_fixup(dev); + error = ata_ahci_chipinit(dev); + if ((ctlr->chip->cfg2 & ATI_FORCE_AHCI) != 0) + ctlr->resume = ata_ati_ahci_resume; + if ((ctlr->chip->cfg2 & ATI_INTx_BUG) != 0) + pci_write_config(dev, PCIR_COMMAND, + pci_read_config(dev, PCIR_COMMAND, 2) & ~PCIM_CMD_INTxDIS, 2); + return (error); +} + +static int +ata_ati_ahci_resume(device_t dev) +{ + + ata_ati_ahci_fixup(dev); + return (ata_ahci_ctlr_reset(dev)); +} + +static void +ata_ati_ahci_fixup(device_t dev) +{ + struct pci_devinfo *dinfo = device_get_ivars(dev); + pcicfgregs *cfg = &dinfo->cfg; + uint32_t ctrl; + + ctrl = pci_read_config(dev, ATI_PCI_MISC_CTRL, 4); + pci_write_config(dev, ATI_PCI_MISC_CTRL, + ctrl | ATI_PCI_MISCCTRL_ENABLE_WR, 4); + pci_write_config(dev, PCIR_SUBCLASS, cfg->subclass, 1); + pci_write_config(dev, PCIR_PROGIF, cfg->progif, 1); + if (cfg->msi.msi_location != 0) + pci_write_config(dev, cfg->msi.msi_location + PCIR_MSI_CTRL, + cfg->msi.msi_ctrl, 2); + pci_write_config(dev, ATI_PCI_MISC_CTRL, + ctrl & ~ATI_PCI_MISCCTRL_ENABLE_WR, 4); +} + ATA_DECLARE_DRIVER(ata_ati); MODULE_DEPEND(ata_ati, ata_ahci, 1, 1, 1); MODULE_DEPEND(ata_ati, ata_sii, 1, 1, 1); --Boundary-00=_oa27J69VBdrMQvQ--