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