[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: |
Fri, 14 Nov 2008 12:24:58 -0700 |
User-agent: |
Mutt/1.4.2.1i |
On Thu, Nov 13, 2008 at 08:05:37PM +0200, Vesa J??skel?inen wrote:
> Hi Don,
>
> Thanks for the patch!
>
Here is a new patch incorporating your comments.
(Still waiting on legal about the copyright assignment, I'm sure it'll
happen - someday.)
Signed-off-by: Donald D. Dugger <address@hidden>
--
Don Dugger
"Censeo Toto nos in Kansa esse decisse." - D. Gale
address@hidden
Ph: 303/443-3786
diffstat pci_serial-grub-1113.patch
ChangeLog | 14 +
include/grub/i386/pc/serial.h | 10 +
include/grub/i386/pc/serial_table.h | 86 ++++++++++
include/grub/i386/pci.h | 16 ++
include/grub/pci.h | 6
include/grub/pci_ids.h | 29 +++
term/i386/pc/serial.c | 288 +++++++++++++++++++++++++-----------
7 files changed, 368 insertions(+), 81 deletions(-)
Index: include/grub/i386/pci.h
===================================================================
--- include/grub/i386/pci.h (revision 1911)
+++ include/grub/i386/pci.h (working copy)
@@ -32,4 +32,20 @@
return grub_inl (GRUB_PCI_DATA_REG);
}
+static inline grub_uint32_t
+grub_pci_read_config(unsigned int bus, unsigned int dev, unsigned int func,
unsigned int off)
+{
+ grub_pci_address_t addr;
+
+ addr = grub_pci_make_address (bus, dev, func, off);
+ return grub_pci_read (addr);
+}
+
+static inline grub_uint32_t
+grub_pci_get_bar(unsigned int bus, unsigned int dev, unsigned int func,
unsigned int bar)
+{
+
+ return grub_pci_read_config(bus, dev, func, 4 + bar) & ~3;
+}
+
#endif /* GRUB_CPU_PCI_H */
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,11 @@
/* 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
+
+void grub_serial_add(int type, unsigned int id, unsigned int base, unsigned
int port);
+
#endif /* ! GRUB_SERIAL_MACHINE_HEADER */
Index: include/grub/i386/pc/serial_table.h
===================================================================
--- include/grub/i386/pc/serial_table.h (revision 0)
+++ include/grub/i386/pc/serial_table.h (revision 0)
@@ -0,0 +1,86 @@
+/*
+ * GRUB -- GRand Unified Bootloader
+ * Copyright (C) 2008 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/>.
+ */
+
+static void
+titan(unsigned int bus, unsigned int dev, unsigned int func, unsigned int
bbaud)
+{
+ unsigned int port;
+
+ port = grub_pci_get_bar(bus, dev, func, 1);
+ grub_serial_add(SERIAL_PCI, GRUB_PCI_BDF(bus, dev, func), bbaud, port);
+ return;
+}
+
+static void
+netmos(unsigned int bus, unsigned int dev, unsigned int func, unsigned int
bbaud)
+{
+ unsigned int port;
+
+ port = grub_pci_get_bar(bus, dev, func, 0);
+ grub_serial_add(SERIAL_PCI, GRUB_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, GRUB_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_TITAN, PCI_ANY_ID,
+ PCI_ANY_ID, PCI_ANY_ID, 0, 0,
+ 921600, titan },
+ { PCI_VENDOR_ID_NETMOS, PCI_ANY_ID,
+ PCI_ANY_ID, PCI_ANY_ID, 0, 0,
+ 115200, netmos },
+ /*
+ * Generic entries that define the defaults
+ */
+ { PCI_ANY_ID, PCI_ANY_ID,
+ PCI_ANY_ID, PCI_ANY_ID,
+ PCI_CLASS_COMM_SERIAL << 8, 0xffff00,
+ 115200, generic },
+ { PCI_ANY_ID, PCI_ANY_ID,
+ PCI_ANY_ID, PCI_ANY_ID,
+ PCI_CLASS_COMM_SERIAL_16450 << 8, 0xffff00,
+ 115200, generic },
+ { PCI_ANY_ID, PCI_ANY_ID,
+ PCI_ANY_ID, PCI_ANY_ID,
+ PCI_CLASS_COMM_SERIAL_16550 << 8, 0xffff00,
+ 115200, generic },
+ {
+ 0, 0, 0, 0, 0, 0, 0, generic },
+};
Index: include/grub/pci_ids.h
===================================================================
--- include/grub/pci_ids.h (revision 0)
+++ include/grub/pci_ids.h (revision 0)
@@ -0,0 +1,29 @@
+/*
+ * GRUB -- GRand Unified Bootloader
+ * Copyright (C) 2008 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_COMM_SERIAL 0x0700
+#define PCI_CLASS_COMM_SERIAL_16450 0x0702
+#define PCI_CLASS_COMM_SERIAL_16550 0x0703
+
+#define PCI_VENDOR_ID_TITAN 0x14D2
+#define PCI_DEVICE_ID_TITAN_100L 0x8010
+
+#define PCI_VENDOR_ID_NETMOS 0x9710
+#define PCI_DEVICE_ID_NETMOS_9835 0x9835
Index: include/grub/pci.h
===================================================================
--- include/grub/pci.h (revision 1911)
+++ include/grub/pci.h (working copy)
@@ -35,6 +35,12 @@
#define GRUB_PCI_ADDR_MEM_MASK ~0xf
#define GRUB_PCI_ADDR_IO_MASK ~0x03
+#define GRUB_PCI_BDF(b,d,f) ((b << 8) | (d << 3) | f)
+
+#define GRUB_PCI_VENDOR(id) (id & 0xffff)
+#define GRUB_PCI_DEVICE(id) ((id >> 16) & 0xffff)
+#define GRUB_PCI_DEVICE_CLASS(c) ((c >> 16) | ((c >> 8) & 0xff))
+
typedef grub_uint32_t grub_pci_id_t;
typedef int (*grub_pci_iteratefunc_t) (int bus, int device, int func,
grub_pci_id_t pciid);
Index: ChangeLog
===================================================================
--- ChangeLog (revision 1911)
+++ ChangeLog (working copy)
@@ -1,3 +1,17 @@
+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/i386/pc/serial_table.h: define base bauds for known
+ serial devices
+ * include/grub/pci_ids.h: start at a PCI IDs table
+ * include/grub/pci.h: add some helper functions
+ * include/grub/i386/pci.h: add some helper functions
+
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,6 +27,10 @@
#include <grub/arg.h>
#include <grub/terminfo.h>
#include <grub/cpu/io.h>
+#include <grub/mm.h>
+#include <grub/pci.h>
+#include <grub/pci_ids.h>
+#include <grub/machine/serial_table.h>
#define TEXT_WIDTH 80
#define TEXT_HEIGHT 25
@@ -48,22 +52,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 +79,94 @@
#define GRUB_SERIAL_PORT_NUM (sizeof(serial_hw_io_addr)/(serial_hw_io_addr[0]))
#endif
+static const char *serial_types[] = {
+ "legacy",
+ "pci",
+ "usb"
+};
+
+static void
+serial_pr_type(int i, struct serial_dev *p)
+{
+
+ grub_printf("%c%2d: %6.6s ", (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;
+}
+
+static const 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 +181,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 +194,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 +304,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 +342,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 +568,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 +610,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 +626,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 +640,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 +676,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 +695,55 @@
return hwiniterr;
}
+static int
+serial_pci_scan (int bus, int dev, int func, grub_pci_id_t pci_id)
+{
+ struct pci_device_id *p;
+ unsigned int w, vid, did, ss_vid, ss_did, class;
+
+ vid = GRUB_PCI_VENDOR(pci_id);
+ did = GRUB_PCI_DEVICE(pci_id);
+ class = GRUB_PCI_DEVICE_CLASS(grub_pci_read_config(bus, dev, func, 2));
+ w = grub_pci_read_config (bus, dev, func, 11);
+ ss_vid = GRUB_PCI_VENDOR(w);
+ ss_did = GRUB_PCI_DEVICE(w);
+ 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;
+ unsigned int port;
+
(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++)
+ if ((port = serial_hw_get_port(i)) != 0)
+ grub_serial_add(SERIAL_LEGACY, i, UART_BASE_BAUD, port);
+ 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, 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, 2008/11/12
- 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 <=
- 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