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

📄 xd.c

📁 讲述linux的初始化过程
💻 C
📖 第 1 页 / 共 3 页
字号:
	xd_maxsectors = 0x01;		/* this one doesn't wrap properly either... */	outb(0,XD_RESET);		/* reset the controller */	xd_timer.expires = jiffies + XD_INIT_DISK_DELAY;	add_timer(&xd_timer);	sleep_on(&xdc_wait);}static void __init xd_wd_init_drive (u_char drive){	/* values from controller's BIOS - BIOS may be disabled */	static u_short geometry_table[][4] = {		{0x264,4,0x1C2,0x1C2},   /* common part */		{0x132,4,0x099,0x0},		{0x267,2,0x1C2,0x1C2},		{0x267,4,0x1C2,0x1C2},		{0x334,6,0x335,0x335},   /* 1004 series RLL */		{0x30E,4,0x30F,0x3DC},		{0x30E,2,0x30F,0x30F},		{0x267,4,0x268,0x268},		{0x3D5,5,0x3D6,0x3D6},   /* 1002 series RLL */		{0x3DB,7,0x3DC,0x3DC},		{0x264,4,0x265,0x265},		{0x267,4,0x268,0x268}};	u_char cmdblk[6],buf[0x200];	u_char n = 0,rll,jumper_state,use_jumper_geo;	u_char wd_1002 = (xd_sigs[xd_type].string[7] == '6');		jumper_state = ~(inb(0x322));	if (jumper_state & 0x40)		xd_irq = 9;	rll = (jumper_state & 0x30) ? (0x04 << wd_1002) : 0;	xd_build(cmdblk,CMD_READ,drive,0,0,0,1,0);	if (!xd_command(cmdblk,PIO_MODE,buf,0,0,XD_TIMEOUT * 2)) {		xd_info[drive].heads = buf[0x1AF];				/* heads */		xd_info[drive].cylinders = ((u_short *) (buf + 1))[0xD6];	/* cylinders */		xd_info[drive].sectors = 17;					/* sectors */		if (xd_geo[3*drive])			xd_manual_geo_set(drive);#if 0		xd_info[drive].rwrite = ((u_short *) (buf))[0xD8];		/* reduced write */		xd_info[drive].wprecomp = ((u_short *) (buf))[0xDA];		/* write precomp */		xd_info[drive].ecc = buf[0x1B4];				/* ecc length */#endif /* 0 */		xd_info[drive].control = buf[0x1B5];				/* control byte */		use_jumper_geo = !(xd_info[drive].heads) || !(xd_info[drive].cylinders);		if (xd_geo[3*drive]) {			xd_manual_geo_set(drive);			xd_info[drive].control = rll ? 7 : 5;		}		else if (use_jumper_geo) {			n = (((jumper_state & 0x0F) >> (drive << 1)) & 0x03) | rll;			xd_info[drive].cylinders = geometry_table[n][0];			xd_info[drive].heads = (u_char)(geometry_table[n][1]);			xd_info[drive].control = rll ? 7 : 5;#if 0			xd_info[drive].rwrite = geometry_table[n][2];			xd_info[drive].wprecomp = geometry_table[n][3];			xd_info[drive].ecc = 0x0B;#endif /* 0 */		}		if (!wd_1002) {			if (use_jumper_geo)				xd_setparam(CMD_WDSETPARAM,drive,xd_info[drive].heads,xd_info[drive].cylinders,					geometry_table[n][2],geometry_table[n][3],0x0B);			else				xd_setparam(CMD_WDSETPARAM,drive,xd_info[drive].heads,xd_info[drive].cylinders,					((u_short *) (buf))[0xD8],((u_short *) (buf))[0xDA],buf[0x1B4]);		}	/* 1002 based RLL controler requests converted addressing, but reports physical 	   (physical 26 sec., logical 17 sec.) 	   1004 based ???? */		if (rll & wd_1002) {			if ((xd_info[drive].cylinders *= 26,			     xd_info[drive].cylinders /= 17) > 1023)				xd_info[drive].cylinders = 1023;  /* 1024 ? */#if 0			xd_info[drive].rwrite *= 26; 			xd_info[drive].rwrite /= 17;			xd_info[drive].wprecomp *= 26			xd_info[drive].wprecomp /= 17;#endif /* 0 */		}	}	else		printk("xd_wd_init_drive: error reading geometry for xd%c\n",'a'+drive);	}static void __init xd_seagate_init_controller (unsigned int address){	switch (address) {		case 0x00000:		case 0xC8000:	break;			/*initial: 0x320 */		case 0xD0000:	xd_iobase = 0x324; break;		case 0xD8000:	xd_iobase = 0x328; break;		case 0xE0000:	xd_iobase = 0x32C; break;		default:	printk("xd_seagate_init_controller: unsupported BIOS address %06x\n",address);				break;	}	xd_maxsectors = 0x40;	outb(0,XD_RESET);		/* reset the controller */}static void __init xd_seagate_init_drive (u_char drive){	u_char cmdblk[6],buf[0x200];	xd_build(cmdblk,CMD_ST11GETGEOM,drive,0,0,0,1,0);	if (!xd_command(cmdblk,PIO_MODE,buf,0,0,XD_TIMEOUT * 2)) {		xd_info[drive].heads = buf[0x04];				/* heads */		xd_info[drive].cylinders = (buf[0x02] << 8) | buf[0x03];	/* cylinders */		xd_info[drive].sectors = buf[0x05];				/* sectors */		xd_info[drive].control = 0;					/* control byte */	}	else		printk("xd_seagate_init_drive: error reading geometry from xd%c\n", 'a'+drive);}/* Omti support courtesy Dirk Melchers */static void __init xd_omti_init_controller (unsigned int address){	switch (address) {		case 0x00000:		case 0xC8000:	break;			/*initial: 0x320 */		case 0xD0000:	xd_iobase = 0x324; break;		case 0xD8000:	xd_iobase = 0x328; break;		case 0xE0000:	xd_iobase = 0x32C; break;		default:	printk("xd_omti_init_controller: unsupported BIOS address %06x\n",address);				break;	}		xd_maxsectors = 0x40;	outb(0,XD_RESET);		/* reset the controller */}static void __init xd_omti_init_drive (u_char drive){	/* gets infos from drive */	xd_override_init_drive(drive);	/* set other parameters, Hardcoded, not that nice :-) */	xd_info[drive].control = 2;}/* Xebec support (AK) */static void __init xd_xebec_init_controller (unsigned int address){/* iobase may be set manually in range 0x300 - 0x33C      irq may be set manually to 2(9),3,4,5,6,7      dma may be set manually to 1,2,3	(How to detect them ???)BIOS address may be set manually in range 0x0 - 0xF8000If you need non-standard settings use the xd=... command */	switch (address) {		case 0x00000:		case 0xC8000:	/* initially: xd_iobase==0x320 */		case 0xD0000:		case 0xD2000:		case 0xD4000:		case 0xD6000:		case 0xD8000:		case 0xDA000:		case 0xDC000:		case 0xDE000:		case 0xE0000:	break;		default:	printk("xd_xebec_init_controller: unsupported BIOS address %06x\n",address);				break;		}	xd_maxsectors = 0x01;	outb(0,XD_RESET);		/* reset the controller */	xd_timer.expires = jiffies + XD_INIT_DISK_DELAY;	add_timer(&xd_timer);	sleep_on(&xdc_wait);}static void __init xd_xebec_init_drive (u_char drive){	/* values from controller's BIOS - BIOS chip may be removed */	static u_short geometry_table[][5] = {		{0x132,4,0x080,0x080,0x7},		{0x132,4,0x080,0x080,0x17},		{0x264,2,0x100,0x100,0x7},		{0x264,2,0x100,0x100,0x17},		{0x132,8,0x080,0x080,0x7},		{0x132,8,0x080,0x080,0x17},		{0x264,4,0x100,0x100,0x6},		{0x264,4,0x100,0x100,0x17},		{0x2BC,5,0x2BC,0x12C,0x6},		{0x3A5,4,0x3A5,0x3A5,0x7},		{0x26C,6,0x26C,0x26C,0x7},		{0x200,8,0x200,0x100,0x17},		{0x400,5,0x400,0x400,0x7},		{0x400,6,0x400,0x400,0x7},		{0x264,8,0x264,0x200,0x17},		{0x33E,7,0x33E,0x200,0x7}};	u_char n;	n = inb(XD_JUMPER) & 0x0F; /* BIOS's drive number: same geometry 					is assumed for BOTH drives */	if (xd_geo[3*drive])		xd_manual_geo_set(drive);	else {		xd_info[drive].heads = (u_char)(geometry_table[n][1]);			/* heads */		xd_info[drive].cylinders = geometry_table[n][0];	/* cylinders */		xd_info[drive].sectors = 17;				/* sectors */#if 0		xd_info[drive].rwrite = geometry_table[n][2];	/* reduced write */		xd_info[drive].precomp = geometry_table[n][3]		/* write precomp */		xd_info[drive].ecc = 0x0B;				/* ecc length */#endif /* 0 */	}	xd_info[drive].control = geometry_table[n][4];			/* control byte */	xd_setparam(CMD_XBSETPARAM,drive,xd_info[drive].heads,xd_info[drive].cylinders,geometry_table[n][2],geometry_table[n][3],0x0B);	xd_recalibrate(drive);}/* xd_override_init_drive: this finds disk geometry in a "binary search" style, narrowing in on the "correct" number of heads   etc. by trying values until it gets the highest successful value. Idea courtesy Salvador Abreu (spa@fct.unl.pt). */static void __init xd_override_init_drive (u_char drive){	u_short min[] = { 0,0,0 },max[] = { 16,1024,64 },test[] = { 0,0,0 };	u_char cmdblk[6],i;	if (xd_geo[3*drive])		xd_manual_geo_set(drive);	else {		for (i = 0; i < 3; i++) {			while (min[i] != max[i] - 1) {				test[i] = (min[i] + max[i]) / 2;				xd_build(cmdblk,CMD_SEEK,drive,(u_char) test[0],(u_short) test[1],(u_char) test[2],0,0);				if (!xd_command(cmdblk,PIO_MODE,0,0,0,XD_TIMEOUT * 2))					min[i] = test[i];				else					max[i] = test[i];			}			test[i] = min[i];		}		xd_info[drive].heads = (u_char) min[0] + 1;		xd_info[drive].cylinders = (u_short) min[1] + 1;		xd_info[drive].sectors = (u_char) min[2] + 1;	}	xd_info[drive].control = 0;}/* xd_setup: initialise controler from command line parameters */void __init do_xd_setup (int *integers){	switch (integers[0]) {		case 4: if (integers[4] < 0)				nodma = 1;			else if (integers[4] < 8)				xd_dma = integers[4];		case 3: if ((integers[3] > 0) && (integers[3] <= 0x3FC))				xd_iobase = integers[3];		case 2: if ((integers[2] > 0) && (integers[2] < 16))				xd_irq = integers[2];		case 1: xd_override = 1;			if ((integers[1] >= 0) && (integers[1] < (sizeof(xd_sigs) / sizeof(xd_sigs[0]))))				xd_type = integers[1];		case 0: break;		default:printk("xd: too many parameters for xd\n");	}	xd_maxsectors = 0x01;}/* xd_setparam: set the drive characteristics */static void __init xd_setparam (u_char command,u_char drive,u_char heads,u_short cylinders,u_short rwrite,u_short wprecomp,u_char ecc){	u_char cmdblk[14];	xd_build(cmdblk,command,drive,0,0,0,0,0);	cmdblk[6] = (u_char) (cylinders >> 8) & 0x03;	cmdblk[7] = (u_char) (cylinders & 0xFF);	cmdblk[8] = heads & 0x1F;	cmdblk[9] = (u_char) (rwrite >> 8) & 0x03;	cmdblk[10] = (u_char) (rwrite & 0xFF);	cmdblk[11] = (u_char) (wprecomp >> 8) & 0x03;	cmdblk[12] = (u_char) (wprecomp & 0xFF);	cmdblk[13] = ecc;	/* Some controllers require geometry info as data, not command */	if (xd_command(cmdblk,PIO_MODE,0,&cmdblk[6],0,XD_TIMEOUT * 2))		printk("xd: error setting characteristics for xd%c\n", 'a'+drive);}#ifdef MODULEstatic int xd[5] = { -1,-1,-1,-1, };MODULE_PARM(xd, "1-4i");MODULE_PARM(xd_geo, "3-6i");MODULE_PARM(nodma, "i");static void xd_done (void){	struct gendisk ** gdp;		blksize_size[MAJOR_NR] = NULL;	blk_cleanup_queue(BLK_DEFAULT_QUEUE(MAJOR_NR));	blk_size[MAJOR_NR] = NULL;	hardsect_size[MAJOR_NR] = NULL;	read_ahead[MAJOR_NR] = 0;	for (gdp = &gendisk_head; *gdp; gdp = &((*gdp)->next))		if (*gdp == &xd_gendisk)			break;	if (*gdp)		*gdp = (*gdp)->next;	release_region(xd_iobase,4);}int init_module(void){	int i,count = 0;	int error;	for (i = 4; i > 0; i--)		if(((xd[i] = xd[i-1]) >= 0) && !count)			count = i;	if((xd[0] = count))		do_xd_setup(xd);	error = xd_init();	if (error) return error;	printk(KERN_INFO "XD: Loaded as a module.\n");	if (!xd_drives) {		/* no drives detected - unload module */		devfs_unregister_blkdev(MAJOR_NR, "xd");		xd_done();		return (-1);	}        	return 0;}void cleanup_module(void){	int partition,dev,start;	devfs_unregister_blkdev(MAJOR_NR, "xd");	for (dev = 0; dev < xd_drives; dev++) {		start = dev << xd_gendisk.minor_shift; 		for (partition = xd_gendisk.max_p - 1; partition >= 0; partition--) {			int minor = (start | partition);			kdev_t devp = MKDEV(MAJOR_NR, minor);			start = dev << xd_gendisk.minor_shift; 			sync_dev(devp);			invalidate_buffers(devp);		}	}	xd_done();	devfs_unregister (devfs_handle);	if (xd_drives) {		free_irq(xd_irq, NULL);		free_dma(xd_dma);		if (xd_dma_buffer)			xd_dma_mem_free((unsigned long)xd_dma_buffer, xd_maxsectors * 0x200);	}}#elsestatic int __init xd_setup (char *str){	int ints[5];	get_options (str, ARRAY_SIZE (ints), ints);	do_xd_setup (ints);	return 1;}/* xd_manual_geo_init: initialise drive geometry from command line parameters   (used only for WD drives) */static int __init xd_manual_geo_init (char *str){	int i, integers[1 + 3*XD_MAXDRIVES];	get_options (str, ARRAY_SIZE (integers), integers);	if (integers[0]%3 != 0) {		printk("xd: incorrect number of parameters for xd_geo\n");		return 1;	}	for (i = 0; (i < integers[0]) && (i < 3*XD_MAXDRIVES); i++)		xd_geo[i] = integers[i+1];	return 1;}__setup ("xd=", xd_setup);__setup ("xd_geo=", xd_manual_geo_init);#endif /* MODULE */

⌨️ 快捷键说明

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