aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/message/fusion
diff options
context:
space:
mode:
authorMoore, Eric <Eric.Moore@lsil.com>2006-02-02 19:19:47 -0500
committer <jejb@mulgrave.il.steeleye.com>2006-02-04 17:32:51 -0500
commit592f9c2fc9725b922ba8c4b1d67318ea4a301b59 (patch)
treec6412bd0074ee48693d4560bcbe28927c95de3bb /drivers/message/fusion
parent5f07e2499d629045f7f8a60a5b442792f08732cb (diff)
[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: Eric Moore <Eric.Moore@lsil.com> Signed-off-by: James Bottomley <James.Bottomley@SteelEye.com>
Diffstat (limited to 'drivers/message/fusion')
-rw-r--r--drivers/message/fusion/mptbase.c113
-rw-r--r--drivers/message/fusion/mptbase.h1
-rw-r--r--drivers/message/fusion/mptctl.c74
3 files changed, 63 insertions, 125 deletions
diff --git a/drivers/message/fusion/mptbase.c b/drivers/message/fusion/mptbase.c
index a3751d86216e..642a61b6d0a4 100644
--- a/drivers/message/fusion/mptbase.c
+++ b/drivers/message/fusion/mptbase.c
@@ -452,8 +452,7 @@ mpt_base_reply(MPT_ADAPTER *ioc, MPT_FRAME_HDR *mf, MPT_FRAME_HDR *reply)
452 } else if (func == MPI_FUNCTION_EVENT_ACK) { 452 } else if (func == MPI_FUNCTION_EVENT_ACK) {
453 dprintk((MYIOC_s_INFO_FMT "mpt_base_reply, EventAck reply received\n", 453 dprintk((MYIOC_s_INFO_FMT "mpt_base_reply, EventAck reply received\n",
454 ioc->name)); 454 ioc->name));
455 } else if (func == MPI_FUNCTION_CONFIG || 455 } else if (func == MPI_FUNCTION_CONFIG) {
456 func == MPI_FUNCTION_TOOLBOX) {
457 CONFIGPARMS *pCfg; 456 CONFIGPARMS *pCfg;
458 unsigned long flags; 457 unsigned long flags;
459 458
@@ -5327,115 +5326,6 @@ mpt_config(MPT_ADAPTER *ioc, CONFIGPARMS *pCfg)
5327} 5326}
5328 5327
5329/*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/ 5328/*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
5330/**
5331 * mpt_toolbox - Generic function to issue toolbox message
5332 * @ioc - Pointer to an adapter structure
5333 * @cfg - Pointer to a toolbox structure. Struct contains
5334 * action, page address, direction, physical address
5335 * and pointer to a configuration page header
5336 * Page header is updated.
5337 *
5338 * Returns 0 for success
5339 * -EPERM if not allowed due to ISR context
5340 * -EAGAIN if no msg frames currently available
5341 * -EFAULT for non-successful reply or no reply (timeout)
5342 */
5343int
5344mpt_toolbox(MPT_ADAPTER *ioc, CONFIGPARMS *pCfg)
5345{
5346 ToolboxIstwiReadWriteRequest_t *pReq;
5347 MPT_FRAME_HDR *mf;
5348 struct pci_dev *pdev;
5349 unsigned long flags;
5350 int rc;
5351 u32 flagsLength;
5352 int in_isr;
5353
5354 /* Prevent calling wait_event() (below), if caller happens
5355 * to be in ISR context, because that is fatal!
5356 */
5357 in_isr = in_interrupt();
5358 if (in_isr) {
5359 dcprintk((MYIOC_s_WARN_FMT "toobox request not allowed in ISR context!\n",
5360 ioc->name));
5361 return -EPERM;
5362 }
5363
5364 /* Get and Populate a free Frame
5365 */
5366 if ((mf = mpt_get_msg_frame(mpt_base_index, ioc)) == NULL) {
5367 dcprintk((MYIOC_s_WARN_FMT "mpt_toolbox: no msg frames!\n",
5368 ioc->name));
5369 return -EAGAIN;
5370 }
5371 pReq = (ToolboxIstwiReadWriteRequest_t *)mf;
5372 pReq->Tool = pCfg->action;
5373 pReq->Reserved = 0;
5374 pReq->ChainOffset = 0;
5375 pReq->Function = MPI_FUNCTION_TOOLBOX;
5376 pReq->Reserved1 = 0;
5377 pReq->Reserved2 = 0;
5378 pReq->MsgFlags = 0;
5379 pReq->Flags = pCfg->dir;
5380 pReq->BusNum = 0;
5381 pReq->Reserved3 = 0;
5382 pReq->NumAddressBytes = 0x01;
5383 pReq->Reserved4 = 0;
5384 pReq->DataLength = cpu_to_le16(0x04);
5385 pdev = ioc->pcidev;
5386 if (pdev->devfn & 1)
5387 pReq->DeviceAddr = 0xB2;
5388 else
5389 pReq->DeviceAddr = 0xB0;
5390 pReq->Addr1 = 0;
5391 pReq->Addr2 = 0;
5392 pReq->Addr3 = 0;
5393 pReq->Reserved5 = 0;
5394
5395 /* Add a SGE to the config request.
5396 */
5397
5398 flagsLength = MPT_SGE_FLAGS_SSIMPLE_READ | 4;
5399
5400 mpt_add_sge((char *)&pReq->SGL, flagsLength, pCfg->physAddr);
5401
5402 dcprintk((MYIOC_s_INFO_FMT "Sending Toolbox request, Tool=%x\n",
5403 ioc->name, pReq->Tool));
5404
5405 /* Append pCfg pointer to end of mf
5406 */
5407 *((void **) (((u8 *) mf) + (ioc->req_sz - sizeof(void *)))) = (void *) pCfg;
5408
5409 /* Initalize the timer
5410 */
5411 init_timer(&pCfg->timer);
5412 pCfg->timer.data = (unsigned long) ioc;
5413 pCfg->timer.function = mpt_timer_expired;
5414 pCfg->wait_done = 0;
5415
5416 /* Set the timer; ensure 10 second minimum */
5417 if (pCfg->timeout < 10)
5418 pCfg->timer.expires = jiffies + HZ*10;
5419 else
5420 pCfg->timer.expires = jiffies + HZ*pCfg->timeout;
5421
5422 /* Add to end of Q, set timer and then issue this command */
5423 spin_lock_irqsave(&ioc->FreeQlock, flags);
5424 list_add_tail(&pCfg->linkage, &ioc->configQ);
5425 spin_unlock_irqrestore(&ioc->FreeQlock, flags);
5426
5427 add_timer(&pCfg->timer);
5428 mpt_put_msg_frame(mpt_base_index, ioc, mf);
5429 wait_event(mpt_waitq, pCfg->wait_done);
5430
5431 /* mf has been freed - do not access */
5432
5433 rc = pCfg->status;
5434
5435 return rc;
5436}
5437
5438/*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
5439/* 5329/*
5440 * mpt_timer_expired - Call back for timer process. 5330 * mpt_timer_expired - Call back for timer process.
5441 * Used only internal config functionality. 5331 * Used only internal config functionality.
@@ -6540,7 +6430,6 @@ EXPORT_SYMBOL(mpt_lan_index);
6540EXPORT_SYMBOL(mpt_stm_index); 6430EXPORT_SYMBOL(mpt_stm_index);
6541EXPORT_SYMBOL(mpt_HardResetHandler); 6431EXPORT_SYMBOL(mpt_HardResetHandler);
6542EXPORT_SYMBOL(mpt_config); 6432EXPORT_SYMBOL(mpt_config);
6543EXPORT_SYMBOL(mpt_toolbox);
6544EXPORT_SYMBOL(mpt_findImVolumes); 6433EXPORT_SYMBOL(mpt_findImVolumes);
6545EXPORT_SYMBOL(mpt_read_ioc_pg_3); 6434EXPORT_SYMBOL(mpt_read_ioc_pg_3);
6546EXPORT_SYMBOL(mpt_alloc_fw_memory); 6435EXPORT_SYMBOL(mpt_alloc_fw_memory);
diff --git a/drivers/message/fusion/mptbase.h b/drivers/message/fusion/mptbase.h
index ea2649ecad1f..2e5377309cea 100644
--- a/drivers/message/fusion/mptbase.h
+++ b/drivers/message/fusion/mptbase.h
@@ -1026,7 +1026,6 @@ extern u32 mpt_GetIocState(MPT_ADAPTER *ioc, int cooked);
1026extern void mpt_print_ioc_summary(MPT_ADAPTER *ioc, char *buf, int *size, int len, int showlan); 1026extern void mpt_print_ioc_summary(MPT_ADAPTER *ioc, char *buf, int *size, int len, int showlan);
1027extern int mpt_HardResetHandler(MPT_ADAPTER *ioc, int sleepFlag); 1027extern int mpt_HardResetHandler(MPT_ADAPTER *ioc, int sleepFlag);
1028extern int mpt_config(MPT_ADAPTER *ioc, CONFIGPARMS *cfg); 1028extern int mpt_config(MPT_ADAPTER *ioc, CONFIGPARMS *cfg);
1029extern int mpt_toolbox(MPT_ADAPTER *ioc, CONFIGPARMS *cfg);
1030extern void mpt_alloc_fw_memory(MPT_ADAPTER *ioc, int size); 1029extern void mpt_alloc_fw_memory(MPT_ADAPTER *ioc, int size);
1031extern void mpt_free_fw_memory(MPT_ADAPTER *ioc); 1030extern void mpt_free_fw_memory(MPT_ADAPTER *ioc);
1032extern int mpt_findImVolumes(MPT_ADAPTER *ioc); 1031extern int mpt_findImVolumes(MPT_ADAPTER *ioc);
diff --git a/drivers/message/fusion/mptctl.c b/drivers/message/fusion/mptctl.c
index be5fcd8db63b..2df3b8756545 100644
--- a/drivers/message/fusion/mptctl.c
+++ b/drivers/message/fusion/mptctl.c
@@ -2271,13 +2271,16 @@ mptctl_hp_hostinfo(unsigned long arg, unsigned int data_size)
2271 hp_host_info_t __user *uarg = (void __user *) arg; 2271 hp_host_info_t __user *uarg = (void __user *) arg;
2272 MPT_ADAPTER *ioc; 2272 MPT_ADAPTER *ioc;
2273 struct pci_dev *pdev; 2273 struct pci_dev *pdev;
2274 char *pbuf; 2274 char *pbuf=NULL;
2275 dma_addr_t buf_dma; 2275 dma_addr_t buf_dma;
2276 hp_host_info_t karg; 2276 hp_host_info_t karg;
2277 CONFIGPARMS cfg; 2277 CONFIGPARMS cfg;
2278 ConfigPageHeader_t hdr; 2278 ConfigPageHeader_t hdr;
2279 int iocnum; 2279 int iocnum;
2280 int rc, cim_rev; 2280 int rc, cim_rev;
2281 ToolboxIstwiReadWriteRequest_t *IstwiRWRequest;
2282 MPT_FRAME_HDR *mf = NULL;
2283 MPIHeader_t *mpi_hdr;
2281 2284
2282 dctlprintk((": mptctl_hp_hostinfo called.\n")); 2285 dctlprintk((": mptctl_hp_hostinfo called.\n"));
2283 /* Reset long to int. Should affect IA64 and SPARC only 2286 /* 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 } 2416 }
2414 } 2417 }
2415 2418
2416 cfg.pageAddr = 0; 2419 /*
2417 cfg.action = MPI_TOOLBOX_ISTWI_READ_WRITE_TOOL; 2420 * Gather ISTWI(Industry Standard Two Wire Interface) Data
2418 cfg.dir = MPI_TB_ISTWI_FLAGS_READ; 2421 */
2419 cfg.timeout = 10; 2422 if ((mf = mpt_get_msg_frame(mptctl_id, ioc)) == NULL) {
2423 dfailprintk((MYIOC_s_WARN_FMT "%s, no msg frames!!\n",
2424 ioc->name,__FUNCTION__));
2425 goto out;
2426 }
2427
2428 IstwiRWRequest = (ToolboxIstwiReadWriteRequest_t *)mf;
2429 mpi_hdr = (MPIHeader_t *) mf;
2430 memset(IstwiRWRequest,0,sizeof(ToolboxIstwiReadWriteRequest_t));
2431 IstwiRWRequest->Function = MPI_FUNCTION_TOOLBOX;
2432 IstwiRWRequest->Tool = MPI_TOOLBOX_ISTWI_READ_WRITE_TOOL;
2433 IstwiRWRequest->MsgContext = mpi_hdr->MsgContext;
2434 IstwiRWRequest->Flags = MPI_TB_ISTWI_FLAGS_READ;
2435 IstwiRWRequest->NumAddressBytes = 0x01;
2436 IstwiRWRequest->DataLength = cpu_to_le16(0x04);
2437 if (pdev->devfn & 1)
2438 IstwiRWRequest->DeviceAddr = 0xB2;
2439 else
2440 IstwiRWRequest->DeviceAddr = 0xB0;
2441
2420 pbuf = pci_alloc_consistent(ioc->pcidev, 4, &buf_dma); 2442 pbuf = pci_alloc_consistent(ioc->pcidev, 4, &buf_dma);
2421 if (pbuf) { 2443 if (!pbuf)
2422 cfg.physAddr = buf_dma; 2444 goto out;
2423 if ((mpt_toolbox(ioc, &cfg)) == 0) { 2445 mpt_add_sge((char *)&IstwiRWRequest->SGL,
2424 karg.rsvd = *(u32 *)pbuf; 2446 (MPT_SGE_FLAGS_SSIMPLE_READ|4), buf_dma);
2425 } 2447
2426 pci_free_consistent(ioc->pcidev, 4, pbuf, buf_dma); 2448 ioc->ioctl->wait_done = 0;
2427 pbuf = NULL; 2449 mpt_put_msg_frame(mptctl_id, ioc, mf);
2450
2451 rc = wait_event_timeout(mptctl_wait,
2452 ioc->ioctl->wait_done == 1,
2453 HZ*MPT_IOCTL_DEFAULT_TIMEOUT /* 10 sec */);
2454
2455 if(rc <=0 && (ioc->ioctl->wait_done != 1 )) {
2456 /*
2457 * Now we need to reset the board
2458 */
2459 mpt_free_msg_frame(ioc, mf);
2460 mptctl_timeout_expired(ioc->ioctl);
2461 goto out;
2428 } 2462 }
2429 2463
2464 /*
2465 *ISTWI Data Definition
2466 * pbuf[0] = FW_VERSION = 0x4
2467 * pbuf[1] = Bay Count = 6 or 4 or 2, depending on
2468 * the config, you should be seeing one out of these three values
2469 * pbuf[2] = Drive Installed Map = bit pattern depend on which
2470 * bays have drives in them
2471 * pbuf[3] = Checksum (0x100 = (byte0 + byte2 + byte3)
2472 */
2473 if (ioc->ioctl->status & MPT_IOCTL_STATUS_RF_VALID)
2474 karg.rsvd = *(u32 *)pbuf;
2475
2476 out:
2477 if (pbuf)
2478 pci_free_consistent(ioc->pcidev, 4, pbuf, buf_dma);
2479
2430 /* Copy the data from kernel memory to user memory 2480 /* Copy the data from kernel memory to user memory
2431 */ 2481 */
2432 if (copy_to_user((char __user *)arg, &karg, sizeof(hp_host_info_t))) { 2482 if (copy_to_user((char __user *)arg, &karg, sizeof(hp_host_info_t))) {