diff options
author | ken <ken@FreeBSD.org> | 2013-07-22 18:41:53 +0000 |
---|---|---|
committer | ken <ken@FreeBSD.org> | 2013-07-22 18:41:53 +0000 |
commit | ba9cc3ab8526ced3a521b91f2a372d9962474fb0 (patch) | |
tree | 334176d6edbef84c24ecb7c3a9043fed3904a4e2 /sys/dev/mps/mps_config.c | |
parent | 71b805798bf6d7e4be7d593becfe3bcd5c3bdbf6 (diff) | |
download | FreeBSD-src-ba9cc3ab8526ced3a521b91f2a372d9962474fb0.zip FreeBSD-src-ba9cc3ab8526ced3a521b91f2a372d9962474fb0.tar.gz |
Merge in phase 14+ -> 16 mps driver fixes from LSI:
---------------------------------------------------------------
System panics during a Port reset with ouststanding I/O
---------------------------------------------------------------
It is possible to call mps_mapping_free_memory after this
memory is already freed, causing a panic. Removed this extra
call to mps_mappiing_free_memory and call mps_mapping_exit
in place of the mps_mapping_free_memory call so that any
outstanding mapping items can be flushed before memory is
freed.
---------------------------------------------------------------
Correct memory leak during a Port reset with ouststanding I/O
---------------------------------------------------------------
In mps_reinit function, the mapping memory was not being
freed before being re-allocated. Added line to call the
memory free function for mapping memory.
---------------------------------------------------------------
Use CAM_SIM_QUEUED flag in Driver IO path.
---------------------------------------------------------------
This flag informs the XPT that successful abort of a CCB
requires an abort ccb to be issued to the SIM. While
processing SCSI IO's, set the CAM_SIM_QUEUED flag in the
status for the IO. When the command completes, clear this
flag.
---------------------------------------------------------------
Check for CAM_REQ_INPROG in I/O path.
---------------------------------------------------------------
Added a check in mpssas_action_scsiio for the In Progress
status for the IO. If this flag is set, the IO has already
been aborted by the upper layer (before CAM_SIM_QUEUED was
set) and there is no need to send the IO. The request will
be completed without error.
---------------------------------------------------------------
Improve "doorbell handshake method" for mps_get_iocfacts
---------------------------------------------------------------
Removed call to get Port Facts since this information is
not used currently.
Added mps_iocfacts_allocate function to allocate memory
that is based on IOC Facts data. Added mps_iocfacts_free
function to free memory that is based on IOC Facts data.
Both of the functions are used when a Diag Reset is performed
or when the driver is attached/detached. This is needed in
case IOC Facts changes after a Diag Reset, which could
happen if FW is upgraded.
Moved call of mps_bases_static_config_pages from the attach
routine to after the IOC is ready to process accesses based
on the new memory allocations (instead of polling through
the Doorbell).
---------------------------------------------------------------
Set TimeStamp in INIT message in millisecond format Set the IOC
---------------------------------------------------------------
---------------------------------------------------------------
Prefer mps_wait_command to mps_request_polled
---------------------------------------------------------------
Instead of using mps_request_polled, call mps_wait_command
whenever possible. Change the mps_wait_command function to
check the current context and either use interrupt context
or poll if required by using the pause or DELAY function.
Added a check after waiting 50mSecs to see if the command
has timed out. This is only done if polliing, the msleep
command will automatically timeout if the command has taken
too long to complete.
---------------------------------------------------------------
Integrated RAID: Volume Activation Failed error message is
displayed though the volume has been activated.
---------------------------------------------------------------
Instead of failing an IOCTL request that does not have a
large enough buffer to hold the complete reply, copy as
much data from the reply as possible into the user's buffer
and log a message saying that the user's buffer was smaller
than the returned data.
---------------------------------------------------------------
mapping_add_new_device failure due to persistent table FULL
---------------------------------------------------------------
When a new device is added, if it is determined that the
device persistent table is being used and is full, instead
of displaying a message for this condition every time, only
log a message if the MPS_INFO bit is set in the debug_flags.
Submitted by: LSI
MFC after: 1 week
Diffstat (limited to 'sys/dev/mps/mps_config.c')
-rw-r--r-- | sys/dev/mps/mps_config.c | 197 |
1 files changed, 149 insertions, 48 deletions
diff --git a/sys/dev/mps/mps_config.c b/sys/dev/mps/mps_config.c index 939872e..d6e2a8c 100644 --- a/sys/dev/mps/mps_config.c +++ b/sys/dev/mps/mps_config.c @@ -93,12 +93,15 @@ mps_config_get_ioc_pg8(struct mps_softc *sc, Mpi2ConfigReply_t *mpi_reply, request->Header.PageVersion = MPI2_IOCPAGE8_PAGEVERSION; cm->cm_desc.Default.RequestFlags = MPI2_REQ_DESCRIPT_FLAGS_DEFAULT_TYPE; cm->cm_data = NULL; - error = mps_request_polled(sc, cm); + error = mps_wait_command(sc, cm, 60, CAN_SLEEP); reply = (MPI2_CONFIG_REPLY *)cm->cm_reply; if (error || (reply == NULL)) { /* FIXME */ - /* If the poll returns error then we need to do diag reset */ - printf("%s: poll for header completed with error %d", + /* + * If the request returns an error then we need to do a diag + * reset + */ + printf("%s: request for header completed with error %d", __func__, error); error = ENXIO; goto out; @@ -107,7 +110,10 @@ mps_config_get_ioc_pg8(struct mps_softc *sc, Mpi2ConfigReply_t *mpi_reply, bcopy(reply, mpi_reply, sizeof(MPI2_CONFIG_REPLY)); if (ioc_status != MPI2_IOCSTATUS_SUCCESS) { /* FIXME */ - /* If the poll returns error then we need to do diag reset */ + /* + * If the request returns an error then we need to do a diag + * reset + */ printf("%s: header read with error; iocstatus = 0x%x\n", __func__, ioc_status); error = ENXIO; @@ -144,12 +150,16 @@ mps_config_get_ioc_pg8(struct mps_softc *sc, Mpi2ConfigReply_t *mpi_reply, goto out; } cm->cm_data = page; - error = mps_request_polled(sc, cm); + + error = mps_wait_command(sc, cm, 60, CAN_SLEEP); reply = (MPI2_CONFIG_REPLY *)cm->cm_reply; if (error || (reply == NULL)) { /* FIXME */ - /* If the poll returns error then we need to do diag reset */ - printf("%s: poll for page completed with error %d", + /* + * 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; goto out; @@ -158,7 +168,10 @@ mps_config_get_ioc_pg8(struct mps_softc *sc, Mpi2ConfigReply_t *mpi_reply, bcopy(reply, mpi_reply, sizeof(MPI2_CONFIG_REPLY)); if (ioc_status != MPI2_IOCSTATUS_SUCCESS) { /* FIXME */ - /* If the poll returns error then we need to do diag reset */ + /* + * If the request returns an error then we need to do a diag + * reset + */ printf("%s: page read with error; iocstatus = 0x%x\n", __func__, ioc_status); error = ENXIO; @@ -211,6 +224,11 @@ mps_config_get_man_pg10(struct mps_softc *sc, Mpi2ConfigReply_t *mpi_reply) request->Header.PageVersion = MPI2_MANUFACTURING10_PAGEVERSION; cm->cm_desc.Default.RequestFlags = MPI2_REQ_DESCRIPT_FLAGS_DEFAULT_TYPE; cm->cm_data = NULL; + + /* + * This page must be polled because the IOC isn't ready yet when this + * page is needed. + */ error = mps_request_polled(sc, cm); reply = (MPI2_CONFIG_REPLY *)cm->cm_reply; if (error || (reply == NULL)) { @@ -262,6 +280,11 @@ mps_config_get_man_pg10(struct mps_softc *sc, Mpi2ConfigReply_t *mpi_reply) goto out; } cm->cm_data = page; + + /* + * This page must be polled because the IOC isn't ready yet when this + * page is needed. + */ error = mps_request_polled(sc, cm); reply = (MPI2_CONFIG_REPLY *)cm->cm_reply; if (error || (reply == NULL)) { @@ -561,12 +584,15 @@ mps_config_get_dpm_pg0(struct mps_softc *sc, Mpi2ConfigReply_t *mpi_reply, MPI2_DPM_PGAD_ENTRY_COUNT_SHIFT; cm->cm_desc.Default.RequestFlags = MPI2_REQ_DESCRIPT_FLAGS_DEFAULT_TYPE; cm->cm_data = NULL; - error = mps_request_polled(sc, cm); + error = mps_wait_command(sc, cm, 60, CAN_SLEEP); reply = (MPI2_CONFIG_REPLY *)cm->cm_reply; if (error || (reply == NULL)) { /* FIXME */ - /* If the poll returns error then we need to do diag reset */ - printf("%s: poll for header completed with error %d", + /* + * If the request returns an error then we need to do a diag + * reset + */ + printf("%s: request for header completed with error %d", __func__, error); error = ENXIO; goto out; @@ -575,7 +601,10 @@ mps_config_get_dpm_pg0(struct mps_softc *sc, Mpi2ConfigReply_t *mpi_reply, bcopy(reply, mpi_reply, sizeof(MPI2_CONFIG_REPLY)); if (ioc_status != MPI2_IOCSTATUS_SUCCESS) { /* FIXME */ - /* If the poll returns error then we need to do diag reset */ + /* + * If the request returns an error then we need to do a diag + * reset + */ printf("%s: header read with error; iocstatus = 0x%x\n", __func__, ioc_status); error = ENXIO; @@ -615,12 +644,15 @@ mps_config_get_dpm_pg0(struct mps_softc *sc, Mpi2ConfigReply_t *mpi_reply, goto out; } cm->cm_data = page; - error = mps_request_polled(sc, cm); + error = mps_wait_command(sc, cm, 60, CAN_SLEEP); reply = (MPI2_CONFIG_REPLY *)cm->cm_reply; if (error || (reply == NULL)) { /* FIXME */ - /* If the poll returns error then we need to do diag reset */ - printf("%s: poll for page completed with error %d", + /* + * 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; goto out; @@ -629,7 +661,10 @@ mps_config_get_dpm_pg0(struct mps_softc *sc, Mpi2ConfigReply_t *mpi_reply, bcopy(reply, mpi_reply, sizeof(MPI2_CONFIG_REPLY)); if (ioc_status != MPI2_IOCSTATUS_SUCCESS) { /* FIXME */ - /* If the poll returns error then we need to do diag reset */ + /* + * If the request returns an error then we need to do a diag + * reset + */ printf("%s: page read with error; iocstatus = 0x%x\n", __func__, ioc_status); error = ENXIO; @@ -685,12 +720,15 @@ int mps_config_set_dpm_pg0(struct mps_softc *sc, Mpi2ConfigReply_t *mpi_reply, request->PageAddress |= htole16(entry_idx); cm->cm_desc.Default.RequestFlags = MPI2_REQ_DESCRIPT_FLAGS_DEFAULT_TYPE; cm->cm_data = NULL; - error = mps_request_polled(sc, cm); + error = mps_wait_command(sc, cm, 60, CAN_SLEEP); reply = (MPI2_CONFIG_REPLY *)cm->cm_reply; if (error || (reply == NULL)) { /* FIXME */ - /* If the poll returns error then we need to do diag reset */ - printf("%s: poll for header completed with error %d", + /* + * If the request returns an error then we need to do a diag + * reset + */ + printf("%s: request for header completed with error %d", __func__, error); error = ENXIO; goto out; @@ -699,7 +737,10 @@ int mps_config_set_dpm_pg0(struct mps_softc *sc, Mpi2ConfigReply_t *mpi_reply, bcopy(reply, mpi_reply, sizeof(MPI2_CONFIG_REPLY)); if (ioc_status != MPI2_IOCSTATUS_SUCCESS) { /* FIXME */ - /* If the poll returns error then we need to do diag reset */ + /* + * If the request returns an error then we need to do a diag + * reset + */ printf("%s: header read with error; iocstatus = 0x%x\n", __func__, ioc_status); error = ENXIO; @@ -741,12 +782,15 @@ int mps_config_set_dpm_pg0(struct mps_softc *sc, Mpi2ConfigReply_t *mpi_reply, bcopy(config_page, page, MIN(cm->cm_length, (sizeof(Mpi2DriverMappingPage0_t)))); cm->cm_data = page; - error = mps_request_polled(sc, cm); + error = mps_wait_command(sc, cm, 60, CAN_SLEEP); reply = (MPI2_CONFIG_REPLY *)cm->cm_reply; if (error || (reply == NULL)) { /* FIXME */ - /* If the poll returns error then we need to do diag reset */ - printf("%s: poll for page completed with error %d", + /* + * If the request returns an error then we need to do a diag + * reset + */ + printf("%s: request to write page completed with error %d", __func__, error); error = ENXIO; goto out; @@ -755,7 +799,10 @@ int mps_config_set_dpm_pg0(struct mps_softc *sc, Mpi2ConfigReply_t *mpi_reply, bcopy(reply, mpi_reply, sizeof(MPI2_CONFIG_REPLY)); if (ioc_status != MPI2_IOCSTATUS_SUCCESS) { /* FIXME */ - /* If the poll returns error then we need to do diag reset */ + /* + * If the request returns an error then we need to do a diag + * reset + */ printf("%s: page written with error; iocstatus = 0x%x\n", __func__, ioc_status); error = ENXIO; @@ -808,12 +855,15 @@ mps_config_get_sas_device_pg0(struct mps_softc *sc, Mpi2ConfigReply_t request->Header.PageVersion = MPI2_SASDEVICE0_PAGEVERSION; cm->cm_desc.Default.RequestFlags = MPI2_REQ_DESCRIPT_FLAGS_DEFAULT_TYPE; cm->cm_data = NULL; - error = mps_request_polled(sc, cm); + error = mps_wait_command(sc, cm, 60, CAN_SLEEP); reply = (MPI2_CONFIG_REPLY *)cm->cm_reply; if (error || (reply == NULL)) { /* FIXME */ - /* If the poll returns error then we need to do diag reset */ - printf("%s: poll for header completed with error %d", + /* + * If the request returns an error then we need to do a diag + * reset + */ + printf("%s: request for header completed with error %d", __func__, error); error = ENXIO; goto out; @@ -822,7 +872,10 @@ mps_config_get_sas_device_pg0(struct mps_softc *sc, Mpi2ConfigReply_t bcopy(reply, mpi_reply, sizeof(MPI2_CONFIG_REPLY)); if (ioc_status != MPI2_IOCSTATUS_SUCCESS) { /* FIXME */ - /* If the poll returns error then we need to do diag reset */ + /* + * If the request returns an error then we need to do a diag + * reset + */ printf("%s: header read with error; iocstatus = 0x%x\n", __func__, ioc_status); error = ENXIO; @@ -862,12 +915,15 @@ mps_config_get_sas_device_pg0(struct mps_softc *sc, Mpi2ConfigReply_t } cm->cm_data = page; - error = mps_request_polled(sc, cm); + error = mps_wait_command(sc, cm, 60, CAN_SLEEP); reply = (MPI2_CONFIG_REPLY *)cm->cm_reply; if (error || (reply == NULL)) { /* FIXME */ - /* If the poll returns error then we need to do diag reset */ - printf("%s: poll for page completed with error %d", + /* + * 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; goto out; @@ -876,7 +932,10 @@ mps_config_get_sas_device_pg0(struct mps_softc *sc, Mpi2ConfigReply_t bcopy(reply, mpi_reply, sizeof(MPI2_CONFIG_REPLY)); if (ioc_status != MPI2_IOCSTATUS_SUCCESS) { /* FIXME */ - /* If the poll returns error then we need to do diag reset */ + /* + * If the request returns an error then we need to do a diag + * reset + */ printf("%s: page read with error; iocstatus = 0x%x\n", __func__, ioc_status); error = ENXIO; @@ -928,12 +987,15 @@ mps_config_get_bios_pg3(struct mps_softc *sc, Mpi2ConfigReply_t *mpi_reply, request->Header.PageVersion = MPI2_BIOSPAGE3_PAGEVERSION; cm->cm_desc.Default.RequestFlags = MPI2_REQ_DESCRIPT_FLAGS_DEFAULT_TYPE; cm->cm_data = NULL; - error = mps_request_polled(sc, cm); + error = mps_wait_command(sc, cm, 60, CAN_SLEEP); reply = (MPI2_CONFIG_REPLY *)cm->cm_reply; if (error || (reply == NULL)) { /* FIXME */ - /* If the poll returns error then we need to do diag reset */ - printf("%s: poll for header completed with error %d", + /* + * If the request returns an error then we need to do a diag + * reset + */ + printf("%s: request for header completed with error %d", __func__, error); error = ENXIO; goto out; @@ -942,7 +1004,10 @@ mps_config_get_bios_pg3(struct mps_softc *sc, Mpi2ConfigReply_t *mpi_reply, bcopy(reply, mpi_reply, sizeof(MPI2_CONFIG_REPLY)); if (ioc_status != MPI2_IOCSTATUS_SUCCESS) { /* FIXME */ - /* If the poll returns error then we need to do diag reset */ + /* + * If the request returns an error then we need to do a diag + * reset + */ printf("%s: header read with error; iocstatus = 0x%x\n", __func__, ioc_status); error = ENXIO; @@ -980,12 +1045,15 @@ mps_config_get_bios_pg3(struct mps_softc *sc, Mpi2ConfigReply_t *mpi_reply, } cm->cm_data = page; - error = mps_request_polled(sc, cm); + error = mps_wait_command(sc, cm, 60, CAN_SLEEP); reply = (MPI2_CONFIG_REPLY *)cm->cm_reply; if (error || (reply == NULL)) { /* FIXME */ - /* If the poll returns error then we need to do diag reset */ - printf("%s: poll for page completed with error %d", + /* + * 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; goto out; @@ -994,7 +1062,10 @@ mps_config_get_bios_pg3(struct mps_softc *sc, Mpi2ConfigReply_t *mpi_reply, bcopy(reply, mpi_reply, sizeof(MPI2_CONFIG_REPLY)); if (ioc_status != MPI2_IOCSTATUS_SUCCESS) { /* FIXME */ - /* If the poll returns error then we need to do diag reset */ + /* + * If the request returns an error then we need to do a diag + * reset + */ printf("%s: page read with error; iocstatus = 0x%x\n", __func__, ioc_status); error = ENXIO; @@ -1046,6 +1117,11 @@ mps_config_get_raid_volume_pg0(struct mps_softc *sc, Mpi2ConfigReply_t request->Header.PageVersion = MPI2_RAIDVOLPAGE0_PAGEVERSION; cm->cm_desc.Default.RequestFlags = MPI2_REQ_DESCRIPT_FLAGS_DEFAULT_TYPE; cm->cm_data = NULL; + + /* + * This page must be polled because the IOC isn't ready yet when this + * page is needed. + */ error = mps_request_polled(sc, cm); reply = (MPI2_CONFIG_REPLY *)cm->cm_reply; if (error || (reply == NULL)) { @@ -1099,6 +1175,10 @@ mps_config_get_raid_volume_pg0(struct mps_softc *sc, Mpi2ConfigReply_t } cm->cm_data = page; + /* + * This page must be polled because the IOC isn't ready yet when this + * page is needed. + */ error = mps_request_polled(sc, cm); reply = (MPI2_CONFIG_REPLY *)cm->cm_reply; if (error || (reply == NULL)) { @@ -1166,12 +1246,15 @@ mps_config_get_raid_volume_pg1(struct mps_softc *sc, Mpi2ConfigReply_t request->Header.PageVersion = MPI2_RAIDVOLPAGE1_PAGEVERSION; cm->cm_desc.Default.RequestFlags = MPI2_REQ_DESCRIPT_FLAGS_DEFAULT_TYPE; cm->cm_data = NULL; - error = mps_request_polled(sc, cm); + error = mps_wait_command(sc, cm, 60, CAN_SLEEP); reply = (MPI2_CONFIG_REPLY *)cm->cm_reply; if (error || (reply == NULL)) { /* FIXME */ - /* If the poll returns error then we need to do diag reset */ - printf("%s: poll for header completed with error %d", + /* + * If the request returns an error then we need to do a diag + * reset + */ + printf("%s: request for header completed with error %d", __func__, error); error = ENXIO; goto out; @@ -1180,7 +1263,10 @@ mps_config_get_raid_volume_pg1(struct mps_softc *sc, Mpi2ConfigReply_t bcopy(reply, mpi_reply, sizeof(MPI2_CONFIG_REPLY)); if (ioc_status != MPI2_IOCSTATUS_SUCCESS) { /* FIXME */ - /* If the poll returns error then we need to do diag reset */ + /* + * If the request returns an error then we need to do a diag + * reset + */ printf("%s: header read with error; iocstatus = 0x%x\n", __func__, ioc_status); error = ENXIO; @@ -1219,12 +1305,15 @@ mps_config_get_raid_volume_pg1(struct mps_softc *sc, Mpi2ConfigReply_t } cm->cm_data = page; - error = mps_request_polled(sc, cm); + error = mps_wait_command(sc, cm, 60, CAN_SLEEP); reply = (MPI2_CONFIG_REPLY *)cm->cm_reply; if (error || (reply == NULL)) { /* FIXME */ - /* If the poll returns error then we need to do diag reset */ - printf("%s: poll for page completed with error %d", + /* + * 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; goto out; @@ -1233,7 +1322,10 @@ mps_config_get_raid_volume_pg1(struct mps_softc *sc, Mpi2ConfigReply_t bcopy(reply, mpi_reply, sizeof(MPI2_CONFIG_REPLY)); if (ioc_status != MPI2_IOCSTATUS_SUCCESS) { /* FIXME */ - /* If the poll returns error then we need to do diag reset */ + /* + * If the request returns an error then we need to do a diag + * reset + */ printf("%s: page read with error; iocstatus = 0x%x\n", __func__, ioc_status); error = ENXIO; @@ -1311,6 +1403,11 @@ mps_config_get_raid_pd_pg0(struct mps_softc *sc, Mpi2ConfigReply_t *mpi_reply, request->Header.PageVersion = MPI2_RAIDPHYSDISKPAGE0_PAGEVERSION; cm->cm_desc.Default.RequestFlags = MPI2_REQ_DESCRIPT_FLAGS_DEFAULT_TYPE; cm->cm_data = NULL; + + /* + * This page must be polled because the IOC isn't ready yet when this + * page is needed. + */ error = mps_request_polled(sc, cm); reply = (MPI2_CONFIG_REPLY *)cm->cm_reply; if (error || (reply == NULL)) { @@ -1364,6 +1461,10 @@ mps_config_get_raid_pd_pg0(struct mps_softc *sc, Mpi2ConfigReply_t *mpi_reply, } cm->cm_data = page; + /* + * This page must be polled because the IOC isn't ready yet when this + * page is needed. + */ error = mps_request_polled(sc, cm); reply = (MPI2_CONFIG_REPLY *)cm->cm_reply; if (error || (reply == NULL)) { |