11da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds/* $Id: b1isa.c,v 1.1.2.3 2004/02/10 01:07:12 keil Exp $ 2475be4d85a274d0961593db41cf85689db1d583cJoe Perches * 31da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * Module for AVM B1 ISA-card. 4475be4d85a274d0961593db41cf85689db1d583cJoe Perches * 51da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * Copyright 1999 by Carsten Paeth <calle@calle.de> 6475be4d85a274d0961593db41cf85689db1d583cJoe Perches * 71da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * This software may be used and distributed according to the terms 81da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * of the GNU General Public License, incorporated herein by reference. 91da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * 101da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds */ 111da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 121da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds#include <linux/module.h> 131da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds#include <linux/kernel.h> 141da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds#include <linux/skbuff.h> 151da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds#include <linux/delay.h> 161da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds#include <linux/mm.h> 171da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds#include <linux/interrupt.h> 181da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds#include <linux/ioport.h> 191da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds#include <linux/capi.h> 201da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds#include <linux/init.h> 211da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds#include <linux/pci.h> 221da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds#include <asm/io.h> 231da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds#include <linux/isdn/capicmd.h> 241da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds#include <linux/isdn/capiutil.h> 251da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds#include <linux/isdn/capilli.h> 261da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds#include "avmcard.h" 271da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 281da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds/* ------------------------------------------------------------- */ 291da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 301da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsstatic char *revision = "$Revision: 1.1.2.3 $"; 311da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 321da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds/* ------------------------------------------------------------- */ 331da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 341da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus TorvaldsMODULE_DESCRIPTION("CAPI4Linux: Driver for AVM B1 ISA card"); 351da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus TorvaldsMODULE_AUTHOR("Carsten Paeth"); 361da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus TorvaldsMODULE_LICENSE("GPL"); 371da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 381da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds/* ------------------------------------------------------------- */ 391da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 401da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsstatic void b1isa_remove(struct pci_dev *pdev) 411da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds{ 421da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds avmctrl_info *cinfo = pci_get_drvdata(pdev); 431da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds avmcard *card; 441da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 451da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds if (!cinfo) 461da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds return; 471da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 481da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds card = cinfo->card; 491da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 501da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds b1_reset(card->port); 511da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds b1_reset(card->port); 521da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 531da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds detach_capi_ctr(&cinfo->capi_ctrl); 541da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds free_irq(card->irq, card); 551da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds release_region(card->port, AVMB1_PORTLEN); 561da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds b1_free_card(card); 571da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds} 581da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 591da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds/* ------------------------------------------------------------- */ 601da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 611da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsstatic char *b1isa_procinfo(struct capi_ctr *ctrl); 621da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 631da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsstatic int b1isa_probe(struct pci_dev *pdev) 641da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds{ 651da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds avmctrl_info *cinfo; 661da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds avmcard *card; 671da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds int retval; 681da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 691da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds card = b1_alloc_card(1); 701da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds if (!card) { 711da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds printk(KERN_WARNING "b1isa: no memory.\n"); 721da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds retval = -ENOMEM; 731da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds goto err; 741da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds } 751da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 761da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds cinfo = card->ctrlinfo; 771da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 781da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds card->port = pci_resource_start(pdev, 0); 791da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds card->irq = pdev->irq; 801da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds card->cardtype = avm_b1isa; 811da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds sprintf(card->name, "b1isa-%x", card->port); 821da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 83475be4d85a274d0961593db41cf85689db1d583cJoe Perches if (card->port != 0x150 && card->port != 0x250 841da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds && card->port != 0x300 && card->port != 0x340) { 851da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds printk(KERN_WARNING "b1isa: invalid port 0x%x.\n", card->port); 861da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds retval = -EINVAL; 871da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds goto err_free; 881da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds } 891da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds if (b1_irq_table[card->irq & 0xf] == 0) { 901da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds printk(KERN_WARNING "b1isa: irq %d not valid.\n", card->irq); 911da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds retval = -EINVAL; 921da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds goto err_free; 931da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds } 941da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds if (!request_region(card->port, AVMB1_PORTLEN, card->name)) { 951da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds printk(KERN_WARNING "b1isa: ports 0x%03x-0x%03x in use.\n", 961da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds card->port, card->port + AVMB1_PORTLEN); 971da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds retval = -EBUSY; 981da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds goto err_free; 991da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds } 1001da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds retval = request_irq(card->irq, b1_interrupt, 0, card->name, card); 1011da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds if (retval) { 1021da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds printk(KERN_ERR "b1isa: unable to get IRQ %d.\n", card->irq); 1031da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds goto err_release_region; 1041da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds } 1051da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds b1_reset(card->port); 1061da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds if ((retval = b1_detect(card->port, card->cardtype)) != 0) { 1071da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds printk(KERN_NOTICE "b1isa: NO card at 0x%x (%d)\n", 1081da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds card->port, retval); 1091da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds retval = -ENODEV; 1101da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds goto err_free_irq; 1111da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds } 1121da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds b1_reset(card->port); 1131da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds b1_getrevision(card); 1141da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 1151da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds cinfo->capi_ctrl.owner = THIS_MODULE; 1161da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds cinfo->capi_ctrl.driver_name = "b1isa"; 1171da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds cinfo->capi_ctrl.driverdata = cinfo; 1181da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds cinfo->capi_ctrl.register_appl = b1_register_appl; 1191da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds cinfo->capi_ctrl.release_appl = b1_release_appl; 1201da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds cinfo->capi_ctrl.send_message = b1_send_message; 1211da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds cinfo->capi_ctrl.load_firmware = b1_load_firmware; 1221da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds cinfo->capi_ctrl.reset_ctr = b1_reset_ctr; 1231da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds cinfo->capi_ctrl.procinfo = b1isa_procinfo; 1249a58a80a701bdb2d220cdab4914218df5b48d781Alexey Dobriyan cinfo->capi_ctrl.proc_fops = &b1ctl_proc_fops; 1251da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds strcpy(cinfo->capi_ctrl.name, card->name); 1261da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 1271da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds retval = attach_capi_ctr(&cinfo->capi_ctrl); 1281da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds if (retval) { 1291da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds printk(KERN_ERR "b1isa: attach controller failed.\n"); 1301da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds goto err_free_irq; 1311da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds } 1321da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 1331da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds printk(KERN_INFO "b1isa: AVM B1 ISA at i/o %#x, irq %d, revision %d\n", 1341da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds card->port, card->irq, card->revision); 1351da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 1361da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds pci_set_drvdata(pdev, cinfo); 1371da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds return 0; 1381da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 139475be4d85a274d0961593db41cf85689db1d583cJoe Percheserr_free_irq: 1401da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds free_irq(card->irq, card); 141475be4d85a274d0961593db41cf85689db1d583cJoe Percheserr_release_region: 1421da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds release_region(card->port, AVMB1_PORTLEN); 143475be4d85a274d0961593db41cf85689db1d583cJoe Percheserr_free: 1441da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds b1_free_card(card); 145475be4d85a274d0961593db41cf85689db1d583cJoe Percheserr: 1461da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds return retval; 1471da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds} 1481da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 1491da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsstatic char *b1isa_procinfo(struct capi_ctr *ctrl) 1501da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds{ 1511da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds avmctrl_info *cinfo = (avmctrl_info *)(ctrl->driverdata); 1521da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 1531da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds if (!cinfo) 1541da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds return ""; 1551da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds sprintf(cinfo->infobuf, "%s %s 0x%x %d r%d", 1561da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds cinfo->cardname[0] ? cinfo->cardname : "-", 1571da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds cinfo->version[VER_DRIVER] ? cinfo->version[VER_DRIVER] : "-", 1581da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds cinfo->card ? cinfo->card->port : 0x0, 1591da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds cinfo->card ? cinfo->card->irq : 0, 1601da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds cinfo->card ? cinfo->card->revision : 0 1611da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds ); 1621da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds return cinfo->infobuf; 1631da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds} 1641da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 1651da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds/* ------------------------------------------------------------- */ 1661da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 1671da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds#define MAX_CARDS 4 1681da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsstatic struct pci_dev isa_dev[MAX_CARDS]; 1691da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsstatic int io[MAX_CARDS]; 1701da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsstatic int irq[MAX_CARDS]; 1711da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 1728d3b33f67fdc0fb364a1ef6d8fbbea7c2e4e6c98Rusty Russellmodule_param_array(io, int, NULL, 0); 1738d3b33f67fdc0fb364a1ef6d8fbbea7c2e4e6c98Rusty Russellmodule_param_array(irq, int, NULL, 0); 1741da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus TorvaldsMODULE_PARM_DESC(io, "I/O base address(es)"); 1751da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus TorvaldsMODULE_PARM_DESC(irq, "IRQ number(s) (assigned)"); 1761da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 1771da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsstatic int b1isa_add_card(struct capi_driver *driver, capicardparams *data) 1781da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds{ 1791da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds int i; 1801da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 1811da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds for (i = 0; i < MAX_CARDS; i++) { 1821da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds if (isa_dev[i].resource[0].start) 1831da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds continue; 1841da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 1851da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds isa_dev[i].resource[0].start = data->port; 1861da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds isa_dev[i].irq = data->irq; 1871da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 1881da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds if (b1isa_probe(&isa_dev[i]) == 0) 1891da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds return 0; 1901da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds } 1911da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds return -ENODEV; 1921da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds} 1931da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 1941da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsstatic struct capi_driver capi_driver_b1isa = { 1951da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds .name = "b1isa", 1961da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds .revision = "1.0", 1971da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds .add_card = b1isa_add_card, 1981da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds}; 1991da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 2001da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsstatic int __init b1isa_init(void) 2011da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds{ 2021da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds char *p; 2031da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds char rev[32]; 2041da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds int i; 2051da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 2068e44b29da5300f4698c41b5fd2d1ce52c28e2148Harvey Harrison if ((p = strchr(revision, ':')) != NULL && p[1]) { 2071da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds strlcpy(rev, p + 2, 32); 2088e44b29da5300f4698c41b5fd2d1ce52c28e2148Harvey Harrison if ((p = strchr(rev, '$')) != NULL && p > rev) 209475be4d85a274d0961593db41cf85689db1d583cJoe Perches *(p - 1) = 0; 2101da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds } else 2111da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds strcpy(rev, "1.0"); 2121da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 2131da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds for (i = 0; i < MAX_CARDS; i++) { 2141da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds if (!io[i]) 2151da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds break; 2161da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 2171da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds isa_dev[i].resource[0].start = io[i]; 2181da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds isa_dev[i].irq = irq[i]; 2191da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 2201da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds if (b1isa_probe(&isa_dev[i]) != 0) 2211da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds return -ENODEV; 2221da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds } 2231da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 2241da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds strlcpy(capi_driver_b1isa.revision, rev, 32); 2251da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds register_capi_driver(&capi_driver_b1isa); 2261da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds printk(KERN_INFO "b1isa: revision %s\n", rev); 2271da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 2281da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds return 0; 2291da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds} 2301da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 2311da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsstatic void __exit b1isa_exit(void) 2321da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds{ 2331da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds int i; 2341da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 2351da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds for (i = 0; i < MAX_CARDS; i++) { 2361c594c05a75770ab53a329fc4eb99c797a4bc7d7Wilfried Klaebe if (isa_dev[i].resource[0].start) 2371c594c05a75770ab53a329fc4eb99c797a4bc7d7Wilfried Klaebe b1isa_remove(&isa_dev[i]); 2381da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds } 2391da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds unregister_capi_driver(&capi_driver_b1isa); 2401da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds} 2411da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 2421da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsmodule_init(b1isa_init); 2431da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsmodule_exit(b1isa_exit); 244