From: gwes@oat.com Subject: netmos/asix nm9912 2 serial 1 parallel port chip To: tech@openbsd.org Date: Mon, 29 Dec 2025 21:15:43 -0500 The ASIX variant of the NetMos NM9901 multiport PCIe chip shows up in inexpensive add-in cards. The chip is marked NM9901 but identifies itself as a 9912 2 serial 1 parallel interface. It will only work correctly using MSI. Using legacy interrupt line signalling it drops interrupts frequently. Many drivers disable MSI for broken chip variants. If this is a problem a quirk table can be added. Testing against other PCIe serial chips is very much desired. Re the change to com.c: Draining the FIFO and input buffers in attach and open beyond a simple once-only flush seems unnecessary. We cannot reliably guarantee the interface is empty. Best effort is all we can do and trying to handle a continuous input stream is futile. Several datasheets declare that flushing the FIFO will not clear the data registers. The interaction isn't clear for other chips. An unlimited loop in the kernel seems risky. Other OSes (xBSDs & Linux) limit attempts to clear the chip. BTW a) the flush code in open is a cut-and-paste of the code in attach. FreeBSD put it into a subroutine. b) cc/clang/llvm combined the two tests of the COM_IIR register at the head of com.c:comintr() That optimization in that instance is harmless but.... caveat emptor. Geoff Steckel Index: dev/ic/com.c =================================================================== RCS file: /cvs/src/sys/dev/ic/com.c,v diff -u -p -u -r1.180 com.c --- dev/ic/com.c 16 Sep 2025 12:18:10 -0000 1.180 +++ dev/ic/com.c 30 Dec 2025 01:31:39 -0000 @@ -338,7 +338,9 @@ comopen(dev_t dev, int flag, int mode, s * * Set the FIFO threshold based on the receive speed. */ - for (;;) { + + /* from NetBSD - prevent infinite loop */ + for (int i = 0; i < 2000; i++) { com_write_reg(sc, com_fifo, 0); delay(100); (void) com_read_reg(sc, com_data); Index: dev/pci/puc.c =================================================================== RCS file: /cvs/src/sys/dev/pci/puc.c,v diff -u -p -u -r1.32 puc.c --- dev/pci/puc.c 9 Nov 2024 10:23:06 -0000 1.32 +++ dev/pci/puc.c 30 Dec 2025 01:43:24 -0000 @@ -216,7 +216,7 @@ puc_pci_attach(struct device *parent, st /* Map interrupt. */ psc->pc = pa->pa_pc; - if (pci_intr_map(pa, &psc->ih)) { + if (pci_intr_map_msi(pa, &psc->ih) != 0 && pci_intr_map(pa, &psc->ih) != 0) { printf("%s: couldn't map interrupt\n", sc->sc_dev.dv_xname); return; }