while (ioread8(&rtl_table->command)) {
msleep(10); if (count++ > 500) {
pr_err("Hardware not responding to " "mode switch request\n");
ret = -EIO; break;
}
}
if (ioread8(&rtl_table->command_status)) {
RTL_DEBUG("command_status reports failed command\n");
ret = -EIO;
}
}
ret = subsys_system_register(&rtl_subsys, NULL); if (!ret) { struct device *dev_root = bus_get_dev_root(&rtl_subsys);
if (dev_root) { for (i = 0; rtl_attributes[i]; i ++)
device_create_file(dev_root, rtl_attributes[i]);
put_device(dev_root);
}
} return ret;
}
staticvoid rtl_teardown_sysfs(void) { struct device *dev_root = bus_get_dev_root(&rtl_subsys); int i;
if (dev_root) { for (i = 0; rtl_attributes[i]; i ++)
device_remove_file(dev_root, rtl_attributes[i]);
put_device(dev_root);
}
bus_unregister(&rtl_subsys);
}
staticint __init ibm_rtl_init(void) { unsignedlong ebda_addr, ebda_size; unsignedint ebda_kb; int ret = -ENODEV, i;
if (force)
pr_warn("module loaded by force\n"); /* first ensure that we are running on IBM HW */ elseif (efi_enabled(EFI_BOOT) || !dmi_check_system(ibm_rtl_dmi_table)) return -ENODEV;
/* Get the address for the Extended BIOS Data Area */
ebda_addr = get_bios_ebda(); if (!ebda_addr) {
RTL_DEBUG("no BIOS EBDA found\n"); return -ENODEV;
}
ebda_map = ioremap(ebda_addr, 4); if (!ebda_map) return -ENOMEM;
/* First word in the EDBA is the Size in KB */
ebda_kb = ioread16(ebda_map);
RTL_DEBUG("EBDA is %d kB\n", ebda_kb);
if (ebda_kb == 0) goto out;
iounmap(ebda_map);
ebda_size = ebda_kb*1024;
/* Remap the whole table */
ebda_map = ioremap(ebda_addr, ebda_size); if (!ebda_map) return -ENOMEM;
/* search for the _RTL_ signature at the start of the table */ for (i = 0 ; i < ebda_size/sizeof(unsignedint); i++) { struct ibm_rtl_table __iomem * tmp;
tmp = (struct ibm_rtl_table __iomem *) (ebda_map+i); if ((readq(&tmp->signature) & RTL_MASK) == RTL_SIGNATURE) {
phys_addr_t addr; unsignedint plen;
RTL_DEBUG("found RTL_SIGNATURE at %p\n", tmp);
rtl_table = tmp; /* The address, value, width and offset are platform
* dependent and found in the ibm_rtl_table */
rtl_cmd_width = ioread8(&rtl_table->cmd_granularity);
rtl_cmd_type = ioread8(&rtl_table->cmd_address_type);
RTL_DEBUG("rtl_cmd_width = %u, rtl_cmd_type = %u\n",
rtl_cmd_width, rtl_cmd_type);
addr = ioread32(&rtl_table->cmd_port_address);
RTL_DEBUG("addr = %#llx\n", (unsignedlonglong)addr);
plen = rtl_cmd_width/sizeof(char);
rtl_cmd_addr = rtl_port_map(addr, plen);
RTL_DEBUG("rtl_cmd_addr = %p\n", rtl_cmd_addr); if (!rtl_cmd_addr) {
ret = -ENOMEM; break;
}
ret = rtl_setup_sysfs(); break;
}
}
out: if (ret) {
iounmap(ebda_map);
rtl_port_unmap(rtl_cmd_addr);
}
return ret;
}
staticvoid __exit ibm_rtl_exit(void)
{ if (rtl_table) {
RTL_DEBUG("cleaning up"); /* do not leave the machine in SMI-free mode */
ibm_rtl_write(0); /* unmap, unlink and remove all traces */
rtl_teardown_sysfs();
iounmap(ebda_map);
rtl_port_unmap(rtl_cmd_addr);
}
}
Die Informationen auf dieser Webseite wurden
nach bestem Wissen sorgfältig zusammengestellt. Es wird jedoch weder Vollständigkeit, noch Richtigkeit,
noch Qualität der bereit gestellten Informationen zugesichert.
Bemerkung:
Die farbliche Syntaxdarstellung und die Messung sind noch experimentell.