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))) { |