diff options
| -rw-r--r-- | drivers/message/fusion/mptbase.c | 113 | ||||
| -rw-r--r-- | drivers/message/fusion/mptbase.h | 1 | ||||
| -rw-r--r-- | drivers/message/fusion/mptctl.c | 74 |
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 | */ | ||
| 5343 | int | ||
| 5344 | mpt_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); | |||
| 6540 | EXPORT_SYMBOL(mpt_stm_index); | 6430 | EXPORT_SYMBOL(mpt_stm_index); |
| 6541 | EXPORT_SYMBOL(mpt_HardResetHandler); | 6431 | EXPORT_SYMBOL(mpt_HardResetHandler); |
| 6542 | EXPORT_SYMBOL(mpt_config); | 6432 | EXPORT_SYMBOL(mpt_config); |
| 6543 | EXPORT_SYMBOL(mpt_toolbox); | ||
| 6544 | EXPORT_SYMBOL(mpt_findImVolumes); | 6433 | EXPORT_SYMBOL(mpt_findImVolumes); |
| 6545 | EXPORT_SYMBOL(mpt_read_ioc_pg_3); | 6434 | EXPORT_SYMBOL(mpt_read_ioc_pg_3); |
| 6546 | EXPORT_SYMBOL(mpt_alloc_fw_memory); | 6435 | EXPORT_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); | |||
| 1026 | extern void mpt_print_ioc_summary(MPT_ADAPTER *ioc, char *buf, int *size, int len, int showlan); | 1026 | extern void mpt_print_ioc_summary(MPT_ADAPTER *ioc, char *buf, int *size, int len, int showlan); |
| 1027 | extern int mpt_HardResetHandler(MPT_ADAPTER *ioc, int sleepFlag); | 1027 | extern int mpt_HardResetHandler(MPT_ADAPTER *ioc, int sleepFlag); |
| 1028 | extern int mpt_config(MPT_ADAPTER *ioc, CONFIGPARMS *cfg); | 1028 | extern int mpt_config(MPT_ADAPTER *ioc, CONFIGPARMS *cfg); |
| 1029 | extern int mpt_toolbox(MPT_ADAPTER *ioc, CONFIGPARMS *cfg); | ||
| 1030 | extern void mpt_alloc_fw_memory(MPT_ADAPTER *ioc, int size); | 1029 | extern void mpt_alloc_fw_memory(MPT_ADAPTER *ioc, int size); |
| 1031 | extern void mpt_free_fw_memory(MPT_ADAPTER *ioc); | 1030 | extern void mpt_free_fw_memory(MPT_ADAPTER *ioc); |
| 1032 | extern int mpt_findImVolumes(MPT_ADAPTER *ioc); | 1031 | extern 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))) { |
