diff options
author | mjacob <mjacob@FreeBSD.org> | 2006-09-21 20:35:12 +0000 |
---|---|---|
committer | mjacob <mjacob@FreeBSD.org> | 2006-09-21 20:35:12 +0000 |
commit | 90dd743d5c6c95ddecc22fab81136d8e2b4a9ed6 (patch) | |
tree | dfdf4e1535fe71e0dda49a2743ccf480ff850f50 /sys/dev/mpt | |
parent | ab54ab783bfc0a3afd305ba716c3dd42d6d38d80 (diff) | |
download | FreeBSD-src-90dd743d5c6c95ddecc22fab81136d8e2b4a9ed6.zip FreeBSD-src-90dd743d5c6c95ddecc22fab81136d8e2b4a9ed6.tar.gz |
Connect up a QUEUE FULL event with CAM and adjust openings.
Unfortunately, the QUEUE FULL event only tells you Bus && Target.
It doesn't tell you lun. In order for the XPT_REL_SIMQ action to
work, we have to have a real lun. But which one? For now, just
iterate over MPT_MAX_LUNS.
Practically speaking, this is only going to be happening for lower
quality SAS or SATA drives behind the SAS controller, which means
only lun 0, so it's not so bad.
Helpful Reminder Nagging from: John Baldwin, Fred Whiteside
MFC after: 5 days
Diffstat (limited to 'sys/dev/mpt')
-rw-r--r-- | sys/dev/mpt/mpt_cam.c | 34 |
1 files changed, 32 insertions, 2 deletions
diff --git a/sys/dev/mpt/mpt_cam.c b/sys/dev/mpt/mpt_cam.c index 4b25fda..8beaa40 100644 --- a/sys/dev/mpt/mpt_cam.c +++ b/sys/dev/mpt/mpt_cam.c @@ -2148,10 +2148,40 @@ mpt_cam_event(struct mpt_softc *mpt, request_t *req, break; case MPI_EVENT_QUEUE_FULL: { + struct cam_sim *sim; + struct cam_path *tmppath; + struct ccb_relsim crs; PTR_EVENT_DATA_QUEUE_FULL pqf = (PTR_EVENT_DATA_QUEUE_FULL) msg->Data; - mpt_prt(mpt, "QUEUE_FULL: Bus 0x%02x Target 0x%02x Depth %d\n", - pqf->Bus, pqf->TargetID, pqf->CurrentDepth); + lun_id_t lun_id; + + mpt_prt(mpt, "QUEUE FULL EVENT: Bus 0x%02x Target 0x%02x Depth " + "%d\n", pqf->Bus, pqf->TargetID, pqf->CurrentDepth); + if (mpt->phydisk_sim) { + sim = mpt->phydisk_sim; + } else { + sim = mpt->sim; + } + MPTLOCK_2_CAMLOCK(mpt); + for (lun_id = 0; lun_id < MPT_MAX_LUNS; lun_id++) { + if (xpt_create_path(&tmppath, NULL, cam_sim_path(sim), + pqf->TargetID, lun_id) != CAM_REQ_CMP) { + mpt_prt(mpt, "unable to create a path to send " + "XPT_REL_SIMQ"); + CAMLOCK_2_MPTLOCK(mpt); + break; + } + xpt_setup_ccb(&crs.ccb_h, tmppath, 5); + crs.ccb_h.func_code = XPT_REL_SIMQ; + crs.release_flags = RELSIM_ADJUST_OPENINGS; + crs.openings = pqf->CurrentDepth - 1; + xpt_action((union ccb *)&crs); + if (crs.ccb_h.status != CAM_REQ_CMP) { + mpt_prt(mpt, "XPT_REL_SIMQ failed\n"); + } + xpt_free_path(tmppath); + } + CAMLOCK_2_MPTLOCK(mpt); break; } case MPI_EVENT_SAS_DEVICE_STATUS_CHANGE: |