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