Annotation of cci/sys/bsc/bscm.c, revision 1.1.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.