Commit 5572e103 authored by Jiri Slaby's avatar Jiri Slaby Committed by Linus Torvalds

[PATCH] Char: sx, convert to pci probing

Convert old pci code to pci probing.

Cc: <R.E.Wolff@BitWizard.nl>
Signed-off-by: default avatarJiri Slaby <jirislaby@gmail.com>
Cc: Alan Cox <alan@lxorguk.ukuu.org.uk>
Signed-off-by: default avatarAndrew Morton <akpm@osdl.org>
Signed-off-by: default avatarLinus Torvalds <torvalds@osdl.org>
parent 17c4edf0
...@@ -246,14 +246,6 @@ ...@@ -246,14 +246,6 @@
#define PCI_DEVICE_ID_SPECIALIX_SX_XIO_IO8 0x2000 #define PCI_DEVICE_ID_SPECIALIX_SX_XIO_IO8 0x2000
#endif #endif
#ifdef CONFIG_PCI
static struct pci_device_id sx_pci_tbl[] = {
{ PCI_VENDOR_ID_SPECIALIX, PCI_DEVICE_ID_SPECIALIX_SX_XIO_IO8, PCI_ANY_ID, PCI_ANY_ID },
{ 0 }
};
MODULE_DEVICE_TABLE(pci, sx_pci_tbl);
#endif /* CONFIG_PCI */
/* Configurable options: /* Configurable options:
(Don't be too sure that it'll work if you toggle them) */ (Don't be too sure that it'll work if you toggle them) */
...@@ -2373,7 +2365,6 @@ static void __exit sx_release_drivers(void) ...@@ -2373,7 +2365,6 @@ static void __exit sx_release_drivers(void)
func_exit(); func_exit();
} }
#ifdef CONFIG_PCI
/******************************************************** /********************************************************
* Setting bit 17 in the CNTRL register of the PLX 9050 * * Setting bit 17 in the CNTRL register of the PLX 9050 *
* chip forces a retry on writes while a read is pending.* * chip forces a retry on writes while a read is pending.*
...@@ -2404,94 +2395,125 @@ static void fix_sx_pci (struct pci_dev *pdev, struct sx_board *board) ...@@ -2404,94 +2395,125 @@ static void fix_sx_pci (struct pci_dev *pdev, struct sx_board *board)
} }
iounmap(rebase); iounmap(rebase);
} }
#endif
static int __devinit sx_pci_probe(struct pci_dev *pdev,
static int __init sx_init(void) const struct pci_device_id *ent)
{ {
int i;
int found = 0;
int eisa_slot;
struct sx_board *board; struct sx_board *board;
unsigned int i;
int retval = -EIO;
#ifdef CONFIG_PCI for (i = 0; i < SX_NBOARDS; i++)
struct pci_dev *pdev = NULL; if (!(boards[i].flags & SX_BOARD_PRESENT))
unsigned int tint; break;
unsigned short tshort;
#endif
func_enter(); if (i == SX_NBOARDS)
sx_dprintk (SX_DEBUG_INIT, "Initing sx module... (sx_debug=%d)\n", sx_debug); goto err;
if (abs ((long) (&sx_debug) - sx_debug) < 0x10000) {
printk (KERN_WARNING "sx: sx_debug is an address, instead of a value. "
"Assuming -1.\n");
printk ("(%p)\n", &sx_debug);
sx_debug=-1;
}
if (misc_register(&sx_fw_device) < 0) { retval = pci_enable_device(pdev);
printk(KERN_ERR "SX: Unable to register firmware loader driver.\n"); if (retval)
return -EIO; goto err;
}
#ifdef CONFIG_PCI board = &boards[i];
while ((pdev = pci_find_device (PCI_VENDOR_ID_SPECIALIX,
PCI_DEVICE_ID_SPECIALIX_SX_XIO_IO8,
pdev))) {
if (pci_enable_device(pdev))
continue;
/* Specialix has a whole bunch of cards with
0x2000 as the device ID. They say its because
the standard requires it. Stupid standard. */
/* It seems that reading a word doesn't work reliably on 2.0.
Also, reading a non-aligned dword doesn't work. So we read the
whole dword at 0x2c and extract the word at 0x2e (SUBSYSTEM_ID)
ourselves */
/* I don't know why the define doesn't work, constant 0x2c does --REW */
pci_read_config_dword (pdev, 0x2c, &tint);
tshort = (tint >> 16) & 0xffff;
sx_dprintk (SX_DEBUG_PROBE, "Got a specialix card: %x.\n", tint);
/* sx_dprintk (SX_DEBUG_PROBE, "pdev = %d/%d (%x)\n", pdev, tint); */
if ((tshort != 0x0200) && (tshort != 0x0300)) {
sx_dprintk (SX_DEBUG_PROBE, "But it's not an SX card (%d)...\n",
tshort);
continue;
}
board = &boards[found];
board->flags &= ~SX_BOARD_TYPE; board->flags &= ~SX_BOARD_TYPE;
board->flags |= (tshort == 0x200)?SX_PCI_BOARD: board->flags |= (pdev->subsystem_vendor == 0x200) ? SX_PCI_BOARD :
SX_CFPCI_BOARD; SX_CFPCI_BOARD;
/* CF boards use base address 3.... */ /* CF boards use base address 3.... */
if (IS_CF_BOARD (board)) if (IS_CF_BOARD (board))
board->hw_base = pci_resource_start (pdev, 3); board->hw_base = pci_resource_start(pdev, 3);
else else
board->hw_base = pci_resource_start (pdev, 2); board->hw_base = pci_resource_start(pdev, 2);
board->base2 = board->base2 =
board->base = ioremap(board->hw_base, WINDOW_LEN (board)); board->base = ioremap(board->hw_base, WINDOW_LEN (board));
if (!board->base) { if (!board->base) {
printk(KERN_ERR "ioremap failed\n"); dev_err(&pdev->dev, "ioremap failed\n");
/* XXX handle error */ goto err;
} }
/* Most of the stuff on the CF board is offset by /* Most of the stuff on the CF board is offset by 0x18000 .... */
0x18000 .... */ if (IS_CF_BOARD (board))
if (IS_CF_BOARD (board)) board->base += 0x18000; board->base += 0x18000;
board->irq = pdev->irq; board->irq = pdev->irq;
sx_dprintk (SX_DEBUG_PROBE, "Got a specialix card: %x/%p(%d) %x.\n", dev_info(&pdev->dev, "Got a specialix card: %p(%d) %x.\n", board->base,
tint, boards[found].base, board->irq, board->flags); board->irq, board->flags);
if (probe_sx (board)) { if (!probe_sx(board)) {
found++; retval = -EIO;
fix_sx_pci (pdev, board); goto err_unmap;
} else }
fix_sx_pci(pdev, board);
pci_set_drvdata(pdev, board);
return 0;
err_unmap:
iounmap(board->base2); iounmap(board->base2);
err:
return retval;
}
static void __devexit sx_pci_remove(struct pci_dev *pdev)
{
struct sx_board *board = pci_get_drvdata(pdev);
if (board->flags & SX_BOARD_INITIALIZED) {
/* The board should stop messing with us. (actually I mean the
interrupt) */
sx_reset(board);
if ((board->irq) && (board->flags & SX_IRQ_ALLOCATED))
free_irq(board->irq, board);
/* It is safe/allowed to del_timer a non-active timer */
del_timer(&board->timer);
iounmap(board->base);
board->flags &= ~(SX_BOARD_INITIALIZED|SX_BOARD_PRESENT);
}
}
/* Specialix has a whole bunch of cards with 0x2000 as the device ID. They say
its because the standard requires it. So check for SUBVENDOR_ID. */
static struct pci_device_id sx_pci_tbl[] = {
{ PCI_VENDOR_ID_SPECIALIX, PCI_DEVICE_ID_SPECIALIX_SX_XIO_IO8,
.subvendor = 0x0200, .subdevice = PCI_ANY_ID },
{ PCI_VENDOR_ID_SPECIALIX, PCI_DEVICE_ID_SPECIALIX_SX_XIO_IO8,
.subvendor = 0x0300, .subdevice = PCI_ANY_ID },
{ 0 }
};
MODULE_DEVICE_TABLE(pci, sx_pci_tbl);
static struct pci_driver sx_pcidriver = {
.name = "sx",
.id_table = sx_pci_tbl,
.probe = sx_pci_probe,
.remove = __devexit_p(sx_pci_remove)
};
static int __init sx_init(void)
{
int retval, i;
int found = 0;
int eisa_slot;
struct sx_board *board;
func_enter();
sx_dprintk (SX_DEBUG_INIT, "Initing sx module... (sx_debug=%d)\n", sx_debug);
if (abs ((long) (&sx_debug) - sx_debug) < 0x10000) {
printk (KERN_WARNING "sx: sx_debug is an address, instead of a value. "
"Assuming -1.\n");
printk ("(%p)\n", &sx_debug);
sx_debug=-1;
}
if (misc_register(&sx_fw_device) < 0) {
printk(KERN_ERR "SX: Unable to register firmware loader driver.\n");
return -EIO;
} }
#endif
for (i=0;i<NR_SX_ADDRS;i++) { for (i=0;i<NR_SX_ADDRS;i++) {
board = &boards[found]; board = &boards[found];
...@@ -2568,14 +2590,18 @@ static int __init sx_init(void) ...@@ -2568,14 +2590,18 @@ static int __init sx_init(void)
found++; found++;
} }
} }
retval = pci_register_driver(&sx_pcidriver);
if (found) { if (found) {
printk (KERN_INFO "sx: total of %d boards detected.\n", found); printk (KERN_INFO "sx: total of %d boards detected.\n", found);
} else { retval = 0;
} else if (retval) {
misc_deregister(&sx_fw_device); misc_deregister(&sx_fw_device);
} }
func_exit(); func_exit();
return found?0:-EIO; return retval;
} }
...@@ -2585,6 +2611,7 @@ static void __exit sx_exit (void) ...@@ -2585,6 +2611,7 @@ static void __exit sx_exit (void)
struct sx_board *board; struct sx_board *board;
func_enter(); func_enter();
pci_unregister_driver(&sx_pcidriver);
for (i = 0; i < SX_NBOARDS; i++) { for (i = 0; i < SX_NBOARDS; i++) {
board = &boards[i]; board = &boards[i];
if (board->flags & SX_BOARD_INITIALIZED) { if (board->flags & SX_BOARD_INITIALIZED) {
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment