diff options
Diffstat (limited to 'drivers/scsi/mpt2sas/mpt2sas_base.c')
| -rw-r--r-- | drivers/scsi/mpt2sas/mpt2sas_base.c | 247 |
1 files changed, 203 insertions, 44 deletions
diff --git a/drivers/scsi/mpt2sas/mpt2sas_base.c b/drivers/scsi/mpt2sas/mpt2sas_base.c index 81209ca87274..beda04a8404b 100644 --- a/drivers/scsi/mpt2sas/mpt2sas_base.c +++ b/drivers/scsi/mpt2sas/mpt2sas_base.c | |||
| @@ -81,6 +81,15 @@ static int missing_delay[2] = {-1, -1}; | |||
| 81 | module_param_array(missing_delay, int, NULL, 0); | 81 | module_param_array(missing_delay, int, NULL, 0); |
| 82 | MODULE_PARM_DESC(missing_delay, " device missing delay , io missing delay"); | 82 | MODULE_PARM_DESC(missing_delay, " device missing delay , io missing delay"); |
| 83 | 83 | ||
| 84 | static int mpt2sas_fwfault_debug; | ||
| 85 | MODULE_PARM_DESC(mpt2sas_fwfault_debug, " enable detection of firmware fault " | ||
| 86 | "and halt firmware - (default=0)"); | ||
| 87 | |||
| 88 | static int disable_discovery = -1; | ||
| 89 | module_param(disable_discovery, int, 0); | ||
| 90 | MODULE_PARM_DESC(disable_discovery, " disable discovery "); | ||
| 91 | |||
| 92 | |||
| 84 | /* diag_buffer_enable is bitwise | 93 | /* diag_buffer_enable is bitwise |
| 85 | * bit 0 set = TRACE | 94 | * bit 0 set = TRACE |
| 86 | * bit 1 set = SNAPSHOT | 95 | * bit 1 set = SNAPSHOT |
| @@ -93,14 +102,6 @@ module_param(diag_buffer_enable, int, 0); | |||
| 93 | MODULE_PARM_DESC(diag_buffer_enable, " post diag buffers " | 102 | MODULE_PARM_DESC(diag_buffer_enable, " post diag buffers " |
| 94 | "(TRACE=1/SNAPSHOT=2/EXTENDED=4/default=0)"); | 103 | "(TRACE=1/SNAPSHOT=2/EXTENDED=4/default=0)"); |
| 95 | 104 | ||
| 96 | static int mpt2sas_fwfault_debug; | ||
| 97 | MODULE_PARM_DESC(mpt2sas_fwfault_debug, " enable detection of firmware fault " | ||
| 98 | "and halt firmware - (default=0)"); | ||
| 99 | |||
| 100 | static int disable_discovery = -1; | ||
| 101 | module_param(disable_discovery, int, 0); | ||
| 102 | MODULE_PARM_DESC(disable_discovery, " disable discovery "); | ||
| 103 | |||
| 104 | /** | 105 | /** |
| 105 | * _scsih_set_fwfault_debug - global setting of ioc->fwfault_debug. | 106 | * _scsih_set_fwfault_debug - global setting of ioc->fwfault_debug. |
| 106 | * | 107 | * |
| @@ -691,6 +692,7 @@ mpt2sas_base_done(struct MPT2SAS_ADAPTER *ioc, u16 smid, u8 msix_index, | |||
| 691 | memcpy(ioc->base_cmds.reply, mpi_reply, mpi_reply->MsgLength*4); | 692 | memcpy(ioc->base_cmds.reply, mpi_reply, mpi_reply->MsgLength*4); |
| 692 | } | 693 | } |
| 693 | ioc->base_cmds.status &= ~MPT2_CMD_PENDING; | 694 | ioc->base_cmds.status &= ~MPT2_CMD_PENDING; |
| 695 | |||
| 694 | complete(&ioc->base_cmds.done); | 696 | complete(&ioc->base_cmds.done); |
| 695 | return 1; | 697 | return 1; |
| 696 | } | 698 | } |
| @@ -3470,6 +3472,58 @@ _base_send_ioc_init(struct MPT2SAS_ADAPTER *ioc, int sleep_flag) | |||
| 3470 | } | 3472 | } |
| 3471 | 3473 | ||
| 3472 | /** | 3474 | /** |
| 3475 | * mpt2sas_port_enable_done - command completion routine for port enable | ||
| 3476 | * @ioc: per adapter object | ||
| 3477 | * @smid: system request message index | ||
| 3478 | * @msix_index: MSIX table index supplied by the OS | ||
| 3479 | * @reply: reply message frame(lower 32bit addr) | ||
| 3480 | * | ||
| 3481 | * Return 1 meaning mf should be freed from _base_interrupt | ||
| 3482 | * 0 means the mf is freed from this function. | ||
| 3483 | */ | ||
| 3484 | u8 | ||
| 3485 | mpt2sas_port_enable_done(struct MPT2SAS_ADAPTER *ioc, u16 smid, u8 msix_index, | ||
| 3486 | u32 reply) | ||
| 3487 | { | ||
| 3488 | MPI2DefaultReply_t *mpi_reply; | ||
| 3489 | u16 ioc_status; | ||
| 3490 | |||
| 3491 | mpi_reply = mpt2sas_base_get_reply_virt_addr(ioc, reply); | ||
| 3492 | if (mpi_reply && mpi_reply->Function == MPI2_FUNCTION_EVENT_ACK) | ||
| 3493 | return 1; | ||
| 3494 | |||
| 3495 | if (ioc->port_enable_cmds.status == MPT2_CMD_NOT_USED) | ||
| 3496 | return 1; | ||
| 3497 | |||
| 3498 | ioc->port_enable_cmds.status |= MPT2_CMD_COMPLETE; | ||
| 3499 | if (mpi_reply) { | ||
| 3500 | ioc->port_enable_cmds.status |= MPT2_CMD_REPLY_VALID; | ||
| 3501 | memcpy(ioc->port_enable_cmds.reply, mpi_reply, | ||
| 3502 | mpi_reply->MsgLength*4); | ||
| 3503 | } | ||
| 3504 | ioc->port_enable_cmds.status &= ~MPT2_CMD_PENDING; | ||
| 3505 | |||
| 3506 | ioc_status = le16_to_cpu(mpi_reply->IOCStatus) & MPI2_IOCSTATUS_MASK; | ||
| 3507 | |||
| 3508 | if (ioc_status != MPI2_IOCSTATUS_SUCCESS) | ||
| 3509 | ioc->port_enable_failed = 1; | ||
| 3510 | |||
| 3511 | if (ioc->is_driver_loading) { | ||
| 3512 | if (ioc_status == MPI2_IOCSTATUS_SUCCESS) { | ||
| 3513 | mpt2sas_port_enable_complete(ioc); | ||
| 3514 | return 1; | ||
| 3515 | } else { | ||
| 3516 | ioc->start_scan_failed = ioc_status; | ||
| 3517 | ioc->start_scan = 0; | ||
| 3518 | return 1; | ||
| 3519 | } | ||
| 3520 | } | ||
| 3521 | complete(&ioc->port_enable_cmds.done); | ||
| 3522 | return 1; | ||
| 3523 | } | ||
| 3524 | |||
| 3525 | |||
| 3526 | /** | ||
| 3473 | * _base_send_port_enable - send port_enable(discovery stuff) to firmware | 3527 | * _base_send_port_enable - send port_enable(discovery stuff) to firmware |
| 3474 | * @ioc: per adapter object | 3528 | * @ioc: per adapter object |
| 3475 | * @sleep_flag: CAN_SLEEP or NO_SLEEP | 3529 | * @sleep_flag: CAN_SLEEP or NO_SLEEP |
| @@ -3480,67 +3534,151 @@ static int | |||
| 3480 | _base_send_port_enable(struct MPT2SAS_ADAPTER *ioc, int sleep_flag) | 3534 | _base_send_port_enable(struct MPT2SAS_ADAPTER *ioc, int sleep_flag) |
| 3481 | { | 3535 | { |
| 3482 | Mpi2PortEnableRequest_t *mpi_request; | 3536 | Mpi2PortEnableRequest_t *mpi_request; |
| 3483 | u32 ioc_state; | 3537 | Mpi2PortEnableReply_t *mpi_reply; |
| 3484 | unsigned long timeleft; | 3538 | unsigned long timeleft; |
| 3485 | int r = 0; | 3539 | int r = 0; |
| 3486 | u16 smid; | 3540 | u16 smid; |
| 3541 | u16 ioc_status; | ||
| 3487 | 3542 | ||
| 3488 | printk(MPT2SAS_INFO_FMT "sending port enable !!\n", ioc->name); | 3543 | printk(MPT2SAS_INFO_FMT "sending port enable !!\n", ioc->name); |
| 3489 | 3544 | ||
| 3490 | if (ioc->base_cmds.status & MPT2_CMD_PENDING) { | 3545 | if (ioc->port_enable_cmds.status & MPT2_CMD_PENDING) { |
| 3491 | printk(MPT2SAS_ERR_FMT "%s: internal command already in use\n", | 3546 | printk(MPT2SAS_ERR_FMT "%s: internal command already in use\n", |
| 3492 | ioc->name, __func__); | 3547 | ioc->name, __func__); |
| 3493 | return -EAGAIN; | 3548 | return -EAGAIN; |
| 3494 | } | 3549 | } |
| 3495 | 3550 | ||
| 3496 | smid = mpt2sas_base_get_smid(ioc, ioc->base_cb_idx); | 3551 | smid = mpt2sas_base_get_smid(ioc, ioc->port_enable_cb_idx); |
| 3497 | if (!smid) { | 3552 | if (!smid) { |
| 3498 | printk(MPT2SAS_ERR_FMT "%s: failed obtaining a smid\n", | 3553 | printk(MPT2SAS_ERR_FMT "%s: failed obtaining a smid\n", |
| 3499 | ioc->name, __func__); | 3554 | ioc->name, __func__); |
| 3500 | return -EAGAIN; | 3555 | return -EAGAIN; |
| 3501 | } | 3556 | } |
| 3502 | 3557 | ||
| 3503 | ioc->base_cmds.status = MPT2_CMD_PENDING; | 3558 | ioc->port_enable_cmds.status = MPT2_CMD_PENDING; |
| 3504 | mpi_request = mpt2sas_base_get_msg_frame(ioc, smid); | 3559 | mpi_request = mpt2sas_base_get_msg_frame(ioc, smid); |
| 3505 | ioc->base_cmds.smid = smid; | 3560 | ioc->port_enable_cmds.smid = smid; |
| 3506 | memset(mpi_request, 0, sizeof(Mpi2PortEnableRequest_t)); | 3561 | memset(mpi_request, 0, sizeof(Mpi2PortEnableRequest_t)); |
| 3507 | mpi_request->Function = MPI2_FUNCTION_PORT_ENABLE; | 3562 | mpi_request->Function = MPI2_FUNCTION_PORT_ENABLE; |
| 3508 | mpi_request->VF_ID = 0; /* TODO */ | ||
| 3509 | mpi_request->VP_ID = 0; | ||
| 3510 | 3563 | ||
| 3564 | init_completion(&ioc->port_enable_cmds.done); | ||
| 3511 | mpt2sas_base_put_smid_default(ioc, smid); | 3565 | mpt2sas_base_put_smid_default(ioc, smid); |
| 3512 | init_completion(&ioc->base_cmds.done); | 3566 | timeleft = wait_for_completion_timeout(&ioc->port_enable_cmds.done, |
| 3513 | timeleft = wait_for_completion_timeout(&ioc->base_cmds.done, | ||
| 3514 | 300*HZ); | 3567 | 300*HZ); |
| 3515 | if (!(ioc->base_cmds.status & MPT2_CMD_COMPLETE)) { | 3568 | if (!(ioc->port_enable_cmds.status & MPT2_CMD_COMPLETE)) { |
| 3516 | printk(MPT2SAS_ERR_FMT "%s: timeout\n", | 3569 | printk(MPT2SAS_ERR_FMT "%s: timeout\n", |
| 3517 | ioc->name, __func__); | 3570 | ioc->name, __func__); |
| 3518 | _debug_dump_mf(mpi_request, | 3571 | _debug_dump_mf(mpi_request, |
| 3519 | sizeof(Mpi2PortEnableRequest_t)/4); | 3572 | sizeof(Mpi2PortEnableRequest_t)/4); |
| 3520 | if (ioc->base_cmds.status & MPT2_CMD_RESET) | 3573 | if (ioc->port_enable_cmds.status & MPT2_CMD_RESET) |
| 3521 | r = -EFAULT; | 3574 | r = -EFAULT; |
| 3522 | else | 3575 | else |
| 3523 | r = -ETIME; | 3576 | r = -ETIME; |
| 3524 | goto out; | 3577 | goto out; |
| 3525 | } else | 3578 | } |
| 3526 | dinitprintk(ioc, printk(MPT2SAS_INFO_FMT "%s: complete\n", | 3579 | mpi_reply = ioc->port_enable_cmds.reply; |
| 3527 | ioc->name, __func__)); | ||
| 3528 | 3580 | ||
| 3529 | ioc_state = _base_wait_on_iocstate(ioc, MPI2_IOC_STATE_OPERATIONAL, | 3581 | ioc_status = le16_to_cpu(mpi_reply->IOCStatus) & MPI2_IOCSTATUS_MASK; |
| 3530 | 60, sleep_flag); | 3582 | if (ioc_status != MPI2_IOCSTATUS_SUCCESS) { |
| 3531 | if (ioc_state) { | 3583 | printk(MPT2SAS_ERR_FMT "%s: failed with (ioc_status=0x%08x)\n", |
| 3532 | printk(MPT2SAS_ERR_FMT "%s: failed going to operational state " | 3584 | ioc->name, __func__, ioc_status); |
| 3533 | " (ioc_state=0x%x)\n", ioc->name, __func__, ioc_state); | ||
| 3534 | r = -EFAULT; | 3585 | r = -EFAULT; |
| 3586 | goto out; | ||
| 3535 | } | 3587 | } |
| 3536 | out: | 3588 | out: |
| 3537 | ioc->base_cmds.status = MPT2_CMD_NOT_USED; | 3589 | ioc->port_enable_cmds.status = MPT2_CMD_NOT_USED; |
| 3538 | printk(MPT2SAS_INFO_FMT "port enable: %s\n", | 3590 | printk(MPT2SAS_INFO_FMT "port enable: %s\n", ioc->name, ((r == 0) ? |
| 3539 | ioc->name, ((r == 0) ? "SUCCESS" : "FAILED")); | 3591 | "SUCCESS" : "FAILED")); |
| 3540 | return r; | 3592 | return r; |
| 3541 | } | 3593 | } |
| 3542 | 3594 | ||
| 3543 | /** | 3595 | /** |
| 3596 | * mpt2sas_port_enable - initiate firmware discovery (don't wait for reply) | ||
| 3597 | * @ioc: per adapter object | ||
| 3598 | * | ||
| 3599 | * Returns 0 for success, non-zero for failure. | ||
| 3600 | */ | ||
| 3601 | int | ||
| 3602 | mpt2sas_port_enable(struct MPT2SAS_ADAPTER *ioc) | ||
| 3603 | { | ||
| 3604 | Mpi2PortEnableRequest_t *mpi_request; | ||
| 3605 | u16 smid; | ||
| 3606 | |||
| 3607 | printk(MPT2SAS_INFO_FMT "sending port enable !!\n", ioc->name); | ||
| 3608 | |||
| 3609 | if (ioc->port_enable_cmds.status & MPT2_CMD_PENDING) { | ||
| 3610 | printk(MPT2SAS_ERR_FMT "%s: internal command already in use\n", | ||
| 3611 | ioc->name, __func__); | ||
| 3612 | return -EAGAIN; | ||
| 3613 | } | ||
| 3614 | |||
| 3615 | smid = mpt2sas_base_get_smid(ioc, ioc->port_enable_cb_idx); | ||
| 3616 | if (!smid) { | ||
| 3617 | printk(MPT2SAS_ERR_FMT "%s: failed obtaining a smid\n", | ||
| 3618 | ioc->name, __func__); | ||
| 3619 | return -EAGAIN; | ||
| 3620 | } | ||
| 3621 | |||
| 3622 | ioc->port_enable_cmds.status = MPT2_CMD_PENDING; | ||
| 3623 | mpi_request = mpt2sas_base_get_msg_frame(ioc, smid); | ||
| 3624 | ioc->port_enable_cmds.smid = smid; | ||
| 3625 | memset(mpi_request, 0, sizeof(Mpi2PortEnableRequest_t)); | ||
| 3626 | mpi_request->Function = MPI2_FUNCTION_PORT_ENABLE; | ||
| 3627 | |||
| 3628 | mpt2sas_base_put_smid_default(ioc, smid); | ||
| 3629 | return 0; | ||
| 3630 | } | ||
| 3631 | |||
| 3632 | /** | ||
| 3633 | * _base_determine_wait_on_discovery - desposition | ||
| 3634 | * @ioc: per adapter object | ||
| 3635 | * | ||
| 3636 | * Decide whether to wait on discovery to complete. Used to either | ||
| 3637 | * locate boot device, or report volumes ahead of physical devices. | ||
| 3638 | * | ||
| 3639 | * Returns 1 for wait, 0 for don't wait | ||
| 3640 | */ | ||
| 3641 | static int | ||
| 3642 | _base_determine_wait_on_discovery(struct MPT2SAS_ADAPTER *ioc) | ||
| 3643 | { | ||
| 3644 | /* We wait for discovery to complete if IR firmware is loaded. | ||
| 3645 | * The sas topology events arrive before PD events, so we need time to | ||
| 3646 | * turn on the bit in ioc->pd_handles to indicate PD | ||
| 3647 | * Also, it maybe required to report Volumes ahead of physical | ||
| 3648 | * devices when MPI2_IOCPAGE8_IRFLAGS_LOW_VOLUME_MAPPING is set. | ||
| 3649 | */ | ||
| 3650 | if (ioc->ir_firmware) | ||
| 3651 | return 1; | ||
| 3652 | |||
| 3653 | /* if no Bios, then we don't need to wait */ | ||
| 3654 | if (!ioc->bios_pg3.BiosVersion) | ||
| 3655 | return 0; | ||
| 3656 | |||
| 3657 | /* Bios is present, then we drop down here. | ||
| 3658 | * | ||
| 3659 | * If there any entries in the Bios Page 2, then we wait | ||
| 3660 | * for discovery to complete. | ||
| 3661 | */ | ||
| 3662 | |||
| 3663 | /* Current Boot Device */ | ||
| 3664 | if ((ioc->bios_pg2.CurrentBootDeviceForm & | ||
| 3665 | MPI2_BIOSPAGE2_FORM_MASK) == | ||
| 3666 | MPI2_BIOSPAGE2_FORM_NO_DEVICE_SPECIFIED && | ||
| 3667 | /* Request Boot Device */ | ||
| 3668 | (ioc->bios_pg2.ReqBootDeviceForm & | ||
| 3669 | MPI2_BIOSPAGE2_FORM_MASK) == | ||
| 3670 | MPI2_BIOSPAGE2_FORM_NO_DEVICE_SPECIFIED && | ||
| 3671 | /* Alternate Request Boot Device */ | ||
| 3672 | (ioc->bios_pg2.ReqAltBootDeviceForm & | ||
| 3673 | MPI2_BIOSPAGE2_FORM_MASK) == | ||
| 3674 | MPI2_BIOSPAGE2_FORM_NO_DEVICE_SPECIFIED) | ||
| 3675 | return 0; | ||
| 3676 | |||
| 3677 | return 1; | ||
| 3678 | } | ||
| 3679 | |||
| 3680 | |||
| 3681 | /** | ||
| 3544 | * _base_unmask_events - turn on notification for this event | 3682 | * _base_unmask_events - turn on notification for this event |
| 3545 | * @ioc: per adapter object | 3683 | * @ioc: per adapter object |
| 3546 | * @event: firmware event | 3684 | * @event: firmware event |
| @@ -3962,6 +4100,7 @@ _base_make_ioc_operational(struct MPT2SAS_ADAPTER *ioc, int sleep_flag) | |||
| 3962 | skip_init_reply_post_host_index: | 4100 | skip_init_reply_post_host_index: |
| 3963 | 4101 | ||
| 3964 | _base_unmask_interrupts(ioc); | 4102 | _base_unmask_interrupts(ioc); |
| 4103 | |||
| 3965 | r = _base_event_notification(ioc, sleep_flag); | 4104 | r = _base_event_notification(ioc, sleep_flag); |
| 3966 | if (r) | 4105 | if (r) |
| 3967 | return r; | 4106 | return r; |
| @@ -3969,7 +4108,18 @@ _base_make_ioc_operational(struct MPT2SAS_ADAPTER *ioc, int sleep_flag) | |||
| 3969 | if (sleep_flag == CAN_SLEEP) | 4108 | if (sleep_flag == CAN_SLEEP) |
| 3970 | _base_static_config_pages(ioc); | 4109 | _base_static_config_pages(ioc); |
| 3971 | 4110 | ||
| 3972 | if (ioc->wait_for_port_enable_to_complete && ioc->is_warpdrive) { | 4111 | |
| 4112 | if (ioc->is_driver_loading) { | ||
| 4113 | |||
| 4114 | |||
| 4115 | |||
| 4116 | ioc->wait_for_discovery_to_complete = | ||
| 4117 | _base_determine_wait_on_discovery(ioc); | ||
| 4118 | return r; /* scan_start and scan_finished support */ | ||
| 4119 | } | ||
| 4120 | |||
| 4121 | |||
| 4122 | if (ioc->wait_for_discovery_to_complete && ioc->is_warpdrive) { | ||
| 3973 | if (ioc->manu_pg10.OEMIdentifier == 0x80) { | 4123 | if (ioc->manu_pg10.OEMIdentifier == 0x80) { |
| 3974 | hide_flag = (u8) (ioc->manu_pg10.OEMSpecificFlags0 & | 4124 | hide_flag = (u8) (ioc->manu_pg10.OEMSpecificFlags0 & |
| 3975 | MFG_PAGE10_HIDE_SSDS_MASK); | 4125 | MFG_PAGE10_HIDE_SSDS_MASK); |
| @@ -3978,13 +4128,6 @@ _base_make_ioc_operational(struct MPT2SAS_ADAPTER *ioc, int sleep_flag) | |||
| 3978 | } | 4128 | } |
| 3979 | } | 4129 | } |
| 3980 | 4130 | ||
| 3981 | if (ioc->wait_for_port_enable_to_complete) { | ||
| 3982 | if (diag_buffer_enable != 0) | ||
| 3983 | mpt2sas_enable_diag_buffer(ioc, diag_buffer_enable); | ||
| 3984 | if (disable_discovery > 0) | ||
| 3985 | return r; | ||
| 3986 | } | ||
| 3987 | |||
| 3988 | r = _base_send_port_enable(ioc, sleep_flag); | 4131 | r = _base_send_port_enable(ioc, sleep_flag); |
| 3989 | if (r) | 4132 | if (r) |
| 3990 | return r; | 4133 | return r; |
| @@ -4121,6 +4264,10 @@ mpt2sas_base_attach(struct MPT2SAS_ADAPTER *ioc) | |||
| 4121 | ioc->base_cmds.reply = kzalloc(ioc->reply_sz, GFP_KERNEL); | 4264 | ioc->base_cmds.reply = kzalloc(ioc->reply_sz, GFP_KERNEL); |
| 4122 | ioc->base_cmds.status = MPT2_CMD_NOT_USED; | 4265 | ioc->base_cmds.status = MPT2_CMD_NOT_USED; |
| 4123 | 4266 | ||
| 4267 | /* port_enable command bits */ | ||
| 4268 | ioc->port_enable_cmds.reply = kzalloc(ioc->reply_sz, GFP_KERNEL); | ||
| 4269 | ioc->port_enable_cmds.status = MPT2_CMD_NOT_USED; | ||
| 4270 | |||
| 4124 | /* transport internal command bits */ | 4271 | /* transport internal command bits */ |
| 4125 | ioc->transport_cmds.reply = kzalloc(ioc->reply_sz, GFP_KERNEL); | 4272 | ioc->transport_cmds.reply = kzalloc(ioc->reply_sz, GFP_KERNEL); |
| 4126 | ioc->transport_cmds.status = MPT2_CMD_NOT_USED; | 4273 | ioc->transport_cmds.status = MPT2_CMD_NOT_USED; |
| @@ -4162,8 +4309,6 @@ mpt2sas_base_attach(struct MPT2SAS_ADAPTER *ioc) | |||
| 4162 | goto out_free_resources; | 4309 | goto out_free_resources; |
| 4163 | } | 4310 | } |
| 4164 | 4311 | ||
| 4165 | init_completion(&ioc->shost_recovery_done); | ||
| 4166 | |||
| 4167 | for (i = 0; i < MPI2_EVENT_NOTIFY_EVENTMASK_WORDS; i++) | 4312 | for (i = 0; i < MPI2_EVENT_NOTIFY_EVENTMASK_WORDS; i++) |
| 4168 | ioc->event_masks[i] = -1; | 4313 | ioc->event_masks[i] = -1; |
| 4169 | 4314 | ||
| @@ -4186,7 +4331,6 @@ mpt2sas_base_attach(struct MPT2SAS_ADAPTER *ioc) | |||
| 4186 | _base_update_missing_delay(ioc, missing_delay[0], | 4331 | _base_update_missing_delay(ioc, missing_delay[0], |
| 4187 | missing_delay[1]); | 4332 | missing_delay[1]); |
| 4188 | 4333 | ||
| 4189 | mpt2sas_base_start_watchdog(ioc); | ||
| 4190 | return 0; | 4334 | return 0; |
| 4191 | 4335 | ||
| 4192 | out_free_resources: | 4336 | out_free_resources: |
| @@ -4204,6 +4348,7 @@ mpt2sas_base_attach(struct MPT2SAS_ADAPTER *ioc) | |||
| 4204 | kfree(ioc->scsih_cmds.reply); | 4348 | kfree(ioc->scsih_cmds.reply); |
| 4205 | kfree(ioc->config_cmds.reply); | 4349 | kfree(ioc->config_cmds.reply); |
| 4206 | kfree(ioc->base_cmds.reply); | 4350 | kfree(ioc->base_cmds.reply); |
| 4351 | kfree(ioc->port_enable_cmds.reply); | ||
| 4207 | kfree(ioc->ctl_cmds.reply); | 4352 | kfree(ioc->ctl_cmds.reply); |
| 4208 | kfree(ioc->ctl_cmds.sense); | 4353 | kfree(ioc->ctl_cmds.sense); |
| 4209 | kfree(ioc->pfacts); | 4354 | kfree(ioc->pfacts); |
| @@ -4243,6 +4388,7 @@ mpt2sas_base_detach(struct MPT2SAS_ADAPTER *ioc) | |||
| 4243 | kfree(ioc->ctl_cmds.reply); | 4388 | kfree(ioc->ctl_cmds.reply); |
| 4244 | kfree(ioc->ctl_cmds.sense); | 4389 | kfree(ioc->ctl_cmds.sense); |
| 4245 | kfree(ioc->base_cmds.reply); | 4390 | kfree(ioc->base_cmds.reply); |
| 4391 | kfree(ioc->port_enable_cmds.reply); | ||
| 4246 | kfree(ioc->tm_cmds.reply); | 4392 | kfree(ioc->tm_cmds.reply); |
| 4247 | kfree(ioc->transport_cmds.reply); | 4393 | kfree(ioc->transport_cmds.reply); |
| 4248 | kfree(ioc->scsih_cmds.reply); | 4394 | kfree(ioc->scsih_cmds.reply); |
| @@ -4284,6 +4430,20 @@ _base_reset_handler(struct MPT2SAS_ADAPTER *ioc, int reset_phase) | |||
| 4284 | mpt2sas_base_free_smid(ioc, ioc->base_cmds.smid); | 4430 | mpt2sas_base_free_smid(ioc, ioc->base_cmds.smid); |
| 4285 | complete(&ioc->base_cmds.done); | 4431 | complete(&ioc->base_cmds.done); |
| 4286 | } | 4432 | } |
| 4433 | if (ioc->port_enable_cmds.status & MPT2_CMD_PENDING) { | ||
| 4434 | ioc->port_enable_failed = 1; | ||
| 4435 | ioc->port_enable_cmds.status |= MPT2_CMD_RESET; | ||
| 4436 | mpt2sas_base_free_smid(ioc, ioc->port_enable_cmds.smid); | ||
| 4437 | if (ioc->is_driver_loading) { | ||
| 4438 | ioc->start_scan_failed = | ||
| 4439 | MPI2_IOCSTATUS_INTERNAL_ERROR; | ||
| 4440 | ioc->start_scan = 0; | ||
| 4441 | ioc->port_enable_cmds.status = | ||
| 4442 | MPT2_CMD_NOT_USED; | ||
| 4443 | } else | ||
| 4444 | complete(&ioc->port_enable_cmds.done); | ||
| 4445 | |||
| 4446 | } | ||
| 4287 | if (ioc->config_cmds.status & MPT2_CMD_PENDING) { | 4447 | if (ioc->config_cmds.status & MPT2_CMD_PENDING) { |
| 4288 | ioc->config_cmds.status |= MPT2_CMD_RESET; | 4448 | ioc->config_cmds.status |= MPT2_CMD_RESET; |
| 4289 | mpt2sas_base_free_smid(ioc, ioc->config_cmds.smid); | 4449 | mpt2sas_base_free_smid(ioc, ioc->config_cmds.smid); |
| @@ -4349,7 +4509,6 @@ mpt2sas_base_hard_reset_handler(struct MPT2SAS_ADAPTER *ioc, int sleep_flag, | |||
| 4349 | { | 4509 | { |
| 4350 | int r; | 4510 | int r; |
| 4351 | unsigned long flags; | 4511 | unsigned long flags; |
| 4352 | u8 pe_complete = ioc->wait_for_port_enable_to_complete; | ||
| 4353 | 4512 | ||
| 4354 | dtmprintk(ioc, printk(MPT2SAS_INFO_FMT "%s: enter\n", ioc->name, | 4513 | dtmprintk(ioc, printk(MPT2SAS_INFO_FMT "%s: enter\n", ioc->name, |
| 4355 | __func__)); | 4514 | __func__)); |
| @@ -4396,7 +4555,8 @@ mpt2sas_base_hard_reset_handler(struct MPT2SAS_ADAPTER *ioc, int sleep_flag, | |||
| 4396 | /* If this hard reset is called while port enable is active, then | 4555 | /* If this hard reset is called while port enable is active, then |
| 4397 | * there is no reason to call make_ioc_operational | 4556 | * there is no reason to call make_ioc_operational |
| 4398 | */ | 4557 | */ |
| 4399 | if (pe_complete) { | 4558 | if (ioc->is_driver_loading && ioc->port_enable_failed) { |
| 4559 | ioc->remove_host = 1; | ||
| 4400 | r = -EFAULT; | 4560 | r = -EFAULT; |
| 4401 | goto out; | 4561 | goto out; |
| 4402 | } | 4562 | } |
| @@ -4410,7 +4570,6 @@ mpt2sas_base_hard_reset_handler(struct MPT2SAS_ADAPTER *ioc, int sleep_flag, | |||
| 4410 | spin_lock_irqsave(&ioc->ioc_reset_in_progress_lock, flags); | 4570 | spin_lock_irqsave(&ioc->ioc_reset_in_progress_lock, flags); |
| 4411 | ioc->ioc_reset_in_progress_status = r; | 4571 | ioc->ioc_reset_in_progress_status = r; |
| 4412 | ioc->shost_recovery = 0; | 4572 | ioc->shost_recovery = 0; |
| 4413 | complete(&ioc->shost_recovery_done); | ||
| 4414 | spin_unlock_irqrestore(&ioc->ioc_reset_in_progress_lock, flags); | 4573 | spin_unlock_irqrestore(&ioc->ioc_reset_in_progress_lock, flags); |
| 4415 | mutex_unlock(&ioc->reset_in_progress_mutex); | 4574 | mutex_unlock(&ioc->reset_in_progress_mutex); |
| 4416 | 4575 | ||
