freebsd-skq/sys/dev/mpt/mpt_raid.c

1696 lines
44 KiB
C
Raw Normal View History

Massive overhaul of MPT Fusion driver: o Add timeout error recovery (from a thread context to avoid the deferral of other critical interrupts). o Properly recover commands across controller reset events. o Update the driver to handle events and status codes that have been added to the MPI spec since the driver was originally written. o Make the driver more modular to improve maintainability and support dynamic "personality" registration (e.g. SCSI Initiator, RAID, SAS, FC, etc). o Shorten and simplify the common I/O path to improve driver performance. o Add RAID volume and RAID member state/settings reporting. o Add periodic volume resynchronization status reporting. o Add support for sysctl tunable resync rate, member write cache enable, and volume transaction queue depth. Sponsored by ---------------- Avid Technologies Inc: SCSI error recovery, driver re-organization, update of MPI library headers, portions of dynamic personality registration, and misc bug fixes. Wheel Open Technologies: RAID event notification, RAID member pass-thru support, firmware upload/download support, enhanced RAID resync speed, portions of dynamic personality registration, and misc bug fixes. Detailed Changes ================ mpt.c mpt_cam.c mpt_raid.c mpt_pci.c: o Add support for personality modules. Each module exports load, and unload module scope methods as well as probe, attach, event, reset, shutdown, and detach per-device instance methods mpt.c mpt.h mpt_pci.c: o The driver now associates a callback function (via an index) with every transaction submitted to the controller. This allows the main interrupt handler to absolve itself of any knowledge of individual transaction/response types by simply calling the callback function "registered" for the transaction. We use a callback index instead of a callback function pointer in each requests so we can properly handle responses (e.g. event notifications) that are not associated with a transaction. Personality modules dynamically register their callbacks with the driver core to receive the callback index to use for their handlers. o Move the interrupt handler into mpt.c. The ISR algorithm is bus transport and OS independent and thus had no reason to be in mpt_pci.c. o Simplify configuration message reply handling by copying reply frame data for the requester and storing completion status in the original request structure. o Add the mpt_complete_request_chain() helper method and use it to implement reset handlers that must abort transactions. o Keep track of all pending requests on the new requests_pending_list in the softc. o Add default handlers to mpt.c to handle generic event notifications and controller reset activities. The event handler code is largely the same as in the original driver. The reset handler is new and terminates any pending transactions with a status code indicating the controller needs to be re-initialized. o Add some endian support to the driver. A complete audit is still required for this driver to have any hope of operating in a big-endian environment. o Use inttypes.h and __inline. Come closer to being style(9) compliant. o Remove extraneous use of typedefs. o Convert request state from a strict enumeration to a series of flags. This allows us to, for example, tag transactions that have timed-out while retaining the state that the transaction is still in-flight on the controller. o Add mpt_wait_req() which allows a caller to poll or sleep for the completion of a request. Use this to simplify and factor code out from many initialization routines. We also use this to sleep for task management request completions in our CAM timeout handler. mpt.c: o Correct a bug in the event handler where request structures were freed even if the request reply was marked as a continuation reply. Continuation replies indicate that the controller still owns the request and freeing these replies prematurely corrupted controller state. o Implement firmware upload and download. On controllers that do not have dedicated NVRAM (as in the Sun v20/v40z), the firmware image is downloaded to the controller by the system BIOS. This image occupies precious controller RAM space until the host driver fetches the image, reducing the number of concurrent I/Os the controller can processes. The uploaded image is used to re-program the controller during hard reset events since the controller cannot fetch the firmware on its own. Implementing this feature allows much higher queue depths when RAID volumes are configured. o Changed configuration page accessors to allow threads to sleep rather than busy wait for completion. o Removed hard coded data transfer sizes from configuration page routines so that RAID configuration page processing is possible. mpt_reg.h: o Move controller register definitions into a separate file. mpt.h: o Re-arrange includes to allow inlined functions to be defined in mpt.h. o Add reply, event, and reset handler definitions. o Add softc fields for handling timeout and controller reset recovery. mpt_cam.c: o Move mpt_freebsd.c to mpt_cam.c. Move all core functionality, such as event handling, into mpt.c leaving only CAM SCSI support here. o Revamp completion handler to provide correct CAM status for all currently defined SCSI MPI message result codes. o Register event and reset handlers with the MPT core. Modify the event handler to notify CAM of bus reset events. The controller reset handler will abort any transactions that have timed out. All other pending CAM transactions are correctly aborted by the core driver's reset handler. o Allocate a single request up front to perform task management operations. This guarantees that we can always perform a TMF operation even when the controller is saturated with other operations. The single request also serves as a perfect mechanism of guaranteeing that only a single TMF is in flight at a time - something that is required according to the MPT Fusion documentation. o Add a helper function for issuing task management requests to the controller. This is used to abort individual requests or perform a bus reset. o Modify the CAM XPT_BUS_RESET ccb handler to wait for and properly handle the status of the bus reset task management frame used to reset the bus. The previous code assumed that the reset request would always succeed. o Add timeout recovery support. When a timeout occurs, the timed-out request is added to a queue to be processed by our recovery thread and the thread is woken up. The recovery thread processes timed-out command serially, attempting first to abort them and then falling back to a bus reset if an abort fails. o Add calls to mpt_reset() to reset the controller if any handshake command, bus reset attempt or abort attempt fails due to a timeout. o Export a secondary "bus" to CAM that exposes all volume drive members as pass-thru devices, allowing CAM to perform proper speed negotiation to hidden devices. o Add a CAM async event handler tracking the AC_FOUND_DEVICE event. Use this to trigger calls to set the per-volume queue depth once the volume is fully registered with CAM. This is required to avoid hitting firmware limits on volume queue depth. Exceeding the limit causes the firmware to hang. mpt_cam.h: o Add several helper functions for interfacing to CAM and performing timeout recovery. mpt_pci.c: o Disable interrupts on the controller before registering and enabling interrupt delivery to the OS. Otherwise we risk receiving interrupts before the driver is ready to receive them. o Make use of compatibility macros that allow the driver to be compiled under 4.x and 5.x. mpt_raid.c: o Add a per-controller instance RAID thread to perform settings changes and query status (minimizes CPU busy wait loops). o Use a shutdown handler to disable "Member Write Cache Enable" (MWCE) setting for RAID arrays set to enable MWCE During Rebuild. o Change reply handler function signature to allow handlers to defer the deletion of reply frames. Use this to allow the event reply handler to queue up events that need to be acked if no resources are available to immediately ack an event. Queued events are processed in mpt_free_request() where resources are freed. This avoids a panic on resource shortage. o Parse and print out RAID controller capabilities during driver probe. o Define, allocate, and maintain RAID data structures for volumes, hidden member physical disks and spare disks. o Add dynamic sysctls for per-instance setting of the log level, array resync rate, array member cache enable, and volume queue depth. mpt_debug.c: o Add mpt_lprt and mpt_lprtc for printing diagnostics conditioned on a particular log level to aid in tracking down driver issues. o Add mpt_decode_value() which parses the bits in an integer value based on a parsing table (mask, value, name string, tuples). mpilib/*: o Update mpi library header files to latest distribution from LSI. Submitted by: gibbs Approved by: re
2005-07-10 15:05:39 +00:00
/*-
* Routines for handling the integrated RAID features LSI MPT Fusion adapters.
*
* Copyright (c) 2005, WHEEL Sp. z o.o.
* Copyright (c) 2005 Justin T. Gibbs.
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are
* met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce at minimum a disclaimer
* substantially similar to the "NO WARRANTY" disclaimer below
* ("Disclaimer") and any redistribution must be conditioned upon including
* a substantially similar Disclaimer requirement for further binary
* redistribution.
* 3. Neither the names of the above listed copyright holders nor the names
* of any contributors may be used to endorse or promote products derived
* from this software without specific prior written permission.
Massive overhaul of MPT Fusion driver: o Add timeout error recovery (from a thread context to avoid the deferral of other critical interrupts). o Properly recover commands across controller reset events. o Update the driver to handle events and status codes that have been added to the MPI spec since the driver was originally written. o Make the driver more modular to improve maintainability and support dynamic "personality" registration (e.g. SCSI Initiator, RAID, SAS, FC, etc). o Shorten and simplify the common I/O path to improve driver performance. o Add RAID volume and RAID member state/settings reporting. o Add periodic volume resynchronization status reporting. o Add support for sysctl tunable resync rate, member write cache enable, and volume transaction queue depth. Sponsored by ---------------- Avid Technologies Inc: SCSI error recovery, driver re-organization, update of MPI library headers, portions of dynamic personality registration, and misc bug fixes. Wheel Open Technologies: RAID event notification, RAID member pass-thru support, firmware upload/download support, enhanced RAID resync speed, portions of dynamic personality registration, and misc bug fixes. Detailed Changes ================ mpt.c mpt_cam.c mpt_raid.c mpt_pci.c: o Add support for personality modules. Each module exports load, and unload module scope methods as well as probe, attach, event, reset, shutdown, and detach per-device instance methods mpt.c mpt.h mpt_pci.c: o The driver now associates a callback function (via an index) with every transaction submitted to the controller. This allows the main interrupt handler to absolve itself of any knowledge of individual transaction/response types by simply calling the callback function "registered" for the transaction. We use a callback index instead of a callback function pointer in each requests so we can properly handle responses (e.g. event notifications) that are not associated with a transaction. Personality modules dynamically register their callbacks with the driver core to receive the callback index to use for their handlers. o Move the interrupt handler into mpt.c. The ISR algorithm is bus transport and OS independent and thus had no reason to be in mpt_pci.c. o Simplify configuration message reply handling by copying reply frame data for the requester and storing completion status in the original request structure. o Add the mpt_complete_request_chain() helper method and use it to implement reset handlers that must abort transactions. o Keep track of all pending requests on the new requests_pending_list in the softc. o Add default handlers to mpt.c to handle generic event notifications and controller reset activities. The event handler code is largely the same as in the original driver. The reset handler is new and terminates any pending transactions with a status code indicating the controller needs to be re-initialized. o Add some endian support to the driver. A complete audit is still required for this driver to have any hope of operating in a big-endian environment. o Use inttypes.h and __inline. Come closer to being style(9) compliant. o Remove extraneous use of typedefs. o Convert request state from a strict enumeration to a series of flags. This allows us to, for example, tag transactions that have timed-out while retaining the state that the transaction is still in-flight on the controller. o Add mpt_wait_req() which allows a caller to poll or sleep for the completion of a request. Use this to simplify and factor code out from many initialization routines. We also use this to sleep for task management request completions in our CAM timeout handler. mpt.c: o Correct a bug in the event handler where request structures were freed even if the request reply was marked as a continuation reply. Continuation replies indicate that the controller still owns the request and freeing these replies prematurely corrupted controller state. o Implement firmware upload and download. On controllers that do not have dedicated NVRAM (as in the Sun v20/v40z), the firmware image is downloaded to the controller by the system BIOS. This image occupies precious controller RAM space until the host driver fetches the image, reducing the number of concurrent I/Os the controller can processes. The uploaded image is used to re-program the controller during hard reset events since the controller cannot fetch the firmware on its own. Implementing this feature allows much higher queue depths when RAID volumes are configured. o Changed configuration page accessors to allow threads to sleep rather than busy wait for completion. o Removed hard coded data transfer sizes from configuration page routines so that RAID configuration page processing is possible. mpt_reg.h: o Move controller register definitions into a separate file. mpt.h: o Re-arrange includes to allow inlined functions to be defined in mpt.h. o Add reply, event, and reset handler definitions. o Add softc fields for handling timeout and controller reset recovery. mpt_cam.c: o Move mpt_freebsd.c to mpt_cam.c. Move all core functionality, such as event handling, into mpt.c leaving only CAM SCSI support here. o Revamp completion handler to provide correct CAM status for all currently defined SCSI MPI message result codes. o Register event and reset handlers with the MPT core. Modify the event handler to notify CAM of bus reset events. The controller reset handler will abort any transactions that have timed out. All other pending CAM transactions are correctly aborted by the core driver's reset handler. o Allocate a single request up front to perform task management operations. This guarantees that we can always perform a TMF operation even when the controller is saturated with other operations. The single request also serves as a perfect mechanism of guaranteeing that only a single TMF is in flight at a time - something that is required according to the MPT Fusion documentation. o Add a helper function for issuing task management requests to the controller. This is used to abort individual requests or perform a bus reset. o Modify the CAM XPT_BUS_RESET ccb handler to wait for and properly handle the status of the bus reset task management frame used to reset the bus. The previous code assumed that the reset request would always succeed. o Add timeout recovery support. When a timeout occurs, the timed-out request is added to a queue to be processed by our recovery thread and the thread is woken up. The recovery thread processes timed-out command serially, attempting first to abort them and then falling back to a bus reset if an abort fails. o Add calls to mpt_reset() to reset the controller if any handshake command, bus reset attempt or abort attempt fails due to a timeout. o Export a secondary "bus" to CAM that exposes all volume drive members as pass-thru devices, allowing CAM to perform proper speed negotiation to hidden devices. o Add a CAM async event handler tracking the AC_FOUND_DEVICE event. Use this to trigger calls to set the per-volume queue depth once the volume is fully registered with CAM. This is required to avoid hitting firmware limits on volume queue depth. Exceeding the limit causes the firmware to hang. mpt_cam.h: o Add several helper functions for interfacing to CAM and performing timeout recovery. mpt_pci.c: o Disable interrupts on the controller before registering and enabling interrupt delivery to the OS. Otherwise we risk receiving interrupts before the driver is ready to receive them. o Make use of compatibility macros that allow the driver to be compiled under 4.x and 5.x. mpt_raid.c: o Add a per-controller instance RAID thread to perform settings changes and query status (minimizes CPU busy wait loops). o Use a shutdown handler to disable "Member Write Cache Enable" (MWCE) setting for RAID arrays set to enable MWCE During Rebuild. o Change reply handler function signature to allow handlers to defer the deletion of reply frames. Use this to allow the event reply handler to queue up events that need to be acked if no resources are available to immediately ack an event. Queued events are processed in mpt_free_request() where resources are freed. This avoids a panic on resource shortage. o Parse and print out RAID controller capabilities during driver probe. o Define, allocate, and maintain RAID data structures for volumes, hidden member physical disks and spare disks. o Add dynamic sysctls for per-instance setting of the log level, array resync rate, array member cache enable, and volume queue depth. mpt_debug.c: o Add mpt_lprt and mpt_lprtc for printing diagnostics conditioned on a particular log level to aid in tracking down driver issues. o Add mpt_decode_value() which parses the bits in an integer value based on a parsing table (mask, value, name string, tuples). mpilib/*: o Update mpi library header files to latest distribution from LSI. Submitted by: gibbs Approved by: re
2005-07-10 15:05:39 +00:00
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
* LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF THE COPYRIGHT
* OWNER OR CONTRIBUTOR IS ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
#include <sys/cdefs.h>
__FBSDID("$FreeBSD$");
#include <dev/mpt/mpt.h>
#include <dev/mpt/mpt_raid.h>
#include "dev/mpt/mpilib/mpi_ioc.h" /* XXX Fix Event Handling!!! */
#include "dev/mpt/mpilib/mpi_raid.h"
#include <cam/cam.h>
#include <cam/cam_ccb.h>
#include <cam/cam_sim.h>
#include <cam/cam_xpt_sim.h>
#if __FreeBSD_version < 500000
#include <sys/devicestat.h>
#define GIANT_REQUIRED
#endif
Massive overhaul of MPT Fusion driver: o Add timeout error recovery (from a thread context to avoid the deferral of other critical interrupts). o Properly recover commands across controller reset events. o Update the driver to handle events and status codes that have been added to the MPI spec since the driver was originally written. o Make the driver more modular to improve maintainability and support dynamic "personality" registration (e.g. SCSI Initiator, RAID, SAS, FC, etc). o Shorten and simplify the common I/O path to improve driver performance. o Add RAID volume and RAID member state/settings reporting. o Add periodic volume resynchronization status reporting. o Add support for sysctl tunable resync rate, member write cache enable, and volume transaction queue depth. Sponsored by ---------------- Avid Technologies Inc: SCSI error recovery, driver re-organization, update of MPI library headers, portions of dynamic personality registration, and misc bug fixes. Wheel Open Technologies: RAID event notification, RAID member pass-thru support, firmware upload/download support, enhanced RAID resync speed, portions of dynamic personality registration, and misc bug fixes. Detailed Changes ================ mpt.c mpt_cam.c mpt_raid.c mpt_pci.c: o Add support for personality modules. Each module exports load, and unload module scope methods as well as probe, attach, event, reset, shutdown, and detach per-device instance methods mpt.c mpt.h mpt_pci.c: o The driver now associates a callback function (via an index) with every transaction submitted to the controller. This allows the main interrupt handler to absolve itself of any knowledge of individual transaction/response types by simply calling the callback function "registered" for the transaction. We use a callback index instead of a callback function pointer in each requests so we can properly handle responses (e.g. event notifications) that are not associated with a transaction. Personality modules dynamically register their callbacks with the driver core to receive the callback index to use for their handlers. o Move the interrupt handler into mpt.c. The ISR algorithm is bus transport and OS independent and thus had no reason to be in mpt_pci.c. o Simplify configuration message reply handling by copying reply frame data for the requester and storing completion status in the original request structure. o Add the mpt_complete_request_chain() helper method and use it to implement reset handlers that must abort transactions. o Keep track of all pending requests on the new requests_pending_list in the softc. o Add default handlers to mpt.c to handle generic event notifications and controller reset activities. The event handler code is largely the same as in the original driver. The reset handler is new and terminates any pending transactions with a status code indicating the controller needs to be re-initialized. o Add some endian support to the driver. A complete audit is still required for this driver to have any hope of operating in a big-endian environment. o Use inttypes.h and __inline. Come closer to being style(9) compliant. o Remove extraneous use of typedefs. o Convert request state from a strict enumeration to a series of flags. This allows us to, for example, tag transactions that have timed-out while retaining the state that the transaction is still in-flight on the controller. o Add mpt_wait_req() which allows a caller to poll or sleep for the completion of a request. Use this to simplify and factor code out from many initialization routines. We also use this to sleep for task management request completions in our CAM timeout handler. mpt.c: o Correct a bug in the event handler where request structures were freed even if the request reply was marked as a continuation reply. Continuation replies indicate that the controller still owns the request and freeing these replies prematurely corrupted controller state. o Implement firmware upload and download. On controllers that do not have dedicated NVRAM (as in the Sun v20/v40z), the firmware image is downloaded to the controller by the system BIOS. This image occupies precious controller RAM space until the host driver fetches the image, reducing the number of concurrent I/Os the controller can processes. The uploaded image is used to re-program the controller during hard reset events since the controller cannot fetch the firmware on its own. Implementing this feature allows much higher queue depths when RAID volumes are configured. o Changed configuration page accessors to allow threads to sleep rather than busy wait for completion. o Removed hard coded data transfer sizes from configuration page routines so that RAID configuration page processing is possible. mpt_reg.h: o Move controller register definitions into a separate file. mpt.h: o Re-arrange includes to allow inlined functions to be defined in mpt.h. o Add reply, event, and reset handler definitions. o Add softc fields for handling timeout and controller reset recovery. mpt_cam.c: o Move mpt_freebsd.c to mpt_cam.c. Move all core functionality, such as event handling, into mpt.c leaving only CAM SCSI support here. o Revamp completion handler to provide correct CAM status for all currently defined SCSI MPI message result codes. o Register event and reset handlers with the MPT core. Modify the event handler to notify CAM of bus reset events. The controller reset handler will abort any transactions that have timed out. All other pending CAM transactions are correctly aborted by the core driver's reset handler. o Allocate a single request up front to perform task management operations. This guarantees that we can always perform a TMF operation even when the controller is saturated with other operations. The single request also serves as a perfect mechanism of guaranteeing that only a single TMF is in flight at a time - something that is required according to the MPT Fusion documentation. o Add a helper function for issuing task management requests to the controller. This is used to abort individual requests or perform a bus reset. o Modify the CAM XPT_BUS_RESET ccb handler to wait for and properly handle the status of the bus reset task management frame used to reset the bus. The previous code assumed that the reset request would always succeed. o Add timeout recovery support. When a timeout occurs, the timed-out request is added to a queue to be processed by our recovery thread and the thread is woken up. The recovery thread processes timed-out command serially, attempting first to abort them and then falling back to a bus reset if an abort fails. o Add calls to mpt_reset() to reset the controller if any handshake command, bus reset attempt or abort attempt fails due to a timeout. o Export a secondary "bus" to CAM that exposes all volume drive members as pass-thru devices, allowing CAM to perform proper speed negotiation to hidden devices. o Add a CAM async event handler tracking the AC_FOUND_DEVICE event. Use this to trigger calls to set the per-volume queue depth once the volume is fully registered with CAM. This is required to avoid hitting firmware limits on volume queue depth. Exceeding the limit causes the firmware to hang. mpt_cam.h: o Add several helper functions for interfacing to CAM and performing timeout recovery. mpt_pci.c: o Disable interrupts on the controller before registering and enabling interrupt delivery to the OS. Otherwise we risk receiving interrupts before the driver is ready to receive them. o Make use of compatibility macros that allow the driver to be compiled under 4.x and 5.x. mpt_raid.c: o Add a per-controller instance RAID thread to perform settings changes and query status (minimizes CPU busy wait loops). o Use a shutdown handler to disable "Member Write Cache Enable" (MWCE) setting for RAID arrays set to enable MWCE During Rebuild. o Change reply handler function signature to allow handlers to defer the deletion of reply frames. Use this to allow the event reply handler to queue up events that need to be acked if no resources are available to immediately ack an event. Queued events are processed in mpt_free_request() where resources are freed. This avoids a panic on resource shortage. o Parse and print out RAID controller capabilities during driver probe. o Define, allocate, and maintain RAID data structures for volumes, hidden member physical disks and spare disks. o Add dynamic sysctls for per-instance setting of the log level, array resync rate, array member cache enable, and volume queue depth. mpt_debug.c: o Add mpt_lprt and mpt_lprtc for printing diagnostics conditioned on a particular log level to aid in tracking down driver issues. o Add mpt_decode_value() which parses the bits in an integer value based on a parsing table (mask, value, name string, tuples). mpilib/*: o Update mpi library header files to latest distribution from LSI. Submitted by: gibbs Approved by: re
2005-07-10 15:05:39 +00:00
#include <cam/cam_periph.h>
#include <sys/callout.h>
#include <sys/kthread.h>
#include <sys/sysctl.h>
#include <machine/stdarg.h>
struct mpt_raid_action_result
{
union {
MPI_RAID_VOL_INDICATOR indicator_struct;
uint32_t new_settings;
uint8_t phys_disk_num;
} action_data;
uint16_t action_status;
};
#define REQ_TO_RAID_ACTION_RESULT(req) ((struct mpt_raid_action_result *) \
(((MSG_RAID_ACTION_REQUEST *)(req->req_vbuf)) + 1))
#define REQ_IOCSTATUS(req) ((req)->IOCStatus & MPI_IOCSTATUS_MASK)
static mpt_probe_handler_t mpt_raid_probe;
static mpt_attach_handler_t mpt_raid_attach;
static mpt_event_handler_t mpt_raid_event;
static mpt_shutdown_handler_t mpt_raid_shutdown;
static mpt_reset_handler_t mpt_raid_ioc_reset;
static mpt_detach_handler_t mpt_raid_detach;
static struct mpt_personality mpt_raid_personality =
{
.name = "mpt_raid",
.probe = mpt_raid_probe,
.attach = mpt_raid_attach,
.event = mpt_raid_event,
.reset = mpt_raid_ioc_reset,
.shutdown = mpt_raid_shutdown,
.detach = mpt_raid_detach,
};
DECLARE_MPT_PERSONALITY(mpt_raid, SI_ORDER_THIRD);
MPT_PERSONALITY_DEPEND(mpt_raid, mpt_cam, 1, 1, 1);
static mpt_reply_handler_t mpt_raid_reply_handler;
static int mpt_raid_reply_frame_handler(struct mpt_softc *mpt, request_t *req,
MSG_DEFAULT_REPLY *reply_frame);
static int mpt_spawn_raid_thread(struct mpt_softc *mpt);
static void mpt_terminate_raid_thread(struct mpt_softc *mpt);
static void mpt_raid_thread(void *arg);
static timeout_t mpt_raid_timer;
static timeout_t mpt_raid_quiesce_timeout;
2005-12-04 02:12:43 +00:00
#if 0
Massive overhaul of MPT Fusion driver: o Add timeout error recovery (from a thread context to avoid the deferral of other critical interrupts). o Properly recover commands across controller reset events. o Update the driver to handle events and status codes that have been added to the MPI spec since the driver was originally written. o Make the driver more modular to improve maintainability and support dynamic "personality" registration (e.g. SCSI Initiator, RAID, SAS, FC, etc). o Shorten and simplify the common I/O path to improve driver performance. o Add RAID volume and RAID member state/settings reporting. o Add periodic volume resynchronization status reporting. o Add support for sysctl tunable resync rate, member write cache enable, and volume transaction queue depth. Sponsored by ---------------- Avid Technologies Inc: SCSI error recovery, driver re-organization, update of MPI library headers, portions of dynamic personality registration, and misc bug fixes. Wheel Open Technologies: RAID event notification, RAID member pass-thru support, firmware upload/download support, enhanced RAID resync speed, portions of dynamic personality registration, and misc bug fixes. Detailed Changes ================ mpt.c mpt_cam.c mpt_raid.c mpt_pci.c: o Add support for personality modules. Each module exports load, and unload module scope methods as well as probe, attach, event, reset, shutdown, and detach per-device instance methods mpt.c mpt.h mpt_pci.c: o The driver now associates a callback function (via an index) with every transaction submitted to the controller. This allows the main interrupt handler to absolve itself of any knowledge of individual transaction/response types by simply calling the callback function "registered" for the transaction. We use a callback index instead of a callback function pointer in each requests so we can properly handle responses (e.g. event notifications) that are not associated with a transaction. Personality modules dynamically register their callbacks with the driver core to receive the callback index to use for their handlers. o Move the interrupt handler into mpt.c. The ISR algorithm is bus transport and OS independent and thus had no reason to be in mpt_pci.c. o Simplify configuration message reply handling by copying reply frame data for the requester and storing completion status in the original request structure. o Add the mpt_complete_request_chain() helper method and use it to implement reset handlers that must abort transactions. o Keep track of all pending requests on the new requests_pending_list in the softc. o Add default handlers to mpt.c to handle generic event notifications and controller reset activities. The event handler code is largely the same as in the original driver. The reset handler is new and terminates any pending transactions with a status code indicating the controller needs to be re-initialized. o Add some endian support to the driver. A complete audit is still required for this driver to have any hope of operating in a big-endian environment. o Use inttypes.h and __inline. Come closer to being style(9) compliant. o Remove extraneous use of typedefs. o Convert request state from a strict enumeration to a series of flags. This allows us to, for example, tag transactions that have timed-out while retaining the state that the transaction is still in-flight on the controller. o Add mpt_wait_req() which allows a caller to poll or sleep for the completion of a request. Use this to simplify and factor code out from many initialization routines. We also use this to sleep for task management request completions in our CAM timeout handler. mpt.c: o Correct a bug in the event handler where request structures were freed even if the request reply was marked as a continuation reply. Continuation replies indicate that the controller still owns the request and freeing these replies prematurely corrupted controller state. o Implement firmware upload and download. On controllers that do not have dedicated NVRAM (as in the Sun v20/v40z), the firmware image is downloaded to the controller by the system BIOS. This image occupies precious controller RAM space until the host driver fetches the image, reducing the number of concurrent I/Os the controller can processes. The uploaded image is used to re-program the controller during hard reset events since the controller cannot fetch the firmware on its own. Implementing this feature allows much higher queue depths when RAID volumes are configured. o Changed configuration page accessors to allow threads to sleep rather than busy wait for completion. o Removed hard coded data transfer sizes from configuration page routines so that RAID configuration page processing is possible. mpt_reg.h: o Move controller register definitions into a separate file. mpt.h: o Re-arrange includes to allow inlined functions to be defined in mpt.h. o Add reply, event, and reset handler definitions. o Add softc fields for handling timeout and controller reset recovery. mpt_cam.c: o Move mpt_freebsd.c to mpt_cam.c. Move all core functionality, such as event handling, into mpt.c leaving only CAM SCSI support here. o Revamp completion handler to provide correct CAM status for all currently defined SCSI MPI message result codes. o Register event and reset handlers with the MPT core. Modify the event handler to notify CAM of bus reset events. The controller reset handler will abort any transactions that have timed out. All other pending CAM transactions are correctly aborted by the core driver's reset handler. o Allocate a single request up front to perform task management operations. This guarantees that we can always perform a TMF operation even when the controller is saturated with other operations. The single request also serves as a perfect mechanism of guaranteeing that only a single TMF is in flight at a time - something that is required according to the MPT Fusion documentation. o Add a helper function for issuing task management requests to the controller. This is used to abort individual requests or perform a bus reset. o Modify the CAM XPT_BUS_RESET ccb handler to wait for and properly handle the status of the bus reset task management frame used to reset the bus. The previous code assumed that the reset request would always succeed. o Add timeout recovery support. When a timeout occurs, the timed-out request is added to a queue to be processed by our recovery thread and the thread is woken up. The recovery thread processes timed-out command serially, attempting first to abort them and then falling back to a bus reset if an abort fails. o Add calls to mpt_reset() to reset the controller if any handshake command, bus reset attempt or abort attempt fails due to a timeout. o Export a secondary "bus" to CAM that exposes all volume drive members as pass-thru devices, allowing CAM to perform proper speed negotiation to hidden devices. o Add a CAM async event handler tracking the AC_FOUND_DEVICE event. Use this to trigger calls to set the per-volume queue depth once the volume is fully registered with CAM. This is required to avoid hitting firmware limits on volume queue depth. Exceeding the limit causes the firmware to hang. mpt_cam.h: o Add several helper functions for interfacing to CAM and performing timeout recovery. mpt_pci.c: o Disable interrupts on the controller before registering and enabling interrupt delivery to the OS. Otherwise we risk receiving interrupts before the driver is ready to receive them. o Make use of compatibility macros that allow the driver to be compiled under 4.x and 5.x. mpt_raid.c: o Add a per-controller instance RAID thread to perform settings changes and query status (minimizes CPU busy wait loops). o Use a shutdown handler to disable "Member Write Cache Enable" (MWCE) setting for RAID arrays set to enable MWCE During Rebuild. o Change reply handler function signature to allow handlers to defer the deletion of reply frames. Use this to allow the event reply handler to queue up events that need to be acked if no resources are available to immediately ack an event. Queued events are processed in mpt_free_request() where resources are freed. This avoids a panic on resource shortage. o Parse and print out RAID controller capabilities during driver probe. o Define, allocate, and maintain RAID data structures for volumes, hidden member physical disks and spare disks. o Add dynamic sysctls for per-instance setting of the log level, array resync rate, array member cache enable, and volume queue depth. mpt_debug.c: o Add mpt_lprt and mpt_lprtc for printing diagnostics conditioned on a particular log level to aid in tracking down driver issues. o Add mpt_decode_value() which parses the bits in an integer value based on a parsing table (mask, value, name string, tuples). mpilib/*: o Update mpi library header files to latest distribution from LSI. Submitted by: gibbs Approved by: re
2005-07-10 15:05:39 +00:00
static void mpt_enable_vol(struct mpt_softc *mpt,
struct mpt_raid_volume *mpt_vol, int enable);
#endif
static void mpt_verify_mwce(struct mpt_softc *mpt,
struct mpt_raid_volume *mpt_vol);
static void mpt_adjust_queue_depth(struct mpt_softc *mpt,
struct mpt_raid_volume *mpt_vol,
struct cam_path *path);
static void mpt_raid_sysctl_attach(struct mpt_softc *mpt);
static uint32_t raid_handler_id = MPT_HANDLER_ID_NONE;
const char *
mpt_vol_type(struct mpt_raid_volume *vol)
{
switch (vol->config_page->VolumeType) {
case MPI_RAID_VOL_TYPE_IS:
return ("RAID-0");
case MPI_RAID_VOL_TYPE_IME:
return ("RAID-1E");
case MPI_RAID_VOL_TYPE_IM:
return ("RAID-1");
default:
return ("Unknown");
}
}
const char *
mpt_vol_state(struct mpt_raid_volume *vol)
{
switch (vol->config_page->VolumeStatus.State) {
case MPI_RAIDVOL0_STATUS_STATE_OPTIMAL:
return ("Optimal");
case MPI_RAIDVOL0_STATUS_STATE_DEGRADED:
return ("Degraded");
case MPI_RAIDVOL0_STATUS_STATE_FAILED:
return ("Failed");
default:
return ("Unknown");
}
}
const char *
mpt_disk_state(struct mpt_raid_disk *disk)
{
switch (disk->config_page.PhysDiskStatus.State) {
case MPI_PHYSDISK0_STATUS_ONLINE:
return ("Online");
case MPI_PHYSDISK0_STATUS_MISSING:
return ("Missing");
case MPI_PHYSDISK0_STATUS_NOT_COMPATIBLE:
return ("Incompatible");
case MPI_PHYSDISK0_STATUS_FAILED:
return ("Failed");
case MPI_PHYSDISK0_STATUS_INITIALIZING:
return ("Initializing");
case MPI_PHYSDISK0_STATUS_OFFLINE_REQUESTED:
return ("Offline Requested");
case MPI_PHYSDISK0_STATUS_FAILED_REQUESTED:
return ("Failed per Host Request");
case MPI_PHYSDISK0_STATUS_OTHER_OFFLINE:
return ("Offline");
default:
return ("Unknown");
}
}
void
mpt_vol_prt(struct mpt_softc *mpt, struct mpt_raid_volume *vol,
const char *fmt, ...)
{
va_list ap;
printf("%s:vol%d(%s:%d:%d): ", device_get_nameunit(mpt->dev),
(u_int)(vol - mpt->raid_volumes), device_get_nameunit(mpt->dev),
vol->config_page->VolumeBus, vol->config_page->VolumeID);
va_start(ap, fmt);
vprintf(fmt, ap);
va_end(ap);
}
void
mpt_disk_prt(struct mpt_softc *mpt, struct mpt_raid_disk *disk,
const char *fmt, ...)
{
va_list ap;
if (disk->volume != NULL) {
printf("(%s:vol%d:%d): ",
device_get_nameunit(mpt->dev),
disk->volume->config_page->VolumeID,
disk->member_number);
} else {
printf("(%s:%d:%d): ", device_get_nameunit(mpt->dev),
disk->config_page.PhysDiskBus,
disk->config_page.PhysDiskID);
}
va_start(ap, fmt);
vprintf(fmt, ap);
va_end(ap);
}
static void
mpt_raid_async(void *callback_arg, u_int32_t code,
struct cam_path *path, void *arg)
{
struct mpt_softc *mpt;
mpt = (struct mpt_softc*)callback_arg;
switch (code) {
case AC_FOUND_DEVICE:
{
struct ccb_getdev *cgd;
struct mpt_raid_volume *mpt_vol;
cgd = (struct ccb_getdev *)arg;
if (cgd == NULL)
break;
mpt_lprt(mpt, MPT_PRT_DEBUG, " Callback for %d\n",
cgd->ccb_h.target_id);
RAID_VOL_FOREACH(mpt, mpt_vol) {
if ((mpt_vol->flags & MPT_RVF_ACTIVE) == 0)
continue;
if (mpt_vol->config_page->VolumeID
== cgd->ccb_h.target_id) {
mpt_adjust_queue_depth(mpt, mpt_vol, path);
break;
}
}
}
default:
break;
}
}
int
mpt_raid_probe(struct mpt_softc *mpt)
{
if (mpt->ioc_page2 == NULL || mpt->ioc_page2->MaxPhysDisks == 0) {
Massive overhaul of MPT Fusion driver: o Add timeout error recovery (from a thread context to avoid the deferral of other critical interrupts). o Properly recover commands across controller reset events. o Update the driver to handle events and status codes that have been added to the MPI spec since the driver was originally written. o Make the driver more modular to improve maintainability and support dynamic "personality" registration (e.g. SCSI Initiator, RAID, SAS, FC, etc). o Shorten and simplify the common I/O path to improve driver performance. o Add RAID volume and RAID member state/settings reporting. o Add periodic volume resynchronization status reporting. o Add support for sysctl tunable resync rate, member write cache enable, and volume transaction queue depth. Sponsored by ---------------- Avid Technologies Inc: SCSI error recovery, driver re-organization, update of MPI library headers, portions of dynamic personality registration, and misc bug fixes. Wheel Open Technologies: RAID event notification, RAID member pass-thru support, firmware upload/download support, enhanced RAID resync speed, portions of dynamic personality registration, and misc bug fixes. Detailed Changes ================ mpt.c mpt_cam.c mpt_raid.c mpt_pci.c: o Add support for personality modules. Each module exports load, and unload module scope methods as well as probe, attach, event, reset, shutdown, and detach per-device instance methods mpt.c mpt.h mpt_pci.c: o The driver now associates a callback function (via an index) with every transaction submitted to the controller. This allows the main interrupt handler to absolve itself of any knowledge of individual transaction/response types by simply calling the callback function "registered" for the transaction. We use a callback index instead of a callback function pointer in each requests so we can properly handle responses (e.g. event notifications) that are not associated with a transaction. Personality modules dynamically register their callbacks with the driver core to receive the callback index to use for their handlers. o Move the interrupt handler into mpt.c. The ISR algorithm is bus transport and OS independent and thus had no reason to be in mpt_pci.c. o Simplify configuration message reply handling by copying reply frame data for the requester and storing completion status in the original request structure. o Add the mpt_complete_request_chain() helper method and use it to implement reset handlers that must abort transactions. o Keep track of all pending requests on the new requests_pending_list in the softc. o Add default handlers to mpt.c to handle generic event notifications and controller reset activities. The event handler code is largely the same as in the original driver. The reset handler is new and terminates any pending transactions with a status code indicating the controller needs to be re-initialized. o Add some endian support to the driver. A complete audit is still required for this driver to have any hope of operating in a big-endian environment. o Use inttypes.h and __inline. Come closer to being style(9) compliant. o Remove extraneous use of typedefs. o Convert request state from a strict enumeration to a series of flags. This allows us to, for example, tag transactions that have timed-out while retaining the state that the transaction is still in-flight on the controller. o Add mpt_wait_req() which allows a caller to poll or sleep for the completion of a request. Use this to simplify and factor code out from many initialization routines. We also use this to sleep for task management request completions in our CAM timeout handler. mpt.c: o Correct a bug in the event handler where request structures were freed even if the request reply was marked as a continuation reply. Continuation replies indicate that the controller still owns the request and freeing these replies prematurely corrupted controller state. o Implement firmware upload and download. On controllers that do not have dedicated NVRAM (as in the Sun v20/v40z), the firmware image is downloaded to the controller by the system BIOS. This image occupies precious controller RAM space until the host driver fetches the image, reducing the number of concurrent I/Os the controller can processes. The uploaded image is used to re-program the controller during hard reset events since the controller cannot fetch the firmware on its own. Implementing this feature allows much higher queue depths when RAID volumes are configured. o Changed configuration page accessors to allow threads to sleep rather than busy wait for completion. o Removed hard coded data transfer sizes from configuration page routines so that RAID configuration page processing is possible. mpt_reg.h: o Move controller register definitions into a separate file. mpt.h: o Re-arrange includes to allow inlined functions to be defined in mpt.h. o Add reply, event, and reset handler definitions. o Add softc fields for handling timeout and controller reset recovery. mpt_cam.c: o Move mpt_freebsd.c to mpt_cam.c. Move all core functionality, such as event handling, into mpt.c leaving only CAM SCSI support here. o Revamp completion handler to provide correct CAM status for all currently defined SCSI MPI message result codes. o Register event and reset handlers with the MPT core. Modify the event handler to notify CAM of bus reset events. The controller reset handler will abort any transactions that have timed out. All other pending CAM transactions are correctly aborted by the core driver's reset handler. o Allocate a single request up front to perform task management operations. This guarantees that we can always perform a TMF operation even when the controller is saturated with other operations. The single request also serves as a perfect mechanism of guaranteeing that only a single TMF is in flight at a time - something that is required according to the MPT Fusion documentation. o Add a helper function for issuing task management requests to the controller. This is used to abort individual requests or perform a bus reset. o Modify the CAM XPT_BUS_RESET ccb handler to wait for and properly handle the status of the bus reset task management frame used to reset the bus. The previous code assumed that the reset request would always succeed. o Add timeout recovery support. When a timeout occurs, the timed-out request is added to a queue to be processed by our recovery thread and the thread is woken up. The recovery thread processes timed-out command serially, attempting first to abort them and then falling back to a bus reset if an abort fails. o Add calls to mpt_reset() to reset the controller if any handshake command, bus reset attempt or abort attempt fails due to a timeout. o Export a secondary "bus" to CAM that exposes all volume drive members as pass-thru devices, allowing CAM to perform proper speed negotiation to hidden devices. o Add a CAM async event handler tracking the AC_FOUND_DEVICE event. Use this to trigger calls to set the per-volume queue depth once the volume is fully registered with CAM. This is required to avoid hitting firmware limits on volume queue depth. Exceeding the limit causes the firmware to hang. mpt_cam.h: o Add several helper functions for interfacing to CAM and performing timeout recovery. mpt_pci.c: o Disable interrupts on the controller before registering and enabling interrupt delivery to the OS. Otherwise we risk receiving interrupts before the driver is ready to receive them. o Make use of compatibility macros that allow the driver to be compiled under 4.x and 5.x. mpt_raid.c: o Add a per-controller instance RAID thread to perform settings changes and query status (minimizes CPU busy wait loops). o Use a shutdown handler to disable "Member Write Cache Enable" (MWCE) setting for RAID arrays set to enable MWCE During Rebuild. o Change reply handler function signature to allow handlers to defer the deletion of reply frames. Use this to allow the event reply handler to queue up events that need to be acked if no resources are available to immediately ack an event. Queued events are processed in mpt_free_request() where resources are freed. This avoids a panic on resource shortage. o Parse and print out RAID controller capabilities during driver probe. o Define, allocate, and maintain RAID data structures for volumes, hidden member physical disks and spare disks. o Add dynamic sysctls for per-instance setting of the log level, array resync rate, array member cache enable, and volume queue depth. mpt_debug.c: o Add mpt_lprt and mpt_lprtc for printing diagnostics conditioned on a particular log level to aid in tracking down driver issues. o Add mpt_decode_value() which parses the bits in an integer value based on a parsing table (mask, value, name string, tuples). mpilib/*: o Update mpi library header files to latest distribution from LSI. Submitted by: gibbs Approved by: re
2005-07-10 15:05:39 +00:00
return (ENODEV);
}
Massive overhaul of MPT Fusion driver: o Add timeout error recovery (from a thread context to avoid the deferral of other critical interrupts). o Properly recover commands across controller reset events. o Update the driver to handle events and status codes that have been added to the MPI spec since the driver was originally written. o Make the driver more modular to improve maintainability and support dynamic "personality" registration (e.g. SCSI Initiator, RAID, SAS, FC, etc). o Shorten and simplify the common I/O path to improve driver performance. o Add RAID volume and RAID member state/settings reporting. o Add periodic volume resynchronization status reporting. o Add support for sysctl tunable resync rate, member write cache enable, and volume transaction queue depth. Sponsored by ---------------- Avid Technologies Inc: SCSI error recovery, driver re-organization, update of MPI library headers, portions of dynamic personality registration, and misc bug fixes. Wheel Open Technologies: RAID event notification, RAID member pass-thru support, firmware upload/download support, enhanced RAID resync speed, portions of dynamic personality registration, and misc bug fixes. Detailed Changes ================ mpt.c mpt_cam.c mpt_raid.c mpt_pci.c: o Add support for personality modules. Each module exports load, and unload module scope methods as well as probe, attach, event, reset, shutdown, and detach per-device instance methods mpt.c mpt.h mpt_pci.c: o The driver now associates a callback function (via an index) with every transaction submitted to the controller. This allows the main interrupt handler to absolve itself of any knowledge of individual transaction/response types by simply calling the callback function "registered" for the transaction. We use a callback index instead of a callback function pointer in each requests so we can properly handle responses (e.g. event notifications) that are not associated with a transaction. Personality modules dynamically register their callbacks with the driver core to receive the callback index to use for their handlers. o Move the interrupt handler into mpt.c. The ISR algorithm is bus transport and OS independent and thus had no reason to be in mpt_pci.c. o Simplify configuration message reply handling by copying reply frame data for the requester and storing completion status in the original request structure. o Add the mpt_complete_request_chain() helper method and use it to implement reset handlers that must abort transactions. o Keep track of all pending requests on the new requests_pending_list in the softc. o Add default handlers to mpt.c to handle generic event notifications and controller reset activities. The event handler code is largely the same as in the original driver. The reset handler is new and terminates any pending transactions with a status code indicating the controller needs to be re-initialized. o Add some endian support to the driver. A complete audit is still required for this driver to have any hope of operating in a big-endian environment. o Use inttypes.h and __inline. Come closer to being style(9) compliant. o Remove extraneous use of typedefs. o Convert request state from a strict enumeration to a series of flags. This allows us to, for example, tag transactions that have timed-out while retaining the state that the transaction is still in-flight on the controller. o Add mpt_wait_req() which allows a caller to poll or sleep for the completion of a request. Use this to simplify and factor code out from many initialization routines. We also use this to sleep for task management request completions in our CAM timeout handler. mpt.c: o Correct a bug in the event handler where request structures were freed even if the request reply was marked as a continuation reply. Continuation replies indicate that the controller still owns the request and freeing these replies prematurely corrupted controller state. o Implement firmware upload and download. On controllers that do not have dedicated NVRAM (as in the Sun v20/v40z), the firmware image is downloaded to the controller by the system BIOS. This image occupies precious controller RAM space until the host driver fetches the image, reducing the number of concurrent I/Os the controller can processes. The uploaded image is used to re-program the controller during hard reset events since the controller cannot fetch the firmware on its own. Implementing this feature allows much higher queue depths when RAID volumes are configured. o Changed configuration page accessors to allow threads to sleep rather than busy wait for completion. o Removed hard coded data transfer sizes from configuration page routines so that RAID configuration page processing is possible. mpt_reg.h: o Move controller register definitions into a separate file. mpt.h: o Re-arrange includes to allow inlined functions to be defined in mpt.h. o Add reply, event, and reset handler definitions. o Add softc fields for handling timeout and controller reset recovery. mpt_cam.c: o Move mpt_freebsd.c to mpt_cam.c. Move all core functionality, such as event handling, into mpt.c leaving only CAM SCSI support here. o Revamp completion handler to provide correct CAM status for all currently defined SCSI MPI message result codes. o Register event and reset handlers with the MPT core. Modify the event handler to notify CAM of bus reset events. The controller reset handler will abort any transactions that have timed out. All other pending CAM transactions are correctly aborted by the core driver's reset handler. o Allocate a single request up front to perform task management operations. This guarantees that we can always perform a TMF operation even when the controller is saturated with other operations. The single request also serves as a perfect mechanism of guaranteeing that only a single TMF is in flight at a time - something that is required according to the MPT Fusion documentation. o Add a helper function for issuing task management requests to the controller. This is used to abort individual requests or perform a bus reset. o Modify the CAM XPT_BUS_RESET ccb handler to wait for and properly handle the status of the bus reset task management frame used to reset the bus. The previous code assumed that the reset request would always succeed. o Add timeout recovery support. When a timeout occurs, the timed-out request is added to a queue to be processed by our recovery thread and the thread is woken up. The recovery thread processes timed-out command serially, attempting first to abort them and then falling back to a bus reset if an abort fails. o Add calls to mpt_reset() to reset the controller if any handshake command, bus reset attempt or abort attempt fails due to a timeout. o Export a secondary "bus" to CAM that exposes all volume drive members as pass-thru devices, allowing CAM to perform proper speed negotiation to hidden devices. o Add a CAM async event handler tracking the AC_FOUND_DEVICE event. Use this to trigger calls to set the per-volume queue depth once the volume is fully registered with CAM. This is required to avoid hitting firmware limits on volume queue depth. Exceeding the limit causes the firmware to hang. mpt_cam.h: o Add several helper functions for interfacing to CAM and performing timeout recovery. mpt_pci.c: o Disable interrupts on the controller before registering and enabling interrupt delivery to the OS. Otherwise we risk receiving interrupts before the driver is ready to receive them. o Make use of compatibility macros that allow the driver to be compiled under 4.x and 5.x. mpt_raid.c: o Add a per-controller instance RAID thread to perform settings changes and query status (minimizes CPU busy wait loops). o Use a shutdown handler to disable "Member Write Cache Enable" (MWCE) setting for RAID arrays set to enable MWCE During Rebuild. o Change reply handler function signature to allow handlers to defer the deletion of reply frames. Use this to allow the event reply handler to queue up events that need to be acked if no resources are available to immediately ack an event. Queued events are processed in mpt_free_request() where resources are freed. This avoids a panic on resource shortage. o Parse and print out RAID controller capabilities during driver probe. o Define, allocate, and maintain RAID data structures for volumes, hidden member physical disks and spare disks. o Add dynamic sysctls for per-instance setting of the log level, array resync rate, array member cache enable, and volume queue depth. mpt_debug.c: o Add mpt_lprt and mpt_lprtc for printing diagnostics conditioned on a particular log level to aid in tracking down driver issues. o Add mpt_decode_value() which parses the bits in an integer value based on a parsing table (mask, value, name string, tuples). mpilib/*: o Update mpi library header files to latest distribution from LSI. Submitted by: gibbs Approved by: re
2005-07-10 15:05:39 +00:00
return (0);
}
int
mpt_raid_attach(struct mpt_softc *mpt)
{
struct ccb_setasync csa;
mpt_handler_t handler;
int error;
mpt_callout_init(&mpt->raid_timer);
handler.reply_handler = mpt_raid_reply_handler;
error = mpt_register_handler(mpt, MPT_HANDLER_REPLY, handler,
&raid_handler_id);
if (error != 0)
goto cleanup;
error = mpt_spawn_raid_thread(mpt);
if (error != 0) {
mpt_prt(mpt, "Unable to spawn RAID thread!\n");
goto cleanup;
}
xpt_setup_ccb(&csa.ccb_h, mpt->path, /*priority*/5);
csa.ccb_h.func_code = XPT_SASYNC_CB;
csa.event_enable = AC_FOUND_DEVICE;
csa.callback = mpt_raid_async;
csa.callback_arg = mpt;
xpt_action((union ccb *)&csa);
if (csa.ccb_h.status != CAM_REQ_CMP) {
mpt_prt(mpt, "mpt_raid_attach: Unable to register "
"CAM async handler.\n");
}
mpt_raid_sysctl_attach(mpt);
return (0);
cleanup:
mpt_raid_detach(mpt);
return (error);
}
void
mpt_raid_detach(struct mpt_softc *mpt)
{
struct ccb_setasync csa;
mpt_handler_t handler;
callout_stop(&mpt->raid_timer);
mpt_terminate_raid_thread(mpt);
handler.reply_handler = mpt_raid_reply_handler;
mpt_deregister_handler(mpt, MPT_HANDLER_REPLY, handler,
raid_handler_id);
xpt_setup_ccb(&csa.ccb_h, mpt->path, /*priority*/5);
csa.ccb_h.func_code = XPT_SASYNC_CB;
csa.event_enable = 0;
csa.callback = mpt_raid_async;
csa.callback_arg = mpt;
xpt_action((union ccb *)&csa);
}
static void
mpt_raid_ioc_reset(struct mpt_softc *mpt, int type)
{
/* Nothing to do yet. */
}
static const char *raid_event_txt[] =
{
"Volume Created",
"Volume Deleted",
"Volume Settings Changed",
"Volume Status Changed",
"Volume Physical Disk Membership Changed",
"Physical Disk Created",
"Physical Disk Deleted",
"Physical Disk Settings Changed",
"Physical Disk Status Changed",
"Domain Validation Required",
"SMART Data Received",
"Replace Action Started",
};
static int
mpt_raid_event(struct mpt_softc *mpt, request_t *req,
MSG_EVENT_NOTIFY_REPLY *msg)
{
EVENT_DATA_RAID *raid_event;
struct mpt_raid_volume *mpt_vol;
struct mpt_raid_disk *mpt_disk;
CONFIG_PAGE_RAID_VOL_0 *vol_pg;
int i;
int print_event;
if (msg->Event != MPI_EVENT_INTEGRATED_RAID)
return (/*handled*/0);
raid_event = (EVENT_DATA_RAID *)&msg->Data;
mpt_vol = NULL;
vol_pg = NULL;
if (mpt->raid_volumes != NULL && mpt->ioc_page2 != NULL) {
for (i = 0; i < mpt->ioc_page2->MaxVolumes; i++) {
mpt_vol = &mpt->raid_volumes[i];
vol_pg = mpt_vol->config_page;
if ((mpt_vol->flags & MPT_RVF_ACTIVE) == 0)
continue;
if (vol_pg->VolumeID == raid_event->VolumeID
&& vol_pg->VolumeBus == raid_event->VolumeBus)
break;
}
if (i >= mpt->ioc_page2->MaxVolumes) {
mpt_vol = NULL;
vol_pg = NULL;
}
}
mpt_disk = NULL;
if (raid_event->PhysDiskNum != 0xFF
&& mpt->raid_disks != NULL) {
mpt_disk = mpt->raid_disks
+ raid_event->PhysDiskNum;
if ((mpt_disk->flags & MPT_RDF_ACTIVE) == 0)
mpt_disk = NULL;
}
print_event = 1;
switch(raid_event->ReasonCode) {
case MPI_EVENT_RAID_RC_VOLUME_CREATED:
case MPI_EVENT_RAID_RC_VOLUME_DELETED:
break;
case MPI_EVENT_RAID_RC_VOLUME_STATUS_CHANGED:
if (mpt_vol != NULL) {
if ((mpt_vol->flags & MPT_RVF_UP2DATE) != 0) {
mpt_vol->flags &= ~MPT_RVF_UP2DATE;
} else {
/*
* Coalesce status messages into one
* per background run of our RAID thread.
* This removes "spurious" status messages
* from our output.
*/
print_event = 0;
}
}
break;
case MPI_EVENT_RAID_RC_VOLUME_SETTINGS_CHANGED:
case MPI_EVENT_RAID_RC_VOLUME_PHYSDISK_CHANGED:
mpt->raid_rescan++;
if (mpt_vol != NULL)
mpt_vol->flags &= ~(MPT_RVF_UP2DATE|MPT_RVF_ANNOUNCED);
break;
case MPI_EVENT_RAID_RC_PHYSDISK_CREATED:
case MPI_EVENT_RAID_RC_PHYSDISK_DELETED:
mpt->raid_rescan++;
break;
case MPI_EVENT_RAID_RC_PHYSDISK_SETTINGS_CHANGED:
case MPI_EVENT_RAID_RC_PHYSDISK_STATUS_CHANGED:
mpt->raid_rescan++;
if (mpt_disk != NULL)
mpt_disk->flags &= ~MPT_RDF_UP2DATE;
break;
case MPI_EVENT_RAID_RC_DOMAIN_VAL_NEEDED:
mpt->raid_rescan++;
break;
case MPI_EVENT_RAID_RC_SMART_DATA:
case MPI_EVENT_RAID_RC_REPLACE_ACTION_STARTED:
break;
}
if (print_event) {
if (mpt_disk != NULL) {
mpt_disk_prt(mpt, mpt_disk, "");
} else if (mpt_vol != NULL) {
mpt_vol_prt(mpt, mpt_vol, "");
} else {
mpt_prt(mpt, "Volume(%d:%d", raid_event->VolumeBus,
raid_event->VolumeID);
if (raid_event->PhysDiskNum != 0xFF)
mpt_prtc(mpt, ":%d): ",
raid_event->PhysDiskNum);
else
mpt_prtc(mpt, "): ");
}
if (raid_event->ReasonCode >= NUM_ELEMENTS(raid_event_txt))
mpt_prtc(mpt, "Unhandled RaidEvent %#x\n",
raid_event->ReasonCode);
else
mpt_prtc(mpt, "%s\n",
raid_event_txt[raid_event->ReasonCode]);
}
if (raid_event->ReasonCode == MPI_EVENT_RAID_RC_SMART_DATA) {
/* XXX Use CAM's print sense for this... */
if (mpt_disk != NULL)
mpt_disk_prt(mpt, mpt_disk, "");
else
mpt_prt(mpt, "Volume(%d:%d:%d: ",
raid_event->VolumeBus, raid_event->VolumeID,
raid_event->PhysDiskNum);
mpt_prtc(mpt, "ASC 0x%x, ASCQ 0x%x)\n",
Massive overhaul of MPT Fusion driver: o Add timeout error recovery (from a thread context to avoid the deferral of other critical interrupts). o Properly recover commands across controller reset events. o Update the driver to handle events and status codes that have been added to the MPI spec since the driver was originally written. o Make the driver more modular to improve maintainability and support dynamic "personality" registration (e.g. SCSI Initiator, RAID, SAS, FC, etc). o Shorten and simplify the common I/O path to improve driver performance. o Add RAID volume and RAID member state/settings reporting. o Add periodic volume resynchronization status reporting. o Add support for sysctl tunable resync rate, member write cache enable, and volume transaction queue depth. Sponsored by ---------------- Avid Technologies Inc: SCSI error recovery, driver re-organization, update of MPI library headers, portions of dynamic personality registration, and misc bug fixes. Wheel Open Technologies: RAID event notification, RAID member pass-thru support, firmware upload/download support, enhanced RAID resync speed, portions of dynamic personality registration, and misc bug fixes. Detailed Changes ================ mpt.c mpt_cam.c mpt_raid.c mpt_pci.c: o Add support for personality modules. Each module exports load, and unload module scope methods as well as probe, attach, event, reset, shutdown, and detach per-device instance methods mpt.c mpt.h mpt_pci.c: o The driver now associates a callback function (via an index) with every transaction submitted to the controller. This allows the main interrupt handler to absolve itself of any knowledge of individual transaction/response types by simply calling the callback function "registered" for the transaction. We use a callback index instead of a callback function pointer in each requests so we can properly handle responses (e.g. event notifications) that are not associated with a transaction. Personality modules dynamically register their callbacks with the driver core to receive the callback index to use for their handlers. o Move the interrupt handler into mpt.c. The ISR algorithm is bus transport and OS independent and thus had no reason to be in mpt_pci.c. o Simplify configuration message reply handling by copying reply frame data for the requester and storing completion status in the original request structure. o Add the mpt_complete_request_chain() helper method and use it to implement reset handlers that must abort transactions. o Keep track of all pending requests on the new requests_pending_list in the softc. o Add default handlers to mpt.c to handle generic event notifications and controller reset activities. The event handler code is largely the same as in the original driver. The reset handler is new and terminates any pending transactions with a status code indicating the controller needs to be re-initialized. o Add some endian support to the driver. A complete audit is still required for this driver to have any hope of operating in a big-endian environment. o Use inttypes.h and __inline. Come closer to being style(9) compliant. o Remove extraneous use of typedefs. o Convert request state from a strict enumeration to a series of flags. This allows us to, for example, tag transactions that have timed-out while retaining the state that the transaction is still in-flight on the controller. o Add mpt_wait_req() which allows a caller to poll or sleep for the completion of a request. Use this to simplify and factor code out from many initialization routines. We also use this to sleep for task management request completions in our CAM timeout handler. mpt.c: o Correct a bug in the event handler where request structures were freed even if the request reply was marked as a continuation reply. Continuation replies indicate that the controller still owns the request and freeing these replies prematurely corrupted controller state. o Implement firmware upload and download. On controllers that do not have dedicated NVRAM (as in the Sun v20/v40z), the firmware image is downloaded to the controller by the system BIOS. This image occupies precious controller RAM space until the host driver fetches the image, reducing the number of concurrent I/Os the controller can processes. The uploaded image is used to re-program the controller during hard reset events since the controller cannot fetch the firmware on its own. Implementing this feature allows much higher queue depths when RAID volumes are configured. o Changed configuration page accessors to allow threads to sleep rather than busy wait for completion. o Removed hard coded data transfer sizes from configuration page routines so that RAID configuration page processing is possible. mpt_reg.h: o Move controller register definitions into a separate file. mpt.h: o Re-arrange includes to allow inlined functions to be defined in mpt.h. o Add reply, event, and reset handler definitions. o Add softc fields for handling timeout and controller reset recovery. mpt_cam.c: o Move mpt_freebsd.c to mpt_cam.c. Move all core functionality, such as event handling, into mpt.c leaving only CAM SCSI support here. o Revamp completion handler to provide correct CAM status for all currently defined SCSI MPI message result codes. o Register event and reset handlers with the MPT core. Modify the event handler to notify CAM of bus reset events. The controller reset handler will abort any transactions that have timed out. All other pending CAM transactions are correctly aborted by the core driver's reset handler. o Allocate a single request up front to perform task management operations. This guarantees that we can always perform a TMF operation even when the controller is saturated with other operations. The single request also serves as a perfect mechanism of guaranteeing that only a single TMF is in flight at a time - something that is required according to the MPT Fusion documentation. o Add a helper function for issuing task management requests to the controller. This is used to abort individual requests or perform a bus reset. o Modify the CAM XPT_BUS_RESET ccb handler to wait for and properly handle the status of the bus reset task management frame used to reset the bus. The previous code assumed that the reset request would always succeed. o Add timeout recovery support. When a timeout occurs, the timed-out request is added to a queue to be processed by our recovery thread and the thread is woken up. The recovery thread processes timed-out command serially, attempting first to abort them and then falling back to a bus reset if an abort fails. o Add calls to mpt_reset() to reset the controller if any handshake command, bus reset attempt or abort attempt fails due to a timeout. o Export a secondary "bus" to CAM that exposes all volume drive members as pass-thru devices, allowing CAM to perform proper speed negotiation to hidden devices. o Add a CAM async event handler tracking the AC_FOUND_DEVICE event. Use this to trigger calls to set the per-volume queue depth once the volume is fully registered with CAM. This is required to avoid hitting firmware limits on volume queue depth. Exceeding the limit causes the firmware to hang. mpt_cam.h: o Add several helper functions for interfacing to CAM and performing timeout recovery. mpt_pci.c: o Disable interrupts on the controller before registering and enabling interrupt delivery to the OS. Otherwise we risk receiving interrupts before the driver is ready to receive them. o Make use of compatibility macros that allow the driver to be compiled under 4.x and 5.x. mpt_raid.c: o Add a per-controller instance RAID thread to perform settings changes and query status (minimizes CPU busy wait loops). o Use a shutdown handler to disable "Member Write Cache Enable" (MWCE) setting for RAID arrays set to enable MWCE During Rebuild. o Change reply handler function signature to allow handlers to defer the deletion of reply frames. Use this to allow the event reply handler to queue up events that need to be acked if no resources are available to immediately ack an event. Queued events are processed in mpt_free_request() where resources are freed. This avoids a panic on resource shortage. o Parse and print out RAID controller capabilities during driver probe. o Define, allocate, and maintain RAID data structures for volumes, hidden member physical disks and spare disks. o Add dynamic sysctls for per-instance setting of the log level, array resync rate, array member cache enable, and volume queue depth. mpt_debug.c: o Add mpt_lprt and mpt_lprtc for printing diagnostics conditioned on a particular log level to aid in tracking down driver issues. o Add mpt_decode_value() which parses the bits in an integer value based on a parsing table (mask, value, name string, tuples). mpilib/*: o Update mpi library header files to latest distribution from LSI. Submitted by: gibbs Approved by: re
2005-07-10 15:05:39 +00:00
raid_event->ASC, raid_event->ASCQ);
}
mpt_raid_wakeup(mpt);
return (/*handled*/1);
}
static void
mpt_raid_shutdown(struct mpt_softc *mpt)
{
struct mpt_raid_volume *mpt_vol;
if (mpt->raid_mwce_setting != MPT_RAID_MWCE_REBUILD_ONLY) {
Massive overhaul of MPT Fusion driver: o Add timeout error recovery (from a thread context to avoid the deferral of other critical interrupts). o Properly recover commands across controller reset events. o Update the driver to handle events and status codes that have been added to the MPI spec since the driver was originally written. o Make the driver more modular to improve maintainability and support dynamic "personality" registration (e.g. SCSI Initiator, RAID, SAS, FC, etc). o Shorten and simplify the common I/O path to improve driver performance. o Add RAID volume and RAID member state/settings reporting. o Add periodic volume resynchronization status reporting. o Add support for sysctl tunable resync rate, member write cache enable, and volume transaction queue depth. Sponsored by ---------------- Avid Technologies Inc: SCSI error recovery, driver re-organization, update of MPI library headers, portions of dynamic personality registration, and misc bug fixes. Wheel Open Technologies: RAID event notification, RAID member pass-thru support, firmware upload/download support, enhanced RAID resync speed, portions of dynamic personality registration, and misc bug fixes. Detailed Changes ================ mpt.c mpt_cam.c mpt_raid.c mpt_pci.c: o Add support for personality modules. Each module exports load, and unload module scope methods as well as probe, attach, event, reset, shutdown, and detach per-device instance methods mpt.c mpt.h mpt_pci.c: o The driver now associates a callback function (via an index) with every transaction submitted to the controller. This allows the main interrupt handler to absolve itself of any knowledge of individual transaction/response types by simply calling the callback function "registered" for the transaction. We use a callback index instead of a callback function pointer in each requests so we can properly handle responses (e.g. event notifications) that are not associated with a transaction. Personality modules dynamically register their callbacks with the driver core to receive the callback index to use for their handlers. o Move the interrupt handler into mpt.c. The ISR algorithm is bus transport and OS independent and thus had no reason to be in mpt_pci.c. o Simplify configuration message reply handling by copying reply frame data for the requester and storing completion status in the original request structure. o Add the mpt_complete_request_chain() helper method and use it to implement reset handlers that must abort transactions. o Keep track of all pending requests on the new requests_pending_list in the softc. o Add default handlers to mpt.c to handle generic event notifications and controller reset activities. The event handler code is largely the same as in the original driver. The reset handler is new and terminates any pending transactions with a status code indicating the controller needs to be re-initialized. o Add some endian support to the driver. A complete audit is still required for this driver to have any hope of operating in a big-endian environment. o Use inttypes.h and __inline. Come closer to being style(9) compliant. o Remove extraneous use of typedefs. o Convert request state from a strict enumeration to a series of flags. This allows us to, for example, tag transactions that have timed-out while retaining the state that the transaction is still in-flight on the controller. o Add mpt_wait_req() which allows a caller to poll or sleep for the completion of a request. Use this to simplify and factor code out from many initialization routines. We also use this to sleep for task management request completions in our CAM timeout handler. mpt.c: o Correct a bug in the event handler where request structures were freed even if the request reply was marked as a continuation reply. Continuation replies indicate that the controller still owns the request and freeing these replies prematurely corrupted controller state. o Implement firmware upload and download. On controllers that do not have dedicated NVRAM (as in the Sun v20/v40z), the firmware image is downloaded to the controller by the system BIOS. This image occupies precious controller RAM space until the host driver fetches the image, reducing the number of concurrent I/Os the controller can processes. The uploaded image is used to re-program the controller during hard reset events since the controller cannot fetch the firmware on its own. Implementing this feature allows much higher queue depths when RAID volumes are configured. o Changed configuration page accessors to allow threads to sleep rather than busy wait for completion. o Removed hard coded data transfer sizes from configuration page routines so that RAID configuration page processing is possible. mpt_reg.h: o Move controller register definitions into a separate file. mpt.h: o Re-arrange includes to allow inlined functions to be defined in mpt.h. o Add reply, event, and reset handler definitions. o Add softc fields for handling timeout and controller reset recovery. mpt_cam.c: o Move mpt_freebsd.c to mpt_cam.c. Move all core functionality, such as event handling, into mpt.c leaving only CAM SCSI support here. o Revamp completion handler to provide correct CAM status for all currently defined SCSI MPI message result codes. o Register event and reset handlers with the MPT core. Modify the event handler to notify CAM of bus reset events. The controller reset handler will abort any transactions that have timed out. All other pending CAM transactions are correctly aborted by the core driver's reset handler. o Allocate a single request up front to perform task management operations. This guarantees that we can always perform a TMF operation even when the controller is saturated with other operations. The single request also serves as a perfect mechanism of guaranteeing that only a single TMF is in flight at a time - something that is required according to the MPT Fusion documentation. o Add a helper function for issuing task management requests to the controller. This is used to abort individual requests or perform a bus reset. o Modify the CAM XPT_BUS_RESET ccb handler to wait for and properly handle the status of the bus reset task management frame used to reset the bus. The previous code assumed that the reset request would always succeed. o Add timeout recovery support. When a timeout occurs, the timed-out request is added to a queue to be processed by our recovery thread and the thread is woken up. The recovery thread processes timed-out command serially, attempting first to abort them and then falling back to a bus reset if an abort fails. o Add calls to mpt_reset() to reset the controller if any handshake command, bus reset attempt or abort attempt fails due to a timeout. o Export a secondary "bus" to CAM that exposes all volume drive members as pass-thru devices, allowing CAM to perform proper speed negotiation to hidden devices. o Add a CAM async event handler tracking the AC_FOUND_DEVICE event. Use this to trigger calls to set the per-volume queue depth once the volume is fully registered with CAM. This is required to avoid hitting firmware limits on volume queue depth. Exceeding the limit causes the firmware to hang. mpt_cam.h: o Add several helper functions for interfacing to CAM and performing timeout recovery. mpt_pci.c: o Disable interrupts on the controller before registering and enabling interrupt delivery to the OS. Otherwise we risk receiving interrupts before the driver is ready to receive them. o Make use of compatibility macros that allow the driver to be compiled under 4.x and 5.x. mpt_raid.c: o Add a per-controller instance RAID thread to perform settings changes and query status (minimizes CPU busy wait loops). o Use a shutdown handler to disable "Member Write Cache Enable" (MWCE) setting for RAID arrays set to enable MWCE During Rebuild. o Change reply handler function signature to allow handlers to defer the deletion of reply frames. Use this to allow the event reply handler to queue up events that need to be acked if no resources are available to immediately ack an event. Queued events are processed in mpt_free_request() where resources are freed. This avoids a panic on resource shortage. o Parse and print out RAID controller capabilities during driver probe. o Define, allocate, and maintain RAID data structures for volumes, hidden member physical disks and spare disks. o Add dynamic sysctls for per-instance setting of the log level, array resync rate, array member cache enable, and volume queue depth. mpt_debug.c: o Add mpt_lprt and mpt_lprtc for printing diagnostics conditioned on a particular log level to aid in tracking down driver issues. o Add mpt_decode_value() which parses the bits in an integer value based on a parsing table (mask, value, name string, tuples). mpilib/*: o Update mpi library header files to latest distribution from LSI. Submitted by: gibbs Approved by: re
2005-07-10 15:05:39 +00:00
return;
}
Massive overhaul of MPT Fusion driver: o Add timeout error recovery (from a thread context to avoid the deferral of other critical interrupts). o Properly recover commands across controller reset events. o Update the driver to handle events and status codes that have been added to the MPI spec since the driver was originally written. o Make the driver more modular to improve maintainability and support dynamic "personality" registration (e.g. SCSI Initiator, RAID, SAS, FC, etc). o Shorten and simplify the common I/O path to improve driver performance. o Add RAID volume and RAID member state/settings reporting. o Add periodic volume resynchronization status reporting. o Add support for sysctl tunable resync rate, member write cache enable, and volume transaction queue depth. Sponsored by ---------------- Avid Technologies Inc: SCSI error recovery, driver re-organization, update of MPI library headers, portions of dynamic personality registration, and misc bug fixes. Wheel Open Technologies: RAID event notification, RAID member pass-thru support, firmware upload/download support, enhanced RAID resync speed, portions of dynamic personality registration, and misc bug fixes. Detailed Changes ================ mpt.c mpt_cam.c mpt_raid.c mpt_pci.c: o Add support for personality modules. Each module exports load, and unload module scope methods as well as probe, attach, event, reset, shutdown, and detach per-device instance methods mpt.c mpt.h mpt_pci.c: o The driver now associates a callback function (via an index) with every transaction submitted to the controller. This allows the main interrupt handler to absolve itself of any knowledge of individual transaction/response types by simply calling the callback function "registered" for the transaction. We use a callback index instead of a callback function pointer in each requests so we can properly handle responses (e.g. event notifications) that are not associated with a transaction. Personality modules dynamically register their callbacks with the driver core to receive the callback index to use for their handlers. o Move the interrupt handler into mpt.c. The ISR algorithm is bus transport and OS independent and thus had no reason to be in mpt_pci.c. o Simplify configuration message reply handling by copying reply frame data for the requester and storing completion status in the original request structure. o Add the mpt_complete_request_chain() helper method and use it to implement reset handlers that must abort transactions. o Keep track of all pending requests on the new requests_pending_list in the softc. o Add default handlers to mpt.c to handle generic event notifications and controller reset activities. The event handler code is largely the same as in the original driver. The reset handler is new and terminates any pending transactions with a status code indicating the controller needs to be re-initialized. o Add some endian support to the driver. A complete audit is still required for this driver to have any hope of operating in a big-endian environment. o Use inttypes.h and __inline. Come closer to being style(9) compliant. o Remove extraneous use of typedefs. o Convert request state from a strict enumeration to a series of flags. This allows us to, for example, tag transactions that have timed-out while retaining the state that the transaction is still in-flight on the controller. o Add mpt_wait_req() which allows a caller to poll or sleep for the completion of a request. Use this to simplify and factor code out from many initialization routines. We also use this to sleep for task management request completions in our CAM timeout handler. mpt.c: o Correct a bug in the event handler where request structures were freed even if the request reply was marked as a continuation reply. Continuation replies indicate that the controller still owns the request and freeing these replies prematurely corrupted controller state. o Implement firmware upload and download. On controllers that do not have dedicated NVRAM (as in the Sun v20/v40z), the firmware image is downloaded to the controller by the system BIOS. This image occupies precious controller RAM space until the host driver fetches the image, reducing the number of concurrent I/Os the controller can processes. The uploaded image is used to re-program the controller during hard reset events since the controller cannot fetch the firmware on its own. Implementing this feature allows much higher queue depths when RAID volumes are configured. o Changed configuration page accessors to allow threads to sleep rather than busy wait for completion. o Removed hard coded data transfer sizes from configuration page routines so that RAID configuration page processing is possible. mpt_reg.h: o Move controller register definitions into a separate file. mpt.h: o Re-arrange includes to allow inlined functions to be defined in mpt.h. o Add reply, event, and reset handler definitions. o Add softc fields for handling timeout and controller reset recovery. mpt_cam.c: o Move mpt_freebsd.c to mpt_cam.c. Move all core functionality, such as event handling, into mpt.c leaving only CAM SCSI support here. o Revamp completion handler to provide correct CAM status for all currently defined SCSI MPI message result codes. o Register event and reset handlers with the MPT core. Modify the event handler to notify CAM of bus reset events. The controller reset handler will abort any transactions that have timed out. All other pending CAM transactions are correctly aborted by the core driver's reset handler. o Allocate a single request up front to perform task management operations. This guarantees that we can always perform a TMF operation even when the controller is saturated with other operations. The single request also serves as a perfect mechanism of guaranteeing that only a single TMF is in flight at a time - something that is required according to the MPT Fusion documentation. o Add a helper function for issuing task management requests to the controller. This is used to abort individual requests or perform a bus reset. o Modify the CAM XPT_BUS_RESET ccb handler to wait for and properly handle the status of the bus reset task management frame used to reset the bus. The previous code assumed that the reset request would always succeed. o Add timeout recovery support. When a timeout occurs, the timed-out request is added to a queue to be processed by our recovery thread and the thread is woken up. The recovery thread processes timed-out command serially, attempting first to abort them and then falling back to a bus reset if an abort fails. o Add calls to mpt_reset() to reset the controller if any handshake command, bus reset attempt or abort attempt fails due to a timeout. o Export a secondary "bus" to CAM that exposes all volume drive members as pass-thru devices, allowing CAM to perform proper speed negotiation to hidden devices. o Add a CAM async event handler tracking the AC_FOUND_DEVICE event. Use this to trigger calls to set the per-volume queue depth once the volume is fully registered with CAM. This is required to avoid hitting firmware limits on volume queue depth. Exceeding the limit causes the firmware to hang. mpt_cam.h: o Add several helper functions for interfacing to CAM and performing timeout recovery. mpt_pci.c: o Disable interrupts on the controller before registering and enabling interrupt delivery to the OS. Otherwise we risk receiving interrupts before the driver is ready to receive them. o Make use of compatibility macros that allow the driver to be compiled under 4.x and 5.x. mpt_raid.c: o Add a per-controller instance RAID thread to perform settings changes and query status (minimizes CPU busy wait loops). o Use a shutdown handler to disable "Member Write Cache Enable" (MWCE) setting for RAID arrays set to enable MWCE During Rebuild. o Change reply handler function signature to allow handlers to defer the deletion of reply frames. Use this to allow the event reply handler to queue up events that need to be acked if no resources are available to immediately ack an event. Queued events are processed in mpt_free_request() where resources are freed. This avoids a panic on resource shortage. o Parse and print out RAID controller capabilities during driver probe. o Define, allocate, and maintain RAID data structures for volumes, hidden member physical disks and spare disks. o Add dynamic sysctls for per-instance setting of the log level, array resync rate, array member cache enable, and volume queue depth. mpt_debug.c: o Add mpt_lprt and mpt_lprtc for printing diagnostics conditioned on a particular log level to aid in tracking down driver issues. o Add mpt_decode_value() which parses the bits in an integer value based on a parsing table (mask, value, name string, tuples). mpilib/*: o Update mpi library header files to latest distribution from LSI. Submitted by: gibbs Approved by: re
2005-07-10 15:05:39 +00:00
mpt->raid_mwce_setting = MPT_RAID_MWCE_OFF;
RAID_VOL_FOREACH(mpt, mpt_vol) {
mpt_verify_mwce(mpt, mpt_vol);
}
}
static int
mpt_raid_reply_handler(struct mpt_softc *mpt, request_t *req,
uint32_t reply_desc, MSG_DEFAULT_REPLY *reply_frame)
Massive overhaul of MPT Fusion driver: o Add timeout error recovery (from a thread context to avoid the deferral of other critical interrupts). o Properly recover commands across controller reset events. o Update the driver to handle events and status codes that have been added to the MPI spec since the driver was originally written. o Make the driver more modular to improve maintainability and support dynamic "personality" registration (e.g. SCSI Initiator, RAID, SAS, FC, etc). o Shorten and simplify the common I/O path to improve driver performance. o Add RAID volume and RAID member state/settings reporting. o Add periodic volume resynchronization status reporting. o Add support for sysctl tunable resync rate, member write cache enable, and volume transaction queue depth. Sponsored by ---------------- Avid Technologies Inc: SCSI error recovery, driver re-organization, update of MPI library headers, portions of dynamic personality registration, and misc bug fixes. Wheel Open Technologies: RAID event notification, RAID member pass-thru support, firmware upload/download support, enhanced RAID resync speed, portions of dynamic personality registration, and misc bug fixes. Detailed Changes ================ mpt.c mpt_cam.c mpt_raid.c mpt_pci.c: o Add support for personality modules. Each module exports load, and unload module scope methods as well as probe, attach, event, reset, shutdown, and detach per-device instance methods mpt.c mpt.h mpt_pci.c: o The driver now associates a callback function (via an index) with every transaction submitted to the controller. This allows the main interrupt handler to absolve itself of any knowledge of individual transaction/response types by simply calling the callback function "registered" for the transaction. We use a callback index instead of a callback function pointer in each requests so we can properly handle responses (e.g. event notifications) that are not associated with a transaction. Personality modules dynamically register their callbacks with the driver core to receive the callback index to use for their handlers. o Move the interrupt handler into mpt.c. The ISR algorithm is bus transport and OS independent and thus had no reason to be in mpt_pci.c. o Simplify configuration message reply handling by copying reply frame data for the requester and storing completion status in the original request structure. o Add the mpt_complete_request_chain() helper method and use it to implement reset handlers that must abort transactions. o Keep track of all pending requests on the new requests_pending_list in the softc. o Add default handlers to mpt.c to handle generic event notifications and controller reset activities. The event handler code is largely the same as in the original driver. The reset handler is new and terminates any pending transactions with a status code indicating the controller needs to be re-initialized. o Add some endian support to the driver. A complete audit is still required for this driver to have any hope of operating in a big-endian environment. o Use inttypes.h and __inline. Come closer to being style(9) compliant. o Remove extraneous use of typedefs. o Convert request state from a strict enumeration to a series of flags. This allows us to, for example, tag transactions that have timed-out while retaining the state that the transaction is still in-flight on the controller. o Add mpt_wait_req() which allows a caller to poll or sleep for the completion of a request. Use this to simplify and factor code out from many initialization routines. We also use this to sleep for task management request completions in our CAM timeout handler. mpt.c: o Correct a bug in the event handler where request structures were freed even if the request reply was marked as a continuation reply. Continuation replies indicate that the controller still owns the request and freeing these replies prematurely corrupted controller state. o Implement firmware upload and download. On controllers that do not have dedicated NVRAM (as in the Sun v20/v40z), the firmware image is downloaded to the controller by the system BIOS. This image occupies precious controller RAM space until the host driver fetches the image, reducing the number of concurrent I/Os the controller can processes. The uploaded image is used to re-program the controller during hard reset events since the controller cannot fetch the firmware on its own. Implementing this feature allows much higher queue depths when RAID volumes are configured. o Changed configuration page accessors to allow threads to sleep rather than busy wait for completion. o Removed hard coded data transfer sizes from configuration page routines so that RAID configuration page processing is possible. mpt_reg.h: o Move controller register definitions into a separate file. mpt.h: o Re-arrange includes to allow inlined functions to be defined in mpt.h. o Add reply, event, and reset handler definitions. o Add softc fields for handling timeout and controller reset recovery. mpt_cam.c: o Move mpt_freebsd.c to mpt_cam.c. Move all core functionality, such as event handling, into mpt.c leaving only CAM SCSI support here. o Revamp completion handler to provide correct CAM status for all currently defined SCSI MPI message result codes. o Register event and reset handlers with the MPT core. Modify the event handler to notify CAM of bus reset events. The controller reset handler will abort any transactions that have timed out. All other pending CAM transactions are correctly aborted by the core driver's reset handler. o Allocate a single request up front to perform task management operations. This guarantees that we can always perform a TMF operation even when the controller is saturated with other operations. The single request also serves as a perfect mechanism of guaranteeing that only a single TMF is in flight at a time - something that is required according to the MPT Fusion documentation. o Add a helper function for issuing task management requests to the controller. This is used to abort individual requests or perform a bus reset. o Modify the CAM XPT_BUS_RESET ccb handler to wait for and properly handle the status of the bus reset task management frame used to reset the bus. The previous code assumed that the reset request would always succeed. o Add timeout recovery support. When a timeout occurs, the timed-out request is added to a queue to be processed by our recovery thread and the thread is woken up. The recovery thread processes timed-out command serially, attempting first to abort them and then falling back to a bus reset if an abort fails. o Add calls to mpt_reset() to reset the controller if any handshake command, bus reset attempt or abort attempt fails due to a timeout. o Export a secondary "bus" to CAM that exposes all volume drive members as pass-thru devices, allowing CAM to perform proper speed negotiation to hidden devices. o Add a CAM async event handler tracking the AC_FOUND_DEVICE event. Use this to trigger calls to set the per-volume queue depth once the volume is fully registered with CAM. This is required to avoid hitting firmware limits on volume queue depth. Exceeding the limit causes the firmware to hang. mpt_cam.h: o Add several helper functions for interfacing to CAM and performing timeout recovery. mpt_pci.c: o Disable interrupts on the controller before registering and enabling interrupt delivery to the OS. Otherwise we risk receiving interrupts before the driver is ready to receive them. o Make use of compatibility macros that allow the driver to be compiled under 4.x and 5.x. mpt_raid.c: o Add a per-controller instance RAID thread to perform settings changes and query status (minimizes CPU busy wait loops). o Use a shutdown handler to disable "Member Write Cache Enable" (MWCE) setting for RAID arrays set to enable MWCE During Rebuild. o Change reply handler function signature to allow handlers to defer the deletion of reply frames. Use this to allow the event reply handler to queue up events that need to be acked if no resources are available to immediately ack an event. Queued events are processed in mpt_free_request() where resources are freed. This avoids a panic on resource shortage. o Parse and print out RAID controller capabilities during driver probe. o Define, allocate, and maintain RAID data structures for volumes, hidden member physical disks and spare disks. o Add dynamic sysctls for per-instance setting of the log level, array resync rate, array member cache enable, and volume queue depth. mpt_debug.c: o Add mpt_lprt and mpt_lprtc for printing diagnostics conditioned on a particular log level to aid in tracking down driver issues. o Add mpt_decode_value() which parses the bits in an integer value based on a parsing table (mask, value, name string, tuples). mpilib/*: o Update mpi library header files to latest distribution from LSI. Submitted by: gibbs Approved by: re
2005-07-10 15:05:39 +00:00
{
int free_req;
if (req == NULL)
return (/*free_reply*/TRUE);
free_req = TRUE;
if (reply_frame != NULL)
free_req = mpt_raid_reply_frame_handler(mpt, req, reply_frame);
2005-12-04 02:12:43 +00:00
#ifdef NOTYET
Massive overhaul of MPT Fusion driver: o Add timeout error recovery (from a thread context to avoid the deferral of other critical interrupts). o Properly recover commands across controller reset events. o Update the driver to handle events and status codes that have been added to the MPI spec since the driver was originally written. o Make the driver more modular to improve maintainability and support dynamic "personality" registration (e.g. SCSI Initiator, RAID, SAS, FC, etc). o Shorten and simplify the common I/O path to improve driver performance. o Add RAID volume and RAID member state/settings reporting. o Add periodic volume resynchronization status reporting. o Add support for sysctl tunable resync rate, member write cache enable, and volume transaction queue depth. Sponsored by ---------------- Avid Technologies Inc: SCSI error recovery, driver re-organization, update of MPI library headers, portions of dynamic personality registration, and misc bug fixes. Wheel Open Technologies: RAID event notification, RAID member pass-thru support, firmware upload/download support, enhanced RAID resync speed, portions of dynamic personality registration, and misc bug fixes. Detailed Changes ================ mpt.c mpt_cam.c mpt_raid.c mpt_pci.c: o Add support for personality modules. Each module exports load, and unload module scope methods as well as probe, attach, event, reset, shutdown, and detach per-device instance methods mpt.c mpt.h mpt_pci.c: o The driver now associates a callback function (via an index) with every transaction submitted to the controller. This allows the main interrupt handler to absolve itself of any knowledge of individual transaction/response types by simply calling the callback function "registered" for the transaction. We use a callback index instead of a callback function pointer in each requests so we can properly handle responses (e.g. event notifications) that are not associated with a transaction. Personality modules dynamically register their callbacks with the driver core to receive the callback index to use for their handlers. o Move the interrupt handler into mpt.c. The ISR algorithm is bus transport and OS independent and thus had no reason to be in mpt_pci.c. o Simplify configuration message reply handling by copying reply frame data for the requester and storing completion status in the original request structure. o Add the mpt_complete_request_chain() helper method and use it to implement reset handlers that must abort transactions. o Keep track of all pending requests on the new requests_pending_list in the softc. o Add default handlers to mpt.c to handle generic event notifications and controller reset activities. The event handler code is largely the same as in the original driver. The reset handler is new and terminates any pending transactions with a status code indicating the controller needs to be re-initialized. o Add some endian support to the driver. A complete audit is still required for this driver to have any hope of operating in a big-endian environment. o Use inttypes.h and __inline. Come closer to being style(9) compliant. o Remove extraneous use of typedefs. o Convert request state from a strict enumeration to a series of flags. This allows us to, for example, tag transactions that have timed-out while retaining the state that the transaction is still in-flight on the controller. o Add mpt_wait_req() which allows a caller to poll or sleep for the completion of a request. Use this to simplify and factor code out from many initialization routines. We also use this to sleep for task management request completions in our CAM timeout handler. mpt.c: o Correct a bug in the event handler where request structures were freed even if the request reply was marked as a continuation reply. Continuation replies indicate that the controller still owns the request and freeing these replies prematurely corrupted controller state. o Implement firmware upload and download. On controllers that do not have dedicated NVRAM (as in the Sun v20/v40z), the firmware image is downloaded to the controller by the system BIOS. This image occupies precious controller RAM space until the host driver fetches the image, reducing the number of concurrent I/Os the controller can processes. The uploaded image is used to re-program the controller during hard reset events since the controller cannot fetch the firmware on its own. Implementing this feature allows much higher queue depths when RAID volumes are configured. o Changed configuration page accessors to allow threads to sleep rather than busy wait for completion. o Removed hard coded data transfer sizes from configuration page routines so that RAID configuration page processing is possible. mpt_reg.h: o Move controller register definitions into a separate file. mpt.h: o Re-arrange includes to allow inlined functions to be defined in mpt.h. o Add reply, event, and reset handler definitions. o Add softc fields for handling timeout and controller reset recovery. mpt_cam.c: o Move mpt_freebsd.c to mpt_cam.c. Move all core functionality, such as event handling, into mpt.c leaving only CAM SCSI support here. o Revamp completion handler to provide correct CAM status for all currently defined SCSI MPI message result codes. o Register event and reset handlers with the MPT core. Modify the event handler to notify CAM of bus reset events. The controller reset handler will abort any transactions that have timed out. All other pending CAM transactions are correctly aborted by the core driver's reset handler. o Allocate a single request up front to perform task management operations. This guarantees that we can always perform a TMF operation even when the controller is saturated with other operations. The single request also serves as a perfect mechanism of guaranteeing that only a single TMF is in flight at a time - something that is required according to the MPT Fusion documentation. o Add a helper function for issuing task management requests to the controller. This is used to abort individual requests or perform a bus reset. o Modify the CAM XPT_BUS_RESET ccb handler to wait for and properly handle the status of the bus reset task management frame used to reset the bus. The previous code assumed that the reset request would always succeed. o Add timeout recovery support. When a timeout occurs, the timed-out request is added to a queue to be processed by our recovery thread and the thread is woken up. The recovery thread processes timed-out command serially, attempting first to abort them and then falling back to a bus reset if an abort fails. o Add calls to mpt_reset() to reset the controller if any handshake command, bus reset attempt or abort attempt fails due to a timeout. o Export a secondary "bus" to CAM that exposes all volume drive members as pass-thru devices, allowing CAM to perform proper speed negotiation to hidden devices. o Add a CAM async event handler tracking the AC_FOUND_DEVICE event. Use this to trigger calls to set the per-volume queue depth once the volume is fully registered with CAM. This is required to avoid hitting firmware limits on volume queue depth. Exceeding the limit causes the firmware to hang. mpt_cam.h: o Add several helper functions for interfacing to CAM and performing timeout recovery. mpt_pci.c: o Disable interrupts on the controller before registering and enabling interrupt delivery to the OS. Otherwise we risk receiving interrupts before the driver is ready to receive them. o Make use of compatibility macros that allow the driver to be compiled under 4.x and 5.x. mpt_raid.c: o Add a per-controller instance RAID thread to perform settings changes and query status (minimizes CPU busy wait loops). o Use a shutdown handler to disable "Member Write Cache Enable" (MWCE) setting for RAID arrays set to enable MWCE During Rebuild. o Change reply handler function signature to allow handlers to defer the deletion of reply frames. Use this to allow the event reply handler to queue up events that need to be acked if no resources are available to immediately ack an event. Queued events are processed in mpt_free_request() where resources are freed. This avoids a panic on resource shortage. o Parse and print out RAID controller capabilities during driver probe. o Define, allocate, and maintain RAID data structures for volumes, hidden member physical disks and spare disks. o Add dynamic sysctls for per-instance setting of the log level, array resync rate, array member cache enable, and volume queue depth. mpt_debug.c: o Add mpt_lprt and mpt_lprtc for printing diagnostics conditioned on a particular log level to aid in tracking down driver issues. o Add mpt_decode_value() which parses the bits in an integer value based on a parsing table (mask, value, name string, tuples). mpilib/*: o Update mpi library header files to latest distribution from LSI. Submitted by: gibbs Approved by: re
2005-07-10 15:05:39 +00:00
else if (req->ccb != NULL) {
/* Complete Quiesce CCB with error... */
}
#endif
req->state &= ~REQ_STATE_QUEUED;
req->state |= REQ_STATE_DONE;
TAILQ_REMOVE(&mpt->request_pending_list, req, links);
if ((req->state & REQ_STATE_NEED_WAKEUP) != 0) {
wakeup(req);
} else if (free_req) {
mpt_free_request(mpt, req);
}
return (/*free_reply*/TRUE);
}
/*
* Parse additional completion information in the reply
* frame for RAID I/O requests.
*/
static int
mpt_raid_reply_frame_handler(struct mpt_softc *mpt, request_t *req,
MSG_DEFAULT_REPLY *reply_frame)
{
MSG_RAID_ACTION_REPLY *reply;
struct mpt_raid_action_result *action_result;
MSG_RAID_ACTION_REQUEST *rap;
reply = (MSG_RAID_ACTION_REPLY *)reply_frame;
req->IOCStatus = le16toh(reply->IOCStatus);
rap = (MSG_RAID_ACTION_REQUEST *)req->req_vbuf;
switch (rap->Action) {
case MPI_RAID_ACTION_QUIESCE_PHYS_IO:
/*
* Parse result, call mpt_start with ccb,
* release device queue.
* COWWWWW
*/
break;
case MPI_RAID_ACTION_ENABLE_PHYS_IO:
/*
* Need additional state for transition to enabled to
* protect against attempts to disable??
*/
break;
default:
action_result = REQ_TO_RAID_ACTION_RESULT(req);
memcpy(&action_result->action_data, &reply->ActionData,
sizeof(action_result->action_data));
action_result->action_status = reply->ActionStatus;
break;
}
return (/*Free Request*/TRUE);
}
/*
* Utiltity routine to perform a RAID action command;
*/
int
mpt_issue_raid_req(struct mpt_softc *mpt, struct mpt_raid_volume *vol,
struct mpt_raid_disk *disk, request_t *req, u_int Action,
uint32_t ActionDataWord, bus_addr_t addr, bus_size_t len,
int write, int wait)
{
MSG_RAID_ACTION_REQUEST *rap;
SGE_SIMPLE32 *se;
rap = req->req_vbuf;
memset(rap, 0, sizeof *rap);
rap->Action = Action;
rap->ActionDataWord = ActionDataWord;
rap->Function = MPI_FUNCTION_RAID_ACTION;
rap->VolumeID = vol->config_page->VolumeID;
rap->VolumeBus = vol->config_page->VolumeBus;
if (disk != 0)
rap->PhysDiskNum = disk->config_page.PhysDiskNum;
else
rap->PhysDiskNum = 0xFF;
se = (SGE_SIMPLE32 *)&rap->ActionDataSGE;
se->Address = addr;
MPI_pSGE_SET_LENGTH(se, len);
MPI_pSGE_SET_FLAGS(se, (MPI_SGE_FLAGS_SIMPLE_ELEMENT |
MPI_SGE_FLAGS_LAST_ELEMENT | MPI_SGE_FLAGS_END_OF_BUFFER |
MPI_SGE_FLAGS_END_OF_LIST |
write ? MPI_SGE_FLAGS_HOST_TO_IOC : MPI_SGE_FLAGS_IOC_TO_HOST));
rap->MsgContext = htole32(req->index | raid_handler_id);
mpt_check_doorbell(mpt);
mpt_send_cmd(mpt, req);
if (wait) {
return (mpt_wait_req(mpt, req, REQ_STATE_DONE, REQ_STATE_DONE,
/*sleep_ok*/FALSE, /*time_ms*/2000));
} else {
return (0);
}
}
/*************************** RAID Status Monitoring ***************************/
static int
mpt_spawn_raid_thread(struct mpt_softc *mpt)
{
int error;
/*
* Freeze out any CAM transactions until our thread
* is able to run at least once. We need to update
* our RAID pages before acception I/O or we may
* reject I/O to an ID we later determine is for a
* hidden physdisk.
*/
xpt_freeze_simq(mpt->phydisk_sim, 1);
error = mpt_kthread_create(mpt_raid_thread, mpt,
&mpt->raid_thread, /*flags*/0, /*altstack*/0,
"mpt_raid%d", mpt->unit);
if (error != 0)
xpt_release_simq(mpt->phydisk_sim, /*run_queue*/FALSE);
return (error);
}
static void
mpt_terminate_raid_thread(struct mpt_softc *mpt)
{
if (mpt->raid_thread == NULL) {
return;
}
mpt->shutdwn_raid = 1;
wakeup(mpt->raid_volumes);
/*
* Sleep on a slightly different location
* for this interlock just for added safety.
*/
mpt_sleep(mpt, &mpt->raid_thread, PUSER, "thtrm", 0);
}
static void
mpt_cam_rescan_callback(struct cam_periph *periph, union ccb *ccb)
{
xpt_free_path(ccb->ccb_h.path);
free(ccb, M_DEVBUF);
}
static void
mpt_raid_thread(void *arg)
{
struct mpt_softc *mpt;
int firstrun;
#if __FreeBSD_version >= 500000
mtx_lock(&Giant);
#endif
mpt = (struct mpt_softc *)arg;
firstrun = 1;
MPT_LOCK(mpt);
while (mpt->shutdwn_raid == 0) {
if (mpt->raid_wakeup == 0) {
mpt_sleep(mpt, &mpt->raid_volumes, PUSER, "idle", 0);
continue;
}
mpt->raid_wakeup = 0;
mpt_refresh_raid_data(mpt);
/*
* Now that we have our first snapshot of RAID data,
* allow CAM to access our physical disk bus.
*/
if (firstrun) {
firstrun = 0;
xpt_release_simq(mpt->phydisk_sim, /*run_queue*/TRUE);
}
if (mpt->raid_rescan != 0) {
union ccb *ccb;
struct cam_path *path;
int error;
mpt->raid_rescan = 0;
ccb = malloc(sizeof(*ccb), M_DEVBUF, M_WAITOK);
error = xpt_create_path(&path, xpt_periph,
cam_sim_path(mpt->phydisk_sim),
CAM_TARGET_WILDCARD,
CAM_LUN_WILDCARD);
if (error != CAM_REQ_CMP) {
free(ccb, M_DEVBUF);
mpt_prt(mpt, "Unable to rescan RAID Bus!\n");
} else {
xpt_setup_ccb(&ccb->ccb_h, path, /*priority*/5);
ccb->ccb_h.func_code = XPT_SCAN_BUS;
ccb->ccb_h.cbfcnp = mpt_cam_rescan_callback;
ccb->crcn.flags = CAM_FLAG_NONE;
xpt_action(ccb);
}
}
}
mpt->raid_thread = NULL;
wakeup(&mpt->raid_thread);
MPT_UNLOCK(mpt);
#if __FreeBSD_version >= 500000
mtx_unlock(&Giant);
#endif
kthread_exit(0);
}
cam_status
mpt_raid_quiesce_disk(struct mpt_softc *mpt, struct mpt_raid_disk *mpt_disk,
request_t *req)
{
union ccb *ccb;
ccb = req->ccb;
if ((mpt_disk->flags & MPT_RDF_QUIESCED) != 0)
return (CAM_REQ_CMP);
if ((mpt_disk->flags & MPT_RDF_QUIESCING) == 0) {
int rv;
mpt_disk->flags |= MPT_RDF_QUIESCING;
xpt_freeze_devq(ccb->ccb_h.path, 1);
rv = mpt_issue_raid_req(mpt, mpt_disk->volume, mpt_disk, req,
MPI_RAID_ACTION_QUIESCE_PHYS_IO,
/*ActionData*/0, /*addr*/0,
/*len*/0, /*write*/FALSE,
/*wait*/FALSE);
if (rv != 0)
return (CAM_REQ_CMP_ERR);
ccb->ccb_h.timeout_ch =
timeout(mpt_raid_quiesce_timeout, (caddr_t)ccb, 5 * hz);
#if 0
if (rv == ETIMEDOUT) {
mpt_disk_prt(mpt, mpt_disk, "mpt_raid_quiesce_disk: "
"Quiece Timed-out\n");
xpt_release_devq(ccb->ccb_h.path, 1, /*run*/0);
return (CAM_REQ_CMP_ERR);
}
ar = REQ_TO_RAID_ACTION_RESULT(req);
if (rv != 0
|| REQ_IOCSTATUS(req) != MPI_IOCSTATUS_SUCCESS
|| (ar->action_status != MPI_RAID_ACTION_ASTATUS_SUCCESS)) {
mpt_disk_prt(mpt, mpt_disk, "Quiece Failed"
"%d:%x:%x\n", rv, req->IOCStatus,
ar->action_status);
xpt_release_devq(ccb->ccb_h.path, 1, /*run*/0);
return (CAM_REQ_CMP_ERR);
}
#endif
return (CAM_REQ_INPROG);
}
return (CAM_REQUEUE_REQ);
}
/* XXX Ignores that there may be multiple busses/IOCs involved. */
cam_status
mpt_map_physdisk(struct mpt_softc *mpt, union ccb *ccb, u_int *tgt)
{
struct mpt_raid_disk *mpt_disk;
mpt_disk = mpt->raid_disks + ccb->ccb_h.target_id;
if (ccb->ccb_h.target_id < mpt->raid_max_disks
&& (mpt_disk->flags & MPT_RDF_ACTIVE) != 0) {
*tgt = mpt_disk->config_page.PhysDiskID;
return (0);
}
mpt_lprt(mpt, MPT_PRT_DEBUG, "mpt_map_physdisk(%d) - Not Active\n",
ccb->ccb_h.target_id);
return (-1);
}
2005-12-04 02:12:43 +00:00
#if 0
Massive overhaul of MPT Fusion driver: o Add timeout error recovery (from a thread context to avoid the deferral of other critical interrupts). o Properly recover commands across controller reset events. o Update the driver to handle events and status codes that have been added to the MPI spec since the driver was originally written. o Make the driver more modular to improve maintainability and support dynamic "personality" registration (e.g. SCSI Initiator, RAID, SAS, FC, etc). o Shorten and simplify the common I/O path to improve driver performance. o Add RAID volume and RAID member state/settings reporting. o Add periodic volume resynchronization status reporting. o Add support for sysctl tunable resync rate, member write cache enable, and volume transaction queue depth. Sponsored by ---------------- Avid Technologies Inc: SCSI error recovery, driver re-organization, update of MPI library headers, portions of dynamic personality registration, and misc bug fixes. Wheel Open Technologies: RAID event notification, RAID member pass-thru support, firmware upload/download support, enhanced RAID resync speed, portions of dynamic personality registration, and misc bug fixes. Detailed Changes ================ mpt.c mpt_cam.c mpt_raid.c mpt_pci.c: o Add support for personality modules. Each module exports load, and unload module scope methods as well as probe, attach, event, reset, shutdown, and detach per-device instance methods mpt.c mpt.h mpt_pci.c: o The driver now associates a callback function (via an index) with every transaction submitted to the controller. This allows the main interrupt handler to absolve itself of any knowledge of individual transaction/response types by simply calling the callback function "registered" for the transaction. We use a callback index instead of a callback function pointer in each requests so we can properly handle responses (e.g. event notifications) that are not associated with a transaction. Personality modules dynamically register their callbacks with the driver core to receive the callback index to use for their handlers. o Move the interrupt handler into mpt.c. The ISR algorithm is bus transport and OS independent and thus had no reason to be in mpt_pci.c. o Simplify configuration message reply handling by copying reply frame data for the requester and storing completion status in the original request structure. o Add the mpt_complete_request_chain() helper method and use it to implement reset handlers that must abort transactions. o Keep track of all pending requests on the new requests_pending_list in the softc. o Add default handlers to mpt.c to handle generic event notifications and controller reset activities. The event handler code is largely the same as in the original driver. The reset handler is new and terminates any pending transactions with a status code indicating the controller needs to be re-initialized. o Add some endian support to the driver. A complete audit is still required for this driver to have any hope of operating in a big-endian environment. o Use inttypes.h and __inline. Come closer to being style(9) compliant. o Remove extraneous use of typedefs. o Convert request state from a strict enumeration to a series of flags. This allows us to, for example, tag transactions that have timed-out while retaining the state that the transaction is still in-flight on the controller. o Add mpt_wait_req() which allows a caller to poll or sleep for the completion of a request. Use this to simplify and factor code out from many initialization routines. We also use this to sleep for task management request completions in our CAM timeout handler. mpt.c: o Correct a bug in the event handler where request structures were freed even if the request reply was marked as a continuation reply. Continuation replies indicate that the controller still owns the request and freeing these replies prematurely corrupted controller state. o Implement firmware upload and download. On controllers that do not have dedicated NVRAM (as in the Sun v20/v40z), the firmware image is downloaded to the controller by the system BIOS. This image occupies precious controller RAM space until the host driver fetches the image, reducing the number of concurrent I/Os the controller can processes. The uploaded image is used to re-program the controller during hard reset events since the controller cannot fetch the firmware on its own. Implementing this feature allows much higher queue depths when RAID volumes are configured. o Changed configuration page accessors to allow threads to sleep rather than busy wait for completion. o Removed hard coded data transfer sizes from configuration page routines so that RAID configuration page processing is possible. mpt_reg.h: o Move controller register definitions into a separate file. mpt.h: o Re-arrange includes to allow inlined functions to be defined in mpt.h. o Add reply, event, and reset handler definitions. o Add softc fields for handling timeout and controller reset recovery. mpt_cam.c: o Move mpt_freebsd.c to mpt_cam.c. Move all core functionality, such as event handling, into mpt.c leaving only CAM SCSI support here. o Revamp completion handler to provide correct CAM status for all currently defined SCSI MPI message result codes. o Register event and reset handlers with the MPT core. Modify the event handler to notify CAM of bus reset events. The controller reset handler will abort any transactions that have timed out. All other pending CAM transactions are correctly aborted by the core driver's reset handler. o Allocate a single request up front to perform task management operations. This guarantees that we can always perform a TMF operation even when the controller is saturated with other operations. The single request also serves as a perfect mechanism of guaranteeing that only a single TMF is in flight at a time - something that is required according to the MPT Fusion documentation. o Add a helper function for issuing task management requests to the controller. This is used to abort individual requests or perform a bus reset. o Modify the CAM XPT_BUS_RESET ccb handler to wait for and properly handle the status of the bus reset task management frame used to reset the bus. The previous code assumed that the reset request would always succeed. o Add timeout recovery support. When a timeout occurs, the timed-out request is added to a queue to be processed by our recovery thread and the thread is woken up. The recovery thread processes timed-out command serially, attempting first to abort them and then falling back to a bus reset if an abort fails. o Add calls to mpt_reset() to reset the controller if any handshake command, bus reset attempt or abort attempt fails due to a timeout. o Export a secondary "bus" to CAM that exposes all volume drive members as pass-thru devices, allowing CAM to perform proper speed negotiation to hidden devices. o Add a CAM async event handler tracking the AC_FOUND_DEVICE event. Use this to trigger calls to set the per-volume queue depth once the volume is fully registered with CAM. This is required to avoid hitting firmware limits on volume queue depth. Exceeding the limit causes the firmware to hang. mpt_cam.h: o Add several helper functions for interfacing to CAM and performing timeout recovery. mpt_pci.c: o Disable interrupts on the controller before registering and enabling interrupt delivery to the OS. Otherwise we risk receiving interrupts before the driver is ready to receive them. o Make use of compatibility macros that allow the driver to be compiled under 4.x and 5.x. mpt_raid.c: o Add a per-controller instance RAID thread to perform settings changes and query status (minimizes CPU busy wait loops). o Use a shutdown handler to disable "Member Write Cache Enable" (MWCE) setting for RAID arrays set to enable MWCE During Rebuild. o Change reply handler function signature to allow handlers to defer the deletion of reply frames. Use this to allow the event reply handler to queue up events that need to be acked if no resources are available to immediately ack an event. Queued events are processed in mpt_free_request() where resources are freed. This avoids a panic on resource shortage. o Parse and print out RAID controller capabilities during driver probe. o Define, allocate, and maintain RAID data structures for volumes, hidden member physical disks and spare disks. o Add dynamic sysctls for per-instance setting of the log level, array resync rate, array member cache enable, and volume queue depth. mpt_debug.c: o Add mpt_lprt and mpt_lprtc for printing diagnostics conditioned on a particular log level to aid in tracking down driver issues. o Add mpt_decode_value() which parses the bits in an integer value based on a parsing table (mask, value, name string, tuples). mpilib/*: o Update mpi library header files to latest distribution from LSI. Submitted by: gibbs Approved by: re
2005-07-10 15:05:39 +00:00
static void
mpt_enable_vol(struct mpt_softc *mpt, struct mpt_raid_volume *mpt_vol,
int enable)
{
request_t *req;
struct mpt_raid_action_result *ar;
CONFIG_PAGE_RAID_VOL_0 *vol_pg;
int enabled;
int rv;
vol_pg = mpt_vol->config_page;
enabled = vol_pg->VolumeStatus.Flags & MPI_RAIDVOL0_STATUS_FLAG_ENABLED;
/*
* If the setting matches the configuration,
* there is nothing to do.
*/
if ((enabled && enable)
|| (!enabled && !enable))
return;
req = mpt_get_request(mpt, /*sleep_ok*/TRUE);
if (req == NULL) {
mpt_vol_prt(mpt, mpt_vol,
"mpt_enable_vol: Get request failed!\n");
return;
}
rv = mpt_issue_raid_req(mpt, mpt_vol, /*disk*/NULL, req,
enable ? MPI_RAID_ACTION_ENABLE_VOLUME
: MPI_RAID_ACTION_DISABLE_VOLUME,
/*data*/0, /*addr*/0, /*len*/0,
/*write*/FALSE, /*wait*/TRUE);
if (rv == ETIMEDOUT) {
mpt_vol_prt(mpt, mpt_vol, "mpt_enable_vol: "
"%s Volume Timed-out\n",
enable ? "Enable" : "Disable");
return;
}
ar = REQ_TO_RAID_ACTION_RESULT(req);
if (rv != 0
|| REQ_IOCSTATUS(req) != MPI_IOCSTATUS_SUCCESS
|| (ar->action_status != MPI_RAID_ACTION_ASTATUS_SUCCESS)) {
mpt_vol_prt(mpt, mpt_vol, "%s Volume Failed: %d:%x:%x\n",
enable ? "Enable" : "Disable",
rv, req->IOCStatus, ar->action_status);
}
mpt_free_request(mpt, req);
}
#endif
static void
mpt_verify_mwce(struct mpt_softc *mpt, struct mpt_raid_volume *mpt_vol)
{
request_t *req;
struct mpt_raid_action_result *ar;
CONFIG_PAGE_RAID_VOL_0 *vol_pg;
uint32_t data;
int rv;
int resyncing;
int mwce;
vol_pg = mpt_vol->config_page;
resyncing = vol_pg->VolumeStatus.Flags
& MPI_RAIDVOL0_STATUS_FLAG_RESYNC_IN_PROGRESS;
mwce = vol_pg->VolumeSettings.Settings
& MPI_RAIDVOL0_SETTING_WRITE_CACHING_ENABLE;
/*
* If the setting matches the configuration,
* there is nothing to do.
*/
switch (mpt->raid_mwce_setting) {
case MPT_RAID_MWCE_REBUILD_ONLY:
if ((resyncing && mwce) || (!resyncing && !mwce)) {
Massive overhaul of MPT Fusion driver: o Add timeout error recovery (from a thread context to avoid the deferral of other critical interrupts). o Properly recover commands across controller reset events. o Update the driver to handle events and status codes that have been added to the MPI spec since the driver was originally written. o Make the driver more modular to improve maintainability and support dynamic "personality" registration (e.g. SCSI Initiator, RAID, SAS, FC, etc). o Shorten and simplify the common I/O path to improve driver performance. o Add RAID volume and RAID member state/settings reporting. o Add periodic volume resynchronization status reporting. o Add support for sysctl tunable resync rate, member write cache enable, and volume transaction queue depth. Sponsored by ---------------- Avid Technologies Inc: SCSI error recovery, driver re-organization, update of MPI library headers, portions of dynamic personality registration, and misc bug fixes. Wheel Open Technologies: RAID event notification, RAID member pass-thru support, firmware upload/download support, enhanced RAID resync speed, portions of dynamic personality registration, and misc bug fixes. Detailed Changes ================ mpt.c mpt_cam.c mpt_raid.c mpt_pci.c: o Add support for personality modules. Each module exports load, and unload module scope methods as well as probe, attach, event, reset, shutdown, and detach per-device instance methods mpt.c mpt.h mpt_pci.c: o The driver now associates a callback function (via an index) with every transaction submitted to the controller. This allows the main interrupt handler to absolve itself of any knowledge of individual transaction/response types by simply calling the callback function "registered" for the transaction. We use a callback index instead of a callback function pointer in each requests so we can properly handle responses (e.g. event notifications) that are not associated with a transaction. Personality modules dynamically register their callbacks with the driver core to receive the callback index to use for their handlers. o Move the interrupt handler into mpt.c. The ISR algorithm is bus transport and OS independent and thus had no reason to be in mpt_pci.c. o Simplify configuration message reply handling by copying reply frame data for the requester and storing completion status in the original request structure. o Add the mpt_complete_request_chain() helper method and use it to implement reset handlers that must abort transactions. o Keep track of all pending requests on the new requests_pending_list in the softc. o Add default handlers to mpt.c to handle generic event notifications and controller reset activities. The event handler code is largely the same as in the original driver. The reset handler is new and terminates any pending transactions with a status code indicating the controller needs to be re-initialized. o Add some endian support to the driver. A complete audit is still required for this driver to have any hope of operating in a big-endian environment. o Use inttypes.h and __inline. Come closer to being style(9) compliant. o Remove extraneous use of typedefs. o Convert request state from a strict enumeration to a series of flags. This allows us to, for example, tag transactions that have timed-out while retaining the state that the transaction is still in-flight on the controller. o Add mpt_wait_req() which allows a caller to poll or sleep for the completion of a request. Use this to simplify and factor code out from many initialization routines. We also use this to sleep for task management request completions in our CAM timeout handler. mpt.c: o Correct a bug in the event handler where request structures were freed even if the request reply was marked as a continuation reply. Continuation replies indicate that the controller still owns the request and freeing these replies prematurely corrupted controller state. o Implement firmware upload and download. On controllers that do not have dedicated NVRAM (as in the Sun v20/v40z), the firmware image is downloaded to the controller by the system BIOS. This image occupies precious controller RAM space until the host driver fetches the image, reducing the number of concurrent I/Os the controller can processes. The uploaded image is used to re-program the controller during hard reset events since the controller cannot fetch the firmware on its own. Implementing this feature allows much higher queue depths when RAID volumes are configured. o Changed configuration page accessors to allow threads to sleep rather than busy wait for completion. o Removed hard coded data transfer sizes from configuration page routines so that RAID configuration page processing is possible. mpt_reg.h: o Move controller register definitions into a separate file. mpt.h: o Re-arrange includes to allow inlined functions to be defined in mpt.h. o Add reply, event, and reset handler definitions. o Add softc fields for handling timeout and controller reset recovery. mpt_cam.c: o Move mpt_freebsd.c to mpt_cam.c. Move all core functionality, such as event handling, into mpt.c leaving only CAM SCSI support here. o Revamp completion handler to provide correct CAM status for all currently defined SCSI MPI message result codes. o Register event and reset handlers with the MPT core. Modify the event handler to notify CAM of bus reset events. The controller reset handler will abort any transactions that have timed out. All other pending CAM transactions are correctly aborted by the core driver's reset handler. o Allocate a single request up front to perform task management operations. This guarantees that we can always perform a TMF operation even when the controller is saturated with other operations. The single request also serves as a perfect mechanism of guaranteeing that only a single TMF is in flight at a time - something that is required according to the MPT Fusion documentation. o Add a helper function for issuing task management requests to the controller. This is used to abort individual requests or perform a bus reset. o Modify the CAM XPT_BUS_RESET ccb handler to wait for and properly handle the status of the bus reset task management frame used to reset the bus. The previous code assumed that the reset request would always succeed. o Add timeout recovery support. When a timeout occurs, the timed-out request is added to a queue to be processed by our recovery thread and the thread is woken up. The recovery thread processes timed-out command serially, attempting first to abort them and then falling back to a bus reset if an abort fails. o Add calls to mpt_reset() to reset the controller if any handshake command, bus reset attempt or abort attempt fails due to a timeout. o Export a secondary "bus" to CAM that exposes all volume drive members as pass-thru devices, allowing CAM to perform proper speed negotiation to hidden devices. o Add a CAM async event handler tracking the AC_FOUND_DEVICE event. Use this to trigger calls to set the per-volume queue depth once the volume is fully registered with CAM. This is required to avoid hitting firmware limits on volume queue depth. Exceeding the limit causes the firmware to hang. mpt_cam.h: o Add several helper functions for interfacing to CAM and performing timeout recovery. mpt_pci.c: o Disable interrupts on the controller before registering and enabling interrupt delivery to the OS. Otherwise we risk receiving interrupts before the driver is ready to receive them. o Make use of compatibility macros that allow the driver to be compiled under 4.x and 5.x. mpt_raid.c: o Add a per-controller instance RAID thread to perform settings changes and query status (minimizes CPU busy wait loops). o Use a shutdown handler to disable "Member Write Cache Enable" (MWCE) setting for RAID arrays set to enable MWCE During Rebuild. o Change reply handler function signature to allow handlers to defer the deletion of reply frames. Use this to allow the event reply handler to queue up events that need to be acked if no resources are available to immediately ack an event. Queued events are processed in mpt_free_request() where resources are freed. This avoids a panic on resource shortage. o Parse and print out RAID controller capabilities during driver probe. o Define, allocate, and maintain RAID data structures for volumes, hidden member physical disks and spare disks. o Add dynamic sysctls for per-instance setting of the log level, array resync rate, array member cache enable, and volume queue depth. mpt_debug.c: o Add mpt_lprt and mpt_lprtc for printing diagnostics conditioned on a particular log level to aid in tracking down driver issues. o Add mpt_decode_value() which parses the bits in an integer value based on a parsing table (mask, value, name string, tuples). mpilib/*: o Update mpi library header files to latest distribution from LSI. Submitted by: gibbs Approved by: re
2005-07-10 15:05:39 +00:00
return;
}
Massive overhaul of MPT Fusion driver: o Add timeout error recovery (from a thread context to avoid the deferral of other critical interrupts). o Properly recover commands across controller reset events. o Update the driver to handle events and status codes that have been added to the MPI spec since the driver was originally written. o Make the driver more modular to improve maintainability and support dynamic "personality" registration (e.g. SCSI Initiator, RAID, SAS, FC, etc). o Shorten and simplify the common I/O path to improve driver performance. o Add RAID volume and RAID member state/settings reporting. o Add periodic volume resynchronization status reporting. o Add support for sysctl tunable resync rate, member write cache enable, and volume transaction queue depth. Sponsored by ---------------- Avid Technologies Inc: SCSI error recovery, driver re-organization, update of MPI library headers, portions of dynamic personality registration, and misc bug fixes. Wheel Open Technologies: RAID event notification, RAID member pass-thru support, firmware upload/download support, enhanced RAID resync speed, portions of dynamic personality registration, and misc bug fixes. Detailed Changes ================ mpt.c mpt_cam.c mpt_raid.c mpt_pci.c: o Add support for personality modules. Each module exports load, and unload module scope methods as well as probe, attach, event, reset, shutdown, and detach per-device instance methods mpt.c mpt.h mpt_pci.c: o The driver now associates a callback function (via an index) with every transaction submitted to the controller. This allows the main interrupt handler to absolve itself of any knowledge of individual transaction/response types by simply calling the callback function "registered" for the transaction. We use a callback index instead of a callback function pointer in each requests so we can properly handle responses (e.g. event notifications) that are not associated with a transaction. Personality modules dynamically register their callbacks with the driver core to receive the callback index to use for their handlers. o Move the interrupt handler into mpt.c. The ISR algorithm is bus transport and OS independent and thus had no reason to be in mpt_pci.c. o Simplify configuration message reply handling by copying reply frame data for the requester and storing completion status in the original request structure. o Add the mpt_complete_request_chain() helper method and use it to implement reset handlers that must abort transactions. o Keep track of all pending requests on the new requests_pending_list in the softc. o Add default handlers to mpt.c to handle generic event notifications and controller reset activities. The event handler code is largely the same as in the original driver. The reset handler is new and terminates any pending transactions with a status code indicating the controller needs to be re-initialized. o Add some endian support to the driver. A complete audit is still required for this driver to have any hope of operating in a big-endian environment. o Use inttypes.h and __inline. Come closer to being style(9) compliant. o Remove extraneous use of typedefs. o Convert request state from a strict enumeration to a series of flags. This allows us to, for example, tag transactions that have timed-out while retaining the state that the transaction is still in-flight on the controller. o Add mpt_wait_req() which allows a caller to poll or sleep for the completion of a request. Use this to simplify and factor code out from many initialization routines. We also use this to sleep for task management request completions in our CAM timeout handler. mpt.c: o Correct a bug in the event handler where request structures were freed even if the request reply was marked as a continuation reply. Continuation replies indicate that the controller still owns the request and freeing these replies prematurely corrupted controller state. o Implement firmware upload and download. On controllers that do not have dedicated NVRAM (as in the Sun v20/v40z), the firmware image is downloaded to the controller by the system BIOS. This image occupies precious controller RAM space until the host driver fetches the image, reducing the number of concurrent I/Os the controller can processes. The uploaded image is used to re-program the controller during hard reset events since the controller cannot fetch the firmware on its own. Implementing this feature allows much higher queue depths when RAID volumes are configured. o Changed configuration page accessors to allow threads to sleep rather than busy wait for completion. o Removed hard coded data transfer sizes from configuration page routines so that RAID configuration page processing is possible. mpt_reg.h: o Move controller register definitions into a separate file. mpt.h: o Re-arrange includes to allow inlined functions to be defined in mpt.h. o Add reply, event, and reset handler definitions. o Add softc fields for handling timeout and controller reset recovery. mpt_cam.c: o Move mpt_freebsd.c to mpt_cam.c. Move all core functionality, such as event handling, into mpt.c leaving only CAM SCSI support here. o Revamp completion handler to provide correct CAM status for all currently defined SCSI MPI message result codes. o Register event and reset handlers with the MPT core. Modify the event handler to notify CAM of bus reset events. The controller reset handler will abort any transactions that have timed out. All other pending CAM transactions are correctly aborted by the core driver's reset handler. o Allocate a single request up front to perform task management operations. This guarantees that we can always perform a TMF operation even when the controller is saturated with other operations. The single request also serves as a perfect mechanism of guaranteeing that only a single TMF is in flight at a time - something that is required according to the MPT Fusion documentation. o Add a helper function for issuing task management requests to the controller. This is used to abort individual requests or perform a bus reset. o Modify the CAM XPT_BUS_RESET ccb handler to wait for and properly handle the status of the bus reset task management frame used to reset the bus. The previous code assumed that the reset request would always succeed. o Add timeout recovery support. When a timeout occurs, the timed-out request is added to a queue to be processed by our recovery thread and the thread is woken up. The recovery thread processes timed-out command serially, attempting first to abort them and then falling back to a bus reset if an abort fails. o Add calls to mpt_reset() to reset the controller if any handshake command, bus reset attempt or abort attempt fails due to a timeout. o Export a secondary "bus" to CAM that exposes all volume drive members as pass-thru devices, allowing CAM to perform proper speed negotiation to hidden devices. o Add a CAM async event handler tracking the AC_FOUND_DEVICE event. Use this to trigger calls to set the per-volume queue depth once the volume is fully registered with CAM. This is required to avoid hitting firmware limits on volume queue depth. Exceeding the limit causes the firmware to hang. mpt_cam.h: o Add several helper functions for interfacing to CAM and performing timeout recovery. mpt_pci.c: o Disable interrupts on the controller before registering and enabling interrupt delivery to the OS. Otherwise we risk receiving interrupts before the driver is ready to receive them. o Make use of compatibility macros that allow the driver to be compiled under 4.x and 5.x. mpt_raid.c: o Add a per-controller instance RAID thread to perform settings changes and query status (minimizes CPU busy wait loops). o Use a shutdown handler to disable "Member Write Cache Enable" (MWCE) setting for RAID arrays set to enable MWCE During Rebuild. o Change reply handler function signature to allow handlers to defer the deletion of reply frames. Use this to allow the event reply handler to queue up events that need to be acked if no resources are available to immediately ack an event. Queued events are processed in mpt_free_request() where resources are freed. This avoids a panic on resource shortage. o Parse and print out RAID controller capabilities during driver probe. o Define, allocate, and maintain RAID data structures for volumes, hidden member physical disks and spare disks. o Add dynamic sysctls for per-instance setting of the log level, array resync rate, array member cache enable, and volume queue depth. mpt_debug.c: o Add mpt_lprt and mpt_lprtc for printing diagnostics conditioned on a particular log level to aid in tracking down driver issues. o Add mpt_decode_value() which parses the bits in an integer value based on a parsing table (mask, value, name string, tuples). mpilib/*: o Update mpi library header files to latest distribution from LSI. Submitted by: gibbs Approved by: re
2005-07-10 15:05:39 +00:00
mpt_vol->flags ^= MPT_RVF_WCE_CHANGED;
if ((mpt_vol->flags & MPT_RVF_WCE_CHANGED) == 0) {
/*
* Wait one more status update to see if
* resyncing gets enabled. It gets disabled
* temporarilly when WCE is changed.
*/
return;
}
break;
case MPT_RAID_MWCE_ON:
if (mwce)
return;
break;
case MPT_RAID_MWCE_OFF:
if (!mwce)
return;
break;
case MPT_RAID_MWCE_NC:
return;
}
req = mpt_get_request(mpt, /*sleep_ok*/TRUE);
if (req == NULL) {
mpt_vol_prt(mpt, mpt_vol,
"mpt_verify_mwce: Get request failed!\n");
return;
}
vol_pg->VolumeSettings.Settings ^=
MPI_RAIDVOL0_SETTING_WRITE_CACHING_ENABLE;
memcpy(&data, &vol_pg->VolumeSettings, sizeof(data));
vol_pg->VolumeSettings.Settings ^=
MPI_RAIDVOL0_SETTING_WRITE_CACHING_ENABLE;
rv = mpt_issue_raid_req(mpt, mpt_vol, /*disk*/NULL, req,
MPI_RAID_ACTION_CHANGE_VOLUME_SETTINGS,
data, /*addr*/0, /*len*/0,
/*write*/FALSE, /*wait*/TRUE);
if (rv == ETIMEDOUT) {
mpt_vol_prt(mpt, mpt_vol, "mpt_verify_mwce: "
"Write Cache Enable Timed-out\n");
return;
}
ar = REQ_TO_RAID_ACTION_RESULT(req);
if (rv != 0
|| REQ_IOCSTATUS(req) != MPI_IOCSTATUS_SUCCESS
|| (ar->action_status != MPI_RAID_ACTION_ASTATUS_SUCCESS)) {
mpt_vol_prt(mpt, mpt_vol, "Write Cache Enable Failed: "
"%d:%x:%x\n", rv, req->IOCStatus,
ar->action_status);
} else {
vol_pg->VolumeSettings.Settings ^=
MPI_RAIDVOL0_SETTING_WRITE_CACHING_ENABLE;
}
mpt_free_request(mpt, req);
}
static void
mpt_verify_resync_rate(struct mpt_softc *mpt, struct mpt_raid_volume *mpt_vol)
{
request_t *req;
struct mpt_raid_action_result *ar;
CONFIG_PAGE_RAID_VOL_0 *vol_pg;
u_int prio;
int rv;
vol_pg = mpt_vol->config_page;
if (mpt->raid_resync_rate == MPT_RAID_RESYNC_RATE_NC)
return;
/*
* If the current RAID resync rate does not
* match our configured rate, update it.
*/
prio = vol_pg->VolumeSettings.Settings
& MPI_RAIDVOL0_SETTING_PRIORITY_RESYNC;
if (vol_pg->ResyncRate != 0
&& vol_pg->ResyncRate != mpt->raid_resync_rate) {
req = mpt_get_request(mpt, /*sleep_ok*/TRUE);
if (req == NULL) {
mpt_vol_prt(mpt, mpt_vol, "mpt_verify_resync_rate: "
"Get request failed!\n");
return;
}
rv = mpt_issue_raid_req(mpt, mpt_vol, /*disk*/NULL, req,
MPI_RAID_ACTION_SET_RESYNC_RATE,
mpt->raid_resync_rate, /*addr*/0,
/*len*/0, /*write*/FALSE, /*wait*/TRUE);
if (rv == ETIMEDOUT) {
mpt_vol_prt(mpt, mpt_vol, "mpt_refresh_raid_data: "
"Resync Rate Setting Timed-out\n");
return;
}
ar = REQ_TO_RAID_ACTION_RESULT(req);
if (rv != 0
|| REQ_IOCSTATUS(req) != MPI_IOCSTATUS_SUCCESS
|| (ar->action_status != MPI_RAID_ACTION_ASTATUS_SUCCESS)) {
mpt_vol_prt(mpt, mpt_vol, "Resync Rate Setting Failed: "
"%d:%x:%x\n", rv, req->IOCStatus,
ar->action_status);
} else
vol_pg->ResyncRate = mpt->raid_resync_rate;
mpt_free_request(mpt, req);
} else if ((prio && mpt->raid_resync_rate < 128)
|| (!prio && mpt->raid_resync_rate >= 128)) {
uint32_t data;
req = mpt_get_request(mpt, /*sleep_ok*/TRUE);
if (req == NULL) {
mpt_vol_prt(mpt, mpt_vol, "mpt_verify_resync_rate: "
"Get request failed!\n");
return;
}
vol_pg->VolumeSettings.Settings ^=
MPI_RAIDVOL0_SETTING_PRIORITY_RESYNC;
memcpy(&data, &vol_pg->VolumeSettings, sizeof(data));
vol_pg->VolumeSettings.Settings ^=
MPI_RAIDVOL0_SETTING_PRIORITY_RESYNC;
rv = mpt_issue_raid_req(mpt, mpt_vol, /*disk*/NULL, req,
MPI_RAID_ACTION_CHANGE_VOLUME_SETTINGS,
data, /*addr*/0, /*len*/0,
/*write*/FALSE, /*wait*/TRUE);
if (rv == ETIMEDOUT) {
mpt_vol_prt(mpt, mpt_vol, "mpt_refresh_raid_data: "
"Resync Rate Setting Timed-out\n");
return;
}
ar = REQ_TO_RAID_ACTION_RESULT(req);
if (rv != 0
|| REQ_IOCSTATUS(req) != MPI_IOCSTATUS_SUCCESS
|| (ar->action_status != MPI_RAID_ACTION_ASTATUS_SUCCESS)) {
mpt_vol_prt(mpt, mpt_vol, "Resync Rate Setting Failed: "
"%d:%x:%x\n", rv, req->IOCStatus,
ar->action_status);
} else {
vol_pg->VolumeSettings.Settings ^=
MPI_RAIDVOL0_SETTING_PRIORITY_RESYNC;
}
mpt_free_request(mpt, req);
}
}
static void
mpt_adjust_queue_depth(struct mpt_softc *mpt, struct mpt_raid_volume *mpt_vol,
struct cam_path *path)
{
struct ccb_relsim crs;
xpt_setup_ccb(&crs.ccb_h, path, /*priority*/5);
crs.ccb_h.func_code = XPT_REL_SIMQ;
crs.release_flags = RELSIM_ADJUST_OPENINGS;
crs.openings = mpt->raid_queue_depth;
xpt_action((union ccb *)&crs);
if (crs.ccb_h.status != CAM_REQ_CMP)
mpt_vol_prt(mpt, mpt_vol, "mpt_adjust_queue_depth failed "
"with CAM status %#x\n", crs.ccb_h.status);
}
static void
mpt_announce_vol(struct mpt_softc *mpt, struct mpt_raid_volume *mpt_vol)
{
CONFIG_PAGE_RAID_VOL_0 *vol_pg;
u_int i;
vol_pg = mpt_vol->config_page;
mpt_vol_prt(mpt, mpt_vol, "Settings (");
for (i = 1; i <= 0x8000; i <<= 1) {
switch (vol_pg->VolumeSettings.Settings & i) {
case MPI_RAIDVOL0_SETTING_WRITE_CACHING_ENABLE:
mpt_prtc(mpt, " Member-WCE");
break;
case MPI_RAIDVOL0_SETTING_OFFLINE_ON_SMART:
mpt_prtc(mpt, " Offline-On-SMART-Err");
break;
case MPI_RAIDVOL0_SETTING_AUTO_CONFIGURE:
mpt_prtc(mpt, " Hot-Plug-Spares");
break;
case MPI_RAIDVOL0_SETTING_PRIORITY_RESYNC:
mpt_prtc(mpt, " High-Priority-ReSync");
break;
default:
break;
}
}
mpt_prtc(mpt, " )\n");
if (vol_pg->VolumeSettings.HotSparePool != 0) {
mpt_vol_prt(mpt, mpt_vol, "Using Spare Pool%s",
powerof2(vol_pg->VolumeSettings.HotSparePool)
? ":" : "s:");
for (i = 0; i < 8; i++) {
u_int mask;
mask = 0x1 << i;
if ((vol_pg->VolumeSettings.HotSparePool & mask) == 0)
continue;
mpt_prtc(mpt, " %d", i);
}
mpt_prtc(mpt, "\n");
}
mpt_vol_prt(mpt, mpt_vol, "%d Members:\n", vol_pg->NumPhysDisks);
for (i = 0; i < vol_pg->NumPhysDisks; i++){
struct mpt_raid_disk *mpt_disk;
CONFIG_PAGE_RAID_PHYS_DISK_0 *disk_pg;
mpt_disk = mpt->raid_disks
+ vol_pg->PhysDisk[i].PhysDiskNum;
disk_pg = &mpt_disk->config_page;
mpt_prtc(mpt, " ");
mpt_prtc(mpt, "(%s:%d:%d): ", device_get_nameunit(mpt->dev),
disk_pg->PhysDiskBus, disk_pg->PhysDiskID);
if (vol_pg->VolumeType == MPI_RAID_VOL_TYPE_IM)
mpt_prtc(mpt, "%s\n",
mpt_disk->member_number == 0
? "Primary" : "Secondary");
else
mpt_prtc(mpt, "Stripe Position %d\n",
mpt_disk->member_number);
}
}
static void
mpt_announce_disk(struct mpt_softc *mpt, struct mpt_raid_disk *mpt_disk)
{
CONFIG_PAGE_RAID_PHYS_DISK_0 *disk_pg;
u_int i;
disk_pg = &mpt_disk->config_page;
mpt_disk_prt(mpt, mpt_disk,
"Physical (%s:%d:%d), Pass-thru (%s:%d:%d)\n",
device_get_nameunit(mpt->dev), disk_pg->PhysDiskBus,
disk_pg->PhysDiskID, device_get_nameunit(mpt->dev),
/*bus*/1, mpt_disk - mpt->raid_disks);
if (disk_pg->PhysDiskSettings.HotSparePool == 0)
return;
mpt_disk_prt(mpt, mpt_disk, "Member of Hot Spare Pool%s",
powerof2(disk_pg->PhysDiskSettings.HotSparePool)
? ":" : "s:");
for (i = 0; i < 8; i++) {
u_int mask;
mask = 0x1 << i;
if ((disk_pg->PhysDiskSettings.HotSparePool & mask) == 0)
continue;
mpt_prtc(mpt, " %d", i);
}
mpt_prtc(mpt, "\n");
}
static void
mpt_refresh_raid_disk(struct mpt_softc *mpt, struct mpt_raid_disk *mpt_disk,
IOC_3_PHYS_DISK *ioc_disk)
{
int rv;
rv = mpt_read_cfg_header(mpt, MPI_CONFIG_PAGETYPE_RAID_PHYSDISK,
/*PageNumber*/0, ioc_disk->PhysDiskNum,
&mpt_disk->config_page.Header,
/*sleep_ok*/TRUE, /*timeout_ms*/5000);
if (rv != 0) {
mpt_prt(mpt, "mpt_refresh_raid_disk: "
"Failed to read RAID Disk Hdr(%d)\n",
ioc_disk->PhysDiskNum);
return;
}
rv = mpt_read_cur_cfg_page(mpt, ioc_disk->PhysDiskNum,
&mpt_disk->config_page.Header,
sizeof(mpt_disk->config_page),
/*sleep_ok*/TRUE, /*timeout_ms*/5000);
if (rv != 0)
mpt_prt(mpt, "mpt_refresh_raid_disk: "
"Failed to read RAID Disk Page(%d)\n",
ioc_disk->PhysDiskNum);
}
static void
mpt_refresh_raid_vol(struct mpt_softc *mpt, struct mpt_raid_volume *mpt_vol,
CONFIG_PAGE_IOC_2_RAID_VOL *ioc_vol)
{
CONFIG_PAGE_RAID_VOL_0 *vol_pg;
struct mpt_raid_action_result *ar;
request_t *req;
int rv;
int i;
vol_pg = mpt_vol->config_page;
mpt_vol->flags &= ~MPT_RVF_UP2DATE;
rv = mpt_read_cfg_header(mpt, MPI_CONFIG_PAGETYPE_RAID_VOLUME,
/*PageNumber*/0, ioc_vol->VolumePageNumber,
&vol_pg->Header, /*sleep_ok*/TRUE,
/*timeout_ms*/5000);
if (rv != 0) {
mpt_vol_prt(mpt, mpt_vol, "mpt_refresh_raid_vol: "
"Failed to read RAID Vol Hdr(%d)\n",
ioc_vol->VolumePageNumber);
return;
}
rv = mpt_read_cur_cfg_page(mpt, ioc_vol->VolumePageNumber,
&vol_pg->Header, mpt->raid_page0_len,
/*sleep_ok*/TRUE, /*timeout_ms*/5000);
if (rv != 0) {
mpt_vol_prt(mpt, mpt_vol, "mpt_refresh_raid_vol: "
"Failed to read RAID Vol Page(%d)\n",
ioc_vol->VolumePageNumber);
return;
}
mpt_vol->flags |= MPT_RVF_ACTIVE;
/* Update disk entry array data. */
for (i = 0; i < vol_pg->NumPhysDisks; i++) {
struct mpt_raid_disk *mpt_disk;
mpt_disk = mpt->raid_disks + vol_pg->PhysDisk[i].PhysDiskNum;
mpt_disk->volume = mpt_vol;
mpt_disk->member_number = vol_pg->PhysDisk[i].PhysDiskMap;
if (vol_pg->VolumeType == MPI_RAID_VOL_TYPE_IM)
mpt_disk->member_number--;
}
if ((vol_pg->VolumeStatus.Flags
& MPI_RAIDVOL0_STATUS_FLAG_RESYNC_IN_PROGRESS) == 0)
return;
req = mpt_get_request(mpt, /*sleep_ok*/TRUE);
if (req == NULL) {
mpt_vol_prt(mpt, mpt_vol,
"mpt_refresh_raid_vol: Get request failed!\n");
return;
}
rv = mpt_issue_raid_req(mpt, mpt_vol, /*disk*/NULL, req,
MPI_RAID_ACTION_INDICATOR_STRUCT,
/*ActionWord*/0, /*addr*/0, /*len*/0,
/*write*/FALSE, /*wait*/TRUE);
if (rv == ETIMEDOUT) {
mpt_vol_prt(mpt, mpt_vol, "mpt_refresh_raid_vol: "
"Progress indicator fetch timedout!\n");
return;
}
ar = REQ_TO_RAID_ACTION_RESULT(req);
if (rv == 0
&& ar->action_status == MPI_RAID_ACTION_ASTATUS_SUCCESS
&& REQ_IOCSTATUS(req) == MPI_IOCSTATUS_SUCCESS) {
memcpy(&mpt_vol->sync_progress,
&ar->action_data.indicator_struct,
sizeof(mpt_vol->sync_progress));
} else {
mpt_vol_prt(mpt, mpt_vol, "mpt_refresh_raid_vol: "
"Progress indicator fetch failed!\n");
}
mpt_free_request(mpt, req);
}
/*
* Update in-core information about RAID support. We update any entries
* that didn't previously exists or have been marked as needing to
* be updated by our event handler. Interesting changes are displayed
* to the console.
*/
void
mpt_refresh_raid_data(struct mpt_softc *mpt)
{
CONFIG_PAGE_IOC_2_RAID_VOL *ioc_vol;
CONFIG_PAGE_IOC_2_RAID_VOL *ioc_last_vol;
IOC_3_PHYS_DISK *ioc_disk;
IOC_3_PHYS_DISK *ioc_last_disk;
CONFIG_PAGE_RAID_VOL_0 *vol_pg;
size_t len;
int rv;
int i;
u_int nonopt_volumes;
Massive overhaul of MPT Fusion driver: o Add timeout error recovery (from a thread context to avoid the deferral of other critical interrupts). o Properly recover commands across controller reset events. o Update the driver to handle events and status codes that have been added to the MPI spec since the driver was originally written. o Make the driver more modular to improve maintainability and support dynamic "personality" registration (e.g. SCSI Initiator, RAID, SAS, FC, etc). o Shorten and simplify the common I/O path to improve driver performance. o Add RAID volume and RAID member state/settings reporting. o Add periodic volume resynchronization status reporting. o Add support for sysctl tunable resync rate, member write cache enable, and volume transaction queue depth. Sponsored by ---------------- Avid Technologies Inc: SCSI error recovery, driver re-organization, update of MPI library headers, portions of dynamic personality registration, and misc bug fixes. Wheel Open Technologies: RAID event notification, RAID member pass-thru support, firmware upload/download support, enhanced RAID resync speed, portions of dynamic personality registration, and misc bug fixes. Detailed Changes ================ mpt.c mpt_cam.c mpt_raid.c mpt_pci.c: o Add support for personality modules. Each module exports load, and unload module scope methods as well as probe, attach, event, reset, shutdown, and detach per-device instance methods mpt.c mpt.h mpt_pci.c: o The driver now associates a callback function (via an index) with every transaction submitted to the controller. This allows the main interrupt handler to absolve itself of any knowledge of individual transaction/response types by simply calling the callback function "registered" for the transaction. We use a callback index instead of a callback function pointer in each requests so we can properly handle responses (e.g. event notifications) that are not associated with a transaction. Personality modules dynamically register their callbacks with the driver core to receive the callback index to use for their handlers. o Move the interrupt handler into mpt.c. The ISR algorithm is bus transport and OS independent and thus had no reason to be in mpt_pci.c. o Simplify configuration message reply handling by copying reply frame data for the requester and storing completion status in the original request structure. o Add the mpt_complete_request_chain() helper method and use it to implement reset handlers that must abort transactions. o Keep track of all pending requests on the new requests_pending_list in the softc. o Add default handlers to mpt.c to handle generic event notifications and controller reset activities. The event handler code is largely the same as in the original driver. The reset handler is new and terminates any pending transactions with a status code indicating the controller needs to be re-initialized. o Add some endian support to the driver. A complete audit is still required for this driver to have any hope of operating in a big-endian environment. o Use inttypes.h and __inline. Come closer to being style(9) compliant. o Remove extraneous use of typedefs. o Convert request state from a strict enumeration to a series of flags. This allows us to, for example, tag transactions that have timed-out while retaining the state that the transaction is still in-flight on the controller. o Add mpt_wait_req() which allows a caller to poll or sleep for the completion of a request. Use this to simplify and factor code out from many initialization routines. We also use this to sleep for task management request completions in our CAM timeout handler. mpt.c: o Correct a bug in the event handler where request structures were freed even if the request reply was marked as a continuation reply. Continuation replies indicate that the controller still owns the request and freeing these replies prematurely corrupted controller state. o Implement firmware upload and download. On controllers that do not have dedicated NVRAM (as in the Sun v20/v40z), the firmware image is downloaded to the controller by the system BIOS. This image occupies precious controller RAM space until the host driver fetches the image, reducing the number of concurrent I/Os the controller can processes. The uploaded image is used to re-program the controller during hard reset events since the controller cannot fetch the firmware on its own. Implementing this feature allows much higher queue depths when RAID volumes are configured. o Changed configuration page accessors to allow threads to sleep rather than busy wait for completion. o Removed hard coded data transfer sizes from configuration page routines so that RAID configuration page processing is possible. mpt_reg.h: o Move controller register definitions into a separate file. mpt.h: o Re-arrange includes to allow inlined functions to be defined in mpt.h. o Add reply, event, and reset handler definitions. o Add softc fields for handling timeout and controller reset recovery. mpt_cam.c: o Move mpt_freebsd.c to mpt_cam.c. Move all core functionality, such as event handling, into mpt.c leaving only CAM SCSI support here. o Revamp completion handler to provide correct CAM status for all currently defined SCSI MPI message result codes. o Register event and reset handlers with the MPT core. Modify the event handler to notify CAM of bus reset events. The controller reset handler will abort any transactions that have timed out. All other pending CAM transactions are correctly aborted by the core driver's reset handler. o Allocate a single request up front to perform task management operations. This guarantees that we can always perform a TMF operation even when the controller is saturated with other operations. The single request also serves as a perfect mechanism of guaranteeing that only a single TMF is in flight at a time - something that is required according to the MPT Fusion documentation. o Add a helper function for issuing task management requests to the controller. This is used to abort individual requests or perform a bus reset. o Modify the CAM XPT_BUS_RESET ccb handler to wait for and properly handle the status of the bus reset task management frame used to reset the bus. The previous code assumed that the reset request would always succeed. o Add timeout recovery support. When a timeout occurs, the timed-out request is added to a queue to be processed by our recovery thread and the thread is woken up. The recovery thread processes timed-out command serially, attempting first to abort them and then falling back to a bus reset if an abort fails. o Add calls to mpt_reset() to reset the controller if any handshake command, bus reset attempt or abort attempt fails due to a timeout. o Export a secondary "bus" to CAM that exposes all volume drive members as pass-thru devices, allowing CAM to perform proper speed negotiation to hidden devices. o Add a CAM async event handler tracking the AC_FOUND_DEVICE event. Use this to trigger calls to set the per-volume queue depth once the volume is fully registered with CAM. This is required to avoid hitting firmware limits on volume queue depth. Exceeding the limit causes the firmware to hang. mpt_cam.h: o Add several helper functions for interfacing to CAM and performing timeout recovery. mpt_pci.c: o Disable interrupts on the controller before registering and enabling interrupt delivery to the OS. Otherwise we risk receiving interrupts before the driver is ready to receive them. o Make use of compatibility macros that allow the driver to be compiled under 4.x and 5.x. mpt_raid.c: o Add a per-controller instance RAID thread to perform settings changes and query status (minimizes CPU busy wait loops). o Use a shutdown handler to disable "Member Write Cache Enable" (MWCE) setting for RAID arrays set to enable MWCE During Rebuild. o Change reply handler function signature to allow handlers to defer the deletion of reply frames. Use this to allow the event reply handler to queue up events that need to be acked if no resources are available to immediately ack an event. Queued events are processed in mpt_free_request() where resources are freed. This avoids a panic on resource shortage. o Parse and print out RAID controller capabilities during driver probe. o Define, allocate, and maintain RAID data structures for volumes, hidden member physical disks and spare disks. o Add dynamic sysctls for per-instance setting of the log level, array resync rate, array member cache enable, and volume queue depth. mpt_debug.c: o Add mpt_lprt and mpt_lprtc for printing diagnostics conditioned on a particular log level to aid in tracking down driver issues. o Add mpt_decode_value() which parses the bits in an integer value based on a parsing table (mask, value, name string, tuples). mpilib/*: o Update mpi library header files to latest distribution from LSI. Submitted by: gibbs Approved by: re
2005-07-10 15:05:39 +00:00
if (mpt->ioc_page2 == NULL || mpt->ioc_page3 == NULL) {
Massive overhaul of MPT Fusion driver: o Add timeout error recovery (from a thread context to avoid the deferral of other critical interrupts). o Properly recover commands across controller reset events. o Update the driver to handle events and status codes that have been added to the MPI spec since the driver was originally written. o Make the driver more modular to improve maintainability and support dynamic "personality" registration (e.g. SCSI Initiator, RAID, SAS, FC, etc). o Shorten and simplify the common I/O path to improve driver performance. o Add RAID volume and RAID member state/settings reporting. o Add periodic volume resynchronization status reporting. o Add support for sysctl tunable resync rate, member write cache enable, and volume transaction queue depth. Sponsored by ---------------- Avid Technologies Inc: SCSI error recovery, driver re-organization, update of MPI library headers, portions of dynamic personality registration, and misc bug fixes. Wheel Open Technologies: RAID event notification, RAID member pass-thru support, firmware upload/download support, enhanced RAID resync speed, portions of dynamic personality registration, and misc bug fixes. Detailed Changes ================ mpt.c mpt_cam.c mpt_raid.c mpt_pci.c: o Add support for personality modules. Each module exports load, and unload module scope methods as well as probe, attach, event, reset, shutdown, and detach per-device instance methods mpt.c mpt.h mpt_pci.c: o The driver now associates a callback function (via an index) with every transaction submitted to the controller. This allows the main interrupt handler to absolve itself of any knowledge of individual transaction/response types by simply calling the callback function "registered" for the transaction. We use a callback index instead of a callback function pointer in each requests so we can properly handle responses (e.g. event notifications) that are not associated with a transaction. Personality modules dynamically register their callbacks with the driver core to receive the callback index to use for their handlers. o Move the interrupt handler into mpt.c. The ISR algorithm is bus transport and OS independent and thus had no reason to be in mpt_pci.c. o Simplify configuration message reply handling by copying reply frame data for the requester and storing completion status in the original request structure. o Add the mpt_complete_request_chain() helper method and use it to implement reset handlers that must abort transactions. o Keep track of all pending requests on the new requests_pending_list in the softc. o Add default handlers to mpt.c to handle generic event notifications and controller reset activities. The event handler code is largely the same as in the original driver. The reset handler is new and terminates any pending transactions with a status code indicating the controller needs to be re-initialized. o Add some endian support to the driver. A complete audit is still required for this driver to have any hope of operating in a big-endian environment. o Use inttypes.h and __inline. Come closer to being style(9) compliant. o Remove extraneous use of typedefs. o Convert request state from a strict enumeration to a series of flags. This allows us to, for example, tag transactions that have timed-out while retaining the state that the transaction is still in-flight on the controller. o Add mpt_wait_req() which allows a caller to poll or sleep for the completion of a request. Use this to simplify and factor code out from many initialization routines. We also use this to sleep for task management request completions in our CAM timeout handler. mpt.c: o Correct a bug in the event handler where request structures were freed even if the request reply was marked as a continuation reply. Continuation replies indicate that the controller still owns the request and freeing these replies prematurely corrupted controller state. o Implement firmware upload and download. On controllers that do not have dedicated NVRAM (as in the Sun v20/v40z), the firmware image is downloaded to the controller by the system BIOS. This image occupies precious controller RAM space until the host driver fetches the image, reducing the number of concurrent I/Os the controller can processes. The uploaded image is used to re-program the controller during hard reset events since the controller cannot fetch the firmware on its own. Implementing this feature allows much higher queue depths when RAID volumes are configured. o Changed configuration page accessors to allow threads to sleep rather than busy wait for completion. o Removed hard coded data transfer sizes from configuration page routines so that RAID configuration page processing is possible. mpt_reg.h: o Move controller register definitions into a separate file. mpt.h: o Re-arrange includes to allow inlined functions to be defined in mpt.h. o Add reply, event, and reset handler definitions. o Add softc fields for handling timeout and controller reset recovery. mpt_cam.c: o Move mpt_freebsd.c to mpt_cam.c. Move all core functionality, such as event handling, into mpt.c leaving only CAM SCSI support here. o Revamp completion handler to provide correct CAM status for all currently defined SCSI MPI message result codes. o Register event and reset handlers with the MPT core. Modify the event handler to notify CAM of bus reset events. The controller reset handler will abort any transactions that have timed out. All other pending CAM transactions are correctly aborted by the core driver's reset handler. o Allocate a single request up front to perform task management operations. This guarantees that we can always perform a TMF operation even when the controller is saturated with other operations. The single request also serves as a perfect mechanism of guaranteeing that only a single TMF is in flight at a time - something that is required according to the MPT Fusion documentation. o Add a helper function for issuing task management requests to the controller. This is used to abort individual requests or perform a bus reset. o Modify the CAM XPT_BUS_RESET ccb handler to wait for and properly handle the status of the bus reset task management frame used to reset the bus. The previous code assumed that the reset request would always succeed. o Add timeout recovery support. When a timeout occurs, the timed-out request is added to a queue to be processed by our recovery thread and the thread is woken up. The recovery thread processes timed-out command serially, attempting first to abort them and then falling back to a bus reset if an abort fails. o Add calls to mpt_reset() to reset the controller if any handshake command, bus reset attempt or abort attempt fails due to a timeout. o Export a secondary "bus" to CAM that exposes all volume drive members as pass-thru devices, allowing CAM to perform proper speed negotiation to hidden devices. o Add a CAM async event handler tracking the AC_FOUND_DEVICE event. Use this to trigger calls to set the per-volume queue depth once the volume is fully registered with CAM. This is required to avoid hitting firmware limits on volume queue depth. Exceeding the limit causes the firmware to hang. mpt_cam.h: o Add several helper functions for interfacing to CAM and performing timeout recovery. mpt_pci.c: o Disable interrupts on the controller before registering and enabling interrupt delivery to the OS. Otherwise we risk receiving interrupts before the driver is ready to receive them. o Make use of compatibility macros that allow the driver to be compiled under 4.x and 5.x. mpt_raid.c: o Add a per-controller instance RAID thread to perform settings changes and query status (minimizes CPU busy wait loops). o Use a shutdown handler to disable "Member Write Cache Enable" (MWCE) setting for RAID arrays set to enable MWCE During Rebuild. o Change reply handler function signature to allow handlers to defer the deletion of reply frames. Use this to allow the event reply handler to queue up events that need to be acked if no resources are available to immediately ack an event. Queued events are processed in mpt_free_request() where resources are freed. This avoids a panic on resource shortage. o Parse and print out RAID controller capabilities during driver probe. o Define, allocate, and maintain RAID data structures for volumes, hidden member physical disks and spare disks. o Add dynamic sysctls for per-instance setting of the log level, array resync rate, array member cache enable, and volume queue depth. mpt_debug.c: o Add mpt_lprt and mpt_lprtc for printing diagnostics conditioned on a particular log level to aid in tracking down driver issues. o Add mpt_decode_value() which parses the bits in an integer value based on a parsing table (mask, value, name string, tuples). mpilib/*: o Update mpi library header files to latest distribution from LSI. Submitted by: gibbs Approved by: re
2005-07-10 15:05:39 +00:00
return;
}
Massive overhaul of MPT Fusion driver: o Add timeout error recovery (from a thread context to avoid the deferral of other critical interrupts). o Properly recover commands across controller reset events. o Update the driver to handle events and status codes that have been added to the MPI spec since the driver was originally written. o Make the driver more modular to improve maintainability and support dynamic "personality" registration (e.g. SCSI Initiator, RAID, SAS, FC, etc). o Shorten and simplify the common I/O path to improve driver performance. o Add RAID volume and RAID member state/settings reporting. o Add periodic volume resynchronization status reporting. o Add support for sysctl tunable resync rate, member write cache enable, and volume transaction queue depth. Sponsored by ---------------- Avid Technologies Inc: SCSI error recovery, driver re-organization, update of MPI library headers, portions of dynamic personality registration, and misc bug fixes. Wheel Open Technologies: RAID event notification, RAID member pass-thru support, firmware upload/download support, enhanced RAID resync speed, portions of dynamic personality registration, and misc bug fixes. Detailed Changes ================ mpt.c mpt_cam.c mpt_raid.c mpt_pci.c: o Add support for personality modules. Each module exports load, and unload module scope methods as well as probe, attach, event, reset, shutdown, and detach per-device instance methods mpt.c mpt.h mpt_pci.c: o The driver now associates a callback function (via an index) with every transaction submitted to the controller. This allows the main interrupt handler to absolve itself of any knowledge of individual transaction/response types by simply calling the callback function "registered" for the transaction. We use a callback index instead of a callback function pointer in each requests so we can properly handle responses (e.g. event notifications) that are not associated with a transaction. Personality modules dynamically register their callbacks with the driver core to receive the callback index to use for their handlers. o Move the interrupt handler into mpt.c. The ISR algorithm is bus transport and OS independent and thus had no reason to be in mpt_pci.c. o Simplify configuration message reply handling by copying reply frame data for the requester and storing completion status in the original request structure. o Add the mpt_complete_request_chain() helper method and use it to implement reset handlers that must abort transactions. o Keep track of all pending requests on the new requests_pending_list in the softc. o Add default handlers to mpt.c to handle generic event notifications and controller reset activities. The event handler code is largely the same as in the original driver. The reset handler is new and terminates any pending transactions with a status code indicating the controller needs to be re-initialized. o Add some endian support to the driver. A complete audit is still required for this driver to have any hope of operating in a big-endian environment. o Use inttypes.h and __inline. Come closer to being style(9) compliant. o Remove extraneous use of typedefs. o Convert request state from a strict enumeration to a series of flags. This allows us to, for example, tag transactions that have timed-out while retaining the state that the transaction is still in-flight on the controller. o Add mpt_wait_req() which allows a caller to poll or sleep for the completion of a request. Use this to simplify and factor code out from many initialization routines. We also use this to sleep for task management request completions in our CAM timeout handler. mpt.c: o Correct a bug in the event handler where request structures were freed even if the request reply was marked as a continuation reply. Continuation replies indicate that the controller still owns the request and freeing these replies prematurely corrupted controller state. o Implement firmware upload and download. On controllers that do not have dedicated NVRAM (as in the Sun v20/v40z), the firmware image is downloaded to the controller by the system BIOS. This image occupies precious controller RAM space until the host driver fetches the image, reducing the number of concurrent I/Os the controller can processes. The uploaded image is used to re-program the controller during hard reset events since the controller cannot fetch the firmware on its own. Implementing this feature allows much higher queue depths when RAID volumes are configured. o Changed configuration page accessors to allow threads to sleep rather than busy wait for completion. o Removed hard coded data transfer sizes from configuration page routines so that RAID configuration page processing is possible. mpt_reg.h: o Move controller register definitions into a separate file. mpt.h: o Re-arrange includes to allow inlined functions to be defined in mpt.h. o Add reply, event, and reset handler definitions. o Add softc fields for handling timeout and controller reset recovery. mpt_cam.c: o Move mpt_freebsd.c to mpt_cam.c. Move all core functionality, such as event handling, into mpt.c leaving only CAM SCSI support here. o Revamp completion handler to provide correct CAM status for all currently defined SCSI MPI message result codes. o Register event and reset handlers with the MPT core. Modify the event handler to notify CAM of bus reset events. The controller reset handler will abort any transactions that have timed out. All other pending CAM transactions are correctly aborted by the core driver's reset handler. o Allocate a single request up front to perform task management operations. This guarantees that we can always perform a TMF operation even when the controller is saturated with other operations. The single request also serves as a perfect mechanism of guaranteeing that only a single TMF is in flight at a time - something that is required according to the MPT Fusion documentation. o Add a helper function for issuing task management requests to the controller. This is used to abort individual requests or perform a bus reset. o Modify the CAM XPT_BUS_RESET ccb handler to wait for and properly handle the status of the bus reset task management frame used to reset the bus. The previous code assumed that the reset request would always succeed. o Add timeout recovery support. When a timeout occurs, the timed-out request is added to a queue to be processed by our recovery thread and the thread is woken up. The recovery thread processes timed-out command serially, attempting first to abort them and then falling back to a bus reset if an abort fails. o Add calls to mpt_reset() to reset the controller if any handshake command, bus reset attempt or abort attempt fails due to a timeout. o Export a secondary "bus" to CAM that exposes all volume drive members as pass-thru devices, allowing CAM to perform proper speed negotiation to hidden devices. o Add a CAM async event handler tracking the AC_FOUND_DEVICE event. Use this to trigger calls to set the per-volume queue depth once the volume is fully registered with CAM. This is required to avoid hitting firmware limits on volume queue depth. Exceeding the limit causes the firmware to hang. mpt_cam.h: o Add several helper functions for interfacing to CAM and performing timeout recovery. mpt_pci.c: o Disable interrupts on the controller before registering and enabling interrupt delivery to the OS. Otherwise we risk receiving interrupts before the driver is ready to receive them. o Make use of compatibility macros that allow the driver to be compiled under 4.x and 5.x. mpt_raid.c: o Add a per-controller instance RAID thread to perform settings changes and query status (minimizes CPU busy wait loops). o Use a shutdown handler to disable "Member Write Cache Enable" (MWCE) setting for RAID arrays set to enable MWCE During Rebuild. o Change reply handler function signature to allow handlers to defer the deletion of reply frames. Use this to allow the event reply handler to queue up events that need to be acked if no resources are available to immediately ack an event. Queued events are processed in mpt_free_request() where resources are freed. This avoids a panic on resource shortage. o Parse and print out RAID controller capabilities during driver probe. o Define, allocate, and maintain RAID data structures for volumes, hidden member physical disks and spare disks. o Add dynamic sysctls for per-instance setting of the log level, array resync rate, array member cache enable, and volume queue depth. mpt_debug.c: o Add mpt_lprt and mpt_lprtc for printing diagnostics conditioned on a particular log level to aid in tracking down driver issues. o Add mpt_decode_value() which parses the bits in an integer value based on a parsing table (mask, value, name string, tuples). mpilib/*: o Update mpi library header files to latest distribution from LSI. Submitted by: gibbs Approved by: re
2005-07-10 15:05:39 +00:00
/*
* Mark all items as unreferenced by the configuration.
Massive overhaul of MPT Fusion driver: o Add timeout error recovery (from a thread context to avoid the deferral of other critical interrupts). o Properly recover commands across controller reset events. o Update the driver to handle events and status codes that have been added to the MPI spec since the driver was originally written. o Make the driver more modular to improve maintainability and support dynamic "personality" registration (e.g. SCSI Initiator, RAID, SAS, FC, etc). o Shorten and simplify the common I/O path to improve driver performance. o Add RAID volume and RAID member state/settings reporting. o Add periodic volume resynchronization status reporting. o Add support for sysctl tunable resync rate, member write cache enable, and volume transaction queue depth. Sponsored by ---------------- Avid Technologies Inc: SCSI error recovery, driver re-organization, update of MPI library headers, portions of dynamic personality registration, and misc bug fixes. Wheel Open Technologies: RAID event notification, RAID member pass-thru support, firmware upload/download support, enhanced RAID resync speed, portions of dynamic personality registration, and misc bug fixes. Detailed Changes ================ mpt.c mpt_cam.c mpt_raid.c mpt_pci.c: o Add support for personality modules. Each module exports load, and unload module scope methods as well as probe, attach, event, reset, shutdown, and detach per-device instance methods mpt.c mpt.h mpt_pci.c: o The driver now associates a callback function (via an index) with every transaction submitted to the controller. This allows the main interrupt handler to absolve itself of any knowledge of individual transaction/response types by simply calling the callback function "registered" for the transaction. We use a callback index instead of a callback function pointer in each requests so we can properly handle responses (e.g. event notifications) that are not associated with a transaction. Personality modules dynamically register their callbacks with the driver core to receive the callback index to use for their handlers. o Move the interrupt handler into mpt.c. The ISR algorithm is bus transport and OS independent and thus had no reason to be in mpt_pci.c. o Simplify configuration message reply handling by copying reply frame data for the requester and storing completion status in the original request structure. o Add the mpt_complete_request_chain() helper method and use it to implement reset handlers that must abort transactions. o Keep track of all pending requests on the new requests_pending_list in the softc. o Add default handlers to mpt.c to handle generic event notifications and controller reset activities. The event handler code is largely the same as in the original driver. The reset handler is new and terminates any pending transactions with a status code indicating the controller needs to be re-initialized. o Add some endian support to the driver. A complete audit is still required for this driver to have any hope of operating in a big-endian environment. o Use inttypes.h and __inline. Come closer to being style(9) compliant. o Remove extraneous use of typedefs. o Convert request state from a strict enumeration to a series of flags. This allows us to, for example, tag transactions that have timed-out while retaining the state that the transaction is still in-flight on the controller. o Add mpt_wait_req() which allows a caller to poll or sleep for the completion of a request. Use this to simplify and factor code out from many initialization routines. We also use this to sleep for task management request completions in our CAM timeout handler. mpt.c: o Correct a bug in the event handler where request structures were freed even if the request reply was marked as a continuation reply. Continuation replies indicate that the controller still owns the request and freeing these replies prematurely corrupted controller state. o Implement firmware upload and download. On controllers that do not have dedicated NVRAM (as in the Sun v20/v40z), the firmware image is downloaded to the controller by the system BIOS. This image occupies precious controller RAM space until the host driver fetches the image, reducing the number of concurrent I/Os the controller can processes. The uploaded image is used to re-program the controller during hard reset events since the controller cannot fetch the firmware on its own. Implementing this feature allows much higher queue depths when RAID volumes are configured. o Changed configuration page accessors to allow threads to sleep rather than busy wait for completion. o Removed hard coded data transfer sizes from configuration page routines so that RAID configuration page processing is possible. mpt_reg.h: o Move controller register definitions into a separate file. mpt.h: o Re-arrange includes to allow inlined functions to be defined in mpt.h. o Add reply, event, and reset handler definitions. o Add softc fields for handling timeout and controller reset recovery. mpt_cam.c: o Move mpt_freebsd.c to mpt_cam.c. Move all core functionality, such as event handling, into mpt.c leaving only CAM SCSI support here. o Revamp completion handler to provide correct CAM status for all currently defined SCSI MPI message result codes. o Register event and reset handlers with the MPT core. Modify the event handler to notify CAM of bus reset events. The controller reset handler will abort any transactions that have timed out. All other pending CAM transactions are correctly aborted by the core driver's reset handler. o Allocate a single request up front to perform task management operations. This guarantees that we can always perform a TMF operation even when the controller is saturated with other operations. The single request also serves as a perfect mechanism of guaranteeing that only a single TMF is in flight at a time - something that is required according to the MPT Fusion documentation. o Add a helper function for issuing task management requests to the controller. This is used to abort individual requests or perform a bus reset. o Modify the CAM XPT_BUS_RESET ccb handler to wait for and properly handle the status of the bus reset task management frame used to reset the bus. The previous code assumed that the reset request would always succeed. o Add timeout recovery support. When a timeout occurs, the timed-out request is added to a queue to be processed by our recovery thread and the thread is woken up. The recovery thread processes timed-out command serially, attempting first to abort them and then falling back to a bus reset if an abort fails. o Add calls to mpt_reset() to reset the controller if any handshake command, bus reset attempt or abort attempt fails due to a timeout. o Export a secondary "bus" to CAM that exposes all volume drive members as pass-thru devices, allowing CAM to perform proper speed negotiation to hidden devices. o Add a CAM async event handler tracking the AC_FOUND_DEVICE event. Use this to trigger calls to set the per-volume queue depth once the volume is fully registered with CAM. This is required to avoid hitting firmware limits on volume queue depth. Exceeding the limit causes the firmware to hang. mpt_cam.h: o Add several helper functions for interfacing to CAM and performing timeout recovery. mpt_pci.c: o Disable interrupts on the controller before registering and enabling interrupt delivery to the OS. Otherwise we risk receiving interrupts before the driver is ready to receive them. o Make use of compatibility macros that allow the driver to be compiled under 4.x and 5.x. mpt_raid.c: o Add a per-controller instance RAID thread to perform settings changes and query status (minimizes CPU busy wait loops). o Use a shutdown handler to disable "Member Write Cache Enable" (MWCE) setting for RAID arrays set to enable MWCE During Rebuild. o Change reply handler function signature to allow handlers to defer the deletion of reply frames. Use this to allow the event reply handler to queue up events that need to be acked if no resources are available to immediately ack an event. Queued events are processed in mpt_free_request() where resources are freed. This avoids a panic on resource shortage. o Parse and print out RAID controller capabilities during driver probe. o Define, allocate, and maintain RAID data structures for volumes, hidden member physical disks and spare disks. o Add dynamic sysctls for per-instance setting of the log level, array resync rate, array member cache enable, and volume queue depth. mpt_debug.c: o Add mpt_lprt and mpt_lprtc for printing diagnostics conditioned on a particular log level to aid in tracking down driver issues. o Add mpt_decode_value() which parses the bits in an integer value based on a parsing table (mask, value, name string, tuples). mpilib/*: o Update mpi library header files to latest distribution from LSI. Submitted by: gibbs Approved by: re
2005-07-10 15:05:39 +00:00
* This allows us to find, report, and discard stale
* entries.
*/
for (i = 0; i < mpt->ioc_page2->MaxPhysDisks; i++) {
Massive overhaul of MPT Fusion driver: o Add timeout error recovery (from a thread context to avoid the deferral of other critical interrupts). o Properly recover commands across controller reset events. o Update the driver to handle events and status codes that have been added to the MPI spec since the driver was originally written. o Make the driver more modular to improve maintainability and support dynamic "personality" registration (e.g. SCSI Initiator, RAID, SAS, FC, etc). o Shorten and simplify the common I/O path to improve driver performance. o Add RAID volume and RAID member state/settings reporting. o Add periodic volume resynchronization status reporting. o Add support for sysctl tunable resync rate, member write cache enable, and volume transaction queue depth. Sponsored by ---------------- Avid Technologies Inc: SCSI error recovery, driver re-organization, update of MPI library headers, portions of dynamic personality registration, and misc bug fixes. Wheel Open Technologies: RAID event notification, RAID member pass-thru support, firmware upload/download support, enhanced RAID resync speed, portions of dynamic personality registration, and misc bug fixes. Detailed Changes ================ mpt.c mpt_cam.c mpt_raid.c mpt_pci.c: o Add support for personality modules. Each module exports load, and unload module scope methods as well as probe, attach, event, reset, shutdown, and detach per-device instance methods mpt.c mpt.h mpt_pci.c: o The driver now associates a callback function (via an index) with every transaction submitted to the controller. This allows the main interrupt handler to absolve itself of any knowledge of individual transaction/response types by simply calling the callback function "registered" for the transaction. We use a callback index instead of a callback function pointer in each requests so we can properly handle responses (e.g. event notifications) that are not associated with a transaction. Personality modules dynamically register their callbacks with the driver core to receive the callback index to use for their handlers. o Move the interrupt handler into mpt.c. The ISR algorithm is bus transport and OS independent and thus had no reason to be in mpt_pci.c. o Simplify configuration message reply handling by copying reply frame data for the requester and storing completion status in the original request structure. o Add the mpt_complete_request_chain() helper method and use it to implement reset handlers that must abort transactions. o Keep track of all pending requests on the new requests_pending_list in the softc. o Add default handlers to mpt.c to handle generic event notifications and controller reset activities. The event handler code is largely the same as in the original driver. The reset handler is new and terminates any pending transactions with a status code indicating the controller needs to be re-initialized. o Add some endian support to the driver. A complete audit is still required for this driver to have any hope of operating in a big-endian environment. o Use inttypes.h and __inline. Come closer to being style(9) compliant. o Remove extraneous use of typedefs. o Convert request state from a strict enumeration to a series of flags. This allows us to, for example, tag transactions that have timed-out while retaining the state that the transaction is still in-flight on the controller. o Add mpt_wait_req() which allows a caller to poll or sleep for the completion of a request. Use this to simplify and factor code out from many initialization routines. We also use this to sleep for task management request completions in our CAM timeout handler. mpt.c: o Correct a bug in the event handler where request structures were freed even if the request reply was marked as a continuation reply. Continuation replies indicate that the controller still owns the request and freeing these replies prematurely corrupted controller state. o Implement firmware upload and download. On controllers that do not have dedicated NVRAM (as in the Sun v20/v40z), the firmware image is downloaded to the controller by the system BIOS. This image occupies precious controller RAM space until the host driver fetches the image, reducing the number of concurrent I/Os the controller can processes. The uploaded image is used to re-program the controller during hard reset events since the controller cannot fetch the firmware on its own. Implementing this feature allows much higher queue depths when RAID volumes are configured. o Changed configuration page accessors to allow threads to sleep rather than busy wait for completion. o Removed hard coded data transfer sizes from configuration page routines so that RAID configuration page processing is possible. mpt_reg.h: o Move controller register definitions into a separate file. mpt.h: o Re-arrange includes to allow inlined functions to be defined in mpt.h. o Add reply, event, and reset handler definitions. o Add softc fields for handling timeout and controller reset recovery. mpt_cam.c: o Move mpt_freebsd.c to mpt_cam.c. Move all core functionality, such as event handling, into mpt.c leaving only CAM SCSI support here. o Revamp completion handler to provide correct CAM status for all currently defined SCSI MPI message result codes. o Register event and reset handlers with the MPT core. Modify the event handler to notify CAM of bus reset events. The controller reset handler will abort any transactions that have timed out. All other pending CAM transactions are correctly aborted by the core driver's reset handler. o Allocate a single request up front to perform task management operations. This guarantees that we can always perform a TMF operation even when the controller is saturated with other operations. The single request also serves as a perfect mechanism of guaranteeing that only a single TMF is in flight at a time - something that is required according to the MPT Fusion documentation. o Add a helper function for issuing task management requests to the controller. This is used to abort individual requests or perform a bus reset. o Modify the CAM XPT_BUS_RESET ccb handler to wait for and properly handle the status of the bus reset task management frame used to reset the bus. The previous code assumed that the reset request would always succeed. o Add timeout recovery support. When a timeout occurs, the timed-out request is added to a queue to be processed by our recovery thread and the thread is woken up. The recovery thread processes timed-out command serially, attempting first to abort them and then falling back to a bus reset if an abort fails. o Add calls to mpt_reset() to reset the controller if any handshake command, bus reset attempt or abort attempt fails due to a timeout. o Export a secondary "bus" to CAM that exposes all volume drive members as pass-thru devices, allowing CAM to perform proper speed negotiation to hidden devices. o Add a CAM async event handler tracking the AC_FOUND_DEVICE event. Use this to trigger calls to set the per-volume queue depth once the volume is fully registered with CAM. This is required to avoid hitting firmware limits on volume queue depth. Exceeding the limit causes the firmware to hang. mpt_cam.h: o Add several helper functions for interfacing to CAM and performing timeout recovery. mpt_pci.c: o Disable interrupts on the controller before registering and enabling interrupt delivery to the OS. Otherwise we risk receiving interrupts before the driver is ready to receive them. o Make use of compatibility macros that allow the driver to be compiled under 4.x and 5.x. mpt_raid.c: o Add a per-controller instance RAID thread to perform settings changes and query status (minimizes CPU busy wait loops). o Use a shutdown handler to disable "Member Write Cache Enable" (MWCE) setting for RAID arrays set to enable MWCE During Rebuild. o Change reply handler function signature to allow handlers to defer the deletion of reply frames. Use this to allow the event reply handler to queue up events that need to be acked if no resources are available to immediately ack an event. Queued events are processed in mpt_free_request() where resources are freed. This avoids a panic on resource shortage. o Parse and print out RAID controller capabilities during driver probe. o Define, allocate, and maintain RAID data structures for volumes, hidden member physical disks and spare disks. o Add dynamic sysctls for per-instance setting of the log level, array resync rate, array member cache enable, and volume queue depth. mpt_debug.c: o Add mpt_lprt and mpt_lprtc for printing diagnostics conditioned on a particular log level to aid in tracking down driver issues. o Add mpt_decode_value() which parses the bits in an integer value based on a parsing table (mask, value, name string, tuples). mpilib/*: o Update mpi library header files to latest distribution from LSI. Submitted by: gibbs Approved by: re
2005-07-10 15:05:39 +00:00
mpt->raid_disks[i].flags &= ~MPT_RDF_REFERENCED;
}
for (i = 0; i < mpt->ioc_page2->MaxVolumes; i++) {
Massive overhaul of MPT Fusion driver: o Add timeout error recovery (from a thread context to avoid the deferral of other critical interrupts). o Properly recover commands across controller reset events. o Update the driver to handle events and status codes that have been added to the MPI spec since the driver was originally written. o Make the driver more modular to improve maintainability and support dynamic "personality" registration (e.g. SCSI Initiator, RAID, SAS, FC, etc). o Shorten and simplify the common I/O path to improve driver performance. o Add RAID volume and RAID member state/settings reporting. o Add periodic volume resynchronization status reporting. o Add support for sysctl tunable resync rate, member write cache enable, and volume transaction queue depth. Sponsored by ---------------- Avid Technologies Inc: SCSI error recovery, driver re-organization, update of MPI library headers, portions of dynamic personality registration, and misc bug fixes. Wheel Open Technologies: RAID event notification, RAID member pass-thru support, firmware upload/download support, enhanced RAID resync speed, portions of dynamic personality registration, and misc bug fixes. Detailed Changes ================ mpt.c mpt_cam.c mpt_raid.c mpt_pci.c: o Add support for personality modules. Each module exports load, and unload module scope methods as well as probe, attach, event, reset, shutdown, and detach per-device instance methods mpt.c mpt.h mpt_pci.c: o The driver now associates a callback function (via an index) with every transaction submitted to the controller. This allows the main interrupt handler to absolve itself of any knowledge of individual transaction/response types by simply calling the callback function "registered" for the transaction. We use a callback index instead of a callback function pointer in each requests so we can properly handle responses (e.g. event notifications) that are not associated with a transaction. Personality modules dynamically register their callbacks with the driver core to receive the callback index to use for their handlers. o Move the interrupt handler into mpt.c. The ISR algorithm is bus transport and OS independent and thus had no reason to be in mpt_pci.c. o Simplify configuration message reply handling by copying reply frame data for the requester and storing completion status in the original request structure. o Add the mpt_complete_request_chain() helper method and use it to implement reset handlers that must abort transactions. o Keep track of all pending requests on the new requests_pending_list in the softc. o Add default handlers to mpt.c to handle generic event notifications and controller reset activities. The event handler code is largely the same as in the original driver. The reset handler is new and terminates any pending transactions with a status code indicating the controller needs to be re-initialized. o Add some endian support to the driver. A complete audit is still required for this driver to have any hope of operating in a big-endian environment. o Use inttypes.h and __inline. Come closer to being style(9) compliant. o Remove extraneous use of typedefs. o Convert request state from a strict enumeration to a series of flags. This allows us to, for example, tag transactions that have timed-out while retaining the state that the transaction is still in-flight on the controller. o Add mpt_wait_req() which allows a caller to poll or sleep for the completion of a request. Use this to simplify and factor code out from many initialization routines. We also use this to sleep for task management request completions in our CAM timeout handler. mpt.c: o Correct a bug in the event handler where request structures were freed even if the request reply was marked as a continuation reply. Continuation replies indicate that the controller still owns the request and freeing these replies prematurely corrupted controller state. o Implement firmware upload and download. On controllers that do not have dedicated NVRAM (as in the Sun v20/v40z), the firmware image is downloaded to the controller by the system BIOS. This image occupies precious controller RAM space until the host driver fetches the image, reducing the number of concurrent I/Os the controller can processes. The uploaded image is used to re-program the controller during hard reset events since the controller cannot fetch the firmware on its own. Implementing this feature allows much higher queue depths when RAID volumes are configured. o Changed configuration page accessors to allow threads to sleep rather than busy wait for completion. o Removed hard coded data transfer sizes from configuration page routines so that RAID configuration page processing is possible. mpt_reg.h: o Move controller register definitions into a separate file. mpt.h: o Re-arrange includes to allow inlined functions to be defined in mpt.h. o Add reply, event, and reset handler definitions. o Add softc fields for handling timeout and controller reset recovery. mpt_cam.c: o Move mpt_freebsd.c to mpt_cam.c. Move all core functionality, such as event handling, into mpt.c leaving only CAM SCSI support here. o Revamp completion handler to provide correct CAM status for all currently defined SCSI MPI message result codes. o Register event and reset handlers with the MPT core. Modify the event handler to notify CAM of bus reset events. The controller reset handler will abort any transactions that have timed out. All other pending CAM transactions are correctly aborted by the core driver's reset handler. o Allocate a single request up front to perform task management operations. This guarantees that we can always perform a TMF operation even when the controller is saturated with other operations. The single request also serves as a perfect mechanism of guaranteeing that only a single TMF is in flight at a time - something that is required according to the MPT Fusion documentation. o Add a helper function for issuing task management requests to the controller. This is used to abort individual requests or perform a bus reset. o Modify the CAM XPT_BUS_RESET ccb handler to wait for and properly handle the status of the bus reset task management frame used to reset the bus. The previous code assumed that the reset request would always succeed. o Add timeout recovery support. When a timeout occurs, the timed-out request is added to a queue to be processed by our recovery thread and the thread is woken up. The recovery thread processes timed-out command serially, attempting first to abort them and then falling back to a bus reset if an abort fails. o Add calls to mpt_reset() to reset the controller if any handshake command, bus reset attempt or abort attempt fails due to a timeout. o Export a secondary "bus" to CAM that exposes all volume drive members as pass-thru devices, allowing CAM to perform proper speed negotiation to hidden devices. o Add a CAM async event handler tracking the AC_FOUND_DEVICE event. Use this to trigger calls to set the per-volume queue depth once the volume is fully registered with CAM. This is required to avoid hitting firmware limits on volume queue depth. Exceeding the limit causes the firmware to hang. mpt_cam.h: o Add several helper functions for interfacing to CAM and performing timeout recovery. mpt_pci.c: o Disable interrupts on the controller before registering and enabling interrupt delivery to the OS. Otherwise we risk receiving interrupts before the driver is ready to receive them. o Make use of compatibility macros that allow the driver to be compiled under 4.x and 5.x. mpt_raid.c: o Add a per-controller instance RAID thread to perform settings changes and query status (minimizes CPU busy wait loops). o Use a shutdown handler to disable "Member Write Cache Enable" (MWCE) setting for RAID arrays set to enable MWCE During Rebuild. o Change reply handler function signature to allow handlers to defer the deletion of reply frames. Use this to allow the event reply handler to queue up events that need to be acked if no resources are available to immediately ack an event. Queued events are processed in mpt_free_request() where resources are freed. This avoids a panic on resource shortage. o Parse and print out RAID controller capabilities during driver probe. o Define, allocate, and maintain RAID data structures for volumes, hidden member physical disks and spare disks. o Add dynamic sysctls for per-instance setting of the log level, array resync rate, array member cache enable, and volume queue depth. mpt_debug.c: o Add mpt_lprt and mpt_lprtc for printing diagnostics conditioned on a particular log level to aid in tracking down driver issues. o Add mpt_decode_value() which parses the bits in an integer value based on a parsing table (mask, value, name string, tuples). mpilib/*: o Update mpi library header files to latest distribution from LSI. Submitted by: gibbs Approved by: re
2005-07-10 15:05:39 +00:00
mpt->raid_volumes[i].flags &= ~MPT_RVF_REFERENCED;
}
Massive overhaul of MPT Fusion driver: o Add timeout error recovery (from a thread context to avoid the deferral of other critical interrupts). o Properly recover commands across controller reset events. o Update the driver to handle events and status codes that have been added to the MPI spec since the driver was originally written. o Make the driver more modular to improve maintainability and support dynamic "personality" registration (e.g. SCSI Initiator, RAID, SAS, FC, etc). o Shorten and simplify the common I/O path to improve driver performance. o Add RAID volume and RAID member state/settings reporting. o Add periodic volume resynchronization status reporting. o Add support for sysctl tunable resync rate, member write cache enable, and volume transaction queue depth. Sponsored by ---------------- Avid Technologies Inc: SCSI error recovery, driver re-organization, update of MPI library headers, portions of dynamic personality registration, and misc bug fixes. Wheel Open Technologies: RAID event notification, RAID member pass-thru support, firmware upload/download support, enhanced RAID resync speed, portions of dynamic personality registration, and misc bug fixes. Detailed Changes ================ mpt.c mpt_cam.c mpt_raid.c mpt_pci.c: o Add support for personality modules. Each module exports load, and unload module scope methods as well as probe, attach, event, reset, shutdown, and detach per-device instance methods mpt.c mpt.h mpt_pci.c: o The driver now associates a callback function (via an index) with every transaction submitted to the controller. This allows the main interrupt handler to absolve itself of any knowledge of individual transaction/response types by simply calling the callback function "registered" for the transaction. We use a callback index instead of a callback function pointer in each requests so we can properly handle responses (e.g. event notifications) that are not associated with a transaction. Personality modules dynamically register their callbacks with the driver core to receive the callback index to use for their handlers. o Move the interrupt handler into mpt.c. The ISR algorithm is bus transport and OS independent and thus had no reason to be in mpt_pci.c. o Simplify configuration message reply handling by copying reply frame data for the requester and storing completion status in the original request structure. o Add the mpt_complete_request_chain() helper method and use it to implement reset handlers that must abort transactions. o Keep track of all pending requests on the new requests_pending_list in the softc. o Add default handlers to mpt.c to handle generic event notifications and controller reset activities. The event handler code is largely the same as in the original driver. The reset handler is new and terminates any pending transactions with a status code indicating the controller needs to be re-initialized. o Add some endian support to the driver. A complete audit is still required for this driver to have any hope of operating in a big-endian environment. o Use inttypes.h and __inline. Come closer to being style(9) compliant. o Remove extraneous use of typedefs. o Convert request state from a strict enumeration to a series of flags. This allows us to, for example, tag transactions that have timed-out while retaining the state that the transaction is still in-flight on the controller. o Add mpt_wait_req() which allows a caller to poll or sleep for the completion of a request. Use this to simplify and factor code out from many initialization routines. We also use this to sleep for task management request completions in our CAM timeout handler. mpt.c: o Correct a bug in the event handler where request structures were freed even if the request reply was marked as a continuation reply. Continuation replies indicate that the controller still owns the request and freeing these replies prematurely corrupted controller state. o Implement firmware upload and download. On controllers that do not have dedicated NVRAM (as in the Sun v20/v40z), the firmware image is downloaded to the controller by the system BIOS. This image occupies precious controller RAM space until the host driver fetches the image, reducing the number of concurrent I/Os the controller can processes. The uploaded image is used to re-program the controller during hard reset events since the controller cannot fetch the firmware on its own. Implementing this feature allows much higher queue depths when RAID volumes are configured. o Changed configuration page accessors to allow threads to sleep rather than busy wait for completion. o Removed hard coded data transfer sizes from configuration page routines so that RAID configuration page processing is possible. mpt_reg.h: o Move controller register definitions into a separate file. mpt.h: o Re-arrange includes to allow inlined functions to be defined in mpt.h. o Add reply, event, and reset handler definitions. o Add softc fields for handling timeout and controller reset recovery. mpt_cam.c: o Move mpt_freebsd.c to mpt_cam.c. Move all core functionality, such as event handling, into mpt.c leaving only CAM SCSI support here. o Revamp completion handler to provide correct CAM status for all currently defined SCSI MPI message result codes. o Register event and reset handlers with the MPT core. Modify the event handler to notify CAM of bus reset events. The controller reset handler will abort any transactions that have timed out. All other pending CAM transactions are correctly aborted by the core driver's reset handler. o Allocate a single request up front to perform task management operations. This guarantees that we can always perform a TMF operation even when the controller is saturated with other operations. The single request also serves as a perfect mechanism of guaranteeing that only a single TMF is in flight at a time - something that is required according to the MPT Fusion documentation. o Add a helper function for issuing task management requests to the controller. This is used to abort individual requests or perform a bus reset. o Modify the CAM XPT_BUS_RESET ccb handler to wait for and properly handle the status of the bus reset task management frame used to reset the bus. The previous code assumed that the reset request would always succeed. o Add timeout recovery support. When a timeout occurs, the timed-out request is added to a queue to be processed by our recovery thread and the thread is woken up. The recovery thread processes timed-out command serially, attempting first to abort them and then falling back to a bus reset if an abort fails. o Add calls to mpt_reset() to reset the controller if any handshake command, bus reset attempt or abort attempt fails due to a timeout. o Export a secondary "bus" to CAM that exposes all volume drive members as pass-thru devices, allowing CAM to perform proper speed negotiation to hidden devices. o Add a CAM async event handler tracking the AC_FOUND_DEVICE event. Use this to trigger calls to set the per-volume queue depth once the volume is fully registered with CAM. This is required to avoid hitting firmware limits on volume queue depth. Exceeding the limit causes the firmware to hang. mpt_cam.h: o Add several helper functions for interfacing to CAM and performing timeout recovery. mpt_pci.c: o Disable interrupts on the controller before registering and enabling interrupt delivery to the OS. Otherwise we risk receiving interrupts before the driver is ready to receive them. o Make use of compatibility macros that allow the driver to be compiled under 4.x and 5.x. mpt_raid.c: o Add a per-controller instance RAID thread to perform settings changes and query status (minimizes CPU busy wait loops). o Use a shutdown handler to disable "Member Write Cache Enable" (MWCE) setting for RAID arrays set to enable MWCE During Rebuild. o Change reply handler function signature to allow handlers to defer the deletion of reply frames. Use this to allow the event reply handler to queue up events that need to be acked if no resources are available to immediately ack an event. Queued events are processed in mpt_free_request() where resources are freed. This avoids a panic on resource shortage. o Parse and print out RAID controller capabilities during driver probe. o Define, allocate, and maintain RAID data structures for volumes, hidden member physical disks and spare disks. o Add dynamic sysctls for per-instance setting of the log level, array resync rate, array member cache enable, and volume queue depth. mpt_debug.c: o Add mpt_lprt and mpt_lprtc for printing diagnostics conditioned on a particular log level to aid in tracking down driver issues. o Add mpt_decode_value() which parses the bits in an integer value based on a parsing table (mask, value, name string, tuples). mpilib/*: o Update mpi library header files to latest distribution from LSI. Submitted by: gibbs Approved by: re
2005-07-10 15:05:39 +00:00
/*
* Get Physical Disk information.
*/
len = mpt->ioc_page3->Header.PageLength * sizeof(uint32_t);
rv = mpt_read_cur_cfg_page(mpt, /*PageAddress*/0,
&mpt->ioc_page3->Header, len,
/*sleep_ok*/TRUE, /*timeout_ms*/5000);
if (rv) {
mpt_prt(mpt, "mpt_refresh_raid_data: "
"Failed to read IOC Page 3\n");
return;
}
ioc_disk = mpt->ioc_page3->PhysDisk;
ioc_last_disk = ioc_disk + mpt->ioc_page3->NumPhysDisks;
for (; ioc_disk != ioc_last_disk; ioc_disk++) {
struct mpt_raid_disk *mpt_disk;
mpt_disk = mpt->raid_disks + ioc_disk->PhysDiskNum;
mpt_disk->flags |= MPT_RDF_REFERENCED;
if ((mpt_disk->flags & (MPT_RDF_ACTIVE|MPT_RDF_UP2DATE))
!= (MPT_RDF_ACTIVE|MPT_RDF_UP2DATE)) {
mpt_refresh_raid_disk(mpt, mpt_disk, ioc_disk);
}
mpt_disk->flags |= MPT_RDF_ACTIVE;
mpt->raid_rescan++;
}
/*
* Refresh volume data.
*/
len = mpt->ioc_page2->Header.PageLength * sizeof(uint32_t);
rv = mpt_read_cur_cfg_page(mpt, /*PageAddress*/0,
&mpt->ioc_page2->Header, len,
/*sleep_ok*/TRUE, /*timeout_ms*/5000);
if (rv) {
mpt_prt(mpt, "mpt_refresh_raid_data: "
"Failed to read IOC Page 2\n");
return;
}
ioc_vol = mpt->ioc_page2->RaidVolume;
ioc_last_vol = ioc_vol + mpt->ioc_page2->NumActiveVolumes;
for (;ioc_vol != ioc_last_vol; ioc_vol++) {
struct mpt_raid_volume *mpt_vol;
mpt_vol = mpt->raid_volumes + ioc_vol->VolumePageNumber;
mpt_vol->flags |= MPT_RVF_REFERENCED;
vol_pg = mpt_vol->config_page;
if (vol_pg == NULL)
continue;
if (((mpt_vol->flags & (MPT_RVF_ACTIVE|MPT_RVF_UP2DATE))
!= (MPT_RVF_ACTIVE|MPT_RVF_UP2DATE))
|| (vol_pg->VolumeStatus.Flags
& MPI_RAIDVOL0_STATUS_FLAG_RESYNC_IN_PROGRESS) != 0) {
mpt_refresh_raid_vol(mpt, mpt_vol, ioc_vol);
}
mpt_vol->flags |= MPT_RVF_ACTIVE;
}
nonopt_volumes = 0;
Massive overhaul of MPT Fusion driver: o Add timeout error recovery (from a thread context to avoid the deferral of other critical interrupts). o Properly recover commands across controller reset events. o Update the driver to handle events and status codes that have been added to the MPI spec since the driver was originally written. o Make the driver more modular to improve maintainability and support dynamic "personality" registration (e.g. SCSI Initiator, RAID, SAS, FC, etc). o Shorten and simplify the common I/O path to improve driver performance. o Add RAID volume and RAID member state/settings reporting. o Add periodic volume resynchronization status reporting. o Add support for sysctl tunable resync rate, member write cache enable, and volume transaction queue depth. Sponsored by ---------------- Avid Technologies Inc: SCSI error recovery, driver re-organization, update of MPI library headers, portions of dynamic personality registration, and misc bug fixes. Wheel Open Technologies: RAID event notification, RAID member pass-thru support, firmware upload/download support, enhanced RAID resync speed, portions of dynamic personality registration, and misc bug fixes. Detailed Changes ================ mpt.c mpt_cam.c mpt_raid.c mpt_pci.c: o Add support for personality modules. Each module exports load, and unload module scope methods as well as probe, attach, event, reset, shutdown, and detach per-device instance methods mpt.c mpt.h mpt_pci.c: o The driver now associates a callback function (via an index) with every transaction submitted to the controller. This allows the main interrupt handler to absolve itself of any knowledge of individual transaction/response types by simply calling the callback function "registered" for the transaction. We use a callback index instead of a callback function pointer in each requests so we can properly handle responses (e.g. event notifications) that are not associated with a transaction. Personality modules dynamically register their callbacks with the driver core to receive the callback index to use for their handlers. o Move the interrupt handler into mpt.c. The ISR algorithm is bus transport and OS independent and thus had no reason to be in mpt_pci.c. o Simplify configuration message reply handling by copying reply frame data for the requester and storing completion status in the original request structure. o Add the mpt_complete_request_chain() helper method and use it to implement reset handlers that must abort transactions. o Keep track of all pending requests on the new requests_pending_list in the softc. o Add default handlers to mpt.c to handle generic event notifications and controller reset activities. The event handler code is largely the same as in the original driver. The reset handler is new and terminates any pending transactions with a status code indicating the controller needs to be re-initialized. o Add some endian support to the driver. A complete audit is still required for this driver to have any hope of operating in a big-endian environment. o Use inttypes.h and __inline. Come closer to being style(9) compliant. o Remove extraneous use of typedefs. o Convert request state from a strict enumeration to a series of flags. This allows us to, for example, tag transactions that have timed-out while retaining the state that the transaction is still in-flight on the controller. o Add mpt_wait_req() which allows a caller to poll or sleep for the completion of a request. Use this to simplify and factor code out from many initialization routines. We also use this to sleep for task management request completions in our CAM timeout handler. mpt.c: o Correct a bug in the event handler where request structures were freed even if the request reply was marked as a continuation reply. Continuation replies indicate that the controller still owns the request and freeing these replies prematurely corrupted controller state. o Implement firmware upload and download. On controllers that do not have dedicated NVRAM (as in the Sun v20/v40z), the firmware image is downloaded to the controller by the system BIOS. This image occupies precious controller RAM space until the host driver fetches the image, reducing the number of concurrent I/Os the controller can processes. The uploaded image is used to re-program the controller during hard reset events since the controller cannot fetch the firmware on its own. Implementing this feature allows much higher queue depths when RAID volumes are configured. o Changed configuration page accessors to allow threads to sleep rather than busy wait for completion. o Removed hard coded data transfer sizes from configuration page routines so that RAID configuration page processing is possible. mpt_reg.h: o Move controller register definitions into a separate file. mpt.h: o Re-arrange includes to allow inlined functions to be defined in mpt.h. o Add reply, event, and reset handler definitions. o Add softc fields for handling timeout and controller reset recovery. mpt_cam.c: o Move mpt_freebsd.c to mpt_cam.c. Move all core functionality, such as event handling, into mpt.c leaving only CAM SCSI support here. o Revamp completion handler to provide correct CAM status for all currently defined SCSI MPI message result codes. o Register event and reset handlers with the MPT core. Modify the event handler to notify CAM of bus reset events. The controller reset handler will abort any transactions that have timed out. All other pending CAM transactions are correctly aborted by the core driver's reset handler. o Allocate a single request up front to perform task management operations. This guarantees that we can always perform a TMF operation even when the controller is saturated with other operations. The single request also serves as a perfect mechanism of guaranteeing that only a single TMF is in flight at a time - something that is required according to the MPT Fusion documentation. o Add a helper function for issuing task management requests to the controller. This is used to abort individual requests or perform a bus reset. o Modify the CAM XPT_BUS_RESET ccb handler to wait for and properly handle the status of the bus reset task management frame used to reset the bus. The previous code assumed that the reset request would always succeed. o Add timeout recovery support. When a timeout occurs, the timed-out request is added to a queue to be processed by our recovery thread and the thread is woken up. The recovery thread processes timed-out command serially, attempting first to abort them and then falling back to a bus reset if an abort fails. o Add calls to mpt_reset() to reset the controller if any handshake command, bus reset attempt or abort attempt fails due to a timeout. o Export a secondary "bus" to CAM that exposes all volume drive members as pass-thru devices, allowing CAM to perform proper speed negotiation to hidden devices. o Add a CAM async event handler tracking the AC_FOUND_DEVICE event. Use this to trigger calls to set the per-volume queue depth once the volume is fully registered with CAM. This is required to avoid hitting firmware limits on volume queue depth. Exceeding the limit causes the firmware to hang. mpt_cam.h: o Add several helper functions for interfacing to CAM and performing timeout recovery. mpt_pci.c: o Disable interrupts on the controller before registering and enabling interrupt delivery to the OS. Otherwise we risk receiving interrupts before the driver is ready to receive them. o Make use of compatibility macros that allow the driver to be compiled under 4.x and 5.x. mpt_raid.c: o Add a per-controller instance RAID thread to perform settings changes and query status (minimizes CPU busy wait loops). o Use a shutdown handler to disable "Member Write Cache Enable" (MWCE) setting for RAID arrays set to enable MWCE During Rebuild. o Change reply handler function signature to allow handlers to defer the deletion of reply frames. Use this to allow the event reply handler to queue up events that need to be acked if no resources are available to immediately ack an event. Queued events are processed in mpt_free_request() where resources are freed. This avoids a panic on resource shortage. o Parse and print out RAID controller capabilities during driver probe. o Define, allocate, and maintain RAID data structures for volumes, hidden member physical disks and spare disks. o Add dynamic sysctls for per-instance setting of the log level, array resync rate, array member cache enable, and volume queue depth. mpt_debug.c: o Add mpt_lprt and mpt_lprtc for printing diagnostics conditioned on a particular log level to aid in tracking down driver issues. o Add mpt_decode_value() which parses the bits in an integer value based on a parsing table (mask, value, name string, tuples). mpilib/*: o Update mpi library header files to latest distribution from LSI. Submitted by: gibbs Approved by: re
2005-07-10 15:05:39 +00:00
for (i = 0; i < mpt->ioc_page2->MaxVolumes; i++) {
struct mpt_raid_volume *mpt_vol;
uint64_t total;
uint64_t left;
int m;
u_int prio;
mpt_vol = &mpt->raid_volumes[i];
if ((mpt_vol->flags & MPT_RVF_ACTIVE) == 0)
continue;
vol_pg = mpt_vol->config_page;
if ((mpt_vol->flags & (MPT_RVF_REFERENCED|MPT_RVF_ANNOUNCED))
== MPT_RVF_ANNOUNCED) {
mpt_vol_prt(mpt, mpt_vol, "No longer configured\n");
mpt_vol->flags = 0;
continue;
}
if ((mpt_vol->flags & MPT_RVF_ANNOUNCED) == 0) {
mpt_announce_vol(mpt, mpt_vol);
mpt_vol->flags |= MPT_RVF_ANNOUNCED;
}
if (vol_pg->VolumeStatus.State !=
MPI_RAIDVOL0_STATUS_STATE_OPTIMAL)
nonopt_volumes++;
Massive overhaul of MPT Fusion driver: o Add timeout error recovery (from a thread context to avoid the deferral of other critical interrupts). o Properly recover commands across controller reset events. o Update the driver to handle events and status codes that have been added to the MPI spec since the driver was originally written. o Make the driver more modular to improve maintainability and support dynamic "personality" registration (e.g. SCSI Initiator, RAID, SAS, FC, etc). o Shorten and simplify the common I/O path to improve driver performance. o Add RAID volume and RAID member state/settings reporting. o Add periodic volume resynchronization status reporting. o Add support for sysctl tunable resync rate, member write cache enable, and volume transaction queue depth. Sponsored by ---------------- Avid Technologies Inc: SCSI error recovery, driver re-organization, update of MPI library headers, portions of dynamic personality registration, and misc bug fixes. Wheel Open Technologies: RAID event notification, RAID member pass-thru support, firmware upload/download support, enhanced RAID resync speed, portions of dynamic personality registration, and misc bug fixes. Detailed Changes ================ mpt.c mpt_cam.c mpt_raid.c mpt_pci.c: o Add support for personality modules. Each module exports load, and unload module scope methods as well as probe, attach, event, reset, shutdown, and detach per-device instance methods mpt.c mpt.h mpt_pci.c: o The driver now associates a callback function (via an index) with every transaction submitted to the controller. This allows the main interrupt handler to absolve itself of any knowledge of individual transaction/response types by simply calling the callback function "registered" for the transaction. We use a callback index instead of a callback function pointer in each requests so we can properly handle responses (e.g. event notifications) that are not associated with a transaction. Personality modules dynamically register their callbacks with the driver core to receive the callback index to use for their handlers. o Move the interrupt handler into mpt.c. The ISR algorithm is bus transport and OS independent and thus had no reason to be in mpt_pci.c. o Simplify configuration message reply handling by copying reply frame data for the requester and storing completion status in the original request structure. o Add the mpt_complete_request_chain() helper method and use it to implement reset handlers that must abort transactions. o Keep track of all pending requests on the new requests_pending_list in the softc. o Add default handlers to mpt.c to handle generic event notifications and controller reset activities. The event handler code is largely the same as in the original driver. The reset handler is new and terminates any pending transactions with a status code indicating the controller needs to be re-initialized. o Add some endian support to the driver. A complete audit is still required for this driver to have any hope of operating in a big-endian environment. o Use inttypes.h and __inline. Come closer to being style(9) compliant. o Remove extraneous use of typedefs. o Convert request state from a strict enumeration to a series of flags. This allows us to, for example, tag transactions that have timed-out while retaining the state that the transaction is still in-flight on the controller. o Add mpt_wait_req() which allows a caller to poll or sleep for the completion of a request. Use this to simplify and factor code out from many initialization routines. We also use this to sleep for task management request completions in our CAM timeout handler. mpt.c: o Correct a bug in the event handler where request structures were freed even if the request reply was marked as a continuation reply. Continuation replies indicate that the controller still owns the request and freeing these replies prematurely corrupted controller state. o Implement firmware upload and download. On controllers that do not have dedicated NVRAM (as in the Sun v20/v40z), the firmware image is downloaded to the controller by the system BIOS. This image occupies precious controller RAM space until the host driver fetches the image, reducing the number of concurrent I/Os the controller can processes. The uploaded image is used to re-program the controller during hard reset events since the controller cannot fetch the firmware on its own. Implementing this feature allows much higher queue depths when RAID volumes are configured. o Changed configuration page accessors to allow threads to sleep rather than busy wait for completion. o Removed hard coded data transfer sizes from configuration page routines so that RAID configuration page processing is possible. mpt_reg.h: o Move controller register definitions into a separate file. mpt.h: o Re-arrange includes to allow inlined functions to be defined in mpt.h. o Add reply, event, and reset handler definitions. o Add softc fields for handling timeout and controller reset recovery. mpt_cam.c: o Move mpt_freebsd.c to mpt_cam.c. Move all core functionality, such as event handling, into mpt.c leaving only CAM SCSI support here. o Revamp completion handler to provide correct CAM status for all currently defined SCSI MPI message result codes. o Register event and reset handlers with the MPT core. Modify the event handler to notify CAM of bus reset events. The controller reset handler will abort any transactions that have timed out. All other pending CAM transactions are correctly aborted by the core driver's reset handler. o Allocate a single request up front to perform task management operations. This guarantees that we can always perform a TMF operation even when the controller is saturated with other operations. The single request also serves as a perfect mechanism of guaranteeing that only a single TMF is in flight at a time - something that is required according to the MPT Fusion documentation. o Add a helper function for issuing task management requests to the controller. This is used to abort individual requests or perform a bus reset. o Modify the CAM XPT_BUS_RESET ccb handler to wait for and properly handle the status of the bus reset task management frame used to reset the bus. The previous code assumed that the reset request would always succeed. o Add timeout recovery support. When a timeout occurs, the timed-out request is added to a queue to be processed by our recovery thread and the thread is woken up. The recovery thread processes timed-out command serially, attempting first to abort them and then falling back to a bus reset if an abort fails. o Add calls to mpt_reset() to reset the controller if any handshake command, bus reset attempt or abort attempt fails due to a timeout. o Export a secondary "bus" to CAM that exposes all volume drive members as pass-thru devices, allowing CAM to perform proper speed negotiation to hidden devices. o Add a CAM async event handler tracking the AC_FOUND_DEVICE event. Use this to trigger calls to set the per-volume queue depth once the volume is fully registered with CAM. This is required to avoid hitting firmware limits on volume queue depth. Exceeding the limit causes the firmware to hang. mpt_cam.h: o Add several helper functions for interfacing to CAM and performing timeout recovery. mpt_pci.c: o Disable interrupts on the controller before registering and enabling interrupt delivery to the OS. Otherwise we risk receiving interrupts before the driver is ready to receive them. o Make use of compatibility macros that allow the driver to be compiled under 4.x and 5.x. mpt_raid.c: o Add a per-controller instance RAID thread to perform settings changes and query status (minimizes CPU busy wait loops). o Use a shutdown handler to disable "Member Write Cache Enable" (MWCE) setting for RAID arrays set to enable MWCE During Rebuild. o Change reply handler function signature to allow handlers to defer the deletion of reply frames. Use this to allow the event reply handler to queue up events that need to be acked if no resources are available to immediately ack an event. Queued events are processed in mpt_free_request() where resources are freed. This avoids a panic on resource shortage. o Parse and print out RAID controller capabilities during driver probe. o Define, allocate, and maintain RAID data structures for volumes, hidden member physical disks and spare disks. o Add dynamic sysctls for per-instance setting of the log level, array resync rate, array member cache enable, and volume queue depth. mpt_debug.c: o Add mpt_lprt and mpt_lprtc for printing diagnostics conditioned on a particular log level to aid in tracking down driver issues. o Add mpt_decode_value() which parses the bits in an integer value based on a parsing table (mask, value, name string, tuples). mpilib/*: o Update mpi library header files to latest distribution from LSI. Submitted by: gibbs Approved by: re
2005-07-10 15:05:39 +00:00
if ((mpt_vol->flags & MPT_RVF_UP2DATE) != 0)
continue;
mpt_vol->flags |= MPT_RVF_UP2DATE;
mpt_vol_prt(mpt, mpt_vol, "%s - %s\n",
mpt_vol_type(mpt_vol), mpt_vol_state(mpt_vol));
mpt_verify_mwce(mpt, mpt_vol);
if (vol_pg->VolumeStatus.Flags == 0)
continue;
mpt_vol_prt(mpt, mpt_vol, "Status (");
for (m = 1; m <= 0x80; m <<= 1) {
switch (vol_pg->VolumeStatus.Flags & m) {
case MPI_RAIDVOL0_STATUS_FLAG_ENABLED:
mpt_prtc(mpt, " Enabled");
break;
case MPI_RAIDVOL0_STATUS_FLAG_QUIESCED:
mpt_prtc(mpt, " Quiesced");
break;
case MPI_RAIDVOL0_STATUS_FLAG_RESYNC_IN_PROGRESS:
mpt_prtc(mpt, " Re-Syncing");
break;
case MPI_RAIDVOL0_STATUS_FLAG_VOLUME_INACTIVE:
mpt_prtc(mpt, " Inactive");
break;
default:
break;
}
}
mpt_prtc(mpt, " )\n");
if ((vol_pg->VolumeStatus.Flags
& MPI_RAIDVOL0_STATUS_FLAG_RESYNC_IN_PROGRESS) == 0)
continue;
mpt_verify_resync_rate(mpt, mpt_vol);
left = u64toh(mpt_vol->sync_progress.BlocksRemaining);
total = u64toh(mpt_vol->sync_progress.TotalBlocks);
if (vol_pg->ResyncRate != 0) {
prio = ((u_int)vol_pg->ResyncRate * 100000) / 0xFF;
mpt_vol_prt(mpt, mpt_vol, "Rate %d.%d%%\n",
prio / 1000, prio % 1000);
} else {
prio = vol_pg->VolumeSettings.Settings
& MPI_RAIDVOL0_SETTING_PRIORITY_RESYNC;
mpt_vol_prt(mpt, mpt_vol, "%s Priority Re-Sync\n",
prio ? "High" : "Low");
}
#if __FreeBSD_version >= 500000
Massive overhaul of MPT Fusion driver: o Add timeout error recovery (from a thread context to avoid the deferral of other critical interrupts). o Properly recover commands across controller reset events. o Update the driver to handle events and status codes that have been added to the MPI spec since the driver was originally written. o Make the driver more modular to improve maintainability and support dynamic "personality" registration (e.g. SCSI Initiator, RAID, SAS, FC, etc). o Shorten and simplify the common I/O path to improve driver performance. o Add RAID volume and RAID member state/settings reporting. o Add periodic volume resynchronization status reporting. o Add support for sysctl tunable resync rate, member write cache enable, and volume transaction queue depth. Sponsored by ---------------- Avid Technologies Inc: SCSI error recovery, driver re-organization, update of MPI library headers, portions of dynamic personality registration, and misc bug fixes. Wheel Open Technologies: RAID event notification, RAID member pass-thru support, firmware upload/download support, enhanced RAID resync speed, portions of dynamic personality registration, and misc bug fixes. Detailed Changes ================ mpt.c mpt_cam.c mpt_raid.c mpt_pci.c: o Add support for personality modules. Each module exports load, and unload module scope methods as well as probe, attach, event, reset, shutdown, and detach per-device instance methods mpt.c mpt.h mpt_pci.c: o The driver now associates a callback function (via an index) with every transaction submitted to the controller. This allows the main interrupt handler to absolve itself of any knowledge of individual transaction/response types by simply calling the callback function "registered" for the transaction. We use a callback index instead of a callback function pointer in each requests so we can properly handle responses (e.g. event notifications) that are not associated with a transaction. Personality modules dynamically register their callbacks with the driver core to receive the callback index to use for their handlers. o Move the interrupt handler into mpt.c. The ISR algorithm is bus transport and OS independent and thus had no reason to be in mpt_pci.c. o Simplify configuration message reply handling by copying reply frame data for the requester and storing completion status in the original request structure. o Add the mpt_complete_request_chain() helper method and use it to implement reset handlers that must abort transactions. o Keep track of all pending requests on the new requests_pending_list in the softc. o Add default handlers to mpt.c to handle generic event notifications and controller reset activities. The event handler code is largely the same as in the original driver. The reset handler is new and terminates any pending transactions with a status code indicating the controller needs to be re-initialized. o Add some endian support to the driver. A complete audit is still required for this driver to have any hope of operating in a big-endian environment. o Use inttypes.h and __inline. Come closer to being style(9) compliant. o Remove extraneous use of typedefs. o Convert request state from a strict enumeration to a series of flags. This allows us to, for example, tag transactions that have timed-out while retaining the state that the transaction is still in-flight on the controller. o Add mpt_wait_req() which allows a caller to poll or sleep for the completion of a request. Use this to simplify and factor code out from many initialization routines. We also use this to sleep for task management request completions in our CAM timeout handler. mpt.c: o Correct a bug in the event handler where request structures were freed even if the request reply was marked as a continuation reply. Continuation replies indicate that the controller still owns the request and freeing these replies prematurely corrupted controller state. o Implement firmware upload and download. On controllers that do not have dedicated NVRAM (as in the Sun v20/v40z), the firmware image is downloaded to the controller by the system BIOS. This image occupies precious controller RAM space until the host driver fetches the image, reducing the number of concurrent I/Os the controller can processes. The uploaded image is used to re-program the controller during hard reset events since the controller cannot fetch the firmware on its own. Implementing this feature allows much higher queue depths when RAID volumes are configured. o Changed configuration page accessors to allow threads to sleep rather than busy wait for completion. o Removed hard coded data transfer sizes from configuration page routines so that RAID configuration page processing is possible. mpt_reg.h: o Move controller register definitions into a separate file. mpt.h: o Re-arrange includes to allow inlined functions to be defined in mpt.h. o Add reply, event, and reset handler definitions. o Add softc fields for handling timeout and controller reset recovery. mpt_cam.c: o Move mpt_freebsd.c to mpt_cam.c. Move all core functionality, such as event handling, into mpt.c leaving only CAM SCSI support here. o Revamp completion handler to provide correct CAM status for all currently defined SCSI MPI message result codes. o Register event and reset handlers with the MPT core. Modify the event handler to notify CAM of bus reset events. The controller reset handler will abort any transactions that have timed out. All other pending CAM transactions are correctly aborted by the core driver's reset handler. o Allocate a single request up front to perform task management operations. This guarantees that we can always perform a TMF operation even when the controller is saturated with other operations. The single request also serves as a perfect mechanism of guaranteeing that only a single TMF is in flight at a time - something that is required according to the MPT Fusion documentation. o Add a helper function for issuing task management requests to the controller. This is used to abort individual requests or perform a bus reset. o Modify the CAM XPT_BUS_RESET ccb handler to wait for and properly handle the status of the bus reset task management frame used to reset the bus. The previous code assumed that the reset request would always succeed. o Add timeout recovery support. When a timeout occurs, the timed-out request is added to a queue to be processed by our recovery thread and the thread is woken up. The recovery thread processes timed-out command serially, attempting first to abort them and then falling back to a bus reset if an abort fails. o Add calls to mpt_reset() to reset the controller if any handshake command, bus reset attempt or abort attempt fails due to a timeout. o Export a secondary "bus" to CAM that exposes all volume drive members as pass-thru devices, allowing CAM to perform proper speed negotiation to hidden devices. o Add a CAM async event handler tracking the AC_FOUND_DEVICE event. Use this to trigger calls to set the per-volume queue depth once the volume is fully registered with CAM. This is required to avoid hitting firmware limits on volume queue depth. Exceeding the limit causes the firmware to hang. mpt_cam.h: o Add several helper functions for interfacing to CAM and performing timeout recovery. mpt_pci.c: o Disable interrupts on the controller before registering and enabling interrupt delivery to the OS. Otherwise we risk receiving interrupts before the driver is ready to receive them. o Make use of compatibility macros that allow the driver to be compiled under 4.x and 5.x. mpt_raid.c: o Add a per-controller instance RAID thread to perform settings changes and query status (minimizes CPU busy wait loops). o Use a shutdown handler to disable "Member Write Cache Enable" (MWCE) setting for RAID arrays set to enable MWCE During Rebuild. o Change reply handler function signature to allow handlers to defer the deletion of reply frames. Use this to allow the event reply handler to queue up events that need to be acked if no resources are available to immediately ack an event. Queued events are processed in mpt_free_request() where resources are freed. This avoids a panic on resource shortage. o Parse and print out RAID controller capabilities during driver probe. o Define, allocate, and maintain RAID data structures for volumes, hidden member physical disks and spare disks. o Add dynamic sysctls for per-instance setting of the log level, array resync rate, array member cache enable, and volume queue depth. mpt_debug.c: o Add mpt_lprt and mpt_lprtc for printing diagnostics conditioned on a particular log level to aid in tracking down driver issues. o Add mpt_decode_value() which parses the bits in an integer value based on a parsing table (mask, value, name string, tuples). mpilib/*: o Update mpi library header files to latest distribution from LSI. Submitted by: gibbs Approved by: re
2005-07-10 15:05:39 +00:00
mpt_vol_prt(mpt, mpt_vol, "%ju of %ju "
"blocks remaining\n", (uintmax_t)left,
(uintmax_t)total);
#else
mpt_vol_prt(mpt, mpt_vol, "%llu of %llu "
"blocks remaining\n", (uint64_t)left,
(uint64_t)total);
#endif
Massive overhaul of MPT Fusion driver: o Add timeout error recovery (from a thread context to avoid the deferral of other critical interrupts). o Properly recover commands across controller reset events. o Update the driver to handle events and status codes that have been added to the MPI spec since the driver was originally written. o Make the driver more modular to improve maintainability and support dynamic "personality" registration (e.g. SCSI Initiator, RAID, SAS, FC, etc). o Shorten and simplify the common I/O path to improve driver performance. o Add RAID volume and RAID member state/settings reporting. o Add periodic volume resynchronization status reporting. o Add support for sysctl tunable resync rate, member write cache enable, and volume transaction queue depth. Sponsored by ---------------- Avid Technologies Inc: SCSI error recovery, driver re-organization, update of MPI library headers, portions of dynamic personality registration, and misc bug fixes. Wheel Open Technologies: RAID event notification, RAID member pass-thru support, firmware upload/download support, enhanced RAID resync speed, portions of dynamic personality registration, and misc bug fixes. Detailed Changes ================ mpt.c mpt_cam.c mpt_raid.c mpt_pci.c: o Add support for personality modules. Each module exports load, and unload module scope methods as well as probe, attach, event, reset, shutdown, and detach per-device instance methods mpt.c mpt.h mpt_pci.c: o The driver now associates a callback function (via an index) with every transaction submitted to the controller. This allows the main interrupt handler to absolve itself of any knowledge of individual transaction/response types by simply calling the callback function "registered" for the transaction. We use a callback index instead of a callback function pointer in each requests so we can properly handle responses (e.g. event notifications) that are not associated with a transaction. Personality modules dynamically register their callbacks with the driver core to receive the callback index to use for their handlers. o Move the interrupt handler into mpt.c. The ISR algorithm is bus transport and OS independent and thus had no reason to be in mpt_pci.c. o Simplify configuration message reply handling by copying reply frame data for the requester and storing completion status in the original request structure. o Add the mpt_complete_request_chain() helper method and use it to implement reset handlers that must abort transactions. o Keep track of all pending requests on the new requests_pending_list in the softc. o Add default handlers to mpt.c to handle generic event notifications and controller reset activities. The event handler code is largely the same as in the original driver. The reset handler is new and terminates any pending transactions with a status code indicating the controller needs to be re-initialized. o Add some endian support to the driver. A complete audit is still required for this driver to have any hope of operating in a big-endian environment. o Use inttypes.h and __inline. Come closer to being style(9) compliant. o Remove extraneous use of typedefs. o Convert request state from a strict enumeration to a series of flags. This allows us to, for example, tag transactions that have timed-out while retaining the state that the transaction is still in-flight on the controller. o Add mpt_wait_req() which allows a caller to poll or sleep for the completion of a request. Use this to simplify and factor code out from many initialization routines. We also use this to sleep for task management request completions in our CAM timeout handler. mpt.c: o Correct a bug in the event handler where request structures were freed even if the request reply was marked as a continuation reply. Continuation replies indicate that the controller still owns the request and freeing these replies prematurely corrupted controller state. o Implement firmware upload and download. On controllers that do not have dedicated NVRAM (as in the Sun v20/v40z), the firmware image is downloaded to the controller by the system BIOS. This image occupies precious controller RAM space until the host driver fetches the image, reducing the number of concurrent I/Os the controller can processes. The uploaded image is used to re-program the controller during hard reset events since the controller cannot fetch the firmware on its own. Implementing this feature allows much higher queue depths when RAID volumes are configured. o Changed configuration page accessors to allow threads to sleep rather than busy wait for completion. o Removed hard coded data transfer sizes from configuration page routines so that RAID configuration page processing is possible. mpt_reg.h: o Move controller register definitions into a separate file. mpt.h: o Re-arrange includes to allow inlined functions to be defined in mpt.h. o Add reply, event, and reset handler definitions. o Add softc fields for handling timeout and controller reset recovery. mpt_cam.c: o Move mpt_freebsd.c to mpt_cam.c. Move all core functionality, such as event handling, into mpt.c leaving only CAM SCSI support here. o Revamp completion handler to provide correct CAM status for all currently defined SCSI MPI message result codes. o Register event and reset handlers with the MPT core. Modify the event handler to notify CAM of bus reset events. The controller reset handler will abort any transactions that have timed out. All other pending CAM transactions are correctly aborted by the core driver's reset handler. o Allocate a single request up front to perform task management operations. This guarantees that we can always perform a TMF operation even when the controller is saturated with other operations. The single request also serves as a perfect mechanism of guaranteeing that only a single TMF is in flight at a time - something that is required according to the MPT Fusion documentation. o Add a helper function for issuing task management requests to the controller. This is used to abort individual requests or perform a bus reset. o Modify the CAM XPT_BUS_RESET ccb handler to wait for and properly handle the status of the bus reset task management frame used to reset the bus. The previous code assumed that the reset request would always succeed. o Add timeout recovery support. When a timeout occurs, the timed-out request is added to a queue to be processed by our recovery thread and the thread is woken up. The recovery thread processes timed-out command serially, attempting first to abort them and then falling back to a bus reset if an abort fails. o Add calls to mpt_reset() to reset the controller if any handshake command, bus reset attempt or abort attempt fails due to a timeout. o Export a secondary "bus" to CAM that exposes all volume drive members as pass-thru devices, allowing CAM to perform proper speed negotiation to hidden devices. o Add a CAM async event handler tracking the AC_FOUND_DEVICE event. Use this to trigger calls to set the per-volume queue depth once the volume is fully registered with CAM. This is required to avoid hitting firmware limits on volume queue depth. Exceeding the limit causes the firmware to hang. mpt_cam.h: o Add several helper functions for interfacing to CAM and performing timeout recovery. mpt_pci.c: o Disable interrupts on the controller before registering and enabling interrupt delivery to the OS. Otherwise we risk receiving interrupts before the driver is ready to receive them. o Make use of compatibility macros that allow the driver to be compiled under 4.x and 5.x. mpt_raid.c: o Add a per-controller instance RAID thread to perform settings changes and query status (minimizes CPU busy wait loops). o Use a shutdown handler to disable "Member Write Cache Enable" (MWCE) setting for RAID arrays set to enable MWCE During Rebuild. o Change reply handler function signature to allow handlers to defer the deletion of reply frames. Use this to allow the event reply handler to queue up events that need to be acked if no resources are available to immediately ack an event. Queued events are processed in mpt_free_request() where resources are freed. This avoids a panic on resource shortage. o Parse and print out RAID controller capabilities during driver probe. o Define, allocate, and maintain RAID data structures for volumes, hidden member physical disks and spare disks. o Add dynamic sysctls for per-instance setting of the log level, array resync rate, array member cache enable, and volume queue depth. mpt_debug.c: o Add mpt_lprt and mpt_lprtc for printing diagnostics conditioned on a particular log level to aid in tracking down driver issues. o Add mpt_decode_value() which parses the bits in an integer value based on a parsing table (mask, value, name string, tuples). mpilib/*: o Update mpi library header files to latest distribution from LSI. Submitted by: gibbs Approved by: re
2005-07-10 15:05:39 +00:00
/* Periodically report on sync progress. */
mpt_schedule_raid_refresh(mpt);
}
for (i = 0; i < mpt->ioc_page2->MaxPhysDisks; i++) {
struct mpt_raid_disk *mpt_disk;
CONFIG_PAGE_RAID_PHYS_DISK_0 *disk_pg;
int m;
mpt_disk = &mpt->raid_disks[i];
disk_pg = &mpt_disk->config_page;
if ((mpt_disk->flags & MPT_RDF_ACTIVE) == 0)
continue;
if ((mpt_disk->flags & (MPT_RDF_REFERENCED|MPT_RDF_ANNOUNCED))
== MPT_RDF_ANNOUNCED) {
mpt_disk_prt(mpt, mpt_disk, "No longer configured\n");
mpt_disk->flags = 0;
mpt->raid_rescan++;
continue;
}
if ((mpt_disk->flags & MPT_RDF_ANNOUNCED) == 0) {
mpt_announce_disk(mpt, mpt_disk);
mpt_disk->flags |= MPT_RVF_ANNOUNCED;
}
if ((mpt_disk->flags & MPT_RDF_UP2DATE) != 0)
continue;
mpt_disk->flags |= MPT_RDF_UP2DATE;
mpt_disk_prt(mpt, mpt_disk, "%s\n", mpt_disk_state(mpt_disk));
if (disk_pg->PhysDiskStatus.Flags == 0)
continue;
mpt_disk_prt(mpt, mpt_disk, "Status (");
for (m = 1; m <= 0x80; m <<= 1) {
switch (disk_pg->PhysDiskStatus.Flags & m) {
case MPI_PHYSDISK0_STATUS_FLAG_OUT_OF_SYNC:
mpt_prtc(mpt, " Out-Of-Sync");
break;
case MPI_PHYSDISK0_STATUS_FLAG_QUIESCED:
mpt_prtc(mpt, " Quiesced");
break;
default:
break;
}
}
mpt_prtc(mpt, " )\n");
}
mpt->raid_nonopt_volumes = nonopt_volumes;
Massive overhaul of MPT Fusion driver: o Add timeout error recovery (from a thread context to avoid the deferral of other critical interrupts). o Properly recover commands across controller reset events. o Update the driver to handle events and status codes that have been added to the MPI spec since the driver was originally written. o Make the driver more modular to improve maintainability and support dynamic "personality" registration (e.g. SCSI Initiator, RAID, SAS, FC, etc). o Shorten and simplify the common I/O path to improve driver performance. o Add RAID volume and RAID member state/settings reporting. o Add periodic volume resynchronization status reporting. o Add support for sysctl tunable resync rate, member write cache enable, and volume transaction queue depth. Sponsored by ---------------- Avid Technologies Inc: SCSI error recovery, driver re-organization, update of MPI library headers, portions of dynamic personality registration, and misc bug fixes. Wheel Open Technologies: RAID event notification, RAID member pass-thru support, firmware upload/download support, enhanced RAID resync speed, portions of dynamic personality registration, and misc bug fixes. Detailed Changes ================ mpt.c mpt_cam.c mpt_raid.c mpt_pci.c: o Add support for personality modules. Each module exports load, and unload module scope methods as well as probe, attach, event, reset, shutdown, and detach per-device instance methods mpt.c mpt.h mpt_pci.c: o The driver now associates a callback function (via an index) with every transaction submitted to the controller. This allows the main interrupt handler to absolve itself of any knowledge of individual transaction/response types by simply calling the callback function "registered" for the transaction. We use a callback index instead of a callback function pointer in each requests so we can properly handle responses (e.g. event notifications) that are not associated with a transaction. Personality modules dynamically register their callbacks with the driver core to receive the callback index to use for their handlers. o Move the interrupt handler into mpt.c. The ISR algorithm is bus transport and OS independent and thus had no reason to be in mpt_pci.c. o Simplify configuration message reply handling by copying reply frame data for the requester and storing completion status in the original request structure. o Add the mpt_complete_request_chain() helper method and use it to implement reset handlers that must abort transactions. o Keep track of all pending requests on the new requests_pending_list in the softc. o Add default handlers to mpt.c to handle generic event notifications and controller reset activities. The event handler code is largely the same as in the original driver. The reset handler is new and terminates any pending transactions with a status code indicating the controller needs to be re-initialized. o Add some endian support to the driver. A complete audit is still required for this driver to have any hope of operating in a big-endian environment. o Use inttypes.h and __inline. Come closer to being style(9) compliant. o Remove extraneous use of typedefs. o Convert request state from a strict enumeration to a series of flags. This allows us to, for example, tag transactions that have timed-out while retaining the state that the transaction is still in-flight on the controller. o Add mpt_wait_req() which allows a caller to poll or sleep for the completion of a request. Use this to simplify and factor code out from many initialization routines. We also use this to sleep for task management request completions in our CAM timeout handler. mpt.c: o Correct a bug in the event handler where request structures were freed even if the request reply was marked as a continuation reply. Continuation replies indicate that the controller still owns the request and freeing these replies prematurely corrupted controller state. o Implement firmware upload and download. On controllers that do not have dedicated NVRAM (as in the Sun v20/v40z), the firmware image is downloaded to the controller by the system BIOS. This image occupies precious controller RAM space until the host driver fetches the image, reducing the number of concurrent I/Os the controller can processes. The uploaded image is used to re-program the controller during hard reset events since the controller cannot fetch the firmware on its own. Implementing this feature allows much higher queue depths when RAID volumes are configured. o Changed configuration page accessors to allow threads to sleep rather than busy wait for completion. o Removed hard coded data transfer sizes from configuration page routines so that RAID configuration page processing is possible. mpt_reg.h: o Move controller register definitions into a separate file. mpt.h: o Re-arrange includes to allow inlined functions to be defined in mpt.h. o Add reply, event, and reset handler definitions. o Add softc fields for handling timeout and controller reset recovery. mpt_cam.c: o Move mpt_freebsd.c to mpt_cam.c. Move all core functionality, such as event handling, into mpt.c leaving only CAM SCSI support here. o Revamp completion handler to provide correct CAM status for all currently defined SCSI MPI message result codes. o Register event and reset handlers with the MPT core. Modify the event handler to notify CAM of bus reset events. The controller reset handler will abort any transactions that have timed out. All other pending CAM transactions are correctly aborted by the core driver's reset handler. o Allocate a single request up front to perform task management operations. This guarantees that we can always perform a TMF operation even when the controller is saturated with other operations. The single request also serves as a perfect mechanism of guaranteeing that only a single TMF is in flight at a time - something that is required according to the MPT Fusion documentation. o Add a helper function for issuing task management requests to the controller. This is used to abort individual requests or perform a bus reset. o Modify the CAM XPT_BUS_RESET ccb handler to wait for and properly handle the status of the bus reset task management frame used to reset the bus. The previous code assumed that the reset request would always succeed. o Add timeout recovery support. When a timeout occurs, the timed-out request is added to a queue to be processed by our recovery thread and the thread is woken up. The recovery thread processes timed-out command serially, attempting first to abort them and then falling back to a bus reset if an abort fails. o Add calls to mpt_reset() to reset the controller if any handshake command, bus reset attempt or abort attempt fails due to a timeout. o Export a secondary "bus" to CAM that exposes all volume drive members as pass-thru devices, allowing CAM to perform proper speed negotiation to hidden devices. o Add a CAM async event handler tracking the AC_FOUND_DEVICE event. Use this to trigger calls to set the per-volume queue depth once the volume is fully registered with CAM. This is required to avoid hitting firmware limits on volume queue depth. Exceeding the limit causes the firmware to hang. mpt_cam.h: o Add several helper functions for interfacing to CAM and performing timeout recovery. mpt_pci.c: o Disable interrupts on the controller before registering and enabling interrupt delivery to the OS. Otherwise we risk receiving interrupts before the driver is ready to receive them. o Make use of compatibility macros that allow the driver to be compiled under 4.x and 5.x. mpt_raid.c: o Add a per-controller instance RAID thread to perform settings changes and query status (minimizes CPU busy wait loops). o Use a shutdown handler to disable "Member Write Cache Enable" (MWCE) setting for RAID arrays set to enable MWCE During Rebuild. o Change reply handler function signature to allow handlers to defer the deletion of reply frames. Use this to allow the event reply handler to queue up events that need to be acked if no resources are available to immediately ack an event. Queued events are processed in mpt_free_request() where resources are freed. This avoids a panic on resource shortage. o Parse and print out RAID controller capabilities during driver probe. o Define, allocate, and maintain RAID data structures for volumes, hidden member physical disks and spare disks. o Add dynamic sysctls for per-instance setting of the log level, array resync rate, array member cache enable, and volume queue depth. mpt_debug.c: o Add mpt_lprt and mpt_lprtc for printing diagnostics conditioned on a particular log level to aid in tracking down driver issues. o Add mpt_decode_value() which parses the bits in an integer value based on a parsing table (mask, value, name string, tuples). mpilib/*: o Update mpi library header files to latest distribution from LSI. Submitted by: gibbs Approved by: re
2005-07-10 15:05:39 +00:00
}
static void
mpt_raid_timer(void *arg)
{
struct mpt_softc *mpt;
mpt = (struct mpt_softc *)arg;
MPT_LOCK(mpt);
mpt_raid_wakeup(mpt);
MPT_UNLOCK(mpt);
}
static void
mpt_raid_quiesce_timeout(void *arg)
{
/* Complete the CCB with error */
/* COWWWW */
}
void
mpt_schedule_raid_refresh(struct mpt_softc *mpt)
{
callout_reset(&mpt->raid_timer, MPT_RAID_SYNC_REPORT_INTERVAL,
mpt_raid_timer, mpt);
}
static int
mpt_raid_set_vol_resync_rate(struct mpt_softc *mpt, u_int rate)
{
struct mpt_raid_volume *mpt_vol;
if ((rate > MPT_RAID_RESYNC_RATE_MAX
|| rate < MPT_RAID_RESYNC_RATE_MIN)
&& rate != MPT_RAID_RESYNC_RATE_NC)
return (EINVAL);
MPT_LOCK(mpt);
mpt->raid_resync_rate = rate;
RAID_VOL_FOREACH(mpt, mpt_vol) {
if ((mpt_vol->flags & MPT_RVF_ACTIVE) == 0) {
Massive overhaul of MPT Fusion driver: o Add timeout error recovery (from a thread context to avoid the deferral of other critical interrupts). o Properly recover commands across controller reset events. o Update the driver to handle events and status codes that have been added to the MPI spec since the driver was originally written. o Make the driver more modular to improve maintainability and support dynamic "personality" registration (e.g. SCSI Initiator, RAID, SAS, FC, etc). o Shorten and simplify the common I/O path to improve driver performance. o Add RAID volume and RAID member state/settings reporting. o Add periodic volume resynchronization status reporting. o Add support for sysctl tunable resync rate, member write cache enable, and volume transaction queue depth. Sponsored by ---------------- Avid Technologies Inc: SCSI error recovery, driver re-organization, update of MPI library headers, portions of dynamic personality registration, and misc bug fixes. Wheel Open Technologies: RAID event notification, RAID member pass-thru support, firmware upload/download support, enhanced RAID resync speed, portions of dynamic personality registration, and misc bug fixes. Detailed Changes ================ mpt.c mpt_cam.c mpt_raid.c mpt_pci.c: o Add support for personality modules. Each module exports load, and unload module scope methods as well as probe, attach, event, reset, shutdown, and detach per-device instance methods mpt.c mpt.h mpt_pci.c: o The driver now associates a callback function (via an index) with every transaction submitted to the controller. This allows the main interrupt handler to absolve itself of any knowledge of individual transaction/response types by simply calling the callback function "registered" for the transaction. We use a callback index instead of a callback function pointer in each requests so we can properly handle responses (e.g. event notifications) that are not associated with a transaction. Personality modules dynamically register their callbacks with the driver core to receive the callback index to use for their handlers. o Move the interrupt handler into mpt.c. The ISR algorithm is bus transport and OS independent and thus had no reason to be in mpt_pci.c. o Simplify configuration message reply handling by copying reply frame data for the requester and storing completion status in the original request structure. o Add the mpt_complete_request_chain() helper method and use it to implement reset handlers that must abort transactions. o Keep track of all pending requests on the new requests_pending_list in the softc. o Add default handlers to mpt.c to handle generic event notifications and controller reset activities. The event handler code is largely the same as in the original driver. The reset handler is new and terminates any pending transactions with a status code indicating the controller needs to be re-initialized. o Add some endian support to the driver. A complete audit is still required for this driver to have any hope of operating in a big-endian environment. o Use inttypes.h and __inline. Come closer to being style(9) compliant. o Remove extraneous use of typedefs. o Convert request state from a strict enumeration to a series of flags. This allows us to, for example, tag transactions that have timed-out while retaining the state that the transaction is still in-flight on the controller. o Add mpt_wait_req() which allows a caller to poll or sleep for the completion of a request. Use this to simplify and factor code out from many initialization routines. We also use this to sleep for task management request completions in our CAM timeout handler. mpt.c: o Correct a bug in the event handler where request structures were freed even if the request reply was marked as a continuation reply. Continuation replies indicate that the controller still owns the request and freeing these replies prematurely corrupted controller state. o Implement firmware upload and download. On controllers that do not have dedicated NVRAM (as in the Sun v20/v40z), the firmware image is downloaded to the controller by the system BIOS. This image occupies precious controller RAM space until the host driver fetches the image, reducing the number of concurrent I/Os the controller can processes. The uploaded image is used to re-program the controller during hard reset events since the controller cannot fetch the firmware on its own. Implementing this feature allows much higher queue depths when RAID volumes are configured. o Changed configuration page accessors to allow threads to sleep rather than busy wait for completion. o Removed hard coded data transfer sizes from configuration page routines so that RAID configuration page processing is possible. mpt_reg.h: o Move controller register definitions into a separate file. mpt.h: o Re-arrange includes to allow inlined functions to be defined in mpt.h. o Add reply, event, and reset handler definitions. o Add softc fields for handling timeout and controller reset recovery. mpt_cam.c: o Move mpt_freebsd.c to mpt_cam.c. Move all core functionality, such as event handling, into mpt.c leaving only CAM SCSI support here. o Revamp completion handler to provide correct CAM status for all currently defined SCSI MPI message result codes. o Register event and reset handlers with the MPT core. Modify the event handler to notify CAM of bus reset events. The controller reset handler will abort any transactions that have timed out. All other pending CAM transactions are correctly aborted by the core driver's reset handler. o Allocate a single request up front to perform task management operations. This guarantees that we can always perform a TMF operation even when the controller is saturated with other operations. The single request also serves as a perfect mechanism of guaranteeing that only a single TMF is in flight at a time - something that is required according to the MPT Fusion documentation. o Add a helper function for issuing task management requests to the controller. This is used to abort individual requests or perform a bus reset. o Modify the CAM XPT_BUS_RESET ccb handler to wait for and properly handle the status of the bus reset task management frame used to reset the bus. The previous code assumed that the reset request would always succeed. o Add timeout recovery support. When a timeout occurs, the timed-out request is added to a queue to be processed by our recovery thread and the thread is woken up. The recovery thread processes timed-out command serially, attempting first to abort them and then falling back to a bus reset if an abort fails. o Add calls to mpt_reset() to reset the controller if any handshake command, bus reset attempt or abort attempt fails due to a timeout. o Export a secondary "bus" to CAM that exposes all volume drive members as pass-thru devices, allowing CAM to perform proper speed negotiation to hidden devices. o Add a CAM async event handler tracking the AC_FOUND_DEVICE event. Use this to trigger calls to set the per-volume queue depth once the volume is fully registered with CAM. This is required to avoid hitting firmware limits on volume queue depth. Exceeding the limit causes the firmware to hang. mpt_cam.h: o Add several helper functions for interfacing to CAM and performing timeout recovery. mpt_pci.c: o Disable interrupts on the controller before registering and enabling interrupt delivery to the OS. Otherwise we risk receiving interrupts before the driver is ready to receive them. o Make use of compatibility macros that allow the driver to be compiled under 4.x and 5.x. mpt_raid.c: o Add a per-controller instance RAID thread to perform settings changes and query status (minimizes CPU busy wait loops). o Use a shutdown handler to disable "Member Write Cache Enable" (MWCE) setting for RAID arrays set to enable MWCE During Rebuild. o Change reply handler function signature to allow handlers to defer the deletion of reply frames. Use this to allow the event reply handler to queue up events that need to be acked if no resources are available to immediately ack an event. Queued events are processed in mpt_free_request() where resources are freed. This avoids a panic on resource shortage. o Parse and print out RAID controller capabilities during driver probe. o Define, allocate, and maintain RAID data structures for volumes, hidden member physical disks and spare disks. o Add dynamic sysctls for per-instance setting of the log level, array resync rate, array member cache enable, and volume queue depth. mpt_debug.c: o Add mpt_lprt and mpt_lprtc for printing diagnostics conditioned on a particular log level to aid in tracking down driver issues. o Add mpt_decode_value() which parses the bits in an integer value based on a parsing table (mask, value, name string, tuples). mpilib/*: o Update mpi library header files to latest distribution from LSI. Submitted by: gibbs Approved by: re
2005-07-10 15:05:39 +00:00
continue;
}
Massive overhaul of MPT Fusion driver: o Add timeout error recovery (from a thread context to avoid the deferral of other critical interrupts). o Properly recover commands across controller reset events. o Update the driver to handle events and status codes that have been added to the MPI spec since the driver was originally written. o Make the driver more modular to improve maintainability and support dynamic "personality" registration (e.g. SCSI Initiator, RAID, SAS, FC, etc). o Shorten and simplify the common I/O path to improve driver performance. o Add RAID volume and RAID member state/settings reporting. o Add periodic volume resynchronization status reporting. o Add support for sysctl tunable resync rate, member write cache enable, and volume transaction queue depth. Sponsored by ---------------- Avid Technologies Inc: SCSI error recovery, driver re-organization, update of MPI library headers, portions of dynamic personality registration, and misc bug fixes. Wheel Open Technologies: RAID event notification, RAID member pass-thru support, firmware upload/download support, enhanced RAID resync speed, portions of dynamic personality registration, and misc bug fixes. Detailed Changes ================ mpt.c mpt_cam.c mpt_raid.c mpt_pci.c: o Add support for personality modules. Each module exports load, and unload module scope methods as well as probe, attach, event, reset, shutdown, and detach per-device instance methods mpt.c mpt.h mpt_pci.c: o The driver now associates a callback function (via an index) with every transaction submitted to the controller. This allows the main interrupt handler to absolve itself of any knowledge of individual transaction/response types by simply calling the callback function "registered" for the transaction. We use a callback index instead of a callback function pointer in each requests so we can properly handle responses (e.g. event notifications) that are not associated with a transaction. Personality modules dynamically register their callbacks with the driver core to receive the callback index to use for their handlers. o Move the interrupt handler into mpt.c. The ISR algorithm is bus transport and OS independent and thus had no reason to be in mpt_pci.c. o Simplify configuration message reply handling by copying reply frame data for the requester and storing completion status in the original request structure. o Add the mpt_complete_request_chain() helper method and use it to implement reset handlers that must abort transactions. o Keep track of all pending requests on the new requests_pending_list in the softc. o Add default handlers to mpt.c to handle generic event notifications and controller reset activities. The event handler code is largely the same as in the original driver. The reset handler is new and terminates any pending transactions with a status code indicating the controller needs to be re-initialized. o Add some endian support to the driver. A complete audit is still required for this driver to have any hope of operating in a big-endian environment. o Use inttypes.h and __inline. Come closer to being style(9) compliant. o Remove extraneous use of typedefs. o Convert request state from a strict enumeration to a series of flags. This allows us to, for example, tag transactions that have timed-out while retaining the state that the transaction is still in-flight on the controller. o Add mpt_wait_req() which allows a caller to poll or sleep for the completion of a request. Use this to simplify and factor code out from many initialization routines. We also use this to sleep for task management request completions in our CAM timeout handler. mpt.c: o Correct a bug in the event handler where request structures were freed even if the request reply was marked as a continuation reply. Continuation replies indicate that the controller still owns the request and freeing these replies prematurely corrupted controller state. o Implement firmware upload and download. On controllers that do not have dedicated NVRAM (as in the Sun v20/v40z), the firmware image is downloaded to the controller by the system BIOS. This image occupies precious controller RAM space until the host driver fetches the image, reducing the number of concurrent I/Os the controller can processes. The uploaded image is used to re-program the controller during hard reset events since the controller cannot fetch the firmware on its own. Implementing this feature allows much higher queue depths when RAID volumes are configured. o Changed configuration page accessors to allow threads to sleep rather than busy wait for completion. o Removed hard coded data transfer sizes from configuration page routines so that RAID configuration page processing is possible. mpt_reg.h: o Move controller register definitions into a separate file. mpt.h: o Re-arrange includes to allow inlined functions to be defined in mpt.h. o Add reply, event, and reset handler definitions. o Add softc fields for handling timeout and controller reset recovery. mpt_cam.c: o Move mpt_freebsd.c to mpt_cam.c. Move all core functionality, such as event handling, into mpt.c leaving only CAM SCSI support here. o Revamp completion handler to provide correct CAM status for all currently defined SCSI MPI message result codes. o Register event and reset handlers with the MPT core. Modify the event handler to notify CAM of bus reset events. The controller reset handler will abort any transactions that have timed out. All other pending CAM transactions are correctly aborted by the core driver's reset handler. o Allocate a single request up front to perform task management operations. This guarantees that we can always perform a TMF operation even when the controller is saturated with other operations. The single request also serves as a perfect mechanism of guaranteeing that only a single TMF is in flight at a time - something that is required according to the MPT Fusion documentation. o Add a helper function for issuing task management requests to the controller. This is used to abort individual requests or perform a bus reset. o Modify the CAM XPT_BUS_RESET ccb handler to wait for and properly handle the status of the bus reset task management frame used to reset the bus. The previous code assumed that the reset request would always succeed. o Add timeout recovery support. When a timeout occurs, the timed-out request is added to a queue to be processed by our recovery thread and the thread is woken up. The recovery thread processes timed-out command serially, attempting first to abort them and then falling back to a bus reset if an abort fails. o Add calls to mpt_reset() to reset the controller if any handshake command, bus reset attempt or abort attempt fails due to a timeout. o Export a secondary "bus" to CAM that exposes all volume drive members as pass-thru devices, allowing CAM to perform proper speed negotiation to hidden devices. o Add a CAM async event handler tracking the AC_FOUND_DEVICE event. Use this to trigger calls to set the per-volume queue depth once the volume is fully registered with CAM. This is required to avoid hitting firmware limits on volume queue depth. Exceeding the limit causes the firmware to hang. mpt_cam.h: o Add several helper functions for interfacing to CAM and performing timeout recovery. mpt_pci.c: o Disable interrupts on the controller before registering and enabling interrupt delivery to the OS. Otherwise we risk receiving interrupts before the driver is ready to receive them. o Make use of compatibility macros that allow the driver to be compiled under 4.x and 5.x. mpt_raid.c: o Add a per-controller instance RAID thread to perform settings changes and query status (minimizes CPU busy wait loops). o Use a shutdown handler to disable "Member Write Cache Enable" (MWCE) setting for RAID arrays set to enable MWCE During Rebuild. o Change reply handler function signature to allow handlers to defer the deletion of reply frames. Use this to allow the event reply handler to queue up events that need to be acked if no resources are available to immediately ack an event. Queued events are processed in mpt_free_request() where resources are freed. This avoids a panic on resource shortage. o Parse and print out RAID controller capabilities during driver probe. o Define, allocate, and maintain RAID data structures for volumes, hidden member physical disks and spare disks. o Add dynamic sysctls for per-instance setting of the log level, array resync rate, array member cache enable, and volume queue depth. mpt_debug.c: o Add mpt_lprt and mpt_lprtc for printing diagnostics conditioned on a particular log level to aid in tracking down driver issues. o Add mpt_decode_value() which parses the bits in an integer value based on a parsing table (mask, value, name string, tuples). mpilib/*: o Update mpi library header files to latest distribution from LSI. Submitted by: gibbs Approved by: re
2005-07-10 15:05:39 +00:00
mpt_verify_resync_rate(mpt, mpt_vol);
}
MPT_UNLOCK(mpt);
return (0);
}
static int
mpt_raid_set_vol_queue_depth(struct mpt_softc *mpt, u_int vol_queue_depth)
{
struct mpt_raid_volume *mpt_vol;
if (vol_queue_depth > 255 || vol_queue_depth < 1)
Massive overhaul of MPT Fusion driver: o Add timeout error recovery (from a thread context to avoid the deferral of other critical interrupts). o Properly recover commands across controller reset events. o Update the driver to handle events and status codes that have been added to the MPI spec since the driver was originally written. o Make the driver more modular to improve maintainability and support dynamic "personality" registration (e.g. SCSI Initiator, RAID, SAS, FC, etc). o Shorten and simplify the common I/O path to improve driver performance. o Add RAID volume and RAID member state/settings reporting. o Add periodic volume resynchronization status reporting. o Add support for sysctl tunable resync rate, member write cache enable, and volume transaction queue depth. Sponsored by ---------------- Avid Technologies Inc: SCSI error recovery, driver re-organization, update of MPI library headers, portions of dynamic personality registration, and misc bug fixes. Wheel Open Technologies: RAID event notification, RAID member pass-thru support, firmware upload/download support, enhanced RAID resync speed, portions of dynamic personality registration, and misc bug fixes. Detailed Changes ================ mpt.c mpt_cam.c mpt_raid.c mpt_pci.c: o Add support for personality modules. Each module exports load, and unload module scope methods as well as probe, attach, event, reset, shutdown, and detach per-device instance methods mpt.c mpt.h mpt_pci.c: o The driver now associates a callback function (via an index) with every transaction submitted to the controller. This allows the main interrupt handler to absolve itself of any knowledge of individual transaction/response types by simply calling the callback function "registered" for the transaction. We use a callback index instead of a callback function pointer in each requests so we can properly handle responses (e.g. event notifications) that are not associated with a transaction. Personality modules dynamically register their callbacks with the driver core to receive the callback index to use for their handlers. o Move the interrupt handler into mpt.c. The ISR algorithm is bus transport and OS independent and thus had no reason to be in mpt_pci.c. o Simplify configuration message reply handling by copying reply frame data for the requester and storing completion status in the original request structure. o Add the mpt_complete_request_chain() helper method and use it to implement reset handlers that must abort transactions. o Keep track of all pending requests on the new requests_pending_list in the softc. o Add default handlers to mpt.c to handle generic event notifications and controller reset activities. The event handler code is largely the same as in the original driver. The reset handler is new and terminates any pending transactions with a status code indicating the controller needs to be re-initialized. o Add some endian support to the driver. A complete audit is still required for this driver to have any hope of operating in a big-endian environment. o Use inttypes.h and __inline. Come closer to being style(9) compliant. o Remove extraneous use of typedefs. o Convert request state from a strict enumeration to a series of flags. This allows us to, for example, tag transactions that have timed-out while retaining the state that the transaction is still in-flight on the controller. o Add mpt_wait_req() which allows a caller to poll or sleep for the completion of a request. Use this to simplify and factor code out from many initialization routines. We also use this to sleep for task management request completions in our CAM timeout handler. mpt.c: o Correct a bug in the event handler where request structures were freed even if the request reply was marked as a continuation reply. Continuation replies indicate that the controller still owns the request and freeing these replies prematurely corrupted controller state. o Implement firmware upload and download. On controllers that do not have dedicated NVRAM (as in the Sun v20/v40z), the firmware image is downloaded to the controller by the system BIOS. This image occupies precious controller RAM space until the host driver fetches the image, reducing the number of concurrent I/Os the controller can processes. The uploaded image is used to re-program the controller during hard reset events since the controller cannot fetch the firmware on its own. Implementing this feature allows much higher queue depths when RAID volumes are configured. o Changed configuration page accessors to allow threads to sleep rather than busy wait for completion. o Removed hard coded data transfer sizes from configuration page routines so that RAID configuration page processing is possible. mpt_reg.h: o Move controller register definitions into a separate file. mpt.h: o Re-arrange includes to allow inlined functions to be defined in mpt.h. o Add reply, event, and reset handler definitions. o Add softc fields for handling timeout and controller reset recovery. mpt_cam.c: o Move mpt_freebsd.c to mpt_cam.c. Move all core functionality, such as event handling, into mpt.c leaving only CAM SCSI support here. o Revamp completion handler to provide correct CAM status for all currently defined SCSI MPI message result codes. o Register event and reset handlers with the MPT core. Modify the event handler to notify CAM of bus reset events. The controller reset handler will abort any transactions that have timed out. All other pending CAM transactions are correctly aborted by the core driver's reset handler. o Allocate a single request up front to perform task management operations. This guarantees that we can always perform a TMF operation even when the controller is saturated with other operations. The single request also serves as a perfect mechanism of guaranteeing that only a single TMF is in flight at a time - something that is required according to the MPT Fusion documentation. o Add a helper function for issuing task management requests to the controller. This is used to abort individual requests or perform a bus reset. o Modify the CAM XPT_BUS_RESET ccb handler to wait for and properly handle the status of the bus reset task management frame used to reset the bus. The previous code assumed that the reset request would always succeed. o Add timeout recovery support. When a timeout occurs, the timed-out request is added to a queue to be processed by our recovery thread and the thread is woken up. The recovery thread processes timed-out command serially, attempting first to abort them and then falling back to a bus reset if an abort fails. o Add calls to mpt_reset() to reset the controller if any handshake command, bus reset attempt or abort attempt fails due to a timeout. o Export a secondary "bus" to CAM that exposes all volume drive members as pass-thru devices, allowing CAM to perform proper speed negotiation to hidden devices. o Add a CAM async event handler tracking the AC_FOUND_DEVICE event. Use this to trigger calls to set the per-volume queue depth once the volume is fully registered with CAM. This is required to avoid hitting firmware limits on volume queue depth. Exceeding the limit causes the firmware to hang. mpt_cam.h: o Add several helper functions for interfacing to CAM and performing timeout recovery. mpt_pci.c: o Disable interrupts on the controller before registering and enabling interrupt delivery to the OS. Otherwise we risk receiving interrupts before the driver is ready to receive them. o Make use of compatibility macros that allow the driver to be compiled under 4.x and 5.x. mpt_raid.c: o Add a per-controller instance RAID thread to perform settings changes and query status (minimizes CPU busy wait loops). o Use a shutdown handler to disable "Member Write Cache Enable" (MWCE) setting for RAID arrays set to enable MWCE During Rebuild. o Change reply handler function signature to allow handlers to defer the deletion of reply frames. Use this to allow the event reply handler to queue up events that need to be acked if no resources are available to immediately ack an event. Queued events are processed in mpt_free_request() where resources are freed. This avoids a panic on resource shortage. o Parse and print out RAID controller capabilities during driver probe. o Define, allocate, and maintain RAID data structures for volumes, hidden member physical disks and spare disks. o Add dynamic sysctls for per-instance setting of the log level, array resync rate, array member cache enable, and volume queue depth. mpt_debug.c: o Add mpt_lprt and mpt_lprtc for printing diagnostics conditioned on a particular log level to aid in tracking down driver issues. o Add mpt_decode_value() which parses the bits in an integer value based on a parsing table (mask, value, name string, tuples). mpilib/*: o Update mpi library header files to latest distribution from LSI. Submitted by: gibbs Approved by: re
2005-07-10 15:05:39 +00:00
return (EINVAL);
MPT_LOCK(mpt);
mpt->raid_queue_depth = vol_queue_depth;
RAID_VOL_FOREACH(mpt, mpt_vol) {
struct cam_path *path;
int error;
if ((mpt_vol->flags & MPT_RVF_ACTIVE) == 0)
continue;
mpt->raid_rescan = 0;
error = xpt_create_path(&path, xpt_periph,
cam_sim_path(mpt->sim),
mpt_vol->config_page->VolumeID,
/*lun*/0);
if (error != CAM_REQ_CMP) {
mpt_vol_prt(mpt, mpt_vol, "Unable to allocate path!\n");
continue;
}
mpt_adjust_queue_depth(mpt, mpt_vol, path);
xpt_free_path(path);
}
MPT_UNLOCK(mpt);
return (0);
}
static int
mpt_raid_set_vol_mwce(struct mpt_softc *mpt, mpt_raid_mwce_t mwce)
{
struct mpt_raid_volume *mpt_vol;
int force_full_resync;
MPT_LOCK(mpt);
if (mwce == mpt->raid_mwce_setting) {
MPT_UNLOCK(mpt);
return (0);
}
/*
* Catch MWCE being left on due to a failed shutdown. Since
* sysctls cannot be set by the loader, we treat the first
* setting of this varible specially and force a full volume
* resync if MWCE is enabled and a resync is in progress.
*/
force_full_resync = 0;
if (mpt->raid_mwce_set == 0
&& mpt->raid_mwce_setting == MPT_RAID_MWCE_NC
&& mwce == MPT_RAID_MWCE_REBUILD_ONLY)
force_full_resync = 1;
mpt->raid_mwce_setting = mwce;
RAID_VOL_FOREACH(mpt, mpt_vol) {
CONFIG_PAGE_RAID_VOL_0 *vol_pg;
int resyncing;
int mwce;
if ((mpt_vol->flags & MPT_RVF_ACTIVE) == 0)
continue;
vol_pg = mpt_vol->config_page;
resyncing = vol_pg->VolumeStatus.Flags
& MPI_RAIDVOL0_STATUS_FLAG_RESYNC_IN_PROGRESS;
mwce = vol_pg->VolumeSettings.Settings
& MPI_RAIDVOL0_SETTING_WRITE_CACHING_ENABLE;
if (force_full_resync && resyncing && mwce) {
/*
* XXX disable/enable volume should force a resync,
* but we'll need to queice, drain, and restart
* I/O to do that.
*/
mpt_vol_prt(mpt, mpt_vol, "WARNING - Unsafe shutdown "
"detected. Suggest full resync.\n");
}
mpt_verify_mwce(mpt, mpt_vol);
}
mpt->raid_mwce_set = 1;
MPT_UNLOCK(mpt);
return (0);
}
const char *mpt_vol_mwce_strs[] =
{
"On",
"Off",
"On-During-Rebuild",
"NC"
};
static int
mpt_raid_sysctl_vol_member_wce(SYSCTL_HANDLER_ARGS)
{
char inbuf[20];
struct mpt_softc *mpt;
const char *str;
int error;
u_int size;
u_int i;
GIANT_REQUIRED;
mpt = (struct mpt_softc *)arg1;
str = mpt_vol_mwce_strs[mpt->raid_mwce_setting];
error = SYSCTL_OUT(req, str, strlen(str) + 1);
if (error || !req->newptr)
return (error);
size = req->newlen - req->newidx;
if (size >= sizeof(inbuf))
return (EINVAL);
error = SYSCTL_IN(req, inbuf, size);
if (error)
return (error);
inbuf[size] = '\0';
for (i = 0; i < NUM_ELEMENTS(mpt_vol_mwce_strs); i++) {
if (strcmp(mpt_vol_mwce_strs[i], inbuf) == 0)
return (mpt_raid_set_vol_mwce(mpt, i));
}
return (EINVAL);
}
static int
mpt_raid_sysctl_vol_resync_rate(SYSCTL_HANDLER_ARGS)
{
struct mpt_softc *mpt;
u_int raid_resync_rate;
int error;
GIANT_REQUIRED;
mpt = (struct mpt_softc *)arg1;
raid_resync_rate = mpt->raid_resync_rate;
error = sysctl_handle_int(oidp, &raid_resync_rate, 0, req);
if (error || !req->newptr)
return error;
return (mpt_raid_set_vol_resync_rate(mpt, raid_resync_rate));
}
static int
mpt_raid_sysctl_vol_queue_depth(SYSCTL_HANDLER_ARGS)
{
struct mpt_softc *mpt;
u_int raid_queue_depth;
int error;
GIANT_REQUIRED;
mpt = (struct mpt_softc *)arg1;
raid_queue_depth = mpt->raid_queue_depth;
error = sysctl_handle_int(oidp, &raid_queue_depth, 0, req);
if (error || !req->newptr)
return error;
return (mpt_raid_set_vol_queue_depth(mpt, raid_queue_depth));
}
static void
mpt_raid_sysctl_attach(struct mpt_softc *mpt)
{
#if __FreeBSD_version >= 500000
Massive overhaul of MPT Fusion driver: o Add timeout error recovery (from a thread context to avoid the deferral of other critical interrupts). o Properly recover commands across controller reset events. o Update the driver to handle events and status codes that have been added to the MPI spec since the driver was originally written. o Make the driver more modular to improve maintainability and support dynamic "personality" registration (e.g. SCSI Initiator, RAID, SAS, FC, etc). o Shorten and simplify the common I/O path to improve driver performance. o Add RAID volume and RAID member state/settings reporting. o Add periodic volume resynchronization status reporting. o Add support for sysctl tunable resync rate, member write cache enable, and volume transaction queue depth. Sponsored by ---------------- Avid Technologies Inc: SCSI error recovery, driver re-organization, update of MPI library headers, portions of dynamic personality registration, and misc bug fixes. Wheel Open Technologies: RAID event notification, RAID member pass-thru support, firmware upload/download support, enhanced RAID resync speed, portions of dynamic personality registration, and misc bug fixes. Detailed Changes ================ mpt.c mpt_cam.c mpt_raid.c mpt_pci.c: o Add support for personality modules. Each module exports load, and unload module scope methods as well as probe, attach, event, reset, shutdown, and detach per-device instance methods mpt.c mpt.h mpt_pci.c: o The driver now associates a callback function (via an index) with every transaction submitted to the controller. This allows the main interrupt handler to absolve itself of any knowledge of individual transaction/response types by simply calling the callback function "registered" for the transaction. We use a callback index instead of a callback function pointer in each requests so we can properly handle responses (e.g. event notifications) that are not associated with a transaction. Personality modules dynamically register their callbacks with the driver core to receive the callback index to use for their handlers. o Move the interrupt handler into mpt.c. The ISR algorithm is bus transport and OS independent and thus had no reason to be in mpt_pci.c. o Simplify configuration message reply handling by copying reply frame data for the requester and storing completion status in the original request structure. o Add the mpt_complete_request_chain() helper method and use it to implement reset handlers that must abort transactions. o Keep track of all pending requests on the new requests_pending_list in the softc. o Add default handlers to mpt.c to handle generic event notifications and controller reset activities. The event handler code is largely the same as in the original driver. The reset handler is new and terminates any pending transactions with a status code indicating the controller needs to be re-initialized. o Add some endian support to the driver. A complete audit is still required for this driver to have any hope of operating in a big-endian environment. o Use inttypes.h and __inline. Come closer to being style(9) compliant. o Remove extraneous use of typedefs. o Convert request state from a strict enumeration to a series of flags. This allows us to, for example, tag transactions that have timed-out while retaining the state that the transaction is still in-flight on the controller. o Add mpt_wait_req() which allows a caller to poll or sleep for the completion of a request. Use this to simplify and factor code out from many initialization routines. We also use this to sleep for task management request completions in our CAM timeout handler. mpt.c: o Correct a bug in the event handler where request structures were freed even if the request reply was marked as a continuation reply. Continuation replies indicate that the controller still owns the request and freeing these replies prematurely corrupted controller state. o Implement firmware upload and download. On controllers that do not have dedicated NVRAM (as in the Sun v20/v40z), the firmware image is downloaded to the controller by the system BIOS. This image occupies precious controller RAM space until the host driver fetches the image, reducing the number of concurrent I/Os the controller can processes. The uploaded image is used to re-program the controller during hard reset events since the controller cannot fetch the firmware on its own. Implementing this feature allows much higher queue depths when RAID volumes are configured. o Changed configuration page accessors to allow threads to sleep rather than busy wait for completion. o Removed hard coded data transfer sizes from configuration page routines so that RAID configuration page processing is possible. mpt_reg.h: o Move controller register definitions into a separate file. mpt.h: o Re-arrange includes to allow inlined functions to be defined in mpt.h. o Add reply, event, and reset handler definitions. o Add softc fields for handling timeout and controller reset recovery. mpt_cam.c: o Move mpt_freebsd.c to mpt_cam.c. Move all core functionality, such as event handling, into mpt.c leaving only CAM SCSI support here. o Revamp completion handler to provide correct CAM status for all currently defined SCSI MPI message result codes. o Register event and reset handlers with the MPT core. Modify the event handler to notify CAM of bus reset events. The controller reset handler will abort any transactions that have timed out. All other pending CAM transactions are correctly aborted by the core driver's reset handler. o Allocate a single request up front to perform task management operations. This guarantees that we can always perform a TMF operation even when the controller is saturated with other operations. The single request also serves as a perfect mechanism of guaranteeing that only a single TMF is in flight at a time - something that is required according to the MPT Fusion documentation. o Add a helper function for issuing task management requests to the controller. This is used to abort individual requests or perform a bus reset. o Modify the CAM XPT_BUS_RESET ccb handler to wait for and properly handle the status of the bus reset task management frame used to reset the bus. The previous code assumed that the reset request would always succeed. o Add timeout recovery support. When a timeout occurs, the timed-out request is added to a queue to be processed by our recovery thread and the thread is woken up. The recovery thread processes timed-out command serially, attempting first to abort them and then falling back to a bus reset if an abort fails. o Add calls to mpt_reset() to reset the controller if any handshake command, bus reset attempt or abort attempt fails due to a timeout. o Export a secondary "bus" to CAM that exposes all volume drive members as pass-thru devices, allowing CAM to perform proper speed negotiation to hidden devices. o Add a CAM async event handler tracking the AC_FOUND_DEVICE event. Use this to trigger calls to set the per-volume queue depth once the volume is fully registered with CAM. This is required to avoid hitting firmware limits on volume queue depth. Exceeding the limit causes the firmware to hang. mpt_cam.h: o Add several helper functions for interfacing to CAM and performing timeout recovery. mpt_pci.c: o Disable interrupts on the controller before registering and enabling interrupt delivery to the OS. Otherwise we risk receiving interrupts before the driver is ready to receive them. o Make use of compatibility macros that allow the driver to be compiled under 4.x and 5.x. mpt_raid.c: o Add a per-controller instance RAID thread to perform settings changes and query status (minimizes CPU busy wait loops). o Use a shutdown handler to disable "Member Write Cache Enable" (MWCE) setting for RAID arrays set to enable MWCE During Rebuild. o Change reply handler function signature to allow handlers to defer the deletion of reply frames. Use this to allow the event reply handler to queue up events that need to be acked if no resources are available to immediately ack an event. Queued events are processed in mpt_free_request() where resources are freed. This avoids a panic on resource shortage. o Parse and print out RAID controller capabilities during driver probe. o Define, allocate, and maintain RAID data structures for volumes, hidden member physical disks and spare disks. o Add dynamic sysctls for per-instance setting of the log level, array resync rate, array member cache enable, and volume queue depth. mpt_debug.c: o Add mpt_lprt and mpt_lprtc for printing diagnostics conditioned on a particular log level to aid in tracking down driver issues. o Add mpt_decode_value() which parses the bits in an integer value based on a parsing table (mask, value, name string, tuples). mpilib/*: o Update mpi library header files to latest distribution from LSI. Submitted by: gibbs Approved by: re
2005-07-10 15:05:39 +00:00
struct sysctl_ctx_list *ctx = device_get_sysctl_ctx(mpt->dev);
struct sysctl_oid *tree = device_get_sysctl_tree(mpt->dev);
SYSCTL_ADD_PROC(ctx, SYSCTL_CHILDREN(tree), OID_AUTO,
"vol_member_wce", CTLTYPE_STRING | CTLFLAG_RW, mpt, 0,
mpt_raid_sysctl_vol_member_wce, "A",
"volume member WCE(On,Off,On-During-Rebuild,NC)");
SYSCTL_ADD_PROC(ctx, SYSCTL_CHILDREN(tree), OID_AUTO,
"vol_queue_depth", CTLTYPE_INT | CTLFLAG_RW, mpt, 0,
mpt_raid_sysctl_vol_queue_depth, "I",
"default volume queue depth");
SYSCTL_ADD_PROC(ctx, SYSCTL_CHILDREN(tree), OID_AUTO,
"vol_resync_rate", CTLTYPE_INT | CTLFLAG_RW, mpt, 0,
mpt_raid_sysctl_vol_resync_rate, "I",
"volume resync priority (0 == NC, 1 - 255)");
SYSCTL_ADD_INT(ctx, SYSCTL_CHILDREN(tree), OID_AUTO,
"nonoptimal_volumes", CTLFLAG_RD,
&mpt->raid_nonopt_volumes, 0,
"number of nonoptimal volumes");
#endif
Massive overhaul of MPT Fusion driver: o Add timeout error recovery (from a thread context to avoid the deferral of other critical interrupts). o Properly recover commands across controller reset events. o Update the driver to handle events and status codes that have been added to the MPI spec since the driver was originally written. o Make the driver more modular to improve maintainability and support dynamic "personality" registration (e.g. SCSI Initiator, RAID, SAS, FC, etc). o Shorten and simplify the common I/O path to improve driver performance. o Add RAID volume and RAID member state/settings reporting. o Add periodic volume resynchronization status reporting. o Add support for sysctl tunable resync rate, member write cache enable, and volume transaction queue depth. Sponsored by ---------------- Avid Technologies Inc: SCSI error recovery, driver re-organization, update of MPI library headers, portions of dynamic personality registration, and misc bug fixes. Wheel Open Technologies: RAID event notification, RAID member pass-thru support, firmware upload/download support, enhanced RAID resync speed, portions of dynamic personality registration, and misc bug fixes. Detailed Changes ================ mpt.c mpt_cam.c mpt_raid.c mpt_pci.c: o Add support for personality modules. Each module exports load, and unload module scope methods as well as probe, attach, event, reset, shutdown, and detach per-device instance methods mpt.c mpt.h mpt_pci.c: o The driver now associates a callback function (via an index) with every transaction submitted to the controller. This allows the main interrupt handler to absolve itself of any knowledge of individual transaction/response types by simply calling the callback function "registered" for the transaction. We use a callback index instead of a callback function pointer in each requests so we can properly handle responses (e.g. event notifications) that are not associated with a transaction. Personality modules dynamically register their callbacks with the driver core to receive the callback index to use for their handlers. o Move the interrupt handler into mpt.c. The ISR algorithm is bus transport and OS independent and thus had no reason to be in mpt_pci.c. o Simplify configuration message reply handling by copying reply frame data for the requester and storing completion status in the original request structure. o Add the mpt_complete_request_chain() helper method and use it to implement reset handlers that must abort transactions. o Keep track of all pending requests on the new requests_pending_list in the softc. o Add default handlers to mpt.c to handle generic event notifications and controller reset activities. The event handler code is largely the same as in the original driver. The reset handler is new and terminates any pending transactions with a status code indicating the controller needs to be re-initialized. o Add some endian support to the driver. A complete audit is still required for this driver to have any hope of operating in a big-endian environment. o Use inttypes.h and __inline. Come closer to being style(9) compliant. o Remove extraneous use of typedefs. o Convert request state from a strict enumeration to a series of flags. This allows us to, for example, tag transactions that have timed-out while retaining the state that the transaction is still in-flight on the controller. o Add mpt_wait_req() which allows a caller to poll or sleep for the completion of a request. Use this to simplify and factor code out from many initialization routines. We also use this to sleep for task management request completions in our CAM timeout handler. mpt.c: o Correct a bug in the event handler where request structures were freed even if the request reply was marked as a continuation reply. Continuation replies indicate that the controller still owns the request and freeing these replies prematurely corrupted controller state. o Implement firmware upload and download. On controllers that do not have dedicated NVRAM (as in the Sun v20/v40z), the firmware image is downloaded to the controller by the system BIOS. This image occupies precious controller RAM space until the host driver fetches the image, reducing the number of concurrent I/Os the controller can processes. The uploaded image is used to re-program the controller during hard reset events since the controller cannot fetch the firmware on its own. Implementing this feature allows much higher queue depths when RAID volumes are configured. o Changed configuration page accessors to allow threads to sleep rather than busy wait for completion. o Removed hard coded data transfer sizes from configuration page routines so that RAID configuration page processing is possible. mpt_reg.h: o Move controller register definitions into a separate file. mpt.h: o Re-arrange includes to allow inlined functions to be defined in mpt.h. o Add reply, event, and reset handler definitions. o Add softc fields for handling timeout and controller reset recovery. mpt_cam.c: o Move mpt_freebsd.c to mpt_cam.c. Move all core functionality, such as event handling, into mpt.c leaving only CAM SCSI support here. o Revamp completion handler to provide correct CAM status for all currently defined SCSI MPI message result codes. o Register event and reset handlers with the MPT core. Modify the event handler to notify CAM of bus reset events. The controller reset handler will abort any transactions that have timed out. All other pending CAM transactions are correctly aborted by the core driver's reset handler. o Allocate a single request up front to perform task management operations. This guarantees that we can always perform a TMF operation even when the controller is saturated with other operations. The single request also serves as a perfect mechanism of guaranteeing that only a single TMF is in flight at a time - something that is required according to the MPT Fusion documentation. o Add a helper function for issuing task management requests to the controller. This is used to abort individual requests or perform a bus reset. o Modify the CAM XPT_BUS_RESET ccb handler to wait for and properly handle the status of the bus reset task management frame used to reset the bus. The previous code assumed that the reset request would always succeed. o Add timeout recovery support. When a timeout occurs, the timed-out request is added to a queue to be processed by our recovery thread and the thread is woken up. The recovery thread processes timed-out command serially, attempting first to abort them and then falling back to a bus reset if an abort fails. o Add calls to mpt_reset() to reset the controller if any handshake command, bus reset attempt or abort attempt fails due to a timeout. o Export a secondary "bus" to CAM that exposes all volume drive members as pass-thru devices, allowing CAM to perform proper speed negotiation to hidden devices. o Add a CAM async event handler tracking the AC_FOUND_DEVICE event. Use this to trigger calls to set the per-volume queue depth once the volume is fully registered with CAM. This is required to avoid hitting firmware limits on volume queue depth. Exceeding the limit causes the firmware to hang. mpt_cam.h: o Add several helper functions for interfacing to CAM and performing timeout recovery. mpt_pci.c: o Disable interrupts on the controller before registering and enabling interrupt delivery to the OS. Otherwise we risk receiving interrupts before the driver is ready to receive them. o Make use of compatibility macros that allow the driver to be compiled under 4.x and 5.x. mpt_raid.c: o Add a per-controller instance RAID thread to perform settings changes and query status (minimizes CPU busy wait loops). o Use a shutdown handler to disable "Member Write Cache Enable" (MWCE) setting for RAID arrays set to enable MWCE During Rebuild. o Change reply handler function signature to allow handlers to defer the deletion of reply frames. Use this to allow the event reply handler to queue up events that need to be acked if no resources are available to immediately ack an event. Queued events are processed in mpt_free_request() where resources are freed. This avoids a panic on resource shortage. o Parse and print out RAID controller capabilities during driver probe. o Define, allocate, and maintain RAID data structures for volumes, hidden member physical disks and spare disks. o Add dynamic sysctls for per-instance setting of the log level, array resync rate, array member cache enable, and volume queue depth. mpt_debug.c: o Add mpt_lprt and mpt_lprtc for printing diagnostics conditioned on a particular log level to aid in tracking down driver issues. o Add mpt_decode_value() which parses the bits in an integer value based on a parsing table (mask, value, name string, tuples). mpilib/*: o Update mpi library header files to latest distribution from LSI. Submitted by: gibbs Approved by: re
2005-07-10 15:05:39 +00:00
}