summaryrefslogtreecommitdiffstats
path: root/sys/dev/mpr/mpr_sas.c
diff options
context:
space:
mode:
Diffstat (limited to 'sys/dev/mpr/mpr_sas.c')
-rw-r--r--sys/dev/mpr/mpr_sas.c136
1 files changed, 68 insertions, 68 deletions
diff --git a/sys/dev/mpr/mpr_sas.c b/sys/dev/mpr/mpr_sas.c
index eac3360..64c0d07 100644
--- a/sys/dev/mpr/mpr_sas.c
+++ b/sys/dev/mpr/mpr_sas.c
@@ -1,7 +1,7 @@
/*-
* Copyright (c) 2009 Yahoo! Inc.
* Copyright (c) 2011-2015 LSI Corp.
- * Copyright (c) 2013-2015 Avago Technologies
+ * Copyright (c) 2013-2016 Avago Technologies
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
@@ -119,13 +119,11 @@ static void mprsas_remove_complete(struct mpr_softc *, struct mpr_command *);
static void mprsas_action(struct cam_sim *sim, union ccb *ccb);
static void mprsas_poll(struct cam_sim *sim);
static void mprsas_scsiio_timeout(void *data);
-static void mprsas_abort_complete(struct mpr_softc *sc,
- struct mpr_command *cm);
+static void mprsas_abort_complete(struct mpr_softc *sc, struct mpr_command *cm);
static void mprsas_action_scsiio(struct mprsas_softc *, union ccb *);
static void mprsas_scsiio_complete(struct mpr_softc *, struct mpr_command *);
static void mprsas_action_resetdev(struct mprsas_softc *, union ccb *);
-static void mprsas_resetdev_complete(struct mpr_softc *,
- struct mpr_command *);
+static void mprsas_resetdev_complete(struct mpr_softc *, struct mpr_command *);
static int mprsas_send_abort(struct mpr_softc *sc, struct mpr_command *tm,
struct mpr_command *cm);
static void mprsas_async(void *callback_arg, uint32_t code,
@@ -142,10 +140,9 @@ static void mprsas_portenable_complete(struct mpr_softc *sc,
struct mpr_command *cm);
#if __FreeBSD_version >= 900026
-static void mprsas_smpio_complete(struct mpr_softc *sc,
- struct mpr_command *cm);
-static void mprsas_send_smpcmd(struct mprsas_softc *sassc,
- union ccb *ccb, uint64_t sasaddr);
+static void mprsas_smpio_complete(struct mpr_softc *sc, struct mpr_command *cm);
+static void mprsas_send_smpcmd(struct mprsas_softc *sassc, union ccb *ccb,
+ uint64_t sasaddr);
static void mprsas_action_smpio(struct mprsas_softc *sassc, union ccb *ccb);
#endif //FreeBSD_version >= 900026
@@ -246,6 +243,8 @@ mprsas_alloc_tm(struct mpr_softc *sc)
void
mprsas_free_tm(struct mpr_softc *sc, struct mpr_command *tm)
{
+ int target_id = 0xFFFFFFFF;
+
MPR_FUNCTRACE(sc);
if (tm == NULL)
return;
@@ -257,10 +256,11 @@ mprsas_free_tm(struct mpr_softc *sc, struct mpr_command *tm)
*/
if (tm->cm_targ != NULL) {
tm->cm_targ->flags &= ~MPRSAS_TARGET_INRESET;
+ target_id = tm->cm_targ->tid;
}
if (tm->cm_ccb) {
mpr_dprint(sc, MPR_INFO, "Unfreezing devq for target ID %d\n",
- tm->cm_targ->tid);
+ target_id);
xpt_release_devq(tm->cm_ccb->ccb_h.path, 1, TRUE);
xpt_free_path(tm->cm_ccb->ccb_h.path);
xpt_free_ccb(tm->cm_ccb);
@@ -375,15 +375,14 @@ mprsas_remove_volume(struct mpr_softc *sc, struct mpr_command *tm)
return;
}
- if (reply->IOCStatus != MPI2_IOCSTATUS_SUCCESS) {
- mpr_dprint(sc, MPR_FAULT, "IOCStatus = 0x%x while resetting "
- "device 0x%x\n", reply->IOCStatus, handle);
- mprsas_free_tm(sc, tm);
- return;
+ if ((le16toh(reply->IOCStatus) & MPI2_IOCSTATUS_MASK) !=
+ MPI2_IOCSTATUS_SUCCESS) {
+ mpr_dprint(sc, MPR_ERROR, "IOCStatus = 0x%x while resetting "
+ "device 0x%x\n", le16toh(reply->IOCStatus), handle);
}
mpr_dprint(sc, MPR_XINFO, "Reset aborted %u commands\n",
- reply->TerminationCount);
+ le32toh(reply->TerminationCount));
mpr_free_reply(sc, tm->cm_reply_data);
tm->cm_reply = NULL; /* Ensures the reply won't get re-freed */
@@ -396,7 +395,8 @@ mprsas_remove_volume(struct mpr_softc *sc, struct mpr_command *tm)
* this target id if possible, and so we can assign the same target id
* to this device if it comes back in the future.
*/
- if (reply->IOCStatus == MPI2_IOCSTATUS_SUCCESS) {
+ if ((le16toh(reply->IOCStatus) & MPI2_IOCSTATUS_MASK) ==
+ MPI2_IOCSTATUS_SUCCESS) {
targ = tm->cm_targ;
targ->handle = 0x0;
targ->encl_handle = 0x0;
@@ -564,8 +564,6 @@ mprsas_remove_device(struct mpr_softc *sc, struct mpr_command *tm)
mpr_dprint(sc, MPR_ERROR, "%s: cm_flags = %#x for remove of "
"handle %#04x! This should not happen!\n", __func__,
tm->cm_flags, handle);
- mprsas_free_tm(sc, tm);
- return;
}
if (reply == NULL) {
@@ -576,11 +574,10 @@ mprsas_remove_device(struct mpr_softc *sc, struct mpr_command *tm)
return;
}
- if (le16toh(reply->IOCStatus) != MPI2_IOCSTATUS_SUCCESS) {
- mpr_dprint(sc, MPR_FAULT, "IOCStatus = 0x%x while resetting "
+ if ((le16toh(reply->IOCStatus) & MPI2_IOCSTATUS_MASK) !=
+ MPI2_IOCSTATUS_SUCCESS) {
+ mpr_dprint(sc, MPR_ERROR, "IOCStatus = 0x%x while resetting "
"device 0x%x\n", le16toh(reply->IOCStatus), handle);
- mprsas_free_tm(sc, tm);
- return;
}
mpr_dprint(sc, MPR_XINFO, "Reset aborted %u commands\n",
@@ -661,7 +658,8 @@ mprsas_remove_complete(struct mpr_softc *sc, struct mpr_command *tm)
* this target id if possible, and so we can assign the same target id
* to this device if it comes back in the future.
*/
- if (le16toh(reply->IOCStatus) == MPI2_IOCSTATUS_SUCCESS) {
+ if ((le16toh(reply->IOCStatus) & MPI2_IOCSTATUS_MASK) ==
+ MPI2_IOCSTATUS_SUCCESS) {
targ = tm->cm_targ;
targ->handle = 0x0;
targ->encl_handle = 0x0;
@@ -707,6 +705,7 @@ mprsas_register_events(struct mpr_softc *sc)
setbit(events, MPI2_EVENT_IR_PHYSICAL_DISK);
setbit(events, MPI2_EVENT_IR_OPERATION_STATUS);
setbit(events, MPI2_EVENT_TEMP_THRESHOLD);
+ setbit(events, MPI2_EVENT_ACTIVE_CABLE_EXCEPTION);
mpr_register_events(sc, events, mprsas_evt_handler, NULL,
&sc->sassc->mprsas_eh);
@@ -926,7 +925,6 @@ mpr_detach_sas(struct mpr_softc *sc)
cam_sim_free(sassc->sim, FALSE);
}
- sassc->flags |= MPRSAS_SHUTDOWN;
mpr_unlock(sc);
if (sassc->devq != NULL)
@@ -1065,15 +1063,15 @@ mprsas_action(struct cam_sim *sim, union ccb *ccb)
mprsas_set_ccbstatus(ccb, CAM_REQ_CMP);
break;
case XPT_RESET_DEV:
- mpr_dprint(sassc->sc, MPR_XINFO,
- "mprsas_action XPT_RESET_DEV\n");
+ mpr_dprint(sassc->sc, MPR_XINFO, "mprsas_action "
+ "XPT_RESET_DEV\n");
mprsas_action_resetdev(sassc, ccb);
return;
case XPT_RESET_BUS:
case XPT_ABORT:
case XPT_TERM_IO:
- mpr_dprint(sassc->sc, MPR_XINFO,
- "mprsas_action faking success for abort or reset\n");
+ mpr_dprint(sassc->sc, MPR_XINFO, "mprsas_action faking success "
+ "for abort or reset\n");
mprsas_set_ccbstatus(ccb, CAM_REQ_CMP);
break;
case XPT_SCSI_IO:
@@ -1134,8 +1132,8 @@ mprsas_complete_all_commands(struct mpr_softc *sc)
if (cm->cm_complete != NULL) {
mprsas_log_command(cm, MPR_RECOVERY,
- "completing cm %p state %x ccb %p for diag "
- "reset\n", cm, cm->cm_state, cm->cm_ccb);
+ "completing cm %p state %x ccb %p for diag reset\n",
+ cm, cm->cm_state, cm->cm_ccb);
cm->cm_complete(sc, cm);
completed = 1;
}
@@ -1216,14 +1214,13 @@ mprsas_tm_timeout(void *data)
mtx_assert(&sc->mpr_mtx, MA_OWNED);
- mprsas_log_command(tm, MPR_INFO|MPR_RECOVERY,
- "task mgmt %p timed out\n", tm);
+ mprsas_log_command(tm, MPR_INFO|MPR_RECOVERY, "task mgmt %p timed "
+ "out\n", tm);
mpr_reinit(sc);
}
static void
-mprsas_logical_unit_reset_complete(struct mpr_softc *sc,
- struct mpr_command *tm)
+mprsas_logical_unit_reset_complete(struct mpr_softc *sc, struct mpr_command *tm)
{
MPI2_SCSI_TASK_MANAGE_REPLY *reply;
MPI2_SCSI_TASK_MANAGE_REQUEST *req;
@@ -1250,8 +1247,8 @@ mprsas_logical_unit_reset_complete(struct mpr_softc *sc,
}
if (reply == NULL) {
- mprsas_log_command(tm, MPR_RECOVERY,
- "NULL reset reply for tm %p\n", tm);
+ mprsas_log_command(tm, MPR_RECOVERY, "NULL reset reply for tm "
+ "%p\n", tm);
if ((sc->mpr_flags & MPR_FLAGS_DIAGRESET) != 0) {
/* this completion was due to a reset, just cleanup */
targ->tm = NULL;
@@ -1338,8 +1335,8 @@ mprsas_target_reset_complete(struct mpr_softc *sc, struct mpr_command *tm)
}
if (reply == NULL) {
- mprsas_log_command(tm, MPR_RECOVERY,
- "NULL reset reply for tm %p\n", tm);
+ mprsas_log_command(tm, MPR_RECOVERY, "NULL reset reply for tm "
+ "%p\n", tm);
if ((sc->mpr_flags & MPR_FLAGS_DIAGRESET) != 0) {
/* this completion was due to a reset, just cleanup */
targ->tm = NULL;
@@ -1626,9 +1623,8 @@ mprsas_scsiio_timeout(void *data)
targ = cm->cm_targ;
targ->timeouts++;
- mprsas_log_command(cm, MPR_ERROR, "command timeout cm %p ccb %p "
- "target %u, handle(0x%04x)\n", cm, cm->cm_ccb, targ->tid,
- targ->handle);
+ mprsas_log_command(cm, MPR_ERROR, "command timeout cm %p ccb %p target "
+ "%u, handle(0x%04x)\n", cm, cm->cm_ccb, targ->tid, targ->handle);
if (targ->encl_level_valid) {
mpr_dprint(sc, MPR_ERROR, "At enclosure level %d, slot %d, "
"connector name (%4s)\n", targ->encl_level, targ->encl_slot,
@@ -1666,8 +1662,8 @@ mprsas_scsiio_timeout(void *data)
* more credits than disks in an enclosure, and limit
* ourselves to one TM per target for recovery.
*/
- mpr_dprint(sc, MPR_RECOVERY,
- "timedout cm %p failed to allocate a tm\n", cm);
+ mpr_dprint(sc, MPR_RECOVERY, "timedout cm %p failed to "
+ "allocate a tm\n", cm);
}
}
@@ -1927,8 +1923,13 @@ mprsas_action_scsiio(struct mprsas_softc *sassc, union ccb *ccb)
cm->cm_desc.SCSIIO.DevHandle = htole16(targ->handle);
}
+#if __FreeBSD_version >= 1000029
callout_reset_sbt(&cm->cm_callout, SBT_1MS * ccb->ccb_h.timeout, 0,
mprsas_scsiio_timeout, cm, 0);
+#else //__FreeBSD_version < 1000029
+ callout_reset(&cm->cm_callout, (ccb->ccb_h.timeout * hz) / 1000,
+ mprsas_scsiio_timeout, cm);
+#endif //__FreeBSD_version >= 1000029
targ->issued++;
targ->outstanding++;
@@ -2053,6 +2054,9 @@ mpr_sc_failed_io_info(struct mpr_softc *sc, struct ccb_scsiio *csio,
case MPI2_IOCSTATUS_EEDP_APP_TAG_ERROR:
desc_ioc_state = "eedp app tag error";
break;
+ case MPI2_IOCSTATUS_INSUFFICIENT_POWER:
+ desc_ioc_state = "insufficient power";
+ break;
default:
desc_ioc_state = "unknown";
break;
@@ -2578,8 +2582,7 @@ bailout:
}
static void
-mprsas_send_smpcmd(struct mprsas_softc *sassc, union ccb *ccb,
- uint64_t sasaddr)
+mprsas_send_smpcmd(struct mprsas_softc *sassc, union ccb *ccb, uint64_t sasaddr)
{
struct mpr_command *cm;
uint8_t *request, *response;
@@ -2612,9 +2615,9 @@ mprsas_send_smpcmd(struct mprsas_softc *sassc, union ccb *ccb,
*/
if ((ccb->smpio.smp_request_sglist_cnt > 1)
|| (ccb->smpio.smp_response_sglist_cnt > 1)) {
- mpr_dprint(sc, MPR_ERROR,
- "%s: multiple request or response buffer segments "
- "not supported for SMP\n", __func__);
+ mpr_dprint(sc, MPR_ERROR, "%s: multiple request or "
+ "response buffer segments not supported for SMP\n",
+ __func__);
mprsas_set_ccbstatus(ccb, CAM_REQ_INVALID);
xpt_done(ccb);
return;
@@ -2715,8 +2718,8 @@ mprsas_send_smpcmd(struct mprsas_softc *sassc, union ccb *ccb,
cm = mpr_alloc_command(sc);
if (cm == NULL) {
- mpr_dprint(sc, MPR_ERROR,
- "%s: cannot allocate command\n", __func__);
+ mpr_dprint(sc, MPR_ERROR, "%s: cannot allocate command\n",
+ __func__);
mprsas_set_ccbstatus(ccb, CAM_RESRC_UNAVAIL);
xpt_done(ccb);
return;
@@ -2949,14 +2952,13 @@ mprsas_action_resetdev(struct mprsas_softc *sassc, union ccb *ccb)
MPR_FUNCTRACE(sassc->sc);
mtx_assert(&sassc->sc->mpr_mtx, MA_OWNED);
- KASSERT(ccb->ccb_h.target_id < sassc->maxtargets,
- ("Target %d out of bounds in XPT_RESET_DEV\n",
- ccb->ccb_h.target_id));
+ KASSERT(ccb->ccb_h.target_id < sassc->maxtargets, ("Target %d out of "
+ "bounds in XPT_RESET_DEV\n", ccb->ccb_h.target_id));
sc = sassc->sc;
tm = mpr_alloc_command(sc);
if (tm == NULL) {
- mpr_dprint(sc, MPR_ERROR,
- "command alloc failure in mprsas_action_resetdev\n");
+ mpr_dprint(sc, MPR_ERROR, "command alloc failure in "
+ "mprsas_action_resetdev\n");
mprsas_set_ccbstatus(ccb, CAM_RESRC_UNAVAIL);
xpt_done(ccb);
return;
@@ -3014,9 +3016,8 @@ mprsas_resetdev_complete(struct mpr_softc *sc, struct mpr_command *tm)
goto bailout;
}
- mpr_dprint(sc, MPR_XINFO,
- "%s: IOCStatus = 0x%x ResponseCode = 0x%x\n", __func__,
- le16toh(resp->IOCStatus), le32toh(resp->ResponseCode));
+ mpr_dprint(sc, MPR_XINFO, "%s: IOCStatus = 0x%x ResponseCode = 0x%x\n",
+ __func__, le16toh(resp->IOCStatus), le32toh(resp->ResponseCode));
if (le32toh(resp->ResponseCode) == MPI2_SCSITASKMGMT_RSP_TM_COMPLETE) {
mprsas_set_ccbstatus(ccb, CAM_REQ_CMP);
@@ -3205,8 +3206,8 @@ mprsas_check_eedp(struct mpr_softc *sc, struct cam_path *path,
targetid = xpt_path_target_id(path);
lunid = xpt_path_lun_id(path);
- KASSERT(targetid < sassc->maxtargets,
- ("Target %d out of bounds in mprsas_check_eedp\n", targetid));
+ KASSERT(targetid < sassc->maxtargets, ("Target %d out of bounds in "
+ "mprsas_check_eedp\n", targetid));
target = &sassc->targets[targetid];
if (target->handle == 0x0)
return;
@@ -3216,7 +3217,7 @@ mprsas_check_eedp(struct mpr_softc *sc, struct cam_path *path,
*
* If this flag is set in the inquiry data, the device supports
* protection information, and must support the 16 byte read capacity
- * command, otherwise continue without sending read cap 16
+ * command, otherwise continue without sending read cap 16.
*/
if ((cgd->inq_data.spc3_flags & SPC3_SID_PROTECT) == 0)
return;
@@ -3232,10 +3233,10 @@ mprsas_check_eedp(struct mpr_softc *sc, struct cam_path *path,
return;
}
- if (xpt_create_path(&local_path, xpt_periph, pathid, targetid, lunid)
- != CAM_REQ_CMP) {
+ if (xpt_create_path(&local_path, xpt_periph, pathid, targetid, lunid) !=
+ CAM_REQ_CMP) {
mpr_dprint(sc, MPR_ERROR, "Unable to create path for EEDP "
- "support\n");
+ "support.\n");
xpt_free_ccb(ccb);
return;
}
@@ -3337,9 +3338,8 @@ mprsas_read_cap_done(struct cam_periph *periph, union ccb *done_ccb)
* target.
*/
sassc = (struct mprsas_softc *)done_ccb->ccb_h.ppriv_ptr1;
- KASSERT(done_ccb->ccb_h.target_id < sassc->maxtargets,
- ("Target %d out of bounds in mprsas_read_cap_done\n",
- done_ccb->ccb_h.target_id));
+ KASSERT(done_ccb->ccb_h.target_id < sassc->maxtargets, ("Target %d out "
+ "of bounds in mprsas_read_cap_done\n", done_ccb->ccb_h.target_id));
target = &sassc->targets[done_ccb->ccb_h.target_id];
SLIST_FOREACH(lun, &target->luns, lun_link) {
if (lun->lun_id != done_ccb->ccb_h.target_lun)
OpenPOWER on IntegriCloud