[PATCH] Char: sx, convert to pci probing
Convert old pci code to pci probing. Cc: <R.E.Wolff@BitWizard.nl> 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>
This commit is contained in:
committed by
Linus Torvalds
parent
17c4edf0c8
commit
5572e10323
@@ -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)
|
|||||||
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,22 +2395,112 @@ 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,
|
||||||
|
const struct pci_device_id *ent)
|
||||||
|
{
|
||||||
|
struct sx_board *board;
|
||||||
|
unsigned int i;
|
||||||
|
int retval = -EIO;
|
||||||
|
|
||||||
|
for (i = 0; i < SX_NBOARDS; i++)
|
||||||
|
if (!(boards[i].flags & SX_BOARD_PRESENT))
|
||||||
|
break;
|
||||||
|
|
||||||
|
if (i == SX_NBOARDS)
|
||||||
|
goto err;
|
||||||
|
|
||||||
|
retval = pci_enable_device(pdev);
|
||||||
|
if (retval)
|
||||||
|
goto err;
|
||||||
|
|
||||||
|
board = &boards[i];
|
||||||
|
|
||||||
|
board->flags &= ~SX_BOARD_TYPE;
|
||||||
|
board->flags |= (pdev->subsystem_vendor == 0x200) ? SX_PCI_BOARD :
|
||||||
|
SX_CFPCI_BOARD;
|
||||||
|
|
||||||
|
/* CF boards use base address 3.... */
|
||||||
|
if (IS_CF_BOARD (board))
|
||||||
|
board->hw_base = pci_resource_start(pdev, 3);
|
||||||
|
else
|
||||||
|
board->hw_base = pci_resource_start(pdev, 2);
|
||||||
|
board->base2 =
|
||||||
|
board->base = ioremap(board->hw_base, WINDOW_LEN (board));
|
||||||
|
if (!board->base) {
|
||||||
|
dev_err(&pdev->dev, "ioremap failed\n");
|
||||||
|
goto err;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Most of the stuff on the CF board is offset by 0x18000 .... */
|
||||||
|
if (IS_CF_BOARD (board))
|
||||||
|
board->base += 0x18000;
|
||||||
|
|
||||||
|
board->irq = pdev->irq;
|
||||||
|
|
||||||
|
dev_info(&pdev->dev, "Got a specialix card: %p(%d) %x.\n", board->base,
|
||||||
|
board->irq, board->flags);
|
||||||
|
|
||||||
|
if (!probe_sx(board)) {
|
||||||
|
retval = -EIO;
|
||||||
|
goto err_unmap;
|
||||||
|
}
|
||||||
|
|
||||||
|
fix_sx_pci(pdev, board);
|
||||||
|
|
||||||
|
pci_set_drvdata(pdev, board);
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
err_unmap:
|
||||||
|
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)
|
static int __init sx_init(void)
|
||||||
{
|
{
|
||||||
int i;
|
int retval, i;
|
||||||
int found = 0;
|
int found = 0;
|
||||||
int eisa_slot;
|
int eisa_slot;
|
||||||
struct sx_board *board;
|
struct sx_board *board;
|
||||||
|
|
||||||
#ifdef CONFIG_PCI
|
|
||||||
struct pci_dev *pdev = NULL;
|
|
||||||
unsigned int tint;
|
|
||||||
unsigned short tshort;
|
|
||||||
#endif
|
|
||||||
|
|
||||||
func_enter();
|
func_enter();
|
||||||
sx_dprintk (SX_DEBUG_INIT, "Initing sx module... (sx_debug=%d)\n", sx_debug);
|
sx_dprintk (SX_DEBUG_INIT, "Initing sx module... (sx_debug=%d)\n", sx_debug);
|
||||||
if (abs ((long) (&sx_debug) - sx_debug) < 0x10000) {
|
if (abs ((long) (&sx_debug) - sx_debug) < 0x10000) {
|
||||||
@@ -2434,65 +2515,6 @@ static int __init sx_init(void)
|
|||||||
return -EIO;
|
return -EIO;
|
||||||
}
|
}
|
||||||
|
|
||||||
#ifdef CONFIG_PCI
|
|
||||||
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 |= (tshort == 0x200)?SX_PCI_BOARD:
|
|
||||||
SX_CFPCI_BOARD;
|
|
||||||
|
|
||||||
/* CF boards use base address 3.... */
|
|
||||||
if (IS_CF_BOARD (board))
|
|
||||||
board->hw_base = pci_resource_start (pdev, 3);
|
|
||||||
else
|
|
||||||
board->hw_base = pci_resource_start (pdev, 2);
|
|
||||||
board->base2 =
|
|
||||||
board->base = ioremap(board->hw_base, WINDOW_LEN (board));
|
|
||||||
if (!board->base) {
|
|
||||||
printk(KERN_ERR "ioremap failed\n");
|
|
||||||
/* XXX handle error */
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Most of the stuff on the CF board is offset by
|
|
||||||
0x18000 .... */
|
|
||||||
if (IS_CF_BOARD (board)) board->base += 0x18000;
|
|
||||||
|
|
||||||
board->irq = pdev->irq;
|
|
||||||
|
|
||||||
sx_dprintk (SX_DEBUG_PROBE, "Got a specialix card: %x/%p(%d) %x.\n",
|
|
||||||
tint, boards[found].base, board->irq, board->flags);
|
|
||||||
|
|
||||||
if (probe_sx (board)) {
|
|
||||||
found++;
|
|
||||||
fix_sx_pci (pdev, board);
|
|
||||||
} else
|
|
||||||
iounmap(board->base2);
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
|
|
||||||
for (i=0;i<NR_SX_ADDRS;i++) {
|
for (i=0;i<NR_SX_ADDRS;i++) {
|
||||||
board = &boards[found];
|
board = &boards[found];
|
||||||
board->hw_base = sx_probe_addrs[i];
|
board->hw_base = sx_probe_addrs[i];
|
||||||
@@ -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)
|
|||||||
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) {
|
||||||
|
Reference in New Issue
Block a user