aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/message/fusion/mptbase.c
diff options
context:
space:
mode:
authorLinus Torvalds <torvalds@linux-foundation.org>2009-06-12 12:50:42 -0400
committerLinus Torvalds <torvalds@linux-foundation.org>2009-06-12 12:50:42 -0400
commitc9b8af00ff71f86ff3d092cc60ca673e1d0eae5b (patch)
tree25cc016481cc693552bebb4040041817280c2ccf /drivers/message/fusion/mptbase.c
parentc59a264c9e932c828d533497e286b89e43c8d1be (diff)
parent82681a318f9f028ea64e61f24bbd9ac535531921 (diff)
Merge git://git.kernel.org/pub/scm/linux/kernel/git/jejb/scsi-misc-2.6
* git://git.kernel.org/pub/scm/linux/kernel/git/jejb/scsi-misc-2.6: (154 commits) [SCSI] osd: Remove out-of-tree left overs [SCSI] libosd: Use REQ_QUIET requests. [SCSI] osduld: use filp_open() when looking up an osd-device [SCSI] libosd: Define an osd_dev wrapper to retrieve the request_queue [SCSI] libosd: osd_req_{read,write} takes a length parameter [SCSI] libosd: Let _osd_req_finalize_data_integrity receive number of out_bytes [SCSI] libosd: osd_req_{read,write}_kern new API [SCSI] libosd: Better printout of OSD target system information [SCSI] libosd: OSD2r05: Attribute definitions [SCSI] libosd: OSD2r05: Additional command enums [SCSI] mpt fusion: fix up doc book comments [SCSI] mpt fusion: Added support for Broadcast primitives Event handling [SCSI] mpt fusion: Queue full event handling [SCSI] mpt fusion: RAID device handling and Dual port Raid support is added [SCSI] mpt fusion: Put IOC into ready state if it not already in ready state [SCSI] mpt fusion: Code Cleanup patch [SCSI] mpt fusion: Rescan SAS topology added [SCSI] mpt fusion: SAS topology scan changes, expander events [SCSI] mpt fusion: Firmware event implementation using seperate WorkQueue [SCSI] mpt fusion: rewrite of ioctl_cmds internal generated function ...
Diffstat (limited to 'drivers/message/fusion/mptbase.c')
-rw-r--r--drivers/message/fusion/mptbase.c1571
1 files changed, 1101 insertions, 470 deletions
diff --git a/drivers/message/fusion/mptbase.c b/drivers/message/fusion/mptbase.c
index 5d496a99e034..44b931504457 100644
--- a/drivers/message/fusion/mptbase.c
+++ b/drivers/message/fusion/mptbase.c
@@ -146,7 +146,6 @@ static MPT_EVHANDLER MptEvHandlers[MPT_MAX_PROTOCOL_DRIVERS];
146static MPT_RESETHANDLER MptResetHandlers[MPT_MAX_PROTOCOL_DRIVERS]; 146static MPT_RESETHANDLER MptResetHandlers[MPT_MAX_PROTOCOL_DRIVERS];
147static struct mpt_pci_driver *MptDeviceDriverHandlers[MPT_MAX_PROTOCOL_DRIVERS]; 147static struct mpt_pci_driver *MptDeviceDriverHandlers[MPT_MAX_PROTOCOL_DRIVERS];
148 148
149static DECLARE_WAIT_QUEUE_HEAD(mpt_waitq);
150 149
151/* 150/*
152 * Driver Callback Index's 151 * Driver Callback Index's
@@ -159,7 +158,8 @@ static u8 last_drv_idx;
159 * Forward protos... 158 * Forward protos...
160 */ 159 */
161static irqreturn_t mpt_interrupt(int irq, void *bus_id); 160static irqreturn_t mpt_interrupt(int irq, void *bus_id);
162static int mpt_base_reply(MPT_ADAPTER *ioc, MPT_FRAME_HDR *req, MPT_FRAME_HDR *reply); 161static int mptbase_reply(MPT_ADAPTER *ioc, MPT_FRAME_HDR *req,
162 MPT_FRAME_HDR *reply);
163static int mpt_handshake_req_reply_wait(MPT_ADAPTER *ioc, int reqBytes, 163static int mpt_handshake_req_reply_wait(MPT_ADAPTER *ioc, int reqBytes,
164 u32 *req, int replyBytes, u16 *u16reply, int maxwait, 164 u32 *req, int replyBytes, u16 *u16reply, int maxwait,
165 int sleepFlag); 165 int sleepFlag);
@@ -190,9 +190,9 @@ static int mpt_GetScsiPortSettings(MPT_ADAPTER *ioc, int portnum);
190static int mpt_readScsiDevicePageHeaders(MPT_ADAPTER *ioc, int portnum); 190static int mpt_readScsiDevicePageHeaders(MPT_ADAPTER *ioc, int portnum);
191static void mpt_read_ioc_pg_1(MPT_ADAPTER *ioc); 191static void mpt_read_ioc_pg_1(MPT_ADAPTER *ioc);
192static void mpt_read_ioc_pg_4(MPT_ADAPTER *ioc); 192static void mpt_read_ioc_pg_4(MPT_ADAPTER *ioc);
193static void mpt_timer_expired(unsigned long data);
194static void mpt_get_manufacturing_pg_0(MPT_ADAPTER *ioc); 193static void mpt_get_manufacturing_pg_0(MPT_ADAPTER *ioc);
195static int SendEventNotification(MPT_ADAPTER *ioc, u8 EvSwitch); 194static int SendEventNotification(MPT_ADAPTER *ioc, u8 EvSwitch,
195 int sleepFlag);
196static int SendEventAck(MPT_ADAPTER *ioc, EventNotificationReply_t *evnp); 196static int SendEventAck(MPT_ADAPTER *ioc, EventNotificationReply_t *evnp);
197static int mpt_host_page_access_control(MPT_ADAPTER *ioc, u8 access_control_value, int sleepFlag); 197static int mpt_host_page_access_control(MPT_ADAPTER *ioc, u8 access_control_value, int sleepFlag);
198static int mpt_host_page_alloc(MPT_ADAPTER *ioc, pIOCInit_t ioc_init); 198static int mpt_host_page_alloc(MPT_ADAPTER *ioc, pIOCInit_t ioc_init);
@@ -207,8 +207,8 @@ static int procmpt_iocinfo_read(char *buf, char **start, off_t offset,
207#endif 207#endif
208static void mpt_get_fw_exp_ver(char *buf, MPT_ADAPTER *ioc); 208static void mpt_get_fw_exp_ver(char *buf, MPT_ADAPTER *ioc);
209 209
210//int mpt_HardResetHandler(MPT_ADAPTER *ioc, int sleepFlag); 210static int ProcessEventNotification(MPT_ADAPTER *ioc,
211static int ProcessEventNotification(MPT_ADAPTER *ioc, EventNotificationReply_t *evReply, int *evHandlers); 211 EventNotificationReply_t *evReply, int *evHandlers);
212static void mpt_iocstatus_info(MPT_ADAPTER *ioc, u32 ioc_status, MPT_FRAME_HDR *mf); 212static void mpt_iocstatus_info(MPT_ADAPTER *ioc, u32 ioc_status, MPT_FRAME_HDR *mf);
213static void mpt_fc_log_info(MPT_ADAPTER *ioc, u32 log_info); 213static void mpt_fc_log_info(MPT_ADAPTER *ioc, u32 log_info);
214static void mpt_spi_log_info(MPT_ADAPTER *ioc, u32 log_info); 214static void mpt_spi_log_info(MPT_ADAPTER *ioc, u32 log_info);
@@ -277,6 +277,56 @@ mpt_get_cb_idx(MPT_DRIVER_CLASS dclass)
277} 277}
278 278
279/** 279/**
280 * mpt_is_discovery_complete - determine if discovery has completed
281 * @ioc: per adatper instance
282 *
283 * Returns 1 when discovery completed, else zero.
284 */
285static int
286mpt_is_discovery_complete(MPT_ADAPTER *ioc)
287{
288 ConfigExtendedPageHeader_t hdr;
289 CONFIGPARMS cfg;
290 SasIOUnitPage0_t *buffer;
291 dma_addr_t dma_handle;
292 int rc = 0;
293
294 memset(&hdr, 0, sizeof(ConfigExtendedPageHeader_t));
295 memset(&cfg, 0, sizeof(CONFIGPARMS));
296 hdr.PageVersion = MPI_SASIOUNITPAGE0_PAGEVERSION;
297 hdr.PageType = MPI_CONFIG_PAGETYPE_EXTENDED;
298 hdr.ExtPageType = MPI_CONFIG_EXTPAGETYPE_SAS_IO_UNIT;
299 cfg.cfghdr.ehdr = &hdr;
300 cfg.action = MPI_CONFIG_ACTION_PAGE_HEADER;
301
302 if ((mpt_config(ioc, &cfg)))
303 goto out;
304 if (!hdr.ExtPageLength)
305 goto out;
306
307 buffer = pci_alloc_consistent(ioc->pcidev, hdr.ExtPageLength * 4,
308 &dma_handle);
309 if (!buffer)
310 goto out;
311
312 cfg.physAddr = dma_handle;
313 cfg.action = MPI_CONFIG_ACTION_PAGE_READ_CURRENT;
314
315 if ((mpt_config(ioc, &cfg)))
316 goto out_free_consistent;
317
318 if (!(buffer->PhyData[0].PortFlags &
319 MPI_SAS_IOUNIT0_PORT_FLAGS_DISCOVERY_IN_PROGRESS))
320 rc = 1;
321
322 out_free_consistent:
323 pci_free_consistent(ioc->pcidev, hdr.ExtPageLength * 4,
324 buffer, dma_handle);
325 out:
326 return rc;
327}
328
329/**
280 * mpt_fault_reset_work - work performed on workq after ioc fault 330 * mpt_fault_reset_work - work performed on workq after ioc fault
281 * @work: input argument, used to derive ioc 331 * @work: input argument, used to derive ioc
282 * 332 *
@@ -290,7 +340,7 @@ mpt_fault_reset_work(struct work_struct *work)
290 int rc; 340 int rc;
291 unsigned long flags; 341 unsigned long flags;
292 342
293 if (ioc->diagPending || !ioc->active) 343 if (ioc->ioc_reset_in_progress || !ioc->active)
294 goto out; 344 goto out;
295 345
296 ioc_raw_state = mpt_GetIocState(ioc, 0); 346 ioc_raw_state = mpt_GetIocState(ioc, 0);
@@ -307,6 +357,12 @@ mpt_fault_reset_work(struct work_struct *work)
307 printk(MYIOC_s_WARN_FMT "IOC is in FAULT state after " 357 printk(MYIOC_s_WARN_FMT "IOC is in FAULT state after "
308 "reset (%04xh)\n", ioc->name, ioc_raw_state & 358 "reset (%04xh)\n", ioc->name, ioc_raw_state &
309 MPI_DOORBELL_DATA_MASK); 359 MPI_DOORBELL_DATA_MASK);
360 } else if (ioc->bus_type == SAS && ioc->sas_discovery_quiesce_io) {
361 if ((mpt_is_discovery_complete(ioc))) {
362 devtprintk(ioc, printk(MYIOC_s_DEBUG_FMT "clearing "
363 "discovery_quiesce_io flag\n", ioc->name));
364 ioc->sas_discovery_quiesce_io = 0;
365 }
310 } 366 }
311 367
312 out: 368 out:
@@ -317,11 +373,11 @@ mpt_fault_reset_work(struct work_struct *work)
317 ioc = ioc->alt_ioc; 373 ioc = ioc->alt_ioc;
318 374
319 /* rearm the timer */ 375 /* rearm the timer */
320 spin_lock_irqsave(&ioc->fault_reset_work_lock, flags); 376 spin_lock_irqsave(&ioc->taskmgmt_lock, flags);
321 if (ioc->reset_work_q) 377 if (ioc->reset_work_q)
322 queue_delayed_work(ioc->reset_work_q, &ioc->fault_reset_work, 378 queue_delayed_work(ioc->reset_work_q, &ioc->fault_reset_work,
323 msecs_to_jiffies(MPT_POLLING_INTERVAL)); 379 msecs_to_jiffies(MPT_POLLING_INTERVAL));
324 spin_unlock_irqrestore(&ioc->fault_reset_work_lock, flags); 380 spin_unlock_irqrestore(&ioc->taskmgmt_lock, flags);
325} 381}
326 382
327 383
@@ -501,9 +557,9 @@ mpt_interrupt(int irq, void *bus_id)
501 557
502/*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/ 558/*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
503/** 559/**
504 * mpt_base_reply - MPT base driver's callback routine 560 * mptbase_reply - MPT base driver's callback routine
505 * @ioc: Pointer to MPT_ADAPTER structure 561 * @ioc: Pointer to MPT_ADAPTER structure
506 * @mf: Pointer to original MPT request frame 562 * @req: Pointer to original MPT request frame
507 * @reply: Pointer to MPT reply frame (NULL if TurboReply) 563 * @reply: Pointer to MPT reply frame (NULL if TurboReply)
508 * 564 *
509 * MPT base driver's callback routine; all base driver 565 * MPT base driver's callback routine; all base driver
@@ -514,122 +570,49 @@ mpt_interrupt(int irq, void *bus_id)
514 * should be freed, or 0 if it shouldn't. 570 * should be freed, or 0 if it shouldn't.
515 */ 571 */
516static int 572static int
517mpt_base_reply(MPT_ADAPTER *ioc, MPT_FRAME_HDR *mf, MPT_FRAME_HDR *reply) 573mptbase_reply(MPT_ADAPTER *ioc, MPT_FRAME_HDR *req, MPT_FRAME_HDR *reply)
518{ 574{
575 EventNotificationReply_t *pEventReply;
576 u8 event;
577 int evHandlers;
519 int freereq = 1; 578 int freereq = 1;
520 u8 func;
521 579
522 dmfprintk(ioc, printk(MYIOC_s_DEBUG_FMT "mpt_base_reply() called\n", ioc->name)); 580 switch (reply->u.hdr.Function) {
523#ifdef CONFIG_FUSION_LOGGING 581 case MPI_FUNCTION_EVENT_NOTIFICATION:
524 if ((ioc->debug_level & MPT_DEBUG_MSG_FRAME) && 582 pEventReply = (EventNotificationReply_t *)reply;
525 !(reply->u.hdr.MsgFlags & MPI_MSGFLAGS_CONTINUATION_REPLY)) { 583 evHandlers = 0;
526 dmfprintk(ioc, printk(MYIOC_s_INFO_FMT ": Original request frame (@%p) header\n", 584 ProcessEventNotification(ioc, pEventReply, &evHandlers);
527 ioc->name, mf)); 585 event = le32_to_cpu(pEventReply->Event) & 0xFF;
528 DBG_DUMP_REQUEST_FRAME_HDR(ioc, (u32 *)mf); 586 if (pEventReply->MsgFlags & MPI_MSGFLAGS_CONTINUATION_REPLY)
529 }
530#endif
531
532 func = reply->u.hdr.Function;
533 dmfprintk(ioc, printk(MYIOC_s_DEBUG_FMT "mpt_base_reply, Function=%02Xh\n",
534 ioc->name, func));
535
536 if (func == MPI_FUNCTION_EVENT_NOTIFICATION) {
537 EventNotificationReply_t *pEvReply = (EventNotificationReply_t *) reply;
538 int evHandlers = 0;
539 int results;
540
541 results = ProcessEventNotification(ioc, pEvReply, &evHandlers);
542 if (results != evHandlers) {
543 /* CHECKME! Any special handling needed here? */
544 devtverboseprintk(ioc, printk(MYIOC_s_WARN_FMT "Called %d event handlers, sum results = %d\n",
545 ioc->name, evHandlers, results));
546 }
547
548 /*
549 * Hmmm... It seems that EventNotificationReply is an exception
550 * to the rule of one reply per request.
551 */
552 if (pEvReply->MsgFlags & MPI_MSGFLAGS_CONTINUATION_REPLY) {
553 freereq = 0; 587 freereq = 0;
554 } else { 588 if (event != MPI_EVENT_EVENT_CHANGE)
555 devtverboseprintk(ioc, printk(MYIOC_s_WARN_FMT "EVENT_NOTIFICATION reply %p returns Request frame\n", 589 break;
556 ioc->name, pEvReply)); 590 case MPI_FUNCTION_CONFIG:
557 } 591 case MPI_FUNCTION_SAS_IO_UNIT_CONTROL:
558 592 ioc->mptbase_cmds.status |= MPT_MGMT_STATUS_COMMAND_GOOD;
559#ifdef CONFIG_PROC_FS 593 if (reply) {
560// LogEvent(ioc, pEvReply); 594 ioc->mptbase_cmds.status |= MPT_MGMT_STATUS_RF_VALID;
561#endif 595 memcpy(ioc->mptbase_cmds.reply, reply,
562 596 min(MPT_DEFAULT_FRAME_SIZE,
563 } else if (func == MPI_FUNCTION_EVENT_ACK) { 597 4 * reply->u.reply.MsgLength));
564 dprintk(ioc, printk(MYIOC_s_DEBUG_FMT "mpt_base_reply, EventAck reply received\n",
565 ioc->name));
566 } else if (func == MPI_FUNCTION_CONFIG) {
567 CONFIGPARMS *pCfg;
568 unsigned long flags;
569
570 dcprintk(ioc, printk(MYIOC_s_DEBUG_FMT "config_complete (mf=%p,mr=%p)\n",
571 ioc->name, mf, reply));
572
573 pCfg = * ((CONFIGPARMS **)((u8 *) mf + ioc->req_sz - sizeof(void *)));
574
575 if (pCfg) {
576 /* disable timer and remove from linked list */
577 del_timer(&pCfg->timer);
578
579 spin_lock_irqsave(&ioc->FreeQlock, flags);
580 list_del(&pCfg->linkage);
581 spin_unlock_irqrestore(&ioc->FreeQlock, flags);
582
583 /*
584 * If IOC Status is SUCCESS, save the header
585 * and set the status code to GOOD.
586 */
587 pCfg->status = MPT_CONFIG_ERROR;
588 if (reply) {
589 ConfigReply_t *pReply = (ConfigReply_t *)reply;
590 u16 status;
591
592 status = le16_to_cpu(pReply->IOCStatus) & MPI_IOCSTATUS_MASK;
593 dcprintk(ioc, printk(MYIOC_s_NOTE_FMT " IOCStatus=%04xh, IOCLogInfo=%08xh\n",
594 ioc->name, status, le32_to_cpu(pReply->IOCLogInfo)));
595
596 pCfg->status = status;
597 if (status == MPI_IOCSTATUS_SUCCESS) {
598 if ((pReply->Header.PageType &
599 MPI_CONFIG_PAGETYPE_MASK) ==
600 MPI_CONFIG_PAGETYPE_EXTENDED) {
601 pCfg->cfghdr.ehdr->ExtPageLength =
602 le16_to_cpu(pReply->ExtPageLength);
603 pCfg->cfghdr.ehdr->ExtPageType =
604 pReply->ExtPageType;
605 }
606 pCfg->cfghdr.hdr->PageVersion = pReply->Header.PageVersion;
607
608 /* If this is a regular header, save PageLength. */
609 /* LMP Do this better so not using a reserved field! */
610 pCfg->cfghdr.hdr->PageLength = pReply->Header.PageLength;
611 pCfg->cfghdr.hdr->PageNumber = pReply->Header.PageNumber;
612 pCfg->cfghdr.hdr->PageType = pReply->Header.PageType;
613 }
614 }
615
616 /*
617 * Wake up the original calling thread
618 */
619 pCfg->wait_done = 1;
620 wake_up(&mpt_waitq);
621 } 598 }
622 } else if (func == MPI_FUNCTION_SAS_IO_UNIT_CONTROL) { 599 if (ioc->mptbase_cmds.status & MPT_MGMT_STATUS_PENDING) {
623 /* we should be always getting a reply frame */ 600 ioc->mptbase_cmds.status &= ~MPT_MGMT_STATUS_PENDING;
624 memcpy(ioc->persist_reply_frame, reply, 601 complete(&ioc->mptbase_cmds.done);
625 min(MPT_DEFAULT_FRAME_SIZE, 602 } else
626 4*reply->u.reply.MsgLength)); 603 freereq = 0;
627 del_timer(&ioc->persist_timer); 604 if (ioc->mptbase_cmds.status & MPT_MGMT_STATUS_FREE_MF)
628 ioc->persist_wait_done = 1; 605 freereq = 1;
629 wake_up(&mpt_waitq); 606 break;
630 } else { 607 case MPI_FUNCTION_EVENT_ACK:
631 printk(MYIOC_s_ERR_FMT "Unexpected msg function (=%02Xh) reply received!\n", 608 devtverboseprintk(ioc, printk(MYIOC_s_DEBUG_FMT
632 ioc->name, func); 609 "EventAck reply received\n", ioc->name));
610 break;
611 default:
612 printk(MYIOC_s_ERR_FMT
613 "Unexpected msg function (=%02Xh) reply received!\n",
614 ioc->name, reply->u.hdr.Function);
615 break;
633 } 616 }
634 617
635 /* 618 /*
@@ -988,17 +971,21 @@ mpt_free_msg_frame(MPT_ADAPTER *ioc, MPT_FRAME_HDR *mf)
988 971
989 /* Put Request back on FreeQ! */ 972 /* Put Request back on FreeQ! */
990 spin_lock_irqsave(&ioc->FreeQlock, flags); 973 spin_lock_irqsave(&ioc->FreeQlock, flags);
991 mf->u.frame.linkage.arg1 = 0xdeadbeaf; /* signature to know if this mf is freed */ 974 if (cpu_to_le32(mf->u.frame.linkage.arg1) == 0xdeadbeaf)
975 goto out;
976 /* signature to know if this mf is freed */
977 mf->u.frame.linkage.arg1 = cpu_to_le32(0xdeadbeaf);
992 list_add_tail(&mf->u.frame.linkage.list, &ioc->FreeQ); 978 list_add_tail(&mf->u.frame.linkage.list, &ioc->FreeQ);
993#ifdef MFCNT 979#ifdef MFCNT
994 ioc->mfcnt--; 980 ioc->mfcnt--;
995#endif 981#endif
982 out:
996 spin_unlock_irqrestore(&ioc->FreeQlock, flags); 983 spin_unlock_irqrestore(&ioc->FreeQlock, flags);
997} 984}
998 985
999/*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/ 986/*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
1000/** 987/**
1001 * mpt_add_sge - Place a simple SGE at address pAddr. 988 * mpt_add_sge - Place a simple 32 bit SGE at address pAddr.
1002 * @pAddr: virtual address for SGE 989 * @pAddr: virtual address for SGE
1003 * @flagslength: SGE flags and data transfer length 990 * @flagslength: SGE flags and data transfer length
1004 * @dma_addr: Physical address 991 * @dma_addr: Physical address
@@ -1006,23 +993,117 @@ mpt_free_msg_frame(MPT_ADAPTER *ioc, MPT_FRAME_HDR *mf)
1006 * This routine places a MPT request frame back on the MPT adapter's 993 * This routine places a MPT request frame back on the MPT adapter's
1007 * FreeQ. 994 * FreeQ.
1008 */ 995 */
1009void 996static void
1010mpt_add_sge(char *pAddr, u32 flagslength, dma_addr_t dma_addr) 997mpt_add_sge(void *pAddr, u32 flagslength, dma_addr_t dma_addr)
1011{ 998{
1012 if (sizeof(dma_addr_t) == sizeof(u64)) { 999 SGESimple32_t *pSge = (SGESimple32_t *) pAddr;
1013 SGESimple64_t *pSge = (SGESimple64_t *) pAddr; 1000 pSge->FlagsLength = cpu_to_le32(flagslength);
1001 pSge->Address = cpu_to_le32(dma_addr);
1002}
1003
1004/**
1005 * mpt_add_sge_64bit - Place a simple 64 bit SGE at address pAddr.
1006 * @pAddr: virtual address for SGE
1007 * @flagslength: SGE flags and data transfer length
1008 * @dma_addr: Physical address
1009 *
1010 * This routine places a MPT request frame back on the MPT adapter's
1011 * FreeQ.
1012 **/
1013static void
1014mpt_add_sge_64bit(void *pAddr, u32 flagslength, dma_addr_t dma_addr)
1015{
1016 SGESimple64_t *pSge = (SGESimple64_t *) pAddr;
1017 pSge->Address.Low = cpu_to_le32
1018 (lower_32_bits((unsigned long)(dma_addr)));
1019 pSge->Address.High = cpu_to_le32
1020 (upper_32_bits((unsigned long)dma_addr));
1021 pSge->FlagsLength = cpu_to_le32
1022 ((flagslength | MPT_SGE_FLAGS_64_BIT_ADDRESSING));
1023}
1024
1025/**
1026 * mpt_add_sge_64bit_1078 - Place a simple 64 bit SGE at address pAddr
1027 * (1078 workaround).
1028 * @pAddr: virtual address for SGE
1029 * @flagslength: SGE flags and data transfer length
1030 * @dma_addr: Physical address
1031 *
1032 * This routine places a MPT request frame back on the MPT adapter's
1033 * FreeQ.
1034 **/
1035static void
1036mpt_add_sge_64bit_1078(void *pAddr, u32 flagslength, dma_addr_t dma_addr)
1037{
1038 SGESimple64_t *pSge = (SGESimple64_t *) pAddr;
1039 u32 tmp;
1040
1041 pSge->Address.Low = cpu_to_le32
1042 (lower_32_bits((unsigned long)(dma_addr)));
1043 tmp = (u32)(upper_32_bits((unsigned long)dma_addr));
1044
1045 /*
1046 * 1078 errata workaround for the 36GB limitation
1047 */
1048 if ((((u64)dma_addr + MPI_SGE_LENGTH(flagslength)) >> 32) == 9) {
1049 flagslength |=
1050 MPI_SGE_SET_FLAGS(MPI_SGE_FLAGS_LOCAL_ADDRESS);
1051 tmp |= (1<<31);
1052 if (mpt_debug_level & MPT_DEBUG_36GB_MEM)
1053 printk(KERN_DEBUG "1078 P0M2 addressing for "
1054 "addr = 0x%llx len = %d\n",
1055 (unsigned long long)dma_addr,
1056 MPI_SGE_LENGTH(flagslength));
1057 }
1058
1059 pSge->Address.High = cpu_to_le32(tmp);
1060 pSge->FlagsLength = cpu_to_le32(
1061 (flagslength | MPT_SGE_FLAGS_64_BIT_ADDRESSING));
1062}
1063
1064/*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
1065/**
1066 * mpt_add_chain - Place a 32 bit chain SGE at address pAddr.
1067 * @pAddr: virtual address for SGE
1068 * @next: nextChainOffset value (u32's)
1069 * @length: length of next SGL segment
1070 * @dma_addr: Physical address
1071 *
1072 */
1073static void
1074mpt_add_chain(void *pAddr, u8 next, u16 length, dma_addr_t dma_addr)
1075{
1076 SGEChain32_t *pChain = (SGEChain32_t *) pAddr;
1077 pChain->Length = cpu_to_le16(length);
1078 pChain->Flags = MPI_SGE_FLAGS_CHAIN_ELEMENT;
1079 pChain->NextChainOffset = next;
1080 pChain->Address = cpu_to_le32(dma_addr);
1081}
1082
1083/*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
1084/**
1085 * mpt_add_chain_64bit - Place a 64 bit chain SGE at address pAddr.
1086 * @pAddr: virtual address for SGE
1087 * @next: nextChainOffset value (u32's)
1088 * @length: length of next SGL segment
1089 * @dma_addr: Physical address
1090 *
1091 */
1092static void
1093mpt_add_chain_64bit(void *pAddr, u8 next, u16 length, dma_addr_t dma_addr)
1094{
1095 SGEChain64_t *pChain = (SGEChain64_t *) pAddr;
1014 u32 tmp = dma_addr & 0xFFFFFFFF; 1096 u32 tmp = dma_addr & 0xFFFFFFFF;
1015 1097
1016 pSge->FlagsLength = cpu_to_le32(flagslength); 1098 pChain->Length = cpu_to_le16(length);
1017 pSge->Address.Low = cpu_to_le32(tmp); 1099 pChain->Flags = (MPI_SGE_FLAGS_CHAIN_ELEMENT |
1018 tmp = (u32) ((u64)dma_addr >> 32); 1100 MPI_SGE_FLAGS_64_BIT_ADDRESSING);
1019 pSge->Address.High = cpu_to_le32(tmp);
1020 1101
1021 } else { 1102 pChain->NextChainOffset = next;
1022 SGESimple32_t *pSge = (SGESimple32_t *) pAddr; 1103
1023 pSge->FlagsLength = cpu_to_le32(flagslength); 1104 pChain->Address.Low = cpu_to_le32(tmp);
1024 pSge->Address = cpu_to_le32(dma_addr); 1105 tmp = (u32)(upper_32_bits((unsigned long)dma_addr));
1025 } 1106 pChain->Address.High = cpu_to_le32(tmp);
1026} 1107}
1027 1108
1028/*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/ 1109/*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
@@ -1225,7 +1306,7 @@ mpt_host_page_alloc(MPT_ADAPTER *ioc, pIOCInit_t ioc_init)
1225 } 1306 }
1226 flags_length = flags_length << MPI_SGE_FLAGS_SHIFT; 1307 flags_length = flags_length << MPI_SGE_FLAGS_SHIFT;
1227 flags_length |= ioc->HostPageBuffer_sz; 1308 flags_length |= ioc->HostPageBuffer_sz;
1228 mpt_add_sge(psge, flags_length, ioc->HostPageBuffer_dma); 1309 ioc->add_sge(psge, flags_length, ioc->HostPageBuffer_dma);
1229 ioc->facts.HostPageBufferSGE = ioc_init->HostPageBufferSGE; 1310 ioc->facts.HostPageBufferSGE = ioc_init->HostPageBufferSGE;
1230 1311
1231return 0; 1312return 0;
@@ -1534,21 +1615,42 @@ mpt_mapresources(MPT_ADAPTER *ioc)
1534 1615
1535 pci_read_config_byte(pdev, PCI_CLASS_REVISION, &revision); 1616 pci_read_config_byte(pdev, PCI_CLASS_REVISION, &revision);
1536 1617
1537 if (!pci_set_dma_mask(pdev, DMA_BIT_MASK(64)) 1618 if (sizeof(dma_addr_t) > 4) {
1538 && !pci_set_consistent_dma_mask(pdev, DMA_BIT_MASK(64))) { 1619 const uint64_t required_mask = dma_get_required_mask
1539 dinitprintk(ioc, printk(MYIOC_s_INFO_FMT 1620 (&pdev->dev);
1540 ": 64 BIT PCI BUS DMA ADDRESSING SUPPORTED\n", 1621 if (required_mask > DMA_BIT_MASK(32)
1541 ioc->name)); 1622 && !pci_set_dma_mask(pdev, DMA_BIT_MASK(64))
1542 } else if (!pci_set_dma_mask(pdev, DMA_BIT_MASK(32)) 1623 && !pci_set_consistent_dma_mask(pdev,
1543 && !pci_set_consistent_dma_mask(pdev, DMA_BIT_MASK(32))) { 1624 DMA_BIT_MASK(64))) {
1544 dinitprintk(ioc, printk(MYIOC_s_INFO_FMT 1625 ioc->dma_mask = DMA_BIT_MASK(64);
1545 ": 32 BIT PCI BUS DMA ADDRESSING SUPPORTED\n", 1626 dinitprintk(ioc, printk(MYIOC_s_INFO_FMT
1546 ioc->name)); 1627 ": 64 BIT PCI BUS DMA ADDRESSING SUPPORTED\n",
1628 ioc->name));
1629 } else if (!pci_set_dma_mask(pdev, DMA_BIT_MASK(32))
1630 && !pci_set_consistent_dma_mask(pdev,
1631 DMA_BIT_MASK(32))) {
1632 ioc->dma_mask = DMA_BIT_MASK(32);
1633 dinitprintk(ioc, printk(MYIOC_s_INFO_FMT
1634 ": 32 BIT PCI BUS DMA ADDRESSING SUPPORTED\n",
1635 ioc->name));
1636 } else {
1637 printk(MYIOC_s_WARN_FMT "no suitable DMA mask for %s\n",
1638 ioc->name, pci_name(pdev));
1639 return r;
1640 }
1547 } else { 1641 } else {
1548 printk(MYIOC_s_WARN_FMT "no suitable DMA mask for %s\n", 1642 if (!pci_set_dma_mask(pdev, DMA_BIT_MASK(32))
1549 ioc->name, pci_name(pdev)); 1643 && !pci_set_consistent_dma_mask(pdev,
1550 pci_release_selected_regions(pdev, ioc->bars); 1644 DMA_BIT_MASK(32))) {
1551 return r; 1645 ioc->dma_mask = DMA_BIT_MASK(32);
1646 dinitprintk(ioc, printk(MYIOC_s_INFO_FMT
1647 ": 32 BIT PCI BUS DMA ADDRESSING SUPPORTED\n",
1648 ioc->name));
1649 } else {
1650 printk(MYIOC_s_WARN_FMT "no suitable DMA mask for %s\n",
1651 ioc->name, pci_name(pdev));
1652 return r;
1653 }
1552 } 1654 }
1553 1655
1554 mem_phys = msize = 0; 1656 mem_phys = msize = 0;
@@ -1632,6 +1734,7 @@ mpt_attach(struct pci_dev *pdev, const struct pci_device_id *id)
1632 1734
1633 ioc->id = mpt_ids++; 1735 ioc->id = mpt_ids++;
1634 sprintf(ioc->name, "ioc%d", ioc->id); 1736 sprintf(ioc->name, "ioc%d", ioc->id);
1737 dinitprintk(ioc, printk(KERN_WARNING MYNAM ": mpt_adapter_install\n"));
1635 1738
1636 /* 1739 /*
1637 * set initial debug level 1740 * set initial debug level
@@ -1650,14 +1753,36 @@ mpt_attach(struct pci_dev *pdev, const struct pci_device_id *id)
1650 return r; 1753 return r;
1651 } 1754 }
1652 1755
1756 /*
1757 * Setting up proper handlers for scatter gather handling
1758 */
1759 if (ioc->dma_mask == DMA_BIT_MASK(64)) {
1760 if (pdev->device == MPI_MANUFACTPAGE_DEVID_SAS1078)
1761 ioc->add_sge = &mpt_add_sge_64bit_1078;
1762 else
1763 ioc->add_sge = &mpt_add_sge_64bit;
1764 ioc->add_chain = &mpt_add_chain_64bit;
1765 ioc->sg_addr_size = 8;
1766 } else {
1767 ioc->add_sge = &mpt_add_sge;
1768 ioc->add_chain = &mpt_add_chain;
1769 ioc->sg_addr_size = 4;
1770 }
1771 ioc->SGE_size = sizeof(u32) + ioc->sg_addr_size;
1772
1653 ioc->alloc_total = sizeof(MPT_ADAPTER); 1773 ioc->alloc_total = sizeof(MPT_ADAPTER);
1654 ioc->req_sz = MPT_DEFAULT_FRAME_SIZE; /* avoid div by zero! */ 1774 ioc->req_sz = MPT_DEFAULT_FRAME_SIZE; /* avoid div by zero! */
1655 ioc->reply_sz = MPT_REPLY_FRAME_SIZE; 1775 ioc->reply_sz = MPT_REPLY_FRAME_SIZE;
1656 1776
1657 ioc->pcidev = pdev; 1777 ioc->pcidev = pdev;
1658 ioc->diagPending = 0; 1778
1659 spin_lock_init(&ioc->diagLock); 1779 spin_lock_init(&ioc->taskmgmt_lock);
1660 spin_lock_init(&ioc->initializing_hba_lock); 1780 mutex_init(&ioc->internal_cmds.mutex);
1781 init_completion(&ioc->internal_cmds.done);
1782 mutex_init(&ioc->mptbase_cmds.mutex);
1783 init_completion(&ioc->mptbase_cmds.done);
1784 mutex_init(&ioc->taskmgmt_cmds.mutex);
1785 init_completion(&ioc->taskmgmt_cmds.done);
1661 1786
1662 /* Initialize the event logging. 1787 /* Initialize the event logging.
1663 */ 1788 */
@@ -1670,16 +1795,13 @@ mpt_attach(struct pci_dev *pdev, const struct pci_device_id *id)
1670 ioc->mfcnt = 0; 1795 ioc->mfcnt = 0;
1671#endif 1796#endif
1672 1797
1798 ioc->sh = NULL;
1673 ioc->cached_fw = NULL; 1799 ioc->cached_fw = NULL;
1674 1800
1675 /* Initilize SCSI Config Data structure 1801 /* Initilize SCSI Config Data structure
1676 */ 1802 */
1677 memset(&ioc->spi_data, 0, sizeof(SpiCfgData)); 1803 memset(&ioc->spi_data, 0, sizeof(SpiCfgData));
1678 1804
1679 /* Initialize the running configQ head.
1680 */
1681 INIT_LIST_HEAD(&ioc->configQ);
1682
1683 /* Initialize the fc rport list head. 1805 /* Initialize the fc rport list head.
1684 */ 1806 */
1685 INIT_LIST_HEAD(&ioc->fc_rports); 1807 INIT_LIST_HEAD(&ioc->fc_rports);
@@ -1690,9 +1812,8 @@ mpt_attach(struct pci_dev *pdev, const struct pci_device_id *id)
1690 1812
1691 /* Initialize workqueue */ 1813 /* Initialize workqueue */
1692 INIT_DELAYED_WORK(&ioc->fault_reset_work, mpt_fault_reset_work); 1814 INIT_DELAYED_WORK(&ioc->fault_reset_work, mpt_fault_reset_work);
1693 spin_lock_init(&ioc->fault_reset_work_lock);
1694 1815
1695 snprintf(ioc->reset_work_q_name, sizeof(ioc->reset_work_q_name), 1816 snprintf(ioc->reset_work_q_name, MPT_KOBJ_NAME_LEN,
1696 "mpt_poll_%d", ioc->id); 1817 "mpt_poll_%d", ioc->id);
1697 ioc->reset_work_q = 1818 ioc->reset_work_q =
1698 create_singlethread_workqueue(ioc->reset_work_q_name); 1819 create_singlethread_workqueue(ioc->reset_work_q_name);
@@ -1767,11 +1888,14 @@ mpt_attach(struct pci_dev *pdev, const struct pci_device_id *id)
1767 case MPI_MANUFACTPAGE_DEVID_SAS1064: 1888 case MPI_MANUFACTPAGE_DEVID_SAS1064:
1768 case MPI_MANUFACTPAGE_DEVID_SAS1068: 1889 case MPI_MANUFACTPAGE_DEVID_SAS1068:
1769 ioc->errata_flag_1064 = 1; 1890 ioc->errata_flag_1064 = 1;
1891 ioc->bus_type = SAS;
1892 break;
1770 1893
1771 case MPI_MANUFACTPAGE_DEVID_SAS1064E: 1894 case MPI_MANUFACTPAGE_DEVID_SAS1064E:
1772 case MPI_MANUFACTPAGE_DEVID_SAS1068E: 1895 case MPI_MANUFACTPAGE_DEVID_SAS1068E:
1773 case MPI_MANUFACTPAGE_DEVID_SAS1078: 1896 case MPI_MANUFACTPAGE_DEVID_SAS1078:
1774 ioc->bus_type = SAS; 1897 ioc->bus_type = SAS;
1898 break;
1775 } 1899 }
1776 1900
1777 1901
@@ -1813,6 +1937,11 @@ mpt_attach(struct pci_dev *pdev, const struct pci_device_id *id)
1813 */ 1937 */
1814 mpt_detect_bound_ports(ioc, pdev); 1938 mpt_detect_bound_ports(ioc, pdev);
1815 1939
1940 INIT_LIST_HEAD(&ioc->fw_event_list);
1941 spin_lock_init(&ioc->fw_event_lock);
1942 snprintf(ioc->fw_event_q_name, MPT_KOBJ_NAME_LEN, "mpt/%d", ioc->id);
1943 ioc->fw_event_q = create_singlethread_workqueue(ioc->fw_event_q_name);
1944
1816 if ((r = mpt_do_ioc_recovery(ioc, MPT_HOSTEVENT_IOC_BRINGUP, 1945 if ((r = mpt_do_ioc_recovery(ioc, MPT_HOSTEVENT_IOC_BRINGUP,
1817 CAN_SLEEP)) != 0){ 1946 CAN_SLEEP)) != 0){
1818 printk(MYIOC_s_ERR_FMT "didn't initialize properly! (%d)\n", 1947 printk(MYIOC_s_ERR_FMT "didn't initialize properly! (%d)\n",
@@ -1885,13 +2014,18 @@ mpt_detach(struct pci_dev *pdev)
1885 /* 2014 /*
1886 * Stop polling ioc for fault condition 2015 * Stop polling ioc for fault condition
1887 */ 2016 */
1888 spin_lock_irqsave(&ioc->fault_reset_work_lock, flags); 2017 spin_lock_irqsave(&ioc->taskmgmt_lock, flags);
1889 wq = ioc->reset_work_q; 2018 wq = ioc->reset_work_q;
1890 ioc->reset_work_q = NULL; 2019 ioc->reset_work_q = NULL;
1891 spin_unlock_irqrestore(&ioc->fault_reset_work_lock, flags); 2020 spin_unlock_irqrestore(&ioc->taskmgmt_lock, flags);
1892 cancel_delayed_work(&ioc->fault_reset_work); 2021 cancel_delayed_work(&ioc->fault_reset_work);
1893 destroy_workqueue(wq); 2022 destroy_workqueue(wq);
1894 2023
2024 spin_lock_irqsave(&ioc->fw_event_lock, flags);
2025 wq = ioc->fw_event_q;
2026 ioc->fw_event_q = NULL;
2027 spin_unlock_irqrestore(&ioc->fw_event_lock, flags);
2028 destroy_workqueue(wq);
1895 2029
1896 sprintf(pname, MPT_PROCFS_MPTBASEDIR "/%s/summary", ioc->name); 2030 sprintf(pname, MPT_PROCFS_MPTBASEDIR "/%s/summary", ioc->name);
1897 remove_proc_entry(pname, NULL); 2031 remove_proc_entry(pname, NULL);
@@ -1994,6 +2128,21 @@ mpt_resume(struct pci_dev *pdev)
1994 if (err) 2128 if (err)
1995 return err; 2129 return err;
1996 2130
2131 if (ioc->dma_mask == DMA_BIT_MASK(64)) {
2132 if (pdev->device == MPI_MANUFACTPAGE_DEVID_SAS1078)
2133 ioc->add_sge = &mpt_add_sge_64bit_1078;
2134 else
2135 ioc->add_sge = &mpt_add_sge_64bit;
2136 ioc->add_chain = &mpt_add_chain_64bit;
2137 ioc->sg_addr_size = 8;
2138 } else {
2139
2140 ioc->add_sge = &mpt_add_sge;
2141 ioc->add_chain = &mpt_add_chain;
2142 ioc->sg_addr_size = 4;
2143 }
2144 ioc->SGE_size = sizeof(u32) + ioc->sg_addr_size;
2145
1997 printk(MYIOC_s_INFO_FMT "pci-resume: ioc-state=0x%x,doorbell=0x%x\n", 2146 printk(MYIOC_s_INFO_FMT "pci-resume: ioc-state=0x%x,doorbell=0x%x\n",
1998 ioc->name, (mpt_GetIocState(ioc, 1) >> MPI_IOC_STATE_SHIFT), 2147 ioc->name, (mpt_GetIocState(ioc, 1) >> MPI_IOC_STATE_SHIFT),
1999 CHIPREG_READ32(&ioc->chip->Doorbell)); 2148 CHIPREG_READ32(&ioc->chip->Doorbell));
@@ -2091,12 +2240,16 @@ mpt_do_ioc_recovery(MPT_ADAPTER *ioc, u32 reason, int sleepFlag)
2091 ioc->active = 0; 2240 ioc->active = 0;
2092 2241
2093 if (ioc->alt_ioc) { 2242 if (ioc->alt_ioc) {
2094 if (ioc->alt_ioc->active) 2243 if (ioc->alt_ioc->active ||
2244 reason == MPT_HOSTEVENT_IOC_RECOVER) {
2095 reset_alt_ioc_active = 1; 2245 reset_alt_ioc_active = 1;
2096 2246 /* Disable alt-IOC's reply interrupts
2097 /* Disable alt-IOC's reply interrupts (and FreeQ) for a bit ... */ 2247 * (and FreeQ) for a bit
2098 CHIPREG_WRITE32(&ioc->alt_ioc->chip->IntMask, 0xFFFFFFFF); 2248 **/
2099 ioc->alt_ioc->active = 0; 2249 CHIPREG_WRITE32(&ioc->alt_ioc->chip->IntMask,
2250 0xFFFFFFFF);
2251 ioc->alt_ioc->active = 0;
2252 }
2100 } 2253 }
2101 2254
2102 hard = 1; 2255 hard = 1;
@@ -2117,9 +2270,11 @@ mpt_do_ioc_recovery(MPT_ADAPTER *ioc, u32 reason, int sleepFlag)
2117 } 2270 }
2118 2271
2119 } else { 2272 } else {
2120 printk(MYIOC_s_WARN_FMT "NOT READY!\n", ioc->name); 2273 printk(MYIOC_s_WARN_FMT
2274 "NOT READY WARNING!\n", ioc->name);
2121 } 2275 }
2122 return -1; 2276 ret = -1;
2277 goto out;
2123 } 2278 }
2124 2279
2125 /* hard_reset_done = 0 if a soft reset was performed 2280 /* hard_reset_done = 0 if a soft reset was performed
@@ -2129,7 +2284,9 @@ mpt_do_ioc_recovery(MPT_ADAPTER *ioc, u32 reason, int sleepFlag)
2129 if ((rc = MakeIocReady(ioc->alt_ioc, 0, sleepFlag)) == 0) 2284 if ((rc = MakeIocReady(ioc->alt_ioc, 0, sleepFlag)) == 0)
2130 alt_ioc_ready = 1; 2285 alt_ioc_ready = 1;
2131 else 2286 else
2132 printk(MYIOC_s_WARN_FMT "alt_ioc not ready!\n", ioc->alt_ioc->name); 2287 printk(MYIOC_s_WARN_FMT
2288 ": alt-ioc Not ready WARNING!\n",
2289 ioc->alt_ioc->name);
2133 } 2290 }
2134 2291
2135 for (ii=0; ii<5; ii++) { 2292 for (ii=0; ii<5; ii++) {
@@ -2150,7 +2307,8 @@ mpt_do_ioc_recovery(MPT_ADAPTER *ioc, u32 reason, int sleepFlag)
2150 if (alt_ioc_ready) { 2307 if (alt_ioc_ready) {
2151 if ((rc = GetIocFacts(ioc->alt_ioc, sleepFlag, reason)) != 0) { 2308 if ((rc = GetIocFacts(ioc->alt_ioc, sleepFlag, reason)) != 0) {
2152 dinitprintk(ioc, printk(MYIOC_s_DEBUG_FMT 2309 dinitprintk(ioc, printk(MYIOC_s_DEBUG_FMT
2153 "Initial Alt IocFacts failed rc=%x\n", ioc->name, rc)); 2310 "Initial Alt IocFacts failed rc=%x\n",
2311 ioc->name, rc));
2154 /* Retry - alt IOC was initialized once 2312 /* Retry - alt IOC was initialized once
2155 */ 2313 */
2156 rc = GetIocFacts(ioc->alt_ioc, sleepFlag, reason); 2314 rc = GetIocFacts(ioc->alt_ioc, sleepFlag, reason);
@@ -2194,16 +2352,20 @@ mpt_do_ioc_recovery(MPT_ADAPTER *ioc, u32 reason, int sleepFlag)
2194 IRQF_SHARED, ioc->name, ioc); 2352 IRQF_SHARED, ioc->name, ioc);
2195 if (rc < 0) { 2353 if (rc < 0) {
2196 printk(MYIOC_s_ERR_FMT "Unable to allocate " 2354 printk(MYIOC_s_ERR_FMT "Unable to allocate "
2197 "interrupt %d!\n", ioc->name, ioc->pcidev->irq); 2355 "interrupt %d!\n",
2356 ioc->name, ioc->pcidev->irq);
2198 if (ioc->msi_enable) 2357 if (ioc->msi_enable)
2199 pci_disable_msi(ioc->pcidev); 2358 pci_disable_msi(ioc->pcidev);
2200 return -EBUSY; 2359 ret = -EBUSY;
2360 goto out;
2201 } 2361 }
2202 irq_allocated = 1; 2362 irq_allocated = 1;
2203 ioc->pci_irq = ioc->pcidev->irq; 2363 ioc->pci_irq = ioc->pcidev->irq;
2204 pci_set_master(ioc->pcidev); /* ?? */ 2364 pci_set_master(ioc->pcidev); /* ?? */
2205 dprintk(ioc, printk(MYIOC_s_INFO_FMT "installed at interrupt " 2365 pci_set_drvdata(ioc->pcidev, ioc);
2206 "%d\n", ioc->name, ioc->pcidev->irq)); 2366 dinitprintk(ioc, printk(MYIOC_s_INFO_FMT
2367 "installed at interrupt %d\n", ioc->name,
2368 ioc->pcidev->irq));
2207 } 2369 }
2208 } 2370 }
2209 2371
@@ -2212,17 +2374,22 @@ mpt_do_ioc_recovery(MPT_ADAPTER *ioc, u32 reason, int sleepFlag)
2212 * init as upper addresses are needed for init. 2374 * init as upper addresses are needed for init.
2213 * If fails, continue with alt-ioc processing 2375 * If fails, continue with alt-ioc processing
2214 */ 2376 */
2377 dinitprintk(ioc, printk(MYIOC_s_INFO_FMT "PrimeIocFifos\n",
2378 ioc->name));
2215 if ((ret == 0) && ((rc = PrimeIocFifos(ioc)) != 0)) 2379 if ((ret == 0) && ((rc = PrimeIocFifos(ioc)) != 0))
2216 ret = -3; 2380 ret = -3;
2217 2381
2218 /* May need to check/upload firmware & data here! 2382 /* May need to check/upload firmware & data here!
2219 * If fails, continue with alt-ioc processing 2383 * If fails, continue with alt-ioc processing
2220 */ 2384 */
2385 dinitprintk(ioc, printk(MYIOC_s_INFO_FMT "SendIocInit\n",
2386 ioc->name));
2221 if ((ret == 0) && ((rc = SendIocInit(ioc, sleepFlag)) != 0)) 2387 if ((ret == 0) && ((rc = SendIocInit(ioc, sleepFlag)) != 0))
2222 ret = -4; 2388 ret = -4;
2223// NEW! 2389// NEW!
2224 if (alt_ioc_ready && ((rc = PrimeIocFifos(ioc->alt_ioc)) != 0)) { 2390 if (alt_ioc_ready && ((rc = PrimeIocFifos(ioc->alt_ioc)) != 0)) {
2225 printk(MYIOC_s_WARN_FMT ": alt_ioc (%d) FIFO mgmt alloc!\n", 2391 printk(MYIOC_s_WARN_FMT
2392 ": alt-ioc (%d) FIFO mgmt alloc WARNING!\n",
2226 ioc->alt_ioc->name, rc); 2393 ioc->alt_ioc->name, rc);
2227 alt_ioc_ready = 0; 2394 alt_ioc_ready = 0;
2228 reset_alt_ioc_active = 0; 2395 reset_alt_ioc_active = 0;
@@ -2232,8 +2399,9 @@ mpt_do_ioc_recovery(MPT_ADAPTER *ioc, u32 reason, int sleepFlag)
2232 if ((rc = SendIocInit(ioc->alt_ioc, sleepFlag)) != 0) { 2399 if ((rc = SendIocInit(ioc->alt_ioc, sleepFlag)) != 0) {
2233 alt_ioc_ready = 0; 2400 alt_ioc_ready = 0;
2234 reset_alt_ioc_active = 0; 2401 reset_alt_ioc_active = 0;
2235 printk(MYIOC_s_WARN_FMT "alt_ioc (%d) init failure!\n", 2402 printk(MYIOC_s_WARN_FMT
2236 ioc->alt_ioc->name, rc); 2403 ": alt-ioc: (%d) init failure WARNING!\n",
2404 ioc->alt_ioc->name, rc);
2237 } 2405 }
2238 } 2406 }
2239 2407
@@ -2269,28 +2437,36 @@ mpt_do_ioc_recovery(MPT_ADAPTER *ioc, u32 reason, int sleepFlag)
2269 } 2437 }
2270 } 2438 }
2271 2439
2440 /* Enable MPT base driver management of EventNotification
2441 * and EventAck handling.
2442 */
2443 if ((ret == 0) && (!ioc->facts.EventState)) {
2444 dinitprintk(ioc, printk(MYIOC_s_INFO_FMT
2445 "SendEventNotification\n",
2446 ioc->name));
2447 ret = SendEventNotification(ioc, 1, sleepFlag); /* 1=Enable */
2448 }
2449
2450 if (ioc->alt_ioc && alt_ioc_ready && !ioc->alt_ioc->facts.EventState)
2451 rc = SendEventNotification(ioc->alt_ioc, 1, sleepFlag);
2452
2272 if (ret == 0) { 2453 if (ret == 0) {
2273 /* Enable! (reply interrupt) */ 2454 /* Enable! (reply interrupt) */
2274 CHIPREG_WRITE32(&ioc->chip->IntMask, MPI_HIM_DIM); 2455 CHIPREG_WRITE32(&ioc->chip->IntMask, MPI_HIM_DIM);
2275 ioc->active = 1; 2456 ioc->active = 1;
2276 } 2457 }
2277 2458 if (rc == 0) { /* alt ioc */
2278 if (reset_alt_ioc_active && ioc->alt_ioc) { 2459 if (reset_alt_ioc_active && ioc->alt_ioc) {
2279 /* (re)Enable alt-IOC! (reply interrupt) */ 2460 /* (re)Enable alt-IOC! (reply interrupt) */
2280 dinitprintk(ioc, printk(MYIOC_s_INFO_FMT "alt_ioc reply irq re-enabled\n", 2461 dinitprintk(ioc, printk(MYIOC_s_DEBUG_FMT "alt-ioc"
2281 ioc->alt_ioc->name)); 2462 "reply irq re-enabled\n",
2282 CHIPREG_WRITE32(&ioc->alt_ioc->chip->IntMask, MPI_HIM_DIM); 2463 ioc->alt_ioc->name));
2283 ioc->alt_ioc->active = 1; 2464 CHIPREG_WRITE32(&ioc->alt_ioc->chip->IntMask,
2465 MPI_HIM_DIM);
2466 ioc->alt_ioc->active = 1;
2467 }
2284 } 2468 }
2285 2469
2286 /* Enable MPT base driver management of EventNotification
2287 * and EventAck handling.
2288 */
2289 if ((ret == 0) && (!ioc->facts.EventState))
2290 (void) SendEventNotification(ioc, 1); /* 1=Enable EventNotification */
2291
2292 if (ioc->alt_ioc && alt_ioc_ready && !ioc->alt_ioc->facts.EventState)
2293 (void) SendEventNotification(ioc->alt_ioc, 1); /* 1=Enable EventNotification */
2294 2470
2295 /* Add additional "reason" check before call to GetLanConfigPages 2471 /* Add additional "reason" check before call to GetLanConfigPages
2296 * (combined with GetIoUnitPage2 call). This prevents a somewhat 2472 * (combined with GetIoUnitPage2 call). This prevents a somewhat
@@ -2306,8 +2482,9 @@ mpt_do_ioc_recovery(MPT_ADAPTER *ioc, u32 reason, int sleepFlag)
2306 mutex_init(&ioc->raid_data.inactive_list_mutex); 2482 mutex_init(&ioc->raid_data.inactive_list_mutex);
2307 INIT_LIST_HEAD(&ioc->raid_data.inactive_list); 2483 INIT_LIST_HEAD(&ioc->raid_data.inactive_list);
2308 2484
2309 if (ioc->bus_type == SAS) { 2485 switch (ioc->bus_type) {
2310 2486
2487 case SAS:
2311 /* clear persistency table */ 2488 /* clear persistency table */
2312 if(ioc->facts.IOCExceptions & 2489 if(ioc->facts.IOCExceptions &
2313 MPI_IOCFACTS_EXCEPT_PERSISTENT_TABLE_FULL) { 2490 MPI_IOCFACTS_EXCEPT_PERSISTENT_TABLE_FULL) {
@@ -2321,8 +2498,15 @@ mpt_do_ioc_recovery(MPT_ADAPTER *ioc, u32 reason, int sleepFlag)
2321 */ 2498 */
2322 mpt_findImVolumes(ioc); 2499 mpt_findImVolumes(ioc);
2323 2500
2324 } else if (ioc->bus_type == FC) { 2501 /* Check, and possibly reset, the coalescing value
2325 if ((ioc->pfacts[0].ProtocolFlags & MPI_PORTFACTS_PROTOCOL_LAN) && 2502 */
2503 mpt_read_ioc_pg_1(ioc);
2504
2505 break;
2506
2507 case FC:
2508 if ((ioc->pfacts[0].ProtocolFlags &
2509 MPI_PORTFACTS_PROTOCOL_LAN) &&
2326 (ioc->lan_cnfg_page0.Header.PageLength == 0)) { 2510 (ioc->lan_cnfg_page0.Header.PageLength == 0)) {
2327 /* 2511 /*
2328 * Pre-fetch the ports LAN MAC address! 2512 * Pre-fetch the ports LAN MAC address!
@@ -2331,11 +2515,14 @@ mpt_do_ioc_recovery(MPT_ADAPTER *ioc, u32 reason, int sleepFlag)
2331 (void) GetLanConfigPages(ioc); 2515 (void) GetLanConfigPages(ioc);
2332 a = (u8*)&ioc->lan_cnfg_page1.HardwareAddressLow; 2516 a = (u8*)&ioc->lan_cnfg_page1.HardwareAddressLow;
2333 dprintk(ioc, printk(MYIOC_s_DEBUG_FMT 2517 dprintk(ioc, printk(MYIOC_s_DEBUG_FMT
2334 "LanAddr = %02X:%02X:%02X:%02X:%02X:%02X\n", 2518 "LanAddr = %02X:%02X:%02X"
2335 ioc->name, a[5], a[4], a[3], a[2], a[1], a[0])); 2519 ":%02X:%02X:%02X\n",
2336 2520 ioc->name, a[5], a[4],
2521 a[3], a[2], a[1], a[0]));
2337 } 2522 }
2338 } else { 2523 break;
2524
2525 case SPI:
2339 /* Get NVRAM and adapter maximums from SPP 0 and 2 2526 /* Get NVRAM and adapter maximums from SPP 0 and 2
2340 */ 2527 */
2341 mpt_GetScsiPortSettings(ioc, 0); 2528 mpt_GetScsiPortSettings(ioc, 0);
@@ -2354,6 +2541,8 @@ mpt_do_ioc_recovery(MPT_ADAPTER *ioc, u32 reason, int sleepFlag)
2354 mpt_read_ioc_pg_1(ioc); 2541 mpt_read_ioc_pg_1(ioc);
2355 2542
2356 mpt_read_ioc_pg_4(ioc); 2543 mpt_read_ioc_pg_4(ioc);
2544
2545 break;
2357 } 2546 }
2358 2547
2359 GetIoUnitPage2(ioc); 2548 GetIoUnitPage2(ioc);
@@ -2435,16 +2624,20 @@ mpt_detect_bound_ports(MPT_ADAPTER *ioc, struct pci_dev *pdev)
2435 if (_pcidev == peer) { 2624 if (_pcidev == peer) {
2436 /* Paranoia checks */ 2625 /* Paranoia checks */
2437 if (ioc->alt_ioc != NULL) { 2626 if (ioc->alt_ioc != NULL) {
2438 printk(MYIOC_s_WARN_FMT "Oops, already bound to %s!\n", 2627 printk(MYIOC_s_WARN_FMT
2439 ioc->name, ioc->alt_ioc->name); 2628 "Oops, already bound (%s <==> %s)!\n",
2629 ioc->name, ioc->name, ioc->alt_ioc->name);
2440 break; 2630 break;
2441 } else if (ioc_srch->alt_ioc != NULL) { 2631 } else if (ioc_srch->alt_ioc != NULL) {
2442 printk(MYIOC_s_WARN_FMT "Oops, already bound to %s!\n", 2632 printk(MYIOC_s_WARN_FMT
2443 ioc_srch->name, ioc_srch->alt_ioc->name); 2633 "Oops, already bound (%s <==> %s)!\n",
2634 ioc_srch->name, ioc_srch->name,
2635 ioc_srch->alt_ioc->name);
2444 break; 2636 break;
2445 } 2637 }
2446 dprintk(ioc, printk(MYIOC_s_INFO_FMT "FOUND! binding to %s\n", 2638 dprintk(ioc, printk(MYIOC_s_DEBUG_FMT
2447 ioc->name, ioc_srch->name)); 2639 "FOUND! binding %s <==> %s\n",
2640 ioc->name, ioc->name, ioc_srch->name));
2448 ioc_srch->alt_ioc = ioc; 2641 ioc_srch->alt_ioc = ioc;
2449 ioc->alt_ioc = ioc_srch; 2642 ioc->alt_ioc = ioc_srch;
2450 } 2643 }
@@ -2464,8 +2657,8 @@ mpt_adapter_disable(MPT_ADAPTER *ioc)
2464 int ret; 2657 int ret;
2465 2658
2466 if (ioc->cached_fw != NULL) { 2659 if (ioc->cached_fw != NULL) {
2467 ddlprintk(ioc, printk(MYIOC_s_DEBUG_FMT "%s: Pushing FW onto " 2660 ddlprintk(ioc, printk(MYIOC_s_DEBUG_FMT
2468 "adapter\n", __func__, ioc->name)); 2661 "%s: Pushing FW onto adapter\n", __func__, ioc->name));
2469 if ((ret = mpt_downloadboot(ioc, (MpiFwHeader_t *) 2662 if ((ret = mpt_downloadboot(ioc, (MpiFwHeader_t *)
2470 ioc->cached_fw, CAN_SLEEP)) < 0) { 2663 ioc->cached_fw, CAN_SLEEP)) < 0) {
2471 printk(MYIOC_s_WARN_FMT 2664 printk(MYIOC_s_WARN_FMT
@@ -2474,11 +2667,30 @@ mpt_adapter_disable(MPT_ADAPTER *ioc)
2474 } 2667 }
2475 } 2668 }
2476 2669
2670 /*
2671 * Put the controller into ready state (if its not already)
2672 */
2673 if (mpt_GetIocState(ioc, 1) != MPI_IOC_STATE_READY) {
2674 if (!SendIocReset(ioc, MPI_FUNCTION_IOC_MESSAGE_UNIT_RESET,
2675 CAN_SLEEP)) {
2676 if (mpt_GetIocState(ioc, 1) != MPI_IOC_STATE_READY)
2677 printk(MYIOC_s_ERR_FMT "%s: IOC msg unit "
2678 "reset failed to put ioc in ready state!\n",
2679 ioc->name, __func__);
2680 } else
2681 printk(MYIOC_s_ERR_FMT "%s: IOC msg unit reset "
2682 "failed!\n", ioc->name, __func__);
2683 }
2684
2685
2477 /* Disable adapter interrupts! */ 2686 /* Disable adapter interrupts! */
2687 synchronize_irq(ioc->pcidev->irq);
2478 CHIPREG_WRITE32(&ioc->chip->IntMask, 0xFFFFFFFF); 2688 CHIPREG_WRITE32(&ioc->chip->IntMask, 0xFFFFFFFF);
2479 ioc->active = 0; 2689 ioc->active = 0;
2690
2480 /* Clear any lingering interrupt */ 2691 /* Clear any lingering interrupt */
2481 CHIPREG_WRITE32(&ioc->chip->IntStatus, 0); 2692 CHIPREG_WRITE32(&ioc->chip->IntStatus, 0);
2693 CHIPREG_READ32(&ioc->chip->IntStatus);
2482 2694
2483 if (ioc->alloc != NULL) { 2695 if (ioc->alloc != NULL) {
2484 sz = ioc->alloc_sz; 2696 sz = ioc->alloc_sz;
@@ -2538,19 +2750,22 @@ mpt_adapter_disable(MPT_ADAPTER *ioc)
2538 if((ret = mpt_host_page_access_control(ioc, 2750 if((ret = mpt_host_page_access_control(ioc,
2539 MPI_DB_HPBAC_FREE_BUFFER, NO_SLEEP)) != 0) { 2751 MPI_DB_HPBAC_FREE_BUFFER, NO_SLEEP)) != 0) {
2540 printk(MYIOC_s_ERR_FMT 2752 printk(MYIOC_s_ERR_FMT
2541 "host page buffers free failed (%d)!\n", 2753 ": %s: host page buffers free failed (%d)!\n",
2542 ioc->name, ret); 2754 ioc->name, __func__, ret);
2543 } 2755 }
2544 dexitprintk(ioc, printk(MYIOC_s_INFO_FMT "HostPageBuffer free @ %p, sz=%d bytes\n", 2756 dexitprintk(ioc, printk(MYIOC_s_DEBUG_FMT
2545 ioc->name, ioc->HostPageBuffer, ioc->HostPageBuffer_sz)); 2757 "HostPageBuffer free @ %p, sz=%d bytes\n",
2758 ioc->name, ioc->HostPageBuffer,
2759 ioc->HostPageBuffer_sz));
2546 pci_free_consistent(ioc->pcidev, ioc->HostPageBuffer_sz, 2760 pci_free_consistent(ioc->pcidev, ioc->HostPageBuffer_sz,
2547 ioc->HostPageBuffer, ioc->HostPageBuffer_dma); 2761 ioc->HostPageBuffer, ioc->HostPageBuffer_dma);
2548 ioc->HostPageBuffer = NULL; 2762 ioc->HostPageBuffer = NULL;
2549 ioc->HostPageBuffer_sz = 0; 2763 ioc->HostPageBuffer_sz = 0;
2550 ioc->alloc_total -= ioc->HostPageBuffer_sz; 2764 ioc->alloc_total -= ioc->HostPageBuffer_sz;
2551 } 2765 }
2552}
2553 2766
2767 pci_set_drvdata(ioc->pcidev, NULL);
2768}
2554/*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/ 2769/*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
2555/** 2770/**
2556 * mpt_adapter_dispose - Free all resources associated with an MPT adapter 2771 * mpt_adapter_dispose - Free all resources associated with an MPT adapter
@@ -2690,8 +2905,12 @@ MakeIocReady(MPT_ADAPTER *ioc, int force, int sleepFlag)
2690 } 2905 }
2691 2906
2692 /* Is it already READY? */ 2907 /* Is it already READY? */
2693 if (!statefault && (ioc_state & MPI_IOC_STATE_MASK) == MPI_IOC_STATE_READY) 2908 if (!statefault &&
2909 ((ioc_state & MPI_IOC_STATE_MASK) == MPI_IOC_STATE_READY)) {
2910 dinitprintk(ioc, printk(MYIOC_s_INFO_FMT
2911 "IOC is in READY state\n", ioc->name));
2694 return 0; 2912 return 0;
2913 }
2695 2914
2696 /* 2915 /*
2697 * Check to see if IOC is in FAULT state. 2916 * Check to see if IOC is in FAULT state.
@@ -2764,8 +2983,9 @@ MakeIocReady(MPT_ADAPTER *ioc, int force, int sleepFlag)
2764 2983
2765 ii++; cntdn--; 2984 ii++; cntdn--;
2766 if (!cntdn) { 2985 if (!cntdn) {
2767 printk(MYIOC_s_ERR_FMT "Wait IOC_READY state timeout(%d)!\n", 2986 printk(MYIOC_s_ERR_FMT
2768 ioc->name, (int)((ii+5)/HZ)); 2987 "Wait IOC_READY state (0x%x) timeout(%d)!\n",
2988 ioc->name, ioc_state, (int)((ii+5)/HZ));
2769 return -ETIME; 2989 return -ETIME;
2770 } 2990 }
2771 2991
@@ -2778,9 +2998,8 @@ MakeIocReady(MPT_ADAPTER *ioc, int force, int sleepFlag)
2778 } 2998 }
2779 2999
2780 if (statefault < 3) { 3000 if (statefault < 3) {
2781 printk(MYIOC_s_INFO_FMT "Recovered from %s\n", 3001 printk(MYIOC_s_INFO_FMT "Recovered from %s\n", ioc->name,
2782 ioc->name, 3002 statefault == 1 ? "stuck handshake" : "IOC FAULT");
2783 statefault==1 ? "stuck handshake" : "IOC FAULT");
2784 } 3003 }
2785 3004
2786 return hard_reset_done; 3005 return hard_reset_done;
@@ -2833,8 +3052,9 @@ GetIocFacts(MPT_ADAPTER *ioc, int sleepFlag, int reason)
2833 3052
2834 /* IOC *must* NOT be in RESET state! */ 3053 /* IOC *must* NOT be in RESET state! */
2835 if (ioc->last_state == MPI_IOC_STATE_RESET) { 3054 if (ioc->last_state == MPI_IOC_STATE_RESET) {
2836 printk(MYIOC_s_ERR_FMT "Can't get IOCFacts NOT READY! (%08x)\n", 3055 printk(KERN_ERR MYNAM
2837 ioc->name, ioc->last_state ); 3056 ": ERROR - Can't get IOCFacts, %s NOT READY! (%08x)\n",
3057 ioc->name, ioc->last_state);
2838 return -44; 3058 return -44;
2839 } 3059 }
2840 3060
@@ -2896,7 +3116,7 @@ GetIocFacts(MPT_ADAPTER *ioc, int sleepFlag, int reason)
2896 * Old: u16{Major(4),Minor(4),SubMinor(8)} 3116 * Old: u16{Major(4),Minor(4),SubMinor(8)}
2897 * New: u32{Major(8),Minor(8),Unit(8),Dev(8)} 3117 * New: u32{Major(8),Minor(8),Unit(8),Dev(8)}
2898 */ 3118 */
2899 if (facts->MsgVersion < 0x0102) { 3119 if (facts->MsgVersion < MPI_VERSION_01_02) {
2900 /* 3120 /*
2901 * Handle old FC f/w style, convert to new... 3121 * Handle old FC f/w style, convert to new...
2902 */ 3122 */
@@ -2908,9 +3128,11 @@ GetIocFacts(MPT_ADAPTER *ioc, int sleepFlag, int reason)
2908 facts->FWVersion.Word = le32_to_cpu(facts->FWVersion.Word); 3128 facts->FWVersion.Word = le32_to_cpu(facts->FWVersion.Word);
2909 3129
2910 facts->ProductID = le16_to_cpu(facts->ProductID); 3130 facts->ProductID = le16_to_cpu(facts->ProductID);
3131
2911 if ((ioc->facts.ProductID & MPI_FW_HEADER_PID_PROD_MASK) 3132 if ((ioc->facts.ProductID & MPI_FW_HEADER_PID_PROD_MASK)
2912 > MPI_FW_HEADER_PID_PROD_TARGET_SCSI) 3133 > MPI_FW_HEADER_PID_PROD_TARGET_SCSI)
2913 ioc->ir_firmware = 1; 3134 ioc->ir_firmware = 1;
3135
2914 facts->CurrentHostMfaHighAddr = 3136 facts->CurrentHostMfaHighAddr =
2915 le32_to_cpu(facts->CurrentHostMfaHighAddr); 3137 le32_to_cpu(facts->CurrentHostMfaHighAddr);
2916 facts->GlobalCredits = le16_to_cpu(facts->GlobalCredits); 3138 facts->GlobalCredits = le16_to_cpu(facts->GlobalCredits);
@@ -2926,7 +3148,7 @@ GetIocFacts(MPT_ADAPTER *ioc, int sleepFlag, int reason)
2926 * to 14 in MPI-1.01.0x. 3148 * to 14 in MPI-1.01.0x.
2927 */ 3149 */
2928 if (facts->MsgLength >= (offsetof(IOCFactsReply_t,FWImageSize) + 7)/4 && 3150 if (facts->MsgLength >= (offsetof(IOCFactsReply_t,FWImageSize) + 7)/4 &&
2929 facts->MsgVersion > 0x0100) { 3151 facts->MsgVersion > MPI_VERSION_01_00) {
2930 facts->FWImageSize = le32_to_cpu(facts->FWImageSize); 3152 facts->FWImageSize = le32_to_cpu(facts->FWImageSize);
2931 } 3153 }
2932 3154
@@ -3108,6 +3330,7 @@ SendIocInit(MPT_ADAPTER *ioc, int sleepFlag)
3108 3330
3109 ioc_init.MaxDevices = (U8)ioc->devices_per_bus; 3331 ioc_init.MaxDevices = (U8)ioc->devices_per_bus;
3110 ioc_init.MaxBuses = (U8)ioc->number_of_buses; 3332 ioc_init.MaxBuses = (U8)ioc->number_of_buses;
3333
3111 dinitprintk(ioc, printk(MYIOC_s_DEBUG_FMT "facts.MsgVersion=%x\n", 3334 dinitprintk(ioc, printk(MYIOC_s_DEBUG_FMT "facts.MsgVersion=%x\n",
3112 ioc->name, ioc->facts.MsgVersion)); 3335 ioc->name, ioc->facts.MsgVersion));
3113 if (ioc->facts.MsgVersion >= MPI_VERSION_01_05) { 3336 if (ioc->facts.MsgVersion >= MPI_VERSION_01_05) {
@@ -3122,7 +3345,7 @@ SendIocInit(MPT_ADAPTER *ioc, int sleepFlag)
3122 } 3345 }
3123 ioc_init.ReplyFrameSize = cpu_to_le16(ioc->reply_sz); /* in BYTES */ 3346 ioc_init.ReplyFrameSize = cpu_to_le16(ioc->reply_sz); /* in BYTES */
3124 3347
3125 if (sizeof(dma_addr_t) == sizeof(u64)) { 3348 if (ioc->sg_addr_size == sizeof(u64)) {
3126 /* Save the upper 32-bits of the request 3349 /* Save the upper 32-bits of the request
3127 * (reply) and sense buffers. 3350 * (reply) and sense buffers.
3128 */ 3351 */
@@ -3325,11 +3548,10 @@ mpt_do_upload(MPT_ADAPTER *ioc, int sleepFlag)
3325 FWUpload_t *prequest; 3548 FWUpload_t *prequest;
3326 FWUploadReply_t *preply; 3549 FWUploadReply_t *preply;
3327 FWUploadTCSGE_t *ptcsge; 3550 FWUploadTCSGE_t *ptcsge;
3328 int sgeoffset;
3329 u32 flagsLength; 3551 u32 flagsLength;
3330 int ii, sz, reply_sz; 3552 int ii, sz, reply_sz;
3331 int cmdStatus; 3553 int cmdStatus;
3332 3554 int request_size;
3333 /* If the image size is 0, we are done. 3555 /* If the image size is 0, we are done.
3334 */ 3556 */
3335 if ((sz = ioc->facts.FWImageSize) == 0) 3557 if ((sz = ioc->facts.FWImageSize) == 0)
@@ -3364,42 +3586,41 @@ mpt_do_upload(MPT_ADAPTER *ioc, int sleepFlag)
3364 ptcsge->ImageSize = cpu_to_le32(sz); 3586 ptcsge->ImageSize = cpu_to_le32(sz);
3365 ptcsge++; 3587 ptcsge++;
3366 3588
3367 sgeoffset = sizeof(FWUpload_t) - sizeof(SGE_MPI_UNION) + sizeof(FWUploadTCSGE_t);
3368
3369 flagsLength = MPT_SGE_FLAGS_SSIMPLE_READ | sz; 3589 flagsLength = MPT_SGE_FLAGS_SSIMPLE_READ | sz;
3370 mpt_add_sge((char *)ptcsge, flagsLength, ioc->cached_fw_dma); 3590 ioc->add_sge((char *)ptcsge, flagsLength, ioc->cached_fw_dma);
3371 3591 request_size = offsetof(FWUpload_t, SGL) + sizeof(FWUploadTCSGE_t) +
3372 sgeoffset += sizeof(u32) + sizeof(dma_addr_t); 3592 ioc->SGE_size;
3373 dinitprintk(ioc, printk(MYIOC_s_INFO_FMT ": Sending FW Upload (req @ %p) sgeoffset=%d \n", 3593 dinitprintk(ioc, printk(MYIOC_s_DEBUG_FMT "Sending FW Upload "
3374 ioc->name, prequest, sgeoffset)); 3594 " (req @ %p) fw_size=%d mf_request_size=%d\n", ioc->name, prequest,
3595 ioc->facts.FWImageSize, request_size));
3375 DBG_DUMP_FW_REQUEST_FRAME(ioc, (u32 *)prequest); 3596 DBG_DUMP_FW_REQUEST_FRAME(ioc, (u32 *)prequest);
3376 3597
3377 ii = mpt_handshake_req_reply_wait(ioc, sgeoffset, (u32*)prequest, 3598 ii = mpt_handshake_req_reply_wait(ioc, request_size, (u32 *)prequest,
3378 reply_sz, (u16*)preply, 65 /*seconds*/, sleepFlag); 3599 reply_sz, (u16 *)preply, 65 /*seconds*/, sleepFlag);
3379 3600
3380 dinitprintk(ioc, printk(MYIOC_s_INFO_FMT ": FW Upload completed rc=%x \n", ioc->name, ii)); 3601 dinitprintk(ioc, printk(MYIOC_s_DEBUG_FMT "FW Upload completed "
3602 "rc=%x \n", ioc->name, ii));
3381 3603
3382 cmdStatus = -EFAULT; 3604 cmdStatus = -EFAULT;
3383 if (ii == 0) { 3605 if (ii == 0) {
3384 /* Handshake transfer was complete and successful. 3606 /* Handshake transfer was complete and successful.
3385 * Check the Reply Frame. 3607 * Check the Reply Frame.
3386 */ 3608 */
3387 int status, transfer_sz; 3609 int status;
3388 status = le16_to_cpu(preply->IOCStatus); 3610 status = le16_to_cpu(preply->IOCStatus) &
3389 if (status == MPI_IOCSTATUS_SUCCESS) { 3611 MPI_IOCSTATUS_MASK;
3390 transfer_sz = le32_to_cpu(preply->ActualImageSize); 3612 if (status == MPI_IOCSTATUS_SUCCESS &&
3391 if (transfer_sz == sz) 3613 ioc->facts.FWImageSize ==
3614 le32_to_cpu(preply->ActualImageSize))
3392 cmdStatus = 0; 3615 cmdStatus = 0;
3393 }
3394 } 3616 }
3395 dinitprintk(ioc, printk(MYIOC_s_DEBUG_FMT ": do_upload cmdStatus=%d \n", 3617 dinitprintk(ioc, printk(MYIOC_s_DEBUG_FMT ": do_upload cmdStatus=%d \n",
3396 ioc->name, cmdStatus)); 3618 ioc->name, cmdStatus));
3397 3619
3398 3620
3399 if (cmdStatus) { 3621 if (cmdStatus) {
3400 3622 ddlprintk(ioc, printk(MYIOC_s_DEBUG_FMT "fw upload failed, "
3401 ddlprintk(ioc, printk(MYIOC_s_DEBUG_FMT ": fw upload failed, freeing image \n", 3623 "freeing image \n", ioc->name));
3402 ioc->name));
3403 mpt_free_fw_memory(ioc); 3624 mpt_free_fw_memory(ioc);
3404 } 3625 }
3405 kfree(prequest); 3626 kfree(prequest);
@@ -3723,6 +3944,10 @@ mpt_diag_reset(MPT_ADAPTER *ioc, int ignore, int sleepFlag)
3723 CHIPREG_WRITE32(&ioc->chip->IntStatus, 0); 3944 CHIPREG_WRITE32(&ioc->chip->IntStatus, 0);
3724 3945
3725 if (ioc->pcidev->device == MPI_MANUFACTPAGE_DEVID_SAS1078) { 3946 if (ioc->pcidev->device == MPI_MANUFACTPAGE_DEVID_SAS1078) {
3947
3948 if (!ignore)
3949 return 0;
3950
3726 drsprintk(ioc, printk(MYIOC_s_WARN_FMT "%s: Doorbell=%p; 1078 reset " 3951 drsprintk(ioc, printk(MYIOC_s_WARN_FMT "%s: Doorbell=%p; 1078 reset "
3727 "address=%p\n", ioc->name, __func__, 3952 "address=%p\n", ioc->name, __func__,
3728 &ioc->chip->Doorbell, &ioc->chip->Reset_1078)); 3953 &ioc->chip->Doorbell, &ioc->chip->Reset_1078));
@@ -3740,6 +3965,7 @@ mpt_diag_reset(MPT_ADAPTER *ioc, int ignore, int sleepFlag)
3740 "looking for READY STATE: doorbell=%x" 3965 "looking for READY STATE: doorbell=%x"
3741 " count=%d\n", 3966 " count=%d\n",
3742 ioc->name, doorbell, count)); 3967 ioc->name, doorbell, count));
3968
3743 if (doorbell == MPI_IOC_STATE_READY) { 3969 if (doorbell == MPI_IOC_STATE_READY) {
3744 return 1; 3970 return 1;
3745 } 3971 }
@@ -3890,6 +4116,10 @@ mpt_diag_reset(MPT_ADAPTER *ioc, int ignore, int sleepFlag)
3890 doorbell = CHIPREG_READ32(&ioc->chip->Doorbell); 4116 doorbell = CHIPREG_READ32(&ioc->chip->Doorbell);
3891 doorbell &= MPI_IOC_STATE_MASK; 4117 doorbell &= MPI_IOC_STATE_MASK;
3892 4118
4119 drsprintk(ioc, printk(MYIOC_s_DEBUG_FMT
4120 "looking for READY STATE: doorbell=%x"
4121 " count=%d\n", ioc->name, doorbell, count));
4122
3893 if (doorbell == MPI_IOC_STATE_READY) { 4123 if (doorbell == MPI_IOC_STATE_READY) {
3894 break; 4124 break;
3895 } 4125 }
@@ -3901,6 +4131,11 @@ mpt_diag_reset(MPT_ADAPTER *ioc, int ignore, int sleepFlag)
3901 mdelay (1000); 4131 mdelay (1000);
3902 } 4132 }
3903 } 4133 }
4134
4135 if (doorbell != MPI_IOC_STATE_READY)
4136 printk(MYIOC_s_ERR_FMT "Failed to come READY "
4137 "after reset! IocState=%x", ioc->name,
4138 doorbell);
3904 } 4139 }
3905 } 4140 }
3906 4141
@@ -4019,8 +4254,9 @@ SendIocReset(MPT_ADAPTER *ioc, u8 reset_type, int sleepFlag)
4019 if (sleepFlag != CAN_SLEEP) 4254 if (sleepFlag != CAN_SLEEP)
4020 count *= 10; 4255 count *= 10;
4021 4256
4022 printk(MYIOC_s_ERR_FMT "Wait IOC_READY state timeout(%d)!\n", 4257 printk(MYIOC_s_ERR_FMT
4023 ioc->name, (int)((count+5)/HZ)); 4258 "Wait IOC_READY state (0x%x) timeout(%d)!\n",
4259 ioc->name, state, (int)((count+5)/HZ));
4024 return -ETIME; 4260 return -ETIME;
4025 } 4261 }
4026 4262
@@ -4090,24 +4326,29 @@ initChainBuffers(MPT_ADAPTER *ioc)
4090 * num_sge = num sge in request frame + last chain buffer 4326 * num_sge = num sge in request frame + last chain buffer
4091 * scale = num sge per chain buffer if no chain element 4327 * scale = num sge per chain buffer if no chain element
4092 */ 4328 */
4093 scale = ioc->req_sz/(sizeof(dma_addr_t) + sizeof(u32)); 4329 scale = ioc->req_sz / ioc->SGE_size;
4094 if (sizeof(dma_addr_t) == sizeof(u64)) 4330 if (ioc->sg_addr_size == sizeof(u64))
4095 num_sge = scale + (ioc->req_sz - 60) / (sizeof(dma_addr_t) + sizeof(u32)); 4331 num_sge = scale + (ioc->req_sz - 60) / ioc->SGE_size;
4096 else 4332 else
4097 num_sge = 1+ scale + (ioc->req_sz - 64) / (sizeof(dma_addr_t) + sizeof(u32)); 4333 num_sge = 1 + scale + (ioc->req_sz - 64) / ioc->SGE_size;
4098 4334
4099 if (sizeof(dma_addr_t) == sizeof(u64)) { 4335 if (ioc->sg_addr_size == sizeof(u64)) {
4100 numSGE = (scale - 1) * (ioc->facts.MaxChainDepth-1) + scale + 4336 numSGE = (scale - 1) * (ioc->facts.MaxChainDepth-1) + scale +
4101 (ioc->req_sz - 60) / (sizeof(dma_addr_t) + sizeof(u32)); 4337 (ioc->req_sz - 60) / ioc->SGE_size;
4102 } else { 4338 } else {
4103 numSGE = 1 + (scale - 1) * (ioc->facts.MaxChainDepth-1) + scale + 4339 numSGE = 1 + (scale - 1) * (ioc->facts.MaxChainDepth-1) +
4104 (ioc->req_sz - 64) / (sizeof(dma_addr_t) + sizeof(u32)); 4340 scale + (ioc->req_sz - 64) / ioc->SGE_size;
4105 } 4341 }
4106 dinitprintk(ioc, printk(MYIOC_s_DEBUG_FMT "num_sge=%d numSGE=%d\n", 4342 dinitprintk(ioc, printk(MYIOC_s_DEBUG_FMT "num_sge=%d numSGE=%d\n",
4107 ioc->name, num_sge, numSGE)); 4343 ioc->name, num_sge, numSGE));
4108 4344
4109 if ( numSGE > MPT_SCSI_SG_DEPTH ) 4345 if (ioc->bus_type == FC) {
4110 numSGE = MPT_SCSI_SG_DEPTH; 4346 if (numSGE > MPT_SCSI_FC_SG_DEPTH)
4347 numSGE = MPT_SCSI_FC_SG_DEPTH;
4348 } else {
4349 if (numSGE > MPT_SCSI_SG_DEPTH)
4350 numSGE = MPT_SCSI_SG_DEPTH;
4351 }
4111 4352
4112 num_chain = 1; 4353 num_chain = 1;
4113 while (numSGE - num_sge > 0) { 4354 while (numSGE - num_sge > 0) {
@@ -4161,12 +4402,42 @@ PrimeIocFifos(MPT_ADAPTER *ioc)
4161 dma_addr_t alloc_dma; 4402 dma_addr_t alloc_dma;
4162 u8 *mem; 4403 u8 *mem;
4163 int i, reply_sz, sz, total_size, num_chain; 4404 int i, reply_sz, sz, total_size, num_chain;
4405 u64 dma_mask;
4406
4407 dma_mask = 0;
4164 4408
4165 /* Prime reply FIFO... */ 4409 /* Prime reply FIFO... */
4166 4410
4167 if (ioc->reply_frames == NULL) { 4411 if (ioc->reply_frames == NULL) {
4168 if ( (num_chain = initChainBuffers(ioc)) < 0) 4412 if ( (num_chain = initChainBuffers(ioc)) < 0)
4169 return -1; 4413 return -1;
4414 /*
4415 * 1078 errata workaround for the 36GB limitation
4416 */
4417 if (ioc->pcidev->device == MPI_MANUFACTPAGE_DEVID_SAS1078 &&
4418 ioc->dma_mask > DMA_35BIT_MASK) {
4419 if (!pci_set_dma_mask(ioc->pcidev, DMA_BIT_MASK(32))
4420 && !pci_set_consistent_dma_mask(ioc->pcidev,
4421 DMA_BIT_MASK(32))) {
4422 dma_mask = DMA_35BIT_MASK;
4423 d36memprintk(ioc, printk(MYIOC_s_DEBUG_FMT
4424 "setting 35 bit addressing for "
4425 "Request/Reply/Chain and Sense Buffers\n",
4426 ioc->name));
4427 } else {
4428 /*Reseting DMA mask to 64 bit*/
4429 pci_set_dma_mask(ioc->pcidev,
4430 DMA_BIT_MASK(64));
4431 pci_set_consistent_dma_mask(ioc->pcidev,
4432 DMA_BIT_MASK(64));
4433
4434 printk(MYIOC_s_ERR_FMT
4435 "failed setting 35 bit addressing for "
4436 "Request/Reply/Chain and Sense Buffers\n",
4437 ioc->name);
4438 return -1;
4439 }
4440 }
4170 4441
4171 total_size = reply_sz = (ioc->reply_sz * ioc->reply_depth); 4442 total_size = reply_sz = (ioc->reply_sz * ioc->reply_depth);
4172 dinitprintk(ioc, printk(MYIOC_s_DEBUG_FMT "ReplyBuffer sz=%d bytes, ReplyDepth=%d\n", 4443 dinitprintk(ioc, printk(MYIOC_s_DEBUG_FMT "ReplyBuffer sz=%d bytes, ReplyDepth=%d\n",
@@ -4305,9 +4576,16 @@ PrimeIocFifos(MPT_ADAPTER *ioc)
4305 alloc_dma += ioc->reply_sz; 4576 alloc_dma += ioc->reply_sz;
4306 } 4577 }
4307 4578
4579 if (dma_mask == DMA_35BIT_MASK && !pci_set_dma_mask(ioc->pcidev,
4580 ioc->dma_mask) && !pci_set_consistent_dma_mask(ioc->pcidev,
4581 ioc->dma_mask))
4582 d36memprintk(ioc, printk(MYIOC_s_DEBUG_FMT
4583 "restoring 64 bit addressing\n", ioc->name));
4584
4308 return 0; 4585 return 0;
4309 4586
4310out_fail: 4587out_fail:
4588
4311 if (ioc->alloc != NULL) { 4589 if (ioc->alloc != NULL) {
4312 sz = ioc->alloc_sz; 4590 sz = ioc->alloc_sz;
4313 pci_free_consistent(ioc->pcidev, 4591 pci_free_consistent(ioc->pcidev,
@@ -4324,6 +4602,13 @@ out_fail:
4324 ioc->sense_buf_pool, ioc->sense_buf_pool_dma); 4602 ioc->sense_buf_pool, ioc->sense_buf_pool_dma);
4325 ioc->sense_buf_pool = NULL; 4603 ioc->sense_buf_pool = NULL;
4326 } 4604 }
4605
4606 if (dma_mask == DMA_35BIT_MASK && !pci_set_dma_mask(ioc->pcidev,
4607 DMA_BIT_MASK(64)) && !pci_set_consistent_dma_mask(ioc->pcidev,
4608 DMA_BIT_MASK(64)))
4609 d36memprintk(ioc, printk(MYIOC_s_DEBUG_FMT
4610 "restoring 64 bit addressing\n", ioc->name));
4611
4327 return -1; 4612 return -1;
4328} 4613}
4329 4614
@@ -4759,7 +5044,14 @@ mptbase_sas_persist_operation(MPT_ADAPTER *ioc, u8 persist_opcode)
4759 SasIoUnitControlReply_t *sasIoUnitCntrReply; 5044 SasIoUnitControlReply_t *sasIoUnitCntrReply;
4760 MPT_FRAME_HDR *mf = NULL; 5045 MPT_FRAME_HDR *mf = NULL;
4761 MPIHeader_t *mpi_hdr; 5046 MPIHeader_t *mpi_hdr;
5047 int ret = 0;
5048 unsigned long timeleft;
5049
5050 mutex_lock(&ioc->mptbase_cmds.mutex);
4762 5051
5052 /* init the internal cmd struct */
5053 memset(ioc->mptbase_cmds.reply, 0 , MPT_DEFAULT_FRAME_SIZE);
5054 INITIALIZE_MGMT_STATUS(ioc->mptbase_cmds.status)
4763 5055
4764 /* insure garbage is not sent to fw */ 5056 /* insure garbage is not sent to fw */
4765 switch(persist_opcode) { 5057 switch(persist_opcode) {
@@ -4769,17 +5061,19 @@ mptbase_sas_persist_operation(MPT_ADAPTER *ioc, u8 persist_opcode)
4769 break; 5061 break;
4770 5062
4771 default: 5063 default:
4772 return -1; 5064 ret = -1;
4773 break; 5065 goto out;
4774 } 5066 }
4775 5067
4776 printk("%s: persist_opcode=%x\n",__func__, persist_opcode); 5068 printk(KERN_DEBUG "%s: persist_opcode=%x\n",
5069 __func__, persist_opcode);
4777 5070
4778 /* Get a MF for this command. 5071 /* Get a MF for this command.
4779 */ 5072 */
4780 if ((mf = mpt_get_msg_frame(mpt_base_index, ioc)) == NULL) { 5073 if ((mf = mpt_get_msg_frame(mpt_base_index, ioc)) == NULL) {
4781 printk("%s: no msg frames!\n",__func__); 5074 printk(KERN_DEBUG "%s: no msg frames!\n", __func__);
4782 return -1; 5075 ret = -1;
5076 goto out;
4783 } 5077 }
4784 5078
4785 mpi_hdr = (MPIHeader_t *) mf; 5079 mpi_hdr = (MPIHeader_t *) mf;
@@ -4789,27 +5083,42 @@ mptbase_sas_persist_operation(MPT_ADAPTER *ioc, u8 persist_opcode)
4789 sasIoUnitCntrReq->MsgContext = mpi_hdr->MsgContext; 5083 sasIoUnitCntrReq->MsgContext = mpi_hdr->MsgContext;
4790 sasIoUnitCntrReq->Operation = persist_opcode; 5084 sasIoUnitCntrReq->Operation = persist_opcode;
4791 5085
4792 init_timer(&ioc->persist_timer);
4793 ioc->persist_timer.data = (unsigned long) ioc;
4794 ioc->persist_timer.function = mpt_timer_expired;
4795 ioc->persist_timer.expires = jiffies + HZ*10 /* 10 sec */;
4796 ioc->persist_wait_done=0;
4797 add_timer(&ioc->persist_timer);
4798 mpt_put_msg_frame(mpt_base_index, ioc, mf); 5086 mpt_put_msg_frame(mpt_base_index, ioc, mf);
4799 wait_event(mpt_waitq, ioc->persist_wait_done); 5087 timeleft = wait_for_completion_timeout(&ioc->mptbase_cmds.done, 10*HZ);
5088 if (!(ioc->mptbase_cmds.status & MPT_MGMT_STATUS_COMMAND_GOOD)) {
5089 ret = -ETIME;
5090 printk(KERN_DEBUG "%s: failed\n", __func__);
5091 if (ioc->mptbase_cmds.status & MPT_MGMT_STATUS_DID_IOCRESET)
5092 goto out;
5093 if (!timeleft) {
5094 printk(KERN_DEBUG "%s: Issuing Reset from %s!!\n",
5095 ioc->name, __func__);
5096 mpt_HardResetHandler(ioc, CAN_SLEEP);
5097 mpt_free_msg_frame(ioc, mf);
5098 }
5099 goto out;
5100 }
5101
5102 if (!(ioc->mptbase_cmds.status & MPT_MGMT_STATUS_RF_VALID)) {
5103 ret = -1;
5104 goto out;
5105 }
4800 5106
4801 sasIoUnitCntrReply = 5107 sasIoUnitCntrReply =
4802 (SasIoUnitControlReply_t *)ioc->persist_reply_frame; 5108 (SasIoUnitControlReply_t *)ioc->mptbase_cmds.reply;
4803 if (le16_to_cpu(sasIoUnitCntrReply->IOCStatus) != MPI_IOCSTATUS_SUCCESS) { 5109 if (le16_to_cpu(sasIoUnitCntrReply->IOCStatus) != MPI_IOCSTATUS_SUCCESS) {
4804 printk("%s: IOCStatus=0x%X IOCLogInfo=0x%X\n", 5110 printk(KERN_DEBUG "%s: IOCStatus=0x%X IOCLogInfo=0x%X\n",
4805 __func__, 5111 __func__, sasIoUnitCntrReply->IOCStatus,
4806 sasIoUnitCntrReply->IOCStatus,
4807 sasIoUnitCntrReply->IOCLogInfo); 5112 sasIoUnitCntrReply->IOCLogInfo);
4808 return -1; 5113 printk(KERN_DEBUG "%s: failed\n", __func__);
4809 } 5114 ret = -1;
5115 } else
5116 printk(KERN_DEBUG "%s: success\n", __func__);
5117 out:
4810 5118
4811 printk("%s: success\n",__func__); 5119 CLEAR_MGMT_STATUS(ioc->mptbase_cmds.status)
4812 return 0; 5120 mutex_unlock(&ioc->mptbase_cmds.mutex);
5121 return ret;
4813} 5122}
4814 5123
4815/*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/ 5124/*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
@@ -5394,17 +5703,20 @@ mpt_inactive_raid_volumes(MPT_ADAPTER *ioc, u8 channel, u8 id)
5394 * -ENOMEM if pci_alloc failed 5703 * -ENOMEM if pci_alloc failed
5395 **/ 5704 **/
5396int 5705int
5397mpt_raid_phys_disk_pg0(MPT_ADAPTER *ioc, u8 phys_disk_num, pRaidPhysDiskPage0_t phys_disk) 5706mpt_raid_phys_disk_pg0(MPT_ADAPTER *ioc, u8 phys_disk_num,
5707 RaidPhysDiskPage0_t *phys_disk)
5398{ 5708{
5399 CONFIGPARMS cfg; 5709 CONFIGPARMS cfg;
5400 ConfigPageHeader_t hdr; 5710 ConfigPageHeader_t hdr;
5401 dma_addr_t dma_handle; 5711 dma_addr_t dma_handle;
5402 pRaidPhysDiskPage0_t buffer = NULL; 5712 pRaidPhysDiskPage0_t buffer = NULL;
5403 int rc; 5713 int rc;
5404 5714
5405 memset(&cfg, 0 , sizeof(CONFIGPARMS)); 5715 memset(&cfg, 0 , sizeof(CONFIGPARMS));
5406 memset(&hdr, 0 , sizeof(ConfigPageHeader_t)); 5716 memset(&hdr, 0 , sizeof(ConfigPageHeader_t));
5717 memset(phys_disk, 0, sizeof(RaidPhysDiskPage0_t));
5407 5718
5719 hdr.PageVersion = MPI_RAIDPHYSDISKPAGE0_PAGEVERSION;
5408 hdr.PageType = MPI_CONFIG_PAGETYPE_RAID_PHYSDISK; 5720 hdr.PageType = MPI_CONFIG_PAGETYPE_RAID_PHYSDISK;
5409 cfg.cfghdr.hdr = &hdr; 5721 cfg.cfghdr.hdr = &hdr;
5410 cfg.physAddr = -1; 5722 cfg.physAddr = -1;
@@ -5451,6 +5763,161 @@ mpt_raid_phys_disk_pg0(MPT_ADAPTER *ioc, u8 phys_disk_num, pRaidPhysDiskPage0_t
5451} 5763}
5452 5764
5453/** 5765/**
5766 * mpt_raid_phys_disk_get_num_paths - returns number paths associated to this phys_num
5767 * @ioc: Pointer to a Adapter Structure
5768 * @phys_disk_num: io unit unique phys disk num generated by the ioc
5769 *
5770 * Return:
5771 * returns number paths
5772 **/
5773int
5774mpt_raid_phys_disk_get_num_paths(MPT_ADAPTER *ioc, u8 phys_disk_num)
5775{
5776 CONFIGPARMS cfg;
5777 ConfigPageHeader_t hdr;
5778 dma_addr_t dma_handle;
5779 pRaidPhysDiskPage1_t buffer = NULL;
5780 int rc;
5781
5782 memset(&cfg, 0 , sizeof(CONFIGPARMS));
5783 memset(&hdr, 0 , sizeof(ConfigPageHeader_t));
5784
5785 hdr.PageVersion = MPI_RAIDPHYSDISKPAGE1_PAGEVERSION;
5786 hdr.PageType = MPI_CONFIG_PAGETYPE_RAID_PHYSDISK;
5787 hdr.PageNumber = 1;
5788 cfg.cfghdr.hdr = &hdr;
5789 cfg.physAddr = -1;
5790 cfg.action = MPI_CONFIG_ACTION_PAGE_HEADER;
5791
5792 if (mpt_config(ioc, &cfg) != 0) {
5793 rc = 0;
5794 goto out;
5795 }
5796
5797 if (!hdr.PageLength) {
5798 rc = 0;
5799 goto out;
5800 }
5801
5802 buffer = pci_alloc_consistent(ioc->pcidev, hdr.PageLength * 4,
5803 &dma_handle);
5804
5805 if (!buffer) {
5806 rc = 0;
5807 goto out;
5808 }
5809
5810 cfg.physAddr = dma_handle;
5811 cfg.action = MPI_CONFIG_ACTION_PAGE_READ_CURRENT;
5812 cfg.pageAddr = phys_disk_num;
5813
5814 if (mpt_config(ioc, &cfg) != 0) {
5815 rc = 0;
5816 goto out;
5817 }
5818
5819 rc = buffer->NumPhysDiskPaths;
5820 out:
5821
5822 if (buffer)
5823 pci_free_consistent(ioc->pcidev, hdr.PageLength * 4, buffer,
5824 dma_handle);
5825
5826 return rc;
5827}
5828EXPORT_SYMBOL(mpt_raid_phys_disk_get_num_paths);
5829
5830/**
5831 * mpt_raid_phys_disk_pg1 - returns phys disk page 1
5832 * @ioc: Pointer to a Adapter Structure
5833 * @phys_disk_num: io unit unique phys disk num generated by the ioc
5834 * @phys_disk: requested payload data returned
5835 *
5836 * Return:
5837 * 0 on success
5838 * -EFAULT if read of config page header fails or data pointer not NULL
5839 * -ENOMEM if pci_alloc failed
5840 **/
5841int
5842mpt_raid_phys_disk_pg1(MPT_ADAPTER *ioc, u8 phys_disk_num,
5843 RaidPhysDiskPage1_t *phys_disk)
5844{
5845 CONFIGPARMS cfg;
5846 ConfigPageHeader_t hdr;
5847 dma_addr_t dma_handle;
5848 pRaidPhysDiskPage1_t buffer = NULL;
5849 int rc;
5850 int i;
5851 __le64 sas_address;
5852
5853 memset(&cfg, 0 , sizeof(CONFIGPARMS));
5854 memset(&hdr, 0 , sizeof(ConfigPageHeader_t));
5855 rc = 0;
5856
5857 hdr.PageVersion = MPI_RAIDPHYSDISKPAGE1_PAGEVERSION;
5858 hdr.PageType = MPI_CONFIG_PAGETYPE_RAID_PHYSDISK;
5859 hdr.PageNumber = 1;
5860 cfg.cfghdr.hdr = &hdr;
5861 cfg.physAddr = -1;
5862 cfg.action = MPI_CONFIG_ACTION_PAGE_HEADER;
5863
5864 if (mpt_config(ioc, &cfg) != 0) {
5865 rc = -EFAULT;
5866 goto out;
5867 }
5868
5869 if (!hdr.PageLength) {
5870 rc = -EFAULT;
5871 goto out;
5872 }
5873
5874 buffer = pci_alloc_consistent(ioc->pcidev, hdr.PageLength * 4,
5875 &dma_handle);
5876
5877 if (!buffer) {
5878 rc = -ENOMEM;
5879 goto out;
5880 }
5881
5882 cfg.physAddr = dma_handle;
5883 cfg.action = MPI_CONFIG_ACTION_PAGE_READ_CURRENT;
5884 cfg.pageAddr = phys_disk_num;
5885
5886 if (mpt_config(ioc, &cfg) != 0) {
5887 rc = -EFAULT;
5888 goto out;
5889 }
5890
5891 phys_disk->NumPhysDiskPaths = buffer->NumPhysDiskPaths;
5892 phys_disk->PhysDiskNum = phys_disk_num;
5893 for (i = 0; i < phys_disk->NumPhysDiskPaths; i++) {
5894 phys_disk->Path[i].PhysDiskID = buffer->Path[i].PhysDiskID;
5895 phys_disk->Path[i].PhysDiskBus = buffer->Path[i].PhysDiskBus;
5896 phys_disk->Path[i].OwnerIdentifier =
5897 buffer->Path[i].OwnerIdentifier;
5898 phys_disk->Path[i].Flags = le16_to_cpu(buffer->Path[i].Flags);
5899 memcpy(&sas_address, &buffer->Path[i].WWID, sizeof(__le64));
5900 sas_address = le64_to_cpu(sas_address);
5901 memcpy(&phys_disk->Path[i].WWID, &sas_address, sizeof(__le64));
5902 memcpy(&sas_address,
5903 &buffer->Path[i].OwnerWWID, sizeof(__le64));
5904 sas_address = le64_to_cpu(sas_address);
5905 memcpy(&phys_disk->Path[i].OwnerWWID,
5906 &sas_address, sizeof(__le64));
5907 }
5908
5909 out:
5910
5911 if (buffer)
5912 pci_free_consistent(ioc->pcidev, hdr.PageLength * 4, buffer,
5913 dma_handle);
5914
5915 return rc;
5916}
5917EXPORT_SYMBOL(mpt_raid_phys_disk_pg1);
5918
5919
5920/**
5454 * mpt_findImVolumes - Identify IDs of hidden disks and RAID Volumes 5921 * mpt_findImVolumes - Identify IDs of hidden disks and RAID Volumes
5455 * @ioc: Pointer to a Adapter Strucutre 5922 * @ioc: Pointer to a Adapter Strucutre
5456 * 5923 *
@@ -5775,30 +6242,28 @@ mpt_get_manufacturing_pg_0(MPT_ADAPTER *ioc)
5775 * SendEventNotification - Send EventNotification (on or off) request to adapter 6242 * SendEventNotification - Send EventNotification (on or off) request to adapter
5776 * @ioc: Pointer to MPT_ADAPTER structure 6243 * @ioc: Pointer to MPT_ADAPTER structure
5777 * @EvSwitch: Event switch flags 6244 * @EvSwitch: Event switch flags
6245 * @sleepFlag: Specifies whether the process can sleep
5778 */ 6246 */
5779static int 6247static int
5780SendEventNotification(MPT_ADAPTER *ioc, u8 EvSwitch) 6248SendEventNotification(MPT_ADAPTER *ioc, u8 EvSwitch, int sleepFlag)
5781{ 6249{
5782 EventNotification_t *evnp; 6250 EventNotification_t evn;
6251 MPIDefaultReply_t reply_buf;
5783 6252
5784 evnp = (EventNotification_t *) mpt_get_msg_frame(mpt_base_index, ioc); 6253 memset(&evn, 0, sizeof(EventNotification_t));
5785 if (evnp == NULL) { 6254 memset(&reply_buf, 0, sizeof(MPIDefaultReply_t));
5786 devtverboseprintk(ioc, printk(MYIOC_s_WARN_FMT "Unable to allocate event request frame!\n",
5787 ioc->name));
5788 return 0;
5789 }
5790 memset(evnp, 0, sizeof(*evnp));
5791
5792 devtverboseprintk(ioc, printk(MYIOC_s_DEBUG_FMT "Sending EventNotification (%d) request %p\n", ioc->name, EvSwitch, evnp));
5793 6255
5794 evnp->Function = MPI_FUNCTION_EVENT_NOTIFICATION; 6256 evn.Function = MPI_FUNCTION_EVENT_NOTIFICATION;
5795 evnp->ChainOffset = 0; 6257 evn.Switch = EvSwitch;
5796 evnp->MsgFlags = 0; 6258 evn.MsgContext = cpu_to_le32(mpt_base_index << 16);
5797 evnp->Switch = EvSwitch;
5798 6259
5799 mpt_put_msg_frame(mpt_base_index, ioc, (MPT_FRAME_HDR *)evnp); 6260 devtverboseprintk(ioc, printk(MYIOC_s_DEBUG_FMT
6261 "Sending EventNotification (%d) request %p\n",
6262 ioc->name, EvSwitch, &evn));
5800 6263
5801 return 0; 6264 return mpt_handshake_req_reply_wait(ioc, sizeof(EventNotification_t),
6265 (u32 *)&evn, sizeof(MPIDefaultReply_t), (u16 *)&reply_buf, 30,
6266 sleepFlag);
5802} 6267}
5803 6268
5804/*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/ 6269/*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
@@ -5814,7 +6279,7 @@ SendEventAck(MPT_ADAPTER *ioc, EventNotificationReply_t *evnp)
5814 6279
5815 if ((pAck = (EventAck_t *) mpt_get_msg_frame(mpt_base_index, ioc)) == NULL) { 6280 if ((pAck = (EventAck_t *) mpt_get_msg_frame(mpt_base_index, ioc)) == NULL) {
5816 dfailprintk(ioc, printk(MYIOC_s_WARN_FMT "%s, no msg frames!!\n", 6281 dfailprintk(ioc, printk(MYIOC_s_WARN_FMT "%s, no msg frames!!\n",
5817 ioc->name,__func__)); 6282 ioc->name, __func__));
5818 return -1; 6283 return -1;
5819 } 6284 }
5820 6285
@@ -5851,12 +6316,19 @@ int
5851mpt_config(MPT_ADAPTER *ioc, CONFIGPARMS *pCfg) 6316mpt_config(MPT_ADAPTER *ioc, CONFIGPARMS *pCfg)
5852{ 6317{
5853 Config_t *pReq; 6318 Config_t *pReq;
6319 ConfigReply_t *pReply;
5854 ConfigExtendedPageHeader_t *pExtHdr = NULL; 6320 ConfigExtendedPageHeader_t *pExtHdr = NULL;
5855 MPT_FRAME_HDR *mf; 6321 MPT_FRAME_HDR *mf;
5856 unsigned long flags; 6322 int ii;
5857 int ii, rc;
5858 int flagsLength; 6323 int flagsLength;
5859 int in_isr; 6324 long timeout;
6325 int ret;
6326 u8 page_type = 0, extend_page;
6327 unsigned long timeleft;
6328 unsigned long flags;
6329 int in_isr;
6330 u8 issue_hard_reset = 0;
6331 u8 retry_count = 0;
5860 6332
5861 /* Prevent calling wait_event() (below), if caller happens 6333 /* Prevent calling wait_event() (below), if caller happens
5862 * to be in ISR context, because that is fatal! 6334 * to be in ISR context, because that is fatal!
@@ -5866,15 +6338,43 @@ mpt_config(MPT_ADAPTER *ioc, CONFIGPARMS *pCfg)
5866 dcprintk(ioc, printk(MYIOC_s_WARN_FMT "Config request not allowed in ISR context!\n", 6338 dcprintk(ioc, printk(MYIOC_s_WARN_FMT "Config request not allowed in ISR context!\n",
5867 ioc->name)); 6339 ioc->name));
5868 return -EPERM; 6340 return -EPERM;
6341 }
6342
6343 /* don't send a config page during diag reset */
6344 spin_lock_irqsave(&ioc->taskmgmt_lock, flags);
6345 if (ioc->ioc_reset_in_progress) {
6346 dfailprintk(ioc, printk(MYIOC_s_DEBUG_FMT
6347 "%s: busy with host reset\n", ioc->name, __func__));
6348 spin_unlock_irqrestore(&ioc->taskmgmt_lock, flags);
6349 return -EBUSY;
6350 }
6351 spin_unlock_irqrestore(&ioc->taskmgmt_lock, flags);
6352
6353 /* don't send if no chance of success */
6354 if (!ioc->active ||
6355 mpt_GetIocState(ioc, 1) != MPI_IOC_STATE_OPERATIONAL) {
6356 dfailprintk(ioc, printk(MYIOC_s_DEBUG_FMT
6357 "%s: ioc not operational, %d, %xh\n",
6358 ioc->name, __func__, ioc->active,
6359 mpt_GetIocState(ioc, 0)));
6360 return -EFAULT;
5869 } 6361 }
5870 6362
6363 retry_config:
6364 mutex_lock(&ioc->mptbase_cmds.mutex);
6365 /* init the internal cmd struct */
6366 memset(ioc->mptbase_cmds.reply, 0 , MPT_DEFAULT_FRAME_SIZE);
6367 INITIALIZE_MGMT_STATUS(ioc->mptbase_cmds.status)
6368
5871 /* Get and Populate a free Frame 6369 /* Get and Populate a free Frame
5872 */ 6370 */
5873 if ((mf = mpt_get_msg_frame(mpt_base_index, ioc)) == NULL) { 6371 if ((mf = mpt_get_msg_frame(mpt_base_index, ioc)) == NULL) {
5874 dcprintk(ioc, printk(MYIOC_s_WARN_FMT "mpt_config: no msg frames!\n", 6372 dcprintk(ioc, printk(MYIOC_s_WARN_FMT
5875 ioc->name)); 6373 "mpt_config: no msg frames!\n", ioc->name));
5876 return -EAGAIN; 6374 ret = -EAGAIN;
6375 goto out;
5877 } 6376 }
6377
5878 pReq = (Config_t *)mf; 6378 pReq = (Config_t *)mf;
5879 pReq->Action = pCfg->action; 6379 pReq->Action = pCfg->action;
5880 pReq->Reserved = 0; 6380 pReq->Reserved = 0;
@@ -5900,7 +6400,9 @@ mpt_config(MPT_ADAPTER *ioc, CONFIGPARMS *pCfg)
5900 pReq->ExtPageType = pExtHdr->ExtPageType; 6400 pReq->ExtPageType = pExtHdr->ExtPageType;
5901 pReq->Header.PageType = MPI_CONFIG_PAGETYPE_EXTENDED; 6401 pReq->Header.PageType = MPI_CONFIG_PAGETYPE_EXTENDED;
5902 6402
5903 /* Page Length must be treated as a reserved field for the extended header. */ 6403 /* Page Length must be treated as a reserved field for the
6404 * extended header.
6405 */
5904 pReq->Header.PageLength = 0; 6406 pReq->Header.PageLength = 0;
5905 } 6407 }
5906 6408
@@ -5913,78 +6415,91 @@ mpt_config(MPT_ADAPTER *ioc, CONFIGPARMS *pCfg)
5913 else 6415 else
5914 flagsLength = MPT_SGE_FLAGS_SSIMPLE_READ; 6416 flagsLength = MPT_SGE_FLAGS_SSIMPLE_READ;
5915 6417
5916 if ((pCfg->cfghdr.hdr->PageType & MPI_CONFIG_PAGETYPE_MASK) == MPI_CONFIG_PAGETYPE_EXTENDED) { 6418 if ((pCfg->cfghdr.hdr->PageType & MPI_CONFIG_PAGETYPE_MASK) ==
6419 MPI_CONFIG_PAGETYPE_EXTENDED) {
5917 flagsLength |= pExtHdr->ExtPageLength * 4; 6420 flagsLength |= pExtHdr->ExtPageLength * 4;
5918 6421 page_type = pReq->ExtPageType;
5919 dcprintk(ioc, printk(MYIOC_s_DEBUG_FMT "Sending Config request type %d, page %d and action %d\n", 6422 extend_page = 1;
5920 ioc->name, pReq->ExtPageType, pReq->Header.PageNumber, pReq->Action)); 6423 } else {
5921 }
5922 else {
5923 flagsLength |= pCfg->cfghdr.hdr->PageLength * 4; 6424 flagsLength |= pCfg->cfghdr.hdr->PageLength * 4;
5924 6425 page_type = pReq->Header.PageType;
5925 dcprintk(ioc, printk(MYIOC_s_DEBUG_FMT "Sending Config request type %d, page %d and action %d\n", 6426 extend_page = 0;
5926 ioc->name, pReq->Header.PageType, pReq->Header.PageNumber, pReq->Action));
5927 } 6427 }
5928 6428
5929 mpt_add_sge((char *)&pReq->PageBufferSGE, flagsLength, pCfg->physAddr); 6429 dcprintk(ioc, printk(MYIOC_s_DEBUG_FMT
5930 6430 "Sending Config request type 0x%x, page 0x%x and action %d\n",
5931 /* Append pCfg pointer to end of mf 6431 ioc->name, page_type, pReq->Header.PageNumber, pReq->Action));
5932 */
5933 *((void **) (((u8 *) mf) + (ioc->req_sz - sizeof(void *)))) = (void *) pCfg;
5934
5935 /* Initalize the timer
5936 */
5937 init_timer_on_stack(&pCfg->timer);
5938 pCfg->timer.data = (unsigned long) ioc;
5939 pCfg->timer.function = mpt_timer_expired;
5940 pCfg->wait_done = 0;
5941
5942 /* Set the timer; ensure 10 second minimum */
5943 if (pCfg->timeout < 10)
5944 pCfg->timer.expires = jiffies + HZ*10;
5945 else
5946 pCfg->timer.expires = jiffies + HZ*pCfg->timeout;
5947
5948 /* Add to end of Q, set timer and then issue this command */
5949 spin_lock_irqsave(&ioc->FreeQlock, flags);
5950 list_add_tail(&pCfg->linkage, &ioc->configQ);
5951 spin_unlock_irqrestore(&ioc->FreeQlock, flags);
5952 6432
5953 add_timer(&pCfg->timer); 6433 ioc->add_sge((char *)&pReq->PageBufferSGE, flagsLength, pCfg->physAddr);
6434 timeout = (pCfg->timeout < 15) ? HZ*15 : HZ*pCfg->timeout;
5954 mpt_put_msg_frame(mpt_base_index, ioc, mf); 6435 mpt_put_msg_frame(mpt_base_index, ioc, mf);
5955 wait_event(mpt_waitq, pCfg->wait_done); 6436 timeleft = wait_for_completion_timeout(&ioc->mptbase_cmds.done,
6437 timeout);
6438 if (!(ioc->mptbase_cmds.status & MPT_MGMT_STATUS_COMMAND_GOOD)) {
6439 ret = -ETIME;
6440 dfailprintk(ioc, printk(MYIOC_s_DEBUG_FMT
6441 "Failed Sending Config request type 0x%x, page 0x%x,"
6442 " action %d, status %xh, time left %ld\n\n",
6443 ioc->name, page_type, pReq->Header.PageNumber,
6444 pReq->Action, ioc->mptbase_cmds.status, timeleft));
6445 if (ioc->mptbase_cmds.status & MPT_MGMT_STATUS_DID_IOCRESET)
6446 goto out;
6447 if (!timeleft)
6448 issue_hard_reset = 1;
6449 goto out;
6450 }
5956 6451
5957 /* mf has been freed - do not access */ 6452 if (!(ioc->mptbase_cmds.status & MPT_MGMT_STATUS_RF_VALID)) {
6453 ret = -1;
6454 goto out;
6455 }
6456 pReply = (ConfigReply_t *)ioc->mptbase_cmds.reply;
6457 ret = le16_to_cpu(pReply->IOCStatus) & MPI_IOCSTATUS_MASK;
6458 if (ret == MPI_IOCSTATUS_SUCCESS) {
6459 if (extend_page) {
6460 pCfg->cfghdr.ehdr->ExtPageLength =
6461 le16_to_cpu(pReply->ExtPageLength);
6462 pCfg->cfghdr.ehdr->ExtPageType =
6463 pReply->ExtPageType;
6464 }
6465 pCfg->cfghdr.hdr->PageVersion = pReply->Header.PageVersion;
6466 pCfg->cfghdr.hdr->PageLength = pReply->Header.PageLength;
6467 pCfg->cfghdr.hdr->PageNumber = pReply->Header.PageNumber;
6468 pCfg->cfghdr.hdr->PageType = pReply->Header.PageType;
5958 6469
5959 rc = pCfg->status; 6470 }
5960 6471
5961 return rc; 6472 if (retry_count)
5962} 6473 printk(MYIOC_s_INFO_FMT "Retry completed "
6474 "ret=0x%x timeleft=%ld\n",
6475 ioc->name, ret, timeleft);
5963 6476
5964/*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/ 6477 dcprintk(ioc, printk(KERN_DEBUG "IOCStatus=%04xh, IOCLogInfo=%08xh\n",
5965/** 6478 ret, le32_to_cpu(pReply->IOCLogInfo)));
5966 * mpt_timer_expired - Callback for timer process.
5967 * Used only internal config functionality.
5968 * @data: Pointer to MPT_SCSI_HOST recast as an unsigned long
5969 */
5970static void
5971mpt_timer_expired(unsigned long data)
5972{
5973 MPT_ADAPTER *ioc = (MPT_ADAPTER *) data;
5974
5975 dcprintk(ioc, printk(MYIOC_s_DEBUG_FMT "mpt_timer_expired! \n", ioc->name));
5976 6479
5977 /* Perform a FW reload */ 6480out:
5978 if (mpt_HardResetHandler(ioc, NO_SLEEP) < 0)
5979 printk(MYIOC_s_WARN_FMT "Firmware Reload FAILED!\n", ioc->name);
5980 6481
5981 /* No more processing. 6482 CLEAR_MGMT_STATUS(ioc->mptbase_cmds.status)
5982 * Hard reset clean-up will wake up 6483 mutex_unlock(&ioc->mptbase_cmds.mutex);
5983 * process and free all resources. 6484 if (issue_hard_reset) {
5984 */ 6485 issue_hard_reset = 0;
5985 dcprintk(ioc, printk(MYIOC_s_DEBUG_FMT "mpt_timer_expired complete!\n", ioc->name)); 6486 printk(MYIOC_s_WARN_FMT "Issuing Reset from %s!!\n",
6487 ioc->name, __func__);
6488 mpt_HardResetHandler(ioc, CAN_SLEEP);
6489 mpt_free_msg_frame(ioc, mf);
6490 /* attempt one retry for a timed out command */
6491 if (!retry_count) {
6492 printk(MYIOC_s_INFO_FMT
6493 "Attempting Retry Config request"
6494 " type 0x%x, page 0x%x,"
6495 " action %d\n", ioc->name, page_type,
6496 pCfg->cfghdr.hdr->PageNumber, pCfg->action);
6497 retry_count++;
6498 goto retry_config;
6499 }
6500 }
6501 return ret;
5986 6502
5987 return;
5988} 6503}
5989 6504
5990/*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/ 6505/*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
@@ -5998,41 +6513,34 @@ mpt_timer_expired(unsigned long data)
5998static int 6513static int
5999mpt_ioc_reset(MPT_ADAPTER *ioc, int reset_phase) 6514mpt_ioc_reset(MPT_ADAPTER *ioc, int reset_phase)
6000{ 6515{
6001 CONFIGPARMS *pCfg; 6516 switch (reset_phase) {
6002 unsigned long flags; 6517 case MPT_IOC_SETUP_RESET:
6003 6518 ioc->taskmgmt_quiesce_io = 1;
6004 dprintk(ioc, printk(MYIOC_s_DEBUG_FMT 6519 dtmprintk(ioc, printk(MYIOC_s_DEBUG_FMT
6005 ": IOC %s_reset routed to MPT base driver!\n", 6520 "%s: MPT_IOC_SETUP_RESET\n", ioc->name, __func__));
6006 ioc->name, reset_phase==MPT_IOC_SETUP_RESET ? "setup" : ( 6521 break;
6007 reset_phase==MPT_IOC_PRE_RESET ? "pre" : "post"))); 6522 case MPT_IOC_PRE_RESET:
6008 6523 dtmprintk(ioc, printk(MYIOC_s_DEBUG_FMT
6009 if (reset_phase == MPT_IOC_SETUP_RESET) { 6524 "%s: MPT_IOC_PRE_RESET\n", ioc->name, __func__));
6010 ; 6525 break;
6011 } else if (reset_phase == MPT_IOC_PRE_RESET) { 6526 case MPT_IOC_POST_RESET:
6012 /* If the internal config Q is not empty - 6527 dtmprintk(ioc, printk(MYIOC_s_DEBUG_FMT
6013 * delete timer. MF resources will be freed when 6528 "%s: MPT_IOC_POST_RESET\n", ioc->name, __func__));
6014 * the FIFO's are primed. 6529/* wake up mptbase_cmds */
6015 */ 6530 if (ioc->mptbase_cmds.status & MPT_MGMT_STATUS_PENDING) {
6016 spin_lock_irqsave(&ioc->FreeQlock, flags); 6531 ioc->mptbase_cmds.status |=
6017 list_for_each_entry(pCfg, &ioc->configQ, linkage) 6532 MPT_MGMT_STATUS_DID_IOCRESET;
6018 del_timer(&pCfg->timer); 6533 complete(&ioc->mptbase_cmds.done);
6019 spin_unlock_irqrestore(&ioc->FreeQlock, flags);
6020
6021 } else {
6022 CONFIGPARMS *pNext;
6023
6024 /* Search the configQ for internal commands.
6025 * Flush the Q, and wake up all suspended threads.
6026 */
6027 spin_lock_irqsave(&ioc->FreeQlock, flags);
6028 list_for_each_entry_safe(pCfg, pNext, &ioc->configQ, linkage) {
6029 list_del(&pCfg->linkage);
6030
6031 pCfg->status = MPT_CONFIG_ERROR;
6032 pCfg->wait_done = 1;
6033 wake_up(&mpt_waitq);
6034 } 6534 }
6035 spin_unlock_irqrestore(&ioc->FreeQlock, flags); 6535/* wake up taskmgmt_cmds */
6536 if (ioc->taskmgmt_cmds.status & MPT_MGMT_STATUS_PENDING) {
6537 ioc->taskmgmt_cmds.status |=
6538 MPT_MGMT_STATUS_DID_IOCRESET;
6539 complete(&ioc->taskmgmt_cmds.done);
6540 }
6541 break;
6542 default:
6543 break;
6036 } 6544 }
6037 6545
6038 return 1; /* currently means nothing really */ 6546 return 1; /* currently means nothing really */
@@ -6344,6 +6852,59 @@ mpt_print_ioc_summary(MPT_ADAPTER *ioc, char *buffer, int *size, int len, int sh
6344 6852
6345 *size = y; 6853 *size = y;
6346} 6854}
6855/**
6856 * mpt_set_taskmgmt_in_progress_flag - set flags associated with task managment
6857 * @ioc: Pointer to MPT_ADAPTER structure
6858 *
6859 * Returns 0 for SUCCESS or -1 if FAILED.
6860 *
6861 * If -1 is return, then it was not possible to set the flags
6862 **/
6863int
6864mpt_set_taskmgmt_in_progress_flag(MPT_ADAPTER *ioc)
6865{
6866 unsigned long flags;
6867 int retval;
6868
6869 spin_lock_irqsave(&ioc->taskmgmt_lock, flags);
6870 if (ioc->ioc_reset_in_progress || ioc->taskmgmt_in_progress ||
6871 (ioc->alt_ioc && ioc->alt_ioc->taskmgmt_in_progress)) {
6872 retval = -1;
6873 goto out;
6874 }
6875 retval = 0;
6876 ioc->taskmgmt_in_progress = 1;
6877 ioc->taskmgmt_quiesce_io = 1;
6878 if (ioc->alt_ioc) {
6879 ioc->alt_ioc->taskmgmt_in_progress = 1;
6880 ioc->alt_ioc->taskmgmt_quiesce_io = 1;
6881 }
6882 out:
6883 spin_unlock_irqrestore(&ioc->taskmgmt_lock, flags);
6884 return retval;
6885}
6886EXPORT_SYMBOL(mpt_set_taskmgmt_in_progress_flag);
6887
6888/**
6889 * mpt_clear_taskmgmt_in_progress_flag - clear flags associated with task managment
6890 * @ioc: Pointer to MPT_ADAPTER structure
6891 *
6892 **/
6893void
6894mpt_clear_taskmgmt_in_progress_flag(MPT_ADAPTER *ioc)
6895{
6896 unsigned long flags;
6897
6898 spin_lock_irqsave(&ioc->taskmgmt_lock, flags);
6899 ioc->taskmgmt_in_progress = 0;
6900 ioc->taskmgmt_quiesce_io = 0;
6901 if (ioc->alt_ioc) {
6902 ioc->alt_ioc->taskmgmt_in_progress = 0;
6903 ioc->alt_ioc->taskmgmt_quiesce_io = 0;
6904 }
6905 spin_unlock_irqrestore(&ioc->taskmgmt_lock, flags);
6906}
6907EXPORT_SYMBOL(mpt_clear_taskmgmt_in_progress_flag);
6347 6908
6348 6909
6349/** 6910/**
@@ -6397,7 +6958,9 @@ int
6397mpt_HardResetHandler(MPT_ADAPTER *ioc, int sleepFlag) 6958mpt_HardResetHandler(MPT_ADAPTER *ioc, int sleepFlag)
6398{ 6959{
6399 int rc; 6960 int rc;
6961 u8 cb_idx;
6400 unsigned long flags; 6962 unsigned long flags;
6963 unsigned long time_count;
6401 6964
6402 dtmprintk(ioc, printk(MYIOC_s_DEBUG_FMT "HardResetHandler Entered!\n", ioc->name)); 6965 dtmprintk(ioc, printk(MYIOC_s_DEBUG_FMT "HardResetHandler Entered!\n", ioc->name));
6403#ifdef MFCNT 6966#ifdef MFCNT
@@ -6410,14 +6973,15 @@ mpt_HardResetHandler(MPT_ADAPTER *ioc, int sleepFlag)
6410 /* Reset the adapter. Prevent more than 1 call to 6973 /* Reset the adapter. Prevent more than 1 call to
6411 * mpt_do_ioc_recovery at any instant in time. 6974 * mpt_do_ioc_recovery at any instant in time.
6412 */ 6975 */
6413 spin_lock_irqsave(&ioc->diagLock, flags); 6976 spin_lock_irqsave(&ioc->taskmgmt_lock, flags);
6414 if ((ioc->diagPending) || (ioc->alt_ioc && ioc->alt_ioc->diagPending)){ 6977 if (ioc->ioc_reset_in_progress) {
6415 spin_unlock_irqrestore(&ioc->diagLock, flags); 6978 spin_unlock_irqrestore(&ioc->taskmgmt_lock, flags);
6416 return 0; 6979 return 0;
6417 } else {
6418 ioc->diagPending = 1;
6419 } 6980 }
6420 spin_unlock_irqrestore(&ioc->diagLock, flags); 6981 ioc->ioc_reset_in_progress = 1;
6982 if (ioc->alt_ioc)
6983 ioc->alt_ioc->ioc_reset_in_progress = 1;
6984 spin_unlock_irqrestore(&ioc->taskmgmt_lock, flags);
6421 6985
6422 /* FIXME: If do_ioc_recovery fails, repeat.... 6986 /* FIXME: If do_ioc_recovery fails, repeat....
6423 */ 6987 */
@@ -6427,47 +6991,57 @@ mpt_HardResetHandler(MPT_ADAPTER *ioc, int sleepFlag)
6427 * Prevents timeouts occurring during a diagnostic reset...very bad. 6991 * Prevents timeouts occurring during a diagnostic reset...very bad.
6428 * For all other protocol drivers, this is a no-op. 6992 * For all other protocol drivers, this is a no-op.
6429 */ 6993 */
6430 { 6994 for (cb_idx = MPT_MAX_PROTOCOL_DRIVERS-1; cb_idx; cb_idx--) {
6431 u8 cb_idx; 6995 if (MptResetHandlers[cb_idx]) {
6432 int r = 0; 6996 mpt_signal_reset(cb_idx, ioc, MPT_IOC_SETUP_RESET);
6433 6997 if (ioc->alt_ioc)
6434 for (cb_idx = MPT_MAX_PROTOCOL_DRIVERS-1; cb_idx; cb_idx--) { 6998 mpt_signal_reset(cb_idx, ioc->alt_ioc,
6435 if (MptResetHandlers[cb_idx]) { 6999 MPT_IOC_SETUP_RESET);
6436 dtmprintk(ioc, printk(MYIOC_s_DEBUG_FMT "Calling IOC reset_setup handler #%d\n",
6437 ioc->name, cb_idx));
6438 r += mpt_signal_reset(cb_idx, ioc, MPT_IOC_SETUP_RESET);
6439 if (ioc->alt_ioc) {
6440 dtmprintk(ioc, printk(MYIOC_s_DEBUG_FMT "Calling alt-%s setup reset handler #%d\n",
6441 ioc->name, ioc->alt_ioc->name, cb_idx));
6442 r += mpt_signal_reset(cb_idx, ioc->alt_ioc, MPT_IOC_SETUP_RESET);
6443 }
6444 }
6445 } 7000 }
6446 } 7001 }
6447 7002
6448 if ((rc = mpt_do_ioc_recovery(ioc, MPT_HOSTEVENT_IOC_RECOVER, sleepFlag)) != 0) { 7003 time_count = jiffies;
6449 printk(MYIOC_s_WARN_FMT "Cannot recover rc = %d!\n", ioc->name, rc); 7004 rc = mpt_do_ioc_recovery(ioc, MPT_HOSTEVENT_IOC_RECOVER, sleepFlag);
7005 if (rc != 0) {
7006 printk(KERN_WARNING MYNAM
7007 ": WARNING - (%d) Cannot recover %s\n", rc, ioc->name);
7008 } else {
7009 if (ioc->hard_resets < -1)
7010 ioc->hard_resets++;
6450 } 7011 }
6451 ioc->reload_fw = 0;
6452 if (ioc->alt_ioc)
6453 ioc->alt_ioc->reload_fw = 0;
6454 7012
6455 spin_lock_irqsave(&ioc->diagLock, flags); 7013 spin_lock_irqsave(&ioc->taskmgmt_lock, flags);
6456 ioc->diagPending = 0; 7014 ioc->ioc_reset_in_progress = 0;
6457 if (ioc->alt_ioc) 7015 ioc->taskmgmt_quiesce_io = 0;
6458 ioc->alt_ioc->diagPending = 0; 7016 ioc->taskmgmt_in_progress = 0;
6459 spin_unlock_irqrestore(&ioc->diagLock, flags); 7017 if (ioc->alt_ioc) {
7018 ioc->alt_ioc->ioc_reset_in_progress = 0;
7019 ioc->alt_ioc->taskmgmt_quiesce_io = 0;
7020 ioc->alt_ioc->taskmgmt_in_progress = 0;
7021 }
7022 spin_unlock_irqrestore(&ioc->taskmgmt_lock, flags);
6460 7023
6461 dtmprintk(ioc, printk(MYIOC_s_DEBUG_FMT "HardResetHandler rc = %d!\n", ioc->name, rc)); 7024 dtmprintk(ioc,
7025 printk(MYIOC_s_DEBUG_FMT
7026 "HardResetHandler: completed (%d seconds): %s\n", ioc->name,
7027 jiffies_to_msecs(jiffies - time_count)/1000, ((rc == 0) ?
7028 "SUCCESS" : "FAILED")));
6462 7029
6463 return rc; 7030 return rc;
6464} 7031}
6465 7032
6466/*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/ 7033#ifdef CONFIG_FUSION_LOGGING
6467static void 7034static void
6468EventDescriptionStr(u8 event, u32 evData0, char *evStr) 7035mpt_display_event_info(MPT_ADAPTER *ioc, EventNotificationReply_t *pEventReply)
6469{ 7036{
6470 char *ds = NULL; 7037 char *ds = NULL;
7038 u32 evData0;
7039 int ii;
7040 u8 event;
7041 char *evStr = ioc->evStr;
7042
7043 event = le32_to_cpu(pEventReply->Event) & 0xFF;
7044 evData0 = le32_to_cpu(pEventReply->Data[0]);
6471 7045
6472 switch(event) { 7046 switch(event) {
6473 case MPI_EVENT_NONE: 7047 case MPI_EVENT_NONE:
@@ -6501,9 +7075,9 @@ EventDescriptionStr(u8 event, u32 evData0, char *evStr)
6501 if (evData0 == MPI_EVENT_LOOP_STATE_CHANGE_LIP) 7075 if (evData0 == MPI_EVENT_LOOP_STATE_CHANGE_LIP)
6502 ds = "Loop State(LIP) Change"; 7076 ds = "Loop State(LIP) Change";
6503 else if (evData0 == MPI_EVENT_LOOP_STATE_CHANGE_LPE) 7077 else if (evData0 == MPI_EVENT_LOOP_STATE_CHANGE_LPE)
6504 ds = "Loop State(LPE) Change"; /* ??? */ 7078 ds = "Loop State(LPE) Change";
6505 else 7079 else
6506 ds = "Loop State(LPB) Change"; /* ??? */ 7080 ds = "Loop State(LPB) Change";
6507 break; 7081 break;
6508 case MPI_EVENT_LOGOUT: 7082 case MPI_EVENT_LOGOUT:
6509 ds = "Logout"; 7083 ds = "Logout";
@@ -6703,28 +7277,65 @@ EventDescriptionStr(u8 event, u32 evData0, char *evStr)
6703 } 7277 }
6704 case MPI_EVENT_IR2: 7278 case MPI_EVENT_IR2:
6705 { 7279 {
7280 u8 id = (u8)(evData0);
7281 u8 channel = (u8)(evData0 >> 8);
7282 u8 phys_num = (u8)(evData0 >> 24);
6706 u8 ReasonCode = (u8)(evData0 >> 16); 7283 u8 ReasonCode = (u8)(evData0 >> 16);
7284
6707 switch (ReasonCode) { 7285 switch (ReasonCode) {
6708 case MPI_EVENT_IR2_RC_LD_STATE_CHANGED: 7286 case MPI_EVENT_IR2_RC_LD_STATE_CHANGED:
6709 ds = "IR2: LD State Changed"; 7287 snprintf(evStr, EVENT_DESCR_STR_SZ,
7288 "IR2: LD State Changed: "
7289 "id=%d channel=%d phys_num=%d",
7290 id, channel, phys_num);
6710 break; 7291 break;
6711 case MPI_EVENT_IR2_RC_PD_STATE_CHANGED: 7292 case MPI_EVENT_IR2_RC_PD_STATE_CHANGED:
6712 ds = "IR2: PD State Changed"; 7293 snprintf(evStr, EVENT_DESCR_STR_SZ,
7294 "IR2: PD State Changed "
7295 "id=%d channel=%d phys_num=%d",
7296 id, channel, phys_num);
6713 break; 7297 break;
6714 case MPI_EVENT_IR2_RC_BAD_BLOCK_TABLE_FULL: 7298 case MPI_EVENT_IR2_RC_BAD_BLOCK_TABLE_FULL:
6715 ds = "IR2: Bad Block Table Full"; 7299 snprintf(evStr, EVENT_DESCR_STR_SZ,
7300 "IR2: Bad Block Table Full: "
7301 "id=%d channel=%d phys_num=%d",
7302 id, channel, phys_num);
6716 break; 7303 break;
6717 case MPI_EVENT_IR2_RC_PD_INSERTED: 7304 case MPI_EVENT_IR2_RC_PD_INSERTED:
6718 ds = "IR2: PD Inserted"; 7305 snprintf(evStr, EVENT_DESCR_STR_SZ,
7306 "IR2: PD Inserted: "
7307 "id=%d channel=%d phys_num=%d",
7308 id, channel, phys_num);
6719 break; 7309 break;
6720 case MPI_EVENT_IR2_RC_PD_REMOVED: 7310 case MPI_EVENT_IR2_RC_PD_REMOVED:
6721 ds = "IR2: PD Removed"; 7311 snprintf(evStr, EVENT_DESCR_STR_SZ,
7312 "IR2: PD Removed: "
7313 "id=%d channel=%d phys_num=%d",
7314 id, channel, phys_num);
6722 break; 7315 break;
6723 case MPI_EVENT_IR2_RC_FOREIGN_CFG_DETECTED: 7316 case MPI_EVENT_IR2_RC_FOREIGN_CFG_DETECTED:
6724 ds = "IR2: Foreign CFG Detected"; 7317 snprintf(evStr, EVENT_DESCR_STR_SZ,
7318 "IR2: Foreign CFG Detected: "
7319 "id=%d channel=%d phys_num=%d",
7320 id, channel, phys_num);
6725 break; 7321 break;
6726 case MPI_EVENT_IR2_RC_REBUILD_MEDIUM_ERROR: 7322 case MPI_EVENT_IR2_RC_REBUILD_MEDIUM_ERROR:
6727 ds = "IR2: Rebuild Medium Error"; 7323 snprintf(evStr, EVENT_DESCR_STR_SZ,
7324 "IR2: Rebuild Medium Error: "
7325 "id=%d channel=%d phys_num=%d",
7326 id, channel, phys_num);
7327 break;
7328 case MPI_EVENT_IR2_RC_DUAL_PORT_ADDED:
7329 snprintf(evStr, EVENT_DESCR_STR_SZ,
7330 "IR2: Dual Port Added: "
7331 "id=%d channel=%d phys_num=%d",
7332 id, channel, phys_num);
7333 break;
7334 case MPI_EVENT_IR2_RC_DUAL_PORT_REMOVED:
7335 snprintf(evStr, EVENT_DESCR_STR_SZ,
7336 "IR2: Dual Port Removed: "
7337 "id=%d channel=%d phys_num=%d",
7338 id, channel, phys_num);
6728 break; 7339 break;
6729 default: 7340 default:
6730 ds = "IR2"; 7341 ds = "IR2";
@@ -6760,13 +7371,18 @@ EventDescriptionStr(u8 event, u32 evData0, char *evStr)
6760 case MPI_EVENT_SAS_INIT_DEVICE_STATUS_CHANGE: 7371 case MPI_EVENT_SAS_INIT_DEVICE_STATUS_CHANGE:
6761 { 7372 {
6762 u8 reason = (u8)(evData0); 7373 u8 reason = (u8)(evData0);
6763 u8 port_num = (u8)(evData0 >> 8);
6764 u16 handle = le16_to_cpu(evData0 >> 16);
6765 7374
6766 snprintf(evStr, EVENT_DESCR_STR_SZ, 7375 switch (reason) {
6767 "SAS Initiator Device Status Change: reason=0x%02x " 7376 case MPI_EVENT_SAS_INIT_RC_ADDED:
6768 "port=%d handle=0x%04x", 7377 ds = "SAS Initiator Status Change: Added";
6769 reason, port_num, handle); 7378 break;
7379 case MPI_EVENT_SAS_INIT_RC_REMOVED:
7380 ds = "SAS Initiator Status Change: Deleted";
7381 break;
7382 default:
7383 ds = "SAS Initiator Status Change";
7384 break;
7385 }
6770 break; 7386 break;
6771 } 7387 }
6772 7388
@@ -6814,6 +7430,24 @@ EventDescriptionStr(u8 event, u32 evData0, char *evStr)
6814 break; 7430 break;
6815 } 7431 }
6816 7432
7433 case MPI_EVENT_SAS_EXPANDER_STATUS_CHANGE:
7434 {
7435 u8 reason = (u8)(evData0);
7436
7437 switch (reason) {
7438 case MPI_EVENT_SAS_EXP_RC_ADDED:
7439 ds = "Expander Status Change: Added";
7440 break;
7441 case MPI_EVENT_SAS_EXP_RC_NOT_RESPONDING:
7442 ds = "Expander Status Change: Deleted";
7443 break;
7444 default:
7445 ds = "Expander Status Change";
7446 break;
7447 }
7448 break;
7449 }
7450
6817 /* 7451 /*
6818 * MPT base "custom" events may be added here... 7452 * MPT base "custom" events may be added here...
6819 */ 7453 */
@@ -6823,8 +7457,20 @@ EventDescriptionStr(u8 event, u32 evData0, char *evStr)
6823 } 7457 }
6824 if (ds) 7458 if (ds)
6825 strncpy(evStr, ds, EVENT_DESCR_STR_SZ); 7459 strncpy(evStr, ds, EVENT_DESCR_STR_SZ);
6826}
6827 7460
7461
7462 devtprintk(ioc, printk(MYIOC_s_DEBUG_FMT
7463 "MPT event:(%02Xh) : %s\n",
7464 ioc->name, event, evStr));
7465
7466 devtverboseprintk(ioc, printk(KERN_DEBUG MYNAM
7467 ": Event data:\n"));
7468 for (ii = 0; ii < le16_to_cpu(pEventReply->EventDataLength); ii++)
7469 devtverboseprintk(ioc, printk(" %08x",
7470 le32_to_cpu(pEventReply->Data[ii])));
7471 devtverboseprintk(ioc, printk(KERN_DEBUG "\n"));
7472}
7473#endif
6828/*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/ 7474/*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
6829/** 7475/**
6830 * ProcessEventNotification - Route EventNotificationReply to all event handlers 7476 * ProcessEventNotification - Route EventNotificationReply to all event handlers
@@ -6841,37 +7487,24 @@ ProcessEventNotification(MPT_ADAPTER *ioc, EventNotificationReply_t *pEventReply
6841{ 7487{
6842 u16 evDataLen; 7488 u16 evDataLen;
6843 u32 evData0 = 0; 7489 u32 evData0 = 0;
6844// u32 evCtx;
6845 int ii; 7490 int ii;
6846 u8 cb_idx; 7491 u8 cb_idx;
6847 int r = 0; 7492 int r = 0;
6848 int handlers = 0; 7493 int handlers = 0;
6849 char evStr[EVENT_DESCR_STR_SZ];
6850 u8 event; 7494 u8 event;
6851 7495
6852 /* 7496 /*
6853 * Do platform normalization of values 7497 * Do platform normalization of values
6854 */ 7498 */
6855 event = le32_to_cpu(pEventReply->Event) & 0xFF; 7499 event = le32_to_cpu(pEventReply->Event) & 0xFF;
6856// evCtx = le32_to_cpu(pEventReply->EventContext);
6857 evDataLen = le16_to_cpu(pEventReply->EventDataLength); 7500 evDataLen = le16_to_cpu(pEventReply->EventDataLength);
6858 if (evDataLen) { 7501 if (evDataLen) {
6859 evData0 = le32_to_cpu(pEventReply->Data[0]); 7502 evData0 = le32_to_cpu(pEventReply->Data[0]);
6860 } 7503 }
6861 7504
6862 EventDescriptionStr(event, evData0, evStr);
6863 devtprintk(ioc, printk(MYIOC_s_DEBUG_FMT "MPT event:(%02Xh) : %s\n",
6864 ioc->name,
6865 event,
6866 evStr));
6867
6868#ifdef CONFIG_FUSION_LOGGING 7505#ifdef CONFIG_FUSION_LOGGING
6869 devtverboseprintk(ioc, printk(MYIOC_s_DEBUG_FMT 7506 if (evDataLen)
6870 ": Event data:\n", ioc->name)); 7507 mpt_display_event_info(ioc, pEventReply);
6871 for (ii = 0; ii < evDataLen; ii++)
6872 devtverboseprintk(ioc, printk(" %08x",
6873 le32_to_cpu(pEventReply->Data[ii])));
6874 devtverboseprintk(ioc, printk("\n"));
6875#endif 7508#endif
6876 7509
6877 /* 7510 /*
@@ -6926,8 +7559,9 @@ ProcessEventNotification(MPT_ADAPTER *ioc, EventNotificationReply_t *pEventReply
6926 */ 7559 */
6927 for (cb_idx = MPT_MAX_PROTOCOL_DRIVERS-1; cb_idx; cb_idx--) { 7560 for (cb_idx = MPT_MAX_PROTOCOL_DRIVERS-1; cb_idx; cb_idx--) {
6928 if (MptEvHandlers[cb_idx]) { 7561 if (MptEvHandlers[cb_idx]) {
6929 devtverboseprintk(ioc, printk(MYIOC_s_DEBUG_FMT "Routing Event to event handler #%d\n", 7562 devtverboseprintk(ioc, printk(MYIOC_s_DEBUG_FMT
6930 ioc->name, cb_idx)); 7563 "Routing Event to event handler #%d\n",
7564 ioc->name, cb_idx));
6931 r += (*(MptEvHandlers[cb_idx]))(ioc, pEventReply); 7565 r += (*(MptEvHandlers[cb_idx]))(ioc, pEventReply);
6932 handlers++; 7566 handlers++;
6933 } 7567 }
@@ -7011,8 +7645,6 @@ mpt_spi_log_info(MPT_ADAPTER *ioc, u32 log_info)
7011 switch (info) { 7645 switch (info) {
7012 case 0x00010000: 7646 case 0x00010000:
7013 desc = "bug! MID not found"; 7647 desc = "bug! MID not found";
7014 if (ioc->reload_fw == 0)
7015 ioc->reload_fw++;
7016 break; 7648 break;
7017 7649
7018 case 0x00020000: 7650 case 0x00020000:
@@ -7613,7 +8245,6 @@ EXPORT_SYMBOL(mpt_get_msg_frame);
7613EXPORT_SYMBOL(mpt_put_msg_frame); 8245EXPORT_SYMBOL(mpt_put_msg_frame);
7614EXPORT_SYMBOL(mpt_put_msg_frame_hi_pri); 8246EXPORT_SYMBOL(mpt_put_msg_frame_hi_pri);
7615EXPORT_SYMBOL(mpt_free_msg_frame); 8247EXPORT_SYMBOL(mpt_free_msg_frame);
7616EXPORT_SYMBOL(mpt_add_sge);
7617EXPORT_SYMBOL(mpt_send_handshake_request); 8248EXPORT_SYMBOL(mpt_send_handshake_request);
7618EXPORT_SYMBOL(mpt_verify_adapter); 8249EXPORT_SYMBOL(mpt_verify_adapter);
7619EXPORT_SYMBOL(mpt_GetIocState); 8250EXPORT_SYMBOL(mpt_GetIocState);
@@ -7650,7 +8281,7 @@ fusion_init(void)
7650 /* Register ourselves (mptbase) in order to facilitate 8281 /* Register ourselves (mptbase) in order to facilitate
7651 * EventNotification handling. 8282 * EventNotification handling.
7652 */ 8283 */
7653 mpt_base_index = mpt_register(mpt_base_reply, MPTBASE_DRIVER); 8284 mpt_base_index = mpt_register(mptbase_reply, MPTBASE_DRIVER);
7654 8285
7655 /* Register for hard reset handling callbacks. 8286 /* Register for hard reset handling callbacks.
7656 */ 8287 */