summaryrefslogtreecommitdiff
path: root/usr/src
diff options
context:
space:
mode:
authorshidokht <none@none>2007-10-18 15:56:00 -0700
committershidokht <none@none>2007-10-18 15:56:00 -0700
commit801d74ddb3d063919e6cf7c6eb3ddc2591c3921d (patch)
tree55e56d92f8b7e92a240e7546c64c23472ac2d7dd /usr/src
parent4e93b15cab4093031c84b6a2a2bb78eb5e7ce7f9 (diff)
downloadillumos-joyent-801d74ddb3d063919e6cf7c6eb3ddc2591c3921d.tar.gz
6513832 biosdev should try first block match if BIOS EDD info is buggy
6614902 biosdev debug output can print beyond end of interface_type since formatted as string
Diffstat (limited to 'usr/src')
-rw-r--r--usr/src/cmd/biosdev/biosdev.c114
1 files changed, 91 insertions, 23 deletions
diff --git a/usr/src/cmd/biosdev/biosdev.c b/usr/src/cmd/biosdev/biosdev.c
index 20d2e8c036..7a16fa31b4 100644
--- a/usr/src/cmd/biosdev/biosdev.c
+++ b/usr/src/cmd/biosdev/biosdev.c
@@ -19,7 +19,7 @@
* CDDL HEADER END
*/
/*
- * Copyright 2006 Sun Microsystems, Inc. All rights reserved.
+ * Copyright 2007 Sun Microsystems, Inc. All rights reserved.
* Use is subject to license terms.
*/
@@ -395,10 +395,15 @@ match_edd(biosdev_data_t *bdata)
return (-1);
}
- if (debug)
- (void) printf("interface type %s pci channel %x target %x\n",
- bd->interface_type, bd->interfacepath.pci.channel,
+ if (debug) {
+ int i;
+ (void) printf("interface type ");
+ for (i = 0; i < 8; i++)
+ (void) printf("%c", bd->interface_type[i]);
+ (void) printf(" pci channel %x target %x\n",
+ bd->interfacepath.pci.channel,
bd->devicepath.scsi.target);
+ }
if (strncmp(bd->interface_type, "SCSI", 4) == 0) {
@@ -549,10 +554,11 @@ int
main(int argc, char *argv[])
{
biosdev_data_t *biosdata;
- int len, i, c, j;
+ int i, c, j;
int matchedindex = -1;
char biospropname[BIOSPROPNAME_TMPL_LEN];
int totalmatches = 0;
+ biosdev_data_t *biosdataarray[BIOSDEV_NUM];
while ((c = getopt(argc, argv, "d")) != -1) {
@@ -586,37 +592,96 @@ main(int argc, char *argv[])
/* get a list of all disks in the system */
build_disk_list();
- /* for each property try to match with a disk */
+ /* Get property values that were created at boot up time */
for (i = 0; i < BIOSDEV_NUM; i++) {
(void) snprintf((char *)biospropname, BIOSPROPNAME_TMPL_LEN,
BIOSPROPNAME_TMPL, i + STARTING_DRVNUM);
+ if (di_prop_lookup_bytes(DDI_DEV_T_ANY, root_allnode,
+ biospropname, (uchar_t **)&biosdataarray[i]) <= 0)
+ biosdataarray[i] = NULL;
+ }
- len = di_prop_lookup_bytes(DDI_DEV_T_ANY, root_allnode,
- biospropname, (uchar_t **)&biosdata);
+ /* Try to match based on device/interface path info from BIOS */
+ for (i = 0; i < BIOSDEV_NUM; i++) {
- if (len <= 0) {
+ if ((biosdata = biosdataarray[i]) == NULL)
continue;
- }
-
if (debug)
- (void) printf("matching %s\n", biospropname);
+ (void) printf("matching edd 0x%x\n",
+ i + STARTING_DRVNUM);
matchedindex = match_edd(biosdata);
- if (matchedindex == -1) {
- matchedindex = match_first_block(biosdata);
- if (debug && matchedindex != -1)
- (void) printf("matched first block\n");
- } else if (debug)
- (void) printf("matched thru edd\n");
-
if (matchedindex != -1) {
+ if (debug) {
+ (void) printf("matched by edd\n");
+ (void) printf("0x%x %s\n", i + STARTING_DRVNUM,
+ disk_list[matchedindex]);
+ }
+
mapinfo[i].disklist_index = matchedindex;
mapinfo[i].matchcount++;
+
+ for (j = 0; j < i; j++) {
+ if (mapinfo[j].matchcount > 0 &&
+ mapinfo[j].disklist_index == matchedindex) {
+ mapinfo[j].matchcount++;
+ mapinfo[i].matchcount++;
+ }
+ }
+
+ } else
+ if (debug)
+ (void) printf("No matches by edd\n");
+ }
+
+ /*
+ * Go through the list and ignore any found matches that are dups.
+ * This is to workaround issues with BIOSes that do not implement
+ * providing interface/device path info correctly.
+ */
+
+ for (i = 0; i < BIOSDEV_NUM; i++) {
+ if (mapinfo[i].matchcount > 1) {
if (debug)
+ (void) printf("Ignoring dup match_edd\n(count "
+ "%d): 0x%x %s\n", mapinfo[i].matchcount,
+ i + STARTING_DRVNUM,
+ disk_list[mapinfo[i].disklist_index]);
+
+ mapinfo[i].matchcount = 0;
+ mapinfo[i].disklist_index = 0;
+ }
+ }
+
+
+ /*
+ * For each bios dev number that we do not have exactly one match
+ * already, try to match based on first block
+ */
+ for (i = 0; i < BIOSDEV_NUM; i++) {
+ if (mapinfo[i].matchcount == 1)
+ continue;
+
+ if ((biosdata = biosdataarray[i]) == NULL)
+ continue;
+
+ if (debug)
+ (void) printf("matching first block 0x%x\n",
+ i + STARTING_DRVNUM);
+
+ matchedindex = match_first_block(biosdata);
+ if (matchedindex != -1) {
+ if (debug) {
+ (void) printf("matched by first block\n");
(void) printf("0x%x %s\n", i + STARTING_DRVNUM,
disk_list[matchedindex]);
+ }
+
+ mapinfo[i].disklist_index = matchedindex;
+ mapinfo[i].matchcount++;
+
for (j = 0; j < i; j++) {
if (mapinfo[j].matchcount > 0 &&
mapinfo[j].disklist_index == matchedindex) {
@@ -624,12 +689,15 @@ main(int argc, char *argv[])
mapinfo[i].matchcount++;
}
}
-
- } else if (debug)
- (void) fprintf(stderr, "Could not match %s\n",
- biospropname);
+ } else
+ if (debug) {
+ (void) printf(" No matches by first block\n");
+ (void) fprintf(stderr, "Could not match 0x%x\n",
+ i + STARTING_DRVNUM);
+ }
}
+
for (i = 0; i < BIOSDEV_NUM; i++) {
if (mapinfo[i].matchcount == 1) {
(void) printf("0x%x %s\n", i + STARTING_DRVNUM,