aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorJiri Slaby <jirislaby@gmail.com>2006-12-08 05:39:03 -0500
committerLinus Torvalds <torvalds@woody.osdl.org>2006-12-08 11:28:58 -0500
commit42f6384fe4747f65dc27e8a5f96502204558203b (patch)
tree2426f001057d213fa89b0c2b790ddb93e4faa707
parent927a6f9dd0d0b5f70cb2e0799ce7a3844f43d42f (diff)
[PATCH] Char: sx, lock boards struct
Fix race condition which may occurs when multiple cards are probed at the same time. Add mutex to critical sections to avoid this situation. Signed-off-by: Jiri Slaby <jirislaby@gmail.com> Cc: Alan Cox <alan@lxorguk.ukuu.org.uk> Signed-off-by: Andrew Morton <akpm@osdl.org> Signed-off-by: Linus Torvalds <torvalds@osdl.org>
-rw-r--r--drivers/char/sx.c37
1 files changed, 23 insertions, 14 deletions
diff --git a/drivers/char/sx.c b/drivers/char/sx.c
index 50cd64262a13..42427f4d2ebd 100644
--- a/drivers/char/sx.c
+++ b/drivers/char/sx.c
@@ -298,6 +298,7 @@ static int sx_init_drivers(void);
298 298
299static struct tty_driver *sx_driver; 299static struct tty_driver *sx_driver;
300 300
301static DEFINE_MUTEX(sx_boards_lock);
301static struct sx_board boards[SX_NBOARDS]; 302static struct sx_board boards[SX_NBOARDS];
302static struct sx_port *sx_ports; 303static struct sx_port *sx_ports;
303static int sx_initialized; 304static int sx_initialized;
@@ -1980,7 +1981,6 @@ static int sx_init_board (struct sx_board *board)
1980 } 1981 }
1981 1982
1982 if (chans) { 1983 if (chans) {
1983 /* board->flags |= SX_BOARD_PRESENT; */
1984 if(board->irq > 0) { 1984 if(board->irq > 0) {
1985 /* fixed irq, probably PCI */ 1985 /* fixed irq, probably PCI */
1986 if(sx_irqmask & (1 << board->irq)) { /* may we use this irq? */ 1986 if(sx_irqmask & (1 << board->irq)) { /* may we use this irq? */
@@ -2115,8 +2115,6 @@ static int __devinit probe_sx (struct sx_board *board)
2115 return 0; 2115 return 0;
2116 sx_dprintk (SX_DEBUG_INIT, "reset the board...\n"); 2116 sx_dprintk (SX_DEBUG_INIT, "reset the board...\n");
2117 2117
2118 board->flags |= SX_BOARD_PRESENT;
2119
2120 func_exit(); 2118 func_exit();
2121 return 1; 2119 return 1;
2122} 2120}
@@ -2211,8 +2209,6 @@ static int __devinit probe_si (struct sx_board *board)
2211 return 0; 2209 return 0;
2212 sx_dprintk (SX_DEBUG_INIT, "reset the board...\n"); 2210 sx_dprintk (SX_DEBUG_INIT, "reset the board...\n");
2213 2211
2214 board->flags |= SX_BOARD_PRESENT;
2215
2216 func_exit(); 2212 func_exit();
2217 return 1; 2213 return 1;
2218} 2214}
@@ -2396,10 +2392,15 @@ static int __devinit sx_eisa_probe(struct device *dev)
2396 unsigned int i; 2392 unsigned int i;
2397 int retval = -EIO; 2393 int retval = -EIO;
2398 2394
2395 mutex_lock(&sx_boards_lock);
2399 i = sx_find_free_board(); 2396 i = sx_find_free_board();
2400 2397 if (i == SX_NBOARDS) {
2401 if (i == SX_NBOARDS) 2398 mutex_unlock(&sx_boards_lock);
2402 goto err; 2399 goto err;
2400 }
2401 board = &boards[i];
2402 board->flags |= SX_BOARD_PRESENT;
2403 mutex_unlock(&sx_boards_lock);
2403 2404
2404 dev_info(dev, "XIO : Signature found in EISA slot %lu, " 2405 dev_info(dev, "XIO : Signature found in EISA slot %lu, "
2405 "Product %d Rev %d (REPORT THIS TO LKLM)\n", 2406 "Product %d Rev %d (REPORT THIS TO LKLM)\n",
@@ -2407,7 +2408,6 @@ static int __devinit sx_eisa_probe(struct device *dev)
2407 inb(eisa_slot + EISA_VENDOR_ID_OFFSET + 2), 2408 inb(eisa_slot + EISA_VENDOR_ID_OFFSET + 2),
2408 inb(eisa_slot + EISA_VENDOR_ID_OFFSET + 3)); 2409 inb(eisa_slot + EISA_VENDOR_ID_OFFSET + 3));
2409 2410
2410 board = &boards[i];
2411 board->eisa_base = eisa_slot; 2411 board->eisa_base = eisa_slot;
2412 board->flags &= ~SX_BOARD_TYPE; 2412 board->flags &= ~SX_BOARD_TYPE;
2413 board->flags |= SI_EISA_BOARD; 2413 board->flags |= SI_EISA_BOARD;
@@ -2430,6 +2430,7 @@ static int __devinit sx_eisa_probe(struct device *dev)
2430 return 0; 2430 return 0;
2431err_unmap: 2431err_unmap:
2432 iounmap(board->base); 2432 iounmap(board->base);
2433 board->flags &= ~SX_BOARD_PRESENT;
2433err: 2434err:
2434 return retval; 2435 return retval;
2435} 2436}
@@ -2498,16 +2499,19 @@ static int __devinit sx_pci_probe(struct pci_dev *pdev,
2498 unsigned int i; 2499 unsigned int i;
2499 int retval = -EIO; 2500 int retval = -EIO;
2500 2501
2502 mutex_lock(&sx_boards_lock);
2501 i = sx_find_free_board(); 2503 i = sx_find_free_board();
2502 2504 if (i == SX_NBOARDS) {
2503 if (i == SX_NBOARDS) 2505 mutex_unlock(&sx_boards_lock);
2504 goto err; 2506 goto err;
2507 }
2508 board = &boards[i];
2509 board->flags |= SX_BOARD_PRESENT;
2510 mutex_unlock(&sx_boards_lock);
2505 2511
2506 retval = pci_enable_device(pdev); 2512 retval = pci_enable_device(pdev);
2507 if (retval) 2513 if (retval)
2508 goto err; 2514 goto err_flag;
2509
2510 board = &boards[i];
2511 2515
2512 board->flags &= ~SX_BOARD_TYPE; 2516 board->flags &= ~SX_BOARD_TYPE;
2513 board->flags |= (pdev->subsystem_vendor == 0x200) ? SX_PCI_BOARD : 2517 board->flags |= (pdev->subsystem_vendor == 0x200) ? SX_PCI_BOARD :
@@ -2522,7 +2526,7 @@ static int __devinit sx_pci_probe(struct pci_dev *pdev,
2522 board->base = ioremap(board->hw_base, WINDOW_LEN (board)); 2526 board->base = ioremap(board->hw_base, WINDOW_LEN (board));
2523 if (!board->base) { 2527 if (!board->base) {
2524 dev_err(&pdev->dev, "ioremap failed\n"); 2528 dev_err(&pdev->dev, "ioremap failed\n");
2525 goto err; 2529 goto err_flag;
2526 } 2530 }
2527 2531
2528 /* Most of the stuff on the CF board is offset by 0x18000 .... */ 2532 /* Most of the stuff on the CF board is offset by 0x18000 .... */
@@ -2546,6 +2550,8 @@ static int __devinit sx_pci_probe(struct pci_dev *pdev,
2546 return 0; 2550 return 0;
2547err_unmap: 2551err_unmap:
2548 iounmap(board->base2); 2552 iounmap(board->base2);
2553err_flag:
2554 board->flags &= ~SX_BOARD_PRESENT;
2549err: 2555err:
2550 return retval; 2556 return retval;
2551} 2557}
@@ -2611,6 +2617,7 @@ static int __init sx_init(void)
2611 board->irq = sx_irqmask?-1:0; 2617 board->irq = sx_irqmask?-1:0;
2612 2618
2613 if (probe_sx (board)) { 2619 if (probe_sx (board)) {
2620 board->flags |= SX_BOARD_PRESENT;
2614 found++; 2621 found++;
2615 } else { 2622 } else {
2616 iounmap(board->base); 2623 iounmap(board->base);
@@ -2627,6 +2634,7 @@ static int __init sx_init(void)
2627 board->irq = sx_irqmask ?-1:0; 2634 board->irq = sx_irqmask ?-1:0;
2628 2635
2629 if (probe_si (board)) { 2636 if (probe_si (board)) {
2637 board->flags |= SX_BOARD_PRESENT;
2630 found++; 2638 found++;
2631 } else { 2639 } else {
2632 iounmap (board->base); 2640 iounmap (board->base);
@@ -2642,6 +2650,7 @@ static int __init sx_init(void)
2642 board->irq = sx_irqmask ?-1:0; 2650 board->irq = sx_irqmask ?-1:0;
2643 2651
2644 if (probe_si (board)) { 2652 if (probe_si (board)) {
2653 board->flags |= SX_BOARD_PRESENT;
2645 found++; 2654 found++;
2646 } else { 2655 } else {
2647 iounmap (board->base); 2656 iounmap (board->base);