> Date: Wed, 5 Aug 2020 16:39:06 -0500
> From: joshua stein <[email protected]>
> Content-Type: text/plain; charset=utf-8
> Content-Disposition: inline
> 
> In 2018 I added support for Exar XR17V35x serial ports:
> 
>     The Exar XR17V354 has 4 com ports that have a 256-byte FIFO, use a
>     frequency of 125Mhz, and have a unique sleep register.  A custom
>     interrupt handler is setup in puc for these ports so it can check a
>     register which reports which ports triggered the interrupt, rather
>     than having to run comintr for every port every time.
> 
> https://github.com/openbsd/src/commit/21514470a28cb3682074159e69358d924e73f5f1
> 
> This was backed out shortly after:
> 
>     Revert previous commit; the XR17V35X probe that was added accesses 
> registers
>     that aren't guaranteed to be there and may even belong to a different 
> device.
>     This triggers a fault on hppa machines like the C3000 for example.
> 
> https://github.com/openbsd/src/commit/9f2c39383ee470c5b76fb828f64ea58341b214e9
> https://github.com/openbsd/src/commit/b40f90ead5d17e757784d1aa91d0d0406ce61d20
> 
> I needed this again, so this version sets the sc_uarttype in 
> com_puc_attach ahead of time because the type of port is already 
> known (from pucdata.c).  This avoids any probe in com_attach_subr 
> which previously tried to upgrade from COM_UART_16550A to 
> COM_UART_XR17V35X.
> 
> puc0 at pci4 dev 0 function 0 "Exar XR17V354" rev 0x03: ports: 16 com
> com4 at puc0 port 0 apic 5 int 16: xr17v35x, 256 byte fifo
> com5 at puc0 port 1 apic 5 int 16: xr17v35x, 256 byte fifo
> com6 at puc0 port 2 apic 5 int 16: xr17v35x, 256 byte fifo
> com7 at puc0 port 3 apic 5 int 16: xr17v35x, 256 byte fifo

Yes, this is a better approach.  Two (smallish) issues below though.

> Index: sys/dev/ic/com.c
> ===================================================================
> RCS file: /cvs/src/sys/dev/ic/com.c,v
> retrieving revision 1.172
> diff -u -p -u -p -r1.172 com.c
> --- sys/dev/ic/com.c  9 Mar 2020 04:38:46 -0000       1.172
> +++ sys/dev/ic/com.c  5 Aug 2020 21:35:02 -0000
> @@ -306,6 +306,9 @@ comopen(dev_t dev, int flag, int mode, s
>                       case COM_UART_TI16750:
>                               com_write_reg(sc, com_ier, 0);
>                               break;
> +                     case COM_UART_XR17V35X:
> +                             com_write_reg(sc, UART_EXAR_SLEEP, 0);
> +                             break;
>                       }
>               }
>  
> @@ -498,6 +501,9 @@ compwroff(struct com_softc *sc)
>               case COM_UART_TI16750:
>                       com_write_reg(sc, com_ier, IER_SLEEP);
>                       break;
> +             case COM_UART_XR17V35X:
> +                     com_write_reg(sc, UART_EXAR_SLEEP, 0xff);
> +                     break;
>               }
>       }
>  }
> @@ -533,6 +539,9 @@ com_resume(struct com_softc *sc)
>               case COM_UART_TI16750:
>                       com_write_reg(sc, com_ier, 0);
>                       break;
> +             case COM_UART_XR17V35X:
> +                     com_write_reg(sc, UART_EXAR_SLEEP, 0);
> +                     break;
>               }
>       }
>  
> @@ -919,7 +928,7 @@ comstart(struct tty *tp)
>       }
>  
>       if (ISSET(sc->sc_hwflags, COM_HW_FIFO)) {
> -             u_char buffer[128];     /* largest fifo */
> +             u_char buffer[256];     /* largest fifo */
>               int i, n;
>  
>               n = q_to_b(&tp->t_outq, buffer,
> @@ -1466,6 +1475,11 @@ com_attach_subr(struct com_softc *sc)
>               break;
>  #endif
>  #endif
> +     case COM_UART_XR17V35X:
> +             printf(": xr17v35x, 256 byte fifo\n");
> +             SET(sc->sc_hwflags, COM_HW_FIFO);
> +             sc->sc_fifolen = 256;
> +             break;
>       default:
>               panic("comattach: bad fifo type");
>       }
> @@ -1473,7 +1487,8 @@ com_attach_subr(struct com_softc *sc)
>  #ifdef COM_CONSOLE
>       if (!ISSET(sc->sc_hwflags, COM_HW_CONSOLE))
>  #endif
> -             com_fifo_probe(sc);
> +             if (sc->sc_fifolen < 256)
> +                     com_fifo_probe(sc);
>  
>       if (sc->sc_fifolen == 0) {
>               CLR(sc->sc_hwflags, COM_HW_FIFO);
> Index: sys/dev/ic/comreg.h
> ===================================================================
> RCS file: /cvs/src/sys/dev/ic/comreg.h,v
> retrieving revision 1.19
> diff -u -p -u -p -r1.19 comreg.h
> --- sys/dev/ic/comreg.h       2 May 2018 13:20:12 -0000       1.19
> +++ sys/dev/ic/comreg.h       5 Aug 2020 21:35:02 -0000
> @@ -182,6 +182,11 @@
>  
>  #define      COM_NPORTS      8
>  
> +/* Exar XR17V35X */
> +#define UART_EXAR_INT0       0x80
> +#define UART_EXAR_SLEEP      0x8b    /* Sleep mode */
> +#define UART_EXAR_DVID       0x8d    /* Device identification */
> +
>  /*
>   * WARNING: Serial console is assumed to be at COM1 address
>   */
> Index: sys/dev/ic/comvar.h
> ===================================================================
> RCS file: /cvs/src/sys/dev/ic/comvar.h,v
> retrieving revision 1.57
> diff -u -p -u -p -r1.57 comvar.h
> --- sys/dev/ic/comvar.h       14 May 2018 19:25:54 -0000      1.57
> +++ sys/dev/ic/comvar.h       5 Aug 2020 21:35:02 -0000
> @@ -103,6 +103,7 @@ struct com_softc {
>  #define      COM_UART_ST16C654       0x08            /* 64 bytes fifo */
>  #define      COM_UART_XR16850        0x10            /* 128 byte fifo */
>  #define      COM_UART_OX16C950       0x11            /* 128 byte fifo */
> +#define      COM_UART_XR17V35X       0x12            /* 256 byte fifo */
>  
>       u_char sc_hwflags;
>  #define      COM_HW_NOIEN    0x01
> Index: sys/dev/pci/puc.c
> ===================================================================
> RCS file: /cvs/src/sys/dev/pci/puc.c,v
> retrieving revision 1.29
> diff -u -p -u -p -r1.29 puc.c
> --- sys/dev/pci/puc.c 2 Mar 2020 19:45:42 -0000       1.29
> +++ sys/dev/pci/puc.c 5 Aug 2020 21:35:03 -0000
> @@ -61,6 +61,7 @@
>  #include <dev/pci/pcireg.h>
>  #include <dev/pci/pcivar.h>
>  #include <dev/pci/pucvar.h>
> +#include <dev/pci/pcidevs.h>
>  
>  #include <dev/ic/comreg.h>
>  #include <dev/ic/comvar.h>
> @@ -80,6 +81,7 @@ int puc_pci_detach(struct device *, int)
>  const char *puc_pci_intr_string(struct puc_attach_args *);
>  void *puc_pci_intr_establish(struct puc_attach_args *, int,
>      int (*)(void *), void *, char *);
> +int  puc_pci_xr17v35x_intr(void *arg);
>  
>  struct cfattach puc_pci_ca = {
>       sizeof(struct puc_pci_softc), puc_pci_match,
> @@ -127,9 +129,20 @@ puc_pci_intr_establish(struct puc_attach
>  {
>       struct puc_pci_softc *sc = paa->puc;
>       struct puc_softc *psc = &sc->sc_psc;
> -     
> -     psc->sc_ports[paa->port].intrhand =
> -         pci_intr_establish(sc->pc, sc->ih, type, func, arg, name);
> +
> +     if (psc->sc_xr17v35x) {
> +             psc->sc_ports[paa->port].real_intrhand = func;
> +             psc->sc_ports[paa->port].real_intrhand_arg = arg;
> +             if (paa->port == 0)
> +                     psc->sc_ports[paa->port].intrhand =
> +                         pci_intr_establish(sc->pc, sc->ih, type,
> +                         puc_pci_xr17v35x_intr, sc, name);
> +             return (psc->sc_ports[paa->port].real_intrhand);
> +     } else {
> +             psc->sc_ports[paa->port].intrhand =
> +                 pci_intr_establish(sc->pc, sc->ih, type, func, arg, name);
> +             return (psc->sc_ports[paa->port].intrhand);
> +     }
>  
>       return (psc->sc_ports[paa->port].intrhand);

This last return is unreachable.

>  }
> @@ -148,6 +161,10 @@ puc_pci_attach(struct device *parent, st
>       sc->sc_desc = puc_find_description(PCI_VENDOR(pa->pa_id),
>           PCI_PRODUCT(pa->pa_id), PCI_VENDOR(subsys), PCI_PRODUCT(subsys));
>  
> +     if (PCI_VENDOR(pa->pa_id) == PCI_VENDOR_EXAR &&
> +         PCI_PRODUCT(pa->pa_id) == PCI_PRODUCT_EXAR_XR17V354)
> +             sc->sc_xr17v35x = 1;
> +
>       puc_print_ports(sc->sc_desc);
>  
>       for (i = 0; i < PUC_NBARS; i++) {
> @@ -328,7 +345,6 @@ puc_find_description(u_int16_t vend, u_i
>  const char *
>  puc_port_type_name(int type)
>  {
> -
>       if (PUC_IS_COM(type))
>               return "com";
>       if (PUC_IS_LPT(type))
> @@ -356,4 +372,23 @@ puc_print_ports(const struct puc_device_
>               printf("%d lpt", nlpt);
>       }
>       printf("\n");
> +}
> +
> +int
> +puc_pci_xr17v35x_intr(void *arg)
> +{
> +     struct puc_pci_softc *sc = arg;
> +     struct puc_softc *psc = &sc->sc_psc;
> +     int ports, i;
> +
> +     ports = bus_space_read_1(psc->sc_bar_mappings[0].t,
> +         psc->sc_bar_mappings[0].h, UART_EXAR_INT0);
> +
> +     for (i = 0; i < 8; i++) {
> +             if ((ports & (1 << i)) && psc->sc_ports[i].real_intrhand)
> +                     (*(psc->sc_ports[i].real_intrhand))(
> +                         psc->sc_ports[i].real_intrhand_arg);
> +     }
> +
> +     return (1);
>  }
> Index: sys/dev/pci/pucdata.c
> ===================================================================
> RCS file: /cvs/src/sys/dev/pci/pucdata.c,v
> retrieving revision 1.111
> diff -u -p -u -p -r1.111 pucdata.c
> --- sys/dev/pci/pucdata.c     5 Jan 2020 01:07:59 -0000       1.111
> +++ sys/dev/pci/pucdata.c     5 Aug 2020 21:35:03 -0000
> @@ -2083,10 +2083,10 @@ const struct puc_device_description puc_
>           {   PCI_VENDOR_EXAR, PCI_PRODUCT_EXAR_XR17V354,     0, 0 },
>           {   0xffff, 0xffff,                                 0, 0 },
>           {
> -             { PUC_PORT_COM_MUL8, 0x10, 0x0000 },
> -             { PUC_PORT_COM_MUL8, 0x10, 0x0400 },
> -             { PUC_PORT_COM_MUL8, 0x10, 0x0800 },
> -             { PUC_PORT_COM_MUL8, 0x10, 0x0C00 },
> +             { PUC_PORT_COM_XR17V35X, 0x10, 0x0000 },
> +             { PUC_PORT_COM_XR17V35X, 0x10, 0x0400 },
> +             { PUC_PORT_COM_XR17V35X, 0x10, 0x0800 },
> +             { PUC_PORT_COM_XR17V35X, 0x10, 0x0C00 },
>           },
>       },
>  
> Index: sys/dev/pci/pucvar.h
> ===================================================================
> RCS file: /cvs/src/sys/dev/pci/pucvar.h,v
> retrieving revision 1.16
> diff -u -p -u -p -r1.16 pucvar.h
> --- sys/dev/pci/pucvar.h      2 May 2018 19:11:01 -0000       1.16
> +++ sys/dev/pci/pucvar.h      5 Aug 2020 21:35:03 -0000
> @@ -60,7 +60,7 @@ struct puc_port_type {
>               PUC_PORT_COM_MUL8,
>               PUC_PORT_COM_MUL10,
>               PUC_PORT_COM_MUL128,
> -             PUC_PORT_COM_125MHZ,
> +             PUC_PORT_COM_XR17V35X,
>       } type;
>       u_int32_t       freq;
>  };
> @@ -72,6 +72,7 @@ static const struct puc_port_type puc_po
>       { PUC_PORT_COM_MUL8,    COM_FREQ * 8    },
>       { PUC_PORT_COM_MUL10,   COM_FREQ * 10   },
>       { PUC_PORT_COM_MUL128,  COM_FREQ * 128  },
> +     { PUC_PORT_COM_XR17V35X,125000000       },

There should be a space after the comma; it's ok if things don't line up.

>  };
>  
>  #define PUC_IS_LPT(type)     ((type) == PUC_PORT_LPT)
> @@ -117,7 +118,11 @@ struct puc_softc {
>               struct device   *dev;
>               /* filled in by port attachments */
>               void    *intrhand;
> +             int     (*real_intrhand)(void *);
> +             void    *real_intrhand_arg;
>       } sc_ports[PUC_MAX_PORTS];
> +
> +     int                     sc_xr17v35x;
>  };
>  
>  const struct puc_device_description *
> Index: sys/dev/puc/com_puc.c
> ===================================================================
> RCS file: /cvs/src/sys/dev/puc/com_puc.c,v
> retrieving revision 1.24
> diff -u -p -u -p -r1.24 com_puc.c
> --- sys/dev/puc/com_puc.c     15 Apr 2018 00:10:59 -0000      1.24
> +++ sys/dev/puc/com_puc.c     5 Aug 2020 21:35:03 -0000
> @@ -109,6 +109,9 @@ com_puc_attach(parent, self, aux)
>                       break;
>               }
>  
> +     if (pa->type == PUC_PORT_COM_XR17V35X)
> +             sc->sc_uarttype = COM_UART_XR17V35X;
> +
>       com_attach_subr(sc);
>  }
>  
> 
> 

Reply via email to