From owner-freebsd-acpi@FreeBSD.ORG Thu Jun 22 18:17:21 2006 Return-Path: X-Original-To: acpi@freebsd.org Delivered-To: freebsd-acpi@FreeBSD.ORG Received: from mx1.FreeBSD.org (mx1.freebsd.org [216.136.204.125]) by hub.freebsd.org (Postfix) with ESMTP id 19F0D16A512; Thu, 22 Jun 2006 18:17:21 +0000 (UTC) (envelope-from nate@root.org) Received: from pimout6-ext.prodigy.net (pimout6-ext.prodigy.net [207.115.63.78]) by mx1.FreeBSD.org (Postfix) with ESMTP id CABC443D46; Thu, 22 Jun 2006 18:17:13 +0000 (GMT) (envelope-from nate@root.org) X-ORBL: [67.119.74.222] Received: from [10.0.0.53] (adsl-67-119-74-222.dsl.sntc01.pacbell.net [67.119.74.222]) by pimout6-ext.prodigy.net (8.13.6 out.dk/8.13.6) with ESMTP id k5MIHAZr224328; Thu, 22 Jun 2006 14:17:11 -0400 Message-ID: <449ADE35.3090100@root.org> Date: Thu, 22 Jun 2006 11:15:17 -0700 From: Nate Lawson User-Agent: Thunderbird 1.5.0.2 (X11/20060501) MIME-Version: 1.0 To: iwasaki@freebsd.org Content-Type: multipart/mixed; boundary="------------090406070701080503070303" Cc: acpi@freebsd.org Subject: patch for acpi_dock X-BeenThere: freebsd-acpi@freebsd.org X-Mailman-Version: 2.1.5 Precedence: list List-Id: ACPI and power management development List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Thu, 22 Jun 2006 18:17:21 -0000 This is a multi-part message in MIME format. --------------090406070701080503070303 Content-Type: text/plain; charset=ISO-8859-1; format=flowed Content-Transfer-Encoding: 7bit Iwasaki-san, I've done some minor cleanups in acpi_dock, please make sure it still works for you as I realize my docking station (T23) is handled by SMI even though an acpi_dock0 device appears. Attached is a patch that improves it a little also. The main changes are getting rid of the global acpi_dock_status and changing _STA behavior. For the first one, it seems the goal was to prevent duplicate attachment of docking station devices and duplicate notifies. Duplicate attachment should never happen since newbus probe/attach should prevent reprobe after we return 0. Is that not the case for you? For the second one, it seems the locking and ordering on the taskq should be sufficient that even if multiple notifies come in, we will handle them sequentially. Is there something I'm missing here? For _STA behavior, I added a check for the _STA method not being present. I think even for dock devices, if the method is not present, the device is always there as part of the docking station. What do you think? Thanks, -- Nate --------------090406070701080503070303 Content-Type: text/plain; name="dock.diff" Content-Transfer-Encoding: 7bit Content-Disposition: inline; filename="dock.diff" Index: acpi_dock.c =================================================================== RCS file: /home/ncvs/src/sys/dev/acpica/acpi_dock.c,v retrieving revision 1.3 diff -u -r1.3 acpi_dock.c --- acpi_dock.c 22 Jun 2006 06:34:05 -0000 1.3 +++ acpi_dock.c 22 Jun 2006 18:04:40 -0000 @@ -51,9 +51,11 @@ #define ACPI_DOCK_STATUS_UNDOCKED 0 #define ACPI_DOCK_STATUS_DOCKED 1 -/* Prevent the device from being removed or not. */ -#define ACPI_DOCK_UNLOCK 0 -#define ACPI_DOCK_LOCK 1 +#define ACPI_DOCK_UNLOCK 0 /* Allow device to be ejected */ +#define ACPI_DOCK_LOCK 1 /* Prevent dev from being removed */ + +#define ACPI_DOCK_ISOLATE 0 /* Isolate from dock connector */ +#define ACPI_DOCK_CONNECT 1 /* Connect to dock */ struct acpi_dock_softc { int _sta; @@ -64,9 +66,6 @@ struct sysctl_oid *sysctl_tree; }; -/* Global docking status, for avoiding duplicated docking */ -static int acpi_dock_status = ACPI_DOCK_STATUS_UNKNOWN; - ACPI_SERIAL_DECL(dock, "ACPI Docking Station"); /* @@ -116,7 +115,7 @@ /* * When _DCK is called with 0, OSPM will ignore the return value. */ - if (dock == ACPI_DOCK_STATUS_UNDOCKED) + if (dock == ACPI_DOCK_ISOLATE) return (0); /* If _DCK returned 1, the request succeeded. */ @@ -127,7 +126,7 @@ return (-1); } -/* Lock devices while docked. */ +/* Lock devices while docked to prevent surprise removal. */ static void acpi_dock_execute_lck(device_t dev, int lock) { @@ -137,6 +136,7 @@ acpi_SetInteger(h, "_LCK", lock); } +/* Eject a device (i.e., motorized). */ static int acpi_dock_execute_ejx(device_t dev, int eject, int state) { @@ -153,6 +153,7 @@ return (-1); } +/* Find dependent devices. When their parent is removed, so are they. */ static int acpi_dock_is_ejd_device(ACPI_HANDLE dock_handle, ACPI_HANDLE handle) { @@ -267,17 +268,17 @@ sc = device_get_softc(dev); h = acpi_get_handle(dev); - if (acpi_dock_status == ACPI_DOCK_STATUS_UNDOCKED || - acpi_dock_status == ACPI_DOCK_STATUS_UNKNOWN) { + if (sc->status == ACPI_DOCK_STATUS_UNDOCKED || + sc->status == ACPI_DOCK_STATUS_UNKNOWN) { acpi_dock_execute_lck(dev, ACPI_DOCK_LOCK); - if (acpi_dock_execute_dck(dev, 1) != 0) { + if (acpi_dock_execute_dck(dev, ACPI_DOCK_CONNECT) != 0) { device_printf(dev, "_DCK failed\n"); return; } if (!cold) acpi_dock_insert_children(dev); - sc->status = acpi_dock_status = ACPI_DOCK_STATUS_DOCKED; + sc->status = ACPI_DOCK_STATUS_DOCKED; } } @@ -334,10 +335,10 @@ ACPI_SERIAL_ASSERT(dock); sc = device_get_softc(dev); - if (acpi_dock_status == ACPI_DOCK_STATUS_DOCKED || - acpi_dock_status == ACPI_DOCK_STATUS_UNKNOWN) { + if (sc->status == ACPI_DOCK_STATUS_DOCKED || + sc->status == ACPI_DOCK_STATUS_UNKNOWN) { acpi_dock_eject_children(dev); - if (acpi_dock_execute_dck(dev, 0) != 0) + if (acpi_dock_execute_dck(dev, ACPI_DOCK_ISOLATE) != 0) return; acpi_dock_execute_lck(dev, ACPI_DOCK_UNLOCK); @@ -347,7 +348,7 @@ return; } - sc->status = acpi_dock_status = ACPI_DOCK_STATUS_UNDOCKED; + sc->status = ACPI_DOCK_STATUS_UNDOCKED; } acpi_dock_get_info(dev); @@ -370,12 +371,14 @@ acpi_dock_get_info(dev); /* - * If the _STA indicates 'present' and 'functioning', - * the system is docked. + * If the _STA method indicates 'present' and 'functioning', the + * system is docked. If _STA does not exist for this device, it + * is always present. */ - if (ACPI_DEVICE_PRESENT(sc->_sta)) + if (sc->_sta == ACPI_DOCK_STATUS_UNKNOWN || + ACPI_DEVICE_PRESENT(sc->_sta)) acpi_dock_insert(dev); - if (sc->_sta == 0) + else if (sc->_sta == 0) acpi_dock_removal(dev); } @@ -413,22 +416,23 @@ { struct acpi_dock_softc *sc; device_t dev; - int status, err; + int status, err; err = 0; - dev = (device_t)arg1; + dev = (device_t)arg1; + sc = device_get_softc(dev); - status = sc->status; + status = sc->status; ACPI_SERIAL_BEGIN(dock); - err = sysctl_handle_int(oidp, &status, 0, req); - if (err != 0 || req->newptr == NULL) - goto out; + err = sysctl_handle_int(oidp, &status, 0, req); + if (err != 0 || req->newptr == NULL) + goto out; if (status != ACPI_DOCK_STATUS_UNDOCKED && status != ACPI_DOCK_STATUS_DOCKED) { err = EINVAL; - goto out; + goto out; } if (status == sc->status) @@ -460,9 +464,6 @@ ACPI_FAILURE(AcpiGetHandle(h, "_DCK", &tmp))) return (ENXIO); - if (acpi_dock_status == ACPI_DOCK_STATUS_DOCKED) - return (ENXIO); - device_set_desc(dev, "ACPI Docking Station"); /* @@ -479,14 +480,8 @@ ACPI_HANDLE h; sc = device_get_softc(dev); - if (sc == NULL) - return (ENXIO); - h = acpi_get_handle(dev); - if (h == NULL) - return (ENXIO); - - if (acpi_dock_status == ACPI_DOCK_STATUS_DOCKED) + if (sc == NULL || h == NULL) return (ENXIO); sc->status = ACPI_DOCK_STATUS_UNKNOWN; @@ -497,7 +492,7 @@ acpi_dock_device_check(dev); - /* Get the sysctl tree */ + /* Get the sysctl tree */ sc->sysctl_ctx = device_get_sysctl_ctx(dev); sc->sysctl_tree = device_get_sysctl_tree(dev); --------------090406070701080503070303--