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