Пример #1
0
	{ "IF",		IF,	0 },
	{ "IMPLICIT",	IMPLICIT,	0 },
	{ "INTRINSIC",	INTRINSIC, 0 },
	{ "PROGRAM",	PROGRAM,	0 },
	{ "RETURN",	RETURN,	0 },
	{ "REWIND",	REWIND, 0 },
	{ "SAVE",	SAVE, 0 },
	{ "STOP",	STOP,	0 },
	{ "SUBROUTINE",	SUBROUTINE,	0 },
	{ "THEN",	THEN,	0 },
	NULL
};

/* type declarators */
kwdtab tab_type[] = {
	{ "DOUBLEPRECISION",	TYPE,	MTYPE(REAL, 8), },
	{ "REAL*8",	TYPE,	MTYPE(REAL, 8), },
	{ "REAL*4",	TYPE,	MTYPE(REAL, 4), },
	{ "REAL",	TYPE,	MTYPE(REAL, 4), },
	
	{ "INTEGER*4",	TYPE,	MTYPE(INTEGER, 4), },
	{ "INTEGER",	TYPE,	MTYPE(INTEGER, 4), },


	{ "LOGICAL*4",	TYPE,	MTYPE(LOGICAL, 4), },
	{ "LOGICAL",	TYPE,	MTYPE(LOGICAL, 4), },


	{ "DOUBLECOMPLEX",	TYPE,	MTYPE(COMPLEX, 16), },
	{ "COMPLEX*16",	TYPE,	MTYPE(COMPLEX, 16), },
	{ "COMPLEX*8",	TYPE,	MTYPE(COMPLEX, 8), },
Пример #2
0
/*
 * sppp_dlunitdatareq()
 *
 * MT-Perimeters:
 *    shared inner, shared outer.
 *
 * Description:
 *    Handle DL_UNITDATA_REQ request, called by sppp_mproto. This procedure
 *    gets called for M_PROTO (DLPI) style of transmission. The fact that we
 *    have acknowledged IP's fastpath probing (DL_IOC_HDR_INFO) does not
 *    guarantee that IP will always transmit via M_DATA, and it merely implies
 *    that such situation _may_ happen. In other words, IP may decide to use
 *    M_PROTO (DLPI) for data transmission should it decide to do so.
 *    Therefore, we should never place any restrictions or checks against
 *    streams marked with SPS_FASTPATH, since it is legal for this procedure
 *    to be entered with or without the bit set.
 */
static int
sppp_dlunitdatareq(queue_t *q, mblk_t *mp, spppstr_t *sps)
{
	sppa_t		*ppa;
	mblk_t		*hdrmp;
	mblk_t		*pktmp;
	dl_unitdata_req_t *dludp;
	int		dladdroff;
	int		dladdrlen;
	int		msize;
	int		error = 0;
	boolean_t	is_promisc;

	ASSERT(q != NULL && q->q_ptr != NULL);
	ASSERT(mp != NULL && mp->b_rptr != NULL);
	ASSERT((MTYPE(mp) == M_PCPROTO) || (MTYPE(mp) == M_PROTO));
	dludp = (dl_unitdata_req_t *)mp->b_rptr;
	dladdroff = dludp->dl_dest_addr_offset;
	dladdrlen = dludp->dl_dest_addr_length;
	ASSERT(sps != NULL);
	ASSERT(!IS_SPS_PIOATTACH(sps));
	ASSERT(sps->sps_dlstate == DL_IDLE);
	ASSERT(q->q_ptr == sps);
	/*
	 * If this stream is not attached to any ppas, then discard data
	 * coming down through this stream.
	 */
	ppa = sps->sps_ppa;
	if (ppa == NULL) {
		DBGERROR((CE_CONT, "DLPI unitdata: no attached ppa\n"));
		error = ENOLINK;
	} else if (mp->b_cont == NULL) {
		DBGERROR((CE_CONT, "DLPI unitdata: missing data\n"));
		error = EPROTO;
	}
	if (error != 0) {
		dluderrorind(q, mp, mp->b_rptr + dladdroff, dladdrlen,
		    DL_BADDATA, error);
		return (0);
	}
	ASSERT(mp->b_cont->b_rptr != NULL);
	/*
	 * Check if outgoing packet size is larger than allowed. We use
	 * msgdsize to count all of M_DATA blocks in the message.
	 */
	msize = msgdsize(mp);
	if (msize > ppa->ppa_mtu) {
		/* Log, and send it anyway */
		mutex_enter(&ppa->ppa_sta_lock);
		ppa->ppa_otoolongs++;
		mutex_exit(&ppa->ppa_sta_lock);
	}
	if (IS_SPS_KDEBUG(sps)) {
		SPDEBUG(PPP_DRV_NAME
		    "/%d: DL_UNITDATA_REQ (%d bytes) sps=0x%p flags=0x%b "
		    "ppa=0x%p flags=0x%b\n", sps->sps_mn_id, msize,
		    (void *)sps, sps->sps_flags, SPS_FLAGS_STR,
		    (void *)ppa, ppa->ppa_flags, PPA_FLAGS_STR);
	}
	/* Allocate a message (M_DATA) to contain PPP header bytes. */
	if ((hdrmp = allocb(PPP_HDRLEN, BPRI_MED)) == NULL) {
		mutex_enter(&ppa->ppa_sta_lock);
		ppa->ppa_allocbfail++;
		mutex_exit(&ppa->ppa_sta_lock);
		DBGERROR((CE_CONT,
		    "DLPI unitdata: can't allocate header buffer\n"));
		dluderrorind(q, mp, mp->b_rptr + dladdroff, dladdrlen,
		    DL_SYSERR, ENOSR);
		return (0);
	}
	/*
	 * Should there be any promiscuous stream(s), send the data up
	 * for each promiscuous stream that we recognize.
	 */
	rw_enter(&ppa->ppa_sib_lock, RW_READER);
	is_promisc = ppa->ppa_promicnt;
	if (is_promisc) {
		ASSERT(ppa->ppa_streams != NULL);
		sppp_dlprsendup(ppa->ppa_streams, mp->b_cont, sps->sps_sap,
		    B_FALSE);
	}
	rw_exit(&ppa->ppa_sib_lock);
	/* Discard DLPI header and keep only IP payload (mp->b_cont). */
	pktmp = mp->b_cont;
	mp->b_cont = NULL;
	freemsg(mp);
	mp = hdrmp;

	*(uchar_t *)mp->b_wptr++ = PPP_ALLSTATIONS;
	*(uchar_t *)mp->b_wptr++ = PPP_UI;
	*(uchar_t *)mp->b_wptr++ = ((uint16_t)sps->sps_sap >> 8) & 0xff;
	*(uchar_t *)mp->b_wptr++ = ((uint16_t)sps->sps_sap) & 0xff;
	ASSERT(MBLKL(mp) == PPP_HDRLEN);

	linkb(mp, pktmp);
	/*
	 * Only time-stamp the packet with hrtime if the upper stream
	 * is configured to do so.
	 */
	if (IS_PPA_TIMESTAMP(ppa)) {
		ppa->ppa_lasttx = gethrtime();
	}
	/*
	 * Just put this back on the queue and allow the write service
	 * routine to handle it.  We're nested too deeply here to
	 * rewind the stack sufficiently to prevent overflow.  This is
	 * the slow path anyway.
	 */
	if (putq(q, mp) == 0) {
		mutex_enter(&ppa->ppa_sta_lock);
		ppa->ppa_oqdropped++;
		mutex_exit(&ppa->ppa_sta_lock);
		freemsg(mp);
	} else {
		qenable(q);
	}
	return (0);
}