Date: Sun, 29 Jun 2003 19:01:26 -0700 (PDT) From: Marcel Moolenaar <marcel@FreeBSD.org> To: Perforce Change Reviews <perforce@freebsd.org> Subject: PERFORCE change 33866 for review Message-ID: <200306300201.h5U21QfZ069777@repoman.freebsd.org>
next in thread | raw e-mail | index | archive | help
http://perforce.freebsd.org/chv.cgi?CH=33866 Change 33866 by marcel@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;
Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?200306300201.h5U21QfZ069777>