git-svn-id: file:///srv/svn/repos/haiku/haiku/trunk@16938 a95241bf-73f2-0310-859d-f6bbb57e9c96
This commit is contained in:
Axel Dörfler
2006-03-30 20:43:13 +00:00
parent 2ed4099289
commit af29aba8a6
+44 -43
View File
@@ -1,6 +1,8 @@
/* /*
** Copyright 2002/03, Thomas Kurschel. All rights reserved. * Copyright 2004-2006, Haiku, Inc. All RightsReserved.
** Distributed under the terms of the OpenBeOS License. * Copyright 2002/03, Thomas Kurschel. All rights reserved.
*
* Distributed under the terms of the MIT License.
*/ */
/* /*
@@ -24,9 +26,12 @@
#define IDE_ATAPI_BUFFER_SIZE 512 #define IDE_ATAPI_BUFFER_SIZE 512
// set sense according to error reported by device /** Set sense according to error reported by device
// return: true - device reported error * return: true - device reported error
static bool check_packet_error( ide_device_info *device, ide_qrequest *qrequest ) */
static bool
check_packet_error(ide_device_info *device, ide_qrequest *qrequest)
{ {
ide_bus_info *bus = device->bus; ide_bus_info *bus = device->bus;
int status; int status;
@@ -39,8 +44,7 @@ static bool check_packet_error( ide_device_info *device, ide_qrequest *qrequest
SHOW_FLOW(3, "packet error, status=%02x", status); SHOW_FLOW(3, "packet error, status=%02x", status);
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;
} }
@@ -49,13 +53,13 @@ static bool check_packet_error( ide_device_info *device, ide_qrequest *qrequest
// we don't want to clutter syslog with "not ready" and UA messages, // we don't want to clutter syslog with "not ready" and UA messages,
// so use FLOW messages for them // so use FLOW messages for them
error = device->tf.read.error; error = device->tf.read.error;
if( (error >> 4) == SCSIS_KEY_NOT_READY || if ((error >> 4) == SCSIS_KEY_NOT_READY
(error >> 4) == SCSIS_KEY_UNIT_ATTENTION ) || (error >> 4) == SCSIS_KEY_UNIT_ATTENTION)
SHOW_FLOW(3, "error=%x", error); SHOW_FLOW(3, "error=%x", error);
else else
SHOW_ERROR(3, "error=%x", error); SHOW_ERROR(3, "error=%x", error);
// ATAPI says that // ATAPI says that:
// "ABRT shall be set to one if the requested command has been command // "ABRT shall be set to one if the requested command has been command
// aborted because the command code or a command parameter is invalid. // aborted because the command code or a command parameter is invalid.
// ABRT may be set to one if the device is not able to complete the // ABRT may be set to one if the device is not able to complete the
@@ -84,8 +88,10 @@ static bool check_packet_error( ide_device_info *device, ide_qrequest *qrequest
} }
// IRQ handler of packet transfer (executed as DPC) /** IRQ handler of packet transfer (executed as DPC) */
void packet_dpc( ide_qrequest *qrequest )
void
packet_dpc(ide_qrequest *qrequest)
{ {
ide_device_info *device = qrequest->device; ide_device_info *device = qrequest->device;
ide_bus_info *bus = device->bus; ide_bus_info *bus = device->bus;
@@ -104,10 +110,9 @@ void packet_dpc( ide_qrequest *qrequest )
// device requests packet // device requests packet
qrequest->packet_irq = false; qrequest->packet_irq = false;
if( !device->tf.packet_res.cmd_or_data || if (!device->tf.packet_res.cmd_or_data
device->tf.packet_res.input_or_output || || device->tf.packet_res.input_or_output
(status & ide_status_drq) == 0 ) || (status & ide_status_drq) == 0) {
{
device->subsys_status = SCSI_SEQUENCE_FAIL; device->subsys_status = SCSI_SEQUENCE_FAIL;
goto err; goto err;
} }
@@ -117,8 +122,7 @@ void packet_dpc( ide_qrequest *qrequest )
// send packet // send packet
if (bus->controller->write_pio(bus->channel, if (bus->controller->write_pio(bus->channel,
(uint16 *)device->packet, sizeof(device->packet) / sizeof(uint16), (uint16 *)device->packet, sizeof(device->packet) / sizeof(uint16),
true ) != B_OK ) true) != B_OK) {
{
SHOW_ERROR0( 1, "Error sending command packet" ); SHOW_ERROR0( 1, "Error sending command packet" );
device->subsys_status = SCSI_HBA_ERR; device->subsys_status = SCSI_HBA_ERR;
@@ -157,7 +161,6 @@ void packet_dpc( ide_qrequest *qrequest )
// how much has been transmitted // how much has been transmitted
qrequest->request->data_resid = 0; qrequest->request->data_resid = 0;
finish_checksense(qrequest); finish_checksense(qrequest);
} else { } else {
// DMA transmission went wrong // DMA transmission went wrong
set_sense(device, SCSIS_KEY_HARDWARE_ERROR, SCSIS_ASC_LUN_COM_FAILURE); set_sense(device, SCSIS_KEY_HARDWARE_ERROR, SCSIS_ASC_LUN_COM_FAILURE);
@@ -191,18 +194,17 @@ void packet_dpc( ide_qrequest *qrequest )
if ((device->tf.packet_res.input_or_output ^ qrequest->is_write) == 0) { if ((device->tf.packet_res.input_or_output ^ qrequest->is_write) == 0) {
SHOW_ERROR0(2, "data transmission in wrong way!?"); SHOW_ERROR0(2, "data transmission in wrong way!?");
// XXX hm, either the device is broken or the caller has specified // TODO: hm, either the device is broken or the caller has specified
// the wrong direction - what is the proper handling? // the wrong direction - what is the proper handling?
set_sense(device, SCSIS_KEY_HARDWARE_ERROR, SCSIS_ASC_LUN_COM_FAILURE); set_sense(device, SCSIS_KEY_HARDWARE_ERROR, SCSIS_ASC_LUN_COM_FAILURE);
// reset device to make it alive // reset device to make it alive
// TBD: the device will abort next command with a reset condition // TODO: the device will abort next command with a reset condition
// perhaps we should hide that by reading sense? // perhaps we should hide that by reading sense?
SHOW_FLOW0(3, "Reset"); SHOW_FLOW0(3, "Reset");
reset_device(device, qrequest); reset_device(device, qrequest);
finish_checksense(qrequest); finish_checksense(qrequest);
return; return;
} }
@@ -210,8 +212,8 @@ void packet_dpc( ide_qrequest *qrequest )
bus->controller->read_command_block_regs(bus->channel, bus->controller->read_command_block_regs(bus->channel,
&device->tf, ide_mask_byte_count); &device->tf, ide_mask_byte_count);
length = device->tf.packet_res.byte_count_0_7 | length = device->tf.packet_res.byte_count_0_7
((int)device->tf.packet_res.byte_count_8_15 << 8); | ((int)device->tf.packet_res.byte_count_8_15 << 8);
SHOW_FLOW(3, "device transmittes %d bytes", length); SHOW_FLOW(3, "device transmittes %d bytes", length);
@@ -236,9 +238,7 @@ void packet_dpc( ide_qrequest *qrequest )
} }
SHOW_FLOW0(3, "7"); SHOW_FLOW0(3, "7");
return; return;
} else { } else {
// device has done job and doesn't want to transmit data anymore // device has done job and doesn't want to transmit data anymore
// -> finish request // -> finish request
@@ -258,14 +258,15 @@ void packet_dpc( ide_qrequest *qrequest )
err_cancel_timer: err_cancel_timer:
cancel_irq_timeout(device->bus); cancel_irq_timeout(device->bus);
err: err:
finish_checksense(qrequest); finish_checksense(qrequest);
} }
// create taskfile for ATAPI packet /** Create taskfile for ATAPI packet */
static bool create_packet_taskfile( ide_device_info *device, ide_qrequest *qrequest,
static bool
create_packet_taskfile(ide_device_info *device, ide_qrequest *qrequest,
bool write) bool write)
{ {
scsi_ccb *request = qrequest->request; scsi_ccb *request = qrequest->request;
@@ -285,8 +286,10 @@ static bool create_packet_taskfile( ide_device_info *device, ide_qrequest *qrequ
} }
// send ATAPI packet /** Send ATAPI packet */
void send_packet( ide_device_info *device, ide_qrequest *qrequest, bool write )
void
send_packet(ide_device_info *device, ide_qrequest *qrequest, bool write)
{ {
ide_bus_info *bus = device->bus; ide_bus_info *bus = device->bus;
bool packet_irq = device->atapi.packet_irq; bool packet_irq = device->atapi.packet_irq;
@@ -353,10 +356,11 @@ void send_packet( ide_device_info *device, ide_qrequest *qrequest, bool write )
SHOW_FLOW0(3, "4"); SHOW_FLOW0(3, "4");
if( packet_irq ) if (packet_irq) {
// device asks for packet via IRQ; // device asks for packet via IRQ;
// timeout and stuff is already set by send_command // timeout and stuff is already set by send_command
return; return;
}
SHOW_FLOW0(3, "5"); SHOW_FLOW0(3, "5");
@@ -370,9 +374,8 @@ void send_packet( ide_device_info *device, ide_qrequest *qrequest, bool write )
bus->controller->read_command_block_regs(bus->channel, &device->tf, bus->controller->read_command_block_regs(bus->channel, &device->tf,
ide_mask_ireason); ide_mask_ireason);
if( !device->tf.packet_res.cmd_or_data || if (!device->tf.packet_res.cmd_or_data
device->tf.packet_res.input_or_output ) || device->tf.packet_res.input_or_output) {
{
device->subsys_status = SCSI_SEQUENCE_FAIL; device->subsys_status = SCSI_SEQUENCE_FAIL;
goto err_setup; goto err_setup;
} }
@@ -392,8 +395,7 @@ void send_packet( ide_device_info *device, ide_qrequest *qrequest, bool write )
// write packet // write packet
if (bus->controller->write_pio(bus->channel, if (bus->controller->write_pio(bus->channel,
(uint16 *)device->packet, sizeof(device->packet) / sizeof(uint16) - 2, (uint16 *)device->packet, sizeof(device->packet) / sizeof(uint16) - 2,
true ) != B_OK ) true) != B_OK) {
{
goto err_packet; goto err_packet;
} }
@@ -401,8 +403,7 @@ void send_packet( ide_device_info *device, ide_qrequest *qrequest, bool write )
if (bus->controller->write_pio(bus->channel, if (bus->controller->write_pio(bus->channel,
(uint16 *)device->packet + sizeof(device->packet) / sizeof(uint16) - 2, (uint16 *)device->packet + sizeof(device->packet) / sizeof(uint16) - 2,
2, true ) != B_OK ) 2, true) != B_OK) {
{
goto err_packet2; goto err_packet2;
} }
@@ -420,7 +421,6 @@ void send_packet( ide_device_info *device, ide_qrequest *qrequest, bool write )
} }
SHOW_FLOW0(3, "8"); SHOW_FLOW0(3, "8");
return; return;
err_packet2: err_packet2:
@@ -437,8 +437,10 @@ err_setup:
} }
// execute SCSI I/O for atapi devices /** Execute SCSI I/O for atapi devices */
void atapi_exec_io( ide_device_info *device, ide_qrequest *qrequest )
void
atapi_exec_io(ide_device_info *device, ide_qrequest *qrequest)
{ {
scsi_ccb *request = qrequest->request; scsi_ccb *request = qrequest->request;
@@ -453,7 +455,6 @@ void atapi_exec_io( ide_device_info *device, ide_qrequest *qrequest )
// we have a pending emulated sense - return it on REQUEST SENSE // we have a pending emulated sense - return it on REQUEST SENSE
ide_request_sense(device, qrequest); ide_request_sense(device, qrequest);
finish_checksense(qrequest); finish_checksense(qrequest);
} else { } else {
// reset all error codes for new request // reset all error codes for new request
start_request(device, qrequest); start_request(device, qrequest);