modified interrupt handling to fit ata_adapter
git-svn-id: file:///srv/svn/repos/haiku/haiku/trunk@30493 a95241bf-73f2-0310-859d-f6bbb57e9c96
This commit is contained in:
@@ -91,20 +91,7 @@ inthand(void *arg)
|
|||||||
if ((pci->read_io_8(device, channel->bus_master_base + 3) & 0x20) == 0)
|
if ((pci->read_io_8(device, channel->bus_master_base + 3) & 0x20) == 0)
|
||||||
return B_UNHANDLED_INTERRUPT;
|
return B_UNHANDLED_INTERRUPT;
|
||||||
|
|
||||||
if (channel->dmaing) {
|
return ide_adapter->inthand(arg);
|
||||||
// in DMA mode, there is a safe test
|
|
||||||
// in PIO mode, this doesn't work
|
|
||||||
*(uint8 *)&bm_status = pci->read_io_8( device,
|
|
||||||
channel->bus_master_base + ide_bm_status_reg );
|
|
||||||
|
|
||||||
if (!bm_status.interrupt)
|
|
||||||
return B_UNHANDLED_INTERRUPT;
|
|
||||||
}
|
|
||||||
|
|
||||||
// acknowledge IRQ
|
|
||||||
status = pci->read_io_8(device, channel->command_block_base + 7);
|
|
||||||
|
|
||||||
return ide->irq_handler(channel->ide_channel, status);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
@@ -761,40 +761,27 @@ dma_finish(void *channelCookie)
|
|||||||
|
|
||||||
FLOW("dma_finish enter\n");
|
FLOW("dma_finish enter\n");
|
||||||
|
|
||||||
command = *channel->bm_command_reg & ~IDE_BM_COMMAND_START_STOP;
|
|
||||||
channel->dma_active = false;
|
|
||||||
|
|
||||||
*channel->bm_command_reg = command;
|
|
||||||
|
|
||||||
status = *channel->bm_status_reg;
|
status = *channel->bm_status_reg;
|
||||||
|
|
||||||
*channel->bm_status_reg = status | IDE_BM_STATUS_INTERRUPT
|
command = *channel->bm_command_reg;
|
||||||
| IDE_BM_STATUS_ERROR;
|
*channel->bm_command_reg = command & ~IDE_BM_COMMAND_START_STOP;
|
||||||
|
|
||||||
|
channel->dma_active = false;
|
||||||
|
|
||||||
|
*channel->bm_status_reg = status | IDE_BM_STATUS_ERROR;
|
||||||
*channel->dev_ctrl; // read altstatus to flush
|
*channel->dev_ctrl; // read altstatus to flush
|
||||||
|
|
||||||
|
if ((status & IDE_BM_STATUS_ACTIVE) != 0) {
|
||||||
|
TRACE("dma_finish: buffer too large\n");
|
||||||
|
return B_DEV_DATA_OVERRUN;
|
||||||
|
}
|
||||||
if ((status & IDE_BM_STATUS_ERROR) != 0) {
|
if ((status & IDE_BM_STATUS_ERROR) != 0) {
|
||||||
FLOW("dma_finish: failed\n");
|
FLOW("dma_finish: failed\n");
|
||||||
return B_ERROR;
|
return B_ERROR;
|
||||||
}
|
}
|
||||||
|
|
||||||
if ((status & IDE_BM_STATUS_INTERRUPT) == 0) {
|
FLOW("dma_finish leave\n");
|
||||||
if ((status & IDE_BM_STATUS_ACTIVE) != 0) {
|
return B_OK;
|
||||||
TRACE("dma_finish: transfer aborted\n");
|
|
||||||
return B_ERROR;
|
|
||||||
} else {
|
|
||||||
TRACE("dma_finish: buffer underrun\n");
|
|
||||||
return B_DEV_DATA_UNDERRUN;
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
if ((status & IDE_BM_STATUS_ACTIVE) != 0) {
|
|
||||||
TRACE("dma_finish: buffer too large\n");
|
|
||||||
return B_DEV_DATA_OVERRUN;
|
|
||||||
} else {
|
|
||||||
FLOW("dma_finish leave\n");
|
|
||||||
return B_OK;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@@ -802,12 +789,13 @@ static int32
|
|||||||
handle_interrupt(void *arg)
|
handle_interrupt(void *arg)
|
||||||
{
|
{
|
||||||
controller_data *controller = arg;
|
controller_data *controller = arg;
|
||||||
uint8 status;
|
uint8 statusATA, statusBM;
|
||||||
int32 result, ret;
|
int32 result;
|
||||||
int i;
|
int i;
|
||||||
|
|
||||||
// FLOW("handle_interrupt\n");
|
// FLOW("handle_interrupt\n");
|
||||||
|
|
||||||
|
|
||||||
result = B_UNHANDLED_INTERRUPT;
|
result = B_UNHANDLED_INTERRUPT;
|
||||||
|
|
||||||
for (i = 0; i < controller->channel_count; i++) {
|
for (i = 0; i < controller->channel_count; i++) {
|
||||||
@@ -815,21 +803,19 @@ handle_interrupt(void *arg)
|
|||||||
if (!channel || channel->lost)
|
if (!channel || channel->lost)
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
if (channel->dma_active) {
|
// this could be a spurious interrupt, so always read status
|
||||||
if ((*channel->bm_status_reg & IDE_BM_STATUS_INTERRUPT) == 0)
|
// register unconditionally to acknowledge those
|
||||||
continue;
|
statusATA = *(channel->command_block + 7);
|
||||||
} else {
|
|
||||||
// for PIO, read the "Task File Configuration + Status" Interrupt
|
|
||||||
// status
|
|
||||||
if (!(*channel->stat & (1 << 11)))
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
|
|
||||||
// acknowledge IRQ
|
if (!channel->dma_active)
|
||||||
status = *(channel->command_block + 7);
|
continue;
|
||||||
ret = ide->irq_handler(channel->ide_channel, status);
|
|
||||||
if (ret == B_INVOKE_SCHEDULER || result == B_UNHANDLED_INTERRUPT)
|
statusBM = *channel->bm_status_reg;
|
||||||
result = ret;
|
if (statusBM & IDE_BM_STATUS_INTERRUPT) {
|
||||||
|
*channel->bm_status_reg = (statusBM & 0xf8) | IDE_BM_STATUS_INTERRUPT;
|
||||||
|
ide->irq_handler(channel->ide_channel, statusATA);
|
||||||
|
result = B_INVOKE_SCHEDULER;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return result;
|
return result;
|
||||||
|
|||||||
Reference in New Issue
Block a user