Completely rewrite how cninit() determines which keyboard to use with

the console.  New algorithm:

* if stdin == keyboard, and parent of keyboard == adb, use ADB.
* else, must be a USB keyboard.  Search backwards though the parents
until the USB controller is located.  Determine its location in the PCI
domain, and which type of controller it is, and tell that controller that
it has the console input device.  The USB code will then attach the first
USB keyboard as the console input device during autoconfiguration.

The iMac and Blue and White G3 consoles are fully functional now!
This commit is contained in:
thorpej 1999-05-06 19:24:47 +00:00
parent ac9eee8693
commit 680c3ddbd2
1 changed files with 217 additions and 7 deletions

View File

@ -1,4 +1,4 @@
/* $NetBSD: machdep.c,v 1.42 1999/04/29 05:15:30 tsubai Exp $ */
/* $NetBSD: machdep.c,v 1.43 1999/05/06 19:24:47 thorpej Exp $ */
/*
* Copyright (C) 1995, 1996 Wolfgang Solfrank.
@ -90,6 +90,23 @@
#include <dev/cons.h>
#include <dev/ofw/openfirm.h>
#include <dev/ofw/ofw_pci.h>
#include <machine/bus.h>
#include <dev/pci/pcireg.h>
#include <dev/pci/pcivar.h>
#include <dev/usb/usb.h>
#include <dev/usb/usbdi.h>
#include <dev/usb/usbdivar.h>
#include <dev/usb/usb_mem.h>
#include <dev/usb/uhcireg.h>
#include <dev/usb/uhcivar.h>
#include <dev/usb/ohcireg.h>
#include <dev/usb/ohcivar.h>
vm_map_t exec_map = NULL;
vm_map_t mb_map = NULL;
@ -1082,10 +1099,14 @@ mapiodev(pa, len)
}
#include "akbd.h"
#include "ukbd.h"
#include "uhci.h"
#include "ohci.h"
#include "ofb.h"
#include "ite.h"
#include "zstty.h"
int console_node = -1;
void
@ -1096,6 +1117,12 @@ cninit()
int stdout;
char type[16];
/*
* Initialize the PCI chipsets; can't map configuration
* space registers yet!
*/
pci_init(0);
l = OF_getprop(chosen, "stdout", &stdout, sizeof(stdout));
if (l != sizeof(stdout))
goto nocons;
@ -1110,16 +1137,199 @@ cninit()
#if NOFB > 0
if (strcmp(type, "display") == 0) {
u_int32_t pciclass, reg, bus, device, function;
const char *usbstr;
int stdin, i;
pcitag_t tag;
/*
* Attach the console output now (so we can see
* debugging messages, if any).
*/
ofb_cnattach();
/*
* We must determine which keyboard type we have.
*/
l = OF_getprop(chosen, "stdin", &stdin, sizeof(stdin));
if (l != sizeof(stdin)) {
printf("WARNING: no `stdin' property in /chosen\n");
return;
}
node = OF_instance_to_package(stdout);
bzero(type, sizeof(type));
l = OF_getprop(node, "name", type, sizeof(type));
if (l == -1 || l >= sizeof(type) - 1) {
printf("WARNING: bad `name' property for stdin\n");
return;
}
if (strcmp(type, "keyboard") != 0) {
printf("WARNING: stdin is not a keyboard: %s\n",
type);
return;
}
node = OF_parent(node);
bzero(type, sizeof(type));
l = OF_getprop(node, "name", type, sizeof(type));
if (l == -1 || l >= sizeof(type) - 1) {
printf("WARNING: bad `name' property keyboard "
"parent\n");
return;
}
if (strcmp(type, "adb") == 0) {
printf("console keyboard type: ADB\n");
#if NAKBD > 0
akbd_cnattach();
akbd_cnattach();
#else
panic("akbd support not in kernel");
#endif
#if 0
ukbd_cnattach();
return;
}
/*
* We're not an ADB keyboard; must be USB. The parent
* node is pointing at the root hub. We need to traverse
* back until we find the USB controller.
*/
while (strcmp(type, "usb") != 0) {
node = OF_parent(node);
if (node == 0) {
printf("WARNING: unable to find USB "
"controller\n");
return;
}
bzero(type, sizeof(type));
l = OF_getprop(node, "name", type, sizeof(type));
if (l == -1 || l >= sizeof(type) - 1) {
printf("WARNING: bad `name' property "
"searching for USB controller\n");
return;
}
}
/*
* `node' is now pointing at the USB controller.
* We must determine the type and location of this
* controller.
*/
if (OF_getprop(node, "class-code", &pciclass, sizeof(pciclass))
!= sizeof(pciclass)) {
printf("WARNING: unable to get PCI class code of "
"USB controller\n");
return;
}
/*
* The first address cell of the `reg' property will contain
* bus/device/function information.
*/
if (OF_getprop(node, "reg", &reg, sizeof(reg)) <= 0) {
printf("WARNING: unable to get PCI location of "
"USB controller\n");
return;
}
if (PCI_CLASS(pciclass) != PCI_CLASS_SERIALBUS) {
printf("WARNING: USB controller is not `serial bus' "
"class\n");
return;
}
if (PCI_SUBCLASS(pciclass) != PCI_SUBCLASS_SERIALBUS_USB) {
printf("WARNING: USB controller is not `usb' "
"subclass\n");
return;
}
switch (PCI_INTERFACE(pciclass)) {
case PCI_INTERFACE_UHCI:
usbstr = "UHCI";
break;
case PCI_INTERFACE_OHCI:
usbstr = "OHCI";
break;
default:
printf("WARNING: unknown USB controller interface\n");
return;
}
bus = (reg & OFW_PCI_PHYS_HI_BUSMASK) >>
OFW_PCI_PHYS_HI_BUSSHIFT;
device = (reg & OFW_PCI_PHYS_HI_DEVICEMASK) >>
OFW_PCI_PHYS_HI_DEVICESHIFT;
function = (reg & OFW_PCI_PHYS_HI_FUNCTIONMASK) >>
OFW_PCI_PHYS_HI_FUNCTIONSHIFT;
printf("console keyboard type: USB on %s at %d,%d,%d\n",
usbstr, bus, device, function);
/*
* Locate the PCI bridge we're on, and create the tag
* for the USB driver.
*/
for (i = 0; i < sizeof(pci_bridges) / sizeof(pci_bridges[0]);
i++) {
if (pci_bridges[i].present &&
pci_bridges[i].bus == bus)
break;
}
if (i == sizeof(pci_bridges) / sizeof(pci_bridges[0])) {
printf("WARNING: can't locate USB controller's "
"PCI bridge\n");
return;
}
tag = pci_make_tag(pci_bridges[i].pc, bus, device, function);
#if NUKBD > 0
/*
* XXX We can't attach the USB keyboard just yet. We
* XXX must defer it until autoconfiguration, because
* XXX the USB code must be able to use memory allocation,
* XXX DMA, etc.
* XXX
* XXX THIS SHOULD BE FIXED SOME DAY!
*/
#else
panic("ukbd support not in kernel");
#endif
ofb_cnattach(); /* XXX error check? */
return;
switch (PCI_INTERFACE(pciclass)) {
case PCI_INTERFACE_UHCI:
#if NUHCI > 0
{
extern void uhci_pci_has_console __P((pcitag_t));
uhci_pci_has_console(tag);
}
#else
panic("uhci support not in kernel");
#endif
break;
case PCI_INTERFACE_OHCI:
#if NOHCI > 0
{
extern void ohci_pci_has_console __P((pcitag_t));
ohci_pci_has_console(tag);
}
#else
panic("ohci support not in kernel");
#endif
break;
default:
panic("cninit: impossible");
}
}
#endif
#endif /* NOFB > 0 */
#if NITE > 0
if (strcmp(type, "display") == 0) {