ftp://ftp.kernel.org/pub/linux/kernel/v2.6/linux-2.6.6.tar.bz2
[linux-2.6.git] / drivers / firmware / edd.c
1 /*
2  * linux/arch/i386/kernel/edd.c
3  *  Copyright (C) 2002, 2003, 2004 Dell Inc.
4  *  by Matt Domsch <Matt_Domsch@dell.com>
5  *  disk80 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 Parametes 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://domsch.com/linux/edd30/results.html for
19  * the list of BIOSs which have been reported to implement EDD.
20  * If you don't see yours listed, please send a report as described there.
21  *
22  * This program is free software; you can redistribute it and/or modify
23  * it under the terms of the GNU General Public License v2.0 as published by
24  * the Free Software Foundation
25  *
26  * This program is distributed in the hope that it will be useful,
27  * but WITHOUT ANY WARRANTY; without even the implied warranty of
28  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
29  * GNU General Public License for more details.
30  *
31  */
32
33 /*
34  * Known issues:
35  * - refcounting of struct device objects could be improved.
36  *
37  * TODO:
38  * - Add IDE and USB disk device support
39  * - move edd.[ch] to better locations if/when one is decided
40  */
41
42 #include <linux/module.h>
43 #include <linux/string.h>
44 #include <linux/types.h>
45 #include <linux/init.h>
46 #include <linux/stat.h>
47 #include <linux/err.h>
48 #include <linux/ctype.h>
49 #include <linux/slab.h>
50 #include <linux/limits.h>
51 #include <linux/device.h>
52 #include <linux/pci.h>
53 #include <linux/device.h>
54 #include <linux/blkdev.h>
55 #include <linux/edd.h>
56 /* FIXME - this really belongs in include/scsi/scsi.h */
57 #include <../drivers/scsi/scsi.h>
58 #include <../drivers/scsi/hosts.h>
59
60 MODULE_AUTHOR("Matt Domsch <Matt_Domsch@Dell.com>");
61 MODULE_DESCRIPTION("sysfs interface to BIOS EDD information");
62 MODULE_LICENSE("GPL");
63
64 #define EDD_VERSION "0.13 2004-Mar-09"
65 #define EDD_DEVICE_NAME_SIZE 16
66 #define REPORT_URL "http://linux.dell.com/edd/results.html"
67
68 #define left (PAGE_SIZE - (p - buf) - 1)
69
70 struct edd_device {
71         struct edd_info *info;
72         struct kobject kobj;
73 };
74
75 struct edd_attribute {
76         struct attribute attr;
77         ssize_t(*show) (struct edd_device * edev, char *buf);
78         int (*test) (struct edd_device * edev);
79 };
80
81 /* forward declarations */
82 static int edd_dev_is_type(struct edd_device *edev, const char *type);
83 static struct pci_dev *edd_get_pci_dev(struct edd_device *edev);
84
85 static struct edd_device *edd_devices[EDDMAXNR];
86
87 #define EDD_DEVICE_ATTR(_name,_mode,_show,_test) \
88 struct edd_attribute edd_attr_##_name = {       \
89         .attr = {.name = __stringify(_name), .mode = _mode, .owner = THIS_MODULE },     \
90         .show   = _show,                                \
91         .test   = _test,                                \
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, struct edd_info *info)
102 {
103         edev->info = info;
104 }
105
106 #define to_edd_attr(_attr) container_of(_attr,struct edd_attribute,attr)
107 #define to_edd_device(obj) container_of(obj,struct edd_device,kobj)
108
109 static ssize_t
110 edd_attr_show(struct kobject * kobj, struct attribute *attr, char *buf)
111 {
112         struct edd_device *dev = to_edd_device(kobj);
113         struct edd_attribute *edd_attr = to_edd_attr(attr);
114         ssize_t ret = 0;
115
116         if (edd_attr->show)
117                 ret = edd_attr->show(dev, buf);
118         return ret;
119 }
120
121 static struct sysfs_ops edd_attr_ops = {
122         .show = edd_attr_show,
123 };
124
125 static ssize_t
126 edd_show_host_bus(struct edd_device *edev, char *buf)
127 {
128         struct edd_info *info;
129         char *p = buf;
130         int i;
131
132         if (!edev)
133                 return -EINVAL;
134         info = edd_dev_get_info(edev);
135         if (!info || !buf)
136                 return -EINVAL;
137
138         for (i = 0; i < 4; i++) {
139                 if (isprint(info->params.host_bus_type[i])) {
140                         p += scnprintf(p, left, "%c", info->params.host_bus_type[i]);
141                 } else {
142                         p += scnprintf(p, left, " ");
143                 }
144         }
145
146         if (!strncmp(info->params.host_bus_type, "ISA", 3)) {
147                 p += scnprintf(p, left, "\tbase_address: %x\n",
148                              info->params.interface_path.isa.base_address);
149         } else if (!strncmp(info->params.host_bus_type, "PCIX", 4) ||
150                    !strncmp(info->params.host_bus_type, "PCI", 3)) {
151                 p += scnprintf(p, left,
152                              "\t%02x:%02x.%d  channel: %u\n",
153                              info->params.interface_path.pci.bus,
154                              info->params.interface_path.pci.slot,
155                              info->params.interface_path.pci.function,
156                              info->params.interface_path.pci.channel);
157         } else if (!strncmp(info->params.host_bus_type, "IBND", 4) ||
158                    !strncmp(info->params.host_bus_type, "XPRS", 4) ||
159                    !strncmp(info->params.host_bus_type, "HTPT", 4)) {
160                 p += scnprintf(p, left,
161                              "\tTBD: %llx\n",
162                              info->params.interface_path.ibnd.reserved);
163
164         } else {
165                 p += scnprintf(p, left, "\tunknown: %llx\n",
166                              info->params.interface_path.unknown.reserved);
167         }
168         return (p - buf);
169 }
170
171 static ssize_t
172 edd_show_interface(struct edd_device *edev, char *buf)
173 {
174         struct edd_info *info;
175         char *p = buf;
176         int i;
177
178         if (!edev)
179                 return -EINVAL;
180         info = edd_dev_get_info(edev);
181         if (!info || !buf)
182                 return -EINVAL;
183
184         for (i = 0; i < 8; i++) {
185                 if (isprint(info->params.interface_type[i])) {
186                         p += scnprintf(p, left, "%c", info->params.interface_type[i]);
187                 } else {
188                         p += scnprintf(p, left, " ");
189                 }
190         }
191         if (!strncmp(info->params.interface_type, "ATAPI", 5)) {
192                 p += scnprintf(p, left, "\tdevice: %u  lun: %u\n",
193                              info->params.device_path.atapi.device,
194                              info->params.device_path.atapi.lun);
195         } else if (!strncmp(info->params.interface_type, "ATA", 3)) {
196                 p += scnprintf(p, left, "\tdevice: %u\n",
197                              info->params.device_path.ata.device);
198         } else if (!strncmp(info->params.interface_type, "SCSI", 4)) {
199                 p += scnprintf(p, left, "\tid: %u  lun: %llu\n",
200                              info->params.device_path.scsi.id,
201                              info->params.device_path.scsi.lun);
202         } else if (!strncmp(info->params.interface_type, "USB", 3)) {
203                 p += scnprintf(p, left, "\tserial_number: %llx\n",
204                              info->params.device_path.usb.serial_number);
205         } else if (!strncmp(info->params.interface_type, "1394", 4)) {
206                 p += scnprintf(p, left, "\teui: %llx\n",
207                              info->params.device_path.i1394.eui);
208         } else if (!strncmp(info->params.interface_type, "FIBRE", 5)) {
209                 p += scnprintf(p, left, "\twwid: %llx lun: %llx\n",
210                              info->params.device_path.fibre.wwid,
211                              info->params.device_path.fibre.lun);
212         } else if (!strncmp(info->params.interface_type, "I2O", 3)) {
213                 p += scnprintf(p, left, "\tidentity_tag: %llx\n",
214                              info->params.device_path.i2o.identity_tag);
215         } else if (!strncmp(info->params.interface_type, "RAID", 4)) {
216                 p += scnprintf(p, left, "\tidentity_tag: %x\n",
217                              info->params.device_path.raid.array_number);
218         } else if (!strncmp(info->params.interface_type, "SATA", 4)) {
219                 p += scnprintf(p, left, "\tdevice: %u\n",
220                              info->params.device_path.sata.device);
221         } else {
222                 p += scnprintf(p, left, "\tunknown: %llx %llx\n",
223                              info->params.device_path.unknown.reserved1,
224                              info->params.device_path.unknown.reserved2);
225         }
226
227         return (p - buf);
228 }
229
230 /**
231  * edd_show_raw_data() - copies raw data to buffer for userspace to parse
232  *
233  * Returns: number of bytes written, or -EINVAL on failure
234  */
235 static ssize_t
236 edd_show_raw_data(struct edd_device *edev, char *buf)
237 {
238         struct edd_info *info;
239         ssize_t len = sizeof (info->params);
240         if (!edev)
241                 return -EINVAL;
242         info = edd_dev_get_info(edev);
243         if (!info || !buf)
244                 return -EINVAL;
245
246         if (!(info->params.key == 0xBEDD || info->params.key == 0xDDBE))
247                 len = info->params.length;
248
249         /* In case of buggy BIOSs */
250         if (len > (sizeof(info->params)))
251                 len = sizeof(info->params);
252
253         memcpy(buf, &info->params, len);
254         return len;
255 }
256
257 static ssize_t
258 edd_show_version(struct edd_device *edev, char *buf)
259 {
260         struct edd_info *info;
261         char *p = buf;
262         if (!edev)
263                 return -EINVAL;
264         info = edd_dev_get_info(edev);
265         if (!info || !buf)
266                 return -EINVAL;
267
268         p += scnprintf(p, left, "0x%02x\n", info->version);
269         return (p - buf);
270 }
271
272 static ssize_t
273 edd_show_disk80_sig(struct edd_device *edev, char *buf)
274 {
275         char *p = buf;
276         p += scnprintf(p, left, "0x%08x\n", edd_disk80_sig);
277         return (p - buf);
278 }
279
280 static ssize_t
281 edd_show_extensions(struct edd_device *edev, char *buf)
282 {
283         struct edd_info *info;
284         char *p = buf;
285         if (!edev)
286                 return -EINVAL;
287         info = edd_dev_get_info(edev);
288         if (!info || !buf)
289                 return -EINVAL;
290
291         if (info->interface_support & EDD_EXT_FIXED_DISK_ACCESS) {
292                 p += scnprintf(p, left, "Fixed disk access\n");
293         }
294         if (info->interface_support & EDD_EXT_DEVICE_LOCKING_AND_EJECTING) {
295                 p += scnprintf(p, left, "Device locking and ejecting\n");
296         }
297         if (info->interface_support & EDD_EXT_ENHANCED_DISK_DRIVE_SUPPORT) {
298                 p += scnprintf(p, left, "Enhanced Disk Drive support\n");
299         }
300         if (info->interface_support & EDD_EXT_64BIT_EXTENSIONS) {
301                 p += scnprintf(p, left, "64-bit extensions\n");
302         }
303         return (p - buf);
304 }
305
306 static ssize_t
307 edd_show_info_flags(struct edd_device *edev, char *buf)
308 {
309         struct edd_info *info;
310         char *p = buf;
311         if (!edev)
312                 return -EINVAL;
313         info = edd_dev_get_info(edev);
314         if (!info || !buf)
315                 return -EINVAL;
316
317         if (info->params.info_flags & EDD_INFO_DMA_BOUNDARY_ERROR_TRANSPARENT)
318                 p += scnprintf(p, left, "DMA boundary error transparent\n");
319         if (info->params.info_flags & EDD_INFO_GEOMETRY_VALID)
320                 p += scnprintf(p, left, "geometry valid\n");
321         if (info->params.info_flags & EDD_INFO_REMOVABLE)
322                 p += scnprintf(p, left, "removable\n");
323         if (info->params.info_flags & EDD_INFO_WRITE_VERIFY)
324                 p += scnprintf(p, left, "write verify\n");
325         if (info->params.info_flags & EDD_INFO_MEDIA_CHANGE_NOTIFICATION)
326                 p += scnprintf(p, left, "media change notification\n");
327         if (info->params.info_flags & EDD_INFO_LOCKABLE)
328                 p += scnprintf(p, left, "lockable\n");
329         if (info->params.info_flags & EDD_INFO_NO_MEDIA_PRESENT)
330                 p += scnprintf(p, left, "no media present\n");
331         if (info->params.info_flags & EDD_INFO_USE_INT13_FN50)
332                 p += scnprintf(p, left, "use int13 fn50\n");
333         return (p - buf);
334 }
335
336 static ssize_t
337 edd_show_legacy_cylinders(struct edd_device *edev, char *buf)
338 {
339         struct edd_info *info;
340         char *p = buf;
341         if (!edev)
342                 return -EINVAL;
343         info = edd_dev_get_info(edev);
344         if (!info || !buf)
345                 return -EINVAL;
346
347         p += snprintf(p, left, "0x%x\n", info->legacy_cylinders);
348         return (p - buf);
349 }
350
351 static ssize_t
352 edd_show_legacy_heads(struct edd_device *edev, char *buf)
353 {
354         struct edd_info *info;
355         char *p = buf;
356         if (!edev)
357                 return -EINVAL;
358         info = edd_dev_get_info(edev);
359         if (!info || !buf)
360                 return -EINVAL;
361
362         p += snprintf(p, left, "0x%x\n", info->legacy_heads);
363         return (p - buf);
364 }
365
366 static ssize_t
367 edd_show_legacy_sectors(struct edd_device *edev, char *buf)
368 {
369         struct edd_info *info;
370         char *p = buf;
371         if (!edev)
372                 return -EINVAL;
373         info = edd_dev_get_info(edev);
374         if (!info || !buf)
375                 return -EINVAL;
376
377         p += snprintf(p, left, "0x%x\n", info->legacy_sectors);
378         return (p - buf);
379 }
380
381 static ssize_t
382 edd_show_default_cylinders(struct edd_device *edev, char *buf)
383 {
384         struct edd_info *info;
385         char *p = buf;
386         if (!edev)
387                 return -EINVAL;
388         info = edd_dev_get_info(edev);
389         if (!info || !buf)
390                 return -EINVAL;
391
392         p += scnprintf(p, left, "0x%x\n", info->params.num_default_cylinders);
393         return (p - buf);
394 }
395
396 static ssize_t
397 edd_show_default_heads(struct edd_device *edev, char *buf)
398 {
399         struct edd_info *info;
400         char *p = buf;
401         if (!edev)
402                 return -EINVAL;
403         info = edd_dev_get_info(edev);
404         if (!info || !buf)
405                 return -EINVAL;
406
407         p += scnprintf(p, left, "0x%x\n", info->params.num_default_heads);
408         return (p - buf);
409 }
410
411 static ssize_t
412 edd_show_default_sectors_per_track(struct edd_device *edev, char *buf)
413 {
414         struct edd_info *info;
415         char *p = buf;
416         if (!edev)
417                 return -EINVAL;
418         info = edd_dev_get_info(edev);
419         if (!info || !buf)
420                 return -EINVAL;
421
422         p += scnprintf(p, left, "0x%x\n", info->params.sectors_per_track);
423         return (p - buf);
424 }
425
426 static ssize_t
427 edd_show_sectors(struct edd_device *edev, char *buf)
428 {
429         struct edd_info *info;
430         char *p = buf;
431         if (!edev)
432                 return -EINVAL;
433         info = edd_dev_get_info(edev);
434         if (!info || !buf)
435                 return -EINVAL;
436
437         p += scnprintf(p, left, "0x%llx\n", info->params.number_of_sectors);
438         return (p - buf);
439 }
440
441
442 /*
443  * Some device instances may not have all the above attributes,
444  * or the attribute values may be meaningless (i.e. if
445  * the device is < EDD 3.0, it won't have host_bus and interface
446  * information), so don't bother making files for them.  Likewise
447  * if the default_{cylinders,heads,sectors_per_track} values
448  * are zero, the BIOS doesn't provide sane values, don't bother
449  * creating files for them either.
450  */
451
452 static int
453 edd_has_legacy_cylinders(struct edd_device *edev)
454 {
455         struct edd_info *info;
456         if (!edev)
457                 return -EINVAL;
458         info = edd_dev_get_info(edev);
459         if (!info)
460                 return -EINVAL;
461         return info->legacy_cylinders > 0;
462 }
463
464 static int
465 edd_has_legacy_heads(struct edd_device *edev)
466 {
467         struct edd_info *info;
468         if (!edev)
469                 return -EINVAL;
470         info = edd_dev_get_info(edev);
471         if (!info)
472                 return -EINVAL;
473         return info->legacy_heads > 0;
474 }
475
476 static int
477 edd_has_legacy_sectors(struct edd_device *edev)
478 {
479         struct edd_info *info;
480         if (!edev)
481                 return -EINVAL;
482         info = edd_dev_get_info(edev);
483         if (!info)
484                 return -EINVAL;
485         return info->legacy_sectors > 0;
486 }
487
488 static int
489 edd_has_default_cylinders(struct edd_device *edev)
490 {
491         struct edd_info *info;
492         if (!edev)
493                 return -EINVAL;
494         info = edd_dev_get_info(edev);
495         if (!info)
496                 return -EINVAL;
497         return info->params.num_default_cylinders > 0;
498 }
499
500 static int
501 edd_has_default_heads(struct edd_device *edev)
502 {
503         struct edd_info *info;
504         if (!edev)
505                 return -EINVAL;
506         info = edd_dev_get_info(edev);
507         if (!info)
508                 return -EINVAL;
509         return info->params.num_default_heads > 0;
510 }
511
512 static int
513 edd_has_default_sectors_per_track(struct edd_device *edev)
514 {
515         struct edd_info *info;
516         if (!edev)
517                 return -EINVAL;
518         info = edd_dev_get_info(edev);
519         if (!info)
520                 return -EINVAL;
521         return info->params.sectors_per_track > 0;
522 }
523
524 static int
525 edd_has_edd30(struct edd_device *edev)
526 {
527         struct edd_info *info;
528         int i, nonzero_path = 0;
529         char c;
530
531         if (!edev)
532                 return 0;
533         info = edd_dev_get_info(edev);
534         if (!info)
535                 return 0;
536
537         if (!(info->params.key == 0xBEDD || info->params.key == 0xDDBE)) {
538                 return 0;
539         }
540
541         for (i = 30; i <= 73; i++) {
542                 c = *(((uint8_t *) info) + i + 4);
543                 if (c) {
544                         nonzero_path++;
545                         break;
546                 }
547         }
548         if (!nonzero_path) {
549                 return 0;
550         }
551
552         return 1;
553 }
554
555 static int
556 edd_has_disk80_sig(struct edd_device *edev)
557 {
558         struct edd_info *info;
559         if (!edev)
560                 return 0;
561         info = edd_dev_get_info(edev);
562         if (!info)
563                 return 0;
564         return info->device == 0x80;
565 }
566
567 static EDD_DEVICE_ATTR(raw_data, 0444, edd_show_raw_data, NULL);
568 static EDD_DEVICE_ATTR(version, 0444, edd_show_version, NULL);
569 static EDD_DEVICE_ATTR(extensions, 0444, edd_show_extensions, NULL);
570 static EDD_DEVICE_ATTR(info_flags, 0444, edd_show_info_flags, NULL);
571 static EDD_DEVICE_ATTR(sectors, 0444, edd_show_sectors, NULL);
572 static EDD_DEVICE_ATTR(legacy_cylinders, 0444, edd_show_legacy_cylinders,
573                        edd_has_legacy_cylinders);
574 static EDD_DEVICE_ATTR(legacy_heads, 0444, edd_show_legacy_heads,
575                        edd_has_legacy_heads);
576 static EDD_DEVICE_ATTR(legacy_sectors, 0444, edd_show_legacy_sectors,
577                        edd_has_legacy_sectors);
578 static EDD_DEVICE_ATTR(default_cylinders, 0444, edd_show_default_cylinders,
579                        edd_has_default_cylinders);
580 static EDD_DEVICE_ATTR(default_heads, 0444, edd_show_default_heads,
581                        edd_has_default_heads);
582 static EDD_DEVICE_ATTR(default_sectors_per_track, 0444,
583                        edd_show_default_sectors_per_track,
584                        edd_has_default_sectors_per_track);
585 static EDD_DEVICE_ATTR(interface, 0444, edd_show_interface, edd_has_edd30);
586 static EDD_DEVICE_ATTR(host_bus, 0444, edd_show_host_bus, edd_has_edd30);
587 static EDD_DEVICE_ATTR(mbr_signature, 0444, edd_show_disk80_sig, edd_has_disk80_sig);
588
589
590 /* These are default attributes that are added for every edd
591  * device discovered.
592  */
593 static struct attribute * def_attrs[] = {
594         &edd_attr_raw_data.attr,
595         &edd_attr_version.attr,
596         &edd_attr_extensions.attr,
597         &edd_attr_info_flags.attr,
598         &edd_attr_sectors.attr,
599         NULL,
600 };
601
602 /* These attributes are conditional and only added for some devices. */
603 static struct edd_attribute * edd_attrs[] = {
604         &edd_attr_legacy_cylinders,
605         &edd_attr_legacy_heads,
606         &edd_attr_legacy_sectors,
607         &edd_attr_default_cylinders,
608         &edd_attr_default_heads,
609         &edd_attr_default_sectors_per_track,
610         &edd_attr_interface,
611         &edd_attr_host_bus,
612         &edd_attr_mbr_signature,
613         NULL,
614 };
615
616 /**
617  *      edd_release - free edd structure
618  *      @kobj:  kobject of edd structure
619  *
620  *      This is called when the refcount of the edd structure
621  *      reaches 0. This should happen right after we unregister,
622  *      but just in case, we use the release callback anyway.
623  */
624
625 static void edd_release(struct kobject * kobj)
626 {
627         struct edd_device * dev = to_edd_device(kobj);
628         kfree(dev);
629 }
630
631 static struct kobj_type ktype_edd = {
632         .release        = edd_release,
633         .sysfs_ops      = &edd_attr_ops,
634         .default_attrs  = def_attrs,
635 };
636
637 static decl_subsys(edd,&ktype_edd,NULL);
638
639
640 /**
641  * edd_dev_is_type() - is this EDD device a 'type' device?
642  * @edev
643  * @type - a host bus or interface identifier string per the EDD spec
644  *
645  * Returns 1 (TRUE) if it is a 'type' device, 0 otherwise.
646  */
647 static int
648 edd_dev_is_type(struct edd_device *edev, const char *type)
649 {
650         struct edd_info *info;
651         if (!edev)
652                 return 0;
653         info = edd_dev_get_info(edev);
654
655         if (type && info) {
656                 if (!strncmp(info->params.host_bus_type, type, strlen(type)) ||
657                     !strncmp(info->params.interface_type, type, strlen(type)))
658                         return 1;
659         }
660         return 0;
661 }
662
663 /**
664  * edd_get_pci_dev() - finds pci_dev that matches edev
665  * @edev - edd_device
666  *
667  * Returns pci_dev if found, or NULL
668  */
669 static struct pci_dev *
670 edd_get_pci_dev(struct edd_device *edev)
671 {
672         struct edd_info *info = edd_dev_get_info(edev);
673
674         if (edd_dev_is_type(edev, "PCI")) {
675                 return pci_find_slot(info->params.interface_path.pci.bus,
676                                      PCI_DEVFN(info->params.interface_path.pci.slot,
677                                                info->params.interface_path.pci.
678                                                function));
679         }
680         return NULL;
681 }
682
683 static int
684 edd_create_symlink_to_pcidev(struct edd_device *edev)
685 {
686
687         struct pci_dev *pci_dev = edd_get_pci_dev(edev);
688         if (!pci_dev)
689                 return 1;
690         return sysfs_create_link(&edev->kobj,&pci_dev->dev.kobj,"pci_dev");
691 }
692
693 /*
694  * FIXME - as of 15-Jan-2003, there are some non-"scsi_device"s on the
695  * scsi_bus list.  The following functions could possibly mis-access
696  * memory in that case.  This is actually a problem with the SCSI
697  * layer, which is being addressed there.  Until then, don't use the
698  * SCSI functions.
699  */
700
701 #undef CONFIG_SCSI
702 #undef CONFIG_SCSI_MODULE
703 #if defined(CONFIG_SCSI) || defined(CONFIG_SCSI_MODULE)
704
705 struct edd_match_data {
706         struct edd_device       * edev;
707         struct scsi_device      * sd;
708 };
709
710 /**
711  * edd_match_scsidev()
712  * @edev - EDD device is a known SCSI device
713  * @sd - scsi_device with host who's parent is a PCI controller
714  *
715  * returns 1 if a match is found, 0 if not.
716  */
717 static int edd_match_scsidev(struct device * dev, void * d)
718 {
719         struct edd_match_data * data = (struct edd_match_data *)d;
720         struct edd_info *info = edd_dev_get_info(data->edev);
721         struct scsi_device * sd = to_scsi_device(dev);
722
723         if (info) {
724                 if ((sd->channel == info->params.interface_path.pci.channel) &&
725                     (sd->id == info->params.device_path.scsi.id) &&
726                     (sd->lun == info->params.device_path.scsi.lun)) {
727                         data->sd = sd;
728                         return 1;
729                 }
730         }
731         return 0;
732 }
733
734 /**
735  * edd_find_matching_device()
736  * @edev - edd_device to match
737  *
738  * Search the SCSI devices for a drive that matches the EDD
739  * device descriptor we have. If we find a match, return it,
740  * otherwise, return NULL.
741  */
742
743 static struct scsi_device *
744 edd_find_matching_scsi_device(struct edd_device *edev)
745 {
746         struct edd_match_data data;
747         struct bus_type * scsi_bus = find_bus("scsi");
748
749         if (!scsi_bus) {
750                 return NULL;
751         }
752
753         data.edev = edev;
754
755         if (edd_dev_is_type(edev, "SCSI")) {
756                 if (bus_for_each_dev(scsi_bus,NULL,&data,edd_match_scsidev))
757                         return data.sd;
758         }
759         return NULL;
760 }
761
762 static int
763 edd_create_symlink_to_scsidev(struct edd_device *edev)
764 {
765         struct pci_dev *pci_dev;
766         int rc = -EINVAL;
767
768         pci_dev = edd_get_pci_dev(edev);
769         if (pci_dev) {
770                 struct scsi_device * sdev = edd_find_matching_scsi_device(edev);
771                 if (sdev && get_device(&sdev->sdev_driverfs_dev)) {
772                         rc = sysfs_create_link(&edev->kobj,
773                                                &sdev->sdev_driverfs_dev.kobj,
774                                                "disc");
775                         put_device(&sdev->sdev_driverfs_dev);
776                 }
777         }
778         return rc;
779 }
780
781 #else
782 static int
783 edd_create_symlink_to_scsidev(struct edd_device *edev)
784 {
785         return -ENOSYS;
786 }
787 #endif
788
789
790 static inline void
791 edd_device_unregister(struct edd_device *edev)
792 {
793         kobject_unregister(&edev->kobj);
794 }
795
796 static void edd_populate_dir(struct edd_device * edev)
797 {
798         struct edd_attribute * attr;
799         int error = 0;
800         int i;
801
802         for (i = 0; (attr = edd_attrs[i]) && !error; i++) {
803                 if (!attr->test ||
804                     (attr->test && attr->test(edev)))
805                         error = sysfs_create_file(&edev->kobj,&attr->attr);
806         }
807
808         if (!error) {
809                 edd_create_symlink_to_pcidev(edev);
810                 edd_create_symlink_to_scsidev(edev);
811         }
812 }
813
814 static int
815 edd_device_register(struct edd_device *edev, int i)
816 {
817         int error;
818
819         if (!edev)
820                 return 1;
821         memset(edev, 0, sizeof (*edev));
822         edd_dev_set_info(edev, &edd[i]);
823         snprintf(edev->kobj.name, EDD_DEVICE_NAME_SIZE, "int13_dev%02x",
824                  edd[i].device);
825         kobj_set_kset_s(edev,edd_subsys);
826         error = kobject_register(&edev->kobj);
827         if (!error)
828                 edd_populate_dir(edev);
829         return error;
830 }
831
832 /**
833  * edd_init() - creates sysfs tree of EDD data
834  *
835  * This assumes that eddnr and edd were
836  * assigned in setup.c already.
837  */
838 static int __init
839 edd_init(void)
840 {
841         unsigned int i;
842         int rc=0;
843         struct edd_device *edev;
844
845         printk(KERN_INFO "BIOS EDD facility v%s, %d devices found\n",
846                EDD_VERSION, eddnr);
847         printk(KERN_INFO "Please report your BIOS at %s\n", REPORT_URL);
848
849         if (!eddnr) {
850                 printk(KERN_INFO "EDD information not available.\n");
851                 return 1;
852         }
853
854         rc = firmware_register(&edd_subsys);
855         if (rc)
856                 return rc;
857
858         for (i = 0; i < eddnr && i < EDDMAXNR && !rc; i++) {
859                 edev = kmalloc(sizeof (*edev), GFP_KERNEL);
860                 if (!edev)
861                         return -ENOMEM;
862
863                 rc = edd_device_register(edev, i);
864                 if (rc) {
865                         kfree(edev);
866                         break;
867                 }
868                 edd_devices[i] = edev;
869         }
870
871         if (rc)
872                 firmware_unregister(&edd_subsys);
873         return rc;
874 }
875
876 static void __exit
877 edd_exit(void)
878 {
879         int i;
880         struct edd_device *edev;
881
882         for (i = 0; i < eddnr && i < EDDMAXNR; i++) {
883                 if ((edev = edd_devices[i]))
884                         edd_device_unregister(edev);
885         }
886         firmware_unregister(&edd_subsys);
887 }
888
889 late_initcall(edd_init);
890 module_exit(edd_exit);