Converted check_output() into ata_finish_request().
Moved timeout from device_info int ata_request-. git-svn-id: file:///srv/svn/repos/haiku/haiku/trunk@23411 a95241bf-73f2-0310-859d-f6bbb57e9c96
This commit is contained in:
@@ -151,7 +151,7 @@ ata_wait_idle(ide_bus_info *bus)
|
|||||||
return ata_wait(bus, 0, ide_status_bsy | ide_status_drq, 0, 20000);
|
return ata_wait(bus, 0, ide_status_bsy | ide_status_drq, 0, 20000);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
// busy wait for device beeing ready,
|
// busy wait for device beeing ready,
|
||||||
// using the timeout set by the previous ata_send_command
|
// using the timeout set by the previous ata_send_command
|
||||||
status_t
|
status_t
|
||||||
@@ -160,7 +160,7 @@ ata_pio_wait_drdy(ide_device_info *device)
|
|||||||
ASSERT(device->bus->state == ata_state_pio);
|
ASSERT(device->bus->state == ata_state_pio);
|
||||||
return ata_wait(device->bus, ide_status_drdy, ide_status_bsy, 0, device->pio_timeout);
|
return ata_wait(device->bus, ide_status_drdy, ide_status_bsy, 0, device->pio_timeout);
|
||||||
}
|
}
|
||||||
|
*/
|
||||||
|
|
||||||
status_t
|
status_t
|
||||||
ata_send_command(ide_device_info *device, ata_request *request, ata_flags flags, bigtime_t timeout)
|
ata_send_command(ide_device_info *device, ata_request *request, ata_flags flags, bigtime_t timeout)
|
||||||
@@ -191,13 +191,13 @@ ata_send_command(ide_device_info *device, ata_request *request, ata_flags flags,
|
|||||||
if (ata_wait_idle(bus) != B_OK) {
|
if (ata_wait_idle(bus) != B_OK) {
|
||||||
// resetting the device here will discard current configuration,
|
// resetting the device here will discard current configuration,
|
||||||
// it's better when the SCSI bus manager requests an external reset.
|
// it's better when the SCSI bus manager requests an external reset.
|
||||||
TRACE("device selection timeout\n");
|
TRACE("ata_send_command: device selection timeout\n");
|
||||||
ata_request_set_status(request, SCSI_SEL_TIMEOUT);
|
ata_request_set_status(request, SCSI_SEL_TIMEOUT);
|
||||||
return B_ERROR;
|
return B_ERROR;
|
||||||
}
|
}
|
||||||
|
|
||||||
if ((flags & ATA_DRDY_REQUIRED) && (bus->controller->get_altstatus(bus->channel_cookie) & ide_status_drdy) == 0) {
|
if ((flags & ATA_DRDY_REQUIRED) && (bus->controller->get_altstatus(bus->channel_cookie) & ide_status_drdy) == 0) {
|
||||||
TRACE("drdy not set\n");
|
TRACE("ata_send_command: drdy not set\n");
|
||||||
ata_request_set_status(request, SCSI_SEQUENCE_FAIL);
|
ata_request_set_status(request, SCSI_SEQUENCE_FAIL);
|
||||||
return B_ERROR;
|
return B_ERROR;
|
||||||
}
|
}
|
||||||
@@ -223,15 +223,13 @@ ata_send_command(ide_device_info *device, ata_request *request, ata_flags flags,
|
|||||||
ASSERT(bus->state == ata_state_busy);
|
ASSERT(bus->state == ata_state_busy);
|
||||||
|
|
||||||
bus->state = (flags & ATA_DMA_TRANSFER) ? ata_state_dma : ata_state_pio;
|
bus->state = (flags & ATA_DMA_TRANSFER) ? ata_state_dma : ata_state_pio;
|
||||||
if (request)
|
request->timeout = timeout;
|
||||||
request->device->pio_timeout = timeout;
|
|
||||||
|
|
||||||
IDE_UNLOCK(bus);
|
IDE_UNLOCK(bus);
|
||||||
|
|
||||||
return B_OK;
|
return B_OK;
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
err_clearint:
|
err_clearint:
|
||||||
bus->controller->write_device_control(bus->channel_cookie, ide_devctrl_bit3 | ide_devctrl_nien);
|
bus->controller->write_device_control(bus->channel_cookie, ide_devctrl_bit3 | ide_devctrl_nien);
|
||||||
|
|
||||||
@@ -251,93 +249,104 @@ err:
|
|||||||
status_t
|
status_t
|
||||||
ata_finish_command(ide_device_info *device, ata_request *request, ata_flags flags, uint8 errorMask)
|
ata_finish_command(ide_device_info *device, ata_request *request, ata_flags flags, uint8 errorMask)
|
||||||
{
|
{
|
||||||
#if 0
|
|
||||||
ide_bus_info *bus = device->bus;
|
ide_bus_info *bus = device->bus;
|
||||||
uint8 status;
|
status_t result;
|
||||||
|
uint8 error;
|
||||||
|
|
||||||
// check IRQ timeout
|
if (flags & ATA_WAIT_FINISH) {
|
||||||
if (bus->sync_wait_timeout) {
|
// wait for the command to finish current command (device no longer busy)
|
||||||
bus->sync_wait_timeout = false;
|
result = ata_wait(bus, 0, ide_status_bsy, 0, request->timeout);
|
||||||
|
if (result != B_OK) {
|
||||||
device->subsys_status = SCSI_CMD_TIMEOUT;
|
TRACE("ata_finish_command: timeout\n");
|
||||||
return false;
|
ata_request_set_status(request, SCSI_CMD_TIMEOUT);
|
||||||
|
return result;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
status = bus->controller->get_altstatus(bus->channel_cookie);
|
// read status, this also acknowledges pending interrupts
|
||||||
|
result = device->bus->controller->read_command_block_regs(device->bus->channel_cookie, &device->tf, ide_mask_status | ide_mask_error);
|
||||||
// if device is busy, other flags are indeterminate
|
if (result != B_OK) {
|
||||||
if ((status & ide_status_bsy) != 0) {
|
TRACE("ata_finish_command: status register read failed\n");
|
||||||
device->subsys_status = SCSI_SEQUENCE_FAIL;
|
ata_request_set_status(request, SCSI_SEQUENCE_FAIL);
|
||||||
return false;
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (device->tf.read.status & ide_status_bsy) {
|
||||||
|
TRACE("ata_finish_command: failed! device still busy\n");
|
||||||
|
ata_request_set_status(request, SCSI_SEQUENCE_FAIL);
|
||||||
|
return B_ERROR;
|
||||||
|
}
|
||||||
|
|
||||||
|
if ((flags & ATA_DRDY_REQUIRED) && (device->tf.read.status & ide_status_drdy) == 0) {
|
||||||
|
TRACE("ata_finish_command: failed! drdy not set\n");
|
||||||
|
ata_request_set_status(request, SCSI_SEQUENCE_FAIL);
|
||||||
|
return B_ERROR;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (drdy_required && ((status & ide_status_drdy) == 0)) {
|
if ((device->tf.read.status & ide_status_err) == 0)
|
||||||
device->subsys_status = SCSI_SEQUENCE_FAIL;
|
return B_OK;
|
||||||
return false;
|
|
||||||
|
result = device->bus->controller->read_command_block_regs(device->bus->channel_cookie, &device->tf, ide_mask_error);
|
||||||
|
if (result != B_OK) {
|
||||||
|
TRACE("ata_finish_command: error register read failed\n");
|
||||||
|
ata_request_set_status(request, SCSI_SEQUENCE_FAIL);
|
||||||
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
if ((status & ide_status_err) != 0) {
|
TRACE("ata_finish_command: command failed ERR bit is set\n");
|
||||||
uint8 error;
|
|
||||||
|
|
||||||
if (bus->controller->read_command_block_regs(bus->channel_cookie,
|
// check only relevant error bits
|
||||||
&device->tf, ide_mask_error) != B_OK) {
|
error = device->tf.read.error & errorMask;
|
||||||
device->subsys_status = SCSI_HBA_ERR;
|
result = B_ERROR;
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
error = device->tf.read.error & error_mask;
|
if (error & ide_error_icrc) {
|
||||||
|
ata_request_set_sense(request, SCSIS_KEY_HARDWARE_ERROR, SCSIS_ASC_LUN_COM_CRC);
|
||||||
if ((error & ide_error_icrc) != 0) {
|
return B_ERROR;
|
||||||
set_sense(device, SCSIS_KEY_HARDWARE_ERROR, SCSIS_ASC_LUN_COM_CRC);
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (is_write) {
|
|
||||||
if ((error & ide_error_wp) != 0) {
|
|
||||||
set_sense(device, SCSIS_KEY_DATA_PROTECT, SCSIS_ASC_WRITE_PROTECTED);
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
if ((error & ide_error_unc) != 0) {
|
|
||||||
set_sense(device, SCSIS_KEY_MEDIUM_ERROR, SCSIS_ASC_UNREC_READ_ERR);
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if ((error & ide_error_mc) != 0) {
|
|
||||||
// XXX proper sense key?
|
|
||||||
set_sense(device, SCSIS_KEY_UNIT_ATTENTION, SCSIS_ASC_MEDIUM_CHANGED);
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
if ((error & ide_error_idnf) != 0) {
|
|
||||||
// XXX strange error code, don't really know what it means
|
|
||||||
set_sense(device, SCSIS_KEY_MEDIUM_ERROR, SCSIS_ASC_RANDOM_POS_ERROR);
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
if ((error & ide_error_mcr) != 0) {
|
|
||||||
// XXX proper sense key?
|
|
||||||
set_sense(device, SCSIS_KEY_UNIT_ATTENTION, SCSIS_ASC_REMOVAL_REQUESTED);
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
if ((error & ide_error_nm) != 0) {
|
|
||||||
set_sense(device, SCSIS_KEY_MEDIUM_ERROR, SCSIS_ASC_NO_MEDIUM);
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
if ((error & ide_error_abrt) != 0) {
|
|
||||||
set_sense(device, SCSIS_KEY_ABORTED_COMMAND, SCSIS_ASC_NO_SENSE);
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
// either there was no error bit set or it was masked out
|
|
||||||
set_sense(device, SCSIS_KEY_HARDWARE_ERROR, SCSIS_ASC_INTERNAL_FAILURE);
|
|
||||||
return false;
|
|
||||||
}
|
}
|
||||||
#endif
|
|
||||||
return B_OK;
|
if (flags & ATA_IS_WRITE) {
|
||||||
|
if (error & ide_error_wp) {
|
||||||
|
ata_request_set_sense(request, SCSIS_KEY_DATA_PROTECT, SCSIS_ASC_WRITE_PROTECTED);
|
||||||
|
return B_ERROR;
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
if (error & ide_error_unc) {
|
||||||
|
ata_request_set_sense(request, SCSIS_KEY_MEDIUM_ERROR, SCSIS_ASC_UNREC_READ_ERR);
|
||||||
|
return B_ERROR;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (error & ide_error_mc) {
|
||||||
|
// XXX proper sense key?
|
||||||
|
ata_request_set_sense(request, SCSIS_KEY_UNIT_ATTENTION, SCSIS_ASC_MEDIUM_CHANGED);
|
||||||
|
return B_ERROR;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (error & ide_error_idnf) {
|
||||||
|
// XXX strange error code, don't really know what it means
|
||||||
|
ata_request_set_sense(request, SCSIS_KEY_MEDIUM_ERROR, SCSIS_ASC_RANDOM_POS_ERROR);
|
||||||
|
return B_ERROR;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (error & ide_error_mcr) {
|
||||||
|
// XXX proper sense key?
|
||||||
|
ata_request_set_sense(request, SCSIS_KEY_UNIT_ATTENTION, SCSIS_ASC_REMOVAL_REQUESTED);
|
||||||
|
return B_ERROR;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (error & ide_error_nm) {
|
||||||
|
ata_request_set_sense(request, SCSIS_KEY_MEDIUM_ERROR, SCSIS_ASC_NO_MEDIUM);
|
||||||
|
return B_ERROR;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (error & ide_error_abrt) {
|
||||||
|
ata_request_set_sense(request, SCSIS_KEY_ABORTED_COMMAND, SCSIS_ASC_NO_SENSE);
|
||||||
|
return B_ERROR;
|
||||||
|
}
|
||||||
|
|
||||||
|
// either there was no error bit set or it was masked out
|
||||||
|
ata_request_set_sense(request, SCSIS_KEY_HARDWARE_ERROR, SCSIS_ASC_INTERNAL_FAILURE);
|
||||||
|
return B_ERROR;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@@ -818,7 +827,6 @@ err_send:
|
|||||||
|
|
||||||
// finish_reset_queue(request);
|
// finish_reset_queue(request);
|
||||||
ata_request_finish(request, false);
|
ata_request_finish(request, false);
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@@ -899,106 +907,6 @@ check_rw_error(ide_device_info *device, ata_request *request)
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/** check result of ATA command
|
|
||||||
* drdy_required - true if drdy must be set by device
|
|
||||||
* error_mask - bits to be checked in error register
|
|
||||||
* is_write - true, if command was a write command
|
|
||||||
*/
|
|
||||||
|
|
||||||
bool
|
|
||||||
check_output(ide_device_info *device, bool drdy_required,
|
|
||||||
int error_mask, bool is_write)
|
|
||||||
{
|
|
||||||
#if 0
|
|
||||||
ide_bus_info *bus = device->bus;
|
|
||||||
uint8 status;
|
|
||||||
|
|
||||||
// check IRQ timeout
|
|
||||||
if (bus->sync_wait_timeout) {
|
|
||||||
bus->sync_wait_timeout = false;
|
|
||||||
|
|
||||||
device->subsys_status = SCSI_CMD_TIMEOUT;
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
status = bus->controller->get_altstatus(bus->channel_cookie);
|
|
||||||
|
|
||||||
// if device is busy, other flags are indeterminate
|
|
||||||
if ((status & ide_status_bsy) != 0) {
|
|
||||||
device->subsys_status = SCSI_SEQUENCE_FAIL;
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (drdy_required && ((status & ide_status_drdy) == 0)) {
|
|
||||||
device->subsys_status = SCSI_SEQUENCE_FAIL;
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
if ((status & ide_status_err) != 0) {
|
|
||||||
uint8 error;
|
|
||||||
|
|
||||||
if (bus->controller->read_command_block_regs(bus->channel_cookie,
|
|
||||||
&device->tf, ide_mask_error) != B_OK) {
|
|
||||||
device->subsys_status = SCSI_HBA_ERR;
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
error = device->tf.read.error & error_mask;
|
|
||||||
|
|
||||||
if ((error & ide_error_icrc) != 0) {
|
|
||||||
set_sense(device, SCSIS_KEY_HARDWARE_ERROR, SCSIS_ASC_LUN_COM_CRC);
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (is_write) {
|
|
||||||
if ((error & ide_error_wp) != 0) {
|
|
||||||
set_sense(device, SCSIS_KEY_DATA_PROTECT, SCSIS_ASC_WRITE_PROTECTED);
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
if ((error & ide_error_unc) != 0) {
|
|
||||||
set_sense(device, SCSIS_KEY_MEDIUM_ERROR, SCSIS_ASC_UNREC_READ_ERR);
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if ((error & ide_error_mc) != 0) {
|
|
||||||
// XXX proper sense key?
|
|
||||||
set_sense(device, SCSIS_KEY_UNIT_ATTENTION, SCSIS_ASC_MEDIUM_CHANGED);
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
if ((error & ide_error_idnf) != 0) {
|
|
||||||
// XXX strange error code, don't really know what it means
|
|
||||||
set_sense(device, SCSIS_KEY_MEDIUM_ERROR, SCSIS_ASC_RANDOM_POS_ERROR);
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
if ((error & ide_error_mcr) != 0) {
|
|
||||||
// XXX proper sense key?
|
|
||||||
set_sense(device, SCSIS_KEY_UNIT_ATTENTION, SCSIS_ASC_REMOVAL_REQUESTED);
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
if ((error & ide_error_nm) != 0) {
|
|
||||||
set_sense(device, SCSIS_KEY_MEDIUM_ERROR, SCSIS_ASC_NO_MEDIUM);
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
if ((error & ide_error_abrt) != 0) {
|
|
||||||
set_sense(device, SCSIS_KEY_ABORTED_COMMAND, SCSIS_ASC_NO_SENSE);
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
// either there was no error bit set or it was masked out
|
|
||||||
set_sense(device, SCSIS_KEY_HARDWARE_ERROR, SCSIS_ASC_INTERNAL_FAILURE);
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
/** execute SET FEATURE command
|
/** execute SET FEATURE command
|
||||||
* set subcommand in task file before calling this
|
* set subcommand in task file before calling this
|
||||||
*/
|
*/
|
||||||
@@ -1006,19 +914,22 @@ check_output(ide_device_info *device, bool drdy_required,
|
|||||||
static bool
|
static bool
|
||||||
device_set_feature(ide_device_info *device, int feature)
|
device_set_feature(ide_device_info *device, int feature)
|
||||||
{
|
{
|
||||||
#if 0
|
ata_request request;
|
||||||
|
ata_request_init(&request, device);
|
||||||
|
|
||||||
|
TRACE("device_set_feature: feature %d\n", feature);
|
||||||
|
|
||||||
device->tf_param_mask = ide_mask_features;
|
device->tf_param_mask = ide_mask_features;
|
||||||
|
|
||||||
device->tf.write.features = feature;
|
device->tf.write.features = feature;
|
||||||
device->tf.write.command = IDE_CMD_SET_FEATURES;
|
device->tf.write.command = IDE_CMD_SET_FEATURES;
|
||||||
|
|
||||||
if (!send_command(device, NULL, ATA_DRDY_REQUIRED, 1000000))
|
if (ata_send_command(device, &request, ATA_DRDY_REQUIRED, 1000000) != B_OK)
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
wait_for_sync(device->bus);
|
if (ata_finish_command(device, &request, ATA_WAIT_FINISH | ATA_DRDY_REQUIRED, ide_error_abrt) != B_OK)
|
||||||
|
return false;
|
||||||
|
|
||||||
return check_output(device, true, ide_error_abrt, false);
|
|
||||||
#endif
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -1026,8 +937,8 @@ device_set_feature(ide_device_info *device, int feature)
|
|||||||
static bool
|
static bool
|
||||||
configure_rmsn(ide_device_info *device)
|
configure_rmsn(ide_device_info *device)
|
||||||
{
|
{
|
||||||
#if 0
|
|
||||||
ide_bus_info *bus = device->bus;
|
ide_bus_info *bus = device->bus;
|
||||||
|
ata_request request;
|
||||||
int i;
|
int i;
|
||||||
|
|
||||||
if (!device->infoblock.RMSN_supported
|
if (!device->infoblock.RMSN_supported
|
||||||
@@ -1040,27 +951,27 @@ configure_rmsn(ide_device_info *device)
|
|||||||
bus->controller->read_command_block_regs(bus->channel_cookie, &device->tf,
|
bus->controller->read_command_block_regs(bus->channel_cookie, &device->tf,
|
||||||
ide_mask_LBA_mid | ide_mask_LBA_high);
|
ide_mask_LBA_mid | ide_mask_LBA_high);
|
||||||
|
|
||||||
|
ata_request_init(&request, device);
|
||||||
|
|
||||||
for (i = 0; i < 5; ++i) {
|
for (i = 0; i < 5; ++i) {
|
||||||
// don't use TUR as it checks not ide_error_mcr | ide_error_mc | ide_error_wp
|
// don't use TUR as it checks not ide_error_mcr | ide_error_mc | ide_error_wp
|
||||||
// but: we don't check wp as well
|
// but: we don't check wp as well
|
||||||
device->combined_sense = 0;
|
|
||||||
|
|
||||||
device->tf_param_mask = 0;
|
device->tf_param_mask = 0;
|
||||||
device->tf.write.command = IDE_CMD_GET_MEDIA_STATUS;
|
device->tf.write.command = IDE_CMD_GET_MEDIA_STATUS;
|
||||||
|
|
||||||
if (!send_command(device, NULL, ATA_DRDY_REQUIRED, 15000000))
|
if (!ata_send_command(device, &request, ATA_DRDY_REQUIRED, 15000000))
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
if (check_output(device, true,
|
if (ata_finish_command(device, &request, ATA_WAIT_FINISH | ATA_DRDY_REQUIRED,
|
||||||
ide_error_nm | ide_error_abrt | ide_error_mcr | ide_error_mc,
|
ide_error_nm | ide_error_abrt | ide_error_mcr | ide_error_mc) == B_OK
|
||||||
true)
|
|| ((request.senseAsc << 8) | request.senseAscq) == SCSIS_ASC_NO_MEDIUM)
|
||||||
|| decode_sense_asc_ascq(device->combined_sense) == SCSIS_ASC_NO_MEDIUM)
|
|
||||||
return true;
|
return true;
|
||||||
|
|
||||||
|
ata_request_clear_sense(&request);
|
||||||
}
|
}
|
||||||
|
|
||||||
return false;
|
return false;
|
||||||
#endif
|
|
||||||
return true;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@@ -1151,23 +1062,26 @@ configure_ata_device(ide_device_info *device)
|
|||||||
status_t
|
status_t
|
||||||
ata_identify_device(ide_device_info *device, bool isAtapi)
|
ata_identify_device(ide_device_info *device, bool isAtapi)
|
||||||
{
|
{
|
||||||
|
ata_request request;
|
||||||
ide_bus_info *bus = device->bus;
|
ide_bus_info *bus = device->bus;
|
||||||
|
|
||||||
TRACE("ata_identify_device: bus %p, device %d, isAtapi %d\n", device->bus, device->is_device1, isAtapi);
|
TRACE("ata_identify_device: bus %p, device %d, isAtapi %d\n", device->bus, device->is_device1, isAtapi);
|
||||||
|
|
||||||
|
ata_request_init(&request, device);
|
||||||
|
|
||||||
ata_select(device);
|
ata_select(device);
|
||||||
|
|
||||||
device->tf_param_mask = 0;
|
device->tf_param_mask = 0;
|
||||||
device->tf.write.command = isAtapi ? IDE_CMD_IDENTIFY_PACKET_DEVICE : IDE_CMD_IDENTIFY_DEVICE;
|
device->tf.write.command = isAtapi ? IDE_CMD_IDENTIFY_PACKET_DEVICE : IDE_CMD_IDENTIFY_DEVICE;
|
||||||
|
|
||||||
if (ata_send_command(device, NULL, isAtapi ? 0 : ATA_DRDY_REQUIRED, 20000000) != B_OK) {
|
if (ata_send_command(device, &request, isAtapi ? 0 : ATA_DRDY_REQUIRED, 20000000) != B_OK) {
|
||||||
TRACE("ata_identify_device: send_command failed\n");
|
TRACE("ata_identify_device: send_command failed\n");
|
||||||
goto error;
|
return B_ERROR;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (ata_wait(bus, ide_status_drq, ide_status_bsy, ATA_CHECK_ERROR_BIT, 4000000) != B_OK) {
|
if (ata_wait(bus, ide_status_drq, ide_status_bsy, ATA_CHECK_ERROR_BIT, 4000000) != B_OK) {
|
||||||
TRACE("ata_identify_device: wait failed\n");
|
TRACE("ata_identify_device: wait failed\n");
|
||||||
goto error;
|
return B_ERROR;
|
||||||
}
|
}
|
||||||
|
|
||||||
// get the infoblock
|
// get the infoblock
|
||||||
@@ -1176,29 +1090,12 @@ ata_identify_device(ide_device_info *device, bool isAtapi)
|
|||||||
|
|
||||||
if (ata_wait_for_drqdown(bus) != B_OK) {
|
if (ata_wait_for_drqdown(bus) != B_OK) {
|
||||||
TRACE("ata_identify_device: ata_wait_for_drqdown failed\n");
|
TRACE("ata_identify_device: ata_wait_for_drqdown failed\n");
|
||||||
goto error;
|
return B_ERROR;
|
||||||
}
|
}
|
||||||
|
|
||||||
// clear pending interrupt
|
if (ata_finish_command(device, &request, ATA_WAIT_FINISH | ATA_DRDY_REQUIRED, ide_error_abrt) != B_OK)
|
||||||
ata_read_status(device, NULL);
|
return B_ERROR;
|
||||||
|
|
||||||
// XXX fix me
|
|
||||||
IDE_LOCK(bus);
|
|
||||||
bus->state = ata_state_busy;
|
|
||||||
IDE_UNLOCK(bus);
|
|
||||||
|
|
||||||
TRACE("ata_identify_device: success\n");
|
TRACE("ata_identify_device: success\n");
|
||||||
return B_OK;
|
return B_OK;
|
||||||
|
|
||||||
error:
|
|
||||||
|
|
||||||
// clear pending interrupt
|
|
||||||
ata_read_status(device, NULL);
|
|
||||||
|
|
||||||
|
|
||||||
// XXX fix me
|
|
||||||
IDE_LOCK(bus);
|
|
||||||
bus->state = ata_state_busy;
|
|
||||||
IDE_UNLOCK(bus);
|
|
||||||
return B_ERROR;
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -46,9 +46,12 @@ void ata_request_start(ata_request **_request, struct ide_device_info *device, s
|
|||||||
ASSERT(request->device == device);
|
ASSERT(request->device == device);
|
||||||
|
|
||||||
request->ccb = ccb;
|
request->ccb = ccb;
|
||||||
|
/*
|
||||||
|
already set
|
||||||
request->is_write = 0;
|
request->is_write = 0;
|
||||||
request->uses_dma = 0;
|
request->uses_dma = 0;
|
||||||
request->packet_irq = 0;
|
request->packet_irq = 0;
|
||||||
|
*/
|
||||||
|
|
||||||
// XXX the following always triggers. Why?
|
// XXX the following always triggers. Why?
|
||||||
// ASSERT(request->ccb->subsys_status == SCSI_REQ_INPROG);
|
// ASSERT(request->ccb->subsys_status == SCSI_REQ_INPROG);
|
||||||
@@ -75,17 +78,14 @@ void
|
|||||||
ata_request_set_status(ata_request *request, uint8 status)
|
ata_request_set_status(ata_request *request, uint8 status)
|
||||||
{
|
{
|
||||||
ASSERT(status != SCSI_REQ_CMP);
|
ASSERT(status != SCSI_REQ_CMP);
|
||||||
if (!request)
|
if (request->ccb)
|
||||||
return;
|
request->ccb->subsys_status = status;
|
||||||
request->ccb->subsys_status = status;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
void
|
void
|
||||||
ata_request_set_sense(ata_request *request, uint8 key, uint16 asc_acq)
|
ata_request_set_sense(ata_request *request, uint8 key, uint16 asc_acq)
|
||||||
{
|
{
|
||||||
if (!request)
|
|
||||||
return;
|
|
||||||
request->senseKey = key;
|
request->senseKey = key;
|
||||||
request->senseAsc = asc_acq >> 8;
|
request->senseAsc = asc_acq >> 8;
|
||||||
request->senseAscq = asc_acq & 0xff;
|
request->senseAscq = asc_acq & 0xff;
|
||||||
@@ -95,15 +95,17 @@ ata_request_set_sense(ata_request *request, uint8 key, uint16 asc_acq)
|
|||||||
void
|
void
|
||||||
ata_request_finish(ata_request *request, bool resubmit)
|
ata_request_finish(ata_request *request, bool resubmit)
|
||||||
{
|
{
|
||||||
scsi_ccb *ccb;
|
scsi_ccb *ccb = request->ccb;
|
||||||
|
|
||||||
|
ASSERT(ccb);
|
||||||
|
|
||||||
TRACE("ata_request_finish: request %p, subsys_status 0x%02x, senseKey %02x\n",
|
TRACE("ata_request_finish: request %p, subsys_status 0x%02x, senseKey %02x\n",
|
||||||
request, request->ccb->subsys_status, request->senseKey);
|
request, ccb->subsys_status, request->senseKey);
|
||||||
|
|
||||||
// when the request completed and has set sense
|
// when the request completed and has set sense
|
||||||
// data, report this to the scsci stack by setting
|
// data, report this to the scsci stack by setting
|
||||||
// CHECK CONDITION status
|
// CHECK CONDITION status
|
||||||
if (request->ccb->subsys_status == SCSI_REQ_CMP && request->senseKey != 0) {
|
if (ccb->subsys_status == SCSI_REQ_CMP && request->senseKey != 0) {
|
||||||
|
|
||||||
TRACE("ata_request_finish - setting check condition\n");
|
TRACE("ata_request_finish - setting check condition\n");
|
||||||
|
|
||||||
@@ -136,8 +138,6 @@ ata_request_finish(ata_request *request, bool resubmit)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
ccb = request->ccb;
|
|
||||||
|
|
||||||
IDE_LOCK(request->device->bus);
|
IDE_LOCK(request->device->bus);
|
||||||
ASSERT(request->device->bus->state == ata_state_busy);
|
ASSERT(request->device->bus->state == ata_state_busy);
|
||||||
ASSERT(request->device->bus->active_device == request->device);
|
ASSERT(request->device->bus->active_device == request->device);
|
||||||
|
|||||||
@@ -18,6 +18,8 @@ typedef struct ata_request {
|
|||||||
uint8 senseKey;
|
uint8 senseKey;
|
||||||
uint8 senseAsc;
|
uint8 senseAsc;
|
||||||
uint8 senseAscq;
|
uint8 senseAscq;
|
||||||
|
|
||||||
|
bigtime_t timeout;
|
||||||
} ata_request;
|
} ata_request;
|
||||||
|
|
||||||
struct scsi_ccb;
|
struct scsi_ccb;
|
||||||
|
|||||||
@@ -104,7 +104,6 @@ typedef struct ide_device_info {
|
|||||||
uint8 device_type; // atapi device type
|
uint8 device_type; // atapi device type
|
||||||
|
|
||||||
// pio from here on
|
// pio from here on
|
||||||
bigtime_t pio_timeout;
|
|
||||||
int left_sg_elem; // remaining sg elements
|
int left_sg_elem; // remaining sg elements
|
||||||
const physical_entry *cur_sg_elem; // active sg element
|
const physical_entry *cur_sg_elem; // active sg element
|
||||||
int cur_sg_ofs; // offset in active sg element
|
int cur_sg_ofs; // offset in active sg element
|
||||||
@@ -132,7 +131,8 @@ typedef enum {
|
|||||||
ATA_IS_WRITE = 0x02,
|
ATA_IS_WRITE = 0x02,
|
||||||
// ATA_PIO_TRANSFER = 0x04,
|
// ATA_PIO_TRANSFER = 0x04,
|
||||||
ATA_DMA_TRANSFER = 0x08,
|
ATA_DMA_TRANSFER = 0x08,
|
||||||
ATA_CHECK_ERROR_BIT = 0x10
|
ATA_CHECK_ERROR_BIT = 0x10,
|
||||||
|
ATA_WAIT_FINISH = 0x20
|
||||||
} ata_flags;
|
} ata_flags;
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
@@ -194,7 +194,7 @@ scan_bus(ide_bus_info *bus)
|
|||||||
|
|
||||||
// XXX fix me
|
// XXX fix me
|
||||||
IDE_LOCK(bus);
|
IDE_LOCK(bus);
|
||||||
ASSERT(bus->state == ata_state_busy);
|
ASSERT(bus->state != ata_state_idle);
|
||||||
bus->state = ata_state_idle;
|
bus->state = ata_state_idle;
|
||||||
IDE_UNLOCK(bus);
|
IDE_UNLOCK(bus);
|
||||||
|
|
||||||
|
|||||||
@@ -230,21 +230,18 @@ scsi_test_unit_ready(ide_device_info *device, ata_request *request)
|
|||||||
device->tf_param_mask = 0;
|
device->tf_param_mask = 0;
|
||||||
device->tf.write.command = IDE_CMD_GET_MEDIA_STATUS;
|
device->tf.write.command = IDE_CMD_GET_MEDIA_STATUS;
|
||||||
|
|
||||||
if (ata_send_command(device, request, ATA_DRDY_REQUIRED, 15) != B_OK) {
|
if (ata_send_command(device, request, ATA_DRDY_REQUIRED, 15000000) != B_OK) {
|
||||||
|
ata_request_set_status(request, SCSI_SEQUENCE_FAIL);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
// bits ide_error_mcr | ide_error_mc | ide_error_wp are also valid
|
// bits ide_error_mcr | ide_error_mc | ide_error_wp are also valid
|
||||||
// but not requested by TUR; ide_error_wp can safely be ignored, but
|
// but not requested by TUR; ide_error_wp can safely be ignored, but
|
||||||
// we don't want to loose media change (request) reports
|
// we don't want to loose media change (request) reports
|
||||||
if (!check_output(device, true,
|
ata_finish_command(device, request, ATA_WAIT_FINISH | ATA_DRDY_REQUIRED,
|
||||||
ide_error_nm | ide_error_abrt | ide_error_mcr | ide_error_mc,
|
ide_error_nm | ide_error_abrt | ide_error_mcr | ide_error_mc);
|
||||||
false)) {
|
|
||||||
// SCSI spec is unclear here: we shouldn't report "media change (request)"
|
// SCSI spec is unclear here: we shouldn't report "media change (request)"
|
||||||
// but what to do if there is one? anyway - we report them
|
// but what to do if there is one? anyway - we report them
|
||||||
;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@@ -252,7 +249,6 @@ scsi_test_unit_ready(ide_device_info *device, ata_request *request)
|
|||||||
static bool
|
static bool
|
||||||
scsi_synchronize_cache(ide_device_info *device, ata_request *request)
|
scsi_synchronize_cache(ide_device_info *device, ata_request *request)
|
||||||
{
|
{
|
||||||
#if 0
|
|
||||||
// we should also ask for FLUSH CACHE support, but everyone denies it
|
// we should also ask for FLUSH CACHE support, but everyone denies it
|
||||||
// (looks like they cheat to gain some performance advantage, but
|
// (looks like they cheat to gain some performance advantage, but
|
||||||
// that's pretty useless: everyone does it...)
|
// that's pretty useless: everyone does it...)
|
||||||
@@ -264,14 +260,13 @@ scsi_synchronize_cache(ide_device_info *device, ata_request *request)
|
|||||||
: IDE_CMD_FLUSH_CACHE;
|
: IDE_CMD_FLUSH_CACHE;
|
||||||
|
|
||||||
// spec says that this may take more then 30s, how much more?
|
// spec says that this may take more then 30s, how much more?
|
||||||
if (!send_command(device, request, true, 60, ide_state_sync_waiting))
|
if (ata_send_command(device, request, ATA_DRDY_REQUIRED, 60000000) != B_OK)
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
wait_for_sync(device->bus);
|
if (ata_finish_command(device, request, ATA_WAIT_FINISH | ATA_DRDY_REQUIRED, ide_error_abrt) != B_OK)
|
||||||
|
return false;
|
||||||
|
|
||||||
return check_output(device, true, ide_error_abrt, false);
|
return true;
|
||||||
#endif
|
|
||||||
return false;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@@ -281,24 +276,22 @@ scsi_synchronize_cache(ide_device_info *device, ata_request *request)
|
|||||||
static bool
|
static bool
|
||||||
scsi_load_eject(ide_device_info *device, ata_request *request, bool load)
|
scsi_load_eject(ide_device_info *device, ata_request *request, bool load)
|
||||||
{
|
{
|
||||||
#if 0
|
|
||||||
if (load) {
|
if (load) {
|
||||||
// ATA doesn't support loading
|
// ATA doesn't support loading
|
||||||
set_sense(device, SCSIS_KEY_ILLEGAL_REQUEST, SCSIS_ASC_PARAM_NOT_SUPPORTED);
|
ata_request_set_sense(request, SCSIS_KEY_ILLEGAL_REQUEST, SCSIS_ASC_PARAM_NOT_SUPPORTED);
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
device->tf_param_mask = 0;
|
device->tf_param_mask = 0;
|
||||||
device->tf.lba.command = IDE_CMD_MEDIA_EJECT;
|
device->tf.lba.command = IDE_CMD_MEDIA_EJECT;
|
||||||
|
|
||||||
if (!send_command(device, request, true, 15, ide_state_sync_waiting))
|
if (ata_send_command(device, request, ATA_DRDY_REQUIRED, 15000000) != B_OK)
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
wait_for_sync(device->bus);
|
if (ata_finish_command(device, request, ATA_WAIT_FINISH | ATA_DRDY_REQUIRED, ide_error_abrt | ide_error_nm) != B_OK)
|
||||||
|
return false;
|
||||||
|
|
||||||
return check_output(device, true, ide_error_abrt | ide_error_nm, false);
|
return true;
|
||||||
#endif
|
|
||||||
return false;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user