Annotation of MiNT/src/biosfs.c, revision 1.1.1.4

1.1       root        1: /*
                      2: 
1.1.1.4 ! root        3: Copyright 1991,1992 Eric R. Smith.
        !             4: 
        !             5: Copyright 1993 Atari Corporation.
        !             6: 
        !             7: All rights reserved.
1.1       root        8: 
                      9:  */
                     10: 
                     11: 
                     12: 
                     13: /* simple biosfs.c */
                     14: 
                     15: 
                     16: 
                     17: #include "mint.h"
                     18: 
                     19: 
                     20: 
                     21: extern struct kerinfo kernelinfo;      /* see main.c */
                     22: 
                     23: 
                     24: 
1.1.1.2   root       25: static long    ARGS_ON_STACK bios_root P_((int drv, fcookie *fc));
1.1       root       26: 
1.1.1.2   root       27: static long    ARGS_ON_STACK bios_lookup       P_((fcookie *dir, const char *name, fcookie *fc));
1.1       root       28: 
1.1.1.2   root       29: static long    ARGS_ON_STACK bios_getxattr     P_((fcookie *fc, XATTR *xattr));
1.1       root       30: 
1.1.1.2   root       31: static long    ARGS_ON_STACK bios_chattr       P_((fcookie *fc, int attrib));
1.1       root       32: 
1.1.1.2   root       33: static long    ARGS_ON_STACK bios_chown        P_((fcookie *fc, int uid, int gid));
1.1       root       34: 
1.1.1.2   root       35: static long    ARGS_ON_STACK bios_chmode       P_((fcookie *fc, unsigned mode));
1.1       root       36: 
1.1.1.2   root       37: static long    ARGS_ON_STACK bios_rmdir        P_((fcookie *dir, const char *name));
1.1       root       38: 
1.1.1.2   root       39: static long    ARGS_ON_STACK bios_remove       P_((fcookie *dir, const char *name));
1.1       root       40: 
1.1.1.3   root       41: static long    ARGS_ON_STACK bios_getname      P_((fcookie *root, fcookie *dir, char *pathname, int size));
1.1       root       42: 
1.1.1.2   root       43: static long    ARGS_ON_STACK bios_rename       P_((fcookie *olddir, char *oldname,
1.1       root       44: 
                     45:                                    fcookie *newdir, const char *newname));
                     46: 
1.1.1.2   root       47: static long    ARGS_ON_STACK bios_opendir      P_((DIR *dirh, int flags));
1.1       root       48: 
1.1.1.2   root       49: static long    ARGS_ON_STACK bios_readdir      P_((DIR *dirh, char *nm, int nmlen, fcookie *fc));
1.1       root       50: 
1.1.1.2   root       51: static long    ARGS_ON_STACK bios_rewinddir    P_((DIR *dirh));
1.1       root       52: 
1.1.1.2   root       53: static long    ARGS_ON_STACK bios_closedir     P_((DIR *dirh));
1.1       root       54: 
1.1.1.2   root       55: static long    ARGS_ON_STACK bios_pathconf     P_((fcookie *dir, int which));
1.1       root       56: 
1.1.1.2   root       57: static long    ARGS_ON_STACK bios_dfree        P_((fcookie *dir, long *buf));
1.1       root       58: 
1.1.1.2   root       59: static DEVDRV *        ARGS_ON_STACK bios_getdev       P_((fcookie *fc, long *devspecial));
1.1       root       60: 
1.1.1.2   root       61: static long    ARGS_ON_STACK bios_fscntl       P_((fcookie *, const char *, int, long));
1.1       root       62: 
1.1.1.2   root       63: static long    ARGS_ON_STACK bios_symlink      P_((fcookie *, const char *, const char *));
1.1       root       64: 
1.1.1.2   root       65: static long    ARGS_ON_STACK bios_readlink     P_((fcookie *, char *, int));
1.1       root       66: 
                     67: 
                     68: 
1.1.1.2   root       69: static long    ARGS_ON_STACK bios_topen        P_((FILEPTR *f));
1.1       root       70: 
1.1.1.2   root       71: static long    ARGS_ON_STACK bios_twrite       P_((FILEPTR *f, const char *buf, long bytes));
1.1       root       72: 
1.1.1.2   root       73: static long    ARGS_ON_STACK bios_tread        P_((FILEPTR *f, char *buf, long bytes));
1.1       root       74: 
1.1.1.2   root       75: static long    ARGS_ON_STACK bios_nwrite       P_((FILEPTR *f, const char *buf, long bytes));
1.1       root       76: 
1.1.1.2   root       77: static long    ARGS_ON_STACK bios_nread        P_((FILEPTR *f, char *buf, long bytes));
1.1       root       78: 
1.1.1.2   root       79: static long    ARGS_ON_STACK bios_ioctl        P_((FILEPTR *f, int mode, void *buf));
1.1       root       80: 
1.1.1.2   root       81: static long    ARGS_ON_STACK bios_select       P_((FILEPTR *f, long p, int mode));
1.1       root       82: 
1.1.1.2   root       83: static void    ARGS_ON_STACK bios_unselect     P_((FILEPTR *f, long p, int mode));
1.1       root       84: 
1.1.1.2   root       85: static long    ARGS_ON_STACK bios_tseek        P_((FILEPTR *f, long where, int whence));
1.1       root       86: 
                     87: 
                     88: 
1.1.1.2   root       89: long   ARGS_ON_STACK null_open P_((FILEPTR *f));
1.1       root       90: 
1.1.1.2   root       91: long   ARGS_ON_STACK null_write        P_((FILEPTR *f, const char *buf, long bytes));
1.1       root       92: 
1.1.1.2   root       93: long   ARGS_ON_STACK null_read P_((FILEPTR *f, char *buf, long bytes));
1.1       root       94: 
1.1.1.2   root       95: long   ARGS_ON_STACK null_lseek        P_((FILEPTR *f, long where, int whence));
1.1       root       96: 
1.1.1.2   root       97: long   ARGS_ON_STACK null_ioctl        P_((FILEPTR *f, int mode, void *buf));
1.1       root       98: 
1.1.1.2   root       99: long   ARGS_ON_STACK null_datime       P_((FILEPTR *f, short *time, int rwflag));
1.1       root      100: 
1.1.1.2   root      101: long   ARGS_ON_STACK null_close        P_((FILEPTR *f, int pid));
1.1       root      102: 
1.1.1.2   root      103: long   ARGS_ON_STACK null_select       P_((FILEPTR *f, long p, int mode));
1.1       root      104: 
1.1.1.2   root      105: void   ARGS_ON_STACK null_unselect     P_((FILEPTR *f, long p, int mode));
1.1       root      106: 
                    107: 
                    108: 
1.1.1.2   root      109: static long ARGS_ON_STACK mouse_open   P_((FILEPTR *f));
1.1       root      110: 
1.1.1.2   root      111: static long ARGS_ON_STACK mouse_read   P_((FILEPTR *f, char *buf, long nbytes));
1.1       root      112: 
1.1.1.2   root      113: static long ARGS_ON_STACK mouse_ioctl P_((FILEPTR *f, int mode, void *buf));
1.1       root      114: 
1.1.1.2   root      115: static long ARGS_ON_STACK mouse_close P_((FILEPTR *f, int pid));
1.1       root      116: 
1.1.1.2   root      117: static long ARGS_ON_STACK mouse_select P_((FILEPTR *f, long p, int mode));
1.1       root      118: 
1.1.1.2   root      119: static void ARGS_ON_STACK mouse_unselect P_((FILEPTR *f, long p, int mode));
1.1       root      120: 
                    121: 
                    122: 
                    123: /* device driver for BIOS terminals */
                    124: 
                    125: 
                    126: 
                    127: DEVDRV bios_tdevice = {
                    128: 
                    129:        bios_topen, bios_twrite, bios_tread, bios_tseek, bios_ioctl,
                    130: 
                    131:        null_datime, null_close, bios_select, bios_unselect
                    132: 
                    133: };
                    134: 
                    135: 
                    136: 
                    137: /* device driver for BIOS devices that are not terminals */
                    138: 
                    139: 
                    140: 
                    141: DEVDRV bios_ndevice = {
                    142: 
                    143:        null_open, bios_nwrite, bios_nread, null_lseek, bios_ioctl,
                    144: 
                    145:        null_datime, null_close, bios_select, bios_unselect
                    146: 
                    147: };
                    148: 
                    149: 
                    150: 
                    151: DEVDRV null_device = {
                    152: 
                    153:        null_open, null_write, null_read, null_lseek, null_ioctl,
                    154: 
                    155:        null_datime, null_close, null_select, null_unselect
                    156: 
                    157: };
                    158: 
                    159: 
                    160: 
                    161: DEVDRV mouse_device = {
                    162: 
                    163:        mouse_open, null_write, mouse_read, null_lseek, mouse_ioctl,
                    164: 
                    165:        null_datime, mouse_close, mouse_select, mouse_unselect
                    166: 
                    167: };
                    168: 
                    169: 
                    170: 
                    171: /* this special driver is checked for in dosfile.c, and indicates that
                    172: 
                    173:  * a dup operation is actually wanted rather than an open
                    174: 
                    175:  */
                    176: 
                    177: DEVDRV fakedev;
                    178: 
                    179: 
                    180: 
                    181: #ifdef FASTTEXT
                    182: 
                    183: extern DEVDRV screen_device;   /* see fasttext.c */
                    184: 
                    185: #endif
                    186: 
                    187: 
                    188: 
                    189: FILESYS bios_filesys = {
                    190: 
                    191:        (FILESYS *)0,
                    192: 
1.1.1.3   root      193:        FS_LONGPATH,
1.1       root      194: 
                    195:        bios_root,
                    196: 
                    197:        bios_lookup, nocreat, bios_getdev, bios_getxattr,
                    198: 
                    199:        bios_chattr, bios_chown, bios_chmode,
                    200: 
                    201:        nomkdir, bios_rmdir, bios_remove, bios_getname, bios_rename,
                    202: 
                    203:        bios_opendir, bios_readdir, bios_rewinddir, bios_closedir,
                    204: 
                    205:        bios_pathconf, bios_dfree, nowritelabel, noreadlabel,
                    206: 
                    207:        bios_symlink, bios_readlink, nohardlink, bios_fscntl, nodskchng
                    208: 
                    209: };
                    210: 
                    211: 
                    212: 
                    213: 
                    214: 
                    215: struct tty con_tty, aux_tty, midi_tty;
                    216: 
                    217: struct tty sccb_tty, scca_tty, ttmfp_tty;
                    218: 
                    219: 
                    220: 
                    221: #define BNAME_MAX      13
                    222: 
                    223: 
                    224: 
                    225: struct bios_file {
                    226: 
                    227:        char    name[BNAME_MAX+1];      /* device name */
                    228: 
                    229:        DEVDRV *device;                 /* device driver for device */
                    230: 
                    231:        short   private;                /* extra info for device driver */
                    232: 
                    233:        ushort  flags;                  /* flags for device open */
                    234: 
                    235:        struct tty *tty;                /* tty structure (if appropriate) */
                    236: 
                    237:        struct bios_file *next;
                    238: 
                    239: };
                    240: 
                    241: 
                    242: 
                    243: struct bios_file BDEV[] = {
                    244: 
                    245: 
                    246: 
                    247: /* "real" bios devices present on all machines */
                    248: 
                    249:        {"centr", &bios_ndevice, 0, 0, 0, 0},
                    250: 
                    251:        {"console", &bios_tdevice, 2, O_TTY, &con_tty, 0},
                    252: 
                    253:        {"midi", &bios_tdevice, 3, O_TTY, &midi_tty, 0},
                    254: 
                    255:        {"kbd", &bios_ndevice, 4, 0, 0, 0},
                    256: 
                    257: /* devices that duplicate handles */
                    258: 
                    259:        {"prn", &fakedev, -3, 0, 0, 0}, /* handle -3 (printer) */
                    260: 
                    261:        {"aux", &fakedev, -2, 0, 0, 0}, /* handle -2 (aux. terminal) */
                    262: 
                    263:        {"con", &fakedev, -1, 0, 0, 0}, /* handle -1 (control terminal) */
                    264: 
                    265:        {"tty", &fakedev, -1, 0, 0, 0}, /* the Unix name for it */
                    266: 
                    267:        {"stdin", &fakedev, 0, 0, 0, 0},  /* handle 0 (stdin) */
                    268: 
                    269:        {"stdout", &fakedev, 1, 0, 0, 0}, /* handle 1 (stdout) */
                    270: 
                    271:        {"stderr", &fakedev, 2, 0, 0, 0}, /* handle 2 (stderr) */
                    272: 
                    273: 
                    274: 
                    275: /* other miscellaneous devices */
                    276: 
                    277:        {"mouse", &mouse_device, 0, 0, 0, 0},
                    278: 
                    279:        {"null", &null_device, 0, 0, 0, 0},
                    280: 
                    281: 
                    282: 
                    283: #ifdef FASTTEXT
                    284: 
                    285: /* alternate console driver */
                    286: 
                    287:        {"fasttext", &screen_device, 2, O_TTY, &con_tty, 0},
                    288: 
                    289: #endif
                    290: 
                    291: 
                    292: 
                    293: /* serial port things *must* come last, because not all of these
                    294: 
                    295:  * are present on all machines (except for modem1, which does however
                    296: 
                    297:  * have a different device number on TTs and STs)
                    298: 
                    299:  */
                    300: 
                    301:        {"modem1", &bios_tdevice, 6, O_TTY, &aux_tty, 0},
                    302: 
                    303:        {"modem2", &bios_tdevice, 7, O_TTY, &sccb_tty, 0},
                    304: 
                    305:        {"serial1", &bios_tdevice, 8, O_TTY, &ttmfp_tty, 0},
                    306: 
                    307:        {"serial2", &bios_tdevice, 9, O_TTY, &scca_tty, 0},
                    308: 
                    309:        {"", 0, 0, 0, 0, 0}
                    310: 
                    311: };
                    312: 
                    313: 
                    314: 
                    315: struct bios_file *broot, *bdevlast;
                    316: 
                    317: 
                    318: 
                    319: /* a file pointer for BIOS device 1, provided only for insurance
                    320: 
                    321:  * in case a Bconmap happens and we can't allocate a new FILEPTR;
                    322: 
                    323:  * in most cases, we'll want to build a FILEPTR in the usual
                    324: 
                    325:  * way.
                    326: 
                    327:  */
                    328: 
                    329: 
                    330: 
                    331: FILEPTR *defaultaux;
                    332: 
                    333: 
                    334: 
                    335: void
                    336: 
                    337: biosfs_init()
                    338: 
                    339: {
                    340: 
                    341:        struct bios_file *b;
                    342: 
                    343: 
                    344: 
                    345:        broot = BDEV;
                    346: 
                    347: 
                    348: 
                    349:        for (b = broot; b->name[0]; b++) {
                    350: 
                    351:                b->next = b+1;
                    352: 
                    353: 
                    354: 
                    355:        /* if not a TT or Mega STE, adjust the MODEM1 device to be BIOS
                    356: 
                    357:         * device 1
                    358: 
                    359:         * and ignore the remaining devices, since they're not present
                    360: 
                    361:         */
                    362: 
                    363:                if (!has_bconmap && b->private == 6) {
                    364: 
                    365:                        b->private = 1;
                    366: 
                    367:                        b->next = 0;
                    368: 
                    369:                        break;
                    370: 
                    371:                }
                    372: 
                    373:        /* SERIAL2 is not present on the Mega STe */
                    374: 
                    375:                if (mch == MEGASTE && b->private == 8) {
                    376: 
                    377:                        b->next = 0;
                    378: 
                    379:                        break;
                    380: 
                    381:                }
                    382: 
                    383:                        
                    384: 
                    385:        }
                    386: 
                    387:        bdevlast = b;
                    388: 
                    389:        if (b->name[0] == 0) {
                    390: 
                    391:                --b;
                    392: 
                    393:                b->next = 0;
                    394: 
                    395:        }
                    396: 
                    397:        defaultaux = new_fileptr();
                    398: 
                    399:        defaultaux->links = 1;          /* so it never gets freed */
                    400: 
                    401:        defaultaux->flags = O_RDWR;
                    402: 
                    403:        defaultaux->pos = 0;
                    404: 
                    405:        defaultaux->devinfo = 0;
                    406: 
                    407:        defaultaux->fc.fs = &bios_filesys;
                    408: 
                    409:        defaultaux->fc.index = 0;
                    410: 
                    411:        defaultaux->fc.aux = 1;
                    412: 
                    413:        defaultaux->fc.dev = BIOSDRV;
                    414: 
                    415:        defaultaux->dev = &bios_ndevice;
                    416: 
                    417: }
                    418: 
                    419: 
                    420: 
1.1.1.2   root      421: static long ARGS_ON_STACK 
1.1       root      422: 
                    423: bios_root(drv, fc)
                    424: 
                    425:        int drv;
                    426: 
                    427:        fcookie *fc;
                    428: 
                    429: {
                    430: 
                    431:        if (drv == BIOSDRV) {
                    432: 
                    433:                fc->fs = &bios_filesys;
                    434: 
                    435:                fc->dev = drv;
                    436: 
                    437:                fc->index = 0L;
                    438: 
                    439:                return 0;
                    440: 
                    441:        }
                    442: 
                    443:        fc->fs = 0;
                    444: 
                    445:        return EINTRN;
                    446: 
                    447: }
                    448: 
                    449: 
                    450: 
1.1.1.2   root      451: static long ARGS_ON_STACK 
1.1       root      452: 
                    453: bios_lookup(dir, name, fc)
                    454: 
                    455:        fcookie *dir;
                    456: 
                    457:        const char *name;
                    458: 
                    459:        fcookie *fc;
                    460: 
                    461: {
                    462: 
                    463:        struct bios_file *b;
                    464: 
                    465: 
                    466: 
                    467:        if (dir->index != 0) {
                    468: 
1.1.1.2   root      469:                DEBUG(("bios_lookup: bad directory"));
1.1       root      470: 
                    471:                return EPTHNF;
                    472: 
                    473:        }
                    474: 
                    475: /* special case: an empty name in a directory means that directory */
                    476: 
                    477: /* so does "." */
                    478: 
                    479:        if (!*name || (name[0] == '.' && name[1] == 0)) {
                    480: 
                    481:                *fc = *dir;
                    482: 
                    483:                return 0;
                    484: 
                    485:        }
                    486: 
                    487: 
                    488: 
                    489: /* another special case: ".." could be a mount point */
                    490: 
                    491:        if (!strcmp(name, "..")) {
                    492: 
                    493:                *fc = *dir;
                    494: 
                    495:                return EMOUNT;
                    496: 
                    497:        }
                    498: 
                    499: 
                    500: 
                    501:        for (b = broot; b; b = b->next) {
                    502: 
                    503:                if (!stricmp(b->name, name)) {
                    504: 
                    505:                        fc->fs = &bios_filesys;
                    506: 
                    507:                        fc->index = (long)b;
                    508: 
                    509:                        fc->aux = b->private;
                    510: 
                    511:                        fc->dev = dir->dev;
                    512: 
                    513:                        return 0;
                    514: 
                    515:                }
                    516: 
                    517:        }
                    518: 
1.1.1.2   root      519:        DEBUG(("bios_lookup: name(%s) not found", name));
1.1       root      520: 
                    521:        return EFILNF;
                    522: 
                    523: }
                    524: 
                    525: 
                    526: 
1.1.1.2   root      527: static long ARGS_ON_STACK 
1.1       root      528: 
                    529: bios_getxattr(fc, xattr)
                    530: 
                    531:        fcookie *fc;
                    532: 
                    533:        XATTR *xattr;
                    534: 
                    535: {
                    536: 
1.1.1.2   root      537:        FILEPTR *f;
                    538: 
1.1       root      539:        struct bios_file *b = (struct bios_file *)fc->index;
                    540: 
                    541: 
                    542: 
                    543:        xattr->index = fc->index;
                    544: 
                    545:        xattr->dev = fc->dev;
                    546: 
                    547:        xattr->nlink = 1;
                    548: 
                    549:        xattr->uid = xattr->gid = 0;
                    550: 
                    551:        xattr->size = xattr->nblocks = 0;
                    552: 
                    553:        xattr->blksize = 1;
                    554: 
                    555:        xattr->mtime = xattr->atime = xattr->ctime = timestamp;
                    556: 
                    557:        xattr->mdate = xattr->adate = xattr->cdate = datestamp;
                    558: 
                    559:        if (fc->index == 0) {           /* root directory? */
                    560: 
                    561:                xattr->mode = S_IFDIR | DEFAULT_DIRMODE;
                    562: 
                    563:                xattr->attr = FA_DIR;
                    564: 
                    565:        } else if (b->device == 0) {    /* symbolic link? */
                    566: 
                    567:                xattr->mode = S_IFLNK | DEFAULT_DIRMODE;
                    568: 
1.1.1.2   root      569:        } else if (b->device == &fakedev &&
                    570: 
                    571:                (f = curproc->handle[b->private]) != 0)
                    572: 
                    573:        {
1.1       root      574: 
1.1.1.2   root      575:            /* u:\dev\stdin, u:\dev\stdout, etc. */
                    576: 
                    577:            (*f->fc.fs->getxattr) (&f->fc, xattr);
                    578: 
                    579:            xattr->index = fc->index;
                    580: 
                    581:            xattr->dev = fc->dev;
                    582: 
                    583:        } else {
1.1       root      584: 
                    585:                xattr->mode = S_IFCHR | DEFAULT_MODE;
                    586: 
                    587:                xattr->attr = 0;
                    588: 
                    589:        }
                    590: 
                    591:        return 0;
                    592: 
                    593: }
                    594: 
                    595: 
                    596: 
1.1.1.2   root      597: static long ARGS_ON_STACK 
1.1       root      598: 
                    599: bios_chattr(fc, attrib)
                    600: 
                    601:        fcookie *fc;
                    602: 
                    603:        int attrib;
                    604: 
                    605: {
                    606: 
1.1.1.2   root      607:        UNUSED(fc); UNUSED(attrib);
                    608: 
1.1       root      609:        return EACCDN;
                    610: 
                    611: }
                    612: 
                    613: 
                    614: 
1.1.1.2   root      615: static long ARGS_ON_STACK 
1.1       root      616: 
                    617: bios_chown(fc, uid, gid)
                    618: 
                    619:        fcookie *fc;
                    620: 
                    621:        int uid, gid;
                    622: 
                    623: {
                    624: 
1.1.1.2   root      625:        UNUSED(fc); UNUSED(uid);
                    626: 
                    627:        UNUSED(gid);
                    628: 
1.1       root      629:        return EINVFN;
                    630: 
                    631: }
                    632: 
                    633: 
                    634: 
1.1.1.2   root      635: static long ARGS_ON_STACK 
1.1       root      636: 
                    637: bios_chmode(fc, mode)
                    638: 
                    639:        fcookie *fc;
                    640: 
                    641:        unsigned mode;
                    642: 
                    643: {
                    644: 
1.1.1.2   root      645:        UNUSED(fc); UNUSED(mode);
                    646: 
1.1       root      647:        return EINVFN;
                    648: 
                    649: }
                    650: 
                    651: 
                    652: 
1.1.1.2   root      653: long ARGS_ON_STACK 
1.1       root      654: 
                    655: nomkdir(dir, name, mode)
                    656: 
                    657:        fcookie *dir;
                    658: 
                    659:        const char *name;
                    660: 
                    661:        unsigned mode;
                    662: 
                    663: {
                    664: 
1.1.1.2   root      665:        UNUSED(dir); UNUSED(name);
                    666: 
                    667:        UNUSED(mode);
                    668: 
1.1       root      669:        return EACCDN;
                    670: 
                    671: }
                    672: 
                    673: 
                    674: 
1.1.1.2   root      675: static long ARGS_ON_STACK 
1.1       root      676: 
                    677: bios_rmdir(dir, name)
                    678: 
                    679:        fcookie *dir;
                    680: 
                    681:        const char *name;
                    682: 
                    683: {
                    684: 
                    685:        return bios_remove(dir, name);
                    686: 
                    687: }
                    688: 
                    689: 
                    690: 
                    691: /*
                    692: 
                    693:  * MAJOR BUG: we don't check here for removal of devices for which there
                    694: 
                    695:  * are still open files
                    696: 
                    697:  */
                    698: 
                    699: 
                    700: 
1.1.1.2   root      701: static long ARGS_ON_STACK 
1.1       root      702: 
                    703: bios_remove(dir, name)
                    704: 
                    705:        fcookie *dir;
                    706: 
                    707:        const char *name;
                    708: 
                    709: {
                    710: 
                    711:        struct bios_file *b, **lastb;
                    712: 
                    713: 
                    714: 
1.1.1.2   root      715:        UNUSED(dir);
                    716: 
1.1       root      717:        lastb = &broot;
                    718: 
                    719:        for (b = broot; b; b = *(lastb = &b->next)) {
                    720: 
                    721:                if (!stricmp(b->name, name)) break;
                    722: 
                    723:        }
                    724: 
                    725:        if (!b) return EFILNF;
                    726: 
                    727: 
                    728: 
                    729: /* don't allow removal of the basic system devices */
                    730: 
                    731:        if (b >= BDEV && b <= bdevlast) {
                    732: 
                    733:                return EACCDN;
                    734: 
                    735:        }
                    736: 
                    737:        *lastb = b->next;
                    738: 
                    739: 
                    740: 
                    741:        if (b->device == 0 || b->device == &bios_tdevice)
                    742: 
                    743:                kfree(b->tty);
                    744: 
                    745: 
                    746: 
                    747:        kfree(b);
                    748: 
                    749:        return 0;
                    750: 
                    751: }
                    752: 
                    753: 
                    754: 
1.1.1.2   root      755: static long ARGS_ON_STACK 
1.1       root      756: 
1.1.1.3   root      757: bios_getname(root, dir, pathname, size)
1.1       root      758: 
                    759:        fcookie *root, *dir; char *pathname;
                    760: 
1.1.1.3   root      761:        int size;
                    762: 
1.1       root      763: {
                    764: 
1.1.1.3   root      765:        char *foo = ((struct bios_file *)dir->index)->name;
                    766: 
                    767: 
                    768: 
1.1.1.2   root      769:        UNUSED(root);
                    770: 
1.1.1.3   root      771:        if (dir->index == 0 && size > 0)
1.1       root      772: 
                    773:                *pathname = 0;
                    774: 
1.1.1.3   root      775:        else if (strlen(foo) < size)
                    776: 
                    777:                strcpy(pathname, foo);
                    778: 
1.1       root      779:        else
                    780: 
1.1.1.3   root      781:                return ERANGE;
1.1       root      782: 
                    783:        return 0;
                    784: 
                    785: }
                    786: 
                    787: 
                    788: 
1.1.1.2   root      789: static long ARGS_ON_STACK 
1.1       root      790: 
                    791: bios_rename(olddir, oldname, newdir, newname)
                    792: 
                    793:        fcookie *olddir;
                    794: 
                    795:        char *oldname;
                    796: 
                    797:        fcookie *newdir;
                    798: 
                    799:        const char *newname;
                    800: 
                    801: {
                    802: 
                    803:        struct bios_file *b;
                    804: 
                    805: 
                    806: 
1.1.1.2   root      807:        UNUSED(olddir); UNUSED(newdir);
                    808: 
                    809: 
                    810: 
1.1       root      811: /* BUG: we should check to see if "newname" already exists */
                    812: 
                    813: 
                    814: 
                    815:        for (b = broot; b; b = b->next) {
                    816: 
                    817:                if (!stricmp(b->name, oldname)) {
                    818: 
                    819:                        strncpy(b->name, newname, BNAME_MAX);
                    820: 
                    821:                        return 0;
                    822: 
                    823:                }
                    824: 
                    825:        }
                    826: 
                    827:        return EFILNF;
                    828: 
                    829: }
                    830: 
                    831: 
                    832: 
1.1.1.2   root      833: static long ARGS_ON_STACK 
1.1       root      834: 
                    835: bios_opendir(dirh, flags)
                    836: 
                    837:        DIR *dirh;
                    838: 
                    839:        int flags;
                    840: 
                    841: {
                    842: 
1.1.1.2   root      843:        UNUSED(flags);
                    844: 
                    845: 
                    846: 
1.1       root      847:        if (dirh->fc.index != 0) {
                    848: 
1.1.1.2   root      849:                DEBUG(("bios_opendir: bad directory"));
1.1       root      850: 
                    851:                return EPTHNF;
                    852: 
                    853:        }
                    854: 
                    855:        return 0;
                    856: 
                    857: }
                    858: 
                    859: 
                    860: 
1.1.1.2   root      861: static long ARGS_ON_STACK 
1.1       root      862: 
                    863: bios_readdir(dirh, name, namelen, fc)
                    864: 
                    865:        DIR *dirh;
                    866: 
                    867:        char *name;
                    868: 
                    869:        int namelen;
                    870: 
                    871:        fcookie *fc;
                    872: 
                    873: {
                    874: 
                    875:        struct bios_file *b;
                    876: 
                    877:        int giveindex = dirh->flags == 0;
                    878: 
                    879:        int i;
                    880: 
                    881: 
                    882: 
                    883:        b = broot;
                    884: 
                    885:        i = dirh->index++;
                    886: 
                    887:        while(i-- > 0) {
                    888: 
                    889:                if (!b) break;
                    890: 
                    891:                b = b->next;
                    892: 
                    893:        }
                    894: 
                    895:        if (!b) {
                    896: 
                    897:                return ENMFIL;
                    898: 
                    899:        }
                    900: 
                    901:        fc->fs = &bios_filesys;
                    902: 
                    903:        fc->index = (long)b;
                    904: 
                    905:        fc->aux = b->private;
                    906: 
                    907:        fc->dev = dirh->fc.dev;
                    908: 
                    909:        if (giveindex) {
                    910: 
1.1.1.2   root      911:                namelen -= (int)sizeof(long);
1.1       root      912: 
                    913:                if (namelen <= 0)
                    914: 
                    915:                        return ERANGE;
                    916: 
                    917:                *((long *)name) = (long) b;
                    918: 
                    919:                name += sizeof(long);
                    920: 
                    921:        }
                    922: 
                    923:        strncpy(name, b->name, namelen-1);
                    924: 
                    925:        if (strlen(b->name) >= namelen)
                    926: 
                    927:                return ENAMETOOLONG;
                    928: 
                    929:        return 0;
                    930: 
                    931: }
                    932: 
                    933: 
                    934: 
1.1.1.2   root      935: static long ARGS_ON_STACK 
1.1       root      936: 
                    937: bios_rewinddir(dirh)
                    938: 
                    939:        DIR *dirh;
                    940: 
                    941: {
                    942: 
                    943:        dirh->index = 0;
                    944: 
                    945:        return 0;
                    946: 
                    947: }
                    948: 
                    949: 
                    950: 
1.1.1.2   root      951: static long ARGS_ON_STACK 
1.1       root      952: 
                    953: bios_closedir(dirh)
                    954: 
                    955:        DIR *dirh;
                    956: 
                    957: {
                    958: 
1.1.1.2   root      959:        UNUSED(dirh);
                    960: 
1.1       root      961:        return 0;
                    962: 
                    963: }
                    964: 
                    965: 
                    966: 
1.1.1.2   root      967: static long ARGS_ON_STACK 
1.1       root      968: 
                    969: bios_pathconf(dir, which)
                    970: 
                    971:        fcookie *dir;
                    972: 
                    973:        int which;
                    974: 
                    975: {
                    976: 
1.1.1.2   root      977:        UNUSED(dir);
                    978: 
                    979: 
                    980: 
1.1       root      981:        switch(which) {
                    982: 
                    983:        case -1:
                    984: 
                    985:                return DP_MAXREQ;
                    986: 
                    987:        case DP_IOPEN:
                    988: 
                    989:                return UNLIMITED;       /* no limit on BIOS file descriptors */
                    990: 
                    991:        case DP_MAXLINKS:
                    992: 
                    993:                return 1;               /* no hard links available */
                    994: 
                    995:        case DP_PATHMAX:
                    996: 
                    997:                return PATH_MAX;
                    998: 
                    999:        case DP_NAMEMAX:
                   1000: 
                   1001:                return BNAME_MAX;
                   1002: 
                   1003:        case DP_ATOMIC:
                   1004: 
                   1005:                return 1;               /* no atomic writes */
                   1006: 
                   1007:        case DP_TRUNC:
                   1008: 
                   1009:                return DP_AUTOTRUNC;    /* names are truncated */
                   1010: 
                   1011:        case DP_CASE:
                   1012: 
                   1013:                return DP_CASEINSENS;   /* not case sensitive */
                   1014: 
                   1015:        default:
                   1016: 
                   1017:                return EINVFN;
                   1018: 
                   1019:        }
                   1020: 
                   1021: }
                   1022: 
                   1023: 
                   1024: 
1.1.1.2   root     1025: static long ARGS_ON_STACK 
1.1       root     1026: 
                   1027: bios_dfree(dir, buf)
                   1028: 
                   1029:        fcookie *dir;
                   1030: 
                   1031:        long *buf;
                   1032: 
                   1033: {
                   1034: 
1.1.1.2   root     1035:        UNUSED(dir);
                   1036: 
                   1037: 
                   1038: 
1.1       root     1039:        buf[0] = 0;     /* number of free clusters */
                   1040: 
                   1041:        buf[1] = 0;     /* total number of clusters */
                   1042: 
                   1043:        buf[2] = 1;     /* sector size (bytes) */
                   1044: 
                   1045:        buf[3] = 1;     /* cluster size (sectors) */
                   1046: 
                   1047:        return 0;
                   1048: 
                   1049: }
                   1050: 
                   1051: 
                   1052: 
                   1053: /*
                   1054: 
                   1055:  * BIOS Dcntl() calls:
                   1056: 
                   1057:  * Dcntl(0xde02, "U:\DEV\FOO", &foo_descr): install a new device called
                   1058: 
                   1059:  *     "FOO", which is described by the dev_descr structure "foo_descr".
                   1060: 
                   1061:  *     this structure has the following fields:
                   1062: 
                   1063:  *         DEVDRV *driver              the device driver itself
                   1064: 
                   1065:  *        short  dinfo                 info for the device driver
                   1066: 
                   1067:  *        short  flags                 flags for the file (e.g. O_TTY)
                   1068: 
                   1069:  *        struct tty *tty              tty structure, if appropriate
                   1070: 
                   1071:  *
                   1072: 
                   1073:  * Dcntl(0xde00, "U:\DEV\BAR", n): install a new BIOS terminal device, with
                   1074: 
                   1075:  *     BIOS device number "n".
                   1076: 
                   1077:  * Dcntl(0xde01, "U:\DEV\BAR", n): install a new non-tty BIOS device, with
                   1078: 
                   1079:  *     BIOS device number "n".
                   1080: 
                   1081:  */
                   1082: 
                   1083: 
                   1084: 
1.1.1.2   root     1085: static long ARGS_ON_STACK 
1.1       root     1086: 
                   1087: bios_fscntl(dir, name, cmd, arg)
                   1088: 
                   1089:        fcookie *dir;
                   1090: 
                   1091:        const char *name;
                   1092: 
                   1093:        int cmd;
                   1094: 
                   1095:        long arg;
                   1096: 
                   1097: {
                   1098: 
                   1099:        struct bios_file *b;
                   1100: 
                   1101: 
                   1102: 
1.1.1.2   root     1103:        UNUSED(dir);
                   1104: 
                   1105:        if ((unsigned)cmd == DEV_INSTALL) {
1.1       root     1106: 
                   1107:                struct dev_descr *d = (struct dev_descr *)arg;
                   1108: 
                   1109: 
                   1110: 
                   1111:                b = kmalloc(SIZEOF(struct bios_file));
                   1112: 
                   1113:                if (!b) return 0;
                   1114: 
                   1115:                strncpy(b->name, name, BNAME_MAX);
                   1116: 
                   1117:                b->name[BNAME_MAX] = 0;
                   1118: 
                   1119:                b->device = d->driver;
                   1120: 
                   1121:                b->private = d->dinfo;
                   1122: 
                   1123:                b->flags = d->flags;
                   1124: 
                   1125:                b->tty = d->tty;
                   1126: 
                   1127:                b->next = broot;
                   1128: 
                   1129:                broot = b;
                   1130: 
                   1131:                return (long)&kernelinfo;
                   1132: 
                   1133:        }
                   1134: 
1.1.1.2   root     1135:        if ((unsigned)cmd == DEV_NEWTTY) {
1.1       root     1136: 
                   1137:                b = kmalloc(SIZEOF(struct bios_file));
                   1138: 
                   1139:                if (!b) return ENSMEM;
                   1140: 
                   1141:                b->tty = kmalloc(SIZEOF(struct tty));
                   1142: 
                   1143:                if (!b->tty) {
                   1144: 
                   1145:                        kfree(b);
                   1146: 
                   1147:                        return ENSMEM;
                   1148: 
                   1149:                }
                   1150: 
                   1151:                strncpy(b->name, name, BNAME_MAX);
                   1152: 
                   1153:                b->name[BNAME_MAX] = 0;
                   1154: 
                   1155:                b->device = &bios_tdevice;
                   1156: 
                   1157:                b->private = arg;
                   1158: 
                   1159:                b->flags = O_TTY;
                   1160: 
                   1161:                *b->tty = default_tty;
                   1162: 
                   1163:                b->next = broot;
                   1164: 
                   1165:                broot = b;
                   1166: 
                   1167:                return 0;
                   1168: 
                   1169:        }
                   1170: 
1.1.1.2   root     1171:        if ((unsigned)cmd == DEV_NEWBIOS) {
1.1       root     1172: 
                   1173:                b = kmalloc(SIZEOF(struct bios_file));
                   1174: 
                   1175:                if (!b) return ENSMEM;
                   1176: 
                   1177:                strncpy(b->name, name, BNAME_MAX);
                   1178: 
                   1179:                b->name[BNAME_MAX] = 0;
                   1180: 
                   1181:                b->tty = 0;
                   1182: 
                   1183:                b->device = &bios_ndevice;
                   1184: 
                   1185:                b->private = arg;
                   1186: 
                   1187:                b->flags = 0;
                   1188: 
                   1189:                b->next = broot;
                   1190: 
                   1191:                return 0;
                   1192: 
                   1193:        }
                   1194: 
                   1195:        return EINVFN;
                   1196: 
                   1197: }
                   1198: 
                   1199: 
                   1200: 
1.1.1.2   root     1201: static long ARGS_ON_STACK 
1.1       root     1202: 
                   1203: bios_symlink(dir, name, to)
                   1204: 
                   1205:        fcookie *dir;
                   1206: 
                   1207:        const char *name, *to;
                   1208: 
                   1209: {
                   1210: 
                   1211:        struct bios_file *b;
                   1212: 
                   1213:        long r;
                   1214: 
                   1215:        fcookie fc;
                   1216: 
                   1217: 
                   1218: 
                   1219:        r = bios_lookup(dir, name, &fc);
                   1220: 
                   1221:        if (r == 0) return EACCDN;      /* file already exists */
                   1222: 
                   1223:        if (r != EFILNF) return r;      /* some other error */
                   1224: 
                   1225: 
                   1226: 
                   1227:        b = kmalloc(SIZEOF(struct bios_file));
                   1228: 
                   1229:        if (!b) return EACCDN;
                   1230: 
                   1231: 
                   1232: 
                   1233:        strncpy(b->name, name, BNAME_MAX);
                   1234: 
                   1235:        b->name[BNAME_MAX] = 0;
                   1236: 
                   1237:        b->device = 0;
                   1238: 
                   1239:        b->private = EINVFN;
                   1240: 
                   1241:        b->flags = 0;
                   1242: 
                   1243:        b->tty = kmalloc((long)strlen(to)+1);
                   1244: 
                   1245:        if (!b->tty) {
                   1246: 
                   1247:                kfree(b);
                   1248: 
                   1249:                return EACCDN;
                   1250: 
                   1251:        }
                   1252: 
                   1253:        strcpy((char *)b->tty, to);
                   1254: 
                   1255:        b->next = broot;
                   1256: 
                   1257:        broot = b;
                   1258: 
                   1259:        return 0;
                   1260: 
                   1261: }
                   1262: 
                   1263: 
                   1264: 
1.1.1.2   root     1265: static long ARGS_ON_STACK 
1.1       root     1266: 
                   1267: bios_readlink(fc, buf, buflen)
                   1268: 
                   1269:        fcookie *fc;
                   1270: 
                   1271:        char *buf;
                   1272: 
                   1273:        int buflen;
                   1274: 
                   1275: {
                   1276: 
                   1277:        struct bios_file *b = (struct bios_file *)fc->index;
                   1278: 
                   1279: 
                   1280: 
                   1281:        if (!b) return EINVFN;
                   1282: 
                   1283:        if (b->device) return EINVFN;
                   1284: 
                   1285: 
                   1286: 
                   1287:        strncpy(buf, (char *)b->tty, buflen);
                   1288: 
                   1289:        if (strlen((char *)b->tty) >= buflen)
                   1290: 
                   1291:                return ENAMETOOLONG;
                   1292: 
                   1293:        return 0;
                   1294: 
                   1295: }
                   1296: 
                   1297: 
                   1298: 
                   1299: 
                   1300: 
                   1301: /*
                   1302: 
                   1303:  * routines for file systems that don't support volume labels
                   1304: 
                   1305:  */
                   1306: 
                   1307: 
                   1308: 
1.1.1.2   root     1309: long ARGS_ON_STACK 
1.1       root     1310: 
                   1311: nowritelabel(dir, name)
                   1312: 
                   1313:        fcookie *dir;
                   1314: 
                   1315:        const char *name;
                   1316: 
                   1317: {
                   1318: 
1.1.1.2   root     1319:        UNUSED(dir);
                   1320: 
                   1321:        UNUSED(name);
                   1322: 
1.1       root     1323:        return EACCDN;
                   1324: 
                   1325: }
                   1326: 
                   1327: 
                   1328: 
1.1.1.2   root     1329: long ARGS_ON_STACK 
1.1       root     1330: 
                   1331: noreadlabel(dir, name, namelen)
                   1332: 
                   1333:        fcookie *dir;
                   1334: 
                   1335:        char *name;
                   1336: 
                   1337:        int namelen;
                   1338: 
                   1339: {
                   1340: 
1.1.1.2   root     1341:        UNUSED(dir);
                   1342: 
                   1343:        UNUSED(name);
                   1344: 
                   1345:        UNUSED(namelen);
                   1346: 
1.1       root     1347:        return EFILNF;
                   1348: 
                   1349: }
                   1350: 
                   1351: 
                   1352: 
                   1353: /*
                   1354: 
                   1355:  * routines for file systems that don't support links
                   1356: 
                   1357:  */
                   1358: 
                   1359: 
                   1360: 
1.1.1.2   root     1361: long ARGS_ON_STACK 
1.1       root     1362: 
                   1363: nosymlink(dir, name, to)
                   1364: 
                   1365:        fcookie *dir;
                   1366: 
                   1367:        const char *name, *to;
                   1368: 
                   1369: {
                   1370: 
1.1.1.2   root     1371:        UNUSED(dir); UNUSED(name);
                   1372: 
                   1373:        UNUSED(to);
                   1374: 
1.1       root     1375:        return EINVFN;
                   1376: 
                   1377: }
                   1378: 
                   1379: 
                   1380: 
1.1.1.2   root     1381: long ARGS_ON_STACK 
1.1       root     1382: 
                   1383: noreadlink(dir, buf, buflen)
                   1384: 
                   1385:        fcookie *dir;
                   1386: 
                   1387:        char *buf;
                   1388: 
                   1389:        int buflen;
                   1390: 
                   1391: {
                   1392: 
1.1.1.2   root     1393:        UNUSED(dir); UNUSED(buf);
                   1394: 
                   1395:        UNUSED(buflen);
                   1396: 
1.1       root     1397:        return EINVFN;
                   1398: 
                   1399: }
                   1400: 
                   1401: 
                   1402: 
1.1.1.2   root     1403: long ARGS_ON_STACK 
1.1       root     1404: 
                   1405: nohardlink(fromdir, fromname, todir, toname)
                   1406: 
                   1407:        fcookie *fromdir, *todir;
                   1408: 
                   1409:        const char *fromname, *toname;
                   1410: 
                   1411: {
                   1412: 
1.1.1.2   root     1413:        UNUSED(fromdir); UNUSED(todir);
                   1414: 
                   1415:        UNUSED(fromname); UNUSED(toname);
                   1416: 
1.1       root     1417:        return EINVFN;
                   1418: 
                   1419: }
                   1420: 
                   1421: 
                   1422: 
                   1423: /* dummy routine for file systems with no Fscntl commands */
                   1424: 
                   1425: 
                   1426: 
1.1.1.2   root     1427: long ARGS_ON_STACK 
1.1       root     1428: 
                   1429: nofscntl(dir, name, cmd, arg)
                   1430: 
                   1431:        fcookie *dir;
                   1432: 
                   1433:        const char *name;
                   1434: 
                   1435:        int cmd;
                   1436: 
                   1437:        long arg;
                   1438: 
                   1439: {
                   1440: 
1.1.1.2   root     1441:        UNUSED(dir); UNUSED(name);
                   1442: 
                   1443:        UNUSED(cmd); UNUSED(arg);
                   1444: 
1.1       root     1445:        return EINVFN;
                   1446: 
                   1447: }
                   1448: 
                   1449: 
                   1450: 
                   1451: /*
                   1452: 
                   1453:  * Did the disk change? Not on this drive!
                   1454: 
                   1455:  * However, we have to do Getbpb anyways, because someone has decided
                   1456: 
                   1457:  * to force a media change on our (non-existent) drive.
                   1458: 
                   1459:  */
                   1460: 
1.1.1.2   root     1461: long ARGS_ON_STACK 
1.1       root     1462: 
                   1463: nodskchng(drv)
                   1464: 
                   1465:        int drv;
                   1466: 
                   1467: {
                   1468: 
                   1469:        (void)getbpb(drv);
                   1470: 
                   1471:        return 0;
                   1472: 
                   1473: }
                   1474: 
                   1475: 
                   1476: 
1.1.1.2   root     1477: long ARGS_ON_STACK 
1.1       root     1478: 
                   1479: nocreat(dir, name, mode, attrib, fc)
                   1480: 
                   1481:        fcookie *dir, *fc;
                   1482: 
                   1483:        const char *name;
                   1484: 
                   1485:        unsigned mode;
                   1486: 
                   1487:        int attrib;
                   1488: 
                   1489: {
                   1490: 
1.1.1.2   root     1491:        UNUSED(dir); UNUSED(fc);
                   1492: 
                   1493:        UNUSED(name); UNUSED(mode);
                   1494: 
                   1495:        UNUSED(attrib);
                   1496: 
1.1       root     1497:        return EACCDN;
                   1498: 
                   1499: }
                   1500: 
                   1501: 
                   1502: 
1.1.1.2   root     1503: static DEVDRV * ARGS_ON_STACK 
1.1       root     1504: 
                   1505: bios_getdev(fc, devsp)
                   1506: 
                   1507:        fcookie *fc;
                   1508: 
                   1509:        long *devsp;
                   1510: 
                   1511: {
                   1512: 
                   1513:        struct bios_file *b;
                   1514: 
                   1515: 
                   1516: 
                   1517:        b = (struct bios_file *)fc->index;
                   1518: 
                   1519: 
                   1520: 
                   1521:        if (b->device && b->device != &fakedev)
                   1522: 
                   1523:                *devsp = (long)b->tty;
                   1524: 
                   1525:        else
                   1526: 
                   1527:                *devsp = b->private;
                   1528: 
                   1529: 
                   1530: 
                   1531:        return b->device;       /* return the device driver */
                   1532: 
                   1533: }
                   1534: 
                   1535: 
                   1536: 
                   1537: /*
                   1538: 
                   1539:  * NULL device driver
                   1540: 
                   1541:  */
                   1542: 
                   1543: 
                   1544: 
1.1.1.2   root     1545: long ARGS_ON_STACK 
1.1       root     1546: 
                   1547: null_open(f)
                   1548: 
                   1549:        FILEPTR *f;
                   1550: 
                   1551: {
                   1552: 
1.1.1.2   root     1553:        UNUSED(f);
                   1554: 
1.1       root     1555:        return 0;
                   1556: 
                   1557: }
                   1558: 
                   1559: 
                   1560: 
1.1.1.2   root     1561: long ARGS_ON_STACK 
1.1       root     1562: 
                   1563: null_write(f, buf, bytes)
                   1564: 
                   1565:        FILEPTR *f; const char *buf; long bytes;
                   1566: 
                   1567: {
                   1568: 
1.1.1.2   root     1569:        UNUSED(f); UNUSED(buf);
                   1570: 
1.1       root     1571:        return bytes;
                   1572: 
                   1573: }
                   1574: 
                   1575: 
                   1576: 
1.1.1.2   root     1577: long ARGS_ON_STACK 
1.1       root     1578: 
                   1579: null_read(f, buf, bytes)
                   1580: 
                   1581:        FILEPTR *f; char *buf; long bytes;
                   1582: 
                   1583: {
                   1584: 
1.1.1.2   root     1585:        UNUSED(f); UNUSED(buf);
                   1586: 
                   1587:        UNUSED(bytes);
                   1588: 
1.1       root     1589:        return 0;
                   1590: 
                   1591: }
                   1592: 
                   1593: 
                   1594: 
1.1.1.2   root     1595: long ARGS_ON_STACK 
1.1       root     1596: 
                   1597: null_lseek(f, where, whence)
                   1598: 
                   1599:        FILEPTR *f; long where; int whence;
                   1600: 
                   1601: {
                   1602: 
1.1.1.2   root     1603:        UNUSED(f); UNUSED(whence);
                   1604: 
1.1       root     1605:        return (where == 0) ? 0 : ERANGE;
                   1606: 
                   1607: }
                   1608: 
                   1609: 
                   1610: 
1.1.1.2   root     1611: long ARGS_ON_STACK 
1.1       root     1612: 
                   1613: null_ioctl(f, mode, buf)
                   1614: 
                   1615:        FILEPTR *f; int mode; void *buf;
                   1616: 
                   1617: {
                   1618: 
1.1.1.2   root     1619:        UNUSED(f);
                   1620: 
1.1       root     1621:        if (mode == FIONREAD) {
                   1622: 
                   1623:                *((long *)buf) = 0;
                   1624: 
                   1625:        }
                   1626: 
                   1627:        else if (mode == FIONWRITE)
                   1628: 
                   1629:                *((long *)buf) = 1;
                   1630: 
                   1631:        else
                   1632: 
                   1633:                return EINVFN;
                   1634: 
                   1635:        return 0;
                   1636: 
                   1637: }
                   1638: 
                   1639: 
                   1640: 
1.1.1.2   root     1641: long ARGS_ON_STACK 
1.1       root     1642: 
                   1643: null_datime(f, timeptr, rwflag)
                   1644: 
                   1645:        FILEPTR *f;
                   1646: 
                   1647:        short *timeptr;
                   1648: 
                   1649:        int rwflag;
                   1650: 
                   1651: {
                   1652: 
1.1.1.2   root     1653:        UNUSED(f);
                   1654: 
1.1       root     1655:        if (rwflag)
                   1656: 
                   1657:                return EACCDN;
                   1658: 
                   1659:        *timeptr++ = timestamp;
                   1660: 
                   1661:        *timeptr = datestamp;
                   1662: 
                   1663:        return 0;
                   1664: 
                   1665: }
                   1666: 
                   1667: 
                   1668: 
1.1.1.2   root     1669: long ARGS_ON_STACK 
1.1       root     1670: 
                   1671: null_close(f, pid)
                   1672: 
                   1673:        FILEPTR *f;
                   1674: 
                   1675:        int pid;
                   1676: 
                   1677: {
                   1678: 
1.1.1.2   root     1679:        UNUSED(f);
                   1680: 
                   1681:        UNUSED(pid);
                   1682: 
1.1       root     1683:        return 0;
                   1684: 
                   1685: }
                   1686: 
                   1687: 
                   1688: 
1.1.1.2   root     1689: long ARGS_ON_STACK 
1.1       root     1690: 
                   1691: null_select(f, p, mode)
                   1692: 
                   1693:        FILEPTR *f; long p;
                   1694: 
                   1695:        int mode;
                   1696: 
                   1697: {
                   1698: 
1.1.1.2   root     1699:        UNUSED(f); UNUSED(p);
                   1700: 
                   1701:        UNUSED(mode);
                   1702: 
1.1       root     1703:        return 1;       /* we're always ready to read/write */
                   1704: 
                   1705: }
                   1706: 
                   1707: 
                   1708: 
1.1.1.2   root     1709: void ARGS_ON_STACK 
1.1       root     1710: 
                   1711: null_unselect(f, p, mode)
                   1712: 
                   1713:        FILEPTR *f;
                   1714: 
                   1715:        long p;
                   1716: 
                   1717:        int mode;
                   1718: 
                   1719: {
                   1720: 
1.1.1.2   root     1721:        UNUSED(f); UNUSED(p);
                   1722: 
                   1723:        UNUSED(mode);
                   1724: 
1.1       root     1725:        /* nothing to do */
                   1726: 
                   1727: }
                   1728: 
                   1729: 
                   1730: 
                   1731: /*
                   1732: 
                   1733:  * BIOS terminal device driver
                   1734: 
                   1735:  */
                   1736: 
                   1737: 
                   1738: 
1.1.1.2   root     1739: static long ARGS_ON_STACK 
1.1       root     1740: 
                   1741: bios_topen(f)
                   1742: 
                   1743:        FILEPTR *f;
                   1744: 
                   1745: {
                   1746: 
                   1747:        f->flags |= O_TTY;
                   1748: 
                   1749:        return 0;
                   1750: 
                   1751: }
                   1752: 
                   1753: 
                   1754: 
                   1755: /*
                   1756: 
                   1757:  * Note: when a BIOS device is a terminal (i.e. has the O_TTY flag
                   1758: 
                   1759:  * set), bios_read and bios_write will only ever be called indirectly, via
                   1760: 
                   1761:  * tty_read and tty_write. That's why we can afford to play a bit fast and
                   1762: 
                   1763:  * loose with the pointers ("buf" is really going to point to a long) and
                   1764: 
                   1765:  * why we know that "bytes" is divisible by 4.
                   1766: 
                   1767:  */
                   1768: 
                   1769: 
                   1770: 
1.1.1.2   root     1771: static long ARGS_ON_STACK 
1.1       root     1772: 
                   1773: bios_twrite(f, buf, bytes)
                   1774: 
                   1775:        FILEPTR *f; const char *buf; long bytes;
                   1776: 
                   1777: {
                   1778: 
                   1779:        long *r;
                   1780: 
                   1781:        long ret = 0;
                   1782: 
                   1783:        int bdev = f->fc.aux;
                   1784: 
                   1785: 
                   1786: 
                   1787:        r = (long *)buf;
                   1788: 
1.1.1.3   root     1789: 
                   1790: 
                   1791: /* Check for control characters on any newline output.
                   1792: 
                   1793:  * Note that newlines are always output through tty_putchar,
                   1794: 
                   1795:  * so they'll always be the first thing in the buffer (at least,
                   1796: 
                   1797:  * for cooked TTY output they will, which is the only sort that
                   1798: 
                   1799:  * control characters affect anyways).
                   1800: 
                   1801:  */
                   1802: 
                   1803:        if (bytes > 0 && (*r & 0x000000ffL) == '\n')
                   1804: 
                   1805:                (void) checkkeys();
                   1806: 
                   1807: 
                   1808: 
1.1.1.2   root     1809:        if (f->flags & O_NDELAY) {
1.1       root     1810: 
1.1.1.2   root     1811:                while (bytes > 0) {
                   1812: 
                   1813:                    if (!bcostat(bdev)) break;
                   1814: 
                   1815:                    if (bconout(bdev, (int)*r) == 0)
1.1       root     1816: 
                   1817:                        break;
                   1818: 
1.1.1.2   root     1819:                    r++; bytes -= 4; ret+= 4;
                   1820: 
                   1821:                }
                   1822: 
                   1823:        } else {
1.1       root     1824: 
1.1.1.2   root     1825:                while (bytes > 0) {
1.1       root     1826: 
1.1.1.2   root     1827:                    if (bconout(bdev, (int)*r) == 0)
1.1       root     1828: 
                   1829:                        break;
                   1830: 
1.1.1.2   root     1831:                    r++; bytes -= 4; ret+= 4;
1.1       root     1832: 
1.1.1.2   root     1833:                }
1.1       root     1834: 
                   1835:        }
                   1836: 
1.1.1.2   root     1837: #if 0
                   1838: 
1.1       root     1839:        (void)checkkeys();
                   1840: 
1.1.1.2   root     1841: #endif
                   1842: 
1.1       root     1843:        return ret;
                   1844: 
                   1845: }
                   1846: 
                   1847: 
                   1848: 
1.1.1.2   root     1849: static long ARGS_ON_STACK 
1.1       root     1850: 
                   1851: bios_tread(f, buf, bytes)
                   1852: 
                   1853:        FILEPTR *f; char *buf; long bytes;
                   1854: 
                   1855: {
                   1856: 
                   1857:        long *r, ret = 0;
                   1858: 
                   1859:        int bdev = f->fc.aux;
                   1860: 
                   1861: 
                   1862: 
                   1863:        r = (long *)buf;
                   1864: 
                   1865: 
                   1866: 
1.1.1.2   root     1867:        if ((f->flags & O_NDELAY)) {
1.1       root     1868: 
1.1.1.2   root     1869:                while (bytes > 0) {
                   1870: 
                   1871:                    if ( !bconstat(bdev) )
1.1       root     1872: 
                   1873:                        break;
                   1874: 
1.1.1.2   root     1875:                    *r++ = bconin(bdev) & 0x7fffffffL;
                   1876: 
                   1877:                    bytes -= 4; ret += 4;
                   1878: 
                   1879:                }
                   1880: 
                   1881:        } else {
1.1       root     1882: 
1.1.1.2   root     1883:                while (bytes > 0) {
                   1884: 
                   1885:                    *r++ = bconin(bdev) & 0x7fffffffL;
                   1886: 
                   1887:                    bytes -= 4; ret += 4;
                   1888: 
                   1889:                }
1.1       root     1890: 
                   1891:        }
                   1892: 
                   1893:        return ret;
                   1894: 
                   1895: }
                   1896: 
                   1897: 
                   1898: 
                   1899: /*
                   1900: 
                   1901:  * read/write routines for BIOS devices that aren't terminals (like the
                   1902: 
                   1903:  * printer & IKBD devices)
                   1904: 
                   1905:  */
                   1906: 
                   1907: 
                   1908: 
1.1.1.2   root     1909: static long ARGS_ON_STACK 
1.1       root     1910: 
                   1911: bios_nwrite(f, buf, bytes)
                   1912: 
                   1913:        FILEPTR *f; const char *buf; long bytes;
                   1914: 
                   1915: {
                   1916: 
                   1917:        long ret = 0;
                   1918: 
                   1919:        int bdev = f->fc.aux;
                   1920: 
                   1921:        int c;
                   1922: 
                   1923: 
                   1924: 
                   1925:        while (bytes > 0) {
                   1926: 
                   1927:                if ( (f->flags & O_NDELAY) && !bcostat(bdev) )
                   1928: 
                   1929:                        break;
                   1930: 
                   1931: 
                   1932: 
                   1933:                c = *buf++ & 0x00ff;
                   1934: 
                   1935: 
                   1936: 
                   1937:                if (bconout(bdev, c) == 0)
                   1938: 
                   1939:                        break;
                   1940: 
                   1941: 
                   1942: 
                   1943:                bytes--; ret++;
                   1944: 
                   1945:        }
                   1946: 
                   1947:        return ret;
                   1948: 
                   1949: }
                   1950: 
                   1951: 
                   1952: 
1.1.1.2   root     1953: static long ARGS_ON_STACK 
1.1       root     1954: 
                   1955: bios_nread(f, buf, bytes)
                   1956: 
                   1957:        FILEPTR *f; char *buf; long bytes;
                   1958: 
                   1959: {
                   1960: 
                   1961:        long ret = 0;
                   1962: 
                   1963:        int bdev = f->fc.aux;
                   1964: 
                   1965: 
                   1966: 
                   1967:        while (bytes > 0) {
                   1968: 
                   1969:                if ( (f->flags & O_NDELAY) && !bconstat(bdev) )
                   1970: 
                   1971:                        break;
                   1972: 
                   1973:                *buf++ = bconin(bdev) & 0xff;
                   1974: 
                   1975:                bytes--; ret++;
                   1976: 
                   1977:        }
                   1978: 
                   1979:        return ret;
                   1980: 
                   1981: }
                   1982: 
                   1983: 
                   1984: 
                   1985: /*
                   1986: 
                   1987:  * BIOS terminal seek code -- this has to match the documented
                   1988: 
                   1989:  * way to do isatty()
                   1990: 
                   1991:  */
                   1992: 
                   1993: 
                   1994: 
1.1.1.2   root     1995: static long ARGS_ON_STACK 
1.1       root     1996: 
                   1997: bios_tseek(f, where, whence)
                   1998: 
                   1999:        FILEPTR *f;
                   2000: 
                   2001:        long where;
                   2002: 
                   2003:        int whence;
                   2004: 
                   2005: {
                   2006: 
1.1.1.2   root     2007:        UNUSED(f); UNUSED(where);
                   2008: 
                   2009:        UNUSED(whence);
                   2010: 
1.1       root     2011: /* terminals always are at position 0 */
                   2012: 
                   2013:        return 0;
                   2014: 
                   2015: }
                   2016: 
                   2017: 
                   2018: 
                   2019: #define MAXBAUD 16
                   2020: 
                   2021: 
                   2022: 
1.1.1.2   root     2023: /* keep these sorted in descending order */
                   2024: 
1.1       root     2025: static long baudmap[MAXBAUD] = {
                   2026: 
                   2027: 19200L, 9600L, 4800L, 3600L, 2400L, 2000L, 1800L, 1200L,
                   2028: 
                   2029: 600L, 300L, 200L, 150L, 134L, 110L, 75L, 50L
                   2030: 
                   2031: };
                   2032: 
                   2033: 
                   2034: 
1.1.1.2   root     2035: static long ARGS_ON_STACK 
1.1       root     2036: 
                   2037: bios_ioctl(f, mode, buf)
                   2038: 
                   2039:        FILEPTR *f; int mode; void *buf;
                   2040: 
                   2041: {
                   2042: 
                   2043:        long *r = (long *)buf;
                   2044: 
                   2045:        struct winsize *ws;
                   2046: 
                   2047:        char *aline;
                   2048: 
                   2049:        short dev;
                   2050: 
                   2051:        int i;
                   2052: 
                   2053: 
                   2054: 
                   2055:        if (mode == FIONREAD) {
                   2056: 
                   2057:                if (bconstat(f->fc.aux))
                   2058: 
                   2059:                        *r = 1;
                   2060: 
                   2061:                else
                   2062: 
                   2063:                        *r = 0;
                   2064: 
                   2065:        }
                   2066: 
                   2067:        else if (mode == FIONWRITE) {
                   2068: 
                   2069:                if (bcostat(f->fc.aux))
                   2070: 
                   2071:                        *r = 1;
                   2072: 
                   2073:                else
                   2074: 
                   2075:                        *r = 0;
                   2076: 
                   2077:        }
                   2078: 
                   2079:        else if (mode == TIOCFLUSH) {
                   2080: 
                   2081: /* BUG: this should flush the input/output buffers */
                   2082: 
                   2083:                return 0;
                   2084: 
                   2085:        }
                   2086: 
                   2087:        else if (mode == TIOCGWINSZ && f->fc.aux == 2) {
                   2088: 
                   2089:                aline = lineA0();
                   2090: 
                   2091:                ws = (struct winsize *)buf;
                   2092: 
                   2093:                ws->ws_row = *((short *)(aline - 42)) + 1;
                   2094: 
                   2095:                ws->ws_col = *((short *)(aline - 44)) + 1;
                   2096: 
                   2097:        } else if (mode == TIOCIBAUD || mode == TIOCOBAUD) {
                   2098: 
                   2099:                long oldbaud, newbaud;
                   2100: 
1.1.1.4 ! root     2101:                int oldmap;
        !          2102: 
        !          2103: 
        !          2104: 
1.1       root     2105:                dev = f->fc.aux;
                   2106: 
                   2107: 
                   2108: 
                   2109:                newbaud = *r;
                   2110: 
                   2111:                if (dev == 1 || dev >= 6) {
                   2112: 
1.1.1.4 ! root     2113: /* trick rsconf into setting the correct port (it uses curproc->bconmap) */
        !          2114: 
        !          2115:                        oldmap = curproc->bconmap;
        !          2116: 
1.1       root     2117:                        if (has_bconmap)
                   2118: 
1.1.1.4 ! root     2119:                                curproc->bconmap = 
        !          2120: 
        !          2121:                                        (dev == 1) ? curproc->bconmap : dev;
1.1       root     2122: 
1.1.1.2   root     2123:                        i = (int)rsconf(-2, -1, -1, -1, -1, -1);
1.1       root     2124: 
1.1.1.4 ! root     2125: 
        !          2126: 
1.1       root     2127:                        if (i < 0 || i >= MAXBAUD)
                   2128: 
                   2129:                                oldbaud = -1L;
                   2130: 
                   2131:                        else
                   2132: 
                   2133:                                oldbaud = baudmap[i];
                   2134: 
                   2135:                        *r = oldbaud;
                   2136: 
1.1.1.4 ! root     2137:                        if (newbaud > 0 && newbaud != oldbaud) {
1.1       root     2138: 
1.1.1.2   root     2139:        /* BUG: assert DTR works only on modem1 */
                   2140: 
                   2141:                                if (dev == 1 || dev == 6) {
                   2142: 
                   2143:                                        Offgibit(0xef);
                   2144: 
                   2145:                                }
                   2146: 
1.1       root     2147:                                for (i = 0; i < MAXBAUD; i++) {
                   2148: 
                   2149:                                        if (baudmap[i] == newbaud) {
                   2150: 
                   2151:                                                rsconf(i, -1, -1, -1, -1, -1);
                   2152: 
1.1.1.4 ! root     2153:                                                curproc->bconmap = oldmap;
        !          2154: 
1.1       root     2155:                                                return 0;
                   2156: 
1.1.1.2   root     2157:                                        } else if (baudmap[i] < newbaud) {
                   2158: 
                   2159:                                                *r = baudmap[i];
                   2160: 
1.1.1.4 ! root     2161:                                                curproc->bconmap = oldmap;
        !          2162: 
1.1.1.2   root     2163:                                                break;
                   2164: 
1.1       root     2165:                                        }
                   2166: 
                   2167:                                }
                   2168: 
1.1.1.4 ! root     2169:                                curproc->bconmap = oldmap;
        !          2170: 
1.1       root     2171:                                return ERANGE;
                   2172: 
                   2173:                        } else if (newbaud == 0L) {
                   2174: 
1.1.1.2   root     2175:        /* BUG: drop DTR: works only on modem1 */
1.1       root     2176: 
                   2177:                                if (dev == 1 || dev == 6) {
                   2178: 
                   2179:                                        Ongibit(0x10);
                   2180: 
                   2181:                                }
                   2182: 
                   2183:                        }
                   2184: 
1.1.1.4 ! root     2185:                        curproc->bconmap = oldmap;
        !          2186: 
1.1       root     2187:                        return 0;
                   2188: 
                   2189:                } else if (dev == 2 || dev == 5) {
                   2190: 
                   2191:                        /* screen: assume 9600 baud */
                   2192: 
                   2193:                        oldbaud = 9600L;
                   2194: 
                   2195:                } else if (dev == 3) {
                   2196: 
                   2197:                        /* midi */
                   2198: 
                   2199:                        oldbaud = 31250L;
                   2200: 
                   2201:                } else {
                   2202: 
                   2203:                        oldbaud = -1L;  /* unknown speed */
                   2204: 
                   2205:                }
                   2206: 
                   2207:                *r = oldbaud;
                   2208: 
                   2209:                if (newbaud > 0 && newbaud != oldbaud)
                   2210: 
                   2211:                        return ERANGE;
                   2212: 
                   2213:                return 0;
                   2214: 
                   2215:        } else if (mode == TIOCCBRK || mode == TIOCSBRK) {
                   2216: 
                   2217:                unsigned long bits;
                   2218: 
                   2219: 
                   2220: 
                   2221:                dev = f->fc.aux;
                   2222: 
                   2223:                if (dev == 1 || dev >= 6) {
                   2224: 
                   2225:                        if (has_bconmap)
                   2226: 
                   2227:                                mapin((dev == 1) ? curproc->bconmap : dev);
                   2228: 
                   2229:                } else {
                   2230: 
                   2231:                        return EINVFN;
                   2232: 
                   2233:                }
                   2234: 
                   2235:                bits = rsconf(-1, -1, -1, -1, -1, -1);  /* get settings */
                   2236: 
                   2237:                bits = (bits >> 8) & 0x0ff;             /* isolate TSR byte */
                   2238: 
                   2239:                if (mode == TIOCCBRK)
                   2240: 
                   2241:                        bits &= ~8;
                   2242: 
                   2243:                else
                   2244: 
                   2245:                        bits |= 8;
                   2246: 
                   2247:                (void)rsconf(-1, -1, -1, -1, (int)bits, -1);
                   2248: 
                   2249:        } else if (mode == TIOCGFLAGS || mode == TIOCSFLAGS) {
                   2250: 
                   2251:                unsigned short oflags, flags;
                   2252: 
                   2253:                unsigned long bits;
                   2254: 
                   2255:                unsigned char ucr;
                   2256: 
                   2257:                short flow;
                   2258: 
                   2259: 
                   2260: 
                   2261:                dev = f->fc.aux;
                   2262: 
                   2263:                if (dev == 1 || dev >= 6) {
                   2264: 
                   2265:                        oflags = ((struct tty *)f->devinfo)->sg.sg_flags;
                   2266: 
                   2267:                        oflags &= (T_TANDEM|T_RTSCTS);
                   2268: 
                   2269:                        if (has_bconmap)
                   2270: 
                   2271:                                mapin((dev == 1) ? curproc->bconmap : dev);
                   2272: 
                   2273:                        bits = rsconf(-1, -1, -1, -1, -1, -1);  /* get settings */
                   2274: 
                   2275:                        ucr = (bits >> 24L) & 0x0ff;            /* isolate UCR byte */
                   2276: 
                   2277:                        oflags |= (ucr >> 3) & (TF_STOPBITS|TF_CHARBITS);
                   2278: 
                   2279:                        if (ucr & 0x4) {                        /* parity on? */
                   2280: 
                   2281:                                oflags |= (ucr & 0x2) ? T_EVENP : T_ODDP;
                   2282: 
                   2283:                        }
                   2284: 
                   2285:                        if (mode == TIOCSFLAGS) {
                   2286: 
                   2287:                                flags = (*(unsigned short *)buf);
                   2288: 
                   2289:                                if (flags & T_EVENP) {
                   2290: 
                   2291:                                        ucr |= 0x6;
                   2292: 
                   2293:                                } else if (flags & T_ODDP) {
                   2294: 
                   2295:                                        ucr &= ~2;
                   2296: 
                   2297:                                        ucr |= 0x4;
                   2298: 
                   2299:                                } else {
                   2300: 
                   2301:                                        ucr &= ~6;
                   2302: 
                   2303:                                }
                   2304: 
                   2305:                                if (flags & TF_STOPBITS) {
                   2306: 
                   2307:                                        ucr &= ~(0x18);
                   2308: 
                   2309:                                        ucr |= (flags & TF_STOPBITS) << 3;
                   2310: 
                   2311:                                }
                   2312: 
                   2313:                                ucr &= ~(0x60);
                   2314: 
                   2315:                                ucr |= (flags & TF_CHARBITS) << 3;
                   2316: 
                   2317:                                flow = (flags & (T_RTSCTS|T_TANDEM)) >> 12L;
                   2318: 
                   2319:                                rsconf(-1, flow, ucr, -1, -1, -1);
                   2320: 
                   2321:                        } else {
                   2322: 
                   2323:                                *((unsigned short *)buf) = oflags;
                   2324: 
                   2325:                        }
                   2326: 
                   2327:                } else {
                   2328: 
                   2329:                        return EINVFN;
                   2330: 
                   2331:                }
                   2332: 
1.1.1.4 ! root     2333:        } else if ((mode >= TCURSOFF && mode <= TCURSSTEADY) && (f->fc.aux == 2)) {
        !          2334: 
        !          2335:                return Cursconf(mode - TCURSOFF, 0);
        !          2336: 
        !          2337:        } else if ((mode >= TCURSSRATE && mode <= TCURSGRATE) && (f->fc.aux == 2)) {
        !          2338: 
        !          2339:                long r;
        !          2340: 
        !          2341: 
        !          2342: 
        !          2343:                r = Cursconf(mode - TCURSOFF, *((short *)buf));
        !          2344: 
        !          2345:                if (r >= 0) {
        !          2346: 
        !          2347:                        *(short *)buf = r;
        !          2348: 
        !          2349:                        r = 0;
        !          2350: 
        !          2351:                }
1.1       root     2352: 
1.1.1.4 ! root     2353:                return r;
1.1       root     2354: 
                   2355:        } else {
                   2356: 
                   2357:        /* Fcntl will automatically call tty_ioctl to handle
                   2358: 
                   2359:         * terminal calls that we didn't deal with
                   2360: 
                   2361:         */
                   2362: 
                   2363:                return EINVFN;
                   2364: 
                   2365:        }
                   2366: 
                   2367:        return 0;
                   2368: 
                   2369: }
                   2370: 
                   2371: 
                   2372: 
1.1.1.2   root     2373: static long ARGS_ON_STACK 
1.1       root     2374: 
                   2375: bios_select(f, p, mode)
                   2376: 
                   2377:        FILEPTR *f; long p; int mode;
                   2378: 
                   2379: {
                   2380: 
                   2381:        struct tty *tty = (struct tty *)f->devinfo;
                   2382: 
                   2383:        int dev = f->fc.aux;
                   2384: 
                   2385: 
                   2386: 
                   2387:        if (mode == O_RDONLY) {
                   2388: 
                   2389:                if (bconstat(dev)) {
                   2390: 
1.1.1.2   root     2391:                        TRACE(("bios_select: data present for device %d", dev));
1.1       root     2392: 
                   2393:                        return 1;
                   2394: 
                   2395:                }
                   2396: 
                   2397:                if (tty) {
                   2398: 
                   2399:                /* avoid collisions with other processes */
                   2400: 
                   2401:                        if (!tty->rsel)
                   2402: 
                   2403:                                tty->rsel = p;
                   2404: 
                   2405:                }
                   2406: 
                   2407:                return 0;
                   2408: 
                   2409:        } else if (mode == O_WRONLY) {
                   2410: 
                   2411:                if (bcostat(dev)) {
                   2412: 
1.1.1.2   root     2413:                        TRACE(("bios_select: ready to output on %d", dev));
1.1       root     2414: 
                   2415:                        return 1;
                   2416: 
                   2417:                }
                   2418: 
                   2419:                if (tty) {
                   2420: 
                   2421:                        if (!tty->wsel)
                   2422: 
                   2423:                                tty->wsel = p;
                   2424: 
                   2425:                }
                   2426: 
                   2427:                return 0;
                   2428: 
                   2429:        }
                   2430: 
                   2431:        /* default -- we don't know this mode, return 0 */
                   2432: 
                   2433:        return 0;
                   2434: 
                   2435: }
                   2436: 
                   2437: 
                   2438: 
1.1.1.2   root     2439: static void ARGS_ON_STACK 
1.1       root     2440: 
                   2441: bios_unselect(f, p, mode)
                   2442: 
                   2443:        FILEPTR *f;
                   2444: 
                   2445:        long p;
                   2446: 
                   2447:        int mode;
                   2448: 
                   2449: {
                   2450: 
                   2451:        struct tty *tty = (struct tty *)f->devinfo;
                   2452: 
                   2453: 
                   2454: 
                   2455:        if (tty) {
                   2456: 
                   2457:                if (mode == O_RDONLY && tty->rsel == p)
                   2458: 
                   2459:                        tty->rsel = 0;
                   2460: 
                   2461:                else if (mode == O_WRONLY && tty->wsel == p)
                   2462: 
                   2463:                        tty->wsel = 0;
                   2464: 
                   2465:        }
                   2466: 
                   2467: }
                   2468: 
                   2469: 
                   2470: 
                   2471: /*
                   2472: 
                   2473:  * mouse device driver
                   2474: 
                   2475:  */
                   2476: 
                   2477: 
                   2478: 
                   2479: #define MOUSESIZ 128*3
                   2480: 
                   2481: static unsigned char mousebuf[MOUSESIZ];
                   2482: 
                   2483: static int mousehead, mousetail;
                   2484: 
                   2485: 
                   2486: 
                   2487: long mousersel;        /* is someone calling select() on the mouse? */
                   2488: 
                   2489: 
                   2490: 
                   2491: char mshift;           /* shift key status; set by checkkeys() in bios.c */
                   2492: 
                   2493: short *gcurx = 0,
                   2494: 
                   2495:       *gcury = 0;      /* mouse pos. variables; used by big screen emulators */
                   2496: 
                   2497: 
                   2498: 
1.1.1.2   root     2499: void ARGS_ON_STACK 
1.1       root     2500: 
                   2501: mouse_handler(buf)
                   2502: 
                   2503:        const char *buf;        /* must be a *signed* character */
                   2504: 
                   2505: {
                   2506: 
                   2507:        unsigned char *mbuf, buttons;
                   2508: 
                   2509:        int newmtail;
                   2510: 
                   2511:        short dx, dy;
                   2512: 
                   2513: 
                   2514: 
                   2515: /* the Sun mouse driver has 0=down, 1=up, while the atari hardware gives
                   2516: 
                   2517:    us the reverse. also, we have the "middle" button and the "left"
                   2518: 
                   2519:    button reversed; so we use this table to convert (and also to add the
                   2520: 
                   2521:    0x80 to indicate a mouse packet)
                   2522: 
                   2523:  */
                   2524: 
                   2525:        static int _cnvrt[8] = {
                   2526: 
                   2527:                0x87, 0x86, 0x83, 0x82, 0x85, 0x84, 0x81, 0x80
                   2528: 
                   2529:        };
                   2530: 
                   2531: 
                   2532: 
                   2533:        mbuf = &mousebuf[mousetail];
                   2534: 
                   2535:        newmtail = mousetail + 3;
                   2536: 
                   2537:        if (newmtail >= MOUSESIZ)
                   2538: 
                   2539:                newmtail = 0;
                   2540: 
                   2541:        if (newmtail == mousehead)
                   2542: 
                   2543:                return;                 /* buffer full */
                   2544: 
                   2545: 
                   2546: 
                   2547:        buttons = *buf++ & 0x7;         /* convert to SUN format */
                   2548: 
                   2549:        if (mshift & 0x3) {             /* a shift key held down? */
                   2550: 
                   2551:        /* if so, convert shift+button to a "middle" button */
                   2552: 
                   2553:                if (buttons == 0x1 || buttons == 0x2)
                   2554: 
                   2555:                        buttons = 0x4;
                   2556: 
                   2557:                else if (buttons == 0x3)
                   2558: 
                   2559:                        buttons = 0x7;
                   2560: 
                   2561:        }
                   2562: 
                   2563:        *mbuf++ = _cnvrt[buttons];      /* convert to Sun format */
                   2564: 
                   2565:        dx = *buf++;
                   2566: 
                   2567:        *mbuf++ = dx;                   /* copy X delta */
                   2568: 
1.1.1.2   root     2569:        dy = *buf;
1.1       root     2570: 
1.1.1.2   root     2571:        *mbuf = -dy;                    /* invert Y delta for Sun format */
1.1       root     2572: 
                   2573:        mousetail = newmtail;
                   2574: 
                   2575:        *gcurx += dx;                   /* update line A variables */
                   2576: 
                   2577:        *gcury += dy;
                   2578: 
                   2579: /*
                   2580: 
                   2581:  * if someone has called select() waiting for mouse input, wake them
                   2582: 
                   2583:  * up
                   2584: 
                   2585:  */
                   2586: 
                   2587:        if (mousersel) {
                   2588: 
                   2589:                wakeselect(mousersel);
                   2590: 
                   2591:        }
                   2592: 
                   2593: }
                   2594: 
                   2595: 
                   2596: 
1.1.1.2   root     2597: extern void newmvec(), newjvec();      /* in intr.s */
1.1       root     2598: 
                   2599: static long oldvec = 0;
                   2600: 
1.1.1.2   root     2601: long oldjvec = 0;
                   2602: 
1.1       root     2603: 
                   2604: 
1.1.1.2   root     2605: static long ARGS_ON_STACK 
1.1       root     2606: 
                   2607: mouse_open(f)
                   2608: 
                   2609:        FILEPTR *f;
                   2610: 
                   2611: {
                   2612: 
                   2613:        char *aline;
                   2614: 
                   2615: 
                   2616: 
                   2617:        static char parameters[] = {
                   2618: 
                   2619:                0,              /* Y=0 in lower corner */
                   2620: 
                   2621:                0,              /* normal button handling */
                   2622: 
                   2623:                1, 1            /* X, Y scaling factors */
                   2624: 
                   2625:        };
                   2626: 
                   2627: 
                   2628: 
1.1.1.2   root     2629:        UNUSED(f);
                   2630: 
                   2631: 
                   2632: 
1.1       root     2633:        if (oldvec)             /* mouse in use */
                   2634: 
                   2635:                return EACCDN;
                   2636: 
                   2637: 
                   2638: 
                   2639: /* initialize pointers to line A variables */
                   2640: 
                   2641:        if (!gcurx) {
                   2642: 
                   2643:                aline = lineA0();
                   2644: 
                   2645:                if (aline == 0) {       /* should never happen */
                   2646: 
                   2647:                        ALERT("unable to read line A variables");
                   2648: 
                   2649:                        return -1;
                   2650: 
                   2651:                }
                   2652: 
                   2653:                gcurx = (short *)(aline - 0x25a);
                   2654: 
                   2655:                gcury = (short *)(aline - 0x258);
                   2656: 
                   2657:                *gcurx = *gcury = 32;   /* magic number -- what MGR uses */
                   2658: 
                   2659:        }
                   2660: 
                   2661: 
                   2662: 
                   2663:        oldvec = syskey->mousevec;
                   2664: 
1.1.1.2   root     2665:        oldjvec = syskey->joyvec;       /* jr: save old joystick vector */
                   2666: 
1.1       root     2667:        Initmous(1, parameters, newmvec);
                   2668: 
1.1.1.2   root     2669:        syskey->joyvec = (long)newjvec; /* jr: set up new joystick handler */
                   2670: 
1.1       root     2671:        mousehead = mousetail = 0;
                   2672: 
                   2673:        return 0;
                   2674: 
                   2675: }
                   2676: 
                   2677: 
                   2678: 
1.1.1.2   root     2679: static long ARGS_ON_STACK 
1.1       root     2680: 
                   2681: mouse_close(f, pid)
                   2682: 
                   2683:        FILEPTR *f;
                   2684: 
                   2685:        int pid;
                   2686: 
                   2687: {
                   2688: 
                   2689:        static char parameters[] = {
                   2690: 
                   2691:                0,              /* Y=0 in lower corner */
                   2692: 
                   2693:                0,              /* normal button handling */
                   2694: 
                   2695:                1, 1            /* X, Y scaling factors */
                   2696: 
                   2697:        };
                   2698: 
                   2699: 
                   2700: 
1.1.1.2   root     2701:        UNUSED(pid);
                   2702: 
1.1       root     2703:        if (!f) return EIHNDL;
                   2704: 
                   2705:        if (f->links <= 0) {
                   2706: 
                   2707:                if (!oldvec) {
                   2708: 
1.1.1.2   root     2709:                        DEBUG(("Mouse not open!!"));
1.1       root     2710: 
                   2711:                        return -1;
                   2712: 
                   2713:                }
                   2714: 
                   2715:                Initmous(1, parameters, (void *)oldvec);        /* gratuitous (void *) for Lattice */
                   2716: 
1.1.1.2   root     2717:                syskey->joyvec = oldjvec;       /* jr: restore old joystick handler */
                   2718: 
1.1       root     2719:                oldvec = 0;
                   2720: 
                   2721:        }
                   2722: 
                   2723:        return 0;
                   2724: 
                   2725: }
                   2726: 
                   2727: 
                   2728: 
1.1.1.2   root     2729: static long ARGS_ON_STACK 
1.1       root     2730: 
                   2731: mouse_read(f, buf, nbytes)
                   2732: 
                   2733:        FILEPTR *f;
                   2734: 
                   2735:        char *buf;
                   2736: 
                   2737:        long nbytes;
                   2738: 
                   2739: {
                   2740: 
                   2741:        long count = 0;
                   2742: 
                   2743:        int mhead;
                   2744: 
                   2745:        unsigned char *foo;
                   2746: 
                   2747: 
                   2748: 
                   2749:        mhead = mousehead;
                   2750: 
                   2751:        foo = &mousebuf[mhead];
                   2752: 
                   2753: 
                   2754: 
                   2755:        if (mhead == mousetail) {
                   2756: 
                   2757:                if (f->flags & O_NDELAY)
                   2758: 
                   2759:                        return 0;
                   2760: 
                   2761:                do {
                   2762: 
                   2763:                        yield();
                   2764: 
                   2765:                } while (mhead == mousetail);
                   2766: 
                   2767:        }
                   2768: 
                   2769: 
                   2770: 
                   2771:        while ( (mhead != mousetail) && (nbytes > 0)) {
                   2772: 
                   2773:                *buf++ = *foo++;
                   2774: 
                   2775:                mhead++;
                   2776: 
                   2777:                if (mhead >= MOUSESIZ) {
                   2778: 
                   2779:                        mhead = 0;
                   2780: 
                   2781:                        foo = mousebuf;
                   2782: 
                   2783:                }
                   2784: 
                   2785:                count++;
                   2786: 
                   2787:                --nbytes;
                   2788: 
                   2789:        }
                   2790: 
                   2791:        mousehead = mhead;
                   2792: 
                   2793:        return count;
                   2794: 
                   2795: }
                   2796: 
                   2797: 
                   2798: 
1.1.1.2   root     2799: static long ARGS_ON_STACK 
1.1       root     2800: 
                   2801: mouse_ioctl(f, mode, buf)
                   2802: 
                   2803:        FILEPTR *f;
                   2804: 
                   2805:        int mode;
                   2806: 
                   2807:        void *buf;
                   2808: 
                   2809: {
                   2810: 
                   2811:        long r;
                   2812: 
                   2813: 
                   2814: 
1.1.1.2   root     2815:        UNUSED(f);
                   2816: 
1.1       root     2817:        if (mode == FIONREAD) {
                   2818: 
                   2819:                r = mousetail - mousehead;
                   2820: 
                   2821:                if (r < 0) r += MOUSESIZ;
                   2822: 
                   2823:                *((long *)buf) = r;
                   2824: 
                   2825:        }
                   2826: 
                   2827:        else
                   2828: 
                   2829:                return EINVFN;
                   2830: 
                   2831:        return 0;
                   2832: 
                   2833: }
                   2834: 
                   2835: 
                   2836: 
1.1.1.2   root     2837: static long ARGS_ON_STACK 
1.1       root     2838: 
                   2839: mouse_select(f, p, mode)
                   2840: 
                   2841:        FILEPTR *f;
                   2842: 
                   2843:        long p;
                   2844: 
                   2845:        int mode;
                   2846: 
                   2847: {
                   2848: 
1.1.1.2   root     2849:        UNUSED(f);
                   2850: 
                   2851: 
                   2852: 
1.1       root     2853:        if (mode != O_RDONLY)
                   2854: 
                   2855:                return 1;       /* we can always take output :-) */
                   2856: 
                   2857: 
                   2858: 
                   2859:        if (mousetail - mousehead)
                   2860: 
                   2861:                return 1;       /* input waiting already */
                   2862: 
                   2863: 
                   2864: 
                   2865:        if (!mousersel)
                   2866: 
                   2867:                mousersel = p;
                   2868: 
                   2869:        return 0;
                   2870: 
                   2871: }
                   2872: 
                   2873: 
                   2874: 
1.1.1.2   root     2875: static void ARGS_ON_STACK 
1.1       root     2876: 
                   2877: mouse_unselect(f, p, mode)
                   2878: 
                   2879:        FILEPTR *f;
                   2880: 
                   2881:        long p;
                   2882: 
                   2883:        int mode;
                   2884: 
                   2885: {
                   2886: 
1.1.1.2   root     2887:        UNUSED(f);
                   2888: 
                   2889: 
                   2890: 
1.1       root     2891:        if (mode == O_RDONLY && mousersel == p)
                   2892: 
                   2893:                mousersel = 0;
                   2894: 
                   2895: }
                   2896: 
                   2897: 
                   2898: 
                   2899: 
                   2900: 
                   2901: /*
                   2902: 
                   2903:  * UTILITY ROUTINE called by Bconmap() in xbios.c:
                   2904: 
                   2905:  * this sets handle -1 of process p to a file handle
                   2906: 
                   2907:  * that has BIOS device "dev". Returns 0 on failure,
                   2908: 
                   2909:  * non-zero on success.
                   2910: 
                   2911:  */
                   2912: 
                   2913: 
                   2914: 
                   2915: int
                   2916: 
                   2917: set_auxhandle(p, dev)
                   2918: 
                   2919:        PROC *p;
                   2920: 
                   2921:        int dev;
                   2922: 
                   2923: {
                   2924: 
                   2925:        FILEPTR *f;
                   2926: 
                   2927:        struct bios_file *b;
                   2928: 
                   2929: 
                   2930: 
                   2931:        f = new_fileptr();
                   2932: 
                   2933:        if (f) {
                   2934: 
                   2935:                f->links = 1;
                   2936: 
                   2937:                f->flags = O_RDWR;
                   2938: 
                   2939:                f->pos = 0;
                   2940: 
                   2941:                f->devinfo = 0;
                   2942: 
                   2943:                f->fc.fs = &bios_filesys;
                   2944: 
                   2945:                f->fc.aux = dev;
                   2946: 
                   2947:                f->fc.dev = BIOSDRV;
                   2948: 
                   2949:                for (b = broot; b; b = b->next) {
                   2950: 
                   2951:                        if (b->private == dev &&
                   2952: 
                   2953:                            (b->device == &bios_tdevice ||
                   2954: 
                   2955:                             b->device == &bios_ndevice)) {
                   2956: 
                   2957:                                f->fc.index = (long)b;
                   2958: 
                   2959:                                f->dev = b->device;
                   2960: 
                   2961:                                if (b->device != &fakedev)
                   2962: 
                   2963:                                        f->devinfo = (long)b->tty;
                   2964: 
                   2965:                                goto found_device;
                   2966: 
                   2967:                        }
                   2968: 
                   2969:                }
                   2970: 
                   2971:                f->fc.index = 0;
                   2972: 
                   2973:                f->dev = &bios_ndevice;
                   2974: 
                   2975: found_device:
                   2976: 
                   2977:                if ((*f->dev->open)(f) < 0) {
                   2978: 
                   2979:                        f->links = 0;
                   2980: 
                   2981:                        dispose_fileptr(f);
                   2982: 
                   2983:                        return 0;
                   2984: 
                   2985:                }
                   2986: 
                   2987:        } else {
                   2988: 
                   2989: /* no memory! use the fake FILEPTR we
                   2990: 
                   2991:  * set up in biosfs_init
                   2992: 
                   2993:  */
                   2994: 
                   2995:                f = defaultaux;
                   2996: 
                   2997:                f->links++;
                   2998: 
                   2999:        }
                   3000: 
                   3001: 
                   3002: 
                   3003:        (void)do_pclose(p, p->aux);
                   3004: 
                   3005:        p->aux = f;
                   3006: 
                   3007: 
                   3008: 
                   3009:        return 1;
                   3010: 
                   3011: }
                   3012: 

unix.superglobalmegacorp.com

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