diff options
| -rw-r--r-- | sys/dev/firewire/sbp.c | 30 |
1 files changed, 18 insertions, 12 deletions
diff --git a/sys/dev/firewire/sbp.c b/sys/dev/firewire/sbp.c index 079ea742c1f6..f8bc93b77ff1 100644 --- a/sys/dev/firewire/sbp.c +++ b/sys/dev/firewire/sbp.c @@ -474,7 +474,7 @@ END_DEBUG reg = crom_search_key(&cc, CROM_LUN); if (reg == NULL) break; - lun = reg->val & 0xff; + lun = reg->val & 0xffff; SBP_DEBUG(0) printf("target %d lun %d found\n", target->target_id, lun); END_DEBUG @@ -482,10 +482,11 @@ END_DEBUG maxlun = lun; crom_next(&cc); } - target->num_lun = maxlun + 1; - if (maxlun < 0) { + if (maxlun < 0) printf("no lun found!\n"); - } + if (maxlun >= SBP_NUM_LUNS) + maxlun = SBP_NUM_LUNS; + target->num_lun = maxlun + 1; target->luns = (struct sbp_dev *) malloc( sizeof(struct sbp_dev) * target->num_lun, M_SBP, M_NOWAIT | M_ZERO); @@ -501,13 +502,17 @@ END_DEBUG reg = crom_search_key(&cc, CROM_LUN); if (reg == NULL) break; - lun = reg->val & 0xff; + lun = reg->val & 0xffff; + if (lun >= SBP_NUM_LUNS) { + printf("too large lun %d\n", lun); + continue; + } target->luns[lun].status = SBP_DEV_RESET; - target->luns[lun].type = (reg->val & 0x0f00) >> 16; + target->luns[lun].type = (reg->val & 0xf0000) >> 16; crom_next(&cc); - } - return target; -} + } + return target; + } static void sbp_get_text_leaf(struct fw_device *fwdev, int key, char *buf, int len) @@ -519,9 +524,10 @@ sbp_get_text_leaf(struct fw_device *fwdev, int key, char *buf, int len) u_int32_t *src, *dst; chdr = (struct csrhdr *)&fwdev->csrrom[0]; - creg = (struct csrreg *)chdr; - creg += chdr->info_len; - for( i = chdr->info_len + 4; i <= fwdev->rommax - 4; i+=4){ + /* skip crom header, bus info and root directory */ + creg = (struct csrreg *)chdr + chdr->info_len + 2; + /* search unitl the one before the last. */ + for (i = chdr->info_len + 2; i < fwdev->rommax / 4; i++) { if((creg++)->key == key){ found = 1; break; |
