1 /* $NetBSD: dmover_process.c,v 1.3 2007/10/08 16:18:03 ad 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.3 2007/10/08 16:18:03 ad 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