kbdfs
This commit is contained in:
parent
67856b4507
commit
26c2845917
|
@ -14,6 +14,7 @@ bind -a #S /dev
|
||||||
|
|
||||||
# mount points
|
# mount points
|
||||||
mount -a /srv/slashn /n
|
mount -a /srv/slashn /n
|
||||||
|
mount -b /srv/cons /dev
|
||||||
|
|
||||||
# authentication
|
# authentication
|
||||||
mount -a /srv/factotum /mnt
|
mount -a /srv/factotum /mnt
|
||||||
|
|
|
@ -2,6 +2,12 @@
|
||||||
|
|
||||||
bind -q '#p' /proc
|
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 '#S' /dev
|
||||||
bind -qa '#f' /dev
|
bind -qa '#f' /dev
|
||||||
bind -qa '#k' /dev
|
bind -qa '#k' /dev
|
||||||
|
|
481
sys/src/9/pc/devkbd.c
Normal file
481
sys/src/9/pc/devkbd.c
Normal 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");
|
||||||
|
}
|
|
@ -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;
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -1,6 +1,6 @@
|
||||||
CONF=pc
|
CONF=pcf
|
||||||
CONFLIST=pc pccpu pcf pccpuf
|
CONFLIST=pcf pccpuf
|
||||||
CRAPLIST=pccd pcflop
|
CRAPLIST=pc pccpu pccd pcflop
|
||||||
EXTRACOPIES=
|
EXTRACOPIES=
|
||||||
#EXTRACOPIES=lookout boundary # copy to these servers on install
|
#EXTRACOPIES=lookout boundary # copy to these servers on install
|
||||||
|
|
||||||
|
@ -49,7 +49,6 @@ OBJ=\
|
||||||
cga.$O\
|
cga.$O\
|
||||||
i8253.$O\
|
i8253.$O\
|
||||||
i8259.$O\
|
i8259.$O\
|
||||||
kbd.$O\
|
|
||||||
main.$O\
|
main.$O\
|
||||||
memory.$O\
|
memory.$O\
|
||||||
mmu.$O\
|
mmu.$O\
|
||||||
|
|
|
@ -22,8 +22,6 @@ enum
|
||||||
MousePS2= 2,
|
MousePS2= 2,
|
||||||
};
|
};
|
||||||
|
|
||||||
extern int mouseshifted;
|
|
||||||
|
|
||||||
static QLock mousectlqlock;
|
static QLock mousectlqlock;
|
||||||
static int mousetype;
|
static int mousetype;
|
||||||
static int intellimouse;
|
static int intellimouse;
|
||||||
|
@ -95,11 +93,6 @@ ps2mouseputc(int c, int shift)
|
||||||
ulong m;
|
ulong m;
|
||||||
int buttons, dx, dy;
|
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.
|
* Resynchronize in stream with timing; see comment above.
|
||||||
*/
|
*/
|
||||||
|
|
134
sys/src/9/pc/pc
134
sys/src/9/pc/pc
|
@ -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
|
|
|
@ -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
|
|
|
@ -24,6 +24,7 @@ dev
|
||||||
|
|
||||||
draw screen vga vgax
|
draw screen vga vgax
|
||||||
mouse mouse
|
mouse mouse
|
||||||
|
kbd
|
||||||
vga
|
vga
|
||||||
|
|
||||||
sd
|
sd
|
||||||
|
@ -32,7 +33,6 @@ dev
|
||||||
|
|
||||||
uart
|
uart
|
||||||
usb
|
usb
|
||||||
kbin
|
|
||||||
|
|
||||||
link
|
link
|
||||||
realmode
|
realmode
|
||||||
|
|
|
@ -22,9 +22,8 @@ dev
|
||||||
|
|
||||||
draw screen vga vgax
|
draw screen vga vgax
|
||||||
mouse mouse
|
mouse mouse
|
||||||
|
kbd
|
||||||
vga
|
vga
|
||||||
kbmap
|
|
||||||
kbin
|
|
||||||
|
|
||||||
sd
|
sd
|
||||||
floppy dma
|
floppy dma
|
||||||
|
|
|
@ -133,6 +133,7 @@ hostownerwrite(char *a, int n)
|
||||||
buf[n] = 0;
|
buf[n] = 0;
|
||||||
|
|
||||||
renameuser(eve, buf);
|
renameuser(eve, buf);
|
||||||
|
srvrenameuser(eve, buf);
|
||||||
kstrdup(&eve, buf);
|
kstrdup(&eve, buf);
|
||||||
kstrdup(&up->user, buf);
|
kstrdup(&up->user, buf);
|
||||||
up->basepri = PriNormal;
|
up->basepri = PriNormal;
|
||||||
|
|
|
@ -2,6 +2,8 @@ $cputype
|
||||||
bin
|
bin
|
||||||
9660srv
|
9660srv
|
||||||
awk
|
awk
|
||||||
|
aux
|
||||||
|
kbdfs
|
||||||
bind
|
bind
|
||||||
bzfs
|
bzfs
|
||||||
cat
|
cat
|
||||||
|
|
|
@ -11,8 +11,6 @@
|
||||||
void (*consdebug)(void) = nil;
|
void (*consdebug)(void) = nil;
|
||||||
void (*screenputs)(char*, int) = nil;
|
void (*screenputs)(char*, int) = nil;
|
||||||
|
|
||||||
Queue* kbdq; /* unprocessed console input */
|
|
||||||
Queue* lineq; /* processed console input */
|
|
||||||
Queue* serialoq; /* serial console output */
|
Queue* serialoq; /* serial console output */
|
||||||
Queue* kprintoq; /* console output, for /dev/kprint */
|
Queue* kprintoq; /* console output, for /dev/kprint */
|
||||||
ulong kprintinuse; /* test and set whether /dev/kprint is open */
|
ulong kprintinuse; /* test and set whether /dev/kprint is open */
|
||||||
|
@ -20,30 +18,6 @@ int iprintscreenputs = 1;
|
||||||
|
|
||||||
int panicking;
|
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;
|
char *sysname;
|
||||||
vlong fasthz;
|
vlong fasthz;
|
||||||
|
|
||||||
|
@ -70,10 +44,6 @@ Cmdtab rebootmsg[] =
|
||||||
void
|
void
|
||||||
printinit(void)
|
printinit(void)
|
||||||
{
|
{
|
||||||
lineq = qopen(2*1024, 0, nil, nil);
|
|
||||||
if(lineq == nil)
|
|
||||||
panic("printinit");
|
|
||||||
qnoblock(lineq, 1);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
int
|
int
|
||||||
|
@ -179,7 +149,7 @@ putstrn0(char *str, int n, int usewrite)
|
||||||
|
|
||||||
while(n > 0) {
|
while(n > 0) {
|
||||||
t = memchr(str, '\n', n);
|
t = memchr(str, '\n', n);
|
||||||
if(t && !kbd.raw) {
|
if(t) {
|
||||||
m = t-str;
|
m = t-str;
|
||||||
if(usewrite){
|
if(usewrite){
|
||||||
qwrite(serialoq, str, m);
|
qwrite(serialoq, str, m);
|
||||||
|
@ -206,8 +176,6 @@ putstrn(char *str, int n)
|
||||||
putstrn0(str, n, 0);
|
putstrn0(str, n, 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
int noprint;
|
|
||||||
|
|
||||||
int
|
int
|
||||||
print(char *fmt, ...)
|
print(char *fmt, ...)
|
||||||
{
|
{
|
||||||
|
@ -215,9 +183,6 @@ print(char *fmt, ...)
|
||||||
va_list arg;
|
va_list arg;
|
||||||
char buf[PRINTSIZE];
|
char buf[PRINTSIZE];
|
||||||
|
|
||||||
if(noprint)
|
|
||||||
return -1;
|
|
||||||
|
|
||||||
va_start(arg, fmt);
|
va_start(arg, fmt);
|
||||||
n = vseprint(buf, buf+sizeof(buf), fmt, arg) - buf;
|
n = vseprint(buf, buf+sizeof(buf), fmt, arg) - buf;
|
||||||
va_end(arg);
|
va_end(arg);
|
||||||
|
@ -350,231 +315,10 @@ pprint(char *fmt, ...)
|
||||||
return n;
|
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{
|
enum{
|
||||||
Qdir,
|
Qdir,
|
||||||
Qbintime,
|
Qbintime,
|
||||||
Qcons,
|
Qcons,
|
||||||
Qconsctl,
|
|
||||||
Qcputime,
|
Qcputime,
|
||||||
Qdrivers,
|
Qdrivers,
|
||||||
Qkmesg,
|
Qkmesg,
|
||||||
|
@ -607,7 +351,6 @@ static Dirtab consdir[]={
|
||||||
".", {Qdir, 0, QTDIR}, 0, DMDIR|0555,
|
".", {Qdir, 0, QTDIR}, 0, DMDIR|0555,
|
||||||
"bintime", {Qbintime}, 24, 0664,
|
"bintime", {Qbintime}, 24, 0664,
|
||||||
"cons", {Qcons}, 0, 0660,
|
"cons", {Qcons}, 0, 0660,
|
||||||
"consctl", {Qconsctl}, 0, 0220,
|
|
||||||
"cputime", {Qcputime}, 6*NUMSIZE, 0444,
|
"cputime", {Qcputime}, 6*NUMSIZE, 0444,
|
||||||
"drivers", {Qdrivers}, 0, 0444,
|
"drivers", {Qdrivers}, 0, 0444,
|
||||||
"hostdomain", {Qhostdomain}, DOMLEN, 0664,
|
"hostdomain", {Qhostdomain}, DOMLEN, 0664,
|
||||||
|
@ -665,11 +408,6 @@ consinit(void)
|
||||||
{
|
{
|
||||||
todinit();
|
todinit();
|
||||||
randominit();
|
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*
|
static Chan*
|
||||||
|
@ -696,10 +434,6 @@ consopen(Chan *c, int omode)
|
||||||
c->aux = nil;
|
c->aux = nil;
|
||||||
c = devopen(c, omode, consdir, nelem(consdir), devgen);
|
c = devopen(c, omode, consdir, nelem(consdir), devgen);
|
||||||
switch((ulong)c->qid.path){
|
switch((ulong)c->qid.path){
|
||||||
case Qconsctl:
|
|
||||||
incref(&kbd.ctl);
|
|
||||||
break;
|
|
||||||
|
|
||||||
case Qkprint:
|
case Qkprint:
|
||||||
if(tas(&kprintinuse) != 0){
|
if(tas(&kprintinuse) != 0){
|
||||||
c->flag &= ~COPEN;
|
c->flag &= ~COPEN;
|
||||||
|
@ -724,14 +458,6 @@ static void
|
||||||
consclose(Chan *c)
|
consclose(Chan *c)
|
||||||
{
|
{
|
||||||
switch((ulong)c->qid.path){
|
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 */
|
/* close of kprint allows other opens */
|
||||||
case Qkprint:
|
case Qkprint:
|
||||||
if(c->flag & COPEN){
|
if(c->flag & COPEN){
|
||||||
|
@ -747,9 +473,9 @@ consread(Chan *c, void *buf, long n, vlong off)
|
||||||
{
|
{
|
||||||
ulong l;
|
ulong l;
|
||||||
Mach *mp;
|
Mach *mp;
|
||||||
char *b, *bp, ch;
|
char *b, *bp;
|
||||||
char tmp[256]; /* must be >= 18*NUMSIZE (Qswap) */
|
char tmp[256]; /* must be >= 18*NUMSIZE (Qswap) */
|
||||||
int i, k, id, send;
|
int i, k, id;
|
||||||
vlong offset = off;
|
vlong offset = off;
|
||||||
extern char configfile[];
|
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);
|
return devdirread(c, buf, n, consdir, nelem(consdir), devgen);
|
||||||
|
|
||||||
case Qcons:
|
case Qcons:
|
||||||
qlock(&kbd);
|
error(Egreg);
|
||||||
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;
|
|
||||||
|
|
||||||
case Qcputime:
|
case Qcputime:
|
||||||
k = offset;
|
k = offset;
|
||||||
|
@ -980,7 +664,7 @@ consread(Chan *c, void *buf, long n, vlong off)
|
||||||
static long
|
static long
|
||||||
conswrite(Chan *c, void *va, long n, vlong off)
|
conswrite(Chan *c, void *va, long n, vlong off)
|
||||||
{
|
{
|
||||||
char buf[256], ch;
|
char buf[256];
|
||||||
long l, bp;
|
long l, bp;
|
||||||
char *a;
|
char *a;
|
||||||
Mach *mp;
|
Mach *mp;
|
||||||
|
@ -1010,29 +694,6 @@ conswrite(Chan *c, void *va, long n, vlong off)
|
||||||
}
|
}
|
||||||
break;
|
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:
|
case Qtime:
|
||||||
if(!iseve())
|
if(!iseve())
|
||||||
error(Eperm);
|
error(Eperm);
|
||||||
|
|
|
@ -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,
|
|
||||||
};
|
|
|
@ -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,
|
|
||||||
};
|
|
|
@ -352,3 +352,15 @@ Dev srvdevtab = {
|
||||||
srvremove,
|
srvremove,
|
||||||
srvwstat,
|
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);
|
||||||
|
}
|
||||||
|
|
|
@ -223,9 +223,7 @@ uartreset(void)
|
||||||
if(p->console || p->special){
|
if(p->console || p->special){
|
||||||
if(uartenable(p) != nil){
|
if(uartenable(p) != nil){
|
||||||
if(p->console){
|
if(p->console){
|
||||||
kbdq = p->iq;
|
|
||||||
serialoq = p->oq;
|
serialoq = p->oq;
|
||||||
p->putc = kbdcr2nl;
|
|
||||||
}
|
}
|
||||||
p->opens++;
|
p->opens++;
|
||||||
}
|
}
|
||||||
|
|
|
@ -142,10 +142,6 @@ Segment* isoverlap(Proc*, ulong, int);
|
||||||
int ispages(void*);
|
int ispages(void*);
|
||||||
int isphysseg(char*);
|
int isphysseg(char*);
|
||||||
void ixsummary(void);
|
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 kickpager(void);
|
||||||
void killbig(char*);
|
void killbig(char*);
|
||||||
void kproc(char*, void(*)(void*), void*);
|
void kproc(char*, void(*)(void*), void*);
|
||||||
|
@ -323,6 +319,7 @@ int spllo(void);
|
||||||
void splx(int);
|
void splx(int);
|
||||||
void splxpc(int);
|
void splxpc(int);
|
||||||
char* srvname(Chan*);
|
char* srvname(Chan*);
|
||||||
|
void srvrenameuser(char*, char*);
|
||||||
int swapcount(ulong);
|
int swapcount(ulong);
|
||||||
int swapfull(void);
|
int swapfull(void);
|
||||||
void swapinit(void);
|
void swapinit(void);
|
||||||
|
|
1159
sys/src/cmd/aux/kbdfs.c
Normal file
1159
sys/src/cmd/aux/kbdfs.c
Normal file
File diff suppressed because it is too large
Load diff
|
@ -16,6 +16,7 @@ TARG=\
|
||||||
depend\
|
depend\
|
||||||
disksim\
|
disksim\
|
||||||
getflags\
|
getflags\
|
||||||
|
kbdfs\
|
||||||
lines\
|
lines\
|
||||||
listen\
|
listen\
|
||||||
listen1\
|
listen1\
|
||||||
|
|
Loading…
Reference in a new issue