summaryrefslogtreecommitdiffstats
path: root/sys/dev/isp
diff options
context:
space:
mode:
authormav <mav@FreeBSD.org>2011-12-13 09:58:05 +0000
committermav <mav@FreeBSD.org>2011-12-13 09:58:05 +0000
commitb2bc09ab331217387974604e2bdbfe2e8c1a78c3 (patch)
tree7e6d00f5664ff5d55856051a66b4508ed5d91484 /sys/dev/isp
parentbe30d3045736836c9dc1bbc09ffb3e17094c4b73 (diff)
downloadFreeBSD-src-b2bc09ab331217387974604e2bdbfe2e8c1a78c3.zip
FreeBSD-src-b2bc09ab331217387974604e2bdbfe2e8c1a78c3.tar.gz
Fix few bugs in isp(4) target mode support:
- in destroy_lun_state() assert hold == 1 instead of 0, as it should receive hold taken by the create_lun_state() or get_lun_statep() before; - fix hold count leak inside rls_lun_statep() that also fired above assert; - in destroy_lun_state() use SIM bus number instead of SIM path id for ISP_GET_PC_ADDR(), as it was before r196008; - make isp_disable_lun() to set status in CCB; - make isp_target_mark_aborted() set status into the proper CCB. Reviewed by: mjacob Sponsored by: iXsystems, inc. MFC after: 1 month
Diffstat (limited to 'sys/dev/isp')
-rw-r--r--sys/dev/isp/isp_freebsd.c26
1 files changed, 15 insertions, 11 deletions
diff --git a/sys/dev/isp/isp_freebsd.c b/sys/dev/isp/isp_freebsd.c
index 3d676ab..9d93857 100644
--- a/sys/dev/isp/isp_freebsd.c
+++ b/sys/dev/isp/isp_freebsd.c
@@ -1087,8 +1087,9 @@ static ISP_INLINE void
destroy_lun_state(ispsoftc_t *isp, tstate_t *tptr)
{
struct tslist *lhp;
- KASSERT((tptr->hold == 0), ("tptr still held"));
- ISP_GET_PC_ADDR(isp, xpt_path_path_id(tptr->owner), lun_hash[LUN_HASH_FUNC(xpt_path_lun_id(tptr->owner))], lhp);
+ KASSERT((tptr->hold != 0), ("tptr is not held"));
+ KASSERT((tptr->hold == 1), ("tptr still held (%d)", tptr->hold));
+ ISP_GET_PC_ADDR(isp, cam_sim_bus(xpt_path_sim(tptr->owner)), lun_hash[LUN_HASH_FUNC(xpt_path_lun_id(tptr->owner))], lhp);
SLIST_REMOVE(lhp, tptr, tstate, next);
xpt_free_path(tptr->owner);
free(tptr, M_DEVBUF);
@@ -1316,12 +1317,13 @@ isp_disable_lun(ispsoftc_t *isp, union ccb *ccb)
mtx_sleep(isp, &isp->isp_lock, PRIBIO, "want_isp_disable_lun", 0);
}
isp->isp_osinfo.tmbusy = 1;
+ status = CAM_REQ_INPROG;
/*
* Find the state pointer.
*/
if ((tptr = get_lun_statep(isp, bus, lun)) == NULL) {
- ccb->ccb_h.status = CAM_PATH_INVALID;
+ status = CAM_PATH_INVALID;
goto done;
}
@@ -1341,13 +1343,13 @@ isp_disable_lun(ispsoftc_t *isp, union ccb *ccb)
}
isp->isp_osinfo.rptr = &status;
- status = CAM_REQ_INPROG;
if (isp_lun_cmd(isp, RQSTYPE_ENABLE_LUN, bus, lun, 0, 0)) {
status = CAM_RESRC_UNAVAIL;
} else {
mtx_sleep(ccb, &isp->isp_lock, PRIBIO, "isp_disable_lun", 0);
}
done:
+ ccb->ccb_h.status = status;
if (status == CAM_REQ_CMP) {
xpt_print(ccb->ccb_h.path, "now disabled for target mode\n");
}
@@ -2949,23 +2951,25 @@ isp_target_mark_aborted(ispsoftc_t *isp, union ccb *ccb)
{
tstate_t *tptr;
atio_private_data_t *atp;
+ union ccb *accb = ccb->cab.abort_ccb;
- tptr = get_lun_statep(isp, XS_CHANNEL(ccb), XS_LUN(ccb));
+ tptr = get_lun_statep(isp, XS_CHANNEL(accb), XS_LUN(accb));
if (tptr == NULL) {
- tptr = get_lun_statep(isp, XS_CHANNEL(ccb), CAM_LUN_WILDCARD);
+ tptr = get_lun_statep(isp, XS_CHANNEL(accb), CAM_LUN_WILDCARD);
if (tptr == NULL) {
ccb->ccb_h.status = CAM_REQ_INVALID;
return;
}
}
- atp = isp_get_atpd(isp, tptr, ccb->atio.tag_id);
+ atp = isp_get_atpd(isp, tptr, accb->atio.tag_id);
if (atp == NULL) {
ccb->ccb_h.status = CAM_REQ_INVALID;
- return;
+ } else {
+ atp->dead = 1;
+ ccb->ccb_h.status = CAM_REQ_CMP;
}
- atp->dead = 1;
- ccb->ccb_h.status = CAM_REQ_CMP;
+ rls_lun_statep(isp, tptr);
}
static void
@@ -4519,7 +4523,7 @@ isp_action(struct cam_sim *sim, union ccb *ccb)
switch (accb->ccb_h.func_code) {
#ifdef ISP_TARGET_MODE
case XPT_ACCEPT_TARGET_IO:
- isp_target_mark_aborted(isp, accb);
+ isp_target_mark_aborted(isp, ccb);
break;
#endif
case XPT_SCSI_IO:
OpenPOWER on IntegriCloud