Loading Documentation/scsi/ChangeLog.megaraid_sas +23 −0 Original line number Diff line number Diff line 1 Release Date : Wed Feb 03 14:31:44 PST 2006 - Sumant Patro <Sumant.Patro@lsil.com> 2 Current Version : 00.00.02.04 3 Older Version : 00.00.02.04 i. Support for 1078 type (ppc IOP) controller, device id : 0x60 added. During initialization, depending on the device id, the template members are initialized with function pointers specific to the ppc or xscale controllers. -Sumant Patro <Sumant.Patro@lsil.com> 1 Release Date : Fri Feb 03 14:16:25 PST 2006 - Sumant Patro <Sumant.Patro@lsil.com> 2 Current Version : 00.00.02.04 3 Older Version : 00.00.02.02 i. Register 16 byte CDB capability with scsi midlayer "Ths patch properly registers the 16 byte command length capability of the megaraid_sas controlled hardware with the scsi midlayer. All megaraid_sas hardware supports 16 byte CDB's." -Joshua Giles <joshua_giles@dell.com> 1 Release Date : Mon Jan 23 14:09:01 PST 2006 - Sumant Patro <Sumant.Patro@lsil.com> 2 Current Version : 00.00.02.02 3 Older Version : 00.00.02.01 Loading drivers/message/fusion/mptbase.c +2 −113 Original line number Diff line number Diff line Loading @@ -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; Loading Loading @@ -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. Loading Loading @@ -6142,7 +6032,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; Loading Loading @@ -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); Loading drivers/message/fusion/mptbase.h +1 −1 Original line number Diff line number Diff line Loading @@ -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 */ Loading Loading @@ -1026,7 +1027,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); Loading drivers/message/fusion/mptctl.c +200 −41 Original line number Diff line number Diff line Loading @@ -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... Loading Loading @@ -385,18 +391,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; } Loading Loading @@ -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 Loading Loading @@ -674,22 +743,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; } dlmsg = (FWDownload_t*) mf; ptsge = (FWDownloadTCSGE_t *) &dlmsg->SGL; sgOut = (char *) (ptsge + 1); Loading @@ -702,8 +772,12 @@ 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; 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. */ ptsge->Reserved = 0; Loading Loading @@ -754,7 +828,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, Loading Loading @@ -803,11 +877,11 @@ 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 */ ret = wait_event_interruptible_timeout(mptctl_wait, ret = wait_event_timeout(mptctl_wait, iocp->ioctl->wait_done == 1, HZ*60); Loading Loading @@ -1145,7 +1219,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; Loading Loading @@ -1175,7 +1251,6 @@ mptctl_getiocinfo (unsigned long arg, unsigned int data_size) 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); } Loading Loading @@ -1500,7 +1575,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 Loading Loading @@ -1550,7 +1625,6 @@ mptctl_eventenable (unsigned long arg) memset(ioc->events, 0, sz); ioc->alloc_total += sz; ioc->eventLogSize = MPTCTL_EVENT_LOG_SIZE; ioc->eventContext = 0; } Loading Loading @@ -1590,7 +1664,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. Loading @@ -1598,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); Loading Loading @@ -1817,6 +1894,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: Loading @@ -1837,7 +1916,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 Loading Loading @@ -1888,6 +1969,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 */ Loading @@ -1900,7 +2000,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 Loading Loading @@ -2130,7 +2232,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); Loading Loading @@ -2246,13 +2348,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 Loading Loading @@ -2370,7 +2475,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; Loading @@ -2388,19 +2493,66 @@ 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; 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); pbuf = NULL; } /* Copy the data from kernel memory to user memory */ Loading Loading @@ -2459,7 +2611,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)) Loading Loading @@ -2569,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, Loading Loading @@ -2813,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: Loading drivers/message/fusion/mptctl.h +3 −1 Original line number Diff line number Diff line Loading @@ -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 { Loading Loading
Documentation/scsi/ChangeLog.megaraid_sas +23 −0 Original line number Diff line number Diff line 1 Release Date : Wed Feb 03 14:31:44 PST 2006 - Sumant Patro <Sumant.Patro@lsil.com> 2 Current Version : 00.00.02.04 3 Older Version : 00.00.02.04 i. Support for 1078 type (ppc IOP) controller, device id : 0x60 added. During initialization, depending on the device id, the template members are initialized with function pointers specific to the ppc or xscale controllers. -Sumant Patro <Sumant.Patro@lsil.com> 1 Release Date : Fri Feb 03 14:16:25 PST 2006 - Sumant Patro <Sumant.Patro@lsil.com> 2 Current Version : 00.00.02.04 3 Older Version : 00.00.02.02 i. Register 16 byte CDB capability with scsi midlayer "Ths patch properly registers the 16 byte command length capability of the megaraid_sas controlled hardware with the scsi midlayer. All megaraid_sas hardware supports 16 byte CDB's." -Joshua Giles <joshua_giles@dell.com> 1 Release Date : Mon Jan 23 14:09:01 PST 2006 - Sumant Patro <Sumant.Patro@lsil.com> 2 Current Version : 00.00.02.02 3 Older Version : 00.00.02.01 Loading
drivers/message/fusion/mptbase.c +2 −113 Original line number Diff line number Diff line Loading @@ -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; Loading Loading @@ -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. Loading Loading @@ -6142,7 +6032,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; Loading Loading @@ -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); Loading
drivers/message/fusion/mptbase.h +1 −1 Original line number Diff line number Diff line Loading @@ -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 */ Loading Loading @@ -1026,7 +1027,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); Loading
drivers/message/fusion/mptctl.c +200 −41 Original line number Diff line number Diff line Loading @@ -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... Loading Loading @@ -385,18 +391,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; } Loading Loading @@ -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 Loading Loading @@ -674,22 +743,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; } dlmsg = (FWDownload_t*) mf; ptsge = (FWDownloadTCSGE_t *) &dlmsg->SGL; sgOut = (char *) (ptsge + 1); Loading @@ -702,8 +772,12 @@ 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; 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. */ ptsge->Reserved = 0; Loading Loading @@ -754,7 +828,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, Loading Loading @@ -803,11 +877,11 @@ 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 */ ret = wait_event_interruptible_timeout(mptctl_wait, ret = wait_event_timeout(mptctl_wait, iocp->ioctl->wait_done == 1, HZ*60); Loading Loading @@ -1145,7 +1219,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; Loading Loading @@ -1175,7 +1251,6 @@ mptctl_getiocinfo (unsigned long arg, unsigned int data_size) 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); } Loading Loading @@ -1500,7 +1575,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 Loading Loading @@ -1550,7 +1625,6 @@ mptctl_eventenable (unsigned long arg) memset(ioc->events, 0, sz); ioc->alloc_total += sz; ioc->eventLogSize = MPTCTL_EVENT_LOG_SIZE; ioc->eventContext = 0; } Loading Loading @@ -1590,7 +1664,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. Loading @@ -1598,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); Loading Loading @@ -1817,6 +1894,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: Loading @@ -1837,7 +1916,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 Loading Loading @@ -1888,6 +1969,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 */ Loading @@ -1900,7 +2000,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 Loading Loading @@ -2130,7 +2232,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); Loading Loading @@ -2246,13 +2348,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 Loading Loading @@ -2370,7 +2475,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; Loading @@ -2388,19 +2493,66 @@ 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; 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); pbuf = NULL; } /* Copy the data from kernel memory to user memory */ Loading Loading @@ -2459,7 +2611,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)) Loading Loading @@ -2569,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, Loading Loading @@ -2813,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: Loading
drivers/message/fusion/mptctl.h +3 −1 Original line number Diff line number Diff line Loading @@ -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 { Loading