MFC: r283661
- Updated all files with 2015 Avago copyright, and updated LSI's copyright dates. - Changed all of the PCI device strings from LSI to Avago Technologies (LSI). - Added a sysctl variable to control how StartStopUnit behavior works. User can select to spin down disks based on if disk is SSD or HDD. - Inquiry data is required to tell if a disk will support SSU at shutdown or not. Due to the addition of mprssas_async, which gets Advanced Info but not Inquiry data, the setting of supports_SSU was moved to the mprsas_scsiio_complete function, which snoops for any Inquiry commands. And, since disks are shutdown as a target and not a LUN, this process was simplified by basing it on targets and not LUNs. - Added a sysctl variable that sets the amount of time to retry after sending a failed SATA ID command. This helps with some bad disks and large disks that require a lot of time to spin up. Part of this change was to add a callout to handle timeouts with the SATA ID command. The callout function is called mprsas_ata_id_timeout(). (Fixes PR 191348) - Changed the way resets work by allowing I/O to continue to devices that are not currently under a reset condition. This uses devq's instead of simq's and makes use of the MPSSAS_TARGET_INRESET flag. This change also adds a function called mprsas_prepare_tm(). - Some changes were made to reduce code duplication when getting a SAS address for a SATA disk. - Fixed some formatting and whitespace. - Bump version of mpr driver to 9.255.01.00-fbsd PR: 191348
This commit is contained in:
parent
7e70fa5ddf
commit
ceb5f63b1a
@ -1,5 +1,6 @@
|
||||
/*-
|
||||
* Copyright (c) 2013 LSI Corp.
|
||||
* Copyright (c) 2012-2015 LSI Corp.
|
||||
* Copyright (c) 2013-2015 Avago Technologies
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
@ -26,13 +27,14 @@
|
||||
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
|
||||
* SUCH DAMAGE.
|
||||
*
|
||||
* LSI MPT-Fusion Host Adapter FreeBSD
|
||||
* Avago Technologies (LSI) MPT-Fusion Host Adapter FreeBSD
|
||||
*
|
||||
* $FreeBSD$
|
||||
*/
|
||||
|
||||
/*
|
||||
* Copyright (c) 2000-2013 LSI Corporation.
|
||||
* Copyright (c) 2000-2015 LSI Corporation.
|
||||
* Copyright (c) 2013-2015 Avago Technologies
|
||||
*
|
||||
*
|
||||
* Name: mpi2.h
|
||||
|
@ -1,5 +1,6 @@
|
||||
/*-
|
||||
* Copyright (c) 2013 LSI Corp.
|
||||
* Copyright (c) 2012-2015 LSI Corp.
|
||||
* Copyright (c) 2013-2015 Avago Technologies
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
@ -26,13 +27,14 @@
|
||||
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
|
||||
* SUCH DAMAGE.
|
||||
*
|
||||
* LSI MPT-Fusion Host Adapter FreeBSD
|
||||
* Avago Technologies (LSI) MPT-Fusion Host Adapter FreeBSD
|
||||
*
|
||||
* $FreeBSD$
|
||||
*/
|
||||
|
||||
/*
|
||||
* Copyright (c) 2000-2013 LSI Corporation.
|
||||
* Copyright (c) 2000-2015 LSI Corporation.
|
||||
* Copyright (c) 2013-2015 Avago Technologies
|
||||
*
|
||||
*
|
||||
* Name: mpi2_cnfg.h
|
||||
|
@ -1,5 +1,6 @@
|
||||
/*-
|
||||
* Copyright (c) 2013 LSI Corp.
|
||||
* Copyright (c) 2012-2015 LSI Corp.
|
||||
* Copyright (c) 2013-2015 Avago Technologies
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
@ -26,13 +27,14 @@
|
||||
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
|
||||
* SUCH DAMAGE.
|
||||
*
|
||||
* LSI MPT-Fusion Host Adapter FreeBSD
|
||||
* Avago Technologies (LSI) MPT-Fusion Host Adapter FreeBSD
|
||||
*
|
||||
* $FreeBSD$
|
||||
*/
|
||||
|
||||
/*
|
||||
* Copyright (c) 2009-2011 LSI Corporation.
|
||||
* Copyright (c) 2009-2015 LSI Corporation.
|
||||
* Copyright (c) 2013-2015 Avago Technologies
|
||||
*
|
||||
*
|
||||
* Name: mpi2_hbd.h
|
||||
|
@ -1,5 +1,6 @@
|
||||
/*-
|
||||
* Copyright (c) 2013 LSI Corp.
|
||||
* Copyright (c) 2012-2015 LSI Corp.
|
||||
* Copyright (c) 2013-2015 Avago Technologies
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
@ -26,7 +27,7 @@
|
||||
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
|
||||
* SUCH DAMAGE.
|
||||
*
|
||||
* LSI MPT-Fusion Host Adapter FreeBSD
|
||||
* Avago Technologies (LSI) MPT-Fusion Host Adapter FreeBSD
|
||||
*
|
||||
* $FreeBSD$
|
||||
*/
|
||||
@ -35,7 +36,8 @@
|
||||
Fusion-MPT MPI 2.0 / 2.5 Header File Change History
|
||||
==============================
|
||||
|
||||
Copyright (c) 2000-2013 LSI Corporation.
|
||||
Copyright (c) 2000-2015 LSI Corporation.
|
||||
Copyright (c) 2013-2015 Avago Technologies
|
||||
|
||||
---------------------------------------
|
||||
Header Set Release Version: 02.00.33
|
||||
|
@ -1,5 +1,6 @@
|
||||
/*-
|
||||
* Copyright (c) 2013 LSI Corp.
|
||||
* Copyright (c) 2012-2015 LSI Corp.
|
||||
* Copyright (c) 2013-2015 Avago Technologies
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
@ -26,13 +27,14 @@
|
||||
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
|
||||
* SUCH DAMAGE.
|
||||
*
|
||||
* LSI MPT-Fusion Host Adapter FreeBSD
|
||||
* Avago Technologies (LSI) MPT-Fusion Host Adapter FreeBSD
|
||||
*
|
||||
* $FreeBSD$
|
||||
*/
|
||||
|
||||
/*
|
||||
* Copyright (c) 2000-2013 LSI Corporation.
|
||||
* Copyright (c) 2000-2015 LSI Corporation.
|
||||
* Copyright (c) 2013-2015 Avago Technologies
|
||||
*
|
||||
*
|
||||
* Name: mpi2_init.h
|
||||
|
@ -1,5 +1,6 @@
|
||||
/*-
|
||||
* Copyright (c) 2013 LSI Corp.
|
||||
* Copyright (c) 2012-2015 LSI Corp.
|
||||
* Copyright (c) 2013-2015 Avago Technologies
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
@ -26,13 +27,14 @@
|
||||
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
|
||||
* SUCH DAMAGE.
|
||||
*
|
||||
* LSI MPT-Fusion Host Adapter FreeBSD
|
||||
* Avago Technologies (LSI) MPT-Fusion Host Adapter FreeBSD
|
||||
*
|
||||
* $FreeBSD$
|
||||
*/
|
||||
|
||||
/*
|
||||
* Copyright (c) 2000-2013 LSI Corporation.
|
||||
* Copyright (c) 2000-2015 LSI Corporation.
|
||||
* Copyright (c) 2013-2015 Avago Technologies
|
||||
*
|
||||
*
|
||||
* Name: mpi2_ioc.h
|
||||
|
@ -1,5 +1,6 @@
|
||||
/*-
|
||||
* Copyright (c) 2013 LSI Corp.
|
||||
* Copyright (c) 2012-2015 LSI Corp.
|
||||
* Copyright (c) 2013-2015 Avago Technologies
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
@ -26,13 +27,14 @@
|
||||
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
|
||||
* SUCH DAMAGE.
|
||||
*
|
||||
* LSI MPT-Fusion Host Adapter FreeBSD
|
||||
* Avago Technologies (LSI) MPT-Fusion Host Adapter FreeBSD
|
||||
*
|
||||
* $FreeBSD$
|
||||
*/
|
||||
|
||||
/*
|
||||
* Copyright (c) 2009 LSI Corporation.
|
||||
* Copyright (c) 2012-2015 LSI Corporation.
|
||||
* Copyright (c) 2013-2015 Avago Technologies
|
||||
*
|
||||
*
|
||||
* Name: mpi2_ra.h
|
||||
|
@ -1,5 +1,6 @@
|
||||
/*-
|
||||
* Copyright (c) 2013 LSI Corp.
|
||||
* Copyright (c) 2012-2015 LSI Corp.
|
||||
* Copyright (c) 2013-2015 Avago Technologies
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
@ -26,13 +27,14 @@
|
||||
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
|
||||
* SUCH DAMAGE.
|
||||
*
|
||||
* LSI MPT-Fusion Host Adapter FreeBSD
|
||||
* Avago Technologies (LSI) MPT-Fusion Host Adapter FreeBSD
|
||||
*
|
||||
* $FreeBSD$
|
||||
*/
|
||||
|
||||
/*
|
||||
* Copyright (c) 2000-2013 LSI Corporation.
|
||||
* Copyright (c) 2000-2015 LSI Corporation.
|
||||
* Copyright (c) 2013-2015 Avago Technologies
|
||||
*
|
||||
*
|
||||
* Name: mpi2_raid.h
|
||||
|
@ -1,5 +1,6 @@
|
||||
/*-
|
||||
* Copyright (c) 2013 LSI Corp.
|
||||
* Copyright (c) 2012-2015 LSI Corp.
|
||||
* Copyright (c) 2013-2015 Avago Technologies
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
@ -26,13 +27,14 @@
|
||||
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
|
||||
* SUCH DAMAGE.
|
||||
*
|
||||
* LSI MPT-Fusion Host Adapter FreeBSD
|
||||
* Avago Technologies (LSI) MPT-Fusion Host Adapter FreeBSD
|
||||
*
|
||||
* $FreeBSD$
|
||||
*/
|
||||
|
||||
/*
|
||||
* Copyright (c) 2000-2013 LSI Corporation.
|
||||
* Copyright (c) 2000-2015 LSI Corporation.
|
||||
* Copyright (c) 2013-2015 Avago Technologies
|
||||
*
|
||||
*
|
||||
* Name: mpi2_sas.h
|
||||
|
@ -1,5 +1,6 @@
|
||||
/*-
|
||||
* Copyright (c) 2013 LSI Corp.
|
||||
* Copyright (c) 2012-2015 LSI Corp.
|
||||
* Copyright (c) 2013-2015 Avago Technologies
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
@ -26,13 +27,14 @@
|
||||
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
|
||||
* SUCH DAMAGE.
|
||||
*
|
||||
* LSI MPT-Fusion Host Adapter FreeBSD
|
||||
* Avago Technologies (LSI) MPT-Fusion Host Adapter FreeBSD
|
||||
*
|
||||
* $FreeBSD$
|
||||
*/
|
||||
|
||||
/*
|
||||
* Copyright (c) 2000-2012 LSI Corporation.
|
||||
* Copyright (c) 2000-2015 LSI Corporation.
|
||||
* Copyright (c) 2013-2015 Avago Technologies
|
||||
*
|
||||
*
|
||||
* Name: mpi2_targ.h
|
||||
|
@ -1,5 +1,6 @@
|
||||
/*-
|
||||
* Copyright (c) 2013 LSI Corp.
|
||||
* Copyright (c) 2012-2015 LSI Corp.
|
||||
* Copyright (c) 2013-2015 Avago Technologies
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
@ -26,13 +27,14 @@
|
||||
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
|
||||
* SUCH DAMAGE.
|
||||
*
|
||||
* LSI MPT-Fusion Host Adapter FreeBSD
|
||||
* Avago Technologies (LSI) MPT-Fusion Host Adapter FreeBSD
|
||||
*
|
||||
* $FreeBSD$
|
||||
*/
|
||||
|
||||
/*
|
||||
* Copyright (c) 2000-2013 LSI Corporation.
|
||||
* Copyright (c) 2000-2015 LSI Corporation.
|
||||
* Copyright (c) 2013-2015 Avago Technologies
|
||||
*
|
||||
*
|
||||
* Name: mpi2_tool.h
|
||||
|
@ -1,5 +1,6 @@
|
||||
/*-
|
||||
* Copyright (c) 2013 LSI Corp.
|
||||
* Copyright (c) 2012-2015 LSI Corp.
|
||||
* Copyright (c) 2013-2015 Avago Technologies
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
@ -26,13 +27,14 @@
|
||||
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
|
||||
* SUCH DAMAGE.
|
||||
*
|
||||
* LSI MPT-Fusion Host Adapter FreeBSD
|
||||
* Avago Technologies (LSI) MPT-Fusion Host Adapter FreeBSD
|
||||
*
|
||||
* $FreeBSD$
|
||||
*/
|
||||
|
||||
/*
|
||||
* Copyright (c) 2000-2007 LSI Corporation.
|
||||
* Copyright (c) 2000-2015 LSI Corporation.
|
||||
* Copyright (c) 2013-2015 Avago Technologies
|
||||
*
|
||||
*
|
||||
* Name: mpi2_type.h
|
||||
|
@ -1,6 +1,7 @@
|
||||
/*-
|
||||
* Copyright (c) 2009 Yahoo! Inc.
|
||||
* Copyright (c) 2012-2014 LSI Corp.
|
||||
* Copyright (c) 2011-2015 LSI Corp.
|
||||
* Copyright (c) 2013-2015 Avago Technologies
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
@ -24,12 +25,14 @@
|
||||
* 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 LSI MPT2 */
|
||||
/* Communications core for Avago Technologies (LSI) MPT3 */
|
||||
|
||||
/* TODO Move headers to mprvar */
|
||||
#include <sys/types.h>
|
||||
@ -72,7 +75,6 @@ __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);
|
||||
@ -352,11 +354,9 @@ mpr_transition_operational(struct mpr_softc *sc)
|
||||
static int
|
||||
mpr_iocfacts_allocate(struct mpr_softc *sc, uint8_t attaching)
|
||||
{
|
||||
int error, i;
|
||||
int error;
|
||||
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,27 +513,7 @@ mpr_iocfacts_allocate(struct mpr_softc *sc, uint8_t attaching)
|
||||
*/
|
||||
if (reallocating) {
|
||||
mpr_iocfacts_free(sc);
|
||||
|
||||
/*
|
||||
* 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);
|
||||
}
|
||||
mprsas_realloc_targets(sc, saved_facts.MaxTargets);
|
||||
}
|
||||
|
||||
/*
|
||||
@ -775,7 +755,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;
|
||||
}
|
||||
@ -816,7 +796,8 @@ 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
|
||||
@ -982,7 +963,7 @@ mpr_enqueue_request(struct mpr_softc *sc, struct mpr_command *cm)
|
||||
reply_descriptor rd;
|
||||
|
||||
MPR_FUNCTRACE(sc);
|
||||
mpr_dprint(sc, MPR_TRACE, "%s SMID %u cm %p ccb %p\n", __func__,
|
||||
mpr_dprint(sc, MPR_TRACE, "SMID %u cm %p ccb %p\n",
|
||||
cm->cm_desc.Default.SMID, cm, cm->cm_ccb);
|
||||
|
||||
if (sc->mpr_flags & MPR_FLAGS_ATTACH_DONE && !(sc->mpr_flags &
|
||||
@ -1372,6 +1353,8 @@ 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.
|
||||
@ -1380,6 +1363,8 @@ 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",
|
||||
@ -1402,6 +1387,14 @@ 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
|
||||
@ -1474,11 +1467,20 @@ 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
|
||||
@ -2096,7 +2098,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);
|
||||
@ -2163,8 +2165,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)
|
||||
@ -2246,9 +2248,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,
|
||||
@ -2660,7 +2662,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) ?
|
||||
@ -2717,9 +2719,12 @@ mpr_read_config_page(struct mpr_softc *sc, struct mpr_config_params *params)
|
||||
|
||||
cm->cm_data = params->buffer;
|
||||
cm->cm_length = params->length;
|
||||
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;
|
||||
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_desc.Default.RequestFlags = MPI2_REQ_DESCRIPT_FLAGS_DEFAULT_TYPE;
|
||||
|
||||
cm->cm_complete_data = params;
|
||||
@ -2776,9 +2781,12 @@ mpr_config_complete(struct mpr_softc *sc, struct mpr_command *cm)
|
||||
goto done;
|
||||
}
|
||||
params->status = reply->IOCStatus;
|
||||
if (params->hdr.Ext.ExtPageType != 0) {
|
||||
if (params->hdr.Struct.PageType == MPI2_CONFIG_PAGETYPE_EXTENDED) {
|
||||
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;
|
||||
|
@ -1,5 +1,6 @@
|
||||
/*-
|
||||
* Copyright (c) 2011-2014 LSI Corp.
|
||||
* Copyright (c) 2011-2015 LSI Corp.
|
||||
* Copyright (c) 2013-2015 Avago Technologies
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
@ -23,7 +24,7 @@
|
||||
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
|
||||
* SUCH DAMAGE.
|
||||
*
|
||||
* LSI MPT-Fusion Host Adapter FreeBSD
|
||||
* Avago Technologies (LSI) MPT-Fusion Host Adapter FreeBSD
|
||||
*/
|
||||
|
||||
#include <sys/cdefs.h>
|
||||
|
@ -27,12 +27,13 @@
|
||||
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
|
||||
* SUCH DAMAGE.
|
||||
*
|
||||
* LSI MPT-Fusion Host Adapter FreeBSD userland interface
|
||||
* Avago Technologies (LSI) MPT-Fusion Host Adapter FreeBSD userland interface
|
||||
*
|
||||
* $FreeBSD$
|
||||
*/
|
||||
/*-
|
||||
* Copyright (c) 2011-2014 LSI Corp.
|
||||
* Copyright (c) 2011-2015 LSI Corp.
|
||||
* Copyright (c) 2013-2015 Avago Technologies
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
@ -56,7 +57,7 @@
|
||||
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
|
||||
* SUCH DAMAGE.
|
||||
*
|
||||
* LSI MPT-Fusion Host Adapter FreeBSD
|
||||
* Avago Technologies (LSI) MPT-Fusion Host Adapter FreeBSD
|
||||
*
|
||||
* $FreeBSD$
|
||||
*/
|
||||
|
@ -1,5 +1,6 @@
|
||||
/*-
|
||||
* Copyright (c) 2011-2014 LSI Corp.
|
||||
* Copyright (c) 2011-2015 LSI Corp.
|
||||
* Copyright (c) 2013-2015 Avago Technologies
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
@ -23,7 +24,7 @@
|
||||
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
|
||||
* SUCH DAMAGE.
|
||||
*
|
||||
* LSI MPT-Fusion Host Adapter FreeBSD
|
||||
* Avago Technologies (LSI) MPT-Fusion Host Adapter FreeBSD
|
||||
*/
|
||||
|
||||
#include <sys/cdefs.h>
|
||||
@ -326,11 +327,13 @@ _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 = 0, end_idx_ir;
|
||||
u32 start_idx, end_idx, start_idx_ir, 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;
|
||||
@ -887,14 +890,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;
|
||||
u8 entry, enc_idx, phy_idx, sata_end_device;
|
||||
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;
|
||||
int rc = 1;
|
||||
|
||||
for (entry = 0; entry < topo_change->num_entries; entry++) {
|
||||
phy_change = &topo_change->phy_details[entry];
|
||||
@ -908,41 +911,36 @@ _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);
|
||||
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;
|
||||
}
|
||||
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 {
|
||||
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) {
|
||||
@ -950,10 +948,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;
|
||||
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);
|
||||
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);
|
||||
continue;
|
||||
}
|
||||
if (!((phy_change->device_info &
|
||||
|
@ -1,5 +1,6 @@
|
||||
/*-
|
||||
* Copyright (c) 2011-2014 LSI Corp.
|
||||
* Copyright (c) 2011-2015 LSI Corp.
|
||||
* Copyright (c) 2013-2015 Avago Technologies
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
@ -23,7 +24,7 @@
|
||||
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
|
||||
* SUCH DAMAGE.
|
||||
*
|
||||
* LSI MPT-Fusion Host Adapter FreeBSD
|
||||
* Avago Technologies (LSI) MPT-Fusion Host Adapter FreeBSD
|
||||
*
|
||||
* $FreeBSD$
|
||||
*/
|
||||
@ -38,6 +39,7 @@
|
||||
* @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;
|
||||
@ -46,6 +48,8 @@ struct _map_phy_change {
|
||||
uint16_t slot;
|
||||
uint8_t reason;
|
||||
uint8_t is_processed;
|
||||
uint8_t is_SATA_SSD;
|
||||
uint8_t reserved;
|
||||
};
|
||||
|
||||
/**
|
||||
@ -66,6 +70,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);
|
||||
u64 *sas_address, u16 handle, u32 device_info, u8 *is_SATA_SSD);
|
||||
|
||||
#endif
|
||||
|
@ -27,7 +27,7 @@
|
||||
#include <sys/cdefs.h>
|
||||
__FBSDID("$FreeBSD$");
|
||||
|
||||
/* PCI/PCI-X/PCIe bus interface for the LSI MPT2 controllers */
|
||||
/* PCI/PCI-X/PCIe bus interface for the Avago Tech (LSI) MPT3 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, "LSI SAS3004" },
|
||||
0xffff, 0xffff, 0, "Avago Technologies (LSI) SAS3004" },
|
||||
{ MPI2_MFGPAGE_VENDORID_LSI, MPI25_MFGPAGE_DEVID_SAS3008,
|
||||
0xffff, 0xffff, 0, "LSI SAS3008" },
|
||||
0xffff, 0xffff, 0, "Avago Technologies (LSI) SAS3008" },
|
||||
{ MPI2_MFGPAGE_VENDORID_LSI, MPI25_MFGPAGE_DEVID_SAS3108_1,
|
||||
0xffff, 0xffff, 0, "LSI SAS3108_1" },
|
||||
0xffff, 0xffff, 0, "Avago Technologies (LSI) SAS3108_1" },
|
||||
{ MPI2_MFGPAGE_VENDORID_LSI, MPI25_MFGPAGE_DEVID_SAS3108_2,
|
||||
0xffff, 0xffff, 0, "LSI SAS3108_2" },
|
||||
0xffff, 0xffff, 0, "Avago Technologies (LSI) SAS3108_2" },
|
||||
{ MPI2_MFGPAGE_VENDORID_LSI, MPI25_MFGPAGE_DEVID_SAS3108_5,
|
||||
0xffff, 0xffff, 0, "LSI SAS3108_5" },
|
||||
0xffff, 0xffff, 0, "Avago Technologies (LSI) SAS3108_5" },
|
||||
{ MPI2_MFGPAGE_VENDORID_LSI, MPI25_MFGPAGE_DEVID_SAS3108_6,
|
||||
0xffff, 0xffff, 0, "LSI SAS3108_6" },
|
||||
0xffff, 0xffff, 0, "Avago Technologies (LSI) SAS3108_6" },
|
||||
{ 0, 0, 0, 0, 0, NULL }
|
||||
};
|
||||
|
||||
|
File diff suppressed because it is too large
Load Diff
@ -1,5 +1,6 @@
|
||||
/*-
|
||||
* Copyright (c) 2011-2014 LSI Corp.
|
||||
* Copyright (c) 2011-2015 LSI Corp.
|
||||
* Copyright (c) 2013-2015 Avago Technologies
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
@ -23,7 +24,7 @@
|
||||
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
|
||||
* SUCH DAMAGE.
|
||||
*
|
||||
* LSI MPT-Fusion Host Adapter FreeBSD
|
||||
* Avago Technologies (LSI) MPT-Fusion Host Adapter FreeBSD
|
||||
*
|
||||
* $FreeBSD$
|
||||
*/
|
||||
@ -35,7 +36,6 @@ 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,11 +55,10 @@ 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;
|
||||
@ -82,6 +81,8 @@ 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 {
|
||||
@ -92,7 +93,6 @@ 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,7 +103,6 @@ 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;
|
||||
@ -150,6 +149,19 @@ 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); \
|
||||
@ -158,11 +170,10 @@ 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);
|
||||
|
@ -1,5 +1,6 @@
|
||||
/*-
|
||||
* Copyright (c) 2011-2014 LSI Corp.
|
||||
* Copyright (c) 2011-2015 LSI Corp.
|
||||
* Copyright (c) 2013-2015 Avago Technologies
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
@ -23,13 +24,13 @@
|
||||
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
|
||||
* SUCH DAMAGE.
|
||||
*
|
||||
* LSI MPT-Fusion Host Adapter FreeBSD
|
||||
* Avago Technologies (LSI) MPT-Fusion Host Adapter FreeBSD
|
||||
*/
|
||||
|
||||
#include <sys/cdefs.h>
|
||||
__FBSDID("$FreeBSD$");
|
||||
|
||||
/* Communications core for LSI MPT2 */
|
||||
/* Communications core for LSI MPT3 */
|
||||
|
||||
/* TODO Move headers to mprvar */
|
||||
#include <sys/types.h>
|
||||
@ -105,7 +106,9 @@ struct _ata_identify_device_data {
|
||||
u16 serial_number[10]; /* 10-19 */
|
||||
u16 reserved2[7]; /* 20-26 */
|
||||
u16 model_number[20]; /* 27-46*/
|
||||
u16 reserved3[209]; /* 47-255*/
|
||||
u16 reserved3[170]; /* 47-216 */
|
||||
u16 rotational_speed; /* 217 */
|
||||
u16 reserved4[38]; /* 218-255 */
|
||||
};
|
||||
static u32 event_count;
|
||||
static void mprsas_fw_work(struct mpr_softc *sc,
|
||||
@ -116,8 +119,9 @@ 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);
|
||||
u64 *sas_address, u16 handle, u32 device_info, u8 *is_SATA_SSD);
|
||||
static int mprsas_volume_add(struct mpr_softc *sc,
|
||||
u16 handle);
|
||||
static void mprsas_SSU_to_SATA_devices(struct mpr_softc *sc);
|
||||
@ -325,7 +329,7 @@ mprsas_fw_work(struct mpr_softc *sc, struct mpr_fw_event_work *fw_event)
|
||||
return;
|
||||
}
|
||||
|
||||
mpr_dprint(sc, MPR_INFO, "Sending FP action "
|
||||
mpr_dprint(sc, MPR_EVENT, "Sending FP action "
|
||||
"from "
|
||||
"MPI2_EVENT_IR_CONFIGURATION_CHANGE_LIST "
|
||||
":\n");
|
||||
@ -350,9 +354,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_INFO, "%s: error "
|
||||
"sending RaidActionPage; iocstatus "
|
||||
"= 0x%x\n", __func__,
|
||||
mpr_dprint(sc, MPR_ERROR, "%s: error "
|
||||
"sending RaidActionPage; "
|
||||
"iocstatus = 0x%x\n", __func__,
|
||||
le16toh(reply->IOCStatus));
|
||||
}
|
||||
|
||||
@ -360,7 +364,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_INFO, "Received "
|
||||
mpr_dprint(sc, MPR_EVENT, "Received "
|
||||
"MPI2_EVENT_IR_CONFIGURATION_CHANGE_LIST Reason "
|
||||
"code %x:\n", element->ReasonCode);
|
||||
switch (element->ReasonCode) {
|
||||
@ -421,7 +425,6 @@ mprsas_fw_work(struct mpr_softc *sc, struct mpr_fw_event_work *fw_event)
|
||||
break;
|
||||
targ->flags |= MPR_TARGET_FLAGS_RAID_COMPONENT;
|
||||
mprsas_rescan_target(sc, targ);
|
||||
|
||||
break;
|
||||
case MPI2_EVENT_IR_CHANGE_RC_PD_DELETED:
|
||||
/*
|
||||
@ -678,14 +681,13 @@ 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, sata_sas_address;
|
||||
uint64_t parent_sas_address = 0;
|
||||
u16 ioc_pg8_flags = le16toh(sc->ioc_pg8.Flags);
|
||||
uint64_t sas_address, parent_sas_address = 0;
|
||||
u32 device_info, parent_devinfo = 0;
|
||||
unsigned int id;
|
||||
int ret;
|
||||
int error = 0;
|
||||
int ret = 1, error = 0, i;
|
||||
struct mprsas_lun *lun;
|
||||
u8 is_SATA_SSD = 0;
|
||||
struct mpr_command *cm;
|
||||
|
||||
sassc = sc->sassc;
|
||||
mprsas_startup_increment(sassc);
|
||||
@ -717,26 +719,29 @@ 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;
|
||||
sas_address = (sas_address << 32) | config_page.SASAddress.Low;
|
||||
mpr_dprint(sc, MPR_INFO, "SAS Address from SAS device page0 = %jx\n",
|
||||
sas_address);
|
||||
|
||||
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);
|
||||
/*
|
||||
* 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);
|
||||
}
|
||||
}
|
||||
|
||||
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__,
|
||||
@ -750,7 +755,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];
|
||||
@ -773,6 +778,9 @@ 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 =
|
||||
@ -792,12 +800,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_XINFO|MPR_MAPPING), "Found device <%s> <%s> "
|
||||
mpr_dprint(sc, (MPR_INFO|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_XINFO|MPR_MAPPING), "At enclosure level %d "
|
||||
mpr_dprint(sc, (MPR_INFO|MPR_MAPPING), "At enclosure level %d "
|
||||
"and connector name (%4s)\n", targ->encl_level,
|
||||
targ->connector_name);
|
||||
}
|
||||
@ -807,15 +815,57 @@ 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)
|
||||
u64 *sas_address, u16 handle, u32 device_info, u8 *is_SATA_SSD)
|
||||
{
|
||||
Mpi2SataPassthroughReply_t mpi_reply;
|
||||
int i, rc, try_count;
|
||||
@ -835,7 +885,16 @@ 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;
|
||||
} while ((rc == -EAGAIN || ioc_status || sas_status) &&
|
||||
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) &&
|
||||
(try_count < 5));
|
||||
|
||||
if (rc == 0 && !ioc_status && !sas_status) {
|
||||
@ -884,6 +943,10 @@ 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;
|
||||
}
|
||||
|
||||
@ -923,14 +986,29 @@ 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;
|
||||
@ -946,11 +1024,66 @@ mprsas_get_sata_identify(struct mpr_softc *sc, u16 handle,
|
||||
goto out;
|
||||
}
|
||||
out:
|
||||
mpr_free_command(sc, cm);
|
||||
free(buffer, M_MPR);
|
||||
/*
|
||||
* 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);
|
||||
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)
|
||||
{
|
||||
@ -1024,15 +1157,13 @@ 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 LUN of each target, issue a StartStopUnit command to stop
|
||||
* the device.
|
||||
* For each target, issue a StartStopUnit command to stop the device.
|
||||
*/
|
||||
sc->SSU_started = TRUE;
|
||||
sc->SSU_refcount = 0;
|
||||
@ -1042,59 +1173,52 @@ mprsas_SSU_to_SATA_devices(struct mpr_softc *sc)
|
||||
continue;
|
||||
}
|
||||
|
||||
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");
|
||||
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);
|
||||
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);
|
||||
|
||||
/*
|
||||
* The stop_at_shutdown flag will be set if this LUN is
|
||||
* a SATA direct-access end device.
|
||||
* Issue a START STOP UNIT command for the target.
|
||||
* Increment the SSU counter to be used to count the
|
||||
* number of required replies.
|
||||
*/
|
||||
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);
|
||||
}
|
||||
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);
|
||||
}
|
||||
}
|
||||
|
||||
@ -1102,7 +1226,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.
|
||||
*/
|
||||
@ -1112,7 +1236,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_FAULT, "Time has expired waiting "
|
||||
mpr_dprint(sc, MPR_ERROR, "Time has expired waiting "
|
||||
"for SSU commands to complete.\n");
|
||||
break;
|
||||
}
|
||||
@ -1162,6 +1286,8 @@ 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__);
|
||||
|
||||
@ -1214,5 +1340,47 @@ 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);
|
||||
}
|
||||
|
@ -27,10 +27,11 @@
|
||||
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
|
||||
* SUCH DAMAGE.
|
||||
*
|
||||
* LSI MPT-Fusion Host Adapter FreeBSD userland interface
|
||||
* Avago Technologies (LSI) MPT-Fusion Host Adapter FreeBSD userland interface
|
||||
*/
|
||||
/*-
|
||||
* Copyright (c) 2011-2014 LSI Corp.
|
||||
* Copyright (c) 2011-2015 LSI Corp.
|
||||
* Copyright (c) 2013-2015 Avago Technologies
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
@ -54,7 +55,7 @@
|
||||
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
|
||||
* SUCH DAMAGE.
|
||||
*
|
||||
* LSI MPT-Fusion Host Adapter FreeBSD
|
||||
* Avago Technologies (LSI) MPT-Fusion Host Adapter FreeBSD
|
||||
*
|
||||
* $FreeBSD$
|
||||
*/
|
||||
@ -90,7 +91,7 @@ __FBSDID("$FreeBSD$");
|
||||
#include <sys/rman.h>
|
||||
|
||||
#include <cam/cam.h>
|
||||
#include <cam/scsi/scsi_all.h>
|
||||
#include <cam/cam_ccb.h>
|
||||
|
||||
#include <dev/mpr/mpi/mpi2_type.h>
|
||||
#include <dev/mpr/mpi/mpi2.h>
|
||||
@ -284,8 +285,7 @@ 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,6 +328,10 @@ 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
|
||||
@ -365,8 +369,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->PageNumber = reqhdr->PageNumber;
|
||||
hdr->PageType = MPI2_CONFIG_PAGETYPE_EXTENDED;
|
||||
hdr->PageNumber = reqhdr->PageNumber;
|
||||
hdr->ExtPageType = reqhdr->ExtPageType;
|
||||
hdr->ExtPageLength = reqhdr->ExtPageLength;
|
||||
params.buffer = buf;
|
||||
@ -541,6 +545,8 @@ 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));
|
||||
}
|
||||
|
||||
@ -834,11 +840,22 @@ 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;
|
||||
|
||||
err = mpr_wait_command(sc, cm, 30, CAN_SLEEP);
|
||||
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);
|
||||
}
|
||||
|
||||
if (err != 0) {
|
||||
err = EIO;
|
||||
@ -1029,7 +1046,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);
|
||||
|
||||
@ -1351,8 +1368,8 @@ mpr_release_fw_diag_buffer(struct mpr_softc *sc,
|
||||
}
|
||||
|
||||
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;
|
||||
|
@ -1,6 +1,7 @@
|
||||
/*-
|
||||
* Copyright (c) 2009 Yahoo! Inc.
|
||||
* Copyright (c) 2011-2014 LSI Corp.
|
||||
* Copyright (c) 2011-2015 LSI Corp.
|
||||
* Copyright (c) 2013-2015 Avago Technologies
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
@ -24,13 +25,15 @@
|
||||
* 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 "05.255.05.00-fbsd"
|
||||
#define MPR_DRIVER_VERSION "09.255.01.00-fbsd"
|
||||
|
||||
#define MPR_DB_MAX_WAIT 2500
|
||||
|
||||
@ -47,16 +50,19 @@
|
||||
#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>
|
||||
|
||||
/*
|
||||
@ -213,13 +219,14 @@ 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;
|
||||
@ -256,6 +263,8 @@ 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
|
||||
@ -270,7 +279,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;
|
||||
@ -291,7 +300,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;
|
||||
@ -565,6 +574,11 @@ 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)
|
||||
|
||||
@ -600,9 +614,6 @@ 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)
|
||||
{
|
||||
@ -613,7 +624,6 @@ 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));
|
||||
}
|
||||
|
||||
@ -727,6 +737,12 @@ 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);
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user