Modified device reset and detection, still broken

git-svn-id: file:///srv/svn/repos/haiku/haiku/trunk@23288 a95241bf-73f2-0310-859d-f6bbb57e9c96
This commit is contained in:
Marcus Overhagen
2008-01-08 21:46:30 +00:00
parent 4a76630832
commit 4e9047599d
4 changed files with 84 additions and 40 deletions
+30
View File
@@ -17,6 +17,36 @@
#define TRACE dprintf
void
ata_select_device(ide_bus_info *bus, int device)
{
ide_task_file tf;
tf.chs.head = 0;
tf.chs.mode = ide_mode_lba;
tf.chs.device = device ? 1 : 0;
bus->controller->read_command_block_regs(bus->channel_cookie, &tf, ide_mask_device_head);
spin(1); // wait 400 nsec
}
/*
void
ata_select_device(ide_device_info *device)
{
ide_task_file tf;
tf.chs.head = 0;
tf.chs.mode = ide_mode_lba;
tf.chs.device = device->is_device1;
device->bus->controller->read_command_block_regs(device->bus->channel_cookie, &tf,
ide_mask_device_head);
spin(1); // wait 400 nsec
}
*/
/** verify that device is ready for further PIO transmission */
static bool
@@ -63,62 +63,66 @@ reset_bus(ide_bus_info *bus, uint32 *sigDev0, uint32 *sigDev1)
dprintf("ATA: reset_bus %p\n", bus);
// disable interrupts and assert SRST for at least 5 usec
if (controller->write_device_control(channel, ide_devctrl_bit3 | ide_devctrl_nien | ide_devctrl_srst) != B_OK)
goto error;
spin(20);
// clear SRST for at least 2 ms
// clear SRST and wait for at least 2 ms but (we wait 150ms like everyone else does)
if (controller->write_device_control(channel, ide_devctrl_bit3 | ide_devctrl_nien) != B_OK)
goto error;
snooze(5000);
snooze(150000);
// wait up to 30 seconds for busy to clear, abort when error is set
status = ata_wait(bus, 0, ide_status_bsy, true, 33000000);
if (status != B_OK)
goto error;
ata_select_device(bus, 0);
tf.chs.head = 0;
tf.chs.mode = ide_mode_lba;
dprintf("altstatus device 0: %x\n", controller->get_altstatus(channel));
// select device 0
tf.chs.device = 0;
if (controller->write_command_block_regs(channel, &tf, ide_mask_device_head) != B_OK)
goto error;
status = ata_wait(bus, 0, ide_status_bsy | ide_status_drq, true, 50000);
// wait up to 31 seconds for busy to clear, abort when error is set
status = ata_wait(bus, 0, ide_status_bsy, false, 31000000);
if (status != B_OK) {
dprintf("ATA: reset_bus: device 0 not present\n");
*sigDev0 = 0;
} else {
if (controller->read_command_block_regs(channel, &tf, ide_mask_sector_count |
ide_mask_LBA_low | ide_mask_LBA_mid | ide_mask_LBA_high) != B_OK)
goto error;
*sigDev0 = tf.lba.sector_count;
*sigDev0 |= ((uint32)tf.lba.lba_0_7) << 8;
*sigDev0 |= ((uint32)tf.lba.lba_8_15) << 16;
*sigDev0 |= ((uint32)tf.lba.lba_16_23) << 24;
if (status == B_TIMED_OUT)
dprintf("ATA: reset_bus: timeout\n");
else
dprintf("ATA: reset_bus: error bit set\n");
goto error;
}
// select device 1
tf.chs.device = 1;
if (controller->write_command_block_regs(channel, &tf, ide_mask_device_head) != B_OK)
if (controller->read_command_block_regs(channel, &tf, ide_mask_sector_count |
ide_mask_LBA_low | ide_mask_LBA_mid | ide_mask_LBA_high) != B_OK)
goto error;
status = ata_wait(bus, 0, ide_status_bsy | ide_status_drq, true, 50000);
if (status != B_OK) {
dprintf("ATA: reset_bus: device 1 not present\n");
*sigDev1 = 0;
} else {
if (controller->read_command_block_regs(channel, &tf, ide_mask_sector_count |
ide_mask_LBA_low | ide_mask_LBA_mid | ide_mask_LBA_high) != B_OK)
goto error;
*sigDev1 = tf.lba.sector_count;
*sigDev1 |= ((uint32)tf.lba.lba_0_7) << 8;
*sigDev1 |= ((uint32)tf.lba.lba_8_15) << 16;
*sigDev1 |= ((uint32)tf.lba.lba_16_23) << 24;
*sigDev0 = tf.lba.sector_count;
*sigDev0 |= ((uint32)tf.lba.lba_0_7) << 8;
*sigDev0 |= ((uint32)tf.lba.lba_8_15) << 16;
*sigDev0 |= ((uint32)tf.lba.lba_16_23) << 24;
ata_select_device(bus, 1);
dprintf("altstatus device 1: %x\n", controller->get_altstatus(channel));
// wait up to 31 seconds for busy to clear, abort when error is set
status = ata_wait(bus, 0, ide_status_bsy, false, 31000000);
if (status != B_OK) {
if (status == B_TIMED_OUT)
dprintf("ATA: reset_bus: timeout\n");
else
dprintf("ATA: reset_bus: error bit set\n");
goto error;
}
if (controller->read_command_block_regs(channel, &tf, ide_mask_sector_count |
ide_mask_LBA_low | ide_mask_LBA_mid | ide_mask_LBA_high) != B_OK)
goto error;
*sigDev1 = tf.lba.sector_count;
*sigDev1 |= ((uint32)tf.lba.lba_0_7) << 8;
*sigDev1 |= ((uint32)tf.lba.lba_8_15) << 16;
*sigDev1 |= ((uint32)tf.lba.lba_16_23) << 24;
dprintf("ATA: reset_bus success, device 0 signature: 0x%08lx, device 1 signature: 0x%08lx\n", *sigDev0, *sigDev1);
return B_OK;
@@ -315,6 +315,9 @@ device_released_bus(ide_device_info *device)
// ata.c
//void ata_select_device(ide_device_info *device);
void ata_select_device(ide_bus_info *bus, int device);
bool check_rw_error(ide_device_info *device, ide_qrequest *qrequest);
bool check_output(ide_device_info *device, bool drdy_required, int error_mask, bool is_write);
@@ -264,6 +264,13 @@ sim_scan_bus(ide_bus_info *bus)
return SCSI_REQ_CMP;
}
static uchar
sim_not_scan_bus(ide_bus_info *bus)
{
dprintf("ATA: sim_not_scan_bus\n");
return SCSI_REQ_CMP;
}
static uchar
sim_abort(ide_bus_info *bus, scsi_ccb *ccb_to_abort)
@@ -843,7 +850,7 @@ scsi_sim_interface ide_sim_module = {
(uchar (*)(scsi_sim_cookie, scsi_ccb *)) sim_term_io,
(uchar (*)(scsi_sim_cookie, scsi_path_inquiry *))sim_path_inquiry,
(uchar (*)(scsi_sim_cookie)) sim_scan_bus,
(uchar (*)(scsi_sim_cookie)) sim_not_scan_bus,
(uchar (*)(scsi_sim_cookie)) sim_reset_bus,
(void (*)(scsi_sim_cookie, uchar,