xref: /onnv-gate/usr/src/uts/common/io/sundlpi.c (revision 5102:b6ea1a119e46)
10Sstevel@tonic-gate /*
20Sstevel@tonic-gate  * CDDL HEADER START
30Sstevel@tonic-gate  *
40Sstevel@tonic-gate  * The contents of this file are subject to the terms of the
5*5102Syz147064  * Common Development and Distribution License (the "License").
6*5102Syz147064  * You may not use this file except in compliance with the License.
70Sstevel@tonic-gate  *
80Sstevel@tonic-gate  * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
90Sstevel@tonic-gate  * or http://www.opensolaris.org/os/licensing.
100Sstevel@tonic-gate  * See the License for the specific language governing permissions
110Sstevel@tonic-gate  * and limitations under the License.
120Sstevel@tonic-gate  *
130Sstevel@tonic-gate  * When distributing Covered Code, include this CDDL HEADER in each
140Sstevel@tonic-gate  * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
150Sstevel@tonic-gate  * If applicable, add the following below this CDDL HEADER, with the
160Sstevel@tonic-gate  * fields enclosed by brackets "[]" replaced with your own identifying
170Sstevel@tonic-gate  * information: Portions Copyright [yyyy] [name of copyright owner]
180Sstevel@tonic-gate  *
190Sstevel@tonic-gate  * CDDL HEADER END
200Sstevel@tonic-gate  */
210Sstevel@tonic-gate /*
22*5102Syz147064  * Copyright 2007 Sun Microsystems, Inc.  All rights reserved.
230Sstevel@tonic-gate  * Use is subject to license terms.
240Sstevel@tonic-gate  */
250Sstevel@tonic-gate 
260Sstevel@tonic-gate #pragma ident	"%Z%%M%	%I%	%E% SMI"
270Sstevel@tonic-gate 
280Sstevel@tonic-gate /*
290Sstevel@tonic-gate  *  Common Sun DLPI routines.
300Sstevel@tonic-gate  */
310Sstevel@tonic-gate 
320Sstevel@tonic-gate #include	<sys/types.h>
330Sstevel@tonic-gate #include	<sys/sysmacros.h>
340Sstevel@tonic-gate #include	<sys/byteorder.h>
350Sstevel@tonic-gate #include	<sys/systm.h>
360Sstevel@tonic-gate #include	<sys/stream.h>
370Sstevel@tonic-gate #include	<sys/strsun.h>
380Sstevel@tonic-gate #include	<sys/dlpi.h>
390Sstevel@tonic-gate 
400Sstevel@tonic-gate #define		DLADDRL		(80)
410Sstevel@tonic-gate 
420Sstevel@tonic-gate void
430Sstevel@tonic-gate dlbindack(
440Sstevel@tonic-gate 	queue_t		*wq,
450Sstevel@tonic-gate 	mblk_t		*mp,
460Sstevel@tonic-gate 	t_scalar_t	sap,
470Sstevel@tonic-gate 	void		*addrp,
480Sstevel@tonic-gate 	t_uscalar_t	addrlen,
490Sstevel@tonic-gate 	t_uscalar_t	maxconind,
500Sstevel@tonic-gate 	t_uscalar_t	xidtest)
510Sstevel@tonic-gate {
520Sstevel@tonic-gate 	union DL_primitives	*dlp;
530Sstevel@tonic-gate 	size_t			size;
540Sstevel@tonic-gate 
550Sstevel@tonic-gate 	size = sizeof (dl_bind_ack_t) + addrlen;
560Sstevel@tonic-gate 	if ((mp = mexchange(wq, mp, size, M_PCPROTO, DL_BIND_ACK)) == NULL)
570Sstevel@tonic-gate 		return;
580Sstevel@tonic-gate 
590Sstevel@tonic-gate 	dlp = (union DL_primitives *)mp->b_rptr;
600Sstevel@tonic-gate 	dlp->bind_ack.dl_sap = sap;
610Sstevel@tonic-gate 	dlp->bind_ack.dl_addr_length = addrlen;
620Sstevel@tonic-gate 	dlp->bind_ack.dl_addr_offset = sizeof (dl_bind_ack_t);
630Sstevel@tonic-gate 	dlp->bind_ack.dl_max_conind = maxconind;
640Sstevel@tonic-gate 	dlp->bind_ack.dl_xidtest_flg = xidtest;
650Sstevel@tonic-gate 	if (addrlen != 0)
660Sstevel@tonic-gate 		bcopy(addrp, mp->b_rptr + sizeof (dl_bind_ack_t), addrlen);
670Sstevel@tonic-gate 
680Sstevel@tonic-gate 	qreply(wq, mp);
690Sstevel@tonic-gate }
700Sstevel@tonic-gate 
710Sstevel@tonic-gate void
720Sstevel@tonic-gate dlokack(
730Sstevel@tonic-gate 	queue_t		*wq,
740Sstevel@tonic-gate 	mblk_t		*mp,
750Sstevel@tonic-gate 	t_uscalar_t	correct_primitive)
760Sstevel@tonic-gate {
770Sstevel@tonic-gate 	union DL_primitives	*dlp;
780Sstevel@tonic-gate 
790Sstevel@tonic-gate 	if ((mp = mexchange(wq, mp, sizeof (dl_ok_ack_t), M_PCPROTO,
800Sstevel@tonic-gate 	    DL_OK_ACK)) == NULL)
810Sstevel@tonic-gate 		return;
820Sstevel@tonic-gate 	dlp = (union DL_primitives *)mp->b_rptr;
830Sstevel@tonic-gate 	dlp->ok_ack.dl_correct_primitive = correct_primitive;
840Sstevel@tonic-gate 	qreply(wq, mp);
850Sstevel@tonic-gate }
860Sstevel@tonic-gate 
870Sstevel@tonic-gate void
880Sstevel@tonic-gate dlerrorack(
890Sstevel@tonic-gate 	queue_t		*wq,
900Sstevel@tonic-gate 	mblk_t		*mp,
910Sstevel@tonic-gate 	t_uscalar_t	error_primitive,
920Sstevel@tonic-gate 	t_uscalar_t	error,
930Sstevel@tonic-gate 	t_uscalar_t	unix_errno)
940Sstevel@tonic-gate {
950Sstevel@tonic-gate 	union DL_primitives	*dlp;
960Sstevel@tonic-gate 
970Sstevel@tonic-gate 	if ((mp = mexchange(wq, mp, sizeof (dl_error_ack_t), M_PCPROTO,
980Sstevel@tonic-gate 	    DL_ERROR_ACK)) == NULL)
990Sstevel@tonic-gate 		return;
1000Sstevel@tonic-gate 	dlp = (union DL_primitives *)mp->b_rptr;
1010Sstevel@tonic-gate 	dlp->error_ack.dl_error_primitive = error_primitive;
1020Sstevel@tonic-gate 	dlp->error_ack.dl_errno = error;
1030Sstevel@tonic-gate 	dlp->error_ack.dl_unix_errno = unix_errno;
1040Sstevel@tonic-gate 	qreply(wq, mp);
1050Sstevel@tonic-gate }
1060Sstevel@tonic-gate 
1070Sstevel@tonic-gate void
1080Sstevel@tonic-gate dluderrorind(
1090Sstevel@tonic-gate 	queue_t		*wq,
1100Sstevel@tonic-gate 	mblk_t		*mp,
1110Sstevel@tonic-gate 	void		*addrp,
1120Sstevel@tonic-gate 	t_uscalar_t	addrlen,
1130Sstevel@tonic-gate 	t_uscalar_t	error,
1140Sstevel@tonic-gate 	t_uscalar_t	unix_errno)
1150Sstevel@tonic-gate {
1160Sstevel@tonic-gate 	union DL_primitives	*dlp;
1170Sstevel@tonic-gate 	char			buf[DLADDRL];
1180Sstevel@tonic-gate 	size_t			size;
1190Sstevel@tonic-gate 
1200Sstevel@tonic-gate 	if (addrlen > DLADDRL)
1210Sstevel@tonic-gate 		addrlen = DLADDRL;
1220Sstevel@tonic-gate 
1230Sstevel@tonic-gate 	bcopy(addrp, buf, addrlen);
1240Sstevel@tonic-gate 
1250Sstevel@tonic-gate 	size = sizeof (dl_uderror_ind_t) + addrlen;
1260Sstevel@tonic-gate 
1270Sstevel@tonic-gate 	if ((mp = mexchange(wq, mp, size, M_PCPROTO, DL_UDERROR_IND)) == NULL)
1280Sstevel@tonic-gate 		return;
1290Sstevel@tonic-gate 
1300Sstevel@tonic-gate 	dlp = (union DL_primitives *)mp->b_rptr;
1310Sstevel@tonic-gate 	dlp->uderror_ind.dl_dest_addr_length = addrlen;
1320Sstevel@tonic-gate 	dlp->uderror_ind.dl_dest_addr_offset = sizeof (dl_uderror_ind_t);
1330Sstevel@tonic-gate 	dlp->uderror_ind.dl_unix_errno = unix_errno;
1340Sstevel@tonic-gate 	dlp->uderror_ind.dl_errno = error;
1350Sstevel@tonic-gate 	bcopy((caddr_t)buf,
136*5102Syz147064 	    (caddr_t)(mp->b_rptr + sizeof (dl_uderror_ind_t)), addrlen);
1370Sstevel@tonic-gate 	qreply(wq, mp);
1380Sstevel@tonic-gate }
1390Sstevel@tonic-gate 
1400Sstevel@tonic-gate void
1410Sstevel@tonic-gate dlphysaddrack(
1420Sstevel@tonic-gate 	queue_t		*wq,
1430Sstevel@tonic-gate 	mblk_t		*mp,
1440Sstevel@tonic-gate 	void		*addrp,
1450Sstevel@tonic-gate 	t_uscalar_t	len)
1460Sstevel@tonic-gate {
1470Sstevel@tonic-gate 	union DL_primitives	*dlp;
1480Sstevel@tonic-gate 	size_t			size;
1490Sstevel@tonic-gate 
1500Sstevel@tonic-gate 	size = sizeof (dl_phys_addr_ack_t) + len;
1510Sstevel@tonic-gate 	if ((mp = mexchange(wq, mp, size, M_PCPROTO, DL_PHYS_ADDR_ACK)) == NULL)
1520Sstevel@tonic-gate 		return;
1530Sstevel@tonic-gate 	dlp = (union DL_primitives *)mp->b_rptr;
1540Sstevel@tonic-gate 	dlp->physaddr_ack.dl_addr_length = len;
1550Sstevel@tonic-gate 	dlp->physaddr_ack.dl_addr_offset = sizeof (dl_phys_addr_ack_t);
1560Sstevel@tonic-gate 	if (len != 0)
1570Sstevel@tonic-gate 		bcopy(addrp, mp->b_rptr + sizeof (dl_phys_addr_ack_t), len);
1580Sstevel@tonic-gate 	qreply(wq, mp);
1590Sstevel@tonic-gate }
1600Sstevel@tonic-gate 
1610Sstevel@tonic-gate void
1620Sstevel@tonic-gate dlcapabsetqid(dl_mid_t *idp, const queue_t *q)
1630Sstevel@tonic-gate {
1640Sstevel@tonic-gate #ifndef _LP64
1650Sstevel@tonic-gate 	idp->mid[0] = (t_uscalar_t)q;
1660Sstevel@tonic-gate #else
1670Sstevel@tonic-gate 	idp->mid[0] = (t_uscalar_t)BMASK_32((uint64_t)q);
1680Sstevel@tonic-gate 	idp->mid[1] = (t_uscalar_t)BMASK_32(((uint64_t)q) >> 32);
1690Sstevel@tonic-gate #endif
1700Sstevel@tonic-gate }
1710Sstevel@tonic-gate 
1720Sstevel@tonic-gate boolean_t
1730Sstevel@tonic-gate dlcapabcheckqid(const dl_mid_t *idp, const queue_t *q)
1740Sstevel@tonic-gate {
1750Sstevel@tonic-gate #ifndef _LP64
1760Sstevel@tonic-gate 	return ((queue_t *)(idp->mid[0]) == q);
1770Sstevel@tonic-gate #else
1780Sstevel@tonic-gate 	return ((queue_t *)
1790Sstevel@tonic-gate 	    ((uint64_t)idp->mid[0] | ((uint64_t)idp->mid[1] << 32)) == q);
1800Sstevel@tonic-gate #endif
1810Sstevel@tonic-gate }
1820Sstevel@tonic-gate 
1830Sstevel@tonic-gate void
1840Sstevel@tonic-gate dlnotifyack(
1850Sstevel@tonic-gate 	queue_t		*wq,
1860Sstevel@tonic-gate 	mblk_t		*mp,
1870Sstevel@tonic-gate 	uint32_t	notifications)
1880Sstevel@tonic-gate {
1890Sstevel@tonic-gate 	union DL_primitives	*dlp;
1900Sstevel@tonic-gate 
191*5102Syz147064 	if ((mp = mexchange(wq, mp, sizeof (dl_notify_ack_t), M_PROTO,
1920Sstevel@tonic-gate 	    DL_NOTIFY_ACK)) == NULL)
1930Sstevel@tonic-gate 		return;
1940Sstevel@tonic-gate 	dlp = (union DL_primitives *)mp->b_rptr;
1950Sstevel@tonic-gate 	dlp->notify_ack.dl_notifications = notifications;
1960Sstevel@tonic-gate 	qreply(wq, mp);
1970Sstevel@tonic-gate }
198