patch for acpi_dock
Nate Lawson
nate at root.org
Thu Jun 22 18:17:21 UTC 2006
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
-------------- next part --------------
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);
More information about the freebsd-acpi
mailing list