S3SAVSetGBD();
S3SAVGEReset(int from_timeout, int line, char *file){    unsigned char tmp;    int r;    int32  fifo_control, miu_control, streams_timeout, misc_timeout;    if (from_timeout) {      static int n=0;      if (n++ < 10 || xf86Verbose > 1)	ErrorF("\tS3SAVGEReset called from %s line %d\n",file,line);    }    else      WaitIdleEmpty();    if (from_timeout) {      /* reset will trash these registers, so save them */      fifo_control    = ((mmtr)s3savMmioMem)->memport_regs.regs.fifo_control;      miu_control     = ((mmtr)s3savMmioMem)->memport_regs.regs.miu_control;      streams_timeout = ((mmtr)s3savMmioMem)->memport_regs.regs.streams_timeout;      misc_timeout    = ((mmtr)s3savMmioMem)->memport_regs.regs.misc_timeout;    }    outb(vgaCRIndex, 0x66);    tmp = inb(vgaCRReg);    usleep(10000);    for (r=1; r<10; r++) {  /* try multiple times to avoid lockup of ViRGE/MX */      int success;      outb(vgaCRReg, tmp | 0x02);      usleep(10000);      outb(vgaCRReg, tmp & ~0x02);      usleep(10000);      if (!from_timeout) 	WaitIdleEmpty();      SETB_DEST_SRC_STR(s3vPriv.Bpl, s3vPriv.Bpl);       usleep(10000);      switch( s3vPriv.chip ) {        case S3_SAVAGE3D:        case S3_SAVAGE3D_MV:	  success = (STATUS_WORD0 & 0x0008ffff) == 0x00080000;	  break;	case S3_SAVAGE4:	  success = (ALT_STATUS_WORD0 & 0x0081ffff) == 0x00800000;	  break;	case S3_SAVAGE2000:	  success = (ALT_STATUS_WORD0 & 0x008fffff) == 0;	  break;      }      if( !success ) {        usleep(10000);	ErrorF("restarting S3 graphics engine reset %2d ...\n",r);      }      else	break;    }    if (from_timeout) {      /* restore trashed registers */      ((mmtr)s3savMmioMem)->memport_regs.regs.fifo_control    = fifo_control;      ((mmtr)s3savMmioMem)->memport_regs.regs.miu_control     = miu_control;      ((mmtr)s3savMmioMem)->memport_regs.regs.streams_timeout = streams_timeout;      ((mmtr)s3savMmioMem)->memport_regs.regs.misc_timeout    = misc_timeout;    }    SETB_SRC_BASE(0);    SETB_DEST_BASE(0);       /* Now write some default rgisters and reset cached values */    s3vCached_CLIP_LR = -1;    s3vCached_CLIP_TB = -1;    CACHE_SETB_CLIP_L_R(0, s3vPriv.Width);    CACHE_SETB_CLIP_T_B(0, s3vPriv.ScissB);    s3vCached_MONO_PATTERN0 = 0;    s3vCached_MONO_PATTERN1 = 0;    CACHE_SETB_MONO_PAT0(~0);    CACHE_SETB_MONO_PAT1(~0);       s3vCached_RWIDTH_HEIGHT = -1;    s3vCached_PAT_FGCLR = -1;    s3vCached_PAT_BGCLR = -1;    s3vCached_CMD_SET = -1;    if (xf86Verbose > 1)        ErrorF("ViRGE register cache hits: %d misses: %d\n",            s3vCacheHit, s3vCacheMiss);        s3vCacheHit = 0; s3vCacheMiss = 0;}