Some fairly major changes to this driver.

A) Fibre Channel Target Mode support mostly works
(SAS/SPI won't be too far behind). I'd say that
this probably works just about as well as isp(4)
does right now. Still, it and isp(4) and the whole
target mode stack need a bit of tightening.

B) The startup sequence has been changed so that
after all attaches are done, a set of enable functions
are called. The idea here is that the attaches do
whatever needs to be done *prior* to a port being
enabled and the enables do what need to be done for
enabling stuff for a port after it's been enabled.

This means that we also have events handled by their
proper handlers as we start up.

C) Conditional code that means that this driver goes
back all the way to RELENG_4 in terms of support.

D) Quite a lot of little nitty bug fixes- some discovered
by doing RELENG_4 support. We've been living under Giant
*waaaayyyyy* too long and it's made some of us (me) sloppy.

E) Some shutdown hook stuff that makes sure we don't blow
up during a reboot (like by the arrival of a new command
from an initiator).

There's been some testing and LINT checking, but not as
complete as would be liked. Regression testing with Fusion
RAID instances has not been possible. Caveat Emptor.

Sponsored by: LSI-Logic.
This commit is contained in:
Matt Jacob 2006-03-25 07:08:27 +00:00
parent efe33769b9
commit c87e3f833c
Notes: svn2git 2020-12-20 02:59:44 +00:00
svn path=/head/; revision=157117
7 changed files with 3105 additions and 533 deletions

File diff suppressed because it is too large Load diff

View file

@ -121,6 +121,10 @@
#include <machine/cpu.h>
#include <machine/resource.h>
#if __FreeBSD_version < 500000
#include <machine/bus.h>
#endif
#include <sys/rman.h>
#if __FreeBSD_version < 500000
@ -153,6 +157,12 @@
#define NUM_ELEMENTS(array) (sizeof(array) / sizeof(*array))
#define MPT_ROLE_NONE 0
#define MPT_ROLE_INITIATOR 1
#define MPT_ROLE_TARGET 2
#define MPT_ROLE_BOTH 3
#define MPT_ROLE_DEFAULT MPT_ROLE_INITIATOR
/**************************** Forward Declarations ****************************/
struct mpt_softc;
struct mpt_personality;
@ -162,6 +172,7 @@ typedef struct req_entry request_t;
typedef int mpt_load_handler_t(struct mpt_personality *);
typedef int mpt_probe_handler_t(struct mpt_softc *);
typedef int mpt_attach_handler_t(struct mpt_softc *);
typedef int mpt_enable_handler_t(struct mpt_softc *);
typedef int mpt_event_handler_t(struct mpt_softc *, request_t *,
MSG_EVENT_NOTIFY_REPLY *);
typedef void mpt_reset_handler_t(struct mpt_softc *, int /*type*/);
@ -179,6 +190,7 @@ struct mpt_personality
#define MPT_PERS_FIRST_HANDLER(pers) (&(pers)->load)
mpt_probe_handler_t *probe; /* configure personailty */
mpt_attach_handler_t *attach; /* initialize device instance */
mpt_enable_handler_t *enable; /* enable device */
mpt_event_handler_t *event; /* Handle MPI event. */
mpt_reset_handler_t *reset; /* Re-init after reset. */
mpt_shutdown_handler_t *shutdown; /* Shutdown instance. */
@ -280,7 +292,7 @@ struct req_entry {
mpt_req_state_t state; /* Request State Information */
uint16_t index; /* Index of this entry */
uint16_t IOCStatus; /* Completion status */
uint32_t serno; /* serial number */
uint16_t serno; /* serial number */
union ccb *ccb; /* CAM request */
void *req_vbuf; /* Virtual Address of Entry */
void *sense_vbuf; /* Virtual Address of sense data */
@ -290,6 +302,59 @@ struct req_entry {
struct req_entry *chain; /* for SGE overallocations */
};
/**************************** MPI Target State Info ***************************/
typedef struct {
uint32_t reply_desc; /* current reply descriptor */
uint32_t resid; /* current data residual */
uint32_t bytes_xfered; /* current relative offset */
union ccb *ccb; /* pointer to currently active ccb */
request_t *req; /* pointer to currently active assist request */
int flags;
#define BOGUS_JO 0x01
int nxfers;
enum {
TGT_STATE_NIL,
TGT_STATE_LOADED,
TGT_STATE_IN_CAM,
TGT_STATE_SETTING_UP_FOR_DATA,
TGT_STATE_MOVING_DATA,
TGT_STATE_MOVING_DATA_AND_STATUS,
TGT_STATE_SENDING_STATUS
} state;
} mpt_tgt_state_t;
/*
* When we get an incoming command it has its own tag which is called the
* IoIndex. This is the value we gave that particular command buffer when
* we originally assigned it. It's just a number, really. The FC card uses
* it as an RX_ID. We can use it to index into mpt->tgt_cmd_ptrs, which
* contains pointers the request_t structures related to that IoIndex.
*
* What *we* do is construct a tag out of the index for the target command
* which owns the incoming ATIO plus a rolling sequence number.
*/
#define MPT_MAKE_TAGID(mpt, req, ioindex) \
((ioindex << 16) | (mpt->sequence++))
#ifdef INVARIANTS
#define MPT_TAG_2_REQ(a, b) mpt_tag_2_req(a, (uint32_t) b)
#else
#define MPT_TAG_2_REQ(mpt, tag) mpt->tgt_cmd_ptrs[tag >> 16]
#endif
#define MPT_TGT_STATE(mpt, req) ((mpt_tgt_state_t *) \
(&((uint8_t *)req->req_vbuf)[MPT_RQSL(mpt) - sizeof (mpt_tgt_state_t)]))
STAILQ_HEAD(mpt_hdr_stailq, ccb_hdr);
#define MPT_MAX_LUNS 256
typedef struct {
struct mpt_hdr_stailq atios;
struct mpt_hdr_stailq inots;
int enabled;
} tgt_resource_t;
#define MPT_MAX_ELS 8
/**************************** Handler Registration ****************************/
/*
* Global table of registered reply handlers. The
@ -311,12 +376,12 @@ struct req_entry {
* all commonly executed handlers fit in a single cache
* line.
*/
#define MPT_NUM_REPLY_HANDLERS (16)
#define MPT_NUM_REPLY_HANDLERS (32)
#define MPT_REPLY_HANDLER_EVENTS MPT_CBI_TO_HID(0)
#define MPT_REPLY_HANDLER_CONFIG MPT_CBI_TO_HID(MPT_NUM_REPLY_HANDLERS-1)
#define MPT_REPLY_HANDLER_HANDSHAKE MPT_CBI_TO_HID(MPT_NUM_REPLY_HANDLERS-2)
typedef int mpt_reply_handler_t(struct mpt_softc *mpt, request_t *request,
MSG_DEFAULT_REPLY *reply_frame);
uint32_t reply_desc, MSG_DEFAULT_REPLY *reply_frame);
typedef union {
mpt_reply_handler_t *reply_handler;
} mpt_handler_t;
@ -417,21 +482,24 @@ struct mpt_softc {
struct mtx mpt_lock;
#endif
uint32_t mpt_pers_mask;
uint32_t : 14,
is_sas : 1,
uint32_t : 8,
unit : 8,
: 1,
twildcard : 1,
tenabled : 1,
cap : 2, /* none, ini, target, both */
role : 2, /* none, ini, target, both */
raid_mwce_set : 1,
getreqwaiter : 1,
shutdwn_raid : 1,
shutdwn_recovery: 1,
unit : 8,
outofbeer : 1,
mpt_locksetup : 1,
disabled : 1,
is_fc : 1,
bus : 1; /* FC929/1030 have two busses */
is_sas : 1,
is_fc : 1;
u_int verbose;
uint32_t cmd_serno;
/*
* IOC Facts
@ -449,6 +517,7 @@ struct mpt_softc {
uint16_t mpt_ini_id;
uint16_t mpt_port_type;
uint16_t mpt_proto_flags;
uint16_t mpt_max_tgtcmds;
/*
* Device Configuration Information
@ -475,7 +544,8 @@ struct mpt_softc {
#define mpt_update_params0 cfg.spi._update_params0
#define mpt_update_params1 cfg.spi._update_params1
struct mpi_fc_cfg {
uint8_t nada;
CONFIG_PAGE_FC_PORT_0 _port_page0;
#define mpt_fcport_page0 cfg.fc._port_page0
} fc;
} cfg;
@ -528,7 +598,7 @@ struct mpt_softc {
bus_dma_tag_t request_dmat; /* DMA tag for request memroy */
bus_dmamap_t request_dmap; /* DMA map for request memroy */
uint8_t *request; /* KVA of Request memory */
bus_addr_t request_phys; /* BusADdr of request memory */
bus_addr_t request_phys; /* BusAddr of request memory */
uint32_t max_seg_cnt; /* calculated after IOC facts */
@ -560,9 +630,28 @@ struct mpt_softc {
struct proc *recovery_thread;
request_t *tmf_req;
uint32_t sequence; /* Sequence Number */
uint32_t timeouts; /* timeout count */
uint32_t success; /* successes afer timeout */
/*
* Target Mode Support
*/
uint32_t scsi_tgt_handler_id;
request_t ** tgt_cmd_ptrs;
/*
* *snork*- this is chosen to be here *just in case* somebody
* forgets to point to it exactly and we index off of trt with
* CAM_LUN_WILDCARD.
*/
tgt_resource_t trt_wildcard; /* wildcard luns */
tgt_resource_t trt[MPT_MAX_LUNS];
uint16_t tgt_cmds_allocated;
/*
* Stuff..
*/
uint16_t sequence; /* Sequence Number */
uint16_t timeouts; /* timeout count */
uint16_t success; /* successes afer timeout */
/* Opposing port in a 929 or 1030, or NULL */
struct mpt_softc * mpt2;
@ -580,7 +669,7 @@ struct mpt_softc {
TAILQ_ENTRY(mpt_softc) links;
};
/***************************** Locking Primatives *****************************/
/***************************** Locking Primitives *****************************/
#if __FreeBSD_version < 500000
#define MPT_IFLAGS INTR_TYPE_CAM
#define MPT_LOCK(mpt) mpt_lockspl(mpt)
@ -631,7 +720,7 @@ mpt_sleep(struct mpt_softc *mpt, void *ident, int priority,
saved_spl = mpt->mpt_splsaved;
mpt->mpt_islocked = 0;
error = tsleep(ident, priority, wmesg, timo);
KASSERT(mpt->mpt_islocked = 0, ("Invalid lock count on wakeup"));
KASSERT(mpt->mpt_islocked == 0, ("Invalid lock count on wakeup"));
mpt->mpt_islocked = saved_cnt;
mpt->mpt_splsaved = saved_spl;
return (error);
@ -709,19 +798,27 @@ mpt_pio_read(struct mpt_softc *mpt, int offset)
/* Max MPT Reply we are willing to accept (must be power of 2) */
#define MPT_REPLY_SIZE 256
/*
* Must be less than 16384 in order for target mode to work
*/
#define MPT_MAX_REQUESTS(mpt) 512
#define MPT_REQUEST_AREA 512
#define MPT_SENSE_SIZE 32 /* included in MPT_REQUEST_AREA */
#define MPT_REQ_MEM_SIZE(mpt) (MPT_MAX_REQUESTS(mpt) * MPT_REQUEST_AREA)
#define MPT_CONTEXT_CB_SHIFT (16)
#define MPT_CBI(handle) (handle >> MPT_CONTEXT_CB_SHIFT)
/*
* Currently we try to pack both callbacks and request indices into 14 bits
* so that we don't have to get fancy when we get a target mode context
* reply (which only has 14 bits of IoIndex value) or a normal scsi
* initiator context reply (where we get bits 28..0 of context).
*/
#define MPT_CONTEXT_CB_SHIFT (14)
#define MPT_CBI(handle) (handle >> MPT_CONTEXT_CB_SHIFT)
#define MPT_CBI_TO_HID(cbi) ((cbi) << MPT_CONTEXT_CB_SHIFT)
#define MPT_CONTEXT_TO_CBI(x) \
(((x) >> MPT_CONTEXT_CB_SHIFT) & (MPT_NUM_REPLY_HANDLERS - 1))
#define MPT_CONTEXT_REQI_MASK 0xFFFF
#define MPT_CONTEXT_TO_REQI(x) \
((x) & MPT_CONTEXT_REQI_MASK)
#define MPT_CONTEXT_REQI_MASK 0x3FFF
#define MPT_CONTEXT_TO_REQI(x) ((x) & MPT_CONTEXT_REQI_MASK)
/*
* Convert a 32bit physical address returned from IOC to an
@ -786,7 +883,7 @@ void mpt_complete_request_chain(struct mpt_softc *mpt,
/***************************** IOC Initialization *****************************/
int mpt_reset(struct mpt_softc *, int /*reinit*/);
/****************************** Debugging/Logging *****************************/
/****************************** Debugging ************************************/
typedef struct mpt_decode_entry {
char *name;
u_int value;
@ -804,10 +901,14 @@ enum {
MPT_PRT_WARN,
MPT_PRT_INFO,
MPT_PRT_DEBUG,
MPT_PRT_DEBUG1,
MPT_PRT_DEBUG2,
MPT_PRT_DEBUG3,
MPT_PRT_TRACE,
MPT_PRT_NONE=100
};
#if __FreeBSD_version > 500000
#define mpt_lprt(mpt, level, ...) \
do { \
if (level <= (mpt)->verbose) \
@ -819,9 +920,56 @@ do { \
if (level <= (mpt)->debug_level) \
mpt_prtc(mpt, __VA_ARGS__); \
} while (0)
#else
void mpt_lprt(struct mpt_softc *, int, const char *, ...)
__printflike(3, 4);
void mpt_lprtc(struct mpt_softc *, int, const char *, ...)
__printflike(3, 4);
#endif
void mpt_prt(struct mpt_softc *, const char *, ...)
__printflike(2, 3);
void mpt_prtc(struct mpt_softc *, const char *, ...)
__printflike(2, 3);
void mpt_prt(struct mpt_softc *, const char *, ...);
void mpt_prtc(struct mpt_softc *, const char *, ...);
/**************************** Target Mode Related ***************************/
static __inline int mpt_cdblen(uint8_t, int);
static __inline int
mpt_cdblen(uint8_t cdb0, int maxlen)
{
int group = cdb0 >> 5;
switch (group) {
case 0:
return (6);
case 1:
return (10);
case 4:
case 5:
return (12);
default:
return (16);
}
}
#ifdef INVARIANTS
static __inline request_t * mpt_tag_2_req(struct mpt_softc *, uint32_t);
static __inline request_t *
mpt_tag_2_req(struct mpt_softc *mpt, uint32_t tag)
{
uint16_t rtg = (tag >> 16);
KASSERT(rtg < mpt->tgt_cmds_allocated, ("bad tag %d\n", tag));
KASSERT(mpt->tgt_cmd_ptrs, ("no cmd backpointer array"));
KASSERT(mpt->tgt_cmd_ptrs[rtg], ("no cmd backpointer"));
return (mpt->tgt_cmd_ptrs[rtg]);
}
#endif
typedef enum {
MPT_ABORT_TASK_SET=1234,
MPT_CLEAR_TASK_SET,
MPT_TARGET_RESET,
MPT_CLEAR_ACA,
MPT_TERMINATE_TASK,
MPT_NIL_TMT_VALUE=5678
} mpt_task_mgmt_t;
/**************************** Unclassified Routines ***************************/
void mpt_send_cmd(struct mpt_softc *mpt, request_t *req);

File diff suppressed because it is too large Load diff

View file

@ -68,6 +68,7 @@ __FBSDID("$FreeBSD$");
#include <dev/mpt/mpilib/mpi_ioc.h>
#include <dev/mpt/mpilib/mpi_init.h>
#include <dev/mpt/mpilib/mpi_fc.h>
#include <dev/mpt/mpilib/mpi_targ.h>
#include <cam/scsi/scsi_all.h>
@ -574,6 +575,35 @@ mpt_print_scsi_tmf_request(MSG_SCSI_TASK_MGMT *msg)
printf("\tTaskMsgContext 0x%08x\n", msg->TaskMsgContext);
}
static void
mpt_print_scsi_target_assist_request(PTR_MSG_TARGET_ASSIST_REQUEST msg)
{
mpt_print_request_hdr((MSG_REQUEST_HEADER *)msg);
printf("\tStatusCode 0x%02x\n", msg->StatusCode);
printf("\tTargetAssist 0x%02x\n", msg->TargetAssistFlags);
printf("\tQueueTag 0x%04x\n", msg->QueueTag);
printf("\tReplyWord 0x%08x\n", msg->ReplyWord);
printf("\tLun 0x%02x\n", msg->LUN[1]);
printf("\tRelativeOff 0x%08x\n", msg->RelativeOffset);
printf("\tDataLength 0x%08x\n", msg->DataLength);
mpt_dump_sgl(msg->SGL, 0);
}
static void
mpt_print_scsi_target_status_send_request(MSG_TARGET_STATUS_SEND_REQUEST *msg)
{
SGE_IO_UNION x;
mpt_print_request_hdr((MSG_REQUEST_HEADER *)msg);
printf("\tStatusCode 0x%02x\n", msg->StatusCode);
printf("\tStatusFlags 0x%02x\n", msg->StatusFlags);
printf("\tQueueTag 0x%04x\n", msg->QueueTag);
printf("\tReplyWord 0x%08x\n", msg->ReplyWord);
printf("\tLun 0x%02x\n", msg->LUN[1]);
x.u.Simple = msg->StatusDataSGE;
mpt_dump_sgl(&x, 0);
}
void
mpt_print_request(void *vreq)
{
@ -585,6 +615,15 @@ mpt_print_request(void *vreq)
break;
case MPI_FUNCTION_SCSI_TASK_MGMT:
mpt_print_scsi_tmf_request((MSG_SCSI_TASK_MGMT *)req);
break;
case MPI_FUNCTION_TARGET_ASSIST:
mpt_print_scsi_target_assist_request(
(PTR_MSG_TARGET_ASSIST_REQUEST)req);
break;
case MPI_FUNCTION_TARGET_STATUS_SEND:
mpt_print_scsi_target_status_send_request(
(MSG_TARGET_STATUS_SEND_REQUEST *)req);
break;
default:
mpt_print_request_hdr(req);
break;
@ -754,6 +793,31 @@ mpt_dump_sgl(SGE_IO_UNION *su, int offset)
} while ((flags & MPI_SGE_FLAGS_END_OF_LIST) == 0 && nxtaddr < lim);
}
#if __FreeBSD_version < 500000
void
mpt_lprt(struct mpt_softc *mpt, int level, const char *fmt, ...)
{
va_list ap;
if (level <= mpt->verbose) {
printf("%s: ", device_get_nameunit(mpt->dev));
va_start(ap, fmt);
vprintf(fmt, ap);
va_end(ap);
}
}
void
mpt_lprtc(struct mpt_softc *mpt, int level, const char *fmt, ...)
{
va_list ap;
if (level <= mpt->verbose) {
va_start(ap, fmt);
vprintf(fmt, ap);
va_end(ap);
}
}
#endif
void
mpt_prt(struct mpt_softc *mpt, const char *fmt, ...)
{

View file

@ -242,7 +242,7 @@ mpt_pci_probe(device_t dev)
return (0);
}
#ifdef RELENG_4
#if __FreeBSD_version < 500000
static void
mpt_set_options(struct mpt_softc *mpt)
{
@ -261,7 +261,24 @@ mpt_set_options(struct mpt_softc *mpt)
mpt->verbose = MPT_PRT_DEBUG;
}
}
bitmap = 0;
if (getenv_int("mpt_target", &bitmap)) {
if (bitmap & (1 << mpt->unit)) {
mpt->role = MPT_ROLE_TARGET;
}
}
bitmap = 0;
if (getenv_int("mpt_none", &bitmap)) {
if (bitmap & (1 << mpt->unit)) {
mpt->role = MPT_ROLE_NONE;
}
}
bitmap = 0;
if (getenv_int("mpt_initiator", &bitmap)) {
if (bitmap & (1 << mpt->unit)) {
mpt->role = MPT_ROLE_INITIATOR;
}
}
}
#else
static void
@ -279,6 +296,12 @@ mpt_set_options(struct mpt_softc *mpt)
device_get_unit(mpt->dev), "debug", &tval) == 0 && tval != 0) {
mpt->verbose += tval;
}
tval = 0;
if (resource_int_value(device_get_name(mpt->dev),
device_get_unit(mpt->dev), "role", &tval) == 0 && tval != 0 &&
tval <= 3) {
mpt->role = tval;
}
}
#endif
@ -354,6 +377,7 @@ mpt_pci_attach(device_t dev)
mpt->raid_mwce_setting = MPT_RAID_MWCE_DEFAULT;
mpt->raid_queue_depth = MPT_RAID_QUEUE_DEPTH_DEFAULT;
mpt->verbose = MPT_PRT_NONE;
mpt->role = MPT_ROLE_DEFAULT;
mpt_set_options(mpt);
if (mpt->verbose == MPT_PRT_NONE) {
mpt->verbose = MPT_PRT_WARN;
@ -474,16 +498,44 @@ mpt_pci_attach(device_t dev)
*/
pci_disable_io(dev, SYS_RES_IOPORT);
switch (mpt->role) {
case MPT_ROLE_TARGET:
break;
case MPT_ROLE_INITIATOR:
break;
case MPT_ROLE_TARGET|MPT_ROLE_INITIATOR:
mpt->disabled = 1;
mpt_prt(mpt, "dual roles unsupported\n");
goto bad;
case MPT_ROLE_NONE:
device_printf(dev, "role of NONE same as disable\n");
mpt->disabled = 1;
goto bad;
}
/* Initialize the hardware */
if (mpt->disabled == 0) {
MPT_LOCK(mpt);
if (mpt_attach(mpt) != 0) {
MPT_UNLOCK(mpt);
goto bad;
}
MPT_UNLOCK(mpt);
} else {
mpt_prt(mpt, "device disabled at user request\n");
goto bad;
}
mpt->eh = EVENTHANDLER_REGISTER(shutdown_post_sync, mpt_pci_shutdown,
dev, SHUTDOWN_PRI_DEFAULT);
if (mpt->eh == NULL) {
mpt_prt(mpt, "shutdown event registration failed\n");
MPT_LOCK(mpt);
(void) mpt_detach(mpt);
MPT_UNLOCK(mpt);
goto bad;
}
return (0);
bad:
@ -535,24 +587,23 @@ mpt_pci_detach(device_t dev)
struct mpt_softc *mpt;
mpt = (struct mpt_softc*)device_get_softc(dev);
mpt_prt(mpt, "mpt_detach\n");
if (mpt) {
MPT_LOCK(mpt);
mpt_disable_ints(mpt);
mpt_detach(mpt);
mpt_reset(mpt, /*reinit*/FALSE);
mpt_dma_mem_free(mpt);
mpt_free_bus_resources(mpt);
if (mpt->raid_volumes != NULL
&& mpt->ioc_page2 != NULL) {
if (mpt->raid_volumes != NULL && mpt->ioc_page2 != NULL) {
int i;
for (i = 0; i < mpt->ioc_page2->MaxVolumes; i++) {
struct mpt_raid_volume *mpt_vol;
mpt_vol = &mpt->raid_volumes[i];
if (mpt_vol->config_page)
if (mpt_vol->config_page) {
free(mpt_vol->config_page, M_DEVBUF);
}
}
}
if (mpt->ioc_page2 != NULL)
@ -565,6 +616,7 @@ mpt_pci_detach(device_t dev)
free(mpt->raid_disks, M_DEVBUF);
if (mpt->eh != NULL)
EVENTHANDLER_DEREGISTER(shutdown_final, mpt->eh);
MPT_UNLOCK(mpt);
}
return(0);
}
@ -572,7 +624,6 @@ mpt_pci_detach(device_t dev)
/*
* Disable the hardware
* XXX - Called too early by New Bus!!! ???
*/
static int
mpt_pci_shutdown(device_t dev)
@ -580,8 +631,13 @@ mpt_pci_shutdown(device_t dev)
struct mpt_softc *mpt;
mpt = (struct mpt_softc *)device_get_softc(dev);
if (mpt)
return (mpt_shutdown(mpt));
if (mpt) {
int r;
MPT_LOCK(mpt);
r = mpt_shutdown(mpt);
MPT_UNLOCK(mpt);
return (r);
}
return(0);
}

View file

@ -46,6 +46,10 @@ __FBSDID("$FreeBSD$");
#include <cam/cam_sim.h>
#include <cam/cam_xpt_sim.h>
#if __FreeBSD_version < 500000
#include <sys/devicestat.h>
#define GIANT_REQUIRED
#endif
#include <cam/cam_periph.h>
#include <sys/callout.h>
@ -241,9 +245,9 @@ mpt_raid_async(void *callback_arg, u_int32_t code,
int
mpt_raid_probe(struct mpt_softc *mpt)
{
if (mpt->ioc_page2 == NULL
|| mpt->ioc_page2->MaxPhysDisks == 0)
if (mpt->ioc_page2 == NULL || mpt->ioc_page2->MaxPhysDisks == 0) {
return (ENODEV);
}
return (0);
}
@ -446,8 +450,10 @@ mpt_raid_event(struct mpt_softc *mpt, request_t *req,
if (mpt_disk != NULL)
mpt_disk_prt(mpt, mpt_disk, "");
else
mpt_prt(mpt, "Volume(%d:%d:%d: ");
mpt_prtc(mpt, "ASC 0x%x, ASCQ 0x%x\n",
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",
raid_event->ASC, raid_event->ASCQ);
}
@ -460,19 +466,19 @@ mpt_raid_shutdown(struct mpt_softc *mpt)
{
struct mpt_raid_volume *mpt_vol;
if (mpt->raid_mwce_setting != MPT_RAID_MWCE_REBUILD_ONLY)
if (mpt->raid_mwce_setting != MPT_RAID_MWCE_REBUILD_ONLY) {
return;
}
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,
MSG_DEFAULT_REPLY *reply_frame)
uint32_t reply_desc, MSG_DEFAULT_REPLY *reply_frame)
{
int free_req;
@ -607,16 +613,11 @@ mpt_spawn_raid_thread(struct mpt_softc *mpt)
return (error);
}
/*
* Lock is not held on entry.
*/
static void
mpt_terminate_raid_thread(struct mpt_softc *mpt)
{
MPT_LOCK(mpt);
if (mpt->raid_thread == NULL) {
MPT_UNLOCK(mpt);
return;
}
mpt->shutdwn_raid = 1;
@ -626,7 +627,6 @@ mpt_terminate_raid_thread(struct mpt_softc *mpt)
* for this interlock just for added safety.
*/
mpt_sleep(mpt, &mpt->raid_thread, PUSER, "thtrm", 0);
MPT_UNLOCK(mpt);
}
static void
@ -845,10 +845,9 @@ mpt_verify_mwce(struct mpt_softc *mpt, struct mpt_raid_volume *mpt_vol)
*/
switch (mpt->raid_mwce_setting) {
case MPT_RAID_MWCE_REBUILD_ONLY:
if ((resyncing && mwce)
|| (!resyncing && !mwce))
if ((resyncing && mwce) || (!resyncing && !mwce)) {
return;
}
mpt_vol->flags ^= MPT_RVF_WCE_CHANGED;
if ((mpt_vol->flags & MPT_RVF_WCE_CHANGED) == 0) {
/*
@ -903,7 +902,6 @@ mpt_verify_mwce(struct mpt_softc *mpt, struct mpt_raid_volume *mpt_vol)
vol_pg->VolumeSettings.Settings ^=
MPI_RAIDVOL0_SETTING_WRITE_CACHING_ENABLE;
}
mpt_free_request(mpt, req);
}
@ -1228,18 +1226,21 @@ mpt_refresh_raid_data(struct mpt_softc *mpt)
int i;
u_int nonopt_volumes;
if (mpt->ioc_page2 == NULL || mpt->ioc_page3 == NULL)
if (mpt->ioc_page2 == NULL || mpt->ioc_page3 == NULL) {
return;
}
/*
* Mark all items as unreferrened by the configuration.
* Mark all items as unreferenced by the configuration.
* This allows us to find, report, and discard stale
* entries.
*/
for (i = 0; i < mpt->ioc_page2->MaxPhysDisks; i++)
for (i = 0; i < mpt->ioc_page2->MaxPhysDisks; i++) {
mpt->raid_disks[i].flags &= ~MPT_RDF_REFERENCED;
for (i = 0; i < mpt->ioc_page2->MaxVolumes; i++)
}
for (i = 0; i < mpt->ioc_page2->MaxVolumes; i++) {
mpt->raid_volumes[i].flags &= ~MPT_RVF_REFERENCED;
}
/*
* Get Physical Disk information.
@ -1386,9 +1387,15 @@ mpt_refresh_raid_data(struct mpt_softc *mpt)
mpt_vol_prt(mpt, mpt_vol, "%s Priority Re-Sync\n",
prio ? "High" : "Low");
}
#if __FreeBSD_version >= 500000
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
/* Periodically report on sync progress. */
mpt_schedule_raid_refresh(mpt);
@ -1484,8 +1491,9 @@ mpt_raid_set_vol_resync_rate(struct mpt_softc *mpt, u_int rate)
MPT_LOCK(mpt);
mpt->raid_resync_rate = rate;
RAID_VOL_FOREACH(mpt, mpt_vol) {
if ((mpt_vol->flags & MPT_RVF_ACTIVE) == 0)
if ((mpt_vol->flags & MPT_RVF_ACTIVE) == 0) {
continue;
}
mpt_verify_resync_rate(mpt, mpt_vol);
}
MPT_UNLOCK(mpt);
@ -1497,8 +1505,7 @@ 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)
if (vol_queue_depth > 255 || vol_queue_depth < 1)
return (EINVAL);
MPT_LOCK(mpt);
@ -1662,6 +1669,7 @@ mpt_raid_sysctl_vol_queue_depth(SYSCTL_HANDLER_ARGS)
static void
mpt_raid_sysctl_attach(struct mpt_softc *mpt)
{
#if __FreeBSD_version >= 500000
struct sysctl_ctx_list *ctx = device_get_sysctl_ctx(mpt->dev);
struct sysctl_oid *tree = device_get_sysctl_tree(mpt->dev);
@ -1683,4 +1691,5 @@ mpt_raid_sysctl_attach(struct mpt_softc *mpt)
"nonoptimal_volumes", CTLFLAG_RD,
&mpt->raid_nonopt_volumes, 0,
"number of nonoptimal volumes");
#endif
}

View file

@ -125,7 +125,7 @@ enum _MPT_INTR_REQ_BITS {
#define MPT_DB_INTR(v) (((v) & MPT_INTR_DB_READY) != 0)
#define MPT_REPLY_INTR(v) (((v) & MPT_INTR_REPLY_READY) != 0)
/* Function Maps for INTERRUPT make register */
/* Function Maps for INTERRUPT mask register */
enum _MPT_INTR_MASK_BITS {
MPT_INTR_REPLY_MASK = 0x00000008,
MPT_INTR_DB_MASK = 0x00000001