rem: void scsi_request_finished( scsi_ccb *request, uint num_requests )
add: scsi_request_finished(scsi_ccb *request, uint num_requests)
context: 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 );		return;	}	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 );		return;	}	request->state = SCSI_STATE_FINISHED;	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",			request->subsys_status, request->device_status, (int)request->flags,			device->manual_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 );	}	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 );		// 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 );	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 );	// copy data from buffer and release it	if( request->buffered ) {		scsi_release_dma_buffer( request );	}	// special treatment for finished auto-sense	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*/ );	}	}		