aboutsummaryrefslogtreecommitdiff
path: root/sys/cam/ctl
diff options
context:
space:
mode:
authorKenneth D. Merry <ken@FreeBSD.org>2012-06-26 14:51:35 +0000
committerKenneth D. Merry <ken@FreeBSD.org>2012-06-26 14:51:35 +0000
commitb79dc8a8da264fafa98697a39a967e56ed8647d1 (patch)
tree7b016bc8afd686b682aaffe21bfcace67afaf0e7 /sys/cam/ctl
parent8405fe86627bd23303e30797ec2e5ec37f493491 (diff)
downloadsrc-b79dc8a8da264fafa98697a39a967e56ed8647d1.tar.gz
src-b79dc8a8da264fafa98697a39a967e56ed8647d1.zip
Fix an issue that caused the kernel to panic inside CTL when trying
to attach to target capable HBAs that implement the old immediate notify (XPT_IMMED_NOTIFY) and notify acknowledge (XPT_NOTIFY_ACK) CCBs. The new API has been in place since SVN change 196008 in 2009. The solution is two-fold: fix CTL to handle the responses from the HBAs, and convert the HBA drivers in question to use the new API. These drivers have not been tested with CTL, so how well they will interoperate with CTL is unknown. scsi_target.c: Update the userland target example code to use the new immediate notify API. scsi_ctl.c: Detect when an immediate notify CCB is returned with CAM_REQ_INVALID or CAM_PROVIDE_FAIL status, and just free it. Fix a duplicate assignment. aic79xx.c, aic79xx_osm.c: Update the aic79xx driver to use the new API. Target mode is not enabled on for this driver, so the changes will have no practical effect. aic7xxx.c, aic7xxx_osm.c: Update the aic7xxx driver to use the new API. sbp_targ.c: Update the firewire target code to work with the new API. mpt_cam.c: Update the mpt(4) driver to work with the new API. Target mode is only enabled for Fibre Channel mpt(4) devices. MFC after: 3 days
Notes
Notes: svn path=/head/; revision=237601
Diffstat (limited to 'sys/cam/ctl')
-rw-r--r--sys/cam/ctl/scsi_ctl.c44
1 files changed, 35 insertions, 9 deletions
diff --git a/sys/cam/ctl/scsi_ctl.c b/sys/cam/ctl/scsi_ctl.c
index 0563f72521b7..044b9a9a1c1b 100644
--- a/sys/cam/ctl/scsi_ctl.c
+++ b/sys/cam/ctl/scsi_ctl.c
@@ -558,7 +558,6 @@ ctlferegister(struct cam_periph *periph, void *arg)
TAILQ_INIT(&softc->work_queue);
softc->periph = periph;
- softc->parent_softc = bus_softc;
callout_init_mtx(&softc->dma_callout, sim->mtx, /*flags*/ 0);
periph->softc = softc;
@@ -628,12 +627,22 @@ ctlferegister(struct cam_periph *periph, void *arg)
xpt_action(new_ccb);
softc->inots_sent++;
status = new_ccb->ccb_h.status;
- if (status != CAM_REQ_INPROG) {
- free(new_ccb, M_CTLFE);
+ if ((status & CAM_STATUS_MASK) != CAM_REQ_INPROG) {
+ /*
+ * Note that we don't free the CCB here. If the
+ * status is not CAM_REQ_INPROG, then we're
+ * probably talking to a SIM that says it is
+ * target-capable but doesn't support the
+ * XPT_IMMEDIATE_NOTIFY CCB. i.e. it supports the
+ * older API. In that case, it'll call xpt_done()
+ * on the CCB, and we need to free it in our done
+ * routine as a result.
+ */
break;
}
}
- if (i == 0) {
+ if ((i == 0)
+ || (status != CAM_REQ_INPROG)) {
xpt_print(periph->path, "%s: could not allocate immediate "
"notify CCBs, status 0x%x\n", __func__, status);
return (CAM_REQ_CMP_ERR);
@@ -1460,12 +1469,29 @@ ctlfedone(struct cam_periph *periph, union ccb *done_ccb)
*/
send_ctl_io = 0;
break;
+ case CAM_REQ_INVALID:
+ case CAM_PROVIDE_FAIL:
default:
- xpt_print(periph->path, "%s: "
- "unsupported CAM status 0x%x\n",
- __func__, status);
- send_ctl_io = 0;
- break;
+ /*
+ * We should only get here if we're talking
+ * to a talking to a SIM that is target
+ * capable but supports the old API. In
+ * that case, we need to just free the CCB.
+ * If we actually send a notify acknowledge,
+ * it will send that back with an error as
+ * well.
+ */
+
+ if ((status != CAM_REQ_INVALID)
+ && (status != CAM_PROVIDE_FAIL))
+ xpt_print(periph->path, "%s: "
+ "unsupported CAM status "
+ "0x%x\n", __func__, status);
+
+ ctl_free_io(io);
+ ctlfe_free_ccb(periph, done_ccb);
+
+ return;
}
if (send_ctl_io != 0) {
ctl_queue(io);