1 /* $NetBSD: dmover_process.c,v 1.3 2007/10/08 16:18:03 ad Exp $ */
4 * Copyright (c) 2002 Wasabi Systems, Inc.
7 * Written by Jason R. Thorpe for Wasabi Systems, Inc.
9 * Redistribution and use in source and binary forms, with or without
10 * modification, are permitted provided that the following conditions
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
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.
39 * dmover_process.c: Processing engine for dmover-api.
42 #include <sys/cdefs.h>
43 __KERNEL_RCSID(0, "$NetBSD: dmover_process.c,v 1.3 2007/10/08 16:18:03 ad Exp $");
45 #include <sys/param.h>
46 #include <sys/systm.h>
49 #include <sys/simplelock.h>
51 #include <dev/dmover/dmovervar.h>
53 TAILQ_HEAD(, dmover_request
) dmover_completed_q
;
54 struct simplelock dmover_completed_q_slock
; /* must be held at splbio */
56 void *dmover_completed_si
;
58 void dmover_complete(void *);
61 * dmover_process_init:
63 * Initialize the processing engine.
66 dmover_process_initialize(void)
69 TAILQ_INIT(&dmover_completed_q
);
70 simple_lock_init(&dmover_completed_q_slock
);
72 dmover_completed_si
= softint_establish(SOFTINT_CLOCK
,
73 dmover_complete
, NULL
);
77 * dmover_process: [client interface function]
79 * Submit a tranform request for processing.
82 dmover_process(struct dmover_request
*dreq
)
84 struct dmover_session
*dses
= dreq
->dreq_session
;
85 struct dmover_assignment
*das
;
86 struct dmover_backend
*dmb
;
90 if ((dreq
->dreq_flags
& DMOVER_REQ_WAIT
) != 0 &&
91 dreq
->dreq_callback
!= NULL
)
92 panic("dmover_process: WAIT used with callback");
95 /* Clear unwanted flag bits. */
96 dreq
->dreq_flags
&= __DMOVER_REQ_FLAGS_PRESERVE
;
102 /* XXX Right now, the back-end is statically assigned. */
103 das
= &dses
->__dses_assignment
;
105 dmb
= das
->das_backend
;
106 dreq
->dreq_assignment
= das
;
108 dmover_session_insque(dses
, dreq
);
109 dmover_backend_insque(dmb
, dreq
);
115 /* Kick the back-end into action. */
116 (*dmb
->dmb_process
)(das
->das_backend
);
118 if (dreq
->dreq_flags
& DMOVER_REQ_WAIT
) {
121 while ((dreq
->dreq_flags
& DMOVER_REQ_DONE
) == 0)
122 (void) tsleep(dreq
, PRIBIO
, "dmover", 0);
129 * dmover_done: [back-end interface function]
131 * Back-end notification that the dmover is done.
134 dmover_done(struct dmover_request
*dreq
)
136 struct dmover_session
*dses
= dreq
->dreq_session
;
143 dmover_session_remque(dses
, dreq
);
144 /* backend has removed it from its queue */
148 dreq
->dreq_flags
|= DMOVER_REQ_DONE
;
149 dreq
->dreq_flags
&= ~DMOVER_REQ_RUNNING
;
150 dreq
->dreq_assignment
= NULL
;
152 if (dreq
->dreq_callback
!= NULL
) {
153 simple_lock(&dmover_completed_q_slock
);
154 TAILQ_INSERT_TAIL(&dmover_completed_q
, dreq
, dreq_dmbq
);
155 simple_unlock(&dmover_completed_q_slock
);
156 softint_schedule(dmover_completed_si
);
157 } else if (dreq
->dreq_flags
& DMOVER_REQ_WAIT
)
166 * Complete a request by invoking the callback.
169 dmover_complete(void *arg
)
171 struct dmover_request
*dreq
;
176 simple_lock(&dmover_completed_q_slock
);
177 if ((dreq
= TAILQ_FIRST(&dmover_completed_q
)) != NULL
)
178 TAILQ_REMOVE(&dmover_completed_q
, dreq
, dreq_dmbq
);
179 simple_unlock(&dmover_completed_q_slock
);
185 (*dreq
->dreq_callback
)(dreq
);