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:
@@ -184,22 +184,28 @@ ata_adapter_inthand(void *arg)
|
|||||||
pci_device *device = channel->device;
|
pci_device *device = channel->device;
|
||||||
uint8 statusATA, statusBM;
|
uint8 statusATA, statusBM;
|
||||||
|
|
||||||
// this could be a spurious interrupt, so always read status
|
if (!channel->dmaing) {
|
||||||
// register unconditionally to acknowledge those
|
// this could be a spurious interrupt, so read status
|
||||||
statusATA = pci->read_io_8(device, channel->command_block_base + 7);
|
// register unconditionally to acknowledge those
|
||||||
|
pci->read_io_8(device, channel->command_block_base + 7);
|
||||||
if (!channel->dmaing)
|
|
||||||
return B_UNHANDLED_INTERRUPT;
|
return B_UNHANDLED_INTERRUPT;
|
||||||
|
}
|
||||||
|
|
||||||
// read bus master DMA status to test if the interrupt was
|
// need to read bus master status first, because some controllers
|
||||||
// really generated by our controller
|
// will clear the interrupt status bit once ATA status is read
|
||||||
statusBM = pci->read_io_8(device, channel->bus_master_base
|
statusBM = pci->read_io_8(device, channel->bus_master_base
|
||||||
+ ATA_BM_STATUS_REG);
|
+ ATA_BM_STATUS_REG);
|
||||||
|
|
||||||
|
// test if the interrupt was really generated by our controller
|
||||||
if (statusBM & ATA_BM_STATUS_INTERRUPT) {
|
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,
|
pci->write_io_8(device, channel->bus_master_base + ATA_BM_STATUS_REG,
|
||||||
(statusBM & 0xf8) | ATA_BM_STATUS_INTERRUPT);
|
(statusBM & 0xf8) | ATA_BM_STATUS_INTERRUPT);
|
||||||
|
|
||||||
// signal interrupt to ATA stack
|
// signal interrupt to ATA stack
|
||||||
return sATA->interrupt_handler(channel->ataChannel, statusATA);
|
return sATA->interrupt_handler(channel->ataChannel, statusATA);
|
||||||
} else {
|
} else {
|
||||||
@@ -484,6 +490,7 @@ ata_adapter_detect_channel(pci_device_module_info *pci, pci_device *pci_device,
|
|||||||
uint8 api;
|
uint8 api;
|
||||||
uint16 pcicmdOld;
|
uint16 pcicmdOld;
|
||||||
uint16 pcicmdNew;
|
uint16 pcicmdNew;
|
||||||
|
uint16 pciVendor;
|
||||||
|
|
||||||
SHOW_FLOW0( 3, "" );
|
SHOW_FLOW0( 3, "" );
|
||||||
|
|
||||||
@@ -539,9 +546,9 @@ ata_adapter_detect_channel(pci_device_module_info *pci, pci_device *pci_device,
|
|||||||
}
|
}
|
||||||
if (pcicmdOld != pcicmdNew) {
|
if (pcicmdOld != pcicmdNew) {
|
||||||
pci->write_pci_config(pci_device, PCI_command, 2, 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) {
|
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
|
// 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
|
// bus manager, and I don't see any reason to add extra code for old
|
||||||
// simplex controllers
|
// 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");
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user