summaryrefslogtreecommitdiffstats
path: root/sys/dev/firewire/sbp.c
diff options
context:
space:
mode:
Diffstat (limited to 'sys/dev/firewire/sbp.c')
-rw-r--r--sys/dev/firewire/sbp.c52
1 files changed, 37 insertions, 15 deletions
diff --git a/sys/dev/firewire/sbp.c b/sys/dev/firewire/sbp.c
index 6ddb863..2317e99 100644
--- a/sys/dev/firewire/sbp.c
+++ b/sys/dev/firewire/sbp.c
@@ -253,8 +253,9 @@ struct sbp_dev{
#define SBP_DEV_ATTACHED 5 /* in operation */
#define SBP_DEV_DEAD 6 /* unavailable unit */
#define SBP_DEV_RETRY 7 /* unavailable unit */
- int status;
- int lun_id;
+ u_int8_t status;
+ u_int8_t type;
+ u_int16_t lun_id;
struct cam_path *path;
struct sbp_target *target;
struct sbp_login_res login;
@@ -388,7 +389,6 @@ END_DEBUG
static void
sbp_show_sdev_info(struct sbp_dev *sdev, int new)
{
- int lun;
struct fw_device *fwdev;
printf("%s:%d:%d ",
@@ -400,11 +400,10 @@ sbp_show_sdev_info(struct sbp_dev *sdev, int new)
return;
}
fwdev = sdev->target->fwdev;
- lun = getcsrdata(fwdev, 0x14);
printf("ordered:%d type:%d EUI:%08x%08x node:%d "
"speed:%d maxrec:%d",
- (lun & 0x00400000) >> 22,
- (lun & 0x001f0000) >> 16,
+ (sdev->type & 0x40) >> 6,
+ (sdev->type & 0x1f),
fwdev->eui.hi,
fwdev->eui.lo,
fwdev->dst,
@@ -422,9 +421,11 @@ sbp_show_sdev_info(struct sbp_dev *sdev, int new)
static struct sbp_target *
sbp_alloc_target(struct sbp_softc *sbp, struct fw_device *fwdev)
{
- int i, lun;
+ int i, maxlun, lun;
struct sbp_target *target;
struct sbp_dev *sdev;
+ struct crom_context cc;
+ struct csrreg *reg;
SBP_DEBUG(1)
printf("sbp_alloc_target\n");
@@ -448,10 +449,24 @@ END_DEBUG
}
target->mgm_hi = 0xffff;
target->mgm_lo = 0xf0000000 | target->mgm_lo << 2;
- /* XXX should probe all luns */
/* XXX num_lun may be changed. realloc luns? */
- lun = getcsrdata(target->fwdev, 0x14) & 0xff;
- target->num_lun = lun + 1;
+ crom_init_context(&cc, target->fwdev->csrrom);
+ /* XXX shoud parse appropriate unit directories only */
+ maxlun = -1;
+ while (cc.depth >= 0) {
+ reg = crom_search_key(&cc, CROM_LUN);
+ if (reg == NULL)
+ break;
+ lun = reg->val & 0xff;
+ printf("lun %d found\n", lun);
+ if (maxlun < lun)
+ maxlun = lun;
+ crom_next(&cc);
+ }
+ target->num_lun = maxlun + 1;
+ if (maxlun < 0) {
+ printf("no lun found!\n");
+ }
target->luns = (struct sbp_dev *) malloc(
sizeof(struct sbp_dev) * target->num_lun,
M_SBP, M_NOWAIT | M_ZERO);
@@ -460,10 +475,17 @@ END_DEBUG
sdev->lun_id = i;
sdev->target = target;
STAILQ_INIT(&sdev->ocbs);
- if (i == lun)
- sdev->status = SBP_DEV_RESET;
- else
- sdev->status = SBP_DEV_DEAD;
+ sdev->status = SBP_DEV_DEAD;
+ }
+ crom_init_context(&cc, target->fwdev->csrrom);
+ while (cc.depth >= 0) {
+ reg = crom_search_key(&cc, CROM_LUN);
+ if (reg == NULL)
+ break;
+ lun = reg->val & 0xff;
+ target->luns[lun].status = SBP_DEV_RESET;
+ target->luns[lun].type = (reg->val & 0x0f00) >> 16;
+ crom_next(&cc);
}
return target;
}
@@ -1097,7 +1119,7 @@ END_DEBUG
fp->mode.wreqb.dest_lo = htonl(sdev->target->mgm_lo);
fp->mode.wreqb.len = htons(8);
fp->mode.wreqb.extcode = 0;
- fp->mode.wreqb.payload[0] = htonl(((sdev->target->sbp->fd.fc->nodeid | FWLOCALBUS )<< 16));
+ fp->mode.wreqb.payload[0] = htonl(nid << 16);
fp->mode.wreqb.payload[1] = htonl(vtophys(&ocb->orb[0]));
sbp_enqueue_ocb(sdev, ocb);
OpenPOWER on IntegriCloud