usr/src/uts/common/io/strsun.c
author masputra
Sat, 22 Oct 2005 22:50:14 -0700
changeset 741 40027a3621ac
parent 0 68f95e015346
child 898 64b2a371a6bd
permissions -rw-r--r--
PSARC 2005/082 Yosemite: UDP Performance Enhancement 4796051 Solaris needs a more complete HW checksumming support 4905227 duplicate macros in ipclassifier.h and ip.h 4915681 need hardware checksum offload for the case of IP/UDP reassembly 6201076 outbound flow-control dysfunctional, ip to ce using mdt 6223331 ipv6 flow control may corrupt UDP packets 6223809 16-bit aligned IP header should be allowed for all x86 platforms 6275398 Galaxy hangs when running lmbench 6281836 Yosemite project integration into Solaris 6281885 xge needs to support IPv6 checksum offload 6282776 IPv6 NCE fast path is not created for incoming solicitation 6304890 IP transmit-side checksum logic needs to be tightened 6304902 IP6_IN_NOCKSUM is obsolete and should be torched 6304904 UDP should reject TI_GETPEERNAME for non-connected endpoint 6306768 IP and UDP device and module definitions need to be centralized
Ignore whitespace changes - Everywhere: Within whitespace: At end of lines:
0
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
     1
/*
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
     2
 * CDDL HEADER START
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
     3
 *
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
     4
 * The contents of this file are subject to the terms of the
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
     5
 * Common Development and Distribution License, Version 1.0 only
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
     6
 * (the "License").  You may not use this file except in compliance
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
     7
 * with the License.
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
     8
 *
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
     9
 * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
    10
 * or http://www.opensolaris.org/os/licensing.
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
    11
 * See the License for the specific language governing permissions
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
    12
 * and limitations under the License.
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
    13
 *
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
    14
 * When distributing Covered Code, include this CDDL HEADER in each
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
    15
 * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
    16
 * If applicable, add the following below this CDDL HEADER, with the
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
    17
 * fields enclosed by brackets "[]" replaced with your own identifying
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
    18
 * information: Portions Copyright [yyyy] [name of copyright owner]
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
    19
 *
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
    20
 * CDDL HEADER END
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
    21
 */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
    22
/*
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
    23
 * Copyright 2005 Sun Microsystems, Inc.  All rights reserved.
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
    24
 * Use is subject to license terms.
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
    25
 */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
    26
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
    27
#pragma ident	"%Z%%M%	%I%	%E% SMI"
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
    28
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
    29
/*
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
    30
 * Solaris DDI STREAMS utility routines (PSARC/2003/648).
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
    31
 *
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
    32
 * Please see the appropriate section 9F manpage for documentation.
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
    33
 */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
    34
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
    35
#include <sys/types.h>
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
    36
#include <sys/systm.h>
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
    37
#include <sys/errno.h>
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
    38
#include <sys/stream.h>
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
    39
#include <sys/stropts.h>
741
40027a3621ac PSARC 2005/082 Yosemite: UDP Performance Enhancement
masputra
parents: 0
diff changeset
    40
#include <sys/strsubr.h>
0
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
    41
#include <sys/strsun.h>
741
40027a3621ac PSARC 2005/082 Yosemite: UDP Performance Enhancement
masputra
parents: 0
diff changeset
    42
#include <sys/sysmacros.h>
0
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
    43
#include <sys/cmn_err.h>
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
    44
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
    45
void
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
    46
merror(queue_t *wq, mblk_t *mp, int error)
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
    47
{
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
    48
	if ((mp = mexchange(wq, mp, 1, M_ERROR, -1)) == NULL)
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
    49
		return;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
    50
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
    51
	*mp->b_rptr = (uchar_t)error;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
    52
	qreply(wq, mp);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
    53
}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
    54
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
    55
void
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
    56
mioc2ack(mblk_t *mp, mblk_t *dp, size_t count, int rval)
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
    57
{
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
    58
	struct iocblk *iocp = (struct iocblk *)mp->b_rptr;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
    59
	mblk_t *odp = mp->b_cont;  	/* allows freemsg() to be a tail call */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
    60
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
    61
	DB_TYPE(mp) = M_IOCACK;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
    62
	iocp->ioc_count = count;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
    63
	iocp->ioc_error = 0;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
    64
	iocp->ioc_rval = rval;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
    65
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
    66
	mp->b_cont = dp;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
    67
	if (dp != NULL)
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
    68
		dp->b_wptr = dp->b_rptr + count;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
    69
	freemsg(odp);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
    70
}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
    71
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
    72
void
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
    73
miocack(queue_t *wq, mblk_t *mp, int count, int rval)
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
    74
{
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
    75
	struct iocblk *iocp = (struct iocblk *)mp->b_rptr;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
    76
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
    77
	DB_TYPE(mp) = M_IOCACK;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
    78
	iocp->ioc_count = count;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
    79
	iocp->ioc_error = 0;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
    80
	iocp->ioc_rval = rval;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
    81
	qreply(wq, mp);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
    82
}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
    83
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
    84
void
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
    85
miocnak(queue_t *wq, mblk_t *mp, int count, int error)
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
    86
{
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
    87
	struct iocblk *iocp = (struct iocblk *)mp->b_rptr;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
    88
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
    89
	DB_TYPE(mp) = M_IOCNAK;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
    90
	iocp->ioc_count = count;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
    91
	iocp->ioc_error = error;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
    92
	qreply(wq, mp);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
    93
}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
    94
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
    95
mblk_t *
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
    96
mexchange(queue_t *wq, mblk_t *mp, size_t size, uchar_t type, int32_t primtype)
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
    97
{
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
    98
	if (mp == NULL || MBLKSIZE(mp) < size || DB_REF(mp) > 1) {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
    99
		freemsg(mp);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   100
		if ((mp = allocb(size, BPRI_LO)) == NULL) {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   101
			if (wq != NULL) {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   102
				if ((mp = allocb(1, BPRI_HI)) != NULL)
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   103
					merror(wq, mp, ENOSR);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   104
			}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   105
			return (NULL);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   106
		}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   107
	}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   108
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   109
	DB_TYPE(mp) = type;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   110
	mp->b_rptr = DB_BASE(mp);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   111
	mp->b_wptr = mp->b_rptr + size;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   112
	if (primtype >= 0)
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   113
		*(int32_t *)mp->b_rptr = primtype;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   114
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   115
	return (mp);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   116
}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   117
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   118
size_t
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   119
msgsize(mblk_t *mp)
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   120
{
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   121
	size_t	n = 0;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   122
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   123
	for (; mp != NULL; mp = mp->b_cont)
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   124
		n += MBLKL(mp);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   125
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   126
	return (n);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   127
}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   128
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   129
void
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   130
mcopymsg(mblk_t *mp, void *bufp)
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   131
{
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   132
	caddr_t	dest = bufp;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   133
	mblk_t	*bp;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   134
	size_t	n;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   135
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   136
	for (bp = mp; bp != NULL; bp = bp->b_cont) {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   137
		n = MBLKL(bp);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   138
		bcopy(bp->b_rptr, dest, n);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   139
		dest += n;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   140
	}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   141
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   142
	freemsg(mp);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   143
}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   144
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   145
void
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   146
mcopyin(mblk_t *mp, void *private, size_t size, void *useraddr)
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   147
{
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   148
	struct copyreq *cp = (struct copyreq *)mp->b_rptr;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   149
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   150
	if (useraddr != NULL) {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   151
		cp->cq_addr = (caddr_t)useraddr;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   152
	} else {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   153
		ASSERT(DB_TYPE(mp) == M_IOCTL);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   154
		ASSERT(mp->b_cont != NULL);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   155
		ASSERT(((struct iocblk *)mp->b_rptr)->ioc_count == TRANSPARENT);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   156
		cp->cq_addr = (caddr_t)*(uintptr_t *)mp->b_cont->b_rptr;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   157
	}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   158
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   159
	cp->cq_flag = 0;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   160
	cp->cq_size = size;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   161
	cp->cq_private = (mblk_t *)private;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   162
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   163
	DB_TYPE(mp) = M_COPYIN;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   164
	mp->b_wptr = mp->b_rptr + sizeof (struct copyreq);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   165
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   166
	if (mp->b_cont != NULL) {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   167
		freemsg(mp->b_cont);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   168
		mp->b_cont = NULL;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   169
	}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   170
}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   171
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   172
void
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   173
mcopyout(mblk_t *mp, void *private, size_t size, void *useraddr, mblk_t *dp)
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   174
{
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   175
	struct copyreq *cp = (struct copyreq *)mp->b_rptr;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   176
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   177
	if (useraddr != NULL)
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   178
		cp->cq_addr = (caddr_t)useraddr;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   179
	else {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   180
		ASSERT(DB_TYPE(mp) == M_IOCTL);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   181
		ASSERT(mp->b_cont != NULL);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   182
		ASSERT(((struct iocblk *)mp->b_rptr)->ioc_count == TRANSPARENT);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   183
		cp->cq_addr = (caddr_t)*(uintptr_t *)mp->b_cont->b_rptr;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   184
	}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   185
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   186
	cp->cq_flag = 0;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   187
	cp->cq_size = size;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   188
	cp->cq_private = (mblk_t *)private;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   189
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   190
	DB_TYPE(mp) = M_COPYOUT;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   191
	mp->b_wptr = mp->b_rptr + sizeof (struct copyreq);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   192
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   193
	if (dp != NULL) {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   194
		if (mp->b_cont != NULL)
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   195
			freemsg(mp->b_cont);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   196
		mp->b_cont = dp;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   197
		mp->b_cont->b_wptr = mp->b_cont->b_rptr + size;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   198
	}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   199
}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   200
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   201
int
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   202
miocpullup(mblk_t *iocmp, size_t size)
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   203
{
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   204
	struct iocblk	*iocp = (struct iocblk *)iocmp->b_rptr;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   205
	mblk_t		*datamp = iocmp->b_cont;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   206
	mblk_t		*newdatamp;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   207
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   208
	/*
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   209
	 * We'd like to be sure that DB_TYPE(iocmp) == M_IOCTL, but some
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   210
	 * nitwit routines like ttycommon_ioctl() always reset the type of
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   211
	 * legitimate M_IOCTL messages to M_IOCACK as a "courtesy" to the
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   212
	 * caller, even when the routine does not understand the M_IOCTL.
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   213
	 * The ttycommon_ioctl() routine does us the additional favor of
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   214
	 * clearing ioc_count, so we cannot rely on it having a correct
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   215
	 * size either (blissfully, ttycommon_ioctl() does not screw with
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   216
	 * TRANSPARENT messages, so we can still sanity check for that).
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   217
	 */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   218
	ASSERT(MBLKL(iocmp) == sizeof (struct iocblk));
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   219
	if (MBLKL(iocmp) != sizeof (struct iocblk)) {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   220
		cmn_err(CE_WARN, "miocpullup: passed mblk_t %p is not an ioctl"
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   221
		    " mblk_t", (void *)iocmp);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   222
		return (EINVAL);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   223
	}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   224
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   225
	if (iocp->ioc_count == TRANSPARENT)
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   226
		return (EINVAL);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   227
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   228
	if (size == 0)
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   229
		return (0);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   230
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   231
	if (datamp == NULL)
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   232
		return (EINVAL);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   233
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   234
	if (MBLKL(datamp) >= size)
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   235
		return (0);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   236
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   237
	newdatamp = msgpullup(datamp, size);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   238
	if (newdatamp == NULL) {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   239
		if (msgdsize(datamp) < size)
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   240
			return (EINVAL);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   241
		return (ENOMEM);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   242
	}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   243
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   244
	iocmp->b_cont = newdatamp;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   245
	freemsg(datamp);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   246
	return (0);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   247
}
741
40027a3621ac PSARC 2005/082 Yosemite: UDP Performance Enhancement
masputra
parents: 0
diff changeset
   248
40027a3621ac PSARC 2005/082 Yosemite: UDP Performance Enhancement
masputra
parents: 0
diff changeset
   249
/* Copy userdata into a new mblk_t */
40027a3621ac PSARC 2005/082 Yosemite: UDP Performance Enhancement
masputra
parents: 0
diff changeset
   250
mblk_t *
40027a3621ac PSARC 2005/082 Yosemite: UDP Performance Enhancement
masputra
parents: 0
diff changeset
   251
mcopyinuio(struct stdata *stp, uio_t *uiop, ssize_t iosize,
40027a3621ac PSARC 2005/082 Yosemite: UDP Performance Enhancement
masputra
parents: 0
diff changeset
   252
    ssize_t maxblk, int *errorp)
40027a3621ac PSARC 2005/082 Yosemite: UDP Performance Enhancement
masputra
parents: 0
diff changeset
   253
{
40027a3621ac PSARC 2005/082 Yosemite: UDP Performance Enhancement
masputra
parents: 0
diff changeset
   254
	mblk_t	*head = NULL, **tail = &head;
40027a3621ac PSARC 2005/082 Yosemite: UDP Performance Enhancement
masputra
parents: 0
diff changeset
   255
	size_t	offset = stp->sd_wroff;
40027a3621ac PSARC 2005/082 Yosemite: UDP Performance Enhancement
masputra
parents: 0
diff changeset
   256
40027a3621ac PSARC 2005/082 Yosemite: UDP Performance Enhancement
masputra
parents: 0
diff changeset
   257
	if (iosize == INFPSZ || iosize > uiop->uio_resid)
40027a3621ac PSARC 2005/082 Yosemite: UDP Performance Enhancement
masputra
parents: 0
diff changeset
   258
		iosize = uiop->uio_resid;
40027a3621ac PSARC 2005/082 Yosemite: UDP Performance Enhancement
masputra
parents: 0
diff changeset
   259
40027a3621ac PSARC 2005/082 Yosemite: UDP Performance Enhancement
masputra
parents: 0
diff changeset
   260
	if (maxblk == INFPSZ)
40027a3621ac PSARC 2005/082 Yosemite: UDP Performance Enhancement
masputra
parents: 0
diff changeset
   261
		maxblk = iosize;
40027a3621ac PSARC 2005/082 Yosemite: UDP Performance Enhancement
masputra
parents: 0
diff changeset
   262
40027a3621ac PSARC 2005/082 Yosemite: UDP Performance Enhancement
masputra
parents: 0
diff changeset
   263
	/* Nothing to do in these cases, so we're done */
40027a3621ac PSARC 2005/082 Yosemite: UDP Performance Enhancement
masputra
parents: 0
diff changeset
   264
	if (iosize < 0 || maxblk < 0 || (maxblk == 0 && iosize > 0))
40027a3621ac PSARC 2005/082 Yosemite: UDP Performance Enhancement
masputra
parents: 0
diff changeset
   265
		goto done;
40027a3621ac PSARC 2005/082 Yosemite: UDP Performance Enhancement
masputra
parents: 0
diff changeset
   266
40027a3621ac PSARC 2005/082 Yosemite: UDP Performance Enhancement
masputra
parents: 0
diff changeset
   267
	if (stp->sd_flag & STRCOPYCACHED)
40027a3621ac PSARC 2005/082 Yosemite: UDP Performance Enhancement
masputra
parents: 0
diff changeset
   268
		uiop->uio_extflg |= UIO_COPY_CACHED;
40027a3621ac PSARC 2005/082 Yosemite: UDP Performance Enhancement
masputra
parents: 0
diff changeset
   269
40027a3621ac PSARC 2005/082 Yosemite: UDP Performance Enhancement
masputra
parents: 0
diff changeset
   270
	/*
40027a3621ac PSARC 2005/082 Yosemite: UDP Performance Enhancement
masputra
parents: 0
diff changeset
   271
	 * We will enter the loop below if iosize is 0; it will allocate an
40027a3621ac PSARC 2005/082 Yosemite: UDP Performance Enhancement
masputra
parents: 0
diff changeset
   272
	 * empty message block and call uiomove(9F) which will just return.
40027a3621ac PSARC 2005/082 Yosemite: UDP Performance Enhancement
masputra
parents: 0
diff changeset
   273
	 * We could avoid that with an extra check but would only slow
40027a3621ac PSARC 2005/082 Yosemite: UDP Performance Enhancement
masputra
parents: 0
diff changeset
   274
	 * down the much more likely case where iosize is larger than 0.
40027a3621ac PSARC 2005/082 Yosemite: UDP Performance Enhancement
masputra
parents: 0
diff changeset
   275
	 */
40027a3621ac PSARC 2005/082 Yosemite: UDP Performance Enhancement
masputra
parents: 0
diff changeset
   276
	do {
40027a3621ac PSARC 2005/082 Yosemite: UDP Performance Enhancement
masputra
parents: 0
diff changeset
   277
		ssize_t blocksize;
40027a3621ac PSARC 2005/082 Yosemite: UDP Performance Enhancement
masputra
parents: 0
diff changeset
   278
		mblk_t  *mp;
40027a3621ac PSARC 2005/082 Yosemite: UDP Performance Enhancement
masputra
parents: 0
diff changeset
   279
40027a3621ac PSARC 2005/082 Yosemite: UDP Performance Enhancement
masputra
parents: 0
diff changeset
   280
		blocksize = MIN(iosize, maxblk);
40027a3621ac PSARC 2005/082 Yosemite: UDP Performance Enhancement
masputra
parents: 0
diff changeset
   281
		ASSERT(blocksize >= 0);
40027a3621ac PSARC 2005/082 Yosemite: UDP Performance Enhancement
masputra
parents: 0
diff changeset
   282
		if ((mp = allocb_cred(offset + blocksize, CRED())) == NULL) {
40027a3621ac PSARC 2005/082 Yosemite: UDP Performance Enhancement
masputra
parents: 0
diff changeset
   283
			*errorp = ENOMEM;
40027a3621ac PSARC 2005/082 Yosemite: UDP Performance Enhancement
masputra
parents: 0
diff changeset
   284
			return (head);
40027a3621ac PSARC 2005/082 Yosemite: UDP Performance Enhancement
masputra
parents: 0
diff changeset
   285
		}
40027a3621ac PSARC 2005/082 Yosemite: UDP Performance Enhancement
masputra
parents: 0
diff changeset
   286
		mp->b_rptr += offset;
40027a3621ac PSARC 2005/082 Yosemite: UDP Performance Enhancement
masputra
parents: 0
diff changeset
   287
		mp->b_wptr = mp->b_rptr + blocksize;
40027a3621ac PSARC 2005/082 Yosemite: UDP Performance Enhancement
masputra
parents: 0
diff changeset
   288
		DB_CPID(mp) = curproc->p_pid;
40027a3621ac PSARC 2005/082 Yosemite: UDP Performance Enhancement
masputra
parents: 0
diff changeset
   289
40027a3621ac PSARC 2005/082 Yosemite: UDP Performance Enhancement
masputra
parents: 0
diff changeset
   290
		*tail = mp;
40027a3621ac PSARC 2005/082 Yosemite: UDP Performance Enhancement
masputra
parents: 0
diff changeset
   291
		tail = &mp->b_cont;
40027a3621ac PSARC 2005/082 Yosemite: UDP Performance Enhancement
masputra
parents: 0
diff changeset
   292
40027a3621ac PSARC 2005/082 Yosemite: UDP Performance Enhancement
masputra
parents: 0
diff changeset
   293
		/* uiomove(9F) either returns 0 or EFAULT */
40027a3621ac PSARC 2005/082 Yosemite: UDP Performance Enhancement
masputra
parents: 0
diff changeset
   294
		if ((*errorp = uiomove(mp->b_rptr, (size_t)blocksize,
40027a3621ac PSARC 2005/082 Yosemite: UDP Performance Enhancement
masputra
parents: 0
diff changeset
   295
		    UIO_WRITE, uiop)) != 0) {
40027a3621ac PSARC 2005/082 Yosemite: UDP Performance Enhancement
masputra
parents: 0
diff changeset
   296
			ASSERT(*errorp != ENOMEM);
40027a3621ac PSARC 2005/082 Yosemite: UDP Performance Enhancement
masputra
parents: 0
diff changeset
   297
			freemsg(head);
40027a3621ac PSARC 2005/082 Yosemite: UDP Performance Enhancement
masputra
parents: 0
diff changeset
   298
			return (NULL);
40027a3621ac PSARC 2005/082 Yosemite: UDP Performance Enhancement
masputra
parents: 0
diff changeset
   299
		}
40027a3621ac PSARC 2005/082 Yosemite: UDP Performance Enhancement
masputra
parents: 0
diff changeset
   300
40027a3621ac PSARC 2005/082 Yosemite: UDP Performance Enhancement
masputra
parents: 0
diff changeset
   301
		iosize -= blocksize;
40027a3621ac PSARC 2005/082 Yosemite: UDP Performance Enhancement
masputra
parents: 0
diff changeset
   302
	} while (iosize > 0);
40027a3621ac PSARC 2005/082 Yosemite: UDP Performance Enhancement
masputra
parents: 0
diff changeset
   303
40027a3621ac PSARC 2005/082 Yosemite: UDP Performance Enhancement
masputra
parents: 0
diff changeset
   304
done:
40027a3621ac PSARC 2005/082 Yosemite: UDP Performance Enhancement
masputra
parents: 0
diff changeset
   305
	*errorp = 0;
40027a3621ac PSARC 2005/082 Yosemite: UDP Performance Enhancement
masputra
parents: 0
diff changeset
   306
	return (head);
40027a3621ac PSARC 2005/082 Yosemite: UDP Performance Enhancement
masputra
parents: 0
diff changeset
   307
}