Merge from vendor branch OPENSSH:
[dragonfly.git] / sys / dev / acpica5 / acpi_ec.c
1 /*-
2  * Copyright (c) 2003 Nate Lawson
3  * Copyright (c) 2000 Michael Smith
4  * Copyright (c) 2000 BSDi
5  * All rights reserved.
6  *
7  * Redistribution and use in source and binary forms, with or without
8  * modification, are permitted provided that the following conditions
9  * are met:
10  * 1. Redistributions of source code must retain the above copyright
11  *    notice, this list of conditions and the following disclaimer.
12  * 2. Redistributions in binary form must reproduce the above copyright
13  *    notice, this list of conditions and the following disclaimer in the
14  *    documentation and/or other materials provided with the distribution.
15  *
16  * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
17  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
18  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
19  * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
20  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
21  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
22  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
23  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
24  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
25  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
26  * SUCH DAMAGE.
27  *
28  * $FreeBSD: src/sys/dev/acpica/acpi_ec.c,v 1.51 2004/05/30 20:08:23 phk Exp $
29  * $DragonFly: src/sys/dev/acpica5/acpi_ec.c,v 1.9 2006/10/25 20:55:52 dillon Exp $
30  */
31 /******************************************************************************
32  *
33  * 1. Copyright Notice
34  *
35  * Some or all of this work - Copyright (c) 1999, Intel Corp.  All rights
36  * reserved.
37  *
38  * 2. License
39  *
40  * 2.1. This is your license from Intel Corp. under its intellectual property
41  * rights.  You may have additional license terms from the party that provided
42  * you this software, covering your right to use that party's intellectual
43  * property rights.
44  *
45  * 2.2. Intel grants, free of charge, to any person ("Licensee") obtaining a
46  * copy of the source code appearing in this file ("Covered Code") an
47  * irrevocable, perpetual, worldwide license under Intel's copyrights in the
48  * base code distributed originally by Intel ("Original Intel Code") to copy,
49  * make derivatives, distribute, use and display any portion of the Covered
50  * Code in any form, with the right to sublicense such rights; and
51  *
52  * 2.3. Intel grants Licensee a non-exclusive and non-transferable patent
53  * license (with the right to sublicense), under only those claims of Intel
54  * patents that are infringed by the Original Intel Code, to make, use, sell,
55  * offer to sell, and import the Covered Code and derivative works thereof
56  * solely to the minimum extent necessary to exercise the above copyright
57  * license, and in no event shall the patent license extend to any additions
58  * to or modifications of the Original Intel Code.  No other license or right
59  * is granted directly or by implication, estoppel or otherwise;
60  *
61  * The above copyright and patent license is granted only if the following
62  * conditions are met:
63  *
64  * 3. Conditions 
65  *
66  * 3.1. Redistribution of Source with Rights to Further Distribute Source.  
67  * Redistribution of source code of any substantial portion of the Covered
68  * Code or modification with rights to further distribute source must include
69  * the above Copyright Notice, the above License, this list of Conditions,
70  * and the following Disclaimer and Export Compliance provision.  In addition,
71  * Licensee must cause all Covered Code to which Licensee contributes to
72  * contain a file documenting the changes Licensee made to create that Covered
73  * Code and the date of any change.  Licensee must include in that file the
74  * documentation of any changes made by any predecessor Licensee.  Licensee 
75  * must include a prominent statement that the modification is derived,
76  * directly or indirectly, from Original Intel Code.
77  *
78  * 3.2. Redistribution of Source with no Rights to Further Distribute Source.  
79  * Redistribution of source code of any substantial portion of the Covered
80  * Code or modification without rights to further distribute source must
81  * include the following Disclaimer and Export Compliance provision in the
82  * documentation and/or other materials provided with distribution.  In
83  * addition, Licensee may not authorize further sublicense of source of any
84  * portion of the Covered Code, and must include terms to the effect that the
85  * license from Licensee to its licensee is limited to the intellectual
86  * property embodied in the software Licensee provides to its licensee, and
87  * not to intellectual property embodied in modifications its licensee may
88  * make.
89  *
90  * 3.3. Redistribution of Executable. Redistribution in executable form of any
91  * substantial portion of the Covered Code or modification must reproduce the
92  * above Copyright Notice, and the following Disclaimer and Export Compliance
93  * provision in the documentation and/or other materials provided with the
94  * distribution.
95  *
96  * 3.4. Intel retains all right, title, and interest in and to the Original
97  * Intel Code.
98  *
99  * 3.5. Neither the name Intel nor any other trademark owned or controlled by
100  * Intel shall be used in advertising or otherwise to promote the sale, use or
101  * other dealings in products derived from or relating to the Covered Code
102  * without prior written authorization from Intel.
103  *
104  * 4. Disclaimer and Export Compliance
105  *
106  * 4.1. INTEL MAKES NO WARRANTY OF ANY KIND REGARDING ANY SOFTWARE PROVIDED
107  * HERE.  ANY SOFTWARE ORIGINATING FROM INTEL OR DERIVED FROM INTEL SOFTWARE
108  * IS PROVIDED "AS IS," AND INTEL WILL NOT PROVIDE ANY SUPPORT,  ASSISTANCE,
109  * INSTALLATION, TRAINING OR OTHER SERVICES.  INTEL WILL NOT PROVIDE ANY
110  * UPDATES, ENHANCEMENTS OR EXTENSIONS.  INTEL SPECIFICALLY DISCLAIMS ANY
111  * IMPLIED WARRANTIES OF MERCHANTABILITY, NONINFRINGEMENT AND FITNESS FOR A
112  * PARTICULAR PURPOSE. 
113  *
114  * 4.2. IN NO EVENT SHALL INTEL HAVE ANY LIABILITY TO LICENSEE, ITS LICENSEES
115  * OR ANY OTHER THIRD PARTY, FOR ANY LOST PROFITS, LOST DATA, LOSS OF USE OR
116  * COSTS OF PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES, OR FOR ANY INDIRECT,
117  * SPECIAL OR CONSEQUENTIAL DAMAGES ARISING OUT OF THIS AGREEMENT, UNDER ANY
118  * CAUSE OF ACTION OR THEORY OF LIABILITY, AND IRRESPECTIVE OF WHETHER INTEL
119  * HAS ADVANCE NOTICE OF THE POSSIBILITY OF SUCH DAMAGES.  THESE LIMITATIONS
120  * SHALL APPLY NOTWITHSTANDING THE FAILURE OF THE ESSENTIAL PURPOSE OF ANY
121  * LIMITED REMEDY.
122  *
123  * 4.3. Licensee shall not export, either directly or indirectly, any of this
124  * software or system incorporating such software without first obtaining any
125  * required license or other approval from the U. S. Department of Commerce or
126  * any other agency or department of the United States Government.  In the
127  * event Licensee exports any such software from the United States or
128  * re-exports any such software from a foreign destination, Licensee shall
129  * ensure that the distribution and export/re-export of the software is in
130  * compliance with all laws, regulations, orders, or other restrictions of the
131  * U.S. Export Administration Regulations. Licensee agrees that neither it nor
132  * any of its subsidiaries will export/re-export any technical data, process,
133  * software, or service, directly or indirectly, to any country for which the
134  * United States government or any agency thereof requires an export license,
135  * other governmental approval, or letter of assurance, without first obtaining
136  * such license, approval or letter.
137  *
138  *****************************************************************************/
139  /*
140   * $FreeBSD: src/sys/dev/acpica/acpi_ec.c,v 1.51 2004/05/30 20:08:23 phk Exp $
141   * $DragonFly: src/sys/dev/acpica5/acpi_ec.c,v 1.9 2006/10/25 20:55:52 dillon Exp $
142   *
143   */
144
145 #include "opt_acpi.h"
146 #include <sys/param.h>
147 #include <sys/kernel.h>
148 #include <sys/bus.h>
149 #include <sys/thread.h>
150 #include <sys/malloc.h>
151 #include <sys/module.h>
152 #include <sys/lock.h>
153 #include <sys/rman.h>
154
155 #include "acpi.h"
156 #include <dev/acpica5/acpivar.h>
157
158 /*
159  * Hooks for the ACPI CA debugging infrastructure
160  */
161 #define _COMPONENT      ACPI_EC
162 ACPI_MODULE_NAME("EC")
163
164 /*
165  * EC_COMMAND:
166  * -----------
167  */
168 typedef UINT8                           EC_COMMAND;
169
170 #define EC_COMMAND_UNKNOWN              ((EC_COMMAND) 0x00)
171 #define EC_COMMAND_READ                 ((EC_COMMAND) 0x80)
172 #define EC_COMMAND_WRITE                ((EC_COMMAND) 0x81)
173 #define EC_COMMAND_BURST_ENABLE         ((EC_COMMAND) 0x82)
174 #define EC_COMMAND_BURST_DISABLE        ((EC_COMMAND) 0x83)
175 #define EC_COMMAND_QUERY                ((EC_COMMAND) 0x84)
176
177 /* 
178  * EC_STATUS:
179  * ----------
180  * The encoding of the EC status register is illustrated below.
181  * Note that a set bit (1) indicates the property is TRUE
182  * (e.g. if bit 0 is set then the output buffer is full).
183  * +-+-+-+-+-+-+-+-+
184  * |7|6|5|4|3|2|1|0|    
185  * +-+-+-+-+-+-+-+-+
186  *  | | | | | | | |
187  *  | | | | | | | +- Output Buffer Full?
188  *  | | | | | | +--- Input Buffer Full?
189  *  | | | | | +----- <reserved>
190  *  | | | | +------- Data Register is Command Byte?
191  *  | | | +--------- Burst Mode Enabled?
192  *  | | +----------- SCI Event?
193  *  | +------------- SMI Event?
194  *  +--------------- <Reserved>
195  *
196  */
197 typedef UINT8                           EC_STATUS;
198
199 #define EC_FLAG_OUTPUT_BUFFER           ((EC_STATUS) 0x01)
200 #define EC_FLAG_INPUT_BUFFER            ((EC_STATUS) 0x02)
201 #define EC_FLAG_BURST_MODE              ((EC_STATUS) 0x10)
202 #define EC_FLAG_SCI                     ((EC_STATUS) 0x20)
203
204 /*
205  * EC_EVENT:
206  * ---------
207  */
208 typedef UINT8                           EC_EVENT;
209
210 #define EC_EVENT_UNKNOWN                ((EC_EVENT) 0x00)
211 #define EC_EVENT_OUTPUT_BUFFER_FULL     ((EC_EVENT) 0x01)
212 #define EC_EVENT_INPUT_BUFFER_EMPTY     ((EC_EVENT) 0x02)
213 #define EC_EVENT_SCI                    ((EC_EVENT) 0x20)
214
215 /*
216  * Register access primitives
217  */
218 #define EC_GET_DATA(sc)                                                 \
219         bus_space_read_1((sc)->ec_data_tag, (sc)->ec_data_handle, 0)
220
221 #define EC_SET_DATA(sc, v)                                              \
222         bus_space_write_1((sc)->ec_data_tag, (sc)->ec_data_handle, 0, (v))
223
224 #define EC_GET_CSR(sc)                                                  \
225         bus_space_read_1((sc)->ec_csr_tag, (sc)->ec_csr_handle, 0)
226
227 #define EC_SET_CSR(sc, v)                                               \
228         bus_space_write_1((sc)->ec_csr_tag, (sc)->ec_csr_handle, 0, (v))
229
230 /* Embedded Controller Boot Resources Table (ECDT) */
231 typedef struct {
232     ACPI_TABLE_HEADER           header;
233     ACPI_GENERIC_ADDRESS        control;
234     ACPI_GENERIC_ADDRESS        data;
235     UINT32                      uid;
236     UINT8                       gpe_bit;
237     char                        ec_id[0];
238 } ACPI_TABLE_ECDT;
239
240 /* Additional params to pass from the probe routine */
241 struct acpi_ec_params {
242     int         glk;
243     int         gpe_bit;
244     ACPI_HANDLE gpe_handle;
245     int         uid;
246 };
247
248 /* Indicate that this device has already been probed via ECDT. */
249 #define DEV_ECDT(x)             (acpi_get_magic(x) == (int)&acpi_ec_devclass)
250
251 /*
252  * Driver softc.
253  */
254 struct acpi_ec_softc {
255     device_t            ec_dev;
256     ACPI_HANDLE         ec_handle;
257     int                 ec_uid;
258     ACPI_HANDLE         ec_gpehandle;
259     UINT8               ec_gpebit;
260     UINT8               ec_csrvalue;
261     
262     int                 ec_data_rid;
263     struct resource     *ec_data_res;
264     bus_space_tag_t     ec_data_tag;
265     bus_space_handle_t  ec_data_handle;
266
267     int                 ec_csr_rid;
268     struct resource     *ec_csr_res;
269     bus_space_tag_t     ec_csr_tag;
270     bus_space_handle_t  ec_csr_handle;
271
272     int                 ec_glk;
273     int                 ec_glkhandle;
274     struct lock         ec_lock;
275 };
276
277 /*
278  * XXX
279  * I couldn't find it in the spec but other implementations also use a
280  * value of 1 ms for the time to acquire global lock.
281  */
282 #define EC_LOCK_TIMEOUT 1000
283
284 /* Default interval in microseconds for the status polling loop. */
285 #define EC_POLL_DELAY   10
286
287 /* Total time in ms spent in the poll loop waiting for a response. */
288 #define EC_POLL_TIMEOUT 100
289
290 #define EVENT_READY(event, status)                      \
291         (((event) == EC_EVENT_OUTPUT_BUFFER_FULL &&     \
292          ((status) & EC_FLAG_OUTPUT_BUFFER) != 0) ||    \
293          ((event) == EC_EVENT_INPUT_BUFFER_EMPTY &&     \
294          ((status) & EC_FLAG_INPUT_BUFFER) == 0))
295
296 static int      ec_poll_timeout = EC_POLL_TIMEOUT;
297 TUNABLE_INT("hw.acpi.ec.poll_timeout", &ec_poll_timeout);
298
299 static __inline ACPI_STATUS
300 EcLock(struct acpi_ec_softc *sc)
301 {
302     ACPI_STATUS status = AE_OK;
303
304     /* Always acquire this EC's mutex. */
305     lockmgr(&sc->ec_lock, LK_EXCLUSIVE|LK_RETRY);
306
307     /* If _GLK is non-zero, also acquire the global lock. */
308     if (sc->ec_glk) {
309         status = AcpiAcquireGlobalLock(EC_LOCK_TIMEOUT, &sc->ec_glkhandle);
310         if (ACPI_FAILURE(status))
311             lockmgr(&sc->ec_lock, LK_RELEASE);
312     }
313
314     return (status);
315 }
316
317 static __inline void
318 EcUnlock(struct acpi_ec_softc *sc)
319 {
320     if (sc->ec_glk)
321         AcpiReleaseGlobalLock(sc->ec_glkhandle);
322     lockmgr(&sc->ec_lock, LK_RELEASE);
323 }
324
325 static uint32_t         EcGpeHandler(void *Context);
326 static ACPI_STATUS      EcSpaceSetup(ACPI_HANDLE Region, UINT32 Function, 
327                                 void *Context, void **return_Context);
328 static ACPI_STATUS      EcSpaceHandler(UINT32 Function,
329                                 ACPI_PHYSICAL_ADDRESS Address,
330                                 UINT32 width, ACPI_INTEGER *Value,
331                                 void *Context, void *RegionContext);
332 static ACPI_STATUS      EcWaitEvent(struct acpi_ec_softc *sc, EC_EVENT Event);
333 static ACPI_STATUS      EcCommand(struct acpi_ec_softc *sc, EC_COMMAND cmd);
334 static ACPI_STATUS      EcRead(struct acpi_ec_softc *sc, UINT8 Address,
335                                 UINT8 *Data);
336 static ACPI_STATUS      EcWrite(struct acpi_ec_softc *sc, UINT8 Address,
337                                 UINT8 *Data);
338 static int              acpi_ec_probe(device_t dev);
339 static int              acpi_ec_attach(device_t dev);
340
341 static device_method_t acpi_ec_methods[] = {
342     /* Device interface */
343     DEVMETHOD(device_probe,     acpi_ec_probe),
344     DEVMETHOD(device_attach,    acpi_ec_attach),
345
346     {0, 0}
347 };
348
349 static driver_t acpi_ec_driver = {
350     "acpi_ec",
351     acpi_ec_methods,
352     sizeof(struct acpi_ec_softc),
353 };
354
355 static devclass_t acpi_ec_devclass;
356 DRIVER_MODULE(acpi_ec, acpi, acpi_ec_driver, acpi_ec_devclass, 0, 0);
357 MODULE_DEPEND(acpi_ec, acpi, 1, 1, 1);
358
359 /*
360  * Look for an ECDT and if we find one, set up default GPE and 
361  * space handlers to catch attempts to access EC space before
362  * we have a real driver instance in place.
363  * TODO: if people report invalid ECDTs, add a tunable to disable them.
364  */
365 void
366 acpi_ec_ecdt_probe(device_t parent)
367 {
368     ACPI_TABLE_ECDT *ecdt;
369     ACPI_STATUS      status;
370     device_t         child;
371     ACPI_HANDLE      h;
372     struct acpi_ec_params *params;
373
374     ACPI_FUNCTION_TRACE((char *)(uintptr_t)__func__);
375
376     /* Find and validate the ECDT. */
377     status = AcpiGetFirmwareTable("ECDT", 1, ACPI_LOGICAL_ADDRESSING, 
378                 (ACPI_TABLE_HEADER **)&ecdt);
379     if (ACPI_FAILURE(status) ||
380         ecdt->control.RegisterBitWidth != 8 ||
381         ecdt->data.RegisterBitWidth != 8) {
382         return;
383     }
384
385     /* Create the child device with the given unit number. */
386     child = BUS_ADD_CHILD(parent, parent, 0, "acpi_ec", ecdt->uid);
387     if (child == NULL) {
388         printf("%s: can't add child\n", __func__);
389         return;
390     }
391
392     /* Find and save the ACPI handle for this device. */
393     status = AcpiGetHandle(NULL, ecdt->ec_id, &h);
394     if (ACPI_FAILURE(status)) {
395         device_delete_child(parent, child);
396         printf("%s: can't get handle\n", __func__);
397         return;
398     }
399     acpi_set_handle(child, h);
400
401     /* Set the data and CSR register addresses. */
402     bus_set_resource(child, SYS_RES_IOPORT, 0, ecdt->data.Address,
403         /*count*/1);
404     bus_set_resource(child, SYS_RES_IOPORT, 1, ecdt->control.Address,
405         /*count*/1);
406
407     /*
408      * Store values for the probe/attach routines to use.  Store the
409      * ECDT GPE bit and set the global lock flag according to _GLK.
410      * Note that it is not perfectly correct to be evaluating a method
411      * before initializing devices, but in practice this function
412      * should be safe to call at this point.
413      */
414     params = kmalloc(sizeof(struct acpi_ec_params), M_TEMP, M_WAITOK | M_ZERO);
415     params->gpe_handle = NULL;
416     params->gpe_bit = ecdt->gpe_bit;
417     params->uid = ecdt->uid;
418     acpi_GetInteger(h, "_GLK", &params->glk);
419     acpi_set_private(child, params);
420     acpi_set_magic(child, (int)&acpi_ec_devclass);
421
422     /* Finish the attach process. */
423     if (device_probe_and_attach(child) != 0)
424         device_delete_child(parent, child);
425 }
426
427 static int
428 acpi_ec_probe(device_t dev)
429 {
430     ACPI_BUFFER buf;
431     ACPI_HANDLE h;
432     ACPI_OBJECT *obj;
433     ACPI_STATUS status;
434     device_t    peer;
435     char        desc[64];
436     int         ret;
437     struct acpi_ec_params *params;
438
439     /* Check that this is a device and that EC is not disabled. */
440     if (acpi_get_type(dev) != ACPI_TYPE_DEVICE || acpi_disabled("ec"))
441         return (ENXIO);
442
443     /*
444      * If probed via ECDT, set description and continue.  Otherwise,
445      * we can access the namespace and make sure this is not a
446      * duplicate probe.
447      */
448     ret = ENXIO;
449     params = NULL;
450     buf.Pointer = NULL;
451     buf.Length = ACPI_ALLOCATE_BUFFER;
452     if (DEV_ECDT(dev)) {
453         params = acpi_get_private(dev);
454         ret = 0;
455     } else if (acpi_MatchHid(dev, "PNP0C09")) {
456         params = kmalloc(sizeof(struct acpi_ec_params), M_TEMP,
457                         M_WAITOK | M_ZERO);
458         h = acpi_get_handle(dev);
459
460         /*
461          * Read the unit ID to check for duplicate attach and the
462          * global lock value to see if we should acquire it when
463          * accessing the EC.
464          */
465         status = acpi_GetInteger(h, "_UID", &params->uid);
466         if (ACPI_FAILURE(status))
467             params->uid = 0;
468         status = acpi_GetInteger(h, "_GLK", &params->glk);
469         if (ACPI_FAILURE(status))
470             params->glk = 0;
471
472         /*
473          * Evaluate the _GPE method to find the GPE bit used by the EC to
474          * signal status (SCI).  If it's a package, it contains a reference
475          * and GPE bit, similar to _PRW.
476          */
477         status = AcpiEvaluateObject(h, "_GPE", NULL, &buf);
478         if (ACPI_FAILURE(status)) {
479             device_printf(dev, "can't evaluate _GPE - %s\n",
480                           AcpiFormatException(status));
481             return (ENXIO);
482         }
483         obj = (ACPI_OBJECT *)buf.Pointer;
484         if (obj == NULL)
485             return (ENXIO);
486
487         switch (obj->Type) {
488         case ACPI_TYPE_INTEGER:
489             params->gpe_handle = NULL;
490             params->gpe_bit = obj->Integer.Value;
491             break;
492         case ACPI_TYPE_PACKAGE:
493             if (!ACPI_PKG_VALID(obj, 2))
494                 goto out;
495             params->gpe_handle =
496                 acpi_GetReference(NULL, &obj->Package.Elements[0]);
497             if (params->gpe_handle == NULL ||
498                 acpi_PkgInt32(obj, 1, &params->gpe_bit) != 0)
499                 goto out;
500             break;
501         default:
502             device_printf(dev, "_GPE has invalid type %d\n", obj->Type);
503             goto out;
504         }
505
506         /* Store the values we got from the namespace for attach. */
507         acpi_set_private(dev, params);
508
509         /*
510          * Check for a duplicate probe.  This can happen when a probe
511          * via ECDT succeeded already.  If this is a duplicate, disable
512          * this device.
513          */
514         peer = devclass_get_device(acpi_ec_devclass, params->uid);
515         if (peer == NULL || !device_is_alive(peer))
516             ret = 0;
517         else
518             device_disable(dev);
519     }
520
521 out:
522     if (ret == 0) {
523         snprintf(desc, sizeof(desc), "Embedded Controller: GPE %#x%s%s",
524                  params->gpe_bit, (params->glk) ? ", GLK" : "",
525                  DEV_ECDT(dev) ? ", ECDT" : "");
526         device_set_desc_copy(dev, desc);
527     }
528
529     if (ret > 0 && params)
530         kfree(params, M_TEMP);
531     if (buf.Pointer)
532         AcpiOsFree(buf.Pointer);
533     return (ret);
534 }
535
536 static int
537 acpi_ec_attach(device_t dev)
538 {
539     struct acpi_ec_softc        *sc;
540     struct acpi_ec_params       *params;
541     ACPI_STATUS                 Status;
542
543     ACPI_FUNCTION_TRACE((char *)(uintptr_t)__func__);
544
545     /* Fetch/initialize softc (assumes softc is pre-zeroed). */
546     sc = device_get_softc(dev);
547     params = acpi_get_private(dev);
548     sc->ec_dev = dev;
549     sc->ec_handle = acpi_get_handle(dev);
550     lockinit(&sc->ec_lock, "eclock", 0, 0);
551
552     /* Retrieve previously probed values via device ivars. */
553     sc->ec_glk = params->glk;
554     sc->ec_gpebit = params->gpe_bit;
555     sc->ec_gpehandle = params->gpe_handle;
556     sc->ec_uid = params->uid;
557     kfree(params, M_TEMP);
558
559     /* Attach bus resources for data and command/status ports. */
560     sc->ec_data_rid = 0;
561     sc->ec_data_res = bus_alloc_resource_any(sc->ec_dev, SYS_RES_IOPORT,
562                         &sc->ec_data_rid, RF_ACTIVE);
563     if (sc->ec_data_res == NULL) {
564         device_printf(dev, "can't allocate data port\n");
565         goto error;
566     }
567     sc->ec_data_tag = rman_get_bustag(sc->ec_data_res);
568     sc->ec_data_handle = rman_get_bushandle(sc->ec_data_res);
569
570     sc->ec_csr_rid = 1;
571     sc->ec_csr_res = bus_alloc_resource_any(sc->ec_dev, SYS_RES_IOPORT,
572                         &sc->ec_csr_rid, RF_ACTIVE);
573     if (sc->ec_csr_res == NULL) {
574         device_printf(dev, "can't allocate command/status port\n");
575         goto error;
576     }
577     sc->ec_csr_tag = rman_get_bustag(sc->ec_csr_res);
578     sc->ec_csr_handle = rman_get_bushandle(sc->ec_csr_res);
579
580     /*
581      * Install a handler for this EC's GPE bit.  We want edge-triggered
582      * behavior.
583      */
584     ACPI_DEBUG_PRINT((ACPI_DB_RESOURCES, "attaching GPE handler\n"));
585     Status = AcpiInstallGpeHandler(sc->ec_gpehandle, sc->ec_gpebit,
586                 ACPI_GPE_EDGE_TRIGGERED, &EcGpeHandler, sc);
587     if (ACPI_FAILURE(Status)) {
588         device_printf(dev, "can't install GPE handler for %s - %s\n",
589                       acpi_name(sc->ec_handle), AcpiFormatException(Status));
590         goto error;
591     }
592
593     /* 
594      * Install address space handler
595      */
596     ACPI_DEBUG_PRINT((ACPI_DB_RESOURCES, "attaching address space handler\n"));
597     Status = AcpiInstallAddressSpaceHandler(sc->ec_handle, ACPI_ADR_SPACE_EC,
598                 &EcSpaceHandler, &EcSpaceSetup, sc);
599     if (ACPI_FAILURE(Status)) {
600         device_printf(dev, "can't install address space handler for %s - %s\n",
601                       acpi_name(sc->ec_handle), AcpiFormatException(Status));
602         goto error;
603     }
604
605     /* Enable runtime GPEs for the handler. */
606     Status = AcpiSetGpeType(sc->ec_gpehandle, sc->ec_gpebit,
607                             ACPI_GPE_TYPE_RUNTIME);
608     if (ACPI_FAILURE(Status)) {
609         device_printf(dev, "AcpiSetGpeType failed: %s\n",
610                       AcpiFormatException(Status));
611         goto error;
612     }
613     Status = AcpiEnableGpe(sc->ec_gpehandle, sc->ec_gpebit, ACPI_NOT_ISR);
614     if (ACPI_FAILURE(Status)) {
615         device_printf(dev, "AcpiEnableGpe failed: %s\n",
616                       AcpiFormatException(Status));
617         goto error;
618     }
619
620     ACPI_DEBUG_PRINT((ACPI_DB_RESOURCES, "acpi_ec_attach complete\n"));
621     return (0);
622
623 error:
624     AcpiRemoveGpeHandler(sc->ec_gpehandle, sc->ec_gpebit, &EcGpeHandler);
625     AcpiRemoveAddressSpaceHandler(sc->ec_handle, ACPI_ADR_SPACE_EC,
626         EcSpaceHandler);
627     if (sc->ec_csr_res)
628         bus_release_resource(sc->ec_dev, SYS_RES_IOPORT, sc->ec_csr_rid, 
629                              sc->ec_csr_res);
630     if (sc->ec_data_res)
631         bus_release_resource(sc->ec_dev, SYS_RES_IOPORT, sc->ec_data_rid,
632                              sc->ec_data_res);
633     /* mtx_destroy(&sc->ec_mtx); */
634     return (ENXIO);
635 }
636
637 static void
638 EcGpeQueryHandler(void *Context)
639 {
640     struct acpi_ec_softc        *sc = (struct acpi_ec_softc *)Context;
641     UINT8                       Data;
642     ACPI_STATUS                 Status;
643     EC_STATUS                   EcStatus;
644     char                        qxx[5];
645
646     ACPI_FUNCTION_TRACE((char *)(uintptr_t)__func__);
647     KASSERT(Context != NULL, ("EcGpeQueryHandler called with NULL"));
648
649     Status = EcLock(sc);
650     if (ACPI_FAILURE(Status)) {
651         ACPI_VPRINT(sc->ec_dev, acpi_device_get_parent_softc(sc->ec_dev),
652                     "GpeQuery lock error: %s\n", AcpiFormatException(Status));
653         return;
654     }
655
656     /*
657      * If the EC_SCI bit of the status register is not set, then pass
658      * it along to any potential waiters as it may be an IBE/OBF event.
659      */
660     EcStatus = EC_GET_CSR(sc);
661     if ((EcStatus & EC_EVENT_SCI) == 0) {
662         sc->ec_csrvalue = EcStatus;
663         wakeup(&sc->ec_csrvalue);
664         EcUnlock(sc);
665         goto re_enable;
666     }
667
668     /*
669      * Send a query command to the EC to find out which _Qxx call it
670      * wants to make.  This command clears the SCI bit and also the
671      * interrupt source since we are edge-triggered.
672      */
673     Status = EcCommand(sc, EC_COMMAND_QUERY);
674     if (ACPI_FAILURE(Status)) {
675         EcUnlock(sc);
676         ACPI_VPRINT(sc->ec_dev, acpi_device_get_parent_softc(sc->ec_dev),
677                     "GPE query failed - %s\n", AcpiFormatException(Status));
678         goto re_enable;
679     }
680     Data = EC_GET_DATA(sc);
681     EcUnlock(sc);
682
683     /* Ignore the value for "no outstanding event". (13.3.5) */
684     if (Data == 0)
685         goto re_enable;
686
687     /* Evaluate _Qxx to respond to the controller. */
688     sprintf(qxx, "_Q%02x", Data);
689     strupr(qxx);
690     Status = AcpiEvaluateObject(sc->ec_handle, qxx, NULL, NULL);
691     if (ACPI_FAILURE(Status) && Status != AE_NOT_FOUND) {
692         ACPI_VPRINT(sc->ec_dev, acpi_device_get_parent_softc(sc->ec_dev),
693                     "evaluation of GPE query method %s failed - %s\n", 
694                     qxx, AcpiFormatException(Status));
695     }
696
697 re_enable:
698     /* Re-enable the GPE event so we'll get future requests. */
699     Status = AcpiEnableGpe(sc->ec_gpehandle, sc->ec_gpebit, ACPI_NOT_ISR);
700     if (ACPI_FAILURE(Status))
701         printf("EcGpeQueryHandler: AcpiEnableEvent failed\n");
702 }
703
704 /*
705  * Handle a GPE.  Currently we only handle SCI events as others must
706  * be handled by polling in EcWaitEvent().  This is because some ECs
707  * treat events as level when they should be edge-triggered.
708  */
709 static uint32_t
710 EcGpeHandler(void *Context)
711 {
712     struct acpi_ec_softc *sc = Context;
713     ACPI_STATUS                Status;
714
715     KASSERT(Context != NULL, ("EcGpeHandler called with NULL"));
716
717     /* Disable further GPEs while we handle this one. */
718     AcpiDisableGpe(sc->ec_gpehandle, sc->ec_gpebit, ACPI_NOT_ISR);
719
720     /* Schedule the GPE query handler. */
721     Status = AcpiOsQueueForExecution(OSD_PRIORITY_GPE, EcGpeQueryHandler,
722                 Context);
723     if (ACPI_FAILURE(Status)) {
724         printf("Queuing GPE query handler failed.\n");
725         Status = AcpiEnableGpe(sc->ec_gpehandle, sc->ec_gpebit, ACPI_NOT_ISR);
726         if (ACPI_FAILURE(Status))
727             printf("EcGpeHandler: AcpiEnableEvent failed\n");
728     }
729
730     return (0);
731 }
732
733 static ACPI_STATUS
734 EcSpaceSetup(ACPI_HANDLE Region, UINT32 Function, void *Context,
735              void **RegionContext)
736 {
737
738     ACPI_FUNCTION_TRACE((char *)(uintptr_t)__func__);
739
740     /*
741      * If deactivating a region, always set the output to NULL.  Otherwise,
742      * just pass the context through.
743      */
744     if (Function == ACPI_REGION_DEACTIVATE)
745         *RegionContext = NULL;
746     else
747         *RegionContext = Context;
748
749     return_ACPI_STATUS (AE_OK);
750 }
751
752 static ACPI_STATUS
753 EcSpaceHandler(UINT32 Function, ACPI_PHYSICAL_ADDRESS Address, UINT32 width,
754                ACPI_INTEGER *Value, void *Context, void *RegionContext)
755 {
756     struct acpi_ec_softc        *sc = (struct acpi_ec_softc *)Context;
757     ACPI_STATUS                 Status;
758     UINT8                       EcAddr, EcData;
759     int                         i;
760
761     ACPI_FUNCTION_TRACE_U32((char *)(uintptr_t)__func__, (UINT32)Address);
762
763     if (width % 8 != 0 || Value == NULL || Context == NULL)
764         return_ACPI_STATUS (AE_BAD_PARAMETER);
765     if (Address + (width / 8) - 1 > 0xFF)
766         return_ACPI_STATUS (AE_BAD_ADDRESS);
767
768     if (Function == ACPI_READ)
769         *Value = 0;
770     EcAddr = Address;
771     Status = AE_ERROR;
772
773     /* Perform the transaction(s), based on width. */
774     for (i = 0; i < width; i += 8, EcAddr++) {
775         Status = EcLock(sc);
776         if (ACPI_FAILURE(Status))
777             break;
778
779         switch (Function) {
780         case ACPI_READ:
781             Status = EcRead(sc, EcAddr, &EcData);
782             if (ACPI_SUCCESS(Status))
783                 *Value |= ((ACPI_INTEGER)EcData) << i;
784             break;
785         case ACPI_WRITE:
786             EcData = (UINT8)((*Value) >> i);
787             Status = EcWrite(sc, EcAddr, &EcData);
788             break;
789         default:
790             device_printf(sc->ec_dev, "invalid EcSpaceHandler function %d\n",
791                           Function);
792             Status = AE_BAD_PARAMETER;
793             break;
794         }
795         EcUnlock(sc);
796         if (ACPI_FAILURE(Status))
797             break;
798     }
799
800     return_ACPI_STATUS (Status);
801 }
802
803 static ACPI_STATUS
804 EcWaitEvent(struct acpi_ec_softc *sc, EC_EVENT Event)
805 {
806     EC_STATUS   EcStatus;
807     ACPI_STATUS Status;
808     int         count, i, period, retval, slp_ival;
809     static int  EcDbgMaxDelay;
810
811     /* mtx_assert(&sc->ec_mtx, MA_OWNED); */
812     Status = AE_NO_HARDWARE_RESPONSE;
813
814     /* 
815      * Wait for 1 us before checking the CSR.  Testing shows about
816      * 50% of requests complete in 1 us and 90% of them complete
817      * in 5 us or less.
818      */
819     AcpiOsStall(1);
820
821     /*
822      * Poll the EC status register for up to 1 ms in chunks of 10 us
823      * to detect completion of the last command.
824      */
825     for (i = 0; i < 1000 / EC_POLL_DELAY; i++) {
826         EcStatus = EC_GET_CSR(sc);
827         if (EVENT_READY(Event, EcStatus)) {
828             Status = AE_OK;
829             break;
830         }
831         AcpiOsStall(EC_POLL_DELAY);
832     }
833     period = i * EC_POLL_DELAY;
834
835     /*
836      * If we still don't have a response and we're up and running, wait up
837      * to ec_poll_timeout ms for completion, sleeping for chunks of 10 ms.
838      */
839     slp_ival = 0;
840     if (Status != AE_OK) {
841         retval = ENXIO;
842         count = ec_poll_timeout / 10;
843         if (count == 0)
844             count = 1;
845         slp_ival = hz / 100;
846         if (slp_ival == 0)
847             slp_ival = 1;
848         for (i = 0; i < count; i++) {
849             if (retval != 0)
850                 EcStatus = EC_GET_CSR(sc);
851             else
852                 EcStatus = sc->ec_csrvalue;
853             if (EVENT_READY(Event, EcStatus)) {
854                 Status = AE_OK;
855                 break;
856             }
857             if (!cold)
858                 retval = tsleep(&sc->ec_csrvalue, 0, "ecpoll", slp_ival);
859             else
860                 AcpiOsStall(10000);
861         }
862     }
863
864     /* Calculate new delay and print it if it exceeds the max. */
865     if (slp_ival > 0)
866         period += i * 10000;
867     if (period > EcDbgMaxDelay) {
868         EcDbgMaxDelay = period;
869         ACPI_VPRINT(sc->ec_dev, acpi_device_get_parent_softc(sc->ec_dev),
870                     "info: new max delay is %d us\n", period);
871     }
872
873     return (Status);
874 }    
875
876 static ACPI_STATUS
877 EcCommand(struct acpi_ec_softc *sc, EC_COMMAND cmd)
878 {
879     ACPI_STATUS Status;
880     EC_EVENT    Event;
881
882     /*mtx_assert(&sc->ec_mtx, MA_OWNED);*/
883
884     /* Decide what to wait for based on command type. */
885     switch (cmd) {
886     case EC_COMMAND_READ:
887     case EC_COMMAND_WRITE:
888     case EC_COMMAND_BURST_DISABLE:
889         Event = EC_EVENT_INPUT_BUFFER_EMPTY;
890         break;
891     case EC_COMMAND_QUERY:
892     case EC_COMMAND_BURST_ENABLE:
893         Event = EC_EVENT_OUTPUT_BUFFER_FULL;
894         break;
895     default:
896         ACPI_VPRINT(sc->ec_dev, acpi_device_get_parent_softc(sc->ec_dev),
897                     "EcCommand: Invalid command %#x\n", cmd);
898         return (AE_BAD_PARAMETER);
899     }
900
901     /* Run the command and wait for the chosen event. */
902     EC_SET_CSR(sc, cmd);
903     Status = EcWaitEvent(sc, Event);
904     if (ACPI_FAILURE(Status)) {
905         ACPI_VPRINT(sc->ec_dev, acpi_device_get_parent_softc(sc->ec_dev),
906                     "EcCommand: no response to %#x\n", cmd);
907     }
908
909     return (Status);
910 }
911
912 static ACPI_STATUS
913 EcRead(struct acpi_ec_softc *sc, UINT8 Address, UINT8 *Data)
914 {
915     ACPI_STATUS Status;
916
917     /*mtx_assert(&sc->ec_mtx, MA_OWNED);*/
918
919 #ifdef notyet
920     /* If we can't start burst mode, continue anyway. */
921     EcCommand(sc, EC_COMMAND_BURST_ENABLE);
922 #endif
923
924     Status = EcCommand(sc, EC_COMMAND_READ);
925     if (ACPI_FAILURE(Status))
926         return (Status);
927
928     EC_SET_DATA(sc, Address);
929     Status = EcWaitEvent(sc, EC_EVENT_OUTPUT_BUFFER_FULL);
930     if (ACPI_FAILURE(Status)) {
931         ACPI_VPRINT(sc->ec_dev, acpi_device_get_parent_softc(sc->ec_dev),
932                     "EcRead: Failed waiting for EC to send data.\n");
933         return (Status);
934     }
935
936     *Data = EC_GET_DATA(sc);
937
938 #ifdef notyet
939     if (sc->ec_burstactive) {
940         Status = EcCommand(sc, EC_COMMAND_BURST_DISABLE);
941         if (ACPI_FAILURE(Status))
942             return (Status);
943     }
944 #endif
945
946     return (AE_OK);
947 }    
948
949 static ACPI_STATUS
950 EcWrite(struct acpi_ec_softc *sc, UINT8 Address, UINT8 *Data)
951 {
952     ACPI_STATUS Status;
953
954     /*mtx_assert(&sc->ec_mtx, MA_OWNED);*/
955
956 #ifdef notyet
957     /* If we can't start burst mode, continue anyway. */
958     EcCommand(sc, EC_COMMAND_BURST_ENABLE);
959 #endif
960
961     Status = EcCommand(sc, EC_COMMAND_WRITE);
962     if (ACPI_FAILURE(Status))
963         return (Status);
964
965     EC_SET_DATA(sc, Address);
966     Status = EcWaitEvent(sc, EC_EVENT_INPUT_BUFFER_EMPTY);
967     if (ACPI_FAILURE(Status)) {
968         ACPI_VPRINT(sc->ec_dev, acpi_device_get_parent_softc(sc->ec_dev),
969                     "EcRead: Failed waiting for EC to process address\n");
970         return (Status);
971     }
972
973     EC_SET_DATA(sc, *Data);
974     Status = EcWaitEvent(sc, EC_EVENT_INPUT_BUFFER_EMPTY);
975     if (ACPI_FAILURE(Status)) {
976         ACPI_VPRINT(sc->ec_dev, acpi_device_get_parent_softc(sc->ec_dev),
977                     "EcWrite: Failed waiting for EC to process data\n");
978         return (Status);
979     }
980
981 #ifdef notyet
982     if (sc->ec_burstactive) {
983         Status = EcCommand(sc, EC_COMMAND_BURST_DISABLE);
984         if (ACPI_FAILURE(Status))
985             return (Status);
986     }
987 #endif
988
989     return (AE_OK);
990 }