1 /* $NetBSD: dmover_process.c,v 1.1 2002/08/02 00:30:38 thorpej 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.1 2002/08/02 00:30:38 thorpej Exp $"); 44 45 #include <sys/param.h> 46 #include <sys/systm.h> 47 #include <sys/proc.h> 48 49 #include <machine/intr.h> 50 51 #include <dev/dmover/dmovervar.h> 52 53 TAILQ_HEAD(, dmover_request) dmover_completed_q; 54 struct simplelock dmover_completed_q_slock; /* must be held at splbio */ 55 56 void *dmover_completed_si; 57 58 void dmover_complete(void *); 59 60 /* 61 * dmover_process_init: 62 * 63 * Initialize the processing engine. 64 */ 65 void 66 dmover_process_initialize(void) 67 { 68 69 TAILQ_INIT(&dmover_completed_q); 70 simple_lock_init(&dmover_completed_q_slock); 71 72 dmover_completed_si = softintr_establish(IPL_SOFTCLOCK, 73 dmover_complete, NULL); 74 } 75 76 /* 77 * dmover_process: [client interface function] 78 * 79 * Submit a tranform request for processing. 80 */ 81 void 82 dmover_process(struct dmover_request *dreq) 83 { 84 struct dmover_session *dses = dreq->dreq_session; 85 struct dmover_assignment *das; 86 struct dmover_backend *dmb; 87 int s; 88 89 #ifdef DIAGNOSTIC 90 if ((dreq->dreq_flags & DMOVER_REQ_WAIT) != 0 && 91 dreq->dreq_callback != NULL) 92 panic("dmover_process: WAIT used with callback"); 93 #endif 94 95 /* Clear unwanted flag bits. */ 96 dreq->dreq_flags &= __DMOVER_REQ_FLAGS_PRESERVE; 97 98 s = splbio(); 99 100 /* XXXLOCK */ 101 102 /* XXX Right now, the back-end is statically assigned. */ 103 das = &dses->__dses_assignment; 104 105 dmb = das->das_backend; 106 dreq->dreq_assignment = das; 107 108 dmover_session_insque(dses, dreq); 109 110 /* XXX Currently, both buffers must be of same type. */ 111 if (das->das_algdesc->dad_ninputs != 0 && 112 dreq->dreq_inbuf_type != dreq->dreq_outbuf_type) { 113 dreq->dreq_error = EINVAL; 114 dreq->dreq_flags |= DMOVER_REQ_ERROR; 115 /* XXXUNLOCK */ 116 splx(s); 117 dmover_done(dreq); 118 return; 119 } 120 121 dmover_backend_insque(dmb, dreq); 122 123 /* XXXUNLOCK */ 124 125 splx(s); 126 127 /* Kick the back-end into action. */ 128 (*dmb->dmb_process)(das->das_backend); 129 130 if (dreq->dreq_flags & DMOVER_REQ_WAIT) { 131 s = splbio(); 132 /* XXXLOCK */ 133 while ((dreq->dreq_flags & DMOVER_REQ_DONE) == 0) 134 (void) tsleep(dreq, PRIBIO, "dmover", 0); 135 /* XXXUNLOCK */ 136 splx(s); 137 } 138 } 139 140 /* 141 * dmover_done: [back-end interface function] 142 * 143 * Back-end notification that the dmover is done. 144 */ 145 void 146 dmover_done(struct dmover_request *dreq) 147 { 148 struct dmover_session *dses = dreq->dreq_session; 149 int s; 150 151 s = splbio(); 152 153 /* XXXLOCK */ 154 155 dmover_session_remque(dses, dreq); 156 /* backend has removed it from its queue */ 157 158 /* XXXUNLOCK */ 159 160 dreq->dreq_flags |= DMOVER_REQ_DONE; 161 dreq->dreq_flags &= ~DMOVER_REQ_RUNNING; 162 dreq->dreq_assignment = NULL; 163 164 if (dreq->dreq_callback != NULL) { 165 simple_lock(&dmover_completed_q_slock); 166 TAILQ_INSERT_TAIL(&dmover_completed_q, dreq, dreq_dmbq); 167 simple_unlock(&dmover_completed_q_slock); 168 softintr_schedule(dmover_completed_si); 169 } else if (dreq->dreq_flags & DMOVER_REQ_WAIT) 170 wakeup(dreq); 171 172 splx(s); 173 } 174 175 /* 176 * dmover_complete: 177 * 178 * Complete a request by invoking the callback. 179 */ 180 void 181 dmover_complete(void *arg) 182 { 183 struct dmover_request *dreq; 184 int s; 185 186 for (;;) { 187 s = splbio(); 188 simple_lock(&dmover_completed_q_slock); 189 if ((dreq = TAILQ_FIRST(&dmover_completed_q)) != NULL) 190 TAILQ_REMOVE(&dmover_completed_q, dreq, dreq_dmbq); 191 simple_unlock(&dmover_completed_q_slock); 192 splx(s); 193 194 if (dreq == NULL) 195 return; 196 197 (*dreq->dreq_callback)(dreq); 198 } 199 } 200