Annotation of cci/sys/bsc/bscm.c, revision 1.1

1.1     ! root        1: /*     D.L.Buck and Associates, Inc. - 9/4/84
        !             2:  *
        !             3:  *     COPYRIGHT NOTICE:
        !             4:  *             Copyright c 9/4/84 - An unpublished work by
        !             5:  *             D.L.Buck and Associates, Inc.
        !             6:  *
        !             7:  *     PROPRIETARY RIGHTS NOTICE:
        !             8:  *             All rights reserved. This document and program contains
        !             9:  *             proprietary information of D.L.Buck and Associates,Inc.
        !            10:  *             of San Jose, California, U.S.A., embodying confidential
        !            11:  *             information,  ideas, and expressions,  no part of which
        !            12:  *             may be reproduced, or transmitted in any form or by any
        !            13:  *             means,  electronic,  mechanical,  or otherwise, without
        !            14:  *             the written permission of D.L.Buck and Associates, Inc.
        !            15:  *
        !            16:  * NAME
        !            17:  *     bsm - multi-station bisync device driver
        !            18:  *
        !            19:  * DESCRIPTION
        !            20:  *     This file contains the Unix system interface routines, prepared for
        !            21:  *     UNIX Version 7, System III, System V, or BSD 4.2.
        !            22:  *     The entry points are bsmopen, bsmclose, bsmread, bsmwrite, and
        !            23:  *     bsmioctl.  These routines are meant to be hardware-independent.
        !            24:  */
        !            25: 
        !            26: #ifndef lint
        !            27: static char bsm_c[] = "@(#)bscm.c      1.17 REL";
        !            28: #endif
        !            29: 
        !            30: #include "../bsc/local.h"
        !            31: #include "../bsc/bscio.h"
        !            32: #include "../bsc/bsc.h"
        !            33: 
        !            34: #if defined v7 || defined BSD42
        !            35: #define        delay(x)        sleep((caddr_t)&lbolt, BSCPRI)
        !            36: extern int lbolt;
        !            37: #endif
        !            38: 
        !            39: #if defined BSD42
        !            40: #define ERRRET(x)      return x
        !            41: #define        UCOUNT  uio->uio_resid
        !            42: #else
        !            43: #define        ERRRET(x)       u.u_error = x; return
        !            44: #define        UCOUNT  u.u_count
        !            45: #endif
        !            46: 
        !            47: 
        !            48: /***
        !            49: #define DEV(dev)  (minor(dev) >> 5) & 0x7
        !            50: #define SUBDEV(dev)  minor(dev) & 0x1f
        !            51: ***/
        !            52: 
        !            53: #define DEV(dev)  (minor(dev) >> 4) & 0xf
        !            54: #define SUBDEV(dev)  minor(dev) & 0xf
        !            55: 
        !            56: extern struct state states[];          /* state table in bscpsm.c */
        !            57: #ifdef NBSM
        !            58: extern struct bsc bsc[];               /* device-specific information */
        !            59: struct bscsub bscsubs[NVBSC*NBSM][NBSSUB];
        !            60: 
        !            61: /*
        !            62:  *     DEVICE ADDRESSING TABLES
        !            63:  *             For device numbers 0 - 31, the tables hold the corresponding
        !            64:  *             EBCDIC (ebcdev) or ASCII (ascdev) address
        !            65:  */
        !            66: 
        !            67: 
        !            68: char ascdev[] = {0x20,0x41,0x42,0x43,0x44,0x45,0x46,0x47,
        !            69:                 0x48,0x49,0x5b,0x2e,0x3c,0x28,0x2b,0x21,
        !            70:                 0x26,0x4a,0x4b,0x4c,0x4d,0x4e,0x4f,0x50,
        !            71:                0x51,0x52,0x5d,0x24,0x2a,0x29,0x3b,0x5e};
        !            72: 
        !            73: char ebcdev[] = {0x40,0xc1,0xc2,0xc3,0xc4,0xc5,0xc6,0xc7,
        !            74:                 0xc8,0xc9,0x4a,0x4b,0x4c,0x4d,0x4e,0x4f,
        !            75:                 0x50,0xd1,0xd2,0xd3,0xd4,0xd5,0xd6,0xd7,
        !            76:                0xd8,0xd9,0x5a,0x5b,0x5c,0x5d,0x5e,0x5f};
        !            77: /*
        !            78:  * NAME
        !            79:  *     bsmopen -- Prepare for BISYNC communications, multistation mode
        !            80:  * SYNOPSIS
        !            81:  *     bsmopen (dev, flag)
        !            82:  *     dev_t dev;              minor device number:
        !            83:  *                             bits 7-5: modem port number
        !            84:  *                             bits 4-0: station number, 0-31
        !            85:  *     int flag;               unused
        !            86:  * ALGORITHM
        !            87:  *     1. Check and lock device.
        !            88:  *     2. If first station to open on this line, do line initialization
        !            89:  *             2.1 Set up defaults for ioctl-provided params
        !            90:  *             2.2 Set up counters and fields returned via ioctl
        !            91:  *             2.3 Set up miscellaneous fields for driver
        !            92:  *             2.4 Initialize I/O port
        !            93:  *     3. Wait till DSR shows
        !            94:  *     4. If tracing activated, awaken bstopen
        !            95:  */
        !            96: 
        !            97: /* VARARGS1 */
        !            98: bsmopen (dev)                          /* prepare for BISYNC communication */
        !            99: dev_t dev;
        !           100: {
        !           101:        register dev_t bscdev;          /* modem port number */
        !           102:        register struct bsc *bp;        /* ptr to port's bsc entry */
        !           103:        register int subdev;            /* station number */
        !           104:        register struct bscsub *bpsub;  /* ptr to station's bscsubs entry */
        !           105:        int errcode;
        !           106: 
        !           107:        /* 1. Check and lock device. */
        !           108:        bscdev = DEV(dev);
        !           109:        subdev = SUBDEV(dev);
        !           110: 
        !           111:        if (bscdev >= MX_NBSM || subdev >= NBSSUB){
        !           112:                ERRRET(ENXIO);  /* no such device */
        !           113:        }
        !           114:        bp = &bsc[bscdev];
        !           115:        bpsub = &bscsubs[bscdev][subdev];
        !           116:        if ((bp->b_lock == SSLOCK) ||   /* line opened for point to point */
        !           117:            (bpsub->bs_mode != BS_FREE)) {      /* subdevice busy */
        !           118:                ERRRET(EBUSY);
        !           119:        }
        !           120:        bpsub->bs_mode = BS_IDLE;
        !           121:        bpsub->bs_sema = BSC_DDONE | BSC_PDONE;
        !           122: 
        !           123:        /* 2. If first station to open on this line, do line initialization */
        !           124:        if (++bp->b_lock == 1) {        /* First one initializes */
        !           125: 
        !           126:                /* 2.1 Set up defaults for ioctl-provided params */
        !           127:                bp->b_iocin.b_blks = BSCMBLK;   /* max block size */
        !           128:                bp->b_hlflgs = BSCMPT;          /* flags: we are multipoint */
        !           129:                bp->b_iocin.b_termid[0] = '\0'; /* no terminal id */
        !           130:                bp->b_iocin.b_hostid[0] = '\0'; /* no host id */
        !           131:                bp->b_iocin.b_nbid =            /* max # bids */
        !           132:                bp->b_iocin.b_nnak =            /* max # naks we will give */
        !           133:                bp->b_iocin.b_nretry = 15;      /* max # rcv t/o's and naks */
        !           134:                                                /*       we will accept */
        !           135:                bp->b_iocin.b_nttd =            /* max # ttds we will accept */
        !           136:                bp->b_iocin.b_nwack = 100;      /* max # wacks we will accept */
        !           137:                bp->b_iocin.b_nor = 30;         /* max time to wait on */
        !           138:                                                /* initial rd */
        !           139: 
        !           140:                /* 2.2 Set up counters and fields returned via ioctl */
        !           141:                bp->b_iocout.b_blks = 0;        /* # blocks sent/received */
        !           142:                bp->b_iocout.b_flags = 0;       /* flags: see definition */
        !           143:                bp->b_iocout.b_termid[0] = '\0';/* no terminal id */
        !           144:                bp->b_iocout.b_hostid[0] = '\0';/* no host id */
        !           145:                bp->b_iocout.b_nbid = 0;        /* no bids so far */
        !           146:                bp->b_iocout.b_nnak = 0;        /* no naks so far */
        !           147:                bp->b_iocout.b_nretry = 0;      /* no retry so far */
        !           148:                bp->b_iocout.b_nttd = 0;        /* no ttds so far */
        !           149:                bp->b_iocout.b_nwack = 0;       /* no wacks so far */
        !           150:                bp->b_iocout.b_nor = 0;         /* no overruns so far */
        !           151: 
        !           152:                /* 2.3 Set up miscellaneous fields for driver */
        !           153:                bp->b_state = 0;                /* set initial psm state*/
        !           154:                bp->b_mode = BSC_INIT;          /* initial mode indicates */
        !           155:                                                /* haven't done any i/o yet */
        !           156:                bp->b_psmbsy = -1;              /* no device selected */
        !           157:                bp->b_rxst0 = 0;                /* reset l/l driver state */
        !           158:                bp->b_tmperr = 0;               /* no temp. errors yet */
        !           159:                bp->b_sema = BSC_DDONE;         /* driver not busy */
        !           160: 
        !           161:                /* 2.4 Initialize I/O port */
        !           162:                errcode = bsclopn(bscdev,bp);   /* device-specific init. */
        !           163:                if (errcode) {
        !           164:                        bp->b_lock = 0;         /* Unlock device        */
        !           165:                        ERRRET(errcode);
        !           166:                }
        !           167:        }
        !           168: 
        !           169:        /* 3. Wait till DSR shows */
        !           170:        while (bsckdsr(bscdev,bp), !(bp->b_hlflgs & BSC_DSR) && !u.u_error)
        !           171:                delay(PSMTICK);
        !           172: 
        !           173:        /* 4. If tracing activated, awaken bstopen */
        !           174:        if (bp->b_trace)
        !           175:                wakeup(&bp->b_trace);
        !           176:        if (u.u_error)
        !           177:                bsmclose(dev);
        !           178: #if defined BSD42
        !           179:        return 0;
        !           180: #endif
        !           181: }
        !           182: 
        !           183: /*
        !           184:  * NAME
        !           185:  *     bsmclose -- Terminate station processing
        !           186:  * SYNOPSIS
        !           187:  *     bsmclose(dev)
        !           188:  *     dev_t dev;              minor device number:
        !           189:  *                             bits 7-5: modem port number
        !           190:  *                             bits 4-0: station number, 0-31
        !           191:  * ALGORITHM
        !           192:  *     1. Mark station done, free; decrement multistation lock
        !           193:  *        If not last station using line, return.
        !           194:  *     2. Terminate PSM processing, kill receive and tracing
        !           195:  *     3. Turn off DTR
        !           196:  */
        !           197: bsmclose(dev)
        !           198: dev_t dev;
        !           199: {
        !           200:        register dev_t bscdev;          /* modem port number */
        !           201:        register struct bsc *bp;        /* ptr to port's bsc entry */
        !           202:        register int subdev;            /* station number */
        !           203:        register struct bscsub *bpsub;  /* ptr to station's bscsubs entry */
        !           204:        register long s;
        !           205: 
        !           206:        bscdev = DEV(dev);
        !           207:        subdev = SUBDEV(dev);
        !           208:        bp = &bsc[bscdev];
        !           209:        bpsub = &bscsubs[bscdev][subdev];
        !           210: 
        !           211:        /* 1. Mark station done, free; decrement multistation lock.     */
        !           212:        /*    If not last station using line, return.                   */
        !           213:        bpsub->bs_sema &= ~BSC_DBUSY;
        !           214:        bpsub->bs_sema |= BSC_DDONE;
        !           215:        bpsub->bs_mode = BS_FREE;
        !           216:        bpsub->bs_flags = 0;
        !           217:        if (--bp->b_lock) return;       /* others still using the line */
        !           218:         s = spl8(); 
        !           219: 
        !           220:        /* 2. Terminate PSM processing, kill receive and tracing */
        !           221:        bp->b_mode = BSC_CLOSED;                /* mode is CLOSED */
        !           222:        bp->b_rclptr = (char *)0;               /* terminate receive */
        !           223:        bstclose(bscdev);                       /* close trace device, too */
        !           224: 
        !           225:        /* 3. Turn off DTR */
        !           226:        bsclcls (bscdev, bp);
        !           227:         splx(s);
        !           228: 
        !           229: #if defined BSD42
        !           230:        return 0;
        !           231: #endif
        !           232: }
        !           233: 
        !           234: /*
        !           235:  * NAME
        !           236:  *     bsmread -- read next data block.
        !           237:  * SYNOPSIS
        !           238:  *     bsmread(dev)
        !           239:  *     dev_t dev;              minor device number:
        !           240:  *                             bits 7-5: modem port number
        !           241:  *                             bits 4-0: station number, 0-31
        !           242:  * ALGORITHM
        !           243:  *     1. Check for error latch or lack of DSR.
        !           244:  *        If either set, return EIO error.
        !           245:  *     2. If first activity on line, set up psm.
        !           246:  *     3. Based on present mode:
        !           247:  *     3.1 Write: error (EINVAL)
        !           248:  *     3.2 Idle: Synch up with psm, then go to Read mode
        !           249:  *     3.3 Read: If delay mode in effect, wait for err, eof, or data
        !           250:  *     3.3.1 Check for NO DELAY mode
        !           251:  *     3.3.2 Wait for full buffer, eof, or error
        !           252:  *     3.3.3 If EOF, chg mode to Idle, return 0 bytes read
        !           253:  *     3.3.4 If ERR, leave mode at Read, return -1(EIO)
        !           254:  *     3.3.5 Buffer full. Copy data out, set length.
        !           255:  *     4. Mark buffer empty, awaken psm if its sleeping
        !           256:  */
        !           257: #if defined BSD42
        !           258: bsmread(dev,uio)
        !           259: register dev_t dev;
        !           260: struct uio *uio;
        !           261: #else
        !           262: bsmread(dev)
        !           263: register dev_t dev;
        !           264: #endif
        !           265: {
        !           266:        register dev_t bscdev;          /* modem port number */
        !           267:        register struct bsc *bp;        /* ptr to port's bsc entry */
        !           268:        register int subdev;            /* station number */
        !           269:        register struct bscsub *bpsub;  /* ptr to station's bscsubs entry */
        !           270:        register int l;                 /* length info. */
        !           271:        int x;                          /* prty save area */
        !           272:        int errcode = 0;                /* Error code upon return       */
        !           273: 
        !           274:        bscdev = DEV(dev);
        !           275:        subdev = SUBDEV(dev);
        !           276:        bp = &bsc[bscdev];
        !           277:        bpsub = &bscsubs[bscdev][subdev];
        !           278: 
        !           279:        /* 1. Check for error latch or lack of DSR.     */
        !           280:        /*    If either set, return EIO error.          */
        !           281:        if (!(bp->b_hlflgs & BSC_DSR) || (bpsub->bs_flags & BS_ERR)) {
        !           282:                if (!(bpsub->bs_flags & BS_ERR)) {
        !           283:                        bpsub->bs_flags |= BS_ERR;
        !           284:                        bpsub->bs_err = BSCNDSR;
        !           285:                }
        !           286:                bpsub->bs_mode = BS_IDLE;
        !           287:                ERRRET(EIO);
        !           288:        }
        !           289: 
        !           290:        /* 2. If first activity on line, set up psm */
        !           291:        if (bp->b_mode == BSC_INIT) {
        !           292:                bscsetup(bscdev);
        !           293:                bp->b_mode = BSC_IDLE;
        !           294:        }
        !           295: 
        !           296:        /* 3. Based on present mode:                            */
        !           297:        switch (bpsub->bs_mode)
        !           298:        {
        !           299:        /* 3.1 Write: error (EINVAL)                            */
        !           300:        case BS_WRITE:
        !           301:                ERRRET(EINVAL);
        !           302: 
        !           303:        /* 3.2 Idle: Synch up with psm, then go to Read mode    */
        !           304:        case BS_IDLE:                   /* First read call */
        !           305:                while (!u.u_error &&
        !           306:                       !(bpsub->bs_sema & BSC_PDONE) &&
        !           307:                        (bpsub->bs_mode == BS_IDLE) &&
        !           308:                       !(bpsub->bs_flags&BS_ERR))
        !           309:                        delay(PSMTICK); /* Synchronize */
        !           310:                /* Set read timeout counter */
        !           311:                bpsub->bs_rdflg = bp->b_iocin.b_nor*PSMTPS;
        !           312:                bpsub->bs_mode = BS_READ;
        !           313:                bpsub->bs_sema |= BSC_DBUSY;
        !           314:                bpsub->bs_sema &= ~BSC_DDONE;   /* driver now busy */
        !           315: 
        !           316:        /* 3.3 Read: If delay mode in effect, wait for err, eof, or data */
        !           317:        case BS_READ:                   /* not first read */
        !           318: forceread:
        !           319:                x = spl8();
        !           320:                /* 3.3.1 Check for NO DELAY mode */
        !           321:                if (bpsub->bs_sema & BSC_SEENBUF) {
        !           322:                        bpsub->bs_flags &= ~BS_FULL;
        !           323:                        bpsub->bs_sema &= ~BSC_SEENBUF;
        !           324:                        if (states[bp->b_state].s_type == 'd' &&
        !           325:                            bp->b_alenb) {
        !           326:                                bp->b_alenb = 0;        /* disable alarm */
        !           327:                                splx(x);
        !           328:                                bscpsm(bscdev);         /* awaken psm */
        !           329:                        }
        !           330:                }
        !           331:                if ((bpsub->bs_sema & BSC_NDLY) && 
        !           332:                    !(bpsub->bs_flags & (BS_FULL|BS_ERR|BS_LAST))) {
        !           333:                        splx(x);
        !           334:                        ERRRET(EAGAIN); /* Call again later */
        !           335:                }
        !           336: 
        !           337:                /* 3.3.2 Wait for full buffer, eof, or error */
        !           338:                while (!(bpsub->bs_flags & (BS_FULL|BS_ERR|BS_LAST)))
        !           339:                        sleep ((caddr_t)&bpsub->bs_flags,BSCPRI);
        !           340:                splx(x);
        !           341: 
        !           342:                bpsub->bs_rdflg = 0;            /* cancel read timeout */
        !           343: 
        !           344:                /* 3.3.3 If EOF, chg mode to Idle, return 0 bytes read */
        !           345:                if (bpsub->bs_flags & BS_LAST) {
        !           346:                        bpsub->bs_mode = BS_IDLE;
        !           347:                        bp->b_hlflgs &= ~(BSC_XLAST|BSC_XTRN);
        !           348:                        bpsub->bs_flags &= ~(BS_LAST|BSC_XTRN);
        !           349:                        bpsub->bs_sema |= BSC_DDONE;
        !           350:                        bpsub->bs_sema &= ~BSC_DBUSY;
        !           351:                        goto readexit;
        !           352:                }
        !           353: 
        !           354:                /* 3.3.4 If ERR, leave mode at Read, return -1(EIO) */
        !           355:                if (bpsub->bs_flags & BS_ERR) { /* error way out */
        !           356:                        bp->b_hlflgs &= ~(BSC_XLAST|BSC_FULL|BSC_XTRN);
        !           357:                        bpsub->bs_flags &= ~BS_FULL;
        !           358:                        bpsub->bs_sema &= ~BSC_SEENBUF;
        !           359:                        errcode = EIO;
        !           360:                        goto readexit;
        !           361:                }
        !           362: 
        !           363:                /* 3.3.5 Buffer full. Copy data out, set length.        */
        !           364:                l = bp->b_bsize;        /* buffer space occupied */
        !           365:                if (l > UCOUNT)
        !           366:                        l = UCOUNT;
        !           367:                if (l)
        !           368: #if defined BSD42
        !           369:                        errcode = uiomove(bp->b_buffer,l,UIO_READ,uio);
        !           370: #else
        !           371:                        if (iomove (bp->b_buffer, l, B_READ))
        !           372:                                errcode = EFAULT;
        !           373: #endif
        !           374: 
        !           375:                if (bpsub->bs_sema & BSC_FACK) {
        !           376:                        bpsub->bs_sema |= BSC_SEENBUF;
        !           377:                        goto readret;
        !           378:                }
        !           379: 
        !           380:        /* 4. Mark buffer empty, awaken psm if its sleeping */
        !           381: readexit:
        !           382:                bpsub->bs_flags &= ~BS_FULL;
        !           383:                bp->b_hlflgs &= ~BSC_FULL;      /* mark buffer empty */
        !           384:                x = spl8();
        !           385:                if (states[bp->b_state].s_type == 'd' &&
        !           386:                    bp->b_alenb) {
        !           387:                        bp->b_alenb = 0;        /* disable alarm */
        !           388:                        splx(x);
        !           389:                        bscpsm(bscdev);         /* awaken psm */
        !           390:                } else  splx(x);
        !           391:        }
        !           392: readret:
        !           393: #if defined BSD42
        !           394:        return errcode;
        !           395: #else
        !           396:        if (errcode)
        !           397:                u.u_error = errcode;
        !           398: #endif
        !           399: }
        !           400: 
        !           401: /*
        !           402:  *     bsmwrite -- 1) if user's length = 0 or > max block, error
        !           403:  *                 2) if mode = read, or if error latch set, error!
        !           404:  *                 3) if mode = init, prime the driver
        !           405:  *                 4) if mode = idle, init, or write,
        !           406:  *                       a) set mode to write,
        !           407:  *                       b) wait till buffer empty,
        !           408:  *                       c) fill the buffer, 
        !           409:  *                       d) set flag to show buffer full.
        !           410:  *                 ** The psm will reset the mode to idle after sending EOT.
        !           411:  */
        !           412: #if defined BSD42
        !           413: bsmwrite(dev,uio)
        !           414: register dev_t dev;
        !           415: struct uio *uio;
        !           416: #else
        !           417: bsmwrite(dev)
        !           418: register dev_t dev;
        !           419: #endif
        !           420: {
        !           421:        register int l;                 /* length given us */
        !           422:        register struct bsc *bp;        /* ptr to bsc dev info */
        !           423:        register struct bscsub *bpsub;  /* ptr to bsc prot dev */
        !           424:        register int subdev;
        !           425:        register dev_t bscdev;
        !           426:        int x;                          /* prty save area */
        !           427:        int errcode = 0;                /* Error code to be returned    */
        !           428: 
        !           429:        subdev = SUBDEV(dev);
        !           430:        bscdev = DEV(dev);
        !           431:        bp = &bsc[bscdev];
        !           432:        bpsub = &bscsubs[bscdev][subdev];
        !           433: 
        !           434:        /* 0. Check error latch and DSR */
        !           435:        if ((bpsub->bs_flags & BS_ERR) || !(bp->b_hlflgs & BSC_DSR)) {
        !           436:                if (!(bpsub->bs_flags & BS_ERR)) {
        !           437:                        bpsub->bs_flags |= BS_ERR;
        !           438:                        bpsub->bs_err = BSCNDSR;
        !           439:                }
        !           440:                ERRRET(EIO);
        !           441:        }
        !           442: 
        !           443:        /* 1. Check length and other errors */
        !           444:        if ( (l = UCOUNT) == 0 || l > bp->b_iocin.b_blks) {
        !           445:                ERRRET(EINVAL);
        !           446:        }
        !           447: 
        !           448:        if (bp->b_mode == BSC_INIT) {
        !           449:                bscsetup(bscdev);
        !           450:                bp->b_mode = BSC_IDLE;
        !           451:        }
        !           452: 
        !           453:        /* 2. process according to mode */
        !           454:        switch (bpsub->bs_mode)
        !           455:        {
        !           456:        case BS_READ:
        !           457:                if ((bpsub->bs_sema & BSC_FACK) &&
        !           458:                    (bpsub->bs_sema & BSC_SEENBUF)) {
        !           459:                        bpsub->bs_flags &= ~BS_FULL;
        !           460:                        bpsub->bs_sema &= ~BSC_SEENBUF;
        !           461:                        bpsub->bs_mode = BS_WRITE;
        !           462:                        goto casewrite;
        !           463:                }
        !           464:                if (bpsub->bs_rdflg == 0) {
        !           465:                        ERRRET(EINVAL); /* oops - can't read now! */
        !           466:                } else {
        !           467:                        bpsub->bs_sema &= ~BSC_DBUSY;
        !           468:                        bpsub->bs_sema |= BSC_DDONE;
        !           469:                        bpsub->bs_rdflg = 1;
        !           470:                        while (bpsub->bs_mode == BS_READ &&
        !           471:                               !(bpsub->bs_flags & BS_ERR))
        !           472:                                delay(PSMTICK);
        !           473:                }
        !           474:                bpsub->bs_mode = BS_IDLE;
        !           475: 
        !           476:        case BS_IDLE:
        !           477:                if (bpsub->bs_flags & BS_FULL) {
        !           478:                        ERRRET(EINVAL); /* Caller needs to read */
        !           479:                }
        !           480:                while (!(bpsub->bs_sema & BSC_PDONE) &&
        !           481:                       !(bpsub->bs_flags & BS_ERR))
        !           482:                        delay(PSMTICK); /* Synchronize */
        !           483:                bpsub->bs_mode = BS_WRITE;
        !           484:                bpsub->bs_flags &= ~BS_ERR;     /* reset possible err */
        !           485:                bpsub->bs_sema |= BSC_DBUSY;
        !           486:                bpsub->bs_sema &= ~BSC_DDONE;   /* driver now busy */
        !           487: 
        !           488: casewrite:
        !           489:        case BS_WRITE:
        !           490:                x = spl8();
        !           491:                while ((bpsub->bs_flags & BS_FULL) &&   /*wait til empty */
        !           492:                        (!(bpsub->bs_flags & BS_ERR)))
        !           493:                        sleep ((caddr_t)&bpsub->bs_flags,BSCPRI);
        !           494:                splx(x);
        !           495: 
        !           496:                if (bpsub->bs_flags & BS_ERR){
        !           497:                        bp->b_hlflgs &= ~(BSC_FULL|BSC_XLAST|BSC_XTRN);
        !           498:                        bpsub->bs_flags &= ~(BS_FULL|BS_LAST|BSC_XTRN);
        !           499:                        bpsub->bs_mode = BS_IDLE;
        !           500:                        ERRRET(EIO);
        !           501:                }
        !           502: 
        !           503:                /* copy data to buffer */
        !           504: #if defined BSD42
        !           505:                errcode = uiomove(bpsub->bs_buf,l,UIO_WRITE,uio);
        !           506: #else
        !           507:                if (iomove (bpsub->bs_buf, l, B_WRITE))
        !           508:                        errcode = EFAULT;
        !           509: #endif
        !           510: 
        !           511:                bpsub->bs_size = l;                     /*save size */
        !           512: 
        !           513:                x = spl8();
        !           514:                bpsub->bs_flags |= BS_FULL;             /* bufr now full */
        !           515:                if (states[bp->b_state].s_type == 'd' &&
        !           516:                    bp->b_alenb) {              /* decision wait? */
        !           517:                        bp->b_alenb = 0;        /* disable pto */
        !           518:                        splx(x);
        !           519:                        bscpsm(bscdev);         /* wake 'em up */
        !           520:                } else  splx(x);
        !           521: 
        !           522:                if (bpsub->bs_flags & BS_LAST) { /* if last block, wait */
        !           523:                        x = spl8();
        !           524:                        while ((bpsub->bs_flags & BS_FULL) && /*wait til empty*/
        !           525:                                (!(bpsub->bs_flags & BS_ERR))) /*no error*/
        !           526:                                sleep ((caddr_t)&bpsub->bs_flags, BSCPRI);
        !           527:                        splx(x);
        !           528:                        if (bpsub->bs_flags & BS_ERR){
        !           529:                                errcode = EIO;
        !           530:                        } else  {
        !           531:                                bpsub->bs_sema |= BSC_DDONE;
        !           532:                                bpsub->bs_sema &= ~BSC_DBUSY;
        !           533:                                bpsub->bs_mode = BS_IDLE;
        !           534:                        }
        !           535:                        bp->b_hlflgs &= ~(BSC_XLAST|BSC_FULL|BSC_XTRN);
        !           536:                        bpsub->bs_flags &= ~(BS_LAST|BS_FULL|BSC_XTRN);
        !           537:                }
        !           538:        }
        !           539: #if defined BSD42
        !           540:        return errcode;
        !           541: #else
        !           542:        if (errcode)
        !           543:                u.u_error = errcode;
        !           544: #endif
        !           545: }
        !           546: 
        !           547: /*     bsmioctl -- set options or get counter values
        !           548:  *                 Depending on cmd:
        !           549:  *                 BSCGET   - copy b_iocout to user's area
        !           550:  *                 BSCSET   - copy user's values to b_iocin (set stuff)
        !           551:  *                 BSCTRNSP - set transparent mode flag
        !           552:  *                 BSCNTRNS - reset transparent mode flag
        !           553:  *                 BSCSOH   - set send SOH flag
        !           554:  *                 BSCNSOH  - turn off SOH flag
        !           555:  *                 BSCLAST  - set send last flag
        !           556:  *                 BSCID    - determine port id number 
        !           557:  */
        !           558: 
        !           559: /*VARARGS3*/
        !           560: bsmioctl(dev, cmd, arg)
        !           561: dev_t dev;
        !           562: struct bscio *arg; 
        !           563: {
        !           564:        register struct bsc *bp;        /* ptr to dev info */
        !           565:        register struct bscsub *bpsub;  /* ptr to port info */
        !           566:        struct bscio tmp;               /* temp struct for chk'g user params*/
        !           567:        register int x;
        !           568:        register int subdev;
        !           569:        register dev_t bscdev;
        !           570:        int y,errcode = 0;
        !           571: 
        !           572:        dev = minor(dev);
        !           573:        subdev = SUBDEV(dev);
        !           574:        bscdev = DEV(dev);
        !           575:        bp = &bsc[bscdev];
        !           576:        bpsub = &bscsubs[bscdev][subdev];
        !           577:        if (cmd != BSCGET && cmd != BSCSET) {   /* if write op, wait on buf */
        !           578:                x = spl8();
        !           579:                while (bpsub->bs_mode == BS_WRITE && bpsub->bs_flags & BS_FULL)
        !           580:                        sleep ((caddr_t)&bpsub->bs_flags, BSCPRI);
        !           581:                splx(x);
        !           582:        }
        !           583: 
        !           584:        if ((cmd == BSCSET) && (bp->b_lock != 1)) {/* only 1st can set modes */
        !           585:                ERRRET(EINVAL);
        !           586:        }
        !           587:        switch (cmd) {
        !           588:        case BSCGET:
        !           589:                x = spl8();
        !           590:                bp->b_iocout.b_flags = bpsub->bs_err;
        !           591: #if defined BSD42
        !           592:                bcopy((caddr_t)&bp->b_iocout, arg, sizeof bp->b_iocout);
        !           593: #else
        !           594:                if (copyout(&bp->b_iocout, arg, sizeof bp->b_iocout))
        !           595:                        errcode = EFAULT;
        !           596: #endif
        !           597:                bpsub->bs_err = 0;
        !           598:                bp->b_iocout.b_flags = 0;
        !           599:                if (bpsub->bs_flags & BS_ERR) {
        !           600:                        bpsub->bs_flags &= ~(BS_ERR|BS_LAST|BS_FULL|BSC_XTRN);
        !           601:                        bpsub->bs_sema &= ~BSC_DBUSY;
        !           602:                        bpsub->bs_sema |= BSC_DDONE;
        !           603:                        bpsub->bs_mode = BS_IDLE;
        !           604:                }
        !           605:                splx(x);
        !           606:                break;
        !           607: 
        !           608:        case BSCSET:
        !           609:                if (bpsub->bs_mode == BS_READ || bpsub->bs_mode == BS_WRITE) {
        !           610:                        errcode = EINVAL;       /* can't set if active */
        !           611:                        break;
        !           612:                }
        !           613: #if defined BSD42
        !           614:                bcopy(arg, (caddr_t)&tmp, sizeof tmp);
        !           615: #else
        !           616:                if (copyin (arg, &tmp, sizeof tmp)) {
        !           617:                        errcode = EFAULT;
        !           618:                        break;
        !           619:                }
        !           620: #endif
        !           621:                if (tmp.b_blks > BSCMBLK ||     /* block size too big? */
        !           622:                    tmp.b_blks > sizeof bpsub->bs_buf) {
        !           623:                        errcode = EINVAL;
        !           624:                        break;
        !           625:                }
        !           626:                bcopy (/*from*/&tmp, /*to*/&bp->b_iocin, sizeof tmp);
        !           627:                x = spl8();             /* *** protect hlflgs */
        !           628:                bp->b_hlflgs &= ~BSC_UFLAGS;    /* throw out old user flags */
        !           629:                bp->b_hlflgs |= (BSCMPT|(tmp.b_flags & BSC_UFLAGS));
        !           630:                splx(x);                /* *** end protection */
        !           631:                bscparam(bscdev);       /* redo parameters */
        !           632:                break;
        !           633: 
        !           634:        case BSCTRNSP:
        !           635:                x = spl8();             /* *** protect bsflgs */
        !           636:                bpsub->bs_flags |= BSC_XTRN;    /* set transparent mode */
        !           637:                splx(x);                /* *** end protection */
        !           638:                break;
        !           639: 
        !           640:        case BSCNTRNS:
        !           641:                x = spl8();             /* *** protect bsflgs */
        !           642:                bpsub->bs_flags &= ~BSC_XTRN;   /* reset transp. mode */
        !           643:                splx(x);                /* *** end protection */
        !           644:                break;
        !           645: 
        !           646:        case BSCSOH:
        !           647:                x = spl8();             /* *** protect bsflags */
        !           648:                bpsub->bs_flags |= BSC_XSOH;    /* set send SOH flag */
        !           649:                splx(x);                /* *** end protection */
        !           650:                break;
        !           651: 
        !           652:        case BSCNSOH:
        !           653:                x = spl8();             /* *** protect bsflags */
        !           654:                bpsub->bs_flags &= ~BSC_XSOH;   /* clear send SOH flag*/
        !           655:                splx(x);                /* end protection */
        !           656:                break;
        !           657: 
        !           658:        case BSCLAST:
        !           659:                x = spl8();             /* *** protect bsflags */
        !           660:                bpsub->bs_flags |= BS_LAST;   /* set send last blk flag */
        !           661:                splx(x);                /* end protection */
        !           662:                break;
        !           663: 
        !           664:        case BSCNDLY:
        !           665:                x = spl8();             /* protect bs flags */
        !           666:                bpsub->bs_sema |= BSC_NDLY;
        !           667:                splx(x);
        !           668:                break;
        !           669: 
        !           670:        case BSCID:
        !           671:                y = ((bp->b_hlflgs & BSCASCII)?ascdev:ebcdev)[subdev];
        !           672: #if defined BSD42
        !           673:                bcopy((caddr_t)&y, (int *)arg, sizeof y);
        !           674: #else
        !           675:                copyout(&y,(int *)arg,sizeof y);
        !           676: #endif
        !           677:                break;
        !           678: 
        !           679:        case BSCFACK:
        !           680:                x = spl8();
        !           681:                bpsub->bs_sema |= BSC_FACK;
        !           682:                splx(x);
        !           683:                break;
        !           684: 
        !           685:        default:
        !           686:                errcode = EINVAL;
        !           687:                break;
        !           688:        }
        !           689: #if defined BSD42
        !           690:        return errcode;
        !           691: #else
        !           692:        if (errcode)
        !           693:                u.u_error = errcode;
        !           694: #endif
        !           695: }
        !           696: #endif

unix.superglobalmegacorp.com

This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.