Commit 592f9c2f authored by Moore, Eric's avatar Moore, Eric Committed by

[SCSI] fusion - mptctl - backplane istwi fix

Moving the toolbox call from mptbase.c, over to
mptctl.c, and using the mptctl infastructure to issue
the call.  The existing code is hanging on certain HP platforms
when this ioctl is issued, and this patch fix's that.
Signed-off-by: default avatarEric Moore <Eric.Moore@lsil.com>
Signed-off-by: default avatarJames Bottomley <James.Bottomley@SteelEye.com>
parent 5f07e249
...@@ -452,8 +452,7 @@ mpt_base_reply(MPT_ADAPTER *ioc, MPT_FRAME_HDR *mf, MPT_FRAME_HDR *reply) ...@@ -452,8 +452,7 @@ mpt_base_reply(MPT_ADAPTER *ioc, MPT_FRAME_HDR *mf, MPT_FRAME_HDR *reply)
} else if (func == MPI_FUNCTION_EVENT_ACK) { } else if (func == MPI_FUNCTION_EVENT_ACK) {
dprintk((MYIOC_s_INFO_FMT "mpt_base_reply, EventAck reply received\n", dprintk((MYIOC_s_INFO_FMT "mpt_base_reply, EventAck reply received\n",
ioc->name)); ioc->name));
} else if (func == MPI_FUNCTION_CONFIG || } else if (func == MPI_FUNCTION_CONFIG) {
func == MPI_FUNCTION_TOOLBOX) {
CONFIGPARMS *pCfg; CONFIGPARMS *pCfg;
unsigned long flags; unsigned long flags;
...@@ -5326,115 +5325,6 @@ mpt_config(MPT_ADAPTER *ioc, CONFIGPARMS *pCfg) ...@@ -5326,115 +5325,6 @@ mpt_config(MPT_ADAPTER *ioc, CONFIGPARMS *pCfg)
return rc; return rc;
} }
/*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
/**
* mpt_toolbox - Generic function to issue toolbox message
* @ioc - Pointer to an adapter structure
* @cfg - Pointer to a toolbox structure. Struct contains
* action, page address, direction, physical address
* and pointer to a configuration page header
* Page header is updated.
*
* Returns 0 for success
* -EPERM if not allowed due to ISR context
* -EAGAIN if no msg frames currently available
* -EFAULT for non-successful reply or no reply (timeout)
*/
int
mpt_toolbox(MPT_ADAPTER *ioc, CONFIGPARMS *pCfg)
{
ToolboxIstwiReadWriteRequest_t *pReq;
MPT_FRAME_HDR *mf;
struct pci_dev *pdev;
unsigned long flags;
int rc;
u32 flagsLength;
int in_isr;
/* Prevent calling wait_event() (below), if caller happens
* to be in ISR context, because that is fatal!
*/
in_isr = in_interrupt();
if (in_isr) {
dcprintk((MYIOC_s_WARN_FMT "toobox request not allowed in ISR context!\n",
ioc->name));
return -EPERM;
}
/* Get and Populate a free Frame
*/
if ((mf = mpt_get_msg_frame(mpt_base_index, ioc)) == NULL) {
dcprintk((MYIOC_s_WARN_FMT "mpt_toolbox: no msg frames!\n",
ioc->name));
return -EAGAIN;
}
pReq = (ToolboxIstwiReadWriteRequest_t *)mf;
pReq->Tool = pCfg->action;
pReq->Reserved = 0;
pReq->ChainOffset = 0;
pReq->Function = MPI_FUNCTION_TOOLBOX;
pReq->Reserved1 = 0;
pReq->Reserved2 = 0;
pReq->MsgFlags = 0;
pReq->Flags = pCfg->dir;
pReq->BusNum = 0;
pReq->Reserved3 = 0;
pReq->NumAddressBytes = 0x01;
pReq->Reserved4 = 0;
pReq->DataLength = cpu_to_le16(0x04);
pdev = ioc->pcidev;
if (pdev->devfn & 1)
pReq->DeviceAddr = 0xB2;
else
pReq->DeviceAddr = 0xB0;
pReq->Addr1 = 0;
pReq->Addr2 = 0;
pReq->Addr3 = 0;
pReq->Reserved5 = 0;
/* Add a SGE to the config request.
*/
flagsLength = MPT_SGE_FLAGS_SSIMPLE_READ | 4;
mpt_add_sge((char *)&pReq->SGL, flagsLength, pCfg->physAddr);
dcprintk((MYIOC_s_INFO_FMT "Sending Toolbox request, Tool=%x\n",
ioc->name, pReq->Tool));
/* Append pCfg pointer to end of mf
*/
*((void **) (((u8 *) mf) + (ioc->req_sz - sizeof(void *)))) = (void *) pCfg;
/* Initalize the timer
*/
init_timer(&pCfg->timer);
pCfg->timer.data = (unsigned long) ioc;
pCfg->timer.function = mpt_timer_expired;
pCfg->wait_done = 0;
/* Set the timer; ensure 10 second minimum */
if (pCfg->timeout < 10)
pCfg->timer.expires = jiffies + HZ*10;
else
pCfg->timer.expires = jiffies + HZ*pCfg->timeout;
/* Add to end of Q, set timer and then issue this command */
spin_lock_irqsave(&ioc->FreeQlock, flags);
list_add_tail(&pCfg->linkage, &ioc->configQ);
spin_unlock_irqrestore(&ioc->FreeQlock, flags);
add_timer(&pCfg->timer);
mpt_put_msg_frame(mpt_base_index, ioc, mf);
wait_event(mpt_waitq, pCfg->wait_done);
/* mf has been freed - do not access */
rc = pCfg->status;
return rc;
}
/*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/ /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
/* /*
* mpt_timer_expired - Call back for timer process. * mpt_timer_expired - Call back for timer process.
...@@ -6540,7 +6430,6 @@ EXPORT_SYMBOL(mpt_lan_index); ...@@ -6540,7 +6430,6 @@ EXPORT_SYMBOL(mpt_lan_index);
EXPORT_SYMBOL(mpt_stm_index); EXPORT_SYMBOL(mpt_stm_index);
EXPORT_SYMBOL(mpt_HardResetHandler); EXPORT_SYMBOL(mpt_HardResetHandler);
EXPORT_SYMBOL(mpt_config); EXPORT_SYMBOL(mpt_config);
EXPORT_SYMBOL(mpt_toolbox);
EXPORT_SYMBOL(mpt_findImVolumes); EXPORT_SYMBOL(mpt_findImVolumes);
EXPORT_SYMBOL(mpt_read_ioc_pg_3); EXPORT_SYMBOL(mpt_read_ioc_pg_3);
EXPORT_SYMBOL(mpt_alloc_fw_memory); EXPORT_SYMBOL(mpt_alloc_fw_memory);
......
...@@ -1026,7 +1026,6 @@ extern u32 mpt_GetIocState(MPT_ADAPTER *ioc, int cooked); ...@@ -1026,7 +1026,6 @@ 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 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_HardResetHandler(MPT_ADAPTER *ioc, int sleepFlag);
extern int mpt_config(MPT_ADAPTER *ioc, CONFIGPARMS *cfg); extern int mpt_config(MPT_ADAPTER *ioc, CONFIGPARMS *cfg);
extern int mpt_toolbox(MPT_ADAPTER *ioc, CONFIGPARMS *cfg);
extern void mpt_alloc_fw_memory(MPT_ADAPTER *ioc, int size); extern void mpt_alloc_fw_memory(MPT_ADAPTER *ioc, int size);
extern void mpt_free_fw_memory(MPT_ADAPTER *ioc); extern void mpt_free_fw_memory(MPT_ADAPTER *ioc);
extern int mpt_findImVolumes(MPT_ADAPTER *ioc); extern int mpt_findImVolumes(MPT_ADAPTER *ioc);
......
...@@ -2271,13 +2271,16 @@ mptctl_hp_hostinfo(unsigned long arg, unsigned int data_size) ...@@ -2271,13 +2271,16 @@ mptctl_hp_hostinfo(unsigned long arg, unsigned int data_size)
hp_host_info_t __user *uarg = (void __user *) arg; hp_host_info_t __user *uarg = (void __user *) arg;
MPT_ADAPTER *ioc; MPT_ADAPTER *ioc;
struct pci_dev *pdev; struct pci_dev *pdev;
char *pbuf; char *pbuf=NULL;
dma_addr_t buf_dma; dma_addr_t buf_dma;
hp_host_info_t karg; hp_host_info_t karg;
CONFIGPARMS cfg; CONFIGPARMS cfg;
ConfigPageHeader_t hdr; ConfigPageHeader_t hdr;
int iocnum; int iocnum;
int rc, cim_rev; int rc, cim_rev;
ToolboxIstwiReadWriteRequest_t *IstwiRWRequest;
MPT_FRAME_HDR *mf = NULL;
MPIHeader_t *mpi_hdr;
dctlprintk((": mptctl_hp_hostinfo called.\n")); dctlprintk((": mptctl_hp_hostinfo called.\n"));
/* Reset long to int. Should affect IA64 and SPARC only /* Reset long to int. Should affect IA64 and SPARC only
...@@ -2413,20 +2416,67 @@ mptctl_hp_hostinfo(unsigned long arg, unsigned int data_size) ...@@ -2413,20 +2416,67 @@ mptctl_hp_hostinfo(unsigned long arg, unsigned int data_size)
} }
} }
cfg.pageAddr = 0; /*
cfg.action = MPI_TOOLBOX_ISTWI_READ_WRITE_TOOL; * Gather ISTWI(Industry Standard Two Wire Interface) Data
cfg.dir = MPI_TB_ISTWI_FLAGS_READ; */
cfg.timeout = 10; if ((mf = mpt_get_msg_frame(mptctl_id, ioc)) == NULL) {
dfailprintk((MYIOC_s_WARN_FMT "%s, no msg frames!!\n",
ioc->name,__FUNCTION__));
goto out;
}
IstwiRWRequest = (ToolboxIstwiReadWriteRequest_t *)mf;
mpi_hdr = (MPIHeader_t *) mf;
memset(IstwiRWRequest,0,sizeof(ToolboxIstwiReadWriteRequest_t));
IstwiRWRequest->Function = MPI_FUNCTION_TOOLBOX;
IstwiRWRequest->Tool = MPI_TOOLBOX_ISTWI_READ_WRITE_TOOL;
IstwiRWRequest->MsgContext = mpi_hdr->MsgContext;
IstwiRWRequest->Flags = MPI_TB_ISTWI_FLAGS_READ;
IstwiRWRequest->NumAddressBytes = 0x01;
IstwiRWRequest->DataLength = cpu_to_le16(0x04);
if (pdev->devfn & 1)
IstwiRWRequest->DeviceAddr = 0xB2;
else
IstwiRWRequest->DeviceAddr = 0xB0;
pbuf = pci_alloc_consistent(ioc->pcidev, 4, &buf_dma); pbuf = pci_alloc_consistent(ioc->pcidev, 4, &buf_dma);
if (pbuf) { if (!pbuf)
cfg.physAddr = buf_dma; goto out;
if ((mpt_toolbox(ioc, &cfg)) == 0) { mpt_add_sge((char *)&IstwiRWRequest->SGL,
karg.rsvd = *(u32 *)pbuf; (MPT_SGE_FLAGS_SSIMPLE_READ|4), buf_dma);
}
pci_free_consistent(ioc->pcidev, 4, pbuf, buf_dma); ioc->ioctl->wait_done = 0;
pbuf = NULL; mpt_put_msg_frame(mptctl_id, ioc, mf);
rc = wait_event_timeout(mptctl_wait,
ioc->ioctl->wait_done == 1,
HZ*MPT_IOCTL_DEFAULT_TIMEOUT /* 10 sec */);
if(rc <=0 && (ioc->ioctl->wait_done != 1 )) {
/*
* Now we need to reset the board
*/
mpt_free_msg_frame(ioc, mf);
mptctl_timeout_expired(ioc->ioctl);
goto out;
} }
/*
*ISTWI Data Definition
* pbuf[0] = FW_VERSION = 0x4
* pbuf[1] = Bay Count = 6 or 4 or 2, depending on
* the config, you should be seeing one out of these three values
* pbuf[2] = Drive Installed Map = bit pattern depend on which
* bays have drives in them
* pbuf[3] = Checksum (0x100 = (byte0 + byte2 + byte3)
*/
if (ioc->ioctl->status & MPT_IOCTL_STATUS_RF_VALID)
karg.rsvd = *(u32 *)pbuf;
out:
if (pbuf)
pci_free_consistent(ioc->pcidev, 4, pbuf, buf_dma);
/* Copy the data from kernel memory to user memory /* Copy the data from kernel memory to user memory
*/ */
if (copy_to_user((char __user *)arg, &karg, sizeof(hp_host_info_t))) { if (copy_to_user((char __user *)arg, &karg, sizeof(hp_host_info_t))) {
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment