⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 ide_disk.c

📁 德国Hyperstone公司dsp的CF卡驱动程序
💻 C
📖 第 1 页 / 共 2 页
字号:
//DelayBy(1000);
    }
}

static void WriteSectors(unsigned int drive, unsigned short *buffer,
			 unsigned int NumberOfSectors)
{
int iCount, j, DataReg;
unsigned short data16;

  while (drivebusy(drive));
  outpw(drive_tab[drive].xHD_STATUS, WIN_WRITE);
  DataReg = drive_tab[drive].xHD_DATA;
  for (j=0;  j < NumberOfSectors; j++)
    {
      if (!testAltSTAT(drive, READY_STAT | SEEK_STAT | DRQ_STAT))
	break;
#ifdef __DSC_CFA__
   UpdateMCR(1 << 5, 1 << 4);
#endif
      for (iCount=SECTOR_SHORTS/2; iCount > 0; iCount--)
	{
	  data16 = CvtByteOrder16(*buffer++);
	  outph(DataReg, data16);
	  data16 = CvtByteOrder16(*buffer++);
	  outph(DataReg, data16);
	}
#ifdef __DSC_CFA__
   UpdateMCR(3 << 4, 0);
#endif
//DelayBy(1000);
    }
}
/* Read Hard Drive Identify Structure */
static int GetIdentifyStructure (int drive, struct hd_driveid *hd_id) {
   unsigned short *shptr;
   int i;

   reset_IDE_DRIVE(drive);

	outpw(drive_tab[drive].xHD_STATUS, WIN_IDENTIFY);
   while (drivebusy(drive));

   shptr = (unsigned short *)hd_id;
#ifdef __DSC_CFA__
   UpdateMCR(1 << 5, 1 << 4);
#endif
   for (i=0; i < SECTOR_SHORTS; i++)
      *shptr++ = inph(drive_tab[drive].xHD_DATA);
#ifdef __DSC_CFA__
   UpdateMCR(3 << 4, 0);
#endif
   return 0;
}


/*
     Initialize Drive it have to be always the first function.

     return:   at  ok          0
	            at  error    <> 0
*/

static int  InitializeDrive(int drive, struct hd_driveid *hd_id) {

    unsigned long size;

    if (-1 ==  GetIdentifyStructure (drive, hd_id))
       return -1;
    _hd_ident[drive].initialized = 1;
    _hd_ident[drive].heads       =  (unsigned char)hd_id->heads;
    _hd_ident[drive].sectors     =  (unsigned char)hd_id->sectors;
    _hd_ident[drive].cylinders   =  hd_id->cyls;
    _hd_ident[drive].start       =  0;

    if (hd_id->capability & LBA_capability) {
       _hd_ident[drive].lba = 2;
       size =  CvtByteOrder32(hd_id->lba_capacity);
    }
    else {
       _hd_ident[drive].lba = 0;
       size = _hd_ident[drive].heads * _hd_ident[drive].sectors \
                                     * _hd_ident[drive].cylinders;
    }
    _hd_ident[drive].tot_sectors =  size;
    return 0;
}


/*

        Read Partition Sector
        drive:      0..0
        return value:  at ok       0
                       at error    -1
*/
static int  ReadPartitionSector(int drive, struct PART_SECT *p_sect) {

      /*    read partiotion sector                   */
     return r_w_Disk(drive, 0, 1, (unsigned short*)p_sect, 1);
}


/*

      GetPartitionData (int drive, struct PART_SECT *p_sect)
      reads partition data, convert to big endian and initialize _hd_ident
      structure.

*/
static int  GetPartitionData(int drive, struct PART_SECT *p_sect) {
     int i;

      /*    partiotion sector                   */
     if (ReadPartitionSector(drive, p_sect))
        return -1;
     for (i=0; i < 4; i++) {
        if (p_sect->part_tab[i].partstatus == 0x80) {
            _hd_ident[drive].activ_part = i;
        }
     }
     if (CvtByteOrder16(p_sect->id_code) != 0xAA55)  {
         fprintf(stderr, "Partition has not valid identifier (0xAA55).\n");
         return -2;
     }
     else {
        for (i=0; i < 4; i++) {
           _hd_ident[drive].part_tab[i].partstatus = p_sect->part_tab[i].partstatus;
           _hd_ident[drive].part_tab[i].RW_head_part_start = p_sect->part_tab[i].RW_head_part_start;
           _hd_ident[drive].part_tab[i].sect_part_start = p_sect->part_tab[i].sect_part_start;
           _hd_ident[drive].part_tab[i].cyl_part_start = p_sect->part_tab[i].cyl_part_start;
           _hd_ident[drive].part_tab[i].sys_ind = p_sect->part_tab[i].sys_ind;
           _hd_ident[drive].part_tab[i].RW_head_part_end = p_sect->part_tab[i].RW_head_part_end;
           _hd_ident[drive].part_tab[i].sect_part_end = p_sect->part_tab[i].sect_part_end;
           _hd_ident[drive].part_tab[i].cyl_part_end = p_sect->part_tab[i].cyl_part_end;
           _hd_ident[drive].part_tab[i].dist = CvtByteOrder32(p_sect->part_tab[i].dist);
           _hd_ident[drive].part_tab[i].count_sect_part = CvtByteOrder32(p_sect->part_tab[i].count_sect_part);
        }
     }
     return 0;

}


#ifdef __DSC_CFA__

int installDrive(int drive) {
   int result;

   hardware_drv.cs1       = (1 << 31) | (1 << 12);
   hardware_drv.cs2       = (1 << 31) | (1 << 12) | 8;
   hardware_drv.addroffs  = 0;
   hardware_drv.timeing   = 0;
   hardware_drv.word_access = (1<<13);
   hardware_drv.irq       = 3;
   hardware_drv.drive     = drive;

   Outpw(REG0SEL, 1);   /* enable PCMCIA  */
   Outpw(REG2SEL, Inpw(REG2SEL) & ~(1<<2));   /* enable PCMCIA Wait Pin */
   UpdateBCR( (0x05 << 24) | 0x0a, (0x0a<<24) | 5);
     // mem2: 1 setup, 6 access, 2 hold
   UpdateMCR( 3 << 4,  1 << 26);
     // mem2: 8 bit, wait pin enable

   result = * (char *) 0x80001007;   /* status register */

   _init_hardware_tab( &hardware_drv, 1 << 13);
   result = reset_IDE_DRIVE(hardware_drv.drive);
   return result;
}

#else
#define SETUP_2  (1<<8)
#define ACCESS_6 (2<<5)
#define HOLD_2   (1<<3)

static int installDrive(int drive) {

   hardware_drv.drive     = drive;
   hardware_drv.cs1       = 2 << 24;
   hardware_drv.cs2       = 1 << 24;
   hardware_drv.addroffs  = 13;
   hardware_drv.timeing   = SETUP_2 | ACCESS_6 | HOLD_2;
   hardware_drv.word_access = 0;
//   hardware_drv.timeing   = 0x3F8;
   hardware_drv.irq       = 3;

   _init_hardware_tab( &hardware_drv, 0);
   return reset_IDE_DRIVE(hardware_drv.drive);
}
#endif

/*

        drive:      0
		  partnum:    0..3
        return value:  at ok       0, boot sector contents int boot_sect
                       at error    -1
*/
int  ReadBOOTSector(struct BOOT_SECT * boot_sect, int drive, int partnum /* 0..3 */) {

     if (_hd_ident[drive].initialized)
        r_w_Disk(drive, _hd_ident[drive].part_tab[partnum].dist, 1, (unsigned short*)boot_sect, READ_SEC);
     else
        return -1; /* partition sector is never read */
     return 0;
}

/*

        drive:      0
		  partnum:    0..3
        return value:  at ok       0, boot sector contents int boot_sect
                       at error    -1
*/
int  WriteBOOTSector(int drive, struct BOOT_SECT * boot_sect, int partnum /* 0..3 */) {

     if (_hd_ident[drive].initialized)
        r_w_Disk(drive, _hd_ident[drive].part_tab[partnum].dist, 1, (unsigned short*)boot_sect, 0);
     else
        return -1; /* partition sector is never read */
     return 0;
}

int testFAT(struct BOOT_SECT * boot_sect) {
    int fat_mode;

    if (!memicmp(boot_sect->filesys, "FAT16", 5))
        fat_mode = 16;
    else
    if (!memicmp(boot_sect->filesys, "FAT12", 5))
        fat_mode = 12;
    else
        fat_mode = -1;   /* error condition */
    return fat_mode;
}

static int  GetBootData(int drive, struct BOOT_SECT * boot_sect)
{
int partnum;
int found=0;
struct msdos_b_sect *tmp;
unsigned long MaxCluster;

     for (partnum=0; partnum < 4; partnum++) {
	unsigned long tmp1, tmp2;


	tmp1 = _hd_ident[drive].part_tab[partnum].count_sect_part;
	tmp2 = _hd_ident[drive].part_tab[partnum].sys_ind;
	if ( tmp1 && ( (tmp2 == 1) || (tmp2 == 4) || (tmp2 == 6))) {
	    if (ReadBOOTSector(boot_sect, drive, partnum))
		return -1;
	    tmp = malloc(sizeof(struct msdos_b_sect));
	    if (tmp) {
		 tmp->sectPerFat     = CvtByteOrder16(boot_sect->sectPerFat);
		 tmp->FatSystem      = (tmp2 == 1) ? 12 : 16;
		 tmp->bytesPerSector = CvtByteOrder16(boot_sect->bytesPerSector);
		 tmp->sectPerCluster = boot_sect->sectPerCluster;
		 tmp->resSectors     = CvtByteOrder16(boot_sect->resSectors);
		 tmp->nFats          = boot_sect->nFats;
		 tmp->nRootDir       = CvtByteOrder16(boot_sect->nRootDir);
		 tmp->nSectors       = CvtByteOrder16(boot_sect->nSectors);
		 tmp->nSectorHuge    = CvtByteOrder32(boot_sect->nSectorHuge);
		 tmp->nHidden        = CvtByteOrder32(boot_sect->nHidden);
		 tmp->extBoot        = boot_sect->extBoot;
		 tmp->volid          = CvtByteOrder32(boot_sect->volid);
		 MaxCluster          = tmp->nSectors? tmp->nSectors:tmp->nSectorHuge;
		 MaxCluster          = (MaxCluster-tmp->resSectors-
				       tmp->nFats*tmp->sectPerFat-
				       tmp->nRootDir/(SECTOR_SIZE/sizeof(struct directory)))/
				       tmp->sectPerCluster+1;
		 tmp->MaxCluster     = MaxCluster;
		 tmp->FatStart = malloc(tmp->bytesPerSector*tmp->sectPerFat);// *tmp->nFats);
		 r_w_Disk(drive, tmp->nHidden + tmp->resSectors, tmp->sectPerFat /* *tmp->nFats*/, tmp->FatStart, READ);
		 tmp->RootDirStart   = tmp->nHidden + tmp->resSectors + tmp->nFats * tmp->sectPerFat;
		 tmp->nDir           = tmp->nRootDir / (tmp->bytesPerSector >> 5);
		 tmp->DataStart      = tmp->nDir + tmp->RootDirStart;
		 memcpy(tmp->filesys, boot_sect->filesys, 8);
		 _hd_ident[drive].bootptr[partnum] = tmp;
	    }
	    else
               return -1;
            found = 1;
        }

     }
     return  found ? 0 : -1;
}




/*
      Drive Numerierung

          0                  Channel 0   Master
          1                  Channel 0   Slave
          2                  Channel 1   Master
          3                  Channel 1   Slave
*/

int _install_ATA_sys(int channel, int drive, struct hd_driveid *id,
                                             struct PART_SECT *p_sect,
                                             struct BOOT_SECT *boot_sect)
{

   int dist, pdrive;

   if ((channel < MAX_CHANNEL_NUM) && (drive < 2) && (0 <= drive)) {
      pdrive = (channel << 1) + drive;
      if (installDrive(pdrive))
         return -1;
      if (InitializeDrive(pdrive, id)) /* initialize and identify hard disk */
         return -2;

      if (GetPartitionData(pdrive, p_sect))
          return -3;

      if (GetBootData(drive, boot_sect))
           return -4;
   }
   else
      return -5;
   return 0;
}



⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -