PERFORCE change 33866 for review

Marcel Moolenaar marcel at FreeBSD.org
Sun Jun 29 19:01:29 PDT 2003


http://perforce.freebsd.org/chv.cgi?CH=33866

Change 33866 by marcel at marcel_nfs on 2003/06/29 19:01:24

	Implement a device subtype in puc(4) so that we can distinguish
	between different types of UARTs. The subtype is used to allocate
	the properly sized register range and is exported to children for
	further processing (see uart_bus_puc.c for example). The code is
	a bit sloppy, but helps to get a feel for the problem. It can be
	cleaned up afterwards. On my US5 I now get the following probe
	and attach:
	
	puc0: <Siemens SAB 82532 dual channel SCC> addr #-# irq 43 on ebus0
	uart0: <Siemens SAB 82532 v3.2 (ch A)> on puc0
	uart1: <Siemens SAB 82532 v3.2 (ch B)> on puc0
	uart2: <8250 or 16450 or compatible> addr #-# irq 41 on ebus0
	uart2: fast interrupt
	uart3: <8250 or 16450 or compatible> addr #-# irq 42 on ebus0
	uart3: fast interrupt

Affected files ...

.. //depot/projects/uart/dev/puc/puc.c#3 edit
.. //depot/projects/uart/dev/puc/puc_ebus.c#2 edit
.. //depot/projects/uart/dev/puc/pucvar.h#3 edit
.. //depot/projects/uart/dev/uart/uart_bus_puc.c#2 edit

Differences ...

==== //depot/projects/uart/dev/puc/puc.c#3 (text+ko) ====

@@ -103,6 +103,7 @@
 struct puc_device {
 	struct resource_list resources;
 	u_int serialfreq;
+	u_int subtype;
 };
 
 static void puc_intr(void *arg);
@@ -163,7 +164,7 @@
 puc_attach(device_t dev, const struct puc_device_description *desc)
 {
 	char *typestr;
-	int bidx, childunit, i, irq_setup, rid, type;
+	int bidx, childunit, i, irq_setup, ressz, rid, type;
 	struct puc_softc *sc;
 	struct puc_device *pdev;
 	struct resource *res;
@@ -234,10 +235,10 @@
 				device_printf(dev, "ILR disabled\n");
 		}
 #ifdef PUC_DEBUG
-		printf("%s rid %d bst %x, start %x, end %x\n",
+		printf("%s rid %d bst %lx, start %lx, end %lx\n",
 		    (type == SYS_RES_MEMORY) ? "memory" : "port", rid,
-		    (u_int)rman_get_bustag(res), (u_int)rman_get_start(res),
-		    (u_int)rman_get_end(res));
+		    (u_long)rman_get_bustag(res), (u_long)rman_get_start(res),
+		    (u_long)rman_get_end(res));
 #endif
 	}
 
@@ -253,13 +254,24 @@
 		if (sc->sc_bar_mappings[bidx].res == NULL)
 			continue;
 
-		switch (sc->sc_desc.ports[i].type) {
+		switch (sc->sc_desc.ports[i].type & ~PUC_PORT_SUBTYPE_MASK) {
 		case PUC_PORT_TYPE_COM:
 			typestr = "sio";
 			break;
+		case PUC_PORT_TYPE_UART:
+			typestr = "uart";
+			break;
 		default:
 			continue;
 		}
+		switch (sc->sc_desc.ports[i].type & PUC_PORT_SUBTYPE_MASK) {
+		case PUC_PORT_UART_SAB82532:
+			ressz = 64;
+			break;
+		default:
+			ressz = 8;
+			break;
+		}
 		pdev = malloc(sizeof(struct puc_device), M_DEVBUF,
 		    M_NOWAIT | M_ZERO);
 		if (!pdev)
@@ -278,8 +290,8 @@
 		type = sc->sc_bar_mappings[bidx].type;
 		resource_list_add(&pdev->resources, type, 0,
 		    rman_get_start(res) + sc->sc_desc.ports[i].offset,
-		    rman_get_start(res) + sc->sc_desc.ports[i].offset + 8 - 1,
-		    8);
+		    rman_get_start(res) + sc->sc_desc.ports[i].offset
+		    + ressz - 1, ressz);
 		rle = resource_list_find(&pdev->resources, type, 0);
 
 		if (sc->barmuxed == 0) {
@@ -303,9 +315,16 @@
 		}
 
 		pdev->serialfreq = sc->sc_desc.ports[i].serialfreq;
+		pdev->subtype = sc->sc_desc.ports[i].type &
+		    PUC_PORT_SUBTYPE_MASK;
 
 		childunit = puc_find_free_unit(typestr);
-		sc->sc_ports[i].dev = device_add_child(dev, typestr, childunit);
+		if (childunit < 0 && strcmp(typestr, "uart") != 0) {
+			typestr = "uart";
+			childunit = puc_find_free_unit(typestr);
+		}
+		sc->sc_ports[i].dev = device_add_child(dev, typestr,
+		    childunit);
 		if (sc->sc_ports[i].dev == NULL) {
 			if (sc->barmuxed) {
 				bus_space_unmap(rman_get_bustag(rle->res),
@@ -317,8 +336,6 @@
 		}
 		device_set_ivars(sc->sc_ports[i].dev, pdev);
 		device_set_desc(sc->sc_ports[i].dev, sc->sc_desc.name);
-		if (!bootverbose)
-			device_quiet(sc->sc_ports[i].dev);
 #ifdef PUC_DEBUG
 		printf("puc: type %d, bar %x, offset %x\n",
 		    sc->sc_desc.ports[i].type,
@@ -556,6 +573,9 @@
 	case PUC_IVAR_FREQ:
 		*result = pdev->serialfreq;
 		break;
+	case PUC_IVAR_SUBTYPE:
+		*result = pdev->subtype;
+		break;
 	default:
 		return (ENOENT);
 	}

==== //depot/projects/uart/dev/puc/puc_ebus.c#2 (text+ko) ====

@@ -66,7 +66,7 @@
 	bzero(&dd, sizeof(dd));
 	dd.name = device_get_desc(dev);
 	for (i = 0; i < 2; i++) {
-		dd.ports[i].type = PUC_PORT_TYPE_COM | PUC_PORT_COM_SAB82532;
+		dd.ports[i].type = PUC_PORT_TYPE_UART | PUC_PORT_UART_SAB82532;
 		dd.ports[i].bar = 0;
 		dd.ports[i].offset = 0x40 * i;
 		dd.ports[i].serialfreq = 0;

==== //depot/projects/uart/dev/puc/pucvar.h#3 (text+ko) ====

@@ -92,10 +92,12 @@
 #define	PUC_PORT_TYPE_NONE	0
 #define	PUC_PORT_TYPE_COM	1
 #define	PUC_PORT_TYPE_LPT	2
+#define	PUC_PORT_TYPE_UART	3
 
 /* UART subtypes. */
-#define	PUC_PORT_COM_NS8250	(0<<8)
-#define	PUC_PORT_COM_SAB82532	(1<<8)
+#define	PUC_PORT_SUBTYPE_MASK	(~0xff)
+#define	PUC_PORT_UART_NS8250	(0<<8)
+#define	PUC_PORT_UART_SAB82532	(1<<8)
 
 /* Interrupt Latch Register (ILR) types */
 #define	PUC_ILR_TYPE_NONE	0

==== //depot/projects/uart/dev/uart/uart_bus_puc.c#2 (text+ko) ====

@@ -61,13 +61,25 @@
 static int
 uart_puc_probe(device_t dev)
 {
+	device_t parent;
 	struct uart_softc *sc;
-	uintptr_t rclk;
+	uintptr_t rclk, type;
 
+	parent = device_get_parent(dev);
 	sc = device_get_softc(dev);
 
-	/* XXX we need to support all sorts of UARTs. */
-	sc->sc_class = &uart_ns8250_class;
+	if (BUS_READ_IVAR(parent, dev, PUC_IVAR_SUBTYPE, &type))
+		return (ENXIO);
+	switch (type) {
+	case PUC_PORT_UART_NS8250:
+		sc->sc_class = &uart_ns8250_class;
+		break;
+	case PUC_PORT_UART_SAB82532:
+		sc->sc_class = &uart_sab82532_class;
+		break;
+	default:
+		return (ENXIO);
+	}
 
 	if (BUS_READ_IVAR(device_get_parent(dev), dev, PUC_IVAR_FREQ, &rclk))
 		rclk = 0;


More information about the p4-projects mailing list