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