dmover_process.c revision 1.2.18.1 1 /* $NetBSD: dmover_process.c,v 1.2.18.1 2007/10/27 11:30:13 yamt Exp $ */
2
3 /*
4 * Copyright (c) 2002 Wasabi Systems, Inc.
5 * All rights reserved.
6 *
7 * Written by Jason R. Thorpe for Wasabi Systems, Inc.
8 *
9 * Redistribution and use in source and binary forms, with or without
10 * modification, are permitted provided that the following conditions
11 * are met:
12 * 1. Redistributions of source code must retain the above copyright
13 * notice, this list of conditions and the following disclaimer.
14 * 2. Redistributions in binary form must reproduce the above copyright
15 * notice, this list of conditions and the following disclaimer in the
16 * documentation and/or other materials provided with the distribution.
17 * 3. All advertising materials mentioning features or use of this software
18 * must display the following acknowledgement:
19 * This product includes software developed for the NetBSD Project by
20 * Wasabi Systems, Inc.
21 * 4. The name of Wasabi Systems, Inc. may not be used to endorse
22 * or promote products derived from this software without specific prior
23 * written permission.
24 *
25 * THIS SOFTWARE IS PROVIDED BY WASABI SYSTEMS, INC. ``AS IS'' AND
26 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
27 * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
28 * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL WASABI SYSTEMS, INC
29 * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
30 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
31 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
32 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
33 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
34 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
35 * POSSIBILITY OF SUCH DAMAGE.
36 */
37
38 /*
39 * dmover_process.c: Processing engine for dmover-api.
40 */
41
42 #include <sys/cdefs.h>
43 __KERNEL_RCSID(0, "$NetBSD: dmover_process.c,v 1.2.18.1 2007/10/27 11:30:13 yamt Exp $");
44
45 #include <sys/param.h>
46 #include <sys/systm.h>
47 #include <sys/proc.h>
48 #include <sys/intr.h>
49
50 #include <dev/dmover/dmovervar.h>
51
52 TAILQ_HEAD(, dmover_request) dmover_completed_q;
53 struct simplelock dmover_completed_q_slock; /* must be held at splbio */
54
55 void *dmover_completed_si;
56
57 void dmover_complete(void *);
58
59 /*
60 * dmover_process_init:
61 *
62 * Initialize the processing engine.
63 */
64 void
65 dmover_process_initialize(void)
66 {
67
68 TAILQ_INIT(&dmover_completed_q);
69 simple_lock_init(&dmover_completed_q_slock);
70
71 dmover_completed_si = softint_establish(SOFTINT_CLOCK,
72 dmover_complete, NULL);
73 }
74
75 /*
76 * dmover_process: [client interface function]
77 *
78 * Submit a tranform request for processing.
79 */
80 void
81 dmover_process(struct dmover_request *dreq)
82 {
83 struct dmover_session *dses = dreq->dreq_session;
84 struct dmover_assignment *das;
85 struct dmover_backend *dmb;
86 int s;
87
88 #ifdef DIAGNOSTIC
89 if ((dreq->dreq_flags & DMOVER_REQ_WAIT) != 0 &&
90 dreq->dreq_callback != NULL)
91 panic("dmover_process: WAIT used with callback");
92 #endif
93
94 /* Clear unwanted flag bits. */
95 dreq->dreq_flags &= __DMOVER_REQ_FLAGS_PRESERVE;
96
97 s = splbio();
98
99 /* XXXLOCK */
100
101 /* XXX Right now, the back-end is statically assigned. */
102 das = &dses->__dses_assignment;
103
104 dmb = das->das_backend;
105 dreq->dreq_assignment = das;
106
107 dmover_session_insque(dses, dreq);
108 dmover_backend_insque(dmb, dreq);
109
110 /* XXXUNLOCK */
111
112 splx(s);
113
114 /* Kick the back-end into action. */
115 (*dmb->dmb_process)(das->das_backend);
116
117 if (dreq->dreq_flags & DMOVER_REQ_WAIT) {
118 s = splbio();
119 /* XXXLOCK */
120 while ((dreq->dreq_flags & DMOVER_REQ_DONE) == 0)
121 (void) tsleep(dreq, PRIBIO, "dmover", 0);
122 /* XXXUNLOCK */
123 splx(s);
124 }
125 }
126
127 /*
128 * dmover_done: [back-end interface function]
129 *
130 * Back-end notification that the dmover is done.
131 */
132 void
133 dmover_done(struct dmover_request *dreq)
134 {
135 struct dmover_session *dses = dreq->dreq_session;
136 int s;
137
138 s = splbio();
139
140 /* XXXLOCK */
141
142 dmover_session_remque(dses, dreq);
143 /* backend has removed it from its queue */
144
145 /* XXXUNLOCK */
146
147 dreq->dreq_flags |= DMOVER_REQ_DONE;
148 dreq->dreq_flags &= ~DMOVER_REQ_RUNNING;
149 dreq->dreq_assignment = NULL;
150
151 if (dreq->dreq_callback != NULL) {
152 simple_lock(&dmover_completed_q_slock);
153 TAILQ_INSERT_TAIL(&dmover_completed_q, dreq, dreq_dmbq);
154 simple_unlock(&dmover_completed_q_slock);
155 softint_schedule(dmover_completed_si);
156 } else if (dreq->dreq_flags & DMOVER_REQ_WAIT)
157 wakeup(dreq);
158
159 splx(s);
160 }
161
162 /*
163 * dmover_complete:
164 *
165 * Complete a request by invoking the callback.
166 */
167 void
168 dmover_complete(void *arg)
169 {
170 struct dmover_request *dreq;
171 int s;
172
173 for (;;) {
174 s = splbio();
175 simple_lock(&dmover_completed_q_slock);
176 if ((dreq = TAILQ_FIRST(&dmover_completed_q)) != NULL)
177 TAILQ_REMOVE(&dmover_completed_q, dreq, dreq_dmbq);
178 simple_unlock(&dmover_completed_q_slock);
179 splx(s);
180
181 if (dreq == NULL)
182 return;
183
184 (*dreq->dreq_callback)(dreq);
185 }
186 }
187