FreeBSD/sys/cam/scsi/scsi_target.c
/* Build and send a kernel CCB formed from descr->user_ccb */
Build and send a kernel CCB formed from descr->user_ccb
Build and send a kernel CCB formed from descr - > user_ccb
static int
targsendccb(struct targ_softc *softc, union ccb *ccb,
	    struct targ_cmd_descr *descr)
{
	struct cam_periph_map_info *mapinfo;
	struct ccb_hdr *ccb_h;
	int error;
	ccb_h = &ccb->ccb_h;
	mapinfo = &descr->mapinfo;
	mapinfo->num_bufs_used = 0;
	ccb_h->cbfcnp = targdone;
	ccb_h->targ_descr = descr;
	if ((ccb_h->func_code == XPT_CONT_TARGET_IO) ||
	    (ccb_h->func_code == XPT_DEV_MATCH)) {
		error = cam_periph_mapmem(ccb, mapinfo, softc->maxio);
		if (error) {
			ccb_h->status = CAM_REQ_CMP_ERR;
			mapinfo->num_bufs_used = 0;
			return (error);
		}
	}
	CAM_DEBUG(softc->path, CAM_DEBUG_PERIPH, ("sendccb %p\n", ccb));
	if (XPT_FC_IS_QUEUED(ccb)) {
		TAILQ_INSERT_TAIL(&softc->pending_ccb_queue, ccb_h,
				  periph_links.tqe);
	}
	xpt_action(ccb);
	return (0);
}
static int targsendccb ( struct targ_softc * softc , union ccb * ccb , struct targ_cmd_descr * descr ) { struct cam_periph_map_info * mapinfo ; struct ccb_hdr * ccb_h ; int error ; ccb_h = & ccb -> ccb_h ; mapinfo = & descr -> mapinfo ; mapinfo -> num_bufs_used = 0 ; ccb_h -> cbfcnp = targdone ; ccb_h -> targ_descr = descr ; if ( ( ccb_h -> func_code == XPT_CONT_TARGET_IO ) || ( ccb_h -> func_code == XPT_DEV_MATCH ) ) { error = cam_periph_mapmem ( ccb , mapinfo , softc -> maxio ) ; if ( error ) { ccb_h -> status = CAM_REQ_CMP_ERR ; mapinfo -> num_bufs_used = 0 ; return ( error ) ; } } CAM_DEBUG ( softc -> path , CAM_DEBUG_PERIPH , ( " \n " , ccb ) ) ; if ( XPT_FC_IS_QUEUED ( ccb ) ) { TAILQ_INSERT_TAIL ( & softc -> pending_ccb_queue , ccb_h , periph_links . tqe ) ; } xpt_action ( ccb ) ; return ( 0 ) ; }
Build and send a kernel CCB formed from descr->user_ccb
Build and send a kernel CCB formed from descr - > user_ccb
/*
	 * There's no way for the user to have a completion
	 * function, so we put our own completion function in here.
	 * We also stash in a reference to our descriptor so targreturnccb()
	 * can find our mapping info.
	 */ /*
		 * cam_periph_mapmem returned an error, we can't continue.
		 * Return the error to the user.
		 */ /*
	 * Once queued on the pending CCB list, this CCB will be protected
	 * by our error recovery handler.
	 */