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

📄 ide_raw.c

📁 newos is new operation system
💻 C
📖 第 1 页 / 共 2 页
字号:
        return ERR_DISK_BUSY;      if(status & CB_STAT_DF)        return ERR_DEVICE_FAULT;      if(status & CB_STAT_ERR)        return ERR_HARDWARE_ERROR;      if((status & CB_STAT_DRQ) == 0)        return ERR_DRQ_NOT_SET;    }    return NO_ERR;}static int reg_pio_data_out( int bus, int dev, int cmd, int fr, int sc,			     unsigned int cyl, int head, int sect, const uint8 *output,			     unsigned int numSect, unsigned int multiCnt ){    unsigned char devHead;    unsigned char devCtrl;    unsigned char cylLow;    unsigned char cylHigh;    unsigned char status;    uint16		  *buffer = (uint16*)output;    devCtrl = CB_DC_HD15 | CB_DC_NIEN;    devHead = dev ? CB_DH_DEV1 : CB_DH_DEV0;    devHead = devHead | (head & 0x4f);    cylLow  = cyl & 0x00ff;    cylHigh = (cyl & 0xff00) >> 8;    if (cmd == CMD_WRITE_BUFFER)      numSect = 1;    // only Write Multiple and CFA Write Multiple W/O Erase uses multCnt    if ((cmd != CMD_WRITE_MULTIPLE) && (cmd != CMD_CFA_WRITE_MULTIPLE_WO_ERASE))      multiCnt = 1;    // select the drive    if (ide_select_device(bus, dev) != NO_ERR)      return ERR_TIMEOUT;    // set up the registers    pio_outbyte(CB_DC, devCtrl);    pio_outbyte(CB_FR, fr);    pio_outbyte(CB_SC, sc);    pio_outbyte(CB_SN, sect);    pio_outbyte(CB_CL, cylLow);    pio_outbyte(CB_CH, cylHigh);    pio_outbyte(CB_DH, devHead);    // Start the command. The drive should immediately set BUSY status.    pio_outbyte(CB_CMD, cmd);    DELAY400NS;    if (ide_wait_busy() == false)      return ERR_TIMEOUT;    status = pio_inbyte(CB_STAT);    while (1)    {      if ((status & (CB_STAT_BSY | CB_STAT_DRQ)) == CB_STAT_DRQ)      {        unsigned int wordCnt = multiCnt > numSect ? numSect : multiCnt;        wordCnt = wordCnt * 256;        pio_rep_outword(CB_DATA, buffer, wordCnt);        DELAY400NS;        numSect = numSect - multiCnt;        buffer += wordCnt;      }      // check all possible fault conditions      if(status & CB_STAT_BSY)        return ERR_DISK_BUSY;      if(status & CB_STAT_DF)        return ERR_DEVICE_FAULT;      if(status & CB_STAT_ERR)        return ERR_HARDWARE_ERROR;      if ((status & CB_STAT_DRQ) == 0)        return ERR_DRQ_NOT_SET;      ide_delay(bus, dev);      // ensure drive isn't still busy      ide_reg_poll();      if(numSect < 1 && status & (CB_STAT_BSY | CB_STAT_DF | CB_STAT_ERR))        {          dprintf("status = 0x%x\n", status);          return ERR_BUFFER_NOT_EMPTY;        }    }    return NO_ERR;}static void ide_btochs(uint32 block, ide_device *dev, int *cylinder, int *head, int *sect){  *sect = (block % dev->hardware_device.sectors) + 1;  block /= dev->hardware_device.sectors;  *head = (block % dev->hardware_device.heads) | (dev->device ? 1 : 0);  block /= dev->hardware_device.heads;  *cylinder = block & 0xFFFF;//  dprintf("ide_btochs: block %d -> cyl %d head %d sect %d\n", block, *cylinder, *head, *sect);}static void ide_btolba(uint32 block, ide_device *dev, int *cylinder, int *head, int *sect){  *sect = block & 0xFF;  *cylinder = (block >> 8) & 0xFFFF;  *head = ((block >> 24) & 0xF) | (dev->device ? 1: 0) | CB_DH_LBA;//  dprintf("ide_btolba: block %d -> cyl %d head %d sect %d\n", block, *cylinder, *head, *sect);}int	ide_read_block(ide_device *device, char *data, uint32 block, uint8 numSectors){  int cyl, head, sect;  if(device->lba_supported)    ide_btolba(block, device, &cyl, &head, &sect);  else    ide_btochs(block, device, &cyl, &head, &sect);      return reg_pio_data_in(device->bus, device->device, CMD_READ_SECTORS,			          0, numSectors, cyl, head, sect, data, numSectors, 2);}int	ide_write_block(ide_device *device, const char *data, uint32 block, uint8 numSectors){  int cyl, head, sect;  if(device->lba_supported)    ide_btolba(block, device, &cyl, &head, &sect);  else    ide_btochs(block, device, &cyl, &head, &sect);      return reg_pio_data_out(device->bus, device->device, CMD_WRITE_SECTORS,			          0, numSectors, cyl, head, sect, data, numSectors, 2);}void ide_string_conv (char *str, int len){  unsigned int i;  int	       j;  for (i=0; i<len/sizeof(unsigned short); i++)  {    char c     = str[i*2+1];    str[i*2+1] = str[i*2];    str[i*2]   = c;  }  str[len - 1] = 0;  for (j=len-1; j>=0 && str[j]==' '; j--)    str[j] = 0;}// ide_reset() - execute a software resetbool ide_reset (int bus, int device){  unsigned char devCtrl = CB_DC_HD15 | CB_DC_NIEN;	  // Set and then reset the soft reset bit in the Device  // Control register.  This causes device 0 be selected  pio_outbyte(CB_DC, devCtrl | CB_DC_SRST);  DELAY400NS;  pio_outbyte(CB_DC, devCtrl);  DELAY400NS;  return (ide_wait_busy() ? true : false);}bool ide_identify_device(int bus, int device){	ide_device* ide = &devices[(bus*2) + device];	uint8* buffer;	int rc;	// Store specs for device			ide->bus         = bus;	ide->device      = device;	// Do an IDENTIFY DEVICE command	buffer = (uint8*)&ide->hardware_device;	rc = reg_pio_data_in(bus, device, CMD_IDENTIFY_DEVICE,						1, 0, 0, 0, 0, buffer, 1, 0);	if (rc == NO_ERR) {			// If command was ok, lets assume ATA device		ide->device_type = ATA_DEVICE;				// Convert the model string to ASCIIZ		ide_string_conv(ide->hardware_device.model, 40);				// Get copy over interesting data		ide->sector_count = ide->hardware_device.cyls * ide->hardware_device.heads		* ide->hardware_device.sectors;		ide->bytes_per_sector = 512;		ide->lba_supported = ide->hardware_device.capabilities & DRIVE_SUPPORT_LBA;		ide->start_block = 0;		ide->end_block = ide->sector_count + ide->start_block;				// Give some debugging output to show what was found		dprintf ("ide: disk at bus %d, device %d %s\n", bus, device, ide->hardware_device.model);		dprintf ("ide/%d/%d: %dMB; %d cyl, %d head, %d sec, %d bytes/sec  (LBA=%d)\n",		bus, device, ide->sector_count * ide->bytes_per_sector / (1024*1024),		ide->hardware_device.cyls, ide->hardware_device.heads,		ide->hardware_device.sectors, ide->bytes_per_sector, ide->lba_supported );	} else {		// Something went wrong, let's forget about this device		ide->device_type = NO_DEVICE;	}	return (rc == NO_ERROR) ? true : false;}// Set the pio base addressesvoid ide_raw_init(int base1, int base2){  unsigned int pio_base_addr1 = base1;  unsigned int pio_base_addr2 = base2;  pio_reg_addrs[CB_DATA] = pio_base_addr1 + 0;  // 0  pio_reg_addrs[CB_FR  ] = pio_base_addr1 + 1;  // 1  pio_reg_addrs[CB_SC  ] = pio_base_addr1 + 2;  // 2  pio_reg_addrs[CB_SN  ] = pio_base_addr1 + 3;  // 3  pio_reg_addrs[CB_CL  ] = pio_base_addr1 + 4;  // 4  pio_reg_addrs[CB_CH  ] = pio_base_addr1 + 5;  // 5  pio_reg_addrs[CB_DH  ] = pio_base_addr1 + 6;  // 6  pio_reg_addrs[CB_CMD ] = pio_base_addr1 + 7;  // 7  pio_reg_addrs[CB_DC  ] = pio_base_addr2 + 6;  // 8  pio_reg_addrs[CB_DA  ] = pio_base_addr2 + 7;  // 9}static char getHexChar(uint8 value){  if(value < 10)    return value + '0';  return 'A' + (value - 10);}static void dumpHexLine(uint8 *buffer, int numberPerLine){  uint8	*copy = buffer;  int	i;  for(i=0; i<numberPerLine; i++)    {      uint8	value1 = getHexChar(((*copy) >> 4));      uint8	value2 = getHexChar(((*copy) & 0xF));      dprintf("%c%c ", value1, value2);      copy++;    }  copy = buffer;  for(i=0; i<numberPerLine; i++)    {      if(*copy >= ' ' && *copy <= 'Z')		dprintf("%c", *copy);      else		dprintf(".");      copy++;    }  dprintf("\n");}static void dumpHexBuffer(uint8 *buffer, int size){  int	numberPerLine = 8;  int	numberOfLines = size / numberPerLine;  int	i, j;  for(i=0; i<numberOfLines; i++)    {      dprintf("%d ", i*numberPerLine);      dumpHexLine(buffer, numberPerLine);      buffer += numberPerLine;    }}static bool ide_get_partition_info(ide_device *device, tPartition *partition, uint32 position){	char buffer[512];	uint8* partitionBuffer = buffer;				// Try to read partition table	if (ide_read_block(device, buffer, position, 1) != 0) {		dprintf("unable to read partition table\n");		return false;	}		// Check partition table signature	if (partitionBuffer[PART_MAGIC_OFFSET] != PARTITION_MAGIC1 ||		partitionBuffer[PART_MAGIC_OFFSET+1] != PARTITION_MAGIC2) {		dprintf("partition table magic is incorrect\n");		return false;	}		memcpy(partition, partitionBuffer + PARTITION_OFFSET, sizeof(tPartition) * NUM_PARTITIONS);		return true;}bool ide_get_partitions(ide_device *device){  int		i;  memset(&device->partitions, 0, sizeof(tPartition) * 2 * NUM_PARTITIONS);  if(ide_get_partition_info(device, device->partitions, 0) == false)    return false;    dprintf("Primary Partition Table\n");  for (i = 0; i < NUM_PARTITIONS; i++)    {      dprintf("  %d: flags:%x type:%x start:%d:%d:%d end:%d:%d:%d stblk:%d count:%d\n", 	      i, 	  device->partitions[i].boot_flags,	  device->partitions[i].partition_type,	  device->partitions[i].starting_head,	  device->partitions[i].starting_sector,	  device->partitions[i].starting_cylinder,	  device->partitions[i].ending_head,	  device->partitions[i].ending_sector,	  device->partitions[i].ending_cylinder,	  device->partitions[i].starting_block,	  device->partitions[i].sector_count);    }  if(device->partitions[1].partition_type == PTDosExtended)    {      int extOffset = device->partitions[1].starting_block;      if(ide_get_partition_info(device, &device->partitions[4], extOffset) == false)        return false;      dprintf("Extended Partition Table\n");      for (i=4; i<4+NUM_PARTITIONS; i++)        {          device->partitions[i].starting_block += extOffset;          dprintf("  %d: flags:%x type:%x start:%d:%d:%d end:%d:%d:%d stblk:%d count:%d\n",		  i, 		  device->partitions[i].boot_flags,		  device->partitions[i].partition_type,		  device->partitions[i].starting_head,		  device->partitions[i].starting_sector,		  device->partitions[i].starting_cylinder,		  device->partitions[i].ending_head,		  device->partitions[i].ending_sector,		  device->partitions[i].ending_cylinder,		  device->partitions[i].starting_block,		  device->partitions[i].sector_count);        }    }  return true;}// These two functions are called from ide_ioctl in ide.c. They are far from// tested, and mostly just a C conversion of a DEBUG script presented on// http://www.satwerk.de/ufd552.htm// This should be tweaked some more before actual release!int ide_get_accoustic(ide_device *device, int8* level_ptr){	return ERR_UNIMPLEMENTED;}int ide_set_accoustic(ide_device *device, int8 level){	pio_outbyte(CB_DH, (device->device == 1) ? CB_DH_DEV1 : CB_DH_DEV0);	pio_outbyte(CB_CMD, CMD_SET_ACCOUSTIC_LEVEL);		pio_outbyte(CB_SC, level);	pio_outbyte(CB_STAT, 0xEF);	return NO_ERROR;}

⌨️ 快捷键说明

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