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