copyin(D3)copyin(D3)NAMEcopyin - copy data from a user buffer to a driver buffer
SYNOPSIS
#include <sys/types.h>
#include <sys/ddi.h>
int copyin(caddr_t userbuf, caddr_t driverbuf, size_t count);
Arguments
userbuf User source address from which copy is made.
driverbuf Driver destination address to which copy is made.
count Number of bytes to copy.
DESCRIPTIONcopyin copies count bytes of data from the user virtual address specified
by userbuf to the kernel virtual address specified by driverbuf.
Return Values
If the copy is successful, 0 is returned. Otherwise, -1 is returned to
indicate that the specified user address range is not valid.
USAGE
The driver must ensure that adequate space is allocated for the
destination address.
copyin chooses the best algorithm based on address alignment and number
of bytes to copy. Although the source and destination addresses are not
required to be word aligned, word aligned addresses may result in a more
efficient copy.
Drivers usually convert a return value of -1 into an EFAULT error.
Level
Base only.
Synchronization Constraints
Can sleep.
Driver-defined basic locks and read/write locks may not be held across
calls to this function.
Driver-defined sleep locks may be held across calls to this function.
Warnings
The driver source buffer must be completely within the kernel address
space, or the system can panic.
Page 1
copyin(D3)copyin(D3)
When holding sleep locks across calls to this function, multithreaded
drivers must be careful to avoid creating a deadlock. During the data
transfer, page fault resolution might result in another I/O to the same
device. For example, this could occur if the driver controls the disk
drive used as the swap device.
Examples
A driver ioctl(D2) routine (line 5) can be used to get or set device
attributes or registers. If the specified command is XX_SETREGS (line
9), the driver copies user data to the device registers (line 11). If
the user address is invalid, an error code is returned.
1 struct device { /* device registers layout */
...
2 int command; /* device command word */
3 };
4 extern struct device xx_dev[]; /* physical device registers */
...
5 xxioctl(dev_t dev, int cmd, void *arg, int mode, cred_t *crp, int *rvp)
6 {
7 struct device *dp;
8 switch (cmd) {
9 case XX_SETREGS: /* copy user program data to device registers */
10 dp = &xx_dev[getminor(dev)];
11 if (copyin(arg, (caddr_t)dp, sizeof(struct device)))
12 return (EFAULT);
13 break;
REFERENCESbcopy(D3), copyout(D3), uiomove(D3), ureadc(D3), uwritec(D3)
Page 2