diff options
Diffstat (limited to 'drivers/firmware/edd.c')
| -rw-r--r-- | drivers/firmware/edd.c | 81 |
1 files changed, 44 insertions, 37 deletions
diff --git a/drivers/firmware/edd.c b/drivers/firmware/edd.c index 0fb730ee1da..e2295766580 100644 --- a/drivers/firmware/edd.c +++ b/drivers/firmware/edd.c @@ -11,11 +11,11 @@ * * This code takes information provided by BIOS EDD calls * fn41 - Check Extensions Present and - * fn48 - Get Device Parametes with EDD extensions + * fn48 - Get Device Parameters with EDD extensions * made in setup.S, copied to safe structures in setup.c, * and presents it in sysfs. * - * Please see http://linux.dell.com/edd30/results.html for + * Please see http://linux.dell.com/edd/results.html for * the list of BIOSs which have been reported to implement EDD. * * This program is free software; you can redistribute it and/or modify @@ -122,7 +122,7 @@ edd_attr_show(struct kobject * kobj, struct attribute *attr, char *buf) return ret; } -static struct sysfs_ops edd_attr_ops = { +static const struct sysfs_ops edd_attr_ops = { .show = edd_attr_show, }; @@ -151,7 +151,8 @@ edd_show_host_bus(struct edd_device *edev, char *buf) p += scnprintf(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)) { + !strncmp(info->params.host_bus_type, "PCI", 3) || + !strncmp(info->params.host_bus_type, "XPRS", 4)) { p += scnprintf(p, left, "\t%02x:%02x.%d channel: %u\n", info->params.interface_path.pci.bus, @@ -159,7 +160,6 @@ edd_show_host_bus(struct edd_device *edev, char *buf) 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 += scnprintf(p, left, "\tTBD: %llx\n", @@ -531,8 +531,8 @@ static int edd_has_edd30(struct edd_device *edev) { struct edd_info *info; - int i, nonzero_path = 0; - char c; + int i; + u8 csum = 0; if (!edev) return 0; @@ -544,16 +544,16 @@ edd_has_edd30(struct edd_device *edev) return 0; } - for (i = 30; i <= 73; i++) { - c = *(((uint8_t *) info) + i + 4); - if (c) { - nonzero_path++; - break; - } - } - if (!nonzero_path) { + + /* We support only T13 spec */ + if (info->params.device_path_info_length != 44) + return 0; + + for (i = 30; i < info->params.device_path_info_length + 30; i++) + csum += *(((u8 *)&info->params) + i); + + if (csum) return 0; - } return 1; } @@ -625,13 +625,13 @@ static void edd_release(struct kobject * kobj) kfree(dev); } -static struct kobj_type ktype_edd = { +static struct kobj_type edd_ktype = { .release = edd_release, .sysfs_ops = &edd_attr_ops, .default_attrs = def_attrs, }; -static decl_subsys(edd,&ktype_edd,NULL); +static struct kset *edd_kset; /** @@ -668,7 +668,7 @@ edd_get_pci_dev(struct edd_device *edev) { struct edd_info *info = edd_dev_get_info(edev); - if (edd_dev_is_type(edev, "PCI")) { + if (edd_dev_is_type(edev, "PCI") || edd_dev_is_type(edev, "XPRS")) { return pci_get_bus_and_slot(info->params.interface_path.pci.bus, PCI_DEVFN(info->params.interface_path.pci.slot, info->params.interface_path.pci. @@ -693,7 +693,7 @@ edd_create_symlink_to_pcidev(struct edd_device *edev) static inline void edd_device_unregister(struct edd_device *edev) { - kobject_unregister(&edev->kobj); + kobject_put(&edev->kobj); } static void edd_populate_dir(struct edd_device * edev) @@ -721,12 +721,13 @@ edd_device_register(struct edd_device *edev, int i) if (!edev) return 1; edd_dev_set_info(edev, i); - kobject_set_name(&edev->kobj, "int13_dev%02x", - 0x80 + i); - kobj_set_kset_s(edev,edd_subsys); - error = kobject_register(&edev->kobj); - if (!error) + edev->kobj.kset = edd_kset; + error = kobject_init_and_add(&edev->kobj, &edd_ktype, NULL, + "int13_dev%02x", 0x80 + i); + if (!error) { edd_populate_dir(edev); + kobject_uevent(&edev->kobj, KOBJ_ADD); + } return error; } @@ -743,7 +744,7 @@ static inline int edd_num_devices(void) static int __init edd_init(void) { - unsigned int i; + int i; int rc=0; struct edd_device *edev; @@ -752,28 +753,34 @@ edd_init(void) if (!edd_num_devices()) { printk(KERN_INFO "EDD information not available.\n"); - return 1; + return -ENODEV; } - rc = firmware_register(&edd_subsys); - if (rc) - return rc; + edd_kset = kset_create_and_add("edd", NULL, firmware_kobj); + if (!edd_kset) + return -ENOMEM; - for (i = 0; i < edd_num_devices() && !rc; i++) { + for (i = 0; i < edd_num_devices(); i++) { edev = kzalloc(sizeof (*edev), GFP_KERNEL); - if (!edev) - return -ENOMEM; + if (!edev) { + rc = -ENOMEM; + goto out; + } rc = edd_device_register(edev, i); if (rc) { kfree(edev); - break; + goto out; } edd_devices[i] = edev; } - if (rc) - firmware_unregister(&edd_subsys); + return 0; + +out: + while (--i >= 0) + edd_device_unregister(edd_devices[i]); + kset_unregister(edd_kset); return rc; } @@ -787,7 +794,7 @@ edd_exit(void) if ((edev = edd_devices[i])) edd_device_unregister(edev); } - firmware_unregister(&edd_subsys); + kset_unregister(edd_kset); } late_initcall(edd_init); |
