Merged r32769 from trunk
git-svn-id: file:///srv/svn/repos/haiku/haiku/branches/releases/r1alpha1@32770 a95241bf-73f2-0310-859d-f6bbb57e9c96
Diff
src/add-ons/kernel/bus_managers/ata/ATAChannel.cpp | 111 +++++++++++++++++++++++++++++++++++++++++++++++---------------------------------
src/add-ons/kernel/bus_managers/ata/ATADevice.cpp | 10 +++++++++-
2 files changed, 69 insertions(+), 52 deletions(-)
@@ -118,12 +118,6 @@
status_t
ATAChannel::ScanBus()
{
if (AltStatus() == 0xff) {
TRACE_ALWAYS("illegal status value, assuming no devices connected\n");
return B_OK;
}
bool devicePresent[fDeviceCount];
uint16 deviceSignature[fDeviceCount];
status_t result = Reset(devicePresent, deviceSignature);
@@ -273,17 +267,6 @@
}
_FlushAndWait(1);
#if 1
_ReadRegs(&taskFile, ATA_MASK_DEVICE_HEAD);
if (taskFile.lba.device != device) {
TRACE_ERROR("device %d not selected! unused 0x%x, mode 0x%x,"
" device %d\n", device, taskFile.lba.lba_24_27, taskFile.lba.mode,
taskFile.lba.device);
return B_ERROR;
}
#endif
return B_OK;
}
@@ -330,30 +313,68 @@
_FlushAndWait(150 * 1000);
if (presence != NULL) {
for (uint8 i = 0; i < fDeviceCount; i++)
presence[i] = false;
}
for (uint8 i = 0; i < fDeviceCount; i++)
presence[i] = false;
uint8 deviceCount = fDeviceCount;
for (uint8 i = 0; i < deviceCount; i++) {
if (SelectDevice(i) != B_OK || SelectedDevice() != i) {
TRACE_ALWAYS("cannot select device %d, assuming not present\n", i);
continue;
for (uint8 i = 0; i < fDeviceCount; i++) {
TRACE_ALWAYS("probing device %d\n", i);
SelectDevice(i);
if (i == 1) {
if (presence[0]) {
TRACE_ALWAYS("possibly master and slave configuration...\n");
} else {
TRACE_ALWAYS("possibly single device 1 configuration...\n");
int maxtrys;
for (maxtrys = 20; maxtrys > 0; maxtrys--) {
SelectDevice(1);
ata_task_file taskFile;
taskFile.chs.sector_count = 0x5a;
taskFile.chs.sector_number = 0xa5;
if (_WriteRegs(&taskFile, ATA_MASK_SECTOR_COUNT
| ATA_MASK_SECTOR_NUMBER) != B_OK) {
TRACE_ERROR("writing registers failed\n");
return B_ERROR;
}
if (_ReadRegs(&taskFile, ATA_MASK_SECTOR_COUNT
| ATA_MASK_SECTOR_NUMBER) != B_OK) {
TRACE_ERROR("reading registers failed\n");
return B_ERROR;
}
if (taskFile.chs.sector_count == 0x5a &&
taskFile.chs.sector_number == 0xa5)
break;
snooze(100000);
}
if (maxtrys == 0) {
TRACE_ALWAYS("Can't access device 1\n");
continue;
}
}
}
_WriteControl(ATA_DEVICE_CONTROL_DISABLE_INTS);
if (AltStatus() == 0xff)
snooze(150 * 1000);
if (AltStatus() == 0xff) {
TRACE_ALWAYS("illegal status value for device %d,"
" assuming not present\n", i);
TRACE_ALWAYS("illegal status value for device %d\n", i);
continue;
}
if (Wait(0, ATA_STATUS_BUSY, 0, 31 * 1000 * 1000) != B_OK) {
TRACE_ERROR("device %d reset timeout\n", i);
TRACE_ALWAYS("device %d reset timeout\n", i);
continue;
}
SelectDevice(i);
if (SelectedDevice() != i) {
TRACE_ALWAYS("device selection failed for device %i\n", i);
continue;
}
@@ -362,35 +383,23 @@
| ATA_MASK_ERROR) != B_OK) {
TRACE_ERROR("reading status failed\n");
return B_ERROR;
}
if (taskFile.read.error != 0x01
&& (i > 0 || taskFile.read.error != 0x81)) {
TRACE_ERROR("device %d failed, error code is 0x%02x\n", i,
taskFile.read.error);
if (i == 1 && taskFile.read.error == 0x00) {
TRACE_ERROR("continuing anyway...\n");
} else
continue;
}
if (i == 0 && taskFile.read.error >= 0x80) {
TRACE_ERROR("device %d indicates that other device failed"
" with code 0x%02x\n", i, taskFile.read.error);
deviceCount = 1;
if ((i == 0) && (taskFile.read.error & 0x80)) {
TRACE_ERROR("device 0 indicates that device 1 failed"
" error code is 0x%02x\n", taskFile.read.error);
} else if (taskFile.read.error != 0x01) {
TRACE_ERROR("device %d failed, error code is 0x%02x\n",
i, taskFile.read.error);
}
if (presence != NULL)
presence[i] = true;
presence[i] = true;
uint16 signature = taskFile.lba.lba_8_15
signatures[i] = taskFile.lba.lba_8_15
| (((uint16)taskFile.lba.lba_16_23) << 8);
TRACE_ALWAYS("signature of device %d: 0x%04x\n", i, signature);
TRACE_ALWAYS("signature of device %d: 0x%04x\n", i, signatures[i]);
if (signatures != NULL)
signatures[i] = signature;
}
return B_OK;
@@ -304,7 +304,15 @@
status_t
ATADevice::Select()
{
return fChannel->SelectDevice(fIndex);
status_t err = fChannel->SelectDevice(fIndex);
#if 1
if (fChannel->SelectedDevice() != fIndex) {
TRACE_ERROR("device %d not selected!\n", fIndex);
return B_ERROR;
}
#endif
return err;
}