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