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

📄 ps2esdi.c

📁 讲述linux的初始化过程
💻 C
📖 第 1 页 / 共 3 页
字号:
#ifdef OBSOLETE				if (!ps2esdi_info[drive_num].head) {					ps2esdi_info[drive_num].head = reply[4] & 0Xff;					ps2esdi_info[drive_num].sect = reply[4] >> 8;					ps2esdi_info[drive_num].cyl = reply[3];					ps2esdi_info[drive_num].wpcom = 0;					ps2esdi_info[drive_num].lzone = reply[3];					if (tp720esdi) {	/* store the retrieved parameters */						ps2esdi_info[0].head = reply[4] & 0Xff;						ps2esdi_info[0].sect = reply[4] >> 8;						ps2esdi_info[0].cyl = reply[3];						ps2esdi_info[0].wpcom = 0;						ps2esdi_info[0].lzone = reply[3];					} else {						ps2esdi_drives++;					}				}#endif			} else				printk("%s: failed while getting device config\n", DEVICE_NAME);#undef REPLY_WORDS		} else			printk("%s: command %02X unknown by geometry handler\n",			       DEVICE_NAME, status & 0x1f);		outb((int_ret_code & 0xe0) | ATT_EOI, ESDI_ATTN);		break;	case INT_ATTN_ERROR:		printk("%s: Attention error. interrupt status : %02X\n", DEVICE_NAME,		       int_ret_code);		printk("%s: Device not available\n", DEVICE_NAME);		break;	case INT_CMD_ECC:	case INT_CMD_RETRY:	case INT_CMD_ECC_RETRY:	case INT_CMD_WARNING:	case INT_CMD_ABORT:	case INT_CMD_FAILED:	case INT_DMA_ERR:	case INT_CMD_BLK_ERR:		/*BA */ printk("%s: Whaa. Error occurred...\n", DEVICE_NAME);		dump_cmd_complete_status(int_ret_code);		outb((int_ret_code & 0xe0) | ATT_EOI, ESDI_ATTN);		break;	default:		printk("%s: Unknown interrupt reason: %02X\n",		       DEVICE_NAME, int_ret_code & 0xf);		outb((int_ret_code & 0xe0) | ATT_EOI, ESDI_ATTN);		break;	}	wake_up(&ps2esdi_int);	no_int_yet = FALSE;	outb(CTRL_ENABLE_INTR, ESDI_CONTROL);}static void ps2esdi_normal_interrupt_handler(u_int int_ret_code){	u_int status;	int i;	switch (int_ret_code & 0x0f) {	case INT_TRANSFER_REQ:		ps2esdi_prep_dma(CURRENT->buffer, CURRENT->current_nr_sectors,		    (CURRENT->cmd == READ) ? DMA_READ_16 : DMA_WRITE_16);		outb(CTRL_ENABLE_DMA | CTRL_ENABLE_INTR, ESDI_CONTROL);		break;	case INT_ATTN_ERROR:		printk("%s: Attention error. interrupt status : %02X\n", DEVICE_NAME,		       int_ret_code);		outb(CTRL_ENABLE_INTR, ESDI_CONTROL);		break;	case INT_CMD_COMPLETE:		for (i = ESDI_TIMEOUT; i & !(inb(ESDI_STATUS) & STATUS_STAT_AVAIL); i--);		if (!(inb(ESDI_STATUS) & STATUS_STAT_AVAIL)) {			printk("%s: timeout reading status word\n", DEVICE_NAME);			outb((int_ret_code & 0xe0) | ATT_EOI, ESDI_ATTN);			outb(CTRL_ENABLE_INTR, ESDI_CONTROL);			if ((++CURRENT->errors) < MAX_RETRIES)				do_ps2esdi_request(NULL);			else {				end_request(FAIL);				if (!QUEUE_EMPTY)					do_ps2esdi_request(NULL);			}			break;		}		status = inw(ESDI_STT_INT);		switch (status & 0x1F) {		case (CMD_READ & 0xff):		case (CMD_WRITE & 0xff):			LITE_OFF;			outb((int_ret_code & 0xe0) | ATT_EOI, ESDI_ATTN);			outb(CTRL_ENABLE_INTR, ESDI_CONTROL);#if 0			printk("ps2esdi: cmd_complete b_wait: %p\n", CURRENT->bh->b_wait);#endif			ps2esdi_continue_request();			break;		default:			printk("%s: interrupt for unknown command %02X\n",			       DEVICE_NAME, status & 0x1f);			outb((int_ret_code & 0xe0) | ATT_EOI, ESDI_ATTN);			outb(CTRL_ENABLE_INTR, ESDI_CONTROL);			break;		}		break;	case INT_CMD_ECC:	case INT_CMD_RETRY:	case INT_CMD_ECC_RETRY:		LITE_OFF;		dump_cmd_complete_status(int_ret_code);		outb((int_ret_code & 0xe0) | ATT_EOI, ESDI_ATTN);		outb(CTRL_ENABLE_INTR, ESDI_CONTROL);		ps2esdi_continue_request();		break;	case INT_CMD_WARNING:	case INT_CMD_ABORT:	case INT_CMD_FAILED:	case INT_DMA_ERR:		LITE_OFF;		dump_cmd_complete_status(int_ret_code);		outb((int_ret_code & 0xe0) | ATT_EOI, ESDI_ATTN);		outb(CTRL_ENABLE_INTR, ESDI_CONTROL);		if ((++CURRENT->errors) < MAX_RETRIES)			do_ps2esdi_request(NULL);		else {			end_request(FAIL);			if (!QUEUE_EMPTY)				do_ps2esdi_request(NULL);		}		break;	case INT_CMD_BLK_ERR:		dump_cmd_complete_status(int_ret_code);		outb((int_ret_code & 0xe0) | ATT_EOI, ESDI_ATTN);		outb(CTRL_ENABLE_INTR, ESDI_CONTROL);		end_request(FAIL);		if (!QUEUE_EMPTY)			do_ps2esdi_request(NULL);		break;	case INT_CMD_FORMAT:		printk("%s: huh ? Who issued this format command ?\n"		       ,DEVICE_NAME);		outb((int_ret_code & 0xe0) | ATT_EOI, ESDI_ATTN);		outb(CTRL_ENABLE_INTR, ESDI_CONTROL);		break;	case INT_RESET:		/* BA printk("%s: reset completed.\n", DEVICE_NAME) */ ;		outb((int_ret_code & 0xe0) | ATT_EOI, ESDI_ATTN);		outb(CTRL_ENABLE_INTR, ESDI_CONTROL);		break;	default:		printk("%s: Unknown interrupt reason: %02X\n",		       DEVICE_NAME, int_ret_code & 0xf);		outb((int_ret_code & 0xe0) | ATT_EOI, ESDI_ATTN);		outb(CTRL_ENABLE_INTR, ESDI_CONTROL);		break;	}}				/* handle interrupts */static void ps2esdi_continue_request(void){	if (CURRENT->nr_sectors -= CURRENT->current_nr_sectors) {		CURRENT->buffer += CURRENT->current_nr_sectors * SECT_SIZE;		CURRENT->sector += CURRENT->current_nr_sectors;		do_ps2esdi_request(NULL);	} else {		end_request(SUCCES);		if (!QUEUE_EMPTY)			do_ps2esdi_request(NULL);	}}static int ps2esdi_read_status_words(int num_words,				     int max_words,				     u_short * buffer){	int i;	for (; max_words && num_words; max_words--, num_words--, buffer++) {		for (i = ESDI_TIMEOUT; i && !(inb(ESDI_STATUS) & STATUS_STAT_AVAIL); i--);		if (!(inb(ESDI_STATUS) & STATUS_STAT_AVAIL)) {			printk("%s: timeout reading status word\n", DEVICE_NAME);			return FAIL;		}		*buffer = inw(ESDI_STT_INT);	}	return SUCCES;}static void dump_cmd_complete_status(u_int int_ret_code){#define WAIT_FOR_STATUS \  for(i=ESDI_TIMEOUT;i && !(inb(ESDI_STATUS) & STATUS_STAT_AVAIL);i--); \    if(!(inb(ESDI_STATUS) & STATUS_STAT_AVAIL)) { \    printk("%s: timeout reading status word\n",DEVICE_NAME); \    return; \    }	int i, word_count;	u_short stat_word;	u_long rba;	printk("%s: Device: %u, interrupt ID: %02X\n",	       DEVICE_NAME, int_ret_code >> 5,	       int_ret_code & 0xf);	WAIT_FOR_STATUS;	stat_word = inw(ESDI_STT_INT);	word_count = (stat_word >> 8) - 1;	printk("%s: %u status words, command: %02X\n", DEVICE_NAME, word_count,	       stat_word & 0xff);	if (word_count--) {		WAIT_FOR_STATUS;		stat_word = inw(ESDI_STT_INT);		printk("%s: command status code: %02X, command error code: %02X\n",		       DEVICE_NAME, stat_word >> 8, stat_word & 0xff);	}	if (word_count--) {		WAIT_FOR_STATUS;		stat_word = inw(ESDI_STT_INT);		printk("%s: device error code: %s%s%s%s%s,%02X\n", DEVICE_NAME,		       (stat_word & 0x1000) ? "Ready, " : "Not Ready, ",		  (stat_word & 0x0800) ? "Selected, " : "Not Selected, ",		       (stat_word & 0x0400) ? "Write Fault, " : "",		       (stat_word & 0x0200) ? "Track 0, " : "",		(stat_word & 0x0100) ? "Seek or command complete, " : "",		       stat_word >> 8);	}	if (word_count--) {		WAIT_FOR_STATUS;		stat_word = inw(ESDI_STT_INT);		printk("%s: Blocks to do: %u", DEVICE_NAME, stat_word);	}	if (word_count -= 2) {		WAIT_FOR_STATUS;		rba = inw(ESDI_STT_INT);		WAIT_FOR_STATUS;		rba |= inw(ESDI_STT_INT) << 16;		printk(", Last Cyl: %u Head: %u Sector: %u\n",		       (u_short) ((rba & 0x1ff80000) >> 11),		 (u_short) ((rba & 0x7E0) >> 5), (u_short) (rba & 0x1f));	} else		printk("\n");	if (word_count--) {		WAIT_FOR_STATUS;		stat_word = inw(ESDI_STT_INT);		printk("%s: Blocks required ECC: %u", DEVICE_NAME, stat_word);	}	printk("\n");#undef WAIT_FOR_STATUS}static int ps2esdi_open(struct inode *inode, struct file *file){	int dev = DEVICE_NR(inode->i_rdev);	if (dev < ps2esdi_drives) {		while (!ps2esdi_valid[dev])			sleep_on(&ps2esdi_wait_open);		access_count[dev]++;		return (0);	} else		return (-ENODEV);}static int ps2esdi_release(struct inode *inode, struct file *file){	int dev = DEVICE_NR(inode->i_rdev);	if (dev < ps2esdi_drives) {		access_count[dev]--;	}	return 0;}static int ps2esdi_ioctl(struct inode *inode,			 struct file *file, u_int cmd, u_long arg){	struct ps2esdi_geometry *geometry = (struct ps2esdi_geometry *) arg;	int dev = DEVICE_NR(inode->i_rdev), err;	if (inode && (dev < ps2esdi_drives))		switch (cmd) {		case HDIO_GETGEO:			if (arg) {				if ((err = verify_area(VERIFY_WRITE, geometry, sizeof(*geometry))))					return (err);				put_user(ps2esdi_info[dev].head, (char *) &geometry->heads);				put_user(ps2esdi_info[dev].sect, (char *) &geometry->sectors);				put_user(ps2esdi_info[dev].cyl, (short *) &geometry->cylinders);				put_user(ps2esdi[MINOR(inode->i_rdev)].start_sect,					    (long *) &geometry->start);				return (0);			}			break;		case BLKGETSIZE:			if (arg) {				if ((err = verify_area(VERIFY_WRITE, (long *) arg, sizeof(long))))					 return (err);				put_user(ps2esdi[MINOR(inode->i_rdev)].nr_sects, (long *) arg);				return (0);			}			break;		case BLKRRPART:                        if (!capable(CAP_SYS_ADMIN)) 				return -EACCES;			return (ps2esdi_reread_partitions(inode->i_rdev));		case BLKROSET:		case BLKROGET:		case BLKRASET:		case BLKRAGET:		case BLKFLSBUF:		case BLKPG:			return blk_ioctl(inode->i_rdev, cmd, arg);		}	return (-EINVAL);}static int ps2esdi_reread_partitions(kdev_t dev){	int target = DEVICE_NR(dev);	int start = target << ps2esdi_gendisk.minor_shift;	int partition;	cli();	ps2esdi_valid[target] = (access_count[target] != 1);	sti();	if (ps2esdi_valid[target])		return (-EBUSY);	for (partition = ps2esdi_gendisk.max_p - 1;	     partition >= 0; partition--) {		int minor = (start | partition);		kdev_t devp = MKDEV(MAJOR_NR, minor);		struct super_block * sb = get_super(devp);				sync_dev(devp);		if (sb)			invalidate_inodes(sb);		invalidate_buffers(devp);		ps2esdi_gendisk.part[start + partition].start_sect = 0;		ps2esdi_gendisk.part[start + partition].nr_sects = 0;	}	grok_partitions(&ps2esdi_gendisk, target, 1<<6, 		ps2esdi_info[target].head * ps2esdi_info[target].cyl * ps2esdi_info[target].sect);	ps2esdi_valid[target] = 1;	wake_up(&ps2esdi_wait_open);	return (0);}void ps2esdi_reset_timer(unsigned long unused){	int status;	status = inb(ESDI_INTRPT);	if ((status & 0xf) == INT_RESET) {		outb((status & 0xe0) | ATT_EOI, ESDI_ATTN);		outb(CTRL_ENABLE_INTR, ESDI_CONTROL);		reset_status = 1;	}	wake_up(&ps2esdi_int);}#endif

⌨️ 快捷键说明

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