From owner-p4-projects@FreeBSD.ORG Wed Nov 15 16:59:21 2006 Return-Path: X-Original-To: p4-projects@freebsd.org Delivered-To: p4-projects@freebsd.org Received: by hub.freebsd.org (Postfix, from userid 32767) id 20F7F16A62B; Wed, 15 Nov 2006 16:59:20 +0000 (UTC) X-Original-To: perforce@freebsd.org Delivered-To: perforce@freebsd.org Received: from mx1.FreeBSD.org (mx1.freebsd.org [216.136.204.125]) by hub.freebsd.org (Postfix) with ESMTP id 905EF16A5ED for ; Wed, 15 Nov 2006 16:59:19 +0000 (UTC) (envelope-from marcel@freebsd.org) Received: from repoman.freebsd.org (repoman.freebsd.org [216.136.204.115]) by mx1.FreeBSD.org (Postfix) with ESMTP id A174D43D58 for ; Wed, 15 Nov 2006 16:59:18 +0000 (GMT) (envelope-from marcel@freebsd.org) Received: from repoman.freebsd.org (localhost [127.0.0.1]) by repoman.freebsd.org (8.13.6/8.13.6) with ESMTP id kAFGxIXt007313 for ; Wed, 15 Nov 2006 16:59:18 GMT (envelope-from marcel@freebsd.org) Received: (from perforce@localhost) by repoman.freebsd.org (8.13.6/8.13.4/Submit) id kAFGxHrb007310 for perforce@freebsd.org; Wed, 15 Nov 2006 16:59:17 GMT (envelope-from marcel@freebsd.org) Date: Wed, 15 Nov 2006 16:59:17 GMT Message-Id: <200611151659.kAFGxHrb007310@repoman.freebsd.org> X-Authentication-Warning: repoman.freebsd.org: perforce set sender to marcel@freebsd.org using -f From: Marcel Moolenaar To: Perforce Change Reviews Cc: Subject: PERFORCE change 110037 for review X-BeenThere: p4-projects@freebsd.org X-Mailman-Version: 2.1.5 Precedence: list List-Id: p4 projects tree changes List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Wed, 15 Nov 2006 16:59:21 -0000 http://perforce.freebsd.org/chv.cgi?CH=110037 Change 110037 by marcel@marcel_nfs on 2006/11/15 16:58:17 Hide the uart_ops instances and instead have the device class point to them. By going through the class we can implement the DT tag in uart_getenv() as well as use the correct I/O range in bus_space_map(). Affected files ... .. //depot/projects/uart/dev/uart/uart.h#11 edit .. //depot/projects/uart/dev/uart/uart_bus.h#48 edit .. //depot/projects/uart/dev/uart/uart_core.c#55 edit .. //depot/projects/uart/dev/uart/uart_cpu.h#20 edit .. //depot/projects/uart/dev/uart/uart_cpu_amd64.c#11 edit .. //depot/projects/uart/dev/uart/uart_cpu_i386.c#12 edit .. //depot/projects/uart/dev/uart/uart_cpu_ia64.c#13 edit .. //depot/projects/uart/dev/uart/uart_cpu_pc98.c#13 edit .. //depot/projects/uart/dev/uart/uart_cpu_sparc64.c#26 edit .. //depot/projects/uart/dev/uart/uart_dev_ns8250.c#46 edit .. //depot/projects/uart/dev/uart/uart_dev_sab82532.c#42 edit .. //depot/projects/uart/dev/uart/uart_dev_z8530.c#33 edit .. //depot/projects/uart/dev/uart/uart_kbd_sun.c#11 edit .. //depot/projects/uart/dev/uart/uart_subr.c#7 edit Differences ... ==== //depot/projects/uart/dev/uart/uart.h#11 (text+ko) ==== @@ -60,6 +60,16 @@ BUS_SPACE_BARRIER_READ|BUS_SPACE_BARRIER_WRITE) /* + * UART device classes. + */ +struct uart_class; + +extern struct uart_class uart_ns8250_class; +extern struct uart_class uart_quicc_class; +extern struct uart_class uart_sab82532_class; +extern struct uart_class uart_z8530_class; + +/* * Device flags. */ #define UART_FLAGS_CONSOLE(f) ((f) & 0x10) ==== //depot/projects/uart/dev/uart/uart_bus.h#48 (text+ko) ==== @@ -67,14 +67,11 @@ */ struct uart_class { KOBJ_CLASS_FIELDS; + struct uart_ops *uc_ops; /* Low-level console operations. */ u_int uc_range; /* Bus space address range. */ u_int uc_rclk; /* Default rclk for this device. */ }; -extern struct uart_class uart_ns8250_class; -extern struct uart_class uart_sab82532_class; -extern struct uart_class uart_z8530_class; - struct uart_softc { KOBJ_FIELDS; struct uart_class *sc_class; ==== //depot/projects/uart/dev/uart/uart_core.c#55 (text+ko) ==== @@ -70,6 +70,18 @@ SLIST_INSERT_HEAD(&uart_sysdevs, di, next); } +struct uart_ops * +uart_getops(struct uart_class *uc) +{ + return (uc->uc_ops); +} + +int +uart_getrange(struct uart_class *uc) +{ + return (uc->uc_range); +} + /* * Schedule a soft interrupt. We do this on the 0 to !0 transition * of the TTY pending interrupt status. ==== //depot/projects/uart/dev/uart/uart_cpu.h#20 (text+ko) ==== @@ -45,11 +45,6 @@ int (*getc)(struct uart_bas *, struct mtx *); }; -extern struct uart_ops uart_i8251_ops; -extern struct uart_ops uart_ns8250_ops; -extern struct uart_ops uart_sab82532_ops; -extern struct uart_ops uart_z8530_ops; - extern bus_space_tag_t uart_bus_space_io; extern bus_space_tag_t uart_bus_space_mem; @@ -59,7 +54,7 @@ struct uart_softc; struct uart_devinfo { SLIST_ENTRY(uart_devinfo) next; - struct uart_ops ops; + struct uart_ops *ops; struct uart_bas bas; int baudrate; int databits; @@ -77,7 +72,10 @@ int uart_cpu_eqres(struct uart_bas *, struct uart_bas *); int uart_cpu_getdev(int, struct uart_devinfo *); -int uart_getenv(int, struct uart_devinfo *); + +int uart_getenv(int, struct uart_devinfo *, struct uart_class *); +struct uart_ops *uart_getops(struct uart_class *); +int uart_getrange(struct uart_class *); void uart_add_sysdev(struct uart_devinfo *); @@ -106,7 +104,7 @@ int res; uart_lock(di->hwmtx); - res = di->ops.probe(&di->bas); + res = di->ops->probe(&di->bas); uart_unlock(di->hwmtx); return (res); } @@ -115,7 +113,7 @@ uart_init(struct uart_devinfo *di) { uart_lock(di->hwmtx); - di->ops.init(&di->bas, di->baudrate, di->databits, di->stopbits, + di->ops->init(&di->bas, di->baudrate, di->databits, di->stopbits, di->parity); uart_unlock(di->hwmtx); } @@ -124,7 +122,7 @@ uart_term(struct uart_devinfo *di) { uart_lock(di->hwmtx); - di->ops.term(&di->bas); + di->ops->term(&di->bas); uart_unlock(di->hwmtx); } @@ -132,7 +130,7 @@ uart_putc(struct uart_devinfo *di, int c) { uart_lock(di->hwmtx); - di->ops.putc(&di->bas, c); + di->ops->putc(&di->bas, c); uart_unlock(di->hwmtx); } @@ -142,7 +140,7 @@ int res; uart_lock(di->hwmtx); - res = di->ops.poll(&di->bas); + res = di->ops->poll(&di->bas); uart_unlock(di->hwmtx); return (res); } @@ -151,7 +149,7 @@ uart_getc(struct uart_devinfo *di) { - return (di->ops.getc(&di->bas, di->hwmtx)); + return (di->ops->getc(&di->bas, di->hwmtx)); } #endif /* _DEV_UART_CPU_H_ */ ==== //depot/projects/uart/dev/uart/uart_cpu_amd64.c#11 (text+ko) ==== @@ -49,11 +49,13 @@ int uart_cpu_getdev(int devtype, struct uart_devinfo *di) { + struct uart_class *class; unsigned int i, ivar; + class = &uart_ns8250_class; + /* Check the environment. */ - di->ops = uart_ns8250_ops; - if (uart_getenv(devtype, di) == 0) + if (uart_getenv(devtype, di, class) == 0) return (0); /* @@ -82,10 +84,11 @@ * Got it. Fill in the instance and return it. We only have * ns8250 and successors on i386. */ - di->ops = uart_ns8250_ops; + di->ops = uart_getops(class); di->bas.chan = 0; di->bas.bst = uart_bus_space_io; - if (bus_space_map(di->bas.bst, ivar, 8, 0, &di->bas.bsh) != 0) + if (bus_space_map(di->bas.bst, ivar, uart_getrange(class), 0, + &di->bas.bsh) != 0) continue; di->bas.regshft = 0; di->bas.rclk = 0; ==== //depot/projects/uart/dev/uart/uart_cpu_i386.c#12 (text+ko) ==== @@ -49,11 +49,13 @@ int uart_cpu_getdev(int devtype, struct uart_devinfo *di) { + struct uart_class *class; unsigned int i, ivar; + class = &uart_ns8250_class; + /* Check the environment. */ - di->ops = uart_ns8250_ops; - if (uart_getenv(devtype, di) == 0) + if (uart_getenv(devtype, di, class) == 0) return (0); /* @@ -82,10 +84,11 @@ * Got it. Fill in the instance and return it. We only have * ns8250 and successors on i386. */ - di->ops = uart_ns8250_ops; + di->ops = uart_getops(class); di->bas.chan = 0; di->bas.bst = uart_bus_space_io; - if (bus_space_map(di->bas.bst, ivar, 8, 0, &di->bas.bsh) != 0) + if (bus_space_map(di->bas.bst, ivar, uart_getrange(class), 0, + &di->bas.bsh) != 0) continue; di->bas.regshft = 0; di->bas.rclk = 0; ==== //depot/projects/uart/dev/uart/uart_cpu_ia64.c#13 (text+ko) ==== @@ -59,10 +59,13 @@ { struct dig64_hcdp_table *tbl; struct dig64_hcdp_entry *ent; + struct uart_class *class; bus_addr_t addr; uint64_t hcdp; unsigned int i; + class = &uart_ns8250_class; + /* * Use the DIG64 HCDP table if present. */ @@ -82,12 +85,12 @@ addr = ent->address.addr_high; addr = (addr << 32) + ent->address.addr_low; - di->ops = uart_ns8250_ops; + di->ops = uart_getops(class); di->bas.chan = 0; di->bas.bst = (ent->address.addr_space == 0) ? uart_bus_space_mem : uart_bus_space_io; - if (bus_space_map(di->bas.bst, addr, 8, 0, - &di->bas.bsh) != 0) + if (bus_space_map(di->bas.bst, addr, + uart_getrange(class), 0, &di->bas.bsh) != 0) continue; di->bas.regshft = 0; di->bas.rclk = ent->pclock << 4; @@ -104,6 +107,5 @@ } /* Check the environment. */ - di->ops = uart_ns8250_ops; - return (uart_getenv(devtype, di)); + return (uart_getenv(devtype, di, class)); } ==== //depot/projects/uart/dev/uart/uart_cpu_pc98.c#13 (text+ko) ==== @@ -49,11 +49,13 @@ int uart_cpu_getdev(int devtype, struct uart_devinfo *di) { + struct uart_class *class; unsigned int i, ivar, flags; + class = &uart_ns8250_class; + /* Check the environment. */ - di->ops = uart_ns8250_ops; - if (uart_getenv(devtype, di) == 0) + if (uart_getenv(devtype, di, class) == 0) return (0); /* @@ -81,10 +83,11 @@ ivar == 0) continue; - di->ops = uart_ns8250_ops; + di->ops = uart_getops(class); di->bas.chan = 0; di->bas.bst = uart_bus_space_io; - if (bus_space_map(di->bas.bst, ivar, 8, 0, &di->bas.bsh) != 0) + if (bus_space_map(di->bas.bst, ivar, uart_getrange(class), 0, + &di->bas.bsh) != 0) continue; di->bas.regshft = 0; di->bas.rclk = 0; ==== //depot/projects/uart/dev/uart/uart_cpu_sparc64.c#26 (text+ko) ==== @@ -194,9 +194,10 @@ uart_cpu_getdev(int devtype, struct uart_devinfo *di) { char buf[32], compat[32], dev[64]; + struct uart_class *class; phandle_t input, options; bus_addr_t addr; - int baud, bits, error, space, stop; + int baud, bits, error, range, space, stop; char flag, par; if ((options = OF_finddevice("/options")) == -1) @@ -228,14 +229,15 @@ compat[0] = '\0'; di->bas.regshft = 0; di->bas.rclk = 0; + class = NULL; if (!strcmp(buf, "se") || !strcmp(compat, "sab82532")) { - di->ops = uart_sab82532_ops; + class = &uart_sab82532_class; /* SAB82532 are only known to be used for TTYs. */ if ((di->bas.chan = uart_cpu_channel(dev)) == 0) return (ENXIO); - addr += 64 * (di->bas.chan - 1); + addr += uart_getrange(class) * (di->bas.chan - 1); } else if (!strcmp(buf, "zs")) { - di->ops = uart_z8530_ops; + class = &uart_z8530_class; if ((di->bas.chan = uart_cpu_channel(dev)) == 0) { /* * There's no way to determine from OF which @@ -248,16 +250,19 @@ return (ENXIO); } di->bas.regshft = 1; - addr += 4 - 4 * (di->bas.chan - 1); + range = uart_getrange(class) << di->bas.regshft; + addr += range - range * (di->bas.chan - 1); } else if (!strcmp(buf, "lom-console") || !strcmp(buf, "su") || !strcmp(buf, "su_pnp") || !strcmp(compat, "rsc-console") || !strcmp(compat, "su") || !strcmp(compat, "su16550")) { - di->ops = uart_ns8250_ops; + class = &uart_ns8250_class; di->bas.chan = 0; - } else + } + if (class == NULL) return (ENXIO); /* Fill in the device info. */ + di->ops = uart_getops(class); di->bas.bst = &bst_store[devtype]; di->bas.bsh = sparc64_fake_bustag(space, addr, di->bas.bst); ==== //depot/projects/uart/dev/uart/uart_dev_ns8250.c#46 (text+ko) ==== @@ -220,7 +220,7 @@ static int ns8250_poll(struct uart_bas *bas); static int ns8250_getc(struct uart_bas *bas, struct mtx *); -struct uart_ops uart_ns8250_ops = { +static struct uart_ops uart_ns8250_ops = { .probe = ns8250_probe, .init = ns8250_init, .term = ns8250_term, @@ -368,9 +368,10 @@ }; struct uart_class uart_ns8250_class = { - "ns8250 class", + "ns8250", ns8250_methods, sizeof(struct ns8250_softc), + .uc_ops = &uart_ns8250_ops, .uc_range = 8, .uc_rclk = DEFAULT_RCLK }; ==== //depot/projects/uart/dev/uart/uart_dev_sab82532.c#42 (text+ko) ==== @@ -176,7 +176,7 @@ static int sab82532_poll(struct uart_bas *bas); static int sab82532_getc(struct uart_bas *bas, struct mtx *); -struct uart_ops uart_sab82532_ops = { +static struct uart_ops uart_sab82532_ops = { .probe = sab82532_probe, .init = sab82532_init, .term = sab82532_term, @@ -384,9 +384,10 @@ }; struct uart_class uart_sab82532_class = { - "sab82532 class", + "sab82532", sab82532_methods, sizeof(struct sab82532_softc), + .uc_ops = &uart_sab82532_ops, .uc_range = 64, .uc_rclk = DEFAULT_RCLK }; ==== //depot/projects/uart/dev/uart/uart_dev_z8530.c#33 (text+ko) ==== @@ -195,7 +195,7 @@ static int z8530_poll(struct uart_bas *bas); static int z8530_getc(struct uart_bas *bas, struct mtx *); -struct uart_ops uart_z8530_ops = { +static struct uart_ops uart_z8530_ops = { .probe = z8530_probe, .init = z8530_init, .term = z8530_term, @@ -300,9 +300,10 @@ }; struct uart_class uart_z8530_class = { - "z8530 class", + "z8530", z8530_methods, sizeof(struct z8530_softc), + .uc_ops = &uart_z8530_ops, .uc_range = 2, .uc_rclk = DEFAULT_RCLK }; ==== //depot/projects/uart/dev/uart/uart_kbd_sun.c#11 (text+ko) ==== @@ -719,8 +719,8 @@ if (*(int *)data & SLKED) c |= SKBD_LED_SCROLLLOCK; uart_lock(sc->sc_sysdev->hwmtx); - sc->sc_sysdev->ops.putc(&sc->sc_sysdev->bas, SKBD_CMD_SETLED); - sc->sc_sysdev->ops.putc(&sc->sc_sysdev->bas, c); + sc->sc_sysdev->ops->putc(&sc->sc_sysdev->bas, SKBD_CMD_SETLED); + sc->sc_sysdev->ops->putc(&sc->sc_sysdev->bas, c); uart_unlock(sc->sc_sysdev->hwmtx); KBD_LED_VAL(kbd) = *(int *)data; break; ==== //depot/projects/uart/dev/uart/uart_subr.c#7 (text+ko) ==== @@ -54,6 +54,12 @@ return (strtoul(*p, (char**)(uintptr_t)p, 0)); } +static struct uart_class * +uart_parse_class(struct uart_class *class, __const char **p) +{ + return (class); +} + static long uart_parse_long(__const char **p) { @@ -161,10 +167,15 @@ */ int -uart_getenv(int devtype, struct uart_devinfo *di) +uart_getenv(int devtype, struct uart_devinfo *di, struct uart_class *class) { __const char *spec; bus_addr_t addr = ~0U; + int error; + + /* We must get a valid default device class. */ + if (class == NULL) + return (EDOOFUS); /* * Check the environment variables "hw.uart.console" and @@ -203,7 +214,7 @@ di->databits = uart_parse_long(&spec); break; case UART_TAG_DT: - return (EINVAL); /* XXX not yet implemented. */ + class = uart_parse_class(class, &spec); break; case UART_TAG_IO: di->bas.bst = uart_bus_space_io; @@ -261,8 +272,9 @@ } else di->baudrate = 0; - /* XXX the size of the mapping depends on the UART class. */ - if (bus_space_map(di->bas.bst, addr, 8, 0, &di->bas.bsh) != 0) - return (EINVAL); - return (0); + /* Set the ops and create a bus space handle. */ + di->ops = uart_getops(class); + error = bus_space_map(di->bas.bst, addr, uart_getrange(class), 0, + &di->bas.bsh); + return (error); }