1*7836SJohn.Forte@Sun.COM /*
2*7836SJohn.Forte@Sun.COM * CDDL HEADER START
3*7836SJohn.Forte@Sun.COM *
4*7836SJohn.Forte@Sun.COM * The contents of this file are subject to the terms of the
5*7836SJohn.Forte@Sun.COM * Common Development and Distribution License (the "License").
6*7836SJohn.Forte@Sun.COM * You may not use this file except in compliance with the License.
7*7836SJohn.Forte@Sun.COM *
8*7836SJohn.Forte@Sun.COM * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
9*7836SJohn.Forte@Sun.COM * or http://www.opensolaris.org/os/licensing.
10*7836SJohn.Forte@Sun.COM * See the License for the specific language governing permissions
11*7836SJohn.Forte@Sun.COM * and limitations under the License.
12*7836SJohn.Forte@Sun.COM *
13*7836SJohn.Forte@Sun.COM * When distributing Covered Code, include this CDDL HEADER in each
14*7836SJohn.Forte@Sun.COM * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
15*7836SJohn.Forte@Sun.COM * If applicable, add the following below this CDDL HEADER, with the
16*7836SJohn.Forte@Sun.COM * fields enclosed by brackets "[]" replaced with your own identifying
17*7836SJohn.Forte@Sun.COM * information: Portions Copyright [yyyy] [name of copyright owner]
18*7836SJohn.Forte@Sun.COM *
19*7836SJohn.Forte@Sun.COM * CDDL HEADER END
20*7836SJohn.Forte@Sun.COM */
21*7836SJohn.Forte@Sun.COM /*
22*7836SJohn.Forte@Sun.COM * Copyright 2008 Sun Microsystems, Inc. All rights reserved.
23*7836SJohn.Forte@Sun.COM * Use is subject to license terms.
24*7836SJohn.Forte@Sun.COM */
25*7836SJohn.Forte@Sun.COM
26*7836SJohn.Forte@Sun.COM #include <sys/types.h>
27*7836SJohn.Forte@Sun.COM #include <sys/ksynch.h>
28*7836SJohn.Forte@Sun.COM #include <sys/kmem.h>
29*7836SJohn.Forte@Sun.COM #include <sys/sdt.h>
30*7836SJohn.Forte@Sun.COM
31*7836SJohn.Forte@Sun.COM #include <sys/varargs.h>
32*7836SJohn.Forte@Sun.COM #include <sys/unistat/spcs_s.h>
33*7836SJohn.Forte@Sun.COM
34*7836SJohn.Forte@Sun.COM #include "safestore.h"
35*7836SJohn.Forte@Sun.COM #include "safestore_impl.h"
36*7836SJohn.Forte@Sun.COM #include "sd_trace.h"
37*7836SJohn.Forte@Sun.COM
38*7836SJohn.Forte@Sun.COM typedef struct safestore_modules_s {
39*7836SJohn.Forte@Sun.COM struct safestore_modules_s *ssm_next;
40*7836SJohn.Forte@Sun.COM safestore_ops_t *ssm_module;
41*7836SJohn.Forte@Sun.COM } safestore_modules_t;
42*7836SJohn.Forte@Sun.COM
43*7836SJohn.Forte@Sun.COM safestore_modules_t *ss_modules;
44*7836SJohn.Forte@Sun.COM kmutex_t safestore_mutex;
45*7836SJohn.Forte@Sun.COM int ss_initialized;
46*7836SJohn.Forte@Sun.COM
47*7836SJohn.Forte@Sun.COM /* the safestore module init/deinit functions */
48*7836SJohn.Forte@Sun.COM
49*7836SJohn.Forte@Sun.COM void ss_ram_init();
50*7836SJohn.Forte@Sun.COM void ss_ram_deinit();
51*7836SJohn.Forte@Sun.COM
52*7836SJohn.Forte@Sun.COM /* CSTYLED */
53*7836SJohn.Forte@Sun.COM /**#
54*7836SJohn.Forte@Sun.COM * initialize the safestore subsystem and all safestore
55*7836SJohn.Forte@Sun.COM * modules by calling all safestore modules' initialization functions
56*7836SJohn.Forte@Sun.COM *
57*7836SJohn.Forte@Sun.COM * NOTE: This function must be called with the _sdbc_config_lock held
58*7836SJohn.Forte@Sun.COM *
59*7836SJohn.Forte@Sun.COM * @param none
60*7836SJohn.Forte@Sun.COM * @return void
61*7836SJohn.Forte@Sun.COM *
62*7836SJohn.Forte@Sun.COM */
63*7836SJohn.Forte@Sun.COM void
sst_init()64*7836SJohn.Forte@Sun.COM sst_init()
65*7836SJohn.Forte@Sun.COM {
66*7836SJohn.Forte@Sun.COM /*
67*7836SJohn.Forte@Sun.COM * initialize the ss modules we know about
68*7836SJohn.Forte@Sun.COM * this results in calls to sst_register_mod()
69*7836SJohn.Forte@Sun.COM */
70*7836SJohn.Forte@Sun.COM if (ss_initialized != SS_INITTED) {
71*7836SJohn.Forte@Sun.COM mutex_init(&safestore_mutex, NULL, MUTEX_DRIVER, NULL);
72*7836SJohn.Forte@Sun.COM ss_ram_init();
73*7836SJohn.Forte@Sun.COM ss_initialized = SS_INITTED;
74*7836SJohn.Forte@Sun.COM }
75*7836SJohn.Forte@Sun.COM
76*7836SJohn.Forte@Sun.COM }
77*7836SJohn.Forte@Sun.COM
78*7836SJohn.Forte@Sun.COM /* CSTYLED */
79*7836SJohn.Forte@Sun.COM /**#
80*7836SJohn.Forte@Sun.COM * deinitialize the safestore subsystem and all safestore modules
81*7836SJohn.Forte@Sun.COM * by calling all safestore modules' deinitialization functions
82*7836SJohn.Forte@Sun.COM *
83*7836SJohn.Forte@Sun.COM * NOTE: This function must be called with the _sdbc_config_lock held
84*7836SJohn.Forte@Sun.COM *
85*7836SJohn.Forte@Sun.COM * @param none
86*7836SJohn.Forte@Sun.COM * @return void
87*7836SJohn.Forte@Sun.COM *
88*7836SJohn.Forte@Sun.COM */
89*7836SJohn.Forte@Sun.COM void
sst_deinit()90*7836SJohn.Forte@Sun.COM sst_deinit()
91*7836SJohn.Forte@Sun.COM {
92*7836SJohn.Forte@Sun.COM if (ss_initialized == SS_INITTED) {
93*7836SJohn.Forte@Sun.COM ss_ram_deinit();
94*7836SJohn.Forte@Sun.COM mutex_destroy(&safestore_mutex);
95*7836SJohn.Forte@Sun.COM ss_initialized = 0;
96*7836SJohn.Forte@Sun.COM }
97*7836SJohn.Forte@Sun.COM }
98*7836SJohn.Forte@Sun.COM
99*7836SJohn.Forte@Sun.COM /* BEGIN CSTYLED */
100*7836SJohn.Forte@Sun.COM /**#
101*7836SJohn.Forte@Sun.COM * called by a safestore module to register its ops table
102*7836SJohn.Forte@Sun.COM * for use by clients
103*7836SJohn.Forte@Sun.COM *
104*7836SJohn.Forte@Sun.COM * @param ss_ops structure of safestore functions
105*7836SJohn.Forte@Sun.COM * @return void
106*7836SJohn.Forte@Sun.COM *
107*7836SJohn.Forte@Sun.COM * @see safestore_ops_t{}
108*7836SJohn.Forte@Sun.COM */
109*7836SJohn.Forte@Sun.COM void
sst_register_mod(safestore_ops_t * ss_ops)110*7836SJohn.Forte@Sun.COM sst_register_mod(safestore_ops_t *ss_ops) /* END CSTYLED */
111*7836SJohn.Forte@Sun.COM {
112*7836SJohn.Forte@Sun.COM safestore_modules_t *new;
113*7836SJohn.Forte@Sun.COM
114*7836SJohn.Forte@Sun.COM new = kmem_alloc(sizeof (*new), KM_SLEEP);
115*7836SJohn.Forte@Sun.COM
116*7836SJohn.Forte@Sun.COM mutex_enter(&safestore_mutex);
117*7836SJohn.Forte@Sun.COM new->ssm_module = ss_ops;
118*7836SJohn.Forte@Sun.COM new->ssm_next = ss_modules;
119*7836SJohn.Forte@Sun.COM
120*7836SJohn.Forte@Sun.COM ss_modules = new;
121*7836SJohn.Forte@Sun.COM mutex_exit(&safestore_mutex);
122*7836SJohn.Forte@Sun.COM }
123*7836SJohn.Forte@Sun.COM
124*7836SJohn.Forte@Sun.COM /* BEGIN CSTYLED */
125*7836SJohn.Forte@Sun.COM /**#
126*7836SJohn.Forte@Sun.COM * called by a safestore module to unregister its ops table
127*7836SJohn.Forte@Sun.COM * @param ss_ops structure of safestore functions
128*7836SJohn.Forte@Sun.COM *
129*7836SJohn.Forte@Sun.COM * @return void
130*7836SJohn.Forte@Sun.COM *
131*7836SJohn.Forte@Sun.COM * @see safestore_ops_t{}
132*7836SJohn.Forte@Sun.COM */
133*7836SJohn.Forte@Sun.COM void
sst_unregister_mod(safestore_ops_t * ss_ops)134*7836SJohn.Forte@Sun.COM sst_unregister_mod(safestore_ops_t *ss_ops) /* END CSTYLED */
135*7836SJohn.Forte@Sun.COM {
136*7836SJohn.Forte@Sun.COM safestore_modules_t *ssm, *prev;
137*7836SJohn.Forte@Sun.COM int found = 0;
138*7836SJohn.Forte@Sun.COM
139*7836SJohn.Forte@Sun.COM mutex_enter(&safestore_mutex);
140*7836SJohn.Forte@Sun.COM prev = NULL;
141*7836SJohn.Forte@Sun.COM for (ssm = ss_modules; ssm; prev = ssm, ssm = ssm->ssm_next) {
142*7836SJohn.Forte@Sun.COM if (ssm->ssm_module == ss_ops) {
143*7836SJohn.Forte@Sun.COM if (!prev)
144*7836SJohn.Forte@Sun.COM ss_modules = ssm->ssm_next;
145*7836SJohn.Forte@Sun.COM else
146*7836SJohn.Forte@Sun.COM prev->ssm_next = ssm->ssm_next;
147*7836SJohn.Forte@Sun.COM
148*7836SJohn.Forte@Sun.COM kmem_free(ssm, sizeof (safestore_modules_t));
149*7836SJohn.Forte@Sun.COM ++found;
150*7836SJohn.Forte@Sun.COM break;
151*7836SJohn.Forte@Sun.COM }
152*7836SJohn.Forte@Sun.COM }
153*7836SJohn.Forte@Sun.COM mutex_exit(&safestore_mutex);
154*7836SJohn.Forte@Sun.COM
155*7836SJohn.Forte@Sun.COM if (!found)
156*7836SJohn.Forte@Sun.COM cmn_err(CE_WARN, "ss(sst_unregister_mod) "
157*7836SJohn.Forte@Sun.COM "ss module %p not found", (void *)ss_ops);
158*7836SJohn.Forte@Sun.COM }
159*7836SJohn.Forte@Sun.COM
160*7836SJohn.Forte@Sun.COM /* BEGIN CSTYLED */
161*7836SJohn.Forte@Sun.COM /**#
162*7836SJohn.Forte@Sun.COM * open a safestore module for use by a client
163*7836SJohn.Forte@Sun.COM * @param ss_type specifies a valid media type and transport type.
164*7836SJohn.Forte@Sun.COM * the first module found that supports these reqested type
165*7836SJohn.Forte@Sun.COM * is used. may contain more than one media type or transport
166*7836SJohn.Forte@Sun.COM * type if client has no preference among several types.
167*7836SJohn.Forte@Sun.COM * more than one ss_type may be specified in the call if
168*7836SJohn.Forte@Sun.COM * client has an ordered preference.
169*7836SJohn.Forte@Sun.COM *
170*7836SJohn.Forte@Sun.COM * @return safestore_ops_t * pointer to a valid safestore ops structure
171*7836SJohn.Forte@Sun.COM * if the request is satisfied.
172*7836SJohn.Forte@Sun.COM * NULL otherwise
173*7836SJohn.Forte@Sun.COM *
174*7836SJohn.Forte@Sun.COM * @see safestore_ops_t{}
175*7836SJohn.Forte@Sun.COM * @see SS_M_RAM
176*7836SJohn.Forte@Sun.COM * @see SS_M_NV_SINGLENODE
177*7836SJohn.Forte@Sun.COM * @see SS_M_NV_DUALNODE_NOMIRROR
178*7836SJohn.Forte@Sun.COM * @see SS_M_NV_DUALNODE_MIRROR
179*7836SJohn.Forte@Sun.COM * @see SS_T_STE
180*7836SJohn.Forte@Sun.COM * @see SS_T_RPC
181*7836SJohn.Forte@Sun.COM * @see SS_T_NONE
182*7836SJohn.Forte@Sun.COM */
183*7836SJohn.Forte@Sun.COM safestore_ops_t *
sst_open(uint_t ss_type,...)184*7836SJohn.Forte@Sun.COM sst_open(uint_t ss_type, ...) /* END CSTYLED */
185*7836SJohn.Forte@Sun.COM {
186*7836SJohn.Forte@Sun.COM va_list ap;
187*7836SJohn.Forte@Sun.COM uint_t ssop_type;
188*7836SJohn.Forte@Sun.COM safestore_modules_t *ssm;
189*7836SJohn.Forte@Sun.COM
190*7836SJohn.Forte@Sun.COM if ((ss_modules == NULL) || !ss_type)
191*7836SJohn.Forte@Sun.COM return (NULL);
192*7836SJohn.Forte@Sun.COM
193*7836SJohn.Forte@Sun.COM va_start(ap, ss_type);
194*7836SJohn.Forte@Sun.COM mutex_enter(&safestore_mutex);
195*7836SJohn.Forte@Sun.COM do {
196*7836SJohn.Forte@Sun.COM for (ssm = ss_modules; ssm; ssm = ssm->ssm_next) {
197*7836SJohn.Forte@Sun.COM ssop_type = ssm->ssm_module->ssop_type;
198*7836SJohn.Forte@Sun.COM if ((ssop_type & SS_MEDIA_MASK) & ss_type)
199*7836SJohn.Forte@Sun.COM if ((ssop_type & SS_TRANSPORT_MASK) & ss_type) {
200*7836SJohn.Forte@Sun.COM va_end(ap);
201*7836SJohn.Forte@Sun.COM mutex_exit(&safestore_mutex);
202*7836SJohn.Forte@Sun.COM return (ssm->ssm_module);
203*7836SJohn.Forte@Sun.COM }
204*7836SJohn.Forte@Sun.COM }
205*7836SJohn.Forte@Sun.COM } while ((ss_type = va_arg(ap, uint_t)) != 0);
206*7836SJohn.Forte@Sun.COM mutex_exit(&safestore_mutex);
207*7836SJohn.Forte@Sun.COM
208*7836SJohn.Forte@Sun.COM va_end(ap);
209*7836SJohn.Forte@Sun.COM return (NULL);
210*7836SJohn.Forte@Sun.COM }
211*7836SJohn.Forte@Sun.COM
212*7836SJohn.Forte@Sun.COM /* BEGIN CSTYLED */
213*7836SJohn.Forte@Sun.COM /**#
214*7836SJohn.Forte@Sun.COM * close a safestore module. called when client no longer wishes to use
215*7836SJohn.Forte@Sun.COM * a safestore module
216*7836SJohn.Forte@Sun.COM *
217*7836SJohn.Forte@Sun.COM * @param ssp points to a safestore_ops_t obtained from a previous call
218*7836SJohn.Forte@Sun.COM * to sst_open()
219*7836SJohn.Forte@Sun.COM *
220*7836SJohn.Forte@Sun.COM * @return SS_OK if successful
221*7836SJohn.Forte@Sun.COM * SS_ERR otherwise
222*7836SJohn.Forte@Sun.COM */
223*7836SJohn.Forte@Sun.COM /*ARGSUSED*/
224*7836SJohn.Forte@Sun.COM int
sst_close(safestore_ops_t * ssp)225*7836SJohn.Forte@Sun.COM sst_close(safestore_ops_t *ssp) /* END CSTYLED */
226*7836SJohn.Forte@Sun.COM {
227*7836SJohn.Forte@Sun.COM return (SS_OK);
228*7836SJohn.Forte@Sun.COM }
229*7836SJohn.Forte@Sun.COM
230*7836SJohn.Forte@Sun.COM
231*7836SJohn.Forte@Sun.COM /*
232*7836SJohn.Forte@Sun.COM * _sdbc_writeq_configure - configure the given writeq
233*7836SJohn.Forte@Sun.COM * Allocate the lock and sv we need to maintain waiters
234*7836SJohn.Forte@Sun.COM *
235*7836SJohn.Forte@Sun.COM */
236*7836SJohn.Forte@Sun.COM int
_sdbc_writeq_configure(_sd_writeq_t * wrq)237*7836SJohn.Forte@Sun.COM _sdbc_writeq_configure(_sd_writeq_t *wrq)
238*7836SJohn.Forte@Sun.COM {
239*7836SJohn.Forte@Sun.COM int i;
240*7836SJohn.Forte@Sun.COM
241*7836SJohn.Forte@Sun.COM wrq->wq_inq = 0;
242*7836SJohn.Forte@Sun.COM mutex_init(&wrq->wq_qlock, NULL, MUTEX_DRIVER, NULL);
243*7836SJohn.Forte@Sun.COM wrq->wq_qtop = NULL;
244*7836SJohn.Forte@Sun.COM wrq->wq_slp_top = 0;
245*7836SJohn.Forte@Sun.COM wrq->wq_slp_index = 0;
246*7836SJohn.Forte@Sun.COM wrq->wq_slp_inq = 0;
247*7836SJohn.Forte@Sun.COM
248*7836SJohn.Forte@Sun.COM for (i = 0; i < SD_WR_SLP_Q_MAX; i++) {
249*7836SJohn.Forte@Sun.COM wrq->wq_slp[i].slp_wqneed = 0;
250*7836SJohn.Forte@Sun.COM cv_init(&wrq->wq_slp[i].slp_wqcv, NULL, CV_DRIVER, NULL);
251*7836SJohn.Forte@Sun.COM }
252*7836SJohn.Forte@Sun.COM
253*7836SJohn.Forte@Sun.COM return (0);
254*7836SJohn.Forte@Sun.COM }
255*7836SJohn.Forte@Sun.COM
256*7836SJohn.Forte@Sun.COM /*
257*7836SJohn.Forte@Sun.COM * _sdbc_writeq_deconfigure - deconfigure the given writeq
258*7836SJohn.Forte@Sun.COM * Deallocate the lock and sv if present.
259*7836SJohn.Forte@Sun.COM *
260*7836SJohn.Forte@Sun.COM */
261*7836SJohn.Forte@Sun.COM void
_sdbc_writeq_deconfigure(_sd_writeq_t * wrq)262*7836SJohn.Forte@Sun.COM _sdbc_writeq_deconfigure(_sd_writeq_t *wrq)
263*7836SJohn.Forte@Sun.COM {
264*7836SJohn.Forte@Sun.COM int i;
265*7836SJohn.Forte@Sun.COM
266*7836SJohn.Forte@Sun.COM if (wrq) {
267*7836SJohn.Forte@Sun.COM mutex_destroy(&wrq->wq_qlock);
268*7836SJohn.Forte@Sun.COM for (i = 0; i < SD_WR_SLP_Q_MAX; i++) {
269*7836SJohn.Forte@Sun.COM cv_destroy(&wrq->wq_slp[i].slp_wqcv);
270*7836SJohn.Forte@Sun.COM }
271*7836SJohn.Forte@Sun.COM wrq->wq_inq = 0;
272*7836SJohn.Forte@Sun.COM wrq->wq_qtop = NULL;
273*7836SJohn.Forte@Sun.COM }
274*7836SJohn.Forte@Sun.COM
275*7836SJohn.Forte@Sun.COM }
276*7836SJohn.Forte@Sun.COM
277*7836SJohn.Forte@Sun.COM
278*7836SJohn.Forte@Sun.COM int _sd_wblk_sync = 1;
279*7836SJohn.Forte@Sun.COM
280*7836SJohn.Forte@Sun.COM ss_wr_cctl_t *
ss_alloc_write(int need,int * stall,_sd_writeq_t * q)281*7836SJohn.Forte@Sun.COM ss_alloc_write(int need, int *stall, _sd_writeq_t *q)
282*7836SJohn.Forte@Sun.COM {
283*7836SJohn.Forte@Sun.COM ss_wr_cctl_t *wctl;
284*7836SJohn.Forte@Sun.COM ss_wr_cctl_t *ret;
285*7836SJohn.Forte@Sun.COM int i;
286*7836SJohn.Forte@Sun.COM int aged = 0;
287*7836SJohn.Forte@Sun.COM
288*7836SJohn.Forte@Sun.COM if (_sd_wblk_sync && (q->wq_inq == 0))
289*7836SJohn.Forte@Sun.COM return (NULL); /* do sync write if queue empty */
290*7836SJohn.Forte@Sun.COM
291*7836SJohn.Forte@Sun.COM SDTRACE(ST_ENTER|SDF_WR_ALLOC, SDT_INV_CD, need,
292*7836SJohn.Forte@Sun.COM SDT_INV_BL, q->wq_inq, _SD_NO_NET);
293*7836SJohn.Forte@Sun.COM
294*7836SJohn.Forte@Sun.COM if (need <= 0) {
295*7836SJohn.Forte@Sun.COM cmn_err(CE_WARN, "ss_alloc_write: bogus need value! %d", need);
296*7836SJohn.Forte@Sun.COM return (NULL);
297*7836SJohn.Forte@Sun.COM }
298*7836SJohn.Forte@Sun.COM
299*7836SJohn.Forte@Sun.COM mutex_enter(&(q->wq_qlock));
300*7836SJohn.Forte@Sun.COM retry_wr_get:
301*7836SJohn.Forte@Sun.COM if (q->wq_inq < need) {
302*7836SJohn.Forte@Sun.COM if (!_sd_wblk_sync) {
303*7836SJohn.Forte@Sun.COM unsigned stime;
304*7836SJohn.Forte@Sun.COM stime = nsc_usec();
305*7836SJohn.Forte@Sun.COM
306*7836SJohn.Forte@Sun.COM /*
307*7836SJohn.Forte@Sun.COM * Try to keep requests ordered so large requests
308*7836SJohn.Forte@Sun.COM * are not starved. We can queue 255 write requests,
309*7836SJohn.Forte@Sun.COM * After That go into write-through.
310*7836SJohn.Forte@Sun.COM */
311*7836SJohn.Forte@Sun.COM if (q->wq_slp_inq < SD_WR_SLP_Q_MAX) {
312*7836SJohn.Forte@Sun.COM q->wq_slp_inq++;
313*7836SJohn.Forte@Sun.COM /* give preference to aged requests */
314*7836SJohn.Forte@Sun.COM if (aged) {
315*7836SJohn.Forte@Sun.COM WQ_SVWAIT_TOP(q, need);
316*7836SJohn.Forte@Sun.COM } else {
317*7836SJohn.Forte@Sun.COM WQ_SVWAIT_BOTTOM(q, need);
318*7836SJohn.Forte@Sun.COM }
319*7836SJohn.Forte@Sun.COM aged++;
320*7836SJohn.Forte@Sun.COM } else {
321*7836SJohn.Forte@Sun.COM mutex_exit(&(q->wq_qlock));
322*7836SJohn.Forte@Sun.COM return (NULL);
323*7836SJohn.Forte@Sun.COM }
324*7836SJohn.Forte@Sun.COM
325*7836SJohn.Forte@Sun.COM SDTRACE(ST_INFO|SDF_WR_ALLOC,
326*7836SJohn.Forte@Sun.COM SDT_INV_CD, need, SDT_INV_BL, q->wq_inq,
327*7836SJohn.Forte@Sun.COM (nsc_usec()-stime));
328*7836SJohn.Forte@Sun.COM (void) (*stall)++;
329*7836SJohn.Forte@Sun.COM goto retry_wr_get;
330*7836SJohn.Forte@Sun.COM }
331*7836SJohn.Forte@Sun.COM ret = NULL;
332*7836SJohn.Forte@Sun.COM } else {
333*7836SJohn.Forte@Sun.COM get_wctl:
334*7836SJohn.Forte@Sun.COM wctl = q->wq_qtop;
335*7836SJohn.Forte@Sun.COM ret = wctl;
336*7836SJohn.Forte@Sun.COM DTRACE_PROBE1(alloc_write,
337*7836SJohn.Forte@Sun.COM ss_wr_cctl_t *, wctl);
338*7836SJohn.Forte@Sun.COM for (i = 1; i < need; ++i) {
339*7836SJohn.Forte@Sun.COM wctl = wctl->wc_next;
340*7836SJohn.Forte@Sun.COM DTRACE_PROBE1(alloc_write_cont,
341*7836SJohn.Forte@Sun.COM ss_wr_cctl_t *, wctl);
342*7836SJohn.Forte@Sun.COM }
343*7836SJohn.Forte@Sun.COM
344*7836SJohn.Forte@Sun.COM q->wq_qtop = wctl->wc_next;
345*7836SJohn.Forte@Sun.COM wctl->wc_next = NULL;
346*7836SJohn.Forte@Sun.COM q->wq_inq -= need;
347*7836SJohn.Forte@Sun.COM }
348*7836SJohn.Forte@Sun.COM mutex_exit(&(q->wq_qlock));
349*7836SJohn.Forte@Sun.COM
350*7836SJohn.Forte@Sun.COM SDTRACE(ST_EXIT|SDF_WR_ALLOC, SDT_INV_CD, need,
351*7836SJohn.Forte@Sun.COM SDT_INV_BL, q->wq_inq, _SD_NO_NET);
352*7836SJohn.Forte@Sun.COM return (ret);
353*7836SJohn.Forte@Sun.COM }
354*7836SJohn.Forte@Sun.COM
355*7836SJohn.Forte@Sun.COM /*
356*7836SJohn.Forte@Sun.COM * ss_release_write - put a write block back in the writeq.
357*7836SJohn.Forte@Sun.COM *
358*7836SJohn.Forte@Sun.COM * ARGUMENTS:
359*7836SJohn.Forte@Sun.COM * wctl - Write control block to be release.
360*7836SJohn.Forte@Sun.COM * q - write q to put the wctl
361*7836SJohn.Forte@Sun.COM *
362*7836SJohn.Forte@Sun.COM * RETURNS: NONE
363*7836SJohn.Forte@Sun.COM */
364*7836SJohn.Forte@Sun.COM
365*7836SJohn.Forte@Sun.COM void
ss_release_write(ss_wr_cctl_t * wctl,_sd_writeq_t * q)366*7836SJohn.Forte@Sun.COM ss_release_write(ss_wr_cctl_t *wctl, _sd_writeq_t *q)
367*7836SJohn.Forte@Sun.COM {
368*7836SJohn.Forte@Sun.COM
369*7836SJohn.Forte@Sun.COM SDTRACE(ST_ENTER|SDF_WR_FREE, SDT_INV_CD, 0, SDT_INV_BL, q->wq_inq,
370*7836SJohn.Forte@Sun.COM _SD_NO_NET);
371*7836SJohn.Forte@Sun.COM
372*7836SJohn.Forte@Sun.COM DTRACE_PROBE1(release_write,
373*7836SJohn.Forte@Sun.COM ss_wr_cctl_t *, wctl);
374*7836SJohn.Forte@Sun.COM
375*7836SJohn.Forte@Sun.COM #if defined(_SD_DEBUG)
376*7836SJohn.Forte@Sun.COM if (wctl->wc_gl_info->sci_dirty) {
377*7836SJohn.Forte@Sun.COM SDALERT(SDF_WR_FREE, wctl->wc_gl_info->sci_cd,
378*7836SJohn.Forte@Sun.COM 0, wctl->wc_gl_info->sci_fpos,
379*7836SJohn.Forte@Sun.COM wctl->wc_gl_info->sci_dirty, 0);
380*7836SJohn.Forte@Sun.COM }
381*7836SJohn.Forte@Sun.COM #endif
382*7836SJohn.Forte@Sun.COM mutex_enter(&q->wq_qlock);
383*7836SJohn.Forte@Sun.COM
384*7836SJohn.Forte@Sun.COM wctl->wc_next = q->wq_qtop;
385*7836SJohn.Forte@Sun.COM q->wq_qtop = wctl;
386*7836SJohn.Forte@Sun.COM q->wq_inq++;
387*7836SJohn.Forte@Sun.COM if (WQ_NEED_SIG(q)) {
388*7836SJohn.Forte@Sun.COM q->wq_slp_inq--;
389*7836SJohn.Forte@Sun.COM WQ_SVSIG(q);
390*7836SJohn.Forte@Sun.COM }
391*7836SJohn.Forte@Sun.COM mutex_exit(&q->wq_qlock);
392*7836SJohn.Forte@Sun.COM SDTRACE(ST_EXIT|SDF_WR_FREE, SDT_INV_CD, 0, SDT_INV_BL, q->wq_inq,
393*7836SJohn.Forte@Sun.COM _SD_NO_NET);
394*7836SJohn.Forte@Sun.COM }
395