Commit 91cc110f authored by Kai Germaschewski's avatar Kai Germaschewski

ISDN/HiSax: Simplified request_region() etc.

This patch introduces, private to the HiSax driver, new helper functions
request_io/mmio(), which correspond to request_region()/
request_mem_region() but also are verbose about failures and keep track
of the allocated regions, so unwinding in case of errors is automatic.
  
Additionally, request_mmio() will also ioremap() the region.
parent 811b6a3b
......@@ -188,13 +188,6 @@ ipac_writefifo(struct IsdnCardState *cs, u8 off, u8 * data, int size)
BUILD_IPAC_OPS(ipac);
static void
asuscom_release(struct IsdnCardState *cs)
{
if (cs->hw.asus.cfg_reg)
release_region(cs->hw.asus.cfg_reg, 8);
}
static int
asuscom_reset(struct IsdnCardState *cs)
{
......@@ -233,14 +226,14 @@ Asus_card_msg(struct IsdnCardState *cs, int mt, void *arg)
static struct card_ops asuscom_ops = {
.init = inithscxisac,
.reset = asuscom_reset,
.release = asuscom_release,
.release = hisax_release_resources,
.irq_func = hscxisac_irq,
};
static struct card_ops asuscom_ipac_ops = {
.init = ipac_init,
.reset = asuscom_ipac_reset,
.release = asuscom_release,
.release = hisax_release_resources,
.irq_func = ipac_irq,
};
......@@ -319,15 +312,8 @@ setup_asuscom(struct IsdnCard *card)
bytecnt = 8;
cs->hw.asus.cfg_reg = card->para[1];
cs->irq = card->para[0];
if (!request_region((cs->hw.asus.cfg_reg), bytecnt,
"asuscom isdn")) {
printk(KERN_WARNING
"HiSax: %s config port %x-%x already in use\n",
CardType[card->typ],
cs->hw.asus.cfg_reg,
cs->hw.asus.cfg_reg + bytecnt);
return (0);
}
if (!request_io(&cs->rs, cs->hw.asus.cfg_reg, bytecnt, "asuscom isdn"))
goto err;
printk(KERN_INFO "ISDNLink: defined at 0x%x IRQ %d\n",
cs->hw.asus.cfg_reg, cs->irq);
cs->cardmsg = &Asus_card_msg;
......@@ -355,11 +341,13 @@ setup_asuscom(struct IsdnCard *card)
if (HscxVersion(cs, "ISDNLink:")) {
printk(KERN_WARNING
"ISDNLink: wrong HSCX versions check IO address\n");
asuscom_release(cs);
return (0);
goto err;
}
}
printk(KERN_INFO "ISDNLink: resetting card\n");
cs->card_ops->reset(cs);
return (1);
return 1;
err:
hisax_release_resources(cs);
return 0;
}
......@@ -146,24 +146,6 @@ avm_a1_interrupt(int intno, void *dev_id, struct pt_regs *regs)
spin_unlock(&cs->lock);
}
inline static void
release_ioregs(struct IsdnCardState *cs, int mask)
{
release_region(cs->hw.avm.cfg_reg, 8);
if (mask & 1)
release_region(cs->hw.avm.isac + 32, 32);
if (mask & 2)
release_region(cs->hw.avm.isacfifo, 1);
if (mask & 4)
release_region(cs->hw.avm.hscx[0] + 32, 32);
if (mask & 8)
release_region(cs->hw.avm.hscxfifo[0], 1);
if (mask & 0x10)
release_region(cs->hw.avm.hscx[1] + 32, 32);
if (mask & 0x20)
release_region(cs->hw.avm.hscxfifo[1], 1);
}
static int
AVM_card_msg(struct IsdnCardState *cs, int mt, void *arg)
{
......@@ -178,15 +160,9 @@ avm_a1_init(struct IsdnCardState *cs)
inithscxisac(cs);
}
static void
avm_a1_release(struct IsdnCardState *cs)
{
release_ioregs(cs, 0x3f);
}
static struct card_ops avm_a1_ops = {
.init = avm_a1_init,
.release = avm_a1_release,
.release = hisax_release_resources,
.irq_func = avm_a1_interrupt,
};
......@@ -202,73 +178,25 @@ setup_avm_a1(struct IsdnCard *card)
if (cs->typ != ISDN_CTYPE_A1)
return (0);
cs->hw.avm.cfg_reg = card->para[1] + 0x1800;
cs->hw.avm.isac = card->para[1] + 0x1400 - 0x20;
cs->hw.avm.hscx[0] = card->para[1] + 0x400 - 0x20;
cs->hw.avm.hscx[1] = card->para[1] + 0xc00 - 0x20;
cs->hw.avm.isacfifo = card->para[1] + 0x1000;
cs->hw.avm.hscxfifo[0] = card->para[1];
cs->hw.avm.hscxfifo[1] = card->para[1] + 0x800;
cs->hw.avm.cfg_reg = request_io(&cs->rs, card->para[1] + 0x1800, 8, "avm cfg");
if (!cs->hw.avm.cfg_reg) goto err;
cs->hw.avm.isac = request_io(&cs->rs, card->para[1] + 0x1400, 32, "HiSax isac");
if (!cs->hw.avm.isac) goto err;
cs->hw.avm.isacfifo = request_io(&cs->rs, card->para[1] + 0x1000, 1, "HiSax isac fifo");
if (!cs->hw.avm.isacfifo) goto err;
cs->hw.avm.hscx[0] = request_io(&cs->rs, card->para[1] + 0x400, 32, "HiSax hscx A");
if (!cs->hw.avm.hscx[0]) goto err;
cs->hw.avm.hscxfifo[0] = request_io(&cs->rs, card->para[1], 1, "HiSax hscx A fifo");
if (!cs->hw.avm.hscxfifo[0]) goto err;
cs->hw.avm.hscx[1] = request_io(&cs->rs, card->para[1] + 0xc00, 32, "HiSax hscx B");
if (!cs->hw.avm.hscx[1]) goto err;
cs->hw.avm.hscxfifo[1] = request_io(&cs->rs, card->para[1] + 0x800, 1, "HiSax hscx B fifo");
if (!cs->hw.avm.hscxfifo[1]) goto err;
cs->hw.avm.isac -= 0x20;
cs->hw.avm.hscx[0] -= 0x20;
cs->hw.avm.hscx[1] -= 0x20;
cs->irq = card->para[0];
if (!request_region(cs->hw.avm.cfg_reg, 8, "avm cfg")) {
printk(KERN_WARNING
"HiSax: %s config port %x-%x already in use\n",
CardType[card->typ],
cs->hw.avm.cfg_reg,
cs->hw.avm.cfg_reg + 8);
return (0);
}
if (!request_region(cs->hw.avm.isac + 32, 32, "HiSax isac")) {
printk(KERN_WARNING
"HiSax: %s isac ports %x-%x already in use\n",
CardType[cs->typ],
cs->hw.avm.isac + 32,
cs->hw.avm.isac + 64);
release_ioregs(cs, 0);
return (0);
}
if (!request_region(cs->hw.avm.isacfifo, 1, "HiSax isac fifo")) {
printk(KERN_WARNING
"HiSax: %s isac fifo port %x already in use\n",
CardType[cs->typ],
cs->hw.avm.isacfifo);
release_ioregs(cs, 1);
return (0);
}
if (!request_region(cs->hw.avm.hscx[0] + 32, 32, "HiSax hscx A")) {
printk(KERN_WARNING
"HiSax: %s hscx A ports %x-%x already in use\n",
CardType[cs->typ],
cs->hw.avm.hscx[0] + 32,
cs->hw.avm.hscx[0] + 64);
release_ioregs(cs, 3);
return (0);
}
if (!request_region(cs->hw.avm.hscxfifo[0], 1, "HiSax hscx A fifo")) {
printk(KERN_WARNING
"HiSax: %s hscx A fifo port %x already in use\n",
CardType[cs->typ],
cs->hw.avm.hscxfifo[0]);
release_ioregs(cs, 7);
return (0);
}
if (!request_region(cs->hw.avm.hscx[1] + 32, 32, "HiSax hscx B")) {
printk(KERN_WARNING
"HiSax: %s hscx B ports %x-%x already in use\n",
CardType[cs->typ],
cs->hw.avm.hscx[1] + 32,
cs->hw.avm.hscx[1] + 64);
release_ioregs(cs, 0xf);
return (0);
}
if (!request_region(cs->hw.avm.hscxfifo[1], 1, "HiSax hscx B fifo")) {
printk(KERN_WARNING
"HiSax: %s hscx B fifo port %x already in use\n",
CardType[cs->typ],
cs->hw.avm.hscxfifo[1]);
release_ioregs(cs, 0x1f);
return (0);
}
byteout(cs->hw.avm.cfg_reg, 0x0);
HZDELAY(HZ / 5 + 1);
byteout(cs->hw.avm.cfg_reg, 0x1);
......@@ -316,8 +244,10 @@ setup_avm_a1(struct IsdnCard *card)
if (HscxVersion(cs, "AVM A1:")) {
printk(KERN_WARNING
"AVM A1: wrong HSCX versions check IO address\n");
release_ioregs(cs, 0x3f);
return (0);
goto err;
}
return (1);
return 1;
err:
hisax_release_resources(cs);
return 0;
}
......@@ -592,7 +592,7 @@ static void
avm_pcipnp_release(struct IsdnCardState *cs)
{
outb(0, cs->hw.avm.cfg_reg + 2);
release_region(cs->hw.avm.cfg_reg, 32);
hisax_release_resources(cs);
}
static struct card_ops avm_pci_ops = {
......@@ -693,15 +693,10 @@ setup_avm_pcipnp(struct IsdnCard *card)
}
ready:
cs->hw.avm.isac = cs->hw.avm.cfg_reg + 0x10;
if (!request_region((cs->hw.avm.cfg_reg), 32, (cs->subtyp == AVM_FRITZ_PCI)
? "avm PCI" : "avm PnP")) {
printk(KERN_WARNING
"HiSax: %s config port %x-%x already in use\n",
CardType[card->typ],
cs->hw.avm.cfg_reg,
cs->hw.avm.cfg_reg + 31);
return (0);
}
if (!request_io(&cs->rs, cs->hw.avm.cfg_reg, 32,
cs->subtyp == AVM_FRITZ_PCI ? "avm PCI" : "avm PnP"))
goto err;
switch (cs->subtyp) {
case AVM_FRITZ_PCI:
val = inl(cs->hw.avm.cfg_reg);
......@@ -726,5 +721,8 @@ setup_avm_pcipnp(struct IsdnCard *card)
cs->cardmsg = &AVM_card_msg;
cs->card_ops = &avm_pci_ops;
ISACVersion(cs, (cs->subtyp == AVM_FRITZ_PCI) ? "AVM PCI:" : "AVM PnP:");
return (1);
return 1;
err:
hisax_release_resources(cs);
return 0;
}
......@@ -98,14 +98,6 @@ set_ipac_active(struct IsdnCardState *cs, u_int active)
ipac_write(cs, IPAC_MASK, active ? 0xc0 : 0xff);
}
void
release_io_sct_quadro(struct IsdnCardState *cs)
{
release_region(cs->hw.ax.base & 0xffffffc0, 128);
if (cs->subtyp == SCT_1)
release_region(cs->hw.ax.plx_adr, 64);
}
static void
enable_bkm_int(struct IsdnCardState *cs, unsigned bEnable)
{
......@@ -162,7 +154,7 @@ bkm_a8_release(struct IsdnCardState *cs)
{
set_ipac_active(cs, 0);
enable_bkm_int(cs, 0);
release_io_sct_quadro(cs);
hisax_release_resources(cs);
}
static struct card_ops bkm_a8_ops = {
......@@ -172,18 +164,6 @@ static struct card_ops bkm_a8_ops = {
.irq_func = ipac_irq,
};
int __init
sct_alloc_io(u_int adr, u_int len)
{
if (!request_region(adr, len, "scitel")) {
printk(KERN_WARNING
"HiSax: Scitel port %#x-%#x already in use\n",
adr, adr + len);
return (1);
}
return(0);
}
static struct pci_dev *dev_a8 __initdata = NULL;
static u16 sub_vendor_id __initdata = 0;
static u16 sub_sys_id __initdata = 0;
......@@ -295,28 +275,28 @@ setup_sct_quadro(struct IsdnCard *card)
cs->hw.ax.plx_adr = pci_ioaddr1;
/* Enter all ipac_base addresses */
switch(cs->subtyp) {
case 1:
cs->hw.ax.base = pci_ioaddr5 + 0x00;
if (sct_alloc_io(pci_ioaddr1, 128))
return(0);
if (sct_alloc_io(pci_ioaddr5, 64))
return(0);
break;
case 2:
cs->hw.ax.base = pci_ioaddr4 + 0x08;
if (sct_alloc_io(pci_ioaddr4, 64))
return(0);
break;
case 3:
cs->hw.ax.base = pci_ioaddr3 + 0x10;
if (sct_alloc_io(pci_ioaddr3, 64))
return(0);
break;
case 4:
cs->hw.ax.base = pci_ioaddr2 + 0x20;
if (sct_alloc_io(pci_ioaddr2, 64))
return(0);
break;
case 1:
cs->hw.ax.base = pci_ioaddr5 + 0x00;
if (!request_io(&cs->rs, pci_ioaddr1, 128, "scitel"))
goto err;
if (!request_io(&cs->rs, pci_ioaddr5, 64, "scitel"))
goto err;
break;
case 2:
cs->hw.ax.base = pci_ioaddr4 + 0x08;
if (!request_io(&cs->rs, pci_ioaddr4, 64, "scitel"))
goto err;
break;
case 3:
cs->hw.ax.base = pci_ioaddr3 + 0x10;
if (!request_io(&cs->rs, pci_ioaddr3, 64, "scitel"))
goto err;
break;
case 4:
cs->hw.ax.base = pci_ioaddr2 + 0x20;
if (!request_io(&cs->rs, pci_ioaddr2, 64, "scitel"))
goto err;
break;
}
cs->hw.ax.data_adr = cs->hw.ax.base + 4;
ipac_write(cs, IPAC_MASK, 0xFF);
......@@ -338,8 +318,11 @@ setup_sct_quadro(struct IsdnCard *card)
CardType[card->typ],
sct_quadro_subtypes[cs->subtyp],
ipac_read(cs, IPAC_ID));
return (1);
return 1;
#else
printk(KERN_ERR "HiSax: bkm_a8 only supported on PCI Systems\n");
#endif /* CONFIG_PCI */
err:
hisax_release_resources(cs);
return 0;
}
......@@ -945,6 +945,7 @@ static int __devinit checkcard(int cardnr, char *id, int *busy_flag)
cs->status_end = cs->status_buf + HISAX_STATUS_BUFSIZE - 1;
cs->typ = card->typ;
spin_lock_init(&cs->lock);
resources_init(&cs->rs);
SET_MODULE_OWNER(&cs->iif);
strcpy(cs->iif.id, id);
cs->iif.channels = 2;
......@@ -2055,6 +2056,100 @@ static void EChannel_proc_rcv(struct hisax_d_if *d_if)
}
}
void
resources_init(struct resources *rs)
{
INIT_LIST_HEAD(&rs->res_head);
}
void
resources_release(struct resources *rs)
{
struct res *r;
list_for_each_entry(r, &rs->res_head, node) {
if (r->flags & IORESOURCE_IO) {
release_region(r->start, r->end - r->start + 1);
}
if (r->flags & IORESOURCE_MEM) {
iounmap(r->r_u.ioremap_addr);
release_mem_region(r->start, r->end - r->start + 1);
}
}
}
unsigned long
request_io(struct resources *rs, unsigned long start, int len,
const char *name)
{
struct res *r;
r = kmalloc(sizeof(*r), GFP_KERNEL);
if (!r) {
printk(KERN_WARNING "%s: out of memory\n", __FUNCTION__);
goto err;
}
if (!request_region(start, len, name)) {
printk(KERN_WARNING "%s: IO %#lx-%#lx already in use\n",
__FUNCTION__, start, start + len - 1);
goto err_free;
}
r->flags = IORESOURCE_IO;
r->start = start;
r->end = start + len - 1;
r->name = name;
list_add_tail(&r->node, &rs->res_head);
return r->start;
err_free:
kfree(r);
err:
return 0;
}
void *
request_mmio(struct resources *rs, unsigned long start, int len,
const char *name)
{
struct res *r;
r = kmalloc(sizeof(*r), GFP_KERNEL);
if (!r) {
printk(KERN_WARNING "%s: out of memory\n", __FUNCTION__);
goto err;
}
if (!request_mem_region(start, len, name)) {
printk(KERN_WARNING "%s: MMIO %#lx-%#lx already in use\n",
__FUNCTION__, start, start + len - 1);
goto err_free;
}
r->flags = IORESOURCE_MEM;
r->start = start;
r->end = start + len - 1;
r->name = name;
r->r_u.ioremap_addr = ioremap(start, len);
if (!r->r_u.ioremap_addr)
goto err_release;
list_add_tail(&r->node, &rs->res_head);
return r->r_u.ioremap_addr;
err_release:
release_mem_region(r->start, r->end - r->start + 1);
err_free:
kfree(r);
err:
return 0;
}
void
hisax_resources_release(struct IsdnCardState *cs)
{
resources_release(&cs->rs);
}
#include <linux/pci.h>
static struct pci_device_id hisax_pci_tbl[] __initdata = {
......
......@@ -362,25 +362,11 @@ diva_ipacx_pci_irq(int intno, void *dev_id, struct pt_regs *regs)
static void
diva_release(struct IsdnCardState *cs)
{
int bytecnt;
del_timer(&cs->hw.diva.tl);
if (cs->hw.diva.cfg_reg)
byteout(cs->hw.diva.ctrl, 0); /* LED off, Reset */
if (cs->subtyp == DIVA_ISA)
bytecnt = 8;
else
bytecnt = 32;
if (cs->hw.diva.cfg_reg)
release_region(cs->hw.diva.cfg_reg, bytecnt);
}
static void
diva_ipac_isa_release(struct IsdnCardState *cs)
{
if (cs->hw.diva.cfg_reg)
release_region(cs->hw.diva.cfg_reg, 8);
hisax_release_resources(cs);
}
static void
......@@ -561,7 +547,7 @@ static struct card_ops diva_ops = {
static struct card_ops diva_ipac_isa_ops = {
.init = ipac_init,
.reset = diva_ipac_isa_reset,
.release = diva_ipac_isa_release,
.release = hisax_release_resources,
.irq_func = ipac_irq,
};
......@@ -798,16 +784,8 @@ setup_diva(struct IsdnCard *card)
cs->hw.diva.pci_cfg);
if ((cs->subtyp != DIVA_IPAC_PCI) &&
(cs->subtyp != DIVA_IPACX_PCI) ) {
if (check_region(cs->hw.diva.cfg_reg, bytecnt)) {
printk(KERN_WARNING
"HiSax: %s config port %lx-%lx already in use\n",
CardType[card->typ],
cs->hw.diva.cfg_reg,
cs->hw.diva.cfg_reg + bytecnt);
return (0);
} else {
request_region(cs->hw.diva.cfg_reg, bytecnt, "diva isdn");
}
if (!request_io(&cs->rs, cs->hw.diva.cfg_reg, bytecnt, "diva isdn"))
return 0;
}
cs->cardmsg = &Diva_card_msg;
if (cs->subtyp == DIVA_IPAC_ISA) {
......
......@@ -387,8 +387,6 @@ elsa_interrupt_ipac(int intno, void *dev_id, struct pt_regs *regs)
static void
elsa_release(struct IsdnCardState *cs)
{
int bytecnt = 8;
del_timer(&cs->hw.elsa.tl);
#if ARCOFI_USE
clear_arcofi(cs);
......@@ -398,28 +396,23 @@ elsa_release(struct IsdnCardState *cs)
if (cs->subtyp == ELSA_QS1000PCI) {
byteout(cs->hw.elsa.cfg + 0x4c, 0x01); /* disable IRQ */
writereg(cs, cs->hw.elsa.isac, IPAC_ATX, 0xff);
bytecnt = 2;
release_region(cs->hw.elsa.cfg, 0x80);
}
if (cs->subtyp == ELSA_QS3000PCI) {
byteout(cs->hw.elsa.cfg + 0x4c, 0x03); /* disable ELSA PCI IRQ */
writereg(cs, cs->hw.elsa.isac, IPAC_ATX, 0xff);
release_region(cs->hw.elsa.cfg, 0x80);
}
if (cs->subtyp == ELSA_PCMCIA_IPAC) {
writereg(cs, cs->hw.elsa.isac, IPAC_ATX, 0xff);
}
#if ARCOFI_USE
if ((cs->subtyp == ELSA_PCFPRO) ||
(cs->subtyp == ELSA_QS3000) ||
(cs->subtyp == ELSA_PCF) ||
(cs->subtyp == ELSA_QS3000PCI)) {
bytecnt = 16;
#if ARCOFI_USE
release_modem(cs);
#endif
}
if (cs->hw.elsa.base)
release_region(cs->hw.elsa.base, bytecnt);
#endif
hisax_release_resources(cs);
}
static int
......@@ -532,28 +525,14 @@ check_arcofi(struct IsdnCardState *cs)
"Elsa: %s detected modem at 0x%lx\n",
Elsa_Types[cs->subtyp],
cs->hw.elsa.base+8);
release_region(cs->hw.elsa.base, 8);
if (!request_region(cs->hw.elsa.base, 16,"elsa isdn modem")) {
printk(KERN_WARNING
"HiSax: %s config port %lx-%lx already in use\n",
Elsa_Types[cs->subtyp],
cs->hw.elsa.base + 8,
cs->hw.elsa.base + 16);
}
request_io(&cs->rs, cs->hw.elsa.base+8, 8, "elsa isdn modem");
} else if (cs->subtyp==ELSA_PCC16) {
cs->subtyp = ELSA_PCF;
printk(KERN_INFO
"Elsa: %s detected modem at 0x%lx\n",
Elsa_Types[cs->subtyp],
cs->hw.elsa.base+8);
release_region(cs->hw.elsa.base, 8);
if (!request_region(cs->hw.elsa.base, 16,"elsa isdn modem")) {
printk(KERN_WARNING
"HiSax: %s config port %lx-%lx already in use\n",
Elsa_Types[cs->subtyp],
cs->hw.elsa.base + 8,
cs->hw.elsa.base + 16);
}
request_io(&cs->rs, cs->hw.elsa.base+8, 8, "elsa isdn modem");
} else
printk(KERN_INFO
"Elsa: %s detected modem at 0x%lx\n",
......@@ -1081,29 +1060,17 @@ setup_elsa(struct IsdnCard *card)
reserved for us by the card manager. So we do not check it
here, it would fail. */
if (cs->typ != ISDN_CTYPE_ELSA_PCMCIA)
if (!request_region(cs->hw.elsa.base, bytecnt, "elsa isdn")) {
printk(KERN_WARNING
"HiSax: %s config port %#lx-%#lx already in use\n",
CardType[card->typ],
cs->hw.elsa.base,
cs->hw.elsa.base + bytecnt);
return (0);
}
if (!request_io(&cs->rs, cs->hw.elsa.base, bytecnt, "elsa isdn"))
goto err;
if ((cs->subtyp == ELSA_QS1000PCI) || (cs->subtyp == ELSA_QS3000PCI)) {
if (!request_region(cs->hw.elsa.cfg, 0x80, "elsa isdn pci")) {
printk(KERN_WARNING
"HiSax: %s pci port %x-%x already in use\n",
CardType[card->typ],
cs->hw.elsa.cfg,
cs->hw.elsa.cfg + 0x80);
release_region(cs->hw.elsa.base, bytecnt);
return (0);
}
}
if ((cs->subtyp == ELSA_QS1000PCI) || (cs->subtyp == ELSA_QS3000PCI))
if (!request_io(&cs->rs, cs->hw.elsa.cfg, 0x80, "elsa isdn pci"))
goto err;
#if ARCOFI_USE
init_arcofi(cs);
#endif
cs->hw.elsa.tl.function = (void *) elsa_led_handler;
cs->hw.elsa.tl.data = (long) cs;
init_timer(&cs->hw.elsa.tl);
......@@ -1116,15 +1083,13 @@ setup_elsa(struct IsdnCard *card)
if (!TimerRun(cs)) {
printk(KERN_WARNING
"Elsa: timer do not start\n");
elsa_release(cs);
return (0);
goto err;
}
}
HZDELAY(1); /* wait >=10 ms */
if (TimerRun(cs)) {
printk(KERN_WARNING "Elsa: timer do not run down\n");
elsa_release(cs);
return (0);
goto err;
}
printk(KERN_INFO "Elsa: timer OK; resetting card\n");
}
......@@ -1143,9 +1108,8 @@ setup_elsa(struct IsdnCard *card)
ISACVersion(cs, "Elsa:");
if (HscxVersion(cs, "Elsa:")) {
printk(KERN_WARNING
"Elsa: wrong HSCX versions check IO address\n");
elsa_release(cs);
return (0);
"Elsa: wrong HSCX versions check IO address\n");
goto err;
}
}
if (cs->subtyp == ELSA_PC) {
......@@ -1157,5 +1121,8 @@ setup_elsa(struct IsdnCard *card)
writeitac(cs, ITAC_SCIE, 0);
writeitac(cs, ITAC_STIE, 0);
}
return (1);
return 1;
err:
elsa_release(cs);
return 0;
}
......@@ -280,7 +280,6 @@ static struct pci_dev *dev_netjet __initdata = NULL;
int __init
setup_enternow_pci(struct IsdnCard *card)
{
int bytecnt;
struct IsdnCardState *cs = card->cs;
char tmp[64];
......@@ -359,19 +358,11 @@ setup_enternow_pci(struct IsdnCard *card)
#endif /* CONFIG_PCI */
bytecnt = 256;
printk(KERN_INFO
"enter:now PCI: PCI card configured at 0x%lx IRQ %d\n",
cs->hw.njet.base, cs->irq);
if (!request_region(cs->hw.njet.base, bytecnt, "Fn_ISDN")) {
printk(KERN_WARNING
"HiSax: %s config port %lx-%lx already in use\n",
CardType[card->typ],
cs->hw.njet.base,
cs->hw.njet.base + bytecnt);
return (0);
}
if (!request_io(&cs->rs, cs->hw.njet.base, 0x100, "Fn_ISDN"))
return 0;
reset_enpci(cs);
cs->hw.njet.last_is0 = 0;
cs->dc_hw_ops = &enternow_ops;
......@@ -381,31 +372,5 @@ setup_enternow_pci(struct IsdnCard *card)
cs->irq_flags |= SA_SHIRQ;
cs->card_ops = &enpci_ops;
return (1);
return 1;
}
......@@ -300,127 +300,85 @@ gazel_init(struct IsdnCardState *cs)
inithscxisac(cs);
}
static struct resource *
gazel_request_region(unsigned long start, unsigned long n, const char *name)
{
struct resource *rc = request_region(start, n, name);
if (!rc)
printk(KERN_WARNING "Gazel: io %#lx-%#lx already in use\n",
start, start + n);
return rc;
}
static int
r647_reserve_regions(struct IsdnCardState *cs)
{
int i, base;
int i, base = cs->hw.gazel.hscx[0];
base = cs->hw.gazel.hscx[0];
for (i = 0x0000; i < 0xC000; i += 0x1000) {
if (!gazel_request_region(i + base, 16, "gazel")) {
for (i -= 0x1000; i >= 0; i -= 0x1000)
release_region (i + base, 16);
return -EBUSY;
}
}
if (!gazel_request_region(0xC000 + base, 1, "gazel")) {
for (i = 0x0000; i < 0xC000; i += 0x1000)
release_region (i + base, 16);
return -EBUSY;
for (i = 0; i < 0xc000; i += 0x1000) {
if (!request_io(&cs->rs, i + base, 16, "gazel"))
goto err;
}
if (!request_io(&cs->rs, 0xc000 + base, 1, "gazel"))
goto err;
return 0;
}
static void
r647_release(struct IsdnCardState *cs)
{
int i;
for (i = 0x0000; i < 0xC000; i += 0x1000)
release_region(i + cs->hw.gazel.hscx[0], 16);
release_region(0xC000 + cs->hw.gazel.hscx[0], 1);
err:
hisax_release_resources(cs);
return -EBUSY;
}
static int
r685_reserve_regions(struct IsdnCardState *cs)
{
if (!gazel_request_region(cs->hw.gazel.hscx[0], 0x100, "gazel")) {
return -EBUSY;
}
if (!gazel_request_region(cs->hw.gazel.cfg_reg, 0x80, "gazel")) {
release_region (cs->hw.gazel.hscx[0], 0x100);
return -EBUSY;
}
if (!request_io(&cs->rs, cs->hw.gazel.hscx[0], 0x100, "gazel"))
goto err;
if (!request_io(&cs->rs, cs->hw.gazel.cfg_reg, 0x80, "gazel"))
goto err;
return 0;
}
static void
r685_release(struct IsdnCardState *cs)
{
release_region(cs->hw.gazel.hscx[0], 0x100);
release_region(cs->hw.gazel.cfg_reg, 0x80);
err:
hisax_release_resources(cs);
return -EBUSY;
}
static int
r742_reserve_regions(struct IsdnCardState *cs)
{
if (!gazel_request_region(cs->hw.gazel.ipac, 0x8, "gazel"))
return -EBUSY;
if (!request_io(&cs->rs, cs->hw.gazel.ipac, 0x8, "gazel"))
goto err;
return 0;
}
static void
r742_release(struct IsdnCardState *cs)
{
release_region(cs->hw.gazel.ipac, 8);
err:
hisax_release_resources(cs);
return -EBUSY;
}
static int
r753_reserve_regions(struct IsdnCardState *cs)
{
if (!gazel_request_region(cs->hw.gazel.ipac, 0x8, "gazel")) {
return -EBUSY;
}
if (!gazel_request_region(cs->hw.gazel.cfg_reg, 0x80, "gazel")) {
release_region (cs->hw.gazel.ipac, 0x8);
return -EBUSY;
}
if (!request_io(&cs->rs, cs->hw.gazel.ipac, 0x8, "gazel"))
goto err;
if (!request_io(&cs->rs, cs->hw.gazel.cfg_reg, 0x80, "gazel"))
goto err;
return 0;
}
static void
r753_release(struct IsdnCardState *cs)
{
release_region(cs->hw.gazel.ipac, 0x8);
release_region(cs->hw.gazel.cfg_reg, 0x80);
err:
hisax_release_resources(cs);
return -EBUSY;
}
static struct card_ops r647_ops = {
.init = gazel_init,
.reset = r647_reset,
.release = r647_release,
.release = hisax_release_resources,
.irq_func = hscxisac_irq,
};
static struct card_ops r685_ops = {
.init = gazel_init,
.reset = r685_reset,
.release = r685_release,
.release = hisax_release_resources,
.irq_func = hscxisac_irq,
};
static struct card_ops r742_ops = {
.init = ipac_init,
.reset = r742_reset,
.release = r742_release,
.release = hisax_release_resources,
.irq_func = ipac_irq,
};
static struct card_ops r753_ops = {
.init = ipac_init,
.reset = r753_reset,
.release = r753_release,
.release = hisax_release_resources,
.irq_func = ipac_irq,
};
......
......@@ -318,7 +318,7 @@ hfcsx_release(struct IsdnCardState *cs)
schedule_timeout((30 * HZ) / 1000); /* Timeout 30ms */
Write_hfc(cs, HFCSX_CIRM, 0); /* Reset Off */
del_timer(&cs->hw.hfcsx.timer);
release_region(cs->hw.hfcsx.base, 2); /* release IO-Block */
hisax_release_resources(cs);
kfree(cs->hw.hfcsx.extra);
cs->hw.hfcsx.extra = NULL;
}
......@@ -1236,45 +1236,40 @@ setup_hfcsx(struct IsdnCard *card)
cs->hw.hfcsx.fifo = 255;
if ((cs->typ == ISDN_CTYPE_HFC_SX) ||
(cs->typ == ISDN_CTYPE_HFC_SP_PCMCIA)) {
if ((!cs->hw.hfcsx.base) ||
check_region((cs->hw.hfcsx.base), 2)) {
printk(KERN_WARNING
"HiSax: HFC-SX io-base %#lx already in use\n",
cs->hw.hfcsx.base);
return(0);
} else {
request_region(cs->hw.hfcsx.base, 2, "HFCSX isdn");
}
if (!request_io(&cs->rs, cs->hw.hfcsx.base, 2, "HFCSX isdn"))
return 0;
byteout(cs->hw.hfcsx.base, cs->hw.hfcsx.base & 0xFF);
byteout(cs->hw.hfcsx.base + 1,
((cs->hw.hfcsx.base >> 8) & 3) | 0x54);
udelay(10);
cs->hw.hfcsx.chip = Read_hfc(cs,HFCSX_CHIP_ID);
switch (cs->hw.hfcsx.chip >> 4) {
case 1:
tmp[0] ='+';
break;
case 9:
tmp[0] ='P';
break;
default:
printk(KERN_WARNING
"HFC-SX: invalid chip id 0x%x\n",
cs->hw.hfcsx.chip >> 4);
release_region(cs->hw.hfcsx.base, 2);
return(0);
case 1:
tmp[0] ='+';
break;
case 9:
tmp[0] ='P';
break;
default:
printk(KERN_WARNING "HFC-SX: invalid chip id 0x%x\n",
cs->hw.hfcsx.chip >> 4);
hisax_release_resources(cs);
return 0;
}
if (!ccd_sp_irqtab[cs->irq & 0xF]) {
printk(KERN_WARNING
"HFC_SX: invalid irq %d specified\n",cs->irq & 0xF);
release_region(cs->hw.hfcsx.base, 2);
return(0);
printk(KERN_WARNING
"HFC_SX: invalid irq %d specified\n",
cs->irq & 0xF);
hisax_release_resources(cs);
return 0;
}
if (!(cs->hw.hfcsx.extra = (void *)
kmalloc(sizeof(struct hfcsx_extra), GFP_ATOMIC))) {
release_region(cs->hw.hfcsx.base, 2);
printk(KERN_WARNING "HFC-SX: unable to allocate memory\n");
return(0);
cs->hw.hfcsx.extra = kmalloc(sizeof(struct hfcsx_extra),
GFP_ATOMIC);
if (!cs->hw.hfcsx.extra) {
hisax_release_resources(cs);
printk(KERN_WARNING
"HFC-SX: unable to allocate memory\n");
return 0;
}
printk(KERN_INFO
......
......@@ -69,8 +69,7 @@ hfcs_release(struct IsdnCardState *cs)
{
release2bds0(cs);
del_timer(&cs->hw.hfcD.timer);
if (cs->hw.hfcD.addr)
release_region(cs->hw.hfcD.addr, 2);
hisax_release_resources(cs);
}
static int
......@@ -234,16 +233,8 @@ setup_hfcs(struct IsdnCard *card)
cs->hw.hfcD.bfifosize = 7*1024 + 512;
} else
return (0);
if (check_region((cs->hw.hfcD.addr), 2)) {
printk(KERN_WARNING
"HiSax: %s config port %x-%x already in use\n",
CardType[card->typ],
cs->hw.hfcD.addr,
cs->hw.hfcD.addr + 2);
return (0);
} else {
request_region(cs->hw.hfcD.addr, 2, "HFCS isdn");
}
if (!request_io(&cs->rs, cs->hw.hfcD.addr, 2, "HFCS isdn"))
return 0;
printk(KERN_INFO
"HFCS: defined at 0x%x IRQ %d HZ %d\n",
cs->hw.hfcD.addr,
......
......@@ -149,6 +149,35 @@
/* #define I4L_IRQ_FLAG SA_INTERRUPT */
#define I4L_IRQ_FLAG 0
struct res {
struct list_head node;
const char *name;
unsigned long start, end;
unsigned long flags;
union {
void *ioremap_addr;
} r_u;
};
struct resources {
struct list_head res_head;
};
void
resources_init(struct resources *rs);
void
resources_release(struct resources *rs);
unsigned long
request_io(struct resources *rs, unsigned long start, int len,
const char *name);
void *
request_mmio(struct resources *rs, unsigned long start, int len,
const char *name);
/*
* Statemachine
*/
......@@ -563,8 +592,8 @@ struct teles3_hw {
struct teles0_hw {
unsigned int cfg_reg;
unsigned long membase;
unsigned long phymem;
void *membase;
};
struct avm_hw {
......@@ -730,9 +759,8 @@ struct hfcD_hw {
struct isurf_hw {
unsigned int reset;
unsigned long phymem;
unsigned long isac;
unsigned long isar;
void *isac;
void *isar;
struct isar_reg isar_r;
};
......@@ -919,6 +947,7 @@ struct IsdnCardState {
spinlock_t lock;
struct card_ops *card_ops;
int protocol;
struct resources rs;
unsigned int irq;
unsigned long irq_flags;
long HW_Flags;
......@@ -994,6 +1023,9 @@ struct IsdnCardState {
#endif
};
void
hisax_release_resources(struct IsdnCardState *cs);
#define MON0_RX 1
#define MON1_RX 2
#define MON0_TX 4
......@@ -1437,4 +1469,5 @@ L4L3(struct PStack *st, int pr, void *arg)
st->l3.l4l3(st, pr, arg);
}
#endif
......@@ -132,14 +132,6 @@ isurf_interrupt(int intno, void *dev_id, struct pt_regs *regs)
spin_unlock(&cs->lock);
}
static void
isurf_release(struct IsdnCardState *cs)
{
release_region(cs->hw.isurf.reset, 1);
iounmap((unsigned char *)cs->hw.isurf.isar);
release_mem_region(cs->hw.isurf.phymem, ISURF_IOMEM_SIZE);
}
static void
reset_isurf(struct IsdnCardState *cs, u8 chips)
{
......@@ -193,7 +185,7 @@ isurf_reset(struct IsdnCardState *cs)
static struct card_ops isurf_ops = {
.init = isurf_init,
.reset = isurf_reset,
.release = isurf_release,
.release = hisax_release_resources,
.irq_func = isurf_interrupt,
};
......@@ -215,7 +207,6 @@ setup_isurf(struct IsdnCard *card)
return(0);
if (card->para[1] && card->para[2]) {
cs->hw.isurf.reset = card->para[1];
cs->hw.isurf.phymem = card->para[2];
cs->irq = card->para[0];
} else {
#ifdef __ISAPNP__
......@@ -261,32 +252,17 @@ setup_isurf(struct IsdnCard *card)
return (0);
#endif
}
if (!request_region(cs->hw.isurf.reset, 1, "isurf isdn")) {
printk(KERN_WARNING
"HiSax: %s config port %x already in use\n",
CardType[card->typ],
cs->hw.isurf.reset);
return (0);
}
if (check_mem_region(cs->hw.isurf.phymem, ISURF_IOMEM_SIZE)) {
printk(KERN_WARNING
"HiSax: %s memory region %lx-%lx already in use\n",
CardType[card->typ],
cs->hw.isurf.phymem,
cs->hw.isurf.phymem + ISURF_IOMEM_SIZE);
release_region(cs->hw.isurf.reset, 1);
return (0);
} else {
request_mem_region(cs->hw.isurf.phymem, ISURF_IOMEM_SIZE,
"isurf iomem");
}
cs->hw.isurf.isar =
(unsigned long) ioremap(cs->hw.isurf.phymem, ISURF_IOMEM_SIZE);
if (!request_io(&cs->rs, cs->hw.isurf.reset, 1, "isurf isdn"))
goto err;
cs->hw.isurf.isar = request_mmio(&cs->rs, card->para[2], ISURF_IOMEM_SIZE, "isurf iomem");
if (!cs->hw.isurf.isar)
goto err;
cs->hw.isurf.isac = cs->hw.isurf.isar + ISURF_ISAC_OFFSET;
printk(KERN_INFO
"ISurf: defined at 0x%x 0x%lx IRQ %d\n",
cs->hw.isurf.reset,
cs->hw.isurf.phymem,
card->para[2],
cs->irq);
cs->cardmsg = &ISurf_card_msg;
......@@ -303,8 +279,11 @@ setup_isurf(struct IsdnCard *card)
if (ver < 0) {
printk(KERN_WARNING
"ISurf: wrong ISAR version (ret = %d)\n", ver);
isurf_release(cs);
return (0);
goto err;
}
return (1);
return 1;
err:
hisax_release_resources(cs);
return 0;
}
......@@ -140,13 +140,6 @@ static struct bc_hw_ops hscx_ops = {
.write_fifo = hscx_write_fifo,
};
static void
ix1_release(struct IsdnCardState *cs)
{
if (cs->hw.ix1.cfg_reg)
release_region(cs->hw.ix1.cfg_reg, 4);
}
static int
ix1_reset(struct IsdnCardState *cs)
{
......@@ -171,7 +164,7 @@ ix1_card_msg(struct IsdnCardState *cs, int mt, void *arg)
static struct card_ops ix1_ops = {
.init = inithscxisac,
.reset = ix1_reset,
.release = ix1_release,
.release = hisax_release_resources,
.irq_func = hscxisac_irq,
};
......@@ -247,17 +240,9 @@ setup_ix1micro(struct IsdnCard *card)
cs->hw.ix1.hscx = card->para[1] + HSCX_DATA_OFFSET;
cs->hw.ix1.cfg_reg = card->para[1];
cs->irq = card->para[0];
if (cs->hw.ix1.cfg_reg) {
if (check_region((cs->hw.ix1.cfg_reg), 4)) {
printk(KERN_WARNING
"HiSax: %s config port %x-%x already in use\n",
CardType[card->typ],
cs->hw.ix1.cfg_reg,
cs->hw.ix1.cfg_reg + 4);
return (0);
} else
request_region(cs->hw.ix1.cfg_reg, 4, "ix1micro cfg");
}
if (!request_io(&cs->rs, cs->hw.ix1.cfg_reg, 4, "ix1micro cfg"))
goto err;
printk(KERN_INFO
"HiSax: %s config irq:%d io:0x%X\n",
CardType[cs->typ], cs->irq,
......@@ -271,8 +256,10 @@ setup_ix1micro(struct IsdnCard *card)
if (HscxVersion(cs, "ix1-Micro:")) {
printk(KERN_WARNING
"ix1-Micro: wrong HSCX versions check IO address\n");
ix1_release(cs);
return (0);
goto err;
}
return (1);
return 1;
err:
hisax_release_resources(cs);
return 0;
}
......@@ -132,13 +132,6 @@ static struct bc_hw_ops hscx_ops = {
.write_fifo = hscx_write_fifo,
};
static void
mic_release(struct IsdnCardState *cs)
{
if (cs->hw.mic.cfg_reg)
release_region(cs->hw.mic.cfg_reg, 8);
}
static int
mic_card_msg(struct IsdnCardState *cs, int mt, void *arg)
{
......@@ -147,14 +140,13 @@ mic_card_msg(struct IsdnCardState *cs, int mt, void *arg)
static struct card_ops mic_ops = {
.init = inithscxisac,
.release = mic_release,
.release = hisax_release_resources,
.irq_func = hscxisac_irq,
};
int __init
setup_mic(struct IsdnCard *card)
{
int bytecnt;
struct IsdnCardState *cs = card->cs;
char tmp[64];
......@@ -163,22 +155,15 @@ setup_mic(struct IsdnCard *card)
if (cs->typ != ISDN_CTYPE_MIC)
return (0);
bytecnt = 8;
cs->hw.mic.cfg_reg = card->para[1];
cs->irq = card->para[0];
cs->hw.mic.adr = cs->hw.mic.cfg_reg + MIC_ADR;
cs->hw.mic.isac = cs->hw.mic.cfg_reg + MIC_ISAC;
cs->hw.mic.hscx = cs->hw.mic.cfg_reg + MIC_HSCX;
if (!request_region((cs->hw.mic.cfg_reg), bytecnt, "mic isdn")) {
printk(KERN_WARNING
"HiSax: %s config port %x-%x already in use\n",
CardType[card->typ],
cs->hw.mic.cfg_reg,
cs->hw.mic.cfg_reg + bytecnt);
return (0);
}
if (!request_io(&cs->rs, cs->hw.mic.cfg_reg, 8, "mic isdn"))
goto err;
printk(KERN_INFO
"mic: defined at 0x%x IRQ %d\n",
cs->hw.mic.cfg_reg,
......@@ -191,8 +176,10 @@ setup_mic(struct IsdnCard *card)
if (HscxVersion(cs, "mic:")) {
printk(KERN_WARNING
"mic: wrong HSCX versions check IO address\n");
mic_release(cs);
return (0);
goto err;
}
return (1);
return 1;
err:
hisax_release_resources(cs);
return 0;
}
......@@ -1029,6 +1029,6 @@ netjet_release(struct IsdnCardState *cs)
byteout(cs->hw.njet.base + NETJET_IRQMASK0, 0);
byteout(cs->hw.njet.base + NETJET_IRQMASK1, 0);
releasetiger(cs);
release_region(cs->hw.njet.base, 256);
hisax_release_resources(cs);
}
......@@ -175,12 +175,8 @@ niccy_release(struct IsdnCardState *cs)
val = inl(cs->hw.niccy.cfg_reg + PCI_IRQ_CTRL_REG);
val &= PCI_IRQ_DISABLE;
outl(val, cs->hw.niccy.cfg_reg + PCI_IRQ_CTRL_REG);
release_region(cs->hw.niccy.cfg_reg, 0x40);
release_region(cs->hw.niccy.isac, 4);
} else {
release_region(cs->hw.niccy.isac, 2);
release_region(cs->hw.niccy.isac_ale, 2);
}
hisax_release_resources(cs);
}
static int
......@@ -265,23 +261,10 @@ setup_niccy(struct IsdnCard *card)
cs->hw.niccy.cfg_reg = 0;
cs->subtyp = NICCY_PNP;
cs->irq = card->para[0];
if (!request_region(cs->hw.niccy.isac, 2, "niccy data")) {
printk(KERN_WARNING
"HiSax: %s data port %x-%x already in use\n",
CardType[card->typ],
cs->hw.niccy.isac,
cs->hw.niccy.isac + 1);
return (0);
}
if (!request_region(cs->hw.niccy.isac_ale, 2, "niccy addr")) {
printk(KERN_WARNING
"HiSax: %s address port %x-%x already in use\n",
CardType[card->typ],
cs->hw.niccy.isac_ale,
cs->hw.niccy.isac_ale + 1);
release_region(cs->hw.niccy.isac, 2);
return (0);
}
if (!request_io(&cs->rs, cs->hw.niccy.isac, 2, "niccy data"))
goto err;
if (!request_io(&cs->rs, cs->hw.niccy.isac_ale, 2, "niccy addr"))
goto err;
} else {
#if CONFIG_PCI
u_int pci_ioaddr;
......@@ -320,23 +303,11 @@ setup_niccy(struct IsdnCard *card)
cs->hw.niccy.isac_ale = pci_ioaddr + ISAC_PCI_ADDR;
cs->hw.niccy.hscx = pci_ioaddr + HSCX_PCI_DATA;
cs->hw.niccy.hscx_ale = pci_ioaddr + HSCX_PCI_ADDR;
if (!request_region(cs->hw.niccy.isac, 4, "niccy")) {
printk(KERN_WARNING
"HiSax: %s data port %x-%x already in use\n",
CardType[card->typ],
cs->hw.niccy.isac,
cs->hw.niccy.isac + 4);
return (0);
}
if (!request_region(cs->hw.niccy.cfg_reg, 0x40, "niccy pci")) {
printk(KERN_WARNING
"HiSax: %s pci port %x-%x already in use\n",
CardType[card->typ],
cs->hw.niccy.cfg_reg,
cs->hw.niccy.cfg_reg + 0x40);
release_region(cs->hw.niccy.isac, 4);
return (0);
}
if (!request_io(&cs->rs, cs->hw.niccy.isac, 4, "niccy"))
goto err;
if (!request_io(&cs->rs, cs->hw.niccy.cfg_reg, 0x40, "niccy pci"))
goto err;
#else
printk(KERN_WARNING "Niccy: io0 0 and NO_PCI_BIOS\n");
printk(KERN_WARNING "Niccy: unable to config NICCY PCI\n");
......@@ -355,8 +326,9 @@ setup_niccy(struct IsdnCard *card)
if (HscxVersion(cs, "Niccy:")) {
printk(KERN_WARNING
"Niccy: wrong HSCX versions check IO address\n");
niccy_release(cs);
return (0);
}
return (1);
return 1;
err:
niccy_release(cs);
return 0;
}
......@@ -117,7 +117,6 @@ static struct pci_dev *dev_netjet __initdata = NULL;
int __init
setup_netjet_s(struct IsdnCard *card)
{
int bytecnt;
struct IsdnCardState *cs = card->cs;
char tmp[64];
......@@ -211,26 +210,17 @@ setup_netjet_s(struct IsdnCard *card)
#endif /* CONFIG_PCI */
bytecnt = 256;
printk(KERN_INFO
"NETjet-S: PCI card configured at %#lx IRQ %d\n",
cs->hw.njet.base, cs->irq);
if (check_region(cs->hw.njet.base, bytecnt)) {
printk(KERN_WARNING
"HiSax: %s config port %#lx-%#lx already in use\n",
CardType[card->typ],
cs->hw.njet.base,
cs->hw.njet.base + bytecnt);
return (0);
} else {
request_region(cs->hw.njet.base, bytecnt, "netjet-s isdn");
}
if (!request_io(&cs->rs, cs->hw.njet.base, 0x100, "netjet-s isdn"))
return 0;
nj_s_reset(cs);
cs->dc_hw_ops = &netjet_dc_ops;
cs->cardmsg = &NETjet_S_card_msg;
cs->irq_flags |= SA_SHIRQ;
cs->card_ops = &nj_s_ops;
ISACVersion(cs, "NETjet-S:");
return (1);
return 1;
}
......@@ -121,7 +121,6 @@ static struct pci_dev *dev_netjet __initdata = NULL;
int __init
setup_netjet_u(struct IsdnCard *card)
{
int bytecnt;
struct IsdnCardState *cs = card->cs;
char tmp[64];
#if CONFIG_PCI
......@@ -209,24 +208,17 @@ setup_netjet_u(struct IsdnCard *card)
#endif /* CONFIG_PCI */
bytecnt = 256;
printk(KERN_INFO
"NETspider-U: PCI card configured at %#lx IRQ %d\n",
cs->hw.njet.base, cs->irq);
if (!request_region(cs->hw.njet.base, bytecnt, "netspider-u isdn")) {
printk(KERN_WARNING
"HiSax: %s config port %#lx-%#lx already in use\n",
CardType[card->typ],
cs->hw.njet.base,
cs->hw.njet.base + bytecnt);
return (0);
}
if (!request_io(&cs->rs, cs->hw.njet.base, 0x100, "netjet-s isdn"))
return 0;
nj_u_reset(cs);
cs->dc_hw_ops = &netjet_dc_ops;
cs->cardmsg = &NETjet_U_card_msg;
cs->irq_flags |= SA_SHIRQ;
cs->card_ops = &nj_u_ops;
ICCVersion(cs, "NETspider-U:");
return (1);
return 1;
}
......@@ -166,12 +166,6 @@ static struct bc_hw_ops hscx_ops = {
.write_fifo = hscx_write_fifo,
};
void
s0box_release(struct IsdnCardState *cs)
{
release_region(cs->hw.teles3.cfg_reg, 8);
}
static int
S0Box_card_msg(struct IsdnCardState *cs, int mt, void *arg)
{
......@@ -180,7 +174,7 @@ S0Box_card_msg(struct IsdnCardState *cs, int mt, void *arg)
static struct card_ops s0box_ops = {
.init = inithscxisac,
.release = s0box_release,
.release = hisax_release_resources,
.irq_func = hscxisac_irq,
};
......@@ -203,14 +197,8 @@ setup_s0box(struct IsdnCard *card)
cs->hw.teles3.hscxfifo[0] = cs->hw.teles3.hscx[0] + 0x3e;
cs->hw.teles3.hscxfifo[1] = cs->hw.teles3.hscx[1] + 0x3e;
cs->irq = card->para[0];
if (!request_region(cs->hw.teles3.cfg_reg,8, "S0Box parallel I/O")) {
printk(KERN_WARNING
"HiSax: %s ports %x-%x already in use\n",
CardType[cs->typ],
cs->hw.teles3.cfg_reg,
cs->hw.teles3.cfg_reg + 7);
return 0;
}
if (!request_io(&cs->rs, cs->hw.teles3.cfg_reg, 8, "S0Box parallel I/O"))
goto err;
printk(KERN_INFO
"HiSax: %s config irq:%d isac:0x%x cfg:0x%x\n",
CardType[cs->typ], cs->irq,
......@@ -226,8 +214,10 @@ setup_s0box(struct IsdnCard *card)
if (HscxVersion(cs, "S0Box:")) {
printk(KERN_WARNING
"S0Box: wrong HSCX versions check IO address\n");
s0box_release(cs);
return (0);
goto err;
}
return (1);
return 1;
err:
hisax_release_resources(cs);
return 0;
}
......@@ -155,8 +155,7 @@ saphir_release(struct IsdnCardState *cs)
byteout(cs->hw.saphir.cfg_reg + IRQ_REG, 0xff);
del_timer_sync(&cs->hw.saphir.timer);
cs->hw.saphir.timer.function = NULL;
if (cs->hw.saphir.cfg_reg)
release_region(cs->hw.saphir.cfg_reg, 6);
hisax_release_resources(cs);
}
static int
......@@ -219,20 +218,15 @@ setup_saphir(struct IsdnCard *card)
if (cs->typ != ISDN_CTYPE_HSTSAPHIR)
return (0);
init_timer(&cs->hw.saphir.timer);
/* IO-Ports */
cs->hw.saphir.cfg_reg = card->para[1];
cs->hw.saphir.isac = card->para[1] + ISAC_DATA;
cs->hw.saphir.hscx = card->para[1] + HSCX_DATA;
cs->hw.saphir.ale = card->para[1] + ADDRESS_REG;
cs->irq = card->para[0];
if (!request_region((cs->hw.saphir.cfg_reg), 6, "saphir")) {
printk(KERN_WARNING
"HiSax: %s config port %x-%x already in use\n",
CardType[card->typ],
cs->hw.saphir.cfg_reg,
cs->hw.saphir.cfg_reg + 5);
return (0);
}
if (!request_io(&cs->rs, cs->hw.saphir.cfg_reg, 6, "saphir"))
goto err;
printk(KERN_INFO
"HiSax: %s config irq:%d io:0x%X\n",
......@@ -241,12 +235,10 @@ setup_saphir(struct IsdnCard *card)
cs->hw.saphir.timer.function = (void *) SaphirWatchDog;
cs->hw.saphir.timer.data = (long) cs;
init_timer(&cs->hw.saphir.timer);
cs->hw.saphir.timer.expires = jiffies + 4*HZ;
add_timer(&cs->hw.saphir.timer);
if (saphir_reset(cs)) {
saphir_release(cs);
return (0);
goto err;
}
cs->dc_hw_ops = &isac_ops;
cs->bc_hw_ops = &hscx_ops;
......@@ -256,8 +248,10 @@ setup_saphir(struct IsdnCard *card)
if (HscxVersion(cs, "saphir:")) {
printk(KERN_WARNING
"saphir: wrong HSCX versions check IO address\n");
saphir_release(cs);
return (0);
goto err;
}
return (1);
return 1;
err:
saphir_release(cs);
return 0;
}
......@@ -390,20 +390,6 @@ sedlbauer_reset(struct IsdnCardState *cs)
return 0;
}
static void
sedlbauer_release(struct IsdnCardState *cs)
{
int bytecnt = 8;
if (cs->subtyp == SEDL_SPEED_FAX) {
bytecnt = 16;
} else if (cs->hw.sedl.bus == SEDL_BUS_PCI) {
bytecnt = 256;
}
if (cs->hw.sedl.cfg_reg)
release_region(cs->hw.sedl.cfg_reg, bytecnt);
}
static void
sedlbauer_isar_release(struct IsdnCardState *cs)
{
......@@ -412,7 +398,7 @@ sedlbauer_isar_release(struct IsdnCardState *cs)
sedlbauer_reset(cs);
isar_write(cs, 0, ISAR_IRQBIT, 0);
isac_write(cs, ISAC_MASK, 0xFF);
sedlbauer_release(cs);
hisax_release_resources(cs);
}
static int
......@@ -452,14 +438,14 @@ sedlbauer_isar_init(struct IsdnCardState *cs)
static struct card_ops sedlbauer_ops = {
.init = inithscxisac,
.reset = sedlbauer_reset,
.release = sedlbauer_release,
.release = hisax_release_resources,
.irq_func = sedlbauer_interrupt,
};
static struct card_ops sedlbauer_ipac_ops = {
.init = ipac_init,
.reset = sedlbauer_reset,
.release = sedlbauer_release,
.release = hisax_release_resources,
.irq_func = ipac_irq,
};
......@@ -546,7 +532,7 @@ setup_sedlbauer(struct IsdnCard *card)
printk(KERN_ERR "Sedlbauer PnP:some resources are missing %ld/%lx\n",
card->para[0], card->para[1]);
pd->deactivate(pd);
return(0);
goto err;
}
cs->hw.sedl.cfg_reg = card->para[1];
cs->irq = card->para[0];
......@@ -561,7 +547,7 @@ setup_sedlbauer(struct IsdnCard *card)
goto ready;
} else {
printk(KERN_ERR "Sedlbauer PnP: PnP error card found, no device\n");
return(0);
goto err;
}
}
pdev++;
......@@ -576,21 +562,21 @@ setup_sedlbauer(struct IsdnCard *card)
#if CONFIG_PCI
if (!pci_present()) {
printk(KERN_ERR "Sedlbauer: no PCI bus present\n");
return(0);
goto err;
}
if ((dev_sedl = pci_find_device(PCI_VENDOR_ID_TIGERJET,
PCI_DEVICE_ID_TIGERJET_100, dev_sedl))) {
if (pci_enable_device(dev_sedl))
return(0);
goto err;
cs->irq = dev_sedl->irq;
if (!cs->irq) {
printk(KERN_WARNING "Sedlbauer: No IRQ for PCI card found\n");
return(0);
goto err;
}
cs->hw.sedl.cfg_reg = pci_resource_start(dev_sedl, 0);
} else {
printk(KERN_WARNING "Sedlbauer: No PCI card found\n");
return(0);
goto err;
}
cs->irq_flags |= SA_SHIRQ;
cs->hw.sedl.bus = SEDL_BUS_PCI;
......@@ -602,7 +588,7 @@ setup_sedlbauer(struct IsdnCard *card)
cs->hw.sedl.cfg_reg);
if (sub_id != PCI_SUB_ID_SEDLBAUER) {
printk(KERN_ERR "Sedlbauer: unknown sub id %#x\n", sub_id);
return(0);
goto err;
}
if (sub_vendor_id == PCI_SUBVENDOR_SPEEDFAX_PYRAMID) {
cs->hw.sedl.chip = SEDL_CHIP_ISAC_ISAR;
......@@ -616,7 +602,7 @@ setup_sedlbauer(struct IsdnCard *card)
} else {
printk(KERN_ERR "Sedlbauer: unknown sub vendor id %#x\n",
sub_vendor_id);
return(0);
goto err;
}
bytecnt = 256;
cs->hw.sedl.reset_on = SEDL_ISAR_PCI_ISAR_RESET_ON;
......@@ -631,7 +617,7 @@ setup_sedlbauer(struct IsdnCard *card)
byteout(cs->hw.sedl.cfg_reg +3, cs->hw.sedl.reset_off);
#else
printk(KERN_WARNING "Sedlbauer: NO_PCI_BIOS\n");
return (0);
goto err;
#endif /* CONFIG_PCI */
}
ready:
......@@ -639,14 +625,9 @@ setup_sedlbauer(struct IsdnCard *card)
* reserved for us by the card manager. So we do not check it
* here, it would fail.
*/
if (cs->hw.sedl.bus != SEDL_BUS_PCMCIA &&
(!request_region((cs->hw.sedl.cfg_reg), bytecnt, "sedlbauer isdn"))) {
printk(KERN_WARNING
"HiSax: %s config port %x-%x already in use\n",
CardType[card->typ],
cs->hw.sedl.cfg_reg,
cs->hw.sedl.cfg_reg + bytecnt);
return (0);
if (cs->hw.sedl.bus != SEDL_BUS_PCMCIA) {
if (!request_io(&cs->rs, cs->hw.sedl.cfg_reg, bytecnt, "sedlbauer isdn"))
goto err;
}
printk(KERN_INFO
......@@ -740,8 +721,7 @@ setup_sedlbauer(struct IsdnCard *card)
if (ver < 0) {
printk(KERN_WARNING
"Sedlbauer: wrong ISAR version (ret = %d)\n", ver);
sedlbauer_release(cs);
return (0);
goto err;
}
} else {
if (cs->hw.sedl.bus == SEDL_BUS_PCMCIA) {
......@@ -764,11 +744,13 @@ setup_sedlbauer(struct IsdnCard *card)
if (HscxVersion(cs, "Sedlbauer:")) {
printk(KERN_WARNING
"Sedlbauer: wrong HSCX versions check IO address\n");
sedlbauer_release(cs);
return (0);
goto err;
}
sedlbauer_reset(cs);
}
}
return (1);
return 1;
err:
hisax_release_resources(cs);
return 0;
}
......@@ -170,7 +170,7 @@ static struct card_ops sportster_ops = {
static int __init
get_io_range(struct IsdnCardState *cs)
{
int i, j, adr;
int i, adr;
for (i=0;i<64;i++) {
adr = cs->hw.spt.cfg_reg + i *1024;
......@@ -178,20 +178,18 @@ get_io_range(struct IsdnCardState *cs)
printk(KERN_WARNING
"HiSax: %s config port %x-%x already in use\n",
CardType[cs->typ], adr, adr + 8);
break;
goto err;
}
}
if (i==64)
return(1);
else {
for (j=0; j<i; j++) {
adr = cs->hw.spt.cfg_reg + j *1024;
release_region(adr, 8);
}
return(0);
return 1;
err:
for (i=i-1; i >= 0; i--) {
adr = cs->hw.spt.cfg_reg + i *1024;
release_region(adr, 8);
}
return 0;
}
int __init
setup_sportster(struct IsdnCard *card)
{
......
......@@ -222,8 +222,7 @@ teleint_release(struct IsdnCardState *cs)
{
del_timer(&cs->hw.hfc.timer);
releasehfc(cs);
if (cs->hw.hfc.addr)
release_region(cs->hw.hfc.addr, 2);
hisax_release_resources(cs);
}
static int
......@@ -286,16 +285,9 @@ setup_TeleInt(struct IsdnCard *card)
cs->hw.hfc.timer.function = (void *) TeleInt_Timer;
cs->hw.hfc.timer.data = (long) cs;
init_timer(&cs->hw.hfc.timer);
if (check_region((cs->hw.hfc.addr), 2)) {
printk(KERN_WARNING
"HiSax: %s config port %x-%x already in use\n",
CardType[card->typ],
cs->hw.hfc.addr,
cs->hw.hfc.addr + 2);
return (0);
} else {
request_region(cs->hw.hfc.addr, 2, "TeleInt isdn");
}
if (!request_io(&cs->rs, cs->hw.hfc.addr, 2, "TeleInt isdn"))
goto err;
/* HW IO = IO */
byteout(cs->hw.hfc.addr, cs->hw.hfc.addr & 0xff);
byteout(cs->hw.hfc.addr | 1, ((cs->hw.hfc.addr & 0x300) >> 8) | 0x54);
......@@ -320,8 +312,7 @@ setup_TeleInt(struct IsdnCard *card)
break;
default:
printk(KERN_WARNING "TeleInt: wrong IRQ\n");
teleint_release(cs);
return (0);
goto err;
}
byteout(cs->hw.hfc.addr | 1, cs->hw.hfc.cirm);
byteout(cs->hw.hfc.addr | 1, cs->hw.hfc.ctmt);
......@@ -337,5 +328,8 @@ setup_TeleInt(struct IsdnCard *card)
cs->cardmsg = &TeleInt_card_msg;
cs->card_ops = &teleint_ops;
ISACVersion(cs, "TeleInt:");
return (1);
return 1;
err:
teleint_release(cs);
return 0;
}
......@@ -48,7 +48,7 @@ static void
isac_read_fifo(struct IsdnCardState *cs, u8 * data, int size)
{
int i;
unsigned long ad = cs->hw.teles0.membase + 0x100;
void *ad = cs->hw.teles0.membase + 0x100;
for (i = 0; i < size; i++)
data[i] = readb(ad);
}
......@@ -57,7 +57,7 @@ static void
isac_write_fifo(struct IsdnCardState *cs, u8 * data, int size)
{
int i;
unsigned long ad = cs->hw.teles0.membase + 0x100;
void *ad = cs->hw.teles0.membase + 0x100;
for (i = 0; i < size; i++) {
writeb(data[i], ad); mb();
}
......@@ -88,7 +88,7 @@ static void
hscx_read_fifo(struct IsdnCardState *cs, int hscx, u8 *data, int size)
{
int i;
unsigned long ad = cs->hw.teles0.membase + (hscx ? 0x1c0 : 0x180);
void *ad = cs->hw.teles0.membase + (hscx ? 0x1c0 : 0x180);
for (i = 0; i < size; i++)
data[i] = readb(ad);
}
......@@ -97,7 +97,7 @@ static void
hscx_write_fifo(struct IsdnCardState *cs, int hscx, u8 *data, int size)
{
int i;
unsigned long ad = cs->hw.teles0.membase + (hscx ? 0x1c0 : 0x180);
void *ad = cs->hw.teles0.membase + (hscx ? 0x1c0 : 0x180);
for (i = 0; i < size; i++) {
writeb(data[i], ad);
}
......@@ -110,15 +110,6 @@ static struct bc_hw_ops hscx_ops = {
.write_fifo = hscx_write_fifo,
};
static void
teles0_release(struct IsdnCardState *cs)
{
if (cs->hw.teles0.cfg_reg)
release_region(cs->hw.teles0.cfg_reg, 8);
iounmap((unsigned char *)cs->hw.teles0.membase);
release_mem_region(cs->hw.teles0.phymem, TELES_IOMEM_SIZE);
}
static int
teles0_reset(struct IsdnCardState *cs)
{
......@@ -176,7 +167,7 @@ Teles_card_msg(struct IsdnCardState *cs, int mt, void *arg)
static struct card_ops teles0_ops = {
.init = inithscxisac,
.reset = teles0_reset,
.release = teles0_release,
.release = hisax_release_resources,
.irq_func = hscxisac_irq,
};
......@@ -205,65 +196,43 @@ setup_teles0(struct IsdnCard *card)
}
cs->irq = card->para[0];
if (cs->hw.teles0.cfg_reg) {
if (!request_region(cs->hw.teles0.cfg_reg, 8, "teles cfg")) {
printk(KERN_WARNING
"HiSax: %s config port %x-%x already in use\n",
CardType[card->typ],
cs->hw.teles0.cfg_reg,
cs->hw.teles0.cfg_reg + 8);
return (0);
}
}
if (cs->hw.teles0.cfg_reg) {
if (!request_io(&cs->rs, cs->hw.teles0.cfg_reg, 8, "teles cfg"))
goto err;
if ((val = bytein(cs->hw.teles0.cfg_reg + 0)) != 0x51) {
printk(KERN_WARNING "Teles0: 16.0 Byte at %x is %x\n",
cs->hw.teles0.cfg_reg + 0, val);
release_region(cs->hw.teles0.cfg_reg, 8);
return (0);
goto err;
}
if ((val = bytein(cs->hw.teles0.cfg_reg + 1)) != 0x93) {
printk(KERN_WARNING "Teles0: 16.0 Byte at %x is %x\n",
cs->hw.teles0.cfg_reg + 1, val);
release_region(cs->hw.teles0.cfg_reg, 8);
return (0);
goto err;
}
val = bytein(cs->hw.teles0.cfg_reg + 2); /* 0x1e=without AB
* 0x1f=with AB
* 0x1c 16.3 ???
*/
val = bytein(cs->hw.teles0.cfg_reg + 2);/* 0x1e=without AB
* 0x1f=with AB
* 0x1c 16.3 ???
*/
if (val != 0x1e && val != 0x1f) {
printk(KERN_WARNING "Teles0: 16.0 Byte at %x is %x\n",
cs->hw.teles0.cfg_reg + 2, val);
release_region(cs->hw.teles0.cfg_reg, 8);
return (0);
goto err;
}
}
/* 16.0 and 8.0 designed for IOM1 */
test_and_set_bit(HW_IOM1, &cs->HW_Flags);
cs->hw.teles0.phymem = card->para[1];
if (check_mem_region(cs->hw.teles0.phymem, TELES_IOMEM_SIZE)) {
printk(KERN_WARNING
"HiSax: %s memory region %lx-%lx already in use\n",
CardType[card->typ],
cs->hw.teles0.phymem,
cs->hw.teles0.phymem + TELES_IOMEM_SIZE);
if (cs->hw.teles0.cfg_reg)
release_region(cs->hw.teles0.cfg_reg, 8);
return (0);
} else {
request_mem_region(cs->hw.teles0.phymem, TELES_IOMEM_SIZE,
"teles iomem");
}
cs->hw.teles0.membase =
(unsigned long) ioremap(cs->hw.teles0.phymem, TELES_IOMEM_SIZE);
cs->hw.teles0.membase = request_mmio(&cs->rs, cs->hw.teles0.phymem, TELES_IOMEM_SIZE, "teles iomem");
if (!cs->hw.teles0.membase)
goto err;
printk(KERN_INFO
"HiSax: %s config irq:%d mem:0x%lX cfg:0x%X\n",
"HiSax: %s config irq:%d mem:0x%p cfg:0x%X\n",
CardType[cs->typ], cs->irq,
cs->hw.teles0.membase, cs->hw.teles0.cfg_reg);
if (teles0_reset(cs)) {
printk(KERN_WARNING "Teles0: wrong IRQ\n");
teles0_release(cs);
return (0);
goto err;
}
cs->dc_hw_ops = &isac_ops;
cs->bc_hw_ops = &hscx_ops;
......@@ -273,8 +242,11 @@ setup_teles0(struct IsdnCard *card)
if (HscxVersion(cs, "Teles0:")) {
printk(KERN_WARNING
"Teles0: wrong HSCX versions check IO/MEM addresses\n");
teles0_release(cs);
return (0);
goto err;
}
return (1);
err:
hisax_release_resources(cs);
return 0;
}
......@@ -113,34 +113,6 @@ static struct bc_hw_ops hscx_ops = {
.write_fifo = hscx_write_fifo,
};
inline static void
release_ioregs(struct IsdnCardState *cs, int mask)
{
if (mask & 1)
release_region(cs->hw.teles3.isac + 32, 32);
if (mask & 2)
release_region(cs->hw.teles3.hscx[0] + 32, 32);
if (mask & 4)
release_region(cs->hw.teles3.hscx[1] + 32, 32);
}
static void
teles3_release(struct IsdnCardState *cs)
{
if (cs->typ == ISDN_CTYPE_TELESPCMCIA) {
release_region(cs->hw.teles3.hscx[1], 96);
} else {
if (cs->hw.teles3.cfg_reg) {
if (cs->typ == ISDN_CTYPE_COMPAQ_ISA) {
release_region(cs->hw.teles3.cfg_reg, 1);
} else {
release_region(cs->hw.teles3.cfg_reg, 8);
}
}
release_ioregs(cs, 0x7);
}
}
static int
teles3_reset(struct IsdnCardState *cs)
{
......@@ -206,7 +178,7 @@ Teles_card_msg(struct IsdnCardState *cs, int mt, void *arg)
static struct card_ops teles3_ops = {
.init = inithscxisac,
.reset = teles3_reset,
.release = teles3_release,
.release = hisax_release_resources,
.irq_func = hscxisac_irq,
};
......@@ -315,95 +287,35 @@ setup_teles3(struct IsdnCard *card)
cs->hw.teles3.hscxfifo[0] = cs->hw.teles3.hscx[0] + 0x3e;
cs->hw.teles3.hscxfifo[1] = cs->hw.teles3.hscx[1] + 0x3e;
if (cs->typ == ISDN_CTYPE_TELESPCMCIA) {
if (!request_region(cs->hw.teles3.hscx[1], 96, "HiSax Teles PCMCIA")) {
printk(KERN_WARNING
"HiSax: %s ports %x-%x already in use\n",
CardType[cs->typ],
cs->hw.teles3.hscx[1],
cs->hw.teles3.hscx[1] + 96);
return (0);
}
if (!request_io(&cs->rs, cs->hw.teles3.hscx[1], 96, "HiSax Teles PCMCIA"))
goto err;
} else {
if (cs->hw.teles3.cfg_reg) {
if (cs->typ == ISDN_CTYPE_COMPAQ_ISA) {
if (!request_region(cs->hw.teles3.cfg_reg, 1, "teles3 cfg")) {
printk(KERN_WARNING
"HiSax: %s config port %x already in use\n",
CardType[card->typ],
cs->hw.teles3.cfg_reg);
return (0);
}
if (!request_io(&cs->rs, cs->hw.teles3.cfg_reg, 1, "teles3 cfg"))
goto err;
} else {
if (!request_region(cs->hw.teles3.cfg_reg, 8, "teles3 cfg")) {
printk(KERN_WARNING
"HiSax: %s config port %x-%x already in use\n",
CardType[card->typ],
cs->hw.teles3.cfg_reg,
cs->hw.teles3.cfg_reg + 8);
return (0);
}
}
}
if (!request_region(cs->hw.teles3.isac + 32, 32, "HiSax isac")) {
printk(KERN_WARNING
"HiSax: %s isac ports %x-%x already in use\n",
CardType[cs->typ],
cs->hw.teles3.isac + 32,
cs->hw.teles3.isac + 64);
if (cs->hw.teles3.cfg_reg) {
if (cs->typ == ISDN_CTYPE_COMPAQ_ISA) {
release_region(cs->hw.teles3.cfg_reg, 1);
} else {
release_region(cs->hw.teles3.cfg_reg, 8);
}
}
return (0);
}
if (!request_region(cs->hw.teles3.hscx[0] + 32, 32, "HiSax hscx A")) {
printk(KERN_WARNING
"HiSax: %s hscx A ports %x-%x already in use\n",
CardType[cs->typ],
cs->hw.teles3.hscx[0] + 32,
cs->hw.teles3.hscx[0] + 64);
if (cs->hw.teles3.cfg_reg) {
if (cs->typ == ISDN_CTYPE_COMPAQ_ISA) {
release_region(cs->hw.teles3.cfg_reg, 1);
} else {
release_region(cs->hw.teles3.cfg_reg, 8);
}
}
release_ioregs(cs, 1);
return (0);
}
if (!request_region(cs->hw.teles3.hscx[1] + 32, 32, "HiSax hscx B")) {
printk(KERN_WARNING
"HiSax: %s hscx B ports %x-%x already in use\n",
CardType[cs->typ],
cs->hw.teles3.hscx[1] + 32,
cs->hw.teles3.hscx[1] + 64);
if (cs->hw.teles3.cfg_reg) {
if (cs->typ == ISDN_CTYPE_COMPAQ_ISA) {
release_region(cs->hw.teles3.cfg_reg, 1);
} else {
release_region(cs->hw.teles3.cfg_reg, 8);
}
if (!request_io(&cs->rs, cs->hw.teles3.cfg_reg, 8, "teles3 cfg"))
goto err;
}
release_ioregs(cs, 3);
return (0);
}
if (!request_io(&cs->rs, cs->hw.teles3.isac + 32, 32, "HiSax isac"))
goto err;
if (!request_io(&cs->rs, cs->hw.teles3.hscx[0] + 32, 32, "HiSax hscx A"))
goto err;
if (!request_io(&cs->rs, cs->hw.teles3.hscx[1] + 32, 32, "HiSax hscx B"))
goto err;
}
if ((cs->hw.teles3.cfg_reg) && (cs->typ != ISDN_CTYPE_COMPAQ_ISA)) {
if ((val = bytein(cs->hw.teles3.cfg_reg + 0)) != 0x51) {
printk(KERN_WARNING "Teles: 16.3 Byte at %x is %x\n",
cs->hw.teles3.cfg_reg + 0, val);
teles3_release(cs);
return (0);
goto err;
}
if ((val = bytein(cs->hw.teles3.cfg_reg + 1)) != 0x93) {
printk(KERN_WARNING "Teles: 16.3 Byte at %x is %x\n",
cs->hw.teles3.cfg_reg + 1, val);
teles3_release(cs);
return (0);
goto err;
}
val = bytein(cs->hw.teles3.cfg_reg + 2);/* 0x1e=without AB
* 0x1f=with AB
......@@ -415,8 +327,7 @@ setup_teles3(struct IsdnCard *card)
if (val != 0x46 && val != 0x39 && val != 0x38 && val != 0x1c && val != 0x1e && val != 0x1f) {
printk(KERN_WARNING "Teles: 16.3 Byte at %x is %x\n",
cs->hw.teles3.cfg_reg + 2, val);
teles3_release(cs);
return (0);
goto err;
}
}
printk(KERN_INFO
......@@ -429,8 +340,7 @@ setup_teles3(struct IsdnCard *card)
if (teles3_reset(cs)) {
printk(KERN_WARNING "Teles3: wrong IRQ\n");
teles3_release(cs);
return (0);
goto err;
}
cs->dc_hw_ops = &isac_ops;
cs->bc_hw_ops = &hscx_ops;
......@@ -440,8 +350,11 @@ setup_teles3(struct IsdnCard *card)
if (HscxVersion(cs, "Teles3:")) {
printk(KERN_WARNING
"Teles3: wrong HSCX versions check IO address\n");
teles3_release(cs);
return (0);
goto err;
}
return (1);
err:
hisax_release_resources(cs);
return (0);
}
......@@ -45,7 +45,7 @@ const char *telespci_revision = "$Revision: 2.16.6.5 $";
static u8
isac_read(struct IsdnCardState *cs, u8 off)
{
unsigned long adr = cs->hw.teles0.membase + 0x200;
void *adr = cs->hw.teles0.membase + 0x200;
unsigned int portdata;
ZORAN_WAIT_NOBUSY;
......@@ -63,7 +63,7 @@ isac_read(struct IsdnCardState *cs, u8 off)
static void
isac_write(struct IsdnCardState *cs, u8 off, u8 data)
{
unsigned long adr = cs->hw.teles0.membase + 0x200;
void *adr = cs->hw.teles0.membase + 0x200;
unsigned int portdata;
ZORAN_WAIT_NOBUSY;
......@@ -80,7 +80,7 @@ isac_write(struct IsdnCardState *cs, u8 off, u8 data)
static void
isac_read_fifo(struct IsdnCardState *cs, u8 *data, int size)
{
unsigned long adr = cs->hw.teles0.membase + 0x200;
void *adr = cs->hw.teles0.membase + 0x200;
unsigned int portdata;
int i;
......@@ -99,7 +99,7 @@ isac_read_fifo(struct IsdnCardState *cs, u8 *data, int size)
static void
isac_write_fifo(struct IsdnCardState *cs, u8 *data, int size)
{
unsigned long adr = cs->hw.teles0.membase + 0x200;
void *adr = cs->hw.teles0.membase + 0x200;
unsigned int portdata;
int i;
......@@ -124,7 +124,7 @@ static struct dc_hw_ops isac_ops = {
static u8
hscx_read(struct IsdnCardState *cs, int hscx, u8 off)
{
unsigned long adr = cs->hw.teles0.membase + 0x200;
void *adr = cs->hw.teles0.membase + 0x200;
unsigned int portdata;
ZORAN_WAIT_NOBUSY;
......@@ -141,7 +141,7 @@ hscx_read(struct IsdnCardState *cs, int hscx, u8 off)
static void
hscx_write(struct IsdnCardState *cs, int hscx, u8 off, u8 data)
{
unsigned long adr = cs->hw.teles0.membase + 0x200;
void *adr = cs->hw.teles0.membase + 0x200;
unsigned int portdata;
ZORAN_WAIT_NOBUSY;
......@@ -157,7 +157,7 @@ hscx_write(struct IsdnCardState *cs, int hscx, u8 off, u8 data)
static void
hscx_read_fifo(struct IsdnCardState *cs, int hscx, u8 * data, int size)
{
unsigned long adr = cs->hw.teles0.membase + 0x200;
void *adr = cs->hw.teles0.membase + 0x200;
unsigned int portdata;
int i;
......@@ -176,7 +176,7 @@ hscx_read_fifo(struct IsdnCardState *cs, int hscx, u8 * data, int size)
static void
hscx_write_fifo(struct IsdnCardState *cs, int hscx, u8 * data, int size)
{
unsigned long adr = cs->hw.teles0.membase + 0x200;
void *adr = cs->hw.teles0.membase + 0x200;
unsigned int portdata;
int i;
......@@ -271,7 +271,7 @@ setup_telespci(struct IsdnCard *card)
printk(KERN_WARNING "Teles: No IRQ for PCI card found\n");
return(0);
}
cs->hw.teles0.membase = (u_long) ioremap(pci_resource_start(dev_tel, 0),
cs->hw.teles0.membase = ioremap(pci_resource_start(dev_tel, 0),
PAGE_SIZE);
printk(KERN_INFO "Found: Zoran, base-address: 0x%lx, irq: 0x%x\n",
pci_resource_start(dev_tel, 0), dev_tel->irq);
......@@ -295,7 +295,7 @@ setup_telespci(struct IsdnCard *card)
/* writel(0x00800000, cs->hw.teles0.membase + 0x200); */
printk(KERN_INFO
"HiSax: %s config irq:%d mem:%lx\n",
"HiSax: %s config irq:%d mem:%p\n",
CardType[cs->typ], cs->irq,
cs->hw.teles0.membase);
......
......@@ -639,9 +639,9 @@ static void
w6692_release(struct IsdnCardState *cs)
{
w6692_write_reg(cs, W_IMASK, 0xff);
release_region(cs->hw.w6692.iobase, 256);
if (cs->subtyp == W6692_USR)
w6692_write_reg(cs, W_XDATA, 0x04);
hisax_release_resources(cs);
}
static int
......@@ -738,15 +738,9 @@ setup_w6692(struct IsdnCard *card)
printk(KERN_INFO "Found: %s %s, I/O base: 0x%x, irq: %d\n",
id_list[cs->subtyp].vendor_name, id_list[cs->subtyp].card_name,
pci_ioaddr, pci_irq);
if (!request_region((cs->hw.w6692.iobase), 256,
id_list[cs->subtyp].card_name)) {
printk(KERN_WARNING
"HiSax: %s I/O ports %x-%x already in use\n",
id_list[cs->subtyp].card_name,
cs->hw.w6692.iobase,
cs->hw.w6692.iobase + 255);
return (0);
}
if (!request_io(&cs->rs, cs->hw.w6692.iobase, 0x100, id_list[cs->subtyp].card_name))
return 0;
#else
printk(KERN_WARNING "HiSax: W6692 and NO_PCI_BIOS\n");
printk(KERN_WARNING "HiSax: W6692 unable to config\n");
......
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