- add remaining sysfs device links
- remove locks for request/free IRQ calls, make shure the HW irqs are disabled here
This commit is contained in:
parent
a6debe87e6
commit
f5a08ff371
|
@ -127,7 +127,16 @@ typedef struct hdlc_hw {
|
|||
|
||||
typedef struct _fritzpnppci {
|
||||
struct list_head list;
|
||||
void *pdev;
|
||||
union {
|
||||
#if defined(CONFIG_PNP)
|
||||
#ifdef NEW_ISAPNP
|
||||
struct pnp_dev *pnp;
|
||||
#else
|
||||
struct pci_dev *pnp;
|
||||
#endif
|
||||
#endif
|
||||
struct pci_dev *pci;
|
||||
} dev;
|
||||
u_int type;
|
||||
u_int irq;
|
||||
u_int irqcnt;
|
||||
|
@ -325,6 +334,20 @@ read_status(fritzpnppci *fc, int channel)
|
|||
return(0);
|
||||
}
|
||||
|
||||
static void
|
||||
enable_hwirq(fritzpnppci *fc)
|
||||
{
|
||||
fc->ctrlreg |= AVM_STATUS0_ENA_IRQ;
|
||||
outb(fc->ctrlreg, fc->addr + 2);
|
||||
}
|
||||
|
||||
static void
|
||||
disable_hwirq(fritzpnppci *fc)
|
||||
{
|
||||
fc->ctrlreg &= ~((u_char)AVM_STATUS0_ENA_IRQ);
|
||||
outb(fc->ctrlreg, fc->addr + 2);
|
||||
}
|
||||
|
||||
static int
|
||||
modehdlc(bchannel_t *bch, int bc, int protocol)
|
||||
{
|
||||
|
@ -816,18 +839,22 @@ reset_avmpcipnp(fritzpnppci *fc)
|
|||
break;
|
||||
}
|
||||
printk(KERN_INFO "AVM PCI/PnP: reset\n");
|
||||
outb(fc->ctrlreg, fc->addr + 2);
|
||||
disable_hwirq(fc);
|
||||
mdelay(5);
|
||||
switch (fc->type) {
|
||||
case AVM_FRITZ_PNP:
|
||||
fc->ctrlreg = AVM_STATUS0_DIS_TIMER | AVM_STATUS0_RES_TIMER;
|
||||
disable_hwirq(fc);
|
||||
outb(AVM_STATUS1_ENA_IOM | fc->irq, fc->addr + 3);
|
||||
break;
|
||||
case AVM_FRITZ_PCI:
|
||||
fc->ctrlreg = AVM_STATUS0_DIS_TIMER | AVM_STATUS0_RES_TIMER;
|
||||
outb(fc->ctrlreg, fc->addr + 2);
|
||||
outb(AVM_STATUS1_ENA_IOM | fc->irq, fc->addr + 3);
|
||||
disable_hwirq(fc);
|
||||
outb(AVM_STATUS1_ENA_IOM, fc->addr + 3);
|
||||
break;
|
||||
case AVM_FRITZ_PCIV2:
|
||||
fc->ctrlreg = 0;
|
||||
outb(fc->ctrlreg, fc->addr + 2);
|
||||
disable_hwirq(fc);
|
||||
break;
|
||||
}
|
||||
mdelay(1);
|
||||
|
@ -839,41 +866,40 @@ static int init_card(fritzpnppci *fc)
|
|||
int cnt = 3;
|
||||
u_int shared = SA_SHIRQ;
|
||||
u_long flags;
|
||||
u_char *id = "AVM Fritz!PCI";
|
||||
|
||||
if (fc->type == AVM_FRITZ_PNP)
|
||||
if (fc->type == AVM_FRITZ_PNP) {
|
||||
shared = 0;
|
||||
spin_lock_irqsave(&fc->lock, flags);
|
||||
id = "AVM Fritz!PnP";
|
||||
}
|
||||
reset_avmpcipnp(fc); /* disable IRQ */
|
||||
if (fc->type == AVM_FRITZ_PCIV2) {
|
||||
if (request_irq(fc->irq, avm_fritzv2_interrupt, SA_SHIRQ,
|
||||
"AVM Fritz!PCI", fc)) {
|
||||
if (request_irq(fc->irq, avm_fritzv2_interrupt, shared, id, fc)) {
|
||||
printk(KERN_WARNING "mISDN: couldn't get interrupt %d\n",
|
||||
fc->irq);
|
||||
spin_unlock_irqrestore(&fc->lock, flags);
|
||||
return(-EIO);
|
||||
}
|
||||
} else {
|
||||
if (request_irq(fc->irq, avm_fritz_interrupt, shared,
|
||||
"AVM Fritz!PCI", fc)) {
|
||||
if (request_irq(fc->irq, avm_fritz_interrupt, shared, id, fc)) {
|
||||
printk(KERN_WARNING "mISDN: couldn't get interrupt %d\n",
|
||||
fc->irq);
|
||||
spin_unlock_irqrestore(&fc->lock, flags);
|
||||
return(-EIO);
|
||||
}
|
||||
}
|
||||
reset_avmpcipnp(fc);
|
||||
while (cnt) {
|
||||
int ret;
|
||||
|
||||
spin_lock_irqsave(&fc->lock, flags);
|
||||
mISDN_clear_isac(&fc->dch);
|
||||
if ((ret=mISDN_isac_init(&fc->dch))) {
|
||||
printk(KERN_WARNING "mISDN: mISDN_isac_init failed with %d\n", ret);
|
||||
spin_unlock_irqrestore(&fc->lock, flags);
|
||||
break;
|
||||
}
|
||||
clear_pending_hdlc_ints(fc);
|
||||
inithdlc(fc);
|
||||
outb(fc->ctrlreg, fc->addr + 2);
|
||||
WriteISAC(fc, ISAC_MASK, 0);
|
||||
fc->ctrlreg |= AVM_STATUS0_ENA_IRQ;
|
||||
outb(fc->ctrlreg, fc->addr + 2);
|
||||
enable_hwirq(fc);
|
||||
/* RESET Receiver and Transmitter */
|
||||
WriteISAC(fc, ISAC_CMDR, 0x41);
|
||||
spin_unlock_irqrestore(&fc->lock, flags);
|
||||
|
@ -895,9 +921,7 @@ static int init_card(fritzpnppci *fc)
|
|||
} else {
|
||||
return(0);
|
||||
}
|
||||
spin_lock_irqsave(&fc->lock, flags);
|
||||
}
|
||||
spin_unlock_irqrestore(&fc->lock, flags);
|
||||
return(-EIO);
|
||||
}
|
||||
|
||||
|
@ -993,8 +1017,8 @@ release_card(fritzpnppci *card)
|
|||
{
|
||||
u_long flags;
|
||||
|
||||
disable_hwirq(card);
|
||||
spin_lock_irqsave(&card->lock, flags);
|
||||
outb(0, card->addr + 2);
|
||||
modehdlc(&card->bch[0], 0, ISDN_PID_NONE);
|
||||
modehdlc(&card->bch[1], 1, ISDN_PID_NONE);
|
||||
mISDN_isac_free(&card->dch);
|
||||
|
@ -1005,17 +1029,19 @@ release_card(fritzpnppci *card)
|
|||
mISDN_free_bch(&card->bch[1]);
|
||||
mISDN_free_bch(&card->bch[0]);
|
||||
mISDN_free_dch(&card->dch);
|
||||
fritz.ctrl(&card->dch.inst, MGR_UNREGLAYER | REQUEST, NULL);
|
||||
spin_unlock_irqrestore(&card->lock, flags);
|
||||
fritz.ctrl(&card->dch.inst, MGR_UNREGLAYER | REQUEST, NULL);
|
||||
spin_lock_irqsave(&fritz.lock, flags);
|
||||
list_del(&card->list);
|
||||
spin_unlock_irqrestore(&fritz.lock, flags);
|
||||
if (card->type == AVM_FRITZ_PNP) {
|
||||
pnp_disable_dev(card->pdev);
|
||||
pnp_set_drvdata(card->pdev, NULL);
|
||||
#if defined(CONFIG_PNP)
|
||||
pnp_disable_dev(card->dev.pnp);
|
||||
pnp_set_drvdata(card->dev.pnp, NULL);
|
||||
#endif
|
||||
} else {
|
||||
pci_disable_device(card->pdev);
|
||||
pci_set_drvdata(card->pdev, NULL);
|
||||
pci_disable_device(card->dev.pci);
|
||||
pci_set_drvdata(card->dev.pci, NULL);
|
||||
}
|
||||
kfree(card);
|
||||
}
|
||||
|
@ -1125,13 +1151,24 @@ static int __devinit setup_instance(fritzpnppci *card)
|
|||
int i, err;
|
||||
mISDN_pid_t pid;
|
||||
u_long flags;
|
||||
|
||||
struct device *dev;
|
||||
|
||||
if (card->type == AVM_FRITZ_PNP) {
|
||||
#if defined(CONFIG_PNP)
|
||||
dev = &card->dev.pnp->dev;
|
||||
#else
|
||||
dev = NULL;
|
||||
#endif
|
||||
} else {
|
||||
dev = &card->dev.pci->dev;
|
||||
}
|
||||
spin_lock_irqsave(&fritz.lock, flags);
|
||||
list_add_tail(&card->list, &fritz.ilist);
|
||||
spin_unlock_irqrestore(&fritz.lock, flags);
|
||||
card->dch.debug = debug;
|
||||
spin_lock_init(&card->lock);
|
||||
card->dch.inst.hwlock = &card->lock;
|
||||
card->dch.inst.class_dev.dev = dev;
|
||||
card->dch.inst.pid.layermask = ISDN_LAYER(0);
|
||||
card->dch.inst.pid.protocol[0] = ISDN_PID_L0_TE_S0;
|
||||
mISDN_init_instance(&card->dch.inst, &fritz, card, mISDN_ISAC_l1hw);
|
||||
|
@ -1143,6 +1180,7 @@ static int __devinit setup_instance(fritzpnppci *card)
|
|||
mISDN_init_instance(&card->bch[i].inst, &fritz, card, hdlc_down);
|
||||
card->bch[i].inst.pid.layermask = ISDN_LAYER(0);
|
||||
card->bch[i].inst.hwlock = &card->lock;
|
||||
card->bch[i].inst.class_dev.dev = dev;
|
||||
card->bch[i].debug = debug;
|
||||
sprintf(card->bch[i].inst.name, "%s B%d", card->dch.inst.name, i+1);
|
||||
mISDN_init_bch(&card->bch[i]);
|
||||
|
@ -1205,7 +1243,7 @@ static int __devinit fritzpci_probe(struct pci_dev *pdev, const struct pci_devic
|
|||
card->type = AVM_FRITZ_PCIV2;
|
||||
else
|
||||
card->type = AVM_FRITZ_PCI;
|
||||
card->pdev = pdev;
|
||||
card->dev.pci = pdev;
|
||||
err = pci_enable_device(pdev);
|
||||
if (err) {
|
||||
kfree(card);
|
||||
|
@ -1243,7 +1281,7 @@ static int __devinit fritzpnp_probe(struct pci_dev *pdev, const struct isapnp_de
|
|||
}
|
||||
memset(card, 0, sizeof(fritzpnppci));
|
||||
card->type = AVM_FRITZ_PNP;
|
||||
card->pdev = pdev;
|
||||
card->dev.pnp = pdev;
|
||||
pnp_disable_dev(pdev);
|
||||
err = pnp_activate_dev(pdev);
|
||||
if (err<0) {
|
||||
|
|
|
@ -231,6 +231,20 @@ MODULE_PARM(protocol, MODULE_PORTS_T);
|
|||
MODULE_PARM(layermask, MODULE_PORTS_T);
|
||||
#endif
|
||||
|
||||
static void
|
||||
enable_hwirq(hfc_multi_t *hc)
|
||||
{
|
||||
hc->hw.r_irq_ctrl |= V_GLOB_IRQ_EN;
|
||||
HFC_outb(hc, R_IRQ_CTRL, hc->hw.r_irq_ctrl);
|
||||
}
|
||||
|
||||
static void
|
||||
disable_hwirq(hfc_multi_t *hc)
|
||||
{
|
||||
hc->hw.r_irq_ctrl &= ~((u_char)V_GLOB_IRQ_EN);
|
||||
HFC_outb(hc, R_IRQ_CTRL, hc->hw.r_irq_ctrl);
|
||||
}
|
||||
|
||||
/******************************************/
|
||||
/* free hardware resources used by driver */
|
||||
/******************************************/
|
||||
|
@ -241,9 +255,8 @@ release_io_hfcmulti(hfc_multi_t *hc)
|
|||
if (debug & DEBUG_HFCMULTI_INIT)
|
||||
printk(KERN_DEBUG "%s: entered\n", __FUNCTION__);
|
||||
|
||||
/* irq off */
|
||||
HFC_outb(hc, R_IRQ_CTRL, 0);
|
||||
|
||||
disable_hwirq(hc);
|
||||
/* soft reset */
|
||||
hc->hw.r_cirm |= V_SRES;
|
||||
HFC_outb(hc, R_CIRM, hc->hw.r_cirm);
|
||||
|
@ -419,17 +432,17 @@ init_chip(hfc_multi_t *hc)
|
|||
val += HFC_inb(hc, R_F0_CNTH) << 8;
|
||||
if (debug & DEBUG_HFCMULTI_INIT)
|
||||
printk(KERN_DEBUG "HFC_multi F0_CNT %ld after status ok\n", val);
|
||||
spin_unlock_irqrestore(&hc->lock, flags);
|
||||
set_current_state(TASK_UNINTERRUPTIBLE);
|
||||
while (cnt < 50) { /* max 50 ms */
|
||||
spin_unlock_irqrestore(&hc->lock, flags);
|
||||
schedule_timeout((HZ*10)/1000); /* Timeout 10ms */
|
||||
spin_lock_irqsave(&hc->lock, flags);
|
||||
cnt+=10;
|
||||
val2 = HFC_inb(hc, R_F0_CNTL);
|
||||
val2 += HFC_inb(hc, R_F0_CNTH) << 8;
|
||||
if (val2 >= val+4) /* wait 4 pulses */
|
||||
break;
|
||||
}
|
||||
spin_lock_irqsave(&hc->lock, flags);
|
||||
if (debug & DEBUG_HFCMULTI_INIT)
|
||||
printk(KERN_DEBUG "HFC_multi F0_CNT %ld after %dms\n", val2, cnt);
|
||||
if (val2 < val+4) {
|
||||
|
@ -2643,9 +2656,6 @@ hfcmulti_initmode(hfc_multi_t *hc)
|
|||
HFC_outb(hc, R_E1_WR_STA, r_e1_wr_sta);
|
||||
|
||||
}
|
||||
|
||||
/* set interrupts & global interrupt */
|
||||
hc->hw.r_irq_ctrl = V_FIFO_IRQ | V_GLOB_IRQ_EN;
|
||||
spin_unlock_irqrestore(&hc->lock, flags);
|
||||
if (debug & DEBUG_HFCMULTI_INIT)
|
||||
printk("%s: done\n", __FUNCTION__);
|
||||
|
@ -2664,6 +2674,7 @@ init_card(hfc_multi_t *hc)
|
|||
{
|
||||
int cnt = 1; /* as long as there is no trouble */
|
||||
int err = -EIO;
|
||||
u_long flags;
|
||||
#ifdef CONFIG_PLX_PCI_BRIDGE
|
||||
u_short *plx_acc;
|
||||
#endif
|
||||
|
@ -2671,6 +2682,11 @@ init_card(hfc_multi_t *hc)
|
|||
if (debug & DEBUG_HFCMULTI_INIT)
|
||||
printk(KERN_DEBUG "%s: entered\n", __FUNCTION__);
|
||||
|
||||
spin_lock_irqsave(&hc->lock, flags);
|
||||
/* set interrupts but let global interrupt disabled*/
|
||||
hc->hw.r_irq_ctrl = V_FIFO_IRQ;
|
||||
disable_hwirq(hc);
|
||||
spin_unlock_irqrestore(&hc->lock, flags);
|
||||
if (request_irq(hc->pci_dev->irq, hfcmulti_interrupt, SA_SHIRQ, "HFC-multi", hc)) {
|
||||
printk(KERN_WARNING "mISDN: Could not get interrupt %d.\n", hc->pci_dev->irq);
|
||||
return(-EIO);
|
||||
|
@ -2691,12 +2707,16 @@ init_card(hfc_multi_t *hc)
|
|||
* this is only allowed, if an IRQ routine is allready
|
||||
* established for this HFC, so don't do that earlier
|
||||
*/
|
||||
HFC_outb(hc, R_IRQ_CTRL, V_GLOB_IRQ_EN);
|
||||
spin_lock_irqsave(&hc->lock, flags);
|
||||
enable_hwirq(hc);
|
||||
spin_unlock_irqrestore(&hc->lock, flags);
|
||||
//printk(KERN_DEBUG "no master irq set!!!\n");
|
||||
set_current_state(TASK_UNINTERRUPTIBLE);
|
||||
schedule_timeout((100*HZ)/1000); /* Timeout 100ms */
|
||||
/* turn IRQ off until chip is completely initialized */
|
||||
HFC_outb(hc, R_IRQ_CTRL, 0);
|
||||
spin_lock_irqsave(&hc->lock, flags);
|
||||
disable_hwirq(hc);
|
||||
spin_unlock_irqrestore(&hc->lock, flags);
|
||||
if (debug & DEBUG_HFCMULTI_INIT)
|
||||
printk(KERN_DEBUG "%s: IRQ %d count %d\n", __FUNCTION__, hc->irq, hc->irqcnt);
|
||||
if (hc->irqcnt) {
|
||||
|
@ -2931,12 +2951,8 @@ release_port(hfc_multi_t *hc, int port)
|
|||
return;
|
||||
}
|
||||
|
||||
// if (debug & DEBUG_HFCMULTI_INIT)
|
||||
// printk(KERN_DEBUG "%s: before lock_dev\n", __FUNCTION__);
|
||||
spin_lock_irqsave(&hc->lock, flags);
|
||||
// if (debug & DEBUG_HFCMULTI_INIT)
|
||||
// printk(KERN_DEBUG "%s: after lock_dev\n", __FUNCTION__);
|
||||
|
||||
disable_hwirq(hc);
|
||||
if (port > -1) {
|
||||
i = 0;
|
||||
while(i < hc->type) {
|
||||
|
@ -3078,8 +3094,10 @@ release_port(hfc_multi_t *hc, int port)
|
|||
HFC_cnt--;
|
||||
if (debug & DEBUG_HFCMULTI_INIT)
|
||||
printk(KERN_WARNING "%s: card successfully removed\n", __FUNCTION__);
|
||||
} else
|
||||
} else {
|
||||
enable_hwirq(hc);
|
||||
spin_unlock_irqrestore(&hc->lock, flags);
|
||||
}
|
||||
}
|
||||
|
||||
static int
|
||||
|
@ -3668,12 +3686,12 @@ static int __devinit hfcpci_probe(struct pci_dev *pdev, const struct pci_device_
|
|||
}
|
||||
|
||||
/* now turning on irq */
|
||||
#warning
|
||||
HFC_outb(hc, R_IRQ_CTRL, hc->hw.r_irq_ctrl);
|
||||
|
||||
spin_lock_irqsave(&hc->lock, flags);
|
||||
enable_hwirq(hc);
|
||||
/* we are on air! */
|
||||
allocated[HFC_idx] = 1;
|
||||
HFC_cnt++;
|
||||
spin_unlock_irqrestore(&hc->lock, flags);
|
||||
return(0);
|
||||
|
||||
/* if an error ocurred */
|
||||
|
|
|
@ -172,6 +172,19 @@ typedef struct _hfc_pci {
|
|||
} hfc_pci_t;
|
||||
|
||||
/* Interface functions */
|
||||
static void
|
||||
enable_hwirq(hfc_pci_t *hc)
|
||||
{
|
||||
hc->hw.int_m2 |= HFCPCI_IRQ_ENABLE;
|
||||
Write_hfc(hc, HFCPCI_INT_M2, hc->hw.int_m2);
|
||||
}
|
||||
|
||||
static void
|
||||
disable_hwirq(hfc_pci_t *hc)
|
||||
{
|
||||
hc->hw.int_m2 &= ~((u_char)HFCPCI_IRQ_ENABLE);
|
||||
Write_hfc(hc, HFCPCI_INT_M2, hc->hw.int_m2);
|
||||
}
|
||||
|
||||
/******************************************/
|
||||
/* free hardware resources used by driver */
|
||||
|
@ -179,8 +192,8 @@ typedef struct _hfc_pci {
|
|||
void
|
||||
release_io_hfcpci(hfc_pci_t *hc)
|
||||
{
|
||||
hc->hw.int_m2 = 0; /* interrupt output off ! */
|
||||
Write_hfc(hc, HFCPCI_INT_M2, hc->hw.int_m2);
|
||||
hc->hw.int_m2 = 0; /* interrupt output off ! */
|
||||
disable_hwirq(hc);
|
||||
Write_hfc(hc, HFCPCI_CIRM, HFCPCI_RESET); /* Reset On */
|
||||
mdelay(10); /* Timeout 10ms */
|
||||
hc->hw.cirm = 0; /* Reset Off */
|
||||
|
@ -207,8 +220,7 @@ reset_hfcpci(hfc_pci_t *hc)
|
|||
val = Read_hfc(hc, HFCPCI_CHIP_ID);
|
||||
printk(KERN_INFO "HFC_PCI: resetting HFC ChipId(%x)\n", val);
|
||||
pci_write_config_word(hc->hw.dev, PCI_COMMAND, PCI_ENA_MEMIO); /* enable memory mapped ports, disable busmaster */
|
||||
hc->hw.int_m2 = 0; /* interrupt output off ! */
|
||||
Write_hfc(hc, HFCPCI_INT_M2, hc->hw.int_m2);
|
||||
disable_hwirq(hc);
|
||||
pci_write_config_word(hc->hw.dev, PCI_COMMAND, PCI_ENA_MEMIO + PCI_ENA_MASTER); /* enable memory ports + busmaster */
|
||||
val = Read_hfc(hc, HFCPCI_STATUS);
|
||||
printk(KERN_DEBUG "HFC-PCI status(%x) before reset\n", val);
|
||||
|
@ -1708,20 +1720,22 @@ static int init_card(hfc_pci_t *hc)
|
|||
|
||||
HFC_INFO("init_card: entered\n");
|
||||
|
||||
|
||||
spin_lock_irqsave(&hc->lock, flags);
|
||||
disable_hwirq(hc);
|
||||
spin_unlock_irqrestore(&hc->lock, flags);
|
||||
if (request_irq(hc->irq, hfcpci_interrupt, SA_SHIRQ, "HFC PCI", hc)) {
|
||||
printk(KERN_WARNING "mISDN: couldn't get interrupt %d\n", hc->irq);
|
||||
spin_unlock_irqrestore(&hc->lock, flags);
|
||||
return(-EIO);
|
||||
}
|
||||
spin_lock_irqsave(&hc->lock, flags);
|
||||
while (cnt) {
|
||||
inithfcpci(hc);
|
||||
/* Finally enable IRQ output
|
||||
* this is only allowed, if an IRQ routine is allready
|
||||
* established for this HFC, so don't do that earlier
|
||||
*/
|
||||
hc->hw.int_m2 = HFCPCI_IRQ_ENABLE;
|
||||
Write_hfc(hc, HFCPCI_INT_M2, hc->hw.int_m2);
|
||||
enable_hwirq(hc);
|
||||
spin_unlock_irqrestore(&hc->lock, flags);
|
||||
/* Timeout 80ms */
|
||||
current->state = TASK_UNINTERRUPTIBLE;
|
||||
|
@ -1939,8 +1953,8 @@ setup_hfcpci(hfc_pci_t *hc)
|
|||
(u_long) virt_to_bus(hc->hw.fifos),
|
||||
hc->irq, HZ);
|
||||
pci_write_config_word(hc->hw.dev, PCI_COMMAND, PCI_ENA_MEMIO); /* enable memory mapped ports, disable busmaster */
|
||||
hc->hw.int_m2 = 0; /* disable alle interrupts */
|
||||
Write_hfc(hc, HFCPCI_INT_M2, hc->hw.int_m2);
|
||||
hc->hw.int_m2 = 0;
|
||||
disable_hwirq(hc);
|
||||
hc->hw.int_m1 = 0;
|
||||
Write_hfc(hc, HFCPCI_INT_M1, hc->hw.int_m1);
|
||||
/* At this point the needed PCI config is done */
|
||||
|
@ -2230,6 +2244,7 @@ static int __init HFC_init(void)
|
|||
HFC_cnt);
|
||||
return(err);
|
||||
}
|
||||
card->dch.inst.class_dev.dev = &card->hw.dev->dev;
|
||||
HFC_cnt++;
|
||||
if (prev) {
|
||||
dst = prev->dch.inst.st;
|
||||
|
@ -2248,6 +2263,7 @@ static int __init HFC_init(void)
|
|||
}
|
||||
HFC_obj.ctrl(dst, MGR_STOPSTACK | REQUEST, NULL);
|
||||
for (i = 0; i < 2; i++) {
|
||||
card->bch[i].inst.class_dev.dev = &card->hw.dev->dev;
|
||||
if ((err = HFC_obj.ctrl(dst,
|
||||
MGR_NEWSTACK | REQUEST, &card->bch[i].inst))) {
|
||||
printk(KERN_ERR "MGR_ADDSTACK bchan error %d\n", err);
|
||||
|
|
|
@ -283,6 +283,24 @@ speedfax_pci_interrupt(int intno, void *dev_id, struct pt_regs *regs)
|
|||
return IRQ_HANDLED;
|
||||
}
|
||||
|
||||
static void
|
||||
enable_hwirq(sedl_fax *sf)
|
||||
{
|
||||
WriteISAC(sf, ISAC_MASK, 0);
|
||||
WriteISAR(sf, 0, ISAR_IRQBIT, ISAR_IRQMSK);
|
||||
if (sf->subtyp != SEDL_SPEEDFAX_ISA)
|
||||
byteout(sf->cfg + TIGER_AUX_IRQMASK, SEDL_TIGER_IRQ_BIT);
|
||||
}
|
||||
|
||||
static void
|
||||
disable_hwirq(sedl_fax *sf)
|
||||
{
|
||||
WriteISAC(sf, ISAC_MASK, 0xFF);
|
||||
WriteISAR(sf, 0, ISAR_IRQBIT, 0);
|
||||
if (sf->subtyp != SEDL_SPEEDFAX_ISA)
|
||||
byteout(sf->cfg + TIGER_AUX_IRQMASK, 0);
|
||||
}
|
||||
|
||||
void
|
||||
release_sedlbauer(sedl_fax *sf)
|
||||
{
|
||||
|
@ -290,8 +308,6 @@ release_sedlbauer(sedl_fax *sf)
|
|||
|
||||
if (sf->subtyp == SEDL_SPEEDFAX_ISA)
|
||||
bytecnt = 16;
|
||||
else
|
||||
byteout(sf->cfg + TIGER_AUX_IRQMASK, 0);
|
||||
if (sf->cfg)
|
||||
release_region(sf->cfg, bytecnt);
|
||||
}
|
||||
|
@ -328,13 +344,12 @@ static int init_card(sedl_fax *sf)
|
|||
irq_func = speedfax_isa_interrupt;
|
||||
shared = 0;
|
||||
}
|
||||
spin_lock_irqsave(&sf->lock, flags);
|
||||
if (request_irq(sf->irq, irq_func, shared, "speedfax", sf)) {
|
||||
printk(KERN_WARNING "mISDN: couldn't get interrupt %d\n",
|
||||
sf->irq);
|
||||
spin_unlock_irqrestore(&sf->lock, flags);
|
||||
return(-EIO);
|
||||
}
|
||||
spin_lock_irqsave(&sf->lock, flags);
|
||||
while (cnt) {
|
||||
int ret;
|
||||
|
||||
|
@ -345,10 +360,7 @@ static int init_card(sedl_fax *sf)
|
|||
}
|
||||
init_isar(&sf->bch[0]);
|
||||
init_isar(&sf->bch[1]);
|
||||
if (sf->subtyp != SEDL_SPEEDFAX_ISA)
|
||||
byteout(sf->cfg + TIGER_AUX_IRQMASK, SEDL_TIGER_IRQ_BIT);
|
||||
WriteISAC(sf, ISAC_MASK, 0);
|
||||
WriteISAR(sf, 0, ISAR_IRQBIT, ISAR_IRQMSK);
|
||||
enable_hwirq(sf);
|
||||
/* RESET Receiver and Transmitter */
|
||||
WriteISAC(sf, ISAC_CMDR, 0x41);
|
||||
spin_unlock_irqrestore(&sf->lock, flags);
|
||||
|
@ -455,8 +467,7 @@ setup_speedfax(sedl_fax *sf)
|
|||
sf->bch[1].Read_Reg = &ReadISAR;
|
||||
sf->bch[1].Write_Reg = &WriteISAR;
|
||||
spin_lock_irqsave(&sf->lock, flags);
|
||||
writereg(sf->addr, sf->isar, ISAR_IRQBIT, 0);
|
||||
writereg(sf->addr, sf->isac, ISAC_MASK, 0xFF);
|
||||
disable_hwirq(sf);
|
||||
ver = ISARVersion(&sf->bch[0], "Sedlbauer:");
|
||||
spin_unlock_irqrestore(&sf->lock, flags);
|
||||
if (ver < 0) {
|
||||
|
@ -472,16 +483,14 @@ static void
|
|||
release_card(sedl_fax *card) {
|
||||
u_long flags;
|
||||
|
||||
spin_lock_irqsave(&card->lock, flags);
|
||||
disable_hwirq(card);
|
||||
spin_unlock_irqrestore(&card->lock, flags);
|
||||
free_irq(card->irq, card);
|
||||
spin_lock_irqsave(&card->lock, flags);
|
||||
free_isar(&card->bch[1]);
|
||||
free_isar(&card->bch[0]);
|
||||
mISDN_isac_free(&card->dch);
|
||||
WriteISAR(card, 0, ISAR_IRQBIT, 0);
|
||||
WriteISAC(card, ISAC_MASK, 0xFF);
|
||||
reset_speedfax(card);
|
||||
WriteISAR(card, 0, ISAR_IRQBIT, 0);
|
||||
WriteISAC(card, ISAC_MASK, 0xFF);
|
||||
release_sedlbauer(card);
|
||||
mISDN_free_bch(&card->bch[1]);
|
||||
mISDN_free_bch(&card->bch[0]);
|
||||
|
|
|
@ -48,7 +48,7 @@ typedef struct _w6692_bc {
|
|||
|
||||
typedef struct _w6692pci {
|
||||
struct list_head list;
|
||||
void *pdev;
|
||||
struct pci_dev *pdev;
|
||||
u_int irq;
|
||||
u_int irqcnt;
|
||||
u_int addr;
|
||||
|
@ -91,6 +91,18 @@ WriteW6692B(w6692pci *card, int bchan, u_char offset, u_char value)
|
|||
outb(value, card->addr + (bchan ? 0x40 : 0) + offset);
|
||||
}
|
||||
|
||||
static void
|
||||
enable_hwirq(w6692pci *card)
|
||||
{
|
||||
WriteW6692(card, W_IMASK, card->imask);
|
||||
}
|
||||
|
||||
static void
|
||||
disable_hwirq(w6692pci *card)
|
||||
{
|
||||
WriteW6692(card, W_IMASK, 0xff);
|
||||
}
|
||||
|
||||
static char *W6692Ver[] __initdata =
|
||||
{"W6692 V00", "W6692 V01", "W6692 V10",
|
||||
"W6692 V11"};
|
||||
|
@ -860,16 +872,15 @@ void initW6692(w6692pci *card)
|
|||
mode_w6692(&card->bch[0], 0, -1);
|
||||
mode_w6692(&card->bch[1], 1, -1);
|
||||
WriteW6692(card, W_D_CTL, 0x00);
|
||||
WriteW6692(card, W_IMASK, 0xff);
|
||||
disable_hwirq(card);
|
||||
WriteW6692(card, W_D_SAM, 0xff);
|
||||
WriteW6692(card, W_D_TAM, 0xff);
|
||||
WriteW6692(card, W_D_MODE, W_D_MODE_RACT);
|
||||
card->dch.ph_state = W_L1CMD_RST;
|
||||
ph_command(card, W_L1CMD_RST);
|
||||
ph_command(card, W_L1CMD_ECK);
|
||||
/* Reenable all IRQ */
|
||||
/* enable all IRQ but extern */
|
||||
card->imask = 0x18;
|
||||
WriteW6692(card, W_IMASK, card->imask);
|
||||
WriteW6692(card, W_D_EXIM, 0x00);
|
||||
WriteW6692B(card, 0, W_B_EXIM, 0);
|
||||
WriteW6692B(card, 1, W_B_EXIM, 0);
|
||||
|
@ -909,14 +920,16 @@ static int init_card(w6692pci *card)
|
|||
u_long flags;
|
||||
|
||||
spin_lock_irqsave(&card->lock, flags);
|
||||
disable_hwirq(card);
|
||||
spin_unlock_irqrestore(&card->lock, flags);
|
||||
if (request_irq(card->irq, w6692_interrupt, SA_SHIRQ, "w6692", card)) {
|
||||
printk(KERN_WARNING "mISDN: couldn't get interrupt %d\n", card->irq);
|
||||
spin_unlock_irqrestore(&card->lock, flags);
|
||||
return(-EIO);
|
||||
}
|
||||
spin_lock_irqsave(&card->lock, flags);
|
||||
while (cnt) {
|
||||
initW6692(card);
|
||||
/* RESET Receiver and Transmitter */
|
||||
enable_hwirq(card);
|
||||
spin_unlock_irqrestore(&card->lock, flags);
|
||||
/* Timeout 10ms */
|
||||
current->state = TASK_UNINTERRUPTIBLE;
|
||||
|
@ -1209,8 +1222,7 @@ release_card(w6692pci *card)
|
|||
u_long flags;
|
||||
|
||||
spin_lock_irqsave(&card->lock, flags);
|
||||
/* disable all IRQ */
|
||||
WriteW6692(card, W_IMASK, 0xff);
|
||||
disable_hwirq(card);
|
||||
spin_unlock_irqrestore(&card->lock, flags);
|
||||
free_irq(card->irq, card);
|
||||
spin_lock_irqsave(&card->lock, flags);
|
||||
|
@ -1358,6 +1370,7 @@ static int __devinit setup_instance(w6692pci *card)
|
|||
card->dch.debug = debug;
|
||||
spin_lock_init(&card->lock);
|
||||
card->dch.inst.hwlock = &card->lock;
|
||||
card->dch.inst.class_dev.dev = &card->pdev->dev;
|
||||
card->dch.inst.pid.layermask = ISDN_LAYER(0);
|
||||
card->dch.inst.pid.protocol[0] = ISDN_PID_L0_TE_S0;
|
||||
mISDN_init_instance(&card->dch.inst, &w6692, card, w6692_l1hwD);
|
||||
|
@ -1370,6 +1383,7 @@ static int __devinit setup_instance(w6692pci *card)
|
|||
mISDN_init_instance(&card->bch[i].inst, &w6692, card, w6692_l2l1B);
|
||||
card->bch[i].inst.pid.layermask = ISDN_LAYER(0);
|
||||
card->bch[i].inst.hwlock = &card->lock;
|
||||
card->bch[i].inst.class_dev.dev = &card->pdev->dev;
|
||||
card->bch[i].debug = debug;
|
||||
sprintf(card->bch[i].inst.name, "%s B%d", card->dch.inst.name, i+1);
|
||||
mISDN_init_bch(&card->bch[i]);
|
||||
|
|
Loading…
Reference in New Issue