summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--sys/dev/firewire/sbp.c30
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;