127d5dc18SMarcel Moolenaar /* 227d5dc18SMarcel Moolenaar * Copyright (c) 2001 M. Warner Losh. All rights reserved. 327d5dc18SMarcel Moolenaar * 427d5dc18SMarcel Moolenaar * Redistribution and use in source and binary forms, with or without 527d5dc18SMarcel Moolenaar * modification, are permitted provided that the following conditions 627d5dc18SMarcel Moolenaar * are met: 727d5dc18SMarcel Moolenaar * 1. Redistributions of source code must retain the above copyright 827d5dc18SMarcel Moolenaar * notice, this list of conditions and the following disclaimer. 927d5dc18SMarcel Moolenaar * 2. Redistributions in binary form must reproduce the above copyright 1027d5dc18SMarcel Moolenaar * notice, this list of conditions and the following disclaimer in the 1127d5dc18SMarcel Moolenaar * documentation and/or other materials provided with the distribution. 1227d5dc18SMarcel Moolenaar * 1327d5dc18SMarcel Moolenaar * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR 1427d5dc18SMarcel Moolenaar * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES 1527d5dc18SMarcel Moolenaar * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. 1627d5dc18SMarcel Moolenaar * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, 1727d5dc18SMarcel Moolenaar * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT 1827d5dc18SMarcel Moolenaar * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 1927d5dc18SMarcel Moolenaar * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 2027d5dc18SMarcel Moolenaar * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 2127d5dc18SMarcel Moolenaar * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF 2227d5dc18SMarcel Moolenaar * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 2327d5dc18SMarcel Moolenaar */ 2427d5dc18SMarcel Moolenaar 2527d5dc18SMarcel Moolenaar #include <sys/cdefs.h> 2627d5dc18SMarcel Moolenaar __FBSDID("$FreeBSD$"); 2727d5dc18SMarcel Moolenaar 2827d5dc18SMarcel Moolenaar #include <sys/param.h> 2927d5dc18SMarcel Moolenaar #include <sys/systm.h> 3027d5dc18SMarcel Moolenaar #include <sys/bus.h> 3127d5dc18SMarcel Moolenaar #include <sys/conf.h> 3227d5dc18SMarcel Moolenaar #include <sys/kernel.h> 3327d5dc18SMarcel Moolenaar #include <sys/module.h> 3427d5dc18SMarcel Moolenaar #include <machine/bus.h> 3527d5dc18SMarcel Moolenaar #include <sys/rman.h> 3627d5dc18SMarcel Moolenaar #include <machine/resource.h> 3727d5dc18SMarcel Moolenaar 3827d5dc18SMarcel Moolenaar #include <dev/pci/pcivar.h> 3927d5dc18SMarcel Moolenaar 4027d5dc18SMarcel Moolenaar #include <dev/uart/uart.h> 4127d5dc18SMarcel Moolenaar #include <dev/uart/uart_bus.h> 4227d5dc18SMarcel Moolenaar 4327d5dc18SMarcel Moolenaar static int uart_pci_probe(device_t dev); 4427d5dc18SMarcel Moolenaar 4527d5dc18SMarcel Moolenaar static device_method_t uart_pci_methods[] = { 4627d5dc18SMarcel Moolenaar /* Device interface */ 4727d5dc18SMarcel Moolenaar DEVMETHOD(device_probe, uart_pci_probe), 4827d5dc18SMarcel Moolenaar DEVMETHOD(device_attach, uart_bus_attach), 4927d5dc18SMarcel Moolenaar DEVMETHOD(device_detach, uart_bus_detach), 5027d5dc18SMarcel Moolenaar { 0, 0 } 5127d5dc18SMarcel Moolenaar }; 5227d5dc18SMarcel Moolenaar 5327d5dc18SMarcel Moolenaar static driver_t uart_pci_driver = { 5427d5dc18SMarcel Moolenaar uart_driver_name, 5527d5dc18SMarcel Moolenaar uart_pci_methods, 5627d5dc18SMarcel Moolenaar sizeof(struct uart_softc), 5727d5dc18SMarcel Moolenaar }; 5827d5dc18SMarcel Moolenaar 5927d5dc18SMarcel Moolenaar struct pci_id { 6027d5dc18SMarcel Moolenaar uint32_t type; 6127d5dc18SMarcel Moolenaar const char *desc; 6227d5dc18SMarcel Moolenaar int rid; 6327d5dc18SMarcel Moolenaar }; 6427d5dc18SMarcel Moolenaar 6527d5dc18SMarcel Moolenaar static struct pci_id pci_ns8250_ids[] = { 6627d5dc18SMarcel Moolenaar { 0x100812b9, "3COM PCI FaxModem", 0x10 }, 6727d5dc18SMarcel Moolenaar { 0x2000131f, "CyberSerial (1-port) 16550", 0x10 }, 6827d5dc18SMarcel Moolenaar { 0x01101407, "Koutech IOFLEX-2S PCI Dual Port Serial", 0x10 }, 6927d5dc18SMarcel Moolenaar { 0x01111407, "Koutech IOFLEX-2S PCI Dual Port Serial", 0x10 }, 7027d5dc18SMarcel Moolenaar { 0x048011c1, "Lucent kermit based PCI Modem", 0x14 }, 7127d5dc18SMarcel Moolenaar { 0x95211415, "Oxford Semiconductor PCI Dual Port Serial", 0x10 }, 7227d5dc18SMarcel Moolenaar { 0x7101135e, "SeaLevel Ultra 530.PCI Single Port Serial", 0x18 }, 7327d5dc18SMarcel Moolenaar { 0x0000151f, "SmartLink 5634PCV SurfRider", 0x10 }, 7427d5dc18SMarcel Moolenaar { 0x0103115d, "Xircom Cardbus modem", 0x10 }, 7527d5dc18SMarcel Moolenaar { 0x98459710, "Netmos Nm9845 PCI Bridge with Dual UART", 0x10 }, 7627d5dc18SMarcel Moolenaar { 0x01c0135c, "Quatech SSCLP-200/300", 0x18 7727d5dc18SMarcel Moolenaar /* 7827d5dc18SMarcel Moolenaar * NB: You must mount the "SPAD" jumper to correctly detect 7927d5dc18SMarcel Moolenaar * the FIFO on the UART. Set the options on the jumpers, 8027d5dc18SMarcel Moolenaar * we do not support the extra registers on the Quatech. 8127d5dc18SMarcel Moolenaar */ 8227d5dc18SMarcel Moolenaar }, 8327d5dc18SMarcel Moolenaar { 0x00000000, NULL, 0 } 8427d5dc18SMarcel Moolenaar }; 8527d5dc18SMarcel Moolenaar 8627d5dc18SMarcel Moolenaar static struct pci_id * 8727d5dc18SMarcel Moolenaar uart_pci_match(uint32_t type, struct pci_id *id) 8827d5dc18SMarcel Moolenaar { 8927d5dc18SMarcel Moolenaar 9027d5dc18SMarcel Moolenaar while (id->type && id->type != type) 9127d5dc18SMarcel Moolenaar id++; 9227d5dc18SMarcel Moolenaar return ((id->type) ? id : NULL); 9327d5dc18SMarcel Moolenaar } 9427d5dc18SMarcel Moolenaar 9527d5dc18SMarcel Moolenaar static int 9627d5dc18SMarcel Moolenaar uart_pci_probe(device_t dev) 9727d5dc18SMarcel Moolenaar { 9827d5dc18SMarcel Moolenaar struct uart_softc *sc; 9927d5dc18SMarcel Moolenaar struct pci_id *id; 10027d5dc18SMarcel Moolenaar 10127d5dc18SMarcel Moolenaar sc = device_get_softc(dev); 10227d5dc18SMarcel Moolenaar 10327d5dc18SMarcel Moolenaar id = uart_pci_match(pci_get_devid(dev), pci_ns8250_ids); 10427d5dc18SMarcel Moolenaar if (id != NULL) { 10527d5dc18SMarcel Moolenaar sc->sc_class = &uart_ns8250_class; 10627d5dc18SMarcel Moolenaar goto match; 10727d5dc18SMarcel Moolenaar } 10827d5dc18SMarcel Moolenaar /* Add checks for non-ns8250 IDs here. */ 10927d5dc18SMarcel Moolenaar return (ENXIO); 11027d5dc18SMarcel Moolenaar 11127d5dc18SMarcel Moolenaar match: 11227d5dc18SMarcel Moolenaar if (id->desc) 11327d5dc18SMarcel Moolenaar device_set_desc(dev, id->desc); 11427d5dc18SMarcel Moolenaar return (uart_bus_probe(dev, 0, 0, id->rid)); 11527d5dc18SMarcel Moolenaar } 11627d5dc18SMarcel Moolenaar 11727d5dc18SMarcel Moolenaar DRIVER_MODULE(uart, pci, uart_pci_driver, uart_devclass, 0, 0); 11827d5dc18SMarcel Moolenaar DRIVER_MODULE(uart, cardbus, uart_pci_driver, uart_devclass, 0, 0); 119