COPYIN(9F) Kernel Functions for Drivers COPYIN(9F)


copyin - copy data from a user program to a driver buffer


#include <sys/types.h>
#include <sys/ddi.h>

int copyin(const void *userbuf, void *driverbuf, size_t cn);


This interface is obsolete. ddi_copyin(9F) should be used instead.


User program source address from which data is transferred.

Driver destination address to which data is transferred.

Number of bytes transferred.


copyin() copies data from a user program source address to a driver
buffer. The driver developer must ensure that adequate space is
allocated for the destination address.

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 according to address


Under normal conditions, a 0 is returned indicating a successful copy.
Otherwise, a -1 is returned if one of the following occurs:

o Paging fault; the driver tried to access a page of memory for
which it did not have read or write access.

o Invalid user address, such as a user area or stack area.

o Invalid address that would have resulted in data being copied
into the user block.

o Hardware fault; a hardware error prevented access to the
specified user memory. For example, an uncorrectable parity
or ECC error occurred.

If a -1 is returned to the caller, driver entry point routines should
return EFAULT.


copyin() can be called from user context only.


Example 1: An ioctl() Routine

A driver ioctl(9E) routine (line 10) can be used to get or set device
attributes or registers. In the XX_GETREGS 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.

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 };
8 extern struct device xx_addr[]; /* phys. device regs. location */
9 ...
10 xx_ioctl(dev_t dev, int cmd, int arg, int mode,
11 cred_t *cred_p, int *rval_p)
12 ...
13 {
14 register struct device *rp = &xx_addr[getminor(dev) >> 4];
15 switch (cmd) {
17 case XX_GETREGS: /* copy device regs. to user program */
18 if (copyin(arg, rp, sizeof(struct device)))
19 return(EFAULT);
20 break;
21 ...
22 }
23 ...
24 }


See attributes(7) for a description of the following attributes:

|Stability Level | Obsolete |


attributes(7), ioctl(9E), bcopy(9F), copyout(9F), ddi_copyin(9F),
ddi_copyout(9F), uiomove(9F)

Writing Device Drivers


Driver writers who intend to support layered ioctls in their ioctl(9E)
routines should use ddi_copyin(9F) instead.

Driver defined locks should not be held across calls to this function.

copyin() should not be used from a streams driver. See M_COPYIN and
M_COPYOUT in STREAMS Programming Guide.

illumos September 27, 2002 COPYIN(9F)