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

📄 edd.c

📁 这个linux源代码是很全面的~基本完整了~使用c编译的~由于时间问题我没有亲自测试~但就算用来做参考资料也是非常好的
💻 C
📖 第 1 页 / 共 2 页
字号:
/* * linux/arch/i386/kernel/edd.c *  Copyright (C) 2002 Dell Computer Corporation *  by Matt Domsch <Matt_Domsch@dell.com> * * BIOS Enhanced Disk Drive Services (EDD) * conformant to T13 Committee www.t13.org *   projects 1572D, 1484D, 1386D, 1226DT * * This code takes information provided by BIOS EDD calls * fn41 - Check Extensions Present and * fn48 - Get Device Parametes with EDD extensions * made in setup.S, copied to safe structures in setup.c, * and presents it in /proc. * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License v2.0 as published by * the Free Software Foundation * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the * GNU General Public License for more details. * *//* * TODO: * - move edd.[ch] to better locations if/when one is decided * - keep current with 2.5 EDD code changes */#include <linux/module.h>#include <linux/string.h>#include <linux/types.h>#include <linux/init.h>#include <linux/stat.h>#include <linux/ctype.h>#include <linux/slab.h>#include <linux/limits.h>#include <linux/pci.h>#include <linux/proc_fs.h>#include <asm/edd.h>MODULE_AUTHOR("Matt Domsch <Matt_Domsch@Dell.com>");MODULE_DESCRIPTION("proc interface to BIOS EDD information");MODULE_LICENSE("GPL");#define EDD_VERSION "0.09 2003-Jan-22"#define EDD_DEVICE_NAME_SIZE 16#define REPORT_URL "http://domsch.com/linux/edd30/results.html"#define left (count - (p - page) - 1)static struct proc_dir_entry *bios_dir;struct attr_entry {	struct proc_dir_entry *entry;	struct list_head node;};struct edd_device {	char name[EDD_DEVICE_NAME_SIZE];	struct edd_info *info;	struct proc_dir_entry *dir;	struct list_head attr_list;};static struct edd_device *edd_devices[EDDMAXNR];struct edd_attribute {	char *name;	int (*show)(char *page, char **start, off_t off,		    int count, int *eof, void *data);	int (*test) (struct edd_device * edev);};#define EDD_DEVICE_ATTR(_name,_show,_test) \struct edd_attribute edd_attr_##_name = { 	\	.name = __stringify(_name), \	.show	= _show,	    \        .test   = _test,            \};static inline struct edd_info *edd_dev_get_info(struct edd_device *edev){	return edev->info;}static inline voidedd_dev_set_info(struct edd_device *edev, struct edd_info *info){	edev->info = info;}static intproc_calc_metrics(char *page, char **start, off_t off,		  int count, int *eof, int len){	if (len <= off+count) *eof = 1;	*start = page + off;	len -= off;	if (len>count) len = count;	if (len<0) len = 0;	return len;}static intedd_dump_raw_data(char *b, int count, void *data, int length){	char *orig_b = b;	char hexbuf[80], ascbuf[20], *h, *a, c;	unsigned char *p = data;	unsigned long column = 0;	int length_printed = 0, d;	const char maxcolumn = 16;	while (length_printed < length && count > 0) {		h = hexbuf;		a = ascbuf;		for (column = 0;		     column < maxcolumn && length_printed < length; column++) {			h += sprintf(h, "%02x ", (unsigned char) *p);			if (!isprint(*p))				c = '.';			else				c = *p;			a += sprintf(a, "%c", c);			p++;			length_printed++;		}		/* pad out the line */		for (; column < maxcolumn; column++) {			h += sprintf(h, "   ");			a += sprintf(a, " ");		}		d = snprintf(b, count, "%s\t%s\n", hexbuf, ascbuf);		b += d;		count -= d;	}	return (b - orig_b);}static intedd_show_host_bus(char *page, char **start, off_t off, int count, int *eof, void *data){	struct edd_info *info = data;	char *p = page;	int i;	if (!info || !page || off) {		return proc_calc_metrics(page, start, off, count, eof, 0);	}	for (i = 0; i < 4; i++) {		if (isprint(info->params.host_bus_type[i])) {			p += snprintf(p, left, "%c", info->params.host_bus_type[i]);		} else {			p += snprintf(p, left, " ");		}	}	if (!strncmp(info->params.host_bus_type, "ISA", 3)) {		p += snprintf(p, left, "\tbase_address: %x\n",			     info->params.interface_path.isa.base_address);	} else if (!strncmp(info->params.host_bus_type, "PCIX", 4) ||		   !strncmp(info->params.host_bus_type, "PCI", 3)) {		p += snprintf(p, left,			     "\t%02x:%02x.%d  channel: %u\n",			     info->params.interface_path.pci.bus,			     info->params.interface_path.pci.slot,			     info->params.interface_path.pci.function,			     info->params.interface_path.pci.channel);	} else if (!strncmp(info->params.host_bus_type, "IBND", 4) ||		   !strncmp(info->params.host_bus_type, "XPRS", 4) ||		   !strncmp(info->params.host_bus_type, "HTPT", 4)) {		p += snprintf(p, left,			     "\tTBD: %llx\n",			     info->params.interface_path.ibnd.reserved);	} else {		p += snprintf(p, left, "\tunknown: %llx\n",			     info->params.interface_path.unknown.reserved);	}	return proc_calc_metrics(page, start, off, count, eof, (p - page));}static intedd_show_interface(char *page, char **start, off_t off, int count, int *eof, void *data){	struct edd_info *info = data;	char *p = page;	int i;	if (!info || !page || off) {		return proc_calc_metrics(page, start, off, count, eof, 0);	}	for (i = 0; i < 8; i++) {		if (isprint(info->params.interface_type[i])) {			p += snprintf(p, left, "%c", info->params.interface_type[i]);		} else {			p += snprintf(p, left, " ");		}	}	if (!strncmp(info->params.interface_type, "ATAPI", 5)) {		p += snprintf(p, left, "\tdevice: %u  lun: %u\n",			     info->params.device_path.atapi.device,			     info->params.device_path.atapi.lun);	} else if (!strncmp(info->params.interface_type, "ATA", 3)) {		p += snprintf(p, left, "\tdevice: %u\n",			     info->params.device_path.ata.device);	} else if (!strncmp(info->params.interface_type, "SCSI", 4)) {		p += snprintf(p, left, "\tid: %u  lun: %llu\n",			     info->params.device_path.scsi.id,			     info->params.device_path.scsi.lun);	} else if (!strncmp(info->params.interface_type, "USB", 3)) {		p += snprintf(p, left, "\tserial_number: %llx\n",			     info->params.device_path.usb.serial_number);	} else if (!strncmp(info->params.interface_type, "1394", 4)) {		p += snprintf(p, left, "\teui: %llx\n",			     info->params.device_path.i1394.eui);	} else if (!strncmp(info->params.interface_type, "FIBRE", 5)) {		p += snprintf(p, left, "\twwid: %llx lun: %llx\n",			     info->params.device_path.fibre.wwid,			     info->params.device_path.fibre.lun);	} else if (!strncmp(info->params.interface_type, "I2O", 3)) {		p += snprintf(p, left, "\tidentity_tag: %llx\n",			     info->params.device_path.i2o.identity_tag);	} else if (!strncmp(info->params.interface_type, "RAID", 4)) {		p += snprintf(p, left, "\tidentity_tag: %x\n",			     info->params.device_path.raid.array_number);	} else if (!strncmp(info->params.interface_type, "SATA", 4)) {		p += snprintf(p, left, "\tdevice: %u\n",			     info->params.device_path.sata.device);	} else {		p += snprintf(p, left, "\tunknown: %llx %llx\n",			     info->params.device_path.unknown.reserved1,			     info->params.device_path.unknown.reserved2);	}	return proc_calc_metrics(page, start, off, count, eof, (p - page));}/** * edd_show_raw_data() - unparses EDD information, returned to user-space * * Returns: number of bytes written, or 0 on failure */static intedd_show_raw_data(char *page, char **start, off_t off, int count, int *eof, void *data){	struct edd_info *info = data;	char *p = page;	int i, warn_padding = 0, nonzero_path = 0,		len = sizeof (*info) - 4;	uint8_t checksum = 0, c = 0;	if (!info || !page || off) {		return proc_calc_metrics(page, start, off, count, eof, 0);	}	if (!(info->params.key == 0xBEDD || info->params.key == 0xDDBE))		len = info->params.length;	p += snprintf(p, left, "int13 fn48 returned data:\n\n");	p += edd_dump_raw_data(p, left, ((char *) info) + 4, len);	/* Spec violation.  Adaptec AIC7899 returns 0xDDBE	   here, when it should be 0xBEDD.	 */	p += snprintf(p, left, "\n");	if (info->params.key == 0xDDBE) {		p += snprintf(p, left,			     "Warning: Spec violation.  Key should be 0xBEDD, is 0xDDBE\n");	}	if (!(info->params.key == 0xBEDD || info->params.key == 0xDDBE)) {		goto out;	}	for (i = 30; i <= 73; i++) {		c = *(((uint8_t *) info) + i + 4);		if (c)			nonzero_path++;		checksum += c;	}	if (checksum) {		p += snprintf(p, left,			     "Warning: Spec violation.  Device Path checksum invalid.\n");	}	if (!nonzero_path) {		p += snprintf(p, left, "Error: Spec violation.  Empty device path.\n");		goto out;	}	for (i = 0; i < 4; i++) {		if (!isprint(info->params.host_bus_type[i])) {			warn_padding++;		}	}	for (i = 0; i < 8; i++) {		if (!isprint(info->params.interface_type[i])) {			warn_padding++;		}	}	if (warn_padding) {		p += snprintf(p, left,			     "Warning: Spec violation.  Padding should be 0x20.\n");	}out:	p += snprintf(p, left, "\nPlease check %s\n", REPORT_URL);	p += snprintf(p, left, "to see if this device has been reported.  If not,\n");	p += snprintf(p, left, "please send the information requested there.\n");	return proc_calc_metrics(page, start, off, count, eof, (p - page));}static intedd_show_version(char *page, char **start, off_t off, int count, int *eof, void *data){	struct edd_info *info = data;	char *p = page;	if (!info || !page || off) {		return proc_calc_metrics(page, start, off, count, eof, 0);	}	p += snprintf(p, left, "0x%02x\n", info->version);	return proc_calc_metrics(page, start, off, count, eof, (p - page));}static intedd_show_extensions(char *page, char **start, off_t off, int count, int *eof, void *data){

⌨️ 快捷键说明

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