Adding DMA detection and generally allow DMA. Not used yet though.

git-svn-id: file:///srv/svn/repos/haiku/haiku/trunk@30054 a95241bf-73f2-0310-859d-f6bbb57e9c96
This commit is contained in:
Michael Lotz 2009-04-09 09:21:46 +00:00
parent 6bb01f71bc
commit 9611bddd7a
4 changed files with 56 additions and 13 deletions

View File

@ -17,7 +17,7 @@
// maximum number of devices connected to controller (uint8, optional, default:2)
#define ATA_CONTROLLER_MAX_DEVICES_ITEM "ide/max_devices"
// set to not-0 if DMA is supported (uint8, optional, default:0)
#define ATA_CONTROLLER_CAN_DMA_ITEM "ide/can_dma"
#define ATA_CONTROLLER_CAN_DMA_ITEM "ide/can_DMA"
// name of controller (string, required)
#define ATA_CONTROLLER_CONTROLLER_NAME_ITEM "ide/controller_name"

View File

@ -18,17 +18,21 @@ ATAChannel::ATAChannel(device_node *node)
fSCSIBus(NULL),
fDeviceCount(0),
fDevices(NULL),
fUseDMA(false),
fUseDMA(true),
fRequest(NULL)
{
mutex_init(&fLock, "ata channel");
gDeviceManager->get_attr_uint32(node, ATA_CHANNEL_ID_ITEM, &fChannelID,
true);
snprintf(fDebugContext, sizeof(fDebugContext), " %lu", fChannelID);
if (fUseDMA) {
void *settings = load_driver_settings(B_SAFEMODE_DRIVER_SETTINGS);
if (settings != NULL) {
if (get_driver_boolean_parameter(settings,
B_SAFEMODE_DISABLE_IDE_DMA, false, false)) {
TRACE("disabling dma because of safemode setting\n");
TRACE_ALWAYS("disabling DMA because of safemode setting\n");
fUseDMA = false;
}
@ -39,7 +43,13 @@ ATAChannel::ATAChannel(device_node *node)
if (fUseDMA) {
uint8 canDMA;
if (gDeviceManager->get_attr_uint8(node, ATA_CONTROLLER_CAN_DMA_ITEM,
&canDMA, true) != B_OK || canDMA == 0) {
&canDMA, true) != B_OK) {
TRACE_ERROR("unknown if controller supports DMA, not using it\n");
fUseDMA = false;
}
if (canDMA == 0) {
TRACE_ALWAYS("controller doesn't support DMA, disabling\n");
fUseDMA = false;
}
}
@ -66,11 +76,6 @@ ATAChannel::ATAChannel(device_node *node)
for (uint8 i = 0; i < fDeviceCount; i++)
fDevices[i] = NULL;
gDeviceManager->get_attr_uint32(node, ATA_CHANNEL_ID_ITEM, &fChannelID,
true);
snprintf(fDebugContext, sizeof(fDebugContext), " %lu", fChannelID);
device_node *parent = gDeviceManager->get_parent_node(node);
fStatus = gDeviceManager->get_driver(parent,
(driver_module_info **)&fController, &fCookie);
@ -149,15 +154,15 @@ ATAChannel::ScanBus()
continue;
}
TRACE_ALWAYS("identified ATA%s device %u\n", device->IsATAPI()
? "PI" : "", i);
if (device->Configure() != B_OK) {
TRACE_ERROR("failed to configure device\n");
delete device;
continue;
}
TRACE_ALWAYS("identified ATA%s device %u\n", device->IsATAPI()
? "PI" : "", i);
fDevices[i] = device;
}

View File

@ -16,6 +16,7 @@ ATADevice::ATADevice(ATAChannel *channel, uint8 index)
fUseLBA(false),
fUse48Bits(false),
fUseDMA(channel->UseDMA()),
fDMAMode(0),
fTotalSectors(0),
fRegisterMask(0)
{
@ -361,7 +362,43 @@ ATADevice::ConfigureDMA()
if (!fUseDMA)
return B_OK;
fUseDMA = false;
if (!fInfoBlock.DMA_supported) {
TRACE_ALWAYS("DMA not supported by device\n");
fUseDMA = false;
return B_OK;
}
#define CHECK_DMA_MODE(element, mode) \
if (fInfoBlock.element) { \
fDMAMode = mode; \
modeCount++; \
}
uint32 modeCount = 0;
CHECK_DMA_MODE(MDMA0_selected, 0x00);
CHECK_DMA_MODE(MDMA1_selected, 0x01);
CHECK_DMA_MODE(MDMA2_selected, 0x02);
if (fInfoBlock._88_valid) {
CHECK_DMA_MODE(UDMA0_selected, 0x10);
CHECK_DMA_MODE(UDMA1_selected, 0x11);
CHECK_DMA_MODE(UDMA2_selected, 0x12);
CHECK_DMA_MODE(UDMA3_selected, 0x13);
CHECK_DMA_MODE(UDMA4_selected, 0x14);
CHECK_DMA_MODE(UDMA5_selected, 0x15);
CHECK_DMA_MODE(UDMA6_selected, 0x16);
}
#undef CHECK_DMA_MODE
if (modeCount != 1) {
TRACE_ERROR("more than on DMA mode selected, not using DMA\n");
fUseDMA = false;
return B_OK;
}
TRACE_ALWAYS("using DMA mode 0x%02x\n", fDMAMode);
return B_OK;
}

View File

@ -188,6 +188,7 @@ private:
bool fUseLBA;
bool fUse48Bits;
bool fUseDMA;
uint8 fDMAMode;
uint64 fTotalSectors;
ata_device_infoblock fInfoBlock;
ata_task_file fTaskFile;