1 /*        $NetBSD: device_impl.h,v 1.5 2022/09/13 09:43:33 riastradh Exp $      */
2 
3 /*
4  * Copyright (c) 2022 The NetBSD Foundation, Inc.
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 NETBSD FOUNDATION, INC. AND CONTRIBUTORS
17  * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
18  * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
19  * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS
20  * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
21  * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
22  * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
23  * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
24  * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
25  * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
26  * POSSIBILITY OF SUCH DAMAGE.
27  */
28 
29 /*
30  * Copyright (c) 1996, 2000 Christopher G. Demetriou
31  * All rights reserved.
32  *
33  * Redistribution and use in source and binary forms, with or without
34  * modification, are permitted provided that the following conditions
35  * are met:
36  * 1. Redistributions of source code must retain the above copyright
37  *    notice, this list of conditions and the following disclaimer.
38  * 2. Redistributions in binary form must reproduce the above copyright
39  *    notice, this list of conditions and the following disclaimer in the
40  *    documentation and/or other materials provided with the distribution.
41  * 3. All advertising materials mentioning features or use of this software
42  *    must display the following acknowledgement:
43  *          This product includes software developed for the
44  *          NetBSD Project.  See http://www.NetBSD.org/ for
45  *          information about NetBSD.
46  * 4. The name of the author may not be used to endorse or promote products
47  *    derived from this software without specific prior written permission.
48  *
49  * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
50  * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
51  * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
52  * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
53  * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
54  * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
55  * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
56  * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
57  * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
58  * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
59  *
60  * --(license Id: LICENSE.proto,v 1.1 2000/06/13 21:40:26 cgd Exp )--
61  */
62 
63 /*
64  * Copyright (c) 1992, 1993
65  *        The Regents of the University of California.  All rights reserved.
66  *
67  * This software was developed by the Computer Systems Engineering group
68  * at Lawrence Berkeley Laboratory under DARPA contract BG 91-66 and
69  * contributed to Berkeley.
70  *
71  * All advertising materials mentioning features or use of this software
72  * must display the following acknowledgement:
73  *        This product includes software developed by the University of
74  *        California, Lawrence Berkeley Laboratories.
75  *
76  * Redistribution and use in source and binary forms, with or without
77  * modification, are permitted provided that the following conditions
78  * are met:
79  * 1. Redistributions of source code must retain the above copyright
80  *    notice, this list of conditions and the following disclaimer.
81  * 2. Redistributions in binary form must reproduce the above copyright
82  *    notice, this list of conditions and the following disclaimer in the
83  *    documentation and/or other materials provided with the distribution.
84  * 3. Neither the name of the University nor the names of its contributors
85  *    may be used to endorse or promote products derived from this software
86  *    without specific prior written permission.
87  *
88  * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
89  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
90  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
91  * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
92  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
93  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
94  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
95  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
96  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
97  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
98  * SUCH DAMAGE.
99  *
100  *        @(#)device.h        8.2 (Berkeley) 2/17/94
101  */
102 
103 #ifndef   _SYS_DEVICE_IMPL_H_
104 #define   _SYS_DEVICE_IMPL_H_
105 
106 /*
107  * Private autoconf-internal device structures.
108  *
109  * DO NOT USE outside autoconf internals.
110  */
111 
112 #include <sys/device.h>
113 
114 struct device_lock {
115           int                 dvl_nwait;
116           int                 dvl_nlock;
117           lwp_t               *dvl_holder;
118           kmutex_t  dvl_mtx;
119           kcondvar_t          dvl_cv;
120 };
121 
122 #define   DEVICE_SUSPENSORS_MAX         16
123 
124 struct device {
125           devhandle_t         dv_handle;          /* this device's handle;
126                                                      new device_t's get INVALID */
127           devclass_t          dv_class; /* this device's classification */
128           TAILQ_ENTRY(device) dv_list;  /* entry on list of all devices */
129           cfdata_t  dv_cfdata;          /* config data that found us
130                                                      (NULL if pseudo-device) */
131           cfdriver_t          dv_cfdriver;        /* our cfdriver */
132           cfattach_t          dv_cfattach;        /* our cfattach */
133           int                 dv_unit;  /* device unit number */
134                                                   /* external name (name + unit) */
135           char                dv_xname[DEVICE_XNAME_SIZE];
136           device_t  dv_parent;          /* pointer to parent device
137                                                      (NULL if pseudo- or root node) */
138           int                 dv_depth; /* number of parents until root */
139           int                 dv_flags; /* misc. flags; see below */
140           void                *dv_private;        /* this device's private storage */
141           int                 *dv_locators;       /* our actual locators (optional) */
142           prop_dictionary_t dv_properties;/* properties dictionary */
143           struct localcount *dv_localcount;/* reference count */
144 
145           int                 dv_pending;         /* config_pending count */
146           TAILQ_ENTRY(device) dv_pending_list;
147 
148           struct lwp          *dv_attaching;      /* thread not yet finished in attach */
149           struct lwp          *dv_detaching;      /* detach lock (config_misc_lock/cv) */
150           bool                dv_detach_committed;          /* config_misc_lock */
151           bool                dv_detach_done;               /* dv_detaching */
152 
153           size_t              dv_activity_count;
154           void                (**dv_activity_handlers)(device_t, devactive_t);
155 
156           bool                (*dv_driver_suspend)(device_t, const pmf_qual_t *);
157           bool                (*dv_driver_resume)(device_t, const pmf_qual_t *);
158           bool                (*dv_driver_shutdown)(device_t, int);
159           void                (*dv_driver_child_register)(device_t);
160 
161           void                *dv_bus_private;
162           bool                (*dv_bus_suspend)(device_t, const pmf_qual_t *);
163           bool                (*dv_bus_resume)(device_t, const pmf_qual_t *);
164           bool                (*dv_bus_shutdown)(device_t, int);
165           void                (*dv_bus_deregister)(device_t);
166 
167           void                *dv_class_private;
168           bool                (*dv_class_suspend)(device_t, const pmf_qual_t *);
169           bool                (*dv_class_resume)(device_t, const pmf_qual_t *);
170           void                (*dv_class_deregister)(device_t);
171 
172           devgen_t            dv_add_gen,
173                                         dv_del_gen;
174 
175           struct device_lock  dv_lock;
176           const device_suspensor_t
177               *dv_bus_suspensors[DEVICE_SUSPENSORS_MAX],
178               *dv_driver_suspensors[DEVICE_SUSPENSORS_MAX],
179               *dv_class_suspensors[DEVICE_SUSPENSORS_MAX];
180           struct device_garbage dv_garbage;
181 };
182 
183 /*
184  * struct device::dv_flags (must not overlap with device.h struct
185  * cfattach::ca_flags for now)
186  */
187 #define   DVF_ACTIVE                    0x0001    /* device is activated */
188 #define   DVF_POWER_HANDLERS  0x0004    /* device has suspend/resume support */
189 #define   DVF_CLASS_SUSPENDED 0x0008    /* device class suspend was called */
190 #define   DVF_DRIVER_SUSPENDED          0x0010    /* device driver suspend was called */
191 #define   DVF_BUS_SUSPENDED   0x0020    /* device bus suspend was called */
192 #define   DVF_ATTACH_INPROGRESS         0x0040    /* device attach is in progress */
193 
194 bool                device_pmf_is_registered(device_t);
195 
196 bool                device_pmf_driver_suspend(device_t, const pmf_qual_t *);
197 bool                device_pmf_driver_resume(device_t, const pmf_qual_t *);
198 bool                device_pmf_driver_shutdown(device_t, int);
199 
200 void                device_pmf_driver_register(device_t,
201                         bool (*)(device_t, const pmf_qual_t *),
202                         bool (*)(device_t, const pmf_qual_t *),
203                         bool (*)(device_t, int));
204 void                device_pmf_driver_deregister(device_t);
205 
206 device_lock_t       device_getlock(device_t);
207 void                device_pmf_unlock(device_t);
208 bool                device_pmf_lock(device_t);
209 
210 void                *device_pmf_class_private(device_t);
211 bool                device_pmf_class_suspend(device_t, const pmf_qual_t *);
212 bool                device_pmf_class_resume(device_t, const pmf_qual_t *);
213 
214 void                device_pmf_class_register(device_t, void *,
215                         bool (*)(device_t, const pmf_qual_t *),
216                         bool (*)(device_t, const pmf_qual_t *),
217                         void (*)(device_t));
218 void                device_pmf_class_deregister(device_t);
219 
220 #endif    /* _SYS_DEVICE_IMPL_H_ */
221