This commit is contained in:
cinap_lenrek 2011-05-09 08:32:14 +00:00
parent 67856b4507
commit 26c2845917
20 changed files with 1674 additions and 1611 deletions

View file

@ -14,6 +14,7 @@ bind -a #S /dev
# mount points
mount -a /srv/slashn /n
mount -b /srv/cons /dev
# authentication
mount -a /srv/factotum /mnt

View file

@ -2,6 +2,12 @@
bind -q '#p' /proc
if(test -e '#b' && ! test -e /dev/kbd){
bind -a '#b' /dev
aux/kbdfs -s cons
exec /rc/bin/bootrc </dev/cons >/dev/cons >[2]/dev/cons
}
bind -qa '#S' /dev
bind -qa '#f' /dev
bind -qa '#k' /dev

481
sys/src/9/pc/devkbd.c Normal file
View file

@ -0,0 +1,481 @@
/*
* keyboard input
*/
#include "u.h"
#include "../port/lib.h"
#include "mem.h"
#include "dat.h"
#include "fns.h"
#include "io.h"
#include "../port/error.h"
enum {
Data= 0x60, /* data port */
Status= 0x64, /* status port */
Inready= 0x01, /* input character ready */
Outbusy= 0x02, /* output busy */
Sysflag= 0x04, /* system flag */
Cmddata= 0x08, /* cmd==0, data==1 */
Inhibit= 0x10, /* keyboard/mouse inhibited */
Minready= 0x20, /* mouse character ready */
Rtimeout= 0x40, /* general timeout */
Parity= 0x80,
Cmd= 0x64, /* command port (write only) */
Spec= 0xF800, /* Unicode private space */
PF= Spec|0x20, /* num pad function key */
View= Spec|0x00, /* view (shift window up) */
KF= 0xF000, /* function key (begin Unicode private space) */
Shift= Spec|0x60,
Break= Spec|0x61,
Ctrl= Spec|0x62,
Latin= Spec|0x63,
Caps= Spec|0x64,
Num= Spec|0x65,
Middle= Spec|0x66,
Altgr= Spec|0x67,
Kmouse= Spec|0x100,
No= 0x00, /* peter */
Home= KF|13,
Up= KF|14,
Pgup= KF|15,
Print= KF|16,
Left= KF|17,
Right= KF|18,
End= KF|24,
Down= View,
Pgdown= KF|19,
Ins= KF|20,
Del= 0x7F,
Scroll= KF|21,
Nscan= 128,
Int= 0, /* kbscans indices */
Ext,
Nscans,
};
enum
{
/* controller command byte */
Cscs1= (1<<6), /* scan code set 1 */
Cauxdis= (1<<5), /* mouse disable */
Ckbddis= (1<<4), /* kbd disable */
Csf= (1<<2), /* system flag */
Cauxint= (1<<1), /* mouse interrupt enable */
Ckbdint= (1<<0), /* kbd interrupt enable */
};
enum {
Qdir,
Qscancode,
Qleds,
};
static Dirtab kbdtab[] = {
".", {Qdir, 0, QTDIR}, 0, 0555,
"scancode", {Qscancode, 0}, 0, 0440,
"leds", {Qleds, 0}, 0, 0220,
};
static Lock i8042lock;
static uchar ccc;
static void kbdputc(int);
static void (*auxputc)(int, int);
static int nokbd = 1; /* flag: no PS/2 keyboard */
static struct {
Ref ref;
Queue *q;
} kbd;
/*
* wait for output no longer busy
*/
static int
outready(void)
{
int tries;
for(tries = 0; (inb(Status) & Outbusy); tries++){
if(tries > 500)
return -1;
delay(2);
}
return 0;
}
/*
* wait for input
*/
static int
inready(void)
{
int tries;
for(tries = 0; !(inb(Status) & Inready); tries++){
if(tries > 500)
return -1;
delay(2);
}
return 0;
}
/*
* ask 8042 to reset the machine
*/
void
i8042reset(void)
{
int i, x;
if(nokbd)
return;
*((ushort*)KADDR(0x472)) = 0x1234; /* BIOS warm-boot flag */
/*
* newer reset the machine command
*/
outready();
outb(Cmd, 0xFE);
outready();
/*
* Pulse it by hand (old somewhat reliable)
*/
x = 0xDF;
for(i = 0; i < 5; i++){
x ^= 1;
outready();
outb(Cmd, 0xD1);
outready();
outb(Data, x); /* toggle reset */
delay(100);
}
}
int
i8042auxcmd(int cmd)
{
unsigned int c;
int tries;
static int badkbd;
if(badkbd)
return -1;
c = 0;
tries = 0;
ilock(&i8042lock);
do{
if(tries++ > 2)
break;
if(outready() < 0)
break;
outb(Cmd, 0xD4);
if(outready() < 0)
break;
outb(Data, cmd);
if(outready() < 0)
break;
if(inready() < 0)
break;
c = inb(Data);
} while(c == 0xFE || c == 0);
iunlock(&i8042lock);
if(c != 0xFA){
print("i8042: %2.2ux returned to the %2.2ux command\n", c, cmd);
badkbd = 1; /* don't keep trying; there might not be one */
return -1;
}
return 0;
}
int
i8042auxcmds(uchar *cmd, int ncmd)
{
int i;
ilock(&i8042lock);
for(i=0; i<ncmd; i++){
if(outready() < 0)
break;
outb(Cmd, 0xD4);
if(outready() < 0)
break;
outb(Data, cmd[i]);
}
iunlock(&i8042lock);
return i;
}
/*
* set keyboard's leds for lock states (scroll, numeric, caps).
*
* at least one keyboard (from Qtronics) also sets its numeric-lock
* behaviour to match the led state, though it has no numeric keypad,
* and some BIOSes bring the system up with numeric-lock set and no
* setting to change that. this combination steals the keys for these
* characters and makes it impossible to generate them: uiolkjm&*().
* thus we'd like to be able to force the numeric-lock led (and behaviour) off.
*/
static void
setleds(int leds)
{
static int old = -1;
if(nokbd || leds == old)
return;
leds &= 7;
ilock(&i8042lock);
for(;;){
if(outready() < 0)
break;
outb(Data, 0xed); /* `reset keyboard lock states' */
if(outready() < 0)
break;
outb(Data, leds);
if(outready() < 0)
break;
old = leds;
break;
}
iunlock(&i8042lock);
}
/*
* keyboard interrupt
*/
static void
i8042intr(Ureg*, void*)
{
int s, c;
uchar b;
/*
* get status
*/
ilock(&i8042lock);
s = inb(Status);
if(!(s&Inready)){
iunlock(&i8042lock);
return;
}
/*
* get the character
*/
c = inb(Data);
iunlock(&i8042lock);
/*
* if it's the aux port...
*/
if(s & Minready){
if(auxputc != nil)
auxputc(c, 0);
return;
}
b = c & 0xff;
qproduce(kbd.q, &b, 1);
}
void
i8042auxenable(void (*putc)(int, int))
{
char *err = "i8042: aux init failed\n";
/* enable kbd/aux xfers and interrupts */
ccc &= ~Cauxdis;
ccc |= Cauxint;
ilock(&i8042lock);
if(outready() < 0)
print(err);
outb(Cmd, 0x60); /* write control register */
if(outready() < 0)
print(err);
outb(Data, ccc);
if(outready() < 0)
print(err);
outb(Cmd, 0xA8); /* auxiliary device enable */
if(outready() < 0){
iunlock(&i8042lock);
return;
}
auxputc = putc;
intrenable(IrqAUX, i8042intr, 0, BUSUNKNOWN, "kbdaux");
iunlock(&i8042lock);
}
static Chan *
kbdattach(char *spec)
{
return devattach(L'b', spec);
}
static Walkqid*
kbdwalk(Chan *c, Chan *nc, char **name, int nname)
{
return devwalk(c, nc, name, nname, kbdtab, nelem(kbdtab), devgen);
}
static int
kbdstat(Chan *c, uchar *dp, int n)
{
return devstat(c, dp, n, kbdtab, nelem(kbdtab), devgen);
}
static Chan*
kbdopen(Chan *c, int omode)
{
if(!iseve())
error(Eperm);
if(c->qid.path == Qscancode){
if(incref(&kbd.ref) != 1){
decref(&kbd.ref);
error(Einuse);
}
}
return devopen(c, omode, kbdtab, nelem(kbdtab), devgen);
}
static void
kbdclose(Chan *c)
{
if(c->qid.path == Qscancode)
decref(&kbd.ref);
}
static Block*
kbdbread(Chan *c, long n, ulong)
{
if(c->qid.path != Qscancode)
error(Egreg);
return qbread(kbd.q, n);
}
static long
kbdread(Chan *c, void *a, long n, vlong)
{
if(c->qid.path != Qscancode)
error(Egreg);
return qread(kbd.q, a, n);
}
static long
kbdwrite(Chan *c, void *a, long n, vlong)
{
char tmp[8+1], *p;
if(c->qid.path != Qleds)
error(Egreg);
p = tmp + n;
if(n >= sizeof(tmp))
p = tmp + sizeof(tmp)-1;
memmove(tmp, a, p - tmp);
*p = 0;
setleds(atoi(tmp));
return n;
}
Dev kbddevtab = {
L'b',
"kbd",
devreset,
devinit,
devshutdown,
kbdattach,
kbdwalk,
kbdstat,
kbdopen,
devcreate,
kbdclose,
kbdread,
kbdbread,
kbdwrite,
devbwrite,
devremove,
devwstat,
};
static char *initfailed = "i8042: kbdinit failed\n";
static int
outbyte(int port, int c)
{
outb(port, c);
if(outready() < 0) {
print(initfailed);
return -1;
}
return 0;
}
void
kbdenable(void)
{
kbd.q = qopen(4*1024, 0, 0, 0);
if(kbd.q == nil)
panic("kbdenable");
qnoblock(kbd.q, 1);
ioalloc(Data, 1, 0, "kbd");
ioalloc(Cmd, 1, 0, "kbd");
intrenable(IrqKBD, i8042intr, 0, BUSUNKNOWN, "kbd");
}
void
kbdinit(void)
{
int c, try;
/* wait for a quiescent controller */
try = 1000;
while(try-- > 0 && (c = inb(Status)) & (Outbusy | Inready)) {
if(c & Inready)
inb(Data);
delay(1);
}
if (try <= 0) {
print(initfailed);
return;
}
/* get current controller command byte */
outb(Cmd, 0x20);
if(inready() < 0){
print("i8042: kbdinit can't read ccc\n");
ccc = 0;
} else
ccc = inb(Data);
/* enable kbd xfers and interrupts */
ccc &= ~Ckbddis;
ccc |= Csf | Ckbdint | Cscs1;
if(outready() < 0) {
print(initfailed);
return;
}
nokbd = 0;
/* disable mouse */
if (outbyte(Cmd, 0x60) < 0 || outbyte(Data, ccc) < 0)
print("i8042: kbdinit mouse disable failed\n");
}

View file

@ -1,715 +0,0 @@
/*
* keyboard input
*/
#include "u.h"
#include "../port/lib.h"
#include "mem.h"
#include "dat.h"
#include "fns.h"
#include "io.h"
#include "../port/error.h"
enum {
Data= 0x60, /* data port */
Status= 0x64, /* status port */
Inready= 0x01, /* input character ready */
Outbusy= 0x02, /* output busy */
Sysflag= 0x04, /* system flag */
Cmddata= 0x08, /* cmd==0, data==1 */
Inhibit= 0x10, /* keyboard/mouse inhibited */
Minready= 0x20, /* mouse character ready */
Rtimeout= 0x40, /* general timeout */
Parity= 0x80,
Cmd= 0x64, /* command port (write only) */
Spec= 0xF800, /* Unicode private space */
PF= Spec|0x20, /* num pad function key */
View= Spec|0x00, /* view (shift window up) */
KF= 0xF000, /* function key (begin Unicode private space) */
Shift= Spec|0x60,
Break= Spec|0x61,
Ctrl= Spec|0x62,
Latin= Spec|0x63,
Caps= Spec|0x64,
Num= Spec|0x65,
Middle= Spec|0x66,
Altgr= Spec|0x67,
Kmouse= Spec|0x100,
No= 0x00, /* peter */
Home= KF|13,
Up= KF|14,
Pgup= KF|15,
Print= KF|16,
Left= KF|17,
Right= KF|18,
End= KF|24,
Down= View,
Pgdown= KF|19,
Ins= KF|20,
Del= 0x7F,
Scroll= KF|21,
Nscan= 128,
Int= 0, /* kbscans indices */
Ext,
Nscans,
};
/*
* The codes at 0x79 and 0x7b are produced by the PFU Happy Hacking keyboard.
* A 'standard' keyboard doesn't produce anything above 0x58.
*/
Rune kbtab[Nscan] =
{
[0x00] No, 0x1b, '1', '2', '3', '4', '5', '6',
[0x08] '7', '8', '9', '0', '-', '=', '\b', '\t',
[0x10] 'q', 'w', 'e', 'r', 't', 'y', 'u', 'i',
[0x18] 'o', 'p', '[', ']', '\n', Ctrl, 'a', 's',
[0x20] 'd', 'f', 'g', 'h', 'j', 'k', 'l', ';',
[0x28] '\'', '`', Shift, '\\', 'z', 'x', 'c', 'v',
[0x30] 'b', 'n', 'm', ',', '.', '/', Shift, '*',
[0x38] Latin, ' ', Ctrl, KF|1, KF|2, KF|3, KF|4, KF|5,
[0x40] KF|6, KF|7, KF|8, KF|9, KF|10, Num, Scroll, '7',
[0x48] '8', '9', '-', '4', '5', '6', '+', '1',
[0x50] '2', '3', '0', '.', No, No, No, KF|11,
[0x58] KF|12, No, No, No, No, No, No, No,
[0x60] No, No, No, No, No, No, No, No,
[0x68] No, No, No, No, No, No, No, No,
[0x70] No, No, No, No, No, No, No, No,
[0x78] No, View, No, Up, No, No, No, No,
};
Rune kbtabshift[Nscan] =
{
[0x00] No, 0x1b, '!', '@', '#', '$', '%', '^',
[0x08] '&', '*', '(', ')', '_', '+', '\b', '\t',
[0x10] 'Q', 'W', 'E', 'R', 'T', 'Y', 'U', 'I',
[0x18] 'O', 'P', '{', '}', '\n', Ctrl, 'A', 'S',
[0x20] 'D', 'F', 'G', 'H', 'J', 'K', 'L', ':',
[0x28] '"', '~', Shift, '|', 'Z', 'X', 'C', 'V',
[0x30] 'B', 'N', 'M', '<', '>', '?', Shift, '*',
[0x38] Latin, ' ', Ctrl, KF|1, KF|2, KF|3, KF|4, KF|5,
[0x40] KF|6, KF|7, KF|8, KF|9, KF|10, Num, Scroll, '7',
[0x48] '8', '9', '-', '4', '5', '6', '+', '1',
[0x50] '2', '3', '0', '.', No, No, No, KF|11,
[0x58] KF|12, No, No, No, No, No, No, No,
[0x60] No, No, No, No, No, No, No, No,
[0x68] No, No, No, No, No, No, No, No,
[0x70] No, No, No, No, No, No, No, No,
[0x78] No, Up, No, Up, No, No, No, No,
};
Rune kbtabesc1[Nscan] =
{
[0x00] No, No, No, No, No, No, No, No,
[0x08] No, No, No, No, No, No, No, No,
[0x10] No, No, No, No, No, No, No, No,
[0x18] No, No, No, No, '\n', Ctrl, No, No,
[0x20] No, No, No, No, No, No, No, No,
[0x28] No, No, Shift, No, No, No, No, No,
[0x30] No, No, No, No, No, '/', No, Print,
[0x38] Altgr, No, No, No, No, No, No, No,
[0x40] No, No, No, No, No, No, Break, Home,
[0x48] Up, Pgup, No, Left, No, Right, No, End,
[0x50] Down, Pgdown, Ins, Del, No, No, No, No,
[0x58] No, No, No, No, No, No, No, No,
[0x60] No, No, No, No, No, No, No, No,
[0x68] No, No, No, No, No, No, No, No,
[0x70] No, No, No, No, No, No, No, No,
[0x78] No, Up, No, No, No, No, No, No,
};
Rune kbtabaltgr[Nscan] =
{
[0x00] No, No, No, No, No, No, No, No,
[0x08] No, No, No, No, No, No, No, No,
[0x10] No, No, No, No, No, No, No, No,
[0x18] No, No, No, No, '\n', Ctrl, No, No,
[0x20] No, No, No, No, No, No, No, No,
[0x28] No, No, Shift, No, No, No, No, No,
[0x30] No, No, No, No, No, '/', No, Print,
[0x38] Altgr, No, No, No, No, No, No, No,
[0x40] No, No, No, No, No, No, Break, Home,
[0x48] Up, Pgup, No, Left, No, Right, No, End,
[0x50] Down, Pgdown, Ins, Del, No, No, No, No,
[0x58] No, No, No, No, No, No, No, No,
[0x60] No, No, No, No, No, No, No, No,
[0x68] No, No, No, No, No, No, No, No,
[0x70] No, No, No, No, No, No, No, No,
[0x78] No, Up, No, No, No, No, No, No,
};
Rune kbtabctrl[Nscan] =
{
[0x00] No, '', '', '', '', '', '', '',
[0x08] '', '', '', '', ' ', '', '\b', '\t',
[0x10] '', '', '', '', '', '', '', '\t',
[0x18] '', '', '', '', '\n', Ctrl, '', '',
[0x20] '', '', '', '\b', '\n', ' ', ' ', '',
[0x28] '', No, Shift, '', '', '', '', '',
[0x30] '', '', ' ', ' ', '', '', Shift, '\n',
[0x38] Latin, No, Ctrl, '', '', '', '', '',
[0x40] '', '', ' ', ' ', '', '', '', '',
[0x48] '', '', ' ', '', '', '', ' ', '',
[0x50] '', '', '', '', No, No, No, '',
[0x58] ' ', No, No, No, No, No, No, No,
[0x60] No, No, No, No, No, No, No, No,
[0x68] No, No, No, No, No, No, No, No,
[0x70] No, No, No, No, No, No, No, No,
[0x78] No, '', No, '\b', No, No, No, No,
};
enum
{
/* controller command byte */
Cscs1= (1<<6), /* scan code set 1 */
Cauxdis= (1<<5), /* mouse disable */
Ckbddis= (1<<4), /* kbd disable */
Csf= (1<<2), /* system flag */
Cauxint= (1<<1), /* mouse interrupt enable */
Ckbdint= (1<<0), /* kbd interrupt enable */
};
int mouseshifted;
void (*kbdmouse)(int);
static Lock i8042lock;
static uchar ccc;
static void (*auxputc)(int, int);
static int nokbd = 1; /* flag: no PS/2 keyboard */
/*
* wait for output no longer busy
*/
static int
outready(void)
{
int tries;
for(tries = 0; (inb(Status) & Outbusy); tries++){
if(tries > 500)
return -1;
delay(2);
}
return 0;
}
/*
* wait for input
*/
static int
inready(void)
{
int tries;
for(tries = 0; !(inb(Status) & Inready); tries++){
if(tries > 500)
return -1;
delay(2);
}
return 0;
}
/*
* ask 8042 to reset the machine
*/
void
i8042reset(void)
{
int i, x;
if(nokbd)
return;
*((ushort*)KADDR(0x472)) = 0x1234; /* BIOS warm-boot flag */
/*
* newer reset the machine command
*/
outready();
outb(Cmd, 0xFE);
outready();
/*
* Pulse it by hand (old somewhat reliable)
*/
x = 0xDF;
for(i = 0; i < 5; i++){
x ^= 1;
outready();
outb(Cmd, 0xD1);
outready();
outb(Data, x); /* toggle reset */
delay(100);
}
}
int
i8042auxcmd(int cmd)
{
unsigned int c;
int tries;
static int badkbd;
if(badkbd)
return -1;
c = 0;
tries = 0;
ilock(&i8042lock);
do{
if(tries++ > 2)
break;
if(outready() < 0)
break;
outb(Cmd, 0xD4);
if(outready() < 0)
break;
outb(Data, cmd);
if(outready() < 0)
break;
if(inready() < 0)
break;
c = inb(Data);
} while(c == 0xFE || c == 0);
iunlock(&i8042lock);
if(c != 0xFA){
print("i8042: %2.2ux returned to the %2.2ux command\n", c, cmd);
badkbd = 1; /* don't keep trying; there might not be one */
return -1;
}
return 0;
}
int
i8042auxcmds(uchar *cmd, int ncmd)
{
int i;
ilock(&i8042lock);
for(i=0; i<ncmd; i++){
if(outready() < 0)
break;
outb(Cmd, 0xD4);
if(outready() < 0)
break;
outb(Data, cmd[i]);
}
iunlock(&i8042lock);
return i;
}
typedef struct Kbscan Kbscan;
struct Kbscan {
int esc1;
int esc2;
int alt;
int altgr;
int caps;
int ctl;
int num;
int shift;
int collecting;
int nk;
Rune kc[5];
int buttons;
};
Kbscan kbscans[Nscans]; /* kernel and external scan code state */
static int kdebug;
/*
* set keyboard's leds for lock states (scroll, numeric, caps).
*
* at least one keyboard (from Qtronics) also sets its numeric-lock
* behaviour to match the led state, though it has no numeric keypad,
* and some BIOSes bring the system up with numeric-lock set and no
* setting to change that. this combination steals the keys for these
* characters and makes it impossible to generate them: uiolkjm&*().
* thus we'd like to be able to force the numeric-lock led (and behaviour) off.
*/
static void
setleds(Kbscan *kbscan)
{
int leds;
if(nokbd || kbscan != &kbscans[Int])
return;
leds = 0;
if(kbscan->num)
leds |= 1<<1;
if(0 && kbscan->caps) /* we don't implement caps lock */
leds |= 1<<2;
ilock(&i8042lock);
outready();
outb(Data, 0xed); /* `reset keyboard lock states' */
outready();
outb(Data, leds);
outready();
iunlock(&i8042lock);
}
/*
* Scan code processing
*/
void
kbdputsc(int c, int external)
{
int i, keyup;
Kbscan *kbscan;
if(external)
kbscan = &kbscans[Ext];
else
kbscan = &kbscans[Int];
if(kdebug)
print("sc %x ms %d\n", c, mouseshifted);
/*
* e0's is the first of a 2 character sequence, e1 the first
* of a 3 character sequence (on the safari)
*/
if(c == 0xe0){
kbscan->esc1 = 1;
return;
} else if(c == 0xe1){
kbscan->esc2 = 2;
return;
}
keyup = c & 0x80;
c &= 0x7f;
if(c > sizeof kbtab){
c |= keyup;
if(c != 0xFF) /* these come fairly often: CAPSLOCK U Y */
print("unknown key %ux\n", c);
return;
}
if(kbscan->esc1){
c = kbtabesc1[c];
kbscan->esc1 = 0;
} else if(kbscan->esc2){
kbscan->esc2--;
return;
} else if(kbscan->shift)
c = kbtabshift[c];
else if(kbscan->altgr)
c = kbtabaltgr[c];
else if(kbscan->ctl)
c = kbtabctrl[c];
else
c = kbtab[c];
if(kbscan->caps && c<='z' && c>='a')
c += 'A' - 'a';
/*
* keyup only important for shifts
*/
if(keyup){
switch(c){
case Latin:
kbscan->alt = 0;
break;
case Shift:
kbscan->shift = 0;
mouseshifted = 0;
if(kdebug)
print("shiftclr\n");
break;
case Ctrl:
kbscan->ctl = 0;
break;
case Altgr:
kbscan->altgr = 0;
break;
case Kmouse|1:
case Kmouse|2:
case Kmouse|3:
case Kmouse|4:
case Kmouse|5:
kbscan->buttons &= ~(1<<(c-Kmouse-1));
if(kbdmouse)
kbdmouse(kbscan->buttons);
break;
}
return;
}
/*
* normal character
*/
if(!(c & (Spec|KF))){
if(kbscan->ctl)
if(kbscan->alt && c == Del)
exit(0);
if(!kbscan->collecting){
kbdputc(kbdq, c);
return;
}
kbscan->kc[kbscan->nk++] = c;
c = latin1(kbscan->kc, kbscan->nk);
if(c < -1) /* need more keystrokes */
return;
if(c != -1) /* valid sequence */
kbdputc(kbdq, c);
else /* dump characters */
for(i=0; i<kbscan->nk; i++)
kbdputc(kbdq, kbscan->kc[i]);
kbscan->nk = 0;
kbscan->collecting = 0;
return;
} else {
switch(c){
case Caps:
kbscan->caps ^= 1;
return;
case Num:
kbscan->num ^= 1;
if(!external)
setleds(kbscan);
return;
case Shift:
kbscan->shift = 1;
if(kdebug)
print("shift\n");
mouseshifted = 1;
return;
case Latin:
kbscan->alt = 1;
/*
* VMware and Qemu use Ctl-Alt as the key combination
* to make the VM give up keyboard and mouse focus.
* This has the unfortunate side effect that when you
* come back into focus, Plan 9 thinks you want to type
* a compose sequence (you just typed alt).
*
* As a clumsy hack around this, we look for ctl-alt
* and don't treat it as the start of a compose sequence.
*/
if(!kbscan->ctl){
kbscan->collecting = 1;
kbscan->nk = 0;
}
return;
case Ctrl:
kbscan->ctl = 1;
return;
case Altgr:
kbscan->altgr = 1;
return;
case Kmouse|1:
case Kmouse|2:
case Kmouse|3:
case Kmouse|4:
case Kmouse|5:
kbscan->buttons |= 1<<(c-Kmouse-1);
if(kbdmouse)
kbdmouse(kbscan->buttons);
return;
case KF|11:
print("kbd debug on, F12 turns it off\n");
kdebug = 1;
break;
case KF|12:
kdebug = 0;
break;
}
}
kbdputc(kbdq, c);
}
/*
* keyboard interrupt
*/
static void
i8042intr(Ureg*, void*)
{
int s, c;
/*
* get status
*/
ilock(&i8042lock);
s = inb(Status);
if(!(s&Inready)){
iunlock(&i8042lock);
return;
}
/*
* get the character
*/
c = inb(Data);
iunlock(&i8042lock);
/*
* if it's the aux port...
*/
if(s & Minready){
if(auxputc != nil)
auxputc(c, kbscans[Int].shift);
return;
}
kbdputsc(c, Int);
}
void
i8042auxenable(void (*putc)(int, int))
{
char *err = "i8042: aux init failed\n";
/* enable kbd/aux xfers and interrupts */
ccc &= ~Cauxdis;
ccc |= Cauxint;
ilock(&i8042lock);
if(outready() < 0)
print(err);
outb(Cmd, 0x60); /* write control register */
if(outready() < 0)
print(err);
outb(Data, ccc);
if(outready() < 0)
print(err);
outb(Cmd, 0xA8); /* auxiliary device enable */
if(outready() < 0){
iunlock(&i8042lock);
return;
}
auxputc = putc;
intrenable(IrqAUX, i8042intr, 0, BUSUNKNOWN, "kbdaux");
iunlock(&i8042lock);
}
static char *initfailed = "i8042: kbdinit failed\n";
static int
outbyte(int port, int c)
{
outb(port, c);
if(outready() < 0) {
print(initfailed);
return -1;
}
return 0;
}
void
kbdinit(void)
{
int c, try;
/* wait for a quiescent controller */
try = 1000;
while(try-- > 0 && (c = inb(Status)) & (Outbusy | Inready)) {
if(c & Inready)
inb(Data);
delay(1);
}
if (try <= 0) {
print(initfailed);
return;
}
/* get current controller command byte */
outb(Cmd, 0x20);
if(inready() < 0){
print("i8042: kbdinit can't read ccc\n");
ccc = 0;
} else
ccc = inb(Data);
/* enable kbd xfers and interrupts */
ccc &= ~Ckbddis;
ccc |= Csf | Ckbdint | Cscs1;
if(outready() < 0) {
print(initfailed);
return;
}
nokbd = 0;
/* disable mouse */
if (outbyte(Cmd, 0x60) < 0 || outbyte(Data, ccc) < 0)
print("i8042: kbdinit mouse disable failed\n");
}
void
kbdenable(void)
{
kbdq = qopen(4*1024, 0, 0, 0);
if(kbdq == nil)
panic("kbdinit");
qnoblock(kbdq, 1);
ioalloc(Data, 1, 0, "kbd");
ioalloc(Cmd, 1, 0, "kbd");
intrenable(IrqKBD, i8042intr, 0, BUSUNKNOWN, "kbd");
kbscans[Int].num = 0;
setleds(&kbscans[Int]);
}
void
kbdputmap(ushort m, ushort scanc, Rune r)
{
if(scanc >= Nscan)
error(Ebadarg);
switch(m) {
default:
error(Ebadarg);
case 0:
kbtab[scanc] = r;
break;
case 1:
kbtabshift[scanc] = r;
break;
case 2:
kbtabesc1[scanc] = r;
break;
case 3:
kbtabaltgr[scanc] = r;
break;
case 4:
kbtabctrl[scanc] = r;
break;
}
}
int
kbdgetmap(uint offset, int *t, int *sc, Rune *r)
{
if ((int)offset < 0)
error(Ebadarg);
*t = offset/Nscan;
*sc = offset%Nscan;
switch(*t) {
default:
return 0;
case 0:
*r = kbtab[*sc];
return 1;
case 1:
*r = kbtabshift[*sc];
return 1;
case 2:
*r = kbtabesc1[*sc];
return 1;
case 3:
*r = kbtabaltgr[*sc];
return 1;
case 4:
*r = kbtabctrl[*sc];
return 1;
}
}

View file

@ -1,6 +1,6 @@
CONF=pc
CONFLIST=pc pccpu pcf pccpuf
CRAPLIST=pccd pcflop
CONF=pcf
CONFLIST=pcf pccpuf
CRAPLIST=pc pccpu pccd pcflop
EXTRACOPIES=
#EXTRACOPIES=lookout boundary # copy to these servers on install
@ -49,7 +49,6 @@ OBJ=\
cga.$O\
i8253.$O\
i8259.$O\
kbd.$O\
main.$O\
memory.$O\
mmu.$O\

View file

@ -22,8 +22,6 @@ enum
MousePS2= 2,
};
extern int mouseshifted;
static QLock mousectlqlock;
static int mousetype;
static int intellimouse;
@ -95,11 +93,6 @@ ps2mouseputc(int c, int shift)
ulong m;
int buttons, dx, dy;
/*
* non-ps2 keyboards might not set shift
* but still set mouseshifted.
*/
shift |= mouseshifted;
/*
* Resynchronize in stream with timing; see comment above.
*/

View file

@ -1,134 +0,0 @@
dev
root
cons
arch
pnp pci
env
pipe
proc
mnt
srv
dup
rtc
ssl
tls
cap
kprof
fs
ether netif
ip arp chandial ip ipv6 ipaux iproute netlog nullmedium pktmedium ptclbsum386 inferno
draw screen vga vgax
mouse mouse
vga
kbmap
kbin
sd
floppy dma
lpt
audio dma
pccard
i82365 cis
uart
usb
link
realmode
devpccard
devi82365
ether2000 ether8390
ether2114x pci
ether589 etherelnk3
ether79c970 pci
ether8003 ether8390
ether8139 pci
ether8169 pci ethermii
ether82543gc pci
ether82563 pci
ether82557 pci
ether83815 pci
etherbcm pci
etherdp83820 pci
etherec2t ether8390
etherelnk3 pci
etherga620 pci
etherigbe pci ethermii
ethervgbe pci ethermii
ethervt6102 pci ethermii
ethervt6105m pci ethermii
ethersink
ethersmc devi82365 cis
etherwavelan wavelan devi82365 cis pci
ethermedium
# etherm10g
ether82598 pci
pcmciamodem
netdevmedium
loopbackmedium
usbuhci
usbohci
usbehci usbehcipc
misc
archmp mp apic
mtrr
sdata pci sdscsi
sd53c8xx pci sdscsi
sdmylex pci sdscsi
sdiahci pci sdscsi
uarti8250
uartpci pci
uartisa
vga3dfx +cur
vgaark2000pv +cur
vgabt485 =cur
vgaclgd542x +cur
vgaclgd546x +cur
vgact65545 +cur
vgacyber938x +cur
vgaet4000 +cur
vgahiqvideo +cur
vgai81x +cur
vgamach64xx +cur
vgamga2164w +cur
vgamga4xx +cur
vganeomagic +cur
vganvidia +cur
vgargb524 =cur
vgas3 +cur vgasavage
vgat2r4 +cur
vgatvp3020 =cur
vgatvp3026 =cur
vgavesa
vgavmware +cur
vgageode +cur
ip
tcp
udp
ipifc
icmp
icmp6
gre
ipmux
esp
port
int cpuserver = 0;
boot
tcp
bootdir
bootpc.out boot
/386/bin/ip/ipconfig
/386/bin/auth/factotum
/386/bin/usb/usbd

View file

@ -1,99 +0,0 @@
# pccpu - cpu server kernel
dev
root
cons
arch
pnp pci
env
pipe
proc
mnt
srv
dup
rtc
ssl
tls
bridge log
sdp thwack unthwack
cap
kprof
fs
segment
ether netif
ip arp chandial ip ipv6 ipaux iproute netlog nullmedium pktmedium ptclbsum386 inferno
sd
floppy dma
aoe
uart
usb
kbin
audio
link
realmode
ether2000 ether8390
ether2114x pci
ether79c970 pci
ether8003 ether8390
ether8139 pci
ether8169 pci ethermii
ether82543gc pci
ether82563 pci
ether82557 pci
ether83815 pci
etherdp83820 pci
etherelnk3 pci
etherga620 pci
etherigbe pci ethermii
ethervgbe pci ethermii
ethervt6102 pci ethermii
ethervt6105m pci ethermii
# etherm10g pci ethermii
ether82598 pci
ethersink
ethermedium
loopbackmedium
usbuhci
usbohci
usbehci usbehcipc
misc
archmp mp apic
mtrr
uarti8250
uartpci pci
uartaxp pci
sdata pci sdscsi
sd53c8xx pci sdscsi
sdmv50xx pci sdscsi
sdmylex pci sdscsi
sdiahci pci sdscsi
sdaoe sdscsi
ip
tcp
udp
ipifc
icmp
icmp6
gre
ipmux
esp
rudp
port
int cpuserver = 1;
boot cpu
tcp
bootdir
bootpccpu.out boot
/386/bin/ip/ipconfig ipconfig
/386/bin/auth/factotum
/386/bin/usb/usbd

View file

@ -24,6 +24,7 @@ dev
draw screen vga vgax
mouse mouse
kbd
vga
sd
@ -32,7 +33,6 @@ dev
uart
usb
kbin
link
realmode

View file

@ -22,9 +22,8 @@ dev
draw screen vga vgax
mouse mouse
kbd
vga
kbmap
kbin
sd
floppy dma

View file

@ -133,6 +133,7 @@ hostownerwrite(char *a, int n)
buf[n] = 0;
renameuser(eve, buf);
srvrenameuser(eve, buf);
kstrdup(&eve, buf);
kstrdup(&up->user, buf);
up->basepri = PriNormal;

View file

@ -2,6 +2,8 @@ $cputype
bin
9660srv
awk
aux
kbdfs
bind
bzfs
cat

View file

@ -11,8 +11,6 @@
void (*consdebug)(void) = nil;
void (*screenputs)(char*, int) = nil;
Queue* kbdq; /* unprocessed console input */
Queue* lineq; /* processed console input */
Queue* serialoq; /* serial console output */
Queue* kprintoq; /* console output, for /dev/kprint */
ulong kprintinuse; /* test and set whether /dev/kprint is open */
@ -20,30 +18,6 @@ int iprintscreenputs = 1;
int panicking;
static struct
{
QLock;
int raw; /* true if we shouldn't process input */
Ref ctl; /* number of opens to the control file */
int x; /* index into line */
char line[1024]; /* current input line */
int count;
int ctlpoff;
/* a place to save up characters at interrupt time before dumping them in the queue */
Lock lockputc;
char istage[1024];
char *iw;
char *ir;
char *ie;
} kbd = {
.iw = kbd.istage,
.ir = kbd.istage,
.ie = kbd.istage + sizeof(kbd.istage),
};
char *sysname;
vlong fasthz;
@ -70,10 +44,6 @@ Cmdtab rebootmsg[] =
void
printinit(void)
{
lineq = qopen(2*1024, 0, nil, nil);
if(lineq == nil)
panic("printinit");
qnoblock(lineq, 1);
}
int
@ -179,7 +149,7 @@ putstrn0(char *str, int n, int usewrite)
while(n > 0) {
t = memchr(str, '\n', n);
if(t && !kbd.raw) {
if(t) {
m = t-str;
if(usewrite){
qwrite(serialoq, str, m);
@ -206,8 +176,6 @@ putstrn(char *str, int n)
putstrn0(str, n, 0);
}
int noprint;
int
print(char *fmt, ...)
{
@ -215,9 +183,6 @@ print(char *fmt, ...)
va_list arg;
char buf[PRINTSIZE];
if(noprint)
return -1;
va_start(arg, fmt);
n = vseprint(buf, buf+sizeof(buf), fmt, arg) - buf;
va_end(arg);
@ -350,231 +315,10 @@ pprint(char *fmt, ...)
return n;
}
static void
echoscreen(char *buf, int n)
{
char *e, *p;
char ebuf[128];
int x;
p = ebuf;
e = ebuf + sizeof(ebuf) - 4;
while(n-- > 0){
if(p >= e){
screenputs(ebuf, p - ebuf);
p = ebuf;
}
x = *buf++;
if(x == 0x15){
*p++ = '^';
*p++ = 'U';
*p++ = '\n';
} else
*p++ = x;
}
if(p != ebuf)
screenputs(ebuf, p - ebuf);
}
static void
echoserialoq(char *buf, int n)
{
char *e, *p;
char ebuf[128];
int x;
p = ebuf;
e = ebuf + sizeof(ebuf) - 4;
while(n-- > 0){
if(p >= e){
qiwrite(serialoq, ebuf, p - ebuf);
p = ebuf;
}
x = *buf++;
if(x == '\n'){
*p++ = '\r';
*p++ = '\n';
} else if(x == 0x15){
*p++ = '^';
*p++ = 'U';
*p++ = '\n';
} else
*p++ = x;
}
if(p != ebuf)
qiwrite(serialoq, ebuf, p - ebuf);
}
static void
echo(char *buf, int n)
{
static int ctrlt, pid;
int x;
char *e, *p;
if(n == 0)
return;
e = buf+n;
for(p = buf; p < e; p++){
switch(*p){
case 0x10: /* ^P */
if(cpuserver && !kbd.ctlpoff){
active.exiting = 1;
return;
}
break;
case 0x14: /* ^T */
ctrlt++;
if(ctrlt > 2)
ctrlt = 2;
continue;
}
if(ctrlt != 2)
continue;
/* ^T escapes */
ctrlt = 0;
switch(*p){
case 'S':
x = splhi();
dumpstack();
procdump();
splx(x);
return;
case 's':
dumpstack();
return;
case 'x':
xsummary();
ixsummary();
mallocsummary();
// memorysummary();
pagersummary();
return;
case 'd':
if(consdebug == nil)
consdebug = rdb;
else
consdebug = nil;
print("consdebug now %#p\n", consdebug);
return;
case 'D':
if(consdebug == nil)
consdebug = rdb;
consdebug();
return;
case 'p':
x = spllo();
procdump();
splx(x);
return;
case 'q':
scheddump();
return;
case 'k':
killbig("^t ^t k");
return;
case 'r':
exit(0);
return;
}
}
qproduce(kbdq, buf, n);
if(kbd.raw)
return;
kmesgputs(buf, n);
if(screenputs != nil)
echoscreen(buf, n);
if(serialoq)
echoserialoq(buf, n);
}
/*
* Called by a uart interrupt for console input.
*
* turn '\r' into '\n' before putting it into the queue.
*/
int
kbdcr2nl(Queue*, int ch)
{
char *next;
ilock(&kbd.lockputc); /* just a mutex */
if(ch == '\r' && !kbd.raw)
ch = '\n';
next = kbd.iw+1;
if(next >= kbd.ie)
next = kbd.istage;
if(next != kbd.ir){
*kbd.iw = ch;
kbd.iw = next;
}
iunlock(&kbd.lockputc);
return 0;
}
/*
* Put character, possibly a rune, into read queue at interrupt time.
* Called at interrupt time to process a character.
*/
int
kbdputc(Queue*, int ch)
{
int i, n;
char buf[3];
Rune r;
char *next;
if(kbd.ir == nil)
return 0; /* in case we're not inited yet */
ilock(&kbd.lockputc); /* just a mutex */
r = ch;
n = runetochar(buf, &r);
for(i = 0; i < n; i++){
next = kbd.iw+1;
if(next >= kbd.ie)
next = kbd.istage;
if(next == kbd.ir)
break;
*kbd.iw = buf[i];
kbd.iw = next;
}
iunlock(&kbd.lockputc);
return 0;
}
/*
* we save up input characters till clock time to reduce
* per character interrupt overhead.
*/
static void
kbdputcclock(void)
{
char *iw;
/* this amortizes cost of qproduce */
if(kbd.iw != kbd.ir){
iw = kbd.iw;
if(iw < kbd.ir){
echo(kbd.ir, kbd.ie-kbd.ir);
kbd.ir = kbd.istage;
}
if(kbd.ir != iw){
echo(kbd.ir, iw-kbd.ir);
kbd.ir = iw;
}
}
}
enum{
Qdir,
Qbintime,
Qcons,
Qconsctl,
Qcputime,
Qdrivers,
Qkmesg,
@ -607,7 +351,6 @@ static Dirtab consdir[]={
".", {Qdir, 0, QTDIR}, 0, DMDIR|0555,
"bintime", {Qbintime}, 24, 0664,
"cons", {Qcons}, 0, 0660,
"consctl", {Qconsctl}, 0, 0220,
"cputime", {Qcputime}, 6*NUMSIZE, 0444,
"drivers", {Qdrivers}, 0, 0444,
"hostdomain", {Qhostdomain}, DOMLEN, 0664,
@ -665,11 +408,6 @@ consinit(void)
{
todinit();
randominit();
/*
* at 115200 baud, the 1024 char buffer takes 56 ms to process,
* processing it every 22 ms should be fine
*/
addclock0link(kbdputcclock, 22);
}
static Chan*
@ -696,10 +434,6 @@ consopen(Chan *c, int omode)
c->aux = nil;
c = devopen(c, omode, consdir, nelem(consdir), devgen);
switch((ulong)c->qid.path){
case Qconsctl:
incref(&kbd.ctl);
break;
case Qkprint:
if(tas(&kprintinuse) != 0){
c->flag &= ~COPEN;
@ -724,14 +458,6 @@ static void
consclose(Chan *c)
{
switch((ulong)c->qid.path){
/* last close of control file turns off raw */
case Qconsctl:
if(c->flag&COPEN){
if(decref(&kbd.ctl) == 0)
kbd.raw = 0;
}
break;
/* close of kprint allows other opens */
case Qkprint:
if(c->flag & COPEN){
@ -747,9 +473,9 @@ consread(Chan *c, void *buf, long n, vlong off)
{
ulong l;
Mach *mp;
char *b, *bp, ch;
char *b, *bp;
char tmp[256]; /* must be >= 18*NUMSIZE (Qswap) */
int i, k, id, send;
int i, k, id;
vlong offset = off;
extern char configfile[];
@ -761,49 +487,7 @@ consread(Chan *c, void *buf, long n, vlong off)
return devdirread(c, buf, n, consdir, nelem(consdir), devgen);
case Qcons:
qlock(&kbd);
if(waserror()) {
qunlock(&kbd);
nexterror();
}
while(!qcanread(lineq)){
if(qread(kbdq, &ch, 1) == 0)
continue;
send = 0;
if(ch == 0){
/* flush output on rawoff -> rawon */
if(kbd.x > 0)
send = !qcanread(kbdq);
}else if(kbd.raw){
kbd.line[kbd.x++] = ch;
send = !qcanread(kbdq);
}else{
switch(ch){
case '\b':
if(kbd.x > 0)
kbd.x--;
break;
case 0x15: /* ^U */
kbd.x = 0;
break;
case '\n':
case 0x04: /* ^D */
send = 1;
default:
if(ch != 0x04)
kbd.line[kbd.x++] = ch;
break;
}
}
if(send || kbd.x == sizeof kbd.line){
qwrite(lineq, kbd.line, kbd.x);
kbd.x = 0;
}
}
n = qread(lineq, buf, n);
qunlock(&kbd);
poperror();
return n;
error(Egreg);
case Qcputime:
k = offset;
@ -980,7 +664,7 @@ consread(Chan *c, void *buf, long n, vlong off)
static long
conswrite(Chan *c, void *va, long n, vlong off)
{
char buf[256], ch;
char buf[256];
long l, bp;
char *a;
Mach *mp;
@ -1010,29 +694,6 @@ conswrite(Chan *c, void *va, long n, vlong off)
}
break;
case Qconsctl:
if(n >= sizeof(buf))
n = sizeof(buf)-1;
strncpy(buf, a, n);
buf[n] = 0;
for(a = buf; a;){
if(strncmp(a, "rawon", 5) == 0){
kbd.raw = 1;
/* clumsy hack - wake up reader */
ch = 0;
qwrite(kbdq, &ch, 1);
} else if(strncmp(a, "rawoff", 6) == 0){
kbd.raw = 0;
} else if(strncmp(a, "ctlpon", 6) == 0){
kbd.ctlpoff = 0;
} else if(strncmp(a, "ctlpoff", 7) == 0){
kbd.ctlpoff = 1;
}
if(a = strchr(a, ' '))
a++;
}
break;
case Qtime:
if(!iseve())
error(Eperm);

View file

@ -1,120 +0,0 @@
/*
* keyboard scan code input from outside the kernel.
* to avoid duplication of keyboard map processing for usb.
*/
#include "u.h"
#include "../port/lib.h"
#include "mem.h"
#include "dat.h"
#include "fns.h"
#include "../port/error.h"
extern void kbdputsc(int, int);
enum {
Qdir,
Qkbd,
};
Dirtab kbintab[] = {
".", {Qdir, 0, QTDIR}, 0, 0555,
"kbin", {Qkbd, 0}, 0, 0200,
};
Lock kbinlck;
int kbinbusy;
static Chan *
kbinattach(char *spec)
{
return devattach(L'Ι', spec);
}
static Walkqid*
kbinwalk(Chan *c, Chan *nc, char **name, int nname)
{
return devwalk(c, nc, name, nname, kbintab, nelem(kbintab), devgen);
}
static int
kbinstat(Chan *c, uchar *dp, int n)
{
return devstat(c, dp, n, kbintab, nelem(kbintab), devgen);
}
static Chan*
kbinopen(Chan *c, int omode)
{
if(!iseve())
error(Eperm);
if(c->qid.path == Qkbd){
lock(&kbinlck);
if(kbinbusy){
unlock(&kbinlck);
error(Einuse);
}
kbinbusy++;
unlock(&kbinlck);
}
return devopen(c, omode, kbintab, nelem(kbintab), devgen);
}
static void
kbinclose(Chan *c)
{
if(c->aux){
free(c->aux);
c->aux = nil;
}
if(c->qid.path == Qkbd)
kbinbusy = 0;
}
static long
kbinread(Chan *c, void *a, long n, vlong )
{
if(c->qid.type == QTDIR)
return devdirread(c, a, n, kbintab, nelem(kbintab), devgen);
return 0;
}
static long
kbinwrite(Chan *c, void *a, long n, vlong)
{
int i;
uchar *p = a;
if(c->qid.type == QTDIR)
error(Eisdir);
switch((int)c->qid.path){
case Qkbd:
for(i = 0; i < n; i++)
kbdputsc(*p++, 1); /* external source */
break;
default:
error(Egreg);
}
return n;
}
Dev kbindevtab = {
L'Ι',
"kbin",
devreset,
devinit,
devshutdown,
kbinattach,
kbinwalk,
kbinstat,
kbinopen,
devcreate,
kbinclose,
kbinread,
devbread,
kbinwrite,
devbwrite,
devremove,
devwstat,
};

View file

@ -1,179 +0,0 @@
/*
* keyboard map
*/
#include "u.h"
#include "../port/lib.h"
#include "mem.h"
#include "dat.h"
#include "fns.h"
#include "../port/error.h"
enum{
Qdir,
Qdata,
};
Dirtab kbmaptab[]={
".", {Qdir, 0, QTDIR}, 0, 0555,
"kbmap", {Qdata, 0}, 0, 0600,
};
#define NKBFILE sizeof(kbmaptab)/sizeof(kbmaptab[0])
#define KBLINELEN (3*NUMSIZE+1) /* t code val\n */
static Chan *
kbmapattach(char *spec)
{
return devattach(L'κ', spec);
}
static Walkqid*
kbmapwalk(Chan *c, Chan *nc, char **name, int nname)
{
return devwalk(c, nc, name, nname, kbmaptab, NKBFILE, devgen);
}
static int
kbmapstat(Chan *c, uchar *dp, int n)
{
return devstat(c, dp, n, kbmaptab, NKBFILE, devgen);
}
static Chan*
kbmapopen(Chan *c, int omode)
{
if(!iseve())
error(Eperm);
return devopen(c, omode, kbmaptab, NKBFILE, devgen);
}
static void
kbmapclose(Chan *c)
{
if(c->aux){
free(c->aux);
c->aux = nil;
}
}
static long
kbmapread(Chan *c, void *a, long n, vlong offset)
{
char *bp;
char tmp[KBLINELEN+1];
int t, sc;
Rune r;
if(c->qid.type == QTDIR)
return devdirread(c, a, n, kbmaptab, NKBFILE, devgen);
switch((int)(c->qid.path)){
case Qdata:
if(kbdgetmap(offset/KBLINELEN, &t, &sc, &r)) {
bp = tmp;
bp += readnum(0, bp, NUMSIZE, t, NUMSIZE);
bp += readnum(0, bp, NUMSIZE, sc, NUMSIZE);
bp += readnum(0, bp, NUMSIZE, r, NUMSIZE);
*bp++ = '\n';
*bp = 0;
n = readstr(offset%KBLINELEN, a, n, tmp);
} else
n = 0;
break;
default:
n=0;
break;
}
return n;
}
static long
kbmapwrite(Chan *c, void *a, long n, vlong)
{
char line[100], *lp, *b;
int key, m, l;
Rune r;
if(c->qid.type == QTDIR)
error(Eperm);
switch((int)(c->qid.path)){
case Qdata:
b = a;
l = n;
lp = line;
if(c->aux){
strcpy(line, c->aux);
lp = line+strlen(line);
free(c->aux);
c->aux = nil;
}
while(--l >= 0) {
*lp++ = *b++;
if(lp[-1] == '\n' || lp == &line[sizeof(line)-1]) {
*lp = 0;
if(*line == 0)
error(Ebadarg);
if(*line == '\n' || *line == '#'){
lp = line;
continue;
}
lp = line;
while(*lp == ' ' || *lp == '\t')
lp++;
m = strtoul(line, &lp, 0);
key = strtoul(lp, &lp, 0);
while(*lp == ' ' || *lp == '\t')
lp++;
r = 0;
if(*lp == '\'' && lp[1])
chartorune(&r, lp+1);
else if(*lp == '^' && lp[1]){
chartorune(&r, lp+1);
if(0x40 <= r && r < 0x60)
r -= 0x40;
else
error(Ebadarg);
}else if(*lp == 'M' && ('1' <= lp[1] && lp[1] <= '5'))
r = 0xF900+lp[1]-'0';
else if(*lp>='0' && *lp<='9') /* includes 0x... */
r = strtoul(lp, &lp, 0);
else
error(Ebadarg);
kbdputmap(m, key, r);
lp = line;
}
}
if(lp != line){
l = lp-line;
c->aux = lp = smalloc(l+1);
memmove(lp, line, l);
lp[l] = 0;
}
break;
default:
error(Ebadusefd);
}
return n;
}
Dev kbmapdevtab = {
L'κ',
"kbmap",
devreset,
devinit,
devshutdown,
kbmapattach,
kbmapwalk,
kbmapstat,
kbmapopen,
devcreate,
kbmapclose,
kbmapread,
devbread,
kbmapwrite,
devbwrite,
devremove,
devwstat,
};

View file

@ -352,3 +352,15 @@ Dev srvdevtab = {
srvremove,
srvwstat,
};
void
srvrenameuser(char *old, char *new)
{
Srv *sp;
qlock(&srvlk);
for(sp = srv; sp; sp = sp->link)
if(sp->owner!=nil && strcmp(old, sp->owner)==0)
kstrdup(&sp->owner, new);
qunlock(&srvlk);
}

View file

@ -223,9 +223,7 @@ uartreset(void)
if(p->console || p->special){
if(uartenable(p) != nil){
if(p->console){
kbdq = p->iq;
serialoq = p->oq;
p->putc = kbdcr2nl;
}
p->opens++;
}

View file

@ -142,10 +142,6 @@ Segment* isoverlap(Proc*, ulong, int);
int ispages(void*);
int isphysseg(char*);
void ixsummary(void);
int kbdcr2nl(Queue*, int);
int kbdgetmap(uint, int*, int*, Rune*);
int kbdputc(Queue*, int);
void kbdputmap(ushort, ushort, Rune);
void kickpager(void);
void killbig(char*);
void kproc(char*, void(*)(void*), void*);
@ -323,6 +319,7 @@ int spllo(void);
void splx(int);
void splxpc(int);
char* srvname(Chan*);
void srvrenameuser(char*, char*);
int swapcount(ulong);
int swapfull(void);
void swapinit(void);

1159
sys/src/cmd/aux/kbdfs.c Normal file

File diff suppressed because it is too large Load diff

View file

@ -16,6 +16,7 @@ TARG=\
depend\
disksim\
getflags\
kbdfs\
lines\
listen\
listen1\