Annotation of coherent/f/etc/conf/streams/src/uio.c, revision 1.1.1.1

1.1       root        1: #define        _DDI_DKI        1
                      2: #define        _SYSV3          1
                      3: 
                      4: /*
                      5:  * Implementations of the functions which manipulate the uio(4) structure
                      6:  * under the DDI/DKI. This function runs in _SYSV3 mode to interface with
                      7:  * the iBCS2 Coherent kernel.
                      8:  */
                      9: /*
                     10:  *-IMPORTS:
                     11:  *     <common/ccompat.h>
                     12:  *             __CONST__
                     13:  *             __EXTERN_C_BEGIN__
                     14:  *             __EXTERN_C_END__
                     15:  *             __USE_PROTO__
                     16:  *             __ARGS ()
                     17:  *             __PROTO ()
                     18:  *     <sys/debug.h>
                     19:  *             ASSERT ()
                     20:  *     <sys/types.h>
                     21:  *             _VOID
                     22:  *             size_t
                     23:  *     <sys/errno.h>
                     24:  *             EFAULT
                     25:  *     <limits.h>
                     26:  *             CHAR_BIT
                     27:  *             UCHAR_MAX
                     28:  *     <string.h>
                     29:  *             memcpy ()
                     30:  */
                     31: 
                     32: #include <common/ccompat.h>
                     33: #include <sys/debug.h>
                     34: #include <sys/types.h>
                     35: #include <sys/errno.h>
                     36: #include <limits.h>
                     37: #include <string.h>
                     38: 
                     39: #include <sys/uio.h>
                     40: 
                     41: #if    __COHERENT__
                     42: 
                     43: #include <sys/coherent.h>
                     44: 
                     45: 
                     46: /*
                     47:  * Routines to perform transfers between the user and kernel address spaces.
                     48:  */
                     49: 
                     50: __EXTERN_C_BEGIN__
                     51: 
                     52: int            kucopy          __PROTO ((__CONST__ caddr_t ker, caddr_t usr,
                     53:                                          size_t n));
                     54: int            ukcopy          __PROTO ((__CONST__ caddr_t usr, caddr_t ker,
                     55:                                          size_t n));
                     56: int            getubd          __PROTO ((__CONST__ caddr_t usr));
                     57: void           putubd          __PROTO ((caddr_t usr, int ch));
                     58: 
                     59: __EXTERN_C_END__
                     60: 
                     61: #define        TOUSER(usr,ker,n)       kucopy ((caddr_t) ker, (caddr_t) usr, n)
                     62: #define        FROMUSER(ker,usr,n)     ukcopy ((caddr_t) usr, (caddr_t) ker, n)
                     63: 
                     64: #define        PUTBYTE(c,usr)          (putubd (usr, c), u.u_error)
                     65: #define        GETBYTE(usr)            ((unsigned char) getubd (usr) - \
                     66:                                        (u.u_error > 0 ? UCHAR_MAX : 0))
                     67: 
                     68: #else  /* if ! defined (COHERENT) */
                     69: 
                     70: 
                     71: #define        TOUSER(usr,ker,n)       (memcpy ((usr), (ker), (n)), (n))
                     72: #define        FROMUSER(ker,usr,n)     (memcpy ((ker), (usr), (n)), (n))
                     73: 
                     74: #define        PUTBYTE(c,usr)          (* (usr) = (c), 0)
                     75: #define        GETBYTE(usr)            (* (unsigned char *) (usr))
                     76: 
                     77: 
                     78: #endif
                     79: 
                     80: 
                     81: /*
                     82:  * For some reason the System V DDI/DKI uses "longs" and "ints" in many cases
                     83:  * where a size_t is far more appropriate. We will only work for cases where
                     84:  * the request does not exceed the half range of a size_t.
                     85:  */
                     86: 
                     87: #define        SIZE_T_MAX      ((1UL << (sizeof (size_t) * CHAR_BIT - 1)) - 1)
                     88: 
                     89: 
                     90: /*
                     91:  *-STATUS:
                     92:  *     DDI/DKI
                     93:  *
                     94:  *-NAME:
                     95:  *     bcopy           Copy data between address locations in the kernel.
                     96:  *
                     97:  *-SYNOPSIS:
                     98:  *     #include <sys/types.h>
                     99:  *
                    100:  *     void bcopy (caddr_t from, caddr_t to, size_t bcount);
                    101:  *
                    102:  *-ARGUMENTS:
                    103:  *     from            Source address from which the copy is made.
                    104:  *
                    105:  *     to              Destination address to which the copy is made.
                    106:  *
                    107:  *     bcount          Number of bytes to be copied.
                    108:  *
                    109:  *-DESCRIPTION:
                    110:  *     bcopy () copies "bcount" bytes from one kernel address to another. It
                    111:  *     chooses the best algorithm based on address alignment and number of
                    112:  *     bytes to copy. If the input and output addresses over, the function
                    113:  *     executes, but the results are undefined.
                    114:  *
                    115:  *-RETURN VALUE:
                    116:  *     None.
                    117:  *
                    118:  *-LEVEL:
                    119:  *     Base or interrupt.
                    120:  *
                    121:  *-NOTES:
                    122:  *     Does not sleep.
                    123:  *
                    124:  *     Driver-defined basic locks, read/write locks, and sleep locks may be
                    125:  *     held across calls to this function.
                    126:  *
                    127:  *     The source and destination address ranges must both be within the
                    128:  *     kernel address space and must be memory resident. No range checking is
                    129:  *     done. Since there is no mechanism by which drivers that conform to the
                    130:  *     rules of the DDI/DKI can obtain and use a kernel address which is not
                    131:  *     memory resident (an address which is paged out), DDI/DKI conforming
                    132:  *     drivers can assume that any address to which they have access is
                    133:  *     memory resident and therefore a valid argument to bcopy (). Addresses
                    134:  *     within user space are not valid arguments, and specifying such an
                    135:  *     address may cause the driver to corrupt the system in an unpredictable
                    136:  *     way. For copying between kernel and user space, drivers must use an
                    137:  *     appropriate function defined for that purpose (for example, copyin (),
                    138:  *     copyout (), uiomove (), ureadc (), or uwritec ()).
                    139:  *
                    140:  *-SEE ALSO:
                    141:  *     bzero (), copyin (), copyout (), uiomove (), ureadc (), uwritec ()
                    142:  */
                    143: 
                    144: #if    __USE_PROTO__
                    145: void (bcopy) (__CONST__ _VOID * from, _VOID * to, size_t bcount)
                    146: #else
                    147: void
                    148: bcopy __ARGS ((from, to, bcount))
                    149: __CONST__ _VOID
                    150:              * from;
                    151: _VOID        * to;
                    152: size_t         bcount;
                    153: #endif
                    154: {
                    155:        ASSERT (to != NULL);
                    156: 
                    157:        (void) memcpy (to, from, bcount);
                    158: }
                    159: 
                    160: 
                    161: /*
                    162:  *-STATUS:
                    163:  *     DDI/DKI
                    164:  *
                    165:  *-NAME:
                    166:  *     bzero           Clear memory for a given number of bytes.
                    167:  *
                    168:  *-SYNOPSIS:
                    169:  *     #include <sys/types.h>
                    170:  *
                    171:  *     void bzero (caddr_t addr, size_t bytes);
                    172:  *
                    173:  *-ARGUMENTS:
                    174:  *     addr            Starting virtual address of memory to be cleared.
                    175:  *
                    176:  *     bytes           Number of bytes to clear.
                    177:  *
                    178:  *-DESCRIPTION:
                    179:  *     The bzero () function clears a contiguous portion of memory by filling
                    180:  *     the memory with zeroes. It chooses the best algorithm based on address
                    181:  *     alignment and number of bytes to clear.
                    182:  *
                    183:  *-RETURN VALUE:
                    184:  *     None.
                    185:  *
                    186:  *-LEVEL:
                    187:  *     Base or interrupt.
                    188:  *
                    189:  *-NOTES:
                    190:  *     Does not sleep.
                    191:  *
                    192:  *     Driver-defined basic locks, read/write locks, and sleep locks may be
                    193:  *     held across calls to this function.
                    194:  *
                    195:  *     There are no alignment restrictions on "addr", and no length
                    196:  *     restrictions on "bytes", other than the address range specified must
                    197:  *     be within the kernel address space and must be memory resident. No
                    198:  *     range checking is done. Since there is no mechanism by which drivers
                    199:  *     that conform to the rules of the DDI/DKI can obtain and use a kernel
                    200:  *     address that is not memory resident (an address that is paged out),
                    201:  *     DDI/DKI conforming drivers can assume that any address to which they
                    202:  *     have access is memory resident and therefore a valid argument to
                    203:  *     bzero (). An address within user space is not a valid argument to
                    204:  *     bzero (), and specifying such an address may cause the driver to
                    205:  *     corrupt the system in an unpredictable way.
                    206:  *
                    207:  *-SEE ALSO:
                    208:  *     bcopy (), kmem_zalloc ()
                    209:  */
                    210: 
                    211: #if    __USE_PROTO__
                    212: void (bzero) (_VOID * addr, size_t bytes)
                    213: #else
                    214: void
                    215: bzero __ARGS ((addr, bytes))
                    216: _VOID        * addr;
                    217: size_t         bytes;
                    218: #endif
                    219: {
                    220:        ASSERT (addr != NULL);
                    221: 
                    222:        (void) memset (addr, 0, bytes);
                    223: }
                    224: 
                    225: 
                    226: /*
                    227:  *-STATUS:
                    228:  *     DDI/DKI
                    229:  *
                    230:  *-NAME:
                    231:  *     copyin          Copy data from a user buffer to a driver buffer.
                    232:  *
                    233:  *-SYNOPSIS:
                    234:  *     #include <sys/types.h>
                    235:  *
                    236:  *     int copyin (caddr_t userbuf, caddr_t driverbuf, size_t count);
                    237:  *
                    238:  *-ARGUMENTS:
                    239:  *     userbuf         User source address from which copy is made.
                    240:  *
                    241:  *     driverbuf       Driver destination address to which copy is made.
                    242:  *
                    243:  *     count           Number of bytes to copy.
                    244:  *
                    245:  *-DESCRIPTION:
                    246:  *     copyin () copies "count" bytes of data from the user virtual address
                    247:  *     specified by "userbuf" to the kernel virtual address specified by
                    248:  *     "driverbuf". The driver must ensure that adequate space is allocated
                    249:  *     for the destination address.
                    250:  *
                    251:  *     copyin () chooses the best algorithm based on address alignment and
                    252:  *     number of bytes to copy. Although the source and destination addresses
                    253:  *     are not required to be word aligned, word aligned addresses may result
                    254:  *     in a more efficient copy.
                    255:  *
                    256:  *-RETURN VALUE:
                    257:  *     If the copy is successful, 0 is returned. Otherwise, -1 is returned to
                    258:  *     indicate the specified user address range is invalid.
                    259:  *
                    260:  *-LEVEL:
                    261:  *     Base only.
                    262:  *
                    263:  *-NOTES:
                    264:  *     May sleep.
                    265:  *
                    266:  *     Drivers usually convert a return value of -1 to an EFAULT error.
                    267:  *
                    268:  *     Driver-defined basic locks and read/write locks may not be held across
                    269:  *     calls to this function.
                    270:  *
                    271:  *     Driver-defined sleep locks may be held across calls to this function.
                    272:  *
                    273:  *     When holding sleep locks across calls to this function, drivers must
                    274:  *     be careful to avoid creating a deadlock. During the data transfer,
                    275:  *     page fault resolution might result in another I/O to the same device.
                    276:  *     For example, this could occur if the driver controls the disk drive
                    277:  *     used as the swap device.
                    278:  *
                    279:  *     The driver destination buffer must be completely within the kernel
                    280:  *     address space, or the system can panic.
                    281:  *
                    282:  *-SEE ALSO:
                    283:  *     copyout (), uiomove (), ureadc (), uwritec ()
                    284:  */
                    285: 
                    286: #if    __USE_PROTO__
                    287: int (copyin) (_VOID * userbuf, _VOID * driverbuf, size_t count)
                    288: #else
                    289: int
                    290: copyin __ARGS ((userbuf, driverbuf, count))
                    291: _VOID        * userbuf;
                    292: _VOID        * driverbuf;
                    293: size_t         count;
                    294: #endif
                    295: {
                    296:        ASSERT (driverbuf != 0);
                    297: 
                    298:        return FROMUSER (driverbuf, userbuf, count) != count ? -1 : 0;
                    299: }
                    300: 
                    301: 
                    302: /*
                    303:  *-STATUS:
                    304:  *     DDI/DKI
                    305:  *
                    306:  *-NAME:
                    307:  *     copyout         Copy data from a driver buffer to a user buffer.
                    308:  *
                    309:  *-SYNOPSIS:
                    310:  *     #include <sys/types.h>
                    311:  *
                    312:  *     int copyout (caddr_t driverbuf, caddr_t userbuf, size_t count);
                    313:  *
                    314:  *-ARGUMENTS:
                    315:  *     driverbuf       Driver source address from which copy is made.
                    316:  *
                    317:  *     userbuf         User destination address to which copy is made.
                    318:  *
                    319:  *     count           Number of bytes to copy.
                    320:  *
                    321:  *-DESCRIPTION:
                    322:  *     copyout () copies "count" bytes of data from the kernel virtual
                    323:  *     address specified by "driverbuf" to the user virtual address specified
                    324:  *     by "userbuf".
                    325:  *
                    326:  *     copyout () chooses the best algorithm based on address alignment and
                    327:  *     number of bytes to copy. Although the source and destination addresses
                    328:  *     are not required to be word aligned, word aligned addresses may result
                    329:  *     in a more efficient copy.
                    330:  *
                    331:  *-RETURN VALUE:
                    332:  *     If the copy is successful, 0 is returned. Otherwise, -1 is returned to
                    333:  *     indicate that the specified user address range is not valid.
                    334:  *
                    335:  *-LEVEL:
                    336:  *     Base only.
                    337:  *
                    338:  *-NOTES:
                    339:  *     May sleep.
                    340:  *
                    341:  *     Drivers usually convert a return value of -1 into an EFAULT error.
                    342:  *
                    343:  *     Driver-defined basic locks and read/write locks may not be held across
                    344:  *     calls to this function.
                    345:  *
                    346:  *     Driver-defined sleep locks may be held across calls to this function.
                    347:  *
                    348:  *     When holding sleep locks across calls to this function, drivers must
                    349:  *     be careful to avoid creating a deadlock. During the data transfer,
                    350:  *     page fault resolution may result in another I/O to the same device.
                    351:  *     For example, this could occur if the driver controls the disk drive
                    352:  *     used as the swap device.
                    353:  *
                    354:  *     The driver source buffer must be completely within the kernel address
                    355:  *     space, or the system can panic.
                    356:  *
                    357:  *-SEE ALSO:
                    358:  *     copyin (), uiomove (), ureadc (), uwritec ()
                    359:  */
                    360: 
                    361: #if    __USE_PROTO__
                    362: int (copyout) (_VOID * driverbuf, _VOID * userbuf, size_t count)
                    363: #else
                    364: int
                    365: copyout __ARGS ((driverbuf, userbuf, count))
                    366: _VOID        * driverbuf;
                    367: _VOID        * userbuf;
                    368: size_t         count;
                    369: #endif
                    370: {
                    371:        ASSERT (driverbuf != NULL);
                    372: 
                    373:        return TOUSER (userbuf, driverbuf, count) != count ? -1 : 0;
                    374: }
                    375: 
                    376: 
                    377: /*
                    378:  *-STATUS:
                    379:  *     DDI/DKI
                    380:  *
                    381:  *-NAME:
                    382:  *     uiomove         Copy data using uio structure.
                    383:  *
                    384:  *-SYNOPSIS:
                    385:  *     #include <sys/types.h>
                    386:  *     #include <sys/uio.h>
                    387:  *
                    388:  *     int uiomove (caddr_t addr, long nbytes, uio_rw_t rwflag, uio_t * uiop);
                    389:  *
                    390:  *-ARGUMENTS:
                    391:  *     addr            Source/destination kernel address of the copy.
                    392:  *
                    393:  *     nbytes          Number of bytes to copy.
                    394:  *
                    395:  *     rwflag          Flag indicating read or write operation. Possible
                    396:  *                     values are UIO_READ and UIO_WRITE.
                    397:  *
                    398:  *     uiop            Pointer to the "uio" structure for the copy.
                    399:  *
                    400:  *-DESCRIPTION:
                    401:  *     The uiomove () function copies "nbytes" of data between the kernel
                    402:  *     address "addr" and the space defined by the "uio" structure pointed to
                    403:  *     by "uiop". If "rwflg" is "UIO_READ", the data is copied from "addr" to
                    404:  *     the space described by the "uio" structure. If "rwflag" is "UIO_WRITE",
                    405:  *     the data is copied from the space described by the "uio" structure to
                    406:  *     "addr".
                    407:  *
                    408:  *     The "uio_segflg" member of the "uio" structure specifies the type of
                    409:  *     space described by the "uio" structure. If "uio_segflg" is set to
                    410:  *     "UIO_SYSSPACE" the "uio" structure describes a portion of the kernel
                    411:  *     address space. If "uio_segflg" is set to "UIO_USERSPACE" the "uio"
                    412:  *     structure describes a portion of the user address space.
                    413:  *
                    414:  *     If the copy is successful, uiomove () updates the appropriate members
                    415:  *     of the "uio" and "iovec" structures to reflect the copy ("uio_offset"
                    416:  *     and "iov_base" and increased by "nbytes" and "uio_resid" and "iov_len"
                    417:  *     are decreased by "nbytes").
                    418:  *
                    419:  *-RETURN VALUE:
                    420:  *     uiomove () returns 0 on success or an error number on failure. If a
                    421:  *     partial transfer occurs, the "uio" structure is updated to indicate
                    422:  *     the amount not transferred and an error is returned.
                    423:  *
                    424:  *-LEVEL:
                    425:  *     Base only if "uio_segflg" is set to "UIO_USERSPACE". Base or interrupt
                    426:  *     if "uio_segflg" is set to "UIO_SYSSPACE".
                    427:  *
                    428:  *-NOTES:
                    429:  *     May sleep if "uio_segflg" is set to "UIO_USERSPACE".
                    430:  *
                    431:  *     Driver-defined basic locks and read/write locks may be held across
                    432:  *     calls to this function if "uio_segflg" is "UIO_SYSSPACE" but may not be
                    433:  *     held if "uio_segflg" is "UIO_USERSPACE".
                    434:  *
                    435:  *     Driver-defined sleep locks may be held across calls to this function
                    436:  *     regardless of the value of "uio_segflg".
                    437:  *
                    438:  *     When holding locks across calls to this function, drivers must be
                    439:  *     careful to avoid creating a deadlock. During the data transfer, page
                    440:  *     fault resolution might result in another I/O to the same device. For
                    441:  *     example, this could occur if the driver controls the disk drive used
                    442:  *     as the swap device.
                    443:  *
                    444:  *     If "addr" specifies an address in user space, or if the value of
                    445:  *     "uio_segflg" is not consistent with the type of address space
                    446:  *     described by the "uio" structure, the system can panic.
                    447:  *
                    448:  *-SEE ALSO:
                    449:  *     bcopy (), copyin (), copyout (), ureadc (), uwritec (), iovec, uio
                    450:  */
                    451: 
                    452: #if    __USE_PROTO__
                    453: int (uiomove) (caddr_t addr, long nbytes, uio_rw_t rwflag, uio_t * uiop)
                    454: #else
                    455: int
                    456: uiomove __ARGS ((addr, nbytes, rwflag, uiop))
                    457: caddr_t                addr;
                    458: long           nbytes;
                    459: uio_rw_t       rwflag;
                    460: uio_t        * uiop;
                    461: #endif
                    462: {
                    463:        iovec_t       * scan;
                    464:        iovec_t       * end;
                    465: 
                    466:        ASSERT (addr != NULL);
                    467:        ASSERT (uiop != NULL);
                    468:        ASSERT (nbytes > 0);
                    469:        ASSERT (nbytes <= SIZE_T_MAX);
                    470:        ASSERT (uiop->uio_resid <= SIZE_T_MAX);
                    471:        ASSERT (rwflag == UIO_READ || rwflag == UIO_WRITE);
                    472:        ASSERT (uiop->uio_segflg == UIO_SYSSPACE ||
                    473:                uiop->uio_segflg == UIO_USERSPACE);
                    474:        ASSERT (uiop->uio_resid > 0);
                    475: 
                    476:        for (scan = uiop->uio_iov, end = scan + uiop->uio_iovcnt ;
                    477:             nbytes > 0 ; scan ++) {
                    478:                size_t          size;
                    479: 
                    480: 
                    481:                /*
                    482:                 * Now we are going to move a single block of the scatter/
                    483:                 * gather request. We assume that scan->iov_len is
                    484:                 * less than or equal to uiop->uio_resid!
                    485:                 */
                    486: 
                    487:                ASSERT (scan < end);
                    488:                ASSERT (scan->iov_len > 0);
                    489:                ASSERT (scan->iov_len <= uiop->uio_resid);
                    490: 
                    491:                if (nbytes < (size = (size_t) uiop->uio_iov->iov_len))
                    492:                        size = (size_t) nbytes;
                    493: 
                    494:                if (size == 0)
                    495:                        continue;
                    496: 
                    497: 
                    498:                /*
                    499:                 * Transfer a segment as indicated.
                    500:                 */
                    501: 
                    502:                if (rwflag == UIO_READ) {
                    503: 
                    504:                        if (uiop->uio_segflg == UIO_USERSPACE) {
                    505:                                /*
                    506:                                 * Transfers involving user memory may sleep
                    507:                                 * due to paging!
                    508:                                 */
                    509: 
                    510:                                if (TOUSER (scan->iov_base, addr,
                    511:                                            size) != size)
                    512:                                        break;
                    513:                        } else
                    514:                                memcpy (scan->iov_base, addr, size);
                    515:                } else {
                    516: 
                    517:                        if (uiop->uio_segflg == UIO_USERSPACE) {
                    518:                                /*
                    519:                                 * Transfers involving user memory may sleep
                    520:                                 * due to paging!
                    521:                                 */
                    522: 
                    523: 
                    524:                                if (FROMUSER (addr, scan->iov_base,
                    525:                                              size) != size)
                    526:                                        break;
                    527:                        } else
                    528:                                memcpy (addr, scan->iov_base, size);
                    529:                }
                    530: 
                    531:                addr += size;
                    532:                nbytes -= size;
                    533: 
                    534:                uiop->uio_resid -= size;
                    535:                uiop->uio_offset += size;
                    536: 
                    537:                scan->iov_len -= size;
                    538:                scan->iov_base += size;
                    539:        }
                    540: 
                    541:        return nbytes == 0 ? 0 : EFAULT;
                    542: }
                    543: 
                    544: 
                    545: /*
                    546:  *-STATUS:
                    547:  *     DDI/DKI
                    548:  *
                    549:  *-NAME:
                    550:  *     ureadc          Copy a character to space described by a "uio"
                    551:  *                     structure.
                    552:  *
                    553:  *-SYNOPSIS:
                    554:  *     #include <sys/uio.h>
                    555:  *
                    556:  *     int ureadc (int c, uio_t * uiop);
                    557:  *
                    558:  *-ARGUMENTS:
                    559:  *     c               The character to be copied.
                    560:  *
                    561:  *     uiop            Pointer to the "uio" structure.
                    562:  *
                    563:  *-DESCRIPTION:
                    564:  *     ureadc () copies the character "c" into the space described by the
                    565:  *     "uio" structure pointed to by "uiop".
                    566:  *
                    567:  *     The "uio_segflg" member of the "uio" structure specifies the type of
                    568:  *     space to which the copy is made. If "uio_segflg" is set to
                    569:  *     "UIO_SYSSPACE" the character is copied to a kernel address. If
                    570:  *     "uio_segflg" is set to "UIO_USERSPACE" the character is copied to a
                    571:  *     user address.
                    572:  *
                    573:  *     If the character is successfully copied, ureadc () updates the
                    574:  *     appropriate members of the "uio" and "iovec" structures to reflect
                    575:  *     the copy ("uio_offset" and "iov_base" are incremented and "uio_resid"
                    576:  *     and "iov_len" are decremented).
                    577:  *
                    578:  *-RETURN VALUE:
                    579:  *     ureadc () returns 0 on success or an error number on failure.
                    580:  *
                    581:  *-LEVEL:
                    582:  *     Base only if "uio_segflg" is set to "UIO_USERSPACE". Base or interrupt
                    583:  *     if "uio_segflg" is set to "UIO_SYSSPACE".
                    584:  *
                    585:  *-NOTES:
                    586:  *     May sleep if "uio_segflg" is set to "UIO_USERSPACE".
                    587:  *
                    588:  *     Driver-defined basic locks and read/write locks may be held across
                    589:  *     calls to this function if "uio_segflg" is set to "UIO_SYSSPACE" but
                    590:  *     may not be held if "uio_segflg" is set to "UIO_USERSPACE".
                    591:  *
                    592:  *     Driver-defined sleep locks may be held across calls to this function
                    593:  *     regardless of the value of "uio_segflg".
                    594:  *
                    595:  *     When holding locks across calls to this function, drivers must be
                    596:  *     careful to avoid creating a deadlock. During the data transfer, page
                    597:  *     fault resolution might result in another I/O to the same device. For
                    598:  *     example, this could occur if the driver controls the disk drive used
                    599:  *     as the swap device.
                    600:  *
                    601:  *-SEE ALSO:
                    602:  *     uiomove (), uwritec (), iovec, uio
                    603:  */
                    604: 
                    605: #if    __USE_PROTO__
                    606: int (ureadc) (int c, uio_t * uiop)
                    607: #else
                    608: int
                    609: ureadc __ARGS ((c, uiop))
                    610: int            c;
                    611: uio_t        * uiop;
                    612: #endif
                    613: {
                    614:        iovec_t       * scan;
                    615: 
                    616: 
                    617:        ASSERT (uiop != NULL);
                    618:        ASSERT (uiop->uio_segflg == UIO_SYSSPACE ||
                    619:                uiop->uio_segflg == UIO_USERSPACE);
                    620:        ASSERT (uiop->uio_segflg == UIO_SYSSPACE ||
                    621:                uiop->uio_segflg == UIO_USERSPACE);
                    622:        ASSERT (uiop->uio_resid > 0);
                    623: 
                    624:        /*
                    625:         * What to do if the structure is empty? As indicated above, I
                    626:         * consider that an error worthy of a kernel panic. At a minimum we
                    627:         * should make it a recoverable error as the code below does.
                    628:         */
                    629: 
                    630:        if (uiop->uio_resid <= 0)
                    631:                return EFAULT;
                    632: 
                    633: 
                    634:        /*
                    635:         * For now, we loop over any initial empty segments. It is not clear
                    636:         * to me whether this code can alter "uio_iov" or not, although we
                    637:         * definitely are permitted to maintain a separate entry in the
                    638:         * structure to the same effect.
                    639:         */
                    640: 
                    641:        for (scan = uiop->uio_iov ; scan->iov_len == 0 ; scan ++)
                    642:                ;
                    643: 
                    644:        ASSERT (scan < uiop->uio_iov + uiop->uio_iovcnt);
                    645: 
                    646:        /*
                    647:         * Now, write a single character to the space indicated.
                    648:         */
                    649: 
                    650:        if (uiop->uio_segflg == UIO_USERSPACE) {
                    651: 
                    652:                if (PUTBYTE (c, scan->iov_base) != 0)
                    653:                        return EFAULT;
                    654: 
                    655:                scan->iov_base ++;
                    656:        } else
                    657:                * scan->iov_base ++ = c;
                    658: 
                    659:        scan->iov_len ++;
                    660: 
                    661:        uiop->uio_resid --;
                    662:        uiop->uio_offset ++;
                    663: 
                    664:        return 0;
                    665: }
                    666: 
                    667: 
                    668: /*
                    669:  *-STATUS:
                    670:  *     DDI/DKI
                    671:  *
                    672:  *-NAME:
                    673:  *     uwritec         Return a character from space described by a "uio"
                    674:  *                     structure.
                    675:  *
                    676:  *-SYNOPSIS:
                    677:  *     #include <sys/uio.h>
                    678:  *
                    679:  *     int uwritec (uio_t * uiop);
                    680:  *
                    681:  *-ARGUMENTS:
                    682:  *     uiop            Pointer to the "uio" structure.
                    683:  *
                    684:  *-DESCRIPTION:
                    685:  *     uwritec () copies a character from the space described by the "uio"
                    686:  *     structure pointed to by "uiop" and returns the character to the
                    687:  *     caller.
                    688:  *
                    689:  *     The "uio_segflg" member of the "uio" structure specifies the type of
                    690:  *     space from which the copy is made. If "uio_segflg" is set to
                    691:  *     "UIO_SYSSPACE" the character is copied from a kernel address. If
                    692:  *     "uio_segflg" is set to "UIO_USERSPACE" the character is copied from a
                    693:  *     user address.
                    694:  *
                    695:  *     If the character is successfully copied, uwritec () updates the
                    696:  *     appropriate members of the "uio" and "iovec" structures to reflect the
                    697:  *     copy ("uio_offset" and "iov_base" are incremented and "uio_resid" and
                    698:  *     "iov_len" are decremented).
                    699:  *
                    700:  *-RETURN VALUE:
                    701:  *     If successful, uwritec () returns the character. -1 is returned if the
                    702:  *     space described by the "uio" structure is empty or if there is an
                    703:  *     error.
                    704:  *
                    705:  *-LEVEL:
                    706:  *     Base only if "uio_segflg" is set to "UIO_USERSPACE". Base or interrupt
                    707:  *     if "uio_segflg" is set to "UIO_SYSSPACE".
                    708:  *
                    709:  *-NOTES:
                    710:  *     May sleep if "uio_segflg" is set to "UIO_USERSPACE".
                    711:  *     Driver-defined basic locks and read/write locks may be held across
                    712:  *     calls to this function if "uio_segflg" is "UIO_SYSSPACE" but may not
                    713:  *     be held if "uio_segflg" is "UIO_USERSPACE".
                    714:  *
                    715:  *     Driver-defined sleep locks may be held across calls to this function
                    716:  *     regardless of the value of "uio_segflg".
                    717:  *
                    718:  *     When holding locks across calls to this function, drivers must be
                    719:  *     careful to avoid creating a deadlock. During the data transfer, page
                    720:  *     fault resolution might result in another I/O to the same device. For
                    721:  *     example, this could occur if the driver controls the disk drive used
                    722:  *     as the swap device.
                    723:  *
                    724:  *-SEE ALSO:
                    725:  *     uiomove (), ureadc (), iovec, uio
                    726:  */
                    727: 
                    728: #if    __USE_PROTO__
                    729: int (uwritec) (uio_t * uiop)
                    730: #else
                    731: int
                    732: uwritec __ARGS ((uiop))
                    733: uio_t        * uiop;
                    734: #endif
                    735: {
                    736:        iovec_t       * scan;
                    737:        int             c;
                    738: 
                    739: 
                    740:        ASSERT (uiop != NULL);
                    741:        ASSERT (uiop->uio_segflg == UIO_SYSSPACE ||
                    742:                uiop->uio_segflg == UIO_USERSPACE);
                    743:        ASSERT (uiop->uio_segflg == UIO_SYSSPACE ||
                    744:                uiop->uio_segflg == UIO_USERSPACE);
                    745: 
                    746:        /*
                    747:         * What to do if the structure is empty? Unlike ureadc (), we are
                    748:         * allowed to return -1.
                    749:         */
                    750: 
                    751:        if (uiop->uio_resid <= 0)
                    752:                return -1;
                    753: 
                    754: 
                    755:        /*
                    756:         * For now, we loop over any initial empty segments. It is not clear
                    757:         * to me whether this code can alter "uio_iov" or not, although we
                    758:         * definitely are permitted to maintain a separate entry in the
                    759:         * structure to the same effect.
                    760:         */
                    761: 
                    762:        for (scan = uiop->uio_iov ; scan->iov_len == 0 ; scan ++)
                    763:                ;
                    764: 
                    765:        ASSERT (scan < uiop->uio_iov + uiop->uio_iovcnt);
                    766: 
                    767:        /*
                    768:         * Now, read a single character from the space indicated.
                    769:         */
                    770: 
                    771:        if (uiop->uio_segflg == UIO_USERSPACE) {
                    772: 
                    773:                if ((c = GETBYTE (scan->iov_base)) < 0)
                    774:                        return -1;
                    775: 
                    776:                scan->iov_base ++;
                    777:        } else
                    778:                c = * scan->iov_base ++;
                    779: 
                    780:        scan->iov_len --;
                    781: 
                    782:        uiop->uio_resid --;
                    783:        uiop->uio_offset ++;
                    784: 
                    785:        return c;
                    786: }

unix.superglobalmegacorp.com

This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.