⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 loop.c

📁 7号信令功能代码,为开源代码
💻 C
📖 第 1 页 / 共 2 页
字号:
    loop = (struct loop *) q->q_ptr;    switch (mp->b_datap->db_type)    {    case M_IOCTL:	{	    struct iocblk *iocb;	    int error;	    iocb = (struct iocblk *) mp->b_rptr;	    switch (iocb->ioc_cmd)	    {	    case LOOP_SET:		{		    int to;		    if (iocb->ioc_count != sizeof(int))		    {			printk("Expected ioctl len %d, got %d\n", sizeof(int),			       iocb->ioc_count);			error = EINVAL;			goto iocnak;		    }		    to = *(int *) mp->b_cont->b_rptr;		    if (to >= loop_cnt || to < 0 || !loop_loop[to].qptr)		    {			error = ENXIO;			goto iocnak;		    }		    if (loop->oqptr || loop_loop[to].oqptr)		    {			error = EBUSY;			goto iocnak;		    }		    loop->oqptr = RD(loop_loop[to].qptr);		    loop_loop[to].oqptr = RD(q);		    break;		}	    case LOOP_PUTNXT:		loop->use_putnext = 1;	/* instead of service queue */		break;	    case LOOP_MSGLVL:		if (mp->b_cont != NULL)		    loop->msglvl = *(int *) mp->b_cont->b_rptr;		else		{		    printk("loop_wput: no data buffer in ioctl\n");		    error = EINVAL;		    goto iocnak;		}		break;	    case LOOP_CONCAT:		if (mp->b_cont != NULL)		    loop->catlvl = *(int *) mp->b_cont->b_rptr;		else		{		    printk("loop_wput: no data buffer in ioctl\n");		    error = EINVAL;		    goto iocnak;		}		break;	    case LOOP_TIMR:		if (mp->b_cont != NULL)		    loop->timr = *(int *) mp->b_cont->b_rptr;		else		{		    printk("loop_wput: no data buffer in ioctl\n");		    error = EINVAL;		    goto iocnak;		}		break;	    case LOOP_MARK:		loop->mark++;	/* mark next message */		break;	    case LOOP_GET_DEV:	/* get minor number */		{		    int *devp;		    if (iocb->ioc_count != sizeof(int))		    {			printk("Expected ioctl len %d, got %d\n",			       sizeof(int), iocb->ioc_count);			error = EINVAL;			goto iocnak;		    }		    if (mp->b_cont != NULL)			devp = (int *) mp->b_cont->b_rptr;		    else		    {			printk("loop_wput: no data buffer in ioctl\n");			error = EINVAL;			goto iocnak;		    }		    *devp = loop->minor_nr;	/* return minor device nr */		    rtn_count = sizeof(int);		}		break;	    case LOOP_BUFCALL:		loop->use_bufcall++;		break;	    case LOOP_COPY:		loop->copy_bfr = 1;		break;	    case LOOP_BURST:		loop->burst = *(int *) mp->b_cont->b_rptr;		break;		/*		 * Fetch the loop module's xparent structure from user space.		 * When it arrives then copy data into or out of kernel space		 * as requested.		 */	    case LOOP_XPARENT_COPYIN:	    case LOOP_XPARENT_COPYOUT:		{		    void **ptr_ptr;		    void *uptr;		    if (mp->b_cont == NULL)		    {			printk			    ("loop_wput: LOOP_XPARENT_COPYIN/OUT: no M_DATA\n");			error = EINVAL;			goto iocnak;		    }		    ptr_ptr = (void **) mp->b_cont->b_rptr;		    uptr = *ptr_ptr;		    if (loop_request_copyio(q, loop, mp, M_COPYIN,					    uptr, sizeof(loop_xparent_t)) < 0)		    {			error = EINVAL;			goto iocnak;		    }		    return (0);	/* don't respond w/iocack yet */		}	    case LOOP_DENY_OPEN:		loop->deny_2nd_open ^= 1 ;	/* flip flag */		break ;	    case LOOP_FLUSH:		{		    mblk_t	*fmp ;		    if (loop->oqptr == NULL)		    {			error = EINVAL ;			goto iocnak ;		    }		    if ((fmp = allocb(4, BPRI_MED)) == NULL)		    {			error = ENOMEM ;			goto iocnak ;		    }		    fmp->b_datap->db_type = M_FLUSH ;		    *fmp->b_wptr++ = FLUSHR ;		    putnext(loop->oqptr, fmp) ;		    if (mp->b_cont != NULL)		    {				/* follow with data */			fmp = mp->b_cont ;			mp->b_cont = NULL ;			putnext(loop->oqptr, fmp) ;		    }		}		break ;	    default:		printk("Expected ioctl %x, got %x\n", LOOP_SET, iocb->ioc_cmd);		error = EINVAL;	      iocnak:{		    mp->b_datap->db_type = M_IOCNAK;		    iocb->ioc_error = error;		    qreply(q, mp);		}		return (0);	    }			/* end of switch on ioc_cmd */	    mp->b_datap->db_type = M_IOCACK;	    iocb->ioc_count = rtn_count;	    qreply(q, mp);	    break;	}    case M_IOCDATA:	{	    struct iocblk *iocb;	    int err;	    iocb = (struct iocblk *) mp->b_rptr;	    if ((err = loop_iocdata(q, mp)) < 0)	    {		mp->b_datap->db_type = M_IOCNAK;		iocb->ioc_cmd &= 0xff;	/* original cmnd */		iocb->ioc_count = 0;		iocb->ioc_error = -err;		mp->b_wptr = mp->b_rptr + sizeof(*iocb);		qreply(q, mp);		return (0);	    }	    if (err > 0)	/* more message xchg going on */		break;	    mp->b_datap->db_type = M_IOCACK;	    iocb->ioc_cmd &= 0xff;	/* original cmnd */	    iocb->ioc_count = 0;	    iocb->ioc_error = 0;	    mp->b_wptr = mp->b_rptr + sizeof(*iocb);	    qreply(q, mp);	/* finally ack the ioctl */	    break;	}    case M_FLUSH:	{	    if (*mp->b_rptr & FLUSHW)		flushq(q, FLUSHDATA);	    if (*mp->b_rptr & FLUSHR)	    {		flushq(RD(q), FLUSHDATA);		*mp->b_rptr &= ~FLUSHW;		qreply(q, mp);	    }	    else		freemsg(mp);	    break;	}    default:	if (loop->oqptr == NULL)	{	    putctl1(RD(q)->q_next, M_ERROR, ENXIO);	    freemsg(mp);	    break;	}	if (loop->burst)	{	    mblk_t *new_mp;	    for (--loop->burst; loop->burst > 0; loop->burst--)	    {		new_mp = copymsg(mp);		if (new_mp == NULL)		{		    printk("loop_wput:burst: can't copy message.\n");		    break ;		}		putnext(loop->oqptr, new_mp);	    }	    /*	     * Fall through and send original with rest of options	     */	}	else	if (loop->copy_bfr)	{	    mblk_t *new_mp;	    new_mp = copymsg(mp);	    if (new_mp == NULL)		printk("loop_wput: can't copy message.  Sending original\n");	    else	    {		freemsg(mp);		mp = new_mp;	    }	}	if (loop->mark)	{	    loop->mark--;	    mp->b_flag |= MSGMARK;	}	if (loop->catlvl > 0)	/* concatenating msgs */	{	    mp = loop_concat(loop, mp);	/* do it */	    if (--loop->catlvl > 0)	/* send it yet?  */	    {		loop->saved_msg = mp;	/* no, save it */		break;		/* and exit */	    }	}	if (loop->use_putnext && bcanputnext(loop->oqptr, mp->b_band))	    putnext(loop->oqptr, mp);	else if (loop->use_bufcall)	{	    noenable(q);	/* prevent queue enable */	    putq(q, mp);	    bufcall(0, 0, loop_bufcall, (long) q);	}	else	{	    loop->msgcnt++;	/* count enqueued message */	    if (loop->msglvl > 0 || loop->timr != 0)		noenable(q);	/* prevent queue enable */	    /* ensure timer running before putting into queue */	    if (loop->timr != 0 && loop->timr_hndl == 0)		loop->timr_hndl =		    timeout(loop_timeout, (caddr_t) loop, loop->timr);	    putq(q, mp);	    if (loop->timr_hndl == 0 && loop->msgcnt > loop->msglvl)		qenable(q);	}	break;    }    return (0);}/*  -------------------------------------------------------------------  */static int loop_wsrv(queue_t * q){    mblk_t *mp;    register struct loop *loop;    loop = (struct loop *) q->q_ptr;    if (loop->use_bufcall == 0	&& loop->timr_hndl == 0 && loop->msgcnt <= loop->msglvl) return (0);    if (loop->timr_hndl != 0)    {	untimeout(loop->timr_hndl);	loop->timr_hndl = 0;    }    while ((mp = getq(q)) != NULL)    {	if (loop->oqptr == NULL)	/* other side closed */	{	    freemsg(mp);	    flushq(q, FLUSHALL);	    break;	}	if (mp->b_datap->db_type <= QPCTL &&	    !bcanputnext(loop->oqptr, mp->b_band))	{	    putbq(q, mp);	    if (loop->use_bufcall)		bufcall(0, 0, loop_bufcall, (long) q);	    break;	}	if (loop->use_bufcall)	    loop->use_bufcall--;	putnext(loop->oqptr, mp);	if (--loop->msgcnt <= loop->msglvl)	    break;    }    return (0);}/*  -------------------------------------------------------------------  */static int loop_rsrv(queue_t * q){    struct loop *loop;    loop = (struct loop *) q->q_ptr;    if (loop->oqptr == NULL)	return (0);    qenable(WR(loop->oqptr));    return (0);}/*  -------------------------------------------------------------------  */static int loop_close(queue_t * q, int dummy, cred_t * credp){    struct loop *loop;    loop = (struct loop *) q->q_ptr;    loop->qptr = NULL;    if (loop->timr_hndl != 0)    {	untimeout(loop->timr_hndl);	loop->timr_hndl = 0;    }    if (loop->oqptr)    {	((struct loop *) loop->oqptr->q_ptr)->qptr = NULL;	((struct loop *) loop->oqptr->q_ptr)->oqptr = NULL;	putctl(loop->oqptr->q_next, M_HANGUP);	loop->oqptr = NULL;    }    flushq(q, FLUSHALL);    flushq(WR(q), FLUSHALL);    if (loop->saved_msg != NULL)    {	freemsg(loop->saved_msg);	loop->saved_msg = NULL;    }    if (loop->copy_buf != NULL)    {	FREE(loop->copy_buf);	loop->copy_buf = NULL;    }    loop->use_putnext = 0;    loop->use_bufcall = 0;    loop->msglvl = 0;    loop->msgcnt = 0;    loop->timr = 0;    loop->mark = 0;    loop->copy_bfr = 0;    loop->minor_nr = 0;    loop->catlvl = 0;    loop->deny_2nd_open = 0;    MOD_DEC_USE_COUNT;    return (0);}#ifdef MODULEint init_module(void){    int ret = lis_register_strdev(SLOOP__CMAJOR_0, &sloop_info,				  NLOOP, "loop");    if (ret < 0)    {	printk("loop.init_module: Unable to register driver.\n");	return ret;    }    return 0;}void cleanup_module(void){    if (lis_unregister_strdev(SLOOP__CMAJOR_0) < 0)	printk("loop.cleanup_module: Unable to unregister driver.\n");    else	printk("loop.cleanup_module: Unregistered, ready to be unloaded.\n");    return;}#endif

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -