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