This should fix interrupt timeouts when using DMA mode.

Also ignore simplex bit for Intel controllers, and use
DMA for both channels.


git-svn-id: file:///srv/svn/repos/haiku/haiku/trunk@32977 a95241bf-73f2-0310-859d-f6bbb57e9c96
This commit is contained in:
Marcus Overhagen 2009-09-07 00:46:02 +00:00
parent 1dd6345561
commit ab9074ffa5

View File

@ -184,22 +184,28 @@ ata_adapter_inthand(void *arg)
pci_device *device = channel->device;
uint8 statusATA, statusBM;
// this could be a spurious interrupt, so always read status
// register unconditionally to acknowledge those
statusATA = pci->read_io_8(device, channel->command_block_base + 7);
if (!channel->dmaing)
if (!channel->dmaing) {
// this could be a spurious interrupt, so read status
// register unconditionally to acknowledge those
pci->read_io_8(device, channel->command_block_base + 7);
return B_UNHANDLED_INTERRUPT;
}
// read bus master DMA status to test if the interrupt was
// really generated by our controller
// need to read bus master status first, because some controllers
// will clear the interrupt status bit once ATA status is read
statusBM = pci->read_io_8(device, channel->bus_master_base
+ ATA_BM_STATUS_REG);
// test if the interrupt was really generated by our controller
if (statusBM & ATA_BM_STATUS_INTERRUPT) {
// clear pending PCI bus master DMA interrupt
// read ATA status register to acknowledge interrupt
statusATA = pci->read_io_8(device, channel->command_block_base + 7);
// clear pending PCI bus master DMA interrupt, for those
// controllers who don't clear it themselves
pci->write_io_8(device, channel->bus_master_base + ATA_BM_STATUS_REG,
(statusBM & 0xf8) | ATA_BM_STATUS_INTERRUPT);
// signal interrupt to ATA stack
return sATA->interrupt_handler(channel->ataChannel, statusATA);
} else {
@ -484,6 +490,7 @@ ata_adapter_detect_channel(pci_device_module_info *pci, pci_device *pci_device,
uint8 api;
uint16 pcicmdOld;
uint16 pcicmdNew;
uint16 pciVendor;
SHOW_FLOW0( 3, "" );
@ -539,9 +546,9 @@ ata_adapter_detect_channel(pci_device_module_info *pci, pci_device *pci_device,
}
if (pcicmdOld != pcicmdNew) {
pci->write_pci_config(pci_device, PCI_command, 2, pcicmdNew);
TRACE("PCI-ATA: pcicmd changed from 0x%04x to 0x%04x\n",
pcicmdOld, pcicmdNew);
}
TRACE("PCI-ATA: pcicmd old 0x%04x, new 0x%04x\n",
pcicmdOld, pcicmdNew);
if (supports_compatibility_mode) {
@ -555,8 +562,16 @@ ata_adapter_detect_channel(pci_device_module_info *pci, pci_device *pci_device,
// better were to use a controller lock, but this had to be done in the IDE
// bus manager, and I don't see any reason to add extra code for old
// simplex controllers
TRACE("PCI-ATA: Simplex controller - disabling DMA of secondary channel\n");
controller_can_dma = false;
// Intel controllers use this bit for something else and are not simplex.
pciVendor = pci->read_pci_config(pci_device, PCI_vendor_id, 2);
if (pciVendor != 0x8086) {
TRACE("PCI-ATA: Simplex controller - disabling DMA of secondary channel\n");
controller_can_dma = false;
} else {
TRACE("PCI-ATA: Simplex bit ignored - Intel controller\n");
}
}
}