📄 edd.c
字号:
struct edd_info *info = data; char *p = page; if (!info || !page || off) { return proc_calc_metrics(page, start, off, count, eof, 0); } if (info->interface_support & EDD_EXT_FIXED_DISK_ACCESS) { p += snprintf(p, left, "Fixed disk access\n"); } if (info->interface_support & EDD_EXT_DEVICE_LOCKING_AND_EJECTING) { p += snprintf(p, left, "Device locking and ejecting\n"); } if (info->interface_support & EDD_EXT_ENHANCED_DISK_DRIVE_SUPPORT) { p += snprintf(p, left, "Enhanced Disk Drive support\n"); } if (info->interface_support & EDD_EXT_64BIT_EXTENSIONS) { p += snprintf(p, left, "64-bit extensions\n"); } return proc_calc_metrics(page, start, off, count, eof, (p - page));}static intedd_show_info_flags(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); } if (info->params.info_flags & EDD_INFO_DMA_BOUNDRY_ERROR_TRANSPARENT) p += snprintf(p, left, "DMA boundry error transparent\n"); if (info->params.info_flags & EDD_INFO_GEOMETRY_VALID) p += snprintf(p, left, "geometry valid\n"); if (info->params.info_flags & EDD_INFO_REMOVABLE) p += snprintf(p, left, "removable\n"); if (info->params.info_flags & EDD_INFO_WRITE_VERIFY) p += snprintf(p, left, "write verify\n"); if (info->params.info_flags & EDD_INFO_MEDIA_CHANGE_NOTIFICATION) p += snprintf(p, left, "media change notification\n"); if (info->params.info_flags & EDD_INFO_LOCKABLE) p += snprintf(p, left, "lockable\n"); if (info->params.info_flags & EDD_INFO_NO_MEDIA_PRESENT) p += snprintf(p, left, "no media present\n"); if (info->params.info_flags & EDD_INFO_USE_INT13_FN50) p += snprintf(p, left, "use int13 fn50\n"); return proc_calc_metrics(page, start, off, count, eof, (p - page));}static intedd_show_default_cylinders(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%x\n", info->params.num_default_cylinders); return proc_calc_metrics(page, start, off, count, eof, (p - page));}static intedd_show_default_heads(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%x\n", info->params.num_default_heads); return proc_calc_metrics(page, start, off, count, eof, (p - page));}static intedd_show_default_sectors_per_track(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%x\n", info->params.sectors_per_track); return proc_calc_metrics(page, start, off, count, eof, (p - page));}static intedd_show_sectors(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%llx\n", info->params.number_of_sectors); return proc_calc_metrics(page, start, off, count, eof, (p - page));}static intedd_has_default_cylinders(struct edd_device *edev){ struct edd_info *info = edd_dev_get_info(edev); if (!edev || !info) return 0; return info->params.num_default_cylinders > 0;}static intedd_has_default_heads(struct edd_device *edev){ struct edd_info *info = edd_dev_get_info(edev); if (!edev || !info) return 0; return info->params.num_default_heads > 0;}static intedd_has_default_sectors_per_track(struct edd_device *edev){ struct edd_info *info = edd_dev_get_info(edev); if (!edev || !info) return 0; return info->params.sectors_per_track > 0;}static intedd_has_edd30(struct edd_device *edev){ struct edd_info *info = edd_dev_get_info(edev); int i, nonzero_path = 0; char c; if (!edev || !info) return 0; if (!(info->params.key == 0xBEDD || info->params.key == 0xDDBE)) { return 0; } for (i = 30; i <= 73; i++) { c = *(((uint8_t *) info) + i + 4); if (c) { nonzero_path++; break; } } if (!nonzero_path) { return 0; } return 1;}static EDD_DEVICE_ATTR(raw_data, edd_show_raw_data, NULL);static EDD_DEVICE_ATTR(version, edd_show_version, NULL);static EDD_DEVICE_ATTR(extensions, edd_show_extensions, NULL);static EDD_DEVICE_ATTR(info_flags, edd_show_info_flags, NULL);static EDD_DEVICE_ATTR(sectors, edd_show_sectors, NULL);static EDD_DEVICE_ATTR(default_cylinders, edd_show_default_cylinders, edd_has_default_cylinders);static EDD_DEVICE_ATTR(default_heads, edd_show_default_heads, edd_has_default_heads);static EDD_DEVICE_ATTR(default_sectors_per_track, edd_show_default_sectors_per_track, edd_has_default_sectors_per_track);static EDD_DEVICE_ATTR(interface, edd_show_interface,edd_has_edd30);static EDD_DEVICE_ATTR(host_bus, edd_show_host_bus, edd_has_edd30);static struct edd_attribute *def_attrs[] = { &edd_attr_raw_data, &edd_attr_version, &edd_attr_extensions, &edd_attr_info_flags, &edd_attr_sectors, &edd_attr_default_cylinders, &edd_attr_default_heads, &edd_attr_default_sectors_per_track, &edd_attr_interface, &edd_attr_host_bus, NULL,};static inline voidedd_device_unregister(struct edd_device *edev){ struct list_head *pos, *next; struct attr_entry *ae; list_for_each_safe(pos, next, &edev->attr_list) { ae = list_entry(pos, struct attr_entry, node); remove_proc_entry(ae->entry->name, edev->dir); list_del(&ae->node); kfree(ae); } remove_proc_entry(edev->dir->name, bios_dir);}static intedd_populate_dir(struct edd_device *edev){ struct edd_attribute *attr; struct attr_entry *ae; int i; int error = 0; for (i = 0; (attr=def_attrs[i]); i++) { if (!attr->test || (attr->test && attr->test(edev))) { ae = kmalloc(sizeof (*ae), GFP_KERNEL); if (ae == NULL) { error = 1; break; } INIT_LIST_HEAD(&ae->node); ae->entry = create_proc_read_entry(attr->name, 0444, edev->dir, attr->show, edd_dev_get_info(edev)); if (ae->entry == NULL) { error = 1; break; } list_add(&ae->node, &edev->attr_list); } } if (error) return error; return 0;}static intedd_make_dir(struct edd_device *edev){ int error=1; edev->dir = proc_mkdir(edev->name, bios_dir); if (edev->dir != NULL) { edev->dir->mode = (S_IFDIR | S_IRWXU | S_IRUGO | S_IXUGO); error = edd_populate_dir(edev); } return error;}static intedd_device_register(struct edd_device *edev, int i){ int error; if (!edev) return 1; memset(edev, 0, sizeof (*edev)); INIT_LIST_HEAD(&edev->attr_list); edd_dev_set_info(edev, &edd[i]); snprintf(edev->name, EDD_DEVICE_NAME_SIZE, "int13_dev%02x", edd[i].device); error = edd_make_dir(edev); return error;}/** * edd_init() - creates /proc tree of EDD data * * This assumes that eddnr and edd were * assigned in setup.c already. */static int __initedd_init(void){ unsigned int i; int rc = 0; struct edd_device *edev; printk(KERN_INFO "BIOS EDD facility v%s, %d devices found\n", EDD_VERSION, eddnr); if (!eddnr) { printk(KERN_INFO "EDD information not available.\n"); return 1; } bios_dir = proc_mkdir("bios", NULL); if (bios_dir == NULL) return 1; for (i = 0; i < eddnr && i < EDDMAXNR && !rc; i++) { edev = kmalloc(sizeof (*edev), GFP_KERNEL); if (!edev) { rc = 1; break; } rc = edd_device_register(edev, i); if (rc) { break; } edd_devices[i] = edev; } if (rc) { for (i = 0; i < eddnr && i < EDDMAXNR; i++) { if ((edev = edd_devices[i])) { edd_device_unregister(edev); kfree(edev); } } remove_proc_entry(bios_dir->name, NULL); } return rc;}static void __exitedd_exit(void){ int i; struct edd_device *edev; for (i = 0; i < eddnr && i < EDDMAXNR; i++) { if ((edev = edd_devices[i])) { edd_device_unregister(edev); kfree(edev); } } remove_proc_entry(bios_dir->name, NULL);}module_init(edd_init);module_exit(edd_exit);
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -