FreeBSD/sys/dev/aic7xxx/aic79xx_osm.c
/*
 * We have an scb which has been processed by the
 * adaptor, now we look to see how the operation
 * went.
 */
We have an scb which has been processed by the
adaptor, now we look to see how the operation
went.
We have an scb which has been processed by the adaptor now we look to see how the operation went .
void
ahd_done(struct ahd_softc *ahd, struct scb *scb)
{
	union ccb *ccb;
	CAM_DEBUG(scb->io_ctx->ccb_h.path, CAM_DEBUG_TRACE,
		  ("ahd_done - scb %d\n", SCB_GET_TAG(scb)));
	ccb = scb->io_ctx;
	LIST_REMOVE(scb, pending_links);
	if ((scb->flags & SCB_TIMEDOUT) != 0)
		LIST_REMOVE(scb, timedout_links);
	callout_stop(&scb->io_timer);
	if ((ccb->ccb_h.flags & CAM_DIR_MASK) != CAM_DIR_NONE) {
		bus_dmasync_op_t op;
		if ((ccb->ccb_h.flags & CAM_DIR_MASK) == CAM_DIR_IN)
			op = BUS_DMASYNC_POSTREAD;
		else
			op = BUS_DMASYNC_POSTWRITE;
		bus_dmamap_sync(ahd->buffer_dmat, scb->dmamap, op);
		bus_dmamap_unload(ahd->buffer_dmat, scb->dmamap);
	}
#ifdef AHD_TARGET_MODE
	if (ccb->ccb_h.func_code == XPT_CONT_TARGET_IO) {
		struct cam_path *ccb_path;
		ccb_path = ccb->ccb_h.path;
		if (ahd->pending_device != NULL
		 && xpt_path_comp(ahd->pending_device->path, ccb_path) == 0) {
			if ((ccb->ccb_h.flags & CAM_SEND_STATUS) != 0) {
				ahd->pending_device = NULL;
			} else {
				xpt_print_path(ccb->ccb_h.path);
				printf("Still disconnected\n");
				ahd_freeze_ccb(ccb);
			}
		}
		if (aic_get_transaction_status(scb) == CAM_REQ_INPROG)
			ccb->ccb_h.status |= CAM_REQ_CMP;
		ccb->ccb_h.status &= ~CAM_SIM_QUEUED;
		ahd_free_scb(ahd, scb);
		xpt_done(ccb);
		return;
	}
#endif
	if ((scb->flags & SCB_RECOVERY_SCB) != 0) {
		struct	scb *list_scb;
		ahd->scb_data.recovery_scbs--;
		if (aic_get_transaction_status(scb) == CAM_BDR_SENT
		 || aic_get_transaction_status(scb) == CAM_REQ_ABORTED)
			aic_set_transaction_status(scb, CAM_CMD_TIMEOUT);
		if (ahd->scb_data.recovery_scbs == 0) {
			LIST_FOREACH(list_scb,
				     &ahd->pending_scbs, pending_links) {
				aic_scb_timer_reset(list_scb,
						    aic_get_timeout(scb));
			}
			ahd_print_path(ahd, scb);
			printf("no longer in timeout, status = %x\n",
			       ccb->ccb_h.status);
		}
	}
	if (aic_get_transaction_status(scb) == CAM_REQ_INPROG) {
		ccb->ccb_h.status |= CAM_REQ_CMP;
	} else if ((scb->flags & SCB_SENSE) != 0) {
		memset(&ccb->csio.sense_data, 0, sizeof(ccb->csio.sense_data));
		memcpy(&ccb->csio.sense_data,
		       ahd_get_sense_buf(ahd, scb),
			sizeof(ccb->csio.sense_data)
		       - ccb->csio.sense_resid);
		scb->io_ctx->ccb_h.status |= CAM_AUTOSNS_VALID;
	} else if ((scb->flags & SCB_PKT_SENSE) != 0) {
		struct scsi_status_iu_header *siu;
		u_int sense_len;
		siu = (struct scsi_status_iu_header *)scb->sense_data;
		sense_len = MIN(scsi_4btoul(siu->sense_length),
				sizeof(ccb->csio.sense_data));
		memset(&ccb->csio.sense_data, 0, sizeof(ccb->csio.sense_data));
		memcpy(&ccb->csio.sense_data,
		       ahd_get_sense_buf(ahd, scb) + SIU_SENSE_OFFSET(siu),
		       sense_len);
#ifdef AHD_DEBUG
		if ((ahd_debug & AHD_SHOW_SENSE) != 0) {
			uint8_t *sense_data = (uint8_t *)&ccb->csio.sense_data;
			u_int i;
			printf("Copied %d bytes of sense data offset %d:",
			       sense_len, SIU_SENSE_OFFSET(siu));
			for (i = 0; i < sense_len; i++)
				printf(" 0x%x", *sense_data++);
			printf("\n");
		}
#endif
		scb->io_ctx->ccb_h.status |= CAM_AUTOSNS_VALID;
	}
	ccb->ccb_h.status &= ~CAM_SIM_QUEUED;
	ahd_free_scb(ahd, scb);
	xpt_done(ccb);
}
void ahd_done ( struct ahd_softc * ahd , struct scb * scb ) { union ccb * ccb ; CAM_DEBUG ( scb -> io_ctx -> ccb_h . path , CAM_DEBUG_TRACE , ( " \n " , SCB_GET_TAG ( scb ) ) ) ; ccb = scb -> io_ctx ; LIST_REMOVE ( scb , pending_links ) ; if ( ( scb -> flags & SCB_TIMEDOUT ) != 0 ) LIST_REMOVE ( scb , timedout_links ) ; callout_stop ( & scb -> io_timer ) ; if ( ( ccb -> ccb_h . flags & CAM_DIR_MASK ) != CAM_DIR_NONE ) { bus_dmasync_op_t op ; if ( ( ccb -> ccb_h . flags & CAM_DIR_MASK ) == CAM_DIR_IN ) op = BUS_DMASYNC_POSTREAD ; else op = BUS_DMASYNC_POSTWRITE ; bus_dmamap_sync ( ahd -> buffer_dmat , scb -> dmamap , op ) ; bus_dmamap_unload ( ahd -> buffer_dmat , scb -> dmamap ) ; } #ifdef AHD_TARGET_MODE if ( ccb -> ccb_h . func_code == XPT_CONT_TARGET_IO ) { struct cam_path * ccb_path ; ccb_path = ccb -> ccb_h . path ; if ( ahd -> pending_device != NULL && xpt_path_comp ( ahd -> pending_device -> path , ccb_path ) == 0 ) { if ( ( ccb -> ccb_h . flags & CAM_SEND_STATUS ) != 0 ) { ahd -> pending_device = NULL ; } else { xpt_print_path ( ccb -> ccb_h . path ) ; printf ( " \n " ) ; ahd_freeze_ccb ( ccb ) ; } } if ( aic_get_transaction_status ( scb ) == CAM_REQ_INPROG ) ccb -> ccb_h . status |= CAM_REQ_CMP ; ccb -> ccb_h . status &= ~ CAM_SIM_QUEUED ; ahd_free_scb ( ahd , scb ) ; xpt_done ( ccb ) ; return ; } #endif if ( ( scb -> flags & SCB_RECOVERY_SCB ) != 0 ) { struct scb * list_scb ; ahd -> scb_data . recovery_scbs -- ; if ( aic_get_transaction_status ( scb ) == CAM_BDR_SENT || aic_get_transaction_status ( scb ) == CAM_REQ_ABORTED ) aic_set_transaction_status ( scb , CAM_CMD_TIMEOUT ) ; if ( ahd -> scb_data . recovery_scbs == 0 ) { LIST_FOREACH ( list_scb , & ahd -> pending_scbs , pending_links ) { aic_scb_timer_reset ( list_scb , aic_get_timeout ( scb ) ) ; } ahd_print_path ( ahd , scb ) ; printf ( " \n " , ccb -> ccb_h . status ) ; } } if ( aic_get_transaction_status ( scb ) == CAM_REQ_INPROG ) { ccb -> ccb_h . status |= CAM_REQ_CMP ; } else if ( ( scb -> flags & SCB_SENSE ) != 0 ) { memset ( & ccb -> csio . sense_data , 0 , sizeof ( ccb -> csio . sense_data ) ) ; memcpy ( & ccb -> csio . sense_data , ahd_get_sense_buf ( ahd , scb ) , sizeof ( ccb -> csio . sense_data ) - ccb -> csio . sense_resid ) ; scb -> io_ctx -> ccb_h . status |= CAM_AUTOSNS_VALID ; } else if ( ( scb -> flags & SCB_PKT_SENSE ) != 0 ) { struct scsi_status_iu_header * siu ; u_int sense_len ; siu = ( struct scsi_status_iu_header * ) scb -> sense_data ; sense_len = MIN ( scsi_4btoul ( siu -> sense_length ) , sizeof ( ccb -> csio . sense_data ) ) ; memset ( & ccb -> csio . sense_data , 0 , sizeof ( ccb -> csio . sense_data ) ) ; memcpy ( & ccb -> csio . sense_data , ahd_get_sense_buf ( ahd , scb ) + SIU_SENSE_OFFSET ( siu ) , sense_len ) ; #ifdef AHD_DEBUG if ( ( ahd_debug & AHD_SHOW_SENSE ) != 0 ) { uint8_t * sense_data = ( uint8_t * ) & ccb -> csio . sense_data ; u_int i ; printf ( " " , sense_len , SIU_SENSE_OFFSET ( siu ) ) ; for ( i = 0 ; i < sense_len ; i ++ ) printf ( " " , * sense_data ++ ) ; printf ( " \n " ) ; } #endif scb -> io_ctx -> ccb_h . status |= CAM_AUTOSNS_VALID ; } ccb -> ccb_h . status &= ~ CAM_SIM_QUEUED ; ahd_free_scb ( ahd , scb ) ; xpt_done ( ccb ) ; }
We have an scb which has been processed by the
 adaptor, now we look to see how the operation
 went.
We have an scb which has been processed by the adaptor now we look to see how the operation went .
/*
		 * If we have finally disconnected, clean up our
		 * pending device state.
		 * XXX - There may be error states that cause where
		 *       we will remain connected.
		 */ /*
			 * All recovery actions have completed successfully,
			 * so reinstate the timeouts for all other pending
			 * commands.
			 */ /* Don't clobber any existing error state */ /*
		 * We performed autosense retrieval.
		 *
		 * Zero any sense not transferred by the
		 * device.  The SCSI spec mandates that any
		 * untransfered data should be assumed to be
		 * zero.  Complete the 'bounce' of sense information
		 * through buffers accessible via bus-space by
		 * copying it into the clients csio.
		 */ /* XXX What size do we want to use??? */ /*
		 * Copy only the sense data into the provided buffer.
		 */