FreeBSD/sys/dev/firewire/sbp_targ.c
/*
 * Generate the appropriate CAM status for the
 * target.
 */
Generate the appropriate CAM status for the
target.
Generate the appropriate CAM status for the target .
static void
sbp_targ_send_status(struct orb_info *orbi, union ccb *ccb)
{
	struct sbp_status *sbp_status;
#if	0
	struct orb_info *norbi;
#endif
	sbp_status = &orbi->status;
	orbi->state = ORBI_STATUS_STATUS;
	sbp_status->resp = 0; 
	sbp_status->status = 0; 
	sbp_status->dead = 0; 
	ccb->ccb_h.status= CAM_REQ_CMP;
	switch (ccb->csio.scsi_status) {
	case SCSI_STATUS_OK:
		if (debug)
			printf("%s: STATUS_OK\n", __func__);
		sbp_status->len = 1;
		break;
	case SCSI_STATUS_CHECK_COND:
		if (debug)
			printf("%s: STATUS SCSI_STATUS_CHECK_COND\n", __func__);
		goto process_scsi_status;
	case SCSI_STATUS_BUSY:
		if (debug)
			printf("%s: STATUS SCSI_STATUS_BUSY\n", __func__);
		goto process_scsi_status;
	case SCSI_STATUS_CMD_TERMINATED:
process_scsi_status:
	{
		struct sbp_cmd_status *sbp_cmd_status;
		struct scsi_sense_data *sense;
		int error_code, sense_key, asc, ascq;
		uint8_t stream_bits;
		uint8_t sks[3];
		uint64_t info;
		int64_t sinfo;
		int sense_len;
		sbp_cmd_status = (struct sbp_cmd_status *)&sbp_status->data[0];
		sbp_cmd_status->status = ccb->csio.scsi_status;
		sense = &ccb->csio.sense_data;
#if 0		
#if 0
		sbp_targ_abort(orbi->sc, STAILQ_NEXT(orbi, link));
#else
		norbi = STAILQ_NEXT(orbi, link);
		while (norbi) {
			printf("%s: status=%d\n", __func__, norbi->state);
			if (norbi->ccb != NULL) {
				norbi->ccb->ccb_h.status = CAM_REQ_ABORTED;
				xpt_done(norbi->ccb);
				norbi->ccb = NULL;
			}
			sbp_targ_remove_orb_info_locked(orbi->login, norbi);
			norbi = STAILQ_NEXT(norbi, link);
			free(norbi, M_SBP_TARG);
		}
#endif
#endif
		sense_len = ccb->csio.sense_len - ccb->csio.sense_resid;
		scsi_extract_sense_len(sense, sense_len, &error_code,
		    &sense_key, &asc, &ascq,  0);
		switch (error_code) {
		case SSD_CURRENT_ERROR:
		case SSD_DESC_CURRENT_ERROR:
			sbp_cmd_status->sfmt = SBP_SFMT_CURR;
			break;
		default:
			sbp_cmd_status->sfmt = SBP_SFMT_DEFER;
			break;
		}
		if (scsi_get_sense_info(sense, sense_len, SSD_DESC_INFO, &info,
					&sinfo) == 0) {
			uint32_t info_trunc;
			sbp_cmd_status->valid = 1;
			info_trunc = info;
			sbp_cmd_status->info = htobe32(info_trunc);
		} else {
			sbp_cmd_status->valid = 0;
		}
		sbp_cmd_status->s_key = sense_key;
		if (scsi_get_stream_info(sense, sense_len, NULL,
					 &stream_bits) == 0) {
			sbp_cmd_status->mark =
			    (stream_bits & SSD_FILEMARK) ? 1 : 0;
			sbp_cmd_status->eom =
			    (stream_bits & SSD_EOM) ? 1 : 0;
			sbp_cmd_status->ill_len =
			    (stream_bits & SSD_ILI) ? 1 : 0;
		} else {
			sbp_cmd_status->mark = 0;
			sbp_cmd_status->eom = 0;
			sbp_cmd_status->ill_len = 0;
		}
		sbp_status->len = 4;
		if (scsi_get_sense_info(sense, sense_len, SSD_DESC_COMMAND,
					&info, &sinfo) == 0) {
			uint32_t cmdspec_trunc;
			cmdspec_trunc = info;
			sbp_cmd_status->cdb = htobe32(cmdspec_trunc);
		}
		sbp_cmd_status->s_code = asc;
		sbp_cmd_status->s_qlfr = ascq;
		if (scsi_get_sense_info(sense, sense_len, SSD_DESC_FRU, &info,
					&sinfo) == 0) {
			sbp_cmd_status->fru = (uint8_t)info;
			sbp_status->len = 5;
		} else {
			sbp_cmd_status->fru = 0;
		}
		if (scsi_get_sks(sense, sense_len, sks) == 0) {
			bcopy(sks, &sbp_cmd_status->s_keydep[0], sizeof(sks));
			sbp_status->len = 5;
			ccb->ccb_h.status |= CAM_SENT_SENSE;
		}
		break;
	}
	default:
		printf("%s: unknown scsi status 0x%x\n", __func__,
		    sbp_status->status);
	}
	sbp_targ_status_FIFO(orbi,
	    orbi->login->fifo_hi, orbi->login->fifo_lo, 1);
}
static void sbp_targ_send_status ( struct orb_info * orbi , union ccb * ccb ) { struct sbp_status * sbp_status ; #if 0 struct orb_info * norbi ; #endif sbp_status = & orbi -> status ; orbi -> state = ORBI_STATUS_STATUS ; sbp_status -> resp = 0 ; sbp_status -> status = 0 ; sbp_status -> dead = 0 ; ccb -> ccb_h . status = CAM_REQ_CMP ; switch ( ccb -> csio . scsi_status ) { case SCSI_STATUS_OK : if ( debug ) printf ( " \n " , __func__ ) ; sbp_status -> len = 1 ; break ; case SCSI_STATUS_CHECK_COND : if ( debug ) printf ( " \n " , __func__ ) ; goto process_scsi_status ; case SCSI_STATUS_BUSY : if ( debug ) printf ( " \n " , __func__ ) ; goto process_scsi_status ; case SCSI_STATUS_CMD_TERMINATED : process_scsi_status : { struct sbp_cmd_status * sbp_cmd_status ; struct scsi_sense_data * sense ; int error_code , sense_key , asc , ascq ; uint8_t stream_bits ; uint8_t sks [ 3 ] ; uint64_t info ; int64_t sinfo ; int sense_len ; sbp_cmd_status = ( struct sbp_cmd_status * ) & sbp_status -> data [ 0 ] ; sbp_cmd_status -> status = ccb -> csio . scsi_status ; sense = & ccb -> csio . sense_data ; #if 0 #if 0 sbp_targ_abort ( orbi -> sc , STAILQ_NEXT ( orbi , link ) ) ; #else norbi = STAILQ_NEXT ( orbi , link ) ; while ( norbi ) { printf ( " \n " , __func__ , norbi -> state ) ; if ( norbi -> ccb != NULL ) { norbi -> ccb -> ccb_h . status = CAM_REQ_ABORTED ; xpt_done ( norbi -> ccb ) ; norbi -> ccb = NULL ; } sbp_targ_remove_orb_info_locked ( orbi -> login , norbi ) ; norbi = STAILQ_NEXT ( norbi , link ) ; free ( norbi , M_SBP_TARG ) ; } #endif #endif sense_len = ccb -> csio . sense_len - ccb -> csio . sense_resid ; scsi_extract_sense_len ( sense , sense_len , & error_code , & sense_key , & asc , & ascq , 0 ) ; switch ( error_code ) { case SSD_CURRENT_ERROR : case SSD_DESC_CURRENT_ERROR : sbp_cmd_status -> sfmt = SBP_SFMT_CURR ; break ; default : sbp_cmd_status -> sfmt = SBP_SFMT_DEFER ; break ; } if ( scsi_get_sense_info ( sense , sense_len , SSD_DESC_INFO , & info , & sinfo ) == 0 ) { uint32_t info_trunc ; sbp_cmd_status -> valid = 1 ; info_trunc = info ; sbp_cmd_status -> info = htobe32 ( info_trunc ) ; } else { sbp_cmd_status -> valid = 0 ; } sbp_cmd_status -> s_key = sense_key ; if ( scsi_get_stream_info ( sense , sense_len , NULL , & stream_bits ) == 0 ) { sbp_cmd_status -> mark = ( stream_bits & SSD_FILEMARK ) ? 1 : 0 ; sbp_cmd_status -> eom = ( stream_bits & SSD_EOM ) ? 1 : 0 ; sbp_cmd_status -> ill_len = ( stream_bits & SSD_ILI ) ? 1 : 0 ; } else { sbp_cmd_status -> mark = 0 ; sbp_cmd_status -> eom = 0 ; sbp_cmd_status -> ill_len = 0 ; } sbp_status -> len = 4 ; if ( scsi_get_sense_info ( sense , sense_len , SSD_DESC_COMMAND , & info , & sinfo ) == 0 ) { uint32_t cmdspec_trunc ; cmdspec_trunc = info ; sbp_cmd_status -> cdb = htobe32 ( cmdspec_trunc ) ; } sbp_cmd_status -> s_code = asc ; sbp_cmd_status -> s_qlfr = ascq ; if ( scsi_get_sense_info ( sense , sense_len , SSD_DESC_FRU , & info , & sinfo ) == 0 ) { sbp_cmd_status -> fru = ( uint8_t ) info ; sbp_status -> len = 5 ; } else { sbp_cmd_status -> fru = 0 ; } if ( scsi_get_sks ( sense , sense_len , sks ) == 0 ) { bcopy ( sks , & sbp_cmd_status -> s_keydep [ 0 ] , sizeof ( sks ) ) ; sbp_status -> len = 5 ; ccb -> ccb_h . status |= CAM_SENT_SENSE ; } break ; } default : printf ( " \n " , __func__ , sbp_status -> status ) ; } sbp_targ_status_FIFO ( orbi , orbi -> login -> fifo_hi , orbi -> login -> fifo_lo , 1 ) ; }
Generate the appropriate CAM status for the
 target.
Generate the appropriate CAM status for the target .
/* XXX */ /* XXX */ /* XXX */ /* XXX What we should do? */ /*show_errors*/ /* add_sense_code(_qual), info, cmd_spec_info */ /*dequeue*/