[PATCH] 2/2 : 8250 serial: dynamic port table from arch

From: Benjamin Herrenschmidt (benh_at_kernel.crashing.org)
Date: 10/19/04

  • Next message: Meelis Roos: "Re: [PATCH] Re: Weird... 2.6.9 kills FC2 gcc"
    To: Andrew Morton <akpm@osdl.org>
    Date:	Tue, 19 Oct 2004 16:12:29 +1000
    
    

    Hi !

    This patch adds a ppc64 implementation of the routine providing
    the list of default 8250 serial ports. It provides a empty list
    by default unless the platform code fills it, and it provides
    a generic function for user by Open Firmware based machines which
    fills the list based on serial ports found in the OF device-tree.

    It depends on the previous patch adding the generic support for
    this to the 8250 driver.

    Signed-off-by: Benjamin Herrenschmidt <benh@kernel.crashing.org>

    Index: linux-maple/arch/ppc64/kernel/setup.c
    ===================================================================
    --- linux-maple.orig/arch/ppc64/kernel/setup.c 2004-10-19 13:37:37.000000000 +1000
    +++ linux-maple/arch/ppc64/kernel/setup.c 2004-10-19 16:13:04.264555048 +1000
    @@ -30,6 +30,8 @@
     #include <linux/notifier.h>
     #include <linux/cpu.h>
     #include <linux/unistd.h>
    +#include <linux/serial.h>
    +#include <linux/8250.h>
     #include <asm/io.h>
     #include <asm/prom.h>
     #include <asm/processor.h>
    @@ -51,6 +53,7 @@
     #include <asm/system.h>
     #include <asm/rtas.h>
     #include <asm/iommu.h>
    +#include <asm/serial.h>
     
     #ifdef DEBUG
     #define DBG(fmt...) udbg_printf(fmt)
    @@ -1106,6 +1109,177 @@
     __setup("decr_overclock_proc0=", set_decr_overclock_proc0 );
     __setup("decr_overclock=", set_decr_overclock );
     
    +/*
    + * This function can be used by platforms to "find" legacy serial ports.
    + * It works for "serial" nodes under an "isa" node, and will try to
    + * respect the "ibm,aix-loc" property if any. It works with up to 8
    + * ports.
    + */
    +
    +#define MAX_LEGACY_SERIAL_PORTS 8
    +static struct old_serial_port old_serial_ports[MAX_LEGACY_SERIAL_PORTS];
    +static unsigned int old_serial_count;
    +
    +void __init generic_find_legacy_serial_ports(unsigned int *default_speed)
    +{
    + struct device_node *np;
    + u32 *sizeprop;
    +
    + struct isa_reg_property {
    + u32 space;
    + u32 address;
    + u32 size;
    + };
    + struct pci_reg_property {
    + struct pci_address addr;
    + u32 size_hi;
    + u32 size_lo;
    + };
    +
    + DBG(" -> generic_find_legacy_serial_port()\n");
    +
    + naca->serialPortAddr = 0;
    + if (default_speed)
    + *default_speed = 0;
    +
    + np = of_find_node_by_path("/");
    + if (!np)
    + return;
    +
    + /* First fill our array */
    + for (np = NULL; (np = of_find_node_by_type(np, "serial"));) {
    + struct device_node *isa, *pci;
    + struct isa_reg_property *reg;
    + unsigned long phys_size, addr_size, io_base;
    + u32 *rangesp;
    + u32 *interrupts, *clk, *spd;
    + char *typep;
    + int index, rlen, rentsize;
    +
    + /* Ok, first check if it's under an "isa" parent */
    + isa = of_get_parent(np);
    + if (!isa || strcmp(isa->name, "isa")) {
    + DBG("%s: no isa parent found\n", np->full_name);
    + continue;
    + }
    +
    + /* Now look for an "ibm,aix-loc" property that gives us ordering
    + * if any...
    + */
    + typep = (char *)get_property(np, "ibm,aix-loc", NULL);
    +
    + /* Get the ISA port number */
    + reg = (struct isa_reg_property *)get_property(np, "reg", NULL);
    + if (reg == NULL)
    + goto next_port;
    + /* We assume the interrupt number isn't translated ... */
    + interrupts = (u32 *)get_property(np, "interrupts", NULL);
    + /* get clock freq. if present */
    + clk = (u32 *)get_property(np, "clock-frequency", NULL);
    + /* get default speed if present */
    + spd = (u32 *)get_property(np, "current-speed", NULL);
    + /* Default to locate at end of array */
    + index = old_serial_count; /* end of the array by default */
    +
    + /* If we have a location index, then use it */
    + if (typep && *typep == 'S') {
    + index = simple_strtol(typep+1, NULL, 0) - 1;
    + /* if index is out of range, use end of array instead */
    + if (index >= MAX_LEGACY_SERIAL_PORTS)
    + index = old_serial_count;
    + /* if our index is still out of range, that mean that
    + * array is full, we could scan for a free slot but that
    + * make little sense to bother, just skip the port
    + */
    + if (index >= MAX_LEGACY_SERIAL_PORTS)
    + goto next_port;
    + if (index >= old_serial_count)
    + old_serial_count = index + 1;
    + /* Check if there is a port who already claimed our slot */
    + if (old_serial_ports[index].port != 0) {
    + /* if we still have some room, move it, else override */
    + if (old_serial_count < MAX_LEGACY_SERIAL_PORTS) {
    + DBG("Moved legacy port %d -> %d\n", index,
    + old_serial_count);
    + old_serial_ports[old_serial_count++] =
    + old_serial_ports[index];
    + } else {
    + DBG("Replacing legacy port %d\n", index);
    + }
    + }
    + }
    + if (index >= MAX_LEGACY_SERIAL_PORTS)
    + goto next_port;
    + if (index >= old_serial_count)
    + old_serial_count = index + 1;
    +
    + /* Now fill the entry */
    + memset(&old_serial_ports[index], 0, sizeof(struct old_serial_port));
    + old_serial_ports[index].uart = 0;
    + old_serial_ports[index].baud_base = clk ? (*clk / 16) : BASE_BAUD;
    + old_serial_ports[index].port = reg->address;
    + old_serial_ports[index].irq = interrupts ? interrupts[0] : 0;
    + old_serial_ports[index].flags = ASYNC_BOOT_AUTOCONF;
    +
    + DBG("Added legacy port, index: %d, port: %x, irq: %d, clk: %d\n",
    + index,
    + old_serial_ports[index].port,
    + old_serial_ports[index].irq,
    + old_serial_ports[index].baud_base * 16);
    +
    + /* Get phys address of IO reg for port 1 */
    + if (index != 0)
    + goto next_port;
    +
    + pci = of_get_parent(isa);
    + if (!pci) {
    + DBG("%s: no pci parent found\n", np->full_name);
    + goto next_port;
    + }
    +
    + rangesp = (u32 *)get_property(pci, "ranges", &rlen);
    + if (rangesp == NULL) {
    + of_node_put(pci);
    + goto next_port;
    + }
    + rlen /= 4;
    +
    + /* we need the #size-cells of the PCI bridge node itself */
    + phys_size = 1;
    + sizeprop = (u32 *)get_property(pci, "#size-cells", NULL);
    + if (sizeprop != NULL)
    + phys_size = *sizeprop;
    + /* we need the parent #addr-cells */
    + addr_size = prom_n_addr_cells(pci);
    + rentsize = 3 + addr_size + phys_size;
    + io_base = 0;
    + for (;rlen >= rentsize; rlen -= rentsize,rangesp += rentsize) {
    + if (((rangesp[0] >> 24) & 0x3) != 1)
    + continue; /* not IO space */
    + io_base = rangesp[3];
    + if (addr_size == 2)
    + io_base = (io_base << 32) | rangesp[4];
    + }
    + if (io_base != 0) {
    + naca->serialPortAddr = io_base + reg->address;
    + if (default_speed && spd)
    + *default_speed = *spd;
    + }
    + of_node_put(pci);
    + next_port:
    + of_node_put(isa);
    + }
    +
    + DBG(" <- generic_find_legacy_serial_port()\n");
    +}
    +
    +struct old_serial_port *get_legacy_serial_ports(unsigned int *count)
    +{
    + *count = old_serial_count;
    + return old_serial_ports;
    +}
    +EXPORT_SYMBOL(get_legacy_serial_ports);
    +
     #ifdef CONFIG_XMON
     static int __init early_xmon(char *p)
     {
    Index: linux-maple/arch/ppc64/kernel/udbg.c
    ===================================================================
    --- linux-maple.orig/arch/ppc64/kernel/udbg.c 2004-10-19 13:37:19.000000000 +1000
    +++ linux-maple/arch/ppc64/kernel/udbg.c 2004-10-19 16:13:04.274553528 +1000
    @@ -49,15 +49,28 @@
     
     static volatile struct NS16550 *udbg_comport;
     
    -void udbg_init_uart(void *comport)
    +void udbg_init_uart(void *comport, unsigned int speed)
     {
    + u8 dll = 12;
    +
    + switch(speed) {
    + case 115200:
    + dll = 1;
    + break;
    + case 57600:
    + dll = 2;
    + break;
    + case 38400:
    + dll = 3;
    + break;
    + }
             if (comport) {
                     udbg_comport = (struct NS16550 *)comport;
                     udbg_comport->lcr = 0x00; eieio();
                     udbg_comport->ier = 0xFF; eieio();
                     udbg_comport->ier = 0x00; eieio();
                     udbg_comport->lcr = 0x80; eieio(); /* Access baud rate */
    - udbg_comport->dll = 12; eieio(); /* 1 = 115200, 2 = 57600, 3 = 38400, 12 = 9600 baud */
    + udbg_comport->dll = dll; eieio(); /* 1 = 115200, 2 = 57600, 3 = 38400, 12 = 9600 baud */
                     udbg_comport->dlm = 0; eieio(); /* dll >> 8 which should be zero for fast rates; */
                     udbg_comport->lcr = 0x03; eieio(); /* 8 data, 1 stop, no parity */
                     udbg_comport->mcr = 0x03; eieio(); /* RTS/DTR */
    Index: linux-maple/include/asm-ppc64/serial.h
    ===================================================================
    --- linux-maple.orig/include/asm-ppc64/serial.h 2004-10-19 13:37:55.000000000 +1000
    +++ linux-maple/include/asm-ppc64/serial.h 2004-10-19 16:13:04.283552160 +1000
    @@ -18,113 +18,13 @@
      * as published by the Free Software Foundation; either version
      * 2 of the License, or (at your option) any later version.
      */
    -#define BASE_BAUD ( 1843200 / 16 )
    -
    -#ifdef CONFIG_SERIAL_MANY_PORTS
    -#define RS_TABLE_SIZE 64
    -#else
    -#define RS_TABLE_SIZE 4
    -#endif
    -
    -/* Standard COM flags (except for COM4, because of the 8514 problem) */
    -#ifdef CONFIG_SERIAL_DETECT_IRQ
    -#define STD_COM_FLAGS (ASYNC_BOOT_AUTOCONF | ASYNC_AUTO_IRQ)
    -#else
    -#define STD_COM_FLAGS ASYNC_BOOT_AUTOCONF
    -#endif
    -
    -#ifdef CONFIG_SERIAL_MANY_PORTS
    -#define FOURPORT_FLAGS ASYNC_FOURPORT
    -#define ACCENT_FLAGS 0
    -#define BOCA_FLAGS 0
    -#define HUB6_FLAGS 0
    -#endif
    -
    -/*
    - * The following define the access methods for the HUB6 card. All
    - * access is through two ports for all 24 possible chips. The card is
    - * selected through the high 2 bits, the port on that card with the
    - * "middle" 3 bits, and the register on that port with the bottom
    - * 3 bits.
    - *
    - * While the access port and interrupt is configurable, the default
    - * port locations are 0x302 for the port control register, and 0x303
    - * for the data read/write register. Normally, the interrupt is at irq3
    - * but can be anything from 3 to 7 inclusive. Note that using 3 will
    - * require disabling com2.
    - */
    -
    -#define C_P(card,port) (((card)<<6|(port)<<3) + 1)
     
    -#define STD_SERIAL_PORT_DEFNS \
    - /* UART CLK PORT IRQ FLAGS */ \
    - { 0, BASE_BAUD, 0x3F8, 4, STD_COM_FLAGS }, /* ttyS0 */ \
    - { 0, BASE_BAUD, 0x2F8, 3, STD_COM_FLAGS }, /* ttyS1 */ \
    - { 0, BASE_BAUD, 0x890, 0xf, STD_COM_FLAGS }, /* ttyS2 */ \
    - { 0, BASE_BAUD, 0x898, 0xe, STD_COM_FLAGS }, /* ttyS3 */
    -
    -
    -#ifdef CONFIG_SERIAL_MANY_PORTS
    -#define EXTRA_SERIAL_PORT_DEFNS \
    - { 0, BASE_BAUD, 0x1A0, 9, FOURPORT_FLAGS }, /* ttyS4 */ \
    - { 0, BASE_BAUD, 0x1A8, 9, FOURPORT_FLAGS }, /* ttyS5 */ \
    - { 0, BASE_BAUD, 0x1B0, 9, FOURPORT_FLAGS }, /* ttyS6 */ \
    - { 0, BASE_BAUD, 0x1B8, 9, FOURPORT_FLAGS }, /* ttyS7 */ \
    - { 0, BASE_BAUD, 0x2A0, 5, FOURPORT_FLAGS }, /* ttyS8 */ \
    - { 0, BASE_BAUD, 0x2A8, 5, FOURPORT_FLAGS }, /* ttyS9 */ \
    - { 0, BASE_BAUD, 0x2B0, 5, FOURPORT_FLAGS }, /* ttyS10 */ \
    - { 0, BASE_BAUD, 0x2B8, 5, FOURPORT_FLAGS }, /* ttyS11 */ \
    - { 0, BASE_BAUD, 0x330, 4, ACCENT_FLAGS }, /* ttyS12 */ \
    - { 0, BASE_BAUD, 0x338, 4, ACCENT_FLAGS }, /* ttyS13 */ \
    - { 0, BASE_BAUD, 0x000, 0, 0 }, /* ttyS14 (spare) */ \
    - { 0, BASE_BAUD, 0x000, 0, 0 }, /* ttyS15 (spare) */ \
    - { 0, BASE_BAUD, 0x100, 12, BOCA_FLAGS }, /* ttyS16 */ \
    - { 0, BASE_BAUD, 0x108, 12, BOCA_FLAGS }, /* ttyS17 */ \
    - { 0, BASE_BAUD, 0x110, 12, BOCA_FLAGS }, /* ttyS18 */ \
    - { 0, BASE_BAUD, 0x118, 12, BOCA_FLAGS }, /* ttyS19 */ \
    - { 0, BASE_BAUD, 0x120, 12, BOCA_FLAGS }, /* ttyS20 */ \
    - { 0, BASE_BAUD, 0x128, 12, BOCA_FLAGS }, /* ttyS21 */ \
    - { 0, BASE_BAUD, 0x130, 12, BOCA_FLAGS }, /* ttyS22 */ \
    - { 0, BASE_BAUD, 0x138, 12, BOCA_FLAGS }, /* ttyS23 */ \
    - { 0, BASE_BAUD, 0x140, 12, BOCA_FLAGS }, /* ttyS24 */ \
    - { 0, BASE_BAUD, 0x148, 12, BOCA_FLAGS }, /* ttyS25 */ \
    - { 0, BASE_BAUD, 0x150, 12, BOCA_FLAGS }, /* ttyS26 */ \
    - { 0, BASE_BAUD, 0x158, 12, BOCA_FLAGS }, /* ttyS27 */ \
    - { 0, BASE_BAUD, 0x160, 12, BOCA_FLAGS }, /* ttyS28 */ \
    - { 0, BASE_BAUD, 0x168, 12, BOCA_FLAGS }, /* ttyS29 */ \
    - { 0, BASE_BAUD, 0x170, 12, BOCA_FLAGS }, /* ttyS30 */ \
    - { 0, BASE_BAUD, 0x178, 12, BOCA_FLAGS }, /* ttyS31 */
    -#else
    -#define EXTRA_SERIAL_PORT_DEFNS
    -#endif
    -
    -/* You can have up to four HUB6's in the system, but I've only
    - * included two cards here for a total of twelve ports.
    - */
    -#if (defined(CONFIG_HUB6) && defined(CONFIG_SERIAL_MANY_PORTS))
    -#define HUB6_SERIAL_PORT_DFNS \
    - { 0, BASE_BAUD, 0x302, 3, HUB6_FLAGS, C_P(0,0) }, /* ttyS32 */ \
    - { 0, BASE_BAUD, 0x302, 3, HUB6_FLAGS, C_P(0,1) }, /* ttyS33 */ \
    - { 0, BASE_BAUD, 0x302, 3, HUB6_FLAGS, C_P(0,2) }, /* ttyS34 */ \
    - { 0, BASE_BAUD, 0x302, 3, HUB6_FLAGS, C_P(0,3) }, /* ttyS35 */ \
    - { 0, BASE_BAUD, 0x302, 3, HUB6_FLAGS, C_P(0,4) }, /* ttyS36 */ \
    - { 0, BASE_BAUD, 0x302, 3, HUB6_FLAGS, C_P(0,5) }, /* ttyS37 */ \
    - { 0, BASE_BAUD, 0x302, 3, HUB6_FLAGS, C_P(1,0) }, /* ttyS38 */ \
    - { 0, BASE_BAUD, 0x302, 3, HUB6_FLAGS, C_P(1,1) }, /* ttyS39 */ \
    - { 0, BASE_BAUD, 0x302, 3, HUB6_FLAGS, C_P(1,2) }, /* ttyS40 */ \
    - { 0, BASE_BAUD, 0x302, 3, HUB6_FLAGS, C_P(1,3) }, /* ttyS41 */ \
    - { 0, BASE_BAUD, 0x302, 3, HUB6_FLAGS, C_P(1,4) }, /* ttyS42 */ \
    - { 0, BASE_BAUD, 0x302, 3, HUB6_FLAGS, C_P(1,5) }, /* ttyS43 */
    -#else
    -#define HUB6_SERIAL_PORT_DFNS
    -#endif
    -
    -#define MCA_SERIAL_PORT_DFNS
    +/* Default baud base if not found in device-tree */
    +#define BASE_BAUD ( 1843200 / 16 )
     
    -#define SERIAL_PORT_DFNS \
    - STD_SERIAL_PORT_DEFNS \
    - EXTRA_SERIAL_PORT_DEFNS \
    - HUB6_SERIAL_PORT_DFNS \
    - MCA_SERIAL_PORT_DFNS
    +#define ARCH_HAS_GET_LEGACY_SERIAL_PORTS
    +struct old_serial_port;
    +extern struct old_serial_port *get_legacy_serial_ports(unsigned int *count);
    +#define UART_NR (8 + CONFIG_SERIAL_8250_NR_UARTS)
     
     #endif /* _PPC64_SERIAL_H */
    Index: linux-maple/arch/ppc64/kernel/pSeries_setup.c
    ===================================================================
    --- linux-maple.orig/arch/ppc64/kernel/pSeries_setup.c 2004-10-19 13:37:21.000000000 +1000
    +++ linux-maple/arch/ppc64/kernel/pSeries_setup.c 2004-10-19 16:13:04.304548968 +1000
    @@ -82,6 +82,8 @@
     extern int pSeries_set_rtc_time(struct rtc_time *rtc_time);
     extern void find_udbg_vterm(void);
     extern void SystemReset_FWNMI(void), MachineCheck_FWNMI(void); /* from head.S */
    +extern void generic_find_legacy_serial_ports(unsigned int *default_speed);
    +
     int fwnmi_active; /* TRUE if an FWNMI handler is present */
     
     unsigned long virtPython0Facilities = 0; // python0 facility area (memory mapped io) (64-bit format) VIRTUAL address.
    @@ -189,75 +191,6 @@
     arch_initcall(pSeries_init_panel);
     
     
    -
    -void __init pSeries_find_serial_port(void)
    -{
    - struct device_node *np;
    - unsigned long encode_phys_size = 32;
    - u32 *sizeprop;
    -
    - struct isa_reg_property {
    - u32 space;
    - u32 address;
    - u32 size;
    - };
    - struct pci_reg_property {
    - struct pci_address addr;
    - u32 size_hi;
    - u32 size_lo;
    - };
    -
    - DBG(" -> pSeries_find_serial_port()\n");
    -
    - naca->serialPortAddr = 0;
    -
    - np = of_find_node_by_path("/");
    - if (!np)
    - return;
    - sizeprop = (u32 *)get_property(np, "#size-cells", NULL);
    - if (sizeprop != NULL)
    - encode_phys_size = (*sizeprop) << 5;
    -
    - for (np = NULL; (np = of_find_node_by_type(np, "serial"));) {
    - struct device_node *isa, *pci;
    - struct isa_reg_property *reg;
    - union pci_range *rangesp;
    - char *typep;
    -
    - typep = (char *)get_property(np, "ibm,aix-loc", NULL);
    - if ((typep == NULL) || (typep && strcmp(typep, "S1")))
    - continue;
    -
    - reg = (struct isa_reg_property *)get_property(np, "reg", NULL);
    -
    - isa = of_get_parent(np);
    - if (!isa) {
    - DBG("no isa parent found\n");
    - break;
    - }
    - pci = of_get_parent(isa);
    - if (!pci) {
    - DBG("no pci parent found\n");
    - break;
    - }
    -
    - rangesp = (union pci_range *)get_property(pci, "ranges", NULL);
    -
    - if ( encode_phys_size == 32 )
    - naca->serialPortAddr = rangesp->pci32.phys+reg->address;
    - else {
    - naca->serialPortAddr =
    - ((((unsigned long)rangesp->pci64.phys_hi) << 32)
    - |
    - (rangesp->pci64.phys_lo)) + reg->address;
    - }
    - break;
    - }
    -
    - DBG(" <- pSeries_find_serial_port()\n");
    -}
    -
    -
     /* Build up the firmware_features bitmask field
      * using contents of device-tree/ibm,hypertas-functions.
      * Ultimately this functionality may be moved into prom.c prom_init().
    @@ -337,6 +270,7 @@
     {
             void *comport;
             int iommu_off = 0;
    + unsigned int default_speed;
     
             DBG(" -> pSeries_init_early()\n");
     
    @@ -350,14 +284,14 @@
                                  get_property(of_chosen, "linux,iommu-off", NULL));
             }
     
    - pSeries_find_serial_port();
    + generic_find_legacy_serial_ports(&default_speed);
     
             if (systemcfg->platform & PLATFORM_LPAR)
                     find_udbg_vterm();
             else if (naca->serialPortAddr) {
                     /* Map the uart for udbg. */
                     comport = (void *)__ioremap(naca->serialPortAddr, 16, _PAGE_NO_CACHE);
    - udbg_init_uart(comport);
    + udbg_init_uart(comport, default_speed);
     
                     ppc_md.udbg_putc = udbg_putc;
                     ppc_md.udbg_getc = udbg_getc;
    Index: linux-maple/include/asm-ppc64/udbg.h
    ===================================================================
    --- linux-maple.orig/include/asm-ppc64/udbg.h 2004-10-19 13:37:22.000000000 +1000
    +++ linux-maple/include/asm-ppc64/udbg.h 2004-10-19 16:13:04.305548816 +1000
    @@ -10,7 +10,7 @@
      * 2 of the License, or (at your option) any later version.
      */
     
    -void udbg_init_uart(void *comport);
    +void udbg_init_uart(void *comport, unsigned int speed);
     void udbg_putc(unsigned char c);
     unsigned char udbg_getc(void);
     int udbg_getc_poll(void);

    -
    To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
    the body of a message to majordomo@vger.kernel.org
    More majordomo info at http://vger.kernel.org/majordomo-info.html
    Please read the FAQ at http://www.tux.org/lkml/


  • Next message: Meelis Roos: "Re: [PATCH] Re: Weird... 2.6.9 kills FC2 gcc"

    Relevant Pages

    • Re: 1-wire to USB converter that can use 1820s directly
      ... than to need to add another PCI card to support serial ports. ... how someone could finally say "not one more f'ing wire!" ...
      (comp.home.automation)
    • Re: remote access KVM switch
      ... ->>seen so many Lightwave KVM switches around in server rooms. ... Some console servers even allow ssh access. ... -> very sophisticated, but it has 30 serial ports, telnet ...
      (comp.sys.sun.admin)
    • Re: How 2 connect old computer db9 port to new laptop with db15 or usb
      ... All serial ports are male (the pins ... has a DB9 male port and my new laptop has a DB15 male port and usb ports. ... Support for Flash drives and USB connected hard drives in Windows 98 ...
      (microsoft.public.windowsxp.hardware)
    • Re: Sun Microsystems Enterprise 3500 server
      ... are 5 ethernet ports to choose from. ... the same board that has the serial ports A & B. And there is another ... bottom of the front panel are an MII connector (ethernet which I have ... possibly Fibre Channel intterfaces called OLC j0 and OLC 1). ...
      (comp.sys.sun.hardware)
    • Re: Late to the party: Whats Rosetta?
      ... will have 5 full duplex serial ports, two TTL ports and one pin that can be ... The ZX-24 firmware can be updated over the serial link. ... The other four serial ports are 9600 MAX and will understand the ... communications protocols for the CM11A, CPU/XA, Ocelot, Leopard, Smarthome ...
      (comp.home.automation)