FreeBSD/sys/cam/cam_xpt.c
/* Functions accessed by the peripheral drivers */
Functions accessed by the peripheral drivers
Functions accessed by the peripheral drivers
static int
xpt_init(void *dummy)
{
	struct cam_sim *xpt_sim;
	struct cam_path *path;
	struct cam_devq *devq;
	cam_status status;
	int error, i;
	TAILQ_INIT(&xsoftc.xpt_busses);
	TAILQ_INIT(&xsoftc.ccb_scanq);
	STAILQ_INIT(&xsoftc.highpowerq);
	xsoftc.num_highpower = CAM_MAX_HIGHPOWER;
	mtx_init(&xsoftc.xpt_lock, "XPT lock", NULL, MTX_DEF);
	mtx_init(&xsoftc.xpt_highpower_lock, "XPT highpower lock", NULL, MTX_DEF);
	xsoftc.xpt_taskq = taskqueue_create("CAM XPT task", M_WAITOK,
	    taskqueue_thread_enqueue, &xsoftc.xpt_taskq);
#ifdef CAM_BOOT_DELAY
	xsoftc.boot_delay = CAM_BOOT_DELAY;
#endif
	devq = cam_simq_alloc(16);
	xpt_sim = cam_sim_alloc(xptaction,
				xptpoll,
				"xpt",
				NULL,
				0,
				&xsoftc.xpt_lock,
				0,
				0,
				devq);
	if (xpt_sim == NULL)
		return (ENOMEM);
	mtx_lock(&xsoftc.xpt_lock);
	if ((status = xpt_bus_register(xpt_sim, NULL, 0)) != CAM_SUCCESS) {
		mtx_unlock(&xsoftc.xpt_lock);
		printf("xpt_init: xpt_bus_register failed with status %#x,"
		       " failing attach\n", status);
		return (EINVAL);
	}
	mtx_unlock(&xsoftc.xpt_lock);
	if ((status = xpt_create_path(&path, NULL, CAM_XPT_PATH_ID,
				      CAM_TARGET_WILDCARD,
				      CAM_LUN_WILDCARD)) != CAM_REQ_CMP) {
		printf("xpt_init: xpt_create_path failed with status %#x,"
		       " failing attach\n", status);
		return (EINVAL);
	}
	xpt_path_lock(path);
	cam_periph_alloc(xptregister, NULL, NULL, NULL, "xpt", CAM_PERIPH_BIO,
			 path, NULL, 0, xpt_sim);
	xpt_path_unlock(path);
	xpt_free_path(path);
	if (cam_num_doneqs < 1)
		cam_num_doneqs = 1 + mp_ncpus / 6;
	else if (cam_num_doneqs > MAXCPU)
		cam_num_doneqs = MAXCPU;
	for (i = 0; i < cam_num_doneqs; i++) {
		mtx_init(&cam_doneqs[i].cam_doneq_mtx, "CAM doneq", NULL,
		    MTX_DEF);
		STAILQ_INIT(&cam_doneqs[i].cam_doneq);
		error = kproc_kthread_add(xpt_done_td, &cam_doneqs[i],
		    &cam_proc, NULL, 0, 0, "cam", "doneq%d", i);
		if (error != 0) {
			cam_num_doneqs = i;
			break;
		}
	}
	if (cam_num_doneqs < 1) {
		printf("xpt_init: Cannot init completion queues "
		       "- failing attach\n");
		return (ENOMEM);
	}
	xsoftc.xpt_config_hook =
	    (struct intr_config_hook *)malloc(sizeof(struct intr_config_hook),
					      M_CAMXPT, M_NOWAIT | M_ZERO);
	if (xsoftc.xpt_config_hook == NULL) {
		printf("xpt_init: Cannot malloc config hook "
		       "- failing attach\n");
		return (ENOMEM);
	}
	xsoftc.xpt_config_hook->ich_func = xpt_config;
	if (config_intrhook_establish(xsoftc.xpt_config_hook) != 0) {
		free (xsoftc.xpt_config_hook, M_CAMXPT);
		printf("xpt_init: config_intrhook_establish failed "
		       "- failing attach\n");
	}
	return (0);
}
static int xpt_init ( void * dummy ) { struct cam_sim * xpt_sim ; struct cam_path * path ; struct cam_devq * devq ; cam_status status ; int error , i ; TAILQ_INIT ( & xsoftc . xpt_busses ) ; TAILQ_INIT ( & xsoftc . ccb_scanq ) ; STAILQ_INIT ( & xsoftc . highpowerq ) ; xsoftc . num_highpower = CAM_MAX_HIGHPOWER ; mtx_init ( & xsoftc . xpt_lock , " " , NULL , MTX_DEF ) ; mtx_init ( & xsoftc . xpt_highpower_lock , " " , NULL , MTX_DEF ) ; xsoftc . xpt_taskq = taskqueue_create ( " " , M_WAITOK , taskqueue_thread_enqueue , & xsoftc . xpt_taskq ) ; #ifdef CAM_BOOT_DELAY xsoftc . boot_delay = CAM_BOOT_DELAY ; #endif devq = cam_simq_alloc ( 16 ) ; xpt_sim = cam_sim_alloc ( xptaction , xptpoll , " " , NULL , 0 , & xsoftc . xpt_lock , 0 , 0 , devq ) ; if ( xpt_sim == NULL ) return ( ENOMEM ) ; mtx_lock ( & xsoftc . xpt_lock ) ; if ( ( status = xpt_bus_register ( xpt_sim , NULL , 0 ) ) != CAM_SUCCESS ) { mtx_unlock ( & xsoftc . xpt_lock ) ; printf ( " " " \n " , status ) ; return ( EINVAL ) ; } mtx_unlock ( & xsoftc . xpt_lock ) ; if ( ( status = xpt_create_path ( & path , NULL , CAM_XPT_PATH_ID , CAM_TARGET_WILDCARD , CAM_LUN_WILDCARD ) ) != CAM_REQ_CMP ) { printf ( " " " \n " , status ) ; return ( EINVAL ) ; } xpt_path_lock ( path ) ; cam_periph_alloc ( xptregister , NULL , NULL , NULL , " " , CAM_PERIPH_BIO , path , NULL , 0 , xpt_sim ) ; xpt_path_unlock ( path ) ; xpt_free_path ( path ) ; if ( cam_num_doneqs < 1 ) cam_num_doneqs = 1 + mp_ncpus / 6 ; else if ( cam_num_doneqs > MAXCPU ) cam_num_doneqs = MAXCPU ; for ( i = 0 ; i < cam_num_doneqs ; i ++ ) { mtx_init ( & cam_doneqs [ i ] . cam_doneq_mtx , " " , NULL , MTX_DEF ) ; STAILQ_INIT ( & cam_doneqs [ i ] . cam_doneq ) ; error = kproc_kthread_add ( xpt_done_td , & cam_doneqs [ i ] , & cam_proc , NULL , 0 , 0 , " " , " " , i ) ; if ( error != 0 ) { cam_num_doneqs = i ; break ; } } if ( cam_num_doneqs < 1 ) { printf ( " " " \n " ) ; return ( ENOMEM ) ; } xsoftc . xpt_config_hook = ( struct intr_config_hook * ) malloc ( sizeof ( struct intr_config_hook ) , M_CAMXPT , M_NOWAIT | M_ZERO ) ; if ( xsoftc . xpt_config_hook == NULL ) { printf ( " " " \n " ) ; return ( ENOMEM ) ; } xsoftc . xpt_config_hook -> ich_func = xpt_config ; if ( config_intrhook_establish ( xsoftc . xpt_config_hook ) != 0 ) { free ( xsoftc . xpt_config_hook , M_CAMXPT ) ; printf ( " " " \n " ) ; } return ( 0 ) ; }
Functions accessed by the peripheral drivers
Functions accessed by the peripheral drivers
/*context*/ /*
	 * Override this value at compile time to assist our users
	 * who don't use loader to boot a kernel.
	 */ /*
	 * The xpt layer is, itself, the equivalent of a SIM.
	 * Allow 16 ccbs in the ccb pool for it.  This should
	 * give decent parallelism when we probe busses and
	 * perform other XPT functions.
	 */ /*softc*/ /*unit*/ /*mtx*/ /*max_dev_transactions*/ /*max_tagged_dev_transactions*/ /*
	 * Looking at the XPT from the SIM layer, the XPT is
	 * the equivalent of a peripheral driver.  Allocate
	 * a peripheral driver entry for us.
	 */ /*
	 * Register a callback for when interrupts are enabled.
	 */