From 096f7a2a094af3007937d6fd21560e28dca0994d Mon Sep 17 00:00:00 2001 From: "Moore, Eric" Date: Thu, 2 Feb 2006 17:19:30 -0700 Subject: [SCSI] fusion - mptctl - MPTCOMMAND - adding function types. This adds support for new function types in the existing MPTCOMMAND ioctl. Signed-off-by: Eric Moore Signed-off-by: James Bottomley --- drivers/message/fusion/mptctl.c | 21 +++++++++++++++++++++ 1 file changed, 21 insertions(+) (limited to 'drivers/message') diff --git a/drivers/message/fusion/mptctl.c b/drivers/message/fusion/mptctl.c index bdf709987982..70a812a2514d 100644 --- a/drivers/message/fusion/mptctl.c +++ b/drivers/message/fusion/mptctl.c @@ -1817,6 +1817,8 @@ mptctl_do_mpt_command (struct mpt_ioctl_command karg, void __user *mfPtr) case MPI_FUNCTION_SCSI_ENCLOSURE_PROCESSOR: case MPI_FUNCTION_FW_DOWNLOAD: case MPI_FUNCTION_FC_PRIMITIVE_SEND: + case MPI_FUNCTION_TOOLBOX: + case MPI_FUNCTION_SAS_IO_UNIT_CONTROL: break; case MPI_FUNCTION_SCSI_IO_REQUEST: @@ -1888,6 +1890,25 @@ mptctl_do_mpt_command (struct mpt_ioctl_command karg, void __user *mfPtr) } break; + case MPI_FUNCTION_SMP_PASSTHROUGH: + /* Check mf->PassthruFlags to determine if + * transfer is ImmediateMode or not. + * Immediate mode returns data in the ReplyFrame. + * Else, we are sending request and response data + * in two SGLs at the end of the mf. + */ + break; + + case MPI_FUNCTION_SATA_PASSTHROUGH: + if (!ioc->sh) { + printk(KERN_ERR "%s@%d::mptctl_do_mpt_command - " + "SCSI driver is not loaded. \n", + __FILE__, __LINE__); + rc = -EFAULT; + goto done_free_mem; + } + break; + case MPI_FUNCTION_RAID_ACTION: /* Just add a SGE */ -- cgit v1.2.1 From 9cc1cfbc67d77164f5b612fcf833460eca4d81e9 Mon Sep 17 00:00:00 2001 From: "Moore, Eric" Date: Thu, 2 Feb 2006 17:19:33 -0700 Subject: [SCSI] fusion - mptctl - adding support for bus_type=SAS Add bus_type recognization in ioctl path for SAS. Signed-off-by: Eric Moore Signed-off-by: James Bottomley --- drivers/message/fusion/mptctl.c | 8 +++++--- drivers/message/fusion/mptctl.h | 4 +++- 2 files changed, 8 insertions(+), 4 deletions(-) (limited to 'drivers/message') diff --git a/drivers/message/fusion/mptctl.c b/drivers/message/fusion/mptctl.c index 70a812a2514d..1a1bc66c8e9c 100644 --- a/drivers/message/fusion/mptctl.c +++ b/drivers/message/fusion/mptctl.c @@ -1145,7 +1145,9 @@ mptctl_getiocinfo (unsigned long arg, unsigned int data_size) /* Fill in the data and return the structure to the calling * program */ - if (ioc->bus_type == FC) + if (ioc->bus_type == SAS) + karg->adapterType = MPT_IOCTL_INTERFACE_SAS; + else if (ioc->bus_type == FC) karg->adapterType = MPT_IOCTL_INTERFACE_FC; else karg->adapterType = MPT_IOCTL_INTERFACE_SCSI; @@ -2391,7 +2393,7 @@ mptctl_hp_hostinfo(unsigned long arg, unsigned int data_size) karg.base_io_addr = pci_resource_start(pdev, 0); - if (ioc->bus_type == FC) + if ((ioc->bus_type == SAS) || (ioc->bus_type == FC)) karg.bus_phys_width = HP_BUS_WIDTH_UNK; else karg.bus_phys_width = HP_BUS_WIDTH_16; @@ -2480,7 +2482,7 @@ mptctl_hp_targetinfo(unsigned long arg) /* There is nothing to do for FCP parts. */ - if (ioc->bus_type == FC) + if ((ioc->bus_type == SAS) || (ioc->bus_type == FC)) return 0; if ((ioc->spi_data.sdp0length == 0) || (ioc->sh == NULL)) diff --git a/drivers/message/fusion/mptctl.h b/drivers/message/fusion/mptctl.h index 518996e03481..a2f8a97992e6 100644 --- a/drivers/message/fusion/mptctl.h +++ b/drivers/message/fusion/mptctl.h @@ -169,8 +169,10 @@ struct mpt_ioctl_pci_info2 { * Read only. * Data starts at offset 0xC */ -#define MPT_IOCTL_INTERFACE_FC (0x01) #define MPT_IOCTL_INTERFACE_SCSI (0x00) +#define MPT_IOCTL_INTERFACE_FC (0x01) +#define MPT_IOCTL_INTERFACE_FC_IP (0x02) +#define MPT_IOCTL_INTERFACE_SAS (0x03) #define MPT_IOCTL_VERSION_LENGTH (32) struct mpt_ioctl_iocinfo { -- cgit v1.2.1 From 86a7dcaae9c67a344e51190734b98684072d181c Mon Sep 17 00:00:00 2001 From: "Moore, Eric" Date: Thu, 2 Feb 2006 17:19:37 -0700 Subject: [SCSI] fusion - mtctl - change to wait_event_timeout Change from using wait_event_interruptible_timeout to wait_event_timeout. Also delete white space and duplicate line of code. Signed-off-by: Eric Moore Signed-off-by: James Bottomley --- drivers/message/fusion/mptctl.c | 11 +++++------ 1 file changed, 5 insertions(+), 6 deletions(-) (limited to 'drivers/message') diff --git a/drivers/message/fusion/mptctl.c b/drivers/message/fusion/mptctl.c index 1a1bc66c8e9c..8e2369ff3322 100644 --- a/drivers/message/fusion/mptctl.c +++ b/drivers/message/fusion/mptctl.c @@ -385,18 +385,18 @@ static int mptctl_bus_reset(MPT_IOCTL *ioctl) } /* Now wait for the command to complete */ - ii = wait_event_interruptible_timeout(mptctl_wait, + ii = wait_event_timeout(mptctl_wait, ioctl->wait_done == 1, HZ*5 /* 5 second timeout */); if(ii <=0 && (ioctl->wait_done != 1 )) { + mpt_free_msg_frame(hd->ioc, mf); ioctl->wait_done = 0; retval = -1; /* return failure */ } mptctl_bus_reset_done: - mpt_free_msg_frame(hd->ioc, mf); mptctl_free_tm_flags(ioctl->ioc); return retval; } @@ -807,7 +807,7 @@ mptctl_do_fw_download(int ioc, char __user *ufwbuf, size_t fwlen) mpt_put_msg_frame(mptctl_id, iocp, mf); /* Now wait for the command to complete */ - ret = wait_event_interruptible_timeout(mptctl_wait, + ret = wait_event_timeout(mptctl_wait, iocp->ioctl->wait_done == 1, HZ*60); @@ -1172,12 +1172,11 @@ mptctl_getiocinfo (unsigned long arg, unsigned int data_size) karg->pciInfo.u.bits.deviceNumber = PCI_SLOT( pdev->devfn ); karg->pciInfo.u.bits.functionNumber = PCI_FUNC( pdev->devfn ); } else if (cim_rev == 2) { - /* Get the PCI bus, device, function and segment ID numbers + /* Get the PCI bus, device, function and segment ID numbers for the IOC */ karg->pciInfo.u.bits.busNumber = pdev->bus->number; karg->pciInfo.u.bits.deviceNumber = PCI_SLOT( pdev->devfn ); karg->pciInfo.u.bits.functionNumber = PCI_FUNC( pdev->devfn ); - karg->pciInfo.u.bits.functionNumber = PCI_FUNC( pdev->devfn ); karg->pciInfo.segmentID = pci_domain_nr(pdev->bus); } @@ -2153,7 +2152,7 @@ mptctl_do_mpt_command (struct mpt_ioctl_command karg, void __user *mfPtr) /* Now wait for the command to complete */ timeout = (karg.timeout > 0) ? karg.timeout : MPT_IOCTL_DEFAULT_TIMEOUT; - timeout = wait_event_interruptible_timeout(mptctl_wait, + timeout = wait_event_timeout(mptctl_wait, ioc->ioctl->wait_done == 1, HZ*timeout); -- cgit v1.2.1 From 5b5ef4f617f1706a23b0433d89a9c02ceb0980a5 Mon Sep 17 00:00:00 2001 From: "Moore, Eric" Date: Thu, 2 Feb 2006 17:19:40 -0700 Subject: [SCSI] fusion - mptctl - Event Log Fix Use the hard coded value MPTCTL_EVENT_LOG_SIZE to fix bug where in certain cases, the ioc->eventLogSize was initialized. Signed-off-by: Eric Moore Signed-off-by: James Bottomley --- drivers/message/fusion/mptbase.c | 2 +- drivers/message/fusion/mptctl.c | 5 ++--- drivers/message/fusion/mptscsih.c | 2 +- 3 files changed, 4 insertions(+), 5 deletions(-) (limited to 'drivers/message') diff --git a/drivers/message/fusion/mptbase.c b/drivers/message/fusion/mptbase.c index 9a2c7605d49c..a3751d86216e 100644 --- a/drivers/message/fusion/mptbase.c +++ b/drivers/message/fusion/mptbase.c @@ -6142,7 +6142,7 @@ ProcessEventNotification(MPT_ADAPTER *ioc, EventNotificationReply_t *pEventReply if (ioc->events && (ioc->eventTypes & ( 1 << event))) { int idx; - idx = ioc->eventContext % ioc->eventLogSize; + idx = ioc->eventContext % MPTCTL_EVENT_LOG_SIZE; ioc->events[idx].event = event; ioc->events[idx].eventContext = ioc->eventContext; diff --git a/drivers/message/fusion/mptctl.c b/drivers/message/fusion/mptctl.c index 8e2369ff3322..b603fb8e604b 100644 --- a/drivers/message/fusion/mptctl.c +++ b/drivers/message/fusion/mptctl.c @@ -1501,7 +1501,7 @@ mptctl_eventquery (unsigned long arg) return -ENODEV; } - karg.eventEntries = ioc->eventLogSize; + karg.eventEntries = MPTCTL_EVENT_LOG_SIZE; karg.eventTypes = ioc->eventTypes; /* Copy the data from kernel memory to user memory @@ -1551,7 +1551,6 @@ mptctl_eventenable (unsigned long arg) memset(ioc->events, 0, sz); ioc->alloc_total += sz; - ioc->eventLogSize = MPTCTL_EVENT_LOG_SIZE; ioc->eventContext = 0; } @@ -1591,7 +1590,7 @@ mptctl_eventreport (unsigned long arg) maxEvents = numBytes/sizeof(MPT_IOCTL_EVENTS); - max = ioc->eventLogSize < maxEvents ? ioc->eventLogSize : maxEvents; + max = MPTCTL_EVENT_LOG_SIZE < maxEvents ? MPTCTL_EVENT_LOG_SIZE : maxEvents; /* If fewer than 1 event is requested, there must have * been some type of error. diff --git a/drivers/message/fusion/mptscsih.c b/drivers/message/fusion/mptscsih.c index 05789e505464..4fee6befc93d 100644 --- a/drivers/message/fusion/mptscsih.c +++ b/drivers/message/fusion/mptscsih.c @@ -2489,7 +2489,7 @@ mptscsih_copy_sense_data(struct scsi_cmnd *sc, MPT_SCSI_HOST *hd, MPT_FRAME_HDR int idx; MPT_ADAPTER *ioc = hd->ioc; - idx = ioc->eventContext % ioc->eventLogSize; + idx = ioc->eventContext % MPTCTL_EVENT_LOG_SIZE; ioc->events[idx].event = MPI_EVENT_SCSI_DEVICE_STATUS_CHANGE; ioc->events[idx].eventContext = ioc->eventContext; -- cgit v1.2.1 From 5f07e2499d629045f7f8a60a5b442792f08732cb Mon Sep 17 00:00:00 2001 From: "Moore, Eric" Date: Thu, 2 Feb 2006 17:19:44 -0700 Subject: [SCSI] fusion - mptctl -sense width fix Bug fix for correctly setting sense width for the MPTCOMMAND ioctl. Signed-off-by: Eric Moore Signed-off-by: James Bottomley --- drivers/message/fusion/mptctl.c | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) (limited to 'drivers/message') diff --git a/drivers/message/fusion/mptctl.c b/drivers/message/fusion/mptctl.c index b603fb8e604b..be5fcd8db63b 100644 --- a/drivers/message/fusion/mptctl.c +++ b/drivers/message/fusion/mptctl.c @@ -1839,7 +1839,9 @@ mptctl_do_mpt_command (struct mpt_ioctl_command karg, void __user *mfPtr) goto done_free_mem; } - pScsiReq->MsgFlags = mpt_msg_flags(); + pScsiReq->MsgFlags &= ~MPI_SCSIIO_MSGFLGS_SENSE_WIDTH; + pScsiReq->MsgFlags |= mpt_msg_flags(); + /* verify that app has not requested * more sense data than driver @@ -1921,7 +1923,9 @@ mptctl_do_mpt_command (struct mpt_ioctl_command karg, void __user *mfPtr) int scsidir = MPI_SCSIIO_CONTROL_READ; int dataSize; - pScsiReq->MsgFlags = mpt_msg_flags(); + pScsiReq->MsgFlags &= ~MPI_SCSIIO_MSGFLGS_SENSE_WIDTH; + pScsiReq->MsgFlags |= mpt_msg_flags(); + /* verify that app has not requested * more sense data than driver -- cgit v1.2.1 From 592f9c2fc9725b922ba8c4b1d67318ea4a301b59 Mon Sep 17 00:00:00 2001 From: "Moore, Eric" Date: Thu, 2 Feb 2006 17:19:47 -0700 Subject: [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 Signed-off-by: James Bottomley --- drivers/message/fusion/mptbase.c | 113 +-------------------------------------- drivers/message/fusion/mptbase.h | 1 - drivers/message/fusion/mptctl.c | 74 ++++++++++++++++++++----- 3 files changed, 63 insertions(+), 125 deletions(-) (limited to 'drivers/message') 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) } else if (func == MPI_FUNCTION_EVENT_ACK) { dprintk((MYIOC_s_INFO_FMT "mpt_base_reply, EventAck reply received\n", ioc->name)); - } else if (func == MPI_FUNCTION_CONFIG || - func == MPI_FUNCTION_TOOLBOX) { + } else if (func == MPI_FUNCTION_CONFIG) { CONFIGPARMS *pCfg; unsigned long flags; @@ -5326,115 +5325,6 @@ mpt_config(MPT_ADAPTER *ioc, CONFIGPARMS *pCfg) 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. @@ -6540,7 +6430,6 @@ EXPORT_SYMBOL(mpt_lan_index); EXPORT_SYMBOL(mpt_stm_index); EXPORT_SYMBOL(mpt_HardResetHandler); EXPORT_SYMBOL(mpt_config); -EXPORT_SYMBOL(mpt_toolbox); EXPORT_SYMBOL(mpt_findImVolumes); EXPORT_SYMBOL(mpt_read_ioc_pg_3); 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); 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_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_free_fw_memory(MPT_ADAPTER *ioc); 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) hp_host_info_t __user *uarg = (void __user *) arg; MPT_ADAPTER *ioc; struct pci_dev *pdev; - char *pbuf; + char *pbuf=NULL; dma_addr_t buf_dma; hp_host_info_t karg; CONFIGPARMS cfg; ConfigPageHeader_t hdr; int iocnum; int rc, cim_rev; + ToolboxIstwiReadWriteRequest_t *IstwiRWRequest; + MPT_FRAME_HDR *mf = NULL; + MPIHeader_t *mpi_hdr; dctlprintk((": mptctl_hp_hostinfo called.\n")); /* Reset long to int. Should affect IA64 and SPARC only @@ -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; - cfg.dir = MPI_TB_ISTWI_FLAGS_READ; - cfg.timeout = 10; + /* + * Gather ISTWI(Industry Standard Two Wire Interface) Data + */ + 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); - if (pbuf) { - cfg.physAddr = buf_dma; - if ((mpt_toolbox(ioc, &cfg)) == 0) { - karg.rsvd = *(u32 *)pbuf; - } - pci_free_consistent(ioc->pcidev, 4, pbuf, buf_dma); - pbuf = NULL; + if (!pbuf) + goto out; + mpt_add_sge((char *)&IstwiRWRequest->SGL, + (MPT_SGE_FLAGS_SSIMPLE_READ|4), buf_dma); + + ioc->ioctl->wait_done = 0; + 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 */ if (copy_to_user((char __user *)arg, &karg, sizeof(hp_host_info_t))) { -- cgit v1.2.1 From 946cbf040adb9db05bb895a4b629537fd2d03b0e Mon Sep 17 00:00:00 2001 From: "Moore, Eric" Date: Thu, 2 Feb 2006 17:19:50 -0700 Subject: [SCSI] fusion - mptctl -firmware download fix Fix's firmware download ioctl to work with SAS. Signed-off-by: Eric Moore Signed-off-by: James Bottomley --- drivers/message/fusion/mptctl.c | 35 ++++++++++++++++++++--------------- 1 file changed, 20 insertions(+), 15 deletions(-) (limited to 'drivers/message') diff --git a/drivers/message/fusion/mptctl.c b/drivers/message/fusion/mptctl.c index 2df3b8756545..fe10cc0fe18e 100644 --- a/drivers/message/fusion/mptctl.c +++ b/drivers/message/fusion/mptctl.c @@ -674,22 +674,23 @@ mptctl_do_fw_download(int ioc, char __user *ufwbuf, size_t fwlen) u16 iocstat; pFWDownloadReply_t ReplyMsg = NULL; - dctlprintk((KERN_INFO "mptctl_do_fwdl called. mptctl_id = %xh.\n", mptctl_id)); + dctlprintk(("mptctl_do_fwdl called. mptctl_id = %xh.\n", mptctl_id)); - dctlprintk((KERN_INFO "DbG: kfwdl.bufp = %p\n", ufwbuf)); - dctlprintk((KERN_INFO "DbG: kfwdl.fwlen = %d\n", (int)fwlen)); - dctlprintk((KERN_INFO "DbG: kfwdl.ioc = %04xh\n", ioc)); + dctlprintk(("DbG: kfwdl.bufp = %p\n", ufwbuf)); + dctlprintk(("DbG: kfwdl.fwlen = %d\n", (int)fwlen)); + dctlprintk(("DbG: kfwdl.ioc = %04xh\n", ioc)); - if ((ioc = mpt_verify_adapter(ioc, &iocp)) < 0) { - dctlprintk(("%s@%d::_ioctl_fwdl - ioc%d not found!\n", - __FILE__, __LINE__, ioc)); + if (mpt_verify_adapter(ioc, &iocp) < 0) { + dctlprintk(("ioctl_fwdl - ioc%d not found!\n", + ioc)); return -ENODEV; /* (-6) No such device or address */ - } + } else { - /* Valid device. Get a message frame and construct the FW download message. - */ - if ((mf = mpt_get_msg_frame(mptctl_id, iocp)) == NULL) - return -EAGAIN; + /* Valid device. Get a message frame and construct the FW download message. + */ + if ((mf = mpt_get_msg_frame(mptctl_id, iocp)) == NULL) + return -EAGAIN; + } dlmsg = (FWDownload_t*) mf; ptsge = (FWDownloadTCSGE_t *) &dlmsg->SGL; sgOut = (char *) (ptsge + 1); @@ -702,7 +703,11 @@ mptctl_do_fw_download(int ioc, char __user *ufwbuf, size_t fwlen) dlmsg->ChainOffset = 0; dlmsg->Function = MPI_FUNCTION_FW_DOWNLOAD; dlmsg->Reserved1[0] = dlmsg->Reserved1[1] = dlmsg->Reserved1[2] = 0; - dlmsg->MsgFlags = 0; + if (iocp->facts.MsgVersion >= MPI_VERSION_01_05) + dlmsg->MsgFlags = MPI_FW_DOWNLOAD_MSGFLGS_LAST_SEGMENT; + else + dlmsg->MsgFlags = 0; + /* Set up the Transaction SGE. */ @@ -754,7 +759,7 @@ mptctl_do_fw_download(int ioc, char __user *ufwbuf, size_t fwlen) goto fwdl_out; } - dctlprintk((KERN_INFO "DbG: sgl buffer = %p, sgfrags = %d\n", sgl, numfrags)); + dctlprintk(("DbG: sgl buffer = %p, sgfrags = %d\n", sgl, numfrags)); /* * Parse SG list, copying sgl itself, @@ -803,7 +808,7 @@ mptctl_do_fw_download(int ioc, char __user *ufwbuf, size_t fwlen) /* * Finally, perform firmware download. */ - iocp->ioctl->wait_done = 0; + ReplyMsg = NULL; mpt_put_msg_frame(mptctl_id, iocp, mf); /* Now wait for the command to complete */ -- cgit v1.2.1 From ea5a7a82f9d2d8a81f8fa541c34a12b43d390f61 Mon Sep 17 00:00:00 2001 From: "Moore, Eric" Date: Thu, 2 Feb 2006 17:20:01 -0700 Subject: [SCSI] fusion - mptctl -adding asyn event notification support Adding aen support. Signed-off-by: Eric Moore Signed-off-by: James Bottomley --- drivers/message/fusion/mptbase.h | 1 + drivers/message/fusion/mptctl.c | 79 ++++++++++++++++++++++++++++++++++++++++ 2 files changed, 80 insertions(+) (limited to 'drivers/message') diff --git a/drivers/message/fusion/mptbase.h b/drivers/message/fusion/mptbase.h index 2e5377309cea..723d54300953 100644 --- a/drivers/message/fusion/mptbase.h +++ b/drivers/message/fusion/mptbase.h @@ -616,6 +616,7 @@ typedef struct _MPT_ADAPTER * increments by 32 bytes */ int errata_flag_1064; + int aen_event_read_flag; /* flag to indicate event log was read*/ u8 FirstWhoInit; u8 upload_fw; /* If set, do a fw upload */ u8 reload_fw; /* Force a FW Reload on next reset */ diff --git a/drivers/message/fusion/mptctl.c b/drivers/message/fusion/mptctl.c index fe10cc0fe18e..9b64e07400da 100644 --- a/drivers/message/fusion/mptctl.c +++ b/drivers/message/fusion/mptctl.c @@ -136,6 +136,12 @@ static void mptctl_free_tm_flags(MPT_ADAPTER *ioc); */ static int mptctl_ioc_reset(MPT_ADAPTER *ioc, int reset_phase); +/* + * Event Handler function + */ +static int mptctl_event_process(MPT_ADAPTER *ioc, EventNotificationReply_t *pEvReply); +struct fasync_struct *async_queue=NULL; + /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/ /* * Scatter gather list (SGL) sizes and limits... @@ -471,6 +477,69 @@ mptctl_ioc_reset(MPT_ADAPTER *ioc, int reset_phase) return 1; } +/*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/ +/* ASYNC Event Notification Support */ +static int +mptctl_event_process(MPT_ADAPTER *ioc, EventNotificationReply_t *pEvReply) +{ + u8 event; + + event = le32_to_cpu(pEvReply->Event) & 0xFF; + + dctlprintk(("%s() called\n", __FUNCTION__)); + if(async_queue == NULL) + return 1; + + /* Raise SIGIO for persistent events. + * TODO - this define is not in MPI spec yet, + * but they plan to set it to 0x21 + */ + if (event == 0x21 ) { + ioc->aen_event_read_flag=1; + dctlprintk(("Raised SIGIO to application\n")); + devtprintk(("Raised SIGIO to application\n")); + kill_fasync(&async_queue, SIGIO, POLL_IN); + return 1; + } + + /* This flag is set after SIGIO was raised, and + * remains set until the application has read + * the event log via ioctl=MPTEVENTREPORT + */ + if(ioc->aen_event_read_flag) + return 1; + + /* Signal only for the events that are + * requested for by the application + */ + if (ioc->events && (ioc->eventTypes & ( 1 << event))) { + ioc->aen_event_read_flag=1; + dctlprintk(("Raised SIGIO to application\n")); + devtprintk(("Raised SIGIO to application\n")); + kill_fasync(&async_queue, SIGIO, POLL_IN); + } + return 1; +} + +static int +mptctl_fasync(int fd, struct file *filep, int mode) +{ + MPT_ADAPTER *ioc; + + list_for_each_entry(ioc, &ioc_list, list) + ioc->aen_event_read_flag=0; + + dctlprintk(("%s() called\n", __FUNCTION__)); + return fasync_helper(fd, filep, mode, &async_queue); +} + +static int +mptctl_release(struct inode *inode, struct file *filep) +{ + dctlprintk(("%s() called\n", __FUNCTION__)); + return fasync_helper(-1, filep, 0, &async_queue); +} + /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/ /* * MPT ioctl handler @@ -1603,6 +1672,9 @@ mptctl_eventreport (unsigned long arg) if ((max < 1) || !ioc->events) return -ENODATA; + /* reset this flag so SIGIO can restart */ + ioc->aen_event_read_flag=0; + /* Copy the data from kernel memory to user memory */ numBytes = max * sizeof(MPT_IOCTL_EVENTS); @@ -2649,6 +2721,8 @@ mptctl_hp_targetinfo(unsigned long arg) static struct file_operations mptctl_fops = { .owner = THIS_MODULE, .llseek = no_llseek, + .release = mptctl_release, + .fasync = mptctl_fasync, .unlocked_ioctl = mptctl_ioctl, #ifdef CONFIG_COMPAT .compat_ioctl = compat_mpctl_ioctl, @@ -2893,6 +2967,11 @@ static int __init mptctl_init(void) /* FIXME! */ } + if (mpt_event_register(mptctl_id, mptctl_event_process) == 0) { + devtprintk((KERN_INFO MYNAM + ": Registered for IOC event notifications\n")); + } + return 0; out_fail: -- cgit v1.2.1