FreeBSD/sys/dev/esp/ncr53c9x.c
/*
 * POST PROCESSING OF SCSI_CMD (usually current)
 */
POST PROCESSING OF SCSI_CMD (usually current)
POST PROCESSING OF SCSI_CMD ( usually current )
static void
ncr53c9x_done(struct ncr53c9x_softc *sc, struct ncr53c9x_ecb *ecb)
{
	union ccb *ccb = ecb->ccb;
	struct ncr53c9x_linfo *li;
	struct ncr53c9x_tinfo *ti;
	int lun, sense_returned;
	NCR_LOCK_ASSERT(sc, MA_OWNED);
	NCR_TRACE(("[%s(status:%x)] ", __func__, ccb->ccb_h.status));
	ti = &sc->sc_tinfo[ccb->ccb_h.target_id];
	lun = ccb->ccb_h.target_lun;
	li = TINFO_LUN(ti, lun);
	callout_stop(&ecb->ch);
	if (ccb->ccb_h.status == CAM_REQ_CMP) {
		ccb->csio.scsi_status = ecb->stat;
		if ((ecb->flags & ECB_ABORT) != 0)
			ccb->ccb_h.status = CAM_CMD_TIMEOUT;
		else if ((ecb->flags & ECB_SENSE) != 0 &&
		   (ecb->stat != SCSI_STATUS_CHECK_COND)) {
			ccb->csio.scsi_status = SCSI_STATUS_CHECK_COND;
			ccb->ccb_h.status = CAM_SCSI_STATUS_ERROR |
			    CAM_AUTOSNS_VALID;
			sense_returned = sizeof(ccb->csio.sense_data) -
			    ecb->dleft;
			if (sense_returned < ccb->csio.sense_len)
				ccb->csio.sense_resid = ccb->csio.sense_len -
				    sense_returned;
			else
				ccb->csio.sense_resid = 0;
		} else if (ecb->stat == SCSI_STATUS_CHECK_COND) {
			if ((ecb->flags & ECB_SENSE) != 0)
				ccb->ccb_h.status = CAM_AUTOSENSE_FAIL;
			else {
				ccb->csio.resid = ecb->dleft;
				if ((ccb->ccb_h.flags & CAM_DIS_AUTOSENSE) ==
				    0) {
					ncr53c9x_sense(sc, ecb);
					return;
				}
				ccb->ccb_h.status = CAM_SCSI_STATUS_ERROR;
			}
		} else
			ccb->csio.resid = ecb->dleft;
		if (ecb->stat == SCSI_STATUS_QUEUE_FULL)
			ccb->ccb_h.status = CAM_SCSI_STATUS_ERROR;
		else if (ecb->stat == SCSI_STATUS_BUSY)
			ccb->ccb_h.status = CAM_SCSI_BUSY;
	} else if ((ccb->ccb_h.status & CAM_DEV_QFRZN) == 0) {
		ccb->ccb_h.status |= CAM_DEV_QFRZN;
		xpt_freeze_devq(ccb->ccb_h.path, 1);
	}
#ifdef NCR53C9X_DEBUG
	if ((ncr53c9x_debug & NCR_SHOWTRAC) != 0) {
		if (ccb->csio.resid != 0)
			printf("resid=%d ", ccb->csio.resid);
		if ((ccb->ccb_h.status & CAM_AUTOSNS_VALID) != 0)
			printf("sense=0x%02x\n",
			    ccb->csio.sense_data.error_code);
		else
			printf("status SCSI=0x%x CAM=0x%x\n",
			    ccb->csio.scsi_status, ccb->ccb_h.status);
	}
#endif
	ncr53c9x_dequeue(sc, ecb);
	if (ecb == sc->sc_nexus) {
		sc->sc_nexus = NULL;
		if (sc->sc_state != NCR_CLEANING) {
			sc->sc_state = NCR_IDLE;
			ncr53c9x_sched(sc);
		}
	}
	if ((ccb->ccb_h.status & CAM_SEL_TIMEOUT) != 0) {
		if (li->untagged == NULL && li->used == 0) {
			if (lun < NCR_NLUN)
				ti->lun[lun] = NULL;
			LIST_REMOVE(li, link);
			free(li, M_DEVBUF);
		}
	}
	ncr53c9x_free_ecb(sc, ecb);
	ti->cmds++;
	xpt_done(ccb);
}
static void ncr53c9x_done ( struct ncr53c9x_softc * sc , struct ncr53c9x_ecb * ecb ) { union ccb * ccb = ecb -> ccb ; struct ncr53c9x_linfo * li ; struct ncr53c9x_tinfo * ti ; int lun , sense_returned ; NCR_LOCK_ASSERT ( sc , MA_OWNED ) ; NCR_TRACE ( ( " " , __func__ , ccb -> ccb_h . status ) ) ; ti = & sc -> sc_tinfo [ ccb -> ccb_h . target_id ] ; lun = ccb -> ccb_h . target_lun ; li = TINFO_LUN ( ti , lun ) ; callout_stop ( & ecb -> ch ) ; if ( ccb -> ccb_h . status == CAM_REQ_CMP ) { ccb -> csio . scsi_status = ecb -> stat ; if ( ( ecb -> flags & ECB_ABORT ) != 0 ) ccb -> ccb_h . status = CAM_CMD_TIMEOUT ; else if ( ( ecb -> flags & ECB_SENSE ) != 0 && ( ecb -> stat != SCSI_STATUS_CHECK_COND ) ) { ccb -> csio . scsi_status = SCSI_STATUS_CHECK_COND ; ccb -> ccb_h . status = CAM_SCSI_STATUS_ERROR | CAM_AUTOSNS_VALID ; sense_returned = sizeof ( ccb -> csio . sense_data ) - ecb -> dleft ; if ( sense_returned < ccb -> csio . sense_len ) ccb -> csio . sense_resid = ccb -> csio . sense_len - sense_returned ; else ccb -> csio . sense_resid = 0 ; } else if ( ecb -> stat == SCSI_STATUS_CHECK_COND ) { if ( ( ecb -> flags & ECB_SENSE ) != 0 ) ccb -> ccb_h . status = CAM_AUTOSENSE_FAIL ; else { ccb -> csio . resid = ecb -> dleft ; if ( ( ccb -> ccb_h . flags & CAM_DIS_AUTOSENSE ) == 0 ) { ncr53c9x_sense ( sc , ecb ) ; return ; } ccb -> ccb_h . status = CAM_SCSI_STATUS_ERROR ; } } else ccb -> csio . resid = ecb -> dleft ; if ( ecb -> stat == SCSI_STATUS_QUEUE_FULL ) ccb -> ccb_h . status = CAM_SCSI_STATUS_ERROR ; else if ( ecb -> stat == SCSI_STATUS_BUSY ) ccb -> ccb_h . status = CAM_SCSI_BUSY ; } else if ( ( ccb -> ccb_h . status & CAM_DEV_QFRZN ) == 0 ) { ccb -> ccb_h . status |= CAM_DEV_QFRZN ; xpt_freeze_devq ( ccb -> ccb_h . path , 1 ) ; } #ifdef NCR53C9X_DEBUG if ( ( ncr53c9x_debug & NCR_SHOWTRAC ) != 0 ) { if ( ccb -> csio . resid != 0 ) printf ( " " , ccb -> csio . resid ) ; if ( ( ccb -> ccb_h . status & CAM_AUTOSNS_VALID ) != 0 ) printf ( " \n " , ccb -> csio . sense_data . error_code ) ; else printf ( " \n " , ccb -> csio . scsi_status , ccb -> ccb_h . status ) ; } #endif ncr53c9x_dequeue ( sc , ecb ) ; if ( ecb == sc -> sc_nexus ) { sc -> sc_nexus = NULL ; if ( sc -> sc_state != NCR_CLEANING ) { sc -> sc_state = NCR_IDLE ; ncr53c9x_sched ( sc ) ; } } if ( ( ccb -> ccb_h . status & CAM_SEL_TIMEOUT ) != 0 ) { if ( li -> untagged == NULL && li -> used == 0 ) { if ( lun < NCR_NLUN ) ti -> lun [ lun ] = NULL ; LIST_REMOVE ( li , link ) ; free ( li , M_DEVBUF ) ; } } ncr53c9x_free_ecb ( sc , ecb ) ; ti -> cmds ++ ; xpt_done ( ccb ) ; }
POST PROCESSING OF SCSI_CMD (usually current)
POST PROCESSING OF SCSI_CMD ( usually current )
/*
	 * Now, if we've come here with no error code, i.e. we've kept the
	 * initial CAM_REQ_CMP, and the status code signals that we should
	 * check sense, we'll need to set up a request sense cmd block and
	 * push the command back into the ready queue *before* any other
	 * commands for this target/lunit, else we lose the sense info.
	 * We don't support chk sense conditions for the request sense cmd.
	 */ /* First, save the return values. */ /*
	 * Remove the ECB from whatever queue it's on.
	 */ /* Selection timeout -- discard this LUN if empty. */