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.c183
1 files changed, 105 insertions, 78 deletions
diff --git a/drivers/char/sx.c b/drivers/char/sx.c
index cf08be76b8a7..5e01337e6107 100644
--- a/drivers/char/sx.c
+++ b/drivers/char/sx.c
@@ -246,14 +246,6 @@
246#define PCI_DEVICE_ID_SPECIALIX_SX_XIO_IO8 0x2000 246#define PCI_DEVICE_ID_SPECIALIX_SX_XIO_IO8 0x2000
247#endif 247#endif
248 248
249#ifdef CONFIG_PCI
250static struct pci_device_id sx_pci_tbl[] = {
251 { PCI_VENDOR_ID_SPECIALIX, PCI_DEVICE_ID_SPECIALIX_SX_XIO_IO8, PCI_ANY_ID, PCI_ANY_ID },
252 { 0 }
253};
254MODULE_DEVICE_TABLE(pci, sx_pci_tbl);
255#endif /* CONFIG_PCI */
256
257/* Configurable options: 249/* Configurable options:
258 (Don't be too sure that it'll work if you toggle them) */ 250 (Don't be too sure that it'll work if you toggle them) */
259 251
@@ -2373,7 +2365,6 @@ static void __exit sx_release_drivers(void)
2373 func_exit(); 2365 func_exit();
2374} 2366}
2375 2367
2376#ifdef CONFIG_PCI
2377 /******************************************************** 2368 /********************************************************
2378 * Setting bit 17 in the CNTRL register of the PLX 9050 * 2369 * Setting bit 17 in the CNTRL register of the PLX 9050 *
2379 * chip forces a retry on writes while a read is pending.* 2370 * chip forces a retry on writes while a read is pending.*
@@ -2404,22 +2395,112 @@ static void fix_sx_pci (struct pci_dev *pdev, struct sx_board *board)
2404 } 2395 }
2405 iounmap(rebase); 2396 iounmap(rebase);
2406} 2397}
2407#endif
2408 2398
2399static int __devinit sx_pci_probe(struct pci_dev *pdev,
2400 const struct pci_device_id *ent)
2401{
2402 struct sx_board *board;
2403 unsigned int i;
2404 int retval = -EIO;
2405
2406 for (i = 0; i < SX_NBOARDS; i++)
2407 if (!(boards[i].flags & SX_BOARD_PRESENT))
2408 break;
2409
2410 if (i == SX_NBOARDS)
2411 goto err;
2412
2413 retval = pci_enable_device(pdev);
2414 if (retval)
2415 goto err;
2416
2417 board = &boards[i];
2418
2419 board->flags &= ~SX_BOARD_TYPE;
2420 board->flags |= (pdev->subsystem_vendor == 0x200) ? SX_PCI_BOARD :
2421 SX_CFPCI_BOARD;
2422
2423 /* CF boards use base address 3.... */
2424 if (IS_CF_BOARD (board))
2425 board->hw_base = pci_resource_start(pdev, 3);
2426 else
2427 board->hw_base = pci_resource_start(pdev, 2);
2428 board->base2 =
2429 board->base = ioremap(board->hw_base, WINDOW_LEN (board));
2430 if (!board->base) {
2431 dev_err(&pdev->dev, "ioremap failed\n");
2432 goto err;
2433 }
2434
2435 /* Most of the stuff on the CF board is offset by 0x18000 .... */
2436 if (IS_CF_BOARD (board))
2437 board->base += 0x18000;
2438
2439 board->irq = pdev->irq;
2440
2441 dev_info(&pdev->dev, "Got a specialix card: %p(%d) %x.\n", board->base,
2442 board->irq, board->flags);
2443
2444 if (!probe_sx(board)) {
2445 retval = -EIO;
2446 goto err_unmap;
2447 }
2448
2449 fix_sx_pci(pdev, board);
2450
2451 pci_set_drvdata(pdev, board);
2452
2453 return 0;
2454err_unmap:
2455 iounmap(board->base2);
2456err:
2457 return retval;
2458}
2459
2460static void __devexit sx_pci_remove(struct pci_dev *pdev)
2461{
2462 struct sx_board *board = pci_get_drvdata(pdev);
2463
2464 if (board->flags & SX_BOARD_INITIALIZED) {
2465 /* The board should stop messing with us. (actually I mean the
2466 interrupt) */
2467 sx_reset(board);
2468 if ((board->irq) && (board->flags & SX_IRQ_ALLOCATED))
2469 free_irq(board->irq, board);
2470
2471 /* It is safe/allowed to del_timer a non-active timer */
2472 del_timer(&board->timer);
2473 iounmap(board->base);
2474
2475 board->flags &= ~(SX_BOARD_INITIALIZED|SX_BOARD_PRESENT);
2476 }
2477}
2478
2479/* Specialix has a whole bunch of cards with 0x2000 as the device ID. They say
2480 its because the standard requires it. So check for SUBVENDOR_ID. */
2481static struct pci_device_id sx_pci_tbl[] = {
2482 { PCI_VENDOR_ID_SPECIALIX, PCI_DEVICE_ID_SPECIALIX_SX_XIO_IO8,
2483 .subvendor = 0x0200, .subdevice = PCI_ANY_ID },
2484 { PCI_VENDOR_ID_SPECIALIX, PCI_DEVICE_ID_SPECIALIX_SX_XIO_IO8,
2485 .subvendor = 0x0300, .subdevice = PCI_ANY_ID },
2486 { 0 }
2487};
2488MODULE_DEVICE_TABLE(pci, sx_pci_tbl);
2489
2490static struct pci_driver sx_pcidriver = {
2491 .name = "sx",
2492 .id_table = sx_pci_tbl,
2493 .probe = sx_pci_probe,
2494 .remove = __devexit_p(sx_pci_remove)
2495};
2409 2496
2410static int __init sx_init(void) 2497static int __init sx_init(void)
2411{ 2498{
2412 int i; 2499 int retval, i;
2413 int found = 0; 2500 int found = 0;
2414 int eisa_slot; 2501 int eisa_slot;
2415 struct sx_board *board; 2502 struct sx_board *board;
2416 2503
2417#ifdef CONFIG_PCI
2418 struct pci_dev *pdev = NULL;
2419 unsigned int tint;
2420 unsigned short tshort;
2421#endif
2422
2423 func_enter(); 2504 func_enter();
2424 sx_dprintk (SX_DEBUG_INIT, "Initing sx module... (sx_debug=%d)\n", sx_debug); 2505 sx_dprintk (SX_DEBUG_INIT, "Initing sx module... (sx_debug=%d)\n", sx_debug);
2425 if (abs ((long) (&sx_debug) - sx_debug) < 0x10000) { 2506 if (abs ((long) (&sx_debug) - sx_debug) < 0x10000) {
@@ -2434,65 +2515,6 @@ static int __init sx_init(void)
2434 return -EIO; 2515 return -EIO;
2435 } 2516 }
2436 2517
2437#ifdef CONFIG_PCI
2438 while ((pdev = pci_find_device (PCI_VENDOR_ID_SPECIALIX,
2439 PCI_DEVICE_ID_SPECIALIX_SX_XIO_IO8,
2440 pdev))) {
2441 if (pci_enable_device(pdev))
2442 continue;
2443
2444 /* Specialix has a whole bunch of cards with
2445 0x2000 as the device ID. They say its because
2446 the standard requires it. Stupid standard. */
2447 /* It seems that reading a word doesn't work reliably on 2.0.
2448 Also, reading a non-aligned dword doesn't work. So we read the
2449 whole dword at 0x2c and extract the word at 0x2e (SUBSYSTEM_ID)
2450 ourselves */
2451 /* I don't know why the define doesn't work, constant 0x2c does --REW */
2452 pci_read_config_dword (pdev, 0x2c, &tint);
2453 tshort = (tint >> 16) & 0xffff;
2454 sx_dprintk (SX_DEBUG_PROBE, "Got a specialix card: %x.\n", tint);
2455 /* sx_dprintk (SX_DEBUG_PROBE, "pdev = %d/%d (%x)\n", pdev, tint); */
2456 if ((tshort != 0x0200) && (tshort != 0x0300)) {
2457 sx_dprintk (SX_DEBUG_PROBE, "But it's not an SX card (%d)...\n",
2458 tshort);
2459 continue;
2460 }
2461 board = &boards[found];
2462
2463 board->flags &= ~SX_BOARD_TYPE;
2464 board->flags |= (tshort == 0x200)?SX_PCI_BOARD:
2465 SX_CFPCI_BOARD;
2466
2467 /* CF boards use base address 3.... */
2468 if (IS_CF_BOARD (board))
2469 board->hw_base = pci_resource_start (pdev, 3);
2470 else
2471 board->hw_base = pci_resource_start (pdev, 2);
2472 board->base2 =
2473 board->base = ioremap(board->hw_base, WINDOW_LEN (board));
2474 if (!board->base) {
2475 printk(KERN_ERR "ioremap failed\n");
2476 /* XXX handle error */
2477 }
2478
2479 /* Most of the stuff on the CF board is offset by
2480 0x18000 .... */
2481 if (IS_CF_BOARD (board)) board->base += 0x18000;
2482
2483 board->irq = pdev->irq;
2484
2485 sx_dprintk (SX_DEBUG_PROBE, "Got a specialix card: %x/%p(%d) %x.\n",
2486 tint, boards[found].base, board->irq, board->flags);
2487
2488 if (probe_sx (board)) {
2489 found++;
2490 fix_sx_pci (pdev, board);
2491 } else
2492 iounmap(board->base2);
2493 }
2494#endif
2495
2496 for (i=0;i<NR_SX_ADDRS;i++) { 2518 for (i=0;i<NR_SX_ADDRS;i++) {
2497 board = &boards[found]; 2519 board = &boards[found];
2498 board->hw_base = sx_probe_addrs[i]; 2520 board->hw_base = sx_probe_addrs[i];
@@ -2568,14 +2590,18 @@ static int __init sx_init(void)
2568 found++; 2590 found++;
2569 } 2591 }
2570 } 2592 }
2593
2594 retval = pci_register_driver(&sx_pcidriver);
2595
2571 if (found) { 2596 if (found) {
2572 printk (KERN_INFO "sx: total of %d boards detected.\n", found); 2597 printk (KERN_INFO "sx: total of %d boards detected.\n", found);
2573 } else { 2598 retval = 0;
2599 } else if (retval) {
2574 misc_deregister(&sx_fw_device); 2600 misc_deregister(&sx_fw_device);
2575 } 2601 }
2576 2602
2577 func_exit(); 2603 func_exit();
2578 return found?0:-EIO; 2604 return retval;
2579} 2605}
2580 2606
2581 2607
@@ -2585,6 +2611,7 @@ static void __exit sx_exit (void)
2585 struct sx_board *board; 2611 struct sx_board *board;
2586 2612
2587 func_enter(); 2613 func_enter();
2614 pci_unregister_driver(&sx_pcidriver);
2588 for (i = 0; i < SX_NBOARDS; i++) { 2615 for (i = 0; i < SX_NBOARDS; i++) {
2589 board = &boards[i]; 2616 board = &boards[i];
2590 if (board->flags & SX_BOARD_INITIALIZED) { 2617 if (board->flags & SX_BOARD_INITIALIZED) {