Merge commit '9276b3991ba20d5a5660887ba81b0bc7bed25a0c'
[unleashed.git] / share / man / man9f / ddi_soft_state.9f
blobe841b827f3f7eca3fc949d35c11df19ff0c765c8
1 '\" te
2 .\" Copyright (c) 2006, Sun Microsystems, Inc.
3 .\" All Rights Reserved
4 .\" The contents of this file are subject to the terms of the Common Development and Distribution License (the "License").  You may not use this file except in compliance with the License.
5 .\" You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE or http://www.opensolaris.org/os/licensing.  See the License for the specific language governing permissions and limitations under the License.
6 .\" When distributing Covered Code, include this CDDL HEADER in each file and include the License file at usr/src/OPENSOLARIS.LICENSE.  If applicable, add the following below this CDDL HEADER, with the fields enclosed by brackets "[]" replaced with your own identifying information: Portions Copyright [yyyy] [name of copyright owner]
7 .TH DDI_SOFT_STATE 9F "Jan 16, 2006"
8 .SH NAME
9 ddi_soft_state, ddi_get_soft_state, ddi_soft_state_fini, ddi_soft_state_free,
10 ddi_soft_state_init, ddi_soft_state_zalloc \- driver soft state utility
11 routines
12 .SH SYNOPSIS
13 .LP
14 .nf
15 #include <sys/ddi.h>
16 #include <sys/sunddi.h>
20 \fBvoid *\fR\fBddi_get_soft_state\fR(\fBvoid\fR \fI*state\fR, \fBint\fR \fIitem\fR);
21 .fi
23 .LP
24 .nf
25 \fBvoid\fR \fBddi_soft_state_fini\fR(\fBvoid\fR \fI**state_p\fR);
26 .fi
28 .LP
29 .nf
30 \fBvoid\fR \fBddi_soft_state_free\fR(\fBvoid\fR \fI*state\fR, \fBint\fR \fIitem\fR);
31 .fi
33 .LP
34 .nf
35 \fBint\fR \fBddi_soft_state_init\fR(\fBvoid\fR \fI**state_p\fR, \fBsize_t\fR \fIsize\fR, \fBsize_t\fR \fIn_items\fR);
36 .fi
38 .LP
39 .nf
40 \fBint\fR \fBddi_soft_state_zalloc\fR(\fBvoid\fR \fI*state\fR, \fBint\fR \fIitem\fR);
41 .fi
43 .SH INTERFACE LEVEL
44 .sp
45 .LP
46 Solaris DDI specific (Solaris DDI).
47 .SH PARAMETERS
48 .sp
49 .ne 2
50 .na
51 \fB\fIstate_p\fR\fR
52 .ad
53 .RS 11n
54 Address of the opaque state pointer which will be initialized by
55 \fBddi_soft_state_init()\fR to point to implementation dependent data.
56 .RE
58 .sp
59 .ne 2
60 .na
61 \fB\fIsize\fR\fR
62 .ad
63 .RS 11n
64 Size of the item which will be allocated by subsequent calls to
65 \fBddi_soft_state_zalloc()\fR.
66 .RE
68 .sp
69 .ne 2
70 .na
71 \fB\fIn_items\fR\fR
72 .ad
73 .RS 11n
74 A hint of the number of items which will be preallocated; zero is allowed.
75 .RE
77 .sp
78 .ne 2
79 .na
80 \fB\fIstate\fR\fR
81 .ad
82 .RS 11n
83 An opaque pointer to implementation-dependent data that describes the soft
84 state.
85 .RE
87 .sp
88 .ne 2
89 .na
90 \fB\fIitem\fR\fR
91 .ad
92 .RS 11n
93 The item number for the state structure; usually the instance number of the
94 associated devinfo node.
95 .RE
97 .SH DESCRIPTION
98 .sp
99 .LP
100 Most device drivers maintain state information with each instance of the device
101 they control; for example, a soft copy of a device control register, a mutex
102 that must be held while accessing a piece of hardware, a partition table, or a
103 unit structure. These utility routines are intended to help device drivers
104 manage the space used by the driver to hold such state information.
107 For example, if the driver holds the state of each instance in a single state
108 structure, these routines can be used to dynamically allocate and deallocate a
109 separate structure for each instance of the driver as the instance is attached
110 and detached.
113 To use the routines, the driver writer needs to declare a state pointer,
114 \fIstate_p\fR, which the implementation uses as a place to hang a set of
115 per-driver structures; everything else is managed by these routines.
118 The routine \fBddi_soft_state_init()\fR is usually called in the driver's
119 \fB_init\fR(9E) routine to initialize the state pointer, set the size of the
120 soft state structure, and to allow the driver to pre-allocate a given number of
121 such structures if required.
124 The routine \fBddi_soft_state_zalloc()\fR is usually called in the driver's
125 \fBattach\fR(9E) routine.  The routine is passed an item number which is used
126 to refer to the structure in subsequent calls to \fBddi_get_soft_state()\fR and
127 \fBddi_soft_state_free()\fR. The item number is usually just the instance
128 number of the \fBdevinfo\fR node, obtained with \fBddi_get_instance\fR(9F). The
129 routine attempts to allocate space for the new structure, and if the space
130 allocation was successful, \fBDDI_SUCCESS\fR is returned to the caller.
131 Returned memory is zeroed.
134 A pointer to the space previously allocated for a soft state structure can be
135 obtained by calling \fBddi_get_soft_state()\fR with the appropriate item
136 number.
139 The space used by a given soft state structure can be returned to the system
140 using \fBddi_soft_state_free()\fR. This routine is usually called from the
141 driver's \fBdetach\fR(9E) entry point.
144 The space used by all the soft state structures allocated on a given state
145 pointer, together with the housekeeping information used by the implementation
146 can be returned to the system using \fBddi_soft_state_fini()\fR. This routine
147 can be called from the driver's \fB_fini\fR(9E) routine.
150 The \fBddi_soft_state_zalloc()\fR, \fBddi_soft_state_free()\fR and
151 \fBddi_get_soft_state()\fR routines coordinate access to the underlying data
152 structures in an MT-safe fashion, thus no additional locks should be necessary.
153 .SH RETURN VALUES
156 \fBddi_get_soft_state()\fR
158 .ne 2
160 \fB\fINULL\fR\fR
162 .RS 11n
163 The requested state structure was not allocated at the time of the call.
167 .ne 2
169 \fB\fIpointer\fR\fR
171 .RS 11n
172 The pointer to the state structure.
177 \fBddi_soft_state_init()\fR
179 .ne 2
181 \fB\fB0\fR\fR
183 .RS 10n
184 The allocation was successful.
188 .ne 2
190 \fB\fBEINVAL\fR\fR
192 .RS 10n
193 Either the \fBsize\fR parameter was zero, or the \fIstate_p\fR parameter was
194 invalid.
199 \fBddi_soft_state_zalloc()\fR
201 .ne 2
203 \fB\fBDDI_SUCCESS\fR\fR
205 .RS 15n
206 The allocation was successful.
210 .ne 2
212 \fB\fBDDI_FAILURE\fR\fR
214 .RS 15n
215 The routine failed to allocate the storage required; either the \fIstate\fR
216 parameter was invalid, the item number was negative, or an attempt was made to
217 allocate an item number that was already allocated.
220 .SH CONTEXT
223 The \fBddi_soft_state_init()\fR and \fBddi_soft_state_alloc()\fR functions can
224 be called from user or kernel context only, since they may internally call
225 \fBkmem_zalloc\fR(9F) with the \fBKM_SLEEP\fR flag.
228 The \fBddi_soft_state_fini()\fR, \fBddi_soft_state_free()\fR and
229 \fBddi_get_soft_state()\fR routines can be called from any driver context.
230 .SH EXAMPLES
232 \fBExample 1 \fRCreating and Removing Data Structures
235 The following example shows how the routines described above can be used in
236 terms of the driver entry points of a character-only driver. The example
237 concentrates on the portions of the code that deal with creating and removing
238 the driver's data structures.
241 .in +2
243 typedef struct {
244    volatile caddr_t *csr;        /* device registers */
245    kmutex_t         csr_mutex;   /* protects 'csr' field */
246    unsigned int     state;
247    dev_info_t       *dip;        /* back pointer to devinfo */
248 } devstate_t;
249 static void *statep;
252 _init(void)
254    int error;
256    error = ddi_soft_state_init(&statep, sizeof (devstate_t), 0);
257    if (error != 0)
258                    return (error);
259    if ((error = mod_install(&modlinkage)) != 0)
260                    ddi_soft_state_fini(&statep);
261    return (error);
265 _fini(void)
267    int error;
269    if ((error = mod_remove(&modlinkage)) != 0)
270                    return (error);
271    ddi_soft_state_fini(&statep);
272    return (0);
275 static int
276 xxattach(dev_info_t *dip, ddi_attach_cmd_t cmd)
278    int instance;
279    devstate_t *softc;
281    switch (cmd) {
282    case DDI_ATTACH:
283               instance = ddi_get_instance(dip);
284       if (ddi_soft_state_zalloc(statep, instance) != DDI_SUCCESS)
285                  return (DDI_FAILURE);
286               softc = ddi_get_soft_state(statep, instance);
287               softc->dip = dip; 
288               ...
289               return (DDI_SUCCESS);
290    default:
291               return (DDI_FAILURE);
292    }
295 static int
296 xxdetach(dev_info_t *dip, ddi_detach_cmd_t cmd)
298    int instance;
300    switch (cmd) {
302    case DDI_DETACH:
303               instance = ddi_get_instance(dip);
304               ...
305       ddi_soft_state_free(statep, instance);
306       return (DDI_SUCCESS);
308    default:
309       return (DDI_FAILURE);
310    }
313 static int
314 xxopen(dev_t *devp, int flag, int otyp, cred_t *cred_p)
316    devstate_t *softc;
317    int   instance;
319    instance = getminor(*devp);
320    if ((softc = ddi_get_soft_state(statep, instance)) == NULL)
321               return (ENXIO);
322    ...
323    softc->state |= XX_IN_USE;
324    ...
325    return (0);
328 .in -2
330 .SH SEE ALSO
333 \fB_fini\fR(9E), \fB_init\fR(9E), \fBattach\fR(9E), \fBdetach\fR(9E),
334 \fBddi_get_instance\fR(9F), \fBgetminor\fR(9F), \fBkmem_zalloc\fR(9F)
337 \fIWriting Device Drivers\fR
338 .SH WARNINGS
341 There is no attempt to validate the \fBitem\fR parameter given to
342 \fBddi_soft_state_zalloc()\fR other than it must be a positive signed integer.
343 Therefore very large item numbers may cause the driver to hang forever waiting
344 for virtual memory resources that can never be satisfied.
345 .SH NOTES
348 If necessary, a hierarchy of state structures can be constructed by embedding
349 state pointers in higher order state structures.
350 .SH DIAGNOSTICS
353 All of the messages described below usually indicate bugs in the driver and
354 should not appear in normal operation of the system.
356 .in +2
358 WARNING: ddi_soft_state_zalloc: bad handle
359 WARNING: ddi_soft_state_free: bad handle
360 WARNING: ddi_soft_state_fini: bad handle
362 .in -2
366 The implementation-dependent information kept in the state variable is corrupt.
368 .in +2
370 WARNING: ddi_soft_state_free: null handle
371 WARNING: ddi_soft_state_fini: null handle
373 .in -2
377 The routine has been passed a null or corrupt state pointer.  Check that
378 \fBddi_soft_state_init()\fR has been called.
380 .in +2
382 WARNING: ddi_soft_state_free: item %d not in range [0..%d]
384 .in -2
388 The routine has been asked to free an item which was never allocated. The
389 message prints out the invalid item number and the acceptable range.