Source-Changes-HG archive

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index][Old Index]

[src/trunk]: src/sys/arch/macppc/macppc Completely rewrite how cninit() deter...



details:   https://anonhg.NetBSD.org/src/rev/b755f6c8c84c
branches:  trunk
changeset: 472774:b755f6c8c84c
user:      thorpej <thorpej%NetBSD.org@localhost>
date:      Thu May 06 19:24:47 1999 +0000

description:
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!

diffstat:

 sys/arch/macppc/macppc/machdep.c |  224 +++++++++++++++++++++++++++++++++++++-
 1 files changed, 217 insertions(+), 7 deletions(-)

diffs (267 lines):

diff -r 2598ff64afa9 -r b755f6c8c84c sys/arch/macppc/macppc/machdep.c
--- a/sys/arch/macppc/macppc/machdep.c  Thu May 06 19:20:59 1999 +0000
+++ b/sys/arch/macppc/macppc/machdep.c  Thu May 06 19:24:47 1999 +0000
@@ -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 @@
 }
 
 #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 @@
        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 @@
 
 #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) {



Home | Main Index | Thread Index | Old Index