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
static Lock i8042lock;
static uchar ccc;
-static void kbdputc(int);
static void (*auxputc)(int, int);
static int nokbd = 1; /* flag: no PS/2 keyboard */
iunlock(&i8042lock);
if(c != 0xFA){
- print("i8042: %2.2ux returned to the %2.2ux command (pc=%#p)\n", c, cmd, getcallerpc(&cmd));
+ print("i8042: %2.2ux returned to the %2.2ux command (pc=%#p)\n",
+ c, cmd, getcallerpc(&cmd));
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).
*
void
i8042auxenable(void (*putc)(int, int))
{
- char *err = "i8042: aux init failed\n";
+ static char err[] = "i8042: aux init failed\n";
+
+ ilock(&i8042lock);
/* enable kbd/aux xfers and interrupts */
ccc &= ~Cauxdis;
ccc |= Cauxint;
- ilock(&i8042lock);
if(outready() < 0)
print(err);
outb(Cmd, 0x60); /* write control register */
}
auxputc = putc;
intrenable(IrqAUX, i8042intr, 0, BUSUNKNOWN, "kbdaux");
+
iunlock(&i8042lock);
}
+static void
+kbdpoll(void)
+{
+ if(nokbd || qlen(kbd.q) > 0)
+ return;
+ i8042intr(0, 0);
+}
+
+static void
+kbdshutdown(void)
+{
+ if(nokbd)
+ return;
+ /* disable kbd and aux xfers and interrupts */
+ ccc &= ~(Ckbdint|Cauxint);
+ ccc |= (Cauxdis|Ckbddis);
+ outready();
+ outb(Cmd, 0x60);
+ outready();
+ outb(Data, ccc);
+ outready();
+}
+
static Chan *
kbdattach(char *spec)
{
static Block*
kbdbread(Chan *c, long n, ulong off)
{
- if(c->qid.path == Qscancode)
+ if(c->qid.path == Qscancode){
+ kbdpoll();
return qbread(kbd.q, n);
- else
- return devbread(c, n, off);
+ }
+ return devbread(c, n, off);
}
static long
kbdread(Chan *c, void *a, long n, vlong)
{
- if(c->qid.path == Qscancode)
+ if(c->qid.path == Qscancode){
+ kbdpoll();
return qread(kbd.q, a, n);
+ }
if(c->qid.path == Qdir)
return devdirread(c, a, n, kbdtab, nelem(kbdtab), devgen);
-
error(Egreg);
return 0;
}
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)
+static void
+kbdreset(void)
{
- outb(port, c);
- if(outready() < 0) {
- print(initfailed);
- return -1;
- }
- return 0;
-}
+ static char initfailed[] = "i8042: kbd init failed\n";
+ int c, try;
-void
-kbdenable(void)
-{
kbd.q = qopen(1024, Qcoalesce, 0, 0);
if(kbd.q == nil)
- panic("kbdenable");
+ panic("kbdreset");
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)) {
/* get current controller command byte */
outb(Cmd, 0x20);
if(inready() < 0){
- print("i8042: kbdinit can't read ccc\n");
+ print("i8042: can't read ccc\n");
ccc = 0;
} else
ccc = inb(Data);
/* enable kbd xfers and interrupts */
ccc &= ~Ckbddis;
ccc |= Csf | Ckbdint | Cscs1;
+
+ /* disable ps2 mouse */
+ ccc &= ~Cauxint;
+ ccc |= Cauxdis;
+
if(outready() < 0) {
print(initfailed);
return;
}
+ outb(Cmd, 0x60);
+ outready();
+ outb(Data, ccc);
+ outready();
nokbd = 0;
-
- /* disable mouse */
- if (outbyte(Cmd, 0x60) < 0 || outbyte(Data, ccc) < 0)
- print("i8042: kbdinit mouse disable failed\n");
+ ioalloc(Cmd, 1, 0, "i8042.cs");
+ ioalloc(Data, 1, 0, "i8042.data");
+ intrenable(IrqKBD, i8042intr, 0, BUSUNKNOWN, "kbd");
}
+
+Dev kbddevtab = {
+ L'b',
+ "kbd",
+
+ kbdreset,
+ devinit,
+ kbdshutdown,
+ kbdattach,
+ kbdwalk,
+ kbdstat,
+ kbdopen,
+ devcreate,
+ kbdclose,
+ kbdread,
+ kbdbread,
+ kbdwrite,
+ devbwrite,
+ devremove,
+ devwstat,
+};
+