Partially applied our style guide.

git-svn-id: file:///srv/svn/repos/haiku/trunk/current@9968 a95241bf-73f2-0310-859d-f6bbb57e9c96
This commit is contained in:
Axel Dörfler
2004-11-15 23:11:37 +00:00
parent fac367f27d
commit f16f960989
+241 -234
View File
@@ -19,7 +19,7 @@
/** verify that device is ready for further PIO transmission */ /** verify that device is ready for further PIO transmission */
static bool static bool
check_rw_status(ide_device_info *device, bool drq_required) check_rw_status(ide_device_info *device, bool drqStatus)
{ {
ide_bus_info *bus = device->bus; ide_bus_info *bus = device->bus;
int status; int status;
@@ -31,7 +31,7 @@ check_rw_status(ide_device_info *device, bool drq_required)
return false; return false;
} }
if (drq_required != ((status & ide_status_drq) != 0)) { if (drqStatus != ((status & ide_status_drq) != 0)) {
device->subsys_status = SCSI_SEQUENCE_FAIL; device->subsys_status = SCSI_SEQUENCE_FAIL;
return false; return false;
} }
@@ -52,7 +52,7 @@ ata_dpc_PIO(ide_qrequest *qrequest)
uint32 timeout = qrequest->request->timeout > 0 ? uint32 timeout = qrequest->request->timeout > 0 ?
qrequest->request->timeout : IDE_STD_TIMEOUT; qrequest->request->timeout : IDE_STD_TIMEOUT;
SHOW_FLOW0( 3, "" ); SHOW_FLOW0(3, "");
if (check_rw_error(device, qrequest) if (check_rw_error(device, qrequest)
|| !check_rw_status(device, qrequest->is_write ? device->left_blocks > 1 : true)) || !check_rw_status(device, qrequest->is_write ? device->left_blocks > 1 : true))
@@ -67,18 +67,18 @@ ata_dpc_PIO(ide_qrequest *qrequest)
if (qrequest->is_write) { if (qrequest->is_write) {
if (device->left_blocks == 0) { if (device->left_blocks == 0) {
// this was the end-of-transmission IRQ // this was the end-of-transmission IRQ
SHOW_FLOW0( 3, "write access finished" ); SHOW_FLOW0(3, "write access finished");
if (!wait_for_drq(device)) { if (!wait_for_drq(device)) {
SHOW_ERROR0( 3, "device wants to transmit data though command is finished" ); SHOW_ERROR0(3, "device wants to transmit data though command is finished");
goto finish; goto finish;
} }
goto finish; goto finish;
} }
// wait until device requests data // wait until device requests data
SHOW_FLOW0( 3, "Waiting for device ready to transmit" ); SHOW_FLOW0(3, "Waiting for device ready to transmit");
if (!wait_for_drq(device)) { if (!wait_for_drq(device)) {
SHOW_FLOW0( 3, "device not ready for data transmission - abort" ); SHOW_FLOW0(3, "device not ready for data transmission - abort");
goto finish; goto finish;
} }
@@ -93,7 +93,7 @@ ata_dpc_PIO(ide_qrequest *qrequest)
// having a too short data buffer shouldn't happen here // having a too short data buffer shouldn't happen here
// anyway - we are prepared // anyway - we are prepared
SHOW_FLOW0( 3, "Writing one block" ); SHOW_FLOW0(3, "Writing one block");
if (write_PIO_block(qrequest, 512) == B_ERROR) if (write_PIO_block(qrequest, 512) == B_ERROR)
goto finish_cancel_timeout; goto finish_cancel_timeout;
@@ -180,7 +180,8 @@ static uint8 cmd_28[2][2] = {
}; };
// create IDE read/write command /** create IDE read/write command */
static bool static bool
create_rw_taskfile(ide_device_info *device, ide_qrequest *qrequest, create_rw_taskfile(ide_device_info *device, ide_qrequest *qrequest,
uint64 pos, size_t length, bool write) uint64 pos, size_t length, bool write)
@@ -239,7 +240,7 @@ create_rw_taskfile(ide_device_info *device, ide_qrequest *qrequest,
} }
} else { } else {
// normal LBA // normal LBA
SHOW_FLOW0( 3, "using LBA" ); SHOW_FLOW0(3, "using LBA");
if (length > 0x100) if (length > 0x100)
goto err; goto err;
@@ -247,14 +248,13 @@ create_rw_taskfile(ide_device_info *device, ide_qrequest *qrequest,
if (qrequest->queuable) { if (qrequest->queuable) {
// queued LBA // queued LBA
SHOW_FLOW( 3, "creating DMA queued command, tag=%d", qrequest->tag ); SHOW_FLOW( 3, "creating DMA queued command, tag=%d", qrequest->tag );
device->tf_param_mask = device->tf_param_mask = ide_mask_features
ide_mask_features | | ide_mask_sector_count
ide_mask_sector_count | | ide_mask_LBA_low
ide_mask_LBA_low | | ide_mask_LBA_mid
ide_mask_LBA_mid | | ide_mask_LBA_high
ide_mask_LBA_high | | ide_mask_device_head;
ide_mask_device_head;
device->tf.queued.sector_count = length & 0xff; device->tf.queued.sector_count = length & 0xff;
device->tf.queued.tag = qrequest->tag; device->tf.queued.tag = qrequest->tag;
device->tf.queued.lba_0_7 = pos & 0xff; device->tf.queued.lba_0_7 = pos & 0xff;
@@ -264,16 +264,14 @@ create_rw_taskfile(ide_device_info *device, ide_qrequest *qrequest,
device->tf.queued.command = write ? IDE_CMD_WRITE_DMA_QUEUED device->tf.queued.command = write ? IDE_CMD_WRITE_DMA_QUEUED
: IDE_CMD_READ_DMA_QUEUED; : IDE_CMD_READ_DMA_QUEUED;
return true; return true;
} else { } else {
// non-queued LBA // non-queued LBA
SHOW_FLOW0( 3, "creating normal DMA/PIO command" ); SHOW_FLOW0( 3, "creating normal DMA/PIO command" );
device->tf_param_mask = device->tf_param_mask = ide_mask_sector_count
ide_mask_sector_count | | ide_mask_LBA_low
ide_mask_LBA_low | | ide_mask_LBA_mid
ide_mask_LBA_mid | | ide_mask_LBA_high
ide_mask_LBA_high | | ide_mask_device_head;
ide_mask_device_head;
device->tf.lba.sector_count = length & 0xff; device->tf.lba.sector_count = length & 0xff;
device->tf.lba.lba_0_7 = pos & 0xff; device->tf.lba.lba_0_7 = pos & 0xff;
@@ -282,7 +280,6 @@ create_rw_taskfile(ide_device_info *device, ide_qrequest *qrequest,
device->tf.lba.lba_24_27 = (pos >> 24) & 0xf; device->tf.lba.lba_24_27 = (pos >> 24) & 0xf;
device->tf.lba.command = cmd_28[qrequest->uses_dma][write]; device->tf.lba.command = cmd_28[qrequest->uses_dma][write];
return true; return true;
} }
} }
} else { } else {
@@ -290,29 +287,28 @@ create_rw_taskfile(ide_device_info *device, ide_qrequest *qrequest,
// (probably, noone would notice if we'd dropped support) // (probably, noone would notice if we'd dropped support)
uint32 track_size, cylinder_offset, cylinder; uint32 track_size, cylinder_offset, cylinder;
ide_device_infoblock *infoblock = &device->infoblock; ide_device_infoblock *infoblock = &device->infoblock;
if( length > 0x100 ) if (length > 0x100)
goto err; goto err;
device->tf.chs.mode = ide_mode_chs; device->tf.chs.mode = ide_mode_chs;
device->tf_param_mask = device->tf_param_mask = ide_mask_sector_count
ide_mask_sector_count | | ide_mask_sector_number
ide_mask_sector_number | | ide_mask_cylinder_low
ide_mask_cylinder_low | | ide_mask_cylinder_high
ide_mask_cylinder_high | | ide_mask_device_head;
ide_mask_device_head;
device->tf.chs.sector_count = length & 0xff; device->tf.chs.sector_count = length & 0xff;
track_size = infoblock->current_heads * infoblock->current_sectors; track_size = infoblock->current_heads * infoblock->current_sectors;
if( track_size == 0 ) { if (track_size == 0) {
set_sense( device, set_sense(device,
SCSIS_KEY_MEDIUM_ERROR, SCSIS_ASC_MEDIUM_FORMAT_CORRUPTED ); SCSIS_KEY_MEDIUM_ERROR, SCSIS_ASC_MEDIUM_FORMAT_CORRUPTED);
return false; return false;
} }
cylinder = pos / track_size; cylinder = pos / track_size;
device->tf.chs.cylinder_0_7 = cylinder & 0xff; device->tf.chs.cylinder_0_7 = cylinder & 0xff;
@@ -322,354 +318,365 @@ create_rw_taskfile(ide_device_info *device, ide_qrequest *qrequest,
device->tf.chs.sector_number = (cylinder_offset % infoblock->current_sectors + 1) & 0xff; device->tf.chs.sector_number = (cylinder_offset % infoblock->current_sectors + 1) & 0xff;
device->tf.chs.head = cylinder_offset / infoblock->current_sectors; device->tf.chs.head = cylinder_offset / infoblock->current_sectors;
device->tf.chs.command = cmd_28[qrequest->uses_dma][write]; device->tf.chs.command = cmd_28[qrequest->uses_dma][write];
return true; return true;
} }
return true; return true;
err: err:
set_sense( device, SCSIS_KEY_ILLEGAL_REQUEST, SCSIS_ASC_INV_CDB_FIELD ); set_sense(device, SCSIS_KEY_ILLEGAL_REQUEST, SCSIS_ASC_INV_CDB_FIELD);
return false; return false;
} }
// execute read/write command /** execute read/write command
// pos - first block * pos - first block
// length - number of blocks * length - number of blocks
void ata_send_rw( ide_device_info *device, ide_qrequest *qrequest, */
uint64 pos, size_t length, bool write )
void
ata_send_rw(ide_device_info *device, ide_qrequest *qrequest,
uint64 pos, size_t length, bool write)
{ {
ide_bus_info *bus = device->bus; ide_bus_info *bus = device->bus;
uint32 timeout; uint32 timeout;
// make a copy first as settings may get changed by user during execution // make a copy first as settings may get changed by user during execution
qrequest->is_write = write; qrequest->is_write = write;
qrequest->uses_dma = device->DMA_enabled; qrequest->uses_dma = device->DMA_enabled;
if( qrequest->uses_dma ) { if (qrequest->uses_dma) {
if( !prepare_dma( device, qrequest )) { if (!prepare_dma(device, qrequest)) {
// fall back to PIO on error // fall back to PIO on error
// if command queueing is used and there is another command // if command queueing is used and there is another command
// already running, we cannot fallback to PIO immediately -> declare // already running, we cannot fallback to PIO immediately -> declare
// command as not queuable and resubmit it, so the scsi bus manager // command as not queuable and resubmit it, so the scsi bus manager
// will block other requests on retry // will block other requests on retry
// (XXX this is not fine if the caller wants to recycle the CCB) // (XXX this is not fine if the caller wants to recycle the CCB)
if( device->num_running_reqs > 1 ) { if (device->num_running_reqs > 1) {
qrequest->request->flags &= ~SCSI_ORDERED_QTAG; qrequest->request->flags &= ~SCSI_ORDERED_QTAG;
finish_retry( qrequest ); finish_retry(qrequest);
return; return;
} }
qrequest->uses_dma = false; qrequest->uses_dma = false;
} }
} }
if( !qrequest->uses_dma ) { if (!qrequest->uses_dma) {
prep_PIO_transfer( device, qrequest ); prep_PIO_transfer(device, qrequest);
device->left_blocks = length; device->left_blocks = length;
} }
// compose command // compose command
if( !create_rw_taskfile( device, qrequest, pos, length, write )) if (!create_rw_taskfile(device, qrequest, pos, length, write))
goto err_setup; goto err_setup;
// if no timeout is specified, use standard // if no timeout is specified, use standard
timeout = qrequest->request->timeout > 0 ? timeout = qrequest->request->timeout > 0 ?
qrequest->request->timeout : IDE_STD_TIMEOUT; qrequest->request->timeout : IDE_STD_TIMEOUT;
// in DMA mode, we continue with "accessing", // in DMA mode, we continue with "accessing",
// on PIO read, we continue with "async waiting" // on PIO read, we continue with "async waiting"
// on PIO write, we continue with "accessing" // on PIO write, we continue with "accessing"
if( !send_command( device, qrequest, !device->is_atapi, timeout, if (!send_command(device, qrequest, !device->is_atapi, timeout,
(!qrequest->uses_dma && !qrequest->is_write) ? (!qrequest->uses_dma && !qrequest->is_write) ?
ide_state_async_waiting : ide_state_accessing )) ide_state_async_waiting : ide_state_accessing))
goto err_send; goto err_send;
if( qrequest->uses_dma ) { if (qrequest->uses_dma) {
// if queuing used, we have to ask device first whether it wants // if queuing used, we have to ask device first whether it wants
// to postpone the command // to postpone the command
// XXX: using the bus release IRQ we don't have to busy wait for // XXX: using the bus release IRQ we don't have to busy wait for
// a response, but I heard that IBM drives have problems with // a response, but I heard that IBM drives have problems with
// that IRQ; to be evaluated // that IRQ; to be evaluated
if( qrequest->queuable ) { if (qrequest->queuable) {
if( !wait_for_drdy( device )) if (!wait_for_drdy(device))
goto err_send; goto err_send;
if( check_rw_error( device, qrequest )) if (check_rw_error(device, qrequest))
goto err_send; goto err_send;
if( device_released_bus( device )) { if (device_released_bus(device)) {
// device enqueued command, so we have to wait; // device enqueued command, so we have to wait;
// in access_finished, we'll ask device whether it wants to // in access_finished, we'll ask device whether it wants to
// continue some other command // continue some other command
bus->active_qrequest = NULL; bus->active_qrequest = NULL;
access_finished( bus, device ); access_finished(bus, device);
// we may have rejected commands meanwhile, so tell // we may have rejected commands meanwhile, so tell
// the SIM that it can resend them now // the SIM that it can resend them now
scsi->cont_send_bus( bus->scsi_cookie ); scsi->cont_send_bus(bus->scsi_cookie);
return; return;
} }
//SHOW_ERROR0( 2, "device executes command instantly" );
}
start_dma_wait_no_lock( device, qrequest ); //SHOW_ERROR0( 2, "device executes command instantly" );
}
start_dma_wait_no_lock(device, qrequest);
} else { } else {
// on PIO read, we start with waiting, on PIO write we can // on PIO read, we start with waiting, on PIO write we can
// transmit data immediately; we let the service thread do // transmit data immediately; we let the service thread do
// the writing, so the caller can issue the next command // the writing, so the caller can issue the next command
// immediately (this optimisation really pays on SMP systems // immediately (this optimisation really pays on SMP systems
// only) // only)
SHOW_FLOW0( 3, "Ready for PIO" ); SHOW_FLOW0(3, "Ready for PIO");
if( qrequest->is_write ) { if (qrequest->is_write) {
SHOW_FLOW0( 3, "Scheduling write DPC" ); SHOW_FLOW0(3, "Scheduling write DPC");
scsi->schedule_dpc( bus->scsi_cookie, bus->irq_dpc, ide_dpc, bus ); scsi->schedule_dpc(bus->scsi_cookie, bus->irq_dpc, ide_dpc, bus);
} }
} }
return; return;
err_setup: err_setup:
// error during setup // error during setup
if( qrequest->uses_dma ) if (qrequest->uses_dma)
abort_dma( device, qrequest ); abort_dma(device, qrequest);
finish_checksense( qrequest ); finish_checksense(qrequest);
return; return;
err_send: err_send:
// error during/after send; // error during/after send;
// in this case, the device discards queued request automatically // in this case, the device discards queued request automatically
if( qrequest->uses_dma ) if (qrequest->uses_dma)
abort_dma( device, qrequest ); abort_dma(device, qrequest);
finish_reset_queue( qrequest ); finish_reset_queue(qrequest);
return;
} }
// check for errors reported by read/write command /** check for errors reported by read/write command
// return: true, if an error occured * return: true, if an error occured
bool check_rw_error( ide_device_info *device, ide_qrequest *qrequest ) */
bool
check_rw_error(ide_device_info *device, ide_qrequest *qrequest)
{ {
ide_bus_info *bus = device->bus; ide_bus_info *bus = device->bus;
uint8 status; uint8 status;
status = bus->controller->get_altstatus( bus->channel );
if( (status & ide_status_err) != 0 ) { status = bus->controller->get_altstatus(bus->channel);
if ((status & ide_status_err) != 0) {
uint8 error; uint8 error;
if( bus->controller->read_command_block_regs( bus->channel, if (bus->controller->read_command_block_regs(bus->channel,
&device->tf, ide_mask_error ) != B_OK ) &device->tf, ide_mask_error) != B_OK) {
{
device->subsys_status = SCSI_HBA_ERR; device->subsys_status = SCSI_HBA_ERR;
return true; return true;
} }
error = device->tf.read.error; error = device->tf.read.error;
if( (error & ide_error_icrc) != 0 ) { if ((error & ide_error_icrc) != 0) {
set_sense( device, SCSIS_KEY_HARDWARE_ERROR, SCSIS_ASC_LUN_COM_CRC ); set_sense(device, SCSIS_KEY_HARDWARE_ERROR, SCSIS_ASC_LUN_COM_CRC);
return true; return true;
} }
if( qrequest->is_write ) { if (qrequest->is_write) {
if( (error & ide_error_wp) != 0 ) { if ((error & ide_error_wp) != 0) {
set_sense( device, SCSIS_KEY_DATA_PROTECT, SCSIS_ASC_WRITE_PROTECTED ); set_sense(device, SCSIS_KEY_DATA_PROTECT, SCSIS_ASC_WRITE_PROTECTED);
return true; return true;
} }
} else { } else {
if( (error & ide_error_unc) != 0 ) { if ((error & ide_error_unc) != 0) {
set_sense( device, SCSIS_KEY_MEDIUM_ERROR, SCSIS_ASC_UNREC_READ_ERR ); set_sense(device, SCSIS_KEY_MEDIUM_ERROR, SCSIS_ASC_UNREC_READ_ERR);
return true; return true;
} }
} }
if( (error & ide_error_mc) != 0 ) { if ((error & ide_error_mc) != 0) {
set_sense( device, SCSIS_KEY_UNIT_ATTENTION, SCSIS_ASC_MEDIUM_CHANGED ); set_sense(device, SCSIS_KEY_UNIT_ATTENTION, SCSIS_ASC_MEDIUM_CHANGED);
return true;
}
if( (error & ide_error_idnf) != 0 ) {
// ID not found - invalid CHS mapping (was: seek error?)
set_sense( device, SCSIS_KEY_MEDIUM_ERROR, SCSIS_ASC_RANDOM_POS_ERROR );
return true;
}
if( (error & ide_error_mcr) != 0 ) {
// XXX proper sense key?
// for TUR this case is not defined !?
set_sense( device, SCSIS_KEY_UNIT_ATTENTION, SCSIS_ASC_REMOVAL_REQUESTED );
return true;
}
if( (error & ide_error_nm) != 0 ) {
set_sense( device, SCSIS_KEY_NOT_READY, SCSIS_ASC_NO_MEDIUM );
return true;
}
if( (error & ide_error_abrt) != 0 ) {
set_sense( device, SCSIS_KEY_ABORTED_COMMAND, SCSIS_ASC_NO_SENSE );
return true; return true;
} }
set_sense( device, SCSIS_KEY_HARDWARE_ERROR, SCSIS_ASC_INTERNAL_FAILURE ); if ((error & ide_error_idnf) != 0) {
// ID not found - invalid CHS mapping (was: seek error?)
set_sense(device, SCSIS_KEY_MEDIUM_ERROR, SCSIS_ASC_RANDOM_POS_ERROR);
return true;
}
if ((error & ide_error_mcr) != 0) {
// XXX proper sense key?
// for TUR this case is not defined !?
set_sense(device, SCSIS_KEY_UNIT_ATTENTION, SCSIS_ASC_REMOVAL_REQUESTED);
return true;
}
if ((error & ide_error_nm) != 0) {
set_sense(device, SCSIS_KEY_NOT_READY, SCSIS_ASC_NO_MEDIUM);
return true;
}
if ((error & ide_error_abrt) != 0) {
set_sense(device, SCSIS_KEY_ABORTED_COMMAND, SCSIS_ASC_NO_SENSE);
return true;
}
set_sense(device, SCSIS_KEY_HARDWARE_ERROR, SCSIS_ASC_INTERNAL_FAILURE);
return true; return true;
} }
return false; return false;
} }
// check result of ATA command /** check result of ATA command
// drdy_required - true if drdy must be set by device * drdy_required - true if drdy must be set by device
// error_mask - bits to be checked in error register * error_mask - bits to be checked in error register
// is_write - true, if command was a write command * 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 )
bool
check_output(ide_device_info *device, bool drdy_required,
int error_mask, bool is_write)
{ {
ide_bus_info *bus = device->bus; ide_bus_info *bus = device->bus;
uint8 status; uint8 status;
// check IRQ timeout // check IRQ timeout
if( bus->sync_wait_timeout ) { if (bus->sync_wait_timeout) {
bus->sync_wait_timeout = false; bus->sync_wait_timeout = false;
device->subsys_status = SCSI_CMD_TIMEOUT; device->subsys_status = SCSI_CMD_TIMEOUT;
return false; return false;
} }
status = bus->controller->get_altstatus( bus->channel ); status = bus->controller->get_altstatus(bus->channel);
// if device is busy, other flags are indeterminate // if device is busy, other flags are indeterminate
if( (status & ide_status_bsy) != 0 ) { 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; device->subsys_status = SCSI_SEQUENCE_FAIL;
return false; return false;
} }
if( (status & ide_status_err) != 0 ) { if (drdy_required && ((status & ide_status_drdy) == 0)) {
device->subsys_status = SCSI_SEQUENCE_FAIL;
return false;
}
if ((status & ide_status_err) != 0) {
uint8 error; uint8 error;
if( bus->controller->read_command_block_regs( bus->channel, if (bus->controller->read_command_block_regs(bus->channel,
&device->tf, ide_mask_error ) != B_OK ) &device->tf, ide_mask_error) != B_OK) {
{
device->subsys_status = SCSI_HBA_ERR; device->subsys_status = SCSI_HBA_ERR;
return false; return false;
} }
error = device->tf.read.error & error_mask; error = device->tf.read.error & error_mask;
if( (error & ide_error_icrc) != 0 ) { if ((error & ide_error_icrc) != 0) {
set_sense( device, SCSIS_KEY_HARDWARE_ERROR, SCSIS_ASC_LUN_COM_CRC ); set_sense(device, SCSIS_KEY_HARDWARE_ERROR, SCSIS_ASC_LUN_COM_CRC);
return false; return false;
} }
if( is_write ) { if (is_write) {
if( (error & ide_error_wp) != 0 ) { if ((error & ide_error_wp) != 0) {
set_sense( device, SCSIS_KEY_DATA_PROTECT, SCSIS_ASC_WRITE_PROTECTED ); set_sense(device, SCSIS_KEY_DATA_PROTECT, SCSIS_ASC_WRITE_PROTECTED);
return false; return false;
} }
} else { } else {
if( (error & ide_error_unc) != 0 ) { if ((error & ide_error_unc) != 0) {
set_sense( device, SCSIS_KEY_MEDIUM_ERROR, SCSIS_ASC_UNREC_READ_ERR ); set_sense(device, SCSIS_KEY_MEDIUM_ERROR, SCSIS_ASC_UNREC_READ_ERR);
return false; return false;
} }
} }
if( (error & ide_error_mc) != 0 ) { if ((error & ide_error_mc) != 0) {
// XXX proper sense key? // XXX proper sense key?
set_sense( device, SCSIS_KEY_UNIT_ATTENTION, SCSIS_ASC_MEDIUM_CHANGED ); set_sense(device, SCSIS_KEY_UNIT_ATTENTION, SCSIS_ASC_MEDIUM_CHANGED);
return false; return false;
} }
if( (error & ide_error_idnf) != 0 ) { if ((error & ide_error_idnf) != 0) {
// XXX strange error code, don't really know what it means // XXX strange error code, don't really know what it means
set_sense( device, SCSIS_KEY_MEDIUM_ERROR, SCSIS_ASC_RANDOM_POS_ERROR ); set_sense(device, SCSIS_KEY_MEDIUM_ERROR, SCSIS_ASC_RANDOM_POS_ERROR);
return false; return false;
} }
if( (error & ide_error_mcr) != 0 ) { if ((error & ide_error_mcr) != 0) {
// XXX proper sense key? // XXX proper sense key?
set_sense( device, SCSIS_KEY_UNIT_ATTENTION, SCSIS_ASC_REMOVAL_REQUESTED ); set_sense(device, SCSIS_KEY_UNIT_ATTENTION, SCSIS_ASC_REMOVAL_REQUESTED);
return false; return false;
} }
if( (error & ide_error_nm) != 0 ) { if ((error & ide_error_nm) != 0) {
set_sense( device, SCSIS_KEY_MEDIUM_ERROR, SCSIS_ASC_NO_MEDIUM ); set_sense(device, SCSIS_KEY_MEDIUM_ERROR, SCSIS_ASC_NO_MEDIUM);
return false; return false;
} }
if( (error & ide_error_abrt) != 0 ) { if ((error & ide_error_abrt) != 0) {
set_sense( device, SCSIS_KEY_ABORTED_COMMAND, SCSIS_ASC_NO_SENSE ); set_sense(device, SCSIS_KEY_ABORTED_COMMAND, SCSIS_ASC_NO_SENSE);
return false; return false;
} }
// either there was no error bit set or it was masked out // either there was no error bit set or it was masked out
set_sense( device, SCSIS_KEY_HARDWARE_ERROR, SCSIS_ASC_INTERNAL_FAILURE ); set_sense(device, SCSIS_KEY_HARDWARE_ERROR, SCSIS_ASC_INTERNAL_FAILURE);
return false; return false;
} }
return true; return true;
} }
// execute SET FEATURE command
// set subcommand in task file before calling this /** execute SET FEATURE command
static bool device_set_feature( ide_device_info *device, int feature ) * set subcommand in task file before calling this
*/
static bool
device_set_feature(ide_device_info *device, int 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, true, 1, ide_state_sync_waiting )) if (!send_command(device, NULL, true, 1, ide_state_sync_waiting))
return false; return false;
wait_for_sync( device->bus ); wait_for_sync(device->bus);
return check_output( device, true, ide_error_abrt, false ); return check_output(device, true, ide_error_abrt, false);
} }
static bool configure_rmsn( ide_device_info *device )
static bool
configure_rmsn(ide_device_info *device)
{ {
ide_bus_info *bus = device->bus; ide_bus_info *bus = device->bus;
int i; int i;
if( !device->infoblock.RMSN_supported || if (!device->infoblock.RMSN_supported
device->infoblock._127_RMSN_support != 1 ) || device->infoblock._127_RMSN_support != 1)
return true; return true;
if( !device_set_feature( device, IDE_CMD_SET_FEATURES_ENABLE_MSN )) if (!device_set_feature(device, IDE_CMD_SET_FEATURES_ENABLE_MSN))
return false; return false;
bus->controller->read_command_block_regs( bus->channel, &device->tf, bus->controller->read_command_block_regs(bus->channel, &device->tf,
ide_mask_LBA_mid | ide_mask_LBA_high ); ide_mask_LBA_mid | ide_mask_LBA_high);
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->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, true, 15, ide_state_sync_waiting )) if (!send_command(device, NULL, true, 15, ide_state_sync_waiting))
continue; continue;
if( check_output( device, true, if (check_output(device, true,
ide_error_nm | ide_error_abrt | ide_error_mcr | ide_error_mc, ide_error_nm | ide_error_abrt | ide_error_mcr | ide_error_mc,
true ) true)
|| decode_sense_asc_ascq( device->combined_sense ) == SCSIS_ASC_NO_MEDIUM ) || decode_sense_asc_ascq(device->combined_sense) == SCSIS_ASC_NO_MEDIUM)
return true; return true;
} }
@@ -709,13 +716,13 @@ prep_ata(ide_device_info *device)
{ {
ide_device_infoblock *infoblock = &device->infoblock; ide_device_infoblock *infoblock = &device->infoblock;
uint32 chs_capacity; uint32 chs_capacity;
SHOW_FLOW0( 3, "" ); SHOW_FLOW0(3, "");
device->is_atapi = false; device->is_atapi = false;
device->exec_io = ata_exec_io; device->exec_io = ata_exec_io;
device->last_lun = 0; device->last_lun = 0;
// warning: ata == 0 means "this is ata"... // warning: ata == 0 means "this is ata"...
if (infoblock->_0.ata.ATA != 0) { if (infoblock->_0.ata.ATA != 0) {
// CF has either magic header or CFA bit set // CF has either magic header or CFA bit set
@@ -726,7 +733,7 @@ prep_ata(ide_device_info *device)
return false; return false;
} }
SHOW_FLOW0( 3, "1" ); SHOW_FLOW0(3, "1");
if (!infoblock->_54_58_valid) { if (!infoblock->_54_58_valid) {
// normally, current_xxx contains active CHS mapping, // normally, current_xxx contains active CHS mapping,
@@ -735,16 +742,16 @@ prep_ata(ide_device_info *device)
infoblock->current_sectors = infoblock->sectors; infoblock->current_sectors = infoblock->sectors;
infoblock->current_cylinders = infoblock->cylinders; infoblock->current_cylinders = infoblock->cylinders;
infoblock->current_heads = infoblock->heads; infoblock->current_heads = infoblock->heads;
} }
// just in case capacity_xxx isn't initialized - calculate it manually // just in case capacity_xxx isn't initialized - calculate it manually
// (seems that this information is really redundant; hopefully) // (seems that this information is really redundant; hopefully)
chs_capacity = infoblock->current_sectors * infoblock->current_cylinders * chs_capacity = infoblock->current_sectors * infoblock->current_cylinders *
infoblock->current_heads; infoblock->current_heads;
infoblock->capacity_low = chs_capacity & 0xff; infoblock->capacity_low = chs_capacity & 0xff;
infoblock->capacity_high = chs_capacity >> 8; infoblock->capacity_high = chs_capacity >> 8;
// checking LBA_supported flag should be sufficient, but it seems // checking LBA_supported flag should be sufficient, but it seems
// that checking LBA_total_sectors is a good idea // that checking LBA_total_sectors is a good idea
device->use_LBA = infoblock->LBA_supported && infoblock->LBA_total_sectors != 0; device->use_LBA = infoblock->LBA_supported && infoblock->LBA_total_sectors != 0;
@@ -770,7 +777,7 @@ prep_ata(ide_device_info *device)
return false; return false;
SHOW_FLOW0(3, "3"); SHOW_FLOW0(3, "3");
return true; return true;
} }