···0000000000000000000000011 Release Date : Mon Jan 23 14:09:01 PST 2006 - Sumant Patro <Sumant.Patro@lsil.com>22 Current Version : 00.00.02.0233 Older Version : 00.00.02.01
···1+1 Release Date : Wed Feb 03 14:31:44 PST 2006 - Sumant Patro <Sumant.Patro@lsil.com>2+2 Current Version : 00.00.02.043+3 Older Version : 00.00.02.04 4+5+i. Support for 1078 type (ppc IOP) controller, device id : 0x60 added.6+ During initialization, depending on the device id, the template members 7+ are initialized with function pointers specific to the ppc or 8+ xscale controllers. 9+10+ -Sumant Patro <Sumant.Patro@lsil.com>11+12+1 Release Date : Fri Feb 03 14:16:25 PST 2006 - Sumant Patro 13+ <Sumant.Patro@lsil.com>14+2 Current Version : 00.00.02.0415+3 Older Version : 00.00.02.02 16+i. Register 16 byte CDB capability with scsi midlayer 17+18+ "Ths patch properly registers the 16 byte command length capability of the 19+ megaraid_sas controlled hardware with the scsi midlayer. All megaraid_sas 20+ hardware supports 16 byte CDB's."21+22+ -Joshua Giles <joshua_giles@dell.com> 23+241 Release Date : Mon Jan 23 14:09:01 PST 2006 - Sumant Patro <Sumant.Patro@lsil.com>252 Current Version : 00.00.02.02263 Older Version : 00.00.02.01
+2-113
drivers/message/fusion/mptbase.c
···452 } else if (func == MPI_FUNCTION_EVENT_ACK) {453 dprintk((MYIOC_s_INFO_FMT "mpt_base_reply, EventAck reply received\n",454 ioc->name));455- } else if (func == MPI_FUNCTION_CONFIG ||456- func == MPI_FUNCTION_TOOLBOX) {457 CONFIGPARMS *pCfg;458 unsigned long flags;459···5326}53275328/*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/5329-/**5330- * mpt_toolbox - Generic function to issue toolbox message5331- * @ioc - Pointer to an adapter structure5332- * @cfg - Pointer to a toolbox structure. Struct contains5333- * action, page address, direction, physical address5334- * and pointer to a configuration page header5335- * Page header is updated.5336- *5337- * Returns 0 for success5338- * -EPERM if not allowed due to ISR context5339- * -EAGAIN if no msg frames currently available5340- * -EFAULT for non-successful reply or no reply (timeout)5341- */5342-int5343-mpt_toolbox(MPT_ADAPTER *ioc, CONFIGPARMS *pCfg)5344-{5345- ToolboxIstwiReadWriteRequest_t *pReq;5346- MPT_FRAME_HDR *mf;5347- struct pci_dev *pdev;5348- unsigned long flags;5349- int rc;5350- u32 flagsLength;5351- int in_isr;5352-5353- /* Prevent calling wait_event() (below), if caller happens5354- * to be in ISR context, because that is fatal!5355- */5356- in_isr = in_interrupt();5357- if (in_isr) {5358- dcprintk((MYIOC_s_WARN_FMT "toobox request not allowed in ISR context!\n",5359- ioc->name));5360- return -EPERM;5361- }5362-5363- /* Get and Populate a free Frame5364- */5365- if ((mf = mpt_get_msg_frame(mpt_base_index, ioc)) == NULL) {5366- dcprintk((MYIOC_s_WARN_FMT "mpt_toolbox: no msg frames!\n",5367- ioc->name));5368- return -EAGAIN;5369- }5370- pReq = (ToolboxIstwiReadWriteRequest_t *)mf;5371- pReq->Tool = pCfg->action;5372- pReq->Reserved = 0;5373- pReq->ChainOffset = 0;5374- pReq->Function = MPI_FUNCTION_TOOLBOX;5375- pReq->Reserved1 = 0;5376- pReq->Reserved2 = 0;5377- pReq->MsgFlags = 0;5378- pReq->Flags = pCfg->dir;5379- pReq->BusNum = 0;5380- pReq->Reserved3 = 0;5381- pReq->NumAddressBytes = 0x01;5382- pReq->Reserved4 = 0;5383- pReq->DataLength = cpu_to_le16(0x04);5384- pdev = ioc->pcidev;5385- if (pdev->devfn & 1)5386- pReq->DeviceAddr = 0xB2;5387- else5388- pReq->DeviceAddr = 0xB0;5389- pReq->Addr1 = 0;5390- pReq->Addr2 = 0;5391- pReq->Addr3 = 0;5392- pReq->Reserved5 = 0;5393-5394- /* Add a SGE to the config request.5395- */5396-5397- flagsLength = MPT_SGE_FLAGS_SSIMPLE_READ | 4;5398-5399- mpt_add_sge((char *)&pReq->SGL, flagsLength, pCfg->physAddr);5400-5401- dcprintk((MYIOC_s_INFO_FMT "Sending Toolbox request, Tool=%x\n",5402- ioc->name, pReq->Tool));5403-5404- /* Append pCfg pointer to end of mf5405- */5406- *((void **) (((u8 *) mf) + (ioc->req_sz - sizeof(void *)))) = (void *) pCfg;5407-5408- /* Initalize the timer5409- */5410- init_timer(&pCfg->timer);5411- pCfg->timer.data = (unsigned long) ioc;5412- pCfg->timer.function = mpt_timer_expired;5413- pCfg->wait_done = 0;5414-5415- /* Set the timer; ensure 10 second minimum */5416- if (pCfg->timeout < 10)5417- pCfg->timer.expires = jiffies + HZ*10;5418- else5419- pCfg->timer.expires = jiffies + HZ*pCfg->timeout;5420-5421- /* Add to end of Q, set timer and then issue this command */5422- spin_lock_irqsave(&ioc->FreeQlock, flags);5423- list_add_tail(&pCfg->linkage, &ioc->configQ);5424- spin_unlock_irqrestore(&ioc->FreeQlock, flags);5425-5426- add_timer(&pCfg->timer);5427- mpt_put_msg_frame(mpt_base_index, ioc, mf);5428- wait_event(mpt_waitq, pCfg->wait_done);5429-5430- /* mf has been freed - do not access */5431-5432- rc = pCfg->status;5433-5434- return rc;5435-}5436-5437-/*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/5438/*5439 * mpt_timer_expired - Call back for timer process.5440 * Used only internal config functionality.···6032 if (ioc->events && (ioc->eventTypes & ( 1 << event))) {6033 int idx;60346035- idx = ioc->eventContext % ioc->eventLogSize;60366037 ioc->events[idx].event = event;6038 ioc->events[idx].eventContext = ioc->eventContext;···6430EXPORT_SYMBOL(mpt_stm_index);6431EXPORT_SYMBOL(mpt_HardResetHandler);6432EXPORT_SYMBOL(mpt_config);6433-EXPORT_SYMBOL(mpt_toolbox);6434EXPORT_SYMBOL(mpt_findImVolumes);6435EXPORT_SYMBOL(mpt_read_ioc_pg_3);6436EXPORT_SYMBOL(mpt_alloc_fw_memory);
···452 } else if (func == MPI_FUNCTION_EVENT_ACK) {453 dprintk((MYIOC_s_INFO_FMT "mpt_base_reply, EventAck reply received\n",454 ioc->name));455+ } else if (func == MPI_FUNCTION_CONFIG) {0456 CONFIGPARMS *pCfg;457 unsigned long flags;458···5327}53285329/*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000005330/*5331 * mpt_timer_expired - Call back for timer process.5332 * Used only internal config functionality.···6142 if (ioc->events && (ioc->eventTypes & ( 1 << event))) {6143 int idx;61446145+ idx = ioc->eventContext % MPTCTL_EVENT_LOG_SIZE;61466147 ioc->events[idx].event = event;6148 ioc->events[idx].eventContext = ioc->eventContext;···6540EXPORT_SYMBOL(mpt_stm_index);6541EXPORT_SYMBOL(mpt_HardResetHandler);6542EXPORT_SYMBOL(mpt_config);06543EXPORT_SYMBOL(mpt_findImVolumes);6544EXPORT_SYMBOL(mpt_read_ioc_pg_3);6545EXPORT_SYMBOL(mpt_alloc_fw_memory);
+1-1
drivers/message/fusion/mptbase.h
···616 * increments by 32 bytes617 */618 int errata_flag_1064;0619 u8 FirstWhoInit;620 u8 upload_fw; /* If set, do a fw upload */621 u8 reload_fw; /* Force a FW Reload on next reset */···1027extern void mpt_print_ioc_summary(MPT_ADAPTER *ioc, char *buf, int *size, int len, int showlan);1028extern int mpt_HardResetHandler(MPT_ADAPTER *ioc, int sleepFlag);1029extern int mpt_config(MPT_ADAPTER *ioc, CONFIGPARMS *cfg);1030-extern int mpt_toolbox(MPT_ADAPTER *ioc, CONFIGPARMS *cfg);1031extern void mpt_alloc_fw_memory(MPT_ADAPTER *ioc, int size);1032extern void mpt_free_fw_memory(MPT_ADAPTER *ioc);1033extern int mpt_findImVolumes(MPT_ADAPTER *ioc);
···616 * increments by 32 bytes617 */618 int errata_flag_1064;619+ int aen_event_read_flag; /* flag to indicate event log was read*/620 u8 FirstWhoInit;621 u8 upload_fw; /* If set, do a fw upload */622 u8 reload_fw; /* Force a FW Reload on next reset */···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);1028extern int mpt_config(MPT_ADAPTER *ioc, CONFIGPARMS *cfg);01029extern void mpt_alloc_fw_memory(MPT_ADAPTER *ioc, int size);1030extern void mpt_free_fw_memory(MPT_ADAPTER *ioc);1031extern int mpt_findImVolumes(MPT_ADAPTER *ioc);
+201-42
drivers/message/fusion/mptctl.c
···136 */137static int mptctl_ioc_reset(MPT_ADAPTER *ioc, int reset_phase);138000000139/*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/140/*141 * Scatter gather list (SGL) sizes and limits...···391 }392393 /* Now wait for the command to complete */394- ii = wait_event_interruptible_timeout(mptctl_wait,395 ioctl->wait_done == 1,396 HZ*5 /* 5 second timeout */);397398 if(ii <=0 && (ioctl->wait_done != 1 )) {0399 ioctl->wait_done = 0;400 retval = -1; /* return failure */401 }402403mptctl_bus_reset_done:404405- mpt_free_msg_frame(hd->ioc, mf);406 mptctl_free_tm_flags(ioctl->ioc);407 return retval;408}···475 }476477 return 1;000000000000000000000000000000000000000000000000000000000000000478}479480/*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/···743 u16 iocstat;744 pFWDownloadReply_t ReplyMsg = NULL;745746- dctlprintk((KERN_INFO "mptctl_do_fwdl called. mptctl_id = %xh.\n", mptctl_id));747748- dctlprintk((KERN_INFO "DbG: kfwdl.bufp = %p\n", ufwbuf));749- dctlprintk((KERN_INFO "DbG: kfwdl.fwlen = %d\n", (int)fwlen));750- dctlprintk((KERN_INFO "DbG: kfwdl.ioc = %04xh\n", ioc));751752- if ((ioc = mpt_verify_adapter(ioc, &iocp)) < 0) {753- dctlprintk(("%s@%d::_ioctl_fwdl - ioc%d not found!\n",754- __FILE__, __LINE__, ioc));755 return -ENODEV; /* (-6) No such device or address */756- }757758- /* Valid device. Get a message frame and construct the FW download message.759- */760- if ((mf = mpt_get_msg_frame(mptctl_id, iocp)) == NULL)761- return -EAGAIN;0762 dlmsg = (FWDownload_t*) mf;763 ptsge = (FWDownloadTCSGE_t *) &dlmsg->SGL;764 sgOut = (char *) (ptsge + 1);···772 dlmsg->ChainOffset = 0;773 dlmsg->Function = MPI_FUNCTION_FW_DOWNLOAD;774 dlmsg->Reserved1[0] = dlmsg->Reserved1[1] = dlmsg->Reserved1[2] = 0;775- dlmsg->MsgFlags = 0;0000776777 /* Set up the Transaction SGE.778 */···828 goto fwdl_out;829 }830831- dctlprintk((KERN_INFO "DbG: sgl buffer = %p, sgfrags = %d\n", sgl, numfrags));832833 /*834 * Parse SG list, copying sgl itself,···877 /*878 * Finally, perform firmware download.879 */880- iocp->ioctl->wait_done = 0;881 mpt_put_msg_frame(mptctl_id, iocp, mf);882883 /* Now wait for the command to complete */884- ret = wait_event_interruptible_timeout(mptctl_wait,885 iocp->ioctl->wait_done == 1,886 HZ*60);887···1219 /* Fill in the data and return the structure to the calling1220 * program1221 */1222- if (ioc->bus_type == FC)001223 karg->adapterType = MPT_IOCTL_INTERFACE_FC;1224 else1225 karg->adapterType = MPT_IOCTL_INTERFACE_SCSI;···1246 karg->pciInfo.u.bits.deviceNumber = PCI_SLOT( pdev->devfn );1247 karg->pciInfo.u.bits.functionNumber = PCI_FUNC( pdev->devfn );1248 } else if (cim_rev == 2) {1249- /* Get the PCI bus, device, function and segment ID numbers 1250 for the IOC */1251 karg->pciInfo.u.bits.busNumber = pdev->bus->number;1252 karg->pciInfo.u.bits.deviceNumber = PCI_SLOT( pdev->devfn );1253- karg->pciInfo.u.bits.functionNumber = PCI_FUNC( pdev->devfn );1254 karg->pciInfo.u.bits.functionNumber = PCI_FUNC( pdev->devfn );1255 karg->pciInfo.segmentID = pci_domain_nr(pdev->bus);1256 }···1575 return -ENODEV;1576 }15771578- karg.eventEntries = ioc->eventLogSize;1579 karg.eventTypes = ioc->eventTypes;15801581 /* Copy the data from kernel memory to user memory···1625 memset(ioc->events, 0, sz);1626 ioc->alloc_total += sz;16271628- ioc->eventLogSize = MPTCTL_EVENT_LOG_SIZE;1629 ioc->eventContext = 0;1630 }1631···1664 maxEvents = numBytes/sizeof(MPT_IOCTL_EVENTS);166516661667- max = ioc->eventLogSize < maxEvents ? ioc->eventLogSize : maxEvents;16681669 /* If fewer than 1 event is requested, there must have1670 * been some type of error.1671 */1672 if ((max < 1) || !ioc->events)1673 return -ENODATA;00016741675 /* Copy the data from kernel memory to user memory1676 */···1894 case MPI_FUNCTION_SCSI_ENCLOSURE_PROCESSOR:1895 case MPI_FUNCTION_FW_DOWNLOAD:1896 case MPI_FUNCTION_FC_PRIMITIVE_SEND:001897 break;18981899 case MPI_FUNCTION_SCSI_IO_REQUEST:···1916 goto done_free_mem;1917 }19181919- pScsiReq->MsgFlags = mpt_msg_flags();0019201921 /* verify that app has not requested1922 * more sense data than driver···1969 }1970 break;197100000000000000000001972 case MPI_FUNCTION_RAID_ACTION:1973 /* Just add a SGE1974 */···2000 int scsidir = MPI_SCSIIO_CONTROL_READ;2001 int dataSize;20022003- pScsiReq->MsgFlags = mpt_msg_flags();0020042005 /* verify that app has not requested2006 * more sense data than driver···22322233 /* Now wait for the command to complete */2234 timeout = (karg.timeout > 0) ? karg.timeout : MPT_IOCTL_DEFAULT_TIMEOUT;2235- timeout = wait_event_interruptible_timeout(mptctl_wait,2236 ioc->ioctl->wait_done == 1,2237 HZ*timeout);2238···2348 hp_host_info_t __user *uarg = (void __user *) arg;2349 MPT_ADAPTER *ioc;2350 struct pci_dev *pdev;2351- char *pbuf;2352 dma_addr_t buf_dma;2353 hp_host_info_t karg;2354 CONFIGPARMS cfg;2355 ConfigPageHeader_t hdr;2356 int iocnum;2357 int rc, cim_rev;00023582359 dctlprintk((": mptctl_hp_hostinfo called.\n"));2360 /* Reset long to int. Should affect IA64 and SPARC only···24752476 karg.base_io_addr = pci_resource_start(pdev, 0);24772478- if (ioc->bus_type == FC)2479 karg.bus_phys_width = HP_BUS_WIDTH_UNK;2480 else2481 karg.bus_phys_width = HP_BUS_WIDTH_16;···2493 }2494 }24952496- cfg.pageAddr = 0;2497- cfg.action = MPI_TOOLBOX_ISTWI_READ_WRITE_TOOL;2498- cfg.dir = MPI_TB_ISTWI_FLAGS_READ;2499- cfg.timeout = 10;2500- pbuf = pci_alloc_consistent(ioc->pcidev, 4, &buf_dma);2501- if (pbuf) {2502- cfg.physAddr = buf_dma;2503- if ((mpt_toolbox(ioc, &cfg)) == 0) {2504- karg.rsvd = *(u32 *)pbuf;2505- }2506- pci_free_consistent(ioc->pcidev, 4, pbuf, buf_dma);2507- pbuf = NULL;2508 }000000000000000000000000000000000000000000000000000025092510 /* Copy the data from kernel memory to user memory2511 */···26112612 /* There is nothing to do for FCP parts.2613 */2614- if (ioc->bus_type == FC)2615 return 0;26162617 if ((ioc->spi_data.sdp0length == 0) || (ioc->sh == NULL))···2721static struct file_operations mptctl_fops = {2722 .owner = THIS_MODULE,2723 .llseek = no_llseek,002724 .unlocked_ioctl = mptctl_ioctl,2725#ifdef CONFIG_COMPAT2726 .compat_ioctl = compat_mpctl_ioctl,···2965 dprintk((KERN_INFO MYNAM ": Registered for IOC reset notifications\n"));2966 } else {2967 /* FIXME! */000002968 }29692970 return 0;
···136 */137static int mptctl_ioc_reset(MPT_ADAPTER *ioc, int reset_phase);138139+/*140+ * Event Handler function141+ */142+static int mptctl_event_process(MPT_ADAPTER *ioc, EventNotificationReply_t *pEvReply);143+struct fasync_struct *async_queue=NULL;144+145/*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/146/*147 * Scatter gather list (SGL) sizes and limits...···385 }386387 /* Now wait for the command to complete */388+ ii = wait_event_timeout(mptctl_wait,389 ioctl->wait_done == 1,390 HZ*5 /* 5 second timeout */);391392 if(ii <=0 && (ioctl->wait_done != 1 )) {393+ mpt_free_msg_frame(hd->ioc, mf);394 ioctl->wait_done = 0;395 retval = -1; /* return failure */396 }397398mptctl_bus_reset_done:3990400 mptctl_free_tm_flags(ioctl->ioc);401 return retval;402}···469 }470471 return 1;472+}473+474+/*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/475+/* ASYNC Event Notification Support */476+static int477+mptctl_event_process(MPT_ADAPTER *ioc, EventNotificationReply_t *pEvReply)478+{479+ u8 event;480+481+ event = le32_to_cpu(pEvReply->Event) & 0xFF;482+483+ dctlprintk(("%s() called\n", __FUNCTION__));484+ if(async_queue == NULL)485+ return 1;486+487+ /* Raise SIGIO for persistent events.488+ * TODO - this define is not in MPI spec yet,489+ * but they plan to set it to 0x21490+ */491+ if (event == 0x21 ) {492+ ioc->aen_event_read_flag=1;493+ dctlprintk(("Raised SIGIO to application\n"));494+ devtprintk(("Raised SIGIO to application\n"));495+ kill_fasync(&async_queue, SIGIO, POLL_IN);496+ return 1;497+ }498+499+ /* This flag is set after SIGIO was raised, and500+ * remains set until the application has read501+ * the event log via ioctl=MPTEVENTREPORT502+ */503+ if(ioc->aen_event_read_flag)504+ return 1;505+506+ /* Signal only for the events that are507+ * requested for by the application508+ */509+ if (ioc->events && (ioc->eventTypes & ( 1 << event))) {510+ ioc->aen_event_read_flag=1;511+ dctlprintk(("Raised SIGIO to application\n"));512+ devtprintk(("Raised SIGIO to application\n"));513+ kill_fasync(&async_queue, SIGIO, POLL_IN);514+ }515+ return 1;516+}517+518+static int519+mptctl_fasync(int fd, struct file *filep, int mode)520+{521+ MPT_ADAPTER *ioc;522+523+ list_for_each_entry(ioc, &ioc_list, list)524+ ioc->aen_event_read_flag=0;525+526+ dctlprintk(("%s() called\n", __FUNCTION__));527+ return fasync_helper(fd, filep, mode, &async_queue);528+}529+530+static int531+mptctl_release(struct inode *inode, struct file *filep)532+{533+ dctlprintk(("%s() called\n", __FUNCTION__));534+ return fasync_helper(-1, filep, 0, &async_queue);535}536537/*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/···674 u16 iocstat;675 pFWDownloadReply_t ReplyMsg = NULL;676677+ dctlprintk(("mptctl_do_fwdl called. mptctl_id = %xh.\n", mptctl_id));678679+ dctlprintk(("DbG: kfwdl.bufp = %p\n", ufwbuf));680+ dctlprintk(("DbG: kfwdl.fwlen = %d\n", (int)fwlen));681+ dctlprintk(("DbG: kfwdl.ioc = %04xh\n", ioc));682683+ if (mpt_verify_adapter(ioc, &iocp) < 0) {684+ dctlprintk(("ioctl_fwdl - ioc%d not found!\n",685+ ioc));686 return -ENODEV; /* (-6) No such device or address */687+ } else {688689+ /* Valid device. Get a message frame and construct the FW download message.690+ */691+ if ((mf = mpt_get_msg_frame(mptctl_id, iocp)) == NULL)692+ return -EAGAIN;693+ }694 dlmsg = (FWDownload_t*) mf;695 ptsge = (FWDownloadTCSGE_t *) &dlmsg->SGL;696 sgOut = (char *) (ptsge + 1);···702 dlmsg->ChainOffset = 0;703 dlmsg->Function = MPI_FUNCTION_FW_DOWNLOAD;704 dlmsg->Reserved1[0] = dlmsg->Reserved1[1] = dlmsg->Reserved1[2] = 0;705+ if (iocp->facts.MsgVersion >= MPI_VERSION_01_05)706+ dlmsg->MsgFlags = MPI_FW_DOWNLOAD_MSGFLGS_LAST_SEGMENT;707+ else708+ dlmsg->MsgFlags = 0;709+710711 /* Set up the Transaction SGE.712 */···754 goto fwdl_out;755 }756757+ dctlprintk(("DbG: sgl buffer = %p, sgfrags = %d\n", sgl, numfrags));758759 /*760 * Parse SG list, copying sgl itself,···803 /*804 * Finally, perform firmware download.805 */806+ ReplyMsg = NULL;807 mpt_put_msg_frame(mptctl_id, iocp, mf);808809 /* Now wait for the command to complete */810+ ret = wait_event_timeout(mptctl_wait,811 iocp->ioctl->wait_done == 1,812 HZ*60);813···1145 /* Fill in the data and return the structure to the calling1146 * program1147 */1148+ if (ioc->bus_type == SAS)1149+ karg->adapterType = MPT_IOCTL_INTERFACE_SAS;1150+ else if (ioc->bus_type == FC)1151 karg->adapterType = MPT_IOCTL_INTERFACE_FC;1152 else1153 karg->adapterType = MPT_IOCTL_INTERFACE_SCSI;···1170 karg->pciInfo.u.bits.deviceNumber = PCI_SLOT( pdev->devfn );1171 karg->pciInfo.u.bits.functionNumber = PCI_FUNC( pdev->devfn );1172 } else if (cim_rev == 2) {1173+ /* Get the PCI bus, device, function and segment ID numbers1174 for the IOC */1175 karg->pciInfo.u.bits.busNumber = pdev->bus->number;1176 karg->pciInfo.u.bits.deviceNumber = PCI_SLOT( pdev->devfn );01177 karg->pciInfo.u.bits.functionNumber = PCI_FUNC( pdev->devfn );1178 karg->pciInfo.segmentID = pci_domain_nr(pdev->bus);1179 }···1500 return -ENODEV;1501 }15021503+ karg.eventEntries = MPTCTL_EVENT_LOG_SIZE;1504 karg.eventTypes = ioc->eventTypes;15051506 /* Copy the data from kernel memory to user memory···1550 memset(ioc->events, 0, sz);1551 ioc->alloc_total += sz;155201553 ioc->eventContext = 0;1554 }1555···1590 maxEvents = numBytes/sizeof(MPT_IOCTL_EVENTS);159115921593+ max = MPTCTL_EVENT_LOG_SIZE < maxEvents ? MPTCTL_EVENT_LOG_SIZE : maxEvents;15941595 /* If fewer than 1 event is requested, there must have1596 * been some type of error.1597 */1598 if ((max < 1) || !ioc->events)1599 return -ENODATA;1600+1601+ /* reset this flag so SIGIO can restart */1602+ ioc->aen_event_read_flag=0;16031604 /* Copy the data from kernel memory to user memory1605 */···1817 case MPI_FUNCTION_SCSI_ENCLOSURE_PROCESSOR:1818 case MPI_FUNCTION_FW_DOWNLOAD:1819 case MPI_FUNCTION_FC_PRIMITIVE_SEND:1820+ case MPI_FUNCTION_TOOLBOX:1821+ case MPI_FUNCTION_SAS_IO_UNIT_CONTROL:1822 break;18231824 case MPI_FUNCTION_SCSI_IO_REQUEST:···1837 goto done_free_mem;1838 }18391840+ pScsiReq->MsgFlags &= ~MPI_SCSIIO_MSGFLGS_SENSE_WIDTH;1841+ pScsiReq->MsgFlags |= mpt_msg_flags();1842+18431844 /* verify that app has not requested1845 * more sense data than driver···1888 }1889 break;18901891+ case MPI_FUNCTION_SMP_PASSTHROUGH:1892+ /* Check mf->PassthruFlags to determine if1893+ * transfer is ImmediateMode or not.1894+ * Immediate mode returns data in the ReplyFrame.1895+ * Else, we are sending request and response data1896+ * in two SGLs at the end of the mf.1897+ */1898+ break;1899+1900+ case MPI_FUNCTION_SATA_PASSTHROUGH:1901+ if (!ioc->sh) {1902+ printk(KERN_ERR "%s@%d::mptctl_do_mpt_command - "1903+ "SCSI driver is not loaded. \n",1904+ __FILE__, __LINE__);1905+ rc = -EFAULT;1906+ goto done_free_mem;1907+ }1908+ break;1909+1910 case MPI_FUNCTION_RAID_ACTION:1911 /* Just add a SGE1912 */···1900 int scsidir = MPI_SCSIIO_CONTROL_READ;1901 int dataSize;19021903+ pScsiReq->MsgFlags &= ~MPI_SCSIIO_MSGFLGS_SENSE_WIDTH;1904+ pScsiReq->MsgFlags |= mpt_msg_flags();1905+19061907 /* verify that app has not requested1908 * more sense data than driver···21302131 /* Now wait for the command to complete */2132 timeout = (karg.timeout > 0) ? karg.timeout : MPT_IOCTL_DEFAULT_TIMEOUT;2133+ timeout = wait_event_timeout(mptctl_wait,2134 ioc->ioctl->wait_done == 1,2135 HZ*timeout);2136···2246 hp_host_info_t __user *uarg = (void __user *) arg;2247 MPT_ADAPTER *ioc;2248 struct pci_dev *pdev;2249+ char *pbuf=NULL;2250 dma_addr_t buf_dma;2251 hp_host_info_t karg;2252 CONFIGPARMS cfg;2253 ConfigPageHeader_t hdr;2254 int iocnum;2255 int rc, cim_rev;2256+ ToolboxIstwiReadWriteRequest_t *IstwiRWRequest;2257+ MPT_FRAME_HDR *mf = NULL;2258+ MPIHeader_t *mpi_hdr;22592260 dctlprintk((": mptctl_hp_hostinfo called.\n"));2261 /* Reset long to int. Should affect IA64 and SPARC only···23702371 karg.base_io_addr = pci_resource_start(pdev, 0);23722373+ if ((ioc->bus_type == SAS) || (ioc->bus_type == FC))2374 karg.bus_phys_width = HP_BUS_WIDTH_UNK;2375 else2376 karg.bus_phys_width = HP_BUS_WIDTH_16;···2388 }2389 }23902391+ /* 2392+ * Gather ISTWI(Industry Standard Two Wire Interface) Data2393+ */2394+ if ((mf = mpt_get_msg_frame(mptctl_id, ioc)) == NULL) {2395+ dfailprintk((MYIOC_s_WARN_FMT "%s, no msg frames!!\n",2396+ ioc->name,__FUNCTION__));2397+ goto out;000002398 }2399+2400+ IstwiRWRequest = (ToolboxIstwiReadWriteRequest_t *)mf;2401+ mpi_hdr = (MPIHeader_t *) mf;2402+ memset(IstwiRWRequest,0,sizeof(ToolboxIstwiReadWriteRequest_t));2403+ IstwiRWRequest->Function = MPI_FUNCTION_TOOLBOX;2404+ IstwiRWRequest->Tool = MPI_TOOLBOX_ISTWI_READ_WRITE_TOOL;2405+ IstwiRWRequest->MsgContext = mpi_hdr->MsgContext;2406+ IstwiRWRequest->Flags = MPI_TB_ISTWI_FLAGS_READ;2407+ IstwiRWRequest->NumAddressBytes = 0x01;2408+ IstwiRWRequest->DataLength = cpu_to_le16(0x04);2409+ if (pdev->devfn & 1)2410+ IstwiRWRequest->DeviceAddr = 0xB2;2411+ else2412+ IstwiRWRequest->DeviceAddr = 0xB0;2413+2414+ pbuf = pci_alloc_consistent(ioc->pcidev, 4, &buf_dma);2415+ if (!pbuf)2416+ goto out;2417+ mpt_add_sge((char *)&IstwiRWRequest->SGL,2418+ (MPT_SGE_FLAGS_SSIMPLE_READ|4), buf_dma);2419+2420+ ioc->ioctl->wait_done = 0;2421+ mpt_put_msg_frame(mptctl_id, ioc, mf);2422+2423+ rc = wait_event_timeout(mptctl_wait,2424+ ioc->ioctl->wait_done == 1,2425+ HZ*MPT_IOCTL_DEFAULT_TIMEOUT /* 10 sec */);2426+2427+ if(rc <=0 && (ioc->ioctl->wait_done != 1 )) {2428+ /* 2429+ * Now we need to reset the board2430+ */2431+ mpt_free_msg_frame(ioc, mf);2432+ mptctl_timeout_expired(ioc->ioctl);2433+ goto out;2434+ }2435+2436+ /* 2437+ *ISTWI Data Definition2438+ * pbuf[0] = FW_VERSION = 0x42439+ * pbuf[1] = Bay Count = 6 or 4 or 2, depending on2440+ * the config, you should be seeing one out of these three values2441+ * pbuf[2] = Drive Installed Map = bit pattern depend on which2442+ * bays have drives in them2443+ * pbuf[3] = Checksum (0x100 = (byte0 + byte2 + byte3)2444+ */2445+ if (ioc->ioctl->status & MPT_IOCTL_STATUS_RF_VALID)2446+ karg.rsvd = *(u32 *)pbuf;2447+2448+ out:2449+ if (pbuf)2450+ pci_free_consistent(ioc->pcidev, 4, pbuf, buf_dma);24512452 /* Copy the data from kernel memory to user memory2453 */···24592460 /* There is nothing to do for FCP parts.2461 */2462+ if ((ioc->bus_type == SAS) || (ioc->bus_type == FC))2463 return 0;24642465 if ((ioc->spi_data.sdp0length == 0) || (ioc->sh == NULL))···2569static struct file_operations mptctl_fops = {2570 .owner = THIS_MODULE,2571 .llseek = no_llseek,2572+ .release = mptctl_release,2573+ .fasync = mptctl_fasync,2574 .unlocked_ioctl = mptctl_ioctl,2575#ifdef CONFIG_COMPAT2576 .compat_ioctl = compat_mpctl_ioctl,···2811 dprintk((KERN_INFO MYNAM ": Registered for IOC reset notifications\n"));2812 } else {2813 /* FIXME! */2814+ }2815+2816+ if (mpt_event_register(mptctl_id, mptctl_event_process) == 0) {2817+ devtprintk((KERN_INFO MYNAM2818+ ": Registered for IOC event notifications\n"));2819 }28202821 return 0;
+3-1
drivers/message/fusion/mptctl.h
···169 * Read only.170 * Data starts at offset 0xC171 */172-#define MPT_IOCTL_INTERFACE_FC (0x01)173#define MPT_IOCTL_INTERFACE_SCSI (0x00)000174#define MPT_IOCTL_VERSION_LENGTH (32)175176struct mpt_ioctl_iocinfo {
···63 unsigned size;64 int retval;6566- fibptr = fib_alloc(dev);67 if(fibptr == NULL) {68 return -ENOMEM;69 }···73 * First copy in the header so that we can check the size field.74 */75 if (copy_from_user((void *)kfib, arg, sizeof(struct aac_fibhdr))) {76- fib_free(fibptr);77 return -EFAULT;78 }79 /*···110 */111 kfib->header.XferState = 0;112 } else {113- retval = fib_send(le16_to_cpu(kfib->header.Command), fibptr,114 le16_to_cpu(kfib->header.Size) , FsaNormal,115 1, 1, NULL, NULL);116 if (retval) {117 goto cleanup;118 }119- if (fib_complete(fibptr) != 0) {120 retval = -EINVAL;121 goto cleanup;122 }···138 fibptr->hw_fib_pa = hw_fib_pa;139 fibptr->hw_fib = hw_fib;140 }141- fib_free(fibptr);142 return retval;143}144···464 /*465 * Allocate and initialize a Fib then setup a BlockWrite command466 */467- if (!(srbfib = fib_alloc(dev))) {468 return -ENOMEM;469 }470- fib_init(srbfib);471472 srbcmd = (struct aac_srb*) fib_data(srbfib);473···601602 srbcmd->count = cpu_to_le32(byte_count);603 psg->count = cpu_to_le32(sg_indx+1);604- status = fib_send(ScsiPortCommand64, srbfib, actual_fibsize, FsaNormal, 1, 1,NULL,NULL);605 } else {606 struct user_sgmap* upsg = &user_srbcmd->sg;607 struct sgmap* psg = &srbcmd->sg;···649 }650 srbcmd->count = cpu_to_le32(byte_count);651 psg->count = cpu_to_le32(sg_indx+1);652- status = fib_send(ScsiPortCommand, srbfib, actual_fibsize, FsaNormal, 1, 1, NULL, NULL);653 }654655 if (status != 0){···684 for(i=0; i <= sg_indx; i++){685 kfree(sg_list[i]);686 }687- fib_complete(srbfib);688- fib_free(srbfib);689690 return rcode;691}
···63 unsigned size;64 int retval;6566+ fibptr = aac_fib_alloc(dev);67 if(fibptr == NULL) {68 return -ENOMEM;69 }···73 * First copy in the header so that we can check the size field.74 */75 if (copy_from_user((void *)kfib, arg, sizeof(struct aac_fibhdr))) {76+ aac_fib_free(fibptr);77 return -EFAULT;78 }79 /*···110 */111 kfib->header.XferState = 0;112 } else {113+ retval = aac_fib_send(le16_to_cpu(kfib->header.Command), fibptr,114 le16_to_cpu(kfib->header.Size) , FsaNormal,115 1, 1, NULL, NULL);116 if (retval) {117 goto cleanup;118 }119+ if (aac_fib_complete(fibptr) != 0) {120 retval = -EINVAL;121 goto cleanup;122 }···138 fibptr->hw_fib_pa = hw_fib_pa;139 fibptr->hw_fib = hw_fib;140 }141+ aac_fib_free(fibptr);142 return retval;143}144···464 /*465 * Allocate and initialize a Fib then setup a BlockWrite command466 */467+ if (!(srbfib = aac_fib_alloc(dev))) {468 return -ENOMEM;469 }470+ aac_fib_init(srbfib);471472 srbcmd = (struct aac_srb*) fib_data(srbfib);473···601602 srbcmd->count = cpu_to_le32(byte_count);603 psg->count = cpu_to_le32(sg_indx+1);604+ status = aac_fib_send(ScsiPortCommand64, srbfib, actual_fibsize, FsaNormal, 1, 1,NULL,NULL);605 } else {606 struct user_sgmap* upsg = &user_srbcmd->sg;607 struct sgmap* psg = &srbcmd->sg;···649 }650 srbcmd->count = cpu_to_le32(byte_count);651 psg->count = cpu_to_le32(sg_indx+1);652+ status = aac_fib_send(ScsiPortCommand, srbfib, actual_fibsize, FsaNormal, 1, 1, NULL, NULL);653 }654655 if (status != 0){···684 for(i=0; i <= sg_indx; i++){685 kfree(sg_list[i]);686 }687+ aac_fib_complete(srbfib);688+ aac_fib_free(srbfib);689690 return rcode;691}
+6-6
drivers/scsi/aacraid/comminit.c
···185 struct aac_close *cmd;186 int status;187188- fibctx = fib_alloc(dev);189 if (!fibctx)190 return -ENOMEM;191- fib_init(fibctx);192193 cmd = (struct aac_close *) fib_data(fibctx);194195 cmd->command = cpu_to_le32(VM_CloseAll);196 cmd->cid = cpu_to_le32(0xffffffff);197198- status = fib_send(ContainerCommand,199 fibctx,200 sizeof(struct aac_close),201 FsaNormal,···203 NULL, NULL);204205 if (status == 0)206- fib_complete(fibctx);207- fib_free(fibctx);208 return status;209}210···427 /*428 * Initialize the list of fibs429 */430- if(fib_setup(dev)<0){431 kfree(dev->queues);432 return NULL;433 }
···185 struct aac_close *cmd;186 int status;187188+ fibctx = aac_fib_alloc(dev);189 if (!fibctx)190 return -ENOMEM;191+ aac_fib_init(fibctx);192193 cmd = (struct aac_close *) fib_data(fibctx);194195 cmd->command = cpu_to_le32(VM_CloseAll);196 cmd->cid = cpu_to_le32(0xffffffff);197198+ status = aac_fib_send(ContainerCommand,199 fibctx,200 sizeof(struct aac_close),201 FsaNormal,···203 NULL, NULL);204205 if (status == 0)206+ aac_fib_complete(fibctx);207+ aac_fib_free(fibctx);208 return status;209}210···427 /*428 * Initialize the list of fibs429 */430+ if (aac_fib_setup(dev) < 0) {431 kfree(dev->queues);432 return NULL;433 }
+26-24
drivers/scsi/aacraid/commsup.c
···67}6869/**70- * fib_map_free - free the fib objects71 * @dev: Adapter to free72 *73 * Free the PCI mappings and the memory allocated for FIB blocks74 * on this adapter.75 */7677-void fib_map_free(struct aac_dev *dev)78{79 pci_free_consistent(dev->pdev, dev->max_fib_size * (dev->scsi_host_ptr->can_queue + AAC_NUM_MGT_FIB), dev->hw_fib_va, dev->hw_fib_pa);80}8182/**83- * fib_setup - setup the fibs84 * @dev: Adapter to set up85 *86 * Allocate the PCI space for the fibs, map it and then intialise the87 * fib area, the unmapped fib data and also the free list88 */8990-int fib_setup(struct aac_dev * dev)91{92 struct fib *fibptr;93 struct hw_fib *hw_fib_va;···134}135136/**137- * fib_alloc - allocate a fib138 * @dev: Adapter to allocate the fib for139 *140 * Allocate a fib from the adapter fib pool. If the pool is empty we141 * return NULL.142 */143144-struct fib * fib_alloc(struct aac_dev *dev)145{146 struct fib * fibptr;147 unsigned long flags;···170}171172/**173- * fib_free - free a fib174 * @fibptr: fib to free up175 *176 * Frees up a fib and places it on the appropriate queue177 * (either free or timed out)178 */179180-void fib_free(struct fib * fibptr)181{182 unsigned long flags;183···188 fibptr->dev->timeout_fib = fibptr;189 } else {190 if (fibptr->hw_fib->header.XferState != 0) {191- printk(KERN_WARNING "fib_free, XferState != 0, fibptr = 0x%p, XferState = 0x%x\n", 192 (void*)fibptr, 193 le32_to_cpu(fibptr->hw_fib->header.XferState));194 }···199}200201/**202- * fib_init - initialise a fib203 * @fibptr: The fib to initialize204 * 205 * Set up the generic fib fields ready for use206 */207208-void fib_init(struct fib *fibptr)209{210 struct hw_fib *hw_fib = fibptr->hw_fib;211···362 */363364/**365- * fib_send - send a fib to the adapter366 * @command: Command to send367 * @fibptr: The fib368 * @size: Size of fib data area···378 * response FIB is received from the adapter.379 */380381-int fib_send(u16 command, struct fib * fibptr, unsigned long size, int priority, int wait, int reply, fib_callback callback, void * callback_data)00382{383 struct aac_dev * dev = fibptr->dev;384 struct hw_fib * hw_fib = fibptr->hw_fib;···495 q->numpending++;496 *(q->headers.producer) = cpu_to_le32(index + 1);497 spin_unlock_irqrestore(q->lock, qflags);498- dprintk((KERN_DEBUG "fib_send: inserting a queue entry at index %d.\n",index));499 if (!(nointr & aac_config.irq_mod))500 aac_adapter_notify(dev, AdapNormCmdQueue);501 }···522 list_del(&fibptr->queue);523 spin_unlock_irqrestore(q->lock, qflags);524 if (wait == -1) {525- printk(KERN_ERR "aacraid: fib_send: first asynchronous command timed out.\n"526 "Usually a result of a PCI interrupt routing problem;\n"527 "update mother board BIOS or consider utilizing one of\n"528 "the SAFE mode kernel options (acpi, apic etc)\n");···626} 627628/**629- * fib_adapter_complete - complete adapter issued fib630 * @fibptr: fib to complete631 * @size: size of fib632 *···634 * the adapter.635 */636637-int fib_adapter_complete(struct fib * fibptr, unsigned short size)638{639 struct hw_fib * hw_fib = fibptr->hw_fib;640 struct aac_dev * dev = fibptr->dev;···685 }686 else 687 {688- printk(KERN_WARNING "fib_adapter_complete: Unknown xferstate detected.\n");689 BUG();690 } 691 return 0;692}693694/**695- * fib_complete - fib completion handler696 * @fib: FIB to complete697 *698 * Will do all necessary work to complete a FIB.699 */700701-int fib_complete(struct fib * fibptr)702{703 struct hw_fib * hw_fib = fibptr->hw_fib;704···997 if (!dev || !dev->scsi_host_ptr)998 return;999 /*1000- * force reload of disk info via probe_container1001 */1002 if ((device_config_needed == CHANGE)1003 && (dev->fsa_dev[container].valid == 1))1004 dev->fsa_dev[container].valid = 2;1005 if ((device_config_needed == CHANGE) ||1006 (device_config_needed == ADD))1007- probe_container(dev, container);1008 device = scsi_device_lookup(dev->scsi_host_ptr, 1009 CONTAINER_TO_CHANNEL(container), 1010 CONTAINER_TO_ID(container), ···1106 /* Handle Driver Notify Events */1107 aac_handle_aif(dev, fib);1108 *(__le32 *)hw_fib->data = cpu_to_le32(ST_OK);1109- fib_adapter_complete(fib, (u16)sizeof(u32));1110 } else {1111 struct list_head *entry;1112 /* The u32 here is important and intended. We are using···1243 * Set the status of this FIB1244 */1245 *(__le32 *)hw_fib->data = cpu_to_le32(ST_OK);1246- fib_adapter_complete(fib, sizeof(u32));1247 spin_unlock_irqrestore(&dev->fib_lock, flagv);1248 /* Free up the remaining resources */1249 hw_fib_p = hw_fib_pool;
···67}6869/**70+ * aac_fib_map_free - free the fib objects71 * @dev: Adapter to free72 *73 * Free the PCI mappings and the memory allocated for FIB blocks74 * on this adapter.75 */7677+void aac_fib_map_free(struct aac_dev *dev)78{79 pci_free_consistent(dev->pdev, dev->max_fib_size * (dev->scsi_host_ptr->can_queue + AAC_NUM_MGT_FIB), dev->hw_fib_va, dev->hw_fib_pa);80}8182/**83+ * aac_fib_setup - setup the fibs84 * @dev: Adapter to set up85 *86 * Allocate the PCI space for the fibs, map it and then intialise the87 * fib area, the unmapped fib data and also the free list88 */8990+int aac_fib_setup(struct aac_dev * dev)91{92 struct fib *fibptr;93 struct hw_fib *hw_fib_va;···134}135136/**137+ * aac_fib_alloc - allocate a fib138 * @dev: Adapter to allocate the fib for139 *140 * Allocate a fib from the adapter fib pool. If the pool is empty we141 * return NULL.142 */143144+struct fib *aac_fib_alloc(struct aac_dev *dev)145{146 struct fib * fibptr;147 unsigned long flags;···170}171172/**173+ * aac_fib_free - free a fib174 * @fibptr: fib to free up175 *176 * Frees up a fib and places it on the appropriate queue177 * (either free or timed out)178 */179180+void aac_fib_free(struct fib *fibptr)181{182 unsigned long flags;183···188 fibptr->dev->timeout_fib = fibptr;189 } else {190 if (fibptr->hw_fib->header.XferState != 0) {191+ printk(KERN_WARNING "aac_fib_free, XferState != 0, fibptr = 0x%p, XferState = 0x%x\n",192 (void*)fibptr, 193 le32_to_cpu(fibptr->hw_fib->header.XferState));194 }···199}200201/**202+ * aac_fib_init - initialise a fib203 * @fibptr: The fib to initialize204 * 205 * Set up the generic fib fields ready for use206 */207208+void aac_fib_init(struct fib *fibptr)209{210 struct hw_fib *hw_fib = fibptr->hw_fib;211···362 */363364/**365+ * aac_fib_send - send a fib to the adapter366 * @command: Command to send367 * @fibptr: The fib368 * @size: Size of fib data area···378 * response FIB is received from the adapter.379 */380381+int aac_fib_send(u16 command, struct fib *fibptr, unsigned long size,382+ int priority, int wait, int reply, fib_callback callback,383+ void *callback_data)384{385 struct aac_dev * dev = fibptr->dev;386 struct hw_fib * hw_fib = fibptr->hw_fib;···493 q->numpending++;494 *(q->headers.producer) = cpu_to_le32(index + 1);495 spin_unlock_irqrestore(q->lock, qflags);496+ dprintk((KERN_DEBUG "aac_fib_send: inserting a queue entry at index %d.\n",index));497 if (!(nointr & aac_config.irq_mod))498 aac_adapter_notify(dev, AdapNormCmdQueue);499 }···520 list_del(&fibptr->queue);521 spin_unlock_irqrestore(q->lock, qflags);522 if (wait == -1) {523+ printk(KERN_ERR "aacraid: aac_fib_send: first asynchronous command timed out.\n"524 "Usually a result of a PCI interrupt routing problem;\n"525 "update mother board BIOS or consider utilizing one of\n"526 "the SAFE mode kernel options (acpi, apic etc)\n");···624} 625626/**627+ * aac_fib_adapter_complete - complete adapter issued fib628 * @fibptr: fib to complete629 * @size: size of fib630 *···632 * the adapter.633 */634635+int aac_fib_adapter_complete(struct fib *fibptr, unsigned short size)636{637 struct hw_fib * hw_fib = fibptr->hw_fib;638 struct aac_dev * dev = fibptr->dev;···683 }684 else 685 {686+ printk(KERN_WARNING "aac_fib_adapter_complete: Unknown xferstate detected.\n");687 BUG();688 } 689 return 0;690}691692/**693+ * aac_fib_complete - fib completion handler694 * @fib: FIB to complete695 *696 * Will do all necessary work to complete a FIB.697 */698699+int aac_fib_complete(struct fib *fibptr)700{701 struct hw_fib * hw_fib = fibptr->hw_fib;702···995 if (!dev || !dev->scsi_host_ptr)996 return;997 /*998+ * force reload of disk info via aac_probe_container999 */1000 if ((device_config_needed == CHANGE)1001 && (dev->fsa_dev[container].valid == 1))1002 dev->fsa_dev[container].valid = 2;1003 if ((device_config_needed == CHANGE) ||1004 (device_config_needed == ADD))1005+ aac_probe_container(dev, container);1006 device = scsi_device_lookup(dev->scsi_host_ptr, 1007 CONTAINER_TO_CHANNEL(container), 1008 CONTAINER_TO_ID(container), ···1104 /* Handle Driver Notify Events */1105 aac_handle_aif(dev, fib);1106 *(__le32 *)hw_fib->data = cpu_to_le32(ST_OK);1107+ aac_fib_adapter_complete(fib, (u16)sizeof(u32));1108 } else {1109 struct list_head *entry;1110 /* The u32 here is important and intended. We are using···1241 * Set the status of this FIB1242 */1243 *(__le32 *)hw_fib->data = cpu_to_le32(ST_OK);1244+ aac_fib_adapter_complete(fib, sizeof(u32));1245 spin_unlock_irqrestore(&dev->fib_lock, flagv);1246 /* Free up the remaining resources */1247 hw_fib_p = hw_fib_pool;
+1-1
drivers/scsi/aacraid/dpcsup.c
···206 * Set the status of this FIB207 */208 *(__le32 *)hw_fib->data = cpu_to_le32(ST_OK);209- fib_adapter_complete(fib, sizeof(u32));210 spin_lock_irqsave(q->lock, flags);211 } 212 }
···206 * Set the status of this FIB207 */208 *(__le32 *)hw_fib->data = cpu_to_le32(ST_OK);209+ aac_fib_adapter_complete(fib, sizeof(u32));210 spin_lock_irqsave(q->lock, flags);211 } 212 }
+39-11
drivers/scsi/aacraid/linit.c
···385386static int aac_slave_configure(struct scsi_device *sdev)387{388- struct Scsi_Host *host = sdev->host;0000000000000000389390- if (sdev->tagged_supported)391- scsi_adjust_queue_depth(sdev, MSG_ORDERED_TAG, 128);392- else0000000000000000393 scsi_adjust_queue_depth(sdev, 0, 1);394-395- if (!(((struct aac_dev *)host->hostdata)->adapter_info.options396- & AAC_OPT_NEW_COMM))397- blk_queue_max_segment_size(sdev->request_queue, 65536);398399 return 0;400}···898899 /*900 * max channel will be the physical channels plus 1 virtual channel901- * all containers are on the virtual channel 0902 * physical channels are address by their actual physical number+1903 */904 if (aac->nondasd_support == 1)···941 aac_adapter_disable_int(aac);942 free_irq(pdev->irq, aac);943 out_unmap:944- fib_map_free(aac);945 pci_free_consistent(aac->pdev, aac->comm_size, aac->comm_addr, aac->comm_phys);946 kfree(aac->queues);947 iounmap(aac->regs.sa);···975976 aac_send_shutdown(aac);977 aac_adapter_disable_int(aac);978- fib_map_free(aac);979 pci_free_consistent(aac->pdev, aac->comm_size, aac->comm_addr,980 aac->comm_phys);981 kfree(aac->queues);
···385386static int aac_slave_configure(struct scsi_device *sdev)387{388+ if (sdev_channel(sdev) == CONTAINER_CHANNEL) {389+ sdev->skip_ms_page_8 = 1;390+ sdev->skip_ms_page_3f = 1;391+ }392+ if ((sdev->type == TYPE_DISK) &&393+ (sdev_channel(sdev) != CONTAINER_CHANNEL)) {394+ struct aac_dev *aac = (struct aac_dev *)sdev->host->hostdata;395+ if (!aac->raid_scsi_mode || (sdev_channel(sdev) != 2))396+ sdev->no_uld_attach = 1;397+ }398+ if (sdev->tagged_supported && (sdev->type == TYPE_DISK) &&399+ (sdev_channel(sdev) == CONTAINER_CHANNEL)) {400+ struct scsi_device * dev;401+ struct Scsi_Host *host = sdev->host;402+ unsigned num_lsu = 0;403+ unsigned num_one = 0;404+ unsigned depth;405406+ __shost_for_each_device(dev, host) {407+ if (dev->tagged_supported && (dev->type == TYPE_DISK) &&408+ (sdev_channel(dev) == CONTAINER_CHANNEL))409+ ++num_lsu;410+ else411+ ++num_one;412+ }413+ if (num_lsu == 0)414+ ++num_lsu;415+ depth = (host->can_queue - num_one) / num_lsu;416+ if (depth > 256)417+ depth = 256;418+ else if (depth < 2)419+ depth = 2;420+ scsi_adjust_queue_depth(sdev, MSG_ORDERED_TAG, depth);421+ if (!(((struct aac_dev *)host->hostdata)->adapter_info.options &422+ AAC_OPT_NEW_COMM))423+ blk_queue_max_segment_size(sdev->request_queue, 65536);424+ } else425 scsi_adjust_queue_depth(sdev, 0, 1);0000426427 return 0;428}···870871 /*872 * max channel will be the physical channels plus 1 virtual channel873+ * all containers are on the virtual channel 0 (CONTAINER_CHANNEL)874 * physical channels are address by their actual physical number+1875 */876 if (aac->nondasd_support == 1)···913 aac_adapter_disable_int(aac);914 free_irq(pdev->irq, aac);915 out_unmap:916+ aac_fib_map_free(aac);917 pci_free_consistent(aac->pdev, aac->comm_size, aac->comm_addr, aac->comm_phys);918 kfree(aac->queues);919 iounmap(aac->regs.sa);···947948 aac_send_shutdown(aac);949 aac_adapter_disable_int(aac);950+ aac_fib_map_free(aac);951 pci_free_consistent(aac->pdev, aac->comm_size, aac->comm_addr,952 aac->comm_phys);953 kfree(aac->queues);
···5#include <linux/mutex.h>67#define MEGARAID_VERSION \8- "v2.00.3 (Release Date: Wed Feb 19 08:51:30 EST 2003)\n"910/*11 * Driver features - change the values to enable or disable features in the
···5#include <linux/mutex.h>67#define MEGARAID_VERSION \8+ "v2.00.4 (Release Date: Thu Feb 9 08:51:30 EST 2006)\n"910/*11 * Driver features - change the values to enable or disable features in the
+99-2
drivers/scsi/megaraid/megaraid_sas.c
···10 * 2 of the License, or (at your option) any later version.11 *12 * FILE : megaraid_sas.c13- * Version : v00.00.02.0214 *15 * Authors:16 * Sreenivas Bagalkote <Sreenivas.Bagalkote@lsil.com>···59 PCI_ANY_ID,60 PCI_ANY_ID,61 },00000062 {63 PCI_VENDOR_ID_DELL,64 PCI_DEVICE_ID_DELL_PERC5, // xscale IOP···202/**203* This is the end of set of functions & definitions specific 204* to xscale (deviceid : 1064R, PERC5) controllers00000000000000000000000000000000000000000000000000000000000000000000000000000000205*/206207/**···16931694 reg_set = instance->reg_set;16951696- instance->instancet = &megasas_instance_template_xscale;000000000016971698 /*1699 * We expect the FW state to be READY···2079 host->max_channel = MEGASAS_MAX_CHANNELS - 1;2080 host->max_id = MEGASAS_MAX_DEV_PER_CHANNEL;2081 host->max_lun = MEGASAS_MAX_LUN;020822083 /*2084 * Notify the mid-layer about the new controller
···10 * 2 of the License, or (at your option) any later version.11 *12 * FILE : megaraid_sas.c13+ * Version : v00.00.02.0414 *15 * Authors:16 * Sreenivas Bagalkote <Sreenivas.Bagalkote@lsil.com>···59 PCI_ANY_ID,60 PCI_ANY_ID,61 },62+ {63+ PCI_VENDOR_ID_LSI_LOGIC,64+ PCI_DEVICE_ID_LSI_SAS1078R, // ppc IOP65+ PCI_ANY_ID,66+ PCI_ANY_ID,67+ },68 {69 PCI_VENDOR_ID_DELL,70 PCI_DEVICE_ID_DELL_PERC5, // xscale IOP···196/**197* This is the end of set of functions & definitions specific 198* to xscale (deviceid : 1064R, PERC5) controllers199+*/200+201+/**202+* The following functions are defined for ppc (deviceid : 0x60) 203+* controllers204+*/205+206+/**207+ * megasas_enable_intr_ppc - Enables interrupts208+ * @regs: MFI register set209+ */210+static inline void211+megasas_enable_intr_ppc(struct megasas_register_set __iomem * regs)212+{213+ writel(0xFFFFFFFF, &(regs)->outbound_doorbell_clear);214+215+ writel(~0x80000004, &(regs)->outbound_intr_mask);216+217+ /* Dummy readl to force pci flush */218+ readl(®s->outbound_intr_mask);219+}220+221+/**222+ * megasas_read_fw_status_reg_ppc - returns the current FW status value223+ * @regs: MFI register set224+ */225+static u32226+megasas_read_fw_status_reg_ppc(struct megasas_register_set __iomem * regs)227+{228+ return readl(&(regs)->outbound_scratch_pad);229+}230+231+/**232+ * megasas_clear_interrupt_ppc - Check & clear interrupt233+ * @regs: MFI register set234+ */235+static int 236+megasas_clear_intr_ppc(struct megasas_register_set __iomem * regs)237+{238+ u32 status;239+ /*240+ * Check if it is our interrupt241+ */242+ status = readl(®s->outbound_intr_status);243+244+ if (!(status & MFI_REPLY_1078_MESSAGE_INTERRUPT)) {245+ return 1;246+ }247+248+ /*249+ * Clear the interrupt by writing back the same value250+ */251+ writel(status, ®s->outbound_doorbell_clear);252+253+ return 0;254+}255+/**256+ * megasas_fire_cmd_ppc - Sends command to the FW257+ * @frame_phys_addr : Physical address of cmd258+ * @frame_count : Number of frames for the command259+ * @regs : MFI register set260+ */261+static inline void 262+megasas_fire_cmd_ppc(dma_addr_t frame_phys_addr, u32 frame_count, struct megasas_register_set __iomem *regs)263+{264+ writel((frame_phys_addr | (frame_count<<1))|1, 265+ &(regs)->inbound_queue_port);266+}267+268+static struct megasas_instance_template megasas_instance_template_ppc = {269+270+ .fire_cmd = megasas_fire_cmd_ppc,271+ .enable_intr = megasas_enable_intr_ppc,272+ .clear_intr = megasas_clear_intr_ppc,273+ .read_fw_status_reg = megasas_read_fw_status_reg_ppc,274+};275+276+/**277+* This is the end of set of functions & definitions278+* specific to ppc (deviceid : 0x60) controllers279*/280281/**···16071608 reg_set = instance->reg_set;16091610+ switch(instance->pdev->device)1611+ {1612+ case PCI_DEVICE_ID_LSI_SAS1078R: 1613+ instance->instancet = &megasas_instance_template_ppc;1614+ break;1615+ case PCI_DEVICE_ID_LSI_SAS1064R:1616+ case PCI_DEVICE_ID_DELL_PERC5:1617+ default:1618+ instance->instancet = &megasas_instance_template_xscale;1619+ break;1620+ }16211622 /*1623 * We expect the FW state to be READY···1983 host->max_channel = MEGASAS_MAX_CHANNELS - 1;1984 host->max_id = MEGASAS_MAX_DEV_PER_CHANNEL;1985 host->max_lun = MEGASAS_MAX_LUN;1986+ host->max_cmd_len = 16;19871988 /*1989 * Notify the mid-layer about the new controller
···433/* Used to obtain the PCI location of a device */434#define SCSI_IOCTL_GET_PCI 0x538743500436#endif /* _SCSI_SCSI_H */
···433/* Used to obtain the PCI location of a device */434#define SCSI_IOCTL_GET_PCI 0x5387435436+int scsi_execute_in_process_context(void (*fn)(void *data), void *data);437+438#endif /* _SCSI_SCSI_H */
+18-16
include/scsi/scsi_transport_iscsi.h
···63 int max_lun;64 unsigned int max_conn;65 unsigned int max_cmd_len;66- struct Scsi_Host *(*create_session) (struct scsi_transport_template *t,67- uint32_t initial_cmdsn);68- void (*destroy_session) (struct Scsi_Host *shost);69- struct iscsi_cls_conn *(*create_conn) (struct Scsi_Host *shost,70 uint32_t cid);71- int (*bind_conn) (iscsi_sessionh_t session, iscsi_connh_t conn,072 uint32_t transport_fd, int is_leading);73- int (*start_conn) (iscsi_connh_t conn);74- void (*stop_conn) (iscsi_connh_t conn, int flag);75 void (*destroy_conn) (struct iscsi_cls_conn *conn);76- int (*set_param) (iscsi_connh_t conn, enum iscsi_param param,77 uint32_t value);78- int (*get_conn_param) (void *conndata, enum iscsi_param param,079 uint32_t *value);80- int (*get_session_param) (struct Scsi_Host *shost,81 enum iscsi_param param, uint32_t *value);82- int (*send_pdu) (iscsi_connh_t conn, struct iscsi_hdr *hdr,83 char *data, uint32_t data_size);84- void (*get_stats) (iscsi_connh_t conn, struct iscsi_stats *stats);085};8687/*···96/*97 * control plane upcalls98 */99-extern void iscsi_conn_error(iscsi_connh_t conn, enum iscsi_err error);100-extern int iscsi_recv_pdu(iscsi_connh_t conn, struct iscsi_hdr *hdr,101 char *data, uint32_t data_size);102103struct iscsi_cls_conn {104 struct list_head conn_list; /* item in connlist */105 void *dd_data; /* LLD private data */106 struct iscsi_transport *transport;107- iscsi_connh_t connh;108 int active; /* must be accessed with the connlock */109 struct device dev; /* sysfs transport/container device */110 struct mempool_zone *z_error;···115 container_of(_dev, struct iscsi_cls_conn, dev)116117struct iscsi_cls_session {118- struct list_head list; /* item in session_list */119 struct iscsi_transport *transport;120 struct device dev; /* sysfs transport/container device */121};
···63 int max_lun;64 unsigned int max_conn;65 unsigned int max_cmd_len;66+ struct iscsi_cls_session *(*create_session)67+ (struct scsi_transport_template *t, uint32_t sn, uint32_t *sid);68+ void (*destroy_session) (struct iscsi_cls_session *session);69+ struct iscsi_cls_conn *(*create_conn) (struct iscsi_cls_session *sess,70 uint32_t cid);71+ int (*bind_conn) (struct iscsi_cls_session *session,72+ struct iscsi_cls_conn *cls_conn,73 uint32_t transport_fd, int is_leading);74+ int (*start_conn) (struct iscsi_cls_conn *conn);75+ void (*stop_conn) (struct iscsi_cls_conn *conn, int flag);76 void (*destroy_conn) (struct iscsi_cls_conn *conn);77+ int (*set_param) (struct iscsi_cls_conn *conn, enum iscsi_param param,78 uint32_t value);79+ int (*get_conn_param) (struct iscsi_cls_conn *conn,80+ enum iscsi_param param,81 uint32_t *value);82+ int (*get_session_param) (struct iscsi_cls_session *session,83 enum iscsi_param param, uint32_t *value);84+ int (*send_pdu) (struct iscsi_cls_conn *conn, struct iscsi_hdr *hdr,85 char *data, uint32_t data_size);86+ void (*get_stats) (struct iscsi_cls_conn *conn,87+ struct iscsi_stats *stats);88};8990/*···93/*94 * control plane upcalls95 */96+extern void iscsi_conn_error(struct iscsi_cls_conn *conn, enum iscsi_err error);97+extern int iscsi_recv_pdu(struct iscsi_cls_conn *conn, struct iscsi_hdr *hdr,98 char *data, uint32_t data_size);99100struct iscsi_cls_conn {101 struct list_head conn_list; /* item in connlist */102 void *dd_data; /* LLD private data */103 struct iscsi_transport *transport;0104 int active; /* must be accessed with the connlock */105 struct device dev; /* sysfs transport/container device */106 struct mempool_zone *z_error;···113 container_of(_dev, struct iscsi_cls_conn, dev)114115struct iscsi_cls_session {116+ struct list_head sess_list; /* item in session_list */117 struct iscsi_transport *transport;118 struct device dev; /* sysfs transport/container device */119};