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

1.1       root        1: /*
                      2: 
1.1.1.4   root        3: Copyright 1991,1992 Eric R. Smith.
                      4: 
1.1.1.5   root        5: Copyright 1993,1994 Atari Corporation.
1.1.1.4   root        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.6 ! root       75: static long    ARGS_ON_STACK bios_writeb       P_((FILEPTR *f, const char *buf, long bytes));
        !            76: 
        !            77: static long    ARGS_ON_STACK bios_readb        P_((FILEPTR *f, char *buf, long bytes));
        !            78: 
1.1.1.2   root       79: static long    ARGS_ON_STACK bios_nwrite       P_((FILEPTR *f, const char *buf, long bytes));
1.1       root       80: 
1.1.1.2   root       81: static long    ARGS_ON_STACK bios_nread        P_((FILEPTR *f, char *buf, long bytes));
1.1       root       82: 
1.1.1.2   root       83: static long    ARGS_ON_STACK bios_ioctl        P_((FILEPTR *f, int mode, void *buf));
1.1       root       84: 
1.1.1.2   root       85: static long    ARGS_ON_STACK bios_select       P_((FILEPTR *f, long p, int mode));
1.1       root       86: 
1.1.1.2   root       87: static void    ARGS_ON_STACK bios_unselect     P_((FILEPTR *f, long p, int mode));
1.1       root       88: 
1.1.1.2   root       89: static long    ARGS_ON_STACK bios_tseek        P_((FILEPTR *f, long where, int whence));
1.1       root       90: 
1.1.1.5   root       91: static long    ARGS_ON_STACK bios_close        P_((FILEPTR *f, int pid));
                     92: 
1.1       root       93: 
                     94: 
1.1.1.2   root       95: long   ARGS_ON_STACK null_open P_((FILEPTR *f));
1.1       root       96: 
1.1.1.2   root       97: long   ARGS_ON_STACK null_write        P_((FILEPTR *f, const char *buf, long bytes));
1.1       root       98: 
1.1.1.2   root       99: long   ARGS_ON_STACK null_read P_((FILEPTR *f, char *buf, long bytes));
1.1       root      100: 
1.1.1.2   root      101: long   ARGS_ON_STACK null_lseek        P_((FILEPTR *f, long where, int whence));
1.1       root      102: 
1.1.1.2   root      103: long   ARGS_ON_STACK null_ioctl        P_((FILEPTR *f, int mode, void *buf));
1.1       root      104: 
1.1.1.2   root      105: long   ARGS_ON_STACK null_datime       P_((FILEPTR *f, short *time, int rwflag));
1.1       root      106: 
1.1.1.2   root      107: long   ARGS_ON_STACK null_close        P_((FILEPTR *f, int pid));
1.1       root      108: 
1.1.1.2   root      109: long   ARGS_ON_STACK null_select       P_((FILEPTR *f, long p, int mode));
1.1       root      110: 
1.1.1.2   root      111: void   ARGS_ON_STACK null_unselect     P_((FILEPTR *f, long p, int mode));
1.1       root      112: 
                    113: 
                    114: 
1.1.1.2   root      115: static long ARGS_ON_STACK mouse_open   P_((FILEPTR *f));
1.1       root      116: 
1.1.1.2   root      117: static long ARGS_ON_STACK mouse_read   P_((FILEPTR *f, char *buf, long nbytes));
1.1       root      118: 
1.1.1.2   root      119: static long ARGS_ON_STACK mouse_ioctl P_((FILEPTR *f, int mode, void *buf));
1.1       root      120: 
1.1.1.2   root      121: static long ARGS_ON_STACK mouse_close P_((FILEPTR *f, int pid));
1.1       root      122: 
1.1.1.2   root      123: static long ARGS_ON_STACK mouse_select P_((FILEPTR *f, long p, int mode));
1.1       root      124: 
1.1.1.2   root      125: static void ARGS_ON_STACK mouse_unselect P_((FILEPTR *f, long p, int mode));
1.1       root      126: 
                    127: 
                    128: 
                    129: /* device driver for BIOS terminals */
                    130: 
                    131: 
                    132: 
                    133: DEVDRV bios_tdevice = {
                    134: 
                    135:        bios_topen, bios_twrite, bios_tread, bios_tseek, bios_ioctl,
                    136: 
1.1.1.6 ! root      137:        null_datime, bios_close, bios_select, bios_unselect,
        !           138: 
        !           139:        bios_writeb, bios_readb
1.1       root      140: 
                    141: };
                    142: 
                    143: 
                    144: 
                    145: /* device driver for BIOS devices that are not terminals */
                    146: 
                    147: 
                    148: 
                    149: DEVDRV bios_ndevice = {
                    150: 
                    151:        null_open, bios_nwrite, bios_nread, null_lseek, bios_ioctl,
                    152: 
1.1.1.5   root      153:        null_datime, bios_close, bios_select, bios_unselect
1.1       root      154: 
                    155: };
                    156: 
                    157: 
                    158: 
                    159: DEVDRV null_device = {
                    160: 
                    161:        null_open, null_write, null_read, null_lseek, null_ioctl,
                    162: 
                    163:        null_datime, null_close, null_select, null_unselect
                    164: 
                    165: };
                    166: 
                    167: 
                    168: 
                    169: DEVDRV mouse_device = {
                    170: 
                    171:        mouse_open, null_write, mouse_read, null_lseek, mouse_ioctl,
                    172: 
                    173:        null_datime, mouse_close, mouse_select, mouse_unselect
                    174: 
                    175: };
                    176: 
                    177: 
                    178: 
                    179: /* this special driver is checked for in dosfile.c, and indicates that
                    180: 
                    181:  * a dup operation is actually wanted rather than an open
                    182: 
                    183:  */
                    184: 
                    185: DEVDRV fakedev;
                    186: 
                    187: 
                    188: 
                    189: #ifdef FASTTEXT
                    190: 
                    191: extern DEVDRV screen_device;   /* see fasttext.c */
                    192: 
                    193: #endif
                    194: 
                    195: 
                    196: 
                    197: FILESYS bios_filesys = {
                    198: 
                    199:        (FILESYS *)0,
                    200: 
1.1.1.3   root      201:        FS_LONGPATH,
1.1       root      202: 
                    203:        bios_root,
                    204: 
                    205:        bios_lookup, nocreat, bios_getdev, bios_getxattr,
                    206: 
                    207:        bios_chattr, bios_chown, bios_chmode,
                    208: 
                    209:        nomkdir, bios_rmdir, bios_remove, bios_getname, bios_rename,
                    210: 
                    211:        bios_opendir, bios_readdir, bios_rewinddir, bios_closedir,
                    212: 
                    213:        bios_pathconf, bios_dfree, nowritelabel, noreadlabel,
                    214: 
                    215:        bios_symlink, bios_readlink, nohardlink, bios_fscntl, nodskchng
                    216: 
                    217: };
                    218: 
                    219: 
                    220: 
                    221: 
                    222: 
                    223: struct tty con_tty, aux_tty, midi_tty;
                    224: 
                    225: struct tty sccb_tty, scca_tty, ttmfp_tty;
                    226: 
                    227: 
                    228: 
                    229: struct bios_file BDEV[] = {
                    230: 
                    231: 
                    232: 
                    233: /* "real" bios devices present on all machines */
                    234: 
                    235:        {"centr", &bios_ndevice, 0, 0, 0, 0},
                    236: 
                    237:        {"console", &bios_tdevice, 2, O_TTY, &con_tty, 0},
                    238: 
                    239:        {"midi", &bios_tdevice, 3, O_TTY, &midi_tty, 0},
                    240: 
                    241:        {"kbd", &bios_ndevice, 4, 0, 0, 0},
                    242: 
                    243: /* devices that duplicate handles */
                    244: 
                    245:        {"prn", &fakedev, -3, 0, 0, 0}, /* handle -3 (printer) */
                    246: 
                    247:        {"aux", &fakedev, -2, 0, 0, 0}, /* handle -2 (aux. terminal) */
                    248: 
                    249:        {"con", &fakedev, -1, 0, 0, 0}, /* handle -1 (control terminal) */
                    250: 
                    251:        {"tty", &fakedev, -1, 0, 0, 0}, /* the Unix name for it */
                    252: 
                    253:        {"stdin", &fakedev, 0, 0, 0, 0},  /* handle 0 (stdin) */
                    254: 
                    255:        {"stdout", &fakedev, 1, 0, 0, 0}, /* handle 1 (stdout) */
                    256: 
                    257:        {"stderr", &fakedev, 2, 0, 0, 0}, /* handle 2 (stderr) */
                    258: 
1.1.1.5   root      259:        {"fd", &fakedev, S_IFDIR, 0, 0, 0}, /* file descriptor directory */
                    260: 
1.1       root      261: 
                    262: 
                    263: /* other miscellaneous devices */
                    264: 
                    265:        {"mouse", &mouse_device, 0, 0, 0, 0},
                    266: 
                    267:        {"null", &null_device, 0, 0, 0, 0},
                    268: 
                    269: 
                    270: 
                    271: #ifdef FASTTEXT
                    272: 
                    273: /* alternate console driver */
                    274: 
                    275:        {"fasttext", &screen_device, 2, O_TTY, &con_tty, 0},
                    276: 
                    277: #endif
                    278: 
                    279: 
                    280: 
                    281: /* serial port things *must* come last, because not all of these
                    282: 
                    283:  * are present on all machines (except for modem1, which does however
                    284: 
                    285:  * have a different device number on TTs and STs)
                    286: 
                    287:  */
                    288: 
                    289:        {"modem1", &bios_tdevice, 6, O_TTY, &aux_tty, 0},
                    290: 
                    291:        {"modem2", &bios_tdevice, 7, O_TTY, &sccb_tty, 0},
                    292: 
                    293:        {"serial1", &bios_tdevice, 8, O_TTY, &ttmfp_tty, 0},
                    294: 
                    295:        {"serial2", &bios_tdevice, 9, O_TTY, &scca_tty, 0},
                    296: 
                    297:        {"", 0, 0, 0, 0, 0}
                    298: 
                    299: };
                    300: 
                    301: 
                    302: 
1.1.1.6 ! root      303: #define xconstat ((long *)0x51eL)
        !           304: 
        !           305: #define xconin         ((long *)0x53eL)
        !           306: 
        !           307: #define xcostat ((long *)0x55eL)
        !           308: 
        !           309: #define xconout        ((long *)0x57eL)
        !           310: 
        !           311: 
        !           312: 
        !           313: extern BCONMAP2_T *bconmap2;           /* bconmap struct */
        !           314: 
        !           315: #define MAPTAB (bconmap2->maptab)
        !           316: 
        !           317: 
        !           318: 
        !           319: #define MAXBAUD 16
        !           320: 
        !           321: 
        !           322: 
        !           323: /* keep these sorted in descending order */
        !           324: 
        !           325: static long baudmap[MAXBAUD] = {
        !           326: 
        !           327: 19200L, 9600L, 4800L, 3600L, 2400L, 2000L, 1800L, 1200L,
        !           328: 
        !           329: 600L, 300L, 200L, 150L, 134L, 110L, 75L, 50L
        !           330: 
        !           331: };
        !           332: 
        !           333: 
        !           334: 
        !           335: /* set/reset bits in SCC w5 */
        !           336: 
        !           337: INLINE static void scc_set5 P_((volatile char *control, int setp,
        !           338: 
        !           339:        unsigned bits, IOREC_T *iorec));
        !           340: 
        !           341: 
        !           342: 
        !           343: INLINE static void scc_set5 (control, setp, bits, iorec)
        !           344: 
        !           345: volatile char *control;
        !           346: 
        !           347: int setp;
        !           348: 
        !           349: unsigned bits;
        !           350: 
        !           351: IOREC_T *iorec;
        !           352: 
        !           353: {
        !           354: 
        !           355:        volatile char dummy;
        !           356: 
        !           357: 
        !           358: 
        !           359:        short sr = spl7();
        !           360: 
        !           361: 
        !           362: 
        !           363: #if 1
        !           364: 
        !           365: /* sanity check: if the w5 copy at offset 1d has bit 3 off something is wrong */
        !           366: 
        !           367:        if (!(((char *) iorec)[0x1d] & 8)) {
        !           368: 
        !           369:                spl(sr);
        !           370: 
        !           371:                ALERT ("scc_set5: iorec %lx w5 copy has sender enable bit off, w5 not changed", iorec);
        !           372: 
        !           373:                return;
        !           374: 
        !           375:        }
        !           376: 
        !           377: #endif
        !           378: 
        !           379:        dummy = *((volatile char *) 0xfffffa01L);
        !           380: 
        !           381:        *control = 5;
        !           382: 
        !           383:        dummy = *((volatile char *) 0xfffffa01L);
        !           384: 
        !           385:        if (setp)
        !           386: 
        !           387:                *control = (((char *) iorec)[0x1d] |= bits);
        !           388: 
        !           389:        else
        !           390: 
        !           391:                *control = (((char *) iorec)[0x1d] &= ~bits);
        !           392: 
        !           393:        spl(sr);
        !           394: 
        !           395: #ifdef __TURBOC__
        !           396: 
        !           397:        setp = dummy; /* jr: get rid of warning regarding dummy */
        !           398: 
        !           399: #endif
        !           400: 
        !           401: }
        !           402: 
        !           403: 
        !           404: 
        !           405: #define        MAX_BTTY        4       /* 4 bios_tty structs */
        !           406: 
        !           407: 
        !           408: 
        !           409: /* find bios_tty struct for a FILEPTR
        !           410: 
        !           411:  */
        !           412: 
        !           413: #define BTTY(f) ((((struct tty *)(f)->devinfo) == &aux_tty) ? bttys : \
        !           414: 
        !           415:                 ((has_bconmap && (unsigned)(f)->fc.aux-6 < btty_max) ? \
        !           416: 
        !           417:                    bttys+(f)->fc.aux-6 : 0))
        !           418: 
        !           419: 
        !           420: 
        !           421: struct bios_tty bttys[MAX_BTTY], midi_btty;
        !           422: 
        !           423: short  btty_max;
        !           424: 
        !           425: 
        !           426: 
        !           427: /* RSVF cookie value (read in main.c) */
        !           428: 
        !           429: long rsvf;
        !           430: 
        !           431: 
        !           432: 
        !           433: /* try to get a fd for a BIOS tty to pass some ioctls to... */
        !           434: 
        !           435: 
        !           436: 
        !           437: INLINE static short
        !           438: 
        !           439: rsvf_open(bdev)
        !           440: 
        !           441:        int bdev;
        !           442: 
        !           443: {
        !           444: 
        !           445:        long ret = EUNDEV;
        !           446: 
        !           447:        struct rsvfdev {
        !           448: 
        !           449:                union {
        !           450: 
        !           451:                        char *name;
        !           452: 
        !           453:                        struct rsvfdev *next;
        !           454: 
        !           455:                } f;
        !           456: 
        !           457:                char flags, unused1, bdev, unused2;
        !           458: 
        !           459:        } *r = (struct rsvfdev *)rsvf;
        !           460: 
        !           461: 
        !           462: 
        !           463:        while (r) {
        !           464: 
        !           465:                if (r->flags >= 0) {
        !           466: 
        !           467:                        r = r->f.next;
        !           468: 
        !           469:                        continue;
        !           470: 
        !           471:                }
        !           472: 
        !           473:                if ((r->flags & 0xe0) == 0xe0 && r->bdev == bdev) {
        !           474: 
        !           475:                        char rname[0x80] = "u:\\dev\\";
        !           476: 
        !           477: 
        !           478: 
        !           479:                        strncpy (rname + sizeof "u:\\dev\\" - 1, r->f.name,
        !           480: 
        !           481:                                sizeof rname - sizeof "u:\\dev\\");
        !           482: 
        !           483:                        ret = Fopen (rname, O_RDWR);
        !           484: 
        !           485:                        if (ret < MIN_HANDLE || ret > 0x8000) {
        !           486: 
        !           487:                                ALERT ("rsvf_open(%d): Fopen %s returned %lx",
        !           488: 
        !           489:                                        bdev, rname, ret);
        !           490: 
        !           491:                                return EUNDEV;
        !           492: 
        !           493:                        }
        !           494: 
        !           495:                        break;
        !           496: 
        !           497:                }
        !           498: 
        !           499:                ++r;
        !           500: 
        !           501:        }
        !           502: 
        !           503:        return ret;
        !           504: 
        !           505: }
        !           506: 
        !           507: 
        !           508: 
        !           509: INLINE static long
        !           510: 
        !           511: rsvf_close(f)
        !           512: 
        !           513:        int f;
        !           514: 
        !           515: {
        !           516: 
        !           517:        long ret = EIHNDL;
        !           518: 
        !           519:        if (f != EUNDEV) {
        !           520: 
        !           521:                ret = Fclose (f);
        !           522: 
        !           523:                if (ret)
        !           524: 
        !           525:                        ALERT ("rsvf_close(%d): Fclose %x returned %lx", f, ret);
        !           526: 
        !           527:        }
        !           528: 
        !           529:        return ret;
        !           530: 
        !           531: }
        !           532: 
        !           533: 
        !           534: 
        !           535: INLINE long
        !           536: 
        !           537: rsvf_ioctl(f, arg, mode)
        !           538: 
        !           539:        int f;
        !           540: 
        !           541:        void *arg;
        !           542: 
        !           543:        int mode;
        !           544: 
        !           545: {
        !           546: 
        !           547:        if (f == EUNDEV)
        !           548: 
        !           549:                return EINVFN;
        !           550: 
        !           551:        TRACE(("rsvf_ioctl: passing ioctl %x (tosfd=0x%x)", mode, f));
        !           552: 
        !           553:        /* is there a more direct way than this? */
        !           554: 
        !           555:        return Fcntl (f, (long)arg, mode);
        !           556: 
        !           557: }
        !           558: 
        !           559: 
        !           560: 
        !           561: extern int tosvers;    /* from main.c */
        !           562: 
        !           563: 
        !           564: 
1.1.1.5   root      565: /* Does the fcookie fc refer to the \dev\fd directory? */
                    566: 
                    567: #define IS_FD_DIR(fc) ((fc)->aux == S_IFDIR)
                    568: 
                    569: /* Does the fcookie fc refer to a file in the \dev\fd directory? */
                    570: 
                    571: #define IS_FD_ENTRY(fc) ((fc)->index > 0 && (fc)->index <= MAX_OPEN-MIN_HANDLE)
                    572: 
                    573: 
                    574: 
1.1       root      575: struct bios_file *broot, *bdevlast;
                    576: 
                    577: 
                    578: 
                    579: /* a file pointer for BIOS device 1, provided only for insurance
                    580: 
                    581:  * in case a Bconmap happens and we can't allocate a new FILEPTR;
                    582: 
                    583:  * in most cases, we'll want to build a FILEPTR in the usual
                    584: 
                    585:  * way.
                    586: 
                    587:  */
                    588: 
                    589: 
                    590: 
                    591: FILEPTR *defaultaux;
                    592: 
                    593: 
                    594: 
1.1.1.5   root      595: /* ts: a xattr field used for the root directory, 'cause there's no
                    596: 
                    597:  * bios_file structure for it.
                    598: 
                    599:  */
                    600: 
                    601: XATTR rxattr;
                    602: 
                    603: XATTR fdxattr;
                    604: 
                    605: 
                    606: 
                    607: /* ts: a small utility function to set up a xattr structure
                    608: 
                    609:  */
                    610: 
                    611: 
                    612: 
                    613: static void set_xattr P_((XATTR *xp, ushort mode, int rdev));
                    614: 
                    615: 
                    616: 
                    617: void set_xattr(xp, mode, rdev)
                    618: 
                    619:        XATTR *xp;
                    620: 
                    621:        ushort mode;
                    622: 
                    623:        int rdev;
                    624: 
                    625: {
                    626: 
                    627:        xp->mode = mode;
                    628: 
                    629:        xp->index = 0L;
                    630: 
                    631:        xp->dev = BIOSDRV;
                    632: 
                    633:        xp->rdev = rdev;
                    634: 
                    635:        xp->nlink = 1;
                    636: 
                    637:        xp->uid = curproc->euid;
                    638: 
                    639:        xp->gid = curproc->egid;
                    640: 
                    641:        xp->size = 0L;
                    642: 
1.1.1.6 ! root      643:        xp->blksize = 1024L;
1.1.1.5   root      644: 
                    645:        xp->nblocks = 0L;
                    646: 
                    647: 
                    648: 
                    649:        xp->mtime = xp->atime = xp->ctime = timestamp;
                    650: 
                    651:        xp->mdate = xp->adate = xp->cdate = datestamp;
                    652: 
                    653: 
                    654: 
                    655: /* root directory only */
                    656: 
                    657:        if ((mode & S_IFMT) == S_IFDIR)
                    658: 
                    659:                xp->attr = FA_DIR;
                    660: 
                    661:        else
                    662: 
                    663:                xp->attr = 0;
                    664: 
                    665:        xp->reserved2 = 0;
                    666: 
                    667:        xp->reserved3[0] = 0L;
                    668: 
                    669:        xp->reserved3[1] = 0L;
                    670: 
                    671: }
                    672: 
                    673: 
                    674: 
1.1       root      675: void
                    676: 
                    677: biosfs_init()
                    678: 
                    679: {
                    680: 
1.1.1.6 ! root      681:        struct bios_file *b, *c;
1.1       root      682: 
1.1.1.5   root      683:        int majdev, mindev;
                    684: 
1.1.1.6 ! root      685:        int i;
        !           686: 
1.1       root      687: 
                    688: 
                    689:        broot = BDEV;
                    690: 
                    691: 
                    692: 
1.1.1.6 ! root      693:        c = (struct bios_file *)0;
        !           694: 
1.1       root      695:        for (b = broot; b->name[0]; b++) {
                    696: 
                    697:                b->next = b+1;
                    698: 
                    699: 
                    700: 
1.1.1.6 ! root      701:        /* Save a pointer to the first serial port */
        !           702: 
        !           703:                if (b->private == 6)
        !           704: 
        !           705:                        c = b;
        !           706: 
        !           707:                if (b->device->readb && b->tty != &con_tty)
        !           708: 
        !           709:        /* device has DEVDRV calls beyond unselect */
        !           710: 
        !           711:                        b->drvsize = offsetof (DEVDRV, readb) + sizeof (long);
        !           712: 
        !           713: 
        !           714: 
1.1       root      715:        /* if not a TT or Mega STE, adjust the MODEM1 device to be BIOS
                    716: 
                    717:         * device 1
                    718: 
                    719:         * and ignore the remaining devices, since they're not present
                    720: 
                    721:         */
                    722: 
1.1.1.6 ! root      723:                if (b->private == 6 &&
        !           724: 
        !           725:                    (!has_bconmap || bconmap2->maptabsize == 1)) {
1.1       root      726: 
1.1.1.6 ! root      727:                        if (!has_bconmap)
        !           728: 
        !           729:                                b->private = 1;
1.1       root      730: 
                    731:                        b->next = 0;
                    732: 
                    733:                        break;
                    734: 
                    735:                }
                    736: 
1.1.1.6 ! root      737:        /* SERIAL1(!) is not present on the Mega STe or Falcon,
        !           738: 
        !           739:         * device 8 is SCC channel A
        !           740: 
        !           741:         */
1.1       root      742: 
1.1.1.5   root      743:                if (mch != TT && b->private == 8) {
1.1       root      744: 
1.1.1.6 ! root      745:                        b->name[6] = '2';       /* "serial2" */
        !           746: 
        !           747:                        b->tty = &scca_tty;
        !           748: 
1.1       root      749:                        b->next = 0;
                    750: 
                    751:                        break;
                    752: 
                    753:                }
                    754: 
                    755:        }
                    756: 
                    757:        bdevlast = b;
                    758: 
                    759:        if (b->name[0] == 0) {
                    760: 
                    761:                --b;
                    762: 
                    763:                b->next = 0;
                    764: 
                    765:        }
                    766: 
1.1.1.6 ! root      767:        /* Initialize bios_tty structures */
        !           768: 
        !           769:        for (i=0;c && i<MAX_BTTY;c=c->next, i++) {
        !           770: 
        !           771:                if (has_bconmap)
        !           772: 
        !           773:                        bttys[i].irec = MAPTAB[c->private-6].iorec;
        !           774: 
        !           775:                else
        !           776: 
        !           777:                        bttys[i].irec = Iorec(0);
        !           778: 
        !           779:                bttys[i].orec = bttys[i].irec+1;
        !           780: 
        !           781:                bttys[i].rsel = &(c->tty->rsel);
        !           782: 
        !           783:                bttys[i].wsel = &(c->tty->wsel);
        !           784: 
        !           785:                bttys[i].baudmap = baudmap;
        !           786: 
        !           787:                bttys[i].maxbaud = MAXBAUD;
        !           788: 
        !           789:                bttys[i].baudx = NULL;
        !           790: 
        !           791:                *c->tty = default_tty;
        !           792: 
        !           793:                bttys[i].tty = c->tty;
        !           794: 
        !           795:                bttys[i].clocal = 1;    /* default off would be better but
        !           796: 
        !           797:                                           likely confuses old programs... :/ */
        !           798: 
        !           799:                bttys[i].brkint = 1;
        !           800: 
        !           801:                bttys[i].tosfd = EUNDEV;
        !           802: 
        !           803:                bttys[i].bdev = c->private;
        !           804: 
        !           805:        }
        !           806: 
        !           807:        btty_max = i;
        !           808: 
        !           809: 
        !           810: 
        !           811:        midi_btty.irec = Iorec(2);
        !           812: 
        !           813:        midi_btty.rsel = &midi_tty.rsel;
        !           814: 
        !           815:        midi_btty.wsel = &midi_tty.wsel;
        !           816: 
        !           817:        midi_btty.tty = &midi_tty;
        !           818: 
        !           819:        midi_tty = default_tty;
        !           820: 
        !           821:        midi_btty.clocal = 1;
        !           822: 
        !           823:        midi_btty.tosfd = EUNDEV;
        !           824: 
        !           825:        midi_btty.bdev = 3;
        !           826: 
        !           827: 
        !           828: 
1.1       root      829:        defaultaux = new_fileptr();
                    830: 
                    831:        defaultaux->links = 1;          /* so it never gets freed */
                    832: 
                    833:        defaultaux->flags = O_RDWR;
                    834: 
                    835:        defaultaux->pos = 0;
                    836: 
                    837:        defaultaux->devinfo = 0;
                    838: 
                    839:        defaultaux->fc.fs = &bios_filesys;
                    840: 
                    841:        defaultaux->fc.index = 0;
                    842: 
                    843:        defaultaux->fc.aux = 1;
                    844: 
                    845:        defaultaux->fc.dev = BIOSDRV;
                    846: 
                    847:        defaultaux->dev = &bios_ndevice;
                    848: 
1.1.1.5   root      849: 
                    850: 
                    851: /* set up XATTR fields */
                    852: 
                    853:        set_xattr(&rxattr, S_IFDIR|DEFAULT_DIRMODE, BIOSDRV);
                    854: 
                    855:        set_xattr(&fdxattr, S_IFDIR|DEFAULT_DIRMODE, BIOSDRV);
                    856: 
                    857: 
                    858: 
                    859:        for (b = BDEV; b; b = b->next) {
                    860: 
                    861:                if (b->device == &bios_ndevice || b->device == &bios_tdevice) {
                    862: 
                    863:                        majdev = BIOS_RDEV;
                    864: 
                    865:                        mindev = b->private;
                    866: 
                    867:                } else if (b->device == &fakedev) {
                    868: 
                    869:                        majdev = FAKE_RDEV;
                    870: 
                    871:                        mindev = b->private;
                    872: 
                    873:                } else {
                    874: 
                    875:                        majdev = UNK_RDEV;
                    876: 
                    877:                        mindev = b->private;
                    878: 
                    879:                }
                    880: 
                    881:                set_xattr(&b->xattr, S_IFCHR|DEFAULT_MODE,
                    882: 
                    883:                          majdev | (mindev & 0x00ff) );
                    884: 
                    885:        }
                    886: 
1.1       root      887: }
                    888: 
                    889: 
                    890: 
1.1.1.2   root      891: static long ARGS_ON_STACK 
1.1       root      892: 
                    893: bios_root(drv, fc)
                    894: 
                    895:        int drv;
                    896: 
                    897:        fcookie *fc;
                    898: 
                    899: {
                    900: 
                    901:        if (drv == BIOSDRV) {
                    902: 
                    903:                fc->fs = &bios_filesys;
                    904: 
                    905:                fc->dev = drv;
                    906: 
                    907:                fc->index = 0L;
                    908: 
                    909:                return 0;
                    910: 
                    911:        }
                    912: 
                    913:        fc->fs = 0;
                    914: 
                    915:        return EINTRN;
                    916: 
                    917: }
                    918: 
                    919: 
                    920: 
1.1.1.2   root      921: static long ARGS_ON_STACK 
1.1       root      922: 
                    923: bios_lookup(dir, name, fc)
                    924: 
                    925:        fcookie *dir;
                    926: 
                    927:        const char *name;
                    928: 
                    929:        fcookie *fc;
                    930: 
                    931: {
                    932: 
                    933:        struct bios_file *b;
                    934: 
                    935: 
                    936: 
                    937:        if (dir->index != 0) {
                    938: 
1.1.1.5   root      939:        /* check for \dev\fd directory */
1.1       root      940: 
1.1.1.5   root      941:                if (!IS_FD_DIR(dir)) {
                    942: 
                    943:                        DEBUG(("bios_lookup: bad directory"));
                    944: 
                    945:                        return EPTHNF;
                    946: 
                    947:                }
                    948: 
                    949:                if (!*name || (name[0] == '.' && name[1] == 0)) {
                    950: 
                    951:                        *fc = *dir;
                    952: 
                    953:                        return 0;
                    954: 
                    955:                }
                    956: 
                    957:                if (!strcmp(name, "..")) {
                    958: 
                    959:                /* root directory */
                    960: 
                    961:                        fc->fs = &bios_filesys;
                    962: 
                    963:                        fc->dev = dir->dev;
                    964: 
                    965:                        fc->index = 0L;
                    966: 
                    967:                        return 0;
                    968: 
                    969:                }
                    970: 
                    971:                if (isdigit(*name) || *name == '-') {
                    972: 
                    973:                        int fd = (int) atol(name);
                    974: 
                    975:                        if (fd >= MIN_HANDLE && fd < MAX_OPEN) {
                    976: 
                    977:                                fc->fs = &bios_filesys;
                    978: 
                    979:                                fc->dev = dir->dev;
                    980: 
                    981:                                fc->aux = fd;
                    982: 
                    983:                                fc->index = fd - MIN_HANDLE + 1;
                    984: 
                    985:                                return 0;
                    986: 
                    987:                        }
                    988: 
                    989:                }
                    990: 
                    991:                DEBUG(("bios_lookup: name (%s) not found", name));
                    992: 
                    993:                return EFILNF;
1.1       root      994: 
                    995:        }
                    996: 
1.1.1.5   root      997: 
                    998: 
1.1       root      999: /* special case: an empty name in a directory means that directory */
                   1000: 
                   1001: /* so does "." */
                   1002: 
                   1003:        if (!*name || (name[0] == '.' && name[1] == 0)) {
                   1004: 
                   1005:                *fc = *dir;
                   1006: 
                   1007:                return 0;
                   1008: 
                   1009:        }
                   1010: 
                   1011: 
                   1012: 
                   1013: /* another special case: ".." could be a mount point */
                   1014: 
                   1015:        if (!strcmp(name, "..")) {
                   1016: 
                   1017:                *fc = *dir;
                   1018: 
                   1019:                return EMOUNT;
                   1020: 
                   1021:        }
                   1022: 
                   1023: 
                   1024: 
                   1025:        for (b = broot; b; b = b->next) {
                   1026: 
                   1027:                if (!stricmp(b->name, name)) {
                   1028: 
                   1029:                        fc->fs = &bios_filesys;
                   1030: 
                   1031:                        fc->index = (long)b;
                   1032: 
                   1033:                        fc->aux = b->private;
                   1034: 
                   1035:                        fc->dev = dir->dev;
                   1036: 
                   1037:                        return 0;
                   1038: 
                   1039:                }
                   1040: 
                   1041:        }
                   1042: 
1.1.1.2   root     1043:        DEBUG(("bios_lookup: name(%s) not found", name));
1.1       root     1044: 
                   1045:        return EFILNF;
                   1046: 
                   1047: }
                   1048: 
                   1049: 
                   1050: 
1.1.1.2   root     1051: static long ARGS_ON_STACK 
1.1       root     1052: 
                   1053: bios_getxattr(fc, xattr)
                   1054: 
                   1055:        fcookie *fc;
                   1056: 
                   1057:        XATTR *xattr;
                   1058: 
                   1059: {
                   1060: 
1.1.1.6 ! root     1061: #ifdef FOLLOW_XATTR_CHAIN
1.1.1.2   root     1062: 
1.1.1.6 ! root     1063:        FILEPTR *f;
1.1       root     1064: 
1.1.1.5   root     1065:        long r;
                   1066: 
1.1.1.6 ! root     1067: #endif
        !          1068: 
        !          1069:        struct bios_file *b = (struct bios_file *)fc->index;
        !          1070: 
1.1.1.5   root     1071:        int majdev, mindev;
                   1072: 
                   1073: 
                   1074: 
                   1075:        majdev = UNK_RDEV;
                   1076: 
                   1077:        mindev = 0;
                   1078: 
                   1079: 
                   1080: 
                   1081:        if (fc->index == 0) {                   /* root directory? */
                   1082: 
                   1083:                *xattr = rxattr;
1.1       root     1084: 
1.1.1.5   root     1085:                xattr->index = fc->index;
1.1       root     1086: 
1.1.1.5   root     1087:                xattr->dev = fc->dev;
1.1       root     1088: 
1.1.1.5   root     1089:        } else if (IS_FD_DIR(fc)) {             /* fd directory? */
1.1       root     1090: 
1.1.1.5   root     1091:                *xattr = fdxattr;
1.1       root     1092: 
1.1.1.5   root     1093:                xattr->index = fc->index;
1.1       root     1094: 
1.1.1.5   root     1095:                xattr->dev = fc->dev;
1.1       root     1096: 
1.1.1.5   root     1097:        } else if (IS_FD_ENTRY(fc)) {
1.1       root     1098: 
1.1.1.5   root     1099:                /* u:\dev\fd\n */
1.1       root     1100: 
1.1.1.6 ! root     1101: #ifdef FOLLOW_XATTR_CHAIN
        !          1102: 
1.1.1.5   root     1103:                f = curproc->handle[(int)fc->aux];
1.1       root     1104: 
1.1.1.5   root     1105:                if (f) {
1.1       root     1106: 
1.1.1.5   root     1107:                        r = (*f->fc.fs->getxattr)(&f->fc, xattr);
1.1       root     1108: 
1.1.1.5   root     1109:                        if (r < 0)
1.1       root     1110: 
1.1.1.5   root     1111:                                return r;
1.1       root     1112: 
1.1.1.5   root     1113:                } else {
                   1114: 
1.1.1.6 ! root     1115: #endif
        !          1116: 
1.1.1.5   root     1117:                        majdev = FAKE_RDEV;
                   1118: 
                   1119:                        mindev = ((int)fc->aux) & 0x00ff;
                   1120: 
                   1121:                        set_xattr(xattr, S_IFCHR | DEFAULT_MODE, majdev|mindev);
                   1122: 
1.1.1.6 ! root     1123: #ifndef FOLLOW_XATTR_CHAIN
        !          1124: 
        !          1125:                        xattr->index = fc->index;
        !          1126: 
        !          1127: #else
        !          1128: 
1.1.1.5   root     1129:                }
                   1130: 
1.1.1.6 ! root     1131: #endif
        !          1132: 
1.1.1.5   root     1133:        } else if (b->device == &fakedev) {
1.1       root     1134: 
1.1.1.6 ! root     1135: #ifdef FOLLOW_XATTR_CHAIN
        !          1136: 
1.1.1.5   root     1137:                if ((f = curproc->handle[b->private]) != 0) {
1.1.1.2   root     1138: 
1.1.1.5   root     1139:                    /* u:\dev\stdin, u:\dev\stdout, etc. */
1.1.1.2   root     1140: 
1.1.1.5   root     1141:                    r = (*f->fc.fs->getxattr) (&f->fc, xattr);
1.1       root     1142: 
1.1.1.5   root     1143:                    if (r < 0) return r;
1.1.1.2   root     1144: 
1.1.1.5   root     1145:                } else {
1.1.1.2   root     1146: 
1.1.1.6 ! root     1147: #endif
        !          1148: 
1.1.1.5   root     1149:                        majdev = FAKE_RDEV;
1.1.1.2   root     1150: 
1.1.1.5   root     1151:                        mindev = ((int)b->private) & 0x00ff;
                   1152: 
                   1153:                        set_xattr(xattr, S_IFCHR|DEFAULT_MODE, majdev|mindev);
                   1154: 
1.1.1.6 ! root     1155: #ifndef FOLLOW_XATTR_CHAIN
        !          1156: 
        !          1157:                        xattr->index = fc->index;
        !          1158: 
        !          1159: #else
        !          1160: 
1.1.1.5   root     1161:                }
1.1.1.2   root     1162: 
1.1.1.6 ! root     1163: #endif
        !          1164: 
1.1.1.2   root     1165:        } else {
1.1       root     1166: 
1.1.1.5   root     1167:                *xattr = b->xattr;
                   1168: 
                   1169:                xattr->index = fc->index;
1.1       root     1170: 
1.1.1.5   root     1171:                xattr->dev = fc->dev;
1.1       root     1172: 
                   1173:        }
                   1174: 
                   1175:        return 0;
                   1176: 
                   1177: }
                   1178: 
                   1179: 
                   1180: 
1.1.1.2   root     1181: static long ARGS_ON_STACK 
1.1       root     1182: 
                   1183: bios_chattr(fc, attrib)
                   1184: 
                   1185:        fcookie *fc;
                   1186: 
                   1187:        int attrib;
                   1188: 
                   1189: {
                   1190: 
1.1.1.2   root     1191:        UNUSED(fc); UNUSED(attrib);
                   1192: 
1.1       root     1193:        return EACCDN;
                   1194: 
                   1195: }
                   1196: 
                   1197: 
                   1198: 
1.1.1.2   root     1199: static long ARGS_ON_STACK 
1.1       root     1200: 
                   1201: bios_chown(fc, uid, gid)
                   1202: 
                   1203:        fcookie *fc;
                   1204: 
                   1205:        int uid, gid;
                   1206: 
                   1207: {
                   1208: 
1.1.1.5   root     1209:        struct bios_file *b = (struct bios_file *)fc->index;
1.1.1.2   root     1210: 
                   1211: 
1.1.1.5   root     1212: 
                   1213:        if (!(curproc->euid)) {
                   1214: 
                   1215:                if (!b) {
                   1216: 
                   1217:                        /* a directory */
                   1218: 
                   1219:                        rxattr.uid = uid;
                   1220: 
                   1221:                        rxattr.gid = gid;
                   1222: 
                   1223:                } else if (IS_FD_DIR(fc)) {
                   1224: 
                   1225:                        fdxattr.uid = uid;
                   1226: 
                   1227:                        fdxattr.gid = gid;
                   1228: 
                   1229:                } else if (!IS_FD_ENTRY(fc)) {
                   1230: 
                   1231:                        /* any other entry */
                   1232: 
                   1233:                        b->xattr.uid = uid;
                   1234: 
                   1235:                        b->xattr.gid = gid;
                   1236: 
                   1237:                }
                   1238: 
                   1239:                return 0;
                   1240: 
                   1241:        }
                   1242: 
                   1243: 
                   1244: 
                   1245:        return EACCDN;
1.1       root     1246: 
                   1247: }
                   1248: 
                   1249: 
                   1250: 
1.1.1.2   root     1251: static long ARGS_ON_STACK 
1.1       root     1252: 
                   1253: bios_chmode(fc, mode)
                   1254: 
                   1255:        fcookie *fc;
                   1256: 
                   1257:        unsigned mode;
                   1258: 
                   1259: {
                   1260: 
1.1.1.5   root     1261:        struct bios_file *b = (struct bios_file *)fc->index;
1.1.1.2   root     1262: 
1.1.1.5   root     1263: 
                   1264: 
                   1265:        if (!b) {
                   1266: 
                   1267:                /* root directory */
                   1268: 
                   1269:                if (!curproc->euid || (curproc->euid == rxattr.uid)) {
                   1270: 
                   1271:                        rxattr.mode = (rxattr.mode & S_IFMT) | mode;
                   1272: 
                   1273:                        return 0;
                   1274: 
                   1275:                }
                   1276: 
                   1277:        } else if (IS_FD_DIR(fc)) {
                   1278: 
                   1279:                if (!curproc->euid || (curproc->euid == fdxattr.uid)) {
                   1280: 
                   1281:                        fdxattr.mode = (fdxattr.mode & S_IFMT) | mode;
                   1282: 
                   1283:                        return 0;
                   1284: 
                   1285:                }
                   1286: 
                   1287:        } else if (!IS_FD_ENTRY(fc)) {
                   1288: 
                   1289:                if (!curproc->euid && (curproc->euid == b->xattr.uid)) {
                   1290: 
                   1291:                        b->xattr.mode = (b->xattr.mode & S_IFMT) | mode;
                   1292: 
                   1293:                        return 0;
                   1294: 
                   1295:                }
                   1296: 
                   1297:        }
                   1298: 
                   1299: 
                   1300: 
                   1301:        return EACCDN;
1.1       root     1302: 
                   1303: }
                   1304: 
                   1305: 
                   1306: 
1.1.1.2   root     1307: long ARGS_ON_STACK 
1.1       root     1308: 
                   1309: nomkdir(dir, name, mode)
                   1310: 
                   1311:        fcookie *dir;
                   1312: 
                   1313:        const char *name;
                   1314: 
                   1315:        unsigned mode;
                   1316: 
                   1317: {
                   1318: 
1.1.1.2   root     1319:        UNUSED(dir); UNUSED(name);
                   1320: 
                   1321:        UNUSED(mode);
                   1322: 
1.1       root     1323:        return EACCDN;
                   1324: 
                   1325: }
                   1326: 
                   1327: 
                   1328: 
1.1.1.2   root     1329: static long ARGS_ON_STACK 
1.1       root     1330: 
                   1331: bios_rmdir(dir, name)
                   1332: 
                   1333:        fcookie *dir;
                   1334: 
                   1335:        const char *name;
                   1336: 
                   1337: {
                   1338: 
                   1339:        return bios_remove(dir, name);
                   1340: 
                   1341: }
                   1342: 
                   1343: 
                   1344: 
                   1345: /*
                   1346: 
                   1347:  * MAJOR BUG: we don't check here for removal of devices for which there
                   1348: 
                   1349:  * are still open files
                   1350: 
                   1351:  */
                   1352: 
                   1353: 
                   1354: 
1.1.1.2   root     1355: static long ARGS_ON_STACK 
1.1       root     1356: 
                   1357: bios_remove(dir, name)
                   1358: 
                   1359:        fcookie *dir;
                   1360: 
                   1361:        const char *name;
                   1362: 
                   1363: {
                   1364: 
                   1365:        struct bios_file *b, **lastb;
                   1366: 
                   1367: 
                   1368: 
1.1.1.5   root     1369:        if (curproc->euid)
                   1370: 
                   1371:                return EACCDN;
                   1372: 
                   1373: 
                   1374: 
                   1375: /* don't allow removal in the fd directory */
                   1376: 
                   1377:        if (IS_FD_DIR(dir))
                   1378: 
                   1379:                return EACCDN;
                   1380: 
                   1381: 
                   1382: 
1.1       root     1383:        lastb = &broot;
                   1384: 
                   1385:        for (b = broot; b; b = *(lastb = &b->next)) {
                   1386: 
                   1387:                if (!stricmp(b->name, name)) break;
                   1388: 
                   1389:        }
                   1390: 
                   1391:        if (!b) return EFILNF;
                   1392: 
                   1393: 
                   1394: 
1.1.1.5   root     1395: /* don't allow removal of the device if we don't own it */
                   1396: 
                   1397:        if (curproc->euid && (curproc->euid != b->xattr.uid)) {
                   1398: 
                   1399:                return EACCDN;
                   1400: 
                   1401:        }
                   1402: 
                   1403: 
                   1404: 
1.1       root     1405: /* don't allow removal of the basic system devices */
                   1406: 
                   1407:        if (b >= BDEV && b <= bdevlast) {
                   1408: 
                   1409:                return EACCDN;
                   1410: 
                   1411:        }
                   1412: 
                   1413:        *lastb = b->next;
                   1414: 
                   1415: 
                   1416: 
                   1417:        if (b->device == 0 || b->device == &bios_tdevice)
                   1418: 
                   1419:                kfree(b->tty);
                   1420: 
                   1421: 
                   1422: 
                   1423:        kfree(b);
                   1424: 
                   1425:        return 0;
                   1426: 
                   1427: }
                   1428: 
                   1429: 
                   1430: 
1.1.1.2   root     1431: static long ARGS_ON_STACK 
1.1       root     1432: 
1.1.1.3   root     1433: bios_getname(root, dir, pathname, size)
1.1       root     1434: 
                   1435:        fcookie *root, *dir; char *pathname;
                   1436: 
1.1.1.3   root     1437:        int size;
                   1438: 
1.1       root     1439: {
                   1440: 
1.1.1.5   root     1441:        char *foo;
                   1442: 
1.1.1.3   root     1443: 
                   1444: 
1.1.1.5   root     1445:        if (size == 0)
1.1.1.3   root     1446: 
1.1.1.5   root     1447:          return ERANGE;
1.1.1.2   root     1448: 
1.1.1.5   root     1449:        if (root->index == dir->index) {
1.1       root     1450: 
1.1.1.5   root     1451:            *pathname = 0;
1.1       root     1452: 
1.1.1.5   root     1453:            return 0;
                   1454: 
                   1455:        }
                   1456: 
                   1457:        /* DIR must point to the fd directory */
                   1458: 
                   1459:        if (!IS_FD_DIR (dir))
                   1460: 
                   1461:                return EINTRN;
                   1462: 
                   1463:        *pathname++ = '\\';
                   1464: 
                   1465:        size--;
                   1466: 
                   1467:        foo = ((struct bios_file *)dir->index)->name;
                   1468: 
                   1469:        if (strlen(foo) < size)
1.1.1.3   root     1470: 
                   1471:                strcpy(pathname, foo);
                   1472: 
1.1       root     1473:        else
                   1474: 
1.1.1.3   root     1475:                return ERANGE;
1.1       root     1476: 
                   1477:        return 0;
                   1478: 
                   1479: }
                   1480: 
                   1481: 
                   1482: 
1.1.1.2   root     1483: static long ARGS_ON_STACK 
1.1       root     1484: 
                   1485: bios_rename(olddir, oldname, newdir, newname)
                   1486: 
                   1487:        fcookie *olddir;
                   1488: 
                   1489:        char *oldname;
                   1490: 
                   1491:        fcookie *newdir;
                   1492: 
                   1493:        const char *newname;
                   1494: 
                   1495: {
                   1496: 
1.1.1.5   root     1497:        struct bios_file *b, *be = 0;
1.1       root     1498: 
                   1499: 
                   1500: 
1.1.1.2   root     1501:        UNUSED(olddir); UNUSED(newdir);
                   1502: 
                   1503: 
                   1504: 
1.1.1.5   root     1505:        if (curproc->euid)
                   1506: 
                   1507:                return EACCDN;
1.1       root     1508: 
                   1509: 
                   1510: 
                   1511:        for (b = broot; b; b = b->next) {
                   1512: 
1.1.1.5   root     1513:                if (!stricmp(b->name, newname)) {
1.1       root     1514: 
1.1.1.5   root     1515:                        return EACCDN;
1.1       root     1516: 
1.1.1.5   root     1517:                }
                   1518: 
                   1519:                if (!stricmp(b->name, oldname)) {
                   1520: 
                   1521:                        be = b;
1.1       root     1522: 
                   1523:                }
                   1524: 
                   1525:        }
                   1526: 
1.1.1.5   root     1527:        if (be) {
                   1528: 
                   1529:                strncpy(be->name, newname, BNAME_MAX);
                   1530: 
                   1531:                return 0;
                   1532: 
                   1533:        }
                   1534: 
1.1       root     1535:        return EFILNF;
                   1536: 
                   1537: }
                   1538: 
                   1539: 
                   1540: 
1.1.1.2   root     1541: static long ARGS_ON_STACK 
1.1       root     1542: 
                   1543: bios_opendir(dirh, flags)
                   1544: 
                   1545:        DIR *dirh;
                   1546: 
                   1547:        int flags;
                   1548: 
                   1549: {
                   1550: 
1.1.1.2   root     1551:        UNUSED(flags);
                   1552: 
                   1553: 
                   1554: 
1.1.1.5   root     1555:        if (dirh->fc.index != 0 && !IS_FD_DIR(&dirh->fc)) {
1.1       root     1556: 
1.1.1.2   root     1557:                DEBUG(("bios_opendir: bad directory"));
1.1       root     1558: 
                   1559:                return EPTHNF;
                   1560: 
                   1561:        }
                   1562: 
                   1563:        return 0;
                   1564: 
                   1565: }
                   1566: 
                   1567: 
                   1568: 
1.1.1.2   root     1569: static long ARGS_ON_STACK 
1.1       root     1570: 
                   1571: bios_readdir(dirh, name, namelen, fc)
                   1572: 
                   1573:        DIR *dirh;
                   1574: 
                   1575:        char *name;
                   1576: 
                   1577:        int namelen;
                   1578: 
1.1.1.5   root     1579:        fcookie *fc;
                   1580: 
                   1581: {
                   1582: 
                   1583:        struct bios_file *b;
                   1584: 
                   1585:        int giveindex = dirh->flags == 0;
                   1586: 
                   1587:        int i;
                   1588: 
                   1589:        char buf[5];
                   1590: 
                   1591: 
                   1592: 
                   1593:        if (IS_FD_DIR(&dirh->fc)) {
                   1594: 
                   1595:                i = dirh->index++;
                   1596: 
                   1597:                if (i+MIN_HANDLE >= MAX_OPEN)
                   1598: 
                   1599:                        return ENMFIL;
                   1600: 
                   1601:                fc->fs = &bios_filesys;
                   1602: 
                   1603:                fc->index = i+1;
                   1604: 
                   1605:                fc->aux = i+MIN_HANDLE;
                   1606: 
                   1607:                fc->dev = dirh->fc.dev;
                   1608: 
                   1609:                if (giveindex) {
                   1610: 
                   1611:                        namelen -= (int)sizeof(long);
                   1612: 
                   1613:                        if (namelen <= 0)
                   1614: 
                   1615:                                return ERANGE;
                   1616: 
                   1617:                        *(long *)name = (long)i + 1;
                   1618: 
                   1619:                        name += sizeof(long);
                   1620: 
                   1621:                }
                   1622: 
                   1623:                ksprintf(buf, "%d", i+MIN_HANDLE);
                   1624: 
                   1625:                strncpy(name, buf, namelen - 1);
1.1       root     1626: 
1.1.1.5   root     1627:                if (strlen(buf) >= namelen)
1.1       root     1628: 
1.1.1.5   root     1629:                        return ENAMETOOLONG;
1.1       root     1630: 
1.1.1.5   root     1631:                return 0;
1.1       root     1632: 
1.1.1.5   root     1633:        }
1.1       root     1634: 
                   1635: 
                   1636: 
                   1637:        b = broot;
                   1638: 
                   1639:        i = dirh->index++;
                   1640: 
                   1641:        while(i-- > 0) {
                   1642: 
                   1643:                if (!b) break;
                   1644: 
                   1645:                b = b->next;
                   1646: 
                   1647:        }
                   1648: 
                   1649:        if (!b) {
                   1650: 
                   1651:                return ENMFIL;
                   1652: 
                   1653:        }
                   1654: 
                   1655:        fc->fs = &bios_filesys;
                   1656: 
                   1657:        fc->index = (long)b;
                   1658: 
                   1659:        fc->aux = b->private;
                   1660: 
                   1661:        fc->dev = dirh->fc.dev;
                   1662: 
                   1663:        if (giveindex) {
                   1664: 
1.1.1.2   root     1665:                namelen -= (int)sizeof(long);
1.1       root     1666: 
                   1667:                if (namelen <= 0)
                   1668: 
                   1669:                        return ERANGE;
                   1670: 
                   1671:                *((long *)name) = (long) b;
                   1672: 
                   1673:                name += sizeof(long);
                   1674: 
                   1675:        }
                   1676: 
                   1677:        strncpy(name, b->name, namelen-1);
                   1678: 
                   1679:        if (strlen(b->name) >= namelen)
                   1680: 
                   1681:                return ENAMETOOLONG;
                   1682: 
                   1683:        return 0;
                   1684: 
                   1685: }
                   1686: 
                   1687: 
                   1688: 
1.1.1.2   root     1689: static long ARGS_ON_STACK 
1.1       root     1690: 
                   1691: bios_rewinddir(dirh)
                   1692: 
                   1693:        DIR *dirh;
                   1694: 
                   1695: {
                   1696: 
                   1697:        dirh->index = 0;
                   1698: 
                   1699:        return 0;
                   1700: 
                   1701: }
                   1702: 
                   1703: 
                   1704: 
1.1.1.2   root     1705: static long ARGS_ON_STACK 
1.1       root     1706: 
                   1707: bios_closedir(dirh)
                   1708: 
                   1709:        DIR *dirh;
                   1710: 
                   1711: {
                   1712: 
1.1.1.2   root     1713:        UNUSED(dirh);
                   1714: 
1.1       root     1715:        return 0;
                   1716: 
                   1717: }
                   1718: 
                   1719: 
                   1720: 
1.1.1.2   root     1721: static long ARGS_ON_STACK 
1.1       root     1722: 
                   1723: bios_pathconf(dir, which)
                   1724: 
                   1725:        fcookie *dir;
                   1726: 
                   1727:        int which;
                   1728: 
                   1729: {
                   1730: 
1.1.1.2   root     1731:        UNUSED(dir);
                   1732: 
                   1733: 
                   1734: 
1.1       root     1735:        switch(which) {
                   1736: 
                   1737:        case -1:
                   1738: 
                   1739:                return DP_MAXREQ;
                   1740: 
                   1741:        case DP_IOPEN:
                   1742: 
                   1743:                return UNLIMITED;       /* no limit on BIOS file descriptors */
                   1744: 
                   1745:        case DP_MAXLINKS:
                   1746: 
                   1747:                return 1;               /* no hard links available */
                   1748: 
                   1749:        case DP_PATHMAX:
                   1750: 
                   1751:                return PATH_MAX;
                   1752: 
                   1753:        case DP_NAMEMAX:
                   1754: 
                   1755:                return BNAME_MAX;
                   1756: 
                   1757:        case DP_ATOMIC:
                   1758: 
                   1759:                return 1;               /* no atomic writes */
                   1760: 
                   1761:        case DP_TRUNC:
                   1762: 
                   1763:                return DP_AUTOTRUNC;    /* names are truncated */
                   1764: 
                   1765:        case DP_CASE:
                   1766: 
                   1767:                return DP_CASEINSENS;   /* not case sensitive */
                   1768: 
1.1.1.6 ! root     1769:        case DP_MODEATTR:
        !          1770: 
        !          1771:                return (0777L << 8)|
        !          1772: 
        !          1773:                                DP_FT_DIR|DP_FT_CHR;
        !          1774: 
        !          1775:        case DP_XATTRFIELDS:
        !          1776: 
        !          1777:                return DP_INDEX|DP_DEV|DP_RDEV|DP_NLINK|DP_UID|DP_GID;
        !          1778: 
1.1       root     1779:        default:
                   1780: 
                   1781:                return EINVFN;
                   1782: 
                   1783:        }
                   1784: 
                   1785: }
                   1786: 
                   1787: 
                   1788: 
1.1.1.2   root     1789: static long ARGS_ON_STACK 
1.1       root     1790: 
                   1791: bios_dfree(dir, buf)
                   1792: 
                   1793:        fcookie *dir;
                   1794: 
                   1795:        long *buf;
                   1796: 
                   1797: {
                   1798: 
1.1.1.2   root     1799:        UNUSED(dir);
                   1800: 
                   1801: 
                   1802: 
1.1       root     1803:        buf[0] = 0;     /* number of free clusters */
                   1804: 
                   1805:        buf[1] = 0;     /* total number of clusters */
                   1806: 
                   1807:        buf[2] = 1;     /* sector size (bytes) */
                   1808: 
                   1809:        buf[3] = 1;     /* cluster size (sectors) */
                   1810: 
                   1811:        return 0;
                   1812: 
                   1813: }
                   1814: 
                   1815: 
                   1816: 
                   1817: /*
                   1818: 
                   1819:  * BIOS Dcntl() calls:
                   1820: 
                   1821:  * Dcntl(0xde02, "U:\DEV\FOO", &foo_descr): install a new device called
                   1822: 
                   1823:  *     "FOO", which is described by the dev_descr structure "foo_descr".
                   1824: 
                   1825:  *     this structure has the following fields:
                   1826: 
                   1827:  *         DEVDRV *driver              the device driver itself
                   1828: 
                   1829:  *        short  dinfo                 info for the device driver
                   1830: 
                   1831:  *        short  flags                 flags for the file (e.g. O_TTY)
                   1832: 
                   1833:  *        struct tty *tty              tty structure, if appropriate
                   1834: 
1.1.1.6 ! root     1835:  *        long   drvsize;              size of driver struct
        !          1836: 
1.1       root     1837:  *
                   1838: 
                   1839:  * Dcntl(0xde00, "U:\DEV\BAR", n): install a new BIOS terminal device, with
                   1840: 
                   1841:  *     BIOS device number "n".
                   1842: 
                   1843:  * Dcntl(0xde01, "U:\DEV\BAR", n): install a new non-tty BIOS device, with
                   1844: 
                   1845:  *     BIOS device number "n".
                   1846: 
                   1847:  */
                   1848: 
                   1849: 
                   1850: 
1.1.1.6 ! root     1851: static long ARGS_ON_STACK
1.1       root     1852: 
                   1853: bios_fscntl(dir, name, cmd, arg)
                   1854: 
                   1855:        fcookie *dir;
                   1856: 
                   1857:        const char *name;
                   1858: 
                   1859:        int cmd;
                   1860: 
                   1861:        long arg;
                   1862: 
                   1863: {
                   1864: 
                   1865:        struct bios_file *b;
                   1866: 
1.1.1.5   root     1867:        static int devindex = 0;
                   1868: 
1.1       root     1869: 
                   1870: 
1.1.1.5   root     1871:        if (curproc->euid) {
                   1872: 
                   1873:                DEBUG(("biosfs: Dcntl() by non-privileged process"));
                   1874: 
                   1875:                return ((unsigned)cmd == DEV_INSTALL) ? 0 : EACCDN;
                   1876: 
                   1877:        }
                   1878: 
                   1879: 
                   1880: 
                   1881:        if (IS_FD_DIR(dir))
                   1882: 
                   1883:                return EACCDN;
                   1884: 
                   1885: 
                   1886: 
1.1.1.6 ! root     1887:        /* ts: let's see if such an entry already exists */
        !          1888: 
        !          1889:        for (b=broot; b; b=b->next)
        !          1890: 
        !          1891:                if (!strcmp(b->name, name))
        !          1892: 
        !          1893:                        break;
        !          1894: 
        !          1895: 
        !          1896: 
        !          1897:        switch((unsigned)cmd) {
        !          1898: 
        !          1899:        case DEV_INSTALL:
        !          1900: 
        !          1901:            {
1.1       root     1902: 
                   1903:                struct dev_descr *d = (struct dev_descr *)arg;
                   1904: 
                   1905: 
                   1906: 
1.1.1.6 ! root     1907:                if (!b) {
        !          1908: 
        !          1909:                        b = kmalloc(SIZEOF(struct bios_file));
        !          1910: 
        !          1911:                        if (!b) return 0;
        !          1912: 
        !          1913:                        b->next = broot;
        !          1914: 
        !          1915:                        broot = b;
1.1       root     1916: 
1.1.1.6 ! root     1917:                        strncpy(b->name, name, BNAME_MAX);
1.1       root     1918: 
1.1.1.6 ! root     1919:                        b->name[BNAME_MAX] = 0;
1.1       root     1920: 
1.1.1.6 ! root     1921:                }
1.1       root     1922: 
                   1923:                b->device = d->driver;
                   1924: 
                   1925:                b->private = d->dinfo;
                   1926: 
                   1927:                b->flags = d->flags;
                   1928: 
                   1929:                b->tty = d->tty;
                   1930: 
1.1.1.6 ! root     1931:                b->drvsize = d->drvsize;
1.1       root     1932: 
1.1.1.5   root     1933:                set_xattr(&(b->xattr), S_IFCHR|DEFAULT_MODE, UNK_RDEV|devindex);
                   1934: 
                   1935:                devindex = (devindex+1) & 0x00ff;
                   1936: 
1.1       root     1937:                return (long)&kernelinfo;
                   1938: 
1.1.1.6 ! root     1939:            }
        !          1940: 
        !          1941:        case DEV_NEWTTY:
1.1       root     1942: 
1.1.1.6 ! root     1943:                if (!b) {
1.1       root     1944: 
1.1.1.6 ! root     1945:                        b = kmalloc(SIZEOF(struct bios_file));
1.1       root     1946: 
1.1.1.6 ! root     1947:                        if (!b)
1.1       root     1948: 
1.1.1.6 ! root     1949:                                return ENSMEM;
1.1       root     1950: 
1.1.1.6 ! root     1951:                        strncpy(b->name, name, BNAME_MAX);
1.1       root     1952: 
1.1.1.6 ! root     1953:                        b->name[BNAME_MAX] = 0;
1.1       root     1954: 
1.1.1.6 ! root     1955:                        b->tty = kmalloc(SIZEOF(struct tty));
1.1       root     1956: 
1.1.1.6 ! root     1957:                        if (!b->tty) {
        !          1958: 
        !          1959:                                kfree(b);
        !          1960: 
        !          1961:                                return ENSMEM;
        !          1962: 
        !          1963:                        }
        !          1964: 
        !          1965:                        b->next = broot;
        !          1966: 
        !          1967:                        broot = b;
        !          1968: 
        !          1969:                } else {
1.1       root     1970: 
1.1.1.6 ! root     1971:                        /*  ts: it's probably better to use a new tty
1.1       root     1972: 
1.1.1.6 ! root     1973:                         * structure here, but don't touch the old
        !          1974: 
        !          1975:                         * pointers until we know we've got enough
        !          1976: 
        !          1977:                         * memory to do it!
        !          1978: 
        !          1979:                         */
        !          1980: 
        !          1981:                        struct tty *ttyptr;
        !          1982: 
        !          1983: 
        !          1984: 
        !          1985:                        if ((ttyptr = kmalloc(SIZEOF(struct tty))) == 0)
        !          1986: 
        !          1987:                                return ENSMEM;
        !          1988: 
        !          1989:                        b->tty = ttyptr;
        !          1990: 
        !          1991:                }
        !          1992: 
        !          1993:                b->drvsize = 0;
1.1       root     1994: 
                   1995:                b->device = &bios_tdevice;
                   1996: 
                   1997:                b->private = arg;
                   1998: 
                   1999:                b->flags = O_TTY;
                   2000: 
                   2001:                *b->tty = default_tty;
                   2002: 
1.1.1.5   root     2003:                set_xattr(&(b->xattr), S_IFCHR|DEFAULT_MODE, BIOS_RDEV|(b->private&0x00ff));
                   2004: 
1.1       root     2005:                return 0;
                   2006: 
                   2007: 
                   2008: 
1.1.1.6 ! root     2009:        case DEV_NEWBIOS:
        !          2010: 
        !          2011:                if (!b) {
        !          2012: 
        !          2013:                        b = kmalloc(SIZEOF(struct bios_file));
        !          2014: 
        !          2015:                        if (!b) return ENSMEM;
        !          2016: 
        !          2017:                        b->next = broot;
        !          2018: 
        !          2019:                        broot = b;
        !          2020: 
        !          2021:                        strncpy(b->name, name, BNAME_MAX);
        !          2022: 
        !          2023:                        b->name[BNAME_MAX] = 0;
        !          2024: 
        !          2025:                }
        !          2026: 
        !          2027:                b->drvsize = 0;
1.1       root     2028: 
1.1.1.6 ! root     2029:                /*  ts: it's probably better not to free an old tty
1.1       root     2030: 
1.1.1.6 ! root     2031:                 * structure here, cause we don't know if any process
1.1       root     2032: 
1.1.1.6 ! root     2033:                 * who didn't recognize this change is still using it.
        !          2034: 
        !          2035:                 */
1.1       root     2036: 
                   2037:                b->tty = 0;
                   2038: 
                   2039:                b->device = &bios_ndevice;
                   2040: 
                   2041:                b->private = arg;
                   2042: 
                   2043:                b->flags = 0;
                   2044: 
1.1.1.5   root     2045:                set_xattr(&(b->xattr), S_IFCHR|DEFAULT_MODE, BIOS_RDEV|(b->private&0x00ff));
                   2046: 
1.1       root     2047:                return 0;
                   2048: 
1.1.1.6 ! root     2049:        default:
1.1       root     2050: 
1.1.1.6 ! root     2051:                return EINVFN;
        !          2052: 
        !          2053:        }
1.1       root     2054: 
                   2055: }
                   2056: 
                   2057: 
                   2058: 
1.1.1.2   root     2059: static long ARGS_ON_STACK 
1.1       root     2060: 
                   2061: bios_symlink(dir, name, to)
                   2062: 
                   2063:        fcookie *dir;
                   2064: 
                   2065:        const char *name, *to;
                   2066: 
                   2067: {
                   2068: 
                   2069:        struct bios_file *b;
                   2070: 
                   2071:        long r;
                   2072: 
                   2073:        fcookie fc;
                   2074: 
                   2075: 
                   2076: 
1.1.1.5   root     2077:        if (curproc->euid)
                   2078: 
                   2079:                return EACCDN;
                   2080: 
                   2081: 
                   2082: 
1.1.1.6 ! root     2083:        if (IS_FD_DIR(dir))
        !          2084: 
        !          2085:                return EACCDN;
        !          2086: 
        !          2087: 
        !          2088: 
1.1       root     2089:        r = bios_lookup(dir, name, &fc);
                   2090: 
                   2091:        if (r == 0) return EACCDN;      /* file already exists */
                   2092: 
                   2093:        if (r != EFILNF) return r;      /* some other error */
                   2094: 
                   2095: 
                   2096: 
                   2097:        b = kmalloc(SIZEOF(struct bios_file));
                   2098: 
                   2099:        if (!b) return EACCDN;
                   2100: 
                   2101: 
                   2102: 
                   2103:        strncpy(b->name, name, BNAME_MAX);
                   2104: 
                   2105:        b->name[BNAME_MAX] = 0;
                   2106: 
                   2107:        b->device = 0;
                   2108: 
                   2109:        b->private = EINVFN;
                   2110: 
                   2111:        b->flags = 0;
                   2112: 
                   2113:        b->tty = kmalloc((long)strlen(to)+1);
                   2114: 
                   2115:        if (!b->tty) {
                   2116: 
                   2117:                kfree(b);
                   2118: 
                   2119:                return EACCDN;
                   2120: 
                   2121:        }
                   2122: 
                   2123:        strcpy((char *)b->tty, to);
                   2124: 
1.1.1.5   root     2125: 
                   2126: 
                   2127:        set_xattr(&b->xattr, S_IFLNK|DEFAULT_DIRMODE, BIOSDRV);
                   2128: 
                   2129:        b->xattr.size = strlen(to)+1;
                   2130: 
                   2131: 
                   2132: 
1.1       root     2133:        b->next = broot;
                   2134: 
                   2135:        broot = b;
                   2136: 
                   2137:        return 0;
                   2138: 
                   2139: }
                   2140: 
                   2141: 
                   2142: 
1.1.1.2   root     2143: static long ARGS_ON_STACK 
1.1       root     2144: 
                   2145: bios_readlink(fc, buf, buflen)
                   2146: 
                   2147:        fcookie *fc;
                   2148: 
                   2149:        char *buf;
                   2150: 
                   2151:        int buflen;
                   2152: 
                   2153: {
                   2154: 
                   2155:        struct bios_file *b = (struct bios_file *)fc->index;
                   2156: 
                   2157: 
                   2158: 
1.1.1.5   root     2159:        if (IS_FD_DIR(fc) || IS_FD_ENTRY(fc))
                   2160: 
                   2161:                return EINVFN;
                   2162: 
1.1       root     2163:        if (!b) return EINVFN;
                   2164: 
                   2165:        if (b->device) return EINVFN;
                   2166: 
                   2167: 
                   2168: 
                   2169:        strncpy(buf, (char *)b->tty, buflen);
                   2170: 
                   2171:        if (strlen((char *)b->tty) >= buflen)
                   2172: 
                   2173:                return ENAMETOOLONG;
                   2174: 
                   2175:        return 0;
                   2176: 
                   2177: }
                   2178: 
                   2179: 
                   2180: 
                   2181: 
                   2182: 
                   2183: /*
                   2184: 
                   2185:  * routines for file systems that don't support volume labels
                   2186: 
                   2187:  */
                   2188: 
                   2189: 
                   2190: 
1.1.1.2   root     2191: long ARGS_ON_STACK 
1.1       root     2192: 
                   2193: nowritelabel(dir, name)
                   2194: 
                   2195:        fcookie *dir;
                   2196: 
                   2197:        const char *name;
                   2198: 
                   2199: {
                   2200: 
1.1.1.2   root     2201:        UNUSED(dir);
                   2202: 
                   2203:        UNUSED(name);
                   2204: 
1.1       root     2205:        return EACCDN;
                   2206: 
                   2207: }
                   2208: 
                   2209: 
                   2210: 
1.1.1.2   root     2211: long ARGS_ON_STACK 
1.1       root     2212: 
                   2213: noreadlabel(dir, name, namelen)
                   2214: 
                   2215:        fcookie *dir;
                   2216: 
                   2217:        char *name;
                   2218: 
                   2219:        int namelen;
                   2220: 
                   2221: {
                   2222: 
1.1.1.2   root     2223:        UNUSED(dir);
                   2224: 
                   2225:        UNUSED(name);
                   2226: 
                   2227:        UNUSED(namelen);
                   2228: 
1.1       root     2229:        return EFILNF;
                   2230: 
                   2231: }
                   2232: 
                   2233: 
                   2234: 
                   2235: /*
                   2236: 
                   2237:  * routines for file systems that don't support links
                   2238: 
                   2239:  */
                   2240: 
                   2241: 
                   2242: 
1.1.1.2   root     2243: long ARGS_ON_STACK 
1.1       root     2244: 
                   2245: nosymlink(dir, name, to)
                   2246: 
                   2247:        fcookie *dir;
                   2248: 
                   2249:        const char *name, *to;
                   2250: 
                   2251: {
                   2252: 
1.1.1.2   root     2253:        UNUSED(dir); UNUSED(name);
                   2254: 
                   2255:        UNUSED(to);
                   2256: 
1.1       root     2257:        return EINVFN;
                   2258: 
                   2259: }
                   2260: 
                   2261: 
                   2262: 
1.1.1.2   root     2263: long ARGS_ON_STACK 
1.1       root     2264: 
                   2265: noreadlink(dir, buf, buflen)
                   2266: 
                   2267:        fcookie *dir;
                   2268: 
                   2269:        char *buf;
                   2270: 
                   2271:        int buflen;
                   2272: 
                   2273: {
                   2274: 
1.1.1.2   root     2275:        UNUSED(dir); UNUSED(buf);
                   2276: 
                   2277:        UNUSED(buflen);
                   2278: 
1.1       root     2279:        return EINVFN;
                   2280: 
                   2281: }
                   2282: 
                   2283: 
                   2284: 
1.1.1.2   root     2285: long ARGS_ON_STACK 
1.1       root     2286: 
                   2287: nohardlink(fromdir, fromname, todir, toname)
                   2288: 
                   2289:        fcookie *fromdir, *todir;
                   2290: 
                   2291:        const char *fromname, *toname;
                   2292: 
                   2293: {
                   2294: 
1.1.1.2   root     2295:        UNUSED(fromdir); UNUSED(todir);
                   2296: 
                   2297:        UNUSED(fromname); UNUSED(toname);
                   2298: 
1.1       root     2299:        return EINVFN;
                   2300: 
                   2301: }
                   2302: 
                   2303: 
                   2304: 
                   2305: /* dummy routine for file systems with no Fscntl commands */
                   2306: 
                   2307: 
                   2308: 
1.1.1.2   root     2309: long ARGS_ON_STACK 
1.1       root     2310: 
                   2311: nofscntl(dir, name, cmd, arg)
                   2312: 
                   2313:        fcookie *dir;
                   2314: 
                   2315:        const char *name;
                   2316: 
                   2317:        int cmd;
                   2318: 
                   2319:        long arg;
                   2320: 
                   2321: {
                   2322: 
1.1.1.2   root     2323:        UNUSED(dir); UNUSED(name);
                   2324: 
                   2325:        UNUSED(cmd); UNUSED(arg);
                   2326: 
1.1       root     2327:        return EINVFN;
                   2328: 
                   2329: }
                   2330: 
                   2331: 
                   2332: 
                   2333: /*
                   2334: 
                   2335:  * Did the disk change? Not on this drive!
                   2336: 
                   2337:  * However, we have to do Getbpb anyways, because someone has decided
                   2338: 
                   2339:  * to force a media change on our (non-existent) drive.
                   2340: 
                   2341:  */
                   2342: 
1.1.1.2   root     2343: long ARGS_ON_STACK 
1.1       root     2344: 
                   2345: nodskchng(drv)
                   2346: 
                   2347:        int drv;
                   2348: 
                   2349: {
                   2350: 
                   2351:        (void)getbpb(drv);
                   2352: 
                   2353:        return 0;
                   2354: 
                   2355: }
                   2356: 
                   2357: 
                   2358: 
1.1.1.2   root     2359: long ARGS_ON_STACK 
1.1       root     2360: 
                   2361: nocreat(dir, name, mode, attrib, fc)
                   2362: 
                   2363:        fcookie *dir, *fc;
                   2364: 
                   2365:        const char *name;
                   2366: 
                   2367:        unsigned mode;
                   2368: 
                   2369:        int attrib;
                   2370: 
                   2371: {
                   2372: 
1.1.1.2   root     2373:        UNUSED(dir); UNUSED(fc);
                   2374: 
                   2375:        UNUSED(name); UNUSED(mode);
                   2376: 
                   2377:        UNUSED(attrib);
                   2378: 
1.1       root     2379:        return EACCDN;
                   2380: 
                   2381: }
                   2382: 
                   2383: 
                   2384: 
1.1.1.2   root     2385: static DEVDRV * ARGS_ON_STACK 
1.1       root     2386: 
                   2387: bios_getdev(fc, devsp)
                   2388: 
                   2389:        fcookie *fc;
                   2390: 
                   2391:        long *devsp;
                   2392: 
                   2393: {
                   2394: 
                   2395:        struct bios_file *b;
                   2396: 
                   2397: 
                   2398: 
1.1.1.5   root     2399:        /* Check for \dev\fd\... */
                   2400: 
                   2401:        if (IS_FD_ENTRY(fc)) {
                   2402: 
                   2403:            *devsp = (int) fc->aux;
                   2404: 
                   2405:            return &fakedev;
                   2406: 
                   2407:        }
                   2408: 
                   2409: 
                   2410: 
1.1       root     2411:        b = (struct bios_file *)fc->index;
                   2412: 
                   2413: 
                   2414: 
                   2415:        if (b->device && b->device != &fakedev)
                   2416: 
                   2417:                *devsp = (long)b->tty;
                   2418: 
                   2419:        else
                   2420: 
                   2421:                *devsp = b->private;
                   2422: 
                   2423: 
                   2424: 
                   2425:        return b->device;       /* return the device driver */
                   2426: 
                   2427: }
                   2428: 
                   2429: 
                   2430: 
                   2431: /*
                   2432: 
                   2433:  * NULL device driver
                   2434: 
                   2435:  */
                   2436: 
                   2437: 
                   2438: 
1.1.1.2   root     2439: long ARGS_ON_STACK 
1.1       root     2440: 
                   2441: null_open(f)
                   2442: 
                   2443:        FILEPTR *f;
                   2444: 
                   2445: {
                   2446: 
1.1.1.2   root     2447:        UNUSED(f);
                   2448: 
1.1       root     2449:        return 0;
                   2450: 
                   2451: }
                   2452: 
                   2453: 
                   2454: 
1.1.1.2   root     2455: long ARGS_ON_STACK 
1.1       root     2456: 
                   2457: null_write(f, buf, bytes)
                   2458: 
                   2459:        FILEPTR *f; const char *buf; long bytes;
                   2460: 
                   2461: {
                   2462: 
1.1.1.2   root     2463:        UNUSED(f); UNUSED(buf);
                   2464: 
1.1       root     2465:        return bytes;
                   2466: 
                   2467: }
                   2468: 
                   2469: 
                   2470: 
1.1.1.2   root     2471: long ARGS_ON_STACK 
1.1       root     2472: 
                   2473: null_read(f, buf, bytes)
                   2474: 
                   2475:        FILEPTR *f; char *buf; long bytes;
                   2476: 
                   2477: {
                   2478: 
1.1.1.2   root     2479:        UNUSED(f); UNUSED(buf);
                   2480: 
                   2481:        UNUSED(bytes);
                   2482: 
1.1       root     2483:        return 0;
                   2484: 
                   2485: }
                   2486: 
                   2487: 
                   2488: 
1.1.1.2   root     2489: long ARGS_ON_STACK 
1.1       root     2490: 
                   2491: null_lseek(f, where, whence)
                   2492: 
                   2493:        FILEPTR *f; long where; int whence;
                   2494: 
                   2495: {
                   2496: 
1.1.1.2   root     2497:        UNUSED(f); UNUSED(whence);
                   2498: 
1.1       root     2499:        return (where == 0) ? 0 : ERANGE;
                   2500: 
                   2501: }
                   2502: 
                   2503: 
                   2504: 
1.1.1.2   root     2505: long ARGS_ON_STACK 
1.1       root     2506: 
                   2507: null_ioctl(f, mode, buf)
                   2508: 
                   2509:        FILEPTR *f; int mode; void *buf;
                   2510: 
                   2511: {
                   2512: 
1.1.1.2   root     2513:        UNUSED(f);
                   2514: 
1.1.1.6 ! root     2515: 
        !          2516: 
        !          2517:        switch(mode) {
        !          2518: 
        !          2519:        case FIONREAD:
1.1       root     2520: 
                   2521:                *((long *)buf) = 0;
                   2522: 
1.1.1.6 ! root     2523:                break;
1.1       root     2524: 
1.1.1.6 ! root     2525:        case FIONWRITE:
1.1       root     2526: 
                   2527:                *((long *)buf) = 1;
                   2528: 
1.1.1.6 ! root     2529:                break;
        !          2530: 
        !          2531:        case FIOEXCEPT:
        !          2532: 
        !          2533:                *((long *)buf) = 0;
        !          2534: 
        !          2535:        default:
1.1       root     2536: 
                   2537:                return EINVFN;
                   2538: 
1.1.1.6 ! root     2539:        }
        !          2540: 
1.1       root     2541:        return 0;
                   2542: 
                   2543: }
                   2544: 
                   2545: 
                   2546: 
1.1.1.2   root     2547: long ARGS_ON_STACK 
1.1       root     2548: 
                   2549: null_datime(f, timeptr, rwflag)
                   2550: 
                   2551:        FILEPTR *f;
                   2552: 
                   2553:        short *timeptr;
                   2554: 
                   2555:        int rwflag;
                   2556: 
                   2557: {
                   2558: 
1.1.1.2   root     2559:        UNUSED(f);
                   2560: 
1.1       root     2561:        if (rwflag)
                   2562: 
                   2563:                return EACCDN;
                   2564: 
                   2565:        *timeptr++ = timestamp;
                   2566: 
                   2567:        *timeptr = datestamp;
                   2568: 
                   2569:        return 0;
                   2570: 
                   2571: }
                   2572: 
                   2573: 
                   2574: 
1.1.1.2   root     2575: long ARGS_ON_STACK 
1.1       root     2576: 
                   2577: null_close(f, pid)
                   2578: 
                   2579:        FILEPTR *f;
                   2580: 
                   2581:        int pid;
                   2582: 
                   2583: {
                   2584: 
1.1.1.2   root     2585:        UNUSED(f);
                   2586: 
                   2587:        UNUSED(pid);
                   2588: 
1.1       root     2589:        return 0;
                   2590: 
                   2591: }
                   2592: 
                   2593: 
                   2594: 
1.1.1.2   root     2595: long ARGS_ON_STACK 
1.1       root     2596: 
                   2597: null_select(f, p, mode)
                   2598: 
                   2599:        FILEPTR *f; long p;
                   2600: 
                   2601:        int mode;
                   2602: 
                   2603: {
                   2604: 
1.1.1.2   root     2605:        UNUSED(f); UNUSED(p);
                   2606: 
1.1.1.6 ! root     2607:        if ((mode == O_RDONLY) || (mode == O_WRONLY))
        !          2608: 
        !          2609:                return 1;       /* we're always ready to read/write */
1.1.1.2   root     2610: 
1.1.1.6 ! root     2611: 
        !          2612: 
        !          2613:        return 0;       /* other things we don't care about */
1.1       root     2614: 
                   2615: }
                   2616: 
                   2617: 
                   2618: 
1.1.1.2   root     2619: void ARGS_ON_STACK 
1.1       root     2620: 
                   2621: null_unselect(f, p, mode)
                   2622: 
                   2623:        FILEPTR *f;
                   2624: 
                   2625:        long p;
                   2626: 
                   2627:        int mode;
                   2628: 
                   2629: {
                   2630: 
1.1.1.2   root     2631:        UNUSED(f); UNUSED(p);
                   2632: 
                   2633:        UNUSED(mode);
                   2634: 
1.1       root     2635:        /* nothing to do */
                   2636: 
                   2637: }
                   2638: 
                   2639: 
                   2640: 
                   2641: /*
                   2642: 
                   2643:  * BIOS terminal device driver
                   2644: 
                   2645:  */
                   2646: 
                   2647: 
                   2648: 
1.1.1.2   root     2649: static long ARGS_ON_STACK 
1.1       root     2650: 
                   2651: bios_topen(f)
                   2652: 
                   2653:        FILEPTR *f;
                   2654: 
                   2655: {
                   2656: 
1.1.1.6 ! root     2657:        struct tty *tty = (struct tty *)f->devinfo;
        !          2658: 
        !          2659:        int bdev = f->fc.aux;
        !          2660: 
        !          2661:        struct bios_tty *b;
        !          2662: 
        !          2663: 
        !          2664: 
1.1       root     2665:        f->flags |= O_TTY;
                   2666: 
1.1.1.6 ! root     2667:        if (!tty->use_cnt && ((b = BTTY(f))) && b->tosfd == EUNDEV)
        !          2668: 
        !          2669:                b->tosfd = rsvf_open (bdev);
        !          2670: 
1.1       root     2671:        return 0;
                   2672: 
                   2673: }
                   2674: 
                   2675: 
                   2676: 
                   2677: /*
                   2678: 
                   2679:  * Note: when a BIOS device is a terminal (i.e. has the O_TTY flag
                   2680: 
                   2681:  * set), bios_read and bios_write will only ever be called indirectly, via
                   2682: 
                   2683:  * tty_read and tty_write. That's why we can afford to play a bit fast and
                   2684: 
                   2685:  * loose with the pointers ("buf" is really going to point to a long) and
                   2686: 
                   2687:  * why we know that "bytes" is divisible by 4.
                   2688: 
                   2689:  */
                   2690: 
                   2691: 
                   2692: 
1.1.1.2   root     2693: static long ARGS_ON_STACK 
1.1       root     2694: 
                   2695: bios_twrite(f, buf, bytes)
                   2696: 
                   2697:        FILEPTR *f; const char *buf; long bytes;
                   2698: 
                   2699: {
                   2700: 
                   2701:        long *r;
                   2702: 
                   2703:        long ret = 0;
                   2704: 
                   2705:        int bdev = f->fc.aux;
                   2706: 
1.1.1.5   root     2707:        struct bios_file *b = (struct bios_file *)f->fc.index;
                   2708: 
1.1       root     2709: 
                   2710: 
                   2711:        r = (long *)buf;
                   2712: 
1.1.1.3   root     2713: 
                   2714: 
                   2715: /* Check for control characters on any newline output.
                   2716: 
                   2717:  * Note that newlines are always output through tty_putchar,
                   2718: 
                   2719:  * so they'll always be the first thing in the buffer (at least,
                   2720: 
                   2721:  * for cooked TTY output they will, which is the only sort that
                   2722: 
                   2723:  * control characters affect anyways).
                   2724: 
                   2725:  */
                   2726: 
1.1.1.6 ! root     2727:        if (bdev == 2 && bytes > 0 && (*r & 0x000000ffL) == '\n')
1.1.1.3   root     2728: 
1.1.1.6 ! root     2729:                (void) checkkeys();
1.1.1.3   root     2730: 
                   2731: 
                   2732: 
1.1.1.2   root     2733:        if (f->flags & O_NDELAY) {
1.1       root     2734: 
1.1.1.2   root     2735:                while (bytes > 0) {
                   2736: 
                   2737:                    if (!bcostat(bdev)) break;
                   2738: 
                   2739:                    if (bconout(bdev, (int)*r) == 0)
1.1       root     2740: 
                   2741:                        break;
                   2742: 
1.1.1.2   root     2743:                    r++; bytes -= 4; ret+= 4;
                   2744: 
                   2745:                }
                   2746: 
                   2747:        } else {
1.1       root     2748: 
1.1.1.2   root     2749:                while (bytes > 0) {
1.1       root     2750: 
1.1.1.2   root     2751:                    if (bconout(bdev, (int)*r) == 0)
1.1       root     2752: 
                   2753:                        break;
                   2754: 
1.1.1.2   root     2755:                    r++; bytes -= 4; ret+= 4;
1.1       root     2756: 
1.1.1.2   root     2757:                }
1.1       root     2758: 
                   2759:        }
                   2760: 
1.1.1.2   root     2761: 
1.1       root     2762: 
1.1.1.5   root     2763:        if (ret > 0) {
                   2764: 
                   2765:                b->xattr.mtime = b->xattr.atime = timestamp;
                   2766: 
                   2767:                b->xattr.mdate = b->xattr.adate = datestamp;
                   2768: 
                   2769:        }
1.1.1.2   root     2770: 
1.1       root     2771:        return ret;
                   2772: 
                   2773: }
                   2774: 
                   2775: 
                   2776: 
1.1.1.2   root     2777: static long ARGS_ON_STACK 
1.1       root     2778: 
                   2779: bios_tread(f, buf, bytes)
                   2780: 
                   2781:        FILEPTR *f; char *buf; long bytes;
                   2782: 
                   2783: {
                   2784: 
                   2785:        long *r, ret = 0;
                   2786: 
                   2787:        int bdev = f->fc.aux;
                   2788: 
1.1.1.5   root     2789:        struct  bios_file *b = (struct bios_file *)f->fc.index;
                   2790: 
1.1       root     2791: 
                   2792: 
                   2793:        r = (long *)buf;
                   2794: 
                   2795: 
                   2796: 
1.1.1.2   root     2797:        if ((f->flags & O_NDELAY)) {
1.1       root     2798: 
1.1.1.2   root     2799:                while (bytes > 0) {
                   2800: 
                   2801:                    if ( !bconstat(bdev) )
1.1       root     2802: 
                   2803:                        break;
                   2804: 
1.1.1.2   root     2805:                    *r++ = bconin(bdev) & 0x7fffffffL;
                   2806: 
                   2807:                    bytes -= 4; ret += 4;
                   2808: 
                   2809:                }
                   2810: 
                   2811:        } else {
1.1       root     2812: 
1.1.1.2   root     2813:                while (bytes > 0) {
                   2814: 
                   2815:                    *r++ = bconin(bdev) & 0x7fffffffL;
                   2816: 
                   2817:                    bytes -= 4; ret += 4;
                   2818: 
                   2819:                }
1.1       root     2820: 
                   2821:        }
                   2822: 
1.1.1.5   root     2823:        if (ret > 0) {
                   2824: 
                   2825:                b->xattr.atime = timestamp;
                   2826: 
                   2827:                b->xattr.adate = datestamp;
                   2828: 
                   2829:        }
                   2830: 
1.1       root     2831:        return ret;
                   2832: 
                   2833: }
                   2834: 
                   2835: 
                   2836: 
                   2837: /*
                   2838: 
1.1.1.6 ! root     2839:  * wakewrite(p): wake process p sleeping in write (timeout)
        !          2840: 
        !          2841:  */
        !          2842: 
        !          2843: 
        !          2844: 
        !          2845: static void ARGS_ON_STACK
        !          2846: 
        !          2847: wakewrite(p)
        !          2848: 
        !          2849:        PROC *p;
        !          2850: 
        !          2851: {
        !          2852: 
        !          2853:        short s;
1.1       root     2854: 
1.1.1.6 ! root     2855: 
        !          2856: 
        !          2857:        s = spl7();     /* block interrupts */
        !          2858: 
        !          2859:        p->wait_cond = 0;
        !          2860: 
        !          2861:        if (p->wait_q == IO_Q) {
        !          2862: 
        !          2863:                rm_q(IO_Q, p);
        !          2864: 
        !          2865:                add_q(READY_Q, p);
        !          2866: 
        !          2867:        }
        !          2868: 
        !          2869:        spl(s);
        !          2870: 
        !          2871: }
        !          2872: 
        !          2873: 
        !          2874: 
        !          2875: /*
        !          2876: 
        !          2877:  * fast RAW byte IO for BIOS ttys
        !          2878: 
        !          2879:  * without this a RAW tty read goes thru bios_tread for every single
        !          2880: 
        !          2881:  * char, calling BIOS 3 times per byte at least...  a poor 8 MHz ST
        !          2882: 
        !          2883:  * just can't move real 19200 bits per second that way, before a
        !          2884: 
        !          2885:  * byte crawled thru all this the next has already arrived.
        !          2886: 
        !          2887:  * if the device has xcon* calls and a `normal' iorec these functions
        !          2888: 
        !          2889:  * access the buffers directly using as little CPU time as possible,
        !          2890: 
        !          2891:  * for other devices they return EUNDEV (== do the slow thing then).
        !          2892: 
        !          2893:  * yes it is a hack but better one hack here than hacks in every
        !          2894: 
        !          2895:  * user process that wants good RAW IO performance...
1.1       root     2896: 
                   2897:  */
                   2898: 
                   2899: 
                   2900: 
1.1.1.2   root     2901: static long ARGS_ON_STACK 
1.1       root     2902: 
1.1.1.6 ! root     2903: bios_writeb(f, buf, bytes)
1.1       root     2904: 
                   2905:        FILEPTR *f; const char *buf; long bytes;
                   2906: 
                   2907: {
                   2908: 
                   2909:        int bdev = f->fc.aux;
                   2910: 
1.1.1.5   root     2911:        struct bios_file *b = (struct bios_file *)f->fc.index;
                   2912: 
1.1       root     2913: 
                   2914: 
1.1.1.6 ! root     2915: /* do the slow thing if tty is not in RAW mode until serial lines
1.1       root     2916: 
1.1.1.6 ! root     2917:  * handle control chars properly
1.1       root     2918: 
1.1.1.6 ! root     2919:  */
1.1       root     2920: 
1.1.1.6 ! root     2921:        if (!(((struct tty *)f->devinfo)->sg.sg_flags & T_RAW))
1.1       root     2922: 
1.1.1.6 ! root     2923:                return EUNDEV;
1.1       root     2924: 
1.1.1.6 ! root     2925:        return iwrite (bdev, buf, bytes, (f->flags & O_NDELAY), b);
1.1       root     2926: 
1.1.1.6 ! root     2927: }
1.1       root     2928: 
                   2929: 
                   2930: 
1.1.1.6 ! root     2931: /* FILEPTR-less entrypoint for bflush etc. */
1.1       root     2932: 
                   2933: 
                   2934: 
1.1.1.6 ! root     2935: long
1.1       root     2936: 
1.1.1.6 ! root     2937: iwrite(bdev, buf, bytes, ndelay, b)
1.1       root     2938: 
1.1.1.6 ! root     2939:        int bdev; const char *buf; long bytes; int ndelay; struct bios_file *b;
1.1.1.5   root     2940: 
1.1.1.6 ! root     2941: {
1.1.1.5   root     2942: 
1.1.1.6 ! root     2943:        IOREC_T *ior = 0;
1.1.1.5   root     2944: 
1.1.1.6 ! root     2945:        long *cout = 0; /* keep compiler happy */
1.1.1.5   root     2946: 
1.1.1.6 ! root     2947:        long *ospeed;
1.1       root     2948: 
1.1.1.6 ! root     2949:        struct tty *tty = 0; /* still not happy yet? */
1.1       root     2950: 
1.1.1.6 ! root     2951:        const char *p = buf;
1.1       root     2952: 
1.1.1.6 ! root     2953:        int slept = 0;
1.1       root     2954: 
                   2955: 
                   2956: 
1.1.1.6 ! root     2957: #if 1
1.1       root     2958: 
1.1.1.6 ! root     2959: #define _hz_200 (*((long *)0x4baL))
1.1       root     2960: 
                   2961: 
                   2962: 
1.1.1.6 ! root     2963:        if (bdev == 3 && tosvers >= 0x0102) {
1.1.1.5   root     2964: 
1.1.1.6 ! root     2965:                /* midi */
1.1       root     2966: 
1.1.1.6 ! root     2967:                long ret = 0, tick = _hz_200 + 1;
1.1       root     2968: 
                   2969: 
                   2970: 
1.1.1.6 ! root     2971:                cout = &xconout[3];
1.1       root     2972: 
1.1.1.6 ! root     2973:                while (bytes > 0) {
1.1       root     2974: 
1.1.1.6 ! root     2975:                        while (!(int)callout1(xcostat[4], 4)) {
        !          2976: 
        !          2977:                                if (ndelay)
        !          2978: 
        !          2979:                                        break;
        !          2980: 
        !          2981:                                if (_hz_200 - tick > 0) {
        !          2982: 
        !          2983:                                        yield();
        !          2984: 
        !          2985:                                        tick = _hz_200 + 1;
        !          2986: 
        !          2987:                                }
        !          2988: 
        !          2989:                        }
        !          2990: 
        !          2991:                        (void) callout2(*cout, bdev, (unsigned char) *p++);
        !          2992: 
        !          2993:                        bytes--;
        !          2994: 
        !          2995:                }
        !          2996: 
        !          2997:                if (ret > 0) {
        !          2998: 
        !          2999:                        b->xattr.mtime = b->xattr.atime = timestamp;
        !          3000: 
        !          3001:                        b->xattr.mdate = b->xattr.adate = datestamp;
        !          3002: 
        !          3003:                }
        !          3004: 
        !          3005:                return p - buf;
1.1       root     3006: 
                   3007:        }
                   3008: 
1.1.1.6 ! root     3009: #endif
1.1.1.5   root     3010: 
                   3011: 
1.1.1.6 ! root     3012: 
        !          3013:        if (has_bconmap) {
        !          3014: 
        !          3015:                if ((unsigned)bdev-6 < btty_max) {
        !          3016: 
        !          3017:                        ior = MAPTAB[bdev-6].iorec + 1;
        !          3018: 
        !          3019:                        cout = &MAPTAB[bdev-6].bconout;
        !          3020: 
        !          3021:                        ospeed = &bttys[bdev-6].ospeed;
        !          3022: 
        !          3023:                        tty = bttys[bdev-6].tty;
        !          3024: 
        !          3025:                }
        !          3026: 
        !          3027:        } else if (bdev == 1 && tosvers >= 0x0102) {
        !          3028: 
        !          3029:                ior = bttys[0].orec;
        !          3030: 
        !          3031:                cout = &xconout[1];
        !          3032: 
        !          3033:                ospeed = &bttys[0].ospeed;
        !          3034: 
        !          3035:                tty = bttys[0].tty;
1.1.1.5   root     3036: 
                   3037:        }
                   3038: 
1.1       root     3039: 
                   3040: 
1.1.1.6 ! root     3041: /* no iorec, fall back to the slow way... */
1.1       root     3042: 
1.1.1.6 ! root     3043:        if (!ior)
1.1       root     3044: 
1.1.1.6 ! root     3045:                return EUNDEV;
1.1       root     3046: 
                   3047: 
                   3048: 
1.1.1.6 ! root     3049:        if (!buf) {
1.1       root     3050: 
1.1.1.6 ! root     3051:                /* flush send buffer...  should be safe to just set the
1.1       root     3052: 
1.1.1.6 ! root     3053:                   tail pointer. */
1.1       root     3054: 
1.1.1.6 ! root     3055:                ior->tail = ior->head;
1.1       root     3056: 
1.1.1.6 ! root     3057:                return 0;
1.1       root     3058: 
1.1.1.6 ! root     3059:        }
1.1       root     3060: 
                   3061: 
                   3062: 
1.1.1.6 ! root     3063:        if (!bytes)
1.1       root     3064: 
1.1.1.6 ! root     3065:                /* nothing to do... */
1.1.1.2   root     3066: 
1.1.1.6 ! root     3067:                return 0;
1.1.1.2   root     3068: 
1.1       root     3069: 
                   3070: 
1.1.1.6 ! root     3071:        do {
        !          3072: 
        !          3073:                char ch;
        !          3074: 
        !          3075:                unsigned short tail, bsize, wrap, newtail;
        !          3076: 
        !          3077:                long free;
        !          3078: 
        !          3079: 
        !          3080: 
        !          3081:                if (tty->state & TS_BLIND)
        !          3082: 
        !          3083:                        /* line disconnected... */
        !          3084: 
        !          3085:                        return p - buf;
        !          3086: 
        !          3087: 
        !          3088: 
        !          3089:                tail = ior->tail;
        !          3090: 
        !          3091:                bsize = ior->buflen;
        !          3092: 
        !          3093:                if ((free = (long)ior->head - tail - 1) < 0)
        !          3094: 
        !          3095:                        free += bsize;
        !          3096: 
        !          3097: 
        !          3098: 
        !          3099:                /* if buffer is full or we're blocking and can't write enuf */
        !          3100: 
        !          3101:                if ((unsigned long)free < 2 ||
        !          3102: 
        !          3103:                    (!ndelay && free < bytes && free < bsize/2)) {
        !          3104: 
        !          3105:                        long sleepchars;
        !          3106: 
        !          3107:                        unsigned long isleep = 0;
        !          3108: 
        !          3109: 
        !          3110: 
        !          3111:                        /* if the write should not block thats it. */
        !          3112: 
        !          3113:                        if (ndelay)
        !          3114: 
        !          3115:                                return p - buf;
        !          3116: 
        !          3117: 
        !          3118: 
        !          3119:                        /* else sleep the (minimum) time it takes until
        !          3120: 
        !          3121:                           the buffer is either half-empty or has space
        !          3122: 
        !          3123:                           enough for the write, wichever is smaller. */
        !          3124: 
        !          3125:                        if ((sleepchars = bsize/2) > bytes)
        !          3126: 
        !          3127:                                sleepchars = bytes;
        !          3128: 
        !          3129:                        sleepchars -= free;
        !          3130: 
        !          3131: 
        !          3132: 
        !          3133:                        if (*ospeed > 0)
        !          3134: 
        !          3135:                                isleep = (unsigned long)
        !          3136: 
        !          3137:                                        ((sleepchars * 10000L) / *ospeed);
        !          3138: 
        !          3139: 
        !          3140: 
        !          3141:                        /* except that if we already slept and the buffer
        !          3142: 
        !          3143:                           still was full we sleep for at least 60
        !          3144: 
        !          3145:                           milliseconds. (driver must be waiting for
        !          3146: 
        !          3147:                           some handshake signal and we don't want to
        !          3148: 
        !          3149:                           hog the processor.) */
        !          3150: 
        !          3151:                        if (slept && isleep < 60)
        !          3152: 
        !          3153:                                isleep = 60;
        !          3154: 
        !          3155: 
        !          3156: 
        !          3157:                        if (isleep < 5)
        !          3158: 
        !          3159:                                /* if it still would be less than 5
        !          3160: 
        !          3161:                                   milliseconds then just give up this
        !          3162: 
        !          3163:                                   timeslice */
        !          3164: 
        !          3165:                                yield();
        !          3166: 
        !          3167:                        else if (isleep < 20)
        !          3168: 
        !          3169:                                nap (isleep);
        !          3170: 
        !          3171:                        else {
        !          3172: 
        !          3173:                                TIMEOUT *t;
        !          3174: 
        !          3175: 
        !          3176: 
        !          3177:                                if (isleep > 200)
        !          3178: 
        !          3179:                                        isleep = 200;
        !          3180: 
        !          3181:                                curproc->wait_cond = (long)&tty->state;
        !          3182: 
        !          3183:                                t = addtimeout((long)isleep, wakewrite);
        !          3184: 
        !          3185:                                if (t) {
        !          3186: 
        !          3187:                                        TRACE(("sleeping in iwrite"));
        !          3188: 
        !          3189:                                        sleep(IO_Q|0x100, (long)&tty->state);
        !          3190: 
        !          3191:                                        canceltimeout(t);
        !          3192: 
        !          3193:                                }
        !          3194: 
        !          3195:                        }
        !          3196: 
        !          3197: 
        !          3198: 
        !          3199:                        /* loop and try again. */
        !          3200: 
        !          3201:                        slept = (unsigned long)free < 2;
        !          3202: 
        !          3203:                        continue;
        !          3204: 
        !          3205:                }
        !          3206: 
        !          3207:                slept = 0;
        !          3208: 
        !          3209: 
        !          3210: 
        !          3211:                /* save the 1st char, we could need it later. */
        !          3212: 
        !          3213:                ch = *p;
        !          3214: 
        !          3215:                wrap = bsize - tail;
        !          3216: 
        !          3217:                if (--free > bytes)
        !          3218: 
        !          3219:                        free = bytes;
        !          3220: 
        !          3221:                bytes -= free;
        !          3222: 
        !          3223: 
        !          3224: 
        !          3225:                /* now copy to buffer.  if its just a few then do it here... */
        !          3226: 
        !          3227:                if (free < 5) {
        !          3228: 
        !          3229:                        char *q = ior->bufaddr + tail;
        !          3230: 
        !          3231: 
        !          3232: 
        !          3233:                        while (free--) {
        !          3234: 
        !          3235:                                if (!--wrap)
        !          3236: 
        !          3237:                                        q -= bsize;
        !          3238: 
        !          3239:                                *++q = *p++;
        !          3240: 
        !          3241:                        }
        !          3242: 
        !          3243:                        newtail = q - ior->bufaddr;
        !          3244: 
        !          3245: 
        !          3246: 
        !          3247:                /* else use memcpy.  */
        !          3248: 
        !          3249:                } else {
        !          3250: 
        !          3251:                        /* --wrap and tail+1 because tail is `inc before access' */
        !          3252: 
        !          3253:                        if (--wrap < free) {
        !          3254: 
        !          3255:                                memcpy (ior->bufaddr + tail + 1, p, wrap);
        !          3256: 
        !          3257:                                memcpy (ior->bufaddr, p + wrap, free - wrap);
        !          3258: 
        !          3259:                                newtail = free - wrap - 1;
        !          3260: 
        !          3261:                        } else {
        !          3262: 
        !          3263:                                memcpy (ior->bufaddr + tail + 1, p, free);
        !          3264: 
        !          3265:                                newtail = tail + free;
        !          3266: 
        !          3267:                        }
        !          3268: 
        !          3269:                        p += free;
        !          3270: 
        !          3271:                }
        !          3272: 
        !          3273: 
        !          3274: 
        !          3275:                /* the following has to be done with interrupts off to avoid
        !          3276: 
        !          3277:                   race conditions. */
        !          3278: 
        !          3279:                {
        !          3280: 
        !          3281:                        short sr = spl7();
        !          3282: 
        !          3283: 
        !          3284: 
        !          3285:                        /* if the buffer is empty there might be no
        !          3286: 
        !          3287:                           interrupt that sends the next char, so we
        !          3288: 
        !          3289:                           send it thru the xcon* vector. */
        !          3290: 
        !          3291:                        if (ior->head == ior->tail) {
        !          3292: 
        !          3293:                                (void) callout2(*cout, bdev, (unsigned char) ch);
        !          3294: 
        !          3295: 
        !          3296: 
        !          3297:                                /* if the buffer now is still empty set
        !          3298: 
        !          3299:                                   the head pointer to skip the 1st char
        !          3300: 
        !          3301:                                   (that we just sent). */
        !          3302: 
        !          3303:                                if (ior->head == ior->tail) {
        !          3304: 
        !          3305:                                        if (++tail >= bsize)
        !          3306: 
        !          3307:                                                tail = 0;
        !          3308: 
        !          3309:                                        ior->head = tail;
        !          3310: 
        !          3311:                                }
        !          3312: 
        !          3313:                        }
        !          3314: 
        !          3315:                        ior->tail = newtail;
        !          3316: 
        !          3317: 
        !          3318: 
        !          3319:                        spl(sr);
        !          3320: 
        !          3321:                        if (b) {
        !          3322: 
        !          3323:                                b->xattr.mtime = b->xattr.atime = timestamp;
        !          3324: 
        !          3325:                                b->xattr.mdate = b->xattr.adate = datestamp;
        !          3326: 
        !          3327:                        }
        !          3328: 
        !          3329:                }
        !          3330: 
        !          3331:        /* if we're blocking loop until everything is written */
        !          3332: 
        !          3333:        } while (bytes && !ndelay);
        !          3334: 
        !          3335: 
        !          3336: 
        !          3337:        return p - buf;
        !          3338: 
        !          3339: }
        !          3340: 
        !          3341: 
        !          3342: 
        !          3343: /*
        !          3344: 
        !          3345:  * fast RAW BIOS tty read
        !          3346: 
        !          3347:  * this really works like a RAW tty read i.e. only blocks until _some_
        !          3348: 
        !          3349:  * data is ready.
        !          3350: 
        !          3351:  */
        !          3352: 
        !          3353: 
        !          3354: 
        !          3355: static long ARGS_ON_STACK 
        !          3356: 
        !          3357: bios_readb(f, buf, bytes)
        !          3358: 
        !          3359:        FILEPTR *f; char *buf; long bytes;
        !          3360: 
        !          3361: {
        !          3362: 
        !          3363:        int bdev = f->fc.aux;
        !          3364: 
        !          3365:        struct bios_file *b = (struct bios_file *)f->fc.index;
        !          3366: 
        !          3367:        struct tty *tty = (struct tty *)f->devinfo;
        !          3368: 
        !          3369: 
        !          3370: 
        !          3371:        if (!(tty->sg.sg_flags & T_RAW) || (tty->sg.sg_flags & T_ECHO))
        !          3372: 
        !          3373:                return EUNDEV;
        !          3374: 
        !          3375:        /* if VTIME is set tty_read already select()ed the tty
        !          3376: 
        !          3377:         * so from here on the read should not block anymore */
        !          3378: 
        !          3379:        return iread (bdev, buf, bytes, (f->flags & O_NDELAY) || tty->vtime, b);
        !          3380: 
        !          3381: }
        !          3382: 
        !          3383: 
        !          3384: 
        !          3385: long
        !          3386: 
        !          3387: iread(bdev, buf, bytes, ndelay, b)
        !          3388: 
        !          3389:        int bdev; char *buf; long bytes; int ndelay; struct bios_file *b;
        !          3390: 
        !          3391: {
        !          3392: 
        !          3393:        IOREC_T *ior = 0;
        !          3394: 
        !          3395:        long *cin = 0;  /* keep compiler happy */
        !          3396: 
        !          3397:        long *cinstat;
        !          3398: 
        !          3399:        struct bios_tty *t = 0;
        !          3400: 
        !          3401:        char *p;
        !          3402: 
        !          3403:        unsigned short head, bsize, wrap;
        !          3404: 
        !          3405:        long left;
        !          3406: 
        !          3407: 
        !          3408: 
        !          3409:        if (bdev == 3 && tosvers >= 0x0102) {
        !          3410: 
        !          3411:                /* midi */
        !          3412: 
        !          3413:                t = &midi_btty;
        !          3414: 
        !          3415:                ior = t->irec;
        !          3416: 
        !          3417:                cin = &xconin[3];
        !          3418: 
        !          3419:                cinstat = &xconstat[3];
        !          3420: 
        !          3421:        } else if (has_bconmap) {
        !          3422: 
        !          3423:                if ((unsigned)bdev-6 < btty_max) {
        !          3424: 
        !          3425:                        t = bttys+bdev-6;
        !          3426: 
        !          3427:                        ior = MAPTAB[bdev-6].iorec;
        !          3428: 
        !          3429:                        cin = &MAPTAB[bdev-6].bconin;
        !          3430: 
        !          3431:                        cinstat = &MAPTAB[bdev-6].bconstat;
        !          3432: 
        !          3433:                }
        !          3434: 
        !          3435:        } else if (bdev == 1 && tosvers >= 0x0102) {
        !          3436: 
        !          3437:                t = bttys;
        !          3438: 
        !          3439:                ior = t->irec;
        !          3440: 
        !          3441:                cin = &xconin[1];
        !          3442: 
        !          3443:                cinstat = &xconstat[1];
        !          3444: 
        !          3445:        }
        !          3446: 
        !          3447: 
        !          3448: 
        !          3449: /* no iorec, fall back to the slow way... */
        !          3450: 
        !          3451:        if (!ior)
        !          3452: 
        !          3453:                return EUNDEV;
        !          3454: 
        !          3455: 
        !          3456: 
        !          3457:        if (buf && !bytes)
        !          3458: 
        !          3459:                /* nothing to do... */
        !          3460: 
        !          3461:                return 0;
        !          3462: 
        !          3463: 
        !          3464: 
        !          3465:        /* if the read should block sleep until VMIN chars ready (or disconnect)
        !          3466: 
        !          3467:         */
        !          3468: 
        !          3469:        if (buf && !ndelay) {
        !          3470: 
        !          3471:                while (t ? (!(t->tty->state & TS_BLIND) &&
        !          3472: 
        !          3473:                            btty_ionread(t) < (long)t->tty->vmin)
        !          3474: 
        !          3475:                         : !(int)callout1(*cinstat, bdev)) {
        !          3476: 
        !          3477:                        if (t)
        !          3478: 
        !          3479:                                sleep(IO_Q, (long)t);
        !          3480: 
        !          3481:                        else
        !          3482: 
        !          3483:                                nap(60);
        !          3484: 
        !          3485:                }
        !          3486: 
        !          3487:        }
        !          3488: 
        !          3489: 
        !          3490: 
        !          3491:        if (t && (t->tty->state & TS_BLIND))
        !          3492: 
        !          3493:                /* line disconnected... */
        !          3494: 
        !          3495:                return 0;
        !          3496: 
        !          3497: 
        !          3498: 
        !          3499:        head = ior->head;
        !          3500: 
        !          3501:        if (0 == (left = ((unsigned long) ior->tail) - head)) {
        !          3502: 
        !          3503:                /* if the buffer is still empty we're finished... */
        !          3504: 
        !          3505:                return 0;
        !          3506: 
        !          3507:        }
        !          3508: 
        !          3509: 
        !          3510: 
        !          3511:        /* now copy the data out of the buffer */
        !          3512: 
        !          3513:        bsize = ior->buflen;
        !          3514: 
        !          3515:        if (left < 0)
        !          3516: 
        !          3517:                left += bsize;
        !          3518: 
        !          3519:        wrap = bsize - head;
        !          3520: 
        !          3521: 
        !          3522: 
        !          3523:        /* if we should flush input pretend we want to read it all */
        !          3524: 
        !          3525:        if (!buf && !bytes)
        !          3526: 
        !          3527:                bytes = left;
        !          3528: 
        !          3529: 
        !          3530: 
        !          3531:        if (left > bytes)
        !          3532: 
        !          3533:                left = bytes;
        !          3534: 
        !          3535: 
        !          3536: 
        !          3537:        /* if its just a few then do it here... */
        !          3538: 
        !          3539:        if (buf && left <= 5) {
        !          3540: 
        !          3541:                char *q = ior->bufaddr + head;
        !          3542: 
        !          3543: 
        !          3544: 
        !          3545:                /* the --left in the while() makes us get one char less
        !          3546: 
        !          3547:                   because we want to get the last one thru the driver
        !          3548: 
        !          3549:                   so that it gets a chance to raise RTS or send XON... */
        !          3550: 
        !          3551:                p = buf;
        !          3552: 
        !          3553:                while (--left) {
        !          3554: 
        !          3555:                        if (!--wrap)
        !          3556: 
        !          3557:                                q -= bsize;
        !          3558: 
        !          3559:                        *p++ = *++q;
        !          3560: 
        !          3561:                }
        !          3562: 
        !          3563:                ior->head = q - ior->bufaddr;
        !          3564: 
        !          3565: 
        !          3566: 
        !          3567:        /* else memcpy is faster. */
        !          3568: 
        !          3569:        } else {
        !          3570: 
        !          3571:                /* --wrap and head+1 because head is `inc before access' */
        !          3572: 
        !          3573:                if (--wrap < --left) {
        !          3574: 
        !          3575:                        if (buf) {
        !          3576: 
        !          3577:                                memcpy (buf, ior->bufaddr + head + 1, wrap);
        !          3578: 
        !          3579:                                memcpy (buf + wrap, ior->bufaddr, left - wrap);
        !          3580: 
        !          3581:                        }
        !          3582: 
        !          3583:                        ior->head = left - wrap - 1;
        !          3584: 
        !          3585:                } else {
        !          3586: 
        !          3587:                        if (buf)
        !          3588: 
        !          3589:                                memcpy (buf, ior->bufaddr + head + 1, left);
        !          3590: 
        !          3591:                        ior->head = head + left;
        !          3592: 
        !          3593:                }
        !          3594: 
        !          3595:                /* p points to last char */
        !          3596: 
        !          3597:                p = buf + left;
        !          3598: 
        !          3599:        }
        !          3600: 
        !          3601: 
        !          3602: 
        !          3603:        {
        !          3604: 
        !          3605:                short sr = spl7();
        !          3606: 
        !          3607: 
        !          3608: 
        !          3609:                /* xconin[] are always blocking, and we don't want to
        !          3610: 
        !          3611:                   hang at ipl7 even if something impossible like a
        !          3612: 
        !          3613:                   `magically' empty buffer happens.  so check again. */
        !          3614: 
        !          3615:                if (ior->tail != ior->head)
        !          3616: 
        !          3617:                        if (buf)
        !          3618: 
        !          3619:                                *p++ = callout1(*cin, bdev);
        !          3620: 
        !          3621:                        else
        !          3622: 
        !          3623:                                (void) callout1(*cin, bdev);
        !          3624: 
        !          3625:                spl(sr);
        !          3626: 
        !          3627:                if (b) {
        !          3628: 
        !          3629:                        b->xattr.atime = timestamp;
        !          3630: 
        !          3631:                        b->xattr.adate = datestamp;
        !          3632: 
        !          3633:                }
        !          3634: 
        !          3635:        }
        !          3636: 
        !          3637:        if (!buf)
        !          3638: 
        !          3639:                return 0;
        !          3640: 
        !          3641:        return p - buf;
        !          3642: 
        !          3643: }
        !          3644: 
        !          3645: 
        !          3646: 
        !          3647: /*
        !          3648: 
        !          3649:  * read/write routines for BIOS devices that aren't terminals (like the
        !          3650: 
        !          3651:  * printer & IKBD devices)
        !          3652: 
        !          3653:  */
        !          3654: 
        !          3655: 
        !          3656: 
        !          3657: static long ARGS_ON_STACK 
        !          3658: 
        !          3659: bios_nwrite(f, buf, bytes)
        !          3660: 
        !          3661:        FILEPTR *f; const char *buf; long bytes;
        !          3662: 
        !          3663: {
        !          3664: 
        !          3665:        long ret = 0;
        !          3666: 
        !          3667:        int bdev = f->fc.aux;
        !          3668: 
        !          3669:        int c;
        !          3670: 
        !          3671:        struct bios_file *b = (struct bios_file *)f->fc.index;
        !          3672: 
        !          3673: 
        !          3674: 
        !          3675:        while (bytes > 0) {
        !          3676: 
        !          3677:                if ( (f->flags & O_NDELAY) && !bcostat(bdev) )
        !          3678: 
        !          3679:                        break;
        !          3680: 
        !          3681: 
        !          3682: 
        !          3683:                c = *buf++ & 0x00ff;
        !          3684: 
        !          3685: 
        !          3686: 
        !          3687:                if (bconout(bdev, c) == 0)
        !          3688: 
        !          3689:                        break;
        !          3690: 
        !          3691: 
        !          3692: 
        !          3693:                bytes--; ret++;
        !          3694: 
        !          3695:        }
        !          3696: 
        !          3697:        if (ret > 0) {
        !          3698: 
        !          3699:                b->xattr.mtime = b->xattr.atime = timestamp;
        !          3700: 
        !          3701:                b->xattr.mdate = b->xattr.adate = datestamp;
        !          3702: 
        !          3703:        }
        !          3704: 
        !          3705:        return ret;
        !          3706: 
        !          3707: }
        !          3708: 
        !          3709: 
        !          3710: 
        !          3711: static long ARGS_ON_STACK 
        !          3712: 
        !          3713: bios_nread(f, buf, bytes)
        !          3714: 
        !          3715:        FILEPTR *f; char *buf; long bytes;
        !          3716: 
        !          3717: {
        !          3718: 
        !          3719:        long ret = 0;
        !          3720: 
        !          3721:        int bdev = f->fc.aux;
        !          3722: 
        !          3723:        struct bios_file *b = (struct bios_file *)f->fc.index;
        !          3724: 
        !          3725: 
        !          3726: 
        !          3727:        while (bytes > 0) {
        !          3728: 
        !          3729:                if ( (f->flags & O_NDELAY) && !bconstat(bdev) )
        !          3730: 
        !          3731:                        break;
        !          3732: 
        !          3733:                *buf++ = bconin(bdev) & 0xff;
        !          3734: 
        !          3735:                bytes--; ret++;
        !          3736: 
        !          3737:        }
        !          3738: 
        !          3739:        if (ret > 0) {
        !          3740: 
        !          3741:                b->xattr.atime = timestamp;
        !          3742: 
        !          3743:                b->xattr.adate = datestamp;
        !          3744: 
        !          3745:        }
        !          3746: 
        !          3747:        return ret;
        !          3748: 
        !          3749: }
        !          3750: 
        !          3751: 
        !          3752: 
        !          3753: /*
        !          3754: 
        !          3755:  * BIOS terminal seek code -- this has to match the documented
        !          3756: 
        !          3757:  * way to do isatty()
        !          3758: 
        !          3759:  */
        !          3760: 
        !          3761: 
        !          3762: 
        !          3763: static long ARGS_ON_STACK 
        !          3764: 
        !          3765: bios_tseek(f, where, whence)
        !          3766: 
        !          3767:        FILEPTR *f;
        !          3768: 
        !          3769:        long where;
        !          3770: 
        !          3771:        int whence;
        !          3772: 
        !          3773: {
        !          3774: 
        !          3775:        UNUSED(f); UNUSED(where);
        !          3776: 
        !          3777:        UNUSED(whence);
        !          3778: 
        !          3779: /* terminals always are at position 0 */
        !          3780: 
        !          3781:        return 0;
        !          3782: 
        !          3783: }
        !          3784: 
        !          3785: 
        !          3786: 
        !          3787: /*
        !          3788: 
        !          3789:  * ioctl TIOC[CS]BRK, checkbtty calls it without a FILEPTR
        !          3790: 
        !          3791:  */
        !          3792: 
        !          3793: 
        !          3794: 
        !          3795: long
        !          3796: 
        !          3797: iocsbrk (bdev, mode, t)
        !          3798: 
        !          3799:        int bdev, mode;
        !          3800: 
        !          3801:        struct bios_tty *t;
        !          3802: 
        !          3803: {
        !          3804: 
        !          3805:        unsigned long bits;
        !          3806: 
        !          3807:        int oldmap = curproc->bconmap;
        !          3808: 
        !          3809: 
        !          3810: 
        !          3811:        if (has_bconmap) {
        !          3812: 
        !          3813: /* YABB (Yet Another BIOS Bug):
        !          3814: 
        !          3815:  * SCC Rsconf looks for the break bit in the wrong place...  if this
        !          3816: 
        !          3817:  * dev's Rsconf is in ROM do it ourselves, otherwise assume the user
        !          3818: 
        !          3819:  * has installed a fix.
        !          3820: 
        !          3821:  */
        !          3822: 
        !          3823:                if (t && (bdev == 7 || t->tty == &scca_tty) &&
        !          3824: 
        !          3825:                    MAPTAB[bdev-6].rsconf > 0xe00000L &&
        !          3826: 
        !          3827:                    MAPTAB[bdev-6].rsconf < 0xefffffL) {
        !          3828: 
        !          3829:                        scc_set5 ((volatile char *) (bdev == 7 ?
        !          3830: 
        !          3831:                                    0xffff8c85L : 0xffff8c81L),
        !          3832: 
        !          3833:                                  (mode == TIOCSBRK), (1 << 4), t->irec);
        !          3834: 
        !          3835:                        return 0;
        !          3836: 
        !          3837:                }
        !          3838: 
        !          3839:                if (bdev >= 6)
        !          3840: 
        !          3841:                        curproc->bconmap = bdev;
        !          3842: 
        !          3843:        }
        !          3844: 
        !          3845:        bits = rsconf(-1, -1, -1, -1, -1, -1);  /* get settings */
        !          3846: 
        !          3847:        bits = (bits >> 8) & 0x0ff;             /* isolate TSR byte */
        !          3848: 
        !          3849:        if (mode == TIOCCBRK)
        !          3850: 
        !          3851:                bits &= ~8;
        !          3852: 
        !          3853:        else
        !          3854: 
        !          3855:                bits |= 8;
        !          3856: 
        !          3857:        (void)rsconf(-1, -1, -1, -1, (int)bits, -1);
        !          3858: 
        !          3859:        curproc->bconmap = oldmap;
        !          3860: 
        !          3861:        return 0;
        !          3862: 
        !          3863: }
        !          3864: 
        !          3865: 
        !          3866: 
        !          3867: /*
        !          3868: 
        !          3869:  * ioctl TIOCSFLAGSB, combined TIOC[GS]FLAGS with bitmask to leave
        !          3870: 
        !          3871:  * parts of flags alone...
        !          3872: 
        !          3873:  */
        !          3874: 
        !          3875: 
        !          3876: 
        !          3877: INLINE static long
        !          3878: 
        !          3879: iocsflagsb (bdev, flags, mask, tty, t)
        !          3880: 
        !          3881:        int bdev;
        !          3882: 
        !          3883:        unsigned long flags;    /* new flags, hi bit set == read only */
        !          3884: 
        !          3885:        unsigned long mask;     /* what flags to change/read */
        !          3886: 
        !          3887:        struct tty *tty;
        !          3888: 
        !          3889:        struct bios_tty *t;
        !          3890: 
        !          3891: {
        !          3892: 
        !          3893:        unsigned long oflags;
        !          3894: 
        !          3895:        unsigned short *sgflags;
        !          3896: 
        !          3897:        unsigned long bits;
        !          3898: 
        !          3899:        unsigned char ucr, oucr;
        !          3900: 
        !          3901:        short flow;
        !          3902: 
        !          3903: 
        !          3904: 
        !          3905:        sgflags = &tty->sg.sg_flags;
        !          3906: 
        !          3907:        if (t)
        !          3908: 
        !          3909:                oflags = (((char *) t->irec)[0x20] << 12) & (T_TANDEM|T_RTSCTS);
        !          3910: 
        !          3911:        else
        !          3912: 
        !          3913:                oflags = *sgflags & (T_TANDEM|T_RTSCTS);
        !          3914: 
        !          3915:        if ((long)flags >= 0)
        !          3916: 
        !          3917:                /* clear unused bits */
        !          3918: 
        !          3919:                flags &= (TF_STOPBITS|TF_CHARBITS|TF_BRKINT|TF_CAR|
        !          3920: 
        !          3921:                        T_RTSCTS|T_TANDEM|T_EVENP|T_ODDP);
        !          3922: 
        !          3923:        if (t && (mask & (TF_BRKINT|TF_CAR))) {
        !          3924: 
        !          3925:                if (t->brkint)
        !          3926: 
        !          3927:                        oflags |= TF_BRKINT;
        !          3928: 
        !          3929:                if (!t->clocal)
        !          3930: 
        !          3931:                        oflags |= TF_CAR;
        !          3932: 
        !          3933:                if ((long)flags >= 0) {
        !          3934: 
        !          3935:                        if (mask & TF_CAR) {
        !          3936: 
        !          3937:                                t->clocal = !(flags & TF_CAR);
        !          3938: 
        !          3939: /* update TS_BLIND without signalling */
        !          3940: 
        !          3941:                                checkbtty_nsig (t);
        !          3942: 
        !          3943:                                if ((bdev == 7 || tty == &scca_tty) &&
        !          3944: 
        !          3945:                                    !(mask & (T_RTSCTS|T_TANDEM))) {
        !          3946: 
        !          3947: /* force rsconf be called so it can adjust w3 bit 5 (see xbios.c) */
        !          3948: 
        !          3949:                                        mask |= (T_RTSCTS|T_TANDEM);
        !          3950: 
        !          3951:                                        flags = (flags & ~(T_RTSCTS|T_TANDEM)) |
        !          3952: 
        !          3953:                                                (oflags & (T_RTSCTS|T_TANDEM));
        !          3954: 
        !          3955:                                }
        !          3956: 
        !          3957:                        } else {
        !          3958: 
        !          3959:                                flags = (flags & ~TF_CAR) |
        !          3960: 
        !          3961:                                        (oflags & TF_CAR);
        !          3962: 
        !          3963:                        }
        !          3964: 
        !          3965:                        if (mask & TF_BRKINT) {
        !          3966: 
        !          3967:                                t->brkint = flags & TF_BRKINT;
        !          3968: 
        !          3969:                        } else {
        !          3970: 
        !          3971:                                flags = (flags & ~TF_BRKINT) |
        !          3972: 
        !          3973:                                        (oflags & TF_BRKINT);
        !          3974: 
        !          3975:                        }
        !          3976: 
        !          3977:                }
        !          3978: 
        !          3979:        } else {
        !          3980: 
        !          3981:                flags &= ~(TF_BRKINT|TF_CAR);
        !          3982: 
        !          3983:        }
        !          3984: 
        !          3985:        if (mask & (TF_FLAGS|TF_STOPBITS|TF_CHARBITS)) {
        !          3986: 
        !          3987:                int oldmap = curproc->bconmap;
        !          3988: 
        !          3989: 
        !          3990: 
        !          3991:                if (has_bconmap && bdev >= 6)
        !          3992: 
        !          3993:                        curproc->bconmap = bdev;
        !          3994: 
        !          3995:                bits = rsconf(-1, -1, -1, -1, -1, -1);  /* get settings */
        !          3996: 
        !          3997:                oucr = ucr = (bits >> 24L) & 0x0ff;     /* isolate UCR byte */
        !          3998: 
        !          3999:                oflags |= (ucr >> 3) & (TF_STOPBITS|TF_CHARBITS);
        !          4000: 
        !          4001:                if (ucr & 0x4) {                        /* parity on? */
        !          4002: 
        !          4003:                        oflags |= (ucr & 0x2) ? T_EVENP : T_ODDP;
        !          4004: 
        !          4005:                }
        !          4006: 
        !          4007:                if ((long)flags >= 0) {
        !          4008: 
        !          4009:                        if ((mask & (T_RTSCTS|T_TANDEM)) == (T_RTSCTS|T_TANDEM)) {
        !          4010: 
        !          4011:                                flow = (flags & (T_RTSCTS|T_TANDEM)) >> 12L;
        !          4012: 
        !          4013:                        } else {
        !          4014: 
        !          4015:                                flow = -1;
        !          4016: 
        !          4017:                                flags = (flags & ~(T_RTSCTS|T_TANDEM)) |
        !          4018: 
        !          4019:                                        (oflags & (T_RTSCTS|T_TANDEM));
        !          4020: 
        !          4021:                        }
        !          4022: 
        !          4023:                        if ((mask & (T_EVENP|T_ODDP)) == (T_EVENP|T_ODDP)) {
        !          4024: 
        !          4025:                                if (flags & T_EVENP) {
        !          4026: 
        !          4027:                                        ucr |= 0x6;
        !          4028: 
        !          4029:                                        flags &= ~T_ODDP;
        !          4030: 
        !          4031:                                } else if (flags & T_ODDP) {
        !          4032: 
        !          4033:                                        ucr &= ~2;
        !          4034: 
        !          4035:                                        ucr |= 0x4;
        !          4036: 
        !          4037:                                } else {
        !          4038: 
        !          4039:                                        ucr &= ~6;
        !          4040: 
        !          4041:                                }
        !          4042: 
        !          4043:                        } else {
        !          4044: 
        !          4045:                                flags = (flags & ~(T_EVENP|T_ODDP)) |
        !          4046: 
        !          4047:                                        (oflags & (T_EVENP|T_ODDP));
        !          4048: 
        !          4049:                        }
        !          4050: 
        !          4051:                        if ((mask & TF_STOPBITS) == TF_STOPBITS &&
        !          4052: 
        !          4053:                            (flags & TF_STOPBITS)) {
        !          4054: 
        !          4055:                                ucr &= ~(0x18);
        !          4056: 
        !          4057:                                ucr |= (flags & TF_STOPBITS) << 3;
        !          4058: 
        !          4059:                        } else {
        !          4060: 
        !          4061:                                flags = (flags & ~TF_STOPBITS) |
        !          4062: 
        !          4063:                                        (oflags & TF_STOPBITS);
        !          4064: 
        !          4065:                        }
        !          4066: 
        !          4067:                        if ((mask & TF_CHARBITS) == TF_CHARBITS) {
        !          4068: 
        !          4069:                                ucr &= ~(0x60);
        !          4070: 
        !          4071:                                ucr |= (flags & TF_CHARBITS) << 3;
        !          4072: 
        !          4073:                        } else {
        !          4074: 
        !          4075:                                flags = (flags & ~TF_CHARBITS) |
        !          4076: 
        !          4077:                                        (oflags & TF_CHARBITS);
        !          4078: 
        !          4079:                        }
        !          4080: 
        !          4081:                        if (ucr != oucr)
        !          4082: 
        !          4083:                                rsconf(-1, flow, ucr, -1, -1, -1);
        !          4084: 
        !          4085:                        else if (flow >= 0)
        !          4086: 
        !          4087:                                rsconf(-1, flow, -1, -1, -1, -1);
        !          4088: 
        !          4089:                        if (flow >= 0) {
        !          4090: 
        !          4091:                                if (t)
        !          4092: 
        !          4093:                                        flags = (flags & ~(T_RTSCTS|T_TANDEM)) |
1.1       root     4094: 
1.1.1.6 ! root     4095:                                                ((((char *) t->irec)[0x20] << 12) &
1.1       root     4096: 
1.1.1.6 ! root     4097:                                                 (T_RTSCTS|T_TANDEM));
1.1       root     4098: 
1.1.1.6 ! root     4099:                                *sgflags &= ~(T_RTSCTS|T_TANDEM);
1.1       root     4100: 
1.1.1.6 ! root     4101:                                *sgflags |= flags & (T_RTSCTS|T_TANDEM);
1.1       root     4102: 
1.1.1.6 ! root     4103:                        }
1.1       root     4104: 
1.1.1.6 ! root     4105:                }
1.1.1.2   root     4106: 
1.1.1.6 ! root     4107:                curproc->bconmap = oldmap;
1.1       root     4108: 
1.1.1.6 ! root     4109:        }
1.1       root     4110: 
1.1.1.6 ! root     4111:        return (long)flags >= 0 ? flags : oflags;
1.1       root     4112: 
1.1.1.6 ! root     4113: }
1.1       root     4114: 
                   4115: 
                   4116: 
1.1.1.2   root     4117: static long ARGS_ON_STACK 
1.1       root     4118: 
                   4119: bios_ioctl(f, mode, buf)
                   4120: 
                   4121:        FILEPTR *f; int mode; void *buf;
                   4122: 
                   4123: {
                   4124: 
                   4125:        long *r = (long *)buf;
                   4126: 
                   4127:        struct winsize *ws;
                   4128: 
                   4129:        char *aline;
                   4130: 
                   4131:        short dev;
                   4132: 
                   4133:        int i;
                   4134: 
1.1.1.5   root     4135:        struct bios_file *b;
                   4136: 
1.1.1.6 ! root     4137:        struct bios_tty *t = BTTY(f);
1.1       root     4138: 
                   4139: 
                   4140: 
1.1.1.6 ! root     4141:        switch(mode) {
        !          4142: 
        !          4143:        case FIONREAD:
        !          4144: 
        !          4145:                if (t)
        !          4146: 
        !          4147:                        *r = btty_ionread(t);
        !          4148: 
        !          4149:                else if (f->fc.aux == 3)
        !          4150: 
        !          4151:                        *r = ionread(midi_btty.irec);
        !          4152: 
        !          4153:                else if (bconstat(f->fc.aux))
1.1       root     4154: 
                   4155:                        *r = 1;
                   4156: 
                   4157:                else
                   4158: 
                   4159:                        *r = 0;
                   4160: 
1.1.1.6 ! root     4161:                break;
1.1       root     4162: 
1.1.1.6 ! root     4163:        case FIONWRITE:
1.1       root     4164: 
1.1.1.6 ! root     4165:                if (t)
        !          4166: 
        !          4167:                        *r = ionwrite (t->orec);
        !          4168: 
        !          4169:                else if (bcostat(f->fc.aux))
1.1       root     4170: 
                   4171:                        *r = 1;
                   4172: 
                   4173:                else
                   4174: 
                   4175:                        *r = 0;
                   4176: 
1.1.1.6 ! root     4177:                break;
1.1       root     4178: 
1.1.1.6 ! root     4179:        case FIOEXCEPT:
1.1       root     4180: 
1.1.1.6 ! root     4181:                *r = 0;
        !          4182: 
        !          4183:                break;
        !          4184: 
        !          4185:        case TIOCFLUSH:
        !          4186: 
        !          4187:            {
1.1.1.5   root     4188: 
                   4189:                IOREC_T *ior;
                   4190: 
                   4191:                int flushtype;
                   4192: 
                   4193:                short sr;
                   4194: 
                   4195: 
                   4196: 
                   4197:                dev = f->fc.aux;
                   4198: 
                   4199: 
                   4200: 
                   4201:                if ((!r) || (!(*r & 3))) {
                   4202: 
                   4203:                        flushtype = 3;
                   4204: 
                   4205:                } else {
                   4206: 
                   4207:                        flushtype = (int) *r;
                   4208: 
                   4209:                }
                   4210: 
                   4211:                if (dev == 1 || dev >= 6) {
                   4212: 
1.1.1.6 ! root     4213:                        b = (struct bios_file *)f->fc.index;
1.1.1.5   root     4214: 
1.1.1.6 ! root     4215:                        if (t)
1.1.1.5   root     4216: 
1.1.1.6 ! root     4217:                                ior = t->irec;
1.1.1.5   root     4218: 
1.1.1.6 ! root     4219:                        else
1.1.1.5   root     4220: 
1.1.1.6 ! root     4221:                                ior = (IOREC_T *) uiorec(0);
1.1.1.5   root     4222: 
1.1.1.6 ! root     4223:        /* just resetting iorec pointers here can hang a flow controlled port,
1.1.1.5   root     4224: 
1.1.1.6 ! root     4225:         * iread can do better...
1.1.1.5   root     4226: 
1.1.1.6 ! root     4227:         */
        !          4228: 
        !          4229:                        if ((flushtype & 1) &&
        !          4230: 
        !          4231:                            iread (dev, (char *) NULL, 0, 1, b) == EUNDEV) {
1.1.1.5   root     4232: 
                   4233:                                sr = spl7();
                   4234: 
                   4235:                                ior->head = ior->tail = 0;
                   4236: 
                   4237:                                spl(sr);
                   4238: 
                   4239:                        }
                   4240: 
1.1.1.6 ! root     4241:        /* sender should be ok but iwrite also sets the dev's ctime */
        !          4242: 
        !          4243:                        if ((flushtype & 2) &&
        !          4244: 
        !          4245:                            iwrite (dev, (char *) NULL, 0, 1, b) == EUNDEV) {
1.1.1.5   root     4246: 
                   4247:                                ior++; /* output record */
                   4248: 
                   4249:                                sr = spl7();
                   4250: 
                   4251:                                ior->head = ior->tail = 0;
                   4252: 
                   4253:                                spl(sr);
                   4254: 
                   4255:                        }
                   4256: 
                   4257:                } else if (dev == 3 || dev == 2 || dev == 5) {
                   4258: 
                   4259:                        if (dev == 3) {
                   4260: 
                   4261:                                /* midi */
                   4262: 
1.1.1.6 ! root     4263:                                ior = midi_btty.irec;
1.1.1.5   root     4264: 
                   4265:                        } else {
                   4266: 
                   4267:                                /* ikbd */
                   4268: 
                   4269:                                ior = (IOREC_T *) uiorec(1);
                   4270: 
                   4271:                        }
                   4272: 
                   4273:                        if (flushtype & 1) {
                   4274: 
                   4275:                                sr = spl7();
                   4276: 
                   4277:                                ior->head = ior->tail = 0;
                   4278: 
                   4279:                                spl(sr);
                   4280: 
                   4281:                        }
                   4282: 
                   4283:                }
                   4284: 
                   4285:                return 0;
                   4286: 
1.1.1.6 ! root     4287:            }
1.1.1.5   root     4288: 
1.1.1.6 ! root     4289: #if 1
1.1.1.5   root     4290: 
1.1.1.6 ! root     4291: #ifndef TIONOTSEND
        !          4292: 
        !          4293: #define TIONOTSEND (('T'<<8) | 134)
        !          4294: 
        !          4295: #endif
        !          4296: 
        !          4297:        case TIONOTSEND:
        !          4298: 
        !          4299: #endif
        !          4300: 
        !          4301:        case TIOCOUTQ:
        !          4302: 
        !          4303:            {
1.1.1.5   root     4304: 
                   4305:                IOREC_T *ior;
                   4306: 
                   4307: 
                   4308: 
                   4309:                dev = f->fc.aux;
                   4310: 
                   4311: 
                   4312: 
                   4313:                if (dev == 1 || dev >= 6) {
                   4314: 
1.1.1.6 ! root     4315:                        long ret;
1.1.1.5   root     4316: 
1.1.1.6 ! root     4317: #ifdef TIONOTSEND
1.1.1.5   root     4318: 
1.1.1.6 ! root     4319: /* try trap #1 first, to know about the last char too :) */
1.1.1.5   root     4320: 
1.1.1.6 ! root     4321:                        if (t &&
1.1.1.5   root     4322: 
1.1.1.6 ! root     4323:                            (ret = rsvf_ioctl (t->tosfd, r, TIONOTSEND)) != EINVFN)
1.1.1.5   root     4324: 
1.1.1.6 ! root     4325:                                return ret;
1.1.1.5   root     4326: 
1.1.1.6 ! root     4327: #endif
        !          4328: 
        !          4329:                        if (t)
        !          4330: 
        !          4331:                                ior = t->orec;
        !          4332: 
        !          4333:                        else
        !          4334: 
        !          4335:                                ior = (IOREC_T *) uiorec(0) + 1;
1.1.1.5   root     4336: 
                   4337:                        *r = ior->tail - ior->head;
                   4338: 
                   4339:                        if (*r < 0)
                   4340: 
                   4341:                                *r += ior->buflen;
                   4342: 
                   4343:                }
                   4344: 
                   4345:                else
                   4346: 
                   4347:                        *r = 0;
1.1       root     4348: 
1.1.1.6 ! root     4349:                break;
1.1       root     4350: 
1.1.1.6 ! root     4351:            }
1.1       root     4352: 
1.1.1.6 ! root     4353:        case TIOCGWINSZ:
1.1       root     4354: 
1.1.1.6 ! root     4355:                if (f->fc.aux == 2) {
        !          4356: 
        !          4357:                        aline = lineA0();
        !          4358: 
        !          4359:                        ws = (struct winsize *)buf;
        !          4360: 
        !          4361:                        ws->ws_row = *((short *)(aline - 42)) + 1;
        !          4362: 
        !          4363:                        ws->ws_col = *((short *)(aline - 44)) + 1;
        !          4364: 
        !          4365:                } else {
        !          4366: 
        !          4367:                        return EINVFN;
        !          4368: 
        !          4369:                }
1.1       root     4370: 
1.1.1.6 ! root     4371:                break;
1.1       root     4372: 
1.1.1.6 ! root     4373:        case TIOCIBAUD:
1.1       root     4374: 
1.1.1.6 ! root     4375:        case TIOCOBAUD:
1.1       root     4376: 
1.1.1.6 ! root     4377:            {
1.1       root     4378: 
                   4379:                long oldbaud, newbaud;
                   4380: 
1.1.1.4   root     4381:                int oldmap;
                   4382: 
                   4383: 
                   4384: 
1.1       root     4385:                dev = f->fc.aux;
                   4386: 
                   4387: 
                   4388: 
                   4389:                newbaud = *r;
                   4390: 
                   4391:                if (dev == 1 || dev >= 6) {
                   4392: 
1.1.1.6 ! root     4393: /* can we pass it to trap #1 and set speeds rsconf doesn't know about? */
        !          4394: 
        !          4395:                        if (t &&
        !          4396: 
        !          4397:                            (oldbaud = rsvf_ioctl (t->tosfd, r, mode)) != EINVFN) {
        !          4398: 
        !          4399: /* looks good...  save result and return */
        !          4400: 
        !          4401:                                if (newbaud < 0)
        !          4402: 
        !          4403:                                        newbaud = *r;
        !          4404: 
        !          4405:                                if (newbaud && !oldbaud) {
        !          4406: 
        !          4407:                                        if (mode == TIOCIBAUD)
        !          4408: 
        !          4409:                                                t->ispeed = newbaud;
        !          4410: 
        !          4411:                                        else
        !          4412: 
        !          4413:                                                t->ospeed = newbaud;
        !          4414: 
        !          4415:                                }
        !          4416: 
        !          4417:                                t->vticks = 0;
        !          4418: 
        !          4419:                                return oldbaud;
        !          4420: 
        !          4421:                        }
        !          4422: 
1.1.1.4   root     4423: /* trick rsconf into setting the correct port (it uses curproc->bconmap) */
                   4424: 
                   4425:                        oldmap = curproc->bconmap;
                   4426: 
1.1.1.6 ! root     4427:                        if (has_bconmap && dev >= 6)
1.1       root     4428: 
1.1.1.6 ! root     4429:                                curproc->bconmap = dev;
1.1       root     4430: 
1.1.1.2   root     4431:                        i = (int)rsconf(-2, -1, -1, -1, -1, -1);
1.1       root     4432: 
1.1.1.4   root     4433: 
                   4434: 
1.1       root     4435:                        if (i < 0 || i >= MAXBAUD)
                   4436: 
                   4437:                                oldbaud = -1L;
                   4438: 
                   4439:                        else
                   4440: 
                   4441:                                oldbaud = baudmap[i];
                   4442: 
                   4443:                        *r = oldbaud;
                   4444: 
1.1.1.5   root     4445:                        if (newbaud > 0) {
1.1       root     4446: 
1.1.1.6 ! root     4447:        /* assert DTR works only on modem1 and SCC lines */
1.1.1.2   root     4448: 
                   4449:                                if (dev == 1 || dev == 6) {
                   4450: 
                   4451:                                        Offgibit(0xef);
                   4452: 
1.1.1.6 ! root     4453:                                } else if (t && (dev == 7 ||
        !          4454: 
        !          4455:                                           ((struct tty *)f->devinfo) == &scca_tty)) {
        !          4456: 
        !          4457:                                        scc_set5 ((volatile char *) (dev == 7 ?
        !          4458: 
        !          4459:                                                    0xffff8c85L : 0xffff8c81L),
        !          4460: 
        !          4461:                                                  1, (1 << 7), t->irec);
        !          4462: 
1.1.1.2   root     4463:                                }
                   4464: 
1.1.1.6 ! root     4465:                                if (newbaud == oldbaud ||
        !          4466: 
        !          4467:                                    ((struct tty *)f->devinfo)->hup_ospeed) {
1.1.1.5   root     4468: 
                   4469:                                        curproc->bconmap = oldmap;
                   4470: 
                   4471:                                        return 0;
                   4472: 
                   4473:                                }
                   4474: 
1.1       root     4475:                                for (i = 0; i < MAXBAUD; i++) {
                   4476: 
                   4477:                                        if (baudmap[i] == newbaud) {
                   4478: 
                   4479:                                                rsconf(i, -1, -1, -1, -1, -1);
                   4480: 
1.1.1.4   root     4481:                                                curproc->bconmap = oldmap;
                   4482: 
1.1       root     4483:                                                return 0;
                   4484: 
1.1.1.2   root     4485:                                        } else if (baudmap[i] < newbaud) {
                   4486: 
                   4487:                                                *r = baudmap[i];
                   4488: 
                   4489:                                                break;
                   4490: 
1.1       root     4491:                                        }
                   4492: 
                   4493:                                }
                   4494: 
1.1.1.4   root     4495:                                curproc->bconmap = oldmap;
                   4496: 
1.1       root     4497:                                return ERANGE;
                   4498: 
                   4499:                        } else if (newbaud == 0L) {
                   4500: 
1.1.1.6 ! root     4501:        /* drop DTR: works only on modem1 and SCC lines */
1.1       root     4502: 
                   4503:                                if (dev == 1 || dev == 6) {
                   4504: 
                   4505:                                        Ongibit(0x10);
                   4506: 
1.1.1.6 ! root     4507:                                } else if (t && (dev == 7 ||
        !          4508: 
        !          4509:                                           ((struct tty *)f->devinfo) == &scca_tty)) {
        !          4510: 
        !          4511:                                        scc_set5 ((volatile char *) (dev == 7 ?
        !          4512: 
        !          4513:                                                    0xffff8c85L : 0xffff8c81L),
        !          4514: 
        !          4515:                                                  0, (1 << 7), t->irec);
        !          4516: 
1.1       root     4517:                                }
                   4518: 
                   4519:                        }
                   4520: 
1.1.1.4   root     4521:                        curproc->bconmap = oldmap;
                   4522: 
1.1       root     4523:                        return 0;
                   4524: 
                   4525:                } else if (dev == 2 || dev == 5) {
                   4526: 
                   4527:                        /* screen: assume 9600 baud */
                   4528: 
                   4529:                        oldbaud = 9600L;
                   4530: 
                   4531:                } else if (dev == 3) {
                   4532: 
                   4533:                        /* midi */
                   4534: 
                   4535:                        oldbaud = 31250L;
                   4536: 
                   4537:                } else {
                   4538: 
                   4539:                        oldbaud = -1L;  /* unknown speed */
                   4540: 
                   4541:                }
                   4542: 
                   4543:                *r = oldbaud;
                   4544: 
                   4545:                if (newbaud > 0 && newbaud != oldbaud)
                   4546: 
                   4547:                        return ERANGE;
                   4548: 
1.1.1.6 ! root     4549:                break;
1.1       root     4550: 
1.1.1.6 ! root     4551:            }
1.1       root     4552: 
1.1.1.6 ! root     4553:        case TIOCCBRK:
1.1       root     4554: 
1.1.1.6 ! root     4555:        case TIOCSBRK:
1.1       root     4556: 
                   4557:                dev = f->fc.aux;
                   4558: 
1.1.1.6 ! root     4559:                if (dev != 1 && dev < 6)
1.1       root     4560: 
                   4561:                        return EINVFN;
                   4562: 
1.1.1.6 ! root     4563:                return iocsbrk (dev, mode, t);
1.1       root     4564: 
1.1.1.6 ! root     4565:        case TIOCSFLAGSB:
1.1       root     4566: 
1.1.1.6 ! root     4567:                dev = f->fc.aux;
1.1       root     4568: 
1.1.1.6 ! root     4569:                if (dev != 1 && dev < 6)
1.1       root     4570: 
1.1.1.6 ! root     4571:                        return EINVFN;
1.1       root     4572: 
1.1.1.6 ! root     4573:                *((long *)buf) = iocsflagsb (dev, ((long *)buf)[0], ((long *)buf)[1],
1.1       root     4574: 
1.1.1.6 ! root     4575:                                        (struct tty *)f->devinfo, t);
1.1       root     4576: 
1.1.1.6 ! root     4577:                break;
1.1       root     4578: 
1.1.1.6 ! root     4579:        case TIOCGVMIN:
1.1       root     4580: 
1.1.1.6 ! root     4581:        case TIOCSVMIN:
1.1       root     4582: 
1.1.1.6 ! root     4583:            {
1.1       root     4584: 
1.1.1.6 ! root     4585:                unsigned short *v = buf;
1.1       root     4586: 
1.1.1.6 ! root     4587:                struct tty *tty = (struct tty *)f->devinfo;
1.1       root     4588: 
                   4589: 
                   4590: 
1.1.1.6 ! root     4591:                if (f->fc.aux == 3)
1.1       root     4592: 
1.1.1.6 ! root     4593:                        t = &midi_btty;
1.1       root     4594: 
1.1.1.6 ! root     4595:                if (!tty || !t)
1.1       root     4596: 
1.1.1.6 ! root     4597:                        return EINVFN;
1.1       root     4598: 
1.1.1.6 ! root     4599:                if (mode == TIOCGVMIN) {
1.1       root     4600: 
1.1.1.6 ! root     4601:                        v[0] = tty->vmin;
1.1       root     4602: 
1.1.1.6 ! root     4603:                        v[1] = tty->vtime;
1.1       root     4604: 
1.1.1.6 ! root     4605:                } else {
1.1       root     4606: 
1.1.1.6 ! root     4607:                        if (v[0] > t->irec->buflen/2)
1.1       root     4608: 
1.1.1.6 ! root     4609:                                v[0] = t->irec->buflen/2;
1.1       root     4610: 
1.1.1.6 ! root     4611:                        tty->vmin = v[0];
1.1.1.5   root     4612: 
1.1.1.6 ! root     4613:                        tty->vtime = v[1];
1.1.1.5   root     4614: 
1.1.1.6 ! root     4615:                        t->vticks = 0;
1.1       root     4616: 
1.1.1.6 ! root     4617:                }
1.1       root     4618: 
1.1.1.6 ! root     4619:                return 0;
1.1       root     4620: 
1.1.1.6 ! root     4621:            }
1.1       root     4622: 
1.1.1.6 ! root     4623:        case TIOCWONLINE:
1.1       root     4624: 
1.1.1.6 ! root     4625:            {
1.1       root     4626: 
1.1.1.6 ! root     4627:                struct tty *tty = (struct tty *)f->devinfo;
1.1       root     4628: 
                   4629: 
                   4630: 
1.1.1.6 ! root     4631:                if (!tty)
1.1       root     4632: 
1.1.1.6 ! root     4633:                        return EINVFN;
1.1       root     4634: 
1.1.1.6 ! root     4635:                while (tty->state & TS_BLIND)
1.1       root     4636: 
1.1.1.6 ! root     4637:                        sleep (IO_Q, (long)&tty->state);
1.1       root     4638: 
1.1.1.6 ! root     4639:                return 0;
1.1       root     4640: 
1.1.1.6 ! root     4641:            }
1.1       root     4642: 
1.1.1.6 ! root     4643:        case TCURSOFF:
1.1       root     4644: 
1.1.1.6 ! root     4645:        case TCURSON:
1.1       root     4646: 
1.1.1.6 ! root     4647:        case TCURSBLINK:
1.1       root     4648: 
1.1.1.6 ! root     4649:        case TCURSSTEADY:
1.1       root     4650: 
1.1.1.6 ! root     4651:                if (f->fc.aux != 2)
1.1       root     4652: 
                   4653:                        return EINVFN;
                   4654: 
1.1.1.6 ! root     4655:                return Cursconf(mode - TCURSOFF, 0);
1.1       root     4656: 
1.1.1.6 ! root     4657:        case TCURSSRATE:
1.1.1.4   root     4658: 
1.1.1.6 ! root     4659:        case TCURSGRATE:
1.1.1.4   root     4660: 
1.1.1.6 ! root     4661:            {
1.1.1.4   root     4662: 
                   4663:                long r;
                   4664: 
                   4665: 
                   4666: 
1.1.1.6 ! root     4667:                if (f->fc.aux != 2)
        !          4668: 
        !          4669:                        return EINVFN;
        !          4670: 
1.1.1.4   root     4671:                r = Cursconf(mode - TCURSOFF, *((short *)buf));
                   4672: 
1.1.1.6 ! root     4673:                if (r >= 0 && mode == TCURSGRATE) {
1.1.1.4   root     4674: 
                   4675:                        *(short *)buf = r;
                   4676: 
                   4677:                        r = 0;
                   4678: 
                   4679:                }
1.1       root     4680: 
1.1.1.4   root     4681:                return r;
1.1       root     4682: 
1.1.1.6 ! root     4683:            }
        !          4684: 
        !          4685:        case F_SETLK:
        !          4686: 
        !          4687:        case F_SETLKW:
        !          4688: 
        !          4689:            {
1.1.1.5   root     4690: 
                   4691:                struct flock *lck = (struct flock *)buf;
                   4692: 
                   4693: 
                   4694: 
                   4695:                b = (struct bios_file *)f->fc.index;
                   4696: 
                   4697:                while (b->lockpid && b->lockpid != curproc->pid) {
                   4698: 
                   4699:                        if (mode == F_SETLKW && lck->l_type != F_UNLCK)
                   4700: 
                   4701:                                sleep(IO_Q, (long)b);
                   4702: 
                   4703:                        else
                   4704: 
                   4705:                                return ELOCKED;
                   4706: 
                   4707:                }
                   4708: 
                   4709:                if (lck->l_type == F_UNLCK) {
                   4710: 
                   4711:                        if (!(f->flags & O_LOCK)) {
                   4712: 
                   4713:                                DEBUG(("bios_ioctl: wrong file descriptor for UNLCK"));
                   4714: 
                   4715:                                return ENSLOCK;
                   4716: 
                   4717:                        }
                   4718: 
                   4719:                        if (b->lockpid != curproc->pid)
                   4720: 
                   4721:                                return ENSLOCK;
                   4722: 
                   4723:                        b->lockpid = 0;
                   4724: 
                   4725:                        f->flags &= ~O_LOCK;
                   4726: 
                   4727:                        wake(IO_Q, (long)b);    /* wake anyone waiting for this lock */
                   4728: 
                   4729:                } else {
                   4730: 
                   4731:                        b->lockpid = curproc->pid;
                   4732: 
                   4733:                        f->flags |= O_LOCK;
                   4734: 
                   4735:                }
                   4736: 
1.1.1.6 ! root     4737:                break;
        !          4738: 
        !          4739:            }
        !          4740: 
        !          4741:        case F_GETLK:
        !          4742: 
        !          4743:            {
1.1.1.5   root     4744: 
                   4745:                struct flock *lck = (struct flock *)buf;
                   4746: 
                   4747: 
                   4748: 
                   4749:                b = (struct bios_file *)f->fc.index;
                   4750: 
                   4751:                if (b->lockpid) {
                   4752: 
                   4753:                        lck->l_type = F_WRLCK;
                   4754: 
                   4755:                        lck->l_start = lck->l_len = 0;
                   4756: 
                   4757:                        lck->l_pid = b->lockpid;
                   4758: 
                   4759:                } else {
                   4760: 
                   4761:                        lck->l_type = F_UNLCK;
                   4762: 
                   4763:                }
                   4764: 
1.1.1.6 ! root     4765:                break;
        !          4766: 
        !          4767:            }
        !          4768: 
        !          4769: #ifndef TIOCCTLMAP
        !          4770: 
        !          4771: #define TIOCCTLMAP (('T'<<8) | 129)
        !          4772: 
        !          4773: #define TIOCCTLGET (('T'<<8) | 130)
        !          4774: 
        !          4775: #define TIOCCTLSET (('T'<<8) | 131)
        !          4776: 
        !          4777: #define TIONOTSEND (('T'<<8) | 134)
        !          4778: 
        !          4779: #define TIOCERROR (('T'<<8) | 135)
        !          4780: 
        !          4781: #endif
        !          4782: 
        !          4783:        case TIOCCTLMAP:
        !          4784: 
        !          4785:        case TIOCCTLGET:
        !          4786: 
        !          4787:        case TIOCCTLSET:
        !          4788: 
        !          4789:        case TIOCERROR:
        !          4790: 
        !          4791:            {
        !          4792: 
        !          4793:                long ret;
        !          4794: 
        !          4795: 
        !          4796: 
        !          4797:                if (t &&
        !          4798: 
        !          4799:                    (ret = rsvf_ioctl (t->tosfd, r, mode)) != EINVFN) {
        !          4800: 
        !          4801:                        if (mode == TIOCCTLMAP)
        !          4802: 
        !          4803: /* user processes can get signals but not callbacks from real interrupts... */
        !          4804: 
        !          4805:                                r[1] = r[2] = 0;
        !          4806: 
        !          4807:                        return ret;
        !          4808: 
        !          4809:                }
        !          4810: 
        !          4811:                /*FALLTHRU*/
        !          4812: 
        !          4813:            }
        !          4814: 
        !          4815:        default:
1.1       root     4816: 
                   4817:        /* Fcntl will automatically call tty_ioctl to handle
                   4818: 
                   4819:         * terminal calls that we didn't deal with
                   4820: 
                   4821:         */
                   4822: 
                   4823:                return EINVFN;
                   4824: 
                   4825:        }
                   4826: 
                   4827:        return 0;
                   4828: 
                   4829: }
                   4830: 
                   4831: 
                   4832: 
1.1.1.2   root     4833: static long ARGS_ON_STACK 
1.1       root     4834: 
                   4835: bios_select(f, p, mode)
                   4836: 
                   4837:        FILEPTR *f; long p; int mode;
                   4838: 
                   4839: {
                   4840: 
                   4841:        struct tty *tty = (struct tty *)f->devinfo;
                   4842: 
                   4843:        int dev = f->fc.aux;
                   4844: 
                   4845: 
                   4846: 
                   4847:        if (mode == O_RDONLY) {
                   4848: 
1.1.1.6 ! root     4849:                struct bios_tty *t = &midi_btty;
        !          4850: 
        !          4851:                if (tty && (dev == 3 || ((t = BTTY(f))))) {
        !          4852: 
        !          4853:                        if (!(tty->state & TS_BLIND) &&
        !          4854: 
        !          4855:                            (dev == 3 ? ionread(t->irec) :
        !          4856: 
        !          4857:                                        btty_ionread(t)) >= (long)tty->vmin) {
        !          4858: 
        !          4859:                                return 1;
        !          4860: 
        !          4861:                        }
        !          4862: 
        !          4863:                } else if (bconstat(dev)) {
1.1       root     4864: 
1.1.1.2   root     4865:                        TRACE(("bios_select: data present for device %d", dev));
1.1       root     4866: 
                   4867:                        return 1;
                   4868: 
                   4869:                }
                   4870: 
                   4871:                if (tty) {
                   4872: 
                   4873:                /* avoid collisions with other processes */
                   4874: 
1.1.1.6 ! root     4875:                        if (tty->rsel)
1.1       root     4876: 
1.1.1.5   root     4877:                                return 2;       /* collision */
                   4878: 
                   4879:                        tty->rsel = p;
1.1       root     4880: 
                   4881:                }
                   4882: 
                   4883:                return 0;
                   4884: 
                   4885:        } else if (mode == O_WRONLY) {
                   4886: 
1.1.1.6 ! root     4887:                if ((!tty || !(tty->state & (TS_BLIND|TS_HOLD))) &&
        !          4888: 
        !          4889:                    (dev == 3 || bcostat(dev))) {
1.1       root     4890: 
1.1.1.2   root     4891:                        TRACE(("bios_select: ready to output on %d", dev));
1.1       root     4892: 
                   4893:                        return 1;
                   4894: 
                   4895:                }
                   4896: 
                   4897:                if (tty) {
                   4898: 
1.1.1.6 ! root     4899:                        if (tty->wsel)
1.1       root     4900: 
1.1.1.5   root     4901:                                return 2;       /* collision */
                   4902: 
                   4903:                        tty->wsel = p;
1.1       root     4904: 
                   4905:                }
                   4906: 
                   4907:                return 0;
                   4908: 
                   4909:        }
                   4910: 
                   4911:        /* default -- we don't know this mode, return 0 */
                   4912: 
                   4913:        return 0;
                   4914: 
                   4915: }
                   4916: 
                   4917: 
                   4918: 
1.1.1.2   root     4919: static void ARGS_ON_STACK 
1.1       root     4920: 
                   4921: bios_unselect(f, p, mode)
                   4922: 
                   4923:        FILEPTR *f;
                   4924: 
                   4925:        long p;
                   4926: 
                   4927:        int mode;
                   4928: 
                   4929: {
                   4930: 
                   4931:        struct tty *tty = (struct tty *)f->devinfo;
                   4932: 
                   4933: 
                   4934: 
                   4935:        if (tty) {
                   4936: 
                   4937:                if (mode == O_RDONLY && tty->rsel == p)
                   4938: 
                   4939:                        tty->rsel = 0;
                   4940: 
                   4941:                else if (mode == O_WRONLY && tty->wsel == p)
                   4942: 
                   4943:                        tty->wsel = 0;
                   4944: 
                   4945:        }
                   4946: 
                   4947: }
                   4948: 
                   4949: 
                   4950: 
1.1.1.5   root     4951: static long ARGS_ON_STACK 
                   4952: 
                   4953: bios_close(f, pid)
                   4954: 
                   4955:        FILEPTR *f;
                   4956: 
                   4957:        int pid;
                   4958: 
                   4959: {
                   4960: 
1.1.1.6 ! root     4961:        struct tty *tty = (struct tty *)f->devinfo;
        !          4962: 
1.1.1.5   root     4963:        struct bios_file *b;
                   4964: 
1.1.1.6 ! root     4965:        struct bios_tty *t;
        !          4966: 
1.1.1.5   root     4967: 
                   4968: 
                   4969:        b = (struct bios_file *)f->fc.index;
                   4970: 
                   4971:        if ((f->flags & O_LOCK) && (b->lockpid == pid)) {
                   4972: 
                   4973:                b->lockpid = 0;
                   4974: 
1.1.1.6 ! root     4975:                f->flags &= ~O_LOCK;
        !          4976: 
        !          4977:                wake(IO_Q, (long)b);    /* wake anyone waiting for this lock */
        !          4978: 
        !          4979:        }
        !          4980: 
        !          4981:        if (tty && f->links <= 0 && f->pos)
        !          4982: 
        !          4983: /* f->pos used as flag that f came from Bconmap (/dev/aux) */
        !          4984: 
        !          4985:                tty->aux_cnt--;
        !          4986: 
        !          4987:        if (tty && !tty->use_cnt && ((t = BTTY(f)) && t->tosfd != EUNDEV)) {
        !          4988: 
        !          4989:                rsvf_close (t->tosfd);
        !          4990: 
        !          4991:                t->tosfd = EUNDEV;
        !          4992: 
1.1.1.5   root     4993:        }
                   4994: 
                   4995:        return 0;
                   4996: 
                   4997: }
                   4998: 
                   4999: 
                   5000: 
1.1       root     5001: /*
                   5002: 
                   5003:  * mouse device driver
                   5004: 
                   5005:  */
                   5006: 
                   5007: 
                   5008: 
                   5009: #define MOUSESIZ 128*3
                   5010: 
                   5011: static unsigned char mousebuf[MOUSESIZ];
                   5012: 
                   5013: static int mousehead, mousetail;
                   5014: 
                   5015: 
                   5016: 
                   5017: long mousersel;        /* is someone calling select() on the mouse? */
                   5018: 
                   5019: 
                   5020: 
                   5021: char mshift;           /* shift key status; set by checkkeys() in bios.c */
                   5022: 
                   5023: short *gcurx = 0,
                   5024: 
                   5025:       *gcury = 0;      /* mouse pos. variables; used by big screen emulators */
                   5026: 
                   5027: 
                   5028: 
1.1.1.2   root     5029: void ARGS_ON_STACK 
1.1       root     5030: 
                   5031: mouse_handler(buf)
                   5032: 
                   5033:        const char *buf;        /* must be a *signed* character */
                   5034: 
                   5035: {
                   5036: 
                   5037:        unsigned char *mbuf, buttons;
                   5038: 
                   5039:        int newmtail;
                   5040: 
                   5041:        short dx, dy;
                   5042: 
                   5043: 
                   5044: 
                   5045: /* the Sun mouse driver has 0=down, 1=up, while the atari hardware gives
                   5046: 
                   5047:    us the reverse. also, we have the "middle" button and the "left"
                   5048: 
                   5049:    button reversed; so we use this table to convert (and also to add the
                   5050: 
                   5051:    0x80 to indicate a mouse packet)
                   5052: 
                   5053:  */
                   5054: 
                   5055:        static int _cnvrt[8] = {
                   5056: 
                   5057:                0x87, 0x86, 0x83, 0x82, 0x85, 0x84, 0x81, 0x80
                   5058: 
                   5059:        };
                   5060: 
                   5061: 
                   5062: 
                   5063:        mbuf = &mousebuf[mousetail];
                   5064: 
                   5065:        newmtail = mousetail + 3;
                   5066: 
                   5067:        if (newmtail >= MOUSESIZ)
                   5068: 
                   5069:                newmtail = 0;
                   5070: 
                   5071:        if (newmtail == mousehead)
                   5072: 
                   5073:                return;                 /* buffer full */
                   5074: 
                   5075: 
                   5076: 
                   5077:        buttons = *buf++ & 0x7;         /* convert to SUN format */
                   5078: 
                   5079:        if (mshift & 0x3) {             /* a shift key held down? */
                   5080: 
                   5081:        /* if so, convert shift+button to a "middle" button */
                   5082: 
                   5083:                if (buttons == 0x1 || buttons == 0x2)
                   5084: 
                   5085:                        buttons = 0x4;
                   5086: 
                   5087:                else if (buttons == 0x3)
                   5088: 
                   5089:                        buttons = 0x7;
                   5090: 
                   5091:        }
                   5092: 
                   5093:        *mbuf++ = _cnvrt[buttons];      /* convert to Sun format */
                   5094: 
                   5095:        dx = *buf++;
                   5096: 
                   5097:        *mbuf++ = dx;                   /* copy X delta */
                   5098: 
1.1.1.2   root     5099:        dy = *buf;
1.1       root     5100: 
1.1.1.2   root     5101:        *mbuf = -dy;                    /* invert Y delta for Sun format */
1.1       root     5102: 
                   5103:        mousetail = newmtail;
                   5104: 
                   5105:        *gcurx += dx;                   /* update line A variables */
                   5106: 
                   5107:        *gcury += dy;
                   5108: 
                   5109: /*
                   5110: 
                   5111:  * if someone has called select() waiting for mouse input, wake them
                   5112: 
                   5113:  * up
                   5114: 
                   5115:  */
                   5116: 
                   5117:        if (mousersel) {
                   5118: 
                   5119:                wakeselect(mousersel);
                   5120: 
                   5121:        }
                   5122: 
                   5123: }
                   5124: 
                   5125: 
                   5126: 
1.1.1.2   root     5127: extern void newmvec(), newjvec();      /* in intr.s */
1.1       root     5128: 
                   5129: static long oldvec = 0;
                   5130: 
1.1.1.2   root     5131: long oldjvec = 0;
                   5132: 
1.1       root     5133: 
                   5134: 
1.1.1.2   root     5135: static long ARGS_ON_STACK 
1.1       root     5136: 
                   5137: mouse_open(f)
                   5138: 
                   5139:        FILEPTR *f;
                   5140: 
                   5141: {
                   5142: 
                   5143:        char *aline;
                   5144: 
                   5145: 
                   5146: 
                   5147:        static char parameters[] = {
                   5148: 
                   5149:                0,              /* Y=0 in lower corner */
                   5150: 
                   5151:                0,              /* normal button handling */
                   5152: 
                   5153:                1, 1            /* X, Y scaling factors */
                   5154: 
                   5155:        };
                   5156: 
                   5157: 
                   5158: 
1.1.1.2   root     5159:        UNUSED(f);
                   5160: 
                   5161: 
                   5162: 
1.1       root     5163:        if (oldvec)             /* mouse in use */
                   5164: 
                   5165:                return EACCDN;
                   5166: 
                   5167: 
                   5168: 
                   5169: /* initialize pointers to line A variables */
                   5170: 
                   5171:        if (!gcurx) {
                   5172: 
                   5173:                aline = lineA0();
                   5174: 
                   5175:                if (aline == 0) {       /* should never happen */
                   5176: 
                   5177:                        ALERT("unable to read line A variables");
                   5178: 
                   5179:                        return -1;
                   5180: 
                   5181:                }
                   5182: 
                   5183:                gcurx = (short *)(aline - 0x25a);
                   5184: 
                   5185:                gcury = (short *)(aline - 0x258);
                   5186: 
                   5187:                *gcurx = *gcury = 32;   /* magic number -- what MGR uses */
                   5188: 
                   5189:        }
                   5190: 
                   5191: 
                   5192: 
                   5193:        oldvec = syskey->mousevec;
                   5194: 
1.1.1.2   root     5195:        oldjvec = syskey->joyvec;       /* jr: save old joystick vector */
                   5196: 
1.1       root     5197:        Initmous(1, parameters, newmvec);
                   5198: 
1.1.1.2   root     5199:        syskey->joyvec = (long)newjvec; /* jr: set up new joystick handler */
                   5200: 
1.1       root     5201:        mousehead = mousetail = 0;
                   5202: 
                   5203:        return 0;
                   5204: 
                   5205: }
                   5206: 
                   5207: 
                   5208: 
1.1.1.2   root     5209: static long ARGS_ON_STACK 
1.1       root     5210: 
                   5211: mouse_close(f, pid)
                   5212: 
                   5213:        FILEPTR *f;
                   5214: 
                   5215:        int pid;
                   5216: 
                   5217: {
                   5218: 
                   5219:        static char parameters[] = {
                   5220: 
                   5221:                0,              /* Y=0 in lower corner */
                   5222: 
                   5223:                0,              /* normal button handling */
                   5224: 
                   5225:                1, 1            /* X, Y scaling factors */
                   5226: 
                   5227:        };
                   5228: 
                   5229: 
                   5230: 
1.1.1.2   root     5231:        UNUSED(pid);
                   5232: 
1.1       root     5233:        if (!f) return EIHNDL;
                   5234: 
                   5235:        if (f->links <= 0) {
                   5236: 
                   5237:                if (!oldvec) {
                   5238: 
1.1.1.2   root     5239:                        DEBUG(("Mouse not open!!"));
1.1       root     5240: 
                   5241:                        return -1;
                   5242: 
                   5243:                }
                   5244: 
                   5245:                Initmous(1, parameters, (void *)oldvec);        /* gratuitous (void *) for Lattice */
                   5246: 
1.1.1.2   root     5247:                syskey->joyvec = oldjvec;       /* jr: restore old joystick handler */
                   5248: 
1.1       root     5249:                oldvec = 0;
                   5250: 
                   5251:        }
                   5252: 
                   5253:        return 0;
                   5254: 
                   5255: }
                   5256: 
                   5257: 
                   5258: 
1.1.1.2   root     5259: static long ARGS_ON_STACK 
1.1       root     5260: 
                   5261: mouse_read(f, buf, nbytes)
                   5262: 
                   5263:        FILEPTR *f;
                   5264: 
                   5265:        char *buf;
                   5266: 
                   5267:        long nbytes;
                   5268: 
                   5269: {
                   5270: 
                   5271:        long count = 0;
                   5272: 
                   5273:        int mhead;
                   5274: 
                   5275:        unsigned char *foo;
                   5276: 
1.1.1.5   root     5277:        struct bios_file *b = (struct bios_file *)f->fc.index;
                   5278: 
1.1       root     5279: 
                   5280: 
                   5281:        mhead = mousehead;
                   5282: 
                   5283:        foo = &mousebuf[mhead];
                   5284: 
                   5285: 
                   5286: 
                   5287:        if (mhead == mousetail) {
                   5288: 
                   5289:                if (f->flags & O_NDELAY)
                   5290: 
                   5291:                        return 0;
                   5292: 
                   5293:                do {
                   5294: 
                   5295:                        yield();
                   5296: 
                   5297:                } while (mhead == mousetail);
                   5298: 
                   5299:        }
                   5300: 
                   5301: 
                   5302: 
                   5303:        while ( (mhead != mousetail) && (nbytes > 0)) {
                   5304: 
                   5305:                *buf++ = *foo++;
                   5306: 
                   5307:                mhead++;
                   5308: 
                   5309:                if (mhead >= MOUSESIZ) {
                   5310: 
                   5311:                        mhead = 0;
                   5312: 
                   5313:                        foo = mousebuf;
                   5314: 
                   5315:                }
                   5316: 
                   5317:                count++;
                   5318: 
                   5319:                --nbytes;
                   5320: 
                   5321:        }
                   5322: 
                   5323:        mousehead = mhead;
                   5324: 
1.1.1.5   root     5325:        if (count > 0) {
                   5326: 
                   5327:                b->xattr.atime = timestamp;
                   5328: 
                   5329:                b->xattr.adate = datestamp;
                   5330: 
                   5331:        }
                   5332: 
1.1       root     5333:        return count;
                   5334: 
                   5335: }
                   5336: 
                   5337: 
                   5338: 
1.1.1.2   root     5339: static long ARGS_ON_STACK 
1.1       root     5340: 
                   5341: mouse_ioctl(f, mode, buf)
                   5342: 
                   5343:        FILEPTR *f;
                   5344: 
                   5345:        int mode;
                   5346: 
                   5347:        void *buf;
                   5348: 
                   5349: {
                   5350: 
                   5351:        long r;
                   5352: 
                   5353: 
                   5354: 
1.1.1.2   root     5355:        UNUSED(f);
                   5356: 
1.1       root     5357:        if (mode == FIONREAD) {
                   5358: 
                   5359:                r = mousetail - mousehead;
                   5360: 
                   5361:                if (r < 0) r += MOUSESIZ;
                   5362: 
                   5363:                *((long *)buf) = r;
                   5364: 
1.1.1.6 ! root     5365:        } else if (mode == FIONWRITE)
        !          5366: 
        !          5367:                *((long *)buf) = 0;
        !          5368: 
        !          5369:        else if (mode == FIOEXCEPT)
        !          5370: 
        !          5371:                *((long *)buf) = 0;
1.1       root     5372: 
                   5373:        else
                   5374: 
                   5375:                return EINVFN;
                   5376: 
                   5377:        return 0;
                   5378: 
                   5379: }
                   5380: 
                   5381: 
                   5382: 
1.1.1.2   root     5383: static long ARGS_ON_STACK 
1.1       root     5384: 
                   5385: mouse_select(f, p, mode)
                   5386: 
                   5387:        FILEPTR *f;
                   5388: 
                   5389:        long p;
                   5390: 
                   5391:        int mode;
                   5392: 
                   5393: {
                   5394: 
1.1.1.2   root     5395:        UNUSED(f);
                   5396: 
                   5397: 
                   5398: 
1.1.1.6 ! root     5399:        if (mode != O_RDONLY) {
        !          5400: 
        !          5401:                if (mode == O_WRONLY)
        !          5402: 
        !          5403:                        return 1;       /* we can always take output :-) */
        !          5404: 
        !          5405:                else
        !          5406: 
        !          5407:                        return 0;       /* but don't care for anything else */
1.1       root     5408: 
1.1.1.6 ! root     5409:        }
1.1       root     5410: 
                   5411: 
                   5412: 
                   5413:        if (mousetail - mousehead)
                   5414: 
                   5415:                return 1;       /* input waiting already */
                   5416: 
                   5417: 
                   5418: 
1.1.1.5   root     5419:        if (mousersel)
                   5420: 
                   5421:                return 2;       /* collision */
1.1       root     5422: 
1.1.1.5   root     5423:        mousersel = p;
1.1       root     5424: 
                   5425:        return 0;
                   5426: 
                   5427: }
                   5428: 
                   5429: 
                   5430: 
1.1.1.2   root     5431: static void ARGS_ON_STACK 
1.1       root     5432: 
                   5433: mouse_unselect(f, p, mode)
                   5434: 
                   5435:        FILEPTR *f;
                   5436: 
                   5437:        long p;
                   5438: 
                   5439:        int mode;
                   5440: 
                   5441: {
                   5442: 
1.1.1.2   root     5443:        UNUSED(f);
                   5444: 
                   5445: 
                   5446: 
1.1       root     5447:        if (mode == O_RDONLY && mousersel == p)
                   5448: 
                   5449:                mousersel = 0;
                   5450: 
                   5451: }
                   5452: 
                   5453: 
                   5454: 
                   5455: 
                   5456: 
                   5457: /*
                   5458: 
                   5459:  * UTILITY ROUTINE called by Bconmap() in xbios.c:
                   5460: 
                   5461:  * this sets handle -1 of process p to a file handle
                   5462: 
                   5463:  * that has BIOS device "dev". Returns 0 on failure,
                   5464: 
                   5465:  * non-zero on success.
                   5466: 
                   5467:  */
                   5468: 
                   5469: 
                   5470: 
                   5471: int
                   5472: 
                   5473: set_auxhandle(p, dev)
                   5474: 
                   5475:        PROC *p;
                   5476: 
                   5477:        int dev;
                   5478: 
                   5479: {
                   5480: 
                   5481:        FILEPTR *f;
                   5482: 
                   5483:        struct bios_file *b;
                   5484: 
                   5485: 
                   5486: 
                   5487:        f = new_fileptr();
                   5488: 
                   5489:        if (f) {
                   5490: 
1.1.1.6 ! root     5491:                struct tty *tty;
        !          5492: 
1.1       root     5493:                f->links = 1;
                   5494: 
                   5495:                f->flags = O_RDWR;
                   5496: 
                   5497:                f->pos = 0;
                   5498: 
                   5499:                f->devinfo = 0;
                   5500: 
                   5501:                f->fc.fs = &bios_filesys;
                   5502: 
                   5503:                f->fc.aux = dev;
                   5504: 
                   5505:                f->fc.dev = BIOSDRV;
                   5506: 
                   5507:                for (b = broot; b; b = b->next) {
                   5508: 
                   5509:                        if (b->private == dev &&
                   5510: 
                   5511:                            (b->device == &bios_tdevice ||
                   5512: 
                   5513:                             b->device == &bios_ndevice)) {
                   5514: 
                   5515:                                f->fc.index = (long)b;
                   5516: 
                   5517:                                f->dev = b->device;
                   5518: 
                   5519:                                if (b->device != &fakedev)
                   5520: 
                   5521:                                        f->devinfo = (long)b->tty;
                   5522: 
1.1.1.6 ! root     5523: #if 1
        !          5524: 
        !          5525: /* don't close and reopen the same device again
        !          5526: 
        !          5527:  */
        !          5528: 
        !          5529:                                if (p->aux && p->aux->fc.fs == &bios_filesys &&
        !          5530: 
        !          5531:                                    p->aux->fc.index == f->fc.index) {
        !          5532: 
        !          5533:                                        f->links = 0;
        !          5534: 
        !          5535:                                        dispose_fileptr(f);
        !          5536: 
        !          5537:                                        return 1;
        !          5538: 
        !          5539:                                }
        !          5540: 
        !          5541: #endif
        !          5542: 
1.1       root     5543:                                goto found_device;
                   5544: 
                   5545:                        }
                   5546: 
                   5547:                }
                   5548: 
                   5549:                f->fc.index = 0;
                   5550: 
                   5551:                f->dev = &bios_ndevice;
                   5552: 
                   5553: found_device:
                   5554: 
                   5555:                if ((*f->dev->open)(f) < 0) {
                   5556: 
                   5557:                        f->links = 0;
                   5558: 
                   5559:                        dispose_fileptr(f);
                   5560: 
                   5561:                        return 0;
                   5562: 
                   5563:                }
                   5564: 
1.1.1.6 ! root     5565: /* special code for opening a tty */
        !          5566: 
        !          5567:                if (NULL != (tty = (struct tty *)f->devinfo)) {
        !          5568: 
        !          5569:                        extern struct tty default_tty;  /* in tty.c */
        !          5570: 
        !          5571: 
        !          5572: 
        !          5573:                        tty->use_cnt++;
        !          5574: 
        !          5575:                        while (tty->hup_ospeed) {
        !          5576: 
        !          5577:                                sleep (IO_Q, (long)&tty->state);
        !          5578: 
        !          5579:                        }
        !          5580: 
        !          5581:                        /* first open for this device? */
        !          5582: 
        !          5583:                        if (tty->use_cnt == 1) {
        !          5584: 
        !          5585:                                short s = tty->state & TS_BLIND;
        !          5586: 
        !          5587:                                *tty = default_tty;
        !          5588: 
        !          5589:                                tty->state = s;
        !          5590: 
        !          5591:                                tty->use_cnt = 1;
        !          5592: 
        !          5593:                                tty_ioctl(f, TIOCSTART, 0);
        !          5594: 
        !          5595:                        }
        !          5596: 
        !          5597:                        tty->aux_cnt++;
        !          5598: 
        !          5599:                        f->pos = 1;     /* flag for close to --aux_cnt */
        !          5600: 
        !          5601:                }
        !          5602: 
1.1       root     5603:        } else {
                   5604: 
                   5605: /* no memory! use the fake FILEPTR we
                   5606: 
                   5607:  * set up in biosfs_init
                   5608: 
                   5609:  */
                   5610: 
                   5611:                f = defaultaux;
                   5612: 
                   5613:                f->links++;
                   5614: 
                   5615:        }
                   5616: 
                   5617: 
                   5618: 
                   5619:        (void)do_pclose(p, p->aux);
                   5620: 
                   5621:        p->aux = f;
                   5622: 
                   5623: 
                   5624: 
                   5625:        return 1;
                   5626: 
                   5627: }
                   5628: 

unix.superglobalmegacorp.com

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