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