[Top][All Lists]
[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
Re: [PATCH] PCI serial card support
From: |
n0ano |
Subject: |
Re: [PATCH] PCI serial card support |
Date: |
Wed, 12 Nov 2008 11:58:03 -0700 |
User-agent: |
Mutt/1.4.2.1i |
On Sun, Nov 09, 2008 at 10:57:30PM +0100, Robert Millan wrote:
> On Sat, Nov 08, 2008 at 06:58:19PM -0700, address@hidden wrote:
> > I think this is pretty much what I'm in the middle of doing. I want to
> > put the infrastructure in place so that we can handle an arbitrary PCI
> > device but I will only put the actual code in to handle the PCI card that
> > I have (the only one I can test).
> >
> > What I'm doing is creating a table that matches the tuple (vendor id,
> > device id, subsystem vendor id, subsystem device id, device type, device
> > type mask) to a base baud and a configuration function. The default
> > configuration function does nothing so the table only provides the base
> > baud. We can add config functions for different cards as time goes by.
>
Finally, here is the patch that adds an infrastructure to support
multiple serial devices (legacy & PCI, we can think about USB for
the future but that will be harder).
This patch creates a table with an entry for each serial device
in the system. It attempts to fill in appropriate defaults for
each entry. Right now it should determine the base baud for most
PCI devices but it can only find the I/O port for the Titan PCI
serial card that I have to test.
The command `serial' will print out the table, flagging the
currently selected serial entry, e.g.:
grub> serial
Available serial units:
* 0: legacy COM1 0x0000 9600/115200 8N1
1: legacy COM2 0x0000 9600/115200 8N1
2: legacy COM3 0x0000 9600/115200 8N1
3: legacy COM4 0x0000 9600/115200 8N1
4: pci 1:00.0 0xe880 9600/921600 8N1
Note that unit 0 (the legacy COM1 port) is currently the selected
unit. Since my machine doesn't have any legacy serial devices
(note the 0x0000 for the I/O port) this device won't work. The
command `serial -u 4' will select the PCI device and, since all
the defaults are correct, that device will work. You can override
all defaults with the serial command so, to duplicate the defaults
for the PCI device, you would use the command:
serial -u 4 -p 0xe880 -s 9600 -b 921600 -w 8 -r n -t 1
Signed-off-by: Donald Dugger <address@hidden>
--
Don Dugger
"Censeo Toto nos in Kansa esse decisse." - D. Gale
address@hidden
Ph: 303/443-3786
diffstat /isis/homeb/intel/patch.d/pci_serial-grub-1112a.patch
ChangeLog | 10
include/grub/i386/pc/serial.h | 8
include/grub/pci_serial_ids.h | 642 ++++++++++++++++++++++++++++++++++++++++++
term/i386/pc/serial.c | 291 +++++++++++++------
4 files changed, 870 insertions(+), 81 deletions(-)
Index: include/grub/pci_serial_ids.h
===================================================================
--- include/grub/pci_serial_ids.h (revision 0)
+++ include/grub/pci_serial_ids.h (revision 0)
@@ -0,0 +1,642 @@
+/*
+ * GRUB -- GRand Unified Bootloader
+ * Copyright (C) 2000,2001,2002,2003,2004,2005,2007 Free Software
Foundation, Inc.
+ *
+ * GRUB is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * GRUB is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with GRUB. If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#define PCI_ANY_ID ((unsigned int)(~0))
+
+#define PCI_CLASS_COMMUNICATION_SERIAL 0x0700
+#define PCI_CLASS_COMMUNICATION_MULTISERIAL 0x0702
+#define PCI_CLASS_COMMUNICATION_MODEM 0x0703
+
+#define PCI_VENDOR_ID_DELL 0x1028
+#define PCI_DEVICE_ID_DELL_RACIII 0x0008
+#define PCI_DEVICE_ID_DELL_RAC4 0x0012
+
+#define PCI_VENDOR_ID_SGI 0x10a9
+#define PCI_DEVICE_ID_SGI_IOC3 0x0003
+
+#define PCI_VENDOR_ID_PLX 0x10b5
+#define PCI_DEVICE_ID_PLX_ROMULUS 0x106a
+#define PCI_DEVICE_ID_PLX_SPCOM800 0x1076
+#define PCI_DEVICE_ID_PLX_1077 0x1077
+#define PCI_DEVICE_ID_PLX_SPCOM200 0x1103
+#define PCI_DEVICE_ID_PLX_9030 0x9030
+#define PCI_DEVICE_ID_PLX_9050 0x9050
+#define PCI_SUBVENDOR_ID_KEYSPAN 0x11a9
+#define PCI_SUBVENDOR_ID_KEYSPAN_SX2 0x5334
+
+#define PCI_VENDOR_ID_V3 0x11b0
+#define PCI_DEVICE_ID_V3_V960 0x0001
+#define PCI_DEVICE_ID_V3_V351 0x0002
+
+#define PCI_VENDOR_ID_SPECIALIX 0x11cb
+#define PCI_SUBDEVICE_ID_SPECIALIX_SPEED4 0xa004
+#define PCI_SUBVENDOR_ID_CONNECT_TECH 0x12c4
+#define PCI_SUBDEVICE_ID_CONNECT_TECH_BH8_232 0x0001
+#define PCI_SUBDEVICE_ID_CONNECT_TECH_BH4_232 0x0002
+#define PCI_SUBDEVICE_ID_CONNECT_TECH_BH2_232 0x0003
+#define PCI_SUBDEVICE_ID_CONNECT_TECH_BH2_20MHZ 0x000C
+#define PCI_SUBDEVICE_ID_CONNECT_TECH_PCI_UART_2_232 0x0300
+#define PCI_SUBDEVICE_ID_CONNECT_TECH_PCI_UART_1_1 0x0310
+#define PCI_SUBDEVICE_ID_CONNECT_TECH_PCI_UART_2_2 0x0311
+#define PCI_SUBDEVICE_ID_CONNECT_TECH_PCI_UART_2 0x0320
+#define PCI_SUBDEVICE_ID_CONNECT_TECH_PCI_UART_2_485 0x0330
+#define PCI_SUBVENDOR_ID_CHASE_PCIFAST 0x12E0
+#define PCI_SUBDEVICE_ID_CHASE_PCIFAST4 0x0031
+#define PCI_SUBDEVICE_ID_CHASE_PCIFAST8 0x0021
+#define PCI_SUBDEVICE_ID_CHASE_PCIFAST16 0x0011
+#define PCI_SUBDEVICE_ID_CHASE_PCIFAST16FMC 0x0041
+#define PCI_SUBVENDOR_ID_CHASE_PCIRAS 0x124D
+#define PCI_SUBDEVICE_ID_CHASE_PCIRAS4 0xF001
+#define PCI_SUBDEVICE_ID_CHASE_PCIRAS8 0xF010
+
+#define PCI_VENDOR_ID_SIIG 0x131f
+#define PCI_DEVICE_ID_SIIG_1S_10x_550 0x1000
+#define PCI_DEVICE_ID_SIIG_1S_10x_650 0x1001
+#define PCI_DEVICE_ID_SIIG_1S_10x_850 0x1002
+#define PCI_DEVICE_ID_SIIG_2S_10x_550 0x1030
+#define PCI_DEVICE_ID_SIIG_2S_10x_650 0x1031
+#define PCI_DEVICE_ID_SIIG_2S_10x_850 0x1032
+#define PCI_DEVICE_ID_SIIG_4S_10x_550 0x1050
+#define PCI_DEVICE_ID_SIIG_4S_10x_650 0x1051
+#define PCI_DEVICE_ID_SIIG_4S_10x_850 0x1052
+#define PCI_DEVICE_ID_SIIG_1S_20x_550 0x2000
+#define PCI_DEVICE_ID_SIIG_1S_20x_650 0x2001
+#define PCI_DEVICE_ID_SIIG_1S_20x_850 0x2002
+#define PCI_DEVICE_ID_SIIG_2S_20x_550 0x2030
+#define PCI_DEVICE_ID_SIIG_2S_20x_650 0x2031
+#define PCI_DEVICE_ID_SIIG_2S_20x_850 0x2032
+#define PCI_DEVICE_ID_SIIG_4S_20x_550 0x2050
+#define PCI_DEVICE_ID_SIIG_4S_20x_650 0x2051
+#define PCI_DEVICE_ID_SIIG_4S_20x_850 0x2052
+#define PCI_DEVICE_ID_SIIG_8S_20x_550 0x2080
+#define PCI_DEVICE_ID_SIIG_8S_20x_650 0x2081
+#define PCI_DEVICE_ID_SIIG_8S_20x_850 0x2082
+
+#define PCI_VENDOR_ID_EXAR 0x13a8
+#define PCI_DEVICE_ID_EXAR_XR17C152 0x0152
+#define PCI_DEVICE_ID_EXAR_XR17C154 0x0154
+#define PCI_DEVICE_ID_EXAR_XR17C158 0x0158
+
+#define PCI_VENDOR_ID_LAVA 0x1407
+#define PCI_DEVICE_ID_LAVA_OCTO_A 0x0180
+#define PCI_DEVICE_ID_LAVA_OCTO_B 0x0181
+#define PCI_DEVICE_ID_LAVA_PORT_PLUS 0x0200
+#define PCI_DEVICE_ID_LAVA_QUAD_A 0x0201
+#define PCI_DEVICE_ID_LAVA_QUAD_B 0x0202
+#define PCI_DEVICE_ID_LAVA_PORT_650 0x0600
+
+#define PCI_VENDOR_ID_TIMEDIA 0x1409
+#define PCI_DEVICE_ID_TIMEDIA_1889 0x7168
+
+#define PCI_VENDOR_ID_OXSEMI 0x1415
+#define PCI_DEVICE_ID_OXSEMI_16PCI954 0x9501
+#define PCI_DEVICE_ID_OXSEMI_16PCI95N 0x9511
+#define PCI_DEVICE_ID_OXSEMI_16PCI954PP 0x9513
+#define PCI_DEVICE_ID_OXSEMI_16PCI952 0x9521
+#define PCI_DEVICE_ID_OXSEMI_16PCI952PP 0x9523
+
+#define PCI_VENDOR_ID_TITAN 0x14D2
+#define PCI_DEVICE_ID_TITAN_100L 0x8010
+#define PCI_DEVICE_ID_TITAN_200L 0x8020
+#define PCI_DEVICE_ID_TITAN_400L 0x8040
+#define PCI_DEVICE_ID_TITAN_800L 0x8080
+#define PCI_DEVICE_ID_TITAN_100 0xA001
+#define PCI_DEVICE_ID_TITAN_200 0xA005
+#define PCI_DEVICE_ID_TITAN_400 0xA003
+#define PCI_DEVICE_ID_TITAN_800B 0xA004
+
+#define PCI_VENDOR_ID_PANACOM 0x14d4
+#define PCI_DEVICE_ID_PANACOM_QUADMODEM 0x0400
+#define PCI_DEVICE_ID_PANACOM_DUALMODEM 0x0402
+
+#define PCI_VENDOR_ID_MAINPINE 0x1522
+
+#define PCI_VENDOR_ID_PASEMI 0x1959
+
+#define PCI_VENDOR_ID_KORENIX 0x1982
+#define PCI_DEVICE_ID_KORENIX_JETCARDF0 0x1600
+#define PCI_DEVICE_ID_KORENIX_JETCARDF1 0x16ff
+
+#define PCI_VENDOR_ID_INTEL 0x8086
+#define PCI_DEVICE_ID_INTEL_80960_RP 0x1960
+
+#define PCI_VENDOR_ID_COMPUTONE 0x8e0e
+#define PCI_DEVICE_ID_COMPUTONE_PG 0x0302
+#define PCI_SUBVENDOR_ID_COMPUTONE 0x8e0e
+#define PCI_SUBDEVICE_ID_COMPUTONE_PG4 0x0001
+#define PCI_SUBDEVICE_ID_COMPUTONE_PG8 0x0002
+#define PCI_SUBDEVICE_ID_COMPUTONE_PG6 0x0003
+
+#define PCI_SUBVENDOR_ID_EXSYS 0xd84d
+#define PCI_SUBDEVICE_ID_EXSYS_4055 0x4055
+
+#define PCI_VENDOR_ID_SBSMODULARIO 0x124B
+#define PCI_SUBVENDOR_ID_SBSMODULARIO 0x124B
+
+#define PCI_DEVICE_ID_OCTPRO 0x0001
+#define PCI_SUBDEVICE_ID_OCTPRO232 0x0108
+#define PCI_SUBDEVICE_ID_OCTPRO422 0x0208
+#define PCI_SUBDEVICE_ID_POCTAL232 0x0308
+#define PCI_SUBDEVICE_ID_POCTAL422 0x0408
+
+#define PCI_BDF(b,d,f) ((b << 8) | (d << 3) | f)
+
+static unsigned int
+pci_get_bar(unsigned int bus, unsigned int dev, unsigned int func, unsigned
int bar)
+{
+ grub_pci_address_t addr;
+
+ addr = grub_pci_make_address (bus, dev, func, 4 + bar);
+ return grub_pci_read (addr) & ~3;
+}
+
+static void
+titan(unsigned int bus, unsigned int dev, unsigned int func, unsigned int
bbaud)
+{
+ unsigned int port;
+
+ port = pci_get_bar(bus, dev, func, 1);
+ grub_serial_add(SERIAL_PCI, PCI_BDF(bus, dev, func), bbaud, port);
+ return;
+}
+
+static void
+generic(unsigned int bus, unsigned int dev, unsigned int func, unsigned int
bbaud)
+{
+
+ grub_serial_add(SERIAL_PCI, PCI_BDF(bus, dev, func), bbaud, 0);
+ return;
+}
+
+/*
+ * Table to map PCI ID to config routine. Currently, the config routine
+ * only sets the base baud but, utltimately, it should identify which
+ * I/O port is associated with which serial port.
+ */
+static struct pci_device_id {
+ unsigned int vendor_id;
+ unsigned int device_id;
+ unsigned int ss_vendor;
+ unsigned int ss_device;
+ unsigned int dev_class;
+ unsigned int dev_class_mask;
+ unsigned int base_baud;
+ void (*dev_config)(unsigned int bus, unsigned int dev,
+ unsigned int func, unsigned int bbaud);
+} serial_pci_id[] = {
+ { PCI_VENDOR_ID_V3, PCI_DEVICE_ID_V3_V960,
+ PCI_ANY_ID, PCI_ANY_ID, 0, 0,
+ 1382400, generic },
+ { PCI_VENDOR_ID_V3, PCI_DEVICE_ID_V3_V960,
+ PCI_ANY_ID, PCI_ANY_ID, 0, 0,
+ 1382400, generic },
+ { PCI_VENDOR_ID_V3, PCI_DEVICE_ID_V3_V960,
+ PCI_SUBVENDOR_ID_CONNECT_TECH,
+ PCI_SUBDEVICE_ID_CONNECT_TECH_BH4_232, 0, 0,
+ 1382400, generic },
+ { PCI_VENDOR_ID_V3, PCI_DEVICE_ID_V3_V351,
+ PCI_SUBVENDOR_ID_CONNECT_TECH,
+ PCI_SUBDEVICE_ID_CONNECT_TECH_BH8_232, 0, 0,
+ 1382400, generic },
+ { PCI_VENDOR_ID_V3, PCI_DEVICE_ID_V3_V351,
+ PCI_SUBVENDOR_ID_CONNECT_TECH,
+ PCI_SUBDEVICE_ID_CONNECT_TECH_BH4_232, 0, 0,
+ 1382400, generic },
+ { PCI_VENDOR_ID_V3, PCI_DEVICE_ID_V3_V351,
+ PCI_SUBVENDOR_ID_CONNECT_TECH,
+ PCI_SUBDEVICE_ID_CONNECT_TECH_BH2_232, 0, 0,
+ 1382400, generic },
+ { PCI_VENDOR_ID_V3, PCI_DEVICE_ID_V3_V351,
+ PCI_SUBVENDOR_ID_CONNECT_TECH,
+ PCI_SUBDEVICE_ID_CONNECT_TECH_BH2_20MHZ, 0, 0,
+ 1250000, generic },
+ { PCI_VENDOR_ID_V3, PCI_DEVICE_ID_V3_V351,
+ PCI_ANY_ID, PCI_ANY_ID, 0, 0,
+ 921600, generic },
+ { PCI_VENDOR_ID_PLX, PCI_DEVICE_ID_PLX_SPCOM200,
+ PCI_ANY_ID, PCI_ANY_ID, 0, 0,
+ 921600, generic },
+ { PCI_VENDOR_ID_PLX, PCI_DEVICE_ID_PLX_SPCOM800,
+ PCI_ANY_ID, PCI_ANY_ID, 0, 0,
+ 921600, generic },
+ { PCI_VENDOR_ID_PLX, PCI_DEVICE_ID_PLX_1077,
+ PCI_ANY_ID, PCI_ANY_ID, 0, 0,
+ 921600, generic },
+ { PCI_VENDOR_ID_PLX, PCI_DEVICE_ID_PLX_9030,
+ PCI_ANY_ID, PCI_ANY_ID, 0, 0,
+ 921600, generic },
+ { PCI_VENDOR_ID_PLX, PCI_DEVICE_ID_PLX_9050,
+ PCI_SUBVENDOR_ID_KEYSPAN,
+ PCI_SUBVENDOR_ID_KEYSPAN_SX2, 0, 0,
+ 921600, generic },
+ { PCI_VENDOR_ID_PLX, PCI_DEVICE_ID_PLX_9050,
+ PCI_SUBVENDOR_ID_CHASE_PCIFAST,
+ PCI_SUBDEVICE_ID_CHASE_PCIFAST4, 0, 0,
+ 460800, generic },
+ { PCI_VENDOR_ID_PLX, PCI_DEVICE_ID_PLX_9050,
+ PCI_SUBVENDOR_ID_CHASE_PCIFAST,
+ PCI_SUBDEVICE_ID_CHASE_PCIFAST8, 0, 0,
+ 460800, generic },
+ { PCI_VENDOR_ID_PLX, PCI_DEVICE_ID_PLX_9050,
+ PCI_SUBVENDOR_ID_CHASE_PCIFAST,
+ PCI_SUBDEVICE_ID_CHASE_PCIFAST16, 0, 0,
+ 460800, generic },
+ { PCI_VENDOR_ID_PLX, PCI_DEVICE_ID_PLX_9050,
+ PCI_SUBVENDOR_ID_CHASE_PCIFAST,
+ PCI_SUBDEVICE_ID_CHASE_PCIFAST16FMC, 0, 0,
+ 460800, generic },
+ { PCI_VENDOR_ID_PLX, PCI_DEVICE_ID_PLX_9050,
+ PCI_SUBVENDOR_ID_CHASE_PCIRAS,
+ PCI_SUBDEVICE_ID_CHASE_PCIRAS4, 0, 0,
+ 460800, generic },
+ { PCI_VENDOR_ID_PLX, PCI_DEVICE_ID_PLX_9050,
+ PCI_SUBVENDOR_ID_CHASE_PCIRAS,
+ PCI_SUBDEVICE_ID_CHASE_PCIRAS8, 0, 0,
+ 460800, generic },
+ { PCI_VENDOR_ID_PLX, PCI_DEVICE_ID_PLX_9050,
+ PCI_SUBVENDOR_ID_EXSYS,
+ PCI_SUBDEVICE_ID_EXSYS_4055, 0, 0,
+ 921600, generic },
+ { PCI_VENDOR_ID_PLX, PCI_DEVICE_ID_PLX_ROMULUS,
+ 0x10b5, 0x106a, 0, 0,
+ 921600, generic },
+ { PCI_VENDOR_ID_PANACOM, PCI_DEVICE_ID_PANACOM_QUADMODEM,
+ PCI_ANY_ID, PCI_ANY_ID, 0, 0,
+ 921600, generic },
+ { PCI_VENDOR_ID_PANACOM, PCI_DEVICE_ID_PANACOM_DUALMODEM,
+ PCI_ANY_ID, PCI_ANY_ID, 0, 0,
+ 921600, generic },
+ { PCI_VENDOR_ID_SPECIALIX, PCI_DEVICE_ID_OXSEMI_16PCI954,
+ PCI_VENDOR_ID_SPECIALIX, PCI_SUBDEVICE_ID_SPECIALIX_SPEED4,
+ 0, 0,
+ 921600, generic },
+ { PCI_VENDOR_ID_OXSEMI, PCI_DEVICE_ID_OXSEMI_16PCI954,
+ PCI_ANY_ID, PCI_ANY_ID, 0, 0,
+ 1843200, generic },
+ { PCI_VENDOR_ID_OXSEMI, 0x950a,
+ PCI_ANY_ID, PCI_ANY_ID, 0, 0,
+ 1130000, generic },
+ { PCI_VENDOR_ID_OXSEMI, PCI_DEVICE_ID_OXSEMI_16PCI952,
+ PCI_ANY_ID, PCI_ANY_ID, 0, 0,
+ 921600, generic },
+ { PCI_VENDOR_ID_OXSEMI, 0xc101, /* OXPCIe952 1 Legacy UART */
+ PCI_ANY_ID, PCI_ANY_ID, 0, 0,
+ 4000000, generic },
+ { PCI_VENDOR_ID_OXSEMI, 0xc105, /* OXPCIe952 1 Legacy UART */
+ PCI_ANY_ID, PCI_ANY_ID, 0, 0,
+ 4000000, generic },
+ { PCI_VENDOR_ID_OXSEMI, 0xc11b, /* OXPCIe952 1 Native UART */
+ PCI_ANY_ID, PCI_ANY_ID, 0, 0,
+ 4000000, generic },
+ { PCI_VENDOR_ID_OXSEMI, 0xc11f, /* OXPCIe952 1 Native UART */
+ PCI_ANY_ID, PCI_ANY_ID, 0, 0,
+ 4000000, generic },
+ { PCI_VENDOR_ID_OXSEMI, 0xc120, /* OXPCIe952 1 Legacy UART */
+ PCI_ANY_ID, PCI_ANY_ID, 0, 0,
+ 4000000, generic },
+ { PCI_VENDOR_ID_OXSEMI, 0xc124, /* OXPCIe952 1 Legacy UART */
+ PCI_ANY_ID, PCI_ANY_ID, 0, 0,
+ 4000000, generic },
+ { PCI_VENDOR_ID_OXSEMI, 0xc138, /* OXPCIe952 1 Native UART */
+ PCI_ANY_ID, PCI_ANY_ID, 0, 0,
+ 4000000, generic },
+ { PCI_VENDOR_ID_OXSEMI, 0xc13d, /* OXPCIe952 1 Native UART */
+ PCI_ANY_ID, PCI_ANY_ID, 0, 0,
+ 4000000, generic },
+ { PCI_VENDOR_ID_OXSEMI, 0xc140, /* OXPCIe952 1 Legacy UART */
+ PCI_ANY_ID, PCI_ANY_ID, 0, 0,
+ 4000000, generic },
+ { PCI_VENDOR_ID_OXSEMI, 0xc141, /* OXPCIe952 1 Legacy UART */
+ PCI_ANY_ID, PCI_ANY_ID, 0, 0,
+ 4000000, generic },
+ { PCI_VENDOR_ID_OXSEMI, 0xc144, /* OXPCIe952 1 Legacy UART */
+ PCI_ANY_ID, PCI_ANY_ID, 0, 0,
+ 4000000, generic },
+ { PCI_VENDOR_ID_OXSEMI, 0xc145, /* OXPCIe952 1 Legacy UART */
+ PCI_ANY_ID, PCI_ANY_ID, 0, 0,
+ 4000000, generic },
+ { PCI_VENDOR_ID_OXSEMI, 0xc158, /* OXPCIe952 2 Native UART */
+ PCI_ANY_ID, PCI_ANY_ID, 0, 0,
+ 4000000, generic },
+ { PCI_VENDOR_ID_OXSEMI, 0xc15d, /* OXPCIe952 2 Native UART */
+ PCI_ANY_ID, PCI_ANY_ID, 0, 0,
+ 4000000, generic },
+ { PCI_VENDOR_ID_OXSEMI, 0xc208, /* OXPCIe954 4 Native UART */
+ PCI_ANY_ID, PCI_ANY_ID, 0, 0,
+ 4000000, generic },
+ { PCI_VENDOR_ID_OXSEMI, 0xc20d, /* OXPCIe954 4 Native UART */
+ PCI_ANY_ID, PCI_ANY_ID, 0, 0,
+ 4000000, generic },
+ { PCI_VENDOR_ID_OXSEMI, 0xc308, /* OXPCIe958 8 Native UART */
+ PCI_ANY_ID, PCI_ANY_ID, 0, 0,
+ 4000000, generic },
+ { PCI_VENDOR_ID_OXSEMI, 0xc30d, /* OXPCIe958 8 Native UART */
+ PCI_ANY_ID, PCI_ANY_ID, 0, 0,
+ 4000000, generic },
+ { PCI_VENDOR_ID_OXSEMI, 0xc40b, /* OXPCIe200 1 Native UART */
+ PCI_ANY_ID, PCI_ANY_ID, 0, 0,
+ 4000000, generic },
+ { PCI_VENDOR_ID_OXSEMI, 0xc40f, /* OXPCIe200 1 Native UART */
+ PCI_ANY_ID, PCI_ANY_ID, 0, 0,
+ 4000000, generic },
+ { PCI_VENDOR_ID_OXSEMI, 0xc41b, /* OXPCIe200 1 Native UART */
+ PCI_ANY_ID, PCI_ANY_ID, 0, 0,
+ 4000000, generic },
+ { PCI_VENDOR_ID_OXSEMI, 0xc41f, /* OXPCIe200 1 Native UART */
+ PCI_ANY_ID, PCI_ANY_ID, 0, 0,
+ 4000000, generic },
+ { PCI_VENDOR_ID_OXSEMI, 0xc42b, /* OXPCIe200 1 Native UART */
+ PCI_ANY_ID, PCI_ANY_ID, 0, 0,
+ 4000000, generic },
+ { PCI_VENDOR_ID_OXSEMI, 0xc42f, /* OXPCIe200 1 Native UART */
+ PCI_ANY_ID, PCI_ANY_ID, 0, 0,
+ 4000000, generic },
+ { PCI_VENDOR_ID_OXSEMI, 0xc43b, /* OXPCIe200 1 Native UART */
+ PCI_ANY_ID, PCI_ANY_ID, 0, 0,
+ 4000000, generic },
+ { PCI_VENDOR_ID_OXSEMI, 0xc43f, /* OXPCIe200 1 Native UART */
+ PCI_ANY_ID, PCI_ANY_ID, 0, 0,
+ 4000000, generic },
+ { PCI_VENDOR_ID_OXSEMI, 0xc44b, /* OXPCIe200 1 Native UART */
+ PCI_ANY_ID, PCI_ANY_ID, 0, 0,
+ 4000000, generic },
+ { PCI_VENDOR_ID_OXSEMI, 0xc44f, /* OXPCIe200 1 Native UART */
+ PCI_ANY_ID, PCI_ANY_ID, 0, 0,
+ 4000000, generic },
+ { PCI_VENDOR_ID_OXSEMI, 0xc45b, /* OXPCIe200 1 Native UART */
+ PCI_ANY_ID, PCI_ANY_ID, 0, 0,
+ 4000000, generic },
+ { PCI_VENDOR_ID_OXSEMI, 0xc45f, /* OXPCIe200 1 Native UART */
+ PCI_ANY_ID, PCI_ANY_ID, 0, 0,
+ 4000000, generic },
+ { PCI_VENDOR_ID_OXSEMI, 0xc46b, /* OXPCIe200 1 Native UART */
+ PCI_ANY_ID, PCI_ANY_ID, 0, 0,
+ 4000000, generic },
+ { PCI_VENDOR_ID_OXSEMI, 0xc46f, /* OXPCIe200 1 Native UART */
+ PCI_ANY_ID, PCI_ANY_ID, 0, 0,
+ 4000000, generic },
+ { PCI_VENDOR_ID_OXSEMI, 0xc47b, /* OXPCIe200 1 Native UART */
+ PCI_ANY_ID, PCI_ANY_ID, 0, 0,
+ 4000000, generic },
+ { PCI_VENDOR_ID_OXSEMI, 0xc47f, /* OXPCIe200 1 Native UART */
+ PCI_ANY_ID, PCI_ANY_ID, 0, 0,
+ 4000000, generic },
+ { PCI_VENDOR_ID_OXSEMI, 0xc48b, /* OXPCIe200 1 Native UART */
+ PCI_ANY_ID, PCI_ANY_ID, 0, 0,
+ 4000000, generic },
+ { PCI_VENDOR_ID_OXSEMI, 0xc48f, /* OXPCIe200 1 Native UART */
+ PCI_ANY_ID, PCI_ANY_ID, 0, 0,
+ 4000000, generic },
+ { PCI_VENDOR_ID_OXSEMI, 0xc49b, /* OXPCIe200 1 Native UART */
+ PCI_ANY_ID, PCI_ANY_ID, 0, 0,
+ 4000000, generic },
+ { PCI_VENDOR_ID_OXSEMI, 0xc49f, /* OXPCIe200 1 Native UART */
+ PCI_ANY_ID, PCI_ANY_ID, 0, 0,
+ 4000000, generic },
+ { PCI_VENDOR_ID_OXSEMI, 0xc4ab, /* OXPCIe200 1 Native UART */
+ PCI_ANY_ID, PCI_ANY_ID, 0, 0,
+ 4000000, generic },
+ { PCI_VENDOR_ID_OXSEMI, 0xc4af, /* OXPCIe200 1 Native UART */
+ PCI_ANY_ID, PCI_ANY_ID, 0, 0,
+ 4000000, generic },
+ { PCI_VENDOR_ID_OXSEMI, 0xc4bb, /* OXPCIe200 1 Native UART */
+ PCI_ANY_ID, PCI_ANY_ID, 0, 0,
+ 4000000, generic },
+ { PCI_VENDOR_ID_OXSEMI, 0xc4bf, /* OXPCIe200 1 Native UART */
+ PCI_ANY_ID, PCI_ANY_ID, 0, 0,
+ 4000000, generic },
+ { PCI_VENDOR_ID_OXSEMI, 0xc4cb, /* OXPCIe200 1 Native UART */
+ PCI_ANY_ID, PCI_ANY_ID, 0, 0,
+ 4000000, generic },
+ { PCI_VENDOR_ID_OXSEMI, 0xc4cf, /* OXPCIe200 1 Native UART */
+ PCI_ANY_ID, PCI_ANY_ID, 0, 0,
+ 4000000, generic },
+ { PCI_VENDOR_ID_OXSEMI, PCI_DEVICE_ID_OXSEMI_16PCI95N,
+ PCI_ANY_ID, PCI_ANY_ID, 0, 0,
+ 4000000, generic },
+ { PCI_VENDOR_ID_MAINPINE, 0x4000, /* IQ Express 1 Port V.34
Super-G3 Fax */
+ PCI_VENDOR_ID_MAINPINE, 0x4001, 0, 0,
+ 4000000, generic },
+ { PCI_VENDOR_ID_MAINPINE, 0x4000, /* IQ Express 2 Port V.34
Super-G3 Fax */
+ PCI_VENDOR_ID_MAINPINE, 0x4002, 0, 0,
+ 4000000, generic },
+ { PCI_VENDOR_ID_MAINPINE, 0x4000, /* IQ Express 4 Port V.34
Super-G3 Fax */
+ PCI_VENDOR_ID_MAINPINE, 0x4004, 0, 0,
+ 4000000, generic },
+ { PCI_VENDOR_ID_MAINPINE, 0x4000, /* IQ Express 8 Port V.34
Super-G3 Fax */
+ PCI_VENDOR_ID_MAINPINE, 0x4008, 0, 0,
+ 4000000, generic },
+ { PCI_VENDOR_ID_SBSMODULARIO, PCI_DEVICE_ID_OCTPRO,
+ PCI_SUBVENDOR_ID_SBSMODULARIO, PCI_SUBDEVICE_ID_OCTPRO232, 0, 0,
+ 460800, generic },
+ { PCI_VENDOR_ID_SBSMODULARIO, PCI_DEVICE_ID_OCTPRO,
+ PCI_SUBVENDOR_ID_SBSMODULARIO, PCI_SUBDEVICE_ID_OCTPRO422, 0, 0,
+ 460800, generic },
+ { PCI_VENDOR_ID_SBSMODULARIO, PCI_DEVICE_ID_OCTPRO,
+ PCI_SUBVENDOR_ID_SBSMODULARIO, PCI_SUBDEVICE_ID_POCTAL232, 0, 0,
+ 460800, generic },
+ { PCI_VENDOR_ID_SBSMODULARIO, PCI_DEVICE_ID_OCTPRO,
+ PCI_SUBVENDOR_ID_SBSMODULARIO, PCI_SUBDEVICE_ID_POCTAL422, 0, 0,
+ 460800, generic },
+ { PCI_VENDOR_ID_TITAN, PCI_DEVICE_ID_TITAN_100,
+ PCI_ANY_ID, PCI_ANY_ID, 0, 0,
+ 921600, titan },
+ { PCI_VENDOR_ID_TITAN, PCI_DEVICE_ID_TITAN_200,
+ PCI_ANY_ID, PCI_ANY_ID, 0, 0,
+ 921600, titan },
+ { PCI_VENDOR_ID_TITAN, PCI_DEVICE_ID_TITAN_400,
+ PCI_ANY_ID, PCI_ANY_ID, 0, 0,
+ 921600, titan },
+ { PCI_VENDOR_ID_TITAN, PCI_DEVICE_ID_TITAN_800B,
+ PCI_ANY_ID, PCI_ANY_ID, 0, 0,
+ 921600, titan },
+ { PCI_VENDOR_ID_TITAN, PCI_DEVICE_ID_TITAN_100L,
+ PCI_ANY_ID, PCI_ANY_ID, 0, 0,
+ 921600, titan },
+ { PCI_VENDOR_ID_TITAN, PCI_DEVICE_ID_TITAN_200L,
+ PCI_ANY_ID, PCI_ANY_ID, 0, 0,
+ 921600, titan },
+ { PCI_VENDOR_ID_TITAN, PCI_DEVICE_ID_TITAN_400L,
+ PCI_ANY_ID, PCI_ANY_ID, 0, 0,
+ 921600, titan },
+ { PCI_VENDOR_ID_TITAN, PCI_DEVICE_ID_TITAN_800L,
+ PCI_ANY_ID, PCI_ANY_ID, 0, 0,
+ 921600, titan },
+ { PCI_VENDOR_ID_SIIG, PCI_DEVICE_ID_SIIG_1S_10x_550,
+ PCI_ANY_ID, PCI_ANY_ID, 0, 0,
+ 460800, generic },
+ { PCI_VENDOR_ID_SIIG, PCI_DEVICE_ID_SIIG_1S_10x_650,
+ PCI_ANY_ID, PCI_ANY_ID, 0, 0,
+ 460800, generic },
+ { PCI_VENDOR_ID_SIIG, PCI_DEVICE_ID_SIIG_1S_10x_850,
+ PCI_ANY_ID, PCI_ANY_ID, 0, 0,
+ 460800, generic },
+ { PCI_VENDOR_ID_SIIG, PCI_DEVICE_ID_SIIG_2S_10x_550,
+ PCI_ANY_ID, PCI_ANY_ID, 0, 0,
+ 921600, generic },
+ { PCI_VENDOR_ID_SIIG, PCI_DEVICE_ID_SIIG_2S_10x_650,
+ PCI_ANY_ID, PCI_ANY_ID, 0, 0,
+ 921600, generic },
+ { PCI_VENDOR_ID_SIIG, PCI_DEVICE_ID_SIIG_2S_10x_850,
+ PCI_ANY_ID, PCI_ANY_ID, 0, 0,
+ 921600, generic },
+ { PCI_VENDOR_ID_SIIG, PCI_DEVICE_ID_SIIG_4S_10x_550,
+ PCI_ANY_ID, PCI_ANY_ID, 0, 0,
+ 921600, generic },
+ { PCI_VENDOR_ID_SIIG, PCI_DEVICE_ID_SIIG_4S_10x_650,
+ PCI_ANY_ID, PCI_ANY_ID, 0, 0,
+ 921600, generic },
+ { PCI_VENDOR_ID_SIIG, PCI_DEVICE_ID_SIIG_4S_10x_850,
+ PCI_ANY_ID, PCI_ANY_ID, 0, 0,
+ 921600, generic },
+ { PCI_VENDOR_ID_SIIG, PCI_DEVICE_ID_SIIG_1S_20x_550,
+ PCI_ANY_ID, PCI_ANY_ID, 0, 0,
+ 921600, generic },
+ { PCI_VENDOR_ID_SIIG, PCI_DEVICE_ID_SIIG_1S_20x_650,
+ PCI_ANY_ID, PCI_ANY_ID, 0, 0,
+ 921600, generic },
+ { PCI_VENDOR_ID_SIIG, PCI_DEVICE_ID_SIIG_1S_20x_850,
+ PCI_ANY_ID, PCI_ANY_ID, 0, 0,
+ 921600, generic },
+ { PCI_VENDOR_ID_SIIG, PCI_DEVICE_ID_SIIG_2S_20x_550,
+ PCI_ANY_ID, PCI_ANY_ID, 0, 0,
+ 921600, generic },
+ { PCI_VENDOR_ID_SIIG, PCI_DEVICE_ID_SIIG_2S_20x_650,
+ PCI_ANY_ID, PCI_ANY_ID, 0, 0,
+ 921600, generic },
+ { PCI_VENDOR_ID_SIIG, PCI_DEVICE_ID_SIIG_2S_20x_850,
+ PCI_ANY_ID, PCI_ANY_ID, 0, 0,
+ 921600, generic },
+ { PCI_VENDOR_ID_SIIG, PCI_DEVICE_ID_SIIG_4S_20x_550,
+ PCI_ANY_ID, PCI_ANY_ID, 0, 0,
+ 921600, generic },
+ { PCI_VENDOR_ID_SIIG, PCI_DEVICE_ID_SIIG_4S_20x_650,
+ PCI_ANY_ID, PCI_ANY_ID, 0, 0,
+ 921600, generic },
+ { PCI_VENDOR_ID_SIIG, PCI_DEVICE_ID_SIIG_4S_20x_850,
+ PCI_ANY_ID, PCI_ANY_ID, 0, 0,
+ 921600, generic },
+ { PCI_VENDOR_ID_SIIG, PCI_DEVICE_ID_SIIG_8S_20x_550,
+ PCI_ANY_ID, PCI_ANY_ID, 0, 0,
+ 921600, generic },
+ { PCI_VENDOR_ID_SIIG, PCI_DEVICE_ID_SIIG_8S_20x_650,
+ PCI_ANY_ID, PCI_ANY_ID, 0, 0,
+ 921600, generic },
+ { PCI_VENDOR_ID_SIIG, PCI_DEVICE_ID_SIIG_8S_20x_850,
+ PCI_ANY_ID, PCI_ANY_ID, 0, 0,
+ 921600, generic },
+ { PCI_VENDOR_ID_COMPUTONE, PCI_DEVICE_ID_COMPUTONE_PG,
+ PCI_SUBVENDOR_ID_COMPUTONE, PCI_SUBDEVICE_ID_COMPUTONE_PG4,
+ 0, 0,
+ 921600, generic },
+ { PCI_VENDOR_ID_COMPUTONE, PCI_DEVICE_ID_COMPUTONE_PG,
+ PCI_SUBVENDOR_ID_COMPUTONE, PCI_SUBDEVICE_ID_COMPUTONE_PG8,
+ 0, 0,
+ 921600, generic },
+ { PCI_VENDOR_ID_COMPUTONE, PCI_DEVICE_ID_COMPUTONE_PG,
+ PCI_SUBVENDOR_ID_COMPUTONE, PCI_SUBDEVICE_ID_COMPUTONE_PG6,
+ 0, 0,
+ 921600, generic },
+ { PCI_VENDOR_ID_TIMEDIA, PCI_DEVICE_ID_TIMEDIA_1889,
+ PCI_VENDOR_ID_TIMEDIA, PCI_ANY_ID, 0, 0,
+ 921600, generic },
+ { PCI_VENDOR_ID_LAVA, PCI_DEVICE_ID_LAVA_OCTO_A,
+ PCI_ANY_ID, PCI_ANY_ID, 0, 0,
+ 460800, generic },
+ { PCI_VENDOR_ID_LAVA, PCI_DEVICE_ID_LAVA_OCTO_B,
+ PCI_ANY_ID, PCI_ANY_ID, 0, 0,
+ 460800, generic },
+ { PCI_VENDOR_ID_LAVA, PCI_DEVICE_ID_LAVA_PORT_PLUS,
+ PCI_ANY_ID, PCI_ANY_ID, 0, 0,
+ 460800, generic },
+ { PCI_VENDOR_ID_LAVA, PCI_DEVICE_ID_LAVA_QUAD_A,
+ PCI_ANY_ID, PCI_ANY_ID, 0, 0,
+ 460800, generic },
+ { PCI_VENDOR_ID_LAVA, PCI_DEVICE_ID_LAVA_QUAD_B,
+ PCI_ANY_ID, PCI_ANY_ID, 0, 0,
+ 460800, generic },
+ { PCI_VENDOR_ID_LAVA, PCI_DEVICE_ID_LAVA_PORT_650,
+ PCI_ANY_ID, PCI_ANY_ID, 0, 0,
+ 460800, generic },
+ { PCI_VENDOR_ID_KORENIX, PCI_DEVICE_ID_KORENIX_JETCARDF0,
+ 0x1204, 0x0004, 0, 0,
+ 921600, generic },
+ { PCI_VENDOR_ID_KORENIX, PCI_DEVICE_ID_KORENIX_JETCARDF0,
+ 0x1208, 0x0004, 0, 0,
+ 921600, generic },
+ { PCI_VENDOR_ID_KORENIX, PCI_DEVICE_ID_KORENIX_JETCARDF1,
+ 0x1208, 0x0004, 0, 0,
+ 921600, generic },
+ { PCI_VENDOR_ID_DELL, PCI_DEVICE_ID_DELL_RAC4,
+ PCI_ANY_ID, PCI_ANY_ID, 0, 0,
+ 1382400, generic },
+ { PCI_VENDOR_ID_DELL, PCI_DEVICE_ID_DELL_RACIII,
+ PCI_ANY_ID, PCI_ANY_ID, 0, 0,
+ 1382400, generic },
+ { PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_80960_RP,
+ 0xE4BF, PCI_ANY_ID, 0, 0,
+ 921600, generic },
+ { PCI_VENDOR_ID_SGI, PCI_DEVICE_ID_SGI_IOC3,
+ 0xFF00, 0, 0, 0,
+ 458333, generic },
+ { PCI_VENDOR_ID_EXAR, PCI_DEVICE_ID_EXAR_XR17C152,
+ PCI_SUBVENDOR_ID_CONNECT_TECH,
+ PCI_SUBDEVICE_ID_CONNECT_TECH_PCI_UART_2_485, 0, 0,
+ 1843200, generic },
+ { PCI_VENDOR_ID_EXAR, PCI_DEVICE_ID_EXAR_XR17C152,
+ PCI_SUBVENDOR_ID_CONNECT_TECH,
+ PCI_SUBDEVICE_ID_CONNECT_TECH_PCI_UART_2, 0, 0,
+ 1843200, generic },
+ { PCI_VENDOR_ID_EXAR, PCI_DEVICE_ID_EXAR_XR17C152,
+ PCI_SUBVENDOR_ID_CONNECT_TECH,
+ PCI_SUBDEVICE_ID_CONNECT_TECH_PCI_UART_1_1, 0, 0,
+ 1843200, generic },
+ { PCI_VENDOR_ID_EXAR, PCI_DEVICE_ID_EXAR_XR17C152,
+ PCI_SUBVENDOR_ID_CONNECT_TECH,
+ PCI_SUBDEVICE_ID_CONNECT_TECH_PCI_UART_2_232, 0, 0,
+ 1843200, generic },
+ { PCI_VENDOR_ID_EXAR, PCI_DEVICE_ID_EXAR_XR17C152,
+ PCI_ANY_ID, PCI_ANY_ID, 0, 0,
+ 921600, generic },
+ { PCI_VENDOR_ID_EXAR, PCI_DEVICE_ID_EXAR_XR17C154,
+ PCI_ANY_ID, PCI_ANY_ID, 0, 0,
+ 921600, generic },
+ { PCI_VENDOR_ID_EXAR, PCI_DEVICE_ID_EXAR_XR17C158,
+ PCI_ANY_ID, PCI_ANY_ID, 0, 0,
+ 921600, generic },
+ { PCI_VENDOR_ID_PASEMI, 0xa004,
+ PCI_ANY_ID, PCI_ANY_ID, 0, 0,
+ 8333333, generic },
+ /*
+ * Generic entries that define the defaults
+ */
+ { PCI_ANY_ID, PCI_ANY_ID,
+ PCI_ANY_ID, PCI_ANY_ID,
+ PCI_CLASS_COMMUNICATION_SERIAL << 8, 0xffff00,
+ 115200, generic },
+ { PCI_ANY_ID, PCI_ANY_ID,
+ PCI_ANY_ID, PCI_ANY_ID,
+ PCI_CLASS_COMMUNICATION_MODEM << 8, 0xffff00,
+ 115200, generic },
+ { PCI_ANY_ID, PCI_ANY_ID,
+ PCI_ANY_ID, PCI_ANY_ID,
+ PCI_CLASS_COMMUNICATION_MULTISERIAL << 8, 0xffff00,
+ 115200, generic },
+ {
+ 0, 0, 0, 0, 0, 0, 0, generic },
+};
Index: include/grub/i386/pc/serial.h
===================================================================
--- include/grub/i386/pc/serial.h (revision 1911)
+++ include/grub/i386/pc/serial.h (working copy)
@@ -40,6 +40,9 @@
#define UART_DATA_READY 0x01
#define UART_EMPTY_TRANSMITTER 0x20
+/* Default base baud */
+#define UART_BASE_BAUD 115200
+
/* The type of parity. */
#define UART_NO_PARITY 0x00
#define UART_ODD_PARITY 0x08
@@ -64,4 +67,9 @@
/* Turn on DTR, RTS, and OUT2. */
#define UART_ENABLE_MODEM 0x0B
+/* Serial device types */
+#define SERIAL_LEGACY 0
+#define SERIAL_PCI 1
+#define SERIAL_USB 2
+
#endif /* ! GRUB_SERIAL_MACHINE_HEADER */
Index: ChangeLog
===================================================================
--- ChangeLog (revision 1911)
+++ ChangeLog (working copy)
@@ -1,3 +1,13 @@
+2008-11-03 Don Dugger <address@hidden>
+
+ * term/i386/pc/serial.c: major changes to support multiple serial
+ devices, also add `--base' parameter to serial command allowing
+ user to specify base baud for those UARTs that don't follow
+ the PC standard and are not recognized.
+ * include/grub/i386/pc/serial.h: define default base baud value
+ of 115200 (default for PCs) and serial device types.
+ * include/grub/pci_serial_ids.h: map serial PCI IDs to base baud
+
2008-11-12 Robert Millan <address@hidden>
* conf/i386-pc.rmk (kernel_img_SOURCES): Add `term/i386/vga_common.c'.
Index: term/i386/pc/serial.c
===================================================================
--- term/i386/pc/serial.c (revision 1911)
+++ term/i386/pc/serial.c (working copy)
@@ -27,7 +27,12 @@
#include <grub/arg.h>
#include <grub/terminfo.h>
#include <grub/cpu/io.h>
+#include <grub/mm.h>
+#include <grub/pci.h>
+void grub_serial_add(int type, unsigned int id, unsigned int base, unsigned
int port);
+#include <grub/pci_serial_ids.h>
+
#define TEXT_WIDTH 80
#define TEXT_HEIGHT 25
@@ -48,22 +53,24 @@
{"word", 'w', 0, "Set the serial port word length", 0, ARG_TYPE_INT},
{"parity", 'r', 0, "Set the serial port parity", 0, ARG_TYPE_STRING},
{"stop", 't', 0, "Set the serial port stop bits", 0, ARG_TYPE_INT},
+ {"base", 'b', 0, "Set the serial port base baud", 0, ARG_TYPE_INT},
{0, 0, 0, 0, 0, 0}
};
-/* Serial port settings. */
-struct serial_port
-{
+struct serial_dev {
+ int type;
+ int id;
unsigned short port;
- unsigned short divisor;
+ unsigned int speed;
+ unsigned int base;
unsigned short word_len;
unsigned int parity;
unsigned short stop_bits;
};
+static struct serial_dev *serial_devices = (struct serial_dev *)0;
+static struct serial_dev *serial_dev;
+static int num_dev = 0;
-/* Serial port settings. */
-static struct serial_port serial_settings;
-
#ifdef GRUB_MACHINE_PCBIOS
/* The BIOS data area. */
static const unsigned short *serial_hw_io_addr = (const unsigned short *)
0x0400;
@@ -73,6 +80,94 @@
#define GRUB_SERIAL_PORT_NUM (sizeof(serial_hw_io_addr)/(serial_hw_io_addr[0]))
#endif
+char *serial_types[] = {
+ "legacy",
+ " pci",
+ " usb"
+};
+
+static void
+serial_pr_type(int i, struct serial_dev *p)
+{
+
+ grub_printf("%c%2d: %s ", (p == serial_dev) ? '*' : ' ',
+ i, serial_types[p->type]);
+ switch (p->type) {
+
+ case SERIAL_LEGACY:
+ grub_printf(" COM%d", p->id + 1);
+ break;
+
+ case SERIAL_PCI:
+ {
+ unsigned int b, d, f;
+
+ b = p->id >> 8;
+ d = (p->id >> 3) & 0x1f;
+ f = p->id & 7;
+ grub_printf("%d:%02x.%d", b, d, f);
+ break;
+ }
+
+ case SERIAL_USB:
+ grub_printf(" %2d", p->id);
+ break;
+
+ }
+
+ return;
+}
+
+char parity[] = {
+ 'N',
+ 'O',
+ '?',
+ 'E'
+};
+
+static void
+serial_pr(void)
+{
+ int i;
+ struct serial_dev *p;
+
+ grub_printf("Available serial units:\n");
+ p = serial_devices;
+ for (i = 0; i < num_dev; i++) {
+ serial_pr_type(i, p);
+ grub_printf(" 0x%04x %6d/%-7d %d%c%d\n", p->port, p->speed, p->base,
+ p->word_len + 5,
+ parity[p->parity >> 3],
+ (p->stop_bits >> 2) + 1);
+ p++;
+ }
+}
+
+void
+grub_serial_add(int type, unsigned int id, unsigned int base, unsigned int
port)
+{
+ int idx, unit;
+
+ unit = serial_dev - serial_devices;
+ idx = num_dev++;
+ if ((serial_devices = grub_realloc(serial_devices, num_dev *
(sizeof(*serial_devices)))) == (struct serial_dev *)0) {
+ grub_error (GRUB_ERR_OUT_OF_MEMORY, "realloc of %d bytes failed\n",
num_dev * (sizeof(*serial_devices)));
+ return;
+ }
+
+ serial_devices[idx].type = type;
+ serial_devices[idx].id = id;
+ serial_devices[idx].base = base;
+ serial_devices[idx].port = port;
+ serial_devices[idx].speed = 9600;
+ serial_devices[idx].word_len = UART_8BITS_WORD;
+ serial_devices[idx].parity = UART_NO_PARITY;
+ serial_devices[idx].stop_bits = UART_1_STOP_BIT;
+ serial_dev = &serial_devices[unit];
+
+ return;
+}
+
/* Return the port number for the UNITth serial device. */
static inline unsigned short
serial_hw_get_port (const unsigned int unit)
@@ -87,8 +182,8 @@
static int
serial_hw_fetch (void)
{
- if (grub_inb (serial_settings.port + UART_LSR) & UART_DATA_READY)
- return grub_inb (serial_settings.port + UART_RX);
+ if (grub_inb (serial_dev->port + UART_LSR) & UART_DATA_READY)
+ return grub_inb (serial_dev->port + UART_RX);
return -1;
}
@@ -100,14 +195,14 @@
unsigned int timeout = 100000;
/* Wait until the transmitter holding register is empty. */
- while ((grub_inb (serial_settings.port + UART_LSR) & UART_EMPTY_TRANSMITTER)
== 0)
+ while ((grub_inb (serial_dev->port + UART_LSR) & UART_EMPTY_TRANSMITTER) ==
0)
{
if (--timeout == 0)
/* There is something wrong. But what can I do? */
return;
}
- grub_outb (c, serial_settings.port + UART_TX);
+ grub_outb (c, serial_dev->port + UART_TX);
}
static void
@@ -210,35 +305,9 @@
/* Convert speed to divisor. */
static unsigned short
-serial_get_divisor (unsigned int speed)
+serial_get_divisor (unsigned int speed, unsigned int base)
{
- unsigned int i;
-
- /* The structure for speed vs. divisor. */
- struct divisor
- {
- unsigned int speed;
- unsigned short div;
- };
-
- /* The table which lists common configurations. */
- /* 1843200 / (speed * 16) */
- static struct divisor divisor_tab[] =
- {
- { 2400, 0x0030 },
- { 4800, 0x0018 },
- { 9600, 0x000C },
- { 19200, 0x0006 },
- { 38400, 0x0003 },
- { 57600, 0x0002 },
- { 115200, 0x0001 }
- };
-
- /* Set the baud rate. */
- for (i = 0; i < sizeof (divisor_tab) / sizeof (divisor_tab[0]); i++)
- if (divisor_tab[i].speed == speed)
- return divisor_tab[i].div;
- return 0;
+ return ((base << 4) + (speed << 3)) / (speed << 4);
}
/* The serial version of checkkey. */
@@ -274,31 +343,36 @@
WORD_LEN, PARITY and STOP_BIT_LEN are defined in the header file as
macros. */
static grub_err_t
-serial_hw_init (void)
+serial_hw_init (struct serial_dev *dev)
{
unsigned char status = 0;
+ unsigned short divisor;
+ if (dev->port == 0)
+ return GRUB_ERR_OUT_OF_RANGE;
+
/* Turn off the interrupt. */
- grub_outb (0, serial_settings.port + UART_IER);
+ grub_outb (0, dev->port + UART_IER);
/* Set DLAB. */
- grub_outb (UART_DLAB, serial_settings.port + UART_LCR);
+ grub_outb (UART_DLAB, dev->port + UART_LCR);
/* Set the baud rate. */
- grub_outb (serial_settings.divisor & 0xFF, serial_settings.port + UART_DLL);
- grub_outb (serial_settings.divisor >> 8, serial_settings.port + UART_DLH);
+ divisor = serial_get_divisor(dev->speed, dev->base);
+ grub_outb (divisor & 0xFF, dev->port + UART_DLL);
+ grub_outb (divisor >> 8, dev->port + UART_DLH);
/* Set the line status. */
- status |= (serial_settings.parity
- | serial_settings.word_len
- | serial_settings.stop_bits);
- grub_outb (status, serial_settings.port + UART_LCR);
+ status |= (dev->parity
+ | dev->word_len
+ | dev->stop_bits);
+ grub_outb (status, dev->port + UART_LCR);
/* Enable the FIFO. */
- grub_outb (UART_ENABLE_FIFO, serial_settings.port + UART_FCR);
+ grub_outb (UART_ENABLE_FIFO, dev->port + UART_FCR);
/* Turn on DTR, RTS, and OUT2. */
- grub_outb (UART_ENABLE_MODEM, serial_settings.port + UART_MCR);
+ grub_outb (UART_ENABLE_MODEM, dev->port + UART_MCR);
/* Drain the input buffer. */
while (grub_serial_checkkey () != -1)
@@ -495,31 +569,41 @@
int argc __attribute__ ((unused)),
char **args __attribute__ ((unused)))
{
- struct serial_port backup_settings = serial_settings;
+ int unit;
+ struct serial_dev dev;
grub_err_t hwiniterr;
+ if ((state[0].set == 0) && (state[1].set == 0) && (state[2].set == 0) &&
+ (state[3].set == 0) && (state[4].set == 0) && (state[5].set == 0) &&
+ (state[6].set == 0)) {
+ serial_pr();
+ return GRUB_ERR_NONE;
+ }
+
+ dev = *serial_dev;
+ unit = serial_dev - serial_devices;
if (state[0].set)
{
- unsigned int unit;
unit = grub_strtoul (state[0].arg, 0, 0);
- serial_settings.port = serial_hw_get_port (unit);
- if (!serial_settings.port)
- return grub_error (GRUB_ERR_BAD_ARGUMENT, "bad unit number.");
+ if (unit >= num_dev)
+ {
+ return grub_error (GRUB_ERR_BAD_ARGUMENT, "bad unit number.");
+ }
+ dev = serial_devices[unit];
}
if (state[1].set)
- serial_settings.port = (unsigned short) grub_strtoul (state[1].arg, 0, 0);
+ {
+ dev.port = (unsigned short) grub_strtoul (state[1].arg, 0, 0);
+ }
if (state[2].set)
{
- unsigned long speed;
- speed = grub_strtoul (state[2].arg, 0, 0);
- serial_settings.divisor = serial_get_divisor ((unsigned int) speed);
- if (serial_settings.divisor == 0)
+ dev.speed = (unsigned int )grub_strtoul (state[2].arg, 0, 0);
+ if (dev.speed == 0)
{
- serial_settings = backup_settings;
return grub_error (GRUB_ERR_BAD_ARGUMENT, "bad speed");
}
}
@@ -527,16 +611,15 @@
if (state[3].set)
{
if (! grub_strcmp (state[3].arg, "5"))
- serial_settings.word_len = UART_5BITS_WORD;
+ dev.word_len = UART_5BITS_WORD;
else if (! grub_strcmp (state[3].arg, "6"))
- serial_settings.word_len = UART_6BITS_WORD;
+ dev.word_len = UART_6BITS_WORD;
else if (! grub_strcmp (state[3].arg, "7"))
- serial_settings.word_len = UART_7BITS_WORD;
+ dev.word_len = UART_7BITS_WORD;
else if (! grub_strcmp (state[3].arg, "8"))
- serial_settings.word_len = UART_8BITS_WORD;
+ dev.word_len = UART_8BITS_WORD;
else
{
- serial_settings = backup_settings;
return grub_error (GRUB_ERR_BAD_ARGUMENT, "bad word length");
}
}
@@ -544,14 +627,13 @@
if (state[4].set)
{
if (! grub_strcmp (state[4].arg, "no"))
- serial_settings.parity = UART_NO_PARITY;
+ dev.parity = UART_NO_PARITY;
else if (! grub_strcmp (state[4].arg, "odd"))
- serial_settings.parity = UART_ODD_PARITY;
+ dev.parity = UART_ODD_PARITY;
else if (! grub_strcmp (state[4].arg, "even"))
- serial_settings.parity = UART_EVEN_PARITY;
+ dev.parity = UART_EVEN_PARITY;
else
{
- serial_settings = backup_settings;
return grub_error (GRUB_ERR_BAD_ARGUMENT, "bad parity");
}
}
@@ -559,21 +641,32 @@
if (state[5].set)
{
if (! grub_strcmp (state[5].arg, "1"))
- serial_settings.stop_bits = UART_1_STOP_BIT;
+ dev.stop_bits = UART_1_STOP_BIT;
else if (! grub_strcmp (state[5].arg, "2"))
- serial_settings.stop_bits = UART_2_STOP_BITS;
+ dev.stop_bits = UART_2_STOP_BITS;
else
{
- serial_settings = backup_settings;
return grub_error (GRUB_ERR_BAD_ARGUMENT, "bad number of stop bits");
}
}
+ if (state[6].set)
+ {
+
+ dev.base = grub_strtoul (state[6].arg, 0, 0);
+ if (dev.base == 0)
+ {
+ return grub_error (GRUB_ERR_BAD_ARGUMENT, "bad base baud");
+ }
+ }
+
/* Initialize with new settings. */
- hwiniterr = serial_hw_init ();
+ hwiniterr = serial_hw_init (&dev);
if (hwiniterr == GRUB_ERR_NONE)
{
+ serial_dev = &serial_devices[unit];
+ *serial_dev = dev;
/* Register terminal if not yet registered. */
if (registered == 0)
{
@@ -584,13 +677,13 @@
}
else
{
+ grub_error(GRUB_ERR_BAD_ARGUMENT, "Bad settings, revert to prior
device");
/* Initialization with new settings failed. */
if (registered == 1)
{
/* If the terminal is registered, attempt to restore previous
settings. */
- serial_settings = backup_settings;
- if (serial_hw_init () != GRUB_ERR_NONE)
+ if (serial_hw_init (serial_dev) != GRUB_ERR_NONE)
{
/* If unable to restore settings, unregister terminal. */
grub_term_unregister_input (&grub_serial_term_input);
@@ -603,21 +696,57 @@
return hwiniterr;
}
+static int
+serial_pci_scan (int bus, int dev, int func, grub_pci_id_t pciid)
+{
+ struct pci_device_id *p;
+ grub_pci_address_t addr;
+ unsigned int w, vid, did, ss_vid, ss_did, class;
+
+ vid = pciid & 0xffff;
+ did = pciid >> 16;
+ addr = grub_pci_make_address (bus, dev, func, 2);
+ w = grub_pci_read (addr);
+ class = (w >> 16) | ((w >> 8) & 0xff);
+ addr = grub_pci_make_address (bus, dev, func, 11);
+ w = grub_pci_read (addr);
+ ss_vid = w & 0xffff;
+ ss_did = w >> 16;
+ for (p = serial_pci_id; p->vendor_id; p++) {
+ if ((p->vendor_id == PCI_ANY_ID || p->vendor_id == vid) &&
+ (p->device_id == PCI_ANY_ID || p->device_id == did) &&
+ (p->ss_vendor == PCI_ANY_ID || p->ss_vendor == ss_vid) &&
+ (p->ss_device == PCI_ANY_ID || p->ss_device == ss_did) &&
+ !((p->dev_class ^ (class << 8)) & p->dev_class_mask)) {
+ (p->dev_config)(bus, dev, func, p->base_baud);
+ break;
+ }
+ }
+ return 0;
+}
+
GRUB_MOD_INIT(serial)
{
+ int i;
+
(void) mod; /* To stop warning. */
+ grub_errno = 0;
grub_register_command ("serial", grub_cmd_serial, GRUB_COMMAND_FLAG_BOTH,
"serial [OPTIONS...]", "Configure serial port.",
options);
/* Set default settings. */
- serial_settings.port = serial_hw_get_port (0);
- serial_settings.divisor = serial_get_divisor (9600);
- serial_settings.word_len = UART_8BITS_WORD;
- serial_settings.parity = UART_NO_PARITY;
- serial_settings.stop_bits = UART_1_STOP_BIT;
+ for (i = 0; i < GRUB_SERIAL_PORT_NUM; i++)
+ grub_serial_add(SERIAL_LEGACY, i, UART_BASE_BAUD, serial_hw_get_port(i));
+ serial_dev = &serial_devices[0];
+
+ /*
+ * Check for PCI serial card, set defaults appropriately if one exists
+ */
+ grub_pci_iterate (serial_pci_scan);
}
GRUB_MOD_FINI(serial)
{
+ grub_free (serial_devices);
grub_unregister_command ("serial");
if (registered == 1) /* Unregister terminal only if registered. */
{
- Re: [PATCH] PCI serial card support, (continued)
- Re: [PATCH] PCI serial card support, n0ano, 2008/11/07
- Re: [PATCH] PCI serial card support, Vesa Jääskeläinen, 2008/11/07
- Re: [PATCH] PCI serial card support, Robert Millan, 2008/11/08
- Re: [PATCH] PCI serial card support, Vesa Jääskeläinen, 2008/11/08
- Re: [PATCH] PCI serial card support, Robert Millan, 2008/11/08
- Re: [PATCH] PCI serial card support, Vesa Jääskeläinen, 2008/11/08
- Re: [PATCH] PCI serial card support, n0ano, 2008/11/08
- Re: [PATCH] PCI serial card support, Robert Millan, 2008/11/09
- Re: [PATCH] PCI serial card support, Vesa Jääskeläinen, 2008/11/09
- Re: [PATCH] PCI serial card support, n0ano, 2008/11/09
- Re: [PATCH] PCI serial card support,
n0ano <=
- Re: [PATCH] PCI serial card support, Vesa Jääskeläinen, 2008/11/13
- Re: [PATCH] PCI serial card support, n0ano, 2008/11/13
- Re: [PATCH] PCI serial card support, n0ano, 2008/11/14
- Re: [PATCH] PCI serial card support, Neo Jia, 2008/11/21
- Re: [PATCH] PCI serial card support, Vesa Jääskeläinen, 2008/11/22
Re: [PATCH] PCI serial card support, Vesa Jääskeläinen, 2008/11/04