[BACK]Return to puffs_msgif.c CVS log [TXT][DIR] Up to [cvs.NetBSD.org] / src / sys / fs / puffs

Annotation of src/sys/fs/puffs/puffs_msgif.c, Revision 1.12

1.12    ! pooka       1: /*     $NetBSD: puffs_msgif.c,v 1.11 2006/12/10 22:37:04 pooka Exp $   */
1.1       pooka       2:
                      3: /*
                      4:  * Copyright (c) 2005, 2006  Antti Kantee.  All Rights Reserved.
                      5:  *
                      6:  * Development of this software was supported by the
                      7:  * Google Summer of Code program and the Ulla Tuominen Foundation.
                      8:  * The Google SoC project was mentored by Bill Studenmund.
                      9:  *
                     10:  * Redistribution and use in source and binary forms, with or without
                     11:  * modification, are permitted provided that the following conditions
                     12:  * are met:
                     13:  * 1. Redistributions of source code must retain the above copyright
                     14:  *    notice, this list of conditions and the following disclaimer.
                     15:  * 2. Redistributions in binary form must reproduce the above copyright
                     16:  *    notice, this list of conditions and the following disclaimer in the
                     17:  *    documentation and/or other materials provided with the distribution.
                     18:  * 3. The name of the company nor the name of the author may be used to
                     19:  *    endorse or promote products derived from this software without specific
                     20:  *    prior written permission.
                     21:  *
                     22:  * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS
                     23:  * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
                     24:  * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
                     25:  * DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
                     26:  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
                     27:  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
                     28:  * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
                     29:  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
                     30:  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
                     31:  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
                     32:  * SUCH DAMAGE.
                     33:  */
                     34:
                     35: #include <sys/cdefs.h>
1.12    ! pooka      36: __KERNEL_RCSID(0, "$NetBSD: puffs_msgif.c,v 1.11 2006/12/10 22:37:04 pooka Exp $");
1.1       pooka      37:
                     38: #include <sys/param.h>
                     39: #include <sys/malloc.h>
                     40: #include <sys/mount.h>
                     41: #include <sys/vnode.h>
                     42: #include <sys/lock.h>
                     43:
                     44: #include <fs/puffs/puffs_msgif.h>
                     45: #include <fs/puffs/puffs_sys.h>
                     46:
                     47:
                     48: /*
                     49:  * kernel-user-kernel waitqueues
                     50:  */
                     51:
1.4       pooka      52: static int touser(struct puffs_mount *, struct puffs_park *, uint64_t,
1.1       pooka      53:                  struct vnode *, struct vnode *);
                     54:
1.4       pooka      55: uint64_t
1.1       pooka      56: puffs_getreqid(struct puffs_mount *pmp)
                     57: {
                     58:        unsigned int rv;
                     59:
                     60:        simple_lock(&pmp->pmp_lock);
                     61:        rv = pmp->pmp_nextreq++;
                     62:        simple_unlock(&pmp->pmp_lock);
                     63:
                     64:        return rv;
                     65: }
                     66:
                     67: /* vfs request */
                     68: int
                     69: puffs_vfstouser(struct puffs_mount *pmp, int optype, void *kbuf, size_t buflen)
                     70: {
                     71:        struct puffs_park park;
                     72:
1.9       pooka      73:        park.park_preq = kbuf;
1.1       pooka      74:
1.9       pooka      75:        park.park_preq->preq_opclass = PUFFSOP_VFS;
                     76:        park.park_preq->preq_optype = optype;
1.1       pooka      77:
1.9       pooka      78:        park.park_maxlen = park.park_copylen = buflen;
1.1       pooka      79:
                     80:        return touser(pmp, &park, puffs_getreqid(pmp), NULL, NULL);
                     81: }
                     82:
                     83: /*
                     84:  * vnode level request
                     85:  */
                     86: int
                     87: puffs_vntouser(struct puffs_mount *pmp, int optype,
                     88:        void *kbuf, size_t buflen, void *cookie,
                     89:        struct vnode *vp1, struct vnode *vp2)
                     90: {
                     91:        struct puffs_park park;
                     92:
1.9       pooka      93:        park.park_preq = kbuf;
1.1       pooka      94:
1.9       pooka      95:        park.park_preq->preq_opclass = PUFFSOP_VN;
                     96:        park.park_preq->preq_optype = optype;
                     97:        park.park_preq->preq_cookie = cookie;
                     98:
                     99:        park.park_maxlen = park.park_copylen = buflen;
1.1       pooka     100:
                    101:        return touser(pmp, &park, puffs_getreqid(pmp), vp1, vp2);
                    102: }
                    103:
                    104: /*
                    105:  * vnode level request, caller-controller req id
                    106:  */
                    107: int
                    108: puffs_vntouser_req(struct puffs_mount *pmp, int optype,
1.4       pooka     109:        void *kbuf, size_t buflen, void *cookie, uint64_t reqid,
1.1       pooka     110:        struct vnode *vp1, struct vnode *vp2)
                    111: {
                    112:        struct puffs_park park;
                    113:
1.9       pooka     114:        park.park_preq = kbuf;
                    115:
                    116:        park.park_preq->preq_opclass = PUFFSOP_VN;
                    117:        park.park_preq->preq_optype = optype;
                    118:        park.park_preq->preq_cookie = cookie;
1.1       pooka     119:
1.9       pooka     120:        park.park_maxlen = park.park_copylen = buflen;
1.1       pooka     121:
                    122:        return touser(pmp, &park, reqid, vp1, vp2);
                    123: }
                    124:
                    125: /*
1.9       pooka     126:  * vnode level request, copy routines can adjust "kernbuf".
                    127:  * We overload park_copylen != park_maxlen to signal that the park
                    128:  * in question is of adjusting type.
1.1       pooka     129:  */
                    130: int
                    131: puffs_vntouser_adjbuf(struct puffs_mount *pmp, int optype,
1.9       pooka     132:        void **kbuf, size_t *buflen, size_t maxdelta,
                    133:        void *cookie, struct vnode *vp1, struct vnode *vp2)
1.1       pooka     134: {
                    135:        struct puffs_park park;
                    136:        int error;
                    137:
1.9       pooka     138:        park.park_preq = *kbuf;
1.1       pooka     139:
1.9       pooka     140:        park.park_preq->preq_opclass = PUFFSOP_VN;
                    141:        park.park_preq->preq_optype = optype;
                    142:        park.park_preq->preq_cookie = cookie;
                    143:
                    144:        park.park_copylen = *buflen;
                    145:        park.park_maxlen = maxdelta + *buflen;
1.1       pooka     146:
                    147:        error = touser(pmp, &park, puffs_getreqid(pmp), vp1, vp2);
1.9       pooka     148:
                    149:        *kbuf = park.park_preq;
                    150:        *buflen = park.park_copylen;
1.1       pooka     151:
                    152:        return error;
                    153: }
                    154:
                    155: /*
1.4       pooka     156:  * Notice: kbuf will be free'd later.  I must be allocated from the
                    157:  * kernel heap and it's ownership is shifted to this function from
                    158:  * now on, i.e. the caller is not allowed to use it anymore!
                    159:  */
                    160: void
                    161: puffs_vntouser_faf(struct puffs_mount *pmp, int optype,
                    162:        void *kbuf, size_t buflen, void *cookie)
                    163: {
                    164:        struct puffs_park *ppark;
                    165:
                    166:        /* XXX: is it allowable to sleep here? */
                    167:        ppark = malloc(sizeof(struct puffs_park), M_PUFFS, M_NOWAIT | M_ZERO);
                    168:        if (ppark == NULL)
                    169:                return; /* 2bad */
                    170:
1.9       pooka     171:        ppark->park_preq = kbuf;
                    172:
                    173:        ppark->park_preq->preq_opclass = PUFFSOP_VN | PUFFSOPFLAG_FAF;
                    174:        ppark->park_preq->preq_optype = optype;
                    175:        ppark->park_preq->preq_cookie = cookie;
                    176:
                    177:        ppark->park_maxlen = ppark->park_copylen = buflen;
1.4       pooka     178:
                    179:        (void)touser(pmp, ppark, 0, NULL, NULL);
                    180: }
                    181:
                    182: /*
1.1       pooka     183:  * Wait for the userspace ping-pong game in calling process context.
                    184:  *
                    185:  * This unlocks vnodes if they are supplied.  vp1 is the vnode
                    186:  * before in the locking order, i.e. the one which must be locked
                    187:  * before accessing vp2.  This is done here so that operations are
                    188:  * already ordered in the queue when vnodes are unlocked (I'm not
                    189:  * sure if that's really necessary, but it can't hurt).  Okok, maybe
                    190:  * there's a slight ugly-factor also, but let's not worry about that.
                    191:  */
                    192: static int
1.4       pooka     193: touser(struct puffs_mount *pmp, struct puffs_park *ppark, uint64_t reqid,
1.1       pooka     194:        struct vnode *vp1, struct vnode *vp2)
                    195: {
1.9       pooka     196:        struct puffs_req *preq;
1.1       pooka     197:
                    198:        simple_lock(&pmp->pmp_lock);
                    199:        if (pmp->pmp_status != PUFFSTAT_RUNNING
                    200:            && pmp->pmp_status != PUFFSTAT_MOUNTING) {
                    201:                simple_unlock(&pmp->pmp_lock);
                    202:                return ENXIO;
                    203:        }
                    204:
1.9       pooka     205:        preq = ppark->park_preq;
                    206:        preq->preq_id = reqid;
                    207:        preq->preq_buflen = ALIGN(ppark->park_maxlen);
1.1       pooka     208:
1.4       pooka     209:        TAILQ_INSERT_TAIL(&pmp->pmp_req_touser, ppark, park_entries);
1.1       pooka     210:        pmp->pmp_req_touser_waiters++;
                    211:
                    212:        /*
                    213:         * Don't do unlock-relock dance yet.  There are a couple of
                    214:         * unsolved issues with it.  If we don't unlock, we can have
                    215:         * processes wanting vn_lock in case userspace hangs.  But
                    216:         * that can be "solved" by killing the userspace process.  It
                    217:         * would of course be nicer to have antilocking in the userspace
                    218:         * interface protocol itself.. your patience will be rewarded.
                    219:         */
                    220: #if 0
                    221:        /* unlock */
                    222:        if (vp2)
                    223:                VOP_UNLOCK(vp2, 0);
                    224:        if (vp1)
                    225:                VOP_UNLOCK(vp1, 0);
                    226: #endif
                    227:
                    228:        /*
                    229:         * XXX: does releasing the lock here cause trouble?  Can't hold
                    230:         * it, because otherwise the below would cause locking against
1.4       pooka     231:         * oneself-problems in the kqueue stuff.  yes, it is a
                    232:         * theoretical race, so it must be solved
1.1       pooka     233:         */
                    234:        simple_unlock(&pmp->pmp_lock);
                    235:
                    236:        wakeup(&pmp->pmp_req_touser);
                    237:        selnotify(pmp->pmp_sel, 0);
                    238:
1.9       pooka     239:        if (PUFFSOP_WANTREPLY(ppark->park_preq->preq_opclass))
1.4       pooka     240:                ltsleep(ppark, PUSER, "puffs1", 0, NULL);
1.1       pooka     241:
                    242: #if 0
                    243:        /* relock */
                    244:        if (vp1)
                    245:                KASSERT(vn_lock(vp1, LK_EXCLUSIVE | LK_RETRY) == 0);
                    246:        if (vp2)
                    247:                KASSERT(vn_lock(vp2, LK_EXCLUSIVE | LK_RETRY) == 0);
                    248: #endif
                    249:
1.9       pooka     250:        return ppark->park_preq->preq_rv;
1.1       pooka     251: }
                    252:
                    253:
1.9       pooka     254: /*
                    255:  * getop: scan through queued requests until:
                    256:  *  1) max number of requests satisfied
                    257:  *     OR
                    258:  *  2) buffer runs out of space
                    259:  *     OR
                    260:  *  3) nonblocking is set AND there are no operations available
                    261:  *     OR
                    262:  *  4) at least one operation was transferred AND there are no more waiting
                    263:  */
1.10      pooka     264: int
                    265: puffs_getop(struct puffs_mount *pmp, struct puffs_reqh_get *phg, int nonblock)
1.1       pooka     266: {
                    267:        struct puffs_park *park;
1.9       pooka     268:        struct puffs_req *preq;
                    269:        uint8_t *bufpos;
                    270:        int error, donesome;
                    271:
                    272:        donesome = error = 0;
                    273:        bufpos = phg->phg_buf;
1.1       pooka     274:
                    275:        simple_lock(&pmp->pmp_lock);
1.9       pooka     276:        while (phg->phg_nops == 0 || donesome != phg->phg_nops) {
1.1       pooka     277:  again:
1.9       pooka     278:                if (pmp->pmp_status != PUFFSTAT_RUNNING) {
                    279:                        /* if we got some, they don't really matter anymore */
                    280:                        error = ENXIO;
                    281:                        goto out;
                    282:                }
                    283:                if (TAILQ_EMPTY(&pmp->pmp_req_touser)) {
1.12    ! pooka     284:                        if (donesome)
        !           285:                                goto out;
        !           286:
        !           287:                        if (nonblock) {
        !           288:                                error = EWOULDBLOCK;
1.9       pooka     289:                                goto out;
                    290:                        }
                    291:
1.11      pooka     292:                        error = ltsleep(&pmp->pmp_req_touser, PUSER | PCATCH,
                    293:                            "puffs2", 0, &pmp->pmp_lock);
                    294:                        if (error)
                    295:                                goto out;
                    296:                        else
                    297:                                goto again;
1.9       pooka     298:                }
                    299:
                    300:                park = TAILQ_FIRST(&pmp->pmp_req_touser);
                    301:                preq = park->park_preq;
                    302:
                    303:                if (phg->phg_buflen < preq->preq_buflen) {
                    304:                        if (!donesome)
                    305:                                error = E2BIG;
                    306:                        goto out;
                    307:                }
                    308:                TAILQ_REMOVE(&pmp->pmp_req_touser, park, park_entries);
                    309:
1.1       pooka     310:                simple_unlock(&pmp->pmp_lock);
1.9       pooka     311:                DPRINTF(("puffsgetop: get op %" PRIu64 " (%d.), from %p "
                    312:                    "len %zu (buflen %zu), target %p\n", preq->preq_id,
                    313:                    donesome, preq, park->park_copylen, preq->preq_buflen,
                    314:                    bufpos));
                    315:
                    316:                if ((error = copyout(preq, bufpos, park->park_copylen)) != 0) {
                    317:                        DPRINTF(("    FAILED %d\n", error));
                    318:                        /*
                    319:                         * ok, user server is probably trying to cheat.
                    320:                         * stuff op back & return error to user
                    321:                         */
                    322:                         simple_lock(&pmp->pmp_lock);
                    323:                         TAILQ_INSERT_HEAD(&pmp->pmp_req_touser, park,
                    324:                             park_entries);
                    325:
                    326:                         if (donesome)
                    327:                                error = 0;
                    328:                         goto out;
                    329:                }
                    330:                bufpos += preq->preq_buflen;
                    331:                phg->phg_buflen -= preq->preq_buflen;
                    332:                donesome++;
                    333:
                    334:                simple_lock(&pmp->pmp_lock);
                    335:                pmp->pmp_req_touser_waiters--;
                    336:
                    337:                if (PUFFSOP_WANTREPLY(preq->preq_opclass)) {
                    338:                        TAILQ_INSERT_TAIL(&pmp->pmp_req_replywait, park,
                    339:                            park_entries);
                    340:                } else {
1.1       pooka     341:                        simple_unlock(&pmp->pmp_lock);
1.9       pooka     342:                        free(preq, M_PUFFS);
                    343:                        free(park, M_PUFFS);
                    344:                        simple_lock(&pmp->pmp_lock);
1.1       pooka     345:                }
                    346:        }
                    347:
1.9       pooka     348:  out:
                    349:        phg->phg_more = pmp->pmp_req_touser_waiters;
1.1       pooka     350:        simple_unlock(&pmp->pmp_lock);
                    351:
1.9       pooka     352:        phg->phg_nops = donesome;
1.4       pooka     353:
1.9       pooka     354:        return error;
1.1       pooka     355: }
                    356:
1.10      pooka     357: int
                    358: puffs_putop(struct puffs_mount *pmp, struct puffs_reqh_put *php)
1.1       pooka     359: {
                    360:        struct puffs_park *park;
1.9       pooka     361:        void *userbuf;
                    362:        uint64_t id;
                    363:        size_t reqlen;
1.1       pooka     364:        int error;
1.9       pooka     365:        int donesome;
                    366:
                    367:        donesome = error = 0;
                    368:
                    369:        id = php->php_id;
                    370:        userbuf = php->php_buf;
                    371:        reqlen = php->php_buflen;
1.1       pooka     372:
                    373:        simple_lock(&pmp->pmp_lock);
1.9       pooka     374:        while (donesome != php->php_nops) {
                    375: #ifdef DEBUG
                    376:                simple_unlock(&pmp->pmp_lock);
                    377:                DPRINTF(("puffsputop: searching for %" PRIu64 ", ubuf: %p, "
                    378:                    "len %zu\n", id, userbuf, reqlen));
                    379:                simple_lock(&pmp->pmp_lock);
                    380: #endif
                    381:                TAILQ_FOREACH(park, &pmp->pmp_req_replywait, park_entries) {
                    382:                        if (park->park_preq->preq_id == id)
                    383:                                break;
                    384:                }
                    385:
                    386:                if (park == NULL) {
                    387:                        error = EINVAL;
1.1       pooka     388:                        break;
                    389:                }
1.9       pooka     390:                TAILQ_REMOVE(&pmp->pmp_req_replywait, park, park_entries);
                    391:                simple_unlock(&pmp->pmp_lock);
                    392:
                    393:                if (park->park_maxlen != park->park_copylen) {
                    394:                        /* sanitycheck size of incoming transmission. */
                    395:                        if (reqlen > pmp->pmp_req_maxsize) {
                    396:                                DPRINTF(("puffsputop: outrageous user buf "
                    397:                                    "size: %zu\n", reqlen));
                    398:                                error = EINVAL;
                    399:                                goto loopout;
                    400:                        }
1.1       pooka     401:
1.9       pooka     402:                        if (reqlen > park->park_copylen) {
                    403:                                if (reqlen > park->park_maxlen) {
                    404:                                        DPRINTF(("puffsputop: adj copysize "
                    405:                                            "> max size, %zu vs %zu\n",
                    406:                                            reqlen, park->park_maxlen));
                    407:                                        error = EINVAL;
                    408:                                        goto loopout;
                    409:                                }
                    410:                                free(park->park_preq, M_PUFFS);
                    411:                                park->park_preq = malloc(reqlen,
                    412:                                    M_PUFFS, M_WAITOK);
                    413:
                    414:                                park->park_copylen = reqlen;
                    415:                                DPRINTF(("puffsputop: adjbuf, new addr %p, "
                    416:                                    "len %zu\n", park->park_preq, reqlen));
                    417:                        }
                    418:                } else {
                    419:                        if (reqlen == 0 || reqlen > park->park_copylen) {
                    420:                                reqlen = park->park_copylen;
                    421:                                DPRINTF(("puffsputop: kernel bufsize override: "
                    422:                                    "%zu\n", reqlen));
                    423:                        }
                    424:                }
1.1       pooka     425:
1.9       pooka     426:                DPRINTF(("puffsputpop: copyin from %p to %p, len %zu\n",
                    427:                    userbuf, park->park_preq, reqlen));
                    428:                error = copyin(userbuf, park->park_preq, reqlen);
                    429:                if (error)
                    430:                        goto loopout;
                    431:
                    432:                /* all's well, prepare for next op */
                    433:                id = park->park_preq->preq_id;
                    434:                reqlen = park->park_preq->preq_buflen;
                    435:                userbuf = park->park_preq->preq_nextbuf;
                    436:                donesome++;
                    437:
                    438:  loopout:
                    439:                if (error)
                    440:                        park->park_preq->preq_rv = error;
                    441:                wakeup(park);
1.1       pooka     442:
1.9       pooka     443:                simple_lock(&pmp->pmp_lock);
                    444:                if (error)
                    445:                        break;
1.1       pooka     446:        }
                    447:
1.9       pooka     448:        simple_unlock(&pmp->pmp_lock);
                    449:        php->php_nops -= donesome;
1.1       pooka     450:
                    451:        return error;
                    452: }
                    453:
                    454: /* this is probably going to die away at some point? */
1.9       pooka     455: /*
                    456:  * XXX: currently bitrotted
                    457:  */
                    458: #if 0
1.1       pooka     459: static int
                    460: puffssizeop(struct puffs_mount *pmp, struct puffs_sizeop *psop_user)
                    461: {
                    462:        struct puffs_sizepark *pspark;
                    463:        void *kernbuf;
                    464:        size_t copylen;
                    465:        int error;
                    466:
                    467:        /* locate correct op */
                    468:        simple_lock(&pmp->pmp_lock);
                    469:        TAILQ_FOREACH(pspark, &pmp->pmp_req_sizepark, pkso_entries) {
                    470:                if (pspark->pkso_reqid == psop_user->pso_reqid) {
                    471:                        TAILQ_REMOVE(&pmp->pmp_req_sizepark, pspark,
                    472:                            pkso_entries);
                    473:                        break;
                    474:                }
                    475:        }
                    476:        simple_unlock(&pmp->pmp_lock);
                    477:
                    478:        if (pspark == NULL)
                    479:                return EINVAL;
                    480:
                    481:        error = 0;
                    482:        copylen = MIN(pspark->pkso_bufsize, psop_user->pso_bufsize);
                    483:
                    484:        /*
                    485:         * XXX: uvm stuff to avoid bouncy-bouncy copying?
                    486:         */
                    487:        if (PUFFS_SIZEOP_UIO(pspark->pkso_reqtype)) {
                    488:                kernbuf = malloc(copylen, M_PUFFS, M_WAITOK | M_ZERO);
                    489:                if (pspark->pkso_reqtype == PUFFS_SIZEOPREQ_UIO_IN) {
                    490:                        error = copyin(psop_user->pso_userbuf,
                    491:                            kernbuf, copylen);
                    492:                        if (error) {
                    493:                                printf("psop ERROR1 %d\n", error);
                    494:                                goto escape;
                    495:                        }
                    496:                }
                    497:                error = uiomove(kernbuf, copylen, pspark->pkso_uio);
                    498:                if (error) {
                    499:                        printf("uiomove from kernel %p, len %d failed: %d\n",
                    500:                            kernbuf, (int)copylen, error);
                    501:                        goto escape;
                    502:                }
                    503:
                    504:                if (pspark->pkso_reqtype == PUFFS_SIZEOPREQ_UIO_OUT) {
                    505:                        error = copyout(kernbuf,
                    506:                            psop_user->pso_userbuf, copylen);
                    507:                        if (error) {
                    508:                                printf("psop ERROR2 %d\n", error);
                    509:                                goto escape;
                    510:                        }
                    511:                }
                    512:  escape:
                    513:                free(kernbuf, M_PUFFS);
                    514:        } else if (PUFFS_SIZEOP_BUF(pspark->pkso_reqtype)) {
                    515:                copylen = MAX(pspark->pkso_bufsize, psop_user->pso_bufsize);
                    516:                if (pspark->pkso_reqtype == PUFFS_SIZEOPREQ_BUF_IN) {
                    517:                        error = copyin(psop_user->pso_userbuf,
                    518:                        pspark->pkso_copybuf, copylen);
                    519:                } else {
                    520:                        error = copyout(pspark->pkso_copybuf,
                    521:                            psop_user->pso_userbuf, copylen);
                    522:                }
                    523:        }
                    524: #ifdef DIAGNOSTIC
                    525:        else
                    526:                panic("puffssizeop: invalid reqtype %d\n",
                    527:                    pspark->pkso_reqtype);
                    528: #endif /* DIAGNOSTIC */
                    529:
                    530:        return error;
                    531: }
1.9       pooka     532: #endif

CVSweb <webmaster@jp.NetBSD.org>