1ddi_soft_state(9F)       Kernel Functions for Drivers       ddi_soft_state(9F)
2
3
4

NAME

6       ddi_soft_state,         ddi_get_soft_state,        ddi_soft_state_fini,
7       ddi_soft_state_free,   ddi_soft_state_init,   ddi_soft_state_zalloc   -
8       driver soft state utility routines
9

SYNOPSIS

11       #include <sys/ddi.h>
12       #include <sys/sunddi.h>
13
14
15
16       void *ddi_get_soft_state(void *state, int item);
17
18
19       void ddi_soft_state_fini(void **state_p);
20
21
22       void ddi_soft_state_free(void *state, int item);
23
24
25       int ddi_soft_state_init(void **state_p, size_t size, size_t n_items);
26
27
28       int ddi_soft_state_zalloc(void *state, int item);
29
30

INTERFACE LEVEL

32       Solaris DDI specific (Solaris DDI).
33

PARAMETERS

35       state_p    Address  of  the opaque state pointer which will be initial‐
36                  ized by ddi_soft_state_init()  to  point  to  implementation
37                  dependent data.
38
39
40       size       Size of the item which will be allocated by subsequent calls
41                  to ddi_soft_state_zalloc().
42
43
44       n_items    A hint of the number of items which  will  be  preallocated;
45                  zero is allowed.
46
47
48       state      An  opaque  pointer  to  implementation-dependent  data that
49                  describes the soft state.
50
51
52       item       The  item  number  for  the  state  structure;  usually  the
53                  instance number of the associated devinfo node.
54
55

DESCRIPTION

57       Most  device  drivers  maintain state information with each instance of
58       the device they control; for example, a soft copy of a  device  control
59       register,  a  mutex  that must be held while accessing a piece of hard‐
60       ware, a partition table, or a unit structure.  These  utility  routines
61       are intended to help device drivers manage the space used by the driver
62       to hold such state information.
63
64
65       For example, if the driver holds the state of each instance in a single
66       state structure, these routines can be used to dynamically allocate and
67       deallocate a separate structure for each instance of the driver as  the
68       instance is attached and detached.
69
70
71       To  use  the  routines,  the  driver  writer  needs  to declare a state
72       pointer, state_p, which the implementation uses as a place  to  hang  a
73       set  of per-driver structures; everything else is managed by these rou‐
74       tines.
75
76
77       The routine ddi_soft_state_init() is usually  called  in  the  driver's
78       _init(9E)  routine to initialize the state pointer, set the size of the
79       soft state structure, and to allow the driver to pre-allocate  a  given
80       number of such structures if required.
81
82
83       The  routine  ddi_soft_state_zalloc() is usually called in the driver's
84       attach(9E) routine.  The routine is passed an item number which is used
85       to  refer  to the structure in subsequent calls to ddi_get_soft_state()
86       and ddi_soft_state_free(). The item number is usually just the instance
87       number  of  the  devinfo  node, obtained with ddi_get_instance(9F). The
88       routine attempts to allocate space for the new structure,  and  if  the
89       space allocation was successful, DDI_SUCCESS is returned to the caller.
90       Returned memory is zeroed.
91
92
93       A pointer to the space previously allocated for a soft state  structure
94       can  be  obtained  by calling ddi_get_soft_state() with the appropriate
95       item number.
96
97
98       The space used by a given soft state structure can be returned  to  the
99       system using ddi_soft_state_free(). This routine is usually called from
100       the driver's detach(9E) entry point.
101
102
103       The space used by all the soft state structures allocated  on  a  given
104       state  pointer,  together with the housekeeping information used by the
105       implementation    can    be    returned    to    the    system    using
106       ddi_soft_state_fini().  This  routine  can  be called from the driver's
107       _fini(9E) routine.
108
109
110       The      ddi_soft_state_zalloc(),       ddi_soft_state_free()       and
111       ddi_get_soft_state()  routines coordinate access to the underlying data
112       structures in an MT-safe fashion, thus no additional  locks  should  be
113       necessary.
114

RETURN VALUES

116       ddi_get_soft_state()
117
118       NULL       The  requested state structure was not allocated at the time
119                  of the call.
120
121
122       pointer    The pointer to the state structure.
123
124
125
126       ddi_soft_state_init()
127
128       0         The allocation was successful.
129
130
131       EINVAL    Either the size parameter was zero, or the state_p  parameter
132                 was invalid.
133
134
135
136       ddi_soft_state_zalloc()
137
138       DDI_SUCCESS    The allocation was successful.
139
140
141       DDI_FAILURE    The  routine  failed  to  allocate the storage required;
142                      either the state parameter was invalid, the item  number
143                      was negative, or an attempt was made to allocate an item
144                      number that was already allocated.
145
146

CONTEXT

148       The ddi_soft_state_init() and ddi_soft_state_alloc() functions  can  be
149       called from user or kernel context only, since they may internally call
150       kmem_zalloc(9F) with the KM_SLEEP flag.
151
152
153       The       ddi_soft_state_fini(),       ddi_soft_state_free()        and
154       ddi_get_soft_state() routines can be called from any driver context.
155

EXAMPLES

157       Example 1 Creating and Removing Data Structures
158
159
160       The  following  example  shows  how the routines described above can be
161       used in terms of the driver entry points of  a  character-only  driver.
162       The  example  concentrates  on  the portions of the code that deal with
163       creating and removing the driver's data structures.
164
165
166         typedef struct {
167            volatile caddr_t *csr;        /* device registers */
168            kmutex_t         csr_mutex;   /* protects 'csr' field */
169            unsigned int     state;
170            dev_info_t       *dip;        /* back pointer to devinfo */
171         } devstate_t;
172         static void *statep;
173
174         int
175         _init(void)
176         {
177            int error;
178
179            error = ddi_soft_state_init(&statep, sizeof (devstate_t), 0);
180            if (error != 0)
181                      return (error);
182            if ((error = mod_install(&modlinkage)) != 0)
183                      ddi_soft_state_fini(&statep);
184            return (error);
185         }
186
187         int
188         _fini(void)
189         {
190            int error;
191
192            if ((error = mod_remove(&modlinkage)) != 0)
193                      return (error);
194            ddi_soft_state_fini(&statep);
195            return (0);
196         }
197
198         static int
199         xxattach(dev_info_t *dip, ddi_attach_cmd_t cmd)
200         {
201            int instance;
202            devstate_t *softc;
203
204            switch (cmd) {
205            case DDI_ATTACH:
206                    instance = ddi_get_instance(dip);
207               if (ddi_soft_state_zalloc(statep, instance) != DDI_SUCCESS)
208                       return (DDI_FAILURE);
209                    softc = ddi_get_soft_state(statep, instance);
210                    softc->dip = dip;
211                    ...
212                    return (DDI_SUCCESS);
213            default:
214                    return (DDI_FAILURE);
215            }
216         }
217
218         static int
219         xxdetach(dev_info_t *dip, ddi_detach_cmd_t cmd)
220         {
221            int instance;
222
223            switch (cmd) {
224
225            case DDI_DETACH:
226                    instance = ddi_get_instance(dip);
227                    ...
228               ddi_soft_state_free(statep, instance);
229               return (DDI_SUCCESS);
230
231            default:
232               return (DDI_FAILURE);
233            }
234         }
235
236         static int
237         xxopen(dev_t *devp, int flag, int otyp, cred_t *cred_p)
238         {
239            devstate_t *softc;
240            int   instance;
241
242            instance = getminor(*devp);
243            if ((softc = ddi_get_soft_state(statep, instance)) == NULL)
244                    return (ENXIO);
245            ...
246            softc->state |= XX_IN_USE;
247            ...
248            return (0);
249         }
250
251

SEE ALSO

253       _fini(9E),  _init(9E),  attach(9E),  detach(9E),  ddi_get_instance(9F),
254       getminor(9F), kmem_zalloc(9F)
255
256
257       Writing Device Drivers
258

WARNINGS

260       There   is   no  attempt  to  validate  the  item  parameter  given  to
261       ddi_soft_state_zalloc() other than it must be a positive  signed  inte‐
262       ger.  Therefore  very  large  item numbers may cause the driver to hang
263       forever waiting for virtual memory resources that can never  be  satis‐
264       fied.
265

NOTES

267       If  necessary,  a  hierarchy  of state structures can be constructed by
268       embedding state pointers in higher order state structures.
269

DIAGNOSTICS

271       All of the messages described below usually indicate bugs in the driver
272       and should not appear in normal operation of the system.
273
274         WARNING: ddi_soft_state_zalloc: bad handle
275         WARNING: ddi_soft_state_free: bad handle
276         WARNING: ddi_soft_state_fini: bad handle
277
278
279
280       The  implementation-dependent information kept in the state variable is
281       corrupt.
282
283         WARNING: ddi_soft_state_free: null handle
284         WARNING: ddi_soft_state_fini: null handle
285
286
287
288       The routine has been passed a null or  corrupt  state  pointer.   Check
289       that ddi_soft_state_init() has been called.
290
291         WARNING: ddi_soft_state_free: item %d not in range [0..%d]
292
293
294
295       The  routine  has been asked to free an item which was never allocated.
296       The message prints out the  invalid  item  number  and  the  acceptable
297       range.
298
299
300
301SunOS 5.11                        16 Jan 2006               ddi_soft_state(9F)
Impressum