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

1.1       root        1: #define        _DDI_DKI        1
                      2: #define        _DDI_DKI_IMPL   1
                      3: #define        _SYSV4          1
                      4: 
                      5: /*
                      6:  * Definition for the DDI/DKI linkable version of ddi_proc ()
                      7:  */
                      8: 
                      9: /*
                     10:  *-IMPORTS:
                     11:  *     <common/ccompat.h>
                     12:  *             __USE_PROTO__
                     13:  *             __ARGS ()
                     14:  *     <kernel/x86lock.h>
                     15:  *             ATOMIC_STORE_UCHAR ()
                     16:  *     <kernel/ddi_lock.h>
                     17:  *             INTERNAL_LOCK
                     18:  *             poll_global_hierarchy
                     19:  *             poll_global_priority
                     20:  *             defer_hierarchy
                     21:  *             defer_priority
                     22:  *             proc_global_hierarchy
                     23:  *             proc_global_priority
                     24:  *     <sys/types.h>
                     25:  *             inb ()
                     26:  *             outb ()
                     27:  *     <sys/ksynch.h>
                     28:  *             lkinfo_t
                     29:  *             LOCK_ALLOC ()
                     30:  *     <sys/kmem.h>
                     31:  *             KM_NOSLEEP
                     32:  *             kmem_alloc ()
                     33:  *     <stddef.h>
                     34:  *             NULL
                     35:  *     <string.h>
                     36:  *             memset ()
                     37:  */
                     38: 
                     39: #include <common/ccompat.h>
                     40: #include <kernel/x86lock.h>
                     41: #include <kernel/ddi_lock.h>
                     42: #include <sys/types.h>
                     43: #include <sys/ksynch.h>
                     44: #include <sys/kmem.h>
                     45: #include <stddef.h>
                     46: #include <string.h>
                     47: 
                     48: #include <kernel/ddi_base.h>
                     49: #include <kernel/ddi_proc.h>
                     50: #include <kernel/ddi_cpu.h>
                     51: #include <kernel/ddi_glob.h>
                     52: 
                     53: 
                     54: /*
                     55:  * Here we have the actal static data declarations for the uniprocessor
                     56:  * implementation of the DDI/DKI per-CPU data. Note that under a "real"
                     57:  * system, the dynamic area would be the space left over by the fixed data up
                     58:  * to the size of a page, because that seems the best (read fastest and most
                     59:  * secure) way of doing it (by mapping each processor's private data into the
                     60:  * same address across all processors). Of course, it's questionable whether
                     61:  * any drivers *will* actually use the binary-compatible function-versions of
                     62:  * the accessors, but that's not our problem.
                     63:  *
                     64:  * Don't forget that if we *do* use the paging system for per-CPU data that
                     65:  * those pages will have to be mapped somewhere else as well, because there is
                     66:  * data like the deferred function table that the world may want controlled
                     67:  * access to.
                     68:  */
                     69: 
                     70: dcdata_t       __ddi_cpu_data [1];
                     71: dgdata_t       __ddi_global_data;
                     72: __LOCAL__ char ddi_cpu_dynarea [512];
                     73: 
                     74: 
                     75: /*
                     76:  * Lock information structures.
                     77:  */
                     78: 
                     79: __LOCAL__ lkinfo_t poll_global_lkinfo = {
                     80:        "polling global lock", INTERNAL_LOCK
                     81: };
                     82: 
                     83: __LOCAL__ lkinfo_t defer_lkinfo = {
                     84:        "defer write lock", INTERNAL_LOCK
                     85: };
                     86: 
                     87: __LOCAL__ lkinfo_t proc_global_lkinfo = {
                     88:        "process global lock", INTERNAL_LOCK
                     89: };
                     90: 
                     91: 
                     92: /*
                     93:  *-STATUS:
                     94:  *     Local DDI/DKI extension
                     95:  *
                     96:  *-NAME:
                     97:  *     ddi_base_data           Get per-process DDI/DKI base data.
                     98:  *
                     99:  *-SYNOPSIS:
                    100:  *     #include <kernel/ddi_base.h>
                    101:  *
                    102:  *     dbdata_t * ddi_base_data (void);
                    103:  *
                    104:  *-DESCRIPTION:
                    105:  *     This function returns a base pointer to a table of information that
                    106:  *     the DDI/DKI needs to associate with a process but will not need to
                    107:  *     access outside that process context.
                    108:  *
                    109:  *-RETURN VALUE:
                    110:  *     The base address of a per-process DDI/DKI data table entry. The
                    111:  *     value returned may be considered "constant" and memoized within a
                    112:  *     context provided that no rescheduling may occur.
                    113:  *
                    114:  *-LEVEL:
                    115:  *     Base only.
                    116:  *
                    117:  *-NOTES:
                    118:  *     This function does not sleep.
                    119:  */
                    120: 
                    121: 
                    122: #if    __USE_PROTO__
                    123: dbdata_t * (ddi_base_data) (void)
                    124: #else
                    125: dbdata_t *
                    126: ddi_base_data __ARGS (())
                    127: #endif
                    128: {
                    129:        ASSERT_BASE_LEVEL ();
                    130: 
                    131:        return ddi_base_data ();
                    132: }
                    133: 
                    134: 
                    135: /*
                    136:  *-STATUS:
                    137:  *     Local DDI/DKI extension
                    138:  *
                    139:  *-NAME:
                    140:  *     ddi_proc_data           Get per-process DDI/DKI global data.
                    141:  *
                    142:  *-SYNOPSIS:
                    143:  *     #include <kernel/ddi_proc.h>
                    144:  *
                    145:  *     dpdata_t * ddi_proc_data (void);
                    146:  *
                    147:  *-DESCRIPTION:
                    148:  *     This function returns a base pointer to a table of information that
                    149:  *     the DDI/DKI needs to associate with a process but may need to access
                    150:  *     outside the process context.
                    151:  *
                    152:  *-RETURN VALUE:
                    153:  *     The base address of a per-process DDI/DKI data table entry. The
                    154:  *     value returned may be considered "constant" and memoized within a
                    155:  *     context provided that no rescheduling may occur.
                    156:  *
                    157:  *-LEVEL:
                    158:  *     Base or interrupt.
                    159:  *
                    160:  *-NOTES:
                    161:  *     This function does not sleep.
                    162:  */
                    163: 
                    164: 
                    165: #if    __USE_PROTO__
                    166: dpdata_t * (ddi_proc_data) (void)
                    167: #else
                    168: dpdata_t *
                    169: ddi_proc_data __ARGS (())
                    170: #endif
                    171: {
                    172:        return ddi_proc_data ();
                    173: }
                    174: 
                    175: 
                    176: /*
                    177:  *-STATUS:
                    178:  *     Local DDI/DKI extension
                    179:  *
                    180:  *-NAME:
                    181:  *     ddi_cpu_data            Get per-CPU DDI/DKI global data.
                    182:  *
                    183:  *-SYNOPSIS:
                    184:  *     #include <kernel/ddi_cpu.h>
                    185:  *
                    186:  *     dcdata_t * ddi_cpu_data (void);
                    187:  *
                    188:  *-DESCRIPTION:
                    189:  *     This function returns a base pointer to a table of information that
                    190:  *     can be considered per-CPU DDI/DKI static data. The value returned
                    191:  *     may be considered "constant" and memoized within a context provided
                    192:  *     that no rescheduling could occur.
                    193:  *
                    194:  *-RETURN VALUE:
                    195:  *     The base address of a per-CPU DDI/DKI data table entry.
                    196:  *
                    197:  *-LEVEL:
                    198:  *     Base or interrupt.
                    199:  *
                    200:  *-NOTES:
                    201:  *     This function does not sleep.
                    202:  */
                    203: 
                    204: #if    __USE_PROTO__
                    205: dcdata_t * (ddi_cpu_data) (void)
                    206: #else
                    207: dcdata_t *
                    208: ddi_cpu_data __ARGS (())
                    209: #endif
                    210: {
                    211:        return ddi_cpu_data ();
                    212: }
                    213: 
                    214: 
                    215: /*
                    216:  *-STATUS:
                    217:  *     Local DDI/DKI extension
                    218:  *
                    219:  *-NAME:
                    220:  *     ddi_global_data         Get DDI/DKI global data.
                    221:  *
                    222:  *-SYNOPSIS:
                    223:  *     #include <kernel/ddi_glob.h>
                    224:  *
                    225:  *     dgdata_t * ddi_global_data (void);
                    226:  *
                    227:  *-DESCRIPTION:
                    228:  *     This function returns a base pointer to a table of information that
                    229:  *     represents the global state of the DDI/DKI subsystem, with the
                    230:  *     possible exception of the STREAMS global state.
                    231:  *
                    232:  *-RETURN VALUE:
                    233:  *     The base address of the global DDI/DKI data table. The value returned
                    234:  *     may be considered "constant" and memoized within a context provided
                    235:  *     that no rescheduling may occur.
                    236:  *
                    237:  *-LEVEL:
                    238:  *     Base or interrupt.
                    239:  *
                    240:  *-NOTES:
                    241:  *     This function does not sleep.
                    242:  */
                    243: 
                    244: 
                    245: #if    __USE_PROTO__
                    246: dgdata_t * (ddi_global_data) (void)
                    247: #else
                    248: dgdata_t *
                    249: ddi_global_data __ARGS (())
                    250: #endif
                    251: {
                    252:        return ddi_global_data ();
                    253: }
                    254: 
                    255: 
                    256: /*
                    257:  *-STATUS:
                    258:  *     For the Implementors only.
                    259:  *
                    260:  *-NAME:
                    261:  *     ddi_cpu_id      Determine the current CPU id.
                    262:  *
                    263:  *-SYNOPSIS:
                    264:  *     #include <kernel/ddi_cpu.h>
                    265:  *
                    266:  *     processorid_t ddi_cpu_id (void);
                    267:  *
                    268:  *-DESCRIPTION:
                    269:  *     ddi_cpu_id () allows DDI/DKI code a way of accessing the current CPU
                    270:  *     id for passing to functions such as dtimeout () or defer_int_cpu ().
                    271:  *
                    272:  *-RETURN VALUE:
                    273:  *     The id code of the CPU that the caller is executing on.
                    274:  *
                    275:  *-LEVEL:
                    276:  *     Base or interrupt.
                    277:  *
                    278:  *-NOTES:
                    279:  *     Does not sleep.
                    280:  */
                    281: 
                    282: #if    __USE_PROTO__
                    283: processorid_t (ddi_cpu_id) (void)
                    284: #else
                    285: processorid_t
                    286: ddi_cpu_id __ARGS (())
                    287: #endif
                    288: {
                    289:        return ddi_cpu_data ()->dc_cpuid;
                    290: }
                    291: 
                    292: 
                    293: /*
                    294:  *-STATUS:
                    295:  *     For the Implementors only.
                    296:  *
                    297:  *-NAME:
                    298:  *     ddi_cpu_alloc   Dynamically allocates per-CPU data.
                    299:  *
                    300:  *-SYNOPSIS:
                    301:  *     #include <kernel/ddi_cpu.h>
                    302:  *
                    303:  *     void * ddi_cpu_alloc (size_t size);
                    304:  *
                    305:  *-ARGUMENTS:
                    306:  *     size            The size in bytes to allocate. This value will always
                    307:  *                     be rounded up to the size of an integer to ensure the
                    308:  *                     alignment of the returned space. A value of 0 is not
                    309:  *                     legal and will result in the function returning NULL.
                    310:  *
                    311:  *-DESCRIPTION:
                    312:  *     ddi_cpu_alloc () is for use in the DDI/DKI implementation to request
                    313:  *     per-CPU data in a flexible way. Facilities that require tables of per-
                    314:  *     CPU data should request it at startup time to allow the table sizes to
                    315:  *     be flexibly administered and also to avoid polluting the "dcdata_t"
                    316:  *     structure with information whose size cannot easily be fixed. Using
                    317:  *     this facility should allow for greater levels of internal binary
                    318:  *     compatibility by restricting the amount of change the "dcdata_t"
                    319:  *     structure can undergo between (minor) releases of the operation
                    320:  *     system.
                    321:  *
                    322:  *-RETURN VALUE:
                    323:  *     On failure, NULL is returned. On success, a pointer to the requested
                    324:  *     data is returned. The pointer returned will be aligned to the size of
                    325:  *     an integer on the target machine architecture.
                    326:  *
                    327:  *-LEVEL:
                    328:  *     Base only.
                    329:  *
                    330:  *-NOTES:
                    331:  *     Does not sleep.
                    332:  */
                    333: 
                    334: #if    __USE_PROTO__
                    335: __VOID__ * (ddi_cpu_alloc) (size_t size)
                    336: #else
                    337: __VOID__ *
                    338: ddi_cpu_alloc __ARGS ((size))
                    339: size_t         size;
                    340: #endif
                    341: {
                    342:        dcdata_t      * dcdatap = ddi_cpu_data ();
                    343:        __VOID__      * alloc;
                    344: 
                    345:        ASSERT_BASE_LEVEL ();
                    346: 
                    347:        size = (size + sizeof (int) - 1) & ~ sizeof (int);
                    348: 
                    349:        if (size == 0 || dcdatap->dc_dynalloc + size > dcdatap->dc_dynend)
                    350:                return NULL;
                    351: 
                    352:        alloc = dcdatap->dc_dynalloc;
                    353:        dcdatap->dc_dynalloc += size;
                    354: 
                    355:         memset (alloc, 0, size);
                    356:        return alloc;
                    357: }
                    358: 
                    359: 
                    360: /*
                    361:  *-STATUS:
                    362:  *     For the Implementors only.
                    363:  *
                    364:  *-NAME:
                    365:  *     ddi_cpu_other           Return per-CPU data for other CPUs
                    366:  *
                    367:  *-SYNOPSIS:
                    368:  *     #include <kernel/ddi_cpu.h>
                    369:  *
                    370:  *     dcdata_t * ddi_cpu_ref (processorid_t cpu);
                    371:  *
                    372:  *-ARGUMENTS:
                    373:  *     cpu             ID code for processor whose data needs to be accessed.
                    374:  *
                    375:  *-DESCRIPTION:
                    376:  *     The implementations of DDI/DKI facilities may wish to write into the
                    377:  *     private data areas of other CPUs. This function provides a way of
                    378:  *     accessing that information.
                    379:  *
                    380:  *     Note that the per-CPU data area provides many conveniences to the
                    381:  *     implementor, not the least of which is latitude with synchronization,
                    382:  *     which has a data space cost if not a run-time cost, and also makes
                    383:  *     many operations considerably simpler. Access by other CPUs to per-CPU
                    384:  *     data bypasses most of the assumptions that can be conveniently made
                    385:  *     about access to this area, so users of this function are especially
                    386:  *     cautioned to use all the appropriate interlock mechanisms when writing
                    387:  *     data via the pointer this function provides.
                    388:  *
                    389:  *     There must be exactly one call to ddi_cpu_unref () for each call to
                    390:  *     ddi_cpu_ref (). This should be done as soon as possible after the
                    391:  *     call to ddi_cpu_ref () since on some architectures making this memory
                    392:  *     shared may have a serious impact on performance.
                    393:  *
                    394:  *-RETURN VALUE:
                    395:  *     NULL is returned if the cpu ID is not valid for the machine
                    396:  *     configuration. Otherwise, a pointer to the per-process data for the
                    397:  *     indicated CPU is returned.
                    398:  *
                    399:  *-LEVEL:
                    400:  *     Base or interrupt.
                    401:  *
                    402:  *-NOTES:
                    403:  *     Does not sleep.
                    404:  *
                    405:  *     It is as yet uspecified whether recursive calls to ddi_cpu_ref () are
                    406:  *     permitted.
                    407:  */
                    408: 
                    409: #if    __USE_PROTO__
                    410: dcdata_t * (ddi_cpu_ref) (processorid_t cpu)
                    411: #else
                    412: dcdata_t *
                    413: ddi_cpu_ref __ARGS ((cpu))
                    414: processorid_t  cpu;
                    415: #endif
                    416: {
                    417:        /*
                    418:         * Only one processor, as yet.
                    419:         */
                    420: 
                    421:        return cpu == 0 ? ddi_cpu_data () : NULL;
                    422: }
                    423: 
                    424: 
                    425: /*
                    426:  *-STATUS:
                    427:  *     For the Implementors only.
                    428:  *
                    429:  *-NAME:
                    430:  *     ddi_cpu_other           Return per-CPU data for other CPUs
                    431:  *
                    432:  *-SYNOPSIS:
                    433:  *     #include <kernel/ddi_cpu.h>
                    434:  *
                    435:  *     void ddi_cpu_unref (dcdata_t * data);
                    436:  *
                    437:  *-ARGUMENTS:
                    438:  *     data            A pointer to per-CPU data obtained via the
                    439:  *                     ddi_cpu_ref () function.
                    440:  *
                    441:  *-DESCRIPTION:
                    442:  *     This function is used to release a reference to per-CPU data for some
                    443:  *     CPU that was obtained by ddi_cpu_ref (). This function may perform
                    444:  *     various actions to undo any work necessary to ensure that the memory
                    445:  *     in question can be accessed by the calling CPU, such as unmapping it
                    446:  *     from the calling CPU's address space to provide maximum protection
                    447:  *     against accidental damage.
                    448:  *
                    449:  *     There must be exactly one call to ddi_cpu_unref () for each call to
                    450:  *     ddi_cpu_ref ().
                    451:  *
                    452:  *-RETURN VALUE:
                    453:  *     None.
                    454:  *
                    455:  *-LEVEL:
                    456:  *     Base or interrupt.
                    457:  *
                    458:  *-NOTES:
                    459:  *     Does not sleep.
                    460:  */
                    461: 
                    462: #if    __USE_PROTO__
                    463: void (ddi_cpu_unref) (dcdata_t * data)
                    464: #else
                    465: void
                    466: ddi_cpu_unref __ARGS ((data))
                    467: dcdata_t      *        data;
                    468: #endif
                    469: {
                    470:        ASSERT (data != NULL && data == ddi_cpu_data ());
                    471: }
                    472: 
                    473: 
                    474: /*
                    475:  * Do what we need to do to ensure that the spl... () functions work.
                    476:  */
                    477: 
                    478: #include <sys/inline.h>
                    479: 
                    480: __EXTERN_C__
                    481: #if    __USE_PROTO__
                    482: int (INTR_INIT) (void)
                    483: #else
                    484: int
                    485: INTR_INIT __ARGS (())
                    486: #endif
                    487: {
                    488:        dcdata_t      * dcdatap;
                    489: 
                    490:        /*
                    491:         * This implementation statically allocates the per-CPU data, since
                    492:         * deep down we really "know" that we are working on a uniprocessor.
                    493:         * This also means we don't have to zero-fill anything.
                    494:         */
                    495: 
                    496:        dcdatap = ddi_cpu_data ();
                    497:        dcdatap->dc_base_mask = (inb (__SPICM__) << 8) | inb (__PICM__);
                    498: 
                    499: 
                    500:        /*
                    501:         * We start at interrupt level 1 so we can trap attempts to go to
                    502:         * sleep before we are ready for that.
                    503:         */
                    504: 
                    505:        dcdatap->dc_int_level = 0;
                    506:        dcdatap->dc_ipl = plbase;
                    507: 
                    508: 
                    509:        /*
                    510:         * Set up the "dynamic" part of the structures.
                    511:         */
                    512: 
                    513:        dcdatap->dc_dynalloc = ddi_cpu_dynarea;
                    514:        dcdatap->dc_dynend = ddi_cpu_dynarea + sizeof (ddi_cpu_dynarea);
                    515: 
                    516: 
                    517:        /*
                    518:         * Carve off some of the "dynamic" space for the heirarchy-test stuff.
                    519:         * This is done with the dynamic stuff because it seems like a really
                    520:         * bad idea putting a table in space we want to form the basis of an
                    521:         * internal binary standard (even though this is a very well-defined
                    522:         * array).
                    523:         */
                    524: 
                    525:        dcdatap->dc_hierarchy_cnt = (__lkhier_t *)
                    526:                ddi_cpu_alloc (sizeof (__lkhier_t) *
                    527:                               (__MAX_HIERARCHY__ - __MIN_HIERARCHY__ + 1));
                    528: 
                    529:        return dcdatap->dc_hierarchy_cnt == NULL;
                    530: }
                    531: 
                    532: 
                    533: /*
                    534:  * Set up one of the deferred-function tables.
                    535:  */
                    536: 
                    537: #if    __USE_PROTO__
                    538: __LOCAL__ int (DEFER_INIT) (defer_t * deferp, int local, int max)
                    539: #else
                    540: __LOCAL__ int
                    541: DEFER_INIT __ARGS ((deferp, local, max))
                    542: defer_t              * deferp;
                    543: int            local;
                    544: int            max;
                    545: #endif
                    546: {
                    547:        deferp->df_tab = (__deffuncp_t *) (local == 0 ?
                    548:                kmem_alloc (sizeof (__deffuncp_t) * max, KM_NOSLEEP) :
                    549:                ddi_cpu_alloc (sizeof (__deffuncp_t) * max));
                    550: 
                    551:        deferp->df_wlock = LOCK_ALLOC (defer_hierarchy, defer_priority,
                    552:                                       & defer_lkinfo, KM_NOSLEEP);
                    553: 
                    554:        if (deferp->df_tab == NULL || deferp->df_wlock == NULL)
                    555:                return 1;
                    556: 
                    557:        ATOMIC_STORE_UCHAR (deferp->df_max, max);
                    558:        return 0;
                    559: }
                    560: 
                    561: 
                    562: /*
                    563:  * Set up the global and per-CPU DDI/DKI data, locks and other whatnot.
                    564:  */
                    565: 
                    566: __EXTERN_C__
                    567: #if    __USE_PROTO__
                    568: int (DDI_GLOB_INIT) (void)
                    569: #else
                    570: int
                    571: DDI_GLOB_INIT __ARGS (())
                    572: #endif
                    573: {
                    574:        dgdata_t      * dgdatap = ddi_global_data ();
                    575:        dcdata_t      * dcdatap = ddi_cpu_data ();
                    576: 
                    577:        /*
                    578:         * Set up the global data table. We assume here that our global data
                    579:         * is zeroed by default.
                    580:         */
                    581: 
                    582:        if (DEFER_INIT (& dgdatap->dg_defint, 0, 25) != 0 ||
                    583:            DEFER_INIT (& dgdatap->dg_defproc, 0, 25) != 0 ||
                    584:            DEFER_INIT (& dcdatap->dc_defint, 1, 25) != 0 ||
                    585:            DEFER_INIT (& dcdatap->dc_defproc, 1, 25) != 0)
                    586:                return 1;
                    587: 
                    588:        dgdatap->dg_polllock = LOCK_ALLOC (poll_global_hierarchy,
                    589:                                           poll_global_priority,
                    590:                                           & poll_global_lkinfo, KM_NOSLEEP);
                    591: 
                    592:        dgdatap->dg_proclock = LOCK_ALLOC (proc_global_hierarchy,
                    593:                                           proc_global_priority,
                    594:                                           & proc_global_lkinfo, KM_NOSLEEP);
                    595: 
                    596:        if (dgdatap->dg_polllock == NULL || dgdatap->dg_proclock == NULL)
                    597:                return 1;
                    598: 
                    599:        return 0;
                    600: }

unix.superglobalmegacorp.com

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