From 1a6072a0a1bf9c57347963a44fd415235c36c63a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Fran=C3=A7ois=20Revol?= Date: Thu, 28 Aug 2014 19:13:23 +0200 Subject: [PATCH] pc_serial: manually probe the default ISA ports Since config_manager is basically a stub, and even VirtualBox doesn't publish the serial ports as PCI devices, we must probe for them. Ideally config_manager would find them in the device manager tree which would have been populated from the PnP BIOS or even ACPI tables... --- .../kernel/drivers/ports/pc_serial/Driver.cpp | 42 +++++++++++++++++-- .../drivers/ports/pc_serial/SerialDevice.cpp | 15 +++++++ .../drivers/ports/pc_serial/SerialDevice.h | 2 + 3 files changed, 56 insertions(+), 3 deletions(-) diff --git a/src/add-ons/kernel/drivers/ports/pc_serial/Driver.cpp b/src/add-ons/kernel/drivers/ports/pc_serial/Driver.cpp index feae10c824..46f3ef311a 100644 --- a/src/add-ons/kernel/drivers/ports/pc_serial/Driver.cpp +++ b/src/add-ons/kernel/drivers/ports/pc_serial/Driver.cpp @@ -151,6 +151,17 @@ static const struct serial_support_descriptor sSupportedDevices[] = { }; +// hardcoded ISA ports +static struct isa_ports { + uint32 ioBase; + uint32 irq; +} sHardcodedPorts[] = { + { 0x3f8, 4 }, + { 0x2f8, 3 }, + { 0x3e8, 4 }, + { 0x2e8, 3 }, +}; + #if 0 status_t pc_serial_device_added(pc_device device, void **cookie) @@ -492,6 +503,30 @@ next_split: return B_OK; } + +// until we support ISA device enumeration from PnP BIOS or ACPI, +// we have to probe the 4 default COM ports... +status_t +scan_isa_hardcoded() +{ +#ifdef HANDLE_ISA_COM + int i; + + //TODO: check and filter out the kernel debug port + for (i = 0; i < 4; i++) { + SerialDevice *device; + device = new(std::nothrow) SerialDevice(&sSupportedDevices[0], + sHardcodedPorts[i].ioBase, sHardcodedPorts[i].irq); + if (device && device->Probe()) + pc_serial_insert_device(device); + else + delete device; + } +#endif + return B_OK; +} + + // this version doesn't use config_manager, but can't probe the IRQ yet status_t scan_pci_alt() @@ -695,14 +730,15 @@ init_driver() status = ENOENT; - scan_bus(B_ISA_BUS); + (void)scan_bus; + //scan_bus(B_ISA_BUS); //scan_bus(B_PCI_BUS); + scan_isa_hardcoded(); scan_pci_alt(); // XXX: ISA cards // XXX: pcmcia - - + TRACE_FUNCRET("< init_driver() returns\n"); return B_OK; diff --git a/src/add-ons/kernel/drivers/ports/pc_serial/SerialDevice.cpp b/src/add-ons/kernel/drivers/ports/pc_serial/SerialDevice.cpp index af4fe7eb3e..9b16729e47 100644 --- a/src/add-ons/kernel/drivers/ports/pc_serial/SerialDevice.cpp +++ b/src/add-ons/kernel/drivers/ports/pc_serial/SerialDevice.cpp @@ -65,6 +65,21 @@ SerialDevice::~SerialDevice() } +bool +SerialDevice::Probe() +{ + uint8 msr; + msr = ReadReg8(MSR); + // just in case read twice to make sure the "delta" bits are 0 + msr = ReadReg8(MSR); + // this should be enough to probe for the device for now + // we might want to check the scratch reg, and try identifying + // the model as in: + // http://en.wikibooks.org/wiki/Serial_Programming/8250_UART_Programming#Software_Identification_of_the_UART + return (msr != 0xff); +} + + status_t SerialDevice::Init() { diff --git a/src/add-ons/kernel/drivers/ports/pc_serial/SerialDevice.h b/src/add-ons/kernel/drivers/ports/pc_serial/SerialDevice.h index 52d92ccdbb..af2f3ae63a 100644 --- a/src/add-ons/kernel/drivers/ports/pc_serial/SerialDevice.h +++ b/src/add-ons/kernel/drivers/ports/pc_serial/SerialDevice.h @@ -22,6 +22,8 @@ public: *device, uint32 ioBase, uint32 irq, const SerialDevice *master=NULL); virtual ~SerialDevice(); + bool Probe(); + static SerialDevice * MakeDevice(struct serial_config_descriptor *device);