diff --git a/src/add-ons/kernel/bus_managers/ata/ata.c b/src/add-ons/kernel/bus_managers/ata/ata.c index a957cf7272..e3abbc01a9 100644 --- a/src/add-ons/kernel/bus_managers/ata/ata.c +++ b/src/add-ons/kernel/bus_managers/ata/ata.c @@ -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 diff --git a/src/add-ons/kernel/bus_managers/ata/basic_protocol.c b/src/add-ons/kernel/bus_managers/ata/basic_protocol.c index 61f97c1539..5d9b471f1e 100644 --- a/src/add-ons/kernel/bus_managers/ata/basic_protocol.c +++ b/src/add-ons/kernel/bus_managers/ata/basic_protocol.c @@ -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; diff --git a/src/add-ons/kernel/bus_managers/ata/ide_internal.h b/src/add-ons/kernel/bus_managers/ata/ide_internal.h index 6cfff32d5d..4aa9033328 100644 --- a/src/add-ons/kernel/bus_managers/ata/ide_internal.h +++ b/src/add-ons/kernel/bus_managers/ata/ide_internal.h @@ -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); diff --git a/src/add-ons/kernel/bus_managers/ata/ide_sim.c b/src/add-ons/kernel/bus_managers/ata/ide_sim.c index 4095f96e66..91b83c6f5a 100644 --- a/src/add-ons/kernel/bus_managers/ata/ide_sim.c +++ b/src/add-ons/kernel/bus_managers/ata/ide_sim.c @@ -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,