Update copyrights. Mention TuneTracker Systems as a sponsor.
Add several ways to restrict UART probing when matching devices: - max port count, - PCI subsystem ID mask (some cards encode the port count there), - Base Address Register mask (some cards only have UART in the first 2 ranges). Use those to match 2 specific NetMos chips, and avoid screwing up when input_server tries to access UARTs at boggus ranges. git-svn-id: file:///srv/svn/repos/haiku/haiku/trunk@35965 a95241bf-73f2-0310-859d-f6bbb57e9c96
This commit is contained in:
@@ -1,4 +1,8 @@
|
|||||||
/*
|
/*
|
||||||
|
* Copyright 2009-2010, François Revol, <[email protected]>.
|
||||||
|
* Sponsored by TuneTracker Systems.
|
||||||
|
* Based on the Haiku usb_serial driver which is:
|
||||||
|
*
|
||||||
* Copyright (c) 2007-2008 by Michael Lotz
|
* Copyright (c) 2007-2008 by Michael Lotz
|
||||||
* Heavily based on the original usb_serial driver which is:
|
* Heavily based on the original usb_serial driver which is:
|
||||||
*
|
*
|
||||||
@@ -61,6 +65,8 @@ static const uint32 sBeBoxRates[] = {
|
|||||||
};
|
};
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
// XXX: should really be generated from metadata (CSV ?)
|
||||||
|
|
||||||
static const struct serial_support_descriptor sSupportedDevices[] = {
|
static const struct serial_support_descriptor sSupportedDevices[] = {
|
||||||
|
|
||||||
#ifdef HANDLE_ISA_COM
|
#ifdef HANDLE_ISA_COM
|
||||||
@@ -73,47 +79,71 @@ static const struct serial_support_descriptor sSupportedDevices[] = {
|
|||||||
// vendor/device matches first
|
// vendor/device matches first
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
// vendor: OxfordSemi
|
||||||
|
#define VN "OxfordSemi"
|
||||||
{ B_PCI_BUS, "OxfordSemi 16950 Serial Port", sDefaultRates, NULL, { 32, 32, 8 },
|
{ B_PCI_BUS, "OxfordSemi 16950 Serial Port", sDefaultRates, NULL, { 32, 32, 8 },
|
||||||
{ PCI_simple_communications, PCI_serial, PCI_serial_16950,
|
{ PCI_simple_communications, PCI_serial, PCI_serial_16950,
|
||||||
0x1415, 0x9501 } },
|
0x1415, 0x9501, PCI_INVAL, PCI_INVAL } },
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
|
||||||
|
// vendor: NetMos
|
||||||
|
#define VN "NetMos"
|
||||||
|
|
||||||
|
// used in Manhattan cards
|
||||||
|
// 1 function / port
|
||||||
|
{ B_PCI_BUS, VN" 16550 Serial Port", sDefaultRates, NULL, { 8, 8, 8, 0, 0, 0 },
|
||||||
|
{ PCI_simple_communications, PCI_serial, PCI_serial_16550,
|
||||||
|
0x9710, 0x9865, PCI_INVAL, PCI_INVAL } },
|
||||||
|
|
||||||
|
// http://www.moschip.com/data/products/NM9835/Data%20Sheet_9835.pdf
|
||||||
|
// single function with all ports
|
||||||
|
// only BAR 0 & 1 are UART
|
||||||
|
{ B_PCI_BUS, VN" 16550 Serial Port", sDefaultRates, NULL, { 8, 8, 8, 0x3, 2, 0x000f },
|
||||||
|
{ PCI_simple_communications, PCI_serial, PCI_serial_16550,
|
||||||
|
0x9710, 0x9835, PCI_INVAL, PCI_INVAL } },
|
||||||
|
|
||||||
|
#undef VN
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
// generic fallback matches
|
// generic fallback matches
|
||||||
/*
|
/*
|
||||||
{ B_PCI_BUS, "Generic XT Serial Port", NULL },
|
{ B_PCI_BUS, "Generic XT Serial Port", NULL },
|
||||||
{ PCI_INVAL, PCI_INVAL, PCI_simple_communications,
|
{ PCI_INVAL, PCI_INVAL, PCI_simple_communications,
|
||||||
PCI_serial, PCI_serial_xt } },
|
PCI_serial, PCI_serial_xt, PCI_INVAL, PCI_INVAL } },
|
||||||
|
|
||||||
{ B_PCI_BUS, "Generic 16450 Serial Port", NULL },
|
{ B_PCI_BUS, "Generic 16450 Serial Port", NULL },
|
||||||
{ PCI_INVAL, PCI_INVAL, PCI_simple_communications,
|
{ PCI_INVAL, PCI_INVAL, PCI_simple_communications,
|
||||||
PCI_serial, PCI_serial_16450 } },
|
PCI_serial, PCI_serial_16450, PCI_INVAL, PCI_INVAL } },
|
||||||
|
|
||||||
*/
|
*/
|
||||||
{ B_PCI_BUS, "Generic 16550 Serial Port", sDefaultRates, NULL, { 8, 8, 8 },
|
{ B_PCI_BUS, "Generic 16550 Serial Port", sDefaultRates, NULL, { 8, 8, 8 },
|
||||||
{ PCI_simple_communications, PCI_serial, PCI_serial_16550,
|
{ PCI_simple_communications, PCI_serial, PCI_serial_16550,
|
||||||
PCI_INVAL, PCI_INVAL } },
|
PCI_INVAL, PCI_INVAL, PCI_INVAL, PCI_INVAL } },
|
||||||
|
|
||||||
{ B_PCI_BUS, "Generic 16650 Serial Port", sDefaultRates, NULL, { 8, 8, 8 },
|
{ B_PCI_BUS, "Generic 16650 Serial Port", sDefaultRates, NULL, { 8, 8, 8 },
|
||||||
{ PCI_simple_communications, PCI_serial, PCI_serial_16650,
|
{ PCI_simple_communications, PCI_serial, PCI_serial_16650,
|
||||||
PCI_INVAL, PCI_INVAL } },
|
PCI_INVAL, PCI_INVAL, PCI_INVAL, PCI_INVAL } },
|
||||||
|
|
||||||
{ B_PCI_BUS, "Generic 16750 Serial Port", sDefaultRates, NULL, { 8, 8, 8 },
|
{ B_PCI_BUS, "Generic 16750 Serial Port", sDefaultRates, NULL, { 8, 8, 8 },
|
||||||
{ PCI_simple_communications, PCI_serial, PCI_serial_16750,
|
{ PCI_simple_communications, PCI_serial, PCI_serial_16750,
|
||||||
PCI_INVAL, PCI_INVAL } },
|
PCI_INVAL, PCI_INVAL, PCI_INVAL, PCI_INVAL } },
|
||||||
|
|
||||||
{ B_PCI_BUS, "Generic 16850 Serial Port", sDefaultRates, NULL, { 8, 8, 8 },
|
{ B_PCI_BUS, "Generic 16850 Serial Port", sDefaultRates, NULL, { 8, 8, 8 },
|
||||||
{ PCI_simple_communications, PCI_serial, PCI_serial_16850,
|
{ PCI_simple_communications, PCI_serial, PCI_serial_16850,
|
||||||
PCI_INVAL, PCI_INVAL } },
|
PCI_INVAL, PCI_INVAL, PCI_INVAL, PCI_INVAL } },
|
||||||
|
|
||||||
{ B_PCI_BUS, "Generic 16950 Serial Port", sDefaultRates, NULL, { 8, 8, 8 },
|
{ B_PCI_BUS, "Generic 16950 Serial Port", sDefaultRates, NULL, { 8, 8, 8 },
|
||||||
{ PCI_simple_communications, PCI_serial, PCI_serial_16950,
|
{ PCI_simple_communications, PCI_serial, PCI_serial_16950,
|
||||||
PCI_INVAL, PCI_INVAL } },
|
PCI_INVAL, PCI_INVAL, PCI_INVAL, PCI_INVAL } },
|
||||||
|
|
||||||
// non PCI_serial devices
|
// non PCI_serial devices
|
||||||
|
|
||||||
// beos zz driver supported that one
|
// beos zz driver supported that one
|
||||||
{ B_PCI_BUS, "Lucent Modem", sDefaultRates, NULL, { 8, 8, 8 },
|
{ B_PCI_BUS, "Lucent Modem", sDefaultRates, NULL, { 8, 8, 8 },
|
||||||
{ PCI_simple_communications, PCI_simple_communications_other, 0x00,
|
{ PCI_simple_communications, PCI_simple_communications_other, 0x00,
|
||||||
0x11C1, 0x0480 } },
|
0x11C1, 0x0480, PCI_INVAL, PCI_INVAL } },
|
||||||
|
|
||||||
{ B_PCI_BUS, NULL, NULL, NULL, {0}, {0} }
|
{ B_PCI_BUS, NULL, NULL, NULL, {0}, {0} }
|
||||||
};
|
};
|
||||||
@@ -408,6 +438,9 @@ scan_bus(bus_type bus)
|
|||||||
resource_descriptor iodesc;
|
resource_descriptor iodesc;
|
||||||
SerialDevice *master = NULL;
|
SerialDevice *master = NULL;
|
||||||
|
|
||||||
|
//TODO: handle maxports
|
||||||
|
//TODO: handle subsystem_id_mask
|
||||||
|
|
||||||
// instanciate devices on IO ports
|
// instanciate devices on IO ports
|
||||||
for (int i = 0;
|
for (int i = 0;
|
||||||
gConfigManagerModule->get_nth_resource_descriptor_of_type(
|
gConfigManagerModule->get_nth_resource_descriptor_of_type(
|
||||||
@@ -508,20 +541,50 @@ scan_pci_alt()
|
|||||||
|
|
||||||
SerialDevice *master = NULL;
|
SerialDevice *master = NULL;
|
||||||
|
|
||||||
|
uint8 portCount = 0;
|
||||||
|
uint32 maxPorts = DEVICES_COUNT;
|
||||||
|
|
||||||
|
if (supported->constraints.maxports) {
|
||||||
|
maxPorts = supported->constraints.maxports;
|
||||||
|
TRACE_ALWAYS("card supports up to %d ports\n", maxPorts);
|
||||||
|
}
|
||||||
|
if (supported->constraints.subsystem_id_mask) {
|
||||||
|
uint32 id = info.u.h0.subsystem_id;
|
||||||
|
uint32 mask = supported->constraints.subsystem_id_mask;
|
||||||
|
id &= mask;
|
||||||
|
//TRACE_ALWAYS("mask: %lx, masked: %lx\n", mask, id);
|
||||||
|
while (!(mask & 0x1)) {
|
||||||
|
mask >>= 1;
|
||||||
|
id >>= 1;
|
||||||
|
}
|
||||||
|
maxPorts = (uint8)id;
|
||||||
|
TRACE_ALWAYS("subsystem id tells card has %d ports\n", maxPorts);
|
||||||
|
}
|
||||||
|
|
||||||
// find I/O ports
|
// find I/O ports
|
||||||
for (int r = 0; r < 6; r++) {
|
for (int r = 0; r < 6; r++) {
|
||||||
|
uint32 regbase = info.u.h0.base_registers[r];
|
||||||
|
uint32 reglen = info.u.h0.base_register_sizes[r];
|
||||||
|
|
||||||
/**/
|
/**/
|
||||||
TRACE_ALWAYS("range at 0x%08lx len 0x%lx flags 0x%02x\n",
|
TRACE("ranges[%d] at 0x%08lx len 0x%lx flags 0x%02x\n", r,
|
||||||
info.u.h0.base_registers[r], info.u.h0.base_register_sizes[r],
|
regbase, reglen, info.u.h0.base_register_flags[r]);
|
||||||
info.u.h0.base_register_flags[r]);
|
|
||||||
/**/
|
/**/
|
||||||
|
|
||||||
|
// empty
|
||||||
|
if (reglen == 0)
|
||||||
|
continue;
|
||||||
|
|
||||||
// not I/O
|
// not I/O
|
||||||
if ((info.u.h0.base_register_flags[r] & PCI_address_space) == 0)
|
if ((info.u.h0.base_register_flags[r] & PCI_address_space) == 0)
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
uint32 regbase = info.u.h0.base_registers[r];
|
// the range for sure doesn't contain any UART
|
||||||
uint32 reglen = info.u.h0.base_register_sizes[r];
|
if (supported->constraints.ignoremask & (1 << r)) {
|
||||||
|
TRACE_ALWAYS("ignored regs at 0x%08lx len 0x%lx\n",
|
||||||
|
regbase, reglen);
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
TRACE_ALWAYS("regs at 0x%08lx len 0x%lx\n",
|
TRACE_ALWAYS("regs at 0x%08lx len 0x%lx\n",
|
||||||
regbase, reglen);
|
regbase, reglen);
|
||||||
@@ -538,7 +601,10 @@ next_split_alt:
|
|||||||
// no more to split
|
// no more to split
|
||||||
if ((ioport - regbase) >= reglen)
|
if ((ioport - regbase) >= reglen)
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
|
if (portCount >= maxPorts)
|
||||||
|
break;
|
||||||
|
|
||||||
TRACE_ALWAYS("inserting device at io 0x%04lx as %s\n", ioport,
|
TRACE_ALWAYS("inserting device at io 0x%04lx as %s\n", ioport,
|
||||||
supported->name);
|
supported->name);
|
||||||
|
|
||||||
@@ -553,6 +619,7 @@ next_split_alt:
|
|||||||
master = device;
|
master = device;
|
||||||
|
|
||||||
ioport += supported->constraints.split;
|
ioport += supported->constraints.split;
|
||||||
|
portCount++;
|
||||||
goto next_split_alt;
|
goto next_split_alt;
|
||||||
// try next part of the I/O range now
|
// try next part of the I/O range now
|
||||||
|
|
||||||
|
|||||||
@@ -1,4 +1,8 @@
|
|||||||
/*
|
/*
|
||||||
|
* Copyright 2009-2010, François Revol, <[email protected]>.
|
||||||
|
* Sponsored by TuneTracker Systems.
|
||||||
|
* Based on the Haiku usb_serial driver which is:
|
||||||
|
*
|
||||||
* Copyright (c) 2007-2008 by Michael Lotz
|
* Copyright (c) 2007-2008 by Michael Lotz
|
||||||
* Heavily based on the original usb_serial driver which is:
|
* Heavily based on the original usb_serial driver which is:
|
||||||
*
|
*
|
||||||
@@ -36,7 +40,7 @@ extern "C" {
|
|||||||
#endif
|
#endif
|
||||||
|
|
||||||
#define DRIVER_NAME "pc_serial" // driver name for debug output
|
#define DRIVER_NAME "pc_serial" // driver name for debug output
|
||||||
#define DEVICES_COUNT 20 // max simultaneously open devices
|
#define DEVICES_COUNT 2 // max simultaneously open devices
|
||||||
|
|
||||||
// avoid clashing with BeOS zz driver
|
// avoid clashing with BeOS zz driver
|
||||||
#define DEVFS_BASE "ports/pc_serial"
|
#define DEVFS_BASE "ports/pc_serial"
|
||||||
@@ -59,9 +63,13 @@ struct port_constraints {
|
|||||||
uint32 minsize;
|
uint32 minsize;
|
||||||
uint32 maxsize;
|
uint32 maxsize;
|
||||||
uint32 split; // range to split I/O ports for each device
|
uint32 split; // range to split I/O ports for each device
|
||||||
|
uint8 ignoremask; // bitmask of BARs to ignore when probing
|
||||||
|
uint8 maxports; // max number of ports on the card if > 0
|
||||||
|
uint32 subsystem_id_mask; // if set mask with subsys id and shift to get maxports
|
||||||
};
|
};
|
||||||
|
|
||||||
#define PCI_INVAL 0xffff
|
#define PCI_INVAL 0xffff
|
||||||
|
|
||||||
struct serial_support_descriptor {
|
struct serial_support_descriptor {
|
||||||
bus_type bus; // B_*_BUS
|
bus_type bus; // B_*_BUS
|
||||||
const char *name;
|
const char *name;
|
||||||
@@ -79,6 +87,8 @@ struct serial_support_descriptor {
|
|||||||
// for PCI: if PCI_INVAL then match class
|
// for PCI: if PCI_INVAL then match class
|
||||||
ushort vendor_id;
|
ushort vendor_id;
|
||||||
ushort device_id;
|
ushort device_id;
|
||||||
|
ushort subsystem_vendor_id;
|
||||||
|
ushort subsystem_device_id;
|
||||||
} match;
|
} match;
|
||||||
};
|
};
|
||||||
typedef struct serial_support_descriptor serial_support_descriptor;
|
typedef struct serial_support_descriptor serial_support_descriptor;
|
||||||
|
|||||||
@@ -1,4 +1,8 @@
|
|||||||
/*
|
/*
|
||||||
|
* Copyright 2009-2010, François Revol, <[email protected]>.
|
||||||
|
* Sponsored by TuneTracker Systems.
|
||||||
|
* Based on the Haiku usb_serial driver which is:
|
||||||
|
*
|
||||||
* Copyright (c) 2007-2008 by Michael Lotz
|
* Copyright (c) 2007-2008 by Michael Lotz
|
||||||
* Heavily based on the original usb_serial driver which is:
|
* Heavily based on the original usb_serial driver which is:
|
||||||
*
|
*
|
||||||
|
|||||||
@@ -1,4 +1,8 @@
|
|||||||
/*
|
/*
|
||||||
|
* Copyright 2009-2010, François Revol, <[email protected]>.
|
||||||
|
* Sponsored by TuneTracker Systems.
|
||||||
|
* Based on the Haiku usb_serial driver which is:
|
||||||
|
*
|
||||||
* Copyright (c) 2007-2008 by Michael Lotz
|
* Copyright (c) 2007-2008 by Michael Lotz
|
||||||
* Heavily based on the original usb_serial driver which is:
|
* Heavily based on the original usb_serial driver which is:
|
||||||
*
|
*
|
||||||
|
|||||||
Reference in New Issue
Block a user