From owner-svn-src-head@FreeBSD.ORG Fri Oct 15 21:39:52 2010 Return-Path: Delivered-To: svn-src-head@freebsd.org Received: from mx1.freebsd.org (mx1.freebsd.org [IPv6:2001:4f8:fff6::34]) by hub.freebsd.org (Postfix) with ESMTP id 0144B106566C; Fri, 15 Oct 2010 21:39:52 +0000 (UTC) (envelope-from jkim@FreeBSD.org) Received: from svn.freebsd.org (svn.freebsd.org [IPv6:2001:4f8:fff6::2c]) by mx1.freebsd.org (Postfix) with ESMTP id E3E048FC18; Fri, 15 Oct 2010 21:39:51 +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 o9FLdpQF079278; Fri, 15 Oct 2010 21:39:51 GMT (envelope-from jkim@svn.freebsd.org) Received: (from jkim@localhost) by svn.freebsd.org (8.14.3/8.14.3/Submit) id o9FLdpCe079276; Fri, 15 Oct 2010 21:39:51 GMT (envelope-from jkim@svn.freebsd.org) Message-Id: <201010152139.o9FLdpCe079276@svn.freebsd.org> From: Jung-uk Kim Date: Fri, 15 Oct 2010 21:39:51 +0000 (UTC) To: src-committers@freebsd.org, svn-src-all@freebsd.org, svn-src-head@freebsd.org X-SVN-Group: head MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Cc: Subject: svn commit: r213905 - head/sys/dev/pci X-BeenThere: svn-src-head@freebsd.org X-Mailman-Version: 2.1.5 Precedence: list List-Id: SVN commit messages for the src tree for head/-current List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Fri, 15 Oct 2010 21:39:52 -0000 Author: jkim Date: Fri Oct 15 21:39:51 2010 New Revision: 213905 URL: http://svn.freebsd.org/changeset/base/213905 Log: Move setting power state for children into a separate function as they were essentially the same. This also restores hw.pci.do_power_resume tunable, which was broken since r211430. Reviewed by: jhb Modified: head/sys/dev/pci/pci.c Modified: head/sys/dev/pci/pci.c ============================================================================== --- head/sys/dev/pci/pci.c Fri Oct 15 20:08:16 2010 (r213904) +++ head/sys/dev/pci/pci.c Fri Oct 15 21:39:51 2010 (r213905) @@ -2903,12 +2903,43 @@ pci_attach(device_t dev) return (bus_generic_attach(dev)); } +static void +pci_set_power_children(device_t dev, device_t *devlist, int numdevs, + int state) +{ + device_t child, pcib; + struct pci_devinfo *dinfo; + int dstate, i; + + if (!pci_do_power_resume) + return; + + /* + * Set the device to the given state. If the firmware suggests + * a different power state, use it instead. If power management + * is not present, the firmware is responsible for managing + * device power. Skip children who aren't attached since they + * are handled separately. Only manage type 0 devices for now. + */ + pcib = device_get_parent(dev); + for (i = 0; i < numdevs; i++) { + child = devlist[i]; + dinfo = device_get_ivars(child); + dstate = state; + if (device_is_attached(child) && + (dinfo->cfg.hdrtype & PCIM_HDRTYPE) == + PCIM_HDRTYPE_NORMAL && + PCIB_POWER_FOR_SLEEP(pcib, dev, &dstate) == 0) + pci_set_powerstate(child, dstate); + } +} + int pci_suspend(device_t dev) { - int dstate, error, i, numdevs; - device_t child, *devlist, pcib; + device_t child, *devlist; struct pci_devinfo *dinfo; + int error, i, numdevs; /* * Save the PCI configuration space for each child and set the @@ -2928,26 +2959,7 @@ pci_suspend(device_t dev) free(devlist, M_TEMP); return (error); } - - /* - * Always set the device to D3. If the firmware suggests a - * different power state, use it instead. If power management - * is not present, the firmware is responsible for managing - * device power. Skip children who aren't attached since they - * are powered down separately. Only manage type 0 devices - * for now. - */ - pcib = device_get_parent(dev); - for (i = 0; pci_do_power_resume && i < numdevs; i++) { - child = devlist[i]; - dinfo = (struct pci_devinfo *) device_get_ivars(child); - dstate = PCI_POWERSTATE_D3; - if (device_is_attached(child) && - (dinfo->cfg.hdrtype & PCIM_HDRTYPE) == - PCIM_HDRTYPE_NORMAL && - PCIB_POWER_FOR_SLEEP(pcib, dev, &dstate) == 0) - pci_set_powerstate(child, dstate); - } + pci_set_power_children(dev, devlist, numdevs, PCI_POWERSTATE_D3); free(devlist, M_TEMP); return (0); } @@ -2955,32 +2967,22 @@ pci_suspend(device_t dev) int pci_resume(device_t dev) { - int i, numdevs, error; - device_t child, *devlist, pcib; + device_t child, *devlist; struct pci_devinfo *dinfo; + int error, i, numdevs; /* * Set each child to D0 and restore its PCI configuration space. */ if ((error = device_get_children(dev, &devlist, &numdevs)) != 0) return (error); - pcib = device_get_parent(dev); + pci_set_power_children(dev, devlist, numdevs, PCI_POWERSTATE_D0); + + /* Now the device is powered up, restore its config space. */ for (i = 0; i < numdevs; i++) { - /* - * Notify power managment we're going to D0 but ignore - * the result. If power management is not present, - * the firmware is responsible for managing device - * power. Only manage type 0 devices for now. - */ child = devlist[i]; - dinfo = (struct pci_devinfo *) device_get_ivars(child); - if (device_is_attached(child) && - (dinfo->cfg.hdrtype & PCIM_HDRTYPE) == - PCIM_HDRTYPE_NORMAL && - PCIB_POWER_FOR_SLEEP(pcib, dev, NULL) == 0) - pci_set_powerstate(child, PCI_POWERSTATE_D0); + dinfo = device_get_ivars(child); - /* Now the device is powered up, restore its config space. */ pci_cfg_restore(child, dinfo); if (!device_is_attached(child)) pci_cfg_save(child, dinfo, 1);