aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/char/sx.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/char/sx.c')
-rw-r--r--drivers/char/sx.c164
1 files changed, 117 insertions, 47 deletions
diff --git a/drivers/char/sx.c b/drivers/char/sx.c
index a85f5eb85585..ca3145a440b7 100644
--- a/drivers/char/sx.c
+++ b/drivers/char/sx.c
@@ -214,6 +214,7 @@
214#include <linux/fcntl.h> 214#include <linux/fcntl.h>
215#include <linux/major.h> 215#include <linux/major.h>
216#include <linux/delay.h> 216#include <linux/delay.h>
217#include <linux/eisa.h>
217#include <linux/pci.h> 218#include <linux/pci.h>
218#include <linux/slab.h> 219#include <linux/slab.h>
219#include <linux/init.h> 220#include <linux/init.h>
@@ -2345,6 +2346,17 @@ static int sx_init_portstructs (int nboards, int nports)
2345 return 0; 2346 return 0;
2346} 2347}
2347 2348
2349static unsigned int sx_find_free_board(void)
2350{
2351 unsigned int i;
2352
2353 for (i = 0; i < SX_NBOARDS; i++)
2354 if (!(boards[i].flags & SX_BOARD_PRESENT))
2355 break;
2356
2357 return i;
2358}
2359
2348static void __exit sx_release_drivers(void) 2360static void __exit sx_release_drivers(void)
2349{ 2361{
2350 func_enter(); 2362 func_enter();
@@ -2353,6 +2365,97 @@ static void __exit sx_release_drivers(void)
2353 func_exit(); 2365 func_exit();
2354} 2366}
2355 2367
2368static void __devexit sx_remove_card(struct sx_board *board)
2369{
2370 if (board->flags & SX_BOARD_INITIALIZED) {
2371 /* The board should stop messing with us. (actually I mean the
2372 interrupt) */
2373 sx_reset(board);
2374 if ((board->irq) && (board->flags & SX_IRQ_ALLOCATED))
2375 free_irq(board->irq, board);
2376
2377 /* It is safe/allowed to del_timer a non-active timer */
2378 del_timer(&board->timer);
2379 iounmap(board->base);
2380
2381 board->flags &= ~(SX_BOARD_INITIALIZED|SX_BOARD_PRESENT);
2382 }
2383}
2384
2385#ifdef CONFIG_EISA
2386
2387static int __devinit sx_eisa_probe(struct device *dev)
2388{
2389 struct eisa_device *edev = to_eisa_device(dev);
2390 struct sx_board *board;
2391 unsigned long eisa_slot = edev->base_addr;
2392 unsigned int i;
2393 int retval = -EIO;
2394
2395 i = sx_find_free_board();
2396
2397 if (i == SX_NBOARDS)
2398 goto err;
2399
2400 dev_info(dev, "XIO : Signature found in EISA slot %lu, "
2401 "Product %d Rev %d (REPORT THIS TO LKLM)\n",
2402 eisa_slot >> 12,
2403 inb(eisa_slot + EISA_VENDOR_ID_OFFSET + 2),
2404 inb(eisa_slot + EISA_VENDOR_ID_OFFSET + 3));
2405
2406 board = &boards[i];
2407 board->eisa_base = eisa_slot;
2408 board->flags &= ~SX_BOARD_TYPE;
2409 board->flags |= SI_EISA_BOARD;
2410
2411 board->hw_base = ((inb(eisa_slot + 0xc01) << 8) +
2412 inb(eisa_slot + 0xc00)) << 16;
2413 board->base2 =
2414 board->base = ioremap(board->hw_base, SI2_EISA_WINDOW_LEN);
2415
2416 sx_dprintk(SX_DEBUG_PROBE, "IO hw_base address: %lx\n", board->hw_base);
2417 sx_dprintk(SX_DEBUG_PROBE, "base: %p\n", board->base);
2418 board->irq = inb(eisa_slot + 0xc02) >> 4;
2419 sx_dprintk(SX_DEBUG_PROBE, "IRQ: %d\n", board->irq);
2420
2421 if (!probe_si(board))
2422 goto err_unmap;
2423
2424 dev_set_drvdata(dev, board);
2425
2426 return 0;
2427err_unmap:
2428 iounmap(board->base);
2429err:
2430 return retval;
2431}
2432
2433static int __devexit sx_eisa_remove(struct device *dev)
2434{
2435 struct sx_board *board = dev_get_drvdata(dev);
2436
2437 sx_remove_card(board);
2438
2439 return 0;
2440}
2441
2442static struct eisa_device_id sx_eisa_tbl[] = {
2443 { "SLX" },
2444 { "" }
2445};
2446MODULE_DEVICE_TABLE(eisa, sx_eisa_tbl);
2447
2448static struct eisa_driver sx_eisadriver = {
2449 .id_table = sx_eisa_tbl,
2450 .driver = {
2451 .name = "sx",
2452 .probe = sx_eisa_probe,
2453 .remove = __devexit_p(sx_eisa_remove),
2454 }
2455};
2456
2457#endif
2458
2356 /******************************************************** 2459 /********************************************************
2357 * Setting bit 17 in the CNTRL register of the PLX 9050 * 2460 * Setting bit 17 in the CNTRL register of the PLX 9050 *
2358 * chip forces a retry on writes while a read is pending.* 2461 * chip forces a retry on writes while a read is pending.*
@@ -2391,9 +2494,7 @@ static int __devinit sx_pci_probe(struct pci_dev *pdev,
2391 unsigned int i; 2494 unsigned int i;
2392 int retval = -EIO; 2495 int retval = -EIO;
2393 2496
2394 for (i = 0; i < SX_NBOARDS; i++) 2497 i = sx_find_free_board();
2395 if (!(boards[i].flags & SX_BOARD_PRESENT))
2396 break;
2397 2498
2398 if (i == SX_NBOARDS) 2499 if (i == SX_NBOARDS)
2399 goto err; 2500 goto err;
@@ -2449,19 +2550,7 @@ static void __devexit sx_pci_remove(struct pci_dev *pdev)
2449{ 2550{
2450 struct sx_board *board = pci_get_drvdata(pdev); 2551 struct sx_board *board = pci_get_drvdata(pdev);
2451 2552
2452 if (board->flags & SX_BOARD_INITIALIZED) { 2553 sx_remove_card(board);
2453 /* The board should stop messing with us. (actually I mean the
2454 interrupt) */
2455 sx_reset(board);
2456 if ((board->irq) && (board->flags & SX_IRQ_ALLOCATED))
2457 free_irq(board->irq, board);
2458
2459 /* It is safe/allowed to del_timer a non-active timer */
2460 del_timer(&board->timer);
2461 iounmap(board->base);
2462
2463 board->flags &= ~(SX_BOARD_INITIALIZED|SX_BOARD_PRESENT);
2464 }
2465} 2554}
2466 2555
2467/* Specialix has a whole bunch of cards with 0x2000 as the device ID. They say 2556/* Specialix has a whole bunch of cards with 0x2000 as the device ID. They say
@@ -2484,9 +2573,11 @@ static struct pci_driver sx_pcidriver = {
2484 2573
2485static int __init sx_init(void) 2574static int __init sx_init(void)
2486{ 2575{
2576#ifdef CONFIG_EISA
2577 int retval1;
2578#endif
2487 int retval, i; 2579 int retval, i;
2488 int found = 0; 2580 int found = 0;
2489 int eisa_slot;
2490 struct sx_board *board; 2581 struct sx_board *board;
2491 2582
2492 func_enter(); 2583 func_enter();
@@ -2549,42 +2640,18 @@ static int __init sx_init(void)
2549 iounmap (board->base); 2640 iounmap (board->base);
2550 } 2641 }
2551 } 2642 }
2552 2643#ifdef CONFIG_EISA
2553 sx_dprintk(SX_DEBUG_PROBE, "Probing for EISA cards\n"); 2644 retval1 = eisa_driver_register(&sx_eisadriver);
2554 for(eisa_slot=0x1000; eisa_slot<0x10000; eisa_slot+=0x1000) 2645#endif
2555 {
2556 if((inb(eisa_slot+0xc80)==0x4d) &&
2557 (inb(eisa_slot+0xc81)==0x98))
2558 {
2559 sx_dprintk(SX_DEBUG_PROBE, "%s : Signature found in EISA slot %d, Product %d Rev %d\n",
2560 "XIO", (eisa_slot>>12), inb(eisa_slot+0xc82), inb(eisa_slot+0xc83));
2561
2562 board = &boards[found];
2563 board->eisa_base = eisa_slot;
2564 board->flags &= ~SX_BOARD_TYPE;
2565 board->flags |= SI_EISA_BOARD;
2566
2567 board->hw_base = (((inb(0xc01+eisa_slot) << 8) + inb(0xc00+eisa_slot)) << 16);
2568 board->base2 =
2569 board->base = ioremap(board->hw_base, SI2_EISA_WINDOW_LEN);
2570
2571 sx_dprintk(SX_DEBUG_PROBE, "IO hw_base address: %lx\n", board->hw_base);
2572 sx_dprintk(SX_DEBUG_PROBE, "base: %p\n", board->base);
2573 board->irq = inb(board->eisa_base+0xc02)>>4;
2574 sx_dprintk(SX_DEBUG_PROBE, "IRQ: %d\n", board->irq);
2575
2576 probe_si(board);
2577
2578 found++;
2579 }
2580 }
2581
2582 retval = pci_register_driver(&sx_pcidriver); 2646 retval = pci_register_driver(&sx_pcidriver);
2583 2647
2584 if (found) { 2648 if (found) {
2585 printk (KERN_INFO "sx: total of %d boards detected.\n", found); 2649 printk (KERN_INFO "sx: total of %d boards detected.\n", found);
2586 retval = 0; 2650 retval = 0;
2587 } else if (retval) { 2651 } else if (retval) {
2652#ifdef CONFIG_EISA
2653 if (retval1)
2654#endif
2588 misc_deregister(&sx_fw_device); 2655 misc_deregister(&sx_fw_device);
2589 } 2656 }
2590 2657
@@ -2599,6 +2666,9 @@ static void __exit sx_exit (void)
2599 struct sx_board *board; 2666 struct sx_board *board;
2600 2667
2601 func_enter(); 2668 func_enter();
2669#ifdef CONFIG_EISA
2670 eisa_driver_unregister(&sx_eisadriver);
2671#endif
2602 pci_unregister_driver(&sx_pcidriver); 2672 pci_unregister_driver(&sx_pcidriver);
2603 for (i = 0; i < SX_NBOARDS; i++) { 2673 for (i = 0; i < SX_NBOARDS; i++) {
2604 board = &boards[i]; 2674 board = &boards[i];