Date: Tue, 08 Apr 2008 00:39:21 +0900 From: Takanori Watanabe <takawata@init-main.com> To: sos@freebsd.org, freebsd-acpi@freebsd.org Subject: some problems in suspend/resume on ThinkPad X61 Message-ID: <200804071539.m37FdLcT026089@sana.init-main.com>
next in thread | raw e-mail | index | archive | help
I bought a new laptop;ThinkPad X61 and I'm trying to hack suspend/resume. As the first step, I'm trying to make sure to suspend/resume work in uniprocessor kernel. Finally I did succeeded to suspend and resume with 1) fwohci disabled 2) if_em down 3) hw.acpi.reset_video=1 4) modify ata driver with following crude patch. (Not generic solution.) So I want ata_pci_controller->chipinit and ata_pci_controller->allocate should split into two parts:Hardware initialization and data structure initialization. --- ata-chipset.c.~1.212.~ 2008-03-07 09:29:19.000000000 +0000 +++ ata-chipset.c 2008-04-08 00:23:34.000000000 +0000 @@ -540,7 +540,37 @@ (ATA_INL(ctlr->r_res2, ATA_AHCI_CAP) & ATA_AHCI_NPMASK) + 1); return 0; } +void ata_ahci_tell_dma(device_t dev); +void ata_ahci_tell_dma(device_t dev) +{ + struct ata_pci_controller *ctlr; + struct ata_channel *ch = device_get_softc(dev); + u_int64_t work; + int offset = ch->unit << 7; + + ctlr = device_get_softc(device_get_parent(dev)); + /* setup work areas */ + work = ch->dma->work_bus + ATA_AHCI_CL_OFFSET; + ATA_OUTL(ctlr->r_res2, ATA_AHCI_P_CLB + offset, work & 0xffffffff); + ATA_OUTL(ctlr->r_res2, ATA_AHCI_P_CLBU + offset, work >> 32); + + work = ch->dma->work_bus + ATA_AHCI_FB_OFFSET; + ATA_OUTL(ctlr->r_res2, ATA_AHCI_P_FB + offset, work & 0xffffffff); + ATA_OUTL(ctlr->r_res2, ATA_AHCI_P_FBU + offset, work >> 32); + /* enable wanted port interrupts */ + ATA_OUTL(ctlr->r_res2, ATA_AHCI_P_IE + offset, + (ATA_AHCI_P_IX_CPD | ATA_AHCI_P_IX_TFE | ATA_AHCI_P_IX_HBF | + ATA_AHCI_P_IX_HBD | ATA_AHCI_P_IX_IF | ATA_AHCI_P_IX_OF | + ATA_AHCI_P_IX_PRC | ATA_AHCI_P_IX_PC | ATA_AHCI_P_IX_DP | + ATA_AHCI_P_IX_UF | ATA_AHCI_P_IX_SDB | ATA_AHCI_P_IX_DS | + ATA_AHCI_P_IX_PS | ATA_AHCI_P_IX_DHR)); + + /* start operations on this channel */ + ATA_OUTL(ctlr->r_res2, ATA_AHCI_P_CMD + offset, + (ATA_AHCI_P_CMD_ACTIVE | ATA_AHCI_P_CMD_FRE | + ATA_AHCI_P_CMD_POD | ATA_AHCI_P_CMD_SUD | ATA_AHCI_P_CMD_ST)); +} static int ata_ahci_allocate(device_t dev) { --- ata-pci.c.~1.123.~ 2007-11-18 14:44:52.000000000 +0000 +++ ata-pci.c 2008-04-07 23:25:04.000000000 +0000 @@ -48,6 +48,7 @@ #include <dev/ata/ata-all.h> #include <dev/ata/ata-pci.h> #include <ata_if.h> +extern void ata_ahci_tell_dma(device_t dev); /* local vars */ static MALLOC_DEFINE(M_ATAPCI, "ata_pci", "ATA driver PCI"); @@ -186,6 +187,18 @@ return ENXIO; } +static int ata_pci_resume(device_t dev) +{ + struct ata_pci_controller *ctlr = device_get_softc(dev); + int chans = ctlr->channels; + ctlr->chipinit(dev); + + if(chans != ctlr->channels){ + device_printf(dev, "WARNING: channel number changed\n"); + } + + return bus_generic_resume(dev); +} int ata_pci_attach(device_t dev) { @@ -546,7 +559,7 @@ DEVMETHOD(device_detach, ata_pci_detach), DEVMETHOD(device_shutdown, bus_generic_shutdown), DEVMETHOD(device_suspend, bus_generic_suspend), - DEVMETHOD(device_resume, bus_generic_resume), + DEVMETHOD(device_resume, ata_pci_resume), /* bus methods */ DEVMETHOD(bus_alloc_resource, ata_pci_alloc_resource), @@ -678,6 +691,15 @@ ctlr->setmode(dev, mode); } +static int ata_pcichannel_resume(device_t dev) +{ + struct ata_channel *ch = device_get_softc(dev); + struct ata_pci_controller *ctlr = device_get_softc(device_get_parent(dev)); + if(ch->dma&&ctlr->r_res2) + ata_ahci_tell_dma(dev); + + return ata_resume(dev); +} static device_method_t ata_pcichannel_methods[] = { /* device interface */ DEVMETHOD(device_probe, ata_pcichannel_probe), @@ -685,7 +707,7 @@ DEVMETHOD(device_detach, ata_pcichannel_detach), DEVMETHOD(device_shutdown, bus_generic_shutdown), DEVMETHOD(device_suspend, ata_suspend), - DEVMETHOD(device_resume, ata_resume), + DEVMETHOD(device_resume, ata_pcichannel_resume), /* ATA methods */ DEVMETHOD(ata_setmode, ata_pcichannel_setmode),
Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?200804071539.m37FdLcT026089>