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

📄 ide_disk.c

📁 linux下从网卡远程启动
💻 C
📖 第 1 页 / 共 2 页
字号:
	if (sector > info->sectors) {		return -1;	}	if (info->address_mode == ADDRESS_MODE_CHS) {		result = ide_read_sector_chs(info, disk->buffer, sector);	}	else if (info->address_mode == ADDRESS_MODE_LBA) {		result = ide_read_sector_lba(info, disk->buffer, sector);	}	else if (info->address_mode == ADDRESS_MODE_LBA48) {		result = ide_read_sector_lba48(info, disk->buffer, sector);	}	else {		result = -1;	}	/* On success report the buffer has data */	if (result != -1) {		disk->bytes = IDE_SECTOR_SIZE;		disk->sector = sector;	}	return result;}static int init_drive(struct harddisk_info *info, struct controller *ctrl, int slave,	int basedrive, unsigned char *buffer){	uint16_t* drive_info;	struct ide_pio_command cmd;	int i;	info->ctrl = ctrl;	info->heads = 0u;	info->cylinders = 0u;	info->sectors_per_track = 0u;	info->address_mode = IDE_DH_CHS;	info->sectors = 0ul;	info->drive_exists = 0;	info->slave_absent = 0;	info->slave = slave?IDE_DH_SLAVE: IDE_DH_MASTER;	info->basedrive = basedrive;#if 0	printf("Testing for disk %d\n", info->basedrive);#endif	/* Select the drive that we are testing */	outb(IDE_DH_DEFAULT | IDE_DH_HEAD(0) | IDE_DH_CHS | info->slave, 		IDE_REG_DEVICE(ctrl));	mdelay(50);	/* Test to see if the drive registers exist,	 * In many cases this quickly rules out a missing drive.	 */	for(i = 0; i < 4; i++) {		outb(0xaa + i, (ctrl->cmd_base) + 2 + i);	}	for(i = 0; i < 4; i++) {		if (inb((ctrl->cmd_base) + 2 + i) != 0xaa + i) {			return 1;		}	}	for(i = 0; i < 4; i++) {		outb(0x55 + i, (ctrl->cmd_base) + 2 + i);	}	for(i = 0; i < 4; i++) {		if (inb((ctrl->cmd_base) + 2 + i) != 0x55 + i) {			return 1;		}	}#if 0	printf("Probing for disk %d\n", info->basedrive);#endif		memset(&cmd, 0, sizeof(cmd));	cmd.device = IDE_DH_DEFAULT | IDE_DH_HEAD(0) | IDE_DH_CHS | info->slave;	cmd.command = IDE_CMD_IDENTIFY_DEVICE;		if (pio_data_in(ctrl, &cmd, buffer, IDE_SECTOR_SIZE) < 0) {		/* Well, if that command didn't work, we probably don't have drive. */		return 1;	}		/* Now suck the data out */	drive_info = (uint16_t *)buffer;	if (drive_info[2] == 0x37C8) {		/* If the response is incomplete spin up the drive... */		memset(&cmd, 0, sizeof(cmd));		cmd.device = IDE_DH_DEFAULT | IDE_DH_HEAD(0) | IDE_DH_CHS |			info->slave;		cmd.feature = IDE_FEATURE_STANDBY_SPINUP_DRIVE;		if (pio_non_data(ctrl, &cmd) < 0) {			/* If the command doesn't work give up on the drive */			return 1;		}			}	if ((drive_info[2] == 0x37C8) || (drive_info[2] == 0x8C73)) {		/* The response is incomplete retry the drive info command */		memset(&cmd, 0, sizeof(cmd));		cmd.device = IDE_DH_DEFAULT | IDE_DH_HEAD(0) | IDE_DH_CHS |			info->slave;		cmd.command = IDE_CMD_IDENTIFY_DEVICE;		if(pio_data_in(ctrl, &cmd, buffer, IDE_SECTOR_SIZE) < 0) {			/* If the command didn't work give up on the drive. */			return 1;		}	}	if ((drive_info[2] != 0x37C8) &&		(drive_info[2] != 0x738C) &&		(drive_info[2] != 0x8C73) &&		(drive_info[2] != 0xC837) &&		(drive_info[2] != 0x0000)) {		printf("Invalid IDE Configuration: %hx\n", drive_info[2]);		return 1;	}	for(i = 27; i < 47; i++) {		info->model_number[((i-27)<< 1)] = (drive_info[i] >> 8) & 0xff;		info->model_number[((i-27)<< 1)+1] = drive_info[i] & 0xff;	}	info->model_number[40] = '\0';	info->drive_exists = 1;	/* See if LBA is supported */	if (drive_info[49] & (1 << 9)) {		info->address_mode = ADDRESS_MODE_LBA;		info->sectors = (drive_info[61] << 16) | (drive_info[60]);		/* Enable LBA48 mode if it is present */		if (drive_info[83] & (1 <<10)) {			/* Should LBA48 depend on LBA? */			printf("LBA48 mode\n");			info->address_mode = ADDRESS_MODE_LBA48;			info->sectors = 				(((sector_t)drive_info[103]) << 48) |				(((sector_t)drive_info[102]) << 32) |				(((sector_t)drive_info[101]) << 16) |				(((sector_t)drive_info[100]) <<  0);		}	} else {		info->address_mode = ADDRESS_MODE_CHS;		info->heads = drive_info[3];		info->cylinders = drive_info[1];		info->sectors_per_track = drive_info[6];		info->sectors = 			info->sectors_per_track *			info->heads *			info->cylinders;		printf(__FUNCTION__ " sectors_per_track=[%d], heads=[%d], cylinders=[%d]\n",			info->sectors_per_track,			info->heads,			info->cylinders);	}	/* See if we have a slave */	if (!info->slave && (((drive_info[93] >> 14) & 3) == 1)) {		info->slave_absent = !(drive_info[93] & (1 << 5));	}	/* See if we need to put the device in CFA power mode 1 */	if ((drive_info[160] & ((1 << 15) | (1 << 13)| (1 << 12))) ==		((1 << 15) | (1 << 13)| (1 << 12))) {		memset(&cmd, 0, sizeof(cmd));		cmd.device = IDE_DH_DEFAULT | IDE_DH_HEAD(0) | IDE_DH_CHS | info->slave;		cmd.feature = IDE_FEATURE_CFA_ENABLE_POWER_MODE1;		if (pio_non_data(ctrl, &cmd) < 0) {			/* If I need to power up the drive, and I can't			 * give up.			 */			printf("Cannot power up CFA device\n");			return 1;		}	}	printf("disk%d %dk cap: %hx\n",		info->basedrive,		(unsigned long)(info->sectors >> 1),		drive_info[49]);	return 0;}static int init_controller(struct controller *ctrl, int basedrive, unsigned char *buffer) {	struct harddisk_info *info;	/* Intialize the harddisk_info structures */	memset(harddisk_info, 0, sizeof(harddisk_info));	/* Put the drives ide channel in a know state and wait	 * for the drives to spinup.  	 *	 * In practice IDE disks tend not to respond to commands until	 * they have spun up.  This makes IDE hard to deal with	 * immediately after power up, as the delays can be quite	 * long, so we must be very careful here.	 *	 * There are two pathological cases that must be dealt with:	 *	 * - The BSY bit not being set while the IDE drives spin up.	 *   In this cases only a hard coded delay will work.  As	 *   I have not reproduced it, and this is out of spec for	 *   IDE drives the work around can be enabled by setting	 *   BSY_SET_DURING_SPINUP to 0.	 *	 * - The BSY bit floats high when no drives are plugged in.	 *   This case will not be detected except by timing out but	 *   we avoid the problems by only probing devices we are	 *   supposed to boot from.  If we don't do the probe we	 *   will not experience the problem.	 *	 * So speed wise I am only slow if the BSY bit is not set	 * or not reported by the IDE controller during spinup, which	 * is quite rare.	 * 	 */#if !BSY_SET_DURING_SPINUP	if (await_ide(timeout, ctrl, IDE_TIMEOUT) < 0) {		return -1;	}#endif	if (ide_software_reset(ctrl) < 0) {		return -1;	}	/* Note: I have just done a software reset.  It may be	 * reasonable to just read the boot time signatures 	 * off of the drives to see if they are present.	 *	 * For now I will go with just sending commands to the drives	 * and assuming filtering out missing drives by detecting registers	 * that won't set and commands that fail to execute properly.	 */	/* Now initialize the individual drives */	info = &harddisk_info[0];	init_drive(info, ctrl, 0, basedrive, buffer);	if (info->drive_exists && !info->slave_absent) {		basedrive++;		info++;		init_drive(info, ctrl, 1, basedrive, buffer);	}	return 0;}static void ide_disable(struct dev *dev){	struct disk *disk = (struct disk *)dev;	struct harddisk_info *info = disk->priv;	ide_software_reset(info->ctrl);}#ifdef CONFIG_PCIstatic int ide_pci_probe(struct dev *dev, struct pci_device *pci){	struct disk *disk = (struct disk *)dev;	struct harddisk_info *info;	int index;	adjust_pci_device(pci);		index = dev->index + 1;	if (dev->how_probe == PROBE_NEXT) {		index++;	}	for(; index < 4; index++) {		unsigned mask;		mask = (index < 2)? (1 << 0) : (1 << 2);		if ((pci->class & mask) == 0) {			/* IDE special pci mode */			uint16_t base;			base = (index < 2)?IDE_BASE0:IDE_BASE1;			controller.cmd_base  = base;			controller.ctrl_base = base + IDE_REG_EXTENDED_OFFSET;		} else {			/* IDE normal pci mode */			unsigned cmd_reg, ctrl_reg;			uint32_t cmd_base, ctrl_base;			if (index < 2) {				cmd_reg  = PCI_BASE_ADDRESS_0;				ctrl_reg = PCI_BASE_ADDRESS_1;			} else {				cmd_reg  = PCI_BASE_ADDRESS_2;				ctrl_reg = PCI_BASE_ADDRESS_3;			}			pcibios_read_config_dword(pci->bus, pci->devfn, cmd_reg, &cmd_base);			pcibios_read_config_dword(pci->bus, pci->devfn, ctrl_reg, &ctrl_base);			controller.cmd_base  = cmd_base  & ~3;			controller.ctrl_base = ctrl_base & ~3;		}		if (((index & 1) == 0) || (dev->how_probe == PROBE_AWAKE)) {			if (init_controller(&controller, disk->drive, disk->buffer) < 0) {				/* nothing behind the controller */				continue;			}		}		info = &harddisk_info[index & 1];		if (!info->drive_exists) {			/* unknown drive */			continue;		}		disk->hw_sector_size   = IDE_SECTOR_SIZE;		disk->sectors_per_read = 1;		disk->sectors          = info->sectors;		dev->index   = index;		dev->disable = ide_disable;		disk->read   = ide_read;		disk->priv   = info;				return 1;	}	/* past all of the drives */	dev->index = 0;	return 0;}static struct pci_id ide_controllers[] = {{ PCI_VENDOR_ID_INTEL,       PCI_DEVICE_ID_INTEL_82801CA_11,    "PIIX4" },#if 0  /* Currently I don't need any entries in this table so ignore it */{ PCI_VENDOR_ID_INTEL,       PCI_DEVICE_ID_INTEL_82371FB_0,     "PIIX" },{ PCI_VENDOR_ID_INTEL,       PCI_DEVICE_ID_INTEL_82371FB_1,     "PIIX" },{ PCI_VENDOR_ID_INTEL,       PCI_DEVICE_ID_INTEL_82371MX,       "MPIIX" },{ PCI_VENDOR_ID_INTEL,       PCI_DEVICE_ID_INTEL_82371SB_1,     "PIIX3" },{ PCI_VENDOR_ID_INTEL,       PCI_DEVICE_ID_INTEL_82371AB,       "PIIX4" },{ PCI_VENDOR_ID_INTEL,       PCI_DEVICE_ID_INTEL_82801AB_1,     "PIIX4" },{ PCI_VENDOR_ID_INTEL,       PCI_DEVICE_ID_INTEL_82443MX_1,     "PIIX4" },{ PCI_VENDOR_ID_INTEL,       PCI_DEVICE_ID_INTEL_82801AA_1,     "PIIX4" },{ PCI_VENDOR_ID_INTEL,       PCI_DEVICE_ID_INTEL_82372FB_1,     "PIIX4" },{ PCI_VENDOR_ID_INTEL,       PCI_DEVICE_ID_INTEL_82451NX,       "PIIX4" },{ PCI_VENDOR_ID_INTEL,       PCI_DEVICE_ID_INTEL_82801BA_9,     "PIIX4" },{ PCI_VENDOR_ID_INTEL,       PCI_DEVICE_ID_INTEL_82801BA_8,     "PIIX4" },{ PCI_VENDOR_ID_INTEL,       PCI_DEVICE_ID_INTEL_82801CA_10,    "PIIX4" },{ PCI_VENDOR_ID_VIA,         PCI_DEVICE_ID_VIA_82C561,          "VIA_IDE" },{ PCI_VENDOR_ID_VIA,         PCI_DEVICE_ID_VIA_82C576_1,        "VP_IDE" },{ PCI_VENDOR_ID_VIA,         PCI_DEVICE_ID_VIA_82C586_1,        "VP_IDE" },{ PCI_VENDOR_ID_PROMISE,     PCI_DEVICE_ID_PROMISE_20246,       "PDC20246" },{ PCI_VENDOR_ID_PROMISE,     PCI_DEVICE_ID_PROMISE_20262,       "PDC20262" },{ PCI_VENDOR_ID_PROMISE,     PCI_DEVICE_ID_PROMISE_20265,       "PDC20265" },{ PCI_VENDOR_ID_PROMISE,     PCI_DEVICE_ID_PROMISE_20267,       "PDC20267" },{ PCI_VENDOR_ID_PROMISE,     PCI_DEVICE_ID_PROMISE_20268,       "PDC20268" },{ PCI_VENDOR_ID_PROMISE,     PCI_DEVICE_ID_PROMISE_20268R,      "PDC20268" },{ PCI_VENDOR_ID_PCTECH,      PCI_DEVICE_ID_PCTECH_RZ1000,       "RZ1000" },{ PCI_VENDOR_ID_PCTECH,      PCI_DEVICE_ID_PCTECH_RZ1001,       "RZ1001" },{ PCI_VENDOR_ID_PCTECH,      PCI_DEVICE_ID_PCTECH_SAMURAI_IDE,  "SAMURAI" },{ PCI_VENDOR_ID_CMD,         PCI_DEVICE_ID_CMD_640,             "CMD640" },{ PCI_VENDOR_ID_CMD,         PCI_DEVICE_ID_CMD_643,             "CMD646" },{ PCI_VENDOR_ID_CMD,         PCI_DEVICE_ID_CMD_646,             "CMD648" },{ PCI_VENDOR_ID_CMD,         PCI_DEVICE_ID_CMD_648,             "CMD643" },{ PCI_VENDOR_ID_CMD,         PCI_DEVICE_ID_CMD_649,             "CMD649" },{ PCI_VENDOR_ID_SI,          PCI_DEVICE_ID_SI_5513,             "SIS5513" },{ PCI_VENDOR_ID_OPTI,        PCI_DEVICE_ID_OPTI_82C621,         "OPTI621" },{ PCI_VENDOR_ID_OPTI,        PCI_DEVICE_ID_OPTI_82C558,         "OPTI621V" },{ PCI_VENDOR_ID_OPTI,        PCI_DEVICE_ID_OPTI_82C825,         "OPTI621X" },{ PCI_VENDOR_ID_TEKRAM,      PCI_DEVICE_ID_TEKRAM_DC290,        "TRM290" },{ PCI_VENDOR_ID_NS,          PCI_DEVICE_ID_NS_87410,            "NS87410" },{ PCI_VENDOR_ID_NS,          PCI_DEVICE_ID_NS_87415,            "NS87415" },{ PCI_VENDOR_ID_HOLTEK2,     PCI_DEVICE_ID_HOLTEK2_6565,        "HT6565" },{ PCI_VENDOR_ID_ARTOP,       PCI_DEVICE_ID_ARTOP_ATP850UF,      "AEC6210" },{ PCI_VENDOR_ID_ARTOP,       PCI_DEVICE_ID_ARTOP_ATP860,        "AEC6260" },{ PCI_VENDOR_ID_ARTOP,       PCI_DEVICE_ID_ARTOP_ATP860R,       "AEC6260R" },{ PCI_VENDOR_ID_WINBOND,     PCI_DEVICE_ID_WINBOND_82C105,      "W82C105" },{ PCI_VENDOR_ID_UMC,         PCI_DEVICE_ID_UMC_UM8673F,         "UM8673F" },{ PCI_VENDOR_ID_UMC,         PCI_DEVICE_ID_UMC_UM8886A,         "UM8886A" },{ PCI_VENDOR_ID_UMC,         PCI_DEVICE_ID_UMC_UM8886BF,        "UM8886BF" },{ PCI_VENDOR_ID_TTI,         PCI_DEVICE_ID_TTI_HPT343,          "HPT34X" },{ PCI_VENDOR_ID_TTI,         PCI_DEVICE_ID_TTI_HPT366,          "HPT366" },{ PCI_VENDOR_ID_AL,          PCI_DEVICE_ID_AL_M5229,            "ALI15X3" },{ PCI_VENDOR_ID_CONTAQ,      PCI_DEVICE_ID_CONTAQ_82C693,       "CY82C693" },{ 0x3388,                    0x8013,                            "HINT_IDE" },{ PCI_VENDOR_ID_CYRIX,       PCI_DEVICE_ID_CYRIX_5530_IDE,      "CS5530" },{ PCI_VENDOR_ID_AMD,         PCI_DEVICE_ID_AMD_COBRA_7401,      "AMD7401" },{ PCI_VENDOR_ID_AMD,         PCI_DEVICE_ID_AMD_VIPER_7409,      "AMD7409" },{ PCI_VENDOR_ID_AMD,         PCI_DEVICE_ID_AMD_VIPER_7411,      "AMD7411" },{ PCI_VENDOR_ID_PDC,         PCI_DEVICE_ID_PDC_1841,            "PDCADMA" },{ PCI_VENDOR_ID_EFAR,        PCI_DEVICE_ID_EFAR_SLC90E66_1,     "SLC90E66" },{ PCI_VENDOR_ID_SERVERWORKS, PCI_DEVICE_ID_SERVERWORKS_OSB4IDE, "OSB4" },{ PCI_VENDOR_ID_SERVERWORKS, PCI_DEVICE_ID_SERVERWORKS_CSB5IDE, "OSB5" },{ PCI_VENDOR_ID_ITE,         PCI_DEVICE_ID_ITE_IT8172G,         "ITE8172G" },#endif};static struct pci_driver ide_driver __pci_driver = {	.type      = DISK_DRIVER,	.name      = "IDE",	.probe     = ide_pci_probe,	.ids       = ide_controllers,	.id_count  = sizeof(ide_controllers)/sizeof(ide_controllers),	.class     = PCI_CLASS_STORAGE_IDE,};#endif/* The isa driver works but it causes disks to show up twice. * comment it out for now. */#if 0 && defined(CONFIG_ISA)static int ide_isa_probe(struct dev * dev, unsigned short *probe_addrs){	struct disk *disk = (struct disk *)dev;	int index;	unsigned short addr;	struct harddisk_info *info;	index = dev->index +1;	if (dev->how_probe == PROBE_AWAKE) {		index--;	}	for(; (index >= 0) && (addr = probe_addrs[index >> 1]); index += 2) {		if ((index & 1) == 0) {			controller.cmd_base = addr;			controller.ctrl_base = addr + IDE_REG_EXTENDED_OFFSET;			if (init_controller(&controller, disk->drive, disk->buffer) < 0) {				/* nothing behind the controller */				continue;			}		}		info = &harddisk_info[index & 1];		if (!info->drive_exists) {			/* unknown drive */			return 0;		}		disk->sectors_per_read = 1;		disk->sectors = info->sectors;		dev->index   = index;		dev->disable = ide_disable;		disk->read   = ide_read;		disk->priv   = info;				return 1;	}	/* past all of the drives */	dev->index = -1;	return 0;}static unsigned short ide_base[] = {	IDE_BASE0,	IDE_BASE1, 	IDE_BASE2, 	IDE_BASE3, 	0};static struct isa_driver ide_isa_driver __isa_driver = {	.type    = DISK_DRIVER,	.name    = "IDE/ISA",	.probe   = ide_isa_probe,	.ioaddrs = ide_base,};#endif

⌨️ 快捷键说明

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