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