Home | History | Annotate | Line # | Download | only in src
      1 /*
      2  * Copyright 1999, 2000 ATI Technologies Inc., Markham, Ontario,
      3  *                      Precision Insight, Inc., Cedar Park, Texas, and
      4  *                      VA Linux Systems Inc., Fremont, California.
      5  *
      6  * All Rights Reserved.
      7  *
      8  * Permission is hereby granted, free of charge, to any person obtaining
      9  * a copy of this software and associated documentation files (the
     10  * "Software"), to deal in the Software without restriction, including
     11  * without limitation on the rights to use, copy, modify, merge,
     12  * publish, distribute, sublicense, and/or sell copies of the Software,
     13  * and to permit persons to whom the Software is furnished to do so,
     14  * subject to the following conditions:
     15  *
     16  * The above copyright notice and this permission notice (including the
     17  * next paragraph) shall be included in all copies or substantial
     18  * portions of the Software.
     19  *
     20  * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
     21  * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
     22  * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
     23  * NON-INFRINGEMENT.  IN NO EVENT SHALL ATI, PRECISION INSIGHT, VA LINUX
     24  * SYSTEMS AND/OR THEIR SUPPLIERS BE LIABLE FOR ANY CLAIM, DAMAGES OR
     25  * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
     26  * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
     27  * OTHER DEALINGS IN THE SOFTWARE.
     28  */
     29 
     30 #ifdef HAVE_CONFIG_H
     31 #include "config.h"
     32 #endif
     33 
     34 #include <string.h>
     35 
     36 /*
     37  * Authors:
     38  *   Rickard E. Faith <faith (at) valinux.com>
     39  *   Kevin E. Martin <martin (at) valinux.com>
     40  */
     41 
     42 #include "r128_version.h"
     43 #include "atipcirename.h"
     44 
     45 #include "xf86.h"
     46 
     47 #include "r128_probe.h"
     48 
     49 #ifndef XSERVER_LIBPCIACCESS
     50 static Bool R128Probe(DriverPtr drv, int flags);
     51 #endif
     52 
     53 SymTabRec R128Chipsets[] = {
     54     { PCI_CHIP_RAGE128LE, "ATI Rage 128 Mobility M3 LE (PCI)" },
     55     { PCI_CHIP_RAGE128LF, "ATI Rage 128 Mobility M3 LF (AGP)" },
     56     { PCI_CHIP_RAGE128MF, "ATI Rage 128 Mobility M4 MF (AGP)" },
     57     { PCI_CHIP_RAGE128ML, "ATI Rage 128 Mobility M4 ML (AGP)" },
     58     { PCI_CHIP_RAGE128PA, "ATI Rage 128 Pro GL PA (PCI/AGP)" },
     59     { PCI_CHIP_RAGE128PB, "ATI Rage 128 Pro GL PB (PCI/AGP)" },
     60     { PCI_CHIP_RAGE128PC, "ATI Rage 128 Pro GL PC (PCI/AGP)" },
     61     { PCI_CHIP_RAGE128PD, "ATI Rage 128 Pro GL PD (PCI)" },
     62     { PCI_CHIP_RAGE128PE, "ATI Rage 128 Pro GL PE (PCI/AGP)" },
     63     { PCI_CHIP_RAGE128PF, "ATI Rage 128 Pro GL PF (AGP)" },
     64     { PCI_CHIP_RAGE128PG, "ATI Rage 128 Pro VR PG (PCI/AGP)" },
     65     { PCI_CHIP_RAGE128PH, "ATI Rage 128 Pro VR PH (PCI/AGP)" },
     66     { PCI_CHIP_RAGE128PI, "ATI Rage 128 Pro VR PI (PCI/AGP)" },
     67     { PCI_CHIP_RAGE128PJ, "ATI Rage 128 Pro VR PJ (PCI/AGP)" },
     68     { PCI_CHIP_RAGE128PK, "ATI Rage 128 Pro VR PK (PCI/AGP)" },
     69     { PCI_CHIP_RAGE128PL, "ATI Rage 128 Pro VR PL (PCI/AGP)" },
     70     { PCI_CHIP_RAGE128PM, "ATI Rage 128 Pro VR PM (PCI/AGP)" },
     71     { PCI_CHIP_RAGE128PN, "ATI Rage 128 Pro VR PN (PCI/AGP)" },
     72     { PCI_CHIP_RAGE128PO, "ATI Rage 128 Pro VR PO (PCI/AGP)" },
     73     { PCI_CHIP_RAGE128PP, "ATI Rage 128 Pro VR PP (PCI)" },
     74     { PCI_CHIP_RAGE128PQ, "ATI Rage 128 Pro VR PQ (PCI/AGP)" },
     75     { PCI_CHIP_RAGE128PR, "ATI Rage 128 Pro VR PR (PCI)" },
     76     { PCI_CHIP_RAGE128PS, "ATI Rage 128 Pro VR PS (PCI/AGP)" },
     77     { PCI_CHIP_RAGE128PT, "ATI Rage 128 Pro VR PT (PCI/AGP)" },
     78     { PCI_CHIP_RAGE128PU, "ATI Rage 128 Pro VR PU (PCI/AGP)" },
     79     { PCI_CHIP_RAGE128PV, "ATI Rage 128 Pro VR PV (PCI/AGP)" },
     80     { PCI_CHIP_RAGE128PW, "ATI Rage 128 Pro VR PW (PCI/AGP)" },
     81     { PCI_CHIP_RAGE128PX, "ATI Rage 128 Pro VR PX (PCI/AGP)" },
     82     { PCI_CHIP_RAGE128RE, "ATI Rage 128 GL RE (PCI)" },
     83     { PCI_CHIP_RAGE128RF, "ATI Rage 128 GL RF (AGP)" },
     84     { PCI_CHIP_RAGE128RG, "ATI Rage 128 RG (AGP)" },
     85     { PCI_CHIP_RAGE128RK, "ATI Rage 128 VR RK (PCI)" },
     86     { PCI_CHIP_RAGE128RL, "ATI Rage 128 VR RL (AGP)" },
     87     { PCI_CHIP_RAGE128SE, "ATI Rage 128 4X SE (PCI/AGP)" },
     88     { PCI_CHIP_RAGE128SF, "ATI Rage 128 4X SF (PCI/AGP)" },
     89     { PCI_CHIP_RAGE128SG, "ATI Rage 128 4X SG (PCI/AGP)" },
     90     { PCI_CHIP_RAGE128SH, "ATI Rage 128 4X SH (PCI/AGP)" },
     91     { PCI_CHIP_RAGE128SK, "ATI Rage 128 4X SK (PCI/AGP)" },
     92     { PCI_CHIP_RAGE128SL, "ATI Rage 128 4X SL (PCI/AGP)" },
     93     { PCI_CHIP_RAGE128SM, "ATI Rage 128 4X SM (AGP)" },
     94     { PCI_CHIP_RAGE128SN, "ATI Rage 128 4X SN (PCI/AGP)" },
     95     { PCI_CHIP_RAGE128TF, "ATI Rage 128 Pro ULTRA TF (AGP)" },
     96     { PCI_CHIP_RAGE128TL, "ATI Rage 128 Pro ULTRA TL (AGP)" },
     97     { PCI_CHIP_RAGE128TR, "ATI Rage 128 Pro ULTRA TR (AGP)" },
     98     { PCI_CHIP_RAGE128TS, "ATI Rage 128 Pro ULTRA TS (AGP?)" },
     99     { PCI_CHIP_RAGE128TT, "ATI Rage 128 Pro ULTRA TT (AGP?)" },
    100     { PCI_CHIP_RAGE128TU, "ATI Rage 128 Pro ULTRA TU (AGP?)" },
    101     { -1,                 NULL }
    102 };
    103 
    104 static PciChipsets R128PciChipsets[] = {
    105     { PCI_CHIP_RAGE128LE, PCI_CHIP_RAGE128LE, RES_SHARED_VGA },
    106     { PCI_CHIP_RAGE128LF, PCI_CHIP_RAGE128LF, RES_SHARED_VGA },
    107     { PCI_CHIP_RAGE128MF, PCI_CHIP_RAGE128MF, RES_SHARED_VGA },
    108     { PCI_CHIP_RAGE128ML, PCI_CHIP_RAGE128ML, RES_SHARED_VGA },
    109     { PCI_CHIP_RAGE128PA, PCI_CHIP_RAGE128PA, RES_SHARED_VGA },
    110     { PCI_CHIP_RAGE128PB, PCI_CHIP_RAGE128PB, RES_SHARED_VGA },
    111     { PCI_CHIP_RAGE128PC, PCI_CHIP_RAGE128PC, RES_SHARED_VGA },
    112     { PCI_CHIP_RAGE128PD, PCI_CHIP_RAGE128PD, RES_SHARED_VGA },
    113     { PCI_CHIP_RAGE128PE, PCI_CHIP_RAGE128PE, RES_SHARED_VGA },
    114     { PCI_CHIP_RAGE128PF, PCI_CHIP_RAGE128PF, RES_SHARED_VGA },
    115     { PCI_CHIP_RAGE128PG, PCI_CHIP_RAGE128PG, RES_SHARED_VGA },
    116     { PCI_CHIP_RAGE128PH, PCI_CHIP_RAGE128PH, RES_SHARED_VGA },
    117     { PCI_CHIP_RAGE128PI, PCI_CHIP_RAGE128PI, RES_SHARED_VGA },
    118     { PCI_CHIP_RAGE128PJ, PCI_CHIP_RAGE128PJ, RES_SHARED_VGA },
    119     { PCI_CHIP_RAGE128PK, PCI_CHIP_RAGE128PK, RES_SHARED_VGA },
    120     { PCI_CHIP_RAGE128PL, PCI_CHIP_RAGE128PL, RES_SHARED_VGA },
    121     { PCI_CHIP_RAGE128PM, PCI_CHIP_RAGE128PM, RES_SHARED_VGA },
    122     { PCI_CHIP_RAGE128PN, PCI_CHIP_RAGE128PN, RES_SHARED_VGA },
    123     { PCI_CHIP_RAGE128PO, PCI_CHIP_RAGE128PO, RES_SHARED_VGA },
    124     { PCI_CHIP_RAGE128PP, PCI_CHIP_RAGE128PP, RES_SHARED_VGA },
    125     { PCI_CHIP_RAGE128PQ, PCI_CHIP_RAGE128PQ, RES_SHARED_VGA },
    126     { PCI_CHIP_RAGE128PR, PCI_CHIP_RAGE128PR, RES_SHARED_VGA },
    127     { PCI_CHIP_RAGE128PS, PCI_CHIP_RAGE128PS, RES_SHARED_VGA },
    128     { PCI_CHIP_RAGE128PT, PCI_CHIP_RAGE128PT, RES_SHARED_VGA },
    129     { PCI_CHIP_RAGE128PU, PCI_CHIP_RAGE128PU, RES_SHARED_VGA },
    130     { PCI_CHIP_RAGE128PV, PCI_CHIP_RAGE128PV, RES_SHARED_VGA },
    131     { PCI_CHIP_RAGE128PW, PCI_CHIP_RAGE128PW, RES_SHARED_VGA },
    132     { PCI_CHIP_RAGE128PX, PCI_CHIP_RAGE128PX, RES_SHARED_VGA },
    133     { PCI_CHIP_RAGE128RE, PCI_CHIP_RAGE128RE, RES_SHARED_VGA },
    134     { PCI_CHIP_RAGE128RF, PCI_CHIP_RAGE128RF, RES_SHARED_VGA },
    135     { PCI_CHIP_RAGE128RG, PCI_CHIP_RAGE128RG, RES_SHARED_VGA },
    136     { PCI_CHIP_RAGE128RK, PCI_CHIP_RAGE128RK, RES_SHARED_VGA },
    137     { PCI_CHIP_RAGE128RL, PCI_CHIP_RAGE128RL, RES_SHARED_VGA },
    138     { PCI_CHIP_RAGE128SE, PCI_CHIP_RAGE128SE, RES_SHARED_VGA },
    139     { PCI_CHIP_RAGE128SF, PCI_CHIP_RAGE128SF, RES_SHARED_VGA },
    140     { PCI_CHIP_RAGE128SG, PCI_CHIP_RAGE128SG, RES_SHARED_VGA },
    141     { PCI_CHIP_RAGE128SH, PCI_CHIP_RAGE128SH, RES_SHARED_VGA },
    142     { PCI_CHIP_RAGE128SK, PCI_CHIP_RAGE128SK, RES_SHARED_VGA },
    143     { PCI_CHIP_RAGE128SL, PCI_CHIP_RAGE128SL, RES_SHARED_VGA },
    144     { PCI_CHIP_RAGE128SM, PCI_CHIP_RAGE128SM, RES_SHARED_VGA },
    145     { PCI_CHIP_RAGE128SN, PCI_CHIP_RAGE128SN, RES_SHARED_VGA },
    146     { PCI_CHIP_RAGE128TF, PCI_CHIP_RAGE128TF, RES_SHARED_VGA },
    147     { PCI_CHIP_RAGE128TL, PCI_CHIP_RAGE128TL, RES_SHARED_VGA },
    148     { PCI_CHIP_RAGE128TR, PCI_CHIP_RAGE128TR, RES_SHARED_VGA },
    149     { PCI_CHIP_RAGE128TS, PCI_CHIP_RAGE128TS, RES_SHARED_VGA },
    150     { PCI_CHIP_RAGE128TT, PCI_CHIP_RAGE128TT, RES_SHARED_VGA },
    151     { PCI_CHIP_RAGE128TU, PCI_CHIP_RAGE128TU, RES_SHARED_VGA },
    152     { -1,                 -1,                 RES_UNDEFINED }
    153 };
    154 
    155 #ifdef XSERVER_LIBPCIACCESS
    156 
    157 static const struct pci_id_match r128_device_match[] = {
    158     ATI_DEVICE_MATCH( PCI_CHIP_RAGE128LE, 0 ),
    159     ATI_DEVICE_MATCH( PCI_CHIP_RAGE128LF, 0 ),
    160     ATI_DEVICE_MATCH( PCI_CHIP_RAGE128MF, 0 ),
    161     ATI_DEVICE_MATCH( PCI_CHIP_RAGE128ML, 0 ),
    162     ATI_DEVICE_MATCH( PCI_CHIP_RAGE128PA, 0 ),
    163     ATI_DEVICE_MATCH( PCI_CHIP_RAGE128PB, 0 ),
    164     ATI_DEVICE_MATCH( PCI_CHIP_RAGE128PC, 0 ),
    165     ATI_DEVICE_MATCH( PCI_CHIP_RAGE128PD, 0 ),
    166     ATI_DEVICE_MATCH( PCI_CHIP_RAGE128PE, 0 ),
    167     ATI_DEVICE_MATCH( PCI_CHIP_RAGE128PF, 0 ),
    168     ATI_DEVICE_MATCH( PCI_CHIP_RAGE128PG, 0 ),
    169     ATI_DEVICE_MATCH( PCI_CHIP_RAGE128PH, 0 ),
    170     ATI_DEVICE_MATCH( PCI_CHIP_RAGE128PI, 0 ),
    171     ATI_DEVICE_MATCH( PCI_CHIP_RAGE128PJ, 0 ),
    172     ATI_DEVICE_MATCH( PCI_CHIP_RAGE128PK, 0 ),
    173     ATI_DEVICE_MATCH( PCI_CHIP_RAGE128PL, 0 ),
    174     ATI_DEVICE_MATCH( PCI_CHIP_RAGE128PM, 0 ),
    175     ATI_DEVICE_MATCH( PCI_CHIP_RAGE128PN, 0 ),
    176     ATI_DEVICE_MATCH( PCI_CHIP_RAGE128PO, 0 ),
    177     ATI_DEVICE_MATCH( PCI_CHIP_RAGE128PP, 0 ),
    178     ATI_DEVICE_MATCH( PCI_CHIP_RAGE128PQ, 0 ),
    179     ATI_DEVICE_MATCH( PCI_CHIP_RAGE128PR, 0 ),
    180     ATI_DEVICE_MATCH( PCI_CHIP_RAGE128PS, 0 ),
    181     ATI_DEVICE_MATCH( PCI_CHIP_RAGE128PT, 0 ),
    182     ATI_DEVICE_MATCH( PCI_CHIP_RAGE128PU, 0 ),
    183     ATI_DEVICE_MATCH( PCI_CHIP_RAGE128PV, 0 ),
    184     ATI_DEVICE_MATCH( PCI_CHIP_RAGE128PW, 0 ),
    185     ATI_DEVICE_MATCH( PCI_CHIP_RAGE128PX, 0 ),
    186     ATI_DEVICE_MATCH( PCI_CHIP_RAGE128RE, 0 ),
    187     ATI_DEVICE_MATCH( PCI_CHIP_RAGE128RF, 0 ),
    188     ATI_DEVICE_MATCH( PCI_CHIP_RAGE128RG, 0 ),
    189     ATI_DEVICE_MATCH( PCI_CHIP_RAGE128RK, 0 ),
    190     ATI_DEVICE_MATCH( PCI_CHIP_RAGE128RL, 0 ),
    191     ATI_DEVICE_MATCH( PCI_CHIP_RAGE128SE, 0 ),
    192     ATI_DEVICE_MATCH( PCI_CHIP_RAGE128SF, 0 ),
    193     ATI_DEVICE_MATCH( PCI_CHIP_RAGE128SG, 0 ),
    194     ATI_DEVICE_MATCH( PCI_CHIP_RAGE128SH, 0 ),
    195     ATI_DEVICE_MATCH( PCI_CHIP_RAGE128SK, 0 ),
    196     ATI_DEVICE_MATCH( PCI_CHIP_RAGE128SL, 0 ),
    197     ATI_DEVICE_MATCH( PCI_CHIP_RAGE128SM, 0 ),
    198     ATI_DEVICE_MATCH( PCI_CHIP_RAGE128SN, 0 ),
    199     ATI_DEVICE_MATCH( PCI_CHIP_RAGE128TF, 0 ),
    200     ATI_DEVICE_MATCH( PCI_CHIP_RAGE128TL, 0 ),
    201     ATI_DEVICE_MATCH( PCI_CHIP_RAGE128TR, 0 ),
    202     ATI_DEVICE_MATCH( PCI_CHIP_RAGE128TS, 0 ),
    203     ATI_DEVICE_MATCH( PCI_CHIP_RAGE128TT, 0 ),
    204     ATI_DEVICE_MATCH( PCI_CHIP_RAGE128TU, 0 ),
    205     { 0, 0, 0 }
    206 };
    207 
    208 #endif /* XSERVER_LIBPCIACCESS */
    209 
    210 _X_EXPORT int gR128EntityIndex = -1;
    211 
    212 /* Return the options for supported chipset 'n'; NULL otherwise */
    213 static const OptionInfoRec *
    214 R128AvailableOptions(int chipid, int busid)
    215 {
    216     return R128OptionsWeak();
    217 }
    218 
    219 /* Return the string name for supported chipset 'n'; NULL otherwise. */
    220 static void
    221 R128Identify(int flags)
    222 {
    223     xf86PrintChipsets(R128_NAME,
    224 		      "Driver for ATI Rage 128 chipsets",
    225 		      R128Chipsets);
    226 }
    227 
    228 static Bool
    229 r128_get_scrninfo(int entity_num)
    230 {
    231     ScrnInfoPtr   pScrn = NULL;
    232     EntityInfoPtr pEnt;
    233     DevUnion*     pPriv;
    234 
    235     pScrn = xf86ConfigPciEntity(pScrn, 0, entity_num, R128PciChipsets,
    236                                 NULL,
    237                                 NULL, NULL, NULL, NULL);
    238 
    239     if (!pScrn)
    240         return FALSE;
    241 
    242     pScrn->driverVersion = R128_VERSION_CURRENT;
    243     pScrn->driverName    = R128_DRIVER_NAME;
    244     pScrn->name          = R128_NAME;
    245 #ifdef XSERVER_LIBPCIACCESS
    246     pScrn->Probe         = NULL;
    247 #else
    248     pScrn->Probe         = R128Probe;
    249 #endif
    250     pScrn->PreInit       = R128PreInit;
    251     pScrn->ScreenInit    = R128ScreenInit;
    252     pScrn->SwitchMode    = R128SwitchMode;
    253     pScrn->AdjustFrame   = R128AdjustFrame;
    254     pScrn->EnterVT       = R128EnterVT;
    255     pScrn->LeaveVT       = R128LeaveVT;
    256     pScrn->FreeScreen    = R128FreeScreen;
    257     pScrn->ValidMode     = R128ValidMode;
    258 
    259     pEnt = xf86GetEntityInfo(entity_num);
    260 
    261     /* Allocate private entity used for convenience with one or two heads. */
    262     if (gR128EntityIndex < 0) {
    263         gR128EntityIndex = xf86AllocateEntityPrivateIndex();
    264         pPriv = xf86GetEntityPrivate(pScrn->entityList[0], gR128EntityIndex);
    265 
    266         if (!pPriv->ptr) {
    267             R128EntPtr pR128Ent;
    268             pPriv->ptr = XNFcallocarray(1, sizeof(R128EntRec));
    269             pR128Ent = pPriv->ptr;
    270             pR128Ent->HasSecondary = FALSE;
    271             pR128Ent->IsSecondaryRestored = FALSE;
    272         }
    273     }
    274 
    275     /* mobility cards support Dual-Head, mark the entity as shareable*/
    276     if (pEnt->chipset == PCI_CHIP_RAGE128LE ||
    277         pEnt->chipset == PCI_CHIP_RAGE128LF ||
    278         pEnt->chipset == PCI_CHIP_RAGE128MF ||
    279         pEnt->chipset == PCI_CHIP_RAGE128ML)
    280     {
    281         static int instance = 0;
    282 
    283         xf86SetEntitySharable(entity_num);
    284 
    285         xf86SetEntityInstanceForScreen(pScrn,
    286                                        pScrn->entityList[0],
    287                                        instance);
    288 
    289         instance++;
    290     }
    291 
    292     free(pEnt);
    293 
    294     return TRUE;
    295 }
    296 
    297 #ifndef XSERVER_LIBPCIACCESS
    298 
    299 /* Return TRUE if chipset is present; FALSE otherwise. */
    300 static Bool
    301 R128Probe(DriverPtr drv, int flags)
    302 {
    303     int           numUsed;
    304     int           numDevSections;
    305     int           *usedChips;
    306     GDevPtr       *devSections;
    307     Bool          foundScreen = FALSE;
    308     int           i;
    309 
    310     if (!xf86GetPciVideoInfo()) return FALSE;
    311 
    312     numDevSections = xf86MatchDevice(R128_NAME, &devSections);
    313 
    314     if (!numDevSections) return FALSE;
    315 
    316     numUsed = xf86MatchPciInstances(R128_NAME,
    317 				    PCI_VENDOR_ATI,
    318 				    R128Chipsets,
    319 				    R128PciChipsets,
    320 				    devSections,
    321 				    numDevSections,
    322 				    drv,
    323 				    &usedChips);
    324 
    325     if (numUsed<=0) return FALSE;
    326 
    327     if (flags & PROBE_DETECT)
    328 	foundScreen = TRUE;
    329     else for (i = 0; i < numUsed; i++) {
    330 	if (r128_get_scrninfo(usedChips[i]))
    331 	    foundScreen = TRUE;
    332     }
    333 
    334     free(usedChips);
    335     free(devSections);
    336 
    337     return foundScreen;
    338 }
    339 
    340 #else /* XSERVER_LIBPCIACCESS */
    341 
    342 static Bool
    343 r128_pci_probe(
    344     DriverPtr          pDriver,
    345     int                entity_num,
    346     struct pci_device *device,
    347     intptr_t           match_data
    348 )
    349 {
    350     return r128_get_scrninfo(entity_num);
    351 }
    352 
    353 #endif /* XSERVER_LIBPCIACCESS */
    354 
    355 _X_EXPORT DriverRec R128 =
    356 {
    357     R128_VERSION_CURRENT,
    358     R128_DRIVER_NAME,
    359     R128Identify,
    360 #ifdef XSERVER_LIBPCIACCESS
    361     NULL,
    362 #else
    363     R128Probe,
    364 #endif
    365     R128AvailableOptions,
    366     NULL,
    367     0,
    368     NULL,
    369 #ifdef XSERVER_LIBPCIACCESS
    370     r128_device_match,
    371     r128_pci_probe,
    372 #endif
    373 #ifdef XSERVER_PLATFORM_BUS
    374     NULL
    375 #endif
    376 };
    377