lkml.org 
[lkml]   [2001]   [Feb]   [26]   [last100]   RSS Feed
Views: [wrap][no wrap]   [headers]  [forward] 
 
Messages in this thread
Patches in this message
/
Date
From
Subject[PATCH] serial drivers: get rid of panic() call

Hi all,

please take a look at attached patches (2.4.2-ac1):

cyclades.c: remove panic() calls;

serial.c: ioremap() checks, better error handling in start_pci_pnp_board() function
(dectivate/deinit device on failire), remove panic() calls.


Also I have some questions:
- trying to remove panic() from epca.c I found that it calls tty_register_driver()
3 times and tty_unregister_driver() 2 times (registers pc_driver, pc_callout and
pc_info, but unregisters only first two). BUG ?

- is here any sane reason (this question also about epca.c) to detect PCI devices
before tty_register_driver() calls ?

- amiserial.c calls requesst_irq() for IRQ_AMIGA_TBE and IRQ_AMIGA_RBF, but
doesn't free then on unload and doesn't check return values. BUG too ?

I don't know anything about Amiga's, so last question can be horribly stupid :))

Best regards.

--
Andrey Panin | Embedded systems software engineer
pazke@orbita1.ru | PGP key: http://www.orbita1.ru/~pazke/AndreyPanin.ascdiff -ur /linux.vanilla/drivers/char/cyclades.c /linux/drivers/char/cyclades.c
--- /linux.vanilla/drivers/char/cyclades.c Fri Feb 23 20:37:51 2001
+++ /linux/drivers/char/cyclades.c Mon Feb 26 23:05:10 2001
@@ -5478,6 +5478,15 @@
extra ports are ignored.
*/

+static void __init cy_cleanup_after_failure(struct tty_driver *tty)
+{
+ unsigned long flags;
+ save_flags(flags); cli();
+ remove_bh(CYCLADES_BH);
+ if (tty) tty_unregister_driver(tty);
+ restore_flags(flags);
+}
+
int __init
cy_init(void)
{
@@ -5544,10 +5553,16 @@
cy_callout_driver.proc_entry = 0;


- if (tty_register_driver(&cy_serial_driver))
- panic("Couldn't register Cyclades serial driver\n");
- if (tty_register_driver(&cy_callout_driver))
- panic("Couldn't register Cyclades callout driver\n");
+ if ((i = tty_register_driver(&cy_serial_driver))) {
+ printk(KERN_ERR "cyclades: Couldn't register Cyclades serial driver\n");
+ cy_cleanup_after_failure(NULL);
+ return i;
+ }
+ if ((i = tty_register_driver(&cy_callout_driver))) {
+ printk(KERN_ERR "cyclades: Couldn't register Cyclades callout driver\n");
+ cy_cleanup_after_failure(&cy_serial_driver);
+ return i;
+ }

for (i = 0; i < NR_CARDS; i++) {
/* base_addr=0 indicates board not found */diff -ur linux.vanilla/drivers/char/serial.c linux/drivers/char/serial.c
--- linux.vanilla/drivers/char/serial.c Thu Feb 22 17:20:27 2001
+++ linux/drivers/char/serial.c Mon Feb 26 16:04:02 2001
@@ -3876,7 +3876,8 @@
return 0;
}
req->io_type = SERIAL_IO_MEM;
- req->iomem_base = ioremap(port, board->uart_offset);
+ if ((req->iomem_base = ioremap(port, board->uart_offset)) == NULL)
+ return 1;
req->iomem_reg_shift = board->reg_shift;
req->port = 0;
return 0;
@@ -3939,8 +3940,13 @@
* shutdown the board on a module unload.
*/
if (DEACTIVATE_FUNC(dev) || board->init_fn) {
- if (serial_pci_board_idx >= NR_PCI_BOARDS)
+ if (serial_pci_board_idx >= NR_PCI_BOARDS) {
+ if (board->init_fn)
+ (board->init_fn)(dev, board, 0);
+ if (board->flags & SPCI_FL_ISPNP)
+ (DEACTIVATE_FUNC(dev))(dev);
return;
+ }
serial_pci_board[serial_pci_board_idx].board = *board;
serial_pci_board[serial_pci_board_idx].dev = dev;
serial_pci_board_idx++;
@@ -3954,8 +3960,15 @@

for (k=0; k < board->num_ports; k++) {
serial_req.irq = get_pci_irq(dev, board, k);
- if (get_pci_port(dev, board, &serial_req, k))
+ if (get_pci_port(dev, board, &serial_req, k)) {
+ if (!k) {
+ if (board->init_fn)
+ (board->init_fn)(dev, board, 0);
+ if (board->flags & SPCI_FL_ISPNP)
+ (DEACTIVATE_FUNC(dev))(dev);
+ }
break;
+ }
serial_req.flags = ASYNC_SKIP_TEST | ASYNC_AUTOPROBE;
#ifdef SERIAL_DEBUG_PCI
printk("Setup PCI/PNP port: port %x, irq %d, type %d\n",
@@ -4010,7 +4023,8 @@
data | pci_config);

/* enable/disable interrupts */
- p = ioremap(pci_resource_start(dev, 0), 0x80);
+ if ((p = ioremap(pci_resource_start(dev, 0), 0x80)) == NULL)
+ return 1;
writel(enable ? irq_config : 0x00, (unsigned long)p + 0x4c);
iounmap(p);

@@ -4053,7 +4067,8 @@

if (!enable) return 0;

- p = ioremap(pci_resource_start(dev, 0), 0x80);
+ if ((p = ioremap(pci_resource_start(dev, 0), 0x80)) == NULL)
+ return 1;

switch (dev->device & 0xfff8) {
case PCI_DEVICE_ID_SIIG_1S_10x: /* 1S */
@@ -5099,6 +5114,16 @@
/*
* The serial driver boot-time initialization code!
*/
+static void __init rs_cleanup_after_failure(struct tty_driver *tty)
+{
+ unsigned long flags;
+ del_timer_sync(&serial_timer);
+ save_flags(flags); cli();
+ remove_bh(SERIAL_BH);
+ if (tty) tty_unregister_driver(tty);
+ restore_flags(flags);
+}
+
static int __init rs_init(void)
{
int i;
@@ -5198,11 +5223,17 @@
callout_driver.proc_entry = 0;
#endif

- if (tty_register_driver(&serial_driver))
- panic("Couldn't register serial driver\n");
- if (tty_register_driver(&callout_driver))
- panic("Couldn't register callout driver\n");
-
+ if ((i = tty_register_driver(&serial_driver))) {
+ printk(KERN_ERR "serial: Couldn't register serial driver\n");
+ rs_cleanup_after_failure(NULL);
+ return i;
+ }
+ if ((i = tty_register_driver(&callout_driver))) {
+ printk(KERN_ERR "serial: Couldn't register callout driver\n");
+ rs_cleanup_after_failure(&serial_driver);
+ return i;
+ }
+
for (i = 0, state = rs_table; i < NR_PORTS; i++,state++) {
state->magic = SSTATE_MAGIC;
state->line = i;[unhandled content-type:application/pgp-signature]
\
 
 \ /
  Last update: 2005-03-22 13:17    [W:0.117 / U:0.660 seconds]
©2003-2020 Jasper Spaans|hosted at Digital Ocean and TransIP|Read the blog|Advertise on this site