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"
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
16 #include <sys/sunddi.h>
20 \fBvoid *\fR\fBddi_get_soft_state\fR(\fBvoid\fR \fI*state\fR, \fBint\fR \fIitem\fR);
25 \fBvoid\fR \fBddi_soft_state_fini\fR(\fBvoid\fR \fI**state_p\fR);
30 \fBvoid\fR \fBddi_soft_state_free\fR(\fBvoid\fR \fI*state\fR, \fBint\fR \fIitem\fR);
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);
40 \fBint\fR \fBddi_soft_state_zalloc\fR(\fBvoid\fR \fI*state\fR, \fBint\fR \fIitem\fR);
46 Solaris DDI specific (Solaris DDI).
54 Address of the opaque state pointer which will be initialized by
55 \fBddi_soft_state_init()\fR to point to implementation dependent data.
64 Size of the item which will be allocated by subsequent calls to
65 \fBddi_soft_state_zalloc()\fR.
74 A hint of the number of items which will be preallocated; zero is allowed.
83 An opaque pointer to implementation-dependent data that describes the soft
93 The item number for the state structure; usually the instance number of the
94 associated devinfo node.
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
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
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.
156 \fBddi_get_soft_state()\fR
163 The requested state structure was not allocated at the time of the call.
172 The pointer to the state structure.
177 \fBddi_soft_state_init()\fR
184 The allocation was successful.
193 Either the \fBsize\fR parameter was zero, or the \fIstate_p\fR parameter was
199 \fBddi_soft_state_zalloc()\fR
203 \fB\fBDDI_SUCCESS\fR\fR
206 The allocation was successful.
212 \fB\fBDDI_FAILURE\fR\fR
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.
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.
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.
244 volatile caddr_t *csr; /* device registers */
245 kmutex_t csr_mutex; /* protects 'csr' field */
247 dev_info_t *dip; /* back pointer to devinfo */
256 error = ddi_soft_state_init(&statep, sizeof (devstate_t), 0);
259 if ((error = mod_install(&modlinkage)) != 0)
260 ddi_soft_state_fini(&statep);
269 if ((error = mod_remove(&modlinkage)) != 0)
271 ddi_soft_state_fini(&statep);
276 xxattach(dev_info_t *dip, ddi_attach_cmd_t cmd)
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);
289 return (DDI_SUCCESS);
291 return (DDI_FAILURE);
296 xxdetach(dev_info_t *dip, ddi_detach_cmd_t cmd)
303 instance = ddi_get_instance(dip);
305 ddi_soft_state_free(statep, instance);
306 return (DDI_SUCCESS);
309 return (DDI_FAILURE);
314 xxopen(dev_t *devp, int flag, int otyp, cred_t *cred_p)
319 instance = getminor(*devp);
320 if ((softc = ddi_get_soft_state(statep, instance)) == NULL)
323 softc->state |= XX_IN_USE;
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
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.
348 If necessary, a hierarchy of state structures can be constructed by embedding
349 state pointers in higher order state structures.
353 All of the messages described below usually indicate bugs in the driver and
354 should not appear in normal operation of the system.
358 WARNING: ddi_soft_state_zalloc: bad handle
359 WARNING: ddi_soft_state_free: bad handle
360 WARNING: ddi_soft_state_fini: bad handle
366 The implementation-dependent information kept in the state variable is corrupt.
370 WARNING: ddi_soft_state_free: null handle
371 WARNING: ddi_soft_state_fini: null handle
377 The routine has been passed a null or corrupt state pointer. Check that
378 \fBddi_soft_state_init()\fR has been called.
382 WARNING: ddi_soft_state_free: item %d not in range [0..%d]
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.