Expand PMF_FN_* macros.
[netbsd-mini2440.git] / sys / dev / dmover / swdmover.c
blobc16edb51fc0b2341b125d9c49c1fac531db798a6
1 /* $NetBSD: swdmover.c,v 1.11 2007/07/12 14:15:55 he Exp $ */
3 /*
4 * Copyright (c) 2002, 2003 Wasabi Systems, Inc.
5 * All rights reserved.
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
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.
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 * swdmover.c: Software back-end providing the dmover functions
40 * mentioned in dmover(9).
42 * This module provides a fallback for cases where no hardware
43 * data movers are present in a system, and also serves an an
44 * example of how to write a dmover back-end.
46 * Note that even through the software dmover doesn't require
47 * interrupts to be blocked, we block them anyway to demonstrate
48 * the locking protocol.
51 #include <sys/cdefs.h>
52 __KERNEL_RCSID(0, "$NetBSD: swdmover.c,v 1.11 2007/07/12 14:15:55 he Exp $");
54 #include <sys/param.h>
55 #include <sys/kthread.h>
56 #include <sys/systm.h>
57 #include <sys/uio.h>
59 #include <dev/dmover/dmovervar.h>
61 struct swdmover_function {
62 void (*sdf_process)(struct dmover_request *);
65 static struct dmover_backend swdmover_backend;
66 static struct lwp *swdmover_lwp;
67 static int swdmover_cv;
69 void swdmoverattach(int);
72 * swdmover_process:
74 * Dmover back-end entry point.
76 static void
77 swdmover_process(struct dmover_backend *dmb)
79 int s;
82 * Just wake up the processing thread. This will allow
83 * requests to linger on the middle-end's queue so that
84 * they can be cancelled, if need-be.
86 s = splbio();
87 /* XXXLOCK */
88 if (TAILQ_EMPTY(&dmb->dmb_pendreqs) == 0)
89 wakeup(&swdmover_cv);
90 /* XXXUNLOCK */
91 splx(s);
95 * swdmover_thread:
97 * Request processing thread.
99 static void
100 swdmover_thread(void *arg)
102 struct dmover_backend *dmb = arg;
103 struct dmover_request *dreq;
104 struct swdmover_function *sdf;
105 int s;
107 s = splbio();
108 /* XXXLOCK */
110 for (;;) {
111 dreq = TAILQ_FIRST(&dmb->dmb_pendreqs);
112 if (dreq == NULL) {
113 /* XXXUNLOCK */
114 (void) tsleep(&swdmover_cv, PRIBIO, "swdmvr", 0);
115 continue;
118 dmover_backend_remque(dmb, dreq);
119 dreq->dreq_flags |= DMOVER_REQ_RUNNING;
121 /* XXXUNLOCK */
122 splx(s);
124 sdf = dreq->dreq_assignment->das_algdesc->dad_data;
125 (*sdf->sdf_process)(dreq);
127 s = splbio();
128 /* XXXLOCK */
133 * swdmover_func_zero_process:
135 * Processing routine for the "zero" function.
137 static void
138 swdmover_func_zero_process(struct dmover_request *dreq)
141 switch (dreq->dreq_outbuf_type) {
142 case DMOVER_BUF_LINEAR:
143 memset(dreq->dreq_outbuf.dmbuf_linear.l_addr, 0,
144 dreq->dreq_outbuf.dmbuf_linear.l_len);
145 break;
147 case DMOVER_BUF_UIO:
149 struct uio *uio = dreq->dreq_outbuf.dmbuf_uio;
150 char *cp;
151 size_t count, buflen;
152 int error;
154 if (uio->uio_rw != UIO_READ) {
155 /* XXXLOCK */
156 dreq->dreq_error = EINVAL;
157 dreq->dreq_flags |= DMOVER_REQ_ERROR;
158 /* XXXUNLOCK */
159 break;
162 buflen = uio->uio_resid;
163 if (buflen > 1024)
164 buflen = 1024;
165 cp = alloca(buflen);
166 memset(cp, 0, buflen);
168 while ((count = uio->uio_resid) != 0) {
169 if (count > buflen)
170 count = buflen;
171 error = uiomove(cp, count, uio);
172 if (error) {
173 /* XXXLOCK */
174 dreq->dreq_error = error;
175 dreq->dreq_flags |= DMOVER_REQ_ERROR;
176 /* XXXUNLOCK */
177 break;
180 break;
183 default:
184 /* XXXLOCK */
185 dreq->dreq_error = EINVAL;
186 dreq->dreq_flags |= DMOVER_REQ_ERROR;
187 /* XXXUNLOCK */
190 dmover_done(dreq);
194 * swdmover_func_fill8_process:
196 * Processing routine for the "fill8" function.
198 static void
199 swdmover_func_fill8_process(struct dmover_request *dreq)
202 switch (dreq->dreq_outbuf_type) {
203 case DMOVER_BUF_LINEAR:
204 memset(dreq->dreq_outbuf.dmbuf_linear.l_addr,
205 dreq->dreq_immediate[0],
206 dreq->dreq_outbuf.dmbuf_linear.l_len);
207 break;
209 case DMOVER_BUF_UIO:
211 struct uio *uio = dreq->dreq_outbuf.dmbuf_uio;
212 char *cp;
213 size_t count, buflen;
214 int error;
216 if (uio->uio_rw != UIO_READ) {
217 /* XXXLOCK */
218 dreq->dreq_error = EINVAL;
219 dreq->dreq_flags |= DMOVER_REQ_ERROR;
220 /* XXXUNLOCK */
221 break;
224 buflen = uio->uio_resid;
225 if (buflen > 1024)
226 buflen = 1024;
227 cp = alloca(buflen);
228 memset(cp, dreq->dreq_immediate[0], buflen);
230 while ((count = uio->uio_resid) != 0) {
231 if (count > buflen)
232 count = buflen;
233 error = uiomove(cp, count, uio);
234 if (error) {
235 /* XXXLOCK */
236 dreq->dreq_error = error;
237 dreq->dreq_flags |= DMOVER_REQ_ERROR;
238 /* XXXUNLOCK */
239 break;
242 break;
245 default:
246 /* XXXLOCK */
247 dreq->dreq_error = EINVAL;
248 dreq->dreq_flags |= DMOVER_REQ_ERROR;
249 /* XXXUNLOCK */
252 dmover_done(dreq);
255 static void
256 xor2(uint8_t *dst, uint8_t *src1, uint8_t *src2, int cnt)
259 while (cnt--)
260 *dst++ = *src1++ ^ *src2++;
264 * swdmover_func_xor_process:
266 * Processing routine for the "xor" function.
268 static void
269 swdmover_func_xor_process(struct dmover_request *dreq)
271 #define INBUF_L(x) dreq->dreq_inbuf[(x)].dmbuf_linear
272 #define OUTBUF_L dreq->dreq_outbuf.dmbuf_linear
274 uint32_t *dst32, *src32;
275 uint8_t *dst8, *src8;
276 int i, ninputs = dreq->dreq_assignment->das_algdesc->dad_ninputs;
277 int aligned, len, nwords;
279 /* XXX Currently, both buffers must be of same type. */
280 if (dreq->dreq_inbuf_type != dreq->dreq_outbuf_type) {
281 /* XXXLOCK */
282 dreq->dreq_error = EINVAL;
283 dreq->dreq_flags |= DMOVER_REQ_ERROR;
284 /* XXXUNLOCK */
285 goto done;
288 switch (dreq->dreq_outbuf_type) {
289 case DMOVER_BUF_LINEAR:
290 aligned = 1;
291 if ((ulong) OUTBUF_L.l_addr & 0x3)
292 aligned = 0;
293 len = OUTBUF_L.l_len;
294 for (i = 0 ; i < ninputs ; i++) {
295 if (len != INBUF_L(i).l_len) {
296 /* XXXLOCK */
297 dreq->dreq_error = EINVAL;
298 dreq->dreq_flags |= DMOVER_REQ_ERROR;
299 /* XXXUNLOCK */
300 break;
302 if ((ulong) INBUF_L(i).l_addr & 0x3)
303 aligned = 0;
305 if (aligned) {
306 dst32 = (uint32_t *) OUTBUF_L.l_addr;
307 nwords = len / 4;
308 while (nwords--) {
309 *dst32 = 0;
310 for (i = 0 ; i < ninputs ; i++) {
311 src32 = (uint32_t *) INBUF_L(i).l_addr;
312 *dst32 ^= *src32;
314 dst32++;
315 len -= 4;
318 if (len) {
319 dst8 = (uint8_t *) OUTBUF_L.l_addr;
320 while (len--) {
321 *dst8 = 0;
322 for (i = 0 ; i < ninputs ; i++) {
323 src8 = (uint8_t *) INBUF_L(i).l_addr;
324 *dst8 ^= *src8;
326 dst8++;
330 break;
332 case DMOVER_BUF_UIO:
334 struct uio *uio_out = dreq->dreq_outbuf.dmbuf_uio;
335 struct uio *uio_in = dreq->dreq_inbuf[0].dmbuf_uio;
336 struct uio *uio;
337 char *cp, *dst;
338 size_t count, buflen;
339 int error;
341 if (uio_in->uio_rw != UIO_WRITE ||
342 uio_out->uio_rw != UIO_READ ||
343 uio_in->uio_resid != uio_out->uio_resid) {
344 /* XXXLOCK */
345 dreq->dreq_error = EINVAL;
346 dreq->dreq_flags |= DMOVER_REQ_ERROR;
347 /* XXXUNLOCK */
348 break;
351 buflen = uio_in->uio_resid;
352 if (buflen > 1024)
353 buflen = 1024;
354 cp = alloca(buflen);
355 dst = alloca(buflen);
358 * For each block, copy first input buffer into the destination
359 * buffer and then read the rest, one by one, into a temporary
360 * buffer and xor into the destination buffer. After all of
361 * the inputs have been xor'd in, move the destination buffer
362 * out and loop.
364 while ((count = uio_in->uio_resid) != 0) {
365 if (count > buflen)
366 count = buflen;
367 error = uiomove(dst, count, uio_in);
368 if (error) {
369 /* XXXLOCK */
370 dreq->dreq_error = error;
371 dreq->dreq_flags |= DMOVER_REQ_ERROR;
372 /* XXXUNLOCK */
373 break;
375 for (i=1 ; (i < ninputs) && (error == 0) ; i++) {
376 uio = dreq->dreq_inbuf[i].dmbuf_uio;
377 error = uiomove(cp, count, uio);
378 if (error == 0) {
379 xor2(dst, dst, cp, count);
382 if (error == 0) {
383 error = uiomove(dst, count, uio_out);
384 } else {
385 /* XXXLOCK */
386 dreq->dreq_error = error;
387 dreq->dreq_flags |= DMOVER_REQ_ERROR;
388 /* XXXUNLOCK */
389 break;
392 break;
395 default:
396 /* XXXLOCK */
397 dreq->dreq_error = EINVAL;
398 dreq->dreq_flags |= DMOVER_REQ_ERROR;
399 /* XXXUNLOCK */
402 done:
403 dmover_done(dreq);
407 * swdmover_func_copy_process:
409 * Processing routine for the "copy" function.
411 static void
412 swdmover_func_copy_process(struct dmover_request *dreq)
415 /* XXX Currently, both buffers must be of same type. */
416 if (dreq->dreq_inbuf_type != dreq->dreq_outbuf_type) {
417 /* XXXLOCK */
418 dreq->dreq_error = EINVAL;
419 dreq->dreq_flags |= DMOVER_REQ_ERROR;
420 /* XXXUNLOCK */
421 goto done;
424 switch (dreq->dreq_outbuf_type) {
425 case DMOVER_BUF_LINEAR:
426 if (dreq->dreq_outbuf.dmbuf_linear.l_len !=
427 dreq->dreq_inbuf[0].dmbuf_linear.l_len) {
428 /* XXXLOCK */
429 dreq->dreq_error = EINVAL;
430 dreq->dreq_flags |= DMOVER_REQ_ERROR;
431 /* XXXUNLOCK */
432 break;
434 memcpy(dreq->dreq_outbuf.dmbuf_linear.l_addr,
435 dreq->dreq_inbuf[0].dmbuf_linear.l_addr,
436 dreq->dreq_outbuf.dmbuf_linear.l_len);
437 break;
439 case DMOVER_BUF_UIO:
441 struct uio *uio_out = dreq->dreq_outbuf.dmbuf_uio;
442 struct uio *uio_in = dreq->dreq_inbuf[0].dmbuf_uio;
443 char *cp;
444 size_t count, buflen;
445 int error;
447 if (uio_in->uio_rw != UIO_WRITE ||
448 uio_out->uio_rw != UIO_READ ||
449 uio_in->uio_resid != uio_out->uio_resid) {
450 /* XXXLOCK */
451 dreq->dreq_error = EINVAL;
452 dreq->dreq_flags |= DMOVER_REQ_ERROR;
453 /* XXXUNLOCK */
454 break;
457 buflen = uio_in->uio_resid;
458 if (buflen > 1024)
459 buflen = 1024;
460 cp = alloca(buflen);
462 while ((count = uio_in->uio_resid) != 0) {
463 if (count > buflen)
464 count = buflen;
465 error = uiomove(cp, count, uio_in);
466 if (error == 0)
467 error = uiomove(cp, count, uio_out);
468 if (error) {
469 /* XXXLOCK */
470 dreq->dreq_error = error;
471 dreq->dreq_flags |= DMOVER_REQ_ERROR;
472 /* XXXUNLOCK */
473 break;
476 break;
479 default:
480 /* XXXLOCK */
481 dreq->dreq_error = EINVAL;
482 dreq->dreq_flags |= DMOVER_REQ_ERROR;
483 /* XXXUNLOCK */
486 done:
487 dmover_done(dreq);
490 static const uint32_t iscsi_crc32c_table[256] = {
491 0x00000000, 0xf26b8303, 0xe13b70f7, 0x1350f3f4,
492 0xc79a971f, 0x35f1141c, 0x26a1e7e8, 0xd4ca64eb,
493 0x8ad958cf, 0x78b2dbcc, 0x6be22838, 0x9989ab3b,
494 0x4d43cfd0, 0xbf284cd3, 0xac78bf27, 0x5e133c24,
495 0x105ec76f, 0xe235446c, 0xf165b798, 0x030e349b,
496 0xd7c45070, 0x25afd373, 0x36ff2087, 0xc494a384,
497 0x9a879fa0, 0x68ec1ca3, 0x7bbcef57, 0x89d76c54,
498 0x5d1d08bf, 0xaf768bbc, 0xbc267848, 0x4e4dfb4b,
499 0x20bd8ede, 0xd2d60ddd, 0xc186fe29, 0x33ed7d2a,
500 0xe72719c1, 0x154c9ac2, 0x061c6936, 0xf477ea35,
501 0xaa64d611, 0x580f5512, 0x4b5fa6e6, 0xb93425e5,
502 0x6dfe410e, 0x9f95c20d, 0x8cc531f9, 0x7eaeb2fa,
503 0x30e349b1, 0xc288cab2, 0xd1d83946, 0x23b3ba45,
504 0xf779deae, 0x05125dad, 0x1642ae59, 0xe4292d5a,
505 0xba3a117e, 0x4851927d, 0x5b016189, 0xa96ae28a,
506 0x7da08661, 0x8fcb0562, 0x9c9bf696, 0x6ef07595,
507 0x417b1dbc, 0xb3109ebf, 0xa0406d4b, 0x522bee48,
508 0x86e18aa3, 0x748a09a0, 0x67dafa54, 0x95b17957,
509 0xcba24573, 0x39c9c670, 0x2a993584, 0xd8f2b687,
510 0x0c38d26c, 0xfe53516f, 0xed03a29b, 0x1f682198,
511 0x5125dad3, 0xa34e59d0, 0xb01eaa24, 0x42752927,
512 0x96bf4dcc, 0x64d4cecf, 0x77843d3b, 0x85efbe38,
513 0xdbfc821c, 0x2997011f, 0x3ac7f2eb, 0xc8ac71e8,
514 0x1c661503, 0xee0d9600, 0xfd5d65f4, 0x0f36e6f7,
515 0x61c69362, 0x93ad1061, 0x80fde395, 0x72966096,
516 0xa65c047d, 0x5437877e, 0x4767748a, 0xb50cf789,
517 0xeb1fcbad, 0x197448ae, 0x0a24bb5a, 0xf84f3859,
518 0x2c855cb2, 0xdeeedfb1, 0xcdbe2c45, 0x3fd5af46,
519 0x7198540d, 0x83f3d70e, 0x90a324fa, 0x62c8a7f9,
520 0xb602c312, 0x44694011, 0x5739b3e5, 0xa55230e6,
521 0xfb410cc2, 0x092a8fc1, 0x1a7a7c35, 0xe811ff36,
522 0x3cdb9bdd, 0xceb018de, 0xdde0eb2a, 0x2f8b6829,
523 0x82f63b78, 0x709db87b, 0x63cd4b8f, 0x91a6c88c,
524 0x456cac67, 0xb7072f64, 0xa457dc90, 0x563c5f93,
525 0x082f63b7, 0xfa44e0b4, 0xe9141340, 0x1b7f9043,
526 0xcfb5f4a8, 0x3dde77ab, 0x2e8e845f, 0xdce5075c,
527 0x92a8fc17, 0x60c37f14, 0x73938ce0, 0x81f80fe3,
528 0x55326b08, 0xa759e80b, 0xb4091bff, 0x466298fc,
529 0x1871a4d8, 0xea1a27db, 0xf94ad42f, 0x0b21572c,
530 0xdfeb33c7, 0x2d80b0c4, 0x3ed04330, 0xccbbc033,
531 0xa24bb5a6, 0x502036a5, 0x4370c551, 0xb11b4652,
532 0x65d122b9, 0x97baa1ba, 0x84ea524e, 0x7681d14d,
533 0x2892ed69, 0xdaf96e6a, 0xc9a99d9e, 0x3bc21e9d,
534 0xef087a76, 0x1d63f975, 0x0e330a81, 0xfc588982,
535 0xb21572c9, 0x407ef1ca, 0x532e023e, 0xa145813d,
536 0x758fe5d6, 0x87e466d5, 0x94b49521, 0x66df1622,
537 0x38cc2a06, 0xcaa7a905, 0xd9f75af1, 0x2b9cd9f2,
538 0xff56bd19, 0x0d3d3e1a, 0x1e6dcdee, 0xec064eed,
539 0xc38d26c4, 0x31e6a5c7, 0x22b65633, 0xd0ddd530,
540 0x0417b1db, 0xf67c32d8, 0xe52cc12c, 0x1747422f,
541 0x49547e0b, 0xbb3ffd08, 0xa86f0efc, 0x5a048dff,
542 0x8ecee914, 0x7ca56a17, 0x6ff599e3, 0x9d9e1ae0,
543 0xd3d3e1ab, 0x21b862a8, 0x32e8915c, 0xc083125f,
544 0x144976b4, 0xe622f5b7, 0xf5720643, 0x07198540,
545 0x590ab964, 0xab613a67, 0xb831c993, 0x4a5a4a90,
546 0x9e902e7b, 0x6cfbad78, 0x7fab5e8c, 0x8dc0dd8f,
547 0xe330a81a, 0x115b2b19, 0x020bd8ed, 0xf0605bee,
548 0x24aa3f05, 0xd6c1bc06, 0xc5914ff2, 0x37faccf1,
549 0x69e9f0d5, 0x9b8273d6, 0x88d28022, 0x7ab90321,
550 0xae7367ca, 0x5c18e4c9, 0x4f48173d, 0xbd23943e,
551 0xf36e6f75, 0x0105ec76, 0x12551f82, 0xe03e9c81,
552 0x34f4f86a, 0xc69f7b69, 0xd5cf889d, 0x27a40b9e,
553 0x79b737ba, 0x8bdcb4b9, 0x988c474d, 0x6ae7c44e,
554 0xbe2da0a5, 0x4c4623a6, 0x5f16d052, 0xad7d5351,
557 static uint32_t
558 iscsi_crc32c(const uint8_t *buf, size_t len, uint32_t last)
560 uint32_t crc = 0xffffffffU ^ last;
562 while (len--)
563 crc = iscsi_crc32c_table[(crc ^ *buf++) & 0xff] ^ (crc >> 8);
565 return (crc ^ 0xffffffffU);
569 * swdmover_func_iscsi_crc32c_process:
571 * Processing routine for the "iscsi-crc32c" function.
573 static void
574 swdmover_func_iscsi_crc32c_process(struct dmover_request *dreq)
576 uint32_t result;
578 /* No output buffer; we use the immediate only. */
579 if (dreq->dreq_outbuf_type != DMOVER_BUF_NONE) {
580 /* XXXLOCK */
581 dreq->dreq_error = EINVAL;
582 dreq->dreq_flags |= DMOVER_REQ_ERROR;
583 /* XXXUNLOCK */
584 goto done;
587 memcpy(&result, dreq->dreq_immediate, sizeof(result));
589 switch (dreq->dreq_inbuf_type) {
590 case DMOVER_BUF_LINEAR:
591 result = iscsi_crc32c(dreq->dreq_inbuf[0].dmbuf_linear.l_addr,
592 dreq->dreq_inbuf[0].dmbuf_linear.l_len, result);
593 break;
595 case DMOVER_BUF_UIO:
597 struct uio *uio_in = dreq->dreq_inbuf[0].dmbuf_uio;
598 uint8_t *cp;
599 size_t count, buflen;
600 int error;
602 if (uio_in->uio_rw != UIO_WRITE) {
603 /* XXXLOCK */
604 dreq->dreq_error = EINVAL;
605 dreq->dreq_flags |= DMOVER_REQ_ERROR;
606 /* XXXUNLOCK */
607 goto done;
610 buflen = uio_in->uio_resid;
611 if (buflen > 1024)
612 buflen = 1024;
613 cp = alloca(buflen);
615 while ((count = uio_in->uio_resid) != 0) {
616 if (count > buflen)
617 count = buflen;
618 error = uiomove(cp, count, uio_in);
619 if (error) {
620 /* XXXLOCK */
621 dreq->dreq_error = error;
622 dreq->dreq_flags |= DMOVER_REQ_ERROR;
623 /* XXXUNLOCK */
624 goto done;
625 } else
626 result = iscsi_crc32c(cp, count, result);
628 break;
631 default:
632 /* XXXLOCK */
633 dreq->dreq_error = EINVAL;
634 dreq->dreq_flags |= DMOVER_REQ_ERROR;
635 /* XXXUNLOCK */
636 goto done;
639 memcpy(dreq->dreq_immediate, &result, sizeof(result));
640 done:
641 dmover_done(dreq);
644 static struct swdmover_function swdmover_func_zero = {
645 swdmover_func_zero_process
648 static struct swdmover_function swdmover_func_fill8 = {
649 swdmover_func_fill8_process
652 static struct swdmover_function swdmover_func_copy = {
653 swdmover_func_copy_process
656 static struct swdmover_function swdmover_func_xor = {
657 swdmover_func_xor_process
660 static struct swdmover_function swdmover_func_iscsi_crc32c = {
661 swdmover_func_iscsi_crc32c_process
664 const struct dmover_algdesc swdmover_algdescs[] = {
666 DMOVER_FUNC_XOR2,
667 &swdmover_func_xor,
671 DMOVER_FUNC_XOR3,
672 &swdmover_func_xor,
676 DMOVER_FUNC_XOR4,
677 &swdmover_func_xor,
681 DMOVER_FUNC_XOR5,
682 &swdmover_func_xor,
686 DMOVER_FUNC_XOR6,
687 &swdmover_func_xor,
691 DMOVER_FUNC_XOR7,
692 &swdmover_func_xor,
696 DMOVER_FUNC_XOR8,
697 &swdmover_func_xor,
701 DMOVER_FUNC_ZERO,
702 &swdmover_func_zero,
706 DMOVER_FUNC_FILL8,
707 &swdmover_func_fill8,
711 DMOVER_FUNC_COPY,
712 &swdmover_func_copy,
716 DMOVER_FUNC_ISCSI_CRC32C,
717 &swdmover_func_iscsi_crc32c,
721 #define SWDMOVER_ALGDESC_COUNT \
722 (sizeof(swdmover_algdescs) / sizeof(swdmover_algdescs[0]))
725 * swdmoverattach:
727 * Pesudo-device attach routine.
729 void
730 swdmoverattach(int count)
732 int error;
734 swdmover_backend.dmb_name = "swdmover";
735 swdmover_backend.dmb_speed = 1; /* XXX */
736 swdmover_backend.dmb_cookie = NULL;
737 swdmover_backend.dmb_algdescs = swdmover_algdescs;
738 swdmover_backend.dmb_nalgdescs = SWDMOVER_ALGDESC_COUNT;
739 swdmover_backend.dmb_process = swdmover_process;
741 error = kthread_create(PRI_NONE, 0, NULL, swdmover_thread,
742 &swdmover_backend, &swdmover_lwp, "swdmover");
743 if (error)
744 printf("WARNING: unable to create swdmover thread, "
745 "error = %d\n", error);
747 /* XXX Should only register this when kthread creation succeeds. */
748 dmover_backend_register(&swdmover_backend);