Ejemplo n.º 1
0
int sys_tunopen(struct lwp *l, const struct sys_tunopen_args *uap, register_t *retval)
{
	int error;
	struct file* fp;
	int indx;

	error = ChkSpaceBstrR(SCARG(uap, path), 0);
	if ( error < E_OK ) {
		return EFAULT;
	}

	if ((error = fd_allocfile(&fp, &indx)) != 0)
		return (error);

	if ((error = tkn_tun_open(SCARG(uap, path), SCARG(uap, oflag), fp)) != 0) {
		fd_abort(l->l_proc, fp, indx);
		if ((error == EDUPFD || error == EMOVEFD) &&
		    l->l_dupfd >= 0 &&			/* XXX from fdopen */
		    (error =
			fd_dupopen(l->l_dupfd, &indx, SCARG(uap, oflag), error)) == 0) {
			*retval = indx;
			return (0);
		}
		if (error == ERESTART)
			error = EINTR;
		return (error);
	}

	return ENOTSUP;
}
Ejemplo n.º 2
0
/*
 * Device registration
 */
RAW_U32 _tk_def_dev( CONST UB *devnm, CONST T_DDEV *ddev, void *caller_gp )
{
	DevCB	*devcb;
	INT	len, evttyp;
	ER	ercd;


	len = ChkSpaceBstrR(devnm, 0);
	
	if ( len <= 0 || len > MaxRegDev ) {
		
		RAW_ASSERT(0);
	}


	/* Search whether 'devnm' device is registered */
	devcb = searchDevCB(devnm);
	if ( devcb == 0 ) {
		if ( ddev == 0 ) {
			ercd = E_NOEXS;
			goto err_ret2;
		}

		/* Get 'devcb' for new registration because it is not
		   registered */
		devcb = newDevCB(devnm);
		if ( devcb == NULL ) {
			ercd = E_LIMIT;
			goto err_ret2;
		}
	}

	if ( ddev != NULL ) {
		/* Set/update device registration information */
		devcb->ddev = *ddev;

		evttyp = TSEVT_DEVICE_REGIST;
	} else {
		if ( !isQueEmpty(&devcb->openq) ) {
			/* In use (open) */
			ercd = E_BUSY;
			goto err_ret2;
		}

		/* Device unregistration */
		delDevCB(devcb);
		evttyp = TSEVT_DEVICE_DELETE;
	}

	return DID(devcb);
}
Ejemplo n.º 3
0
int
sys_ifattach(struct lwp *l, const struct sys_ifattach_args *uap, register_t *retval)
{
	const char* devname = SCARG(uap, devnm);
	int dev_num;
	int error = 0;
	int ret;
	T_RDEV rdev;
	struct tkn_nif_info *nif;

	(void)l;

	ret = ChkSpaceBstrR(devname, 0);
	if ( ret < 0 ) {
		return EFAULT;
	}

	for (nif = tkn_nif_mng.nifm_list; nif; nif = nif->nif_next) {
		if (strncmp((char*)nif->nif_dev, devname, TKN_NIFNAMESIZE) == 0) {
			break;
		}
	}
	if( nif != 0 ) {
		/* Already registered. */
		error = EBUSY;
		goto error;
	}

	ret = tk_ref_dev((UB*)devname, &rdev);
	if (ret < 0) {
		error = EINVAL;
		goto error;
	}

	dev_num  = tkn_nif_mng.nifm_nifmax;
	strncpy((char*)tkn_dev_info[dev_num].nif_dev, devname, TKN_NIFNAMESIZE);

	ret = tkn_nif_attach(&tkn_dev_info[dev_num]);
	if (ret != 0) {
		error = EINVAL;
	}

error:
	*retval = 0;

	return error;
}
Ejemplo n.º 4
0
int
sys_ifdetach(struct lwp *l, const struct sys_ifdetach_args *uap, register_t *retval)
{
	const char* devname = SCARG(uap, devnm);
	int error = 0;
	int ret;
	T_RDEV rdev;
	struct tkn_nif_info *nif;

	(void)l;

	ret = ChkSpaceBstrR(devname, 0);
	if ( ret < 0 ) {
		return EFAULT;
	}

	ret = tk_ref_dev((UB*)devname, &rdev);
	if (ret < 0) {
		error = EINVAL;
		goto error;
	}

	for (nif = tkn_nif_mng.nifm_list; nif != NULL; nif = nif->nif_next) {
		if (strncmp((char*)nif->nif_dev, devname, TKN_NIFNAMESIZE) == 0) {
			break;
		}
	}
	if( nif == 0 ) {
		/* Not registered. */
		error = ENOENT;
		goto error;
	}

	ret = tkn_nif_detach(nif);
	if (ret != 0) {
		error = EINVAL;
	}

error:
	*retval = 0;

	return error;
}
Ejemplo n.º 5
0
int
sys_ifnametoindex(struct lwp *l, const struct sys_ifnametoindex_args *uap, register_t *retval)
{
	int error;
	unsigned int ifindex;

	(void)l;

	error = ChkSpaceBstrR(SCARG(uap, ifname), 0);
	if ( error < 0 ) {
		return EFAULT;
	}

	error = if_nametoindex(SCARG(uap,ifname), &ifindex);
	if (error == 0) {
		*retval = ifindex;
	}

	return error;
}
Ejemplo n.º 6
0
/*
 * Device open
 */
EXPORT ID _tk_opn_dev( CONST UB *devnm, UINT omode )
{
	UB	pdevnm[L_DEVNM + 1];
	INT	unitno;
	ResCB	*rescb;
	DevCB	*devcb;
	OpnCB	*opncb;
	WaitQ	waiq;
	ER	ercd;

	ercd = ChkSpaceBstrR(devnm, 0);
	if ( ercd < E_OK ) {
		goto err_ret1;
	}

	unitno = phydevnm(pdevnm, devnm);

	/* Get resource management information */
	rescb = GetResCB(DEVICE_SVC, TSK_SELF);
	if ( rescb == NULL ) {
		ercd = E_CTX;
		goto err_ret1;
	}

	LockDM();

	/* Search device to open */
	devcb = searchDevCB(pdevnm);
	if ( devcb == NULL || unitno > devcb->ddev.nsub ) {
		ercd = E_NOEXS;
		goto err_ret2;
	}

	/* Check open mode */
	ercd = chkopenmode(devcb, unitno, omode);
	if ( ercd < E_OK ) {
		goto err_ret2;
	}

	/* Get open management block */
	opncb = newOpnCB(devcb, unitno, omode, rescb);
	if ( opncb == NULL ) {
		ercd = E_LIMIT;
		goto err_ret2;
	}

	/* Multiple tasks can initiate open/close processing,
	   so ensure processing only by one task at a time. */
	if ( enterSyncWait(&devcb->syncq, &waiq) ) {
		/* Wait for synchronization for concurrent open/close */
		UnlockDM();
		SyncWaitDM();
		LockDM();
	}

	/* Is device driver call required? */
	if ( ! ( chkopen(devcb, unitno, opncb) &&
				(devcb->ddev.drvatr & TDA_OPENREQ) == 0 ) ) {
		/* Device driver call */
		UnlockDM();
		ercd = call_openfn(devcb, DEVID(devcb, unitno), omode);
		LockDM();
		if ( ercd < E_OK ) {
			goto err_ret3;
		}
	}
	opncb->resid = tk_get_rid(TSK_SELF);
			/* Indicate that open processing is completed */

       /* Wake up task waiting for synchronization for concurrent open/close */
	leaveSyncWait(&devcb->syncq, &waiq);
	UnlockDM();

	return DD(opncb);

err_ret3:
	delOpnCB(opncb);
	leaveSyncWait(&devcb->syncq, &waiq);
err_ret2:
	UnlockDM();
err_ret1:
	DEBUG_PRINT(("_tk_opn_dev ercd = %d\n", ercd));
	return ercd;
}