Subject: Re: testers needed for change to ofb.c
To: Chuck Silvers <chuq@chuq.com>
From: Tim Kelly <hockey@dialectronics.com>
List: port-macppc
Date: 12/16/2004 12:51:38
At 7:11 PM -0800 12/13/04, Chuck Silvers wrote:
>this has the effect of not matching video cards that are not the console,
>is that the intent?  if a machine has two video cards, shouldn't ofb
>attach to both of them?

I've reviewed the match/attach process and offer a compromise. I match any
device that lists itself in Open Firmware as a "display" device_type and
specifically match the console listed in /chosen's stdout to the PCI tag
during attachment. As far as I know, the "display" device_type in OF will
only be listed if the device indicates to OF that it is such a device, as
opposed to the current method which uses PCI device types. Since they are
not one and the same, this should allow granularity over ofb's such that
only OF compliant display devices get matched and attached. Other display
devices should be attached elsewhere, and as far as I know, X uses PCI
discovery and tags to identify monitors.

tim


Index: ofb.c
===================================================================
RCS file: /cvsroot/src/sys/arch/macppc/dev/ofb.c,v
retrieving revision 1.39
diff -d -u -r1.39 ofb.c
--- ofb.c	24 Apr 2004 15:49:00 -0000	1.39
+++ ofb.c	16 Dec 2004 17:44:48 -0000
@@ -117,6 +117,9 @@
 static int ofb_getcmap __P((struct ofb_softc *, struct wsdisplay_cmap *));
 static int ofb_putcmap __P((struct ofb_softc *, struct wsdisplay_cmap *));

+int ofb_match_display_type(pci_chipset_tag_t, pcitag_t);
+int ofb_match_console(pci_chipset_tag_t, pcitag_t);
+
 int
 ofbmatch(parent, match, aux)
 	struct device *parent;
@@ -125,14 +128,18 @@
 {
 	struct pci_attach_args *pa = aux;

+/*	printf("ofbmatch PCI tag: %x\n", pa->pa_tag); */
+
 	if (PCI_VENDOR(pa->pa_id) == PCI_VENDOR_APPLE &&
 	    PCI_PRODUCT(pa->pa_id) == PCI_PRODUCT_APPLE_CONTROL)
-		return 1;
+		return ofb_match_display_type(pa->pa_pc, pa->pa_tag);

 	if (PCI_CLASS(pa->pa_class) == PCI_CLASS_DISPLAY)
-		return 1;
+		return ofb_match_display_type(pa->pa_pc, pa->pa_tag);

 	return 0;
+
+
 }

 void
@@ -147,15 +154,18 @@
 	struct ofb_devconfig *dc;
 	char devinfo[256];

-	console = ofb_is_console();
+	console = ofb_match_console(pa->pa_pc, pa->pa_tag);
+/*	console = ofb_is_console();   */

 	if (console) {
+/*		printf("ofb_is_console tag: %x\n", pa->pa_tag); */
 		dc = &ofb_console_dc;
 		node = dc->dc_node;
 		sc->nscreens = 1;
 	} else {
 		int i, len, screenbytes;

+/*		printf("ofb_is_not_console tag: %x\n",pa->pa_tag); */
 		dc = malloc(sizeof(struct ofb_devconfig), M_DEVBUF, M_WAITOK);
 		memset(dc, 0, sizeof(struct ofb_devconfig));
 		node = pcidev_to_ofdev(pa->pa_pc, pa->pa_tag);
@@ -282,7 +292,7 @@
 	ri->ri_flg = RI_FORCEMONO | RI_FULLCLEAR | RI_CENTER;

 	/* If screen is smaller than 1024x768, use small font. */
-	if ((width < 1024 || height < 768) && copy_rom_font() == 0) {
+	if ((width <= 1024 || height <= 768) && copy_rom_font() == 0) {
 		int cols, rows;

 		OF_interpret("#lines", 1, &rows);
@@ -313,6 +323,52 @@
 }

 int
+ofb_match_display_type(pc, tag)
+        pci_chipset_tag_t pc;
+        pcitag_t tag;
+{
+	int node;
+        char type[16];
+
+	node = pcidev_to_ofdev(pc, tag);
+
+	OF_getprop(node, "device_type", type, sizeof(type));
+/*	printf("ofb_match_display_type: %s\n", type); */
+	if (strcmp(type, "display") == 0)
+		return 1;
+	else
+		return 0;
+}
+
+int
+ofb_match_console(pc, tag)
+        pci_chipset_tag_t pc;
+        pcitag_t tag;
+{
+       int chosen, stdout, node;
+
+       chosen = OF_finddevice("/chosen");
+       OF_getprop(chosen, "stdout", &stdout, 4);
+       node = OF_instance_to_package(stdout);
+
+       /* do it by "a-a" property and extract tag */
+       /* if no a-a, it's not the console we're looking for */
+       u_int reg[5];
+       int l;
+
+       l = OF_getprop(node, "assigned-addresses", reg, sizeof(reg));
+/*       printf("ofb_match_console tag: %x, l: %d\n", reg[0] & 0xfff00,
l); */
+        if (l > 4) {
+               if ((tag & 0xfff00) == (reg[0] & 0xfff00))
+                       return 1;
+               else
+                       return 0;
+       } else
+               return 0;
+
+}
+
+int
 ofb_is_console()
 {
 	int chosen, stdout, node;
@@ -477,7 +533,7 @@

 	ofb_common_init(node, dc);

-	if (ri->ri_width >= 1024 && ri->ri_height >= 768) {
+	if (ri->ri_width > 1024 && ri->ri_height > 768) {
 		int i, screenbytes = ri->ri_stride * ri->ri_height;

 		for (i = 0; i < screenbytes; i += sizeof(u_int32_t))