* Turns out the 3com driver wasn't picked up after my changes, but the marvell_yukon driver
worked flawlessly this one time... (I got almost 10 MB/s with that one, now 7.5 MB/s with the 3com driver) * We need to acknowledge the interrupt in the handler, because else, the interrupt continues to fire after the PIC interrupt is acknowledged by the kernel. * It also helps a lot to turn off the interrupts on the device while xl_intr() is handling the interrupt. * When the slow handler is running, we now set the new "handling" field in the internal interrupt handler which will not invoke the scheduler then (but only signals a handled interrupt). git-svn-id: file:///srv/svn/repos/haiku/haiku/trunk@23085 a95241bf-73f2-0310-859d-f6bbb57e9c96
This commit is contained in:
@@ -40,6 +40,8 @@ __haiku_disable_interrupts(device_t dev)
|
|||||||
if (status == 0xffff || (status & XL_INTRS) == 0)
|
if (status == 0xffff || (status & XL_INTRS) == 0)
|
||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
|
CSR_WRITE_2(sc, XL_COMMAND, XL_CMD_STAT_ENB);
|
||||||
|
CSR_WRITE_2(sc, XL_COMMAND, XL_CMD_INTR_ACK | (status & XL_INTRS));
|
||||||
atomic_or((int32 *)&sc->xl_intr_status, status);
|
atomic_or((int32 *)&sc->xl_intr_status, status);
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
@@ -48,6 +50,8 @@ __haiku_disable_interrupts(device_t dev)
|
|||||||
void
|
void
|
||||||
__haiku_reenable_interrupts(device_t dev)
|
__haiku_reenable_interrupts(device_t dev)
|
||||||
{
|
{
|
||||||
|
struct xl_softc *sc = device_get_softc(dev);
|
||||||
|
CSR_WRITE_2(sc, XL_COMMAND, XL_CMD_STAT_ENB | XL_INTRS);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
@@ -2286,16 +2286,13 @@ xl_intr(void *arg)
|
|||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#ifndef __HAIKU__
|
#ifndef __HAIKU__
|
||||||
while ((status = CSR_READ_2(sc, XL_STATUS)) & XL_INTRS &&
|
while ((status = CSR_READ_2(sc, XL_STATUS)) & XL_INTRS &&
|
||||||
status != 0xFFFF) {
|
status != 0xFFFF) {
|
||||||
#else
|
#else
|
||||||
status = atomic_and((int32 *)&sc->xl_intr_status, 0);
|
status = atomic_and((int32 *)&sc->xl_intr_status, 0);
|
||||||
do {
|
while (true) {
|
||||||
#endif
|
#endif
|
||||||
CSR_WRITE_2(sc, XL_COMMAND,
|
|
||||||
XL_CMD_INTR_ACK|(status & XL_INTRS));
|
|
||||||
|
|
||||||
if (status & XL_STAT_UP_COMPLETE) {
|
if (status & XL_STAT_UP_COMPLETE) {
|
||||||
int curpkts;
|
int curpkts;
|
||||||
|
|
||||||
@@ -2331,10 +2328,13 @@ xl_intr(void *arg)
|
|||||||
}
|
}
|
||||||
#ifdef __HAIKU__
|
#ifdef __HAIKU__
|
||||||
status = CSR_READ_2(sc, XL_STATUS);
|
status = CSR_READ_2(sc, XL_STATUS);
|
||||||
} while ((status & XL_INTRS) != 0 && status != 0xFFFF);
|
if ((status & XL_INTRS) == 0 || status == 0xffff)
|
||||||
#else
|
break;
|
||||||
}
|
|
||||||
|
CSR_WRITE_2(sc, XL_COMMAND,
|
||||||
|
XL_CMD_INTR_ACK|(status & XL_INTRS));
|
||||||
#endif
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
if (!IFQ_DRV_IS_EMPTY(&ifp->if_snd)) {
|
if (!IFQ_DRV_IS_EMPTY(&ifp->if_snd)) {
|
||||||
if (sc->xl_type == XL_TYPE_905B)
|
if (sc->xl_type == XL_TYPE_905B)
|
||||||
|
|||||||
@@ -49,6 +49,7 @@ struct internal_intr {
|
|||||||
|
|
||||||
thread_id thread;
|
thread_id thread;
|
||||||
sem_id sem;
|
sem_id sem;
|
||||||
|
int32 handling;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
@@ -235,7 +236,7 @@ intr_wrapper(void *data)
|
|||||||
return B_UNHANDLED_INTERRUPT;
|
return B_UNHANDLED_INTERRUPT;
|
||||||
|
|
||||||
release_sem_etc(intr->sem, 1, B_DO_NOT_RESCHEDULE);
|
release_sem_etc(intr->sem, 1, B_DO_NOT_RESCHEDULE);
|
||||||
return B_INVOKE_SCHEDULER;
|
return intr->handling ? B_HANDLED_INTERRUPT : B_INVOKE_SCHEDULER;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@@ -264,7 +265,9 @@ intr_handler(void *data)
|
|||||||
|
|
||||||
//device_printf(intr->dev, "in soft interrupt handler.\n");
|
//device_printf(intr->dev, "in soft interrupt handler.\n");
|
||||||
|
|
||||||
|
atomic_or(&intr->handling, 1);
|
||||||
intr->handler(intr->arg);
|
intr->handler(intr->arg);
|
||||||
|
atomic_and(&intr->handling, 0);
|
||||||
HAIKU_REENABLE_INTERRUPTS(intr->dev);
|
HAIKU_REENABLE_INTERRUPTS(intr->dev);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user