1 /* 2 * linux/drivers/firmware/edd.c 3 * Copyright (C) 2002, 2003, 2004 Dell Inc. 4 * by Matt Domsch <Matt_Domsch@dell.com> 5 * disk signature by Matt Domsch, Andrew Wilks, and Sandeep K. Shandilya 6 * legacy CHS by Patrick J. LoPresti <patl@users.sourceforge.net> 7 * 8 * BIOS Enhanced Disk Drive Services (EDD) 9 * conformant to T13 Committee www.t13.org 10 * projects 1572D, 1484D, 1386D, 1226DT 11 * 12 * This code takes information provided by BIOS EDD calls 13 * fn41 - Check Extensions Present and 14 * fn48 - Get Device Parameters with EDD extensions 15 * made in setup.S, copied to safe structures in setup.c, 16 * and presents it in sysfs. 17 * 18 * Please see http://linux.dell.com/edd/results.html for 19 * the list of BIOSs which have been reported to implement EDD. 20 * 21 * This program is free software; you can redistribute it and/or modify 22 * it under the terms of the GNU General Public License v2.0 as published by 23 * the Free Software Foundation 24 * 25 * This program is distributed in the hope that it will be useful, 26 * but WITHOUT ANY WARRANTY; without even the implied warranty of 27 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 28 * GNU General Public License for more details. 29 * 30 */ 31 32 #include <linux/module.h> 33 #include <linux/string.h> 34 #include <linux/types.h> 35 #include <linux/init.h> 36 #include <linux/stat.h> 37 #include <linux/err.h> 38 #include <linux/ctype.h> 39 #include <linux/slab.h> 40 #include <linux/limits.h> 41 #include <linux/device.h> 42 #include <linux/pci.h> 43 #include <linux/blkdev.h> 44 #include <linux/edd.h> 45 46 #define EDD_VERSION "0.16" 47 #define EDD_DATE "2004-Jun-25" 48 49 MODULE_AUTHOR("Matt Domsch <Matt_Domsch@Dell.com>"); 50 MODULE_DESCRIPTION("sysfs interface to BIOS EDD information"); 51 MODULE_LICENSE("GPL"); 52 MODULE_VERSION(EDD_VERSION); 53 54 #define left (PAGE_SIZE - (p - buf) - 1) 55 56 struct edd_device { 57 unsigned int index; 58 unsigned int mbr_signature; 59 struct edd_info *info; 60 struct kobject kobj; 61 }; 62 63 struct edd_attribute { 64 struct attribute attr; 65 ssize_t(*show) (struct edd_device * edev, char *buf); 66 int (*test) (struct edd_device * edev); 67 }; 68 69 /* forward declarations */ 70 static int edd_dev_is_type(struct edd_device *edev, const char *type); 71 static struct pci_dev *edd_get_pci_dev(struct edd_device *edev); 72 73 static struct edd_device *edd_devices[EDD_MBR_SIG_MAX]; 74 75 #define EDD_DEVICE_ATTR(_name,_mode,_show,_test) \ 76 struct edd_attribute edd_attr_##_name = { \ 77 .attr = {.name = __stringify(_name), .mode = _mode }, \ 78 .show = _show, \ 79 .test = _test, \ 80 }; 81 82 static int 83 edd_has_mbr_signature(struct edd_device *edev) 84 { 85 return edev->index < min_t(unsigned char, edd.mbr_signature_nr, EDD_MBR_SIG_MAX); 86 } 87 88 static int 89 edd_has_edd_info(struct edd_device *edev) 90 { 91 return edev->index < min_t(unsigned char, edd.edd_info_nr, EDDMAXNR); 92 } 93 94 static inline struct edd_info * 95 edd_dev_get_info(struct edd_device *edev) 96 { 97 return edev->info; 98 } 99 100 static inline void 101 edd_dev_set_info(struct edd_device *edev, int i) 102 { 103 edev->index = i; 104 if (edd_has_mbr_signature(edev)) 105 edev->mbr_signature = edd.mbr_signature[i]; 106 if (edd_has_edd_info(edev)) 107 edev->info = &edd.edd_info[i]; 108 } 109 110 #define to_edd_attr(_attr) container_of(_attr,struct edd_attribute,attr) 111 #define to_edd_device(obj) container_of(obj,struct edd_device,kobj) 112 113 static ssize_t 114 edd_attr_show(struct kobject * kobj, struct attribute *attr, char *buf) 115 { 116 struct edd_device *dev = to_edd_device(kobj); 117 struct edd_attribute *edd_attr = to_edd_attr(attr); 118 ssize_t ret = -EIO; 119 120 if (edd_attr->show) 121 ret = edd_attr->show(dev, buf); 122 return ret; 123 } 124 125 static const struct sysfs_ops edd_attr_ops = { 126 .show = edd_attr_show, 127 }; 128 129 static ssize_t 130 edd_show_host_bus(struct edd_device *edev, char *buf) 131 { 132 struct edd_info *info; 133 char *p = buf; 134 int i; 135 136 if (!edev) 137 return -EINVAL; 138 info = edd_dev_get_info(edev); 139 if (!info || !buf) 140 return -EINVAL; 141 142 for (i = 0; i < 4; i++) { 143 if (isprint(info->params.host_bus_type[i])) { 144 p += scnprintf(p, left, "%c", info->params.host_bus_type[i]); 145 } else { 146 p += scnprintf(p, left, " "); 147 } 148 } 149 150 if (!strncmp(info->params.host_bus_type, "ISA", 3)) { 151 p += scnprintf(p, left, "\tbase_address: %x\n", 152 info->params.interface_path.isa.base_address); 153 } else if (!strncmp(info->params.host_bus_type, "PCIX", 4) || 154 !strncmp(info->params.host_bus_type, "PCI", 3)) { 155 p += scnprintf(p, left, 156 "\t%02x:%02x.%d channel: %u\n", 157 info->params.interface_path.pci.bus, 158 info->params.interface_path.pci.slot, 159 info->params.interface_path.pci.function, 160 info->params.interface_path.pci.channel); 161 } else if (!strncmp(info->params.host_bus_type, "IBND", 4) || 162 !strncmp(info->params.host_bus_type, "XPRS", 4) || 163 !strncmp(info->params.host_bus_type, "HTPT", 4)) { 164 p += scnprintf(p, left, 165 "\tTBD: %llx\n", 166 info->params.interface_path.ibnd.reserved); 167 168 } else { 169 p += scnprintf(p, left, "\tunknown: %llx\n", 170 info->params.interface_path.unknown.reserved); 171 } 172 return (p - buf); 173 } 174 175 static ssize_t 176 edd_show_interface(struct edd_device *edev, char *buf) 177 { 178 struct edd_info *info; 179 char *p = buf; 180 int i; 181 182 if (!edev) 183 return -EINVAL; 184 info = edd_dev_get_info(edev); 185 if (!info || !buf) 186 return -EINVAL; 187 188 for (i = 0; i < 8; i++) { 189 if (isprint(info->params.interface_type[i])) { 190 p += scnprintf(p, left, "%c", info->params.interface_type[i]); 191 } else { 192 p += scnprintf(p, left, " "); 193 } 194 } 195 if (!strncmp(info->params.interface_type, "ATAPI", 5)) { 196 p += scnprintf(p, left, "\tdevice: %u lun: %u\n", 197 info->params.device_path.atapi.device, 198 info->params.device_path.atapi.lun); 199 } else if (!strncmp(info->params.interface_type, "ATA", 3)) { 200 p += scnprintf(p, left, "\tdevice: %u\n", 201 info->params.device_path.ata.device); 202 } else if (!strncmp(info->params.interface_type, "SCSI", 4)) { 203 p += scnprintf(p, left, "\tid: %u lun: %llu\n", 204 info->params.device_path.scsi.id, 205 info->params.device_path.scsi.lun); 206 } else if (!strncmp(info->params.interface_type, "USB", 3)) { 207 p += scnprintf(p, left, "\tserial_number: %llx\n", 208 info->params.device_path.usb.serial_number); 209 } else if (!strncmp(info->params.interface_type, "1394", 4)) { 210 p += scnprintf(p, left, "\teui: %llx\n", 211 info->params.device_path.i1394.eui); 212 } else if (!strncmp(info->params.interface_type, "FIBRE", 5)) { 213 p += scnprintf(p, left, "\twwid: %llx lun: %llx\n", 214 info->params.device_path.fibre.wwid, 215 info->params.device_path.fibre.lun); 216 } else if (!strncmp(info->params.interface_type, "I2O", 3)) { 217 p += scnprintf(p, left, "\tidentity_tag: %llx\n", 218 info->params.device_path.i2o.identity_tag); 219 } else if (!strncmp(info->params.interface_type, "RAID", 4)) { 220 p += scnprintf(p, left, "\tidentity_tag: %x\n", 221 info->params.device_path.raid.array_number); 222 } else if (!strncmp(info->params.interface_type, "SATA", 4)) { 223 p += scnprintf(p, left, "\tdevice: %u\n", 224 info->params.device_path.sata.device); 225 } else { 226 p += scnprintf(p, left, "\tunknown: %llx %llx\n", 227 info->params.device_path.unknown.reserved1, 228 info->params.device_path.unknown.reserved2); 229 } 230 231 return (p - buf); 232 } 233 234 /** 235 * edd_show_raw_data() - copies raw data to buffer for userspace to parse 236 * @edev: target edd_device 237 * @buf: output buffer 238 * 239 * Returns: number of bytes written, or -EINVAL on failure 240 */ 241 static ssize_t 242 edd_show_raw_data(struct edd_device *edev, char *buf) 243 { 244 struct edd_info *info; 245 ssize_t len = sizeof (info->params); 246 if (!edev) 247 return -EINVAL; 248 info = edd_dev_get_info(edev); 249 if (!info || !buf) 250 return -EINVAL; 251 252 if (!(info->params.key == 0xBEDD || info->params.key == 0xDDBE)) 253 len = info->params.length; 254 255 /* In case of buggy BIOSs */ 256 if (len > (sizeof(info->params))) 257 len = sizeof(info->params); 258 259 memcpy(buf, &info->params, len); 260 return len; 261 } 262 263 static ssize_t 264 edd_show_version(struct edd_device *edev, char *buf) 265 { 266 struct edd_info *info; 267 char *p = buf; 268 if (!edev) 269 return -EINVAL; 270 info = edd_dev_get_info(edev); 271 if (!info || !buf) 272 return -EINVAL; 273 274 p += scnprintf(p, left, "0x%02x\n", info->version); 275 return (p - buf); 276 } 277 278 static ssize_t 279 edd_show_mbr_signature(struct edd_device *edev, char *buf) 280 { 281 char *p = buf; 282 p += scnprintf(p, left, "0x%08x\n", edev->mbr_signature); 283 return (p - buf); 284 } 285 286 static ssize_t 287 edd_show_extensions(struct edd_device *edev, char *buf) 288 { 289 struct edd_info *info; 290 char *p = buf; 291 if (!edev) 292 return -EINVAL; 293 info = edd_dev_get_info(edev); 294 if (!info || !buf) 295 return -EINVAL; 296 297 if (info->interface_support & EDD_EXT_FIXED_DISK_ACCESS) { 298 p += scnprintf(p, left, "Fixed disk access\n"); 299 } 300 if (info->interface_support & EDD_EXT_DEVICE_LOCKING_AND_EJECTING) { 301 p += scnprintf(p, left, "Device locking and ejecting\n"); 302 } 303 if (info->interface_support & EDD_EXT_ENHANCED_DISK_DRIVE_SUPPORT) { 304 p += scnprintf(p, left, "Enhanced Disk Drive support\n"); 305 } 306 if (info->interface_support & EDD_EXT_64BIT_EXTENSIONS) { 307 p += scnprintf(p, left, "64-bit extensions\n"); 308 } 309 return (p - buf); 310 } 311 312 static ssize_t 313 edd_show_info_flags(struct edd_device *edev, char *buf) 314 { 315 struct edd_info *info; 316 char *p = buf; 317 if (!edev) 318 return -EINVAL; 319 info = edd_dev_get_info(edev); 320 if (!info || !buf) 321 return -EINVAL; 322 323 if (info->params.info_flags & EDD_INFO_DMA_BOUNDARY_ERROR_TRANSPARENT) 324 p += scnprintf(p, left, "DMA boundary error transparent\n"); 325 if (info->params.info_flags & EDD_INFO_GEOMETRY_VALID) 326 p += scnprintf(p, left, "geometry valid\n"); 327 if (info->params.info_flags & EDD_INFO_REMOVABLE) 328 p += scnprintf(p, left, "removable\n"); 329 if (info->params.info_flags & EDD_INFO_WRITE_VERIFY) 330 p += scnprintf(p, left, "write verify\n"); 331 if (info->params.info_flags & EDD_INFO_MEDIA_CHANGE_NOTIFICATION) 332 p += scnprintf(p, left, "media change notification\n"); 333 if (info->params.info_flags & EDD_INFO_LOCKABLE) 334 p += scnprintf(p, left, "lockable\n"); 335 if (info->params.info_flags & EDD_INFO_NO_MEDIA_PRESENT) 336 p += scnprintf(p, left, "no media present\n"); 337 if (info->params.info_flags & EDD_INFO_USE_INT13_FN50) 338 p += scnprintf(p, left, "use int13 fn50\n"); 339 return (p - buf); 340 } 341 342 static ssize_t 343 edd_show_legacy_max_cylinder(struct edd_device *edev, char *buf) 344 { 345 struct edd_info *info; 346 char *p = buf; 347 if (!edev) 348 return -EINVAL; 349 info = edd_dev_get_info(edev); 350 if (!info || !buf) 351 return -EINVAL; 352 353 p += snprintf(p, left, "%u\n", info->legacy_max_cylinder); 354 return (p - buf); 355 } 356 357 static ssize_t 358 edd_show_legacy_max_head(struct edd_device *edev, char *buf) 359 { 360 struct edd_info *info; 361 char *p = buf; 362 if (!edev) 363 return -EINVAL; 364 info = edd_dev_get_info(edev); 365 if (!info || !buf) 366 return -EINVAL; 367 368 p += snprintf(p, left, "%u\n", info->legacy_max_head); 369 return (p - buf); 370 } 371 372 static ssize_t 373 edd_show_legacy_sectors_per_track(struct edd_device *edev, char *buf) 374 { 375 struct edd_info *info; 376 char *p = buf; 377 if (!edev) 378 return -EINVAL; 379 info = edd_dev_get_info(edev); 380 if (!info || !buf) 381 return -EINVAL; 382 383 p += snprintf(p, left, "%u\n", info->legacy_sectors_per_track); 384 return (p - buf); 385 } 386 387 static ssize_t 388 edd_show_default_cylinders(struct edd_device *edev, char *buf) 389 { 390 struct edd_info *info; 391 char *p = buf; 392 if (!edev) 393 return -EINVAL; 394 info = edd_dev_get_info(edev); 395 if (!info || !buf) 396 return -EINVAL; 397 398 p += scnprintf(p, left, "%u\n", info->params.num_default_cylinders); 399 return (p - buf); 400 } 401 402 static ssize_t 403 edd_show_default_heads(struct edd_device *edev, char *buf) 404 { 405 struct edd_info *info; 406 char *p = buf; 407 if (!edev) 408 return -EINVAL; 409 info = edd_dev_get_info(edev); 410 if (!info || !buf) 411 return -EINVAL; 412 413 p += scnprintf(p, left, "%u\n", info->params.num_default_heads); 414 return (p - buf); 415 } 416 417 static ssize_t 418 edd_show_default_sectors_per_track(struct edd_device *edev, char *buf) 419 { 420 struct edd_info *info; 421 char *p = buf; 422 if (!edev) 423 return -EINVAL; 424 info = edd_dev_get_info(edev); 425 if (!info || !buf) 426 return -EINVAL; 427 428 p += scnprintf(p, left, "%u\n", info->params.sectors_per_track); 429 return (p - buf); 430 } 431 432 static ssize_t 433 edd_show_sectors(struct edd_device *edev, char *buf) 434 { 435 struct edd_info *info; 436 char *p = buf; 437 if (!edev) 438 return -EINVAL; 439 info = edd_dev_get_info(edev); 440 if (!info || !buf) 441 return -EINVAL; 442 443 p += scnprintf(p, left, "%llu\n", info->params.number_of_sectors); 444 return (p - buf); 445 } 446 447 448 /* 449 * Some device instances may not have all the above attributes, 450 * or the attribute values may be meaningless (i.e. if 451 * the device is < EDD 3.0, it won't have host_bus and interface 452 * information), so don't bother making files for them. Likewise 453 * if the default_{cylinders,heads,sectors_per_track} values 454 * are zero, the BIOS doesn't provide sane values, don't bother 455 * creating files for them either. 456 */ 457 458 static int 459 edd_has_legacy_max_cylinder(struct edd_device *edev) 460 { 461 struct edd_info *info; 462 if (!edev) 463 return 0; 464 info = edd_dev_get_info(edev); 465 if (!info) 466 return 0; 467 return info->legacy_max_cylinder > 0; 468 } 469 470 static int 471 edd_has_legacy_max_head(struct edd_device *edev) 472 { 473 struct edd_info *info; 474 if (!edev) 475 return 0; 476 info = edd_dev_get_info(edev); 477 if (!info) 478 return 0; 479 return info->legacy_max_head > 0; 480 } 481 482 static int 483 edd_has_legacy_sectors_per_track(struct edd_device *edev) 484 { 485 struct edd_info *info; 486 if (!edev) 487 return 0; 488 info = edd_dev_get_info(edev); 489 if (!info) 490 return 0; 491 return info->legacy_sectors_per_track > 0; 492 } 493 494 static int 495 edd_has_default_cylinders(struct edd_device *edev) 496 { 497 struct edd_info *info; 498 if (!edev) 499 return 0; 500 info = edd_dev_get_info(edev); 501 if (!info) 502 return 0; 503 return info->params.num_default_cylinders > 0; 504 } 505 506 static int 507 edd_has_default_heads(struct edd_device *edev) 508 { 509 struct edd_info *info; 510 if (!edev) 511 return 0; 512 info = edd_dev_get_info(edev); 513 if (!info) 514 return 0; 515 return info->params.num_default_heads > 0; 516 } 517 518 static int 519 edd_has_default_sectors_per_track(struct edd_device *edev) 520 { 521 struct edd_info *info; 522 if (!edev) 523 return 0; 524 info = edd_dev_get_info(edev); 525 if (!info) 526 return 0; 527 return info->params.sectors_per_track > 0; 528 } 529 530 static int 531 edd_has_edd30(struct edd_device *edev) 532 { 533 struct edd_info *info; 534 int i; 535 u8 csum = 0; 536 537 if (!edev) 538 return 0; 539 info = edd_dev_get_info(edev); 540 if (!info) 541 return 0; 542 543 if (!(info->params.key == 0xBEDD || info->params.key == 0xDDBE)) { 544 return 0; 545 } 546 547 548 /* We support only T13 spec */ 549 if (info->params.device_path_info_length != 44) 550 return 0; 551 552 for (i = 30; i < info->params.device_path_info_length + 30; i++) 553 csum += *(((u8 *)&info->params) + i); 554 555 if (csum) 556 return 0; 557 558 return 1; 559 } 560 561 562 static EDD_DEVICE_ATTR(raw_data, 0444, edd_show_raw_data, edd_has_edd_info); 563 static EDD_DEVICE_ATTR(version, 0444, edd_show_version, edd_has_edd_info); 564 static EDD_DEVICE_ATTR(extensions, 0444, edd_show_extensions, edd_has_edd_info); 565 static EDD_DEVICE_ATTR(info_flags, 0444, edd_show_info_flags, edd_has_edd_info); 566 static EDD_DEVICE_ATTR(sectors, 0444, edd_show_sectors, edd_has_edd_info); 567 static EDD_DEVICE_ATTR(legacy_max_cylinder, 0444, 568 edd_show_legacy_max_cylinder, 569 edd_has_legacy_max_cylinder); 570 static EDD_DEVICE_ATTR(legacy_max_head, 0444, edd_show_legacy_max_head, 571 edd_has_legacy_max_head); 572 static EDD_DEVICE_ATTR(legacy_sectors_per_track, 0444, 573 edd_show_legacy_sectors_per_track, 574 edd_has_legacy_sectors_per_track); 575 static EDD_DEVICE_ATTR(default_cylinders, 0444, edd_show_default_cylinders, 576 edd_has_default_cylinders); 577 static EDD_DEVICE_ATTR(default_heads, 0444, edd_show_default_heads, 578 edd_has_default_heads); 579 static EDD_DEVICE_ATTR(default_sectors_per_track, 0444, 580 edd_show_default_sectors_per_track, 581 edd_has_default_sectors_per_track); 582 static EDD_DEVICE_ATTR(interface, 0444, edd_show_interface, edd_has_edd30); 583 static EDD_DEVICE_ATTR(host_bus, 0444, edd_show_host_bus, edd_has_edd30); 584 static EDD_DEVICE_ATTR(mbr_signature, 0444, edd_show_mbr_signature, edd_has_mbr_signature); 585 586 587 /* These are default attributes that are added for every edd 588 * device discovered. There are none. 589 */ 590 static struct attribute * def_attrs[] = { 591 NULL, 592 }; 593 594 /* These attributes are conditional and only added for some devices. */ 595 static struct edd_attribute * edd_attrs[] = { 596 &edd_attr_raw_data, 597 &edd_attr_version, 598 &edd_attr_extensions, 599 &edd_attr_info_flags, 600 &edd_attr_sectors, 601 &edd_attr_legacy_max_cylinder, 602 &edd_attr_legacy_max_head, 603 &edd_attr_legacy_sectors_per_track, 604 &edd_attr_default_cylinders, 605 &edd_attr_default_heads, 606 &edd_attr_default_sectors_per_track, 607 &edd_attr_interface, 608 &edd_attr_host_bus, 609 &edd_attr_mbr_signature, 610 NULL, 611 }; 612 613 /** 614 * edd_release - free edd structure 615 * @kobj: kobject of edd structure 616 * 617 * This is called when the refcount of the edd structure 618 * reaches 0. This should happen right after we unregister, 619 * but just in case, we use the release callback anyway. 620 */ 621 622 static void edd_release(struct kobject * kobj) 623 { 624 struct edd_device * dev = to_edd_device(kobj); 625 kfree(dev); 626 } 627 628 static struct kobj_type edd_ktype = { 629 .release = edd_release, 630 .sysfs_ops = &edd_attr_ops, 631 .default_attrs = def_attrs, 632 }; 633 634 static struct kset *edd_kset; 635 636 637 /** 638 * edd_dev_is_type() - is this EDD device a 'type' device? 639 * @edev: target edd_device 640 * @type: a host bus or interface identifier string per the EDD spec 641 * 642 * Returns 1 (TRUE) if it is a 'type' device, 0 otherwise. 643 */ 644 static int 645 edd_dev_is_type(struct edd_device *edev, const char *type) 646 { 647 struct edd_info *info; 648 if (!edev) 649 return 0; 650 info = edd_dev_get_info(edev); 651 652 if (type && info) { 653 if (!strncmp(info->params.host_bus_type, type, strlen(type)) || 654 !strncmp(info->params.interface_type, type, strlen(type))) 655 return 1; 656 } 657 return 0; 658 } 659 660 /** 661 * edd_get_pci_dev() - finds pci_dev that matches edev 662 * @edev: edd_device 663 * 664 * Returns pci_dev if found, or NULL 665 */ 666 static struct pci_dev * 667 edd_get_pci_dev(struct edd_device *edev) 668 { 669 struct edd_info *info = edd_dev_get_info(edev); 670 671 if (edd_dev_is_type(edev, "PCI")) { 672 return pci_get_bus_and_slot(info->params.interface_path.pci.bus, 673 PCI_DEVFN(info->params.interface_path.pci.slot, 674 info->params.interface_path.pci. 675 function)); 676 } 677 return NULL; 678 } 679 680 static int 681 edd_create_symlink_to_pcidev(struct edd_device *edev) 682 { 683 684 struct pci_dev *pci_dev = edd_get_pci_dev(edev); 685 int ret; 686 if (!pci_dev) 687 return 1; 688 ret = sysfs_create_link(&edev->kobj,&pci_dev->dev.kobj,"pci_dev"); 689 pci_dev_put(pci_dev); 690 return ret; 691 } 692 693 static inline void 694 edd_device_unregister(struct edd_device *edev) 695 { 696 kobject_put(&edev->kobj); 697 } 698 699 static void edd_populate_dir(struct edd_device * edev) 700 { 701 struct edd_attribute * attr; 702 int error = 0; 703 int i; 704 705 for (i = 0; (attr = edd_attrs[i]) && !error; i++) { 706 if (!attr->test || 707 (attr->test && attr->test(edev))) 708 error = sysfs_create_file(&edev->kobj,&attr->attr); 709 } 710 711 if (!error) { 712 edd_create_symlink_to_pcidev(edev); 713 } 714 } 715 716 static int 717 edd_device_register(struct edd_device *edev, int i) 718 { 719 int error; 720 721 if (!edev) 722 return 1; 723 edd_dev_set_info(edev, i); 724 edev->kobj.kset = edd_kset; 725 error = kobject_init_and_add(&edev->kobj, &edd_ktype, NULL, 726 "int13_dev%02x", 0x80 + i); 727 if (!error) { 728 edd_populate_dir(edev); 729 kobject_uevent(&edev->kobj, KOBJ_ADD); 730 } 731 return error; 732 } 733 734 static inline int edd_num_devices(void) 735 { 736 return max_t(unsigned char, 737 min_t(unsigned char, EDD_MBR_SIG_MAX, edd.mbr_signature_nr), 738 min_t(unsigned char, EDDMAXNR, edd.edd_info_nr)); 739 } 740 741 /** 742 * edd_init() - creates sysfs tree of EDD data 743 */ 744 static int __init 745 edd_init(void) 746 { 747 int i; 748 int rc=0; 749 struct edd_device *edev; 750 751 printk(KERN_INFO "BIOS EDD facility v%s %s, %d devices found\n", 752 EDD_VERSION, EDD_DATE, edd_num_devices()); 753 754 if (!edd_num_devices()) { 755 printk(KERN_INFO "EDD information not available.\n"); 756 return -ENODEV; 757 } 758 759 edd_kset = kset_create_and_add("edd", NULL, firmware_kobj); 760 if (!edd_kset) 761 return -ENOMEM; 762 763 for (i = 0; i < edd_num_devices(); i++) { 764 edev = kzalloc(sizeof (*edev), GFP_KERNEL); 765 if (!edev) { 766 rc = -ENOMEM; 767 goto out; 768 } 769 770 rc = edd_device_register(edev, i); 771 if (rc) { 772 kfree(edev); 773 goto out; 774 } 775 edd_devices[i] = edev; 776 } 777 778 return 0; 779 780 out: 781 while (--i >= 0) 782 edd_device_unregister(edd_devices[i]); 783 kset_unregister(edd_kset); 784 return rc; 785 } 786 787 static void __exit 788 edd_exit(void) 789 { 790 int i; 791 struct edd_device *edev; 792 793 for (i = 0; i < edd_num_devices(); i++) { 794 if ((edev = edd_devices[i])) 795 edd_device_unregister(edev); 796 } 797 kset_unregister(edd_kset); 798 } 799 800 late_initcall(edd_init); 801 module_exit(edd_exit); 802