Merge git://git.kernel.org/pub/scm/linux/kernel/git/jejb/scsi-misc-2.6

* git://git.kernel.org/pub/scm/linux/kernel/git/jejb/scsi-misc-2.6: (182 commits)
  [SCSI] aacraid: add an ifdef'd device delete case instead of taking the device offline
  [SCSI] aacraid: prohibit access to array container space
  [SCSI] aacraid: add support for handling ATA pass-through commands.
  [SCSI] aacraid: expose physical devices for models with newer firmware
  [SCSI] aacraid: respond automatically to volumes added by config tool
  [SCSI] fcoe: fix fcoe module ref counting
  [SCSI] libfcoe: FIP Keep-Alive messages for VPorts are sent with incorrect port_id and wwn
  [SCSI] libfcoe: Fix incorrect MAC address clearing
  [SCSI] fcoe: fix a circular locking issue with rtnl and sysfs mutex
  [SCSI] libfc: Move the port_id into lport
  [SCSI] fcoe: move link speed checking into its own routine
  [SCSI] libfc: Remove extra pointer check
  [SCSI] libfc: Remove unused fc_get_host_port_type
  [SCSI] fcoe: fixes wrong error exit in fcoe_create
  [SCSI] libfc: set seq_id for incoming sequence
  [SCSI] qla2xxx: Updates to ISP82xx support.
  [SCSI] qla2xxx: Optionally disable target reset.
  [SCSI] qla2xxx: ensure flash operation and host reset via sg_reset are mutually exclusive
  [SCSI] qla2xxx: Silence bogus warning by gcc for wrap and did.
  [SCSI] qla2xxx: T10 DIF support added.
  ...
This commit is contained in:
Linus Torvalds 2010-05-21 07:19:18 -07:00
commit 33cf23b0a5
161 changed files with 15301 additions and 4149 deletions

View file

@ -5064,7 +5064,7 @@ mptbase_sas_persist_operation(MPT_ADAPTER *ioc, u8 persist_opcode)
if (!timeleft) {
printk(KERN_DEBUG "%s: Issuing Reset from %s!!\n",
ioc->name, __func__);
mpt_HardResetHandler(ioc, CAN_SLEEP);
mpt_Soft_Hard_ResetHandler(ioc, CAN_SLEEP);
mpt_free_msg_frame(ioc, mf);
}
goto out;
@ -6456,10 +6456,15 @@ out:
issue_hard_reset = 0;
printk(MYIOC_s_WARN_FMT "Issuing Reset from %s!!\n",
ioc->name, __func__);
mpt_HardResetHandler(ioc, CAN_SLEEP);
if (retry_count == 0) {
if (mpt_Soft_Hard_ResetHandler(ioc, CAN_SLEEP) != 0)
retry_count++;
} else
mpt_HardResetHandler(ioc, CAN_SLEEP);
mpt_free_msg_frame(ioc, mf);
/* attempt one retry for a timed out command */
if (!retry_count) {
if (retry_count < 2) {
printk(MYIOC_s_INFO_FMT
"Attempting Retry Config request"
" type 0x%x, page 0x%x,"
@ -6904,6 +6909,172 @@ mpt_halt_firmware(MPT_ADAPTER *ioc)
}
EXPORT_SYMBOL(mpt_halt_firmware);
/**
* mpt_SoftResetHandler - Issues a less expensive reset
* @ioc: Pointer to MPT_ADAPTER structure
* @sleepFlag: Indicates if sleep or schedule must be called.
*
* Returns 0 for SUCCESS or -1 if FAILED.
*
* Message Unit Reset - instructs the IOC to reset the Reply Post and
* Free FIFO's. All the Message Frames on Reply Free FIFO are discarded.
* All posted buffers are freed, and event notification is turned off.
* IOC doesnt reply to any outstanding request. This will transfer IOC
* to READY state.
**/
int
mpt_SoftResetHandler(MPT_ADAPTER *ioc, int sleepFlag)
{
int rc;
int ii;
u8 cb_idx;
unsigned long flags;
u32 ioc_state;
unsigned long time_count;
dtmprintk(ioc, printk(MYIOC_s_DEBUG_FMT "SoftResetHandler Entered!\n",
ioc->name));
ioc_state = mpt_GetIocState(ioc, 0) & MPI_IOC_STATE_MASK;
if (mpt_fwfault_debug)
mpt_halt_firmware(ioc);
if (ioc_state == MPI_IOC_STATE_FAULT ||
ioc_state == MPI_IOC_STATE_RESET) {
dtmprintk(ioc, printk(MYIOC_s_DEBUG_FMT
"skipping, either in FAULT or RESET state!\n", ioc->name));
return -1;
}
if (ioc->bus_type == FC) {
dtmprintk(ioc, printk(MYIOC_s_DEBUG_FMT
"skipping, because the bus type is FC!\n", ioc->name));
return -1;
}
spin_lock_irqsave(&ioc->taskmgmt_lock, flags);
if (ioc->ioc_reset_in_progress) {
spin_unlock_irqrestore(&ioc->taskmgmt_lock, flags);
return -1;
}
ioc->ioc_reset_in_progress = 1;
spin_unlock_irqrestore(&ioc->taskmgmt_lock, flags);
rc = -1;
for (cb_idx = MPT_MAX_PROTOCOL_DRIVERS-1; cb_idx; cb_idx--) {
if (MptResetHandlers[cb_idx])
mpt_signal_reset(cb_idx, ioc, MPT_IOC_SETUP_RESET);
}
spin_lock_irqsave(&ioc->taskmgmt_lock, flags);
if (ioc->taskmgmt_in_progress) {
spin_unlock_irqrestore(&ioc->taskmgmt_lock, flags);
return -1;
}
spin_unlock_irqrestore(&ioc->taskmgmt_lock, flags);
/* Disable reply interrupts (also blocks FreeQ) */
CHIPREG_WRITE32(&ioc->chip->IntMask, 0xFFFFFFFF);
ioc->active = 0;
time_count = jiffies;
rc = SendIocReset(ioc, MPI_FUNCTION_IOC_MESSAGE_UNIT_RESET, sleepFlag);
for (cb_idx = MPT_MAX_PROTOCOL_DRIVERS-1; cb_idx; cb_idx--) {
if (MptResetHandlers[cb_idx])
mpt_signal_reset(cb_idx, ioc, MPT_IOC_PRE_RESET);
}
if (rc)
goto out;
ioc_state = mpt_GetIocState(ioc, 0) & MPI_IOC_STATE_MASK;
if (ioc_state != MPI_IOC_STATE_READY)
goto out;
for (ii = 0; ii < 5; ii++) {
/* Get IOC facts! Allow 5 retries */
rc = GetIocFacts(ioc, sleepFlag,
MPT_HOSTEVENT_IOC_RECOVER);
if (rc == 0)
break;
if (sleepFlag == CAN_SLEEP)
msleep(100);
else
mdelay(100);
}
if (ii == 5)
goto out;
rc = PrimeIocFifos(ioc);
if (rc != 0)
goto out;
rc = SendIocInit(ioc, sleepFlag);
if (rc != 0)
goto out;
rc = SendEventNotification(ioc, 1, sleepFlag);
if (rc != 0)
goto out;
if (ioc->hard_resets < -1)
ioc->hard_resets++;
/*
* At this point, we know soft reset succeeded.
*/
ioc->active = 1;
CHIPREG_WRITE32(&ioc->chip->IntMask, MPI_HIM_DIM);
out:
spin_lock_irqsave(&ioc->taskmgmt_lock, flags);
ioc->ioc_reset_in_progress = 0;
ioc->taskmgmt_quiesce_io = 0;
ioc->taskmgmt_in_progress = 0;
spin_unlock_irqrestore(&ioc->taskmgmt_lock, flags);
if (ioc->active) { /* otherwise, hard reset coming */
for (cb_idx = MPT_MAX_PROTOCOL_DRIVERS-1; cb_idx; cb_idx--) {
if (MptResetHandlers[cb_idx])
mpt_signal_reset(cb_idx, ioc,
MPT_IOC_POST_RESET);
}
}
dtmprintk(ioc, printk(MYIOC_s_DEBUG_FMT
"SoftResetHandler: completed (%d seconds): %s\n",
ioc->name, jiffies_to_msecs(jiffies - time_count)/1000,
((rc == 0) ? "SUCCESS" : "FAILED")));
return rc;
}
/**
* mpt_Soft_Hard_ResetHandler - Try less expensive reset
* @ioc: Pointer to MPT_ADAPTER structure
* @sleepFlag: Indicates if sleep or schedule must be called.
*
* Returns 0 for SUCCESS or -1 if FAILED.
* Try for softreset first, only if it fails go for expensive
* HardReset.
**/
int
mpt_Soft_Hard_ResetHandler(MPT_ADAPTER *ioc, int sleepFlag) {
int ret = -1;
ret = mpt_SoftResetHandler(ioc, sleepFlag);
if (ret == 0)
return ret;
ret = mpt_HardResetHandler(ioc, sleepFlag);
return ret;
}
EXPORT_SYMBOL(mpt_Soft_Hard_ResetHandler);
/*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
/*
* Reset Handling

View file

@ -76,8 +76,8 @@
#define COPYRIGHT "Copyright (c) 1999-2008 " MODULEAUTHOR
#endif
#define MPT_LINUX_VERSION_COMMON "3.04.14"
#define MPT_LINUX_PACKAGE_NAME "@(#)mptlinux-3.04.14"
#define MPT_LINUX_VERSION_COMMON "3.04.15"
#define MPT_LINUX_PACKAGE_NAME "@(#)mptlinux-3.04.15"
#define WHAT_MAGIC_STRING "@" "(" "#" ")"
#define show_mptmod_ver(s,ver) \
@ -940,6 +940,7 @@ extern int mpt_verify_adapter(int iocid, MPT_ADAPTER **iocpp);
extern u32 mpt_GetIocState(MPT_ADAPTER *ioc, int cooked);
extern void mpt_print_ioc_summary(MPT_ADAPTER *ioc, char *buf, int *size, int len, int showlan);
extern int mpt_HardResetHandler(MPT_ADAPTER *ioc, int sleepFlag);
extern int mpt_Soft_Hard_ResetHandler(MPT_ADAPTER *ioc, int sleepFlag);
extern int mpt_config(MPT_ADAPTER *ioc, CONFIGPARMS *cfg);
extern int mpt_alloc_fw_memory(MPT_ADAPTER *ioc, int size);
extern void mpt_free_fw_memory(MPT_ADAPTER *ioc);

View file

@ -128,7 +128,6 @@ static MptSge_t *kbuf_alloc_2_sgl(int bytes, u32 dir, int sge_offset, int *frags
struct buflist **blp, dma_addr_t *sglbuf_dma, MPT_ADAPTER *ioc);
static void kfree_sgl(MptSge_t *sgl, dma_addr_t sgl_dma,
struct buflist *buflist, MPT_ADAPTER *ioc);
static int mptctl_bus_reset(MPT_ADAPTER *ioc, u8 function);
/*
* Reset Handler cleanup function
@ -275,45 +274,6 @@ mptctl_reply(MPT_ADAPTER *ioc, MPT_FRAME_HDR *req, MPT_FRAME_HDR *reply)
return 1;
}
/*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
/* mptctl_timeout_expired
*
* Expecting an interrupt, however timed out.
*
*/
static void
mptctl_timeout_expired(MPT_ADAPTER *ioc, MPT_FRAME_HDR *mf)
{
unsigned long flags;
dtmprintk(ioc, printk(MYIOC_s_DEBUG_FMT ": %s\n",
ioc->name, __func__));
if (mpt_fwfault_debug)
mpt_halt_firmware(ioc);
spin_lock_irqsave(&ioc->taskmgmt_lock, flags);
if (ioc->ioc_reset_in_progress) {
spin_unlock_irqrestore(&ioc->taskmgmt_lock, flags);
CLEAR_MGMT_PENDING_STATUS(ioc->ioctl_cmds.status)
mpt_free_msg_frame(ioc, mf);
return;
}
spin_unlock_irqrestore(&ioc->taskmgmt_lock, flags);
if (!mptctl_bus_reset(ioc, mf->u.hdr.Function))
return;
/* Issue a reset for this device.
* The IOC is not responding.
*/
dtmprintk(ioc, printk(MYIOC_s_DEBUG_FMT "Calling HardReset! \n",
ioc->name));
CLEAR_MGMT_PENDING_STATUS(ioc->ioctl_cmds.status)
mpt_HardResetHandler(ioc, CAN_SLEEP);
mpt_free_msg_frame(ioc, mf);
}
static int
mptctl_taskmgmt_reply(MPT_ADAPTER *ioc, MPT_FRAME_HDR *mf, MPT_FRAME_HDR *mr)
@ -343,12 +303,8 @@ mptctl_taskmgmt_reply(MPT_ADAPTER *ioc, MPT_FRAME_HDR *mf, MPT_FRAME_HDR *mr)
return 0;
}
/* mptctl_bus_reset
*
* Bus reset code.
*
*/
static int mptctl_bus_reset(MPT_ADAPTER *ioc, u8 function)
static int
mptctl_do_taskmgmt(MPT_ADAPTER *ioc, u8 tm_type, u8 bus_id, u8 target_id)
{
MPT_FRAME_HDR *mf;
SCSITaskMgmt_t *pScsiTm;
@ -359,13 +315,6 @@ static int mptctl_bus_reset(MPT_ADAPTER *ioc, u8 function)
unsigned long time_count;
u16 iocstatus;
/* bus reset is only good for SCSI IO, RAID PASSTHRU */
if (!(function == MPI_FUNCTION_RAID_SCSI_IO_PASSTHROUGH ||
function == MPI_FUNCTION_SCSI_IO_REQUEST)) {
dtmprintk(ioc, printk(MYIOC_s_WARN_FMT
"TaskMgmt, not SCSI_IO!!\n", ioc->name));
return -EPERM;
}
mutex_lock(&ioc->taskmgmt_cmds.mutex);
if (mpt_set_taskmgmt_in_progress_flag(ioc) != 0) {
@ -375,15 +324,14 @@ static int mptctl_bus_reset(MPT_ADAPTER *ioc, u8 function)
retval = 0;
/* Send request
*/
mf = mpt_get_msg_frame(mptctl_taskmgmt_id, ioc);
if (mf == NULL) {
dtmprintk(ioc, printk(MYIOC_s_WARN_FMT
"TaskMgmt, no msg frames!!\n", ioc->name));
dtmprintk(ioc,
printk(MYIOC_s_WARN_FMT "TaskMgmt, no msg frames!!\n",
ioc->name));
mpt_clear_taskmgmt_in_progress_flag(ioc);
retval = -ENOMEM;
goto mptctl_bus_reset_done;
goto tm_done;
}
dtmprintk(ioc, printk(MYIOC_s_DEBUG_FMT "TaskMgmt request (mf=%p)\n",
@ -392,10 +340,13 @@ static int mptctl_bus_reset(MPT_ADAPTER *ioc, u8 function)
pScsiTm = (SCSITaskMgmt_t *) mf;
memset(pScsiTm, 0, sizeof(SCSITaskMgmt_t));
pScsiTm->Function = MPI_FUNCTION_SCSI_TASK_MGMT;
pScsiTm->TaskType = MPI_SCSITASKMGMT_TASKTYPE_RESET_BUS;
pScsiTm->MsgFlags = MPI_SCSITASKMGMT_MSGFLAGS_LIPRESET_RESET_OPTION;
pScsiTm->TargetID = 0;
pScsiTm->Bus = 0;
pScsiTm->TaskType = tm_type;
if ((tm_type == MPI_SCSITASKMGMT_TASKTYPE_RESET_BUS) &&
(ioc->bus_type == FC))
pScsiTm->MsgFlags =
MPI_SCSITASKMGMT_MSGFLAGS_LIPRESET_RESET_OPTION;
pScsiTm->TargetID = target_id;
pScsiTm->Bus = bus_id;
pScsiTm->ChainOffset = 0;
pScsiTm->Reserved = 0;
pScsiTm->Reserved1 = 0;
@ -413,17 +364,16 @@ static int mptctl_bus_reset(MPT_ADAPTER *ioc, u8 function)
timeout = 30;
break;
case SPI:
default:
timeout = 2;
default:
timeout = 10;
break;
}
dtmprintk(ioc, printk(MYIOC_s_DEBUG_FMT
"TaskMgmt type=%d timeout=%ld\n",
ioc->name, MPI_SCSITASKMGMT_TASKTYPE_RESET_BUS, timeout));
dtmprintk(ioc,
printk(MYIOC_s_DEBUG_FMT "TaskMgmt type=%d timeout=%ld\n",
ioc->name, tm_type, timeout));
INITIALIZE_MGMT_STATUS(ioc->taskmgmt_cmds.status)
CLEAR_MGMT_STATUS(ioc->taskmgmt_cmds.status)
time_count = jiffies;
if ((ioc->facts.IOCCapabilities & MPI_IOCFACTS_CAPABILITY_HIGH_PRI_Q) &&
(ioc->facts.MsgVersion >= MPI_VERSION_01_05))
@ -432,17 +382,20 @@ static int mptctl_bus_reset(MPT_ADAPTER *ioc, u8 function)
retval = mpt_send_handshake_request(mptctl_taskmgmt_id, ioc,
sizeof(SCSITaskMgmt_t), (u32 *)pScsiTm, CAN_SLEEP);
if (retval != 0) {
dfailprintk(ioc, printk(MYIOC_s_ERR_FMT
dfailprintk(ioc,
printk(MYIOC_s_ERR_FMT
"TaskMgmt send_handshake FAILED!"
" (ioc %p, mf %p, rc=%d) \n", ioc->name,
ioc, mf, retval));
mpt_free_msg_frame(ioc, mf);
mpt_clear_taskmgmt_in_progress_flag(ioc);
goto mptctl_bus_reset_done;
goto tm_done;
}
}
/* Now wait for the command to complete */
ii = wait_for_completion_timeout(&ioc->taskmgmt_cmds.done, timeout*HZ);
if (!(ioc->taskmgmt_cmds.status & MPT_MGMT_STATUS_COMMAND_GOOD)) {
dtmprintk(ioc, printk(MYIOC_s_DEBUG_FMT
"TaskMgmt failed\n", ioc->name));
@ -452,14 +405,14 @@ static int mptctl_bus_reset(MPT_ADAPTER *ioc, u8 function)
retval = 0;
else
retval = -1; /* return failure */
goto mptctl_bus_reset_done;
goto tm_done;
}
if (!(ioc->taskmgmt_cmds.status & MPT_MGMT_STATUS_RF_VALID)) {
dtmprintk(ioc, printk(MYIOC_s_DEBUG_FMT
"TaskMgmt failed\n", ioc->name));
retval = -1; /* return failure */
goto mptctl_bus_reset_done;
goto tm_done;
}
pScsiTmReply = (SCSITaskMgmtReply_t *) ioc->taskmgmt_cmds.reply;
@ -467,7 +420,7 @@ static int mptctl_bus_reset(MPT_ADAPTER *ioc, u8 function)
"TaskMgmt fw_channel = %d, fw_id = %d, task_type=0x%02X, "
"iocstatus=0x%04X\n\tloginfo=0x%08X, response_code=0x%02X, "
"term_cmnds=%d\n", ioc->name, pScsiTmReply->Bus,
pScsiTmReply->TargetID, MPI_SCSITASKMGMT_TASKTYPE_RESET_BUS,
pScsiTmReply->TargetID, tm_type,
le16_to_cpu(pScsiTmReply->IOCStatus),
le32_to_cpu(pScsiTmReply->IOCLogInfo),
pScsiTmReply->ResponseCode,
@ -485,13 +438,71 @@ static int mptctl_bus_reset(MPT_ADAPTER *ioc, u8 function)
retval = -1; /* return failure */
}
mptctl_bus_reset_done:
tm_done:
mutex_unlock(&ioc->taskmgmt_cmds.mutex);
CLEAR_MGMT_STATUS(ioc->taskmgmt_cmds.status)
return retval;
}
/*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
/* mptctl_timeout_expired
*
* Expecting an interrupt, however timed out.
*
*/
static void
mptctl_timeout_expired(MPT_ADAPTER *ioc, MPT_FRAME_HDR *mf)
{
unsigned long flags;
int ret_val = -1;
SCSIIORequest_t *scsi_req = (SCSIIORequest_t *) mf;
u8 function = mf->u.hdr.Function;
dtmprintk(ioc, printk(MYIOC_s_DEBUG_FMT ": %s\n",
ioc->name, __func__));
if (mpt_fwfault_debug)
mpt_halt_firmware(ioc);
spin_lock_irqsave(&ioc->taskmgmt_lock, flags);
if (ioc->ioc_reset_in_progress) {
spin_unlock_irqrestore(&ioc->taskmgmt_lock, flags);
CLEAR_MGMT_PENDING_STATUS(ioc->ioctl_cmds.status)
mpt_free_msg_frame(ioc, mf);
return;
}
spin_unlock_irqrestore(&ioc->taskmgmt_lock, flags);
CLEAR_MGMT_PENDING_STATUS(ioc->ioctl_cmds.status)
if (ioc->bus_type == SAS) {
if (function == MPI_FUNCTION_SCSI_IO_REQUEST)
ret_val = mptctl_do_taskmgmt(ioc,
MPI_SCSITASKMGMT_TASKTYPE_TARGET_RESET,
scsi_req->Bus, scsi_req->TargetID);
else if (function == MPI_FUNCTION_RAID_SCSI_IO_PASSTHROUGH)
ret_val = mptctl_do_taskmgmt(ioc,
MPI_SCSITASKMGMT_TASKTYPE_RESET_BUS,
scsi_req->Bus, 0);
if (!ret_val)
return;
} else {
if ((function == MPI_FUNCTION_SCSI_IO_REQUEST) ||
(function == MPI_FUNCTION_RAID_SCSI_IO_PASSTHROUGH))
ret_val = mptctl_do_taskmgmt(ioc,
MPI_SCSITASKMGMT_TASKTYPE_RESET_BUS,
scsi_req->Bus, 0);
if (!ret_val)
return;
}
dtmprintk(ioc, printk(MYIOC_s_DEBUG_FMT "Calling Reset! \n",
ioc->name));
mpt_Soft_Hard_ResetHandler(ioc, CAN_SLEEP);
mpt_free_msg_frame(ioc, mf);
}
/*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
/* mptctl_ioc_reset
@ -1318,6 +1329,8 @@ mptctl_getiocinfo (unsigned long arg, unsigned int data_size)
if (ioc->sh) {
shost_for_each_device(sdev, ioc->sh) {
vdevice = sdev->hostdata;
if (vdevice == NULL || vdevice->vtarget == NULL)
continue;
if (vdevice->vtarget->tflags &
MPT_TARGET_FLAGS_RAID_COMPONENT)
continue;
@ -1439,6 +1452,8 @@ mptctl_gettargetinfo (unsigned long arg)
if (!maxWordsLeft)
continue;
vdevice = sdev->hostdata;
if (vdevice == NULL || vdevice->vtarget == NULL)
continue;
if (vdevice->vtarget->tflags &
MPT_TARGET_FLAGS_RAID_COMPONENT)
continue;
@ -1967,6 +1982,9 @@ mptctl_do_mpt_command (struct mpt_ioctl_command karg, void __user *mfPtr)
struct scsi_target *starget = scsi_target(sdev);
VirtTarget *vtarget = starget->hostdata;
if (vtarget == NULL)
continue;
if ((pScsiReq->TargetID == vtarget->id) &&
(pScsiReq->Bus == vtarget->channel) &&
(vtarget->tflags & MPT_TARGET_FLAGS_Q_YES))
@ -2991,6 +3009,14 @@ static int __init mptctl_init(void)
}
mptctl_taskmgmt_id = mpt_register(mptctl_taskmgmt_reply, MPTCTL_DRIVER);
if (!mptctl_taskmgmt_id || mptctl_taskmgmt_id >= MPT_MAX_PROTOCOL_DRIVERS) {
printk(KERN_ERR MYNAM ": ERROR: Failed to register with Fusion MPT base driver\n");
mpt_deregister(mptctl_id);
misc_deregister(&mptctl_miscdev);
err = -EBUSY;
goto out_fail;
}
mpt_reset_register(mptctl_id, mptctl_ioc_reset);
mpt_event_register(mptctl_id, mptctl_event_process);
@ -3010,12 +3036,15 @@ static void mptctl_exit(void)
printk(KERN_INFO MYNAM ": Deregistered /dev/%s @ (major,minor=%d,%d)\n",
mptctl_miscdev.name, MISC_MAJOR, mptctl_miscdev.minor);
/* De-register event handler from base module */
mpt_event_deregister(mptctl_id);
/* De-register reset handler from base module */
mpt_reset_deregister(mptctl_id);
/* De-register callback handler from base module */
mpt_deregister(mptctl_taskmgmt_id);
mpt_deregister(mptctl_id);
mpt_reset_deregister(mptctl_taskmgmt_id);
mpt_device_driver_deregister(MPTCTL_DRIVER);

View file

@ -482,6 +482,7 @@ mptfc_register_dev(MPT_ADAPTER *ioc, int channel, FCDevicePage0_t *pg0)
if (vtarget) {
vtarget->id = pg0->CurrentTargetID;
vtarget->channel = pg0->CurrentBus;
vtarget->deleted = 0;
}
}
*((struct mptfc_rport_info **)rport->dd_data) = ri;
@ -1092,6 +1093,8 @@ mptfc_setup_reset(struct work_struct *work)
container_of(work, MPT_ADAPTER, fc_setup_reset_work);
u64 pn;
struct mptfc_rport_info *ri;
struct scsi_target *starget;
VirtTarget *vtarget;
/* reset about to happen, delete (block) all rports */
list_for_each_entry(ri, &ioc->fc_rports, list) {
@ -1099,6 +1102,12 @@ mptfc_setup_reset(struct work_struct *work)
ri->flags &= ~MPT_RPORT_INFO_FLAGS_REGISTERED;
fc_remote_port_delete(ri->rport); /* won't sleep */
ri->rport = NULL;
starget = ri->starget;
if (starget) {
vtarget = starget->hostdata;
if (vtarget)
vtarget->deleted = 1;
}
pn = (u64)ri->pg0.WWPN.High << 32 |
(u64)ri->pg0.WWPN.Low;
@ -1119,6 +1128,8 @@ mptfc_rescan_devices(struct work_struct *work)
int ii;
u64 pn;
struct mptfc_rport_info *ri;
struct scsi_target *starget;
VirtTarget *vtarget;
/* start by tagging all ports as missing */
list_for_each_entry(ri, &ioc->fc_rports, list) {
@ -1146,6 +1157,12 @@ mptfc_rescan_devices(struct work_struct *work)
MPT_RPORT_INFO_FLAGS_MISSING);
fc_remote_port_delete(ri->rport); /* won't sleep */
ri->rport = NULL;
starget = ri->starget;
if (starget) {
vtarget = starget->hostdata;
if (vtarget)
vtarget->deleted = 1;
}
pn = (u64)ri->pg0.WWPN.High << 32 |
(u64)ri->pg0.WWPN.Low;
@ -1358,6 +1375,9 @@ mptfc_event_process(MPT_ADAPTER *ioc, EventNotificationReply_t *pEvReply)
unsigned long flags;
int rc=1;
if (ioc->bus_type != FC)
return 0;
devtverboseprintk(ioc, printk(MYIOC_s_DEBUG_FMT "MPT event (=%02Xh) routed to SCSI host driver!\n",
ioc->name, event));
@ -1396,7 +1416,7 @@ mptfc_ioc_reset(MPT_ADAPTER *ioc, int reset_phase)
unsigned long flags;
rc = mptscsih_ioc_reset(ioc,reset_phase);
if (rc == 0)
if ((ioc->bus_type != FC) || (!rc))
return rc;

View file

@ -1894,7 +1894,7 @@ static struct scsi_host_template mptsas_driver_template = {
.module = THIS_MODULE,
.proc_name = "mptsas",
.proc_info = mptscsih_proc_info,
.name = "MPT SPI Host",
.name = "MPT SAS Host",
.info = mptscsih_info,
.queuecommand = mptsas_qcmd,
.target_alloc = mptsas_target_alloc,
@ -2038,11 +2038,13 @@ static int mptsas_phy_reset(struct sas_phy *phy, int hard_reset)
timeleft = wait_for_completion_timeout(&ioc->sas_mgmt.done,
10 * HZ);
if (!timeleft) {
/* On timeout reset the board */
if (!(ioc->sas_mgmt.status & MPT_MGMT_STATUS_COMMAND_GOOD)) {
error = -ETIME;
mpt_free_msg_frame(ioc, mf);
mpt_HardResetHandler(ioc, CAN_SLEEP);
error = -ETIMEDOUT;
if (ioc->sas_mgmt.status & MPT_MGMT_STATUS_DID_IOCRESET)
goto out_unlock;
if (!timeleft)
mpt_Soft_Hard_ResetHandler(ioc, CAN_SLEEP);
goto out_unlock;
}
@ -2223,11 +2225,14 @@ static int mptsas_smp_handler(struct Scsi_Host *shost, struct sas_rphy *rphy,
mpt_put_msg_frame(mptsasMgmtCtx, ioc, mf);
timeleft = wait_for_completion_timeout(&ioc->sas_mgmt.done, 10 * HZ);
if (!timeleft) {
printk(MYIOC_s_ERR_FMT "%s: smp timeout!\n", ioc->name, __func__);
/* On timeout reset the board */
mpt_HardResetHandler(ioc, CAN_SLEEP);
ret = -ETIMEDOUT;
if (!(ioc->sas_mgmt.status & MPT_MGMT_STATUS_COMMAND_GOOD)) {
ret = -ETIME;
mpt_free_msg_frame(ioc, mf);
mf = NULL;
if (ioc->sas_mgmt.status & MPT_MGMT_STATUS_DID_IOCRESET)
goto unmap;
if (!timeleft)
mpt_Soft_Hard_ResetHandler(ioc, CAN_SLEEP);
goto unmap;
}
mf = NULL;
@ -2518,6 +2523,12 @@ mptsas_sas_device_pg0(MPT_ADAPTER *ioc, struct mptsas_devinfo *device_info,
cfg.action = MPI_CONFIG_ACTION_PAGE_READ_CURRENT;
error = mpt_config(ioc, &cfg);
if (error == MPI_IOCSTATUS_CONFIG_INVALID_PAGE) {
error = -ENODEV;
goto out_free_consistent;
}
if (error)
goto out_free_consistent;
@ -2594,14 +2605,14 @@ mptsas_sas_expander_pg0(MPT_ADAPTER *ioc, struct mptsas_portinfo *port_info,
cfg.action = MPI_CONFIG_ACTION_PAGE_READ_CURRENT;
error = mpt_config(ioc, &cfg);
if (error)
goto out_free_consistent;
if (!buffer->NumPhys) {
if (error == MPI_IOCSTATUS_CONFIG_INVALID_PAGE) {
error = -ENODEV;
goto out_free_consistent;
}
if (error)
goto out_free_consistent;
/* save config data */
port_info->num_phys = (buffer->NumPhys) ? buffer->NumPhys : 1;
port_info->phy_info = kcalloc(port_info->num_phys,
@ -2677,7 +2688,7 @@ mptsas_sas_expander_pg1(MPT_ADAPTER *ioc, struct mptsas_phyinfo *phy_info,
if (error == MPI_IOCSTATUS_CONFIG_INVALID_PAGE) {
error = -ENODEV;
goto out;
goto out_free_consistent;
}
if (error)
@ -2833,7 +2844,7 @@ mptsas_exp_repmanufacture_info(MPT_ADAPTER *ioc,
if (ioc->sas_mgmt.status & MPT_MGMT_STATUS_DID_IOCRESET)
goto out_free;
if (!timeleft)
mpt_HardResetHandler(ioc, CAN_SLEEP);
mpt_Soft_Hard_ResetHandler(ioc, CAN_SLEEP);
goto out_free;
}
@ -4098,6 +4109,7 @@ mptsas_adding_inactive_raid_components(MPT_ADAPTER *ioc, u8 channel, u8 id)
cfg.pageAddr = (channel << 8) + id;
cfg.cfghdr.hdr = &hdr;
cfg.action = MPI_CONFIG_ACTION_PAGE_HEADER;
cfg.timeout = SAS_CONFIG_PAGE_TIMEOUT;
if (mpt_config(ioc, &cfg) != 0)
goto out;
@ -4717,7 +4729,7 @@ mptsas_broadcast_primative_work(struct fw_event_work *fw_event)
if (issue_reset) {
printk(MYIOC_s_WARN_FMT "Issuing Reset from %s!!\n",
ioc->name, __func__);
mpt_HardResetHandler(ioc, CAN_SLEEP);
mpt_Soft_Hard_ResetHandler(ioc, CAN_SLEEP);
}
mptsas_free_fw_event(ioc, fw_event);
}
@ -4779,6 +4791,9 @@ mptsas_event_process(MPT_ADAPTER *ioc, EventNotificationReply_t *reply)
struct fw_event_work *fw_event;
unsigned long delay;
if (ioc->bus_type != SAS)
return 0;
/* events turned off due to host reset or driver unloading */
if (ioc->fw_events_off)
return 0;
@ -5073,6 +5088,12 @@ static void __devexit mptsas_remove(struct pci_dev *pdev)
struct mptsas_portinfo *p, *n;
int i;
if (!ioc->sh) {
printk(MYIOC_s_INFO_FMT "IOC is in Target mode\n", ioc->name);
mpt_detach(pdev);
return;
}
mptsas_shutdown(pdev);
mptsas_del_device_components(ioc);

View file

@ -110,7 +110,7 @@ struct fw_event_work {
MPT_ADAPTER *ioc;
u32 event;
u8 retries;
u8 event_data[1];
u8 __attribute__((aligned(4))) event_data[1];
};
struct mptsas_discovery_event {

View file

@ -1149,11 +1149,6 @@ mptscsih_remove(struct pci_dev *pdev)
MPT_SCSI_HOST *hd;
int sz1;
if(!host) {
mpt_detach(pdev);
return;
}
scsi_remove_host(host);
if((hd = shost_priv(host)) == NULL)
@ -1711,7 +1706,7 @@ mptscsih_IssueTaskMgmt(MPT_SCSI_HOST *hd, u8 type, u8 channel, u8 id, int lun,
if (issue_hard_reset) {
printk(MYIOC_s_WARN_FMT "Issuing Reset from %s!!\n",
ioc->name, __func__);
retval = mpt_HardResetHandler(ioc, CAN_SLEEP);
retval = mpt_Soft_Hard_ResetHandler(ioc, CAN_SLEEP);
mpt_free_msg_frame(ioc, mf);
}
@ -1728,6 +1723,7 @@ mptscsih_get_tm_timeout(MPT_ADAPTER *ioc)
case FC:
return 40;
case SAS:
return 30;
case SPI:
default:
return 10;
@ -1777,7 +1773,7 @@ mptscsih_abort(struct scsi_cmnd * SCpnt)
ioc->name, SCpnt));
SCpnt->result = DID_NO_CONNECT << 16;
SCpnt->scsi_done(SCpnt);
retval = 0;
retval = SUCCESS;
goto out;
}
@ -1792,6 +1788,17 @@ mptscsih_abort(struct scsi_cmnd * SCpnt)
goto out;
}
/* Task aborts are not supported for volumes.
*/
if (vdevice->vtarget->raidVolume) {
dtmprintk(ioc, printk(MYIOC_s_DEBUG_FMT
"task abort: raid volume (sc=%p)\n",
ioc->name, SCpnt));
SCpnt->result = DID_RESET << 16;
retval = FAILED;
goto out;
}
/* Find this command
*/
if ((scpnt_idx = SCPNT_TO_LOOKUP_IDX(ioc, SCpnt)) < 0) {
@ -1991,7 +1998,7 @@ mptscsih_host_reset(struct scsi_cmnd *SCpnt)
/* If our attempts to reset the host failed, then return a failed
* status. The host will be taken off line by the SCSI mid-layer.
*/
retval = mpt_HardResetHandler(ioc, CAN_SLEEP);
retval = mpt_Soft_Hard_ResetHandler(ioc, CAN_SLEEP);
if (retval < 0)
status = FAILED;
else
@ -2344,6 +2351,8 @@ mptscsih_slave_destroy(struct scsi_device *sdev)
starget = scsi_target(sdev);
vtarget = starget->hostdata;
vdevice = sdev->hostdata;
if (!vdevice)
return;
mptscsih_search_running_cmds(hd, vdevice);
vtarget->num_luns--;
@ -3040,7 +3049,7 @@ mptscsih_do_cmd(MPT_SCSI_HOST *hd, INTERNAL_CMD *io)
if (!timeleft) {
printk(MYIOC_s_WARN_FMT "Issuing Reset from %s!!\n",
ioc->name, __func__);
mpt_HardResetHandler(ioc, CAN_SLEEP);
mpt_Soft_Hard_ResetHandler(ioc, CAN_SLEEP);
mpt_free_msg_frame(ioc, mf);
}
goto out;

View file

@ -210,6 +210,10 @@ mptspi_setTargetNegoParms(MPT_SCSI_HOST *hd, VirtTarget *target,
target->maxOffset = offset;
target->maxWidth = width;
spi_min_period(scsi_target(sdev)) = factor;
spi_max_offset(scsi_target(sdev)) = offset;
spi_max_width(scsi_target(sdev)) = width;
target->tflags |= MPT_TARGET_FLAGS_VALID_NEGO;
/* Disable unused features.
@ -558,6 +562,7 @@ static int mptspi_read_spi_device_pg0(struct scsi_target *starget,
cfg.action = MPI_CONFIG_ACTION_PAGE_READ_CURRENT;
cfg.dir = 0;
cfg.pageAddr = starget->id;
cfg.timeout = 60;
if (mpt_config(ioc, &cfg)) {
starget_printk(KERN_ERR, starget, MYIOC_s_FMT "mpt_config failed\n", ioc->name);
@ -1152,6 +1157,9 @@ mptspi_event_process(MPT_ADAPTER *ioc, EventNotificationReply_t *pEvReply)
u8 event = le32_to_cpu(pEvReply->Event) & 0xFF;
struct _MPT_SCSI_HOST *hd = shost_priv(ioc->sh);
if (ioc->bus_type != SPI)
return 0;
if (hd && event == MPI_EVENT_INTEGRATED_RAID) {
int reason
= (le32_to_cpu(pEvReply->Data[0]) & 0x00FF0000) >> 16;
@ -1283,6 +1291,8 @@ mptspi_ioc_reset(MPT_ADAPTER *ioc, int reset_phase)
int rc;
rc = mptscsih_ioc_reset(ioc, reset_phase);
if ((ioc->bus_type != SPI) || (!rc))
return rc;
/* only try to do a renegotiation if we're properly set up
* if we get an ioc fault on bringup, ioc->sh will be NULL */