map_64m[((pcrp->_base2+0x3ffffff) >> 26) & 0x3f] = 1;
s3GetPCIInfo(){   static S3PCIInformation info = {0, };   pciConfigPtr pcrp, *pcrpp;   Bool found = FALSE;   int i = 0;   pcrpp = xf86scanpci(s3InfoRec.scrnIndex);   if (!pcrpp)      return NULL;   while ((pcrp = pcrpp[i])) {      if (pcrp->_vendor == PCI_S3_VENDOR_ID) {	 found = TRUE;	 switch (pcrp->_device) {	 case PCI_ViRGE:	    info.ChipType = S3_ViRGE;	    break;	 case PCI_ViRGE_VX:	    info.ChipType = S3_ViRGE_VX;	    break;	 case PCI_ViRGE_DXGX:	    info.ChipType = S3_ViRGE_DXGX;	    break;	 case PCI_ViRGE_GX2:	    info.ChipType = S3_ViRGE_GX2;	    break;	 case PCI_ViRGE_MX:	    info.ChipType = S3_ViRGE_MX;	    break;	 default:	    info.ChipType = S3_UNKNOWN;	    info.DevID = pcrp->_device;	    break;	 }	 info.ChipRev = pcrp->_rev_id;	 info.MemBase = pcrp->_base0 & 0xFF800000;#ifdef PC98_GA968	 xf86writepci(s3InfoRec.scrnIndex, pcrp->_bus, pcrp->_cardnum,			pcrp->_func,			PCI_CMD_STAT_REG, PCI_CMD_MASK,			PCI_CMD_IO_ENABLE | PCI_CMD_MEM_ENABLE);#endif	 break;      }      i++;   }   if (pcrp == NULL) return NULL;   /* for new mmio we have to ensure that the PCI base address is    * 64MB aligned and that there are no address collitions within 64MB.    * S3 868/968 only pretend to need 32MB and thus fool    * the BIOS PCI auto configuration :-(  */   if (info.ChipType == S3_ViRGE) {      unsigned long base0;      char *probed;      char map_64m[64];      int j;      if (s3InfoRec.MemBase == 0) {	 base0  = info.MemBase;	 probed = XCONFIG_PROBED;      }      else {	 base0  = s3InfoRec.MemBase;	 probed = XCONFIG_GIVEN;      }      /* map allocated 64MB blocks */      for (j=0; j<64; j++) map_64m[j] = 0;      map_64m[63] = 1;  /* don't use the last 64MB area */      for (j=0; (pcrp = pcrpp[j]); j++) {	 if (i != j) {	    map_64m[ (pcrp->_base0 >> 26) & 0x3f] = 1;	    map_64m[((pcrp->_base0+0x3ffffff) >> 26) & 0x3f] = 1;	    map_64m[ (pcrp->_base1 >> 26) & 0x3f] = 1;	    map_64m[((pcrp->_base1+0x3ffffff) >> 26) & 0x3f] = 1;	    map_64m[ (pcrp->_base2 >> 26) & 0x3f] = 1;	    map_64m[((pcrp->_base2+0x3ffffff) >> 26) & 0x3f] = 1;	    map_64m[ (pcrp->_base3 >> 26) & 0x3f] = 1;	    map_64m[((pcrp->_base3+0x3ffffff) >> 26) & 0x3f] = 1;	    map_64m[ (pcrp->_base4 >> 26) & 0x3f] = 1;	    map_64m[((pcrp->_base4+0x3ffffff) >> 26) & 0x3f] = 1;	    map_64m[ (pcrp->_base5 >> 26) & 0x3f] = 1;	    map_64m[((pcrp->_base5+0x3ffffff) >> 26) & 0x3f] = 1;	 }      }      /* check for 64MB alignment and free space */      if ((base0 & 0x3ffffff) ||	  map_64m[(base0 >> 26) & 0x3f] ||	  map_64m[((base0+0x3ffffff) >> 26) & 0x3f]) {	 for (j=63; j>=16 && map_64m[j]; j--);	 info.MemBase = ((unsigned long)j) << 26;	 ErrorF("%s %s: PCI: base address not correctly aligned or address conflict\n",		probed, s3InfoRec.name);	 ErrorF("\t\tbase address changed from 0x%08lx to 0x%08lx\n",		base0, info.MemBase);         xf86writepci(s3InfoRec.scrnIndex, pcrpp[i]->_bus, pcrpp[i]->_cardnum,		    pcrpp[i]->_func, PCI_MAP_REG_START, ~0L,		    info.MemBase | PCI_MAP_MEMORY | PCI_MAP_MEMORY_TYPE_32BIT);      }      s3Port59 = (info.MemBase >> 24) & 0xfc;      s3Port5A = 0;   }   else {      if (s3InfoRec.MemBase != 0) {	 s3Port59 =  s3InfoRec.MemBase >> 24;	 s3Port5A = (s3InfoRec.MemBase >> 16) & 0x08;      }      else {	 s3Port59 =  info.MemBase >> 24;	 s3Port5A = (info.MemBase >> 16) & 0x08;      }   }   /* Free PCI information */   xf86cleanpci();   if (found && xf86Verbose) {      if (info.ChipType != S3_UNKNOWN) {	 ErrorF("%s %s: PCI: %s rev %x, Linear FB @ 0x%08lx\n", XCONFIG_PROBED,		s3InfoRec.name, xf86TokenToString(s3ChipTable, info.ChipType),		info.ChipRev, info.MemBase);      } else {	 ErrorF("%s %s: PCI: unknown (please report), ID 0x%04x rev %x,"		" Linear FB @ 0x%08lx\n", XCONFIG_PROBED,		s3InfoRec.name, info.DevID, info.ChipRev, info.MemBase);      }   }   if (found)      return &info;   else      return NULL;}