static unsigned short au1xac97c_ac97_read(struct snd_ac97 *ac97,
					  unsigned short r)
{
	struct au1xpsc_audio_data *ctx = ac97_to_ctx(ac97);
	unsigned int tmo, retry;
	unsigned long data;

	data = ~0;
	retry = AC97_RW_RETRIES;
	do {
		mutex_lock(&ctx->lock);

		tmo = 5;
		while ((RD(ctx, AC97_STATUS) & STAT_CP) && tmo--)
			udelay(21);	
		if (!tmo) {
			pr_debug("ac97rd timeout #1\n");
			goto next;
		}

		WR(ctx, AC97_CMDRESP, CMD_IDX(r) | CMD_READ);

		tmo = 0x10000;
		while ((RD(ctx, AC97_STATUS) & STAT_CP) && tmo--)
			asm volatile ("nop");
		data = RD(ctx, AC97_CMDRESP);

		if (!tmo)
			pr_debug("ac97rd timeout #2\n");

next:
		mutex_unlock(&ctx->lock);
	} while (--retry && !tmo);

	pr_debug("AC97RD %04x %04lx %d\n", r, data, retry);

	return retry ? data & 0xffff : 0xffff;
}
示例#2
0
static int epia_test_proto( PIA *pi, char * scratch, int verbose )

{       int     j, k, f;
	int	e[2] = {0,0};

        epia_connect(pi);
        for (j=0;j<2;j++) {
            WR(6,0xa0+j*0x10);
            for (k=0;k<256;k++) {
                WR(2,k^0xaa);
                WR(3,k^0x55);
                if (RR(2) != (k^0xaa)) e[j]++;
                }
	    WR(2,1); WR(3,1);
            }
        epia_disconnect(pi);

        f = 0;
        epia_connect(pi);
        WR(0x84,8);
        epia_read_block(pi,scratch,512);
        for (k=0;k<256;k++) {
            if ((scratch[2*k] & 0xff) != ((k+1) & 0xff)) f++;
            if ((scratch[2*k+1] & 0xff) != ((-2-k) & 0xff)) f++;
        }
        WR(0x84,0);
        epia_disconnect(pi);

        if (verbose)  {
#ifdef CONFIG_DEBUG_PRINTK
            printk("%s: epia: port 0x%x, mode %d, test=(%d,%d,%d)\n",
                   pi->device,pi->port,pi->mode,e[0],e[1],f);
#else
            ;
#endif
        }
        
        return (e[0] && e[1]) || f;

}
示例#3
0
/*ARGSUSED*/
static int
pfopen(queue_t *rq, dev_t *dev, int oflag, int sflag, cred_t *crp)
{
	struct epacketfilt	*pfp;

	ASSERT(rq);

	if (sflag != MODOPEN)
		return (EINVAL);

	if (rq->q_ptr)
		return (0);

	/*
	 * Allocate and initialize per-Stream structure.
	 */
	pfp = kmem_alloc(sizeof (struct epacketfilt), KM_SLEEP);
	rq->q_ptr = WR(rq)->q_ptr = (char *)pfp;

	qprocson(rq);

	return (0);
}
示例#4
0
static int
emmcinit(void)
{
	u32int *r;
	ulong clk;
	char *s;

	clk = getclkrate(ClkEmmc);
	s = "";
	if(clk == 0){
		s = "Assuming ";
		clk = Extfreq;
	}
	emmc.extclk = clk;
	print("%seMMC external clock %lud Mhz\n", s, clk/1000000);
	r = (u32int*)EMMCREGS;
	if(0)print("emmc control %8.8ux %8.8ux %8.8ux\n",
		r[Control0], r[Control1], r[Control2]);
	WR(Control1, Srsthc);
	delay(10);
	while(r[Control1] & Srsthc)
		;
	return 0;
}
示例#5
0
/* ARGSUSED */
static int
cvc_close(queue_t *q, int flag, cred_t *crp)
{
	register int		err = DDI_SUCCESS;
	register cvc_t		*cp;

	mutex_enter(&cvcmutex);
	input_ok = 0;
	mutex_exit(&cvcmutex);

	cp = q->q_ptr;
	if (cp->cvc_wbufcid != 0) {
		unbufcall(cp->cvc_wbufcid);
	}
	ttycommon_close(&cp->cvc_tty);
	WR(q)->q_ptr = q->q_ptr = NULL;
	cvcinput_q = NULL;
	bzero((caddr_t)cp, sizeof (cvc_t));
	qprocsoff(q);

	CVC_DBG0(CVC_DBG_CLOSE, "Un-plumbed successfully");

	return (err);
}
示例#6
0
/*
 * Put XOFF message on write queue for all standby paths
 *
 * Requires Lock (( M: Mandatory, P: Prohibited, A: Allowed ))
 *  -. uinst_t->lock   : M [RW_READER or RW_WRITER]
 *  -. uinst_t->u_lock : M
 *  -. uinst_t->l_lock : M
 *  -. uinst_t->c_lock : P
 */
void
oplmsu_cmn_putxoff_standby(void)
{
	upath_t	*upath;
	lpath_t	*lpath;

	ASSERT(RW_LOCK_HELD(&oplmsu_uinst->lock));
	ASSERT(MUTEX_HELD(&oplmsu_uinst->u_lock));
	ASSERT(MUTEX_HELD(&oplmsu_uinst->l_lock));

	upath = oplmsu_uinst->first_upath;
	while (upath) {
		lpath = upath->lpath;
		if ((upath->status != MSU_PSTAT_STANDBY) ||
		    (lpath == NULL)) {
			upath = upath->u_next;
			continue;
		}

		(void) oplmsu_cmn_put_xoffxon(
		    WR(lpath->lower_queue), MSU_XOFF_4);
		upath = upath->u_next;
	}
}
示例#7
0
static void epia_write_block( PIA *pi, char * buf, int count )

{       int     ph, k, last, d;

        switch (pi->mode) {

        case 0:
        case 1:
        case 2: w0(0xa1); w2(1); w2(3); w2(1); w2(5);
                ph = 0;  last = 0x8000;
                for (k=0;k<count;k++) {
                        d = buf[k];
                        if (d != last) { last = d; w0(d); }
                        w2(4+ph);
                        ph = 1 - ph;
                }
                w2(7); w2(4);
                break;

        case 3: if (count < 512) WR(0x84,1);
		w3(0x40);
                for (k=0;k<count;k++) w4(buf[k]);
		if (count < 512) WR(0x84,0);
                break;

        case 4: if (count < 512) WR(0x84,1);
		w3(0x40);
                for (k=0;k<count/2;k++) w4w(((u16 *)buf)[k]);
		if (count < 512) WR(0x84,0);
                break;

        case 5: if (count < 512) WR(0x84,1);
		w3(0x40);
                for (k=0;k<count/4;k++) w4l(((u32 *)buf)[k]);
		if (count < 512) WR(0x84,0);
                break;

        }

}
示例#8
0
/*ARGSUSED1*/
static int
zc_close(queue_t *rqp, int flag, cred_t *credp)
{
	queue_t *wqp;
	mblk_t	*bp;
	zc_state_t *zcs;
	major_t major;
	minor_t minor;

	zcs = (zc_state_t *)rqp->q_ptr;

	if (rqp == zcs->zc_master_rdq) {
		DBG("Closing master side");

		zcs->zc_master_rdq = NULL;
		zcs->zc_state &= ~ZC_STATE_MOPEN;

		/*
		 * qenable slave side write queue so that it can flush
		 * its messages as master's read queue is going away
		 */
		if (zcs->zc_slave_rdq != NULL) {
			qenable(WR(zcs->zc_slave_rdq));
		}

		qprocsoff(rqp);
		WR(rqp)->q_ptr = rqp->q_ptr = NULL;

	} else if (rqp == zcs->zc_slave_rdq) {

		DBG("Closing slave side");
		zcs->zc_state &= ~ZC_STATE_SOPEN;
		zcs->zc_slave_rdq = NULL;

		wqp = WR(rqp);
		while ((bp = getq(wqp)) != NULL) {
			if (zcs->zc_master_rdq != NULL)
				putnext(zcs->zc_master_rdq, bp);
			else if (bp->b_datap->db_type == M_IOCTL)
				miocnak(wqp, bp, 0, 0);
			else
				freemsg(bp);
		}

		/*
		 * Qenable master side write queue so that it can flush its
		 * messages as slaves's read queue is going away.
		 */
		if (zcs->zc_master_rdq != NULL)
			qenable(WR(zcs->zc_master_rdq));

		qprocsoff(rqp);
		WR(rqp)->q_ptr = rqp->q_ptr = NULL;

		/*
		 * Clear the sad configuration so that reopening doesn't fail
		 * to set up sad configuration.
		 */
		major = ddi_driver_major(zcs->zc_devinfo);
		minor = ddi_get_instance(zcs->zc_devinfo) << 1 | ZC_SLAVE_MINOR;
		(void) kstr_autopush(CLR_AUTOPUSH, &major, &minor, NULL, NULL,
		    NULL);
	}

	return (0);
}
示例#9
0
/*ARGSUSED*/
static int
parseopen(
	queue_t *q,
	dev_t dev,
	int flag,
	int sflag
	)
{
	register parsestream_t *parse;
	static int notice = 0;

	parseprintf(DD_OPEN,("parse: OPEN\n"));

	if (sflag != MODOPEN)
	{			/* open only for modules */
		parseprintf(DD_OPEN,("parse: OPEN - FAILED - not MODOPEN\n"));
		return OPENFAIL;
	}

	if (q->q_ptr != (caddr_t)NULL)
	{
		u.u_error = EBUSY;
		parseprintf(DD_OPEN,("parse: OPEN - FAILED - EXCLUSIVE ONLY\n"));
		return OPENFAIL;
	}

#ifdef VDDRV
	parsebusy++;
#endif

	q->q_ptr = (caddr_t)kmem_alloc(sizeof(parsestream_t));
	if (q->q_ptr == (caddr_t)0)
	{
		parseprintf(DD_OPEN,("parse: OPEN - FAILED - no memory\n"));
#ifdef VDDRV
		parsebusy--;
#endif
		return OPENFAIL;
	}
	WR(q)->q_ptr = q->q_ptr;

	parse = (parsestream_t *)(void *)q->q_ptr;
	bzero((caddr_t)parse, sizeof(*parse));
	parse->parse_queue     = q;
	parse->parse_status    = PARSE_ENABLE;
	parse->parse_ppsclockev.tv.tv_sec  = 0;
	parse->parse_ppsclockev.tv.tv_usec = 0;
	parse->parse_ppsclockev.serial     = 0;

	if (!parse_ioinit(&parse->parse_io))
	{
		/*
		 * ok guys - beat it
		 */
		kmem_free((caddr_t)parse, sizeof(parsestream_t));
#ifdef VDDRV
		parsebusy--;
#endif
		return OPENFAIL;
	}

	if (setup_stream(q, M_PARSE))
	{
		(void) init_linemon(q);	/* hook up PPS ISR routines if possible */

		parseprintf(DD_OPEN,("parse: OPEN - SUCCEEDED\n"));

		/*
		 * I know that you know the delete key, but you didn't write this
		 * code, did you ? - So, keep the message in here.
		 */
		if (!notice)
		{
#ifdef VDDRV
			printf("%s: Copyright (C) 1991-2005, Frank Kardel\n", parsesync_vd.Drv_name);
#else
			printf("%s: Copyright (C) 1991-2005, Frank Kardel\n", "parsestreams.c,v 4.11 2005/04/16 17:32:10 kardel RELEASE_20050508_A");
#endif
			notice = 1;
		}

		return MODOPEN;
	}
	else
	{
		kmem_free((caddr_t)parse, sizeof(parsestream_t));

#ifdef VDDRV
		parsebusy--;
#endif
		return OPENFAIL;
	}
}
示例#10
0
文件: ip_to_dlpi.c 项目: iHaD/openss7
STATIC streamscall int
ip2xinet_lrput(queue_t *q, mblk_t *mp)
{
	struct iocblk *iocp;
	union DL_primitives *dp;
	struct ip2xinet_priv *privptr;
	struct net_device *dev;
	int i;

	spin_lock(&ip2xinet_lock);

	/* use the first open ip device */
	for (i = 0; i < NUMIP2XINET; i++) {
		privptr = &ip2xinet_devs[i].priv;

		if (privptr->state == 1)
			break;
	}
	if (i == NUMIP2XINET)
		i = 0;		/* All devices closed, pick the 1st one */
	/* send data up to ip through the 1st open device */
	dev = &ip2xinet_devs[i].dev;

	switch (mp->b_datap->db_type) {
	case M_CTL:
		freemsg(mp);
		break;

	case M_DATA:
		/* NOTE: We don't expect any M_DATA messages from xinet */
		freemsg(mp);
		break;

	case M_PROTO:
	case M_PCPROTO:
		dp = (union DL_primitives *) mp->b_rptr;

#if 0
#ifdef DEBUG
		printk("ip2xinet_lrput: %s size=%d\n", x25dbdlpmsg(dp->dl_primitive),
		       x25dbmsgsize(mp));
#endif
#endif

		switch (dp->dl_primitive) {
		case DL_BIND_ACK:

			/* if we're in in BNDPND and receive a BIND_ACK we go to IDLE */
			ip2xinet_status.ip2x_dlstate = DL_IDLE;

			/* If we're DL_IDLE, then dev is open and the kernel can transmit */
			for (i = 0; i < NUMIP2XINET; i++) {
				privptr = &ip2xinet_devs[i].priv;

				if (privptr->state == 1)
					netif_start_queue(&(ip2xinet_devs[i].dev));
			}
			freemsg(mp);	/* Frees bind_ack no longer needed */
			break;

		case DL_INFO_ACK:

			/* NOTE: currently we don't send info_req to xinet */

			freemsg(mp);
			break;

		case DL_ERROR_ACK:
			switch (ip2xinet_status.ip2x_dlstate) {
			case DL_ATTACH_PENDING:
				/* if we receive ERROR_ACK and we're in ATTACH_PEND go into
				   UNATTACHED */
				ip2xinet_status.ip2x_dlstate = DL_UNATTACHED;
				freemsg(mp);
				break;

			case DL_BIND_PENDING:
				/* if we're in BNDPND and receive an ERR ack we go to UNBND, */
				ip2xinet_status.ip2x_dlstate = DL_UNBOUND;
				freemsg(mp);
				break;

			case DL_UNBIND_PENDING:
				/* If we're in UNBIND_PEND and we receive ERROR_ACK we go into IDLE 
				 */
				ip2xinet_status.ip2x_dlstate = DL_IDLE;
				freemsg(mp);
				break;

			case DL_DETACH_PENDING:
				/* If we're in DETACH_PEND and receive and ERROR_ACK we go into
				   UNBND */
				ip2xinet_status.ip2x_dlstate = DL_UNBOUND;
				freemsg(mp);
				break;
			default:
				freemsg(mp);
				break;

			}
			break;

		case DL_UNITDATA_IND:
			/* if we're in IDLE we can get DL_UNITDATA_IND with data and call the guy
			   who would normally receive data from interrupt handler. */

			/* Check state: can't transmit if dev is closed :-) Note: we have to check
			   both the dlpi state and dev->start because during a close the DLPI state 
			   could remain DL_IDLE if we couldn't allocate mblk for UNBIND_REQ. There
			   are many ways in which the dev->start could be 1 but dlpi state - not
			   DL_IDLE. */
			if (ip2xinet_status.ip2x_dlstate == DL_IDLE && privptr->state == 1)
			{
				mblk_t *newmp;
				unsigned char *buf;
				int len, tmplen;
				struct ethhdr *eth;
				struct sk_buff *skb;

				newmp = unlinkb(mp);

				freemsg(mp);
				mp = newmp;

				/* 1st pass through.  figure out the len */
				for (len = sizeof(struct ethhdr); newmp != NULL;
				     newmp = newmp->b_cont)
					len += (newmp->b_wptr - newmp->b_rptr);

				/* ALLOCATE skb of length len+2, COPY from mp chain to skb */

				skb = dev_alloc_skb(len + 2);
				if (!skb) {
					printk("ip2xinet rx: failed to allocate an skb\n");
					freemsg(mp);
					break;
				}
				skb_reserve(skb, 2);	/* align IP on 16B boundary */
				/* The packet has been retrieved from the transmission medium.
				   Build an skb around it, so upper layers can handle it */
				buf = skb_put(skb, len);
				for (newmp = mp, tmplen = sizeof(struct ethhdr); newmp != NULL;
				     newmp = newmp->b_cont) {
					bcopy(newmp->b_rptr, buf + tmplen,
					      newmp->b_wptr - newmp->b_rptr);
					tmplen += (newmp->b_wptr - newmp->b_rptr);
				}
				eth = (struct ethhdr *) buf;

				/* I am not sure it's necessary, but just in case... */

				memcpy(eth->h_source, dev->dev_addr, dev->addr_len);
				memcpy(eth->h_dest, dev->dev_addr, dev->addr_len);
				eth->h_proto = 0x8;	/* ETH_P_IP in network order */
				eth->h_source[ETH_ALEN - 1] ^= 0x01;	/* say src is us xor 1 */

				/* send it to ip2xinet_rx for handling */
				ip2xinet_rx(dev, skb);
			}
			freemsg(mp);
			break;
		case DL_UDERROR_IND:
			freemsg(mp);
			break;

		case DL_OK_ACK:
			switch (dp->ok_ack.dl_correct_primitive) {

			case DL_ATTACH_REQ:
				/* if we're in ATTACH_PEND and we received OK_ACK1 change state to
				   UNBND */
				ip2xinet_status.ip2x_dlstate = DL_UNBOUND;
				freemsg(mp);
				/* We just completed building up the X.25 stack below us. If IP is
				   already above us, we need to send down the bind that we would
				   normally do when IP opens us.  This allows us to restart the
				   X.25 stack without restarting TCP/IP. */
				if (ip2xinet_num_ip_opened != 0)
					ip2xinet_send_down_bind(WR(q));
				break;

			case DL_UNBIND_REQ:
				/* If we're in UNBIND_PEND and receive OK_ACK1 we go to UNBND. */
				ip2xinet_status.ip2x_dlstate = DL_UNBOUND;
				freemsg(mp);
				break;

			case DL_DETACH_REQ:
				/* If we're in DETACH_PEND and receive OK_ACK1 we go to UNATT */
				ip2xinet_status.ip2x_dlstate = DL_UNATTACHED;
				freemsg(mp);
				break;

			default:
				freemsg(mp);
				break;
			}
			break;

		default:
			printk("ip2xinet_lrput: bad prim=0x%lx", (ulong) dp->dl_primitive);
			freemsg(mp);
			break;
		}
		break;

	case M_FLUSH:
		if (mp->b_rptr[0] & FLUSHR) {
			if (mp->b_rptr[0] & FLUSHBAND)
				flushband(q, mp->b_rptr[1], FLUSHDATA);
			else
				flushq(q, FLUSHDATA);
			qenable(q);
		}
		if (mp->b_rptr[0] & FLUSHW) {
			mp->b_rptr[0] &= ~FLUSHR;
			if (mp->b_rptr[0] & FLUSHBAND)
				flushband(WR(q), mp->b_rptr[1], FLUSHDATA);
			else
				flushq(WR(q), FLUSHDATA);
			qenable(WR(q));
			if (!putq(WR(q), mp)) {
				mp->b_band = 0;
				putq(WR(q), mp);
			}
		} else
			freemsg(mp);
		break;

	case M_HANGUP:
		/* send it to the guy that linked us up, what he does is his problem. */
		if (!putq(ip2xinet_status.readq, mp)) {
			mp->b_band = 0;
			putq(ip2xinet_status.readq, mp);
		}
		break;

	case M_IOCACK:
		iocp = (struct iocblk *) mp->b_rptr;
		if (iocp->ioc_cmd == SIOCSIFMTU) {
			/* The set MTU ioctl was a success Rejoice :-) */
			freemsg(mp);
		} else if (!putq(ip2xinet_status.readq, mp)) {
			mp->b_band = 0;
			putq(ip2xinet_status.readq, mp);
		}
		break;

	case M_IOCNAK:
		iocp = (struct iocblk *) mp->b_rptr;
		if (iocp->ioc_cmd == SIOCSIFMTU) {
			/* The set MTU ioctl was a failure From looking at xinet code this is *
			   impossible, so ignore it */

			freemsg(mp);
		} else if (!putq(ip2xinet_status.readq, mp)) {
			mp->b_band = 0;
			putq(ip2xinet_status.readq, mp);
		}
		break;

	default:
		printk("ip2xinet_lrput: bad type=%d", mp->b_datap->db_type);
		freemsg(mp);
		break;
	}

	spin_unlock(&ip2xinet_lock);
	return (0);
}
示例#11
0
static inline int
m3ua_m_ioctl(queue_t *q, mblk_t *mp)
{
	t_t *t;
	m3ua_t *m3ua = (m3ua_t *) q->q_ptr;
	struct iocblk *iocp = (struct iocblk *) mp->b_rptr;
	void *arg = mp->b_cont ? mp->b_cont->b_rptr : NULL;
	int cmd = iocp->ioc_cmd, count = iocp->ioc_count;
	int ret = -EINVAL;
	struct linkblk *lp = (struct linkblk *) arg;

	trace();
	switch (cmd) {
	case I_LINK:
	case I_PLINK:
		/* 
		 *  NOTE: PLINK can be a bit different and could be rather useful.
		 *  A PLINKED SCTP stream will never be closed, even if the
		 *  configuration daemon crashes, even if the m3ua stream is
		 *  closed.  This permits more permanent M3UA configuration
		 *  structures.  The m3uad upon restart reopens the control
		 *  channel with root priviledges and can access the exisitng
		 *  configuration.
		 *
		 *  NOTE: do a MOD_INC_USE_COUNT when PLINKs are added and a
		 *  MOD_DEC_USE_COUNT when they are removed.  Otherwise the module
		 *  may autoclean.
		 */
		if (getminor(m3ua->devnum)) {
			ret = -EPERM;
			break;
		}
		if (!(t = kmalloc(sizeof(*t), GFP_KERNEL))) {
			ret = -ENOMEM;
			break;
		}
		bzero(t, sizeof(*t));

		t->next = m3ua->links;
		m3ua->links = t;
		t->linked = m3ua;
		t->muxid = lp->l_index;
		t->rq = RD(lp->l_qbot);
		t->rq->q_ptr = t;
		t->wq = WR(lp->l_qbot);
		t->wq->q_ptr = t;

		ret = 0;
		break;
	case I_UNLINK:
	case I_PUNLINK:
		if (getminor(m3ua->devnum)) {
			ret = -EPERM;
			break;
		}
		if (t->next)
			t->next->prev = t->prev;
		if (t->prev)
			t->prev->next = t->next;
		kfree(t);
		ret = 0;
		break;
	default:
		if (count >= _IOC_SIZE(cmd)) {
			ret = m3ua_do_ioctl(m3ua, cmd, arg);
		}
		if (abs(ret) == ENXIO) {
			if (q->q_next) {
				putnext(q, mp);
				return (0);
			}
		}
		break;
	}
	if (ret == 0) {
		mp->b_datap->db_type = M_IOCACK;
		iocp->ioc_error = 0;
		iocp->ioc_rval = 0;
	} else {
		mp->b_datap->db_type = M_IOCNAK;
		iocp->ioc_error = abs(ret);
		iocp->ioc_rval = -1;
	}
	qreply(q, mp);
	return (0);
}
示例#12
0
/**
* Run a self-test on the driver/device. Unless fault injection is implemented
* in hardware, this function only does a minimal test in which available
* registers (if any) are written and read.
*
* With fault injection, all possible single-bit and double-bit errors are
* injected, and checked to the extent possible, given the implemented hardware.
*
* @param	InstancePtr is a pointer to the XBram instance.
*
* @return 	XST_SUCCESS unless fault injection is implemented and an
*		injected fault is not correctly detected.
*
*		If the BRAM device is not present in the
*		hardware a bus error could be generated. Other indicators of a
*		bus error, such as registers in bridges or buses, may be
*		necessary to determine if this function caused a bus error.
*
* @note		None.
*
******************************************************************************/
int XBram_SelfTest(XBram *InstancePtr)
{
    Xil_AssertNonvoid(InstancePtr != NULL);
    Xil_AssertNonvoid(InstancePtr->IsReady == XIL_COMPONENT_IS_READY);

    if (InstancePtr->Config.CtrlBaseAddress == 0)
        return (XST_SUCCESS);

    /*
     * Only 32-bit data width is supported as of yet. 64-bit and 128-bit
     * widths will be supported in future.
     */
    if (InstancePtr->Config.DataWidth != 32)
        return (XST_SUCCESS);

    /*
     * Read from the implemented readable registers in the hardware device.
     */
    if (InstancePtr->Config.CorrectableFailingRegisters) {
        (void) RD(CE_FFA_0_OFFSET);
        (void) RD(CE_FFD_0_OFFSET);
        (void) RD(CE_FFE_0_OFFSET);
    }
    if (InstancePtr->Config.UncorrectableFailingRegisters) {
        (void) RD(UE_FFA_0_OFFSET);
        (void) RD(UE_FFD_0_OFFSET);
        (void) RD(UE_FFE_0_OFFSET);
    }

    /*
     * Write and read the implemented read/write registers in the hardware
     * device.
     */
    if (InstancePtr->Config.EccStatusInterruptPresent) {

        WR(ECC_EN_IRQ_OFFSET, 0);
        if (RD(ECC_EN_IRQ_OFFSET) != 0) {
            return (XST_FAILURE);
        }
    }

    if (InstancePtr->Config.CorrectableCounterBits > 0) {
        u32 Value;

        /* Calculate counter max value */
        if (InstancePtr->Config.CorrectableCounterBits == 32) {
            Value = 0xFFFFFFFF;
        } else {
            Value = (1 <<
                     InstancePtr->Config.CorrectableCounterBits) - 1;
        }

        WR(CE_CNT_OFFSET, 0xFFFFFFFF);
        if (RD(CE_CNT_OFFSET) != Value) {
            return (XST_FAILURE);
        }

        WR(CE_CNT_OFFSET, 0);
        if (RD(CE_CNT_OFFSET) != 0) {
            return (XST_FAILURE);
        }
    }

    /*
     * If fault injection is implemented, inject all possible single-bit
     * and double-bit errors, and check all observable effects.
     */
    if (InstancePtr->Config.FaultInjectionPresent &&
            InstancePtr->Config.WriteAccess != 0) {

        const u32 Addr[2] = {InstancePtr->Config.MemBaseAddress &
                             0xfffffffc,
                             InstancePtr->Config.MemHighAddress &
                             0xfffffffc
                            };
        u32 SavedWords[2];
        u32 ActualData;
        u32 ActualEcc;
        u32 CounterValue;
        u32 CounterMax;
        int WordIndex = 0;
        int Result = XST_SUCCESS;
        int Index1;
        int Index2;

        PrngResult = 42; /* Random seed */

        /* Save two words in BRAM used for test */
        SavedWords[0] = XBram_In32(Addr[0]);
        SavedWords[1] = XBram_In32(Addr[1]);

        /* Calculate counter max value */
        if (InstancePtr->Config.CorrectableCounterBits == 32) {
            CounterMax = 0xFFFFFFFF;
        } else {
            CounterMax =(1 <<
                         InstancePtr->Config.CorrectableCounterBits) - 1;
        }

        /* Inject and check all single bit errors */
        for (Index1 = 0; Index1 < TOTAL_BITS; Index1++) {
            /* Save counter value */
            if (InstancePtr->Config.CorrectableCounterBits > 0) {
                CounterValue = RD(CE_CNT_OFFSET);
            }

            /* Inject single bit error */
            InjectErrors(InstancePtr, Addr[WordIndex], Index1,
                         Index1, &ActualData, &ActualEcc);

            /* Check that CE is set */
            if (InstancePtr->Config.EccStatusInterruptPresent) {
                CHECK(ECC_STATUS_OFFSET,
                      XBRAM_IR_CE_MASK, Result);
            }

            /* Check that address, data, ECC are correct */
            if (InstancePtr->Config.CorrectableFailingRegisters) {
                CHECK(CE_FFA_0_OFFSET, Addr[WordIndex], Result);
#if 0
                /*
                 * The following 2 registers are not implemented
                 * in the current version of the axi_bram_ctrl.
                 * This is a common driver for axi_bram_ctrl and
                 * lmb_bram_if_cntlr.
                 */
                CHECK(CE_FFD_0_OFFSET, ActualData, Result);
                CHECK(CE_FFE_0_OFFSET, ActualEcc, Result);
#endif
            }

            /* Check that counter has incremented */
            if (InstancePtr->Config.CorrectableCounterBits > 0 &&
                    CounterValue < CounterMax) {
                CHECK(CE_CNT_OFFSET,
                      CounterValue + 1, Result);
            }

            /* Restore correct data in the used word */
            XBram_Out32(Addr[WordIndex], SavedWords[WordIndex]);

            /* Clear status register */
            if (InstancePtr->Config.EccStatusInterruptPresent) {
                WR(ECC_STATUS_OFFSET, XBRAM_IR_ALL_MASK);
            }

            /* Switch to the other word */
            WordIndex = WordIndex ^ 1;

            if (Result != XST_SUCCESS) break;

        }

        if (Result != XST_SUCCESS) {
            return XST_FAILURE;
        }

        for (Index1 = 0; Index1 < TOTAL_BITS; Index1++) {
            for (Index2 = 0; Index2 < TOTAL_BITS; Index2++) {
                if (Index1 != Index2) {
                    /* Inject double bit error */
                    InjectErrors(InstancePtr,
                                 Addr[WordIndex],
                                 Index1, Index2,
                                 &ActualData,
                                 &ActualEcc);

                    /* Check that UE is set */
                    if (InstancePtr->Config.
                            EccStatusInterruptPresent) {
                        CHECK(ECC_STATUS_OFFSET,
                              XBRAM_IR_UE_MASK,
                              Result);
                    }

                    /* Check that address, data, ECC are correct */
                    if (InstancePtr->Config.
                            UncorrectableFailingRegisters) {
                        CHECK(UE_FFA_0_OFFSET, Addr[WordIndex],
                              Result);
                        CHECK(UE_FFD_0_OFFSET,
                              ActualData, Result);
                        CHECK(UE_FFE_0_OFFSET, ActualEcc,
                              Result);
                    }

                    /* Restore correct data in the used word */
                    XBram_Out32(Addr[WordIndex],
                                SavedWords[WordIndex]);

                    /* Clear status register */
                    if (InstancePtr->Config.
                            EccStatusInterruptPresent) {
                        WR(ECC_STATUS_OFFSET,
                           XBRAM_IR_ALL_MASK);
                    }

                    /* Switch to the other word */
                    WordIndex = WordIndex ^ 1;
                }
                if (Result != XST_SUCCESS) break;
            }
            if (Result != XST_SUCCESS) break;
        }

        /* Check saturation of correctable error counter */
        if (InstancePtr->Config.CorrectableCounterBits > 0 &&
                Result == XST_SUCCESS) {

            WR(CE_CNT_OFFSET, CounterMax);

            InjectErrors(InstancePtr, Addr[WordIndex], 0, 0,
                         &ActualData, &ActualEcc);

            CHECK(CE_CNT_OFFSET, CounterMax, Result);
        }

        /* Restore the two words used for test */
        XBram_Out32(Addr[0], SavedWords[0]);
        XBram_Out32(Addr[1], SavedWords[1]);

        /* Clear the Status Register. */
        if (InstancePtr->Config.EccStatusInterruptPresent) {
            WR(ECC_STATUS_OFFSET, XBRAM_IR_ALL_MASK);
        }

        /* Set Correctable Counter to zero */
        if (InstancePtr->Config.CorrectableCounterBits > 0) {
            WR(CE_CNT_OFFSET, 0);
        }

        return (Result);
    }

    return (XST_SUCCESS);
}
示例#13
0
static inline void vdin_set_color_matrix1(unsigned int offset, tvin_format_t *tvin_fmt_p, enum vdin_format_convert_e format_convert)
{
#if defined(VDIN_V1)
	//    unsigned int offset = devp->addr_offset;
	enum vdin_matrix_csc_e    matrix_csc = VDIN_MATRIX_NULL;
	struct vdin_matrix_lup_s *matrix_tbl;
	struct tvin_format_s *fmt_info = tvin_fmt_p;

	switch (format_convert)
	{
		case VDIN_MATRIX_XXX_YUV_BLACK:
			matrix_csc = VDIN_MATRIX_XXX_YUV601_BLACK;
			break;
		case VDIN_FORMAT_CONVERT_RGB_YUV422:
		case VDIN_FORMAT_CONVERT_RGB_NV12:
		case VDIN_FORMAT_CONVERT_RGB_NV21:
			matrix_csc = VDIN_MATRIX_RGBS_YUV601;
			break;
		case VDIN_FORMAT_CONVERT_BRG_YUV422:
			matrix_csc = VDIN_MATRIX_BRG_YUV601;
			break;
		case VDIN_FORMAT_CONVERT_GBR_YUV422:
			matrix_csc = VDIN_MATRIX_GBR_YUV601;
			break;
		case VDIN_FORMAT_CONVERT_RGB_YUV444:
			matrix_csc = VDIN_MATRIX_RGB_YUV601;
			break;
		case VDIN_FORMAT_CONVERT_YUV_RGB:
			if (
		              ((fmt_info->scan_mode == TVIN_SCAN_MODE_PROGRESSIVE) && (fmt_info->v_active >= 720)) || //  720p & above
		       	      ((fmt_info->scan_mode == TVIN_SCAN_MODE_INTERLACED)  && (fmt_info->v_active >= 540))    // 1080i & above
			   )
				matrix_csc = VDIN_MATRIX_YUV709_RGB;
			else
				matrix_csc = VDIN_MATRIX_YUV601_RGB;
			break;
		case VDIN_FORMAT_CONVERT_YUV_GBR:
			if (((fmt_info->scan_mode == TVIN_SCAN_MODE_PROGRESSIVE) && (fmt_info->v_active >= 720)) || //  720p & above
			    ((fmt_info->scan_mode == TVIN_SCAN_MODE_INTERLACED)  && (fmt_info->v_active >= 540))    // 1080i & above
			   )
				matrix_csc = VDIN_MATRIX_YUV709_GBR;
			else
				matrix_csc = VDIN_MATRIX_YUV601_GBR;
			break;
		case VDIN_FORMAT_CONVERT_YUV_BRG:
			if (((fmt_info->scan_mode == TVIN_SCAN_MODE_PROGRESSIVE) && (fmt_info->v_active >= 720)) || //  720p & above
			    ((fmt_info->scan_mode == TVIN_SCAN_MODE_INTERLACED)  && (fmt_info->v_active >= 540))    // 1080i & above
			   )
				matrix_csc = VDIN_MATRIX_YUV709_BRG;
			else
				matrix_csc = VDIN_MATRIX_YUV601_BRG;
			break;
		case VDIN_FORMAT_CONVERT_YUV_YUV422:
		case VDIN_FORMAT_CONVERT_YUV_YUV444:
		case VDIN_FORMAT_CONVERT_YUV_NV12:
		case VDIN_FORMAT_CONVERT_YUV_NV21:
			if (((fmt_info->scan_mode == TVIN_SCAN_MODE_PROGRESSIVE) && (fmt_info->v_active >= 720)) || //  720p & above
         		    ((fmt_info->scan_mode == TVIN_SCAN_MODE_INTERLACED)  && (fmt_info->v_active >= 540))    // 1080i & above
			   )
			{
				if (color_convert == 0)
					matrix_csc = VDIN_MATRIX_YUV709_YUV601;
				else if (color_convert == 1)
					matrix_csc = VDIN_MATRIX_YUV709_YUV601F;
				else if (color_convert == 2)
					matrix_csc = VDIN_MATRIX_YUV709_YUV709F;
				else if (color_convert == 3)
					matrix_csc = VDIN_MATRIX_YUV709F_YUV601;
				else if (color_convert == 4)
					matrix_csc = VDIN_MATRIX_YUV709F_YUV601F;
				else
					matrix_csc = VDIN_MATRIX_YUV709_YUV601;
			}
			break;
		default:
			matrix_csc = VDIN_MATRIX_NULL;
			break;
	}

	if (matrix_csc == VDIN_MATRIX_NULL)
	{
		WR_BITS(VDIN_MATRIX_CTRL, 0, VDIN_MATRIX1_EN_BIT, VDIN_MATRIX1_EN_WID);
	}
	else
	{
		matrix_tbl = &vdin_matrix_lup[matrix_csc - 1];
		/*select matrix1 post probe and postion(200,100)*/
		WR_BITS(VDIN_MATRIX_CTRL, 1, VDIN_PROBE_POST_BIT, VDIN_PROBE_POST_WID);
		WR_BITS(VDIN_MATRIX_CTRL, 1, VDIN_PROBE_SEL_BIT, VDIN_PROBE_SEL_WID);
		WR(VDIN_MATRIX_PROBE_POS, 0xc812);
		/*coefficient index select matrix1*/
		WR_BITS(VDIN_MATRIX_CTRL, 1, VDIN_MATRIX_COEF_INDEX_BIT, VDIN_MATRIX_COEF_INDEX_WID);
		WR(VDIN_MATRIX_PRE_OFFSET0_1,matrix_tbl->pre_offset0_1);
		WR(VDIN_MATRIX_PRE_OFFSET2, matrix_tbl->pre_offset2);
		WR(VDIN_MATRIX_COEF00_01, matrix_tbl->coef00_01);
		WR(VDIN_MATRIX_COEF02_10, matrix_tbl->coef02_10);
		WR(VDIN_MATRIX_COEF11_12, matrix_tbl->coef11_12);
		WR(VDIN_MATRIX_COEF20_21, matrix_tbl->coef20_21);
		WR(VDIN_MATRIX_COEF22, matrix_tbl->coef22);
		WR(VDIN_MATRIX_OFFSET0_1, matrix_tbl->post_offset0_1);
		WR(VDIN_MATRIX_OFFSET2, matrix_tbl->post_offset2);
                WR_BITS(VDIN_MATRIX_CTRL, 0, VDIN_MATRIX1_BYPASS_BIT, VDIN_MATRIX1_BYPASS_WID);
		WR_BITS(VDIN_MATRIX_CTRL, 1, VDIN_MATRIX1_EN_BIT, VDIN_MATRIX1_EN_WID);
	}
        #endif
}
示例#14
0
void minx_cpu_device::wr16( UINT32 offset, UINT16 data )
{
	WR( offset, ( data & 0x00FF ) );
	WR( offset + 1, ( data >> 8 ) );
}
示例#15
0
文件: m3ua_mtpp.c 项目: iHaD/openss7
/*
 *  MTP_UNITDATA_IND 20 - Connection-less data receive indication
 *  -------------------------------------------------------------------------
 *  N_UNITDATA_IND (MTP_TRANSFER_IND)
 *  -------------------------------------------------------------------------
 *  This covers only the MTP-TRANSFER-Indication primitive.
 *
 *  Let me ask a question here: why dont we just pass the unitdata on to the
 *  ASP and let the ASP translate it into an M3UA message.  That way, if there
 *  are different ASPs supporting different versions, that can be handled at
 *  the ASP instead of here.  Also, we don't know the transport type.  If it
 *  is an SCTP transport, it can do other things with the message, like select
 *  stream.
 */
static int
mtpp_unitdata_ind(queue_t *q, mblk_t *msg)
{
	sls_t *sls;
	queue_t *wq;
	mtpp_t *mtp = Q_MTP(q);
	mblk_t *mp, *db = msg->b_cont;
	size_t dlen = msgdsize(db);
	N_unitdata_ind_t *p = (N_unitdata_req_t *) msg->b_rptr;
	struct mtp_rl *rl = (mtp_rt *) (((caddr_t) p) + p->SRC_offset);
	static const size_t mlen =
	    M3UA_MHDR_SIZE + M3UA_PARM_SIZE_RC + M3UA_PARM_SIZE_RL + M3UA_PHDR_SIZE;
	/* 
	 *  First let's find out where the data is going.  The AS should have
	 *  this all set up for us in the SLS tables.
	 */
	ensure(mtp, return (-EFAULT));
	ensure(mtp->rc, return (-EFAULT));
	ensure(mtp->rc->as, return (-EFAULT));

	sls = &mtp->rc->as->sls[(rl->sls & UA_SLS_MASK)];

	ensure(sls->sp, return (-EFAULT));
	ensure(sls->sp->lp, return (-EFAULT));
	ensure(sls->sp->lp->q, return (-EFAULT));

	if (!(sls->flags & UA_SLS_BUFFERING))
		if (!(canput((wq = WR(sls->sp->lp->q)))))
			return (-EBUSY);	/* apply backpressure! */

	if ((mp = allocb(mlen, BPRI_MED))) {
		mp->b_datap->db_type = M_DATA;
		*((uint32_t *) mp->b_wptr)++ = M3UA_MAUP_DATA;
		*((uint32_t *) mp->b_wptr)++ = htonl(mlen + dlen);
		*((uint32_t *) mp->b_wptr)++ = M3UA_PARM_NA;
		*((uint32_t *) mp->b_wptr)++ = htonl(mtp->na);
		*((uint32_t *) mp->b_wptr)++ = M3UA_PARM_RC;
		*((uint32_t *) mp->b_wptr)++ = htonl(mtp->rc);
		/* 
		 *  A couple of big arguments on what should be in the
		 *  messages here...
		 */
		*((uint32_t *) mp->b_wptr)++ = M3UA_PARM_RL;
		*((uint32_t *) mp->b_wptr)++ = hotnl(rl->opc);
		*((uint32_t *) mp->b_wptr)++ = hotnl(rl->dpc);
		*((uint8_t *) mp->b_wptr)++ = 0;
		*((uint8_t *) mp->b_wptr)++ = hotnl(rl->sls);
		*((uint8_t *) mp->b_wptr)++ = hotnl(rl->ni);
		*((uint8_t *) mp->b_wptr)++ = hotnl(rl->mp);
		*((uint32_t *) mp->b_wptr)++ = M3UA_PARM_DATA;
		mp->b_cont = db;
		freeb(msg);

		if (sls->flags & UA_SLS_BUFFERING)
			/* hold back data for this sls */
			bufq_queue(&sls->buf, mp);
		else
			putq(wq, mp);
		return (0);
	}
	return (-ENOBUFS);	/* try again later */
}
示例#16
0
/* ARGSUSED */
static int
ptemopen(
	queue_t    *q,		/* pointer to the read side queue */
	dev_t   *devp,		/* pointer to stream tail's dev */
	int	oflag,		/* the user open(2) supplied flags */
	int	sflag,		/* open state flag */
	cred_t *credp)		/* credentials */
{
	struct ptem *ntp;	/* ptem entry for this PTEM module */
	mblk_t *mop;		/* an setopts mblk */
	struct stroptions *sop;
	struct termios *termiosp;
	int len;

	if (sflag != MODOPEN)
		return (EINVAL);

	if (q->q_ptr != NULL) {
		/* It's already attached. */
		return (0);
	}

	/*
	 * Allocate state structure.
	 */
	ntp = kmem_alloc(sizeof (*ntp), KM_SLEEP);

	/*
	 * Allocate a message block, used to pass the zero length message for
	 * "stty 0".
	 *
	 * NOTE: it's better to find out if such a message block can be
	 *	 allocated before it's needed than to not be able to
	 *	 deliver (for possible lack of buffers) when a hang-up
	 *	 occurs.
	 */
	if ((ntp->dack_ptr = allocb(4, BPRI_MED)) == NULL) {
		kmem_free(ntp, sizeof (*ntp));
		return (EAGAIN);
	}

	/*
	 * Initialize an M_SETOPTS message to set up hi/lo water marks on
	 * stream head read queue and add controlling tty if not set.
	 */
	mop = allocb(sizeof (struct stroptions), BPRI_MED);
	if (mop == NULL) {
		freemsg(ntp->dack_ptr);
		kmem_free(ntp, sizeof (*ntp));
		return (EAGAIN);
	}
	mop->b_datap->db_type = M_SETOPTS;
	mop->b_wptr += sizeof (struct stroptions);
	sop = (struct stroptions *)mop->b_rptr;
	sop->so_flags = SO_HIWAT | SO_LOWAT | SO_ISTTY;
	sop->so_hiwat = 512;
	sop->so_lowat = 256;

	/*
	 * Cross-link.
	 */
	ntp->q_ptr = q;
	q->q_ptr = ntp;
	WR(q)->q_ptr = ntp;

	/*
	 * Get termios defaults.  These are stored as
	 * a property in the "options" node.
	 */
	if (ddi_getlongprop(DDI_DEV_T_ANY, ddi_root_node(), 0, "ttymodes",
	    (caddr_t)&termiosp, &len) == DDI_PROP_SUCCESS &&
	    len == sizeof (struct termios)) {

		ntp->cflags = termiosp->c_cflag;
		kmem_free(termiosp, len);
	} else {
		/*
		 * Gack!  Whine about it.
		 */
		cmn_err(CE_WARN, "ptem: Couldn't get ttymodes property!");
	}
	ntp->wsz.ws_row = 0;
	ntp->wsz.ws_col = 0;
	ntp->wsz.ws_xpixel = 0;
	ntp->wsz.ws_ypixel = 0;

	ntp->state = 0;

	/*
	 * Commit to the open and send the M_SETOPTS off to the stream head.
	 */
	qprocson(q);
	putnext(q, mop);

	return (0);
}
示例#17
0
/*
 * ptemrput - Module read queue put procedure.
 *
 * This is called from the module or driver downstream.
 */
static void
ptemrput(queue_t *q, mblk_t *mp)
{
	struct iocblk *iocp;	/* M_IOCTL data */
	struct copyresp *resp;	/* transparent ioctl response struct */
	int error;

	switch (mp->b_datap->db_type) {
	case M_DELAY:
	case M_READ:
		freemsg(mp);
		break;

	case M_IOCTL:
		iocp = (struct iocblk *)mp->b_rptr;

		switch (iocp->ioc_cmd) {
		case TCSBRK:
			/*
			 * Send a break message upstream.
			 *
			 * XXX:	Shouldn't the argument come into play in
			 *	determining whether or not so send an M_BREAK?
			 *	It certainly does in the write-side direction.
			 */
			error = miocpullup(mp, sizeof (int));
			if (error != 0) {
				miocnak(q, mp, 0, error);
				break;
			}
			if (!(*(int *)mp->b_cont->b_rptr)) {
				if (!putnextctl(q, M_BREAK)) {
					/*
					 * Send an NAK reply back
					 */
					miocnak(q, mp, 0, EAGAIN);
					break;
				}
			}
			/*
			 * ACK it.
			 */
			mioc2ack(mp, NULL, 0, 0);
			qreply(q, mp);
			break;

		case JWINSIZE:
		case TIOCGWINSZ:
		case TIOCSWINSZ:
			ptioc(q, mp, RDSIDE);
			break;

		case TIOCSIGNAL:
			/*
			 * The following subtle logic is due to the fact that
			 * `mp' may be in any one of three distinct formats:
			 *
			 *	1. A transparent M_IOCTL with an intptr_t-sized
			 *	   payload containing the signal number.
			 *
			 *	2. An I_STR M_IOCTL with an int-sized payload
			 *	   containing the signal number.
			 *
			 *	3. An M_IOCDATA with an int-sized payload
			 *	   containing the signal number.
			 */
			if (iocp->ioc_count == TRANSPARENT) {
				intptr_t sig = *(intptr_t *)mp->b_cont->b_rptr;

				if (sig < 1 || sig >= NSIG) {
					/*
					 * it's transparent with pointer
					 * to the arg
					 */
					mcopyin(mp, NULL, sizeof (int), NULL);
					qreply(q, mp);
					break;
				}
			}
			ptioc(q, mp, RDSIDE);
			break;

		case TIOCREMOTE:
			if (iocp->ioc_count != TRANSPARENT)
				ptioc(q, mp, RDSIDE);
			else {
				mcopyin(mp, NULL, sizeof (int), NULL);
				qreply(q, mp);
			}
			break;

		default:
			putnext(q, mp);
			break;
		}
		break;

	case M_IOCDATA:
		resp = (struct copyresp *)mp->b_rptr;
		if (resp->cp_rval) {
			/*
			 * Just free message on failure.
			 */
			freemsg(mp);
			break;
		}

		/*
		 * Only need to copy data for the SET case.
		 */
		switch (resp->cp_cmd) {

		case TIOCSWINSZ:
		case TIOCSIGNAL:
		case TIOCREMOTE:
			ptioc(q, mp, RDSIDE);
			break;

		case JWINSIZE:
		case TIOCGWINSZ:
			mp->b_datap->db_type = M_IOCACK;
			mioc2ack(mp, NULL, 0, 0);
			qreply(q, mp);
			break;

		default:
			freemsg(mp);
			break;
	}
	break;

	case M_IOCACK:
	case M_IOCNAK:
		/*
		 * We only pass write-side ioctls through to the master that
		 * we've already ACKed or NAKed to the stream head.  Thus, we
		 * discard ones arriving from below, since they're redundant
		 * from the point of view of modules above us.
		 */
		freemsg(mp);
		break;

	case M_HANGUP:
		/*
		 * clear blocked state.
		 */
		{
			struct ptem *ntp = (struct ptem *)q->q_ptr;
			if (ntp->state & OFLOW_CTL) {
				ntp->state &= ~OFLOW_CTL;
				qenable(WR(q));
			}
		}
	default:
		putnext(q, mp);
		break;
	}
}
static inline void _serial_putc(char c)
{
	while (!(RD(LSR) & 0x20)) ;
	WR(c, THR);
}
示例#19
0
/*
 * display_lines -- read lines to an offset from the end and display.
 *
 * This is the function that reads to a line offset from the end of the input,
 * storing the data in an array of buffers which is then displayed.  If the
 * rflag is set, the data is displayed in lines in reverse order, and this
 * routine has the usual nastiness of trying to find the newlines.  Otherwise,
 * it is displayed from the line closest to the beginning of the input to
 * the end.
 */
int
display_lines(FILE *fp, off_t off)
{
	struct {
		ssize_t blen;
		ssize_t len;
		char *l;
	} *lines;
	int ch, rc = 0;
	char *p = NULL;
	int blen, cnt, recno, wrap;
	char *sp;

	if ((lines = malloc(off * sizeof(*lines))) == NULL)
		err(1, "malloc");
	bzero(lines, off * sizeof(*lines));
	sp = NULL;
	blen = cnt = recno = wrap = 0;

	while ((ch = getc(fp)) != EOF) {
		if (++cnt > blen) {
			if ((sp = realloc(sp, blen += 1024)) == NULL)
				err(1, "realloc");
			p = sp + cnt - 1;
		}
		*p++ = ch;
		if (ch == '\n') {
			if (lines[recno].blen < cnt) {
				lines[recno].blen = cnt + 256;
				if ((lines[recno].l = realloc(lines[recno].l,
				    lines[recno].blen)) == NULL)
					err(1, "realloc");
			}
			bcopy(sp, lines[recno].l, lines[recno].len = cnt);
			cnt = 0;
			p = sp;
			if (++recno == off) {
				wrap = 1;
				recno = 0;
			}
		}
	}
	if (ferror(fp)) {
		ierr();
		rc = 1;
		goto out;
	}
	if (cnt) {
		lines[recno].l = sp;
		sp = NULL;
		lines[recno].len = cnt;
		if (++recno == off) {
			wrap = 1;
			recno = 0;
		}
	}

	if (rflag) {
		for (cnt = recno - 1; cnt >= 0; --cnt)
			WR(lines[cnt].l, lines[cnt].len);
		if (wrap)
			for (cnt = off - 1; cnt >= recno; --cnt)
				WR(lines[cnt].l, lines[cnt].len);
	} else {
		if (wrap)
			for (cnt = recno; cnt < off; ++cnt)
				WR(lines[cnt].l, lines[cnt].len);
		for (cnt = 0; cnt < recno; ++cnt)
			WR(lines[cnt].l, lines[cnt].len);
	}
out:
	for (cnt = 0; cnt < off; cnt++)
		free(lines[cnt].l);
	free(sp);
	free(lines);
	return (rc);
}
示例#20
0
static int
zap_m_ioctl(struct zt_chan *chan, queue_t *q, mblk_t *mp)
{
	struct iocblk *ioc = (typeof(ioc)) mp->b_rptr;
	mblk_t *dp = mp->b_cont;

	switch (ioc->ioc_cmd) {
	case ZT_GET_BLOCKSIZE:
	case ZT_SET_BLOCKSIZE:
	case ZT_FLUSH:
	case ZT_SYNC:
	case ZT_GET_PARAMS:
	case ZT_SET_PARAMS:
	case ZT_HOOK:
	case ZT_SPANSTAT:
	case ZT_MAINT:
	case ZT_GETCONF:
	case ZT_SETCONF:
	case ZT_CONFLINK:
	case ZT_CONFDIAG:
	case ZT_GETGAINS:
	case ZT_SETGAINS:
	case ZT_SPANCONFIG:
	case ZT_CHANCONFIG:
	case ZT_CONFMUTE:
	case ZT_SENDTONE:
	case ZT_SETTONEZONE:
	case ZT_GETTONEZONE:
	case ZT_DEFAULTZONE:
	case ZT_LOADZONE:
	case ZT_FREEZONE:
	case ZT_SET_BUFINFO:
	case ZT_GET_BUFINFO:
	case ZT_GET_DIALPARAMS:
	case ZT_SET_DIALPARAMS:
	case ZT_DIAL:
	case ZT_AUDIOMODE:
	case ZT_ECHOCANCEL:
	case ZT_CHANNO:
	case ZT_DIALING:
	case ZT_HDLCRAWMODE:
	case ZT_HDLCFCSMODE:
	case ZT_SPECIFY:
	{
		int channo = *(int *) dp->b_rptr;

		if ((channo < 1) || (channo > ZT_MAX_CHANNELS))
			miocnak(q, mp, 0, EINVAL);
		if ((err = zt_specchan_open(NULL, qstream(q)->sd_file, channo, 0)) == 0) {
			RD(q)->q_ptr = WR(q)->q_ptr = &chans[channo];
			miocack(q, mp, 0, 0);
		} else {
			miocnak(q, mp, 0, (err < 0 ? -err : err));
		}
		return (0);
	}
	case ZT_SETLAW:
	case ZT_SETLINEAR:
	case ZT_HDLCPPP:
	case ZT_SETCADENCE:
	case ZT_SETTXBITS:
	case ZT_CHANDIAG:
	case ZT_GETRXBITS:
	case ZT_SFCONFIG:
	case ZT_TIMERCONFIG:
	case ZT_TIMERACK:
	case ZT_GETCONFMUTE:
	case ZT_ECHOTRAIN:
	case ZT_ONHOOKTRANSFER:
	case ZT_TIMERPING:
	case ZT_TIMERPONG:
	case ZT_SIGFREEZE:
	case ZT_GETSIGFREEZE:
		mi_copyout(q, mp, NULL, sizeof(int));
		return (0);
	case ZT_INDIRECT:
	case ZT_DYNAMIC_CREATE:
	case ZT_DYNAMIC_DESTROY:
	case ZT_TONEDETECT:
	case ZT_SETPOLARITY:
	case ZT_STARTUP:
	case ZT_SHUTDOWN:
	}
}
示例#21
0
static void epat_connect ( PIA *pi )

{       pi->saved_r0 = r0();
        pi->saved_r2 = r2();

 	/* Initialize the chip */
	CPP(0);

	if (epatc8) {
		CPP(0x40);CPP(0xe0);
		w0(0);w2(1);w2(4);
		WR(0x8,0x12);WR(0xc,0x14);WR(0x12,0x10);
		WR(0xe,0xf);WR(0xf,4);
		/* WR(0xe,0xa);WR(0xf,4); */
		WR(0xe,0xd);WR(0xf,0);
		/* CPP(0x30); */
	}

        /* Connect to the chip */
	CPP(0xe0);
        w0(0);w2(1);w2(4); /* Idle into SPP */
        if (pi->mode >= 3) {
          w0(0);w2(1);w2(4);w2(0xc);
          /* Request EPP */
          w0(0x40);w2(6);w2(7);w2(4);w2(0xc);w2(4);
        }

	if (!epatc8) {
		WR(8,0x10); WR(0xc,0x14); WR(0xa,0x38); WR(0x12,0x10);
	}
}
示例#22
0
void bob::math::eig_(const blitz::Array<double,2>& A,
  blitz::Array<std::complex<double>,2>& V,
  blitz::Array<std::complex<double>,1>& D)
{
  // Size variable
  const int N = A.extent(0);

  // Prepares to call LAPACK function
  // Initialises LAPACK variables
  const char jobvl = 'N'; // Do NOT compute left eigen-vectors
  const char jobvr = 'V'; // Compute right eigen-vectors
  int info = 0;
  const int lda = N;
  const int ldvr = N;
  double VL = 0; // notice we don't compute the left eigen-values
  const int ldvl = 1;

  // Initialises LAPACK arrays
  blitz::Array<double,2> A_lapack = bob::core::array::ccopy(const_cast<blitz::Array<double,2>&>(A).transpose(1,0));

  // temporary arrays to receive LAPACK's eigen-values and eigen-vectors
  blitz::Array<double,1> WR(D.shape()); //real part
  blitz::Array<double,1> WI(D.shape()); //imaginary part
  blitz::Array<double,2> VR(A.shape()); //right eigen-vectors

  // Calls the LAPACK function
  // A/ Queries the optimal size of the working arrays
  const int lwork_query = -1;
  double work_query;
  dgeev_( &jobvl, &jobvr, &N, A_lapack.data(), &lda, WR.data(), WI.data(),
      &VL, &ldvl, VR.data(), &ldvr, &work_query, &lwork_query, &info);

  // B/ Computes the eigenvalue decomposition
  const int lwork = static_cast<int>(work_query);
  boost::shared_array<double> work(new double[lwork]);
  dgeev_( &jobvl, &jobvr, &N, A_lapack.data(), &lda, WR.data(), WI.data(),
      &VL, &ldvl, VR.data(), &ldvr, work.get(), &lwork, &info);

  // Checks info variable
  if (info != 0) {
    throw std::runtime_error("the QR algorithm failed to compute all the eigenvalues, and no eigenvectors have been computed.");
  }

  // Copy results back from WR, WI => D
  blitz::real(D) = WR;
  blitz::imag(D) = WI;

  // Copy results back from VR => V, with two rules:
  // 1) If the j-th eigenvalue is real, then v(j) = VR(:,j), the j-th column of
  //    VR.
  // 2) If the j-th and (j+1)-st eigenvalues form a complex conjugate pair,
  // then v(j) = VR(:,j) + i*VR(:,j+1) and v(j+1) = VR(:,j) - i*VR(:,j+1).
  blitz::Range a = blitz::Range::all();
  int i=0;
  while (i<N) {
    if (std::imag(D(i)) == 0.) { //real eigen-value, consume 1
      blitz::real(V(a,i)) = VR(i,a);
      blitz::imag(V(a,i)) = 0.;
      ++i;
    }
    else { //complex eigen-value, consume 2
      blitz::real(V(a,i)) = VR(i,a);
      blitz::imag(V(a,i)) = VR(i+1,a);
      blitz::real(V(a,i+1)) = VR(i,a);
      blitz::imag(V(a,i+1)) = -VR(i+1,a);
      i += 2;
    }
  }
}
示例#23
0
/*
 * r_buf -- display a non-regular file in reverse order by line.
 *
 * This is the function that saves the entire input, storing the data in a
 * doubly linked list of buffers and then displays them in reverse order.
 * It has the usual nastiness of trying to find the newlines, as there's no
 * guarantee that a newline occurs anywhere in the file, let alone in any
 * particular buffer.  If we run out of memory, input is discarded (and the
 * user warned).
 */
static void
r_buf(FILE *fp)
{
	BF *mark, *tr, *tl = NULL;
	int ch;
	size_t len, llen;
	char *p;
	off_t enomem;

#define	BSZ	(128 * 1024)
	for (mark = NULL, enomem = 0;;) {
		/*
		 * Allocate a new block and link it into place in a doubly
		 * linked list.  If out of memory, toss the LRU block and
		 * keep going.
		 */
		if (enomem || (tl = malloc(sizeof(BF))) == NULL ||
		    (tl->l = malloc(BSZ)) == NULL) {
			if (!mark)
				err(1, NULL);
			tl = enomem ? tl->next : mark;
			enomem += tl->len;
		} else if (mark) {
			tl->next = mark;
			tl->prev = mark->prev;
			mark->prev->next = tl;
			mark->prev = tl;
		} else {
			mark = tl;
			mark->next = mark->prev = mark;
		}

		if (!enomem)
			tl->len = 0;

		/* Fill the block with input data. */
		for (p = tl->l, len = 0;
		    len < BSZ && (ch = getc(fp)) != EOF; ++len)
			*p++ = ch;

		/*
		 * If no input data for this block and we tossed some data,
		 * recover it.
		 */
		if (!len) {
			if (enomem)
				enomem -= tl->len;
			tl = tl->prev;
			break;
		}

		tl->len = len;
		if (ch == EOF)
			break;
	}

	if (enomem) {
		(void)fprintf(stderr,
		    "tail: warning: %lld bytes discarded\n", (long long)enomem);
		rval = 1;
	}

	/*
	 * Step through the blocks in the reverse order read.  The last char
	 * is special, ignore whether newline or not.
	 */
	for (mark = tl;;) {
		for (p = tl->l + (len = tl->len) - 1, llen = 0; len--;
		    --p, ++llen)
			if (*p == '\n') {
				if (llen) {
					WR(p + 1, llen);
					llen = 0;
				}
				if (tl == mark)
					continue;
				for (tr = tl->next; tr->len; tr = tr->next) {
					WR(tr->l, tr->len);
					tr->len = 0;
					if (tr == mark)
						break;
				}
			}
		tl->len = llen;
		if ((tl = tl->prev) == mark)
			break;
	}
	tl = tl->next;
	if (tl->len) {
		WR(tl->l, tl->len);
		tl->len = 0;
	}
	while ((tl = tl->next)->len) {
		WR(tl->l, tl->len);
		tl->len = 0;
	}
}
/*config the register use 720x480*/
inline void d2d3_default_config()
{
        int i = 0;
        for(i=0;i<D2D3_REG_NUM;i++)
        WR(D2D3_CBUS_BASE+i,d2d3_reg_table[i]);
}
示例#25
0
static void i2c_au1550_disable(struct i2c_au1550_data *priv)
{
	WR(priv, PSC_SMBCFG, 0);
	WR(priv, PSC_CTRL, PSC_CTRL_DISABLE);
}
示例#26
0
/**
 * socksys_qopen - SOCKSYS driver STREAMS open routine
 * @q: read queue of opened Stream
 * @devp: pointer to device number opened
 * @oflag: flags to the open call
 * @sflag: STREAMS flag: DRVOPEN, MODOPEN or CLONEOPEN
 * @crp: pointer to opener's credentials
 */
STATIC streamscall int
socksys_qopen(queue_t *q, dev_t *devp, int oflag, int sflag, cred_t *crp)
{
	int mindex = 0;
	int type = 0;
	major_t cmajor = getmajor(*devp);
	minor_t cminor = getminor(*devp);
	struct ssys **sp = &socksys_opens;
	unsigned long flags;

	if (q->q_ptr != NULL) {
		return (0);	/* already open */
	}
	if (sflag == MODOPEN || WR(q)->q_next) {
		ptrace(("%s: ERROR: cannot push as module\n", DRV_NAME));
		return (EIO);
	}
	/* Linux Fast-STREAMS always passes internal major device number (module id).  Note also,
	   however, that strconf-sh attempts to allocate module ids that are identical to the base
	   major device number anyway. */
	/* Linux Fast-STREAMS always passes internal major device numbers (module ids) */
	if (cmajor != DRV_ID)
		return (ENXIO);
	/* sorry, you cannot open by minor device */
	if (cminor > LAST_CMINOR) {
		return (ENXIO);
	}
	type = cminor;
#if 0
	if (sflag == CLONEOPEN)
#endif
		cminor = FREE_CMINOR;
	write_lock_str2(&socksys_lock, flags);
	for (; *sp; sp = &(*sp)->next) {
		if (cmajor != (*sp)->dev.cmajor)
			break;
		if (cmajor == (*sp)->dev.cmajor) {
			if (cminor < (*sp)->dev.cminor)
				break;
			if (cminor == (*sp)->dev.cminor) {
				if (++cminor >= NMINORS) {
					if (++mindex >= CMAJORS || !(cmajor = ssys_majors[mindex]))
						break;
					cminor = 0;	/* start next major */
				}
				continue;
			}
		}
	}
	if (mindex >= CMAJORS || !cmajor) {
		ptrace(("%s: ERROR: no device numbers available\n", DRV_NAME));
		write_unlock_str2(&socksys_lock, flags);
		return (ENXIO);
	}
	_printd(("%s: opened character device %d:%d\n", DRV_NAME, cmajor, cminor));
	*devp = makedevice(cmajor, cminor);
	if (!ssys_alloc_priv(q, sp, type, devp, crp)) {
		ptrace(("%s: ERROR: No memory\n", DRV_NAME));
		write_unlock_str2(&socksys_lock, flags);
		return (ENOMEM);
	}
	write_unlock_str2(&socksys_lock, flags);
	qprocson(q);
	return (0);
}
示例#27
0
/*ARGSUSED*/
static int
zc_slave_open(zc_state_t *zcs,
    queue_t	*rqp,	/* pointer to the read side queue */
    dev_t	*devp,	/* pointer to stream tail's dev */
    int		oflag,	/* the user open(2) supplied flags */
    int		sflag,	/* open state flag */
    cred_t	*credp)	/* credentials */
{
	mblk_t *mop;
	struct stroptions *sop;
	major_t major;
	minor_t minor;
	minor_t lastminor;
	uint_t anchorindex;

	/*
	 * The slave side can be opened as many times as needed.
	 */
	if ((zcs->zc_state & ZC_STATE_SOPEN) != 0) {
		ASSERT((rqp != NULL) && (WR(rqp)->q_ptr == zcs));
		return (0);
	}

	/*
	 * Set up sad(7D) so that the necessary STREAMS modules will be in
	 * place.  A wrinkle is that 'ptem' must be anchored
	 * in place (see streamio(7i)) because we always want the console to
	 * have terminal semantics.
	 */
	minor = ddi_get_instance(zcs->zc_devinfo) << 1 | ZC_SLAVE_MINOR;
	major = ddi_driver_major(zcs->zc_devinfo);
	lastminor = 0;
	anchorindex = 1;
	if (kstr_autopush(SET_AUTOPUSH, &major, &minor, &lastminor,
	    &anchorindex, zcons_mods) != 0) {
		DBG("zc_slave_open(): kstr_autopush() failed\n");
		return (EIO);
	}

	if ((mop = allocb(sizeof (struct stroptions), BPRI_MED)) == NULL) {
		DBG("zc_slave_open(): mop allocation failed\n");
		return (ENOMEM);
	}

	zcs->zc_state |= ZC_STATE_SOPEN;

	/*
	 * q_ptr stores driver private data; stash the soft state data on both
	 * read and write sides of the queue.
	 */
	WR(rqp)->q_ptr = rqp->q_ptr = zcs;

	qprocson(rqp);

	/*
	 * Must follow qprocson(), since we aren't ready to process until then.
	 */
	zcs->zc_slave_rdq = rqp;

	/*
	 * set up hi/lo water marks on stream head read queue and add
	 * controlling tty as needed.
	 */
	mop->b_datap->db_type = M_SETOPTS;
	mop->b_wptr += sizeof (struct stroptions);
	sop = (struct stroptions *)(void *)mop->b_rptr;
	sop->so_flags = SO_HIWAT | SO_LOWAT | SO_ISTTY;
	sop->so_hiwat = _TTY_BUFSIZ;
	sop->so_lowat = 256;
	putnext(rqp, mop);

	return (0);
}
示例#28
0
    static int
dlpi_rput( queue_t *q, mblk_t *m )
{
    struct atif_data	*aid = (struct atif_data *)q->q_ptr;
    union DL_primitives	*dl;
    mblk_t		*m0;
    struct llc		*llc;

    switch ( m->b_datap->db_type ) {
    case M_IOCNAK :
	putnext( q, m );
	return( 0 );

    case M_PCPROTO :
    case M_PROTO :
	if ( m->b_wptr - m->b_rptr < sizeof( dl->dl_primitive )) {
	    break;
	}
	dl = (union DL_primitives *)m->b_rptr;
	switch ( dl->dl_primitive ) {
	case DL_UNITDATA_IND :
	    if ( m->b_wptr - m->b_rptr < sizeof( DL_UNITDATA_IND_SIZE )) {
		break;
	    }
	    if (( m0 = unlinkb( m )) == NULL ) {
		break;
	    }
	    if ( m0->b_wptr - m0->b_rptr < sizeof( struct llc )) {
		freemsg( m0 );
		break;
	    }
	    llc = (struct llc *)m0->b_rptr;
	    if ( llc->llc_dsap != LLC_SNAP_LSAP ||
		    llc->llc_ssap != LLC_SNAP_LSAP ||
		    llc->llc_control != LLC_UI ) {
		freemsg( m0 );
		break;
	    }

	    if ( bcmp( llc->llc_org_code, at_org_code,
		    sizeof( at_org_code )) == 0 &&
		    ntohs( llc->llc_ether_type ) == ETHERTYPE_AT ) {
		adjmsg( m0, sizeof( struct llc ));
		ddp_rput( aid, m0 );
	    } else if ( bcmp( llc->llc_org_code, aarp_org_code,
		    sizeof( aarp_org_code )) == 0 &&
		    ntohs( llc->llc_ether_type ) == ETHERTYPE_AARP ) {
		adjmsg( m0, sizeof( struct llc ));
		aarp_rput( q, m0 );
	    } else {
		freemsg( m0 );
	    }
	    break;

	case DL_OK_ACK :
	    if ( m->b_wptr - m->b_rptr < sizeof( DL_OK_ACK_SIZE )) {
		break;
	    }
	    switch ( dl->ok_ack.dl_correct_primitive ) {
	    case DL_ATTACH_REQ :
		if ( aid->aid_state != DL_ATTACH_PENDING ) {
		    cmn_err( CE_NOTE, "dlpi_rput DL_OK_ACK attach state %d\n",
			    aid->aid_state );
		    break;
		}
		if ( aid->aid_c.c_type != IF_UNITSEL ) {
		    cmn_err( CE_NOTE, "dlpi_rput DL_OK_ACK attach context %x\n",
			    aid->aid_c.c_type );
		    break;
		}

		if ( WR(q)->q_next == NULL || WR(q)->q_next->q_qinfo == NULL ||
			WR(q)->q_next->q_qinfo->qi_minfo == NULL ||
			WR(q)->q_next->q_qinfo->qi_minfo->mi_idname == NULL ) {
		    cmn_err( CE_NOTE, "dlpi_rput can't get interface name\n" );
		    break;
		}

		if_name( aid, WR(q)->q_next->q_qinfo->qi_minfo->mi_idname,
			aid->aid_c.c_u.u_unit.uu_ppa );

		aid->aid_state = DL_BIND_PENDING;

#ifdef i386
		/*
		 * As of Solaris 7 (nice name), the i386 arch needs to be
		 * bound as 0 to receive 802 frames.  However, in the same
		 * OS, Sparcs must be bound as ETHERMTU (or at least not 0)
		 * to receive the same frames.  A bug?  In the Solaris 7
		 * (nice name) kernel?
		 */
		dl_bind_req( WR( q ), 0 );
#else /* i386 */
		dl_bind_req( WR( q ), ETHERMTU );
#endif /* i386 */
		break;

	    case DL_ENABMULTI_REQ :
		if ( aid->aid_c.c_type != SIOCADDMULTI ) {
		    cmn_err( CE_NOTE,
			    "dlpi_rput DL_OK_ACK enabmulti context %x\n",
			    aid->aid_c.c_type );
		    break;
		}

		ioc_ok_ack( aid->aid_c.c_u.u_multi.um_q,
			aid->aid_c.c_u.u_multi.um_m, 0 );
		aid->aid_c.c_type = 0;
		aid->aid_c.c_u.u_multi.um_q = NULL;
		aid->aid_c.c_u.u_multi.um_m = 0;
		break;

	    default :
		cmn_err( CE_CONT, "!dlpi_rput DL_OK_ACK unhandled %d\n",
			dl->ok_ack.dl_correct_primitive );
		break;
	    }
	    break;

	case DL_BIND_ACK :
	    if ( m->b_wptr - m->b_rptr < sizeof( DL_BIND_ACK_SIZE )) {
		break;
	    }
	    if ( aid->aid_state != DL_BIND_PENDING ) {
		break;
	    }
	    if ( aid->aid_c.c_type != IF_UNITSEL ) {
		break;
	    }
	    bcopy( m->b_rptr + dl->bind_ack.dl_addr_offset, aid->aid_hwaddr, 
		    dl->bind_ack.dl_addr_length );
	    aid->aid_state = DL_IDLE;
	    ioc_ok_ack( WR(q), aid->aid_c.c_u.u_unit.uu_m, 0 );
	    aid->aid_c.c_type = 0;
	    aid->aid_c.c_u.u_unit.uu_m = NULL;
	    aid->aid_c.c_u.u_unit.uu_ppa = 0;
	    break;

	case DL_ERROR_ACK :
	    if ( m->b_wptr - m->b_rptr < sizeof( DL_ERROR_ACK_SIZE )) {
		break;
	    }

	    switch ( aid->aid_c.c_type ) {
	    case IF_UNITSEL :
		if ( dl->error_ack.dl_errno == DL_SYSERR ) {
		    ioc_error_ack( WR(q), aid->aid_c.c_u.u_unit.uu_m,
			    dl->error_ack.dl_unix_errno );
		} else {
		    cmn_err( CE_CONT, "dlpi_rput DL_ERROR_ACK 0x%x\n",
			    dl->error_ack.dl_errno );
		    ioc_error_ack( WR(q), aid->aid_c.c_u.u_unit.uu_m, EINVAL );
		}
		aid->aid_c.c_type = 0;
		aid->aid_c.c_u.u_unit.uu_m = NULL;
		aid->aid_c.c_u.u_unit.uu_ppa = 0;
		break;

	    default :
		cmn_err( CE_NOTE, "dlpi_rput DL_ERROR_ACK unhandled %d %d %d\n",
			dl->error_ack.dl_error_primitive,
			dl->error_ack.dl_errno, dl->error_ack.dl_unix_errno );
		break;
	    }
	    break;

	default :
	    cmn_err( CE_NOTE, "dlpi_rput M_PCPROTO 0x%x\n", dl->dl_primitive );
	    break;
	}
	break;

    default :
	cmn_err( CE_NOTE, "dlpi_rput 0x%X\n", m->b_datap->db_type );
	break;
    }

    freemsg( m );
    return( 0 );
}
示例#29
0
/*
 * wput(9E) is symmetric for master and slave sides, so this handles both
 * without splitting the codepath.  (The only exception to this is the
 * processing of zcons ioctls, which is restricted to the master side.)
 *
 * zc_wput() looks at the other side; if there is no process holding that
 * side open, it frees the message.  This prevents processes from hanging
 * if no one is holding open the console.  Otherwise, it putnext's high
 * priority messages, putnext's normal messages if possible, and otherwise
 * enqueues the messages; in the case that something is enqueued, wsrv(9E)
 * will take care of eventually shuttling I/O to the other side.
 */
static void
zc_wput(queue_t *qp, mblk_t *mp)
{
	unsigned char type = mp->b_datap->db_type;
	zc_state_t *zcs;
	struct iocblk *iocbp;
	file_t *slave_filep;
	struct snode *slave_snodep;
	int slave_fd;

	ASSERT(qp->q_ptr);

	DBG1("entering zc_wput, %s side", zc_side(qp));

	/*
	 * Process zcons ioctl messages if qp is the master console's write
	 * queue.
	 */
	zcs = (zc_state_t *)qp->q_ptr;
	if (zcs->zc_master_rdq != NULL && qp == WR(zcs->zc_master_rdq) &&
	    type == M_IOCTL) {
		iocbp = (struct iocblk *)(void *)mp->b_rptr;
		switch (iocbp->ioc_cmd) {
		case ZC_HOLDSLAVE:
			/*
			 * Hold the slave's vnode and increment the refcount
			 * of the snode.  If the vnode is already held, then
			 * indicate success.
			 */
			if (iocbp->ioc_count != TRANSPARENT) {
				miocack(qp, mp, 0, EINVAL);
				return;
			}
			if (zcs->zc_slave_vnode != NULL) {
				miocack(qp, mp, 0, 0);
				return;
			}

			/*
			 * The process that passed the ioctl must be running in
			 * the global zone.
			 */
			if (curzone != global_zone) {
				miocack(qp, mp, 0, EINVAL);
				return;
			}

			/*
			 * The calling process must pass a file descriptor for
			 * the slave device.
			 */
			slave_fd =
			    (int)(intptr_t)*(caddr_t *)(void *)mp->b_cont->
			    b_rptr;
			slave_filep = getf(slave_fd);
			if (slave_filep == NULL) {
				miocack(qp, mp, 0, EINVAL);
				return;
			}
			if (ZC_STATE_TO_SLAVEDEV(zcs) !=
			    slave_filep->f_vnode->v_rdev) {
				releasef(slave_fd);
				miocack(qp, mp, 0, EINVAL);
				return;
			}

			/*
			 * Get a reference to the slave's vnode.  Also bump the
			 * reference count on the associated snode.
			 */
			ASSERT(vn_matchops(slave_filep->f_vnode,
			    spec_getvnodeops()));
			zcs->zc_slave_vnode = slave_filep->f_vnode;
			VN_HOLD(zcs->zc_slave_vnode);
			slave_snodep = VTOCS(zcs->zc_slave_vnode);
			mutex_enter(&slave_snodep->s_lock);
			++slave_snodep->s_count;
			mutex_exit(&slave_snodep->s_lock);
			releasef(slave_fd);
			miocack(qp, mp, 0, 0);
			return;
		case ZC_RELEASESLAVE:
			/*
			 * Release the master's handle on the slave's vnode.
			 * If there isn't a handle for the vnode, then indicate
			 * success.
			 */
			if (iocbp->ioc_count != TRANSPARENT) {
				miocack(qp, mp, 0, EINVAL);
				return;
			}
			if (zcs->zc_slave_vnode == NULL) {
				miocack(qp, mp, 0, 0);
				return;
			}

			/*
			 * The process that passed the ioctl must be running in
			 * the global zone.
			 */
			if (curzone != global_zone) {
				miocack(qp, mp, 0, EINVAL);
				return;
			}

			/*
			 * The process that passed the ioctl must have provided
			 * a file descriptor for the slave device.  Make sure
			 * this is correct.
			 */
			slave_fd =
			    (int)(intptr_t)*(caddr_t *)(void *)mp->b_cont->
			    b_rptr;
			slave_filep = getf(slave_fd);
			if (slave_filep == NULL) {
				miocack(qp, mp, 0, EINVAL);
				return;
			}
			if (zcs->zc_slave_vnode->v_rdev !=
			    slave_filep->f_vnode->v_rdev) {
				releasef(slave_fd);
				miocack(qp, mp, 0, EINVAL);
				return;
			}

			/*
			 * Decrement the snode's reference count and release the
			 * vnode.
			 */
			ASSERT(vn_matchops(slave_filep->f_vnode,
			    spec_getvnodeops()));
			slave_snodep = VTOCS(zcs->zc_slave_vnode);
			mutex_enter(&slave_snodep->s_lock);
			--slave_snodep->s_count;
			mutex_exit(&slave_snodep->s_lock);
			VN_RELE(zcs->zc_slave_vnode);
			zcs->zc_slave_vnode = NULL;
			releasef(slave_fd);
			miocack(qp, mp, 0, 0);
			return;
		default:
			break;
		}
	}

	if (zc_switch(RD(qp)) == NULL) {
		DBG1("wput to %s side (no one listening)", zc_side(qp));
		switch (type) {
		case M_FLUSH:
			handle_mflush(qp, mp);
			break;
		case M_IOCTL:
			miocnak(qp, mp, 0, 0);
			break;
		default:
			freemsg(mp);
			break;
		}
		return;
	}

	if (type >= QPCTL) {
		DBG1("(hipri) wput, %s side", zc_side(qp));
		switch (type) {
		case M_READ:		/* supposedly from ldterm? */
			DBG("zc_wput: tossing M_READ\n");
			freemsg(mp);
			break;
		case M_FLUSH:
			handle_mflush(qp, mp);
			break;
		default:
			/*
			 * Put this to the other side.
			 */
			ASSERT(zc_switch(RD(qp)) != NULL);
			putnext(zc_switch(RD(qp)), mp);
			break;
		}
		DBG1("done (hipri) wput, %s side", zc_side(qp));
		return;
	}

	/*
	 * Only putnext if there isn't already something in the queue.
	 * otherwise things would wind up out of order.
	 */
	if (qp->q_first == NULL && bcanputnext(RD(zc_switch(qp)), mp->b_band)) {
		DBG("wput: putting message to other side\n");
		putnext(RD(zc_switch(qp)), mp);
	} else {
		DBG("wput: putting msg onto queue\n");
		(void) putq(qp, mp);
	}
	DBG1("done wput, %s side", zc_side(qp));
}
示例#30
0
/*ARGSUSED*/
static int
parseopen(
	  queue_t *q,
	  dev_t *dev,
	  int flag,
	  int sflag,
	  cred_t *credp
	  )
{
	register parsestream_t *parse;
	static int notice = 0;
  
	pprintf(DD_OPEN, "parse: OPEN - q=%x\n", q); 
  
	if (sflag != MODOPEN)
	{			/* open only for modules */
		pprintf(DD_OPEN, "parse: OPEN - FAILED - not MODOPEN\n"); 
		return EIO;
	}

	if (q->q_ptr != (caddr_t)NULL)
	{
		pprintf(DD_OPEN, "parse: OPEN - FAILED - EXCLUSIVE ONLY\n"); 
		return EBUSY;
	}

	q->q_ptr = (caddr_t)kmem_alloc(sizeof(parsestream_t), KM_SLEEP);
	if (q->q_ptr == (caddr_t)0)
	{
		return ENOMEM;
	}

	pprintf(DD_OPEN, "parse: OPEN - parse area q=%x, q->q_ptr=%x\n", q, q->q_ptr); 
	WR(q)->q_ptr = q->q_ptr;
	pprintf(DD_OPEN, "parse: OPEN - WQ parse area q=%x, q->q_ptr=%x\n", WR(q), WR(q)->q_ptr); 
  
	parse = (parsestream_t *) q->q_ptr;
	bzero((caddr_t)parse, sizeof(*parse));
	parse->parse_queue     = q;
	parse->parse_status    = PARSE_ENABLE;
	parse->parse_ppsclockev.tv.tv_sec  = 0;
	parse->parse_ppsclockev.tv.tv_usec = 0;
	parse->parse_ppsclockev.serial     = 0;

	qprocson(q);

	pprintf(DD_OPEN, "parse: OPEN - initializing io subsystem q=%x\n", q); 

	if (!parse_ioinit(&parse->parse_io))
	{
		/*
		 * ok guys - beat it
		 */
		qprocsoff(q);

		kmem_free((caddr_t)parse, sizeof(parsestream_t));

		return EIO;
	}

	pprintf(DD_OPEN, "parse: OPEN - initializing stream q=%x\n", q); 

	if (setup_stream(q, M_PARSE))
	{
		(void) init_linemon(q);	/* hook up PPS ISR routines if possible */
		pprintf(DD_OPEN, "parse: OPEN - SUCCEEDED\n"); 

		/*
		 * I know that you know the delete key, but you didn't write this
		 * code, did you ? - So, keep the message in here.
		 */
		if (!notice)
		{
		  cmn_err(CE_CONT, "?%s: Copyright (c) 1993-2005, Frank Kardel\n", modlstrmod.strmod_linkinfo);
			notice = 1;
		}

		return 0;
	}
	else
	{
		qprocsoff(q);

		kmem_free((caddr_t)parse, sizeof(parsestream_t));

		return EIO;
	}
}