summaryrefslogtreecommitdiffstats
path: root/sys/dev/mpt
diff options
context:
space:
mode:
authormjacob <mjacob@FreeBSD.org>2006-09-21 20:35:12 +0000
committermjacob <mjacob@FreeBSD.org>2006-09-21 20:35:12 +0000
commit90dd743d5c6c95ddecc22fab81136d8e2b4a9ed6 (patch)
treedfdf4e1535fe71e0dda49a2743ccf480ff850f50 /sys/dev/mpt
parentab54ab783bfc0a3afd305ba716c3dd42d6d38d80 (diff)
downloadFreeBSD-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.c34
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:
OpenPOWER on IntegriCloud