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