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:
parent
1dd6345561
commit
ab9074ffa5
@ -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");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user