uart_bus_pci.c revision 229379
12116Sjkh/*- 22116Sjkh * Copyright (c) 2006 Marcel Moolenaar 32116Sjkh * Copyright (c) 2001 M. Warner Losh 42116Sjkh * All rights reserved. 52116Sjkh * 62116Sjkh * Redistribution and use in source and binary forms, with or without 72116Sjkh * modification, are permitted provided that the following conditions 82116Sjkh * are met: 92116Sjkh * 1. Redistributions of source code must retain the above copyright 102116Sjkh * notice, this list of conditions and the following disclaimer. 112116Sjkh * 2. Redistributions in binary form must reproduce the above copyright 122116Sjkh * notice, this list of conditions and the following disclaimer in the 132116Sjkh * documentation and/or other materials provided with the distribution. 142116Sjkh * 152116Sjkh * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR 162116Sjkh * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES 172116Sjkh * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. 182116Sjkh * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, 192116Sjkh * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT 202116Sjkh * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 212116Sjkh * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 222116Sjkh * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 232116Sjkh * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF 242116Sjkh * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 252116Sjkh */ 262116Sjkh 272116Sjkh#include <sys/cdefs.h> 282116Sjkh__FBSDID("$FreeBSD: head/sys/dev/uart/uart_bus_pci.c 229379 2012-01-03 10:01:12Z kevlo $"); 292116Sjkh 302116Sjkh#include <sys/param.h> 312116Sjkh#include <sys/systm.h> 322116Sjkh#include <sys/bus.h> 332116Sjkh#include <sys/conf.h> 342116Sjkh#include <sys/kernel.h> 352116Sjkh#include <sys/module.h> 362116Sjkh#include <machine/bus.h> 372116Sjkh#include <sys/rman.h> 382116Sjkh#include <machine/resource.h> 392116Sjkh 402116Sjkh#include <dev/pci/pcivar.h> 412116Sjkh 422116Sjkh#include <dev/uart/uart.h> 432116Sjkh#include <dev/uart/uart_bus.h> 442116Sjkh 452116Sjkh#define DEFAULT_RCLK 1843200 462116Sjkh 472116Sjkhstatic int uart_pci_probe(device_t dev); 482116Sjkh 492116Sjkhstatic device_method_t uart_pci_methods[] = { 502116Sjkh /* Device interface */ 512116Sjkh DEVMETHOD(device_probe, uart_pci_probe), 522116Sjkh DEVMETHOD(device_attach, uart_bus_attach), 532116Sjkh DEVMETHOD(device_detach, uart_bus_detach), 542116Sjkh { 0, 0 } 552116Sjkh}; 562116Sjkh 572116Sjkhstatic driver_t uart_pci_driver = { 582116Sjkh uart_driver_name, 592116Sjkh uart_pci_methods, 602116Sjkh sizeof(struct uart_softc), 612116Sjkh}; 622116Sjkh 632116Sjkhstruct pci_id { 642116Sjkh uint16_t vendor; 652116Sjkh uint16_t device; 662116Sjkh uint16_t subven; 672116Sjkh uint16_t subdev; 682116Sjkh const char *desc; 69 int rid; 70 int rclk; 71}; 72 73static struct pci_id pci_ns8250_ids[] = { 74{ 0x1028, 0x0008, 0xffff, 0, "Dell Remote Access Card III", 0x14, 75 128 * DEFAULT_RCLK }, 76{ 0x1028, 0x0012, 0xffff, 0, "Dell RAC 4 Daughter Card Virtual UART", 0x14, 77 128 * DEFAULT_RCLK }, 78{ 0x1033, 0x0074, 0x1033, 0x8014, "NEC RCV56ACF 56k Voice Modem", 0x10 }, 79{ 0x1033, 0x007d, 0x1033, 0x8012, "NEC RS232C", 0x10 }, 80{ 0x103c, 0x1048, 0x103c, 0x1227, "HP Diva Serial [GSP] UART - Powerbar SP2", 81 0x10 }, 82{ 0x103c, 0x1048, 0x103c, 0x1301, "HP Diva RMP3", 0x14 }, 83{ 0x103c, 0x1290, 0xffff, 0, "HP Auxiliary Diva Serial Port", 0x18 }, 84{ 0x11c1, 0x0480, 0xffff, 0, "Agere Systems Venus Modem (V90, 56KFlex)", 0x14 }, 85{ 0x115d, 0x0103, 0xffff, 0, "Xircom Cardbus Ethernet + 56k Modem", 0x10 }, 86{ 0x1282, 0x6585, 0xffff, 0, "Davicom 56PDV PCI Modem", 0x10 }, 87{ 0x12b9, 0x1008, 0xffff, 0, "3Com 56K FaxModem Model 5610", 0x10 }, 88{ 0x131f, 0x1000, 0xffff, 0, "Siig CyberSerial (1-port) 16550", 0x18 }, 89{ 0x131f, 0x1001, 0xffff, 0, "Siig CyberSerial (1-port) 16650", 0x18 }, 90{ 0x131f, 0x1002, 0xffff, 0, "Siig CyberSerial (1-port) 16850", 0x18 }, 91{ 0x131f, 0x2000, 0xffff, 0, "Siig CyberSerial (1-port) 16550", 0x10 }, 92{ 0x131f, 0x2001, 0xffff, 0, "Siig CyberSerial (1-port) 16650", 0x10 }, 93{ 0x131f, 0x2002, 0xffff, 0, "Siig CyberSerial (1-port) 16850", 0x10 }, 94{ 0x135c, 0x0190, 0xffff, 0, "Quatech SSCLP-100", 0x18 }, 95{ 0x135c, 0x01c0, 0xffff, 0, "Quatech SSCLP-200/300", 0x18 }, 96{ 0x135e, 0x7101, 0xffff, 0, "Sealevel Systems Single Port RS-232/422/485/530", 97 0x18 }, 98{ 0x1407, 0x0110, 0xffff, 0, "Lava Computer mfg DSerial-PCI Port A", 0x10 }, 99{ 0x1407, 0x0111, 0xffff, 0, "Lava Computer mfg DSerial-PCI Port B", 0x10 }, 100{ 0x1407, 0x0510, 0xffff, 0, "Lava SP Serial 550 PCI", 0x10 }, 101{ 0x1409, 0x7168, 0x1409, 0x4025, "Timedia Technology Serial Port", 0x10, 102 8 * DEFAULT_RCLK }, 103{ 0x1409, 0x7168, 0x1409, 0x4027, "Timedia Technology Serial Port", 0x10, 104 8 * DEFAULT_RCLK }, 105{ 0x1409, 0x7168, 0x1409, 0x4028, "Timedia Technology Serial Port", 0x10, 106 8 * DEFAULT_RCLK }, 107{ 0x1409, 0x7168, 0x1409, 0x5025, "Timedia Technology Serial Port", 0x10, 108 8 * DEFAULT_RCLK }, 109{ 0x1409, 0x7168, 0x1409, 0x5027, "Timedia Technology Serial Port", 0x10, 110 8 * DEFAULT_RCLK }, 111{ 0x1415, 0x950b, 0xffff, 0, "Oxford Semiconductor OXCB950 Cardbus 16950 UART", 112 0x10, 16384000 }, 113{ 0x151f, 0x0000, 0xffff, 0, "TOPIC Semiconductor TP560 56k modem", 0x10 }, 114{ 0x8086, 0x1c3d, 0xffff, 0, "Intel AMT - KT Controller", 0x10 }, 115{ 0x8086, 0x8811, 0xffff, 0, "Intel EG20T Serial Port 0", 0x10 }, 116{ 0x8086, 0x8812, 0xffff, 0, "Intel EG20T Serial Port 1", 0x10 }, 117{ 0x8086, 0x8813, 0xffff, 0, "Intel EG20T Serial Port 2", 0x10 }, 118{ 0x8086, 0x8814, 0xffff, 0, "Intel EG20T Serial Port 3", 0x10 }, 119{ 0x9710, 0x9820, 0x1000, 1, "NetMos NM9820 Serial Port", 0x10 }, 120{ 0x9710, 0x9835, 0x1000, 1, "NetMos NM9835 Serial Port", 0x10 }, 121{ 0x9710, 0x9865, 0xa000, 0x1000, "NetMos NM9865 Serial Port", 0x10 }, 122{ 0x9710, 0x9900, 0xa000, 0x1000, 123 "MosChip MCS9900 PCIe to Peripheral Controller", 0x10 }, 124{ 0x9710, 0x9901, 0xa000, 0x1000, 125 "MosChip MCS9901 PCIe to Peripheral Controller", 0x10 }, 126{ 0xdeaf, 0x9051, 0xffff, 0, "Middle Digital PC Weasel Serial Port", 0x10 }, 127{ 0xffff, 0, 0xffff, 0, NULL, 0, 0} 128}; 129 130static struct pci_id * 131uart_pci_match(device_t dev, struct pci_id *id) 132{ 133 uint16_t device, subdev, subven, vendor; 134 135 vendor = pci_get_vendor(dev); 136 device = pci_get_device(dev); 137 while (id->vendor != 0xffff && 138 (id->vendor != vendor || id->device != device)) 139 id++; 140 if (id->vendor == 0xffff) 141 return (NULL); 142 if (id->subven == 0xffff) 143 return (id); 144 subven = pci_get_subvendor(dev); 145 subdev = pci_get_subdevice(dev); 146 while (id->vendor == vendor && id->device == device && 147 (id->subven != subven || id->subdev != subdev)) 148 id++; 149 return ((id->vendor == vendor && id->device == device) ? id : NULL); 150} 151 152static int 153uart_pci_probe(device_t dev) 154{ 155 struct uart_softc *sc; 156 struct pci_id *id; 157 158 sc = device_get_softc(dev); 159 160 id = uart_pci_match(dev, pci_ns8250_ids); 161 if (id != NULL) { 162 sc->sc_class = &uart_ns8250_class; 163 goto match; 164 } 165 /* Add checks for non-ns8250 IDs here. */ 166 return (ENXIO); 167 168 match: 169 if (id->desc) 170 device_set_desc(dev, id->desc); 171 return (uart_bus_probe(dev, 0, id->rclk, id->rid, 0)); 172} 173 174DRIVER_MODULE(uart, pci, uart_pci_driver, uart_devclass, 0, 0); 175