'\"macro stdmacro
.if n .pH ddi_dki.copyout @(#)copyout	40.6 of 10/10/89
.\" Copyright 1989 AT&T
.de IX
.ie '\\n(.z'' .tm .Index: \\$1 \\$2 \\$3 \\$4 \\$5 \\$6 \\$7 \\$8 \\$9	\\n%
.el \\!.IX \\$1 \\$2 \\$3 \\$4 \\$5 \\$6 \\$7 \\$8 \\$9
..
.nr X
.if \nX=0 .ds x} copyout D3DK "" "DDI/DKI" "\&"
.if \nX=1 .ds x} copyout D3DK "" "DDI/DKI"
.if \nX=2 .ds x} copyout D3DK "" "\&"
.if \nX=3 .ds x} copyout "" "" "\&"
.TH \*(x}
.IX "\f4copyout\fP(D3DK)"
.SH NAME
\f4copyout\f1 \- copy data from a driver to a user program
.SH SYNOPSIS
.nf
.na
\f4#include <sys/types.h>
.sp 0.5
int copyout(caddr_t \f2driverbuf, \f4caddr_t \f2userbuf, \f4long\f2 cn\f4);\f1
.ad
.fi
.SH ARGUMENTS
.RS 0n 13
.IP "\f2driverbuf\f1" 10n
Source address in the driver from which the data is transferred.
.IP "\f2userbuf\f1" 10n
Destination address in the user program to which the data is
transferred.
.IP "\f2cn\f1" 10n
Number of bytes moved.
.RE
.SH DESCRIPTION
.IX "\f4read\fP(D2DK)"
.IX "\f4write\fP(D2DK)"
\f4copyout\f1 copies data from driver buffers to user data
space.
.P
Addresses that are word-aligned are moved most efficiently.  However, the
driver developer is not obligated to ensure alignment.  This function
automatically finds the most efficient move algorithm according to address
alignment.
.SH RETURN VALUE
Under normal conditions a \f40\f1 is returned to indicate a successful
copy.  Otherwise, a \f4-1\f1 is returned if the specified address
range is not valid.
.P
If a \f4-1\f1 is returned, return \f4EFAULT\f1.
.SH LEVEL
Base Only  (Do not call from an interrupt routine)
.SH SEE ALSO
\f2BCI Driver Development Guide\f1, Chapter 6, ``Input/Output Operations''
.P
.na
\f4bcopy\f1(D3DK),
\f4uiomove\f1(D3DK),
\f4copyin\f1(D3DK)
.ad
.SH EXAMPLE
.IX "\f4copyout\fP(D3DK), example"
.IX "\f4ioctl\fP(D2DK), example"
.P
A driver \f4ioctl\f1(D2DK) routine (line 9)
can be used to get or set device attributes or registers.  In the
\f4XX_GETREGS\f1 condition (line 17), the driver copies the current device
register values to a user data area (line 18).  If the specified argument
contains an invalid address, an error code is returned.
.ne 4
.P
.nf
.ft 4
.ps 7
 1  struct  device  {      /* layout of physical device registers  */
 2          int      control;     /* physical device control word  */
 3          int      status;      /* physical device status word   */
 4          short    recv_char;   /* receive character from device */
 5          short    xmit_char;   /* transmit character to device  */
 6  }; /* end device */
 7
 8  extern struct device xx_addr[]; /* phys. device regs. location */
      . . .
 9  xx_ioctl(dev, cmd, arg, flag)
10          dev_t   dev;
11          caddr_t arg;
12               ...
13  {
14      register struct device *rp = &xx_addr[getminor(dev) >> 4];
15      switch(cmd)  {
16      
17       case XX_GETREGS:     /* copy device regs. to user program */
18            if (copyout((caddr_t)rp, arg, sizeof(struct device)) 
19                return(EFAULT);
20                /* endif */
21            break;
.ps
.ft 1
.fi
.P
.FG "copyout \- copy data from a buffer to a user program"
