static Chan* sdattach(char* spec) { Chan *c; char *p; SDev *sdev; int idno, subno; if(*spec == '\0'){ c = devattach(sddevtab.dc, spec); mkqid(&c->qid, QID(0, 0, 0, Qtopdir), 0, QTDIR); return c; } if(spec[0] != 's' || spec[1] != 'd') error(Ebadspec); idno = spec[2]; subno = strtol(&spec[3], &p, 0); if(p == &spec[3]) error(Ebadspec); if((sdev=sdgetdev(idno)) == nil) error(Enonexist); if(sdgetunit(sdev, subno) == nil){ decref(&sdev->r); error(Enonexist); } c = devattach(sddevtab.dc, spec); mkqid(&c->qid, QID(sdev->idno, subno, 0, Qunitdir), 0, QTDIR); c->dev = (sdev->idno << UnitLOG) + subno; decref(&sdev->r); return c; }
static Chan* srvattach(char *spec) { Chan *c; SrvFile *d; char srvname[16]; qlock(&dev.l); if(waserror()){ qunlock(&dev.l); nexterror(); } if(spec[0] != '\0'){ for(d = dev.devices; d != nil; d = d->devlist){ if(strcmp(spec, d->spec) == 0){ if(!srvcanattach(d)) error(Eperm); c = devattach('s', spec); c->aux = d; c->qid = d->qid; d->ref++; poperror(); qunlock(&dev.l); return c; } } } d = malloc(sizeof(SrvFile)); if(d == nil) error(Enomem); d->ref = 1; kstrdup(&d->spec, spec); kstrdup(&d->user, up->env->user); snprint(srvname, sizeof(srvname), "srv%ld", up->env->pgrp->pgrpid); kstrdup(&d->name, srvname); d->perm = DMDIR|0770; mkqid(&d->qid, dev.pathgen++, 0, QTDIR); d->devlist = dev.devices; dev.devices = d; poperror(); qunlock(&dev.l); c = devattach('s', spec); c->aux = d; c->qid = d->qid; return c; }
static Chan* fsattach(char *spec) { struct stat st; Chan *c; UnixFd *ufd; int dev; dev = 1; if(spec && spec[0]){ snprint(up->genbuf, sizeof up->genbuf, "no file system #%C%s", FsChar, spec); error(up->genbuf); } if(stat("/", &st) < 0) oserror(); c = devattach(FsChar, 0); ufd = mallocz(sizeof(UnixFd), 1); ufd->path = newpath("/"); ufd->fd = -1; c->aux = ufd; c->dev = dev; c->qid = fsqid(&st); if(Trace) print("fsattach /\n"); return c; }
static Chan* consattach(char *spec) { static int kp; if(kp == 0 && !dflag) { int i; kp = 1; if(eventfiles != NULL) { for(i = 0; eventfiles[i] != NULL; i++) { int *event_num = malloc(sizeof(int)); char buf[40]; snprintf(buf, 40, "events%d", i); if(i >= MAX_EVENTFDS) { // temporary fprintf(stderr, "too many event devices\n"); break; } eventfds[i] = open(eventfiles[i], O_RDONLY); if(eventfds[i] == -1) { perror("could not open event device"); } *event_num = i; kproc(buf, eventslave, event_num, 0); } } kproc("kbd", kbdslave, 0, 0); } return devattach('c', spec); }
/* * create a pipe, no streams are created until an open */ static Chan* pipeattach(char *spec) { Pipe *p; Chan *c; c = devattach('|', spec); p = malloc(sizeof(Pipe)); if(p == 0) exhausted("memory"); p->ref = 1; p->q[0] = qopen(Pipeqsize, 0, 0, 0); if(p->q[0] == 0){ free(p); exhausted("memory"); } p->q[1] = qopen(Pipeqsize, 0, 0, 0); if(p->q[1] == 0){ free(p->q[0]); free(p); exhausted("memory"); } lock(&pipealloc); p->path = ++pipealloc.path; unlock(&pipealloc); mkqid(&c->qid, PIPEQID(2*p->path, Qdir), 0, QTDIR); c->aux = p; c->devno = 0; return c; }
static Chan* lm78attach(char* spec) { lm78enable(); return devattach(lm78devtab.dc, spec); }
static Chan * pmcattach(char *spec) { if (pmctab == nil) error(Enomem); return devattach(L'ε', spec); }
static Chan* vgaattach(char* spec) { if(*spec && strcmp(spec, "0")) error(Eio); return devattach('v', spec); }
static Chan* eiaattach(char *spec) { if(eiadir == nil) error(Enodev); return devattach(Devchar, spec); }
static Chan* mouseattach(char *spec) { if(!conf.monitor) error(Egreg); curs = arrow; Cursortocursor(&arrow); return devattach('m', spec); }
static struct chan *rootattach(char *spec) { struct chan *c; if (*spec) error(EINVAL, ERROR_FIXME); c = devattach(devname(), spec); mkqid(&c->qid, roottab[0].qid.path, roottab[0].qid.vers, QTDIR); return c; }
static struct chan* kprofattach(char *spec) { // Did we initialise completely? if ( !(oprof_alarms && kprof.buf && kprof.systrace) ) error(ENOMEM, NULL); return devattach(devname(), spec); }
static Chan* consattach(char *spec) { static int kp; if(kp == 0 && !dflag) { kp = 1; kproc("kbd", kbdslave, 0, 0); } return devattach('c', spec); }
static struct chan* regressattach(char *spec) { uint32_t n; regress.monitor = qopen(2 << 20, 0, 0, 0); if (! regress.monitor) { printk("monitor allocate failed. No monitor output\n"); } return devattach(devname(), spec); }
Chan * ipattach(char *spec) { Chan *c; c = devattach('I', spec); c->qid.path = QID(0, 0, Qtopdir); c->qid.type = QTDIR; c->qid.vers = 0; return c; }
static Chan * cmdattach(char *spec) { Chan *c; if(cmd.conv == nil) error(Enomem); c = devattach('C', spec); mkqid(&c->qid, QID(0, Qtopdir), 0, QTDIR); return c; }
static Chan* aoeattach(char *spec) { Chan *c; if(*spec) error(Enonexist); aoeinit(); c = devattach(L'æ', spec); mkqid(&c->qid, Qzero, 0, QTDIR); return c; }
Chan * ipattach(char *spec) { Chan *c; if(atoi(spec) != 0) error("bad specification"); c = devattach('I', spec); mkqid(&c->qid, QID(0, 0, Qtopdir), 0, QTDIR); c->dev = 0; return c; }
static Chan* envattach(char *spec) { Chan *c; Egrp *egrp = nil; if(spec != nil && *spec != '\0') { if(strcmp(spec, "c") != 0) error(Ebadarg); egrp = &confegrp; } c = devattach('e', spec); c->aux = egrp; return c; }
static Chan* flashattach(char *spec) { Flash *f; int bank; Chan *c; bank = strtol(spec, nil, 0); if(bank < 0 || bank >= Nbanks || (f = flash.card[bank]) == nil || f->attach != nil && f->attach(f) < 0) error(Enodev); c = devattach('F', spec); c->dev = bank; return c; }
static Chan* audioattach(char *spec) { static int attached = 0; Audiochan *ac; Audio *adev; Chan *c; int i; if(spec != nil && *spec != '\0') i = strtol(spec, 0, 10); else i = 0; for(adev = audiodevs; adev; adev = adev->next) if(adev->ctlrno == i) break; if(adev == nil) error(Enodev); c = devattach('A', spec); c->qid.path = Qdir; if((ac = audioclone(c, adev)) == nil) error(Enomem); i = 1<<adev->ctlrno; if((attached & i) == 0){ static char *settings[] = { "speed 44100", "delay 882", /* 20 ms */ "master 100", "audio 100", "head 100", }; attached |= i; for(i=0; i<nelem(settings) && adev->volwrite; i++){ strcpy(ac->buf, settings[i]); if(!waserror()){ adev->volwrite(adev, ac->buf, strlen(ac->buf), 0); poperror(); } } } return c; }
static Chan * cecattach(char *spec) { Chan *c; static QLock q; static int inited; qlock(&q); if(inited == 0){ kproc("cectimer", cectimer, nil); inited++; } qunlock(&q); c = devattach(L'©', spec); c->qid.path = Qdir; return c; }
static Chan* fsattach(char *spec) { static int devno; Ufsinfo *uif; Chan *c; uif = mallocz(sizeof(Ufsinfo), 1); uif->path = wstrdup(L""); c = devattach('U', spec); c->aux = uif; c->dev = devno++; c->qid.type = QTDIR; return c; }
static Chan* consattach(char *spec) { /* kp is just an init flag, it's 0 when attaching to STDIN */ static int kp; hproc_t* hp = (hproc_t*)((proc_t*) up)->hproc; /* if we're running with an attached console, start consuming characters */ if(kp == 0 && !dflag) { kp = 1; /* attach the console character watcher to this thread */ uv_async_init(hp->loop, &ev_conschar, readline); kproc("kbd", kbdslave, 0, 0); } return devattach('c', spec); }
/* * create a pipe, no streams are created until an open */ static struct chan *pipeattach(char *spec) { ERRSTACK(2); Pipe *p; struct chan *c; c = devattach(devname(), spec); p = kzmalloc(sizeof(Pipe), 0); if (p == 0) error(ENOMEM, ERROR_FIXME); if (waserror()) { freepipe(p); nexterror(); } p->pipedir = kzmalloc(sizeof(pipedir), 0); if (p->pipedir == 0) error(ENOMEM, ERROR_FIXME); memmove(p->pipedir, pipedir, sizeof(pipedir)); kstrdup(&p->user, current->user); kref_init(&p->ref, pipe_release, 1); qlock_init(&p->qlock); p->q[0] = qopen(pipealloc.pipeqsize, Qcoalesce, 0, 0); if (p->q[0] == 0) error(ENOMEM, ERROR_FIXME); p->q[1] = qopen(pipealloc.pipeqsize, Qcoalesce, 0, 0); if (p->q[1] == 0) error(ENOMEM, ERROR_FIXME); poperror(); spin_lock(&(&pipealloc)->lock); p->path = ++pipealloc.path; spin_unlock(&(&pipealloc)->lock); c->qid.path = NETQID(2 * p->path, Qdir); c->qid.vers = 0; c->qid.type = QTDIR; c->aux = p; c->dev = 0; /* taps. */ SLIST_INIT(&p->data_taps[0]); /* already = 0; set to be futureproof */ SLIST_INIT(&p->data_taps[1]); spinlock_init(&p->tap_lock); return c; }
static Chan* envattach(char *spec) { Chan *c; Egrp *egrp = nil; if(spec && *spec) { if(strcmp(spec, "c") == 0) egrp = &confegrp; if(egrp == nil) error(Ebadarg); } c = devattach('e', spec); c->aux = egrp; return c; }
static Chan * devlogfsattach(char *spec) { Chan *c; #ifdef CALLTRACE print("devlogfsattach(spec = %s) - start\n", spec); #endif /* create the identity store on first attach */ if (is == nil) errorany(logfsisnew(&is)); c = devattach(0x29f, spec); // c = devattach(L'ʟ', spec); #ifdef CALLTRACE print("devlogfsattach(spec = %s) - return %.8lux\n", spec, (ulong)c); #endif return c; }
static Chan* floppyattach(char *spec) { static int kstarted; if(fl.ndrive == 0) error(Enodev); if(kstarted == 0){ /* * watchdog to turn off the motors */ kstarted = 1; kproc("floppy", floppykproc, 0); } return devattach('f', spec); }
static Chan* acpiattach(char *spec) { int i; /* * This was written for the stock kernel. * This code must use 64 registers to be acpi ready in nix. */ if(1 || acpiinit() < 0) error("no acpi"); /* * should use fadt->xpm* and fadt->xgpe* registers for 64 bits. * We are not ready in this kernel for that. */ DBG("acpi io alloc\n"); acpiioalloc(fadt.smicmd, 1); acpiioalloc(fadt.pm1aevtblk, fadt.pm1evtlen); acpiioalloc(fadt.pm1bevtblk, fadt.pm1evtlen ); acpiioalloc(fadt.pm1acntblk, fadt.pm1cntlen); acpiioalloc(fadt.pm1bcntblk, fadt.pm1cntlen); acpiioalloc(fadt.pm2cntblk, fadt.pm2cntlen); acpiioalloc(fadt.pmtmrblk, fadt.pmtmrlen); acpiioalloc(fadt.gpe0blk, fadt.gpe0blklen); acpiioalloc(fadt.gpe1blk, fadt.gpe1blklen); DBG("acpi init gpes\n"); initgpes(); /* * This starts ACPI, which may require we handle * power mgmt events ourselves. Use with care. */ DBG("acpi starting\n"); outb(fadt.smicmd, fadt.acpienable); for(i = 0; i < 10; i++) if(getpm1ctl() & Pm1SciEn) break; if(i == 10) error("acpi: failed to enable\n"); if(fadt.sciint != 0) intrenable(fadt.sciint, acpiintr, 0, BUSUNKNOWN, "acpi"); return devattach(L'α', spec); }
static Chan* fsattach(char *spec) { struct stat st; Chan *c; UnixFd *ufd; int plan9, dev; dev = 1; plan9 = 0; if(spec && spec[0]){ if(strcmp(spec, "plan9") == 0) { plan9 = 1; dev = 2; } else{ snprint(up->genbuf, sizeof up->genbuf, "no file system #%C%s", FsChar, spec); error(up->genbuf); } } if(plan9){ if(localroot == nil) error("no #Zplan9 root without -r"); if(stat(localroot, &st) < 0) oserror(); }else{ if(stat("/", &st) < 0) oserror(); } c = devattach(FsChar, spec); ufd = mallocz(sizeof(UnixFd), 1); ufd->path = newpath("/"); ufd->plan9 = plan9; ufd->fd = -1; c->aux = ufd; c->dev = dev; c->qid = fsqid(&st); if(Trace) print("fsattach /\n"); return c; }