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

📄 cfi_probe.c

📁 讲述linux的初始化过程
💻 C
📖 第 1 页 / 共 2 页
字号:
	struct cfi_private *retcfi;	struct flchip chip[MAX_CFI_CHIPS];	int i;	memset(&cfi, 0, sizeof(cfi));	/* The first invocation (with chips == NULL) leaves the device in Query Mode */	cfi.interleave = cfi_probe_new_chip(map, 0, NULL, NULL);	if (!cfi.interleave) {		printk("%s: Found no CFI device at location zero\n", map->name);		/* Doesn't appear to be CFI-compliant at all */		return NULL;	}	/* Read the Basic Query Structure from the device */	for (i=0; i<sizeof(struct cfi_ident); i++) {		((unsigned char *)&cfi.cfiq)[i] = map->read8(map,base + ((0x10 + i)*map->buswidth));	}	/* Do any necessary byteswapping */	cfi.cfiq.P_ID = le16_to_cpu(cfi.cfiq.P_ID);	cfi.cfiq.P_ADR = le16_to_cpu(cfi.cfiq.P_ADR);	cfi.cfiq.A_ID = le16_to_cpu(cfi.cfiq.A_ID);	cfi.cfiq.A_ADR = le16_to_cpu(cfi.cfiq.A_ADR);	cfi.cfiq.InterfaceDesc = le16_to_cpu(cfi.cfiq.InterfaceDesc);	cfi.cfiq.MaxBufWriteSize = le16_to_cpu(cfi.cfiq.MaxBufWriteSize);	#if 1	/* Dump the information therein */	print_cfi_ident(&cfi.cfiq);	for (i=0; i<cfi.cfiq.NumEraseRegions; i++) {		__u16 EraseRegionInfoNum = (map->read8(map,base + ((0x2d + (4*i))*map->buswidth))) + 			(((map->read8(map,(0x2e + (4*i))*map->buswidth)) << 8));		__u16 EraseRegionInfoSize = (map->read8(map, base + ((0x2f + (4*i))*map->buswidth))) + 			(map->read8(map, base + ((0x30 + (4*i))*map->buswidth)) << 8);				printk("  Erase Region #%d: BlockSize 0x%4.4X bytes, %d blocks\n",		       i, EraseRegionInfoSize * 256, EraseRegionInfoNum+1);	}		printk("\n");#endif		/* Switch the chip back into Read Mode, to make the alias detection work */	switch(map->buswidth) {	case 1:		map->write8(map, 0xff, 0x55);		break;	case 2:		map->write16(map, 0xffff, 0xaa);		break;	case 4:		map->write32(map, 0xffffffff, 0x154);		break;	}	/* OK. We've worked out what it is and we're happy with it. Now see if there are others */	chip[0].start = 0;	chip[0].state = FL_READY;	chip[0].mutex = &chip[0]._spinlock;	cfi.chipshift =  cfi.cfiq.DevSize;	cfi.numchips = 1;	if (!cfi.chipshift) {		printk("cfi.chipsize is zero. This is bad. cfi.cfiq.DevSize is %d\n", cfi.cfiq.DevSize);		return NULL;	}	for (base = (1<<cfi.chipshift); base < map->size; base += (1<<cfi.chipshift))		cfi_probe_new_chip(map, base, &chip[0], &cfi);	retcfi = kmalloc(sizeof(struct cfi_private) + cfi.numchips * sizeof(struct flchip), GFP_KERNEL);	if (!retcfi)		return NULL;	memcpy(retcfi, &cfi, sizeof(cfi));	memcpy(&retcfi->chips[0], chip, sizeof(struct flchip) * cfi.numchips);	for (i=0; i< retcfi->numchips; i++) {		init_waitqueue_head(&retcfi->chips[i].wq);		spin_lock_init(&retcfi->chips[i]._spinlock);	}	return retcfi;}static char *vendorname(__u16 vendor) {	switch (vendor) {	case P_ID_NONE:		return "None";			case P_ID_INTEL_EXT:		return "Intel/Sharp Extended";			case P_ID_AMD_STD:		return "AMD/Fujitsu Standard";			case P_ID_INTEL_STD:		return "Intel/Sharp Standard";			case P_ID_AMD_EXT:		return "AMD/Fujitsu Extended";			case P_ID_MITSUBISHI_STD:		return "Mitsubishi Standard";			case P_ID_MITSUBISHI_EXT:		return "Mitsubishi Extended";			case P_ID_RESERVED:		return "Not Allowed / Reserved for Future Use";			default:		return "Unknown";	}}		static void print_cfi_ident(struct cfi_ident *cfip){	if (cfip->qry[0] != 'Q' || cfip->qry[1] != 'R' || cfip->qry[2] != 'Y') {		printk("Invalid CFI ident structure.\n");		return;	}				printk("Primary Vendor Command Set: %4.4X (%s)\n", cfip->P_ID, vendorname(cfip->P_ID));	if (cfip->P_ADR)		printk("Primary Algorithm Table at %4.4X\n", cfip->P_ADR);	else		printk("No Primary Algorithm Table\n");		printk("Alternative Vendor Command Set: %4.4X (%s)\n", cfip->A_ID, vendorname(cfip->A_ID));	if (cfip->A_ADR)		printk("Alternate Algorithm Table at %4.4X\n", cfip->A_ADR);	else		printk("No Alternate Algorithm Table\n");					printk("Vcc Minimum: %x.%x V\n", cfip->VccMin >> 4, cfip->VccMin & 0xf);	printk("Vcc Maximum: %x.%x V\n", cfip->VccMax >> 4, cfip->VccMax & 0xf);	if (cfip->VppMin) {		printk("Vpp Minimum: %x.%x V\n", cfip->VppMin >> 4, cfip->VppMin & 0xf);		printk("Vpp Maximum: %x.%x V\n", cfip->VppMax >> 4, cfip->VppMax & 0xf);	}	else		printk("No Vpp line\n");		printk("Typical byte/word write timeout: %d 祍\n", 1<<cfip->WordWriteTimeoutTyp);	printk("Maximum byte/word write timeout: %d 祍\n", (1<<cfip->WordWriteTimeoutMax) * (1<<cfip->WordWriteTimeoutTyp));		if (cfip->BufWriteTimeoutTyp || cfip->BufWriteTimeoutMax) {		printk("Typical full buffer write timeout: %d 祍\n", 1<<cfip->BufWriteTimeoutTyp);		printk("Maximum full buffer write timeout: %d 祍\n", (1<<cfip->BufWriteTimeoutMax) * (1<<cfip->BufWriteTimeoutTyp));	}	else		printk("Full buffer write not supported\n");		printk("Typical block erase timeout: %d 祍\n", 1<<cfip->BlockEraseTimeoutTyp);	printk("Maximum block erase timeout: %d 祍\n", (1<<cfip->BlockEraseTimeoutMax) * (1<<cfip->BlockEraseTimeoutTyp));	if (cfip->ChipEraseTimeoutTyp || cfip->ChipEraseTimeoutMax) {		printk("Typical chip erase timeout: %d 祍\n", 1<<cfip->ChipEraseTimeoutTyp); 		printk("Maximum chip erase timeout: %d 祍\n", (1<<cfip->ChipEraseTimeoutMax) * (1<<cfip->ChipEraseTimeoutTyp));	}	else		printk("Chip erase not supported\n");		printk("Device size: 0x%X bytes (%d Mb)\n", 1 << cfip->DevSize, 1<< (cfip->DevSize - 20));	printk("Flash Device Interface description: 0x%4.4X\n", cfip->InterfaceDesc);	switch(cfip->InterfaceDesc) {	case 0:		printk("  - x8-only asynchronous interface\n");		break;			case 1:		printk("  - x16-only asynchronous interface\n");		break;			case 2:		printk("  - supports x8 and x16 via BYTE# with asynchronous interface\n");		break;			case 3:		printk("  - x32-only asynchronous interface\n");		break;			case 65535:		printk("  - Not Allowed / Reserved\n");		break;			default:		printk("  - Unknown\n");		break;	}		printk("Max. bytes in buffer write: 0x%x\n", 1<< cfip->MaxBufWriteSize);	printk("Number of Erase Block Regions: %d\n", cfip->NumEraseRegions);	}static void check_cmd_set(struct map_info *map, int primary, unsigned long base){	__u16 adr;	struct cfi_private *cfi = map->fldrv_priv;	__u16 type = primary?cfi->cfiq.P_ID:cfi->cfiq.A_ID;	char probename[32];	void (*probe_function)(struct map_info *, int, unsigned long);		if (type == P_ID_NONE || type == P_ID_RESERVED)		return;		sprintf(probename, "cfi_cmdset_%4.4X", type);		probe_function = inter_module_get_request(probename, probename);	if (probe_function) {		(*probe_function)(map, primary, base);		return;	}	/* This was a command set we don't know about. Print only the basic info */	adr = primary?cfi->cfiq.P_ADR:cfi->cfiq.A_ADR;		if (!adr) {		printk(" No Extended Query Table\n");	}	else if (map->read8(map,base+(adr*map->buswidth)) != (primary?'P':'A') ||		 map->read8(map,base+((adr+1)*map->buswidth)) != (primary?'R':'L') ||		 map->read8(map,base+((adr+2)*map->buswidth)) != (primary?'I':'T')) {		printk ("Invalid Extended Query Table at %4.4X: %2.2X %2.2X %2.2X\n",			adr,			map->read8(map,base+(adr*map->buswidth)),			map->read8(map,base+((adr+1)*map->buswidth)),			map->read8(map,base+((adr+2)*map->buswidth)));	}	else {		printk(" Extended Query Table version %c.%c\n",		       map->read8(map,base+((adr+3)*map->buswidth)), 		       map->read8(map,base+((adr+4)*map->buswidth)));	}}static int __init cfi_probe_init(void){	inter_module_register(im_name, THIS_MODULE, &cfi_probe);	return 0;}static void __exit cfi_probe_exit(void){	inter_module_unregister(im_name);}module_init(cfi_probe_init);module_exit(cfi_probe_exit);

⌨️ 快捷键说明

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