Style cleanup.
Removed some temporary debug output. git-svn-id: file:///srv/svn/repos/haiku/trunk/current@7834 a95241bf-73f2-0310-859d-f6bbb57e9c96
This commit is contained in:
@@ -25,40 +25,40 @@ scsi_requeue_request(scsi_ccb *request, bool bus_overflow)
|
||||
scsi_device_info *device = request->device;
|
||||
bool was_servicable, start_retry;
|
||||
|
||||
FAST_LOG1( device->log, ev_scsi_requeue_request, (uint32)request );
|
||||
SHOW_FLOW0( 3, "" );
|
||||
|
||||
if( request->state != SCSI_STATE_SENT ) {
|
||||
panic( "Unsent ccb was request to requeue\n" );
|
||||
FAST_LOG1(device->log, ev_scsi_requeue_request, (uint32)request);
|
||||
SHOW_FLOW0(3, "");
|
||||
|
||||
if (request->state != SCSI_STATE_SENT) {
|
||||
panic("Unsent ccb was request to requeue\n");
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
request->state = SCSI_STATE_QUEUED;
|
||||
|
||||
ACQUIRE_BEN( &bus->mutex );
|
||||
ACQUIRE_BEN(&bus->mutex);
|
||||
|
||||
was_servicable = scsi_can_service_bus( bus );
|
||||
was_servicable = scsi_can_service_bus(bus);
|
||||
|
||||
if( bus->left_slots++ == 0 )
|
||||
scsi_unblock_bus_noresume( bus, false );
|
||||
|
||||
if( device->left_slots++ == 0 || request->ordered )
|
||||
scsi_unblock_device_noresume( device, false );
|
||||
if (bus->left_slots++ == 0)
|
||||
scsi_unblock_bus_noresume(bus, false);
|
||||
|
||||
if (device->left_slots++ == 0 || request->ordered)
|
||||
scsi_unblock_device_noresume(device, false);
|
||||
|
||||
// make sure it's the next request for this device
|
||||
scsi_add_req_queue_first( request );
|
||||
|
||||
if( bus_overflow ) {
|
||||
scsi_add_req_queue_first(request);
|
||||
|
||||
if (bus_overflow) {
|
||||
// bus has overflown
|
||||
scsi_set_bus_overflow( bus );
|
||||
scsi_set_bus_overflow(bus);
|
||||
// add device to queue as last - other devices may be waiting already
|
||||
scsi_add_device_queue_last( device );
|
||||
scsi_add_device_queue_last(device);
|
||||
// don't change device overflow condition as the device has never seen
|
||||
// this request
|
||||
} else {
|
||||
// device has overflown
|
||||
scsi_set_device_overflow( device );
|
||||
scsi_remove_device_queue( device );
|
||||
scsi_set_device_overflow(device);
|
||||
scsi_remove_device_queue(device);
|
||||
// either, the device has refused the request, i.e. it was transmitted
|
||||
// over the bus - in this case, the bus cannot be overloaded anymore;
|
||||
// or, the driver detected that the device can not be able to process
|
||||
@@ -66,89 +66,93 @@ scsi_requeue_request(scsi_ccb *request, bool bus_overflow)
|
||||
// or something - in this case, the bus state hasn't changed, but the
|
||||
// driver will tell us about any overflow when we submit the next
|
||||
// request, so the overflow state will be fixed automatically
|
||||
scsi_clear_bus_overflow( bus );
|
||||
scsi_clear_bus_overflow(bus);
|
||||
}
|
||||
|
||||
start_retry = !was_servicable && scsi_can_service_bus( bus );
|
||||
start_retry = !was_servicable && scsi_can_service_bus(bus);
|
||||
|
||||
RELEASE_BEN( &bus->mutex );
|
||||
RELEASE_BEN(&bus->mutex);
|
||||
|
||||
// submit requests to other devices in case bus was overloaded
|
||||
if( start_retry )
|
||||
release_sem_etc( bus->start_service, 1, 0/*B_DO_NOT_RESCHEDULE*/ );
|
||||
if (start_retry)
|
||||
release_sem_etc(bus->start_service, 1, 0/*B_DO_NOT_RESCHEDULE*/);
|
||||
}
|
||||
|
||||
|
||||
// restart request ASAP because something went wrong
|
||||
void scsi_resubmit_request( scsi_ccb *request )
|
||||
/** restart request ASAP because something went wrong */
|
||||
|
||||
void
|
||||
scsi_resubmit_request(scsi_ccb *request)
|
||||
{
|
||||
scsi_bus_info *bus = request->bus;
|
||||
scsi_device_info *device = request->device;
|
||||
bool was_servicable, start_retry;
|
||||
|
||||
FAST_LOG1( device->log, ev_scsi_resubmit_request, (uint32)request );
|
||||
SHOW_FLOW0( 3, "" );
|
||||
|
||||
if( request->state != SCSI_STATE_SENT ) {
|
||||
panic( "Unsent ccb was asked to get resubmitted\n" );
|
||||
FAST_LOG1(device->log, ev_scsi_resubmit_request, (uint32)request);
|
||||
SHOW_FLOW0(3, "");
|
||||
|
||||
if (request->state != SCSI_STATE_SENT) {
|
||||
panic("Unsent ccb was asked to get resubmitted\n");
|
||||
return;
|
||||
}
|
||||
|
||||
request->state = SCSI_STATE_QUEUED;
|
||||
|
||||
ACQUIRE_BEN( &bus->mutex );
|
||||
|
||||
was_servicable = scsi_can_service_bus( bus );
|
||||
|
||||
if( bus->left_slots++ == 0 )
|
||||
scsi_unblock_bus_noresume( bus, false );
|
||||
|
||||
if( device->left_slots++ == 0 || request->ordered )
|
||||
scsi_unblock_device_noresume( device, false );
|
||||
|
||||
request->state = SCSI_STATE_QUEUED;
|
||||
|
||||
ACQUIRE_BEN(&bus->mutex);
|
||||
|
||||
was_servicable = scsi_can_service_bus(bus);
|
||||
|
||||
if (bus->left_slots++ == 0)
|
||||
scsi_unblock_bus_noresume(bus, false);
|
||||
|
||||
if (device->left_slots++ == 0 || request->ordered)
|
||||
scsi_unblock_device_noresume(device, false);
|
||||
|
||||
// if SIM reported overflow of device/bus, this should (hopefully) be over now
|
||||
scsi_clear_device_overflow( device );
|
||||
scsi_clear_bus_overflow( bus );
|
||||
|
||||
scsi_clear_device_overflow(device);
|
||||
scsi_clear_bus_overflow(bus);
|
||||
|
||||
// we don't want to let anyone overtake this request
|
||||
request->ordered = true;
|
||||
|
||||
|
||||
// make it the next request submitted to SIM for this device
|
||||
scsi_add_req_queue_first( request );
|
||||
|
||||
scsi_add_req_queue_first(request);
|
||||
|
||||
// if device is not blocked (anymore) add it to waiting list of bus
|
||||
if( device->lock_count == 0 ) {
|
||||
scsi_add_device_queue_first( device );
|
||||
if (device->lock_count == 0) {
|
||||
scsi_add_device_queue_first(device);
|
||||
// as previous line does nothing if already queued, we force device
|
||||
// to be the next one to get handled
|
||||
bus->waiting_devices = device;
|
||||
}
|
||||
|
||||
start_retry = !was_servicable && scsi_can_service_bus( bus );
|
||||
|
||||
RELEASE_BEN( &bus->mutex );
|
||||
|
||||
start_retry = !was_servicable && scsi_can_service_bus(bus);
|
||||
|
||||
RELEASE_BEN(&bus->mutex);
|
||||
|
||||
// let the service thread do the resubmit
|
||||
if( start_retry )
|
||||
release_sem_etc( bus->start_service, 1, 0/*B_DO_NOT_RESCHEDULE*/ );
|
||||
if (start_retry)
|
||||
release_sem_etc(bus->start_service, 1, 0/*B_DO_NOT_RESCHEDULE*/);
|
||||
}
|
||||
|
||||
|
||||
// submit autosense for request
|
||||
static void submit_autosense( scsi_ccb *request )
|
||||
/** submit autosense for request */
|
||||
|
||||
static void
|
||||
submit_autosense(scsi_ccb *request)
|
||||
{
|
||||
scsi_device_info *device = request->device;
|
||||
|
||||
FAST_LOG1( device->log, ev_scsi_submit_autosense, (uint32)request );
|
||||
//snooze( 1000000 );
|
||||
|
||||
SHOW_FLOW0( 3, "sending autosense" );
|
||||
FAST_LOG1(device->log, ev_scsi_submit_autosense, (uint32)request);
|
||||
//snooze(1000000);
|
||||
|
||||
SHOW_FLOW0(3, "sending autosense");
|
||||
// we cannot use scsi_scsi_io but must insert it brute-force
|
||||
|
||||
|
||||
// give SIM a well-defined first state
|
||||
// WARNING: this is a short version of scsi_async_io, so if
|
||||
// you change something there, do it here as well!
|
||||
|
||||
|
||||
// no DMA buffer (we made sure that the data buffer fulfills all
|
||||
// limitations)
|
||||
request->buffered = false;
|
||||
@@ -156,37 +160,37 @@ static void submit_autosense( scsi_ccb *request )
|
||||
request->ordered = true;
|
||||
// initial SIM state for this request
|
||||
request->sim_state = 0;
|
||||
|
||||
|
||||
device->auto_sense_originator = request;
|
||||
|
||||
|
||||
// make it next request to process
|
||||
scsi_add_queued_request_first( device->auto_sense_request );
|
||||
scsi_add_queued_request_first(device->auto_sense_request);
|
||||
}
|
||||
|
||||
|
||||
// finish special auto-sense request
|
||||
static void finish_autosense( scsi_device_info *device )
|
||||
/** finish special auto-sense request */
|
||||
|
||||
static void
|
||||
finish_autosense(scsi_device_info *device)
|
||||
{
|
||||
scsi_ccb
|
||||
*orig_request = device->auto_sense_originator,
|
||||
*request = device->auto_sense_request;
|
||||
scsi_ccb *orig_request = device->auto_sense_originator;
|
||||
scsi_ccb *request = device->auto_sense_request;
|
||||
|
||||
FAST_LOG2( device->log, ev_scsi_finish_autosense, (uint32)request, (uint32)orig_request );
|
||||
SHOW_FLOW0( 3, "" );
|
||||
FAST_LOG2(device->log, ev_scsi_finish_autosense, (uint32)request, (uint32)orig_request);
|
||||
SHOW_FLOW0(3, "");
|
||||
|
||||
if( request->subsys_status == SCSI_REQ_CMP ) {
|
||||
if (request->subsys_status == SCSI_REQ_CMP) {
|
||||
int sense_len;
|
||||
|
||||
|
||||
// we got sense data -> copy it to sense buffer
|
||||
sense_len = min( SCSI_MAX_SENSE_SIZE,
|
||||
request->data_len - request->data_resid );
|
||||
|
||||
SHOW_FLOW( 3, "Got sense: %d bytes", sense_len );
|
||||
|
||||
memcpy( orig_request->sense, request->data, sense_len );
|
||||
|
||||
sense_len = min(SCSI_MAX_SENSE_SIZE,
|
||||
request->data_len - request->data_resid);
|
||||
|
||||
SHOW_FLOW(3, "Got sense: %d bytes", sense_len);
|
||||
|
||||
memcpy(orig_request->sense, request->data, sense_len);
|
||||
|
||||
orig_request->sense_resid = SCSI_MAX_SENSE_SIZE - sense_len;
|
||||
|
||||
orig_request->subsys_status |= SCSI_AUTOSNS_VALID;
|
||||
} else {
|
||||
// failed to get sense
|
||||
@@ -194,185 +198,189 @@ static void finish_autosense( scsi_device_info *device )
|
||||
}
|
||||
|
||||
// inform peripheral driver
|
||||
release_sem_etc( orig_request->completion_sem, 1, 0/*B_DO_NOT_RESCHEDULE*/ );
|
||||
release_sem_etc(orig_request->completion_sem, 1, 0/*B_DO_NOT_RESCHEDULE*/);
|
||||
}
|
||||
|
||||
|
||||
// device refused request because command queue is full
|
||||
static void scsi_device_queue_overflow( scsi_ccb *request, uint num_requests )
|
||||
/** device refused request because command queue is full */
|
||||
|
||||
static void
|
||||
scsi_device_queue_overflow(scsi_ccb *request, uint num_requests)
|
||||
{
|
||||
scsi_bus_info *bus = request->bus;
|
||||
scsi_device_info *device = request->device;
|
||||
int diff_max_slots;
|
||||
|
||||
FAST_LOG2( device->log, ev_scsi_device_queue_overflow, (uint32)request, num_requests );
|
||||
|
||||
FAST_LOG2(device->log, ev_scsi_device_queue_overflow, (uint32)request, num_requests);
|
||||
|
||||
// set maximum number of concurrent requests to number of
|
||||
// requests running when QUEUE FULL condition occurred - 1
|
||||
// (the "1" is the refused request)
|
||||
--num_requests;
|
||||
|
||||
|
||||
// at least one request at once must be possible
|
||||
if( num_requests < 1 )
|
||||
if (num_requests < 1)
|
||||
num_requests = 1;
|
||||
|
||||
SHOW_INFO( 2, "Restricting device queue to %d requests", num_requests );
|
||||
|
||||
|
||||
SHOW_INFO(2, "Restricting device queue to %d requests", num_requests);
|
||||
|
||||
// update slot count
|
||||
ACQUIRE_BEN( &bus->mutex );
|
||||
|
||||
ACQUIRE_BEN(&bus->mutex);
|
||||
|
||||
diff_max_slots = device->total_slots - num_requests;
|
||||
device->total_slots = num_requests;
|
||||
device->left_slots -= diff_max_slots;
|
||||
|
||||
RELEASE_BEN( &bus->mutex );
|
||||
|
||||
|
||||
RELEASE_BEN(&bus->mutex);
|
||||
|
||||
// requeue request, blocking further device requests
|
||||
scsi_requeue_request( request, false );
|
||||
scsi_requeue_request(request, false);
|
||||
}
|
||||
|
||||
// finish scsi request
|
||||
void scsi_request_finished( scsi_ccb *request, uint num_requests )
|
||||
|
||||
/** finish scsi request */
|
||||
|
||||
void
|
||||
scsi_request_finished(scsi_ccb *request, uint num_requests)
|
||||
{
|
||||
scsi_device_info *device = request->device;
|
||||
scsi_bus_info *bus = request->bus;
|
||||
bool was_servicable, start_service, do_autosense;
|
||||
|
||||
FAST_LOG2( device->log, ev_scsi_request_finished, (uint32)request, num_requests );
|
||||
SHOW_FLOW( 3, "%p", request );
|
||||
|
||||
if( request->state != SCSI_STATE_SENT ) {
|
||||
panic( "Unsent ccb 0x%x was reported as done\n", request );
|
||||
FAST_LOG2(device->log, ev_scsi_request_finished, (uint32)request, num_requests);
|
||||
SHOW_FLOW(3, "%p", request);
|
||||
|
||||
if (request->state != SCSI_STATE_SENT) {
|
||||
panic("Unsent ccb 0x%x was reported as done\n", request);
|
||||
return;
|
||||
}
|
||||
|
||||
if( request->subsys_status == SCSI_REQ_INPROG ) {
|
||||
panic( "ccb 0x%xwith status \"Request in Progress\" was reported as done\n",
|
||||
request );
|
||||
if (request->subsys_status == SCSI_REQ_INPROG) {
|
||||
panic("ccb 0x%xwith status \"Request in Progress\" was reported as done\n",
|
||||
request);
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
// check for queue overflow reported by device
|
||||
if( request->subsys_status == SCSI_REQ_CMP_ERR &&
|
||||
request->device_status == SCSI_STATUS_QUEUE_FULL )
|
||||
{
|
||||
scsi_device_queue_overflow( request, num_requests );
|
||||
if (request->subsys_status == SCSI_REQ_CMP_ERR
|
||||
&& request->device_status == SCSI_STATUS_QUEUE_FULL) {
|
||||
scsi_device_queue_overflow(request, num_requests);
|
||||
return;
|
||||
}
|
||||
|
||||
request->state = SCSI_STATE_FINISHED;
|
||||
|
||||
ACQUIRE_BEN( &bus->mutex );
|
||||
|
||||
was_servicable = scsi_can_service_bus( bus );
|
||||
|
||||
ACQUIRE_BEN(&bus->mutex);
|
||||
|
||||
was_servicable = scsi_can_service_bus(bus);
|
||||
|
||||
// do pseudo-autosense if device doesn't support it and
|
||||
// device reported a check condition state and auto-sense haven't
|
||||
// been retrieved by SIM
|
||||
// (last test is implicit as SIM adds SCSI_AUTOSNS_VALID to subsys_status)
|
||||
do_autosense =
|
||||
device->manual_autosense &&
|
||||
(request->flags & SCSI_DIS_AUTOSENSE) == 0 &&
|
||||
request->subsys_status == SCSI_REQ_CMP_ERR &&
|
||||
request->device_status == SCSI_STATUS_CHECK_CONDITION;
|
||||
|
||||
if( request->subsys_status != SCSI_REQ_CMP ) {
|
||||
SHOW_FLOW( 3, "subsys=%x, device=%x, flags=%x, manual_auto_sense=%d",
|
||||
do_autosense = device->manual_autosense
|
||||
&& (request->flags & SCSI_DIS_AUTOSENSE) == 0
|
||||
&& request->subsys_status == SCSI_REQ_CMP_ERR
|
||||
&& request->device_status == SCSI_STATUS_CHECK_CONDITION;
|
||||
|
||||
if (request->subsys_status != SCSI_REQ_CMP) {
|
||||
SHOW_FLOW(3, "subsys=%x, device=%x, flags=%x, manual_auto_sense=%d",
|
||||
request->subsys_status, request->device_status, (int)request->flags,
|
||||
device->manual_autosense );
|
||||
device->manual_autosense);
|
||||
}
|
||||
|
||||
if( do_autosense ) {
|
||||
|
||||
if (do_autosense) {
|
||||
// queue auto-sense request after checking was_servicable but before
|
||||
// releasing locks so no other request overtakes auto-sense
|
||||
submit_autosense( request );
|
||||
submit_autosense(request);
|
||||
}
|
||||
|
||||
if( bus->left_slots++ == 0 )
|
||||
scsi_unblock_bus_noresume( bus, false );
|
||||
|
||||
if( device->left_slots++ == 0 || request->ordered )
|
||||
scsi_unblock_device_noresume( device, false );
|
||||
|
||||
if (bus->left_slots++ == 0)
|
||||
scsi_unblock_bus_noresume(bus, false);
|
||||
|
||||
if (device->left_slots++ == 0 || request->ordered)
|
||||
scsi_unblock_device_noresume(device, false);
|
||||
|
||||
// if SIM reported overflow of device/bus, this should (hopefully) be over now
|
||||
scsi_clear_device_overflow( device );
|
||||
scsi_clear_bus_overflow( bus );
|
||||
|
||||
scsi_clear_device_overflow(device);
|
||||
scsi_clear_bus_overflow(bus);
|
||||
|
||||
// if device is not blocked (anymore) and has pending requests,
|
||||
// add it to waiting list of bus
|
||||
if( device->lock_count == 0 && device->queued_reqs != NULL )
|
||||
scsi_add_device_queue_last( device );
|
||||
if (device->lock_count == 0 && device->queued_reqs != NULL)
|
||||
scsi_add_device_queue_last(device);
|
||||
|
||||
start_service = !was_servicable && scsi_can_service_bus( bus );
|
||||
|
||||
RELEASE_BEN( &bus->mutex );
|
||||
start_service = !was_servicable && scsi_can_service_bus(bus);
|
||||
|
||||
RELEASE_BEN(&bus->mutex);
|
||||
|
||||
// tell service thread to submit new requests to SIM
|
||||
// (do this ASAP to keep bus/device busy)
|
||||
if( start_service )
|
||||
release_sem_etc( bus->start_service, 1, 0/*B_DO_NOT_RESCHEDULE*/ );
|
||||
|
||||
if( request->emulated )
|
||||
scsi_finish_emulation( request );
|
||||
if (start_service)
|
||||
release_sem_etc(bus->start_service, 1, 0/*B_DO_NOT_RESCHEDULE*/);
|
||||
|
||||
if (request->emulated)
|
||||
scsi_finish_emulation(request);
|
||||
|
||||
// copy data from buffer and release it
|
||||
if( request->buffered ) {
|
||||
scsi_release_dma_buffer( request );
|
||||
}
|
||||
if (request->buffered)
|
||||
scsi_release_dma_buffer(request);
|
||||
|
||||
// special treatment for finished auto-sense
|
||||
if( request == device->auto_sense_request )
|
||||
finish_autosense( device );
|
||||
if (request == device->auto_sense_request)
|
||||
finish_autosense(device);
|
||||
else {
|
||||
// tell peripheral driver about completion
|
||||
if( !do_autosense )
|
||||
release_sem_etc( request->completion_sem, 1, 0/*B_DO_NOT_RESCHEDULE*/ );
|
||||
}
|
||||
}
|
||||
if (!do_autosense)
|
||||
release_sem_etc(request->completion_sem, 1, 0/*B_DO_NOT_RESCHEDULE*/);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
// check whether request can be executed right now, enqueuing it if not,
|
||||
// return: true if request can be executed
|
||||
// side effect: updates device->last_sort
|
||||
static inline bool scsi_check_enqueue_request( scsi_ccb *request )
|
||||
/** check whether request can be executed right now, enqueuing it if not,
|
||||
* return: true if request can be executed
|
||||
* side effect: updates device->last_sort
|
||||
*/
|
||||
|
||||
static inline bool
|
||||
scsi_check_enqueue_request(scsi_ccb *request)
|
||||
{
|
||||
scsi_bus_info *bus = request->bus;
|
||||
scsi_device_info *device = request->device;
|
||||
bool execute;
|
||||
|
||||
ACQUIRE_BEN( &bus->mutex );
|
||||
|
||||
ACQUIRE_BEN(&bus->mutex);
|
||||
|
||||
// if device/bus is locked, or there are waiting requests
|
||||
// or waiting devices (last condition makes sure we don't overtake
|
||||
// requests that got queued because bus was full)
|
||||
if( device->lock_count > 0 || device->queued_reqs != NULL ||
|
||||
bus->lock_count > 0 || bus->waiting_devices != NULL )
|
||||
{
|
||||
SHOW_FLOW0( 3, "bus/device is currently locked" );
|
||||
scsi_add_queued_request( request );
|
||||
if (device->lock_count > 0 || device->queued_reqs != NULL
|
||||
|| bus->lock_count > 0 || bus->waiting_devices != NULL) {
|
||||
SHOW_FLOW0(3, "bus/device is currently locked");
|
||||
scsi_add_queued_request(request);
|
||||
execute = false;
|
||||
} else {
|
||||
// if bus is saturated, block it
|
||||
if( --bus->left_slots == 0 ) {
|
||||
SHOW_FLOW0( 3, "bus is saturated, blocking further requests" );
|
||||
scsi_block_bus_nolock( bus, false );
|
||||
if (--bus->left_slots == 0) {
|
||||
SHOW_FLOW0(3, "bus is saturated, blocking further requests");
|
||||
scsi_block_bus_nolock(bus, false);
|
||||
}
|
||||
|
||||
|
||||
// if device saturated or blocking request, block device
|
||||
if( --device->left_slots == 0 || request->ordered ) {
|
||||
if (--device->left_slots == 0 || request->ordered) {
|
||||
SHOW_FLOW0( 3, "device is saturated/blocked by requests, blocking further requests" );
|
||||
scsi_block_device_nolock( device, false );
|
||||
scsi_block_device_nolock(device, false);
|
||||
}
|
||||
|
||||
if( request->sort >= 0 ) {
|
||||
|
||||
if (request->sort >= 0) {
|
||||
device->last_sort = request->sort;
|
||||
SHOW_FLOW( 1, "%Ld", device->last_sort );
|
||||
SHOW_FLOW(1, "%Ld", device->last_sort);
|
||||
}
|
||||
|
||||
|
||||
execute = true;
|
||||
}
|
||||
|
||||
RELEASE_BEN( &bus->mutex );
|
||||
RELEASE_BEN(&bus->mutex);
|
||||
|
||||
return execute;
|
||||
}
|
||||
@@ -449,7 +457,7 @@ scsi_async_io(scsi_ccb *request)
|
||||
if ((request->device->emulation_map[request->cdb[0] >> 3]
|
||||
& (1 << (request->cdb[0] & 7))) != 0) {
|
||||
request->emulated = true;
|
||||
dprintf("emulation!\n");
|
||||
|
||||
if (!scsi_start_emulation(request)) {
|
||||
SHOW_ERROR( 3, "cannot emulate SCSI command 0x%02x", request->cdb[0] );
|
||||
goto err2;
|
||||
@@ -507,7 +515,6 @@ scsi_sync_io(scsi_ccb *request)
|
||||
if ((request->flags & SCSI_DIR_MASK) != SCSI_DIR_NONE
|
||||
&& request->sg_list == NULL && request->data_len > 0) {
|
||||
tmp_sg = true;
|
||||
dprintf("create temp request\n");
|
||||
if (!create_temp_sg(request)) {
|
||||
SHOW_ERROR0( 3, "data is too much fragmented - you should use s/g list" );
|
||||
|
||||
@@ -534,107 +541,112 @@ scsi_term_io(scsi_ccb *ccb_to_terminate)
|
||||
}
|
||||
|
||||
|
||||
uchar scsi_abort( scsi_ccb *req_to_abort )
|
||||
uchar
|
||||
scsi_abort(scsi_ccb *req_to_abort)
|
||||
{
|
||||
scsi_bus_info *bus = req_to_abort->bus;
|
||||
|
||||
if( bus == NULL ) {
|
||||
|
||||
if (bus == NULL) {
|
||||
// checking the validity of the request to abort is a nightmare
|
||||
// this is just a beginning
|
||||
return SCSI_REQ_INVALID;
|
||||
}
|
||||
|
||||
ACQUIRE_BEN( &bus->mutex );
|
||||
|
||||
switch( req_to_abort->state ) {
|
||||
case SCSI_STATE_FINISHED:
|
||||
case SCSI_STATE_SENT:
|
||||
RELEASE_BEN( &bus->mutex );
|
||||
break;
|
||||
|
||||
case SCSI_STATE_QUEUED: {
|
||||
bool was_servicable, start_retry;
|
||||
|
||||
was_servicable = scsi_can_service_bus( bus );
|
||||
|
||||
// remove request from device queue
|
||||
scsi_remove_queued_request( req_to_abort );
|
||||
|
||||
start_retry = scsi_can_service_bus( bus ) && !was_servicable;
|
||||
|
||||
RELEASE_BEN( &bus->mutex );
|
||||
|
||||
req_to_abort->subsys_status = SCSI_REQ_ABORTED;
|
||||
|
||||
// finish emulation
|
||||
if( req_to_abort->emulated )
|
||||
scsi_finish_emulation( req_to_abort );
|
||||
|
||||
// release DMA buffer
|
||||
if( req_to_abort->buffered )
|
||||
scsi_release_dma_buffer( req_to_abort );
|
||||
|
||||
// tell peripheral driver about
|
||||
release_sem_etc( req_to_abort->completion_sem, 1, 0/*B_DO_NOT_RESCHEDULE*/ );
|
||||
|
||||
if( start_retry )
|
||||
release_sem( bus->start_service );
|
||||
|
||||
break; }
|
||||
return SCSI_REQ_INVALID;
|
||||
}
|
||||
|
||||
|
||||
ACQUIRE_BEN(&bus->mutex);
|
||||
|
||||
switch (req_to_abort->state) {
|
||||
case SCSI_STATE_FINISHED:
|
||||
case SCSI_STATE_SENT:
|
||||
RELEASE_BEN(&bus->mutex);
|
||||
break;
|
||||
|
||||
case SCSI_STATE_QUEUED: {
|
||||
bool was_servicable, start_retry;
|
||||
|
||||
was_servicable = scsi_can_service_bus(bus);
|
||||
|
||||
// remove request from device queue
|
||||
scsi_remove_queued_request(req_to_abort);
|
||||
|
||||
start_retry = scsi_can_service_bus(bus) && !was_servicable;
|
||||
|
||||
RELEASE_BEN(&bus->mutex);
|
||||
|
||||
req_to_abort->subsys_status = SCSI_REQ_ABORTED;
|
||||
|
||||
// finish emulation
|
||||
if (req_to_abort->emulated)
|
||||
scsi_finish_emulation(req_to_abort);
|
||||
|
||||
// release DMA buffer
|
||||
if (req_to_abort->buffered)
|
||||
scsi_release_dma_buffer(req_to_abort);
|
||||
|
||||
// tell peripheral driver about
|
||||
release_sem_etc(req_to_abort->completion_sem, 1, 0/*B_DO_NOT_RESCHEDULE*/);
|
||||
|
||||
if (start_retry)
|
||||
release_sem(bus->start_service);
|
||||
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
return SCSI_REQ_CMP;
|
||||
}
|
||||
|
||||
// submit pending request (at most one!)
|
||||
bool scsi_check_exec_service( scsi_bus_info *bus )
|
||||
{
|
||||
SHOW_FLOW0( 3, "" );
|
||||
ACQUIRE_BEN( &bus->mutex );
|
||||
|
||||
if( scsi_can_service_bus( bus )) {
|
||||
/** submit pending request (at most one!) */
|
||||
|
||||
bool
|
||||
scsi_check_exec_service(scsi_bus_info *bus)
|
||||
{
|
||||
SHOW_FLOW0(3, "");
|
||||
ACQUIRE_BEN(&bus->mutex);
|
||||
|
||||
if (scsi_can_service_bus(bus)) {
|
||||
scsi_ccb *request;
|
||||
scsi_device_info *device;
|
||||
|
||||
SHOW_FLOW0( 3, "servicing bus" );
|
||||
|
||||
|
||||
SHOW_FLOW0(3, "servicing bus");
|
||||
|
||||
//snooze( 1000000 );
|
||||
|
||||
|
||||
// handle devices in round-robin-style
|
||||
device = bus->waiting_devices;
|
||||
bus->waiting_devices = bus->waiting_devices->waiting_next;
|
||||
|
||||
|
||||
request = device->queued_reqs;
|
||||
scsi_remove_queued_request( request );
|
||||
|
||||
scsi_remove_queued_request(request);
|
||||
|
||||
// if bus is saturated, block it
|
||||
if( --bus->left_slots == 0 ) {
|
||||
SHOW_FLOW0( 3, "bus is saturated, blocking further requests" );
|
||||
scsi_block_bus_nolock( bus, false );
|
||||
if (--bus->left_slots == 0) {
|
||||
SHOW_FLOW0(3, "bus is saturated, blocking further requests");
|
||||
scsi_block_bus_nolock(bus, false);
|
||||
}
|
||||
|
||||
|
||||
// if device saturated or blocking request, block device
|
||||
if( --device->left_slots == 0 || request->ordered ) {
|
||||
SHOW_FLOW0( 3, "device is saturated/blocked by requests, blocking further requests" );
|
||||
scsi_block_device_nolock( device, false );
|
||||
if (--device->left_slots == 0 || request->ordered) {
|
||||
SHOW_FLOW0(3, "device is saturated/blocked by requests, blocking further requests");
|
||||
scsi_block_device_nolock(device, false);
|
||||
}
|
||||
|
||||
if( request->sort >= 0 ) {
|
||||
|
||||
if (request->sort >= 0) {
|
||||
device->last_sort = request->sort;
|
||||
SHOW_FLOW( 1, "%Ld", device->last_sort );
|
||||
SHOW_FLOW(1, "%Ld", device->last_sort);
|
||||
}
|
||||
|
||||
RELEASE_BEN( &bus->mutex );
|
||||
RELEASE_BEN(&bus->mutex);
|
||||
|
||||
FAST_LOG1(request->device->log, ev_scsi_do_resend_request, (uint32)request);
|
||||
|
||||
FAST_LOG1( request->device->log, ev_scsi_do_resend_request, (uint32)request );
|
||||
|
||||
request->state = SCSI_STATE_SENT;
|
||||
bus->interface->scsi_io( bus->sim_cookie, request );
|
||||
|
||||
bus->interface->scsi_io(bus->sim_cookie, request);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
RELEASE_BEN( &bus->mutex );
|
||||
|
||||
|
||||
RELEASE_BEN(&bus->mutex);
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user