diff options
-rw-r--r-- | sys/dev/mpr/mpi/mpi2.h | 8 | ||||
-rw-r--r-- | sys/dev/mpr/mpi/mpi2_cnfg.h | 8 | ||||
-rw-r--r-- | sys/dev/mpr/mpi/mpi2_hbd.h | 8 | ||||
-rw-r--r-- | sys/dev/mpr/mpi/mpi2_history.txt | 8 | ||||
-rw-r--r-- | sys/dev/mpr/mpi/mpi2_init.h | 8 | ||||
-rw-r--r-- | sys/dev/mpr/mpi/mpi2_ioc.h | 8 | ||||
-rw-r--r-- | sys/dev/mpr/mpi/mpi2_ra.h | 8 | ||||
-rw-r--r-- | sys/dev/mpr/mpi/mpi2_raid.h | 8 | ||||
-rw-r--r-- | sys/dev/mpr/mpi/mpi2_sas.h | 8 | ||||
-rw-r--r-- | sys/dev/mpr/mpi/mpi2_targ.h | 8 | ||||
-rw-r--r-- | sys/dev/mpr/mpi/mpi2_tool.h | 8 | ||||
-rw-r--r-- | sys/dev/mpr/mpi/mpi2_type.h | 8 | ||||
-rw-r--r-- | sys/dev/mpr/mpr.c | 90 | ||||
-rw-r--r-- | sys/dev/mpr/mpr_config.c | 5 | ||||
-rw-r--r-- | sys/dev/mpr/mpr_ioctl.h | 7 | ||||
-rw-r--r-- | sys/dev/mpr/mpr_mapping.c | 72 | ||||
-rw-r--r-- | sys/dev/mpr/mpr_mapping.h | 10 | ||||
-rw-r--r-- | sys/dev/mpr/mpr_pci.c | 14 | ||||
-rw-r--r-- | sys/dev/mpr/mpr_sas.c | 476 | ||||
-rw-r--r-- | sys/dev/mpr/mpr_sas.h | 31 | ||||
-rw-r--r-- | sys/dev/mpr/mpr_sas_lsi.c | 362 | ||||
-rw-r--r-- | sys/dev/mpr/mpr_user.c | 41 | ||||
-rw-r--r-- | sys/dev/mpr/mprvar.h | 38 |
23 files changed, 474 insertions, 768 deletions
diff --git a/sys/dev/mpr/mpi/mpi2.h b/sys/dev/mpr/mpi/mpi2.h index 42fdec2..10f17ab 100644 --- a/sys/dev/mpr/mpi/mpi2.h +++ b/sys/dev/mpr/mpi/mpi2.h @@ -1,6 +1,5 @@ /*- - * Copyright (c) 2012-2015 LSI Corp. - * Copyright (c) 2013-2015 Avago Technologies + * Copyright (c) 2013 LSI Corp. * All rights reserved. * * Redistribution and use in source and binary forms, with or without @@ -27,14 +26,13 @@ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF * SUCH DAMAGE. * - * Avago Technologies (LSI) MPT-Fusion Host Adapter FreeBSD + * LSI MPT-Fusion Host Adapter FreeBSD * * $FreeBSD$ */ /* - * Copyright (c) 2000-2015 LSI Corporation. - * Copyright (c) 2013-2015 Avago Technologies + * Copyright (c) 2000-2013 LSI Corporation. * * * Name: mpi2.h diff --git a/sys/dev/mpr/mpi/mpi2_cnfg.h b/sys/dev/mpr/mpi/mpi2_cnfg.h index 3b0eb63..d82750f 100644 --- a/sys/dev/mpr/mpi/mpi2_cnfg.h +++ b/sys/dev/mpr/mpi/mpi2_cnfg.h @@ -1,6 +1,5 @@ /*- - * Copyright (c) 2012-2015 LSI Corp. - * Copyright (c) 2013-2015 Avago Technologies + * Copyright (c) 2013 LSI Corp. * All rights reserved. * * Redistribution and use in source and binary forms, with or without @@ -27,14 +26,13 @@ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF * SUCH DAMAGE. * - * Avago Technologies (LSI) MPT-Fusion Host Adapter FreeBSD + * LSI MPT-Fusion Host Adapter FreeBSD * * $FreeBSD$ */ /* - * Copyright (c) 2000-2015 LSI Corporation. - * Copyright (c) 2013-2015 Avago Technologies + * Copyright (c) 2000-2013 LSI Corporation. * * * Name: mpi2_cnfg.h diff --git a/sys/dev/mpr/mpi/mpi2_hbd.h b/sys/dev/mpr/mpi/mpi2_hbd.h index 520407b..d0cc09f 100644 --- a/sys/dev/mpr/mpi/mpi2_hbd.h +++ b/sys/dev/mpr/mpi/mpi2_hbd.h @@ -1,6 +1,5 @@ /*- - * Copyright (c) 2012-2015 LSI Corp. - * Copyright (c) 2013-2015 Avago Technologies + * Copyright (c) 2013 LSI Corp. * All rights reserved. * * Redistribution and use in source and binary forms, with or without @@ -27,14 +26,13 @@ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF * SUCH DAMAGE. * - * Avago Technologies (LSI) MPT-Fusion Host Adapter FreeBSD + * LSI MPT-Fusion Host Adapter FreeBSD * * $FreeBSD$ */ /* - * Copyright (c) 2009-2015 LSI Corporation. - * Copyright (c) 2013-2015 Avago Technologies + * Copyright (c) 2009-2011 LSI Corporation. * * * Name: mpi2_hbd.h diff --git a/sys/dev/mpr/mpi/mpi2_history.txt b/sys/dev/mpr/mpi/mpi2_history.txt index 9fca796..296b75b 100644 --- a/sys/dev/mpr/mpi/mpi2_history.txt +++ b/sys/dev/mpr/mpi/mpi2_history.txt @@ -1,6 +1,5 @@ /*- - * Copyright (c) 2012-2015 LSI Corp. - * Copyright (c) 2013-2015 Avago Technologies + * Copyright (c) 2013 LSI Corp. * All rights reserved. * * Redistribution and use in source and binary forms, with or without @@ -27,7 +26,7 @@ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF * SUCH DAMAGE. * - * Avago Technologies (LSI) MPT-Fusion Host Adapter FreeBSD + * LSI MPT-Fusion Host Adapter FreeBSD * * $FreeBSD$ */ @@ -36,8 +35,7 @@ Fusion-MPT MPI 2.0 / 2.5 Header File Change History ============================== - Copyright (c) 2000-2015 LSI Corporation. - Copyright (c) 2013-2015 Avago Technologies + Copyright (c) 2000-2013 LSI Corporation. --------------------------------------- Header Set Release Version: 02.00.33 diff --git a/sys/dev/mpr/mpi/mpi2_init.h b/sys/dev/mpr/mpi/mpi2_init.h index 5f475c0..62b0cfe 100644 --- a/sys/dev/mpr/mpi/mpi2_init.h +++ b/sys/dev/mpr/mpi/mpi2_init.h @@ -1,6 +1,5 @@ /*- - * Copyright (c) 2012-2015 LSI Corp. - * Copyright (c) 2013-2015 Avago Technologies + * Copyright (c) 2013 LSI Corp. * All rights reserved. * * Redistribution and use in source and binary forms, with or without @@ -27,14 +26,13 @@ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF * SUCH DAMAGE. * - * Avago Technologies (LSI) MPT-Fusion Host Adapter FreeBSD + * LSI MPT-Fusion Host Adapter FreeBSD * * $FreeBSD$ */ /* - * Copyright (c) 2000-2015 LSI Corporation. - * Copyright (c) 2013-2015 Avago Technologies + * Copyright (c) 2000-2013 LSI Corporation. * * * Name: mpi2_init.h diff --git a/sys/dev/mpr/mpi/mpi2_ioc.h b/sys/dev/mpr/mpi/mpi2_ioc.h index 54f39a5..38a46f5 100644 --- a/sys/dev/mpr/mpi/mpi2_ioc.h +++ b/sys/dev/mpr/mpi/mpi2_ioc.h @@ -1,6 +1,5 @@ /*- - * Copyright (c) 2012-2015 LSI Corp. - * Copyright (c) 2013-2015 Avago Technologies + * Copyright (c) 2013 LSI Corp. * All rights reserved. * * Redistribution and use in source and binary forms, with or without @@ -27,14 +26,13 @@ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF * SUCH DAMAGE. * - * Avago Technologies (LSI) MPT-Fusion Host Adapter FreeBSD + * LSI MPT-Fusion Host Adapter FreeBSD * * $FreeBSD$ */ /* - * Copyright (c) 2000-2015 LSI Corporation. - * Copyright (c) 2013-2015 Avago Technologies + * Copyright (c) 2000-2013 LSI Corporation. * * * Name: mpi2_ioc.h diff --git a/sys/dev/mpr/mpi/mpi2_ra.h b/sys/dev/mpr/mpi/mpi2_ra.h index 02304aa..76db06b 100644 --- a/sys/dev/mpr/mpi/mpi2_ra.h +++ b/sys/dev/mpr/mpi/mpi2_ra.h @@ -1,6 +1,5 @@ /*- - * Copyright (c) 2012-2015 LSI Corp. - * Copyright (c) 2013-2015 Avago Technologies + * Copyright (c) 2013 LSI Corp. * All rights reserved. * * Redistribution and use in source and binary forms, with or without @@ -27,14 +26,13 @@ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF * SUCH DAMAGE. * - * Avago Technologies (LSI) MPT-Fusion Host Adapter FreeBSD + * LSI MPT-Fusion Host Adapter FreeBSD * * $FreeBSD$ */ /* - * Copyright (c) 2012-2015 LSI Corporation. - * Copyright (c) 2013-2015 Avago Technologies + * Copyright (c) 2009 LSI Corporation. * * * Name: mpi2_ra.h diff --git a/sys/dev/mpr/mpi/mpi2_raid.h b/sys/dev/mpr/mpi/mpi2_raid.h index 52ebf07..c6bb598 100644 --- a/sys/dev/mpr/mpi/mpi2_raid.h +++ b/sys/dev/mpr/mpi/mpi2_raid.h @@ -1,6 +1,5 @@ /*- - * Copyright (c) 2012-2015 LSI Corp. - * Copyright (c) 2013-2015 Avago Technologies + * Copyright (c) 2013 LSI Corp. * All rights reserved. * * Redistribution and use in source and binary forms, with or without @@ -27,14 +26,13 @@ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF * SUCH DAMAGE. * - * Avago Technologies (LSI) MPT-Fusion Host Adapter FreeBSD + * LSI MPT-Fusion Host Adapter FreeBSD * * $FreeBSD$ */ /* - * Copyright (c) 2000-2015 LSI Corporation. - * Copyright (c) 2013-2015 Avago Technologies + * Copyright (c) 2000-2013 LSI Corporation. * * * Name: mpi2_raid.h diff --git a/sys/dev/mpr/mpi/mpi2_sas.h b/sys/dev/mpr/mpi/mpi2_sas.h index 7cae2c3..2a107f1 100644 --- a/sys/dev/mpr/mpi/mpi2_sas.h +++ b/sys/dev/mpr/mpi/mpi2_sas.h @@ -1,6 +1,5 @@ /*- - * Copyright (c) 2012-2015 LSI Corp. - * Copyright (c) 2013-2015 Avago Technologies + * Copyright (c) 2013 LSI Corp. * All rights reserved. * * Redistribution and use in source and binary forms, with or without @@ -27,14 +26,13 @@ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF * SUCH DAMAGE. * - * Avago Technologies (LSI) MPT-Fusion Host Adapter FreeBSD + * LSI MPT-Fusion Host Adapter FreeBSD * * $FreeBSD$ */ /* - * Copyright (c) 2000-2015 LSI Corporation. - * Copyright (c) 2013-2015 Avago Technologies + * Copyright (c) 2000-2013 LSI Corporation. * * * Name: mpi2_sas.h diff --git a/sys/dev/mpr/mpi/mpi2_targ.h b/sys/dev/mpr/mpi/mpi2_targ.h index 85b5ac5..506e64f 100644 --- a/sys/dev/mpr/mpi/mpi2_targ.h +++ b/sys/dev/mpr/mpi/mpi2_targ.h @@ -1,6 +1,5 @@ /*- - * Copyright (c) 2012-2015 LSI Corp. - * Copyright (c) 2013-2015 Avago Technologies + * Copyright (c) 2013 LSI Corp. * All rights reserved. * * Redistribution and use in source and binary forms, with or without @@ -27,14 +26,13 @@ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF * SUCH DAMAGE. * - * Avago Technologies (LSI) MPT-Fusion Host Adapter FreeBSD + * LSI MPT-Fusion Host Adapter FreeBSD * * $FreeBSD$ */ /* - * Copyright (c) 2000-2015 LSI Corporation. - * Copyright (c) 2013-2015 Avago Technologies + * Copyright (c) 2000-2012 LSI Corporation. * * * Name: mpi2_targ.h diff --git a/sys/dev/mpr/mpi/mpi2_tool.h b/sys/dev/mpr/mpi/mpi2_tool.h index 59917c0..94542cc 100644 --- a/sys/dev/mpr/mpi/mpi2_tool.h +++ b/sys/dev/mpr/mpi/mpi2_tool.h @@ -1,6 +1,5 @@ /*- - * Copyright (c) 2012-2015 LSI Corp. - * Copyright (c) 2013-2015 Avago Technologies + * Copyright (c) 2013 LSI Corp. * All rights reserved. * * Redistribution and use in source and binary forms, with or without @@ -27,14 +26,13 @@ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF * SUCH DAMAGE. * - * Avago Technologies (LSI) MPT-Fusion Host Adapter FreeBSD + * LSI MPT-Fusion Host Adapter FreeBSD * * $FreeBSD$ */ /* - * Copyright (c) 2000-2015 LSI Corporation. - * Copyright (c) 2013-2015 Avago Technologies + * Copyright (c) 2000-2013 LSI Corporation. * * * Name: mpi2_tool.h diff --git a/sys/dev/mpr/mpi/mpi2_type.h b/sys/dev/mpr/mpi/mpi2_type.h index b063683..da3aefb 100644 --- a/sys/dev/mpr/mpi/mpi2_type.h +++ b/sys/dev/mpr/mpi/mpi2_type.h @@ -1,6 +1,5 @@ /*- - * Copyright (c) 2012-2015 LSI Corp. - * Copyright (c) 2013-2015 Avago Technologies + * Copyright (c) 2013 LSI Corp. * All rights reserved. * * Redistribution and use in source and binary forms, with or without @@ -27,14 +26,13 @@ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF * SUCH DAMAGE. * - * Avago Technologies (LSI) MPT-Fusion Host Adapter FreeBSD + * LSI MPT-Fusion Host Adapter FreeBSD * * $FreeBSD$ */ /* - * Copyright (c) 2000-2015 LSI Corporation. - * Copyright (c) 2013-2015 Avago Technologies + * Copyright (c) 2000-2007 LSI Corporation. * * * Name: mpi2_type.h diff --git a/sys/dev/mpr/mpr.c b/sys/dev/mpr/mpr.c index 07e73c5..d3fb9a0 100644 --- a/sys/dev/mpr/mpr.c +++ b/sys/dev/mpr/mpr.c @@ -1,7 +1,6 @@ /*- * Copyright (c) 2009 Yahoo! Inc. - * Copyright (c) 2011-2015 LSI Corp. - * Copyright (c) 2013-2015 Avago Technologies + * Copyright (c) 2012-2014 LSI Corp. * All rights reserved. * * Redistribution and use in source and binary forms, with or without @@ -25,14 +24,12 @@ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF * SUCH DAMAGE. * - * Avago Technologies (LSI) MPT-Fusion Host Adapter FreeBSD - * */ #include <sys/cdefs.h> __FBSDID("$FreeBSD$"); -/* Communications core for Avago Technologies (LSI) MPT3 */ +/* Communications core for LSI MPT2 */ /* TODO Move headers to mprvar */ #include <sys/types.h> @@ -75,6 +72,7 @@ __FBSDID("$FreeBSD$"); #include <dev/mpr/mpr_ioctl.h> #include <dev/mpr/mprvar.h> #include <dev/mpr/mpr_table.h> +#include <dev/mpr/mpr_sas.h> static int mpr_diag_reset(struct mpr_softc *sc, int sleep_flag); static int mpr_init_queues(struct mpr_softc *sc); @@ -354,9 +352,11 @@ mpr_transition_operational(struct mpr_softc *sc) static int mpr_iocfacts_allocate(struct mpr_softc *sc, uint8_t attaching) { - int error; + int error, i; Mpi2IOCFactsReply_t saved_facts; uint8_t saved_mode, reallocating; + struct mprsas_lun *lun, *lun_tmp; + struct mprsas_target *targ; mpr_dprint(sc, MPR_TRACE, "%s\n", __func__); @@ -513,7 +513,27 @@ mpr_iocfacts_allocate(struct mpr_softc *sc, uint8_t attaching) */ if (reallocating) { mpr_iocfacts_free(sc); - mprsas_realloc_targets(sc, saved_facts.MaxTargets); + + /* + * The number of targets is based on IOC Facts, so free all of + * the allocated LUNs for each target and then the target buffer + * itself. + */ + for (i=0; i< saved_facts.MaxTargets; i++) { + targ = &sc->sassc->targets[i]; + SLIST_FOREACH_SAFE(lun, &targ->luns, lun_link, + lun_tmp) { + free(lun, M_MPR); + } + } + free(sc->sassc->targets, M_MPR); + + sc->sassc->targets = malloc(sizeof(struct mprsas_target) * + sc->facts->MaxTargets, M_MPR, M_WAITOK|M_ZERO); + if (!sc->sassc->targets) { + panic("%s failed to alloc targets with error %d\n", + __func__, ENOMEM); + } } /* @@ -755,7 +775,7 @@ mpr_reinit(struct mpr_softc *sc) /* the end of discovery will release the simq, so we're done. */ mpr_dprint(sc, MPR_INFO, "%s finished sc %p post %u free %u\n", __func__, sc, sc->replypostindex, sc->replyfreeindex); - mprsas_release_simq_reinit(sassc); + mprsas_release_simq_reinit(sassc); return 0; } @@ -796,8 +816,7 @@ mpr_wait_db_ack(struct mpr_softc *sc, int timeout, int sleep_flag) * 0.5 milisecond */ if (mtx_owned(&sc->mpr_mtx) && sleep_flag == CAN_SLEEP) - msleep(&sc->msleep_fake_chan, &sc->mpr_mtx, 0, "mprdba", - hz/1000); + msleep(&sc->msleep_fake_chan, &sc->mpr_mtx, 0, "mprdba", hz/1000); else if (sleep_flag == CAN_SLEEP) pause("mprdba", hz/1000); else @@ -963,7 +982,7 @@ mpr_enqueue_request(struct mpr_softc *sc, struct mpr_command *cm) reply_descriptor rd; MPR_FUNCTRACE(sc); - mpr_dprint(sc, MPR_TRACE, "SMID %u cm %p ccb %p\n", + mpr_dprint(sc, MPR_TRACE, "%s SMID %u cm %p ccb %p\n", __func__, cm->cm_desc.Default.SMID, cm, cm->cm_ccb); if (sc->mpr_flags & MPR_FLAGS_ATTACH_DONE && !(sc->mpr_flags & @@ -1353,8 +1372,6 @@ mpr_get_tunables(struct mpr_softc *sc) sc->disable_msix = 0; sc->disable_msi = 0; sc->max_chains = MPR_CHAIN_FRAMES; - sc->enable_ssu = MPR_SSU_ENABLE_SSD_DISABLE_HDD; - sc->spinup_wait_time = DEFAULT_SPINUP_WAIT; /* * Grab the global variables. @@ -1363,8 +1380,6 @@ mpr_get_tunables(struct mpr_softc *sc) TUNABLE_INT_FETCH("hw.mpr.disable_msix", &sc->disable_msix); TUNABLE_INT_FETCH("hw.mpr.disable_msi", &sc->disable_msi); TUNABLE_INT_FETCH("hw.mpr.max_chains", &sc->max_chains); - TUNABLE_INT_FETCH("hw.mpr.enable_ssu", &sc->enable_ssu); - TUNABLE_INT_FETCH("hw.mpr.spinup_wait_time", &sc->spinup_wait_time); /* Grab the unit-instance variables */ snprintf(tmpstr, sizeof(tmpstr), "dev.mpr.%d.debug_level", @@ -1387,14 +1402,6 @@ mpr_get_tunables(struct mpr_softc *sc) snprintf(tmpstr, sizeof(tmpstr), "dev.mpr.%d.exclude_ids", device_get_unit(sc->mpr_dev)); TUNABLE_STR_FETCH(tmpstr, sc->exclude_ids, sizeof(sc->exclude_ids)); - - snprintf(tmpstr, sizeof(tmpstr), "dev.mpr.%d.enable_ssu", - device_get_unit(sc->mpr_dev)); - TUNABLE_INT_FETCH(tmpstr, &sc->enable_ssu); - - snprintf(tmpstr, sizeof(tmpstr), "dev.mpr.%d.spinup_wait_time", - device_get_unit(sc->mpr_dev)); - TUNABLE_INT_FETCH(tmpstr, &sc->spinup_wait_time); } static void @@ -1467,20 +1474,11 @@ mpr_setup_sysctl(struct mpr_softc *sc) OID_AUTO, "max_chains", CTLFLAG_RD, &sc->max_chains, 0,"maximum chain frames that will be allocated"); - SYSCTL_ADD_INT(sysctl_ctx, SYSCTL_CHILDREN(sysctl_tree), - OID_AUTO, "enable_ssu", CTLFLAG_RW, &sc->enable_ssu, 0, - "enable SSU to SATA SSD/HDD at shutdown"); - #if __FreeBSD_version >= 900030 SYSCTL_ADD_UQUAD(sysctl_ctx, SYSCTL_CHILDREN(sysctl_tree), OID_AUTO, "chain_alloc_fail", CTLFLAG_RD, &sc->chain_alloc_fail, "chain allocation failures"); #endif //FreeBSD_version >= 900030 - - SYSCTL_ADD_INT(sysctl_ctx, SYSCTL_CHILDREN(sysctl_tree), - OID_AUTO, "spinup_wait_time", CTLFLAG_RD, - &sc->spinup_wait_time, DEFAULT_SPINUP_WAIT, "seconds to wait for " - "spinup after SATA ID error"); } int @@ -2098,7 +2096,7 @@ mpr_update_events(struct mpr_softc *sc, struct mpr_event_handle *handle, (reply->IOCStatus & MPI2_IOCSTATUS_MASK) != MPI2_IOCSTATUS_SUCCESS) error = ENXIO; - if (reply) + if(reply) mpr_print_event(sc, reply); mpr_dprint(sc, MPR_TRACE, "%s finished error %d\n", __func__, error); @@ -2165,8 +2163,8 @@ mpr_deregister_events(struct mpr_softc *sc, struct mpr_event_handle *handle) * Add a chain element as the next SGE for the specified command. * Reset cm_sge and cm_sgesize to indicate all the available space. Chains are * only required for IEEE commands. Therefore there is no code for commands - * that have the MPR_CM_FLAGS_SGE_SIMPLE flag set (and those commands - * shouldn't be requesting chains). + * that have the MPR_CM_FLAGS_SGE_SIMPLE flag set (and those commands shouldn't + * be requesting chains). */ static int mpr_add_chain(struct mpr_command *cm, int segsleft) @@ -2248,9 +2246,9 @@ mpr_add_chain(struct mpr_command *cm, int segsleft) /* * Add one scatter-gather element to the scatter-gather list for a command. - * Maintain cm_sglsize and cm_sge as the remaining size and pointer to the - * next SGE to fill in, respectively. In Gen3, the MPI SGL does not have a - * chain, so don't consider any chain additions. + * Maintain cm_sglsize and cm_sge as the remaining size and pointer to the next + * SGE to fill in, respectively. In Gen3, the MPI SGL does not have a chain, + * so don't consider any chain additions. */ int mpr_push_sge(struct mpr_command *cm, MPI2_SGE_SIMPLE64 *sge, size_t len, @@ -2662,7 +2660,7 @@ mpr_request_polled(struct mpr_softc *sc, struct mpr_command *cm) } } - if (error) { + if(error) { mpr_dprint(sc, MPR_FAULT, "Calling Reinit from %s\n", __func__); rc = mpr_reinit(sc); mpr_dprint(sc, MPR_FAULT, "Reinit %s\n", (rc == 0) ? @@ -2719,12 +2717,9 @@ mpr_read_config_page(struct mpr_softc *sc, struct mpr_config_params *params) cm->cm_data = params->buffer; cm->cm_length = params->length; - if (cm->cm_data != NULL) { - cm->cm_sge = &req->PageBufferSGE; - cm->cm_sglsize = sizeof(MPI2_SGE_IO_UNION); - cm->cm_flags = MPR_CM_FLAGS_SGE_SIMPLE | MPR_CM_FLAGS_DATAIN; - } else - cm->cm_sge = NULL; + cm->cm_sge = &req->PageBufferSGE; + cm->cm_sglsize = sizeof(MPI2_SGE_IO_UNION); + cm->cm_flags = MPR_CM_FLAGS_SGE_SIMPLE | MPR_CM_FLAGS_DATAIN; cm->cm_desc.Default.RequestFlags = MPI2_REQ_DESCRIPT_FLAGS_DEFAULT_TYPE; cm->cm_complete_data = params; @@ -2781,12 +2776,9 @@ mpr_config_complete(struct mpr_softc *sc, struct mpr_command *cm) goto done; } params->status = reply->IOCStatus; - if (params->hdr.Struct.PageType == MPI2_CONFIG_PAGETYPE_EXTENDED) { + if (params->hdr.Ext.ExtPageType != 0) { params->hdr.Ext.ExtPageType = reply->ExtPageType; params->hdr.Ext.ExtPageLength = reply->ExtPageLength; - params->hdr.Ext.PageType = reply->Header.PageType; - params->hdr.Ext.PageNumber = reply->Header.PageNumber; - params->hdr.Ext.PageVersion = reply->Header.PageVersion; } else { params->hdr.Struct.PageType = reply->Header.PageType; params->hdr.Struct.PageNumber = reply->Header.PageNumber; diff --git a/sys/dev/mpr/mpr_config.c b/sys/dev/mpr/mpr_config.c index c0ea3d5..1254516 100644 --- a/sys/dev/mpr/mpr_config.c +++ b/sys/dev/mpr/mpr_config.c @@ -1,6 +1,5 @@ /*- - * Copyright (c) 2011-2015 LSI Corp. - * Copyright (c) 2013-2015 Avago Technologies + * Copyright (c) 2011-2014 LSI Corp. * All rights reserved. * * Redistribution and use in source and binary forms, with or without @@ -24,7 +23,7 @@ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF * SUCH DAMAGE. * - * Avago Technologies (LSI) MPT-Fusion Host Adapter FreeBSD + * LSI MPT-Fusion Host Adapter FreeBSD */ #include <sys/cdefs.h> diff --git a/sys/dev/mpr/mpr_ioctl.h b/sys/dev/mpr/mpr_ioctl.h index aa1a4cb..5ec482f 100644 --- a/sys/dev/mpr/mpr_ioctl.h +++ b/sys/dev/mpr/mpr_ioctl.h @@ -27,13 +27,12 @@ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF * SUCH DAMAGE. * - * Avago Technologies (LSI) MPT-Fusion Host Adapter FreeBSD userland interface + * LSI MPT-Fusion Host Adapter FreeBSD userland interface * * $FreeBSD$ */ /*- - * Copyright (c) 2011-2015 LSI Corp. - * Copyright (c) 2013-2015 Avago Technologies + * Copyright (c) 2011-2014 LSI Corp. * All rights reserved. * * Redistribution and use in source and binary forms, with or without @@ -57,7 +56,7 @@ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF * SUCH DAMAGE. * - * Avago Technologies (LSI) MPT-Fusion Host Adapter FreeBSD + * LSI MPT-Fusion Host Adapter FreeBSD * * $FreeBSD$ */ diff --git a/sys/dev/mpr/mpr_mapping.c b/sys/dev/mpr/mpr_mapping.c index 110e6a3..7f0fc00 100644 --- a/sys/dev/mpr/mpr_mapping.c +++ b/sys/dev/mpr/mpr_mapping.c @@ -1,6 +1,5 @@ /*- - * Copyright (c) 2011-2015 LSI Corp. - * Copyright (c) 2013-2015 Avago Technologies + * Copyright (c) 2011-2014 LSI Corp. * All rights reserved. * * Redistribution and use in source and binary forms, with or without @@ -24,7 +23,7 @@ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF * SUCH DAMAGE. * - * Avago Technologies (LSI) MPT-Fusion Host Adapter FreeBSD + * LSI MPT-Fusion Host Adapter FreeBSD */ #include <sys/cdefs.h> @@ -327,13 +326,11 @@ _mapping_get_high_missing_mt_idx(struct mpr_softc *sc) { u32 map_idx, high_idx = MPR_ENCTABLE_BAD_IDX; u8 high_missing_count = 0; - u32 start_idx, end_idx, start_idx_ir, end_idx_ir; + u32 start_idx, end_idx, start_idx_ir = 0, end_idx_ir; struct dev_mapping_table *mt_entry; u16 ioc_pg8_flags = le16toh(sc->ioc_pg8.Flags); start_idx = 0; - start_idx_ir = 0; - end_idx_ir = 0; end_idx = sc->max_devices; if (ioc_pg8_flags & MPI2_IOCPAGE8_FLAGS_RESERVED_TARGETID_0) start_idx = 1; @@ -890,14 +887,14 @@ _mapping_get_dev_info(struct mpr_softc *sc, u16 ioc_pg8_flags = le16toh(sc->ioc_pg8.Flags); Mpi2ConfigReply_t mpi_reply; Mpi2SasDevicePage0_t sas_device_pg0; - u8 entry, enc_idx, phy_idx, sata_end_device; + u8 entry, enc_idx, phy_idx; u32 map_idx, index, device_info; struct _map_phy_change *phy_change, *tmp_phy_change; uint64_t sas_address; struct enc_mapping_table *et_entry; struct dev_mapping_table *mt_entry; u8 add_code = MPI2_EVENT_SAS_TOPO_RC_TARG_ADDED; - int rc = 1; + int rc; for (entry = 0; entry < topo_change->num_entries; entry++) { phy_change = &topo_change->phy_details[entry]; @@ -911,36 +908,41 @@ _mapping_get_dev_info(struct mpr_softc *sc, continue; } - /* - * Always get SATA Identify information because this is used - * to determine if Start/Stop Unit should be sent to the drive - * when the system is shutdown. - */ device_info = le32toh(sas_device_pg0.DeviceInfo); - sas_address = sas_device_pg0.SASAddress.High; - sas_address = (sas_address << 32) | - sas_device_pg0.SASAddress.Low; - sata_end_device = 0; - if ((device_info & MPI2_SAS_DEVICE_INFO_END_DEVICE) && - (device_info & MPI2_SAS_DEVICE_INFO_SATA_DEVICE)) { - sata_end_device = 1; - rc = mprsas_get_sas_address_for_sata_disk(sc, - &sas_address, phy_change->dev_handle, device_info, - &phy_change->is_SATA_SSD); - if (rc) { - mpr_dprint(sc, MPR_ERROR, "%s: failed to get " - "disk type (SSD or HDD) and SAS Address " - "for SATA device with handle 0x%04x\n", - __func__, phy_change->dev_handle); - } else { + if ((ioc_pg8_flags & MPI2_IOCPAGE8_FLAGS_MASK_MAPPING_MODE) == + MPI2_IOCPAGE8_FLAGS_DEVICE_PERSISTENCE_MAPPING) { + if ((device_info & MPI2_SAS_DEVICE_INFO_END_DEVICE) && + (device_info & MPI2_SAS_DEVICE_INFO_SATA_DEVICE)) { + rc = mprsas_get_sas_address_for_sata_disk(sc, + &sas_address, phy_change->dev_handle, + device_info); + if (rc) { + printf("%s: failed to compute the " + "hashed SAS Address for SATA " + "device with handle 0x%04x\n", + __func__, phy_change->dev_handle); + sas_address = + sas_device_pg0.SASAddress.High; + sas_address = (sas_address << 32) | + sas_device_pg0.SASAddress.Low; + } mpr_dprint(sc, MPR_INFO, "SAS Address for SATA " "device = %jx\n", sas_address); + } else { + sas_address = + sas_device_pg0.SASAddress.High; + sas_address = (sas_address << 32) | + sas_device_pg0.SASAddress.Low; } + } else { + sas_address = sas_device_pg0.SASAddress.High; + sas_address = (sas_address << 32) | + sas_device_pg0.SASAddress.Low; } - phy_change->physical_id = sas_address; phy_change->slot = le16toh(sas_device_pg0.Slot); - phy_change->device_info = le32toh(sas_device_pg0.DeviceInfo); + phy_change->device_info = + le32toh(sas_device_pg0.DeviceInfo); if ((ioc_pg8_flags & MPI2_IOCPAGE8_FLAGS_MASK_MAPPING_MODE) == MPI2_IOCPAGE8_FLAGS_ENCLOSURE_SLOT_MAPPING) { @@ -948,10 +950,10 @@ _mapping_get_dev_info(struct mpr_softc *sc, topo_change->enc_handle); if (enc_idx == MPR_ENCTABLE_BAD_IDX) { phy_change->is_processed = 1; - mpr_dprint(sc, MPR_MAPPING, "%s: failed to add " - "the device with handle 0x%04x because the " - "enclosure is not in the mapping table\n", - __func__, phy_change->dev_handle); + printf("%s: failed to add the device with " + "handle 0x%04x because the enclosure is " + "not in the mapping table\n", __func__, + phy_change->dev_handle); continue; } if (!((phy_change->device_info & diff --git a/sys/dev/mpr/mpr_mapping.h b/sys/dev/mpr/mpr_mapping.h index c00a3b7..3250c42 100644 --- a/sys/dev/mpr/mpr_mapping.h +++ b/sys/dev/mpr/mpr_mapping.h @@ -1,6 +1,5 @@ /*- - * Copyright (c) 2011-2015 LSI Corp. - * Copyright (c) 2013-2015 Avago Technologies + * Copyright (c) 2011-2014 LSI Corp. * All rights reserved. * * Redistribution and use in source and binary forms, with or without @@ -24,7 +23,7 @@ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF * SUCH DAMAGE. * - * Avago Technologies (LSI) MPT-Fusion Host Adapter FreeBSD + * LSI MPT-Fusion Host Adapter FreeBSD * * $FreeBSD$ */ @@ -39,7 +38,6 @@ * @dev_handle: device handle for the device pointed by this entry * @slot: slot ID * @is_processed: Flag to indicate whether this entry is processed or not - * @is_SATA_SSD: 1 if this is a SATA device AND an SSD, 0 otherwise */ struct _map_phy_change { uint64_t physical_id; @@ -48,8 +46,6 @@ struct _map_phy_change { uint16_t slot; uint8_t reason; uint8_t is_processed; - uint8_t is_SATA_SSD; - uint8_t reserved; }; /** @@ -70,6 +66,6 @@ struct _map_topology_change { extern int mprsas_get_sas_address_for_sata_disk(struct mpr_softc *ioc, - u64 *sas_address, u16 handle, u32 device_info, u8 *is_SATA_SSD); + u64 *sas_address, u16 handle, u32 device_info); #endif diff --git a/sys/dev/mpr/mpr_pci.c b/sys/dev/mpr/mpr_pci.c index 7430eac..e19f33a 100644 --- a/sys/dev/mpr/mpr_pci.c +++ b/sys/dev/mpr/mpr_pci.c @@ -27,7 +27,7 @@ #include <sys/cdefs.h> __FBSDID("$FreeBSD$"); -/* PCI/PCI-X/PCIe bus interface for the Avago Tech (LSI) MPT3 controllers */ +/* PCI/PCI-X/PCIe bus interface for the LSI MPT2 controllers */ /* TODO Move headers to mprvar */ #include <sys/types.h> @@ -99,17 +99,17 @@ struct mpr_ident { const char *desc; } mpr_identifiers[] = { { MPI2_MFGPAGE_VENDORID_LSI, MPI25_MFGPAGE_DEVID_SAS3004, - 0xffff, 0xffff, 0, "Avago Technologies (LSI) SAS3004" }, + 0xffff, 0xffff, 0, "LSI SAS3004" }, { MPI2_MFGPAGE_VENDORID_LSI, MPI25_MFGPAGE_DEVID_SAS3008, - 0xffff, 0xffff, 0, "Avago Technologies (LSI) SAS3008" }, + 0xffff, 0xffff, 0, "LSI SAS3008" }, { MPI2_MFGPAGE_VENDORID_LSI, MPI25_MFGPAGE_DEVID_SAS3108_1, - 0xffff, 0xffff, 0, "Avago Technologies (LSI) SAS3108_1" }, + 0xffff, 0xffff, 0, "LSI SAS3108_1" }, { MPI2_MFGPAGE_VENDORID_LSI, MPI25_MFGPAGE_DEVID_SAS3108_2, - 0xffff, 0xffff, 0, "Avago Technologies (LSI) SAS3108_2" }, + 0xffff, 0xffff, 0, "LSI SAS3108_2" }, { MPI2_MFGPAGE_VENDORID_LSI, MPI25_MFGPAGE_DEVID_SAS3108_5, - 0xffff, 0xffff, 0, "Avago Technologies (LSI) SAS3108_5" }, + 0xffff, 0xffff, 0, "LSI SAS3108_5" }, { MPI2_MFGPAGE_VENDORID_LSI, MPI25_MFGPAGE_DEVID_SAS3108_6, - 0xffff, 0xffff, 0, "Avago Technologies (LSI) SAS3108_6" }, + 0xffff, 0xffff, 0, "LSI SAS3108_6" }, { 0, 0, 0, 0, 0, NULL } }; diff --git a/sys/dev/mpr/mpr_sas.c b/sys/dev/mpr/mpr_sas.c index eac3360..32c3a46 100644 --- a/sys/dev/mpr/mpr_sas.c +++ b/sys/dev/mpr/mpr_sas.c @@ -1,7 +1,6 @@ /*- * Copyright (c) 2009 Yahoo! Inc. - * Copyright (c) 2011-2015 LSI Corp. - * Copyright (c) 2013-2015 Avago Technologies + * Copyright (c) 2011-2014 LSI Corp. * All rights reserved. * * Redistribution and use in source and binary forms, with or without @@ -24,15 +23,12 @@ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF * SUCH DAMAGE. - * - * Avago Technologies (LSI) MPT-Fusion Host Adapter FreeBSD - * */ #include <sys/cdefs.h> __FBSDID("$FreeBSD$"); -/* Communications core for Avago Technologies (LSI) MPT3 */ +/* Communications core for LSI MPT2 */ /* TODO Move headers to mprvar */ #include <sys/types.h> @@ -126,10 +122,14 @@ 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 int mprsas_send_abort(struct mpr_softc *sc, struct mpr_command *tm, +static int mprsas_send_abort(struct mpr_softc *sc, struct mpr_command *tm, struct mpr_command *cm); +static int mprsas_send_reset(struct mpr_softc *sc, struct mpr_command *tm, + uint8_t type); static void mprsas_async(void *callback_arg, uint32_t code, struct cam_path *path, void *arg); +static void mprsas_prepare_ssu(struct mpr_softc *sc, struct cam_path *path, + struct ccb_getdev *cgd); #if (__FreeBSD_version < 901503) || \ ((__FreeBSD_version >= 1000000) && (__FreeBSD_version < 1000006)) static void mprsas_check_eedp(struct mpr_softc *sc, struct cam_path *path, @@ -142,12 +142,13 @@ 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_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 + union ccb *ccb, uint64_t sasaddr); +static void +mprsas_action_smpio(struct mprsas_softc *sassc, union ccb *ccb); +#endif struct mprsas_target * mprsas_find_target_by_handle(struct mprsas_softc *sassc, int start, @@ -229,7 +230,7 @@ mprsas_startup_decrement(struct mprsas_softc *sassc) } } -/* The firmware requires us to stop sending commands when we're doing task +/* LSI's firmware requires us to stop sending commands when we're doing task * management, so refcount the TMs and keep the simq frozen when any are in * use. */ @@ -240,31 +241,35 @@ mprsas_alloc_tm(struct mpr_softc *sc) MPR_FUNCTRACE(sc); tm = mpr_alloc_high_priority_command(sc); + if (tm != NULL) { + if (sc->sassc->tm_count++ == 0) { + mpr_dprint(sc, MPR_RECOVERY, + "%s freezing simq\n", __func__); + xpt_freeze_simq(sc->sassc->sim, 1); + } + mpr_dprint(sc, MPR_RECOVERY, "%s tm_count %u\n", __func__, + sc->sassc->tm_count); + } return tm; } void mprsas_free_tm(struct mpr_softc *sc, struct mpr_command *tm) { - MPR_FUNCTRACE(sc); + mpr_dprint(sc, MPR_TRACE, "%s", __func__); if (tm == NULL) return; - /* - * For TM's the devq is frozen for the device. Unfreeze it here and - * free the resources used for freezing the devq. Must clear the - * INRESET flag as well or scsi I/O will not work. + /* if there are no TMs in use, we can release the simq. We use our + * own refcount so that it's easier for a diag reset to cleanup and + * release the simq. */ - if (tm->cm_targ != NULL) { - tm->cm_targ->flags &= ~MPRSAS_TARGET_INRESET; - } - if (tm->cm_ccb) { - mpr_dprint(sc, MPR_INFO, "Unfreezing devq for target ID %d\n", - tm->cm_targ->tid); - 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); + if (--sc->sassc->tm_count == 0) { + mpr_dprint(sc, MPR_RECOVERY, "%s releasing simq\n", __func__); + xpt_release_simq(sc->sassc->sim, 1); } + mpr_dprint(sc, MPR_RECOVERY, "%s tm_count %u\n", __func__, + sc->sassc->tm_count); mpr_free_high_priority_command(sc, tm); } @@ -293,8 +298,8 @@ mprsas_rescan_target(struct mpr_softc *sc, struct mprsas_target *targ) return; } - if (xpt_create_path(&ccb->ccb_h.path, NULL, pathid, targetid, - CAM_LUN_WILDCARD) != CAM_REQ_CMP) { + if (xpt_create_path(&ccb->ccb_h.path, NULL, pathid, + targetid, CAM_LUN_WILDCARD) != CAM_REQ_CMP) { mpr_dprint(sc, MPR_ERROR, "unable to create path for rescan\n"); xpt_free_ccb(ccb); return; @@ -468,16 +473,11 @@ mprsas_prepare_volume_remove(struct mprsas_softc *sassc, uint16_t handle) MPI2_REQ_DESCRIPT_FLAGS_HIGH_PRIORITY; cm->cm_complete = mprsas_remove_volume; cm->cm_complete_data = (void *)(uintptr_t)handle; - - mpr_dprint(sc, MPR_INFO, "%s: Sending reset for target ID %d\n", - __func__, targ->tid); - mprsas_prepare_for_tm(sc, cm, targ, CAM_LUN_WILDCARD); - mpr_map_command(sc, cm); } /* - * The MPT3 firmware performs debounce on the link to avoid transient link + * The MPT2 firmware performs debounce on the link to avoid transient link * errors and false removals. When it does decide that link has been lost * and a device needs to go away, it expects that the host will perform a * target reset and then an op remove. The reset has the side-effect of @@ -532,11 +532,6 @@ mprsas_prepare_remove(struct mprsas_softc *sassc, uint16_t handle) MPI2_REQ_DESCRIPT_FLAGS_HIGH_PRIORITY; cm->cm_complete = mprsas_remove_device; cm->cm_complete_data = (void *)(uintptr_t)handle; - - mpr_dprint(sc, MPR_INFO, "%s: Sending reset for target ID %d\n", - __func__, targ->tid); - mprsas_prepare_for_tm(sc, cm, targ, CAM_LUN_WILDCARD); - mpr_map_command(sc, cm); } @@ -601,10 +596,10 @@ mprsas_remove_device(struct mpr_softc *sc, struct mpr_command *tm) mpr_map_command(sc, tm); - mpr_dprint(sc, MPR_INFO, "clearing target %u handle 0x%04x\n", + mpr_dprint(sc, MPR_XINFO, "clearing target %u handle 0x%04x\n", targ->tid, handle); if (targ->encl_level_valid) { - mpr_dprint(sc, MPR_INFO, "At enclosure level %d, slot %d, " + mpr_dprint(sc, MPR_XINFO, "At enclosure level %d, slot %d, " "connector name (%4s)\n", targ->encl_level, targ->encl_slot, targ->connector_name); } @@ -613,7 +608,7 @@ mprsas_remove_device(struct mpr_softc *sc, struct mpr_command *tm) mpr_dprint(sc, MPR_XINFO, "Completing missed command %p\n", tm); ccb = tm->cm_complete_data; - mprsas_set_ccbstatus(ccb, CAM_DEV_NOT_THERE); + ccb->ccb_h.status = CAM_DEV_NOT_THERE; mprsas_scsiio_complete(sc, tm); } } @@ -731,7 +726,7 @@ mpr_attach_sas(struct mpr_softc *sc) } /* - * XXX MaxTargets could change during a reinit. Since we don't + * XXX MaxTargets could change during a reinit. since we don't * resize the targets[] array during such an event, cache the value * of MaxTargets here so that we don't get into trouble later. This * should move into the reinit logic. @@ -787,7 +782,7 @@ mpr_attach_sas(struct mpr_softc *sc) } /* - * Assume that discovery events will start right away. + * Assume that discovery events will start right away. Freezing * * Hold off boot until discovery is complete. */ @@ -795,7 +790,9 @@ mpr_attach_sas(struct mpr_softc *sc) sc->sassc->startup_refcount = 0; mprsas_startup_increment(sassc); - callout_init(&sassc->discovery_callout, 1 /*mpsafe*/); + callout_init(&sassc->discovery_callout, 1 /*mprafe*/); + + sassc->tm_count = 0; /* * Register for async events so we can determine the EEDP @@ -965,7 +962,7 @@ mprsas_action(struct cam_sim *sim, union ccb *ccb) sassc = cam_sim_softc(sim); MPR_FUNCTRACE(sassc->sc); - mpr_dprint(sassc->sc, MPR_TRACE, "ccb func_code 0x%x\n", + mpr_dprint(sassc->sc, MPR_TRACE, "%s func 0x%x\n", __func__, ccb->ccb_h.func_code); mtx_assert(&sassc->sc->mpr_mtx, MA_OWNED); @@ -988,7 +985,7 @@ mprsas_action(struct cam_sim *sim, union ccb *ccb) cpi->max_lun = 255; cpi->initiator_id = sassc->maxtargets - 1; strncpy(cpi->sim_vid, "FreeBSD", SIM_IDLEN); - strncpy(cpi->hba_vid, "Avago Tech (LSI)", HBA_IDLEN); + strncpy(cpi->hba_vid, "LSILogic", HBA_IDLEN); strncpy(cpi->dev_name, cam_sim_name(sim), DEV_IDLEN); cpi->unit_number = cam_sim_unit(sim); cpi->bus_id = cam_sim_bus(sim); @@ -1008,7 +1005,7 @@ mprsas_action(struct cam_sim *sim, union ccb *ccb) */ cpi->maxio = 256 * 1024; #endif - mprsas_set_ccbstatus(ccb, CAM_REQ_CMP); + cpi->ccb_h.status = CAM_REQ_CMP; break; } case XPT_GET_TRAN_SETTINGS: @@ -1027,7 +1024,7 @@ mprsas_action(struct cam_sim *sim, union ccb *ccb) cts->ccb_h.target_id)); targ = &sassc->targets[cts->ccb_h.target_id]; if (targ->handle == 0x0) { - mprsas_set_ccbstatus(ccb, CAM_DEV_NOT_THERE); + cts->ccb_h.status = CAM_DEV_NOT_THERE; break; } @@ -1057,12 +1054,12 @@ mprsas_action(struct cam_sim *sim, union ccb *ccb) scsi->valid = CTS_SCSI_VALID_TQ; scsi->flags = CTS_SCSI_FLAGS_TAG_ENB; - mprsas_set_ccbstatus(ccb, CAM_REQ_CMP); + cts->ccb_h.status = CAM_REQ_CMP; break; } case XPT_CALC_GEOMETRY: cam_calc_geometry(&ccb->ccg, /*extended*/1); - mprsas_set_ccbstatus(ccb, CAM_REQ_CMP); + ccb->ccb_h.status = CAM_REQ_CMP; break; case XPT_RESET_DEV: mpr_dprint(sassc->sc, MPR_XINFO, @@ -1074,7 +1071,7 @@ mprsas_action(struct cam_sim *sim, union ccb *ccb) case XPT_TERM_IO: mpr_dprint(sassc->sc, MPR_XINFO, "mprsas_action faking success for abort or reset\n"); - mprsas_set_ccbstatus(ccb, CAM_REQ_CMP); + ccb->ccb_h.status = CAM_REQ_CMP; break; case XPT_SCSI_IO: mprsas_action_scsiio(sassc, ccb); @@ -1085,7 +1082,7 @@ mprsas_action(struct cam_sim *sim, union ccb *ccb) return; #endif default: - mprsas_set_ccbstatus(ccb, CAM_FUNC_NOTAVAIL); + ccb->ccb_h.status = CAM_FUNC_NOTAVAIL; break; } xpt_done(ccb); @@ -1105,7 +1102,7 @@ mprsas_announce_reset(struct mpr_softc *sc, uint32_t ac_code, if (xpt_create_path(&path, NULL, path_id, target_id, lun_id) != CAM_REQ_CMP) { mpr_dprint(sc, MPR_ERROR, "unable to create path for reset " - "notification\n"); + "notification\n"); return; } @@ -1134,8 +1131,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; } @@ -1148,14 +1145,6 @@ mprsas_complete_all_commands(struct mpr_softc *sc) completed = 1; } - if (cm->cm_sc->io_cmds_active != 0) { - cm->cm_sc->io_cmds_active--; - } else { - mpr_dprint(cm->cm_sc, MPR_INFO, "Warning: " - "io_cmds_active is out of sync - resynching to " - "0\n"); - } - if ((completed == 0) && (cm->cm_state != MPR_CM_STATE_FREE)) { /* this should never happen, but if it does, log */ mprsas_log_command(cm, MPR_RECOVERY, @@ -1191,8 +1180,9 @@ mprsas_handle_reinit(struct mpr_softc *sc) /* complete and cleanup after all outstanding commands */ mprsas_complete_all_commands(sc); - mpr_dprint(sc, MPR_INIT, "%s startup %u after command completion\n", - __func__, sc->sassc->startup_refcount); + mpr_dprint(sc, MPR_INIT, "%s startup %u tm %u after command " + "completion\n", __func__, sc->sassc->startup_refcount, + sc->sassc->tm_count); /* zero all the target handles, since they may change after the * reset, and we have to rediscover all the targets and use the new @@ -1254,6 +1244,7 @@ mprsas_logical_unit_reset_complete(struct mpr_softc *sc, "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->flags &= ~MPRSAS_TARGET_INRESET; targ->tm = NULL; mprsas_free_tm(sc, tm); } @@ -1331,8 +1322,8 @@ mprsas_target_reset_complete(struct mpr_softc *sc, struct mpr_command *tm) * task management commands don't have S/G lists. */ if ((tm->cm_flags & MPR_CM_FLAGS_ERROR_MASK) != 0) { - mpr_dprint(sc, MPR_ERROR, "%s: cm_flags = %#x for target " - "reset! This should not happen!\n", __func__, tm->cm_flags); + mpr_dprint(sc, MPR_ERROR,"%s: cm_flags = %#x for target reset! " + "This should not happen!\n", __func__, tm->cm_flags); mprsas_free_tm(sc, tm); return; } @@ -1342,6 +1333,7 @@ mprsas_target_reset_complete(struct mpr_softc *sc, struct mpr_command *tm) "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->flags &= ~MPRSAS_TARGET_INRESET; targ->tm = NULL; mprsas_free_tm(sc, tm); } @@ -1357,6 +1349,8 @@ mprsas_target_reset_complete(struct mpr_softc *sc, struct mpr_command *tm) le16toh(reply->IOCStatus), le32toh(reply->ResponseCode), le32toh(reply->TerminationCount)); + targ->flags &= ~MPRSAS_TARGET_INRESET; + if (targ->outstanding == 0) { /* we've finished recovery for this target and all * of its logical units. @@ -1384,7 +1378,7 @@ mprsas_target_reset_complete(struct mpr_softc *sc, struct mpr_command *tm) #define MPR_RESET_TIMEOUT 30 -int +static int mprsas_send_reset(struct mpr_softc *sc, struct mpr_command *tm, uint8_t type) { MPI2_SCSI_TASK_MANAGE_REQUEST *req; @@ -1393,8 +1387,8 @@ mprsas_send_reset(struct mpr_softc *sc, struct mpr_command *tm, uint8_t type) target = tm->cm_targ; if (target->handle == 0) { - mpr_dprint(sc, MPR_ERROR, "%s null devhandle for target_id " - "%d\n", __func__, target->tid); + mpr_dprint(sc, MPR_ERROR,"%s null devhandle for target_id %d\n", + __func__, target->tid); return -1; } @@ -1410,7 +1404,6 @@ mprsas_send_reset(struct mpr_softc *sc, struct mpr_command *tm, uint8_t type) mprsas_log_command(tm, MPR_RECOVERY|MPR_INFO, "sending logical unit reset\n"); tm->cm_complete = mprsas_logical_unit_reset_complete; - mprsas_prepare_for_tm(sc, tm, target, tm->cm_lun); } else if (type == MPI2_SCSITASKMGMT_TASKTYPE_TARGET_RESET) { /* @@ -1419,20 +1412,20 @@ mprsas_send_reset(struct mpr_softc *sc, struct mpr_command *tm, uint8_t type) */ req->MsgFlags = MPI2_SCSITASKMGMT_MSGFLAGS_LINK_RESET; tm->cm_targ->target_resets++; + tm->cm_targ->flags |= MPRSAS_TARGET_INRESET; mprsas_log_command(tm, MPR_RECOVERY|MPR_INFO, "sending target reset\n"); tm->cm_complete = mprsas_target_reset_complete; - mprsas_prepare_for_tm(sc, tm, target, CAM_LUN_WILDCARD); } else { mpr_dprint(sc, MPR_ERROR, "unexpected reset type 0x%x\n", type); return -1; } - mpr_dprint(sc, MPR_INFO, "to target %u handle 0x%04x\n", target->tid, + mpr_dprint(sc, MPR_XINFO, "to target %u handle 0x%04x\n", target->tid, target->handle); if (target->encl_level_valid) { - mpr_dprint(sc, MPR_INFO, "At enclosure level %d, slot %d, " + mpr_dprint(sc, MPR_XINFO, "At enclosure level %d, slot %d, " "connector name (%4s)\n", target->encl_level, target->encl_slot, target->connector_name); } @@ -1448,7 +1441,8 @@ mprsas_send_reset(struct mpr_softc *sc, struct mpr_command *tm, uint8_t type) err = mpr_map_command(sc, tm); if (err) mprsas_log_command(tm, MPR_RECOVERY, - "error %d sending reset type %u\n", err, type); + "error %d sending reset type %u\n", + err, type); return err; } @@ -1579,10 +1573,6 @@ mprsas_send_abort(struct mpr_softc *sc, struct mpr_command *tm, targ->aborts++; - mpr_dprint(sc, MPR_INFO, "Sending reset from %s for target ID %d\n", - __func__, targ->tid); - mprsas_prepare_for_tm(sc, tm, targ, tm->cm_lun); - err = mpr_map_command(sc, tm); if (err) mprsas_log_command(tm, MPR_RECOVERY, @@ -1591,6 +1581,7 @@ mprsas_send_abort(struct mpr_softc *sc, struct mpr_command *tm, return err; } + static void mprsas_scsiio_timeout(void *data) { @@ -1626,11 +1617,11 @@ mprsas_scsiio_timeout(void *data) targ = cm->cm_targ; targ->timeouts++; - mprsas_log_command(cm, MPR_ERROR, "command timeout cm %p ccb %p " + mprsas_log_command(cm, MPR_XINFO, "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, " + mpr_dprint(sc, MPR_XINFO, "At enclosure level %d, slot %d, " "connector name (%4s)\n", targ->encl_level, targ->encl_slot, targ->connector_name); } @@ -1638,7 +1629,8 @@ mprsas_scsiio_timeout(void *data) /* XXX first, check the firmware state, to see if it's still * operational. if not, do a diag reset. */ - mprsas_set_ccbstatus(cm->cm_ccb, CAM_CMD_TIMEOUT); + + cm->cm_ccb->ccb_h.status = CAM_CMD_TIMEOUT; cm->cm_state = MPR_CM_STATE_TIMEDOUT; TAILQ_INSERT_TAIL(&targ->timedout_commands, cm, cm_recovery); @@ -1689,22 +1681,19 @@ mprsas_action_scsiio(struct mprsas_softc *sassc, union ccb *ccb) mtx_assert(&sc->mpr_mtx, MA_OWNED); csio = &ccb->csio; - KASSERT(csio->ccb_h.target_id < sassc->maxtargets, - ("Target %d out of bounds in XPT_SCSI_IO\n", - csio->ccb_h.target_id)); targ = &sassc->targets[csio->ccb_h.target_id]; mpr_dprint(sc, MPR_TRACE, "ccb %p target flag %x\n", ccb, targ->flags); if (targ->handle == 0x0) { mpr_dprint(sc, MPR_ERROR, "%s NULL handle for target %u\n", __func__, csio->ccb_h.target_id); - mprsas_set_ccbstatus(ccb, CAM_DEV_NOT_THERE); + csio->ccb_h.status = CAM_DEV_NOT_THERE; xpt_done(ccb); return; } if (targ->flags & MPR_TARGET_FLAGS_RAID_COMPONENT) { - mpr_dprint(sc, MPR_ERROR, "%s Raid component no SCSI IO " + mpr_dprint(sc, MPR_TRACE, "%s Raid component no SCSI IO " "supported %u\n", __func__, csio->ccb_h.target_id); - mprsas_set_ccbstatus(ccb, CAM_DEV_NOT_THERE); + csio->ccb_h.status = CAM_DEV_NOT_THERE; xpt_done(ccb); return; } @@ -1713,7 +1702,7 @@ mprsas_action_scsiio(struct mprsas_softc *sassc, union ccb *ccb) * Progress" and was actually aborted by the upper layer. Check for * this here and complete the command without error. */ - if (mprsas_get_ccbstatus(ccb) != CAM_REQ_INPROG) { + if (ccb->ccb_h.status != CAM_REQ_INPROG) { mpr_dprint(sc, MPR_TRACE, "%s Command is not in progress for " "target %u\n", __func__, csio->ccb_h.target_id); xpt_done(ccb); @@ -1726,29 +1715,16 @@ mprsas_action_scsiio(struct mprsas_softc *sassc, union ccb *ccb) */ if (targ->flags & MPRSAS_TARGET_INREMOVAL) { if (targ->devinfo == 0) - mprsas_set_ccbstatus(ccb, CAM_REQ_CMP); + csio->ccb_h.status = CAM_REQ_CMP; else - mprsas_set_ccbstatus(ccb, CAM_SEL_TIMEOUT); + csio->ccb_h.status = CAM_SEL_TIMEOUT; xpt_done(ccb); return; } if ((sc->mpr_flags & MPR_FLAGS_SHUTDOWN) != 0) { - mpr_dprint(sc, MPR_INFO, "%s shutting down\n", __func__); - mprsas_set_ccbstatus(ccb, CAM_DEV_NOT_THERE); - xpt_done(ccb); - return; - } - - /* - * If target has a reset in progress, freeze the devq and return. The - * devq will be released when the TM reset is finished. - */ - if (targ->flags & MPRSAS_TARGET_INRESET) { - ccb->ccb_h.status = CAM_BUSY | CAM_DEV_QFRZN; - mpr_dprint(sc, MPR_INFO, "%s: Freezing devq for target ID %d\n", - __func__, targ->tid); - xpt_freeze_devq(ccb->ccb_h.path, 1); + mpr_dprint(sc, MPR_TRACE, "%s shutting down\n", __func__); + csio->ccb_h.status = CAM_DEV_NOT_THERE; xpt_done(ccb); return; } @@ -1831,7 +1807,7 @@ mprsas_action_scsiio(struct mprsas_softc *sassc, union ccb *ccb) if (MPR_SET_LUN(req->LUN, csio->ccb_h.target_lun) != 0) { mpr_free_command(sc, cm); - mprsas_set_ccbstatus(ccb, CAM_LUN_INVALID); + ccb->ccb_h.status = CAM_LUN_INVALID; xpt_done(ccb); return; } @@ -1928,7 +1904,7 @@ mprsas_action_scsiio(struct mprsas_softc *sassc, union ccb *ccb) } callout_reset_sbt(&cm->cm_callout, SBT_1MS * ccb->ccb_h.timeout, 0, - mprsas_scsiio_timeout, cm, 0); + mprsas_scsiio_timeout, cm, 0); targ->issued++; targ->outstanding++; @@ -2126,7 +2102,7 @@ mpr_sc_failed_io_info(struct mpr_softc *sc, struct ccb_scsiio *csio, desc_scsi_state, scsi_state); if (sc->mpr_debug & MPR_XINFO && - scsi_state & MPI2_SCSI_STATE_AUTOSENSE_VALID) { + scsi_state & MPI2_SCSI_STATE_AUTOSENSE_VALID) { mpr_dprint(sc, MPR_XINFO, "-> Sense Buffer Data : Start :\n"); scsi_sense_print(csio); mpr_dprint(sc, MPR_XINFO, "-> Sense Buffer Data : End :\n"); @@ -2150,8 +2126,6 @@ mprsas_scsiio_complete(struct mpr_softc *sc, struct mpr_command *cm) u8 *TLR_bits, TLR_on; int dir = 0, i; u16 alloc_len; - struct mprsas_target *target; - target_id_t target_id; MPR_FUNCTRACE(sc); mpr_dprint(sc, MPR_TRACE, @@ -2165,7 +2139,6 @@ mprsas_scsiio_complete(struct mpr_softc *sc, struct mpr_command *cm) sassc = sc->sassc; ccb = cm->cm_complete_data; csio = &ccb->csio; - target_id = csio->ccb_h.target_id; rep = (MPI2_SCSI_IO_REPLY *)cm->cm_reply; /* * XXX KDM if the chain allocation fails, does it matter if we do @@ -2224,7 +2197,7 @@ mprsas_scsiio_complete(struct mpr_softc *sc, struct mpr_command *cm) * because there can be no reply when we haven't actually * gone out to the hardware. */ - mprsas_set_ccbstatus(ccb, CAM_REQUEUE_REQ); + ccb->ccb_h.status = CAM_REQUEUE_REQ; /* * Currently the only error included in the mask is @@ -2241,7 +2214,7 @@ mprsas_scsiio_complete(struct mpr_softc *sc, struct mpr_command *cm) xpt_freeze_simq(sassc->sim, 1); sassc->flags |= MPRSAS_QUEUE_FROZEN; mpr_dprint(sc, MPR_INFO, "Error sending command, " - "freezing SIM queue\n"); + "freezing SIM queue\n"); } } @@ -2251,7 +2224,7 @@ mprsas_scsiio_complete(struct mpr_softc *sc, struct mpr_command *cm) * commands that were sent. All SSU commands should be completed before * shutdown completes, meaning SSU_refcount will be 0 after SSU_started * is TRUE. - */ + */ if (sc->SSU_started && (csio->cdb_io.cdb_bytes[0] == START_STOP_UNIT)) { mpr_dprint(sc, MPR_INFO, "Decrementing SSU count.\n"); sc->SSU_refcount--; @@ -2259,12 +2232,12 @@ mprsas_scsiio_complete(struct mpr_softc *sc, struct mpr_command *cm) /* Take the fast path to completion */ if (cm->cm_reply == NULL) { - if (mprsas_get_ccbstatus(ccb) == CAM_REQ_INPROG) { + if ((ccb->ccb_h.status & CAM_STATUS_MASK) == CAM_REQ_INPROG) { if ((sc->mpr_flags & MPR_FLAGS_DIAGRESET) != 0) - mprsas_set_ccbstatus(ccb, CAM_SCSI_BUS_RESET); + ccb->ccb_h.status = CAM_SCSI_BUS_RESET; else { - mprsas_set_ccbstatus(ccb, CAM_REQ_CMP); - csio->scsi_status = SCSI_STATUS_OK; + ccb->ccb_h.status = CAM_REQ_CMP; + ccb->csio.scsi_status = SCSI_STATUS_OK; } if (sassc->flags & MPRSAS_QUEUE_FROZEN) { ccb->ccb_h.status |= CAM_RELEASE_SIMQ; @@ -2279,10 +2252,10 @@ mprsas_scsiio_complete(struct mpr_softc *sc, struct mpr_command *cm) * CAM_REQ_CMP. The first is if MPR_CM_FLAGS_ERROR_MASK is * set, the second is in the MPR_FLAGS_DIAGRESET above. */ - if (mprsas_get_ccbstatus(ccb) != CAM_REQ_CMP) { + if ((ccb->ccb_h.status & CAM_STATUS_MASK) != CAM_REQ_CMP) { /* * Freeze the dev queue so that commands are - * executed in the correct order after error + * executed in the correct order with after error * recovery. */ ccb->ccb_h.status |= CAM_DEV_QFRZN; @@ -2312,7 +2285,7 @@ mprsas_scsiio_complete(struct mpr_softc *sc, struct mpr_command *cm) /* Completion failed at the transport level. */ if (rep->SCSIState & (MPI2_SCSI_STATE_NO_SCSI_STATUS | MPI2_SCSI_STATE_TERMINATED)) { - mprsas_set_ccbstatus(ccb, CAM_REQ_CMP_ERR); + ccb->ccb_h.status = CAM_REQ_CMP_ERR; break; } @@ -2321,7 +2294,7 @@ mprsas_scsiio_complete(struct mpr_softc *sc, struct mpr_command *cm) * recover the command. */ if (rep->SCSIState & MPI2_SCSI_STATE_AUTOSENSE_FAILED) { - mprsas_set_ccbstatus(ccb, CAM_AUTOSENSE_FAIL); + ccb->ccb_h.status = CAM_AUTOSENSE_FAIL; break; } @@ -2333,7 +2306,7 @@ mprsas_scsiio_complete(struct mpr_softc *sc, struct mpr_command *cm) if ((rep->SCSIState & MPI2_SCSI_STATE_RESPONSE_INFO_VALID) && ((le32toh(rep->ResponseInfo) & MPI2_SCSI_RI_MASK_REASONCODE) == MPR_SCSI_RI_INVALID_FRAME)) { - sc->mapping_table[target_id].TLR_bits = + sc->mapping_table[csio->ccb_h.target_id].TLR_bits = (u8)MPI2_SCSIIO_CONTROL_NO_TLR; } @@ -2345,16 +2318,16 @@ mprsas_scsiio_complete(struct mpr_softc *sc, struct mpr_command *cm) */ if ((rep->SCSIStatus == MPI2_SCSI_STATUS_COMMAND_TERMINATED) || (rep->SCSIStatus == MPI2_SCSI_STATUS_TASK_ABORTED)) { - mprsas_set_ccbstatus(ccb, CAM_REQ_ABORTED); + ccb->ccb_h.status = CAM_REQ_ABORTED; break; } /* Handle normal status and sense */ csio->scsi_status = rep->SCSIStatus; if (rep->SCSIStatus == MPI2_SCSI_STATUS_GOOD) - mprsas_set_ccbstatus(ccb, CAM_REQ_CMP); + ccb->ccb_h.status = CAM_REQ_CMP; else - mprsas_set_ccbstatus(ccb, CAM_SCSI_STATUS_ERROR); + ccb->ccb_h.status = CAM_SCSI_STATUS_ERROR; if (rep->SCSIState & MPI2_SCSI_STATE_AUTOSENSE_VALID) { int sense_len, returned_sense_len; @@ -2389,11 +2362,12 @@ mprsas_scsiio_complete(struct mpr_softc *sc, struct mpr_command *cm) (csio->data_ptr != NULL) && ((csio->data_ptr[0] & 0x1f) == T_SEQUENTIAL) && (sc->control_TLR) && - (sc->mapping_table[target_id].device_info & + (sc->mapping_table[csio->ccb_h.target_id].device_info & MPI2_SAS_DEVICE_INFO_SSP_TARGET)) { vpd_list = (struct scsi_vpd_supported_page_list *) csio->data_ptr; - TLR_bits = &sc->mapping_table[target_id].TLR_bits; + TLR_bits = &sc->mapping_table[csio->ccb_h.target_id]. + TLR_bits; *TLR_bits = (u8)MPI2_SCSIIO_CONTROL_NO_TLR; TLR_on = (u8)MPI2_SCSIIO_CONTROL_TLR_ON; alloc_len = ((u16)csio->cdb_io.cdb_bytes[3] << 8) + @@ -2406,24 +2380,6 @@ mprsas_scsiio_complete(struct mpr_softc *sc, struct mpr_command *cm) } } } - - /* - * If this is a SATA direct-access end device, mark it so that - * a SCSI StartStopUnit command will be sent to it when the - * driver is being shutdown. - */ - if ((csio->cdb_io.cdb_bytes[0] == INQUIRY) && - ((csio->data_ptr[0] & 0x1f) == T_DIRECT) && - (sc->mapping_table[target_id].device_info & - MPI2_SAS_DEVICE_INFO_SATA_DEVICE) && - ((sc->mapping_table[target_id].device_info & - MPI2_SAS_DEVICE_INFO_MASK_DEVICE_TYPE) == - MPI2_SAS_DEVICE_INFO_END_DEVICE)) { - target = &sassc->targets[target_id]; - target->supports_SSU = TRUE; - mpr_dprint(sc, MPR_XINFO, "Target %d supports SSU\n", - target_id); - } break; case MPI2_IOCSTATUS_SCSI_INVALID_DEVHANDLE: case MPI2_IOCSTATUS_SCSI_DEVICE_NOT_THERE: @@ -2434,13 +2390,13 @@ mprsas_scsiio_complete(struct mpr_softc *sc, struct mpr_command *cm) * failed. */ if (cm->cm_targ->devinfo == 0) - mprsas_set_ccbstatus(ccb, CAM_REQ_CMP); + ccb->ccb_h.status = CAM_REQ_CMP; else - mprsas_set_ccbstatus(ccb, CAM_DEV_NOT_THERE); + ccb->ccb_h.status = CAM_DEV_NOT_THERE; break; case MPI2_IOCSTATUS_INVALID_SGL: mpr_print_scsiio_cmd(sc, cm); - mprsas_set_ccbstatus(ccb, CAM_UNREC_HBA_ERROR); + ccb->ccb_h.status = CAM_UNREC_HBA_ERROR; break; case MPI2_IOCSTATUS_SCSI_TASK_TERMINATED: /* @@ -2453,14 +2409,14 @@ mprsas_scsiio_complete(struct mpr_softc *sc, struct mpr_command *cm) * on the console. */ if (cm->cm_state == MPR_CM_STATE_TIMEDOUT) - mprsas_set_ccbstatus(ccb, CAM_CMD_TIMEOUT); + ccb->ccb_h.status = CAM_CMD_TIMEOUT; else - mprsas_set_ccbstatus(ccb, CAM_REQ_ABORTED); + ccb->ccb_h.status = CAM_REQ_ABORTED; break; case MPI2_IOCSTATUS_SCSI_DATA_OVERRUN: /* resid is ignored for this condition */ csio->resid = 0; - mprsas_set_ccbstatus(ccb, CAM_DATA_RUN_ERR); + ccb->ccb_h.status = CAM_DATA_RUN_ERR; break; case MPI2_IOCSTATUS_SCSI_IOC_TERMINATED: case MPI2_IOCSTATUS_SCSI_EXT_TERMINATED: @@ -2469,7 +2425,7 @@ mprsas_scsiio_complete(struct mpr_softc *sc, struct mpr_command *cm) * transient transport-related) errors, retry these without * decrementing the retry count. */ - mprsas_set_ccbstatus(ccb, CAM_REQUEUE_REQ); + ccb->ccb_h.status = CAM_REQUEUE_REQ; mprsas_log_command(cm, MPR_INFO, "terminated ioc %x scsi %x state %x xfer %u\n", le16toh(rep->IOCStatus), rep->SCSIStatus, rep->SCSIState, @@ -2491,7 +2447,7 @@ mprsas_scsiio_complete(struct mpr_softc *sc, struct mpr_command *cm) le16toh(rep->IOCStatus), rep->SCSIStatus, rep->SCSIState, le32toh(rep->TransferCount)); csio->resid = cm->cm_length; - mprsas_set_ccbstatus(ccb, CAM_REQ_CMP_ERR); + ccb->ccb_h.status = CAM_REQ_CMP_ERR; break; } @@ -2504,7 +2460,7 @@ mprsas_scsiio_complete(struct mpr_softc *sc, struct mpr_command *cm) "queue\n"); } - if (mprsas_get_ccbstatus(ccb) != CAM_REQ_CMP) { + if ((ccb->ccb_h.status & CAM_STATUS_MASK) != CAM_REQ_CMP) { ccb->ccb_h.status |= CAM_DEV_QFRZN; xpt_freeze_devq(ccb->ccb_h.path, /*count*/ 1); } @@ -2531,16 +2487,16 @@ mprsas_smpio_complete(struct mpr_softc *sc, struct mpr_command *cm) * in the standard request size. */ if ((cm->cm_flags & MPR_CM_FLAGS_ERROR_MASK) != 0) { - mpr_dprint(sc, MPR_ERROR, "%s: cm_flags = %#x on SMP " - "request!\n", __func__, cm->cm_flags); - mprsas_set_ccbstatus(ccb, CAM_REQ_CMP_ERR); + mpr_dprint(sc, MPR_ERROR,"%s: cm_flags = %#x on SMP request!\n", + __func__, cm->cm_flags); + ccb->ccb_h.status = CAM_REQ_CMP_ERR; goto bailout; } rpl = (MPI2_SMP_PASSTHROUGH_REPLY *)cm->cm_reply; if (rpl == NULL) { mpr_dprint(sc, MPR_ERROR, "%s: NULL cm_reply!\n", __func__); - mprsas_set_ccbstatus(ccb, CAM_REQ_CMP_ERR); + ccb->ccb_h.status = CAM_REQ_CMP_ERR; goto bailout; } @@ -2553,17 +2509,17 @@ mprsas_smpio_complete(struct mpr_softc *sc, struct mpr_command *cm) rpl->SASStatus != MPI2_SASSTATUS_SUCCESS) { mpr_dprint(sc, MPR_XINFO, "%s: IOCStatus %04x SASStatus %02x\n", __func__, le16toh(rpl->IOCStatus), rpl->SASStatus); - mprsas_set_ccbstatus(ccb, CAM_REQ_CMP_ERR); + ccb->ccb_h.status = CAM_REQ_CMP_ERR; goto bailout; } - mpr_dprint(sc, MPR_XINFO, "%s: SMP request to SAS address %#jx " - "completed successfully\n", __func__, (uintmax_t)sasaddr); + mpr_dprint(sc, MPR_XINFO, "%s: SMP request to SAS address " + "%#jx completed successfully\n", __func__, (uintmax_t)sasaddr); if (ccb->smpio.smp_response[2] == SMP_FR_ACCEPTED) - mprsas_set_ccbstatus(ccb, CAM_REQ_CMP); + ccb->ccb_h.status = CAM_REQ_CMP; else - mprsas_set_ccbstatus(ccb, CAM_SMP_STATUS_ERROR); + ccb->ccb_h.status = CAM_SMP_STATUS_ERROR; bailout: /* @@ -2602,7 +2558,7 @@ mprsas_send_smpcmd(struct mprsas_softc *sassc, union ccb *ccb, */ mpr_dprint(sc, MPR_ERROR, "%s: physical addresses not " "supported\n", __func__); - mprsas_set_ccbstatus(ccb, CAM_REQ_INVALID); + ccb->ccb_h.status = CAM_REQ_INVALID; xpt_done(ccb); return; case CAM_DATA_SG: @@ -2615,7 +2571,7 @@ mprsas_send_smpcmd(struct mprsas_softc *sassc, union ccb *ccb, 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); + ccb->ccb_h.status = CAM_REQ_INVALID; xpt_done(ccb); return; } @@ -2649,7 +2605,7 @@ mprsas_send_smpcmd(struct mprsas_softc *sassc, union ccb *ccb, response = ccb->smpio.smp_response; break; default: - mprsas_set_ccbstatus(ccb, CAM_REQ_INVALID); + ccb->ccb_h.status = CAM_REQ_INVALID; xpt_done(ccb); return; } @@ -2658,9 +2614,9 @@ mprsas_send_smpcmd(struct mprsas_softc *sassc, union ccb *ccb, * XXX We don't yet support physical addresses here. */ if (ccb->ccb_h.flags & (CAM_DATA_PHYS|CAM_SG_LIST_PHYS)) { - mpr_dprint(sc, MPR_ERROR, "%s: physical addresses not " - "supported\n", __func__); - mprsas_set_ccbstatus(ccb, CAM_REQ_INVALID); + mpr_printf(sc, "%s: physical addresses not supported\n", + __func__); + ccb->ccb_h.status = CAM_REQ_INVALID; xpt_done(ccb); return; } @@ -2679,7 +2635,7 @@ mprsas_send_smpcmd(struct mprsas_softc *sassc, union ccb *ccb, 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); + ccb->ccb_h.status = CAM_REQ_INVALID; xpt_done(ccb); return; } @@ -2717,7 +2673,7 @@ mprsas_send_smpcmd(struct mprsas_softc *sassc, union ccb *ccb, if (cm == NULL) { mpr_dprint(sc, MPR_ERROR, "%s: cannot allocate command\n", __func__); - mprsas_set_ccbstatus(ccb, CAM_RESRC_UNAVAIL); + ccb->ccb_h.status = CAM_RESRC_UNAVAIL; xpt_done(ccb); return; } @@ -2804,7 +2760,7 @@ mprsas_send_smpcmd(struct mprsas_softc *sassc, union ccb *ccb, bailout_error: mpr_free_command(sc, cm); - mprsas_set_ccbstatus(ccb, CAM_RESRC_UNAVAIL); + ccb->ccb_h.status = CAM_RESRC_UNAVAIL; xpt_done(ccb); return; } @@ -2827,7 +2783,7 @@ mprsas_action_smpio(struct mprsas_softc *sassc, union ccb *ccb) if (targ->handle == 0x0) { mpr_dprint(sc, MPR_ERROR, "%s: target %d does not exist!\n", __func__, ccb->ccb_h.target_id); - mprsas_set_ccbstatus(ccb, CAM_SEL_TIMEOUT); + ccb->ccb_h.status = CAM_SEL_TIMEOUT; xpt_done(ccb); return; } @@ -2875,7 +2831,7 @@ mprsas_action_smpio(struct mprsas_softc *sassc, union ccb *ccb) if (targ->parent_handle == 0x0) { mpr_dprint(sc, MPR_ERROR, "%s: handle %d does not have " "a valid parent handle!\n", __func__, targ->handle); - mprsas_set_ccbstatus(ccb, CAM_DEV_NOT_THERE); + ccb->ccb_h.status = CAM_DEV_NOT_THERE; goto bailout; } #ifdef OLD_MPR_PROBE @@ -2885,7 +2841,7 @@ mprsas_action_smpio(struct mprsas_softc *sassc, union ccb *ccb) if (parent_target == NULL) { mpr_dprint(sc, MPR_ERROR, "%s: handle %d does not have " "a valid parent target!\n", __func__, targ->handle); - mprsas_set_ccbstatus(ccb, CAM_DEV_NOT_THERE); + ccb->ccb_h.status = CAM_DEV_NOT_THERE; goto bailout; } @@ -2894,8 +2850,9 @@ mprsas_action_smpio(struct mprsas_softc *sassc, union ccb *ccb) mpr_dprint(sc, MPR_ERROR, "%s: handle %d parent %d " "does not have an SMP target!\n", __func__, targ->handle, parent_target->handle); - mprsas_set_ccbstatus(ccb, CAM_DEV_NOT_THERE); + ccb->ccb_h.status = CAM_DEV_NOT_THERE; goto bailout; + } sasaddr = parent_target->sasaddr; @@ -2905,7 +2862,7 @@ mprsas_action_smpio(struct mprsas_softc *sassc, union ccb *ccb) mpr_dprint(sc, MPR_ERROR, "%s: handle %d parent %d " "does not have an SMP target!\n", __func__, targ->handle, targ->parent_handle); - mprsas_set_ccbstatus(ccb, CAM_DEV_NOT_THERE); + ccb->ccb_h.status = CAM_DEV_NOT_THERE; goto bailout; } @@ -2913,7 +2870,7 @@ mprsas_action_smpio(struct mprsas_softc *sassc, union ccb *ccb) mpr_dprint(sc, MPR_ERROR, "%s: handle %d parent handle " "%d does not have a valid SAS address!\n", __func__, targ->handle, targ->parent_handle); - mprsas_set_ccbstatus(ccb, CAM_DEV_NOT_THERE); + ccb->ccb_h.status = CAM_DEV_NOT_THERE; goto bailout; } @@ -2925,7 +2882,7 @@ mprsas_action_smpio(struct mprsas_softc *sassc, union ccb *ccb) if (sasaddr == 0) { mpr_dprint(sc, MPR_INFO, "%s: unable to find SAS address for " "handle %d\n", __func__, targ->handle); - mprsas_set_ccbstatus(ccb, CAM_DEV_NOT_THERE); + ccb->ccb_h.status = CAM_DEV_NOT_THERE; goto bailout; } mprsas_send_smpcmd(sassc, ccb, sasaddr); @@ -2957,7 +2914,7 @@ mprsas_action_resetdev(struct mprsas_softc *sassc, union ccb *ccb) if (tm == NULL) { mpr_dprint(sc, MPR_ERROR, "command alloc failure in mprsas_action_resetdev\n"); - mprsas_set_ccbstatus(ccb, CAM_RESRC_UNAVAIL); + ccb->ccb_h.status = CAM_RESRC_UNAVAIL; xpt_done(ccb); return; } @@ -2976,12 +2933,7 @@ mprsas_action_resetdev(struct mprsas_softc *sassc, union ccb *ccb) MPI2_REQ_DESCRIPT_FLAGS_HIGH_PRIORITY; tm->cm_complete = mprsas_resetdev_complete; tm->cm_complete_data = ccb; - - mpr_dprint(sc, MPR_INFO, "%s: Sending reset for target ID %d\n", - __func__, targ->tid); tm->cm_targ = targ; - targ->flags |= MPRSAS_TARGET_INRESET; - mpr_map_command(sc, tm); } @@ -3010,7 +2962,7 @@ mprsas_resetdev_complete(struct mpr_softc *sc, struct mpr_command *tm) mpr_dprint(sc, MPR_ERROR, "%s: cm_flags = %#x for reset of " "handle %#04x! This should not happen!\n", __func__, tm->cm_flags, req->DevHandle); - mprsas_set_ccbstatus(ccb, CAM_REQ_CMP_ERR); + ccb->ccb_h.status = CAM_REQ_CMP_ERR; goto bailout; } @@ -3019,12 +2971,12 @@ mprsas_resetdev_complete(struct mpr_softc *sc, struct mpr_command *tm) le16toh(resp->IOCStatus), le32toh(resp->ResponseCode)); if (le32toh(resp->ResponseCode) == MPI2_SCSITASKMGMT_RSP_TM_COMPLETE) { - mprsas_set_ccbstatus(ccb, CAM_REQ_CMP); + ccb->ccb_h.status = CAM_REQ_CMP; mprsas_announce_reset(sc, AC_SENT_BDR, tm->cm_targ->tid, CAM_LUN_WILDCARD); } else - mprsas_set_ccbstatus(ccb, CAM_REQ_CMP_ERR); + ccb->ccb_h.status = CAM_REQ_CMP_ERR; bailout: @@ -3043,8 +2995,7 @@ mprsas_poll(struct cam_sim *sim) /* frequent debug messages during a panic just slow * everything down too much. */ - mpr_dprint(sassc->sc, MPR_XINFO, "%s clearing MPR_TRACE\n", - __func__); + mpr_printf(sassc->sc, "%s clearing MPR_TRACE\n", __func__); sassc->sc->mpr_debug &= ~MPR_TRACE; } @@ -3143,7 +3094,7 @@ mprsas_async(void *callback_arg, uint32_t code, struct cam_path *path, if ((cdai.ccb_h.status & CAM_DEV_QFRZN) != 0) cam_release_devq(cdai.ccb_h.path, 0, 0, 0, FALSE); - if ((mprsas_get_ccbstatus((union ccb *)&cdai) == CAM_REQ_CMP) + if (((cdai.ccb_h.status & CAM_STATUS_MASK) == CAM_REQ_CMP) && (rcap_buf.prot & SRC16_PROT_EN)) { lun->eedp_formatted = TRUE; lun->eedp_block_size = scsi_4btoul(rcap_buf.length); @@ -3170,6 +3121,8 @@ mprsas_async(void *callback_arg, uint32_t code, struct cam_path *path, #endif cgd = arg; + mprsas_prepare_ssu(sc, path, cgd); + #if (__FreeBSD_version < 901503) || \ ((__FreeBSD_version >= 1000000) && (__FreeBSD_version < 1000006)) mprsas_check_eedp(sc, path, cgd); @@ -3181,6 +3134,64 @@ mprsas_async(void *callback_arg, uint32_t code, struct cam_path *path, } } +static void +mprsas_prepare_ssu(struct mpr_softc *sc, struct cam_path *path, + struct ccb_getdev *cgd) +{ + struct mprsas_softc *sassc = sc->sassc; + path_id_t pathid; + target_id_t targetid; + lun_id_t lunid; + struct mprsas_target *target; + struct mprsas_lun *lun; + uint8_t found_lun; + + sassc = sc->sassc; + pathid = cam_sim_path(sassc->sim); + targetid = xpt_path_target_id(path); + lunid = xpt_path_lun_id(path); + + KASSERT(targetid < sassc->maxtargets, + ("Target %d out of bounds in mprsas_prepare_ssu\n", targetid)); + target = &sassc->targets[targetid]; + if (target->handle == 0x0) + return; + + /* + * If LUN is already in list, don't create a new one. + */ + found_lun = FALSE; + SLIST_FOREACH(lun, &target->luns, lun_link) { + if (lun->lun_id == lunid) { + found_lun = TRUE; + break; + } + } + if (!found_lun) { + lun = malloc(sizeof(struct mprsas_lun), M_MPR, + M_NOWAIT | M_ZERO); + if (lun == NULL) { + mpr_dprint(sc, MPR_ERROR, "Unable to alloc LUN for " + "preparing SSU.\n"); + return; + } + lun->lun_id = lunid; + SLIST_INSERT_HEAD(&target->luns, lun, lun_link); + } + + /* + * If this is a SATA direct-access end device, mark it so that a SCSI + * StartStopUnit command will be sent to it when the driver is being + * shutdown. + */ + if (((cgd->inq_data.device & 0x1F) == T_DIRECT) && + (target->devinfo & MPI2_SAS_DEVICE_INFO_SATA_DEVICE) && + ((target->devinfo & MPI2_SAS_DEVICE_INFO_MASK_DEVICE_TYPE) == + MPI2_SAS_DEVICE_INFO_END_DEVICE)) { + lun->stop_at_shutdown = TRUE; + } +} + #if (__FreeBSD_version < 901503) || \ ((__FreeBSD_version >= 1000000) && (__FreeBSD_version < 1000006)) static void @@ -3201,6 +3212,7 @@ mprsas_check_eedp(struct mpr_softc *sc, struct cam_path *path, uint8_t found_lun; char path_str[64]; + sassc = sc->sassc; pathid = cam_sim_path(sassc->sim); targetid = xpt_path_target_id(path); lunid = xpt_path_lun_id(path); @@ -3276,7 +3288,7 @@ mprsas_check_eedp(struct mpr_softc *sc, struct cam_path *path, rcap_buf = malloc(sizeof(struct scsi_read_capacity_eedp), M_MPR, M_NOWAIT | M_ZERO); if (rcap_buf == NULL) { - mpr_dprint(sc, MPR_ERROR, "Unable to alloc read capacity " + mpr_dprint(sc, MPR_FAULT, "Unable to alloc read capacity " "buffer for EEDP support.\n"); xpt_free_path(ccb->ccb_h.path); xpt_free_ccb(ccb); @@ -3329,7 +3341,7 @@ mprsas_read_cap_done(struct cam_periph *periph, union ccb *done_ccb) xpt_release_devq(done_ccb->ccb_h.path, /*count*/ 1, /*run_queue*/TRUE); } - + rcap_buf = (struct scsi_read_capacity_eedp *)done_ccb->csio.data_ptr; /* @@ -3347,21 +3359,21 @@ mprsas_read_cap_done(struct cam_periph *periph, union ccb *done_ccb) /* * Got the LUN in the target's LUN list. Fill it in with EEDP - * info. If the READ CAP 16 command had some SCSI error (common + * info. If the READ CAP 16 command had some SCSI error (common * if command is not supported), mark the lun as not supporting * EEDP and set the block size to 0. */ - if ((mprsas_get_ccbstatus(done_ccb) != CAM_REQ_CMP) || - (done_ccb->csio.scsi_status != SCSI_STATUS_OK)) { + if (((done_ccb->ccb_h.status & CAM_STATUS_MASK) != CAM_REQ_CMP) + || (done_ccb->csio.scsi_status != SCSI_STATUS_OK)) { lun->eedp_formatted = FALSE; lun->eedp_block_size = 0; break; } if (rcap_buf->protect & 0x01) { - mpr_dprint(sassc->sc, MPR_INFO, "LUN %d for target ID " - "%d is formatted for EEDP support.\n", - done_ccb->ccb_h.target_lun, + mpr_dprint(sassc->sc, MPR_INFO, "LUN %d for " + "target ID %d is formatted for EEDP " + "support.\n", done_ccb->ccb_h.target_lun, done_ccb->ccb_h.target_id); lun->eedp_formatted = TRUE; lun->eedp_block_size = scsi_4btoul(rcap_buf->length); @@ -3377,34 +3389,6 @@ mprsas_read_cap_done(struct cam_periph *periph, union ccb *done_ccb) #endif /* (__FreeBSD_version < 901503) || \ ((__FreeBSD_version >= 1000000) && (__FreeBSD_version < 1000006)) */ -void -mprsas_prepare_for_tm(struct mpr_softc *sc, struct mpr_command *tm, - struct mprsas_target *target, lun_id_t lun_id) -{ - union ccb *ccb; - path_id_t path_id; - - /* - * Set the INRESET flag for this target so that no I/O will be sent to - * the target until the reset has completed. If an I/O request does - * happen, the devq will be frozen. The CCB holds the path which is - * used to release the devq. The devq is released and the CCB is freed - * when the TM completes. - */ - ccb = xpt_alloc_ccb_nowait(); - if (ccb) { - path_id = cam_sim_path(sc->sassc->sim); - if (xpt_create_path(&ccb->ccb_h.path, xpt_periph, path_id, - target->tid, lun_id) != CAM_REQ_CMP) { - xpt_free_ccb(ccb); - } else { - tm->cm_ccb = ccb; - tm->cm_targ = target; - target->flags |= MPRSAS_TARGET_INRESET; - } - } -} - int mprsas_startup(struct mpr_softc *sc) { @@ -3505,33 +3489,3 @@ mprsas_check_id(struct mprsas_softc *sassc, int id) return (0); } - -void -mprsas_realloc_targets(struct mpr_softc *sc, int maxtargets) -{ - struct mprsas_softc *sassc; - struct mprsas_lun *lun, *lun_tmp; - struct mprsas_target *targ; - int i; - - sassc = sc->sassc; - /* - * The number of targets is based on IOC Facts, so free all of - * the allocated LUNs for each target and then the target buffer - * itself. - */ - for (i=0; i< maxtargets; i++) { - targ = &sassc->targets[i]; - SLIST_FOREACH_SAFE(lun, &targ->luns, lun_link, lun_tmp) { - free(lun, M_MPR); - } - } - free(sassc->targets, M_MPR); - - sassc->targets = malloc(sizeof(struct mprsas_target) * maxtargets, - M_MPR, M_WAITOK|M_ZERO); - if (!sassc->targets) { - panic("%s failed to alloc targets with error %d\n", - __func__, ENOMEM); - } -} diff --git a/sys/dev/mpr/mpr_sas.h b/sys/dev/mpr/mpr_sas.h index ebeed30..9d3116a 100644 --- a/sys/dev/mpr/mpr_sas.h +++ b/sys/dev/mpr/mpr_sas.h @@ -1,6 +1,5 @@ /*- - * Copyright (c) 2011-2015 LSI Corp. - * Copyright (c) 2013-2015 Avago Technologies + * Copyright (c) 2011-2014 LSI Corp. * All rights reserved. * * Redistribution and use in source and binary forms, with or without @@ -24,7 +23,7 @@ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF * SUCH DAMAGE. * - * Avago Technologies (LSI) MPT-Fusion Host Adapter FreeBSD + * LSI MPT-Fusion Host Adapter FreeBSD * * $FreeBSD$ */ @@ -36,6 +35,7 @@ struct mprsas_lun { lun_id_t lun_id; uint8_t eedp_formatted; uint32_t eedp_block_size; + uint8_t stop_at_shutdown; }; struct mprsas_target { @@ -55,10 +55,11 @@ struct mprsas_target { #define MPRSAS_TARGET_INREMOVAL (1 << 3) #define MPR_TARGET_FLAGS_RAID_COMPONENT (1 << 4) #define MPR_TARGET_FLAGS_VOLUME (1 << 5) -#define MPR_TARGET_IS_SATA_SSD (1 << 6) #define MPRSAS_TARGET_INRECOVERY (MPRSAS_TARGET_INABORT | \ MPRSAS_TARGET_INRESET | MPRSAS_TARGET_INCHIPRESET) +#define MPRSAS_TARGET_ADD (1 << 29) +#define MPRSAS_TARGET_REMOVE (1 << 30) uint16_t tid; SLIST_HEAD(, mprsas_lun) luns; TAILQ_HEAD(, mpr_command) commands; @@ -81,8 +82,6 @@ struct mprsas_target { unsigned int logical_unit_resets; unsigned int target_resets; uint8_t scsi_req_desc_type; - uint8_t stop_at_shutdown; - uint8_t supports_SSU; }; struct mprsas_softc { @@ -93,6 +92,7 @@ struct mprsas_softc { #define MPRSAS_DISCOVERY_TIMEOUT_PENDING (1 << 2) #define MPRSAS_QUEUE_FROZEN (1 << 3) #define MPRSAS_SHUTDOWN (1 << 4) +#define MPRSAS_SCANTHREAD (1 << 5) u_int maxtargets; struct mprsas_target *targets; struct cam_devq *devq; @@ -103,6 +103,7 @@ struct mprsas_softc { struct mpr_event_handle *mprsas_eh; u_int startup_refcount; + u_int tm_count; struct proc *sysctl_proc; struct taskqueue *ev_tq; @@ -149,19 +150,6 @@ mprsas_set_lun(uint8_t *lun, u_int ccblun) return (0); } -static __inline void -mprsas_set_ccbstatus(union ccb *ccb, int status) -{ - ccb->ccb_h.status &= ~CAM_STATUS_MASK; - ccb->ccb_h.status |= status; -} - -static __inline int -mprsas_get_ccbstatus(union ccb *ccb) -{ - return (ccb->ccb_h.status & CAM_STATUS_MASK); -} - #define MPR_SET_SINGLE_LUN(req, lun) \ do { \ bzero((req)->LUN, 8); \ @@ -170,10 +158,11 @@ do { \ void mprsas_rescan_target(struct mpr_softc *sc, struct mprsas_target *targ); void mprsas_discovery_end(struct mprsas_softc *sassc); -void mprsas_prepare_for_tm(struct mpr_softc *sc, struct mpr_command *tm, - struct mprsas_target *target, lun_id_t lun_id); void mprsas_startup_increment(struct mprsas_softc *sassc); void mprsas_startup_decrement(struct mprsas_softc *sassc); +void mprsas_release_simq_reinit(struct mprsas_softc *sassc); +struct mpr_command * mprsas_alloc_tm(struct mpr_softc *sc); +void mprsas_free_tm(struct mpr_softc *sc, struct mpr_command *tm); void mprsas_firmware_event_work(void *arg, int pending); int mprsas_check_id(struct mprsas_softc *sassc, int id); diff --git a/sys/dev/mpr/mpr_sas_lsi.c b/sys/dev/mpr/mpr_sas_lsi.c index 7d6ef70..32e9b3a 100644 --- a/sys/dev/mpr/mpr_sas_lsi.c +++ b/sys/dev/mpr/mpr_sas_lsi.c @@ -1,6 +1,5 @@ /*- - * Copyright (c) 2011-2015 LSI Corp. - * Copyright (c) 2013-2015 Avago Technologies + * Copyright (c) 2011-2014 LSI Corp. * All rights reserved. * * Redistribution and use in source and binary forms, with or without @@ -24,13 +23,13 @@ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF * SUCH DAMAGE. * - * Avago Technologies (LSI) MPT-Fusion Host Adapter FreeBSD + * LSI MPT-Fusion Host Adapter FreeBSD */ #include <sys/cdefs.h> __FBSDID("$FreeBSD$"); -/* Communications core for LSI MPT3 */ +/* Communications core for LSI MPT2 */ /* TODO Move headers to mprvar */ #include <sys/types.h> @@ -106,9 +105,7 @@ struct _ata_identify_device_data { u16 serial_number[10]; /* 10-19 */ u16 reserved2[7]; /* 20-26 */ u16 model_number[20]; /* 27-46*/ - u16 reserved3[170]; /* 47-216 */ - u16 rotational_speed; /* 217 */ - u16 reserved4[38]; /* 218-255 */ + u16 reserved3[209]; /* 47-255*/ }; static u32 event_count; static void mprsas_fw_work(struct mpr_softc *sc, @@ -119,9 +116,8 @@ static int mprsas_add_device(struct mpr_softc *sc, u16 handle, u8 linkrate); static int mprsas_get_sata_identify(struct mpr_softc *sc, u16 handle, Mpi2SataPassthroughReply_t *mpi_reply, char *id_buffer, int sz, u32 devinfo); -static void mprsas_ata_id_timeout(void *data); int mprsas_get_sas_address_for_sata_disk(struct mpr_softc *sc, - u64 *sas_address, u16 handle, u32 device_info, u8 *is_SATA_SSD); + u64 *sas_address, u16 handle, u32 device_info); static int mprsas_volume_add(struct mpr_softc *sc, u16 handle); static void mprsas_SSU_to_SATA_devices(struct mpr_softc *sc); @@ -329,7 +325,7 @@ mprsas_fw_work(struct mpr_softc *sc, struct mpr_fw_event_work *fw_event) return; } - mpr_dprint(sc, MPR_EVENT, "Sending FP action " + mpr_dprint(sc, MPR_INFO, "Sending FP action " "from " "MPI2_EVENT_IR_CONFIGURATION_CHANGE_LIST " ":\n"); @@ -354,9 +350,9 @@ mprsas_fw_work(struct mpr_softc *sc, struct mpr_fw_event_work *fw_event) if (reply && (le16toh(reply->IOCStatus) & MPI2_IOCSTATUS_MASK) != MPI2_IOCSTATUS_SUCCESS) { - mpr_dprint(sc, MPR_ERROR, "%s: error " - "sending RaidActionPage; " - "iocstatus = 0x%x\n", __func__, + mpr_dprint(sc, MPR_INFO, "%s: error " + "sending RaidActionPage; iocstatus " + "= 0x%x\n", __func__, le16toh(reply->IOCStatus)); } @@ -364,7 +360,7 @@ mprsas_fw_work(struct mpr_softc *sc, struct mpr_fw_event_work *fw_event) mpr_free_command(sc, cm); } skip_fp_send: - mpr_dprint(sc, MPR_EVENT, "Received " + mpr_dprint(sc, MPR_INFO, "Received " "MPI2_EVENT_IR_CONFIGURATION_CHANGE_LIST Reason " "code %x:\n", element->ReasonCode); switch (element->ReasonCode) { @@ -425,6 +421,7 @@ skip_fp_send: break; targ->flags |= MPR_TARGET_FLAGS_RAID_COMPONENT; mprsas_rescan_target(sc, targ); + break; case MPI2_EVENT_IR_CHANGE_RC_PD_DELETED: /* @@ -681,13 +678,14 @@ mprsas_add_device(struct mpr_softc *sc, u16 handle, u8 linkrate){ struct mprsas_target *targ; Mpi2ConfigReply_t mpi_reply; Mpi2SasDevicePage0_t config_page; - uint64_t sas_address, parent_sas_address = 0; + uint64_t sas_address, sata_sas_address; + uint64_t parent_sas_address = 0; + u16 ioc_pg8_flags = le16toh(sc->ioc_pg8.Flags); u32 device_info, parent_devinfo = 0; unsigned int id; - int ret = 1, error = 0, i; + int ret; + int error = 0; struct mprsas_lun *lun; - u8 is_SATA_SSD = 0; - struct mpr_command *cm; sassc = sc->sassc; mprsas_startup_increment(sassc); @@ -719,29 +717,26 @@ mprsas_add_device(struct mpr_softc *sc, u16 handle, u8 linkrate){ } /* TODO Check proper endianess */ sas_address = config_page.SASAddress.High; - sas_address = (sas_address << 32) | config_page.SASAddress.Low; - mpr_dprint(sc, MPR_INFO, "SAS Address from SAS device page0 = %jx\n", - sas_address); - - /* - * Always get SATA Identify information because this is used to - * determine if Start/Stop Unit should be sent to the drive when the - * system is shutdown. - */ - if (device_info & MPI2_SAS_DEVICE_INFO_SATA_DEVICE) { - ret = mprsas_get_sas_address_for_sata_disk(sc, &sas_address, - handle, device_info, &is_SATA_SSD); - if (ret) { - mpr_dprint(sc, MPR_ERROR, "%s: failed to get disk type " - "(SSD or HDD) for SATA device with handle 0x%04x\n", - __func__, handle); - } else { - mpr_dprint(sc, MPR_INFO, "SAS Address from SATA " - "device = %jx\n", sas_address); - } - } + sas_address = (sas_address << 32) | + config_page.SASAddress.Low; + + if ((ioc_pg8_flags & MPI2_IOCPAGE8_FLAGS_MASK_MAPPING_MODE) + == MPI2_IOCPAGE8_FLAGS_DEVICE_PERSISTENCE_MAPPING) { + if (device_info & MPI2_SAS_DEVICE_INFO_SATA_DEVICE) { + ret = mprsas_get_sas_address_for_sata_disk(sc, + &sata_sas_address, handle, device_info); + if (!ret) + id = mpr_mapping_get_sas_id(sc, + sata_sas_address, handle); + else + id = mpr_mapping_get_sas_id(sc, + sas_address, handle); + } else + id = mpr_mapping_get_sas_id(sc, sas_address, + handle); + } else + id = mpr_mapping_get_sas_id(sc, sas_address, handle); - id = mpr_mapping_get_sas_id(sc, sas_address, handle); if (id == MPR_MAP_BAD_ID) { printf("failure at %s:%d/%s()! Could not get ID for device " "with handle 0x%04x\n", __FILE__, __LINE__, __func__, @@ -755,7 +750,7 @@ mprsas_add_device(struct mpr_softc *sc, u16 handle, u8 linkrate){ error = ENXIO; goto out; } - + mpr_dprint(sc, MPR_MAPPING, "SAS Address from SAS device page0 = %jx\n", sas_address); targ = &sassc->targets[id]; @@ -778,9 +773,6 @@ mprsas_add_device(struct mpr_softc *sc, u16 handle, u8 linkrate){ targ->tid = id; targ->linkrate = (linkrate>>4); targ->flags = 0; - if (is_SATA_SSD) { - targ->flags = MPR_TARGET_IS_SATA_SSD; - } if (le16toh(config_page.Flags) & MPI25_SAS_DEVICE0_FLAGS_FAST_PATH_CAPABLE) { targ->scsi_req_desc_type = @@ -800,12 +792,12 @@ mprsas_add_device(struct mpr_softc *sc, u16 handle, u8 linkrate){ SLIST_INIT(&targ->luns); mpr_describe_devinfo(targ->devinfo, devstring, 80); - mpr_dprint(sc, (MPR_INFO|MPR_MAPPING), "Found device <%s> <%s> " + mpr_dprint(sc, (MPR_XINFO|MPR_MAPPING), "Found device <%s> <%s> " "handle<0x%04x> enclosureHandle<0x%04x> slot %d\n", devstring, mpr_describe_table(mpr_linkrate_names, targ->linkrate), targ->handle, targ->encl_handle, targ->encl_slot); if (targ->encl_level_valid) { - mpr_dprint(sc, (MPR_INFO|MPR_MAPPING), "At enclosure level %d " + mpr_dprint(sc, (MPR_XINFO|MPR_MAPPING), "At enclosure level %d " "and connector name (%4s)\n", targ->encl_level, targ->connector_name); } @@ -815,57 +807,15 @@ mprsas_add_device(struct mpr_softc *sc, u16 handle, u8 linkrate){ #endif mprsas_rescan_target(sc, targ); mpr_dprint(sc, MPR_MAPPING, "Target id 0x%x added\n", targ->tid); - - /* - * Check all commands to see if the SATA_ID_TIMEOUT flag has been set. - * If so, send a Target Reset TM to the target that was just created. - * An Abort Task TM should be used instead of a Target Reset, but that - * would be much more difficult because targets have not been fully - * discovered yet, and LUN's haven't been setup. So, just reset the - * target instead of the LUN. - */ - for (i = 1; i < sc->num_reqs; i++) { - cm = &sc->commands[i]; - if (cm->cm_flags & MPR_CM_FLAGS_SATA_ID_TIMEOUT) { - targ->timeouts++; - cm->cm_state = MPR_CM_STATE_TIMEDOUT; - - if ((targ->tm = mprsas_alloc_tm(sc)) != NULL) { - mpr_dprint(sc, MPR_INFO, "%s: sending Target " - "Reset for stuck SATA identify command " - "(cm = %p)\n", __func__, cm); - targ->tm->cm_targ = targ; - mprsas_send_reset(sc, targ->tm, - MPI2_SCSITASKMGMT_TASKTYPE_TARGET_RESET); - } else { - mpr_dprint(sc, MPR_ERROR, "Failed to allocate " - "tm for Target Reset after SATA ID " - "command timed out (cm %p)\n", cm); - } - /* - * No need to check for more since the target is - * already being reset. - */ - break; - } - } out: - /* - * Free the commands that may not have been freed from the SATA ID call - */ - for (i = 1; i < sc->num_reqs; i++) { - cm = &sc->commands[i]; - if (cm->cm_flags & MPR_CM_FLAGS_SATA_ID_TIMEOUT) { - mpr_free_command(sc, cm); - } - } mprsas_startup_decrement(sassc); return (error); + } int mprsas_get_sas_address_for_sata_disk(struct mpr_softc *sc, - u64 *sas_address, u16 handle, u32 device_info, u8 *is_SATA_SSD) + u64 *sas_address, u16 handle, u32 device_info) { Mpi2SataPassthroughReply_t mpi_reply; int i, rc, try_count; @@ -885,16 +835,7 @@ mprsas_get_sas_address_for_sata_disk(struct mpr_softc *sc, ioc_status = le16toh(mpi_reply.IOCStatus) & MPI2_IOCSTATUS_MASK; sas_status = mpi_reply.SASStatus; - if (ioc_status != MPI2_IOCSTATUS_SUCCESS) { - if (sc->spinup_wait_time > 0) { - mpr_dprint(sc, MPR_INFO, "Sleeping %d seconds " - "after SATA ID error to wait for spinup\n", - sc->spinup_wait_time); - msleep(&sc->msleep_fake_chan, &sc->mpr_mtx, 0, - "mprid", sc->spinup_wait_time * hz); - } - } - } while (((rc && (rc != EWOULDBLOCK)) || ioc_status || sas_status) && + } while ((rc == -EAGAIN || ioc_status || sas_status) && (try_count < 5)); if (rc == 0 && !ioc_status && !sas_status) { @@ -943,10 +884,6 @@ mprsas_get_sas_address_for_sata_disk(struct mpr_softc *sc, (u64)hash_address.wwid[3] << 32 | (u64)hash_address.wwid[4] << 24 | (u64)hash_address.wwid[5] << 16 | (u64)hash_address.wwid[6] << 8 | (u64)hash_address.wwid[7]; - if (ata_identify.rotational_speed == 1) { - *is_SATA_SSD = 1; - } - return 0; } @@ -986,29 +923,14 @@ mprsas_get_sata_identify(struct mpr_softc *sc, u16 handle, cm->cm_desc.Default.RequestFlags = MPI2_REQ_DESCRIPT_FLAGS_DEFAULT_TYPE; cm->cm_data = buffer; cm->cm_length = htole32(sz); - - /* - * Start a timeout counter specifically for the SATA ID command. This - * is used to fix a problem where the FW does not send a reply sometimes - * when a bad disk is in the topology. So, this is used to timeout the - * command so that processing can continue normally. - */ - mpr_dprint(sc, MPR_XINFO, "%s start timeout counter for SATA ID " - "command\n", __func__); - callout_reset(&cm->cm_callout, MPR_ATA_ID_TIMEOUT * hz, - mprsas_ata_id_timeout, cm); error = mpr_wait_command(sc, cm, 60, CAN_SLEEP); - mpr_dprint(sc, MPR_XINFO, "%s stop timeout counter for SATA ID " - "command\n", __func__); - callout_stop(&cm->cm_callout); - reply = (Mpi2SataPassthroughReply_t *)cm->cm_reply; if (error || (reply == NULL)) { /* FIXME */ /* * If the request returns an error then we need to do a diag * reset - */ + */ printf("%s: request for page completed with error %d", __func__, error); error = ENXIO; @@ -1024,66 +946,11 @@ mprsas_get_sata_identify(struct mpr_softc *sc, u16 handle, goto out; } out: - /* - * If the SATA_ID_TIMEOUT flag has been set for this command, don't free - * it. The command will be freed after sending a target reset TM. If - * the command did timeout, use EWOULDBLOCK. - */ - if ((cm->cm_flags & MPR_CM_FLAGS_SATA_ID_TIMEOUT) == 0) - mpr_free_command(sc, cm); - else if (error == 0) - error = EWOULDBLOCK; - free(buffer, M_MPR); + mpr_free_command(sc, cm); + free(buffer, M_MPR); return (error); } -static void -mprsas_ata_id_timeout(void *data) -{ - struct mpr_softc *sc; - struct mpr_command *cm; - - cm = (struct mpr_command *)data; - sc = cm->cm_sc; - mtx_assert(&sc->mpr_mtx, MA_OWNED); - - mpr_dprint(sc, MPR_INFO, "%s checking ATA ID command %p sc %p\n", - __func__, cm, sc); - if ((callout_pending(&cm->cm_callout)) || - (!callout_active(&cm->cm_callout))) { - mpr_dprint(sc, MPR_INFO, "%s ATA ID command almost timed " - "out\n", __func__); - return; - } - callout_deactivate(&cm->cm_callout); - - /* - * Run the interrupt handler to make sure it's not pending. This - * isn't perfect because the command could have already completed - * and been re-used, though this is unlikely. - */ - mpr_intr_locked(sc); - if (cm->cm_state == MPR_CM_STATE_FREE) { - mpr_dprint(sc, MPR_INFO, "%s ATA ID command almost timed " - "out\n", __func__); - return; - } - - mpr_dprint(sc, MPR_INFO, "ATA ID command timeout cm %p\n", cm); - - /* - * Send wakeup() to the sleeping thread that issued this ATA ID - * command. wakeup() will cause msleep to return a 0 (not EWOULDBLOCK), - * and this will keep reinit() from being called. This way, an Abort - * Task TM can be issued so that the timed out command can be cleared. - * The Abort Task cannot be sent from here because the driver has not - * completed setting up targets. Instead, the command is flagged so - * that special handling will be used to send the abort. - */ - cm->cm_flags |= MPR_CM_FLAGS_SATA_ID_TIMEOUT; - wakeup(cm); -} - static int mprsas_volume_add(struct mpr_softc *sc, u16 handle) { @@ -1157,13 +1024,15 @@ mprsas_SSU_to_SATA_devices(struct mpr_softc *sc) path_id_t pathid = cam_sim_path(sassc->sim); target_id_t targetid; struct mprsas_target *target; + struct mprsas_lun *lun; char path_str[64]; struct timeval cur_time, start_time; mpr_lock(sc); /* - * For each target, issue a StartStopUnit command to stop the device. + * For each LUN of each target, issue a StartStopUnit command to stop + * the device. */ sc->SSU_started = TRUE; sc->SSU_refcount = 0; @@ -1173,52 +1042,59 @@ mprsas_SSU_to_SATA_devices(struct mpr_softc *sc) continue; } - ccb = xpt_alloc_ccb_nowait(); - if (ccb == NULL) { - mpr_dprint(sc, MPR_FAULT, "Unable to alloc CCB to stop " - "unit.\n"); - return; - } - - /* - * The stop_at_shutdown flag will be set if this device is - * a SATA direct-access end device. - */ - if (target->stop_at_shutdown) { - if (xpt_create_path(&ccb->ccb_h.path, xpt_periph, - pathid, targetid, CAM_LUN_WILDCARD) != - CAM_REQ_CMP) { - mpr_dprint(sc, MPR_ERROR, "Unable to create " - "path to stop unit.\n"); - xpt_free_ccb(ccb); + SLIST_FOREACH(lun, &target->luns, lun_link) { + ccb = xpt_alloc_ccb_nowait(); + if (ccb == NULL) { + mpr_unlock(sc); + mpr_dprint(sc, MPR_FAULT, "Unable to alloc " + "CCB to stop unit.\n"); return; } - xpt_path_string(ccb->ccb_h.path, path_str, - sizeof(path_str)); - - mpr_dprint(sc, MPR_INFO, "Sending StopUnit: path %s " - "handle %d\n", path_str, target->handle); /* - * Issue a START STOP UNIT command for the target. - * Increment the SSU counter to be used to count the - * number of required replies. + * The stop_at_shutdown flag will be set if this LUN is + * a SATA direct-access end device. */ - mpr_dprint(sc, MPR_INFO, "Incrementing SSU count\n"); - sc->SSU_refcount++; - ccb->ccb_h.target_id = - xpt_path_target_id(ccb->ccb_h.path); - ccb->ccb_h.ppriv_ptr1 = sassc; - scsi_start_stop(&ccb->csio, - /*retries*/0, - mprsas_stop_unit_done, - MSG_SIMPLE_Q_TAG, - /*start*/FALSE, - /*load/eject*/0, - /*immediate*/FALSE, - MPR_SENSE_LEN, - /*timeout*/10000); - xpt_action(ccb); + if (lun->stop_at_shutdown) { + if (xpt_create_path(&ccb->ccb_h.path, + xpt_periph, pathid, targetid, + lun->lun_id) != CAM_REQ_CMP) { + mpr_dprint(sc, MPR_FAULT, "Unable to " + "create LUN path to stop unit.\n"); + xpt_free_ccb(ccb); + mpr_unlock(sc); + return; + } + xpt_path_string(ccb->ccb_h.path, path_str, + sizeof(path_str)); + + mpr_dprint(sc, MPR_INFO, "Sending StopUnit: " + "path %s handle %d\n", path_str, + target->handle); + + /* + * Issue a START STOP UNIT command for the LUN. + * Increment the SSU counter to be used to + * count the number of required replies. + */ + mpr_dprint(sc, MPR_INFO, "Incrementing SSU " + "count\n"); + sc->SSU_refcount++; + ccb->ccb_h.target_id = + xpt_path_target_id(ccb->ccb_h.path); + ccb->ccb_h.target_lun = lun->lun_id; + ccb->ccb_h.ppriv_ptr1 = sassc; + scsi_start_stop(&ccb->csio, + /*retries*/0, + mprsas_stop_unit_done, + MSG_SIMPLE_Q_TAG, + /*start*/FALSE, + /*load/eject*/0, + /*immediate*/FALSE, + MPR_SENSE_LEN, + /*timeout*/10000); + xpt_action(ccb); + } } } @@ -1226,7 +1102,7 @@ mprsas_SSU_to_SATA_devices(struct mpr_softc *sc) /* * Wait until all of the SSU commands have completed or time has - * expired (60 seconds). Pause for 100ms each time through. If any + * expired (60 seconds). pause for 100ms each time through. If any * command times out, the target will be reset in the SCSI command * timeout routine. */ @@ -1236,7 +1112,7 @@ mprsas_SSU_to_SATA_devices(struct mpr_softc *sc) getmicrotime(&cur_time); if ((cur_time.tv_sec - start_time.tv_sec) > 60) { - mpr_dprint(sc, MPR_ERROR, "Time has expired waiting " + mpr_dprint(sc, MPR_FAULT, "Time has expired waiting " "for SSU commands to complete.\n"); break; } @@ -1286,8 +1162,6 @@ mprsas_ir_shutdown(struct mpr_softc *sc) unsigned int id, found_volume = 0; struct mpr_command *cm; Mpi2RaidActionRequest_t *action; - target_id_t targetid; - struct mprsas_target *target; mpr_dprint(sc, MPR_TRACE, "%s\n", __func__); @@ -1340,47 +1214,5 @@ mprsas_ir_shutdown(struct mpr_softc *sc) mpr_free_command(sc, cm); out: - /* - * All of the targets must have the correct value set for - * 'stop_at_shutdown' for the current 'enable_ssu' sysctl variable. - * - * The possible values for the 'enable_ssu' variable are: - * 0: disable to SSD and HDD - * 1: disable only to HDD (default) - * 2: disable only to SSD - * 3: enable to SSD and HDD - * anything else will default to 1. - */ - for (targetid = 0; targetid < sc->facts->MaxTargets; targetid++) { - target = &sc->sassc->targets[targetid]; - if (target->handle == 0x0) { - continue; - } - - if (target->supports_SSU) { - switch (sc->enable_ssu) { - case MPR_SSU_DISABLE_SSD_DISABLE_HDD: - target->stop_at_shutdown = FALSE; - break; - case MPR_SSU_DISABLE_SSD_ENABLE_HDD: - target->stop_at_shutdown = TRUE; - if (target->flags & MPR_TARGET_IS_SATA_SSD) { - target->stop_at_shutdown = FALSE; - } - break; - case MPR_SSU_ENABLE_SSD_ENABLE_HDD: - target->stop_at_shutdown = TRUE; - break; - case MPR_SSU_ENABLE_SSD_DISABLE_HDD: - default: - target->stop_at_shutdown = TRUE; - if ((target->flags & - MPR_TARGET_IS_SATA_SSD) == 0) { - target->stop_at_shutdown = FALSE; - } - break; - } - } - } mprsas_SSU_to_SATA_devices(sc); } diff --git a/sys/dev/mpr/mpr_user.c b/sys/dev/mpr/mpr_user.c index 37d9467..60680f5 100644 --- a/sys/dev/mpr/mpr_user.c +++ b/sys/dev/mpr/mpr_user.c @@ -27,11 +27,10 @@ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF * SUCH DAMAGE. * - * Avago Technologies (LSI) MPT-Fusion Host Adapter FreeBSD userland interface + * LSI MPT-Fusion Host Adapter FreeBSD userland interface */ /*- - * Copyright (c) 2011-2015 LSI Corp. - * Copyright (c) 2013-2015 Avago Technologies + * Copyright (c) 2011-2014 LSI Corp. * All rights reserved. * * Redistribution and use in source and binary forms, with or without @@ -55,7 +54,7 @@ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF * SUCH DAMAGE. * - * Avago Technologies (LSI) MPT-Fusion Host Adapter FreeBSD + * LSI MPT-Fusion Host Adapter FreeBSD * * $FreeBSD$ */ @@ -91,7 +90,7 @@ __FBSDID("$FreeBSD$"); #include <sys/rman.h> #include <cam/cam.h> -#include <cam/cam_ccb.h> +#include <cam/scsi/scsi_all.h> #include <dev/mpr/mpi/mpi2_type.h> #include <dev/mpr/mpi/mpi2.h> @@ -285,7 +284,8 @@ mpr_user_read_cfg_header(struct mpr_softc *sc, static int mpr_user_read_cfg_page(struct mpr_softc *sc, - struct mpr_cfg_page_req *page_req, void *buf) + struct mpr_cfg_page_req *page_req, + void *buf) { MPI2_CONFIG_PAGE_HEADER *reqhdr, *hdr; struct mpr_config_params params; @@ -328,10 +328,6 @@ mpr_user_read_extcfg_header(struct mpr_softc *sc, hdr->PageNumber = ext_page_req->header.PageNumber; hdr->ExtPageType = ext_page_req->header.ExtPageType; params.page_address = le32toh(ext_page_req->page_address); - params.buffer = NULL; - params.length = 0; - params.callback = NULL; - if ((error = mpr_read_config_page(sc, ¶ms)) != 0) { /* * Leave the request. Without resetting the chip, it's @@ -369,8 +365,8 @@ mpr_user_read_extcfg_page(struct mpr_softc *sc, params.action = MPI2_CONFIG_ACTION_PAGE_READ_CURRENT; params.page_address = le32toh(ext_page_req->page_address); hdr->PageVersion = reqhdr->PageVersion; - hdr->PageType = MPI2_CONFIG_PAGETYPE_EXTENDED; hdr->PageNumber = reqhdr->PageNumber; + hdr->PageType = MPI2_CONFIG_PAGETYPE_EXTENDED; hdr->ExtPageType = reqhdr->ExtPageType; hdr->ExtPageLength = reqhdr->ExtPageLength; params.buffer = buf; @@ -545,8 +541,6 @@ mpi_pre_fw_upload(struct mpr_command *cm, struct mpr_usr_command *cmd) req->ImageOffset = 0; req->ImageSize = cmd->len; - cm->cm_flags |= MPR_CM_FLAGS_DATAIN; - return (mpr_push_ieee_sge(cm, &req->SGL, 0)); } @@ -840,22 +834,11 @@ mpr_user_pass_thru(struct mpr_softc *sc, mpr_pass_thru_t *data) task->TaskMID = cm->cm_desc.Default.SMID; cm->cm_data = NULL; - cm->cm_desc.HighPriority.RequestFlags = - MPI2_REQ_DESCRIPT_FLAGS_HIGH_PRIORITY; + cm->cm_desc.HighPriority.RequestFlags = MPI2_REQ_DESCRIPT_FLAGS_HIGH_PRIORITY; cm->cm_complete = NULL; cm->cm_complete_data = NULL; - targ = mprsas_find_target_by_handle(sc->sassc, 0, - task->DevHandle); - if (targ == NULL) { - mpr_dprint(sc, MPR_INFO, - "%s %d : invalid handle for requested TM 0x%x \n", - __func__, __LINE__, task->DevHandle); - err = 1; - } else { - mprsas_prepare_for_tm(sc, cm, targ, CAM_LUN_WILDCARD); - err = mpr_wait_command(sc, cm, 30, CAN_SLEEP); - } + err = mpr_wait_command(sc, cm, 30, CAN_SLEEP); if (err != 0) { err = EIO; @@ -1046,7 +1029,7 @@ mpr_user_pass_thru(struct mpr_softc *sc, mpr_pass_thru_t *data) if (cm->cm_flags & MPR_CM_FLAGS_DATAIN) dir = BUS_DMASYNC_POSTREAD; else if (cm->cm_flags & MPR_CM_FLAGS_DATAOUT) - dir = BUS_DMASYNC_POSTWRITE; + dir = BUS_DMASYNC_POSTWRITE;; bus_dmamap_sync(sc->buffer_dmat, cm->cm_dmamap, dir); bus_dmamap_unload(sc->buffer_dmat, cm->cm_dmamap); @@ -1368,8 +1351,8 @@ done: } static int -mpr_diag_register(struct mpr_softc *sc, mpr_fw_diag_register_t *diag_register, - uint32_t *return_code) +mpr_diag_register(struct mpr_softc *sc, + mpr_fw_diag_register_t *diag_register, uint32_t *return_code) { mpr_fw_diagnostic_buffer_t *pBuffer; uint8_t extended_type, buffer_type, i; diff --git a/sys/dev/mpr/mprvar.h b/sys/dev/mpr/mprvar.h index acac44c..9752dcd 100644 --- a/sys/dev/mpr/mprvar.h +++ b/sys/dev/mpr/mprvar.h @@ -1,7 +1,6 @@ /*- * Copyright (c) 2009 Yahoo! Inc. - * Copyright (c) 2011-2015 LSI Corp. - * Copyright (c) 2013-2015 Avago Technologies + * Copyright (c) 2011-2014 LSI Corp. * All rights reserved. * * Redistribution and use in source and binary forms, with or without @@ -25,15 +24,13 @@ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF * SUCH DAMAGE. * - * Avago Technologies (LSI) MPT-Fusion Host Adapter FreeBSD - * * $FreeBSD$ */ #ifndef _MPRVAR_H #define _MPRVAR_H -#define MPR_DRIVER_VERSION "09.255.01.00-fbsd" +#define MPR_DRIVER_VERSION "05.255.05.00-fbsd" #define MPR_DB_MAX_WAIT 2500 @@ -50,19 +47,16 @@ #define MPR_FUNCTRACE(sc) \ mpr_dprint((sc), MPR_TRACE, "%s\n", __func__) -#define CAN_SLEEP 1 -#define NO_SLEEP 0 +#define CAN_SLEEP 1 +#define NO_SLEEP 0 #define MPR_PERIODIC_DELAY 1 /* 1 second heartbeat/watchdog check */ -#define MPR_ATA_ID_TIMEOUT 5 /* 5 second timeout for SATA ID cmd */ #define IFAULT_IOP_OVER_TEMP_THRESHOLD_EXCEEDED 0x2810 #define MPR_SCSI_RI_INVALID_FRAME (0x00000002) #define MPR_STRING_LENGTH 64 -#define DEFAULT_SPINUP_WAIT 3 /* seconds to wait for spinup */ - #include <sys/endian.h> /* @@ -219,14 +213,13 @@ struct mpr_command { #define MPR_CM_FLAGS_CHAIN_FAILED (1 << 8) #define MPR_CM_FLAGS_ERROR_MASK MPR_CM_FLAGS_CHAIN_FAILED #define MPR_CM_FLAGS_USE_CCB (1 << 9) -#define MPR_CM_FLAGS_SATA_ID_TIMEOUT (1 << 10) u_int cm_state; #define MPR_CM_STATE_FREE 0 #define MPR_CM_STATE_BUSY 1 #define MPR_CM_STATE_TIMEDOUT 2 bus_dmamap_t cm_dmamap; struct scsi_sense_data *cm_sense; - TAILQ_HEAD(, mpr_chain) cm_chain_list; + TAILQ_HEAD(, mpr_chain) cm_chain_list; uint32_t cm_req_busaddr; uint32_t cm_sense_busaddr; struct callout cm_callout; @@ -263,8 +256,6 @@ struct mpr_softc { int chain_free; int max_chains; int chain_free_lowwater; - u_int enable_ssu; - int spinup_wait_time; #if __FreeBSD_version >= 900030 uint64_t chain_alloc_fail; #endif @@ -279,7 +270,7 @@ struct mpr_softc { char tmp_string[MPR_STRING_LENGTH]; TAILQ_HEAD(, mpr_command) req_list; TAILQ_HEAD(, mpr_command) high_priority_req_list; - TAILQ_HEAD(, mpr_chain) chain_list; + TAILQ_HEAD(, mpr_chain) chain_list; TAILQ_HEAD(, mpr_command) tm_list; int replypostindex; int replyfreeindex; @@ -300,7 +291,7 @@ struct mpr_softc { uint8_t event_mask[16]; TAILQ_HEAD(, mpr_event_handle) event_list; - struct mpr_event_handle *mpr_log_eh; + struct mpr_event_handle *mpr_log_eh; struct mtx mpr_mtx; struct intr_config_hook mpr_ich; @@ -574,11 +565,6 @@ mpr_unlock(struct mpr_softc *sc) #define MPR_MAPPING (1 << 9) /* Trace device mappings */ #define MPR_TRACE (1 << 10) /* Function-by-function trace */ -#define MPR_SSU_DISABLE_SSD_DISABLE_HDD 0 -#define MPR_SSU_ENABLE_SSD_DISABLE_HDD 1 -#define MPR_SSU_DISABLE_SSD_ENABLE_HDD 2 -#define MPR_SSU_ENABLE_SSD_ENABLE_HDD 3 - #define mpr_printf(sc, args...) \ device_printf((sc)->mpr_dev, ##args) @@ -614,6 +600,9 @@ do { \ #define MPR_EVENTFIELD(sc, facts, attr, fmt) \ mpr_dprint_field((sc), MPR_EVENT, #attr ": " #fmt "\n", (facts)->attr) +#define CAN_SLEEP 1 +#define NO_SLEEP 0 + static __inline void mpr_from_u64(uint64_t data, U64 *mpr) { @@ -624,6 +613,7 @@ mpr_from_u64(uint64_t data, U64 *mpr) static __inline uint64_t mpr_to_u64(U64 *data) { + return (((uint64_t)le32toh(data->High) << 32) | le32toh(data->Low)); } @@ -737,12 +727,6 @@ void mprsas_prepare_volume_remove(struct mprsas_softc *sassc, int mprsas_startup(struct mpr_softc *sc); struct mprsas_target * mprsas_find_target_by_handle(struct mprsas_softc *, int, uint16_t); -void mprsas_realloc_targets(struct mpr_softc *sc, int maxtargets); -struct mpr_command * mprsas_alloc_tm(struct mpr_softc *sc); -void mprsas_free_tm(struct mpr_softc *sc, struct mpr_command *tm); -void mprsas_release_simq_reinit(struct mprsas_softc *sassc); -int mprsas_send_reset(struct mpr_softc *sc, struct mpr_command *tm, - uint8_t type); SYSCTL_DECL(_hw_mpr); |