diff options
| author | Kashyap, Desai <kashyap.desai@lsi.com> | 2009-09-14 01:34:23 -0400 |
|---|---|---|
| committer | James Bottomley <James.Bottomley@suse.de> | 2009-10-02 10:48:38 -0400 |
| commit | 77e63ed44305e89c0564f8292f9cd5764d4fddfb (patch) | |
| tree | 66aab9af95be1daadf6e648b008f9c1d77cf1ac0 | |
| parent | 595bb0bd62edb28a965993d90e0fa1285560ce53 (diff) | |
[SCSI] mpt2sas: Target Reset will be issued from Interrupt context.
(1) Added three new functions to handle sending target resest and OP_REMOVE
from interrupt time, they are _scsih_tm_tr_send, _scsih_tm_tr_complete, and
_scsih_sas_control_complete. This code will create a link list of pending
target resets if there is no more available request in the hipriority
request queue. The list is stored in ioc->delayed_tr_list.
(2) All callback handler return type is changed from void to u8.
Now _base_interrupt will check for return type of callback handlers to
take decision of message frame is already freed or not.
In genral,
Return 1 meaning mf should be freed from _base_interrupt
0 means the mf is freed from function.
Signed-off-by: Kashyap Desai <kashyap.desai@lsi.com>
Signed-off-by: James Bottomley <James.Bottomley@suse.de>
| -rw-r--r-- | drivers/scsi/mpt2sas/mpt2sas_base.c | 35 | ||||
| -rw-r--r-- | drivers/scsi/mpt2sas/mpt2sas_base.h | 41 | ||||
| -rw-r--r-- | drivers/scsi/mpt2sas/mpt2sas_config.c | 10 | ||||
| -rw-r--r-- | drivers/scsi/mpt2sas/mpt2sas_ctl.c | 16 | ||||
| -rw-r--r-- | drivers/scsi/mpt2sas/mpt2sas_scsih.c | 314 | ||||
| -rw-r--r-- | drivers/scsi/mpt2sas/mpt2sas_transport.c | 10 |
6 files changed, 372 insertions, 54 deletions
diff --git a/drivers/scsi/mpt2sas/mpt2sas_base.c b/drivers/scsi/mpt2sas/mpt2sas_base.c index 4c583ff458db..a9c71769b4ec 100644 --- a/drivers/scsi/mpt2sas/mpt2sas_base.c +++ b/drivers/scsi/mpt2sas/mpt2sas_base.c | |||
| @@ -575,9 +575,10 @@ _base_display_reply_info(struct MPT2SAS_ADAPTER *ioc, u16 smid, u8 msix_index, | |||
| 575 | * @msix_index: MSIX table index supplied by the OS | 575 | * @msix_index: MSIX table index supplied by the OS |
| 576 | * @reply: reply message frame(lower 32bit addr) | 576 | * @reply: reply message frame(lower 32bit addr) |
| 577 | * | 577 | * |
| 578 | * Return nothing. | 578 | * Return 1 meaning mf should be freed from _base_interrupt |
| 579 | * 0 means the mf is freed from this function. | ||
| 579 | */ | 580 | */ |
| 580 | void | 581 | u8 |
| 581 | mpt2sas_base_done(struct MPT2SAS_ADAPTER *ioc, u16 smid, u8 msix_index, | 582 | mpt2sas_base_done(struct MPT2SAS_ADAPTER *ioc, u16 smid, u8 msix_index, |
| 582 | u32 reply) | 583 | u32 reply) |
| 583 | { | 584 | { |
| @@ -585,10 +586,10 @@ mpt2sas_base_done(struct MPT2SAS_ADAPTER *ioc, u16 smid, u8 msix_index, | |||
| 585 | 586 | ||
| 586 | mpi_reply = mpt2sas_base_get_reply_virt_addr(ioc, reply); | 587 | mpi_reply = mpt2sas_base_get_reply_virt_addr(ioc, reply); |
| 587 | if (mpi_reply && mpi_reply->Function == MPI2_FUNCTION_EVENT_ACK) | 588 | if (mpi_reply && mpi_reply->Function == MPI2_FUNCTION_EVENT_ACK) |
| 588 | return; | 589 | return 1; |
| 589 | 590 | ||
| 590 | if (ioc->base_cmds.status == MPT2_CMD_NOT_USED) | 591 | if (ioc->base_cmds.status == MPT2_CMD_NOT_USED) |
| 591 | return; | 592 | return 1; |
| 592 | 593 | ||
| 593 | ioc->base_cmds.status |= MPT2_CMD_COMPLETE; | 594 | ioc->base_cmds.status |= MPT2_CMD_COMPLETE; |
| 594 | if (mpi_reply) { | 595 | if (mpi_reply) { |
| @@ -597,6 +598,7 @@ mpt2sas_base_done(struct MPT2SAS_ADAPTER *ioc, u16 smid, u8 msix_index, | |||
| 597 | } | 598 | } |
| 598 | ioc->base_cmds.status &= ~MPT2_CMD_PENDING; | 599 | ioc->base_cmds.status &= ~MPT2_CMD_PENDING; |
| 599 | complete(&ioc->base_cmds.done); | 600 | complete(&ioc->base_cmds.done); |
| 601 | return 1; | ||
| 600 | } | 602 | } |
| 601 | 603 | ||
| 602 | /** | 604 | /** |
| @@ -605,9 +607,10 @@ mpt2sas_base_done(struct MPT2SAS_ADAPTER *ioc, u16 smid, u8 msix_index, | |||
| 605 | * @msix_index: MSIX table index supplied by the OS | 607 | * @msix_index: MSIX table index supplied by the OS |
| 606 | * @reply: reply message frame(lower 32bit addr) | 608 | * @reply: reply message frame(lower 32bit addr) |
| 607 | * | 609 | * |
| 608 | * Return nothing. | 610 | * Return 1 meaning mf should be freed from _base_interrupt |
| 611 | * 0 means the mf is freed from this function. | ||
| 609 | */ | 612 | */ |
| 610 | static void | 613 | static u8 |
| 611 | _base_async_event(struct MPT2SAS_ADAPTER *ioc, u8 msix_index, u32 reply) | 614 | _base_async_event(struct MPT2SAS_ADAPTER *ioc, u8 msix_index, u32 reply) |
| 612 | { | 615 | { |
| 613 | Mpi2EventNotificationReply_t *mpi_reply; | 616 | Mpi2EventNotificationReply_t *mpi_reply; |
| @@ -616,9 +619,9 @@ _base_async_event(struct MPT2SAS_ADAPTER *ioc, u8 msix_index, u32 reply) | |||
| 616 | 619 | ||
| 617 | mpi_reply = mpt2sas_base_get_reply_virt_addr(ioc, reply); | 620 | mpi_reply = mpt2sas_base_get_reply_virt_addr(ioc, reply); |
| 618 | if (!mpi_reply) | 621 | if (!mpi_reply) |
| 619 | return; | 622 | return 1; |
| 620 | if (mpi_reply->Function != MPI2_FUNCTION_EVENT_NOTIFICATION) | 623 | if (mpi_reply->Function != MPI2_FUNCTION_EVENT_NOTIFICATION) |
| 621 | return; | 624 | return 1; |
| 622 | #ifdef CONFIG_SCSI_MPT2SAS_LOGGING | 625 | #ifdef CONFIG_SCSI_MPT2SAS_LOGGING |
| 623 | _base_display_event_data(ioc, mpi_reply); | 626 | _base_display_event_data(ioc, mpi_reply); |
| 624 | #endif | 627 | #endif |
| @@ -647,6 +650,8 @@ _base_async_event(struct MPT2SAS_ADAPTER *ioc, u8 msix_index, u32 reply) | |||
| 647 | 650 | ||
| 648 | /* ctl callback handler */ | 651 | /* ctl callback handler */ |
| 649 | mpt2sas_ctl_event_callback(ioc, msix_index, reply); | 652 | mpt2sas_ctl_event_callback(ioc, msix_index, reply); |
| 653 | |||
| 654 | return 1; | ||
| 650 | } | 655 | } |
| 651 | 656 | ||
| 652 | /** | 657 | /** |
| @@ -745,6 +750,7 @@ _base_interrupt(int irq, void *bus_id) | |||
| 745 | u8 msix_index; | 750 | u8 msix_index; |
| 746 | struct MPT2SAS_ADAPTER *ioc = bus_id; | 751 | struct MPT2SAS_ADAPTER *ioc = bus_id; |
| 747 | Mpi2ReplyDescriptorsUnion_t *rpf; | 752 | Mpi2ReplyDescriptorsUnion_t *rpf; |
| 753 | u8 rc; | ||
| 748 | 754 | ||
| 749 | if (ioc->mask_interrupts) | 755 | if (ioc->mask_interrupts) |
| 750 | return IRQ_NONE; | 756 | return IRQ_NONE; |
| @@ -777,12 +783,13 @@ _base_interrupt(int irq, void *bus_id) | |||
| 777 | if (smid) | 783 | if (smid) |
| 778 | cb_idx = _base_get_cb_idx(ioc, smid); | 784 | cb_idx = _base_get_cb_idx(ioc, smid); |
| 779 | if (smid && cb_idx != 0xFF) { | 785 | if (smid && cb_idx != 0xFF) { |
| 780 | mpt_callbacks[cb_idx](ioc, smid, msix_index, | 786 | rc = mpt_callbacks[cb_idx](ioc, smid, msix_index, |
| 781 | reply); | 787 | reply); |
| 782 | if (reply) | 788 | if (reply) |
| 783 | _base_display_reply_info(ioc, smid, msix_index, | 789 | _base_display_reply_info(ioc, smid, msix_index, |
| 784 | reply); | 790 | reply); |
| 785 | mpt2sas_base_free_smid(ioc, smid); | 791 | if (rc) |
| 792 | mpt2sas_base_free_smid(ioc, smid); | ||
| 786 | } | 793 | } |
| 787 | if (!smid) | 794 | if (!smid) |
| 788 | _base_async_event(ioc, msix_index, reply); | 795 | _base_async_event(ioc, msix_index, reply); |
| @@ -3323,10 +3330,18 @@ _base_make_ioc_operational(struct MPT2SAS_ADAPTER *ioc, int sleep_flag) | |||
| 3323 | unsigned long flags; | 3330 | unsigned long flags; |
| 3324 | u32 reply_address; | 3331 | u32 reply_address; |
| 3325 | u16 smid; | 3332 | u16 smid; |
| 3333 | struct _tr_list *delayed_tr, *delayed_tr_next; | ||
| 3326 | 3334 | ||
| 3327 | dinitprintk(ioc, printk(MPT2SAS_DEBUG_FMT "%s\n", ioc->name, | 3335 | dinitprintk(ioc, printk(MPT2SAS_DEBUG_FMT "%s\n", ioc->name, |
| 3328 | __func__)); | 3336 | __func__)); |
| 3329 | 3337 | ||
| 3338 | /* clean the delayed target reset list */ | ||
| 3339 | list_for_each_entry_safe(delayed_tr, delayed_tr_next, | ||
| 3340 | &ioc->delayed_tr_list, list) { | ||
| 3341 | list_del(&delayed_tr->list); | ||
| 3342 | kfree(delayed_tr); | ||
| 3343 | } | ||
| 3344 | |||
| 3330 | /* initialize the scsi lookup free list */ | 3345 | /* initialize the scsi lookup free list */ |
| 3331 | spin_lock_irqsave(&ioc->scsi_lookup_lock, flags); | 3346 | spin_lock_irqsave(&ioc->scsi_lookup_lock, flags); |
| 3332 | INIT_LIST_HEAD(&ioc->free_list); | 3347 | INIT_LIST_HEAD(&ioc->free_list); |
diff --git a/drivers/scsi/mpt2sas/mpt2sas_base.h b/drivers/scsi/mpt2sas/mpt2sas_base.h index 91132626f4c5..7f94be90ad12 100644 --- a/drivers/scsi/mpt2sas/mpt2sas_base.h +++ b/drivers/scsi/mpt2sas/mpt2sas_base.h | |||
| @@ -307,6 +307,7 @@ struct _sas_device { | |||
| 307 | u16 slot; | 307 | u16 slot; |
| 308 | u8 hidden_raid_component; | 308 | u8 hidden_raid_component; |
| 309 | u8 responding; | 309 | u8 responding; |
| 310 | u16 state; | ||
| 310 | }; | 311 | }; |
| 311 | 312 | ||
| 312 | /** | 313 | /** |
| @@ -443,6 +444,17 @@ struct request_tracker { | |||
| 443 | struct list_head tracker_list; | 444 | struct list_head tracker_list; |
| 444 | }; | 445 | }; |
| 445 | 446 | ||
| 447 | /** | ||
| 448 | * struct _tr_list - target reset list | ||
| 449 | * @handle: device handle | ||
| 450 | * @state: state machine | ||
| 451 | */ | ||
| 452 | struct _tr_list { | ||
| 453 | struct list_head list; | ||
| 454 | u16 handle; | ||
| 455 | u16 state; | ||
| 456 | }; | ||
| 457 | |||
| 446 | typedef void (*MPT_ADD_SGE)(void *paddr, u32 flags_length, dma_addr_t dma_addr); | 458 | typedef void (*MPT_ADD_SGE)(void *paddr, u32 flags_length, dma_addr_t dma_addr); |
| 447 | 459 | ||
| 448 | /** | 460 | /** |
| @@ -617,6 +629,8 @@ struct MPT2SAS_ADAPTER { | |||
| 617 | u8 ctl_cb_idx; | 629 | u8 ctl_cb_idx; |
| 618 | u8 base_cb_idx; | 630 | u8 base_cb_idx; |
| 619 | u8 config_cb_idx; | 631 | u8 config_cb_idx; |
| 632 | u8 tm_tr_cb_idx; | ||
| 633 | u8 tm_sas_control_cb_idx; | ||
| 620 | struct _internal_cmd base_cmds; | 634 | struct _internal_cmd base_cmds; |
| 621 | struct _internal_cmd transport_cmds; | 635 | struct _internal_cmd transport_cmds; |
| 622 | struct _internal_cmd tm_cmds; | 636 | struct _internal_cmd tm_cmds; |
| @@ -727,6 +741,8 @@ struct MPT2SAS_ADAPTER { | |||
| 727 | struct dma_pool *reply_post_free_dma_pool; | 741 | struct dma_pool *reply_post_free_dma_pool; |
| 728 | u32 reply_post_host_index; | 742 | u32 reply_post_host_index; |
| 729 | 743 | ||
| 744 | struct list_head delayed_tr_list; | ||
| 745 | |||
| 730 | /* diag buffer support */ | 746 | /* diag buffer support */ |
| 731 | u8 *diag_buffer[MPI2_DIAG_BUF_TYPE_COUNT]; | 747 | u8 *diag_buffer[MPI2_DIAG_BUF_TYPE_COUNT]; |
| 732 | u32 diag_buffer_sz[MPI2_DIAG_BUF_TYPE_COUNT]; | 748 | u32 diag_buffer_sz[MPI2_DIAG_BUF_TYPE_COUNT]; |
| @@ -738,8 +754,8 @@ struct MPT2SAS_ADAPTER { | |||
| 738 | u32 diagnostic_flags[MPI2_DIAG_BUF_TYPE_COUNT]; | 754 | u32 diagnostic_flags[MPI2_DIAG_BUF_TYPE_COUNT]; |
| 739 | }; | 755 | }; |
| 740 | 756 | ||
| 741 | typedef void (*MPT_CALLBACK)(struct MPT2SAS_ADAPTER *ioc, u16 smid, | 757 | typedef u8 (*MPT_CALLBACK)(struct MPT2SAS_ADAPTER *ioc, u16 smid, u8 msix_index, |
| 742 | u8 msix_index, u32 reply); | 758 | u32 reply); |
| 743 | 759 | ||
| 744 | 760 | ||
| 745 | /* base shared API */ | 761 | /* base shared API */ |
| @@ -757,7 +773,8 @@ int mpt2sas_base_hard_reset_handler(struct MPT2SAS_ADAPTER *ioc, int sleep_flag, | |||
| 757 | void *mpt2sas_base_get_msg_frame(struct MPT2SAS_ADAPTER *ioc, u16 smid); | 773 | void *mpt2sas_base_get_msg_frame(struct MPT2SAS_ADAPTER *ioc, u16 smid); |
| 758 | void *mpt2sas_base_get_sense_buffer(struct MPT2SAS_ADAPTER *ioc, u16 smid); | 774 | void *mpt2sas_base_get_sense_buffer(struct MPT2SAS_ADAPTER *ioc, u16 smid); |
| 759 | void mpt2sas_base_build_zero_len_sge(struct MPT2SAS_ADAPTER *ioc, void *paddr); | 775 | void mpt2sas_base_build_zero_len_sge(struct MPT2SAS_ADAPTER *ioc, void *paddr); |
| 760 | dma_addr_t mpt2sas_base_get_sense_buffer_dma(struct MPT2SAS_ADAPTER *ioc, u16 smid); | 776 | dma_addr_t mpt2sas_base_get_sense_buffer_dma(struct MPT2SAS_ADAPTER *ioc, |
| 777 | u16 smid); | ||
| 761 | 778 | ||
| 762 | /* hi-priority queue */ | 779 | /* hi-priority queue */ |
| 763 | u16 mpt2sas_base_get_smid_hpr(struct MPT2SAS_ADAPTER *ioc, u8 cb_idx); | 780 | u16 mpt2sas_base_get_smid_hpr(struct MPT2SAS_ADAPTER *ioc, u8 cb_idx); |
| @@ -776,7 +793,7 @@ void mpt2sas_base_initialize_callback_handler(void); | |||
| 776 | u8 mpt2sas_base_register_callback_handler(MPT_CALLBACK cb_func); | 793 | u8 mpt2sas_base_register_callback_handler(MPT_CALLBACK cb_func); |
| 777 | void mpt2sas_base_release_callback_handler(u8 cb_idx); | 794 | void mpt2sas_base_release_callback_handler(u8 cb_idx); |
| 778 | 795 | ||
| 779 | void mpt2sas_base_done(struct MPT2SAS_ADAPTER *ioc, u16 smid, u8 msix_index, | 796 | u8 mpt2sas_base_done(struct MPT2SAS_ADAPTER *ioc, u16 smid, u8 msix_index, |
| 780 | u32 reply); | 797 | u32 reply); |
| 781 | void *mpt2sas_base_get_reply_virt_addr(struct MPT2SAS_ADAPTER *ioc, u32 phys_addr); | 798 | void *mpt2sas_base_get_reply_virt_addr(struct MPT2SAS_ADAPTER *ioc, u32 phys_addr); |
| 782 | 799 | ||
| @@ -791,6 +808,8 @@ int mpt2sas_base_scsi_enclosure_processor(struct MPT2SAS_ADAPTER *ioc, | |||
| 791 | void mpt2sas_base_validate_event_type(struct MPT2SAS_ADAPTER *ioc, u32 *event_type); | 808 | void mpt2sas_base_validate_event_type(struct MPT2SAS_ADAPTER *ioc, u32 *event_type); |
| 792 | 809 | ||
| 793 | /* scsih shared API */ | 810 | /* scsih shared API */ |
| 811 | u8 mpt2sas_scsih_event_callback(struct MPT2SAS_ADAPTER *ioc, u8 msix_index, | ||
| 812 | u32 reply); | ||
| 794 | void mpt2sas_scsih_issue_tm(struct MPT2SAS_ADAPTER *ioc, u16 handle, uint lun, | 813 | void mpt2sas_scsih_issue_tm(struct MPT2SAS_ADAPTER *ioc, u16 handle, uint lun, |
| 795 | u8 type, u16 smid_task, ulong timeout); | 814 | u8 type, u16 smid_task, ulong timeout); |
| 796 | void mpt2sas_scsih_set_tm_flag(struct MPT2SAS_ADAPTER *ioc, u16 handle); | 815 | void mpt2sas_scsih_set_tm_flag(struct MPT2SAS_ADAPTER *ioc, u16 handle); |
| @@ -802,12 +821,10 @@ struct _sas_node *mpt2sas_scsih_expander_find_by_sas_address(struct MPT2SAS_ADAP | |||
| 802 | struct _sas_device *mpt2sas_scsih_sas_device_find_by_sas_address( | 821 | struct _sas_device *mpt2sas_scsih_sas_device_find_by_sas_address( |
| 803 | struct MPT2SAS_ADAPTER *ioc, u64 sas_address); | 822 | struct MPT2SAS_ADAPTER *ioc, u64 sas_address); |
| 804 | 823 | ||
| 805 | void mpt2sas_scsih_event_callback(struct MPT2SAS_ADAPTER *ioc, u8 msix_index, | ||
| 806 | u32 reply); | ||
| 807 | void mpt2sas_scsih_reset_handler(struct MPT2SAS_ADAPTER *ioc, int reset_phase); | 824 | void mpt2sas_scsih_reset_handler(struct MPT2SAS_ADAPTER *ioc, int reset_phase); |
| 808 | 825 | ||
| 809 | /* config shared API */ | 826 | /* config shared API */ |
| 810 | void mpt2sas_config_done(struct MPT2SAS_ADAPTER *ioc, u16 smid, u8 msix_index, | 827 | u8 mpt2sas_config_done(struct MPT2SAS_ADAPTER *ioc, u16 smid, u8 msix_index, |
| 811 | u32 reply); | 828 | u32 reply); |
| 812 | int mpt2sas_config_get_number_hba_phys(struct MPT2SAS_ADAPTER *ioc, u8 *num_phys); | 829 | int mpt2sas_config_get_number_hba_phys(struct MPT2SAS_ADAPTER *ioc, u8 *num_phys); |
| 813 | int mpt2sas_config_get_manufacturing_pg0(struct MPT2SAS_ADAPTER *ioc, | 830 | int mpt2sas_config_get_manufacturing_pg0(struct MPT2SAS_ADAPTER *ioc, |
| @@ -861,17 +878,17 @@ extern struct device_attribute *mpt2sas_host_attrs[]; | |||
| 861 | extern struct device_attribute *mpt2sas_dev_attrs[]; | 878 | extern struct device_attribute *mpt2sas_dev_attrs[]; |
| 862 | void mpt2sas_ctl_init(void); | 879 | void mpt2sas_ctl_init(void); |
| 863 | void mpt2sas_ctl_exit(void); | 880 | void mpt2sas_ctl_exit(void); |
| 864 | void mpt2sas_ctl_done(struct MPT2SAS_ADAPTER *ioc, u16 smid, u8 msix_index, | 881 | u8 mpt2sas_ctl_done(struct MPT2SAS_ADAPTER *ioc, u16 smid, u8 msix_index, |
| 865 | u32 reply); | 882 | u32 reply); |
| 866 | void mpt2sas_ctl_reset_handler(struct MPT2SAS_ADAPTER *ioc, int reset_phase); | 883 | void mpt2sas_ctl_reset_handler(struct MPT2SAS_ADAPTER *ioc, int reset_phase); |
| 867 | void mpt2sas_ctl_event_callback(struct MPT2SAS_ADAPTER *ioc, u8 msix_index, | 884 | u8 mpt2sas_ctl_event_callback(struct MPT2SAS_ADAPTER *ioc, u8 msix_index, |
| 868 | u32 reply); | 885 | u32 reply); |
| 869 | void mpt2sas_ctl_add_to_event_log(struct MPT2SAS_ADAPTER *ioc, | 886 | void mpt2sas_ctl_add_to_event_log(struct MPT2SAS_ADAPTER *ioc, |
| 870 | Mpi2EventNotificationReply_t *mpi_reply); | 887 | Mpi2EventNotificationReply_t *mpi_reply); |
| 871 | 888 | ||
| 872 | /* transport shared API */ | 889 | /* transport shared API */ |
| 873 | void mpt2sas_transport_done(struct MPT2SAS_ADAPTER *ioc, u16 smid, | 890 | u8 mpt2sas_transport_done(struct MPT2SAS_ADAPTER *ioc, u16 smid, u8 msix_index, |
| 874 | u8 msix_index, u32 reply); | 891 | u32 reply); |
| 875 | struct _sas_port *mpt2sas_transport_port_add(struct MPT2SAS_ADAPTER *ioc, | 892 | struct _sas_port *mpt2sas_transport_port_add(struct MPT2SAS_ADAPTER *ioc, |
| 876 | u16 handle, u16 parent_handle); | 893 | u16 handle, u16 parent_handle); |
| 877 | void mpt2sas_transport_port_remove(struct MPT2SAS_ADAPTER *ioc, u64 sas_address, | 894 | void mpt2sas_transport_port_remove(struct MPT2SAS_ADAPTER *ioc, u64 sas_address, |
| @@ -885,6 +902,8 @@ void mpt2sas_transport_update_links(struct MPT2SAS_ADAPTER *ioc, u16 handle, | |||
| 885 | extern struct sas_function_template mpt2sas_transport_functions; | 902 | extern struct sas_function_template mpt2sas_transport_functions; |
| 886 | extern struct scsi_transport_template *mpt2sas_transport_template; | 903 | extern struct scsi_transport_template *mpt2sas_transport_template; |
| 887 | extern int scsi_internal_device_block(struct scsi_device *sdev); | 904 | extern int scsi_internal_device_block(struct scsi_device *sdev); |
| 905 | extern u8 mpt2sas_stm_zero_smid_handler(struct MPT2SAS_ADAPTER *ioc, | ||
| 906 | u8 msix_index, u32 reply); | ||
| 888 | extern int scsi_internal_device_unblock(struct scsi_device *sdev); | 907 | extern int scsi_internal_device_unblock(struct scsi_device *sdev); |
| 889 | 908 | ||
| 890 | #endif /* MPT2SAS_BASE_H_INCLUDED */ | 909 | #endif /* MPT2SAS_BASE_H_INCLUDED */ |
diff --git a/drivers/scsi/mpt2sas/mpt2sas_config.c b/drivers/scsi/mpt2sas/mpt2sas_config.c index d79a4ddf26be..594a389c6526 100644 --- a/drivers/scsi/mpt2sas/mpt2sas_config.c +++ b/drivers/scsi/mpt2sas/mpt2sas_config.c | |||
| @@ -233,18 +233,19 @@ _config_free_config_dma_memory(struct MPT2SAS_ADAPTER *ioc, | |||
| 233 | * | 233 | * |
| 234 | * The callback handler when using _config_request. | 234 | * The callback handler when using _config_request. |
| 235 | * | 235 | * |
| 236 | * Return nothing. | 236 | * Return 1 meaning mf should be freed from _base_interrupt |
| 237 | * 0 means the mf is freed from this function. | ||
| 237 | */ | 238 | */ |
| 238 | void | 239 | u8 |
| 239 | mpt2sas_config_done(struct MPT2SAS_ADAPTER *ioc, u16 smid, u8 msix_index, | 240 | mpt2sas_config_done(struct MPT2SAS_ADAPTER *ioc, u16 smid, u8 msix_index, |
| 240 | u32 reply) | 241 | u32 reply) |
| 241 | { | 242 | { |
| 242 | MPI2DefaultReply_t *mpi_reply; | 243 | MPI2DefaultReply_t *mpi_reply; |
| 243 | 244 | ||
| 244 | if (ioc->config_cmds.status == MPT2_CMD_NOT_USED) | 245 | if (ioc->config_cmds.status == MPT2_CMD_NOT_USED) |
| 245 | return; | 246 | return 1; |
| 246 | if (ioc->config_cmds.smid != smid) | 247 | if (ioc->config_cmds.smid != smid) |
| 247 | return; | 248 | return 1; |
| 248 | ioc->config_cmds.status |= MPT2_CMD_COMPLETE; | 249 | ioc->config_cmds.status |= MPT2_CMD_COMPLETE; |
| 249 | mpi_reply = mpt2sas_base_get_reply_virt_addr(ioc, reply); | 250 | mpi_reply = mpt2sas_base_get_reply_virt_addr(ioc, reply); |
| 250 | if (mpi_reply) { | 251 | if (mpi_reply) { |
| @@ -258,6 +259,7 @@ mpt2sas_config_done(struct MPT2SAS_ADAPTER *ioc, u16 smid, u8 msix_index, | |||
| 258 | #endif | 259 | #endif |
| 259 | ioc->config_cmds.smid = USHORT_MAX; | 260 | ioc->config_cmds.smid = USHORT_MAX; |
| 260 | complete(&ioc->config_cmds.done); | 261 | complete(&ioc->config_cmds.done); |
| 262 | return 1; | ||
| 261 | } | 263 | } |
| 262 | 264 | ||
| 263 | /** | 265 | /** |
diff --git a/drivers/scsi/mpt2sas/mpt2sas_ctl.c b/drivers/scsi/mpt2sas/mpt2sas_ctl.c index 466e2f42367f..33463ace0d48 100644 --- a/drivers/scsi/mpt2sas/mpt2sas_ctl.c +++ b/drivers/scsi/mpt2sas/mpt2sas_ctl.c | |||
| @@ -225,18 +225,19 @@ _ctl_display_some_debug(struct MPT2SAS_ADAPTER *ioc, u16 smid, | |||
| 225 | * | 225 | * |
| 226 | * The callback handler when using ioc->ctl_cb_idx. | 226 | * The callback handler when using ioc->ctl_cb_idx. |
| 227 | * | 227 | * |
| 228 | * Return nothing. | 228 | * Return 1 meaning mf should be freed from _base_interrupt |
| 229 | * 0 means the mf is freed from this function. | ||
| 229 | */ | 230 | */ |
| 230 | void | 231 | u8 |
| 231 | mpt2sas_ctl_done(struct MPT2SAS_ADAPTER *ioc, u16 smid, u8 msix_index, | 232 | mpt2sas_ctl_done(struct MPT2SAS_ADAPTER *ioc, u16 smid, u8 msix_index, |
| 232 | u32 reply) | 233 | u32 reply) |
| 233 | { | 234 | { |
| 234 | MPI2DefaultReply_t *mpi_reply; | 235 | MPI2DefaultReply_t *mpi_reply; |
| 235 | 236 | ||
| 236 | if (ioc->ctl_cmds.status == MPT2_CMD_NOT_USED) | 237 | if (ioc->ctl_cmds.status == MPT2_CMD_NOT_USED) |
| 237 | return; | 238 | return 1; |
| 238 | if (ioc->ctl_cmds.smid != smid) | 239 | if (ioc->ctl_cmds.smid != smid) |
| 239 | return; | 240 | return 1; |
| 240 | ioc->ctl_cmds.status |= MPT2_CMD_COMPLETE; | 241 | ioc->ctl_cmds.status |= MPT2_CMD_COMPLETE; |
| 241 | mpi_reply = mpt2sas_base_get_reply_virt_addr(ioc, reply); | 242 | mpi_reply = mpt2sas_base_get_reply_virt_addr(ioc, reply); |
| 242 | if (mpi_reply) { | 243 | if (mpi_reply) { |
| @@ -248,6 +249,7 @@ mpt2sas_ctl_done(struct MPT2SAS_ADAPTER *ioc, u16 smid, u8 msix_index, | |||
| 248 | #endif | 249 | #endif |
| 249 | ioc->ctl_cmds.status &= ~MPT2_CMD_PENDING; | 250 | ioc->ctl_cmds.status &= ~MPT2_CMD_PENDING; |
| 250 | complete(&ioc->ctl_cmds.done); | 251 | complete(&ioc->ctl_cmds.done); |
| 252 | return 1; | ||
| 251 | } | 253 | } |
| 252 | 254 | ||
| 253 | /** | 255 | /** |
| @@ -336,9 +338,10 @@ mpt2sas_ctl_add_to_event_log(struct MPT2SAS_ADAPTER *ioc, | |||
| 336 | * This function merely adds a new work task into ioc->firmware_event_thread. | 338 | * This function merely adds a new work task into ioc->firmware_event_thread. |
| 337 | * The tasks are worked from _firmware_event_work in user context. | 339 | * The tasks are worked from _firmware_event_work in user context. |
| 338 | * | 340 | * |
| 339 | * Return nothing. | 341 | * Return 1 meaning mf should be freed from _base_interrupt |
| 342 | * 0 means the mf is freed from this function. | ||
| 340 | */ | 343 | */ |
| 341 | void | 344 | u8 |
| 342 | mpt2sas_ctl_event_callback(struct MPT2SAS_ADAPTER *ioc, u8 msix_index, | 345 | mpt2sas_ctl_event_callback(struct MPT2SAS_ADAPTER *ioc, u8 msix_index, |
| 343 | u32 reply) | 346 | u32 reply) |
| 344 | { | 347 | { |
| @@ -346,6 +349,7 @@ mpt2sas_ctl_event_callback(struct MPT2SAS_ADAPTER *ioc, u8 msix_index, | |||
| 346 | 349 | ||
| 347 | mpi_reply = mpt2sas_base_get_reply_virt_addr(ioc, reply); | 350 | mpi_reply = mpt2sas_base_get_reply_virt_addr(ioc, reply); |
| 348 | mpt2sas_ctl_add_to_event_log(ioc, mpi_reply); | 351 | mpt2sas_ctl_add_to_event_log(ioc, mpi_reply); |
| 352 | return 1; | ||
| 349 | } | 353 | } |
| 350 | 354 | ||
| 351 | /** | 355 | /** |
diff --git a/drivers/scsi/mpt2sas/mpt2sas_scsih.c b/drivers/scsi/mpt2sas/mpt2sas_scsih.c index d4b003a618a1..9ec50729d535 100644 --- a/drivers/scsi/mpt2sas/mpt2sas_scsih.c +++ b/drivers/scsi/mpt2sas/mpt2sas_scsih.c | |||
| @@ -79,6 +79,9 @@ static u8 transport_cb_idx = -1; | |||
| 79 | static u8 config_cb_idx = -1; | 79 | static u8 config_cb_idx = -1; |
| 80 | static int mpt_ids; | 80 | static int mpt_ids; |
| 81 | 81 | ||
| 82 | static u8 tm_tr_cb_idx = -1 ; | ||
| 83 | static u8 tm_sas_control_cb_idx = -1; | ||
| 84 | |||
| 82 | /* command line options */ | 85 | /* command line options */ |
| 83 | static u32 logging_level; | 86 | static u32 logging_level; |
| 84 | MODULE_PARM_DESC(logging_level, " bits for enabling additional logging info " | 87 | MODULE_PARM_DESC(logging_level, " bits for enabling additional logging info " |
| @@ -1641,17 +1644,18 @@ _scsih_response_code(struct MPT2SAS_ADAPTER *ioc, u8 response_code) | |||
| 1641 | * | 1644 | * |
| 1642 | * The callback handler when using scsih_issue_tm. | 1645 | * The callback handler when using scsih_issue_tm. |
| 1643 | * | 1646 | * |
| 1644 | * Return nothing. | 1647 | * Return 1 meaning mf should be freed from _base_interrupt |
| 1648 | * 0 means the mf is freed from this function. | ||
| 1645 | */ | 1649 | */ |
| 1646 | static void | 1650 | static u8 |
| 1647 | _scsih_tm_done(struct MPT2SAS_ADAPTER *ioc, u16 smid, u8 msix_index, u32 reply) | 1651 | _scsih_tm_done(struct MPT2SAS_ADAPTER *ioc, u16 smid, u8 msix_index, u32 reply) |
| 1648 | { | 1652 | { |
| 1649 | MPI2DefaultReply_t *mpi_reply; | 1653 | MPI2DefaultReply_t *mpi_reply; |
| 1650 | 1654 | ||
| 1651 | if (ioc->tm_cmds.status == MPT2_CMD_NOT_USED) | 1655 | if (ioc->tm_cmds.status == MPT2_CMD_NOT_USED) |
| 1652 | return; | 1656 | return 1; |
| 1653 | if (ioc->tm_cmds.smid != smid) | 1657 | if (ioc->tm_cmds.smid != smid) |
| 1654 | return; | 1658 | return 1; |
| 1655 | ioc->tm_cmds.status |= MPT2_CMD_COMPLETE; | 1659 | ioc->tm_cmds.status |= MPT2_CMD_COMPLETE; |
| 1656 | mpi_reply = mpt2sas_base_get_reply_virt_addr(ioc, reply); | 1660 | mpi_reply = mpt2sas_base_get_reply_virt_addr(ioc, reply); |
| 1657 | if (mpi_reply) { | 1661 | if (mpi_reply) { |
| @@ -1660,6 +1664,7 @@ _scsih_tm_done(struct MPT2SAS_ADAPTER *ioc, u16 smid, u8 msix_index, u32 reply) | |||
| 1660 | } | 1664 | } |
| 1661 | ioc->tm_cmds.status &= ~MPT2_CMD_PENDING; | 1665 | ioc->tm_cmds.status &= ~MPT2_CMD_PENDING; |
| 1662 | complete(&ioc->tm_cmds.done); | 1666 | complete(&ioc->tm_cmds.done); |
| 1667 | return 1; | ||
| 1663 | } | 1668 | } |
| 1664 | 1669 | ||
| 1665 | /** | 1670 | /** |
| @@ -2312,6 +2317,231 @@ _scsih_block_io_to_children_attached_directly(struct MPT2SAS_ADAPTER *ioc, | |||
| 2312 | } | 2317 | } |
| 2313 | 2318 | ||
| 2314 | /** | 2319 | /** |
| 2320 | * _scsih_tm_tr_send - send task management request | ||
| 2321 | * @ioc: per adapter object | ||
| 2322 | * @handle: device handle | ||
| 2323 | * Context: interrupt time. | ||
| 2324 | * | ||
| 2325 | * This code is to initiate the device removal handshake protocal | ||
| 2326 | * with controller firmware. This function will issue target reset | ||
| 2327 | * using high priority request queue. It will send a sas iounit | ||
| 2328 | * controll request (MPI2_SAS_OP_REMOVE_DEVICE) from this completion. | ||
| 2329 | * | ||
| 2330 | * This is designed to send muliple task management request at the same | ||
| 2331 | * time to the fifo. If the fifo is full, we will append the request, | ||
| 2332 | * and process it in a future completion. | ||
| 2333 | */ | ||
| 2334 | static void | ||
| 2335 | _scsih_tm_tr_send(struct MPT2SAS_ADAPTER *ioc, u16 handle) | ||
| 2336 | { | ||
| 2337 | Mpi2SCSITaskManagementRequest_t *mpi_request; | ||
| 2338 | struct MPT2SAS_TARGET *sas_target_priv_data; | ||
| 2339 | u16 smid; | ||
| 2340 | struct _sas_device *sas_device; | ||
| 2341 | unsigned long flags; | ||
| 2342 | struct _tr_list *delayed_tr; | ||
| 2343 | |||
| 2344 | if (ioc->shost_recovery) { | ||
| 2345 | printk(MPT2SAS_INFO_FMT "%s: host reset in progress!\n", | ||
| 2346 | __func__, ioc->name); | ||
| 2347 | return; | ||
| 2348 | } | ||
| 2349 | |||
| 2350 | spin_lock_irqsave(&ioc->sas_device_lock, flags); | ||
| 2351 | sas_device = _scsih_sas_device_find_by_handle(ioc, handle); | ||
| 2352 | if (!sas_device) { | ||
| 2353 | spin_unlock_irqrestore(&ioc->sas_device_lock, flags); | ||
| 2354 | printk(MPT2SAS_ERR_FMT "%s: failed finding sas_device\n", | ||
| 2355 | ioc->name, __func__); | ||
| 2356 | return; | ||
| 2357 | } | ||
| 2358 | spin_unlock_irqrestore(&ioc->sas_device_lock, flags); | ||
| 2359 | |||
| 2360 | /* skip is hidden raid component */ | ||
| 2361 | if (sas_device->hidden_raid_component) | ||
| 2362 | return; | ||
| 2363 | |||
| 2364 | smid = mpt2sas_base_get_smid_hpr(ioc, ioc->tm_tr_cb_idx); | ||
| 2365 | if (!smid) { | ||
| 2366 | delayed_tr = kzalloc(sizeof(*delayed_tr), GFP_ATOMIC); | ||
| 2367 | if (!delayed_tr) | ||
| 2368 | return; | ||
| 2369 | INIT_LIST_HEAD(&delayed_tr->list); | ||
| 2370 | delayed_tr->handle = handle; | ||
| 2371 | delayed_tr->state = MPT2SAS_REQ_SAS_CNTRL; | ||
| 2372 | list_add_tail(&delayed_tr->list, | ||
| 2373 | &ioc->delayed_tr_list); | ||
| 2374 | if (sas_device->starget) | ||
| 2375 | dewtprintk(ioc, starget_printk(KERN_INFO, | ||
| 2376 | sas_device->starget, "DELAYED:tr:handle(0x%04x), " | ||
| 2377 | "(open)\n", sas_device->handle)); | ||
| 2378 | return; | ||
| 2379 | } | ||
| 2380 | |||
| 2381 | if (sas_device->starget && sas_device->starget->hostdata) { | ||
| 2382 | sas_target_priv_data = sas_device->starget->hostdata; | ||
| 2383 | sas_target_priv_data->tm_busy = 1; | ||
| 2384 | dewtprintk(ioc, starget_printk(KERN_INFO, sas_device->starget, | ||
| 2385 | "tr:handle(0x%04x), (open)\n", sas_device->handle)); | ||
| 2386 | } | ||
| 2387 | |||
| 2388 | mpi_request = mpt2sas_base_get_msg_frame(ioc, smid); | ||
| 2389 | memset(mpi_request, 0, sizeof(Mpi2SCSITaskManagementRequest_t)); | ||
| 2390 | mpi_request->Function = MPI2_FUNCTION_SCSI_TASK_MGMT; | ||
| 2391 | mpi_request->DevHandle = cpu_to_le16(handle); | ||
| 2392 | mpi_request->TaskType = MPI2_SCSITASKMGMT_TASKTYPE_TARGET_RESET; | ||
| 2393 | sas_device->state |= MPTSAS_STATE_TR_SEND; | ||
| 2394 | sas_device->state |= MPT2SAS_REQ_SAS_CNTRL; | ||
| 2395 | mpt2sas_base_put_smid_hi_priority(ioc, smid); | ||
| 2396 | } | ||
| 2397 | |||
| 2398 | |||
| 2399 | |||
| 2400 | /** | ||
| 2401 | * _scsih_sas_control_complete - completion routine | ||
| 2402 | * @ioc: per adapter object | ||
| 2403 | * @smid: system request message index | ||
| 2404 | * @msix_index: MSIX table index supplied by the OS | ||
| 2405 | * @reply: reply message frame(lower 32bit addr) | ||
| 2406 | * Context: interrupt time. | ||
| 2407 | * | ||
| 2408 | * This is the sas iounit controll completion routine. | ||
| 2409 | * This code is part of the code to initiate the device removal | ||
| 2410 | * handshake protocal with controller firmware. | ||
| 2411 | * | ||
| 2412 | * Return 1 meaning mf should be freed from _base_interrupt | ||
| 2413 | * 0 means the mf is freed from this function. | ||
| 2414 | */ | ||
| 2415 | static u8 | ||
| 2416 | _scsih_sas_control_complete(struct MPT2SAS_ADAPTER *ioc, u16 smid, | ||
| 2417 | u8 msix_index, u32 reply) | ||
| 2418 | { | ||
| 2419 | unsigned long flags; | ||
| 2420 | u16 handle; | ||
| 2421 | struct _sas_device *sas_device; | ||
| 2422 | Mpi2SasIoUnitControlReply_t *mpi_reply = | ||
| 2423 | mpt2sas_base_get_reply_virt_addr(ioc, reply); | ||
| 2424 | |||
| 2425 | handle = le16_to_cpu(mpi_reply->DevHandle); | ||
| 2426 | |||
| 2427 | spin_lock_irqsave(&ioc->sas_device_lock, flags); | ||
| 2428 | sas_device = _scsih_sas_device_find_by_handle(ioc, handle); | ||
| 2429 | if (!sas_device) { | ||
| 2430 | spin_unlock_irqrestore(&ioc->sas_device_lock, flags); | ||
| 2431 | printk(MPT2SAS_ERR_FMT "%s: failed finding sas_device\n", | ||
| 2432 | ioc->name, __func__); | ||
| 2433 | return 1; | ||
| 2434 | } | ||
| 2435 | sas_device->state |= MPTSAS_STATE_CNTRL_COMPLETE; | ||
| 2436 | spin_unlock_irqrestore(&ioc->sas_device_lock, flags); | ||
| 2437 | |||
| 2438 | if (sas_device->starget) | ||
| 2439 | dewtprintk(ioc, starget_printk(KERN_INFO, sas_device->starget, | ||
| 2440 | "sc_complete:handle(0x%04x), " | ||
| 2441 | "ioc_status(0x%04x), loginfo(0x%08x)\n", | ||
| 2442 | handle, le16_to_cpu(mpi_reply->IOCStatus), | ||
| 2443 | le32_to_cpu(mpi_reply->IOCLogInfo))); | ||
| 2444 | return 1; | ||
| 2445 | } | ||
| 2446 | |||
| 2447 | /** | ||
| 2448 | * _scsih_tm_tr_complete - | ||
| 2449 | * @ioc: per adapter object | ||
| 2450 | * @smid: system request message index | ||
| 2451 | * @msix_index: MSIX table index supplied by the OS | ||
| 2452 | * @reply: reply message frame(lower 32bit addr) | ||
| 2453 | * Context: interrupt time. | ||
| 2454 | * | ||
| 2455 | * This is the target reset completion routine. | ||
| 2456 | * This code is part of the code to initiate the device removal | ||
| 2457 | * handshake protocal with controller firmware. | ||
| 2458 | * It will send a sas iounit controll request (MPI2_SAS_OP_REMOVE_DEVICE) | ||
| 2459 | * | ||
| 2460 | * Return 1 meaning mf should be freed from _base_interrupt | ||
| 2461 | * 0 means the mf is freed from this function. | ||
| 2462 | */ | ||
| 2463 | static u8 | ||
| 2464 | _scsih_tm_tr_complete(struct MPT2SAS_ADAPTER *ioc, u16 smid, u8 msix_index, | ||
| 2465 | u32 reply) | ||
| 2466 | { | ||
| 2467 | unsigned long flags; | ||
| 2468 | u16 handle; | ||
| 2469 | struct _sas_device *sas_device; | ||
| 2470 | Mpi2SCSITaskManagementReply_t *mpi_reply = | ||
| 2471 | mpt2sas_base_get_reply_virt_addr(ioc, reply); | ||
| 2472 | Mpi2SasIoUnitControlRequest_t *mpi_request; | ||
| 2473 | u16 smid_sas_ctrl; | ||
| 2474 | struct MPT2SAS_TARGET *sas_target_priv_data; | ||
| 2475 | struct _tr_list *delayed_tr; | ||
| 2476 | u8 rc; | ||
| 2477 | |||
| 2478 | handle = le16_to_cpu(mpi_reply->DevHandle); | ||
| 2479 | spin_lock_irqsave(&ioc->sas_device_lock, flags); | ||
| 2480 | sas_device = _scsih_sas_device_find_by_handle(ioc, handle); | ||
| 2481 | if (!sas_device) { | ||
| 2482 | spin_unlock_irqrestore(&ioc->sas_device_lock, flags); | ||
| 2483 | printk(MPT2SAS_ERR_FMT "%s: failed finding sas_device\n", | ||
| 2484 | ioc->name, __func__); | ||
| 2485 | return 1; | ||
| 2486 | } | ||
| 2487 | sas_device->state |= MPTSAS_STATE_TR_COMPLETE; | ||
| 2488 | spin_unlock_irqrestore(&ioc->sas_device_lock, flags); | ||
| 2489 | |||
| 2490 | if (sas_device->starget) | ||
| 2491 | dewtprintk(ioc, starget_printk(KERN_INFO, sas_device->starget, | ||
| 2492 | "tr_complete:handle(0x%04x), (%s) ioc_status(0x%04x), " | ||
| 2493 | "loginfo(0x%08x), completed(%d)\n", | ||
| 2494 | sas_device->handle, (sas_device->state & | ||
| 2495 | MPT2SAS_REQ_SAS_CNTRL) ? "open" : "active", | ||
| 2496 | le16_to_cpu(mpi_reply->IOCStatus), | ||
| 2497 | le32_to_cpu(mpi_reply->IOCLogInfo), | ||
| 2498 | le32_to_cpu(mpi_reply->TerminationCount))); | ||
| 2499 | |||
| 2500 | if (sas_device->starget && sas_device->starget->hostdata) { | ||
| 2501 | sas_target_priv_data = sas_device->starget->hostdata; | ||
| 2502 | sas_target_priv_data->tm_busy = 0; | ||
| 2503 | } | ||
| 2504 | |||
| 2505 | if (!list_empty(&ioc->delayed_tr_list)) { | ||
| 2506 | delayed_tr = list_entry(ioc->delayed_tr_list.next, | ||
| 2507 | struct _tr_list, list); | ||
| 2508 | mpt2sas_base_free_smid(ioc, smid); | ||
| 2509 | if (delayed_tr->state & MPT2SAS_REQ_SAS_CNTRL) | ||
| 2510 | _scsih_tm_tr_send(ioc, delayed_tr->handle); | ||
| 2511 | list_del(&delayed_tr->list); | ||
| 2512 | kfree(delayed_tr); | ||
| 2513 | rc = 0; /* tells base_interrupt not to free mf */ | ||
| 2514 | } else | ||
| 2515 | rc = 1; | ||
| 2516 | |||
| 2517 | |||
| 2518 | if (!(sas_device->state & MPT2SAS_REQ_SAS_CNTRL)) | ||
| 2519 | return rc; | ||
| 2520 | |||
| 2521 | if (ioc->shost_recovery) { | ||
| 2522 | printk(MPT2SAS_INFO_FMT "%s: host reset in progress!\n", | ||
| 2523 | __func__, ioc->name); | ||
| 2524 | return rc; | ||
| 2525 | } | ||
| 2526 | |||
| 2527 | smid_sas_ctrl = mpt2sas_base_get_smid(ioc, ioc->tm_sas_control_cb_idx); | ||
| 2528 | if (!smid_sas_ctrl) { | ||
| 2529 | printk(MPT2SAS_ERR_FMT "%s: failed obtaining a smid\n", | ||
| 2530 | ioc->name, __func__); | ||
| 2531 | return rc; | ||
| 2532 | } | ||
| 2533 | |||
| 2534 | mpi_request = mpt2sas_base_get_msg_frame(ioc, smid_sas_ctrl); | ||
| 2535 | memset(mpi_request, 0, sizeof(Mpi2SasIoUnitControlRequest_t)); | ||
| 2536 | mpi_request->Function = MPI2_FUNCTION_SAS_IO_UNIT_CONTROL; | ||
| 2537 | mpi_request->Operation = MPI2_SAS_OP_REMOVE_DEVICE; | ||
| 2538 | mpi_request->DevHandle = mpi_reply->DevHandle; | ||
| 2539 | sas_device->state |= MPTSAS_STATE_CNTRL_SEND; | ||
| 2540 | mpt2sas_base_put_smid_default(ioc, smid_sas_ctrl); | ||
| 2541 | return rc; | ||
| 2542 | } | ||
| 2543 | |||
| 2544 | /** | ||
| 2315 | * _scsih_check_topo_delete_events - sanity check on topo events | 2545 | * _scsih_check_topo_delete_events - sanity check on topo events |
| 2316 | * @ioc: per adapter object | 2546 | * @ioc: per adapter object |
| 2317 | * @event_data: the event data payload | 2547 | * @event_data: the event data payload |
| @@ -2333,6 +2563,21 @@ _scsih_check_topo_delete_events(struct MPT2SAS_ADAPTER *ioc, | |||
| 2333 | u16 expander_handle; | 2563 | u16 expander_handle; |
| 2334 | struct _sas_node *sas_expander; | 2564 | struct _sas_node *sas_expander; |
| 2335 | unsigned long flags; | 2565 | unsigned long flags; |
| 2566 | int i, reason_code; | ||
| 2567 | u16 handle; | ||
| 2568 | |||
| 2569 | for (i = 0 ; i < event_data->NumEntries; i++) { | ||
| 2570 | if (event_data->PHY[i].PhyStatus & | ||
| 2571 | MPI2_EVENT_SAS_TOPO_PHYSTATUS_VACANT) | ||
| 2572 | continue; | ||
| 2573 | handle = le16_to_cpu(event_data->PHY[i].AttachedDevHandle); | ||
| 2574 | if (!handle) | ||
| 2575 | continue; | ||
| 2576 | reason_code = event_data->PHY[i].PhyStatus & | ||
| 2577 | MPI2_EVENT_SAS_TOPO_RC_MASK; | ||
| 2578 | if (reason_code == MPI2_EVENT_SAS_TOPO_RC_TARG_NOT_RESPONDING) | ||
| 2579 | _scsih_tm_tr_send(ioc, handle); | ||
| 2580 | } | ||
| 2336 | 2581 | ||
| 2337 | expander_handle = le16_to_cpu(event_data->ExpanderDevHandle); | 2582 | expander_handle = le16_to_cpu(event_data->ExpanderDevHandle); |
| 2338 | if (expander_handle < ioc->sas_hba.num_phys) { | 2583 | if (expander_handle < ioc->sas_hba.num_phys) { |
| @@ -2915,11 +3160,12 @@ _scsih_smart_predicted_fault(struct MPT2SAS_ADAPTER *ioc, u16 handle) | |||
| 2915 | * @msix_index: MSIX table index supplied by the OS | 3160 | * @msix_index: MSIX table index supplied by the OS |
| 2916 | * @reply: reply message frame(lower 32bit addr) | 3161 | * @reply: reply message frame(lower 32bit addr) |
| 2917 | * | 3162 | * |
| 2918 | * Callback handler when using scsih_qcmd. | 3163 | * Callback handler when using _scsih_qcmd. |
| 2919 | * | 3164 | * |
| 2920 | * Return nothing. | 3165 | * Return 1 meaning mf should be freed from _base_interrupt |
| 3166 | * 0 means the mf is freed from this function. | ||
| 2921 | */ | 3167 | */ |
| 2922 | static void | 3168 | static u8 |
| 2923 | _scsih_io_done(struct MPT2SAS_ADAPTER *ioc, u16 smid, u8 msix_index, u32 reply) | 3169 | _scsih_io_done(struct MPT2SAS_ADAPTER *ioc, u16 smid, u8 msix_index, u32 reply) |
| 2924 | { | 3170 | { |
| 2925 | Mpi2SCSIIORequest_t *mpi_request; | 3171 | Mpi2SCSIIORequest_t *mpi_request; |
| @@ -2936,7 +3182,7 @@ _scsih_io_done(struct MPT2SAS_ADAPTER *ioc, u16 smid, u8 msix_index, u32 reply) | |||
| 2936 | mpi_reply = mpt2sas_base_get_reply_virt_addr(ioc, reply); | 3182 | mpi_reply = mpt2sas_base_get_reply_virt_addr(ioc, reply); |
| 2937 | scmd = _scsih_scsi_lookup_get(ioc, smid); | 3183 | scmd = _scsih_scsi_lookup_get(ioc, smid); |
| 2938 | if (scmd == NULL) | 3184 | if (scmd == NULL) |
| 2939 | return; | 3185 | return 1; |
| 2940 | 3186 | ||
| 2941 | mpi_request = mpt2sas_base_get_msg_frame(ioc, smid); | 3187 | mpi_request = mpt2sas_base_get_msg_frame(ioc, smid); |
| 2942 | 3188 | ||
| @@ -3092,6 +3338,7 @@ _scsih_io_done(struct MPT2SAS_ADAPTER *ioc, u16 smid, u8 msix_index, u32 reply) | |||
| 3092 | out: | 3338 | out: |
| 3093 | scsi_dma_unmap(scmd); | 3339 | scsi_dma_unmap(scmd); |
| 3094 | scmd->scsi_done(scmd); | 3340 | scmd->scsi_done(scmd); |
| 3341 | return 1; | ||
| 3095 | } | 3342 | } |
| 3096 | 3343 | ||
| 3097 | /** | 3344 | /** |
| @@ -3623,6 +3870,12 @@ _scsih_remove_device(struct MPT2SAS_ADAPTER *ioc, u16 handle) | |||
| 3623 | if (ioc->remove_host) | 3870 | if (ioc->remove_host) |
| 3624 | goto out; | 3871 | goto out; |
| 3625 | 3872 | ||
| 3873 | if ((sas_device->state & MPTSAS_STATE_TR_COMPLETE)) { | ||
| 3874 | dewtprintk(ioc, printk(MPT2SAS_INFO_FMT "\tskip " | ||
| 3875 | "target_reset handle(0x%04x)\n", ioc->name, handle)); | ||
| 3876 | goto skip_tr; | ||
| 3877 | } | ||
| 3878 | |||
| 3626 | /* Target Reset to flush out all the outstanding IO */ | 3879 | /* Target Reset to flush out all the outstanding IO */ |
| 3627 | device_handle = (sas_device->hidden_raid_component) ? | 3880 | device_handle = (sas_device->hidden_raid_component) ? |
| 3628 | sas_device->volume_handle : handle; | 3881 | sas_device->volume_handle : handle; |
| @@ -3639,6 +3892,13 @@ _scsih_remove_device(struct MPT2SAS_ADAPTER *ioc, u16 handle) | |||
| 3639 | if (ioc->shost_recovery) | 3892 | if (ioc->shost_recovery) |
| 3640 | goto out; | 3893 | goto out; |
| 3641 | } | 3894 | } |
| 3895 | skip_tr: | ||
| 3896 | |||
| 3897 | if ((sas_device->state & MPTSAS_STATE_CNTRL_COMPLETE)) { | ||
| 3898 | dewtprintk(ioc, printk(MPT2SAS_INFO_FMT "\tskip " | ||
| 3899 | "sas_cntrl handle(0x%04x)\n", ioc->name, handle)); | ||
| 3900 | goto out; | ||
| 3901 | } | ||
| 3642 | 3902 | ||
| 3643 | /* SAS_IO_UNIT_CNTR - send REMOVE_DEVICE */ | 3903 | /* SAS_IO_UNIT_CNTR - send REMOVE_DEVICE */ |
| 3644 | dewtprintk(ioc, printk(MPT2SAS_INFO_FMT "sas_iounit: handle" | 3904 | dewtprintk(ioc, printk(MPT2SAS_INFO_FMT "sas_iounit: handle" |
| @@ -4829,6 +5089,10 @@ _scsih_mark_responding_sas_device(struct MPT2SAS_ADAPTER *ioc, u64 sas_address, | |||
| 4829 | if (sas_device->sas_address == sas_address && | 5089 | if (sas_device->sas_address == sas_address && |
| 4830 | sas_device->slot == slot && sas_device->starget) { | 5090 | sas_device->slot == slot && sas_device->starget) { |
| 4831 | sas_device->responding = 1; | 5091 | sas_device->responding = 1; |
| 5092 | sas_device->state = 0; | ||
| 5093 | starget = sas_device->starget; | ||
| 5094 | sas_target_priv_data = starget->hostdata; | ||
| 5095 | sas_target_priv_data->tm_busy = 0; | ||
| 4832 | starget_printk(KERN_INFO, sas_device->starget, | 5096 | starget_printk(KERN_INFO, sas_device->starget, |
| 4833 | "handle(0x%04x), sas_addr(0x%016llx), enclosure " | 5097 | "handle(0x%04x), sas_addr(0x%016llx), enclosure " |
| 4834 | "logical id(0x%016llx), slot(%d)\n", handle, | 5098 | "logical id(0x%016llx), slot(%d)\n", handle, |
| @@ -4841,8 +5105,6 @@ _scsih_mark_responding_sas_device(struct MPT2SAS_ADAPTER *ioc, u64 sas_address, | |||
| 4841 | printk(KERN_INFO "\thandle changed from(0x%04x)!!!\n", | 5105 | printk(KERN_INFO "\thandle changed from(0x%04x)!!!\n", |
| 4842 | sas_device->handle); | 5106 | sas_device->handle); |
| 4843 | sas_device->handle = handle; | 5107 | sas_device->handle = handle; |
| 4844 | starget = sas_device->starget; | ||
| 4845 | sas_target_priv_data = starget->hostdata; | ||
| 4846 | sas_target_priv_data->handle = handle; | 5108 | sas_target_priv_data->handle = handle; |
| 4847 | goto out; | 5109 | goto out; |
| 4848 | } | 5110 | } |
| @@ -5235,9 +5497,10 @@ _firmware_event_work(struct work_struct *work) | |||
| 5235 | * This function merely adds a new work task into ioc->firmware_event_thread. | 5497 | * This function merely adds a new work task into ioc->firmware_event_thread. |
| 5236 | * The tasks are worked from _firmware_event_work in user context. | 5498 | * The tasks are worked from _firmware_event_work in user context. |
| 5237 | * | 5499 | * |
| 5238 | * Return nothing. | 5500 | * Return 1 meaning mf should be freed from _base_interrupt |
| 5501 | * 0 means the mf is freed from this function. | ||
| 5239 | */ | 5502 | */ |
| 5240 | void | 5503 | u8 |
| 5241 | mpt2sas_scsih_event_callback(struct MPT2SAS_ADAPTER *ioc, u8 msix_index, | 5504 | mpt2sas_scsih_event_callback(struct MPT2SAS_ADAPTER *ioc, u8 msix_index, |
| 5242 | u32 reply) | 5505 | u32 reply) |
| 5243 | { | 5506 | { |
| @@ -5250,11 +5513,11 @@ mpt2sas_scsih_event_callback(struct MPT2SAS_ADAPTER *ioc, u8 msix_index, | |||
| 5250 | spin_lock_irqsave(&ioc->fw_event_lock, flags); | 5513 | spin_lock_irqsave(&ioc->fw_event_lock, flags); |
| 5251 | if (ioc->fw_events_off || ioc->remove_host) { | 5514 | if (ioc->fw_events_off || ioc->remove_host) { |
| 5252 | spin_unlock_irqrestore(&ioc->fw_event_lock, flags); | 5515 | spin_unlock_irqrestore(&ioc->fw_event_lock, flags); |
| 5253 | return; | 5516 | return 1; |
| 5254 | } | 5517 | } |
| 5255 | spin_unlock_irqrestore(&ioc->fw_event_lock, flags); | 5518 | spin_unlock_irqrestore(&ioc->fw_event_lock, flags); |
| 5256 | 5519 | ||
| 5257 | mpi_reply = mpt2sas_base_get_reply_virt_addr(ioc, reply); | 5520 | mpi_reply = mpt2sas_base_get_reply_virt_addr(ioc, reply); |
| 5258 | event = le16_to_cpu(mpi_reply->Event); | 5521 | event = le16_to_cpu(mpi_reply->Event); |
| 5259 | 5522 | ||
| 5260 | switch (event) { | 5523 | switch (event) { |
| @@ -5268,7 +5531,7 @@ mpt2sas_scsih_event_callback(struct MPT2SAS_ADAPTER *ioc, u8 msix_index, | |||
| 5268 | if (baen_data->Primitive != | 5531 | if (baen_data->Primitive != |
| 5269 | MPI2_EVENT_PRIMITIVE_ASYNCHRONOUS_EVENT || | 5532 | MPI2_EVENT_PRIMITIVE_ASYNCHRONOUS_EVENT || |
| 5270 | ioc->broadcast_aen_busy) | 5533 | ioc->broadcast_aen_busy) |
| 5271 | return; | 5534 | return 1; |
| 5272 | ioc->broadcast_aen_busy = 1; | 5535 | ioc->broadcast_aen_busy = 1; |
| 5273 | break; | 5536 | break; |
| 5274 | } | 5537 | } |
| @@ -5290,14 +5553,14 @@ mpt2sas_scsih_event_callback(struct MPT2SAS_ADAPTER *ioc, u8 msix_index, | |||
| 5290 | break; | 5553 | break; |
| 5291 | 5554 | ||
| 5292 | default: /* ignore the rest */ | 5555 | default: /* ignore the rest */ |
| 5293 | return; | 5556 | return 1; |
| 5294 | } | 5557 | } |
| 5295 | 5558 | ||
| 5296 | fw_event = kzalloc(sizeof(struct fw_event_work), GFP_ATOMIC); | 5559 | fw_event = kzalloc(sizeof(struct fw_event_work), GFP_ATOMIC); |
| 5297 | if (!fw_event) { | 5560 | if (!fw_event) { |
| 5298 | printk(MPT2SAS_ERR_FMT "failure at %s:%d/%s()!\n", | 5561 | printk(MPT2SAS_ERR_FMT "failure at %s:%d/%s()!\n", |
| 5299 | ioc->name, __FILE__, __LINE__, __func__); | 5562 | ioc->name, __FILE__, __LINE__, __func__); |
| 5300 | return; | 5563 | return 1; |
| 5301 | } | 5564 | } |
| 5302 | fw_event->event_data = | 5565 | fw_event->event_data = |
| 5303 | kzalloc(mpi_reply->EventDataLength*4, GFP_ATOMIC); | 5566 | kzalloc(mpi_reply->EventDataLength*4, GFP_ATOMIC); |
| @@ -5305,7 +5568,7 @@ mpt2sas_scsih_event_callback(struct MPT2SAS_ADAPTER *ioc, u8 msix_index, | |||
| 5305 | printk(MPT2SAS_ERR_FMT "failure at %s:%d/%s()!\n", | 5568 | printk(MPT2SAS_ERR_FMT "failure at %s:%d/%s()!\n", |
| 5306 | ioc->name, __FILE__, __LINE__, __func__); | 5569 | ioc->name, __FILE__, __LINE__, __func__); |
| 5307 | kfree(fw_event); | 5570 | kfree(fw_event); |
| 5308 | return; | 5571 | return 1; |
| 5309 | } | 5572 | } |
| 5310 | 5573 | ||
| 5311 | memcpy(fw_event->event_data, mpi_reply->EventData, | 5574 | memcpy(fw_event->event_data, mpi_reply->EventData, |
| @@ -5315,6 +5578,7 @@ mpt2sas_scsih_event_callback(struct MPT2SAS_ADAPTER *ioc, u8 msix_index, | |||
| 5315 | fw_event->VP_ID = mpi_reply->VP_ID; | 5578 | fw_event->VP_ID = mpi_reply->VP_ID; |
| 5316 | fw_event->event = event; | 5579 | fw_event->event = event; |
| 5317 | _scsih_fw_event_add(ioc, fw_event); | 5580 | _scsih_fw_event_add(ioc, fw_event); |
| 5581 | return 1; | ||
| 5318 | } | 5582 | } |
| 5319 | 5583 | ||
| 5320 | /* shost template */ | 5584 | /* shost template */ |
| @@ -5574,7 +5838,7 @@ _scsih_probe_raid(struct MPT2SAS_ADAPTER *ioc) | |||
| 5574 | } | 5838 | } |
| 5575 | 5839 | ||
| 5576 | /** | 5840 | /** |
| 5577 | * _scsih_probe_sas - reporting raid volumes to sas transport | 5841 | * _scsih_probe_sas - reporting sas devices to sas transport |
| 5578 | * @ioc: per adapter object | 5842 | * @ioc: per adapter object |
| 5579 | * | 5843 | * |
| 5580 | * Called during initial loading of the driver. | 5844 | * Called during initial loading of the driver. |
| @@ -5671,6 +5935,8 @@ _scsih_probe(struct pci_dev *pdev, const struct pci_device_id *id) | |||
| 5671 | ioc->base_cb_idx = base_cb_idx; | 5935 | ioc->base_cb_idx = base_cb_idx; |
| 5672 | ioc->transport_cb_idx = transport_cb_idx; | 5936 | ioc->transport_cb_idx = transport_cb_idx; |
| 5673 | ioc->config_cb_idx = config_cb_idx; | 5937 | ioc->config_cb_idx = config_cb_idx; |
| 5938 | ioc->tm_tr_cb_idx = tm_tr_cb_idx; | ||
| 5939 | ioc->tm_sas_control_cb_idx = tm_sas_control_cb_idx; | ||
| 5674 | ioc->logging_level = logging_level; | 5940 | ioc->logging_level = logging_level; |
| 5675 | /* misc semaphores and spin locks */ | 5941 | /* misc semaphores and spin locks */ |
| 5676 | spin_lock_init(&ioc->ioc_reset_in_progress_lock); | 5942 | spin_lock_init(&ioc->ioc_reset_in_progress_lock); |
| @@ -5686,6 +5952,7 @@ _scsih_probe(struct pci_dev *pdev, const struct pci_device_id *id) | |||
| 5686 | INIT_LIST_HEAD(&ioc->fw_event_list); | 5952 | INIT_LIST_HEAD(&ioc->fw_event_list); |
| 5687 | INIT_LIST_HEAD(&ioc->raid_device_list); | 5953 | INIT_LIST_HEAD(&ioc->raid_device_list); |
| 5688 | INIT_LIST_HEAD(&ioc->sas_hba.sas_port_list); | 5954 | INIT_LIST_HEAD(&ioc->sas_hba.sas_port_list); |
| 5955 | INIT_LIST_HEAD(&ioc->delayed_tr_list); | ||
| 5689 | 5956 | ||
| 5690 | /* init shost parameters */ | 5957 | /* init shost parameters */ |
| 5691 | shost->max_cmd_len = 16; | 5958 | shost->max_cmd_len = 16; |
| @@ -5702,6 +5969,7 @@ _scsih_probe(struct pci_dev *pdev, const struct pci_device_id *id) | |||
| 5702 | 5969 | ||
| 5703 | scsi_host_set_prot(shost, SHOST_DIF_TYPE1_PROTECTION | 5970 | scsi_host_set_prot(shost, SHOST_DIF_TYPE1_PROTECTION |
| 5704 | | SHOST_DIF_TYPE3_PROTECTION); | 5971 | | SHOST_DIF_TYPE3_PROTECTION); |
| 5972 | scsi_host_set_guard(shost, SHOST_DIX_GUARD_CRC); | ||
| 5705 | 5973 | ||
| 5706 | /* event thread */ | 5974 | /* event thread */ |
| 5707 | snprintf(ioc->firmware_event_name, sizeof(ioc->firmware_event_name), | 5975 | snprintf(ioc->firmware_event_name, sizeof(ioc->firmware_event_name), |
| @@ -5851,6 +6119,11 @@ _scsih_init(void) | |||
| 5851 | /* ctl module callback handler */ | 6119 | /* ctl module callback handler */ |
| 5852 | ctl_cb_idx = mpt2sas_base_register_callback_handler(mpt2sas_ctl_done); | 6120 | ctl_cb_idx = mpt2sas_base_register_callback_handler(mpt2sas_ctl_done); |
| 5853 | 6121 | ||
| 6122 | tm_tr_cb_idx = mpt2sas_base_register_callback_handler( | ||
| 6123 | _scsih_tm_tr_complete); | ||
| 6124 | tm_sas_control_cb_idx = mpt2sas_base_register_callback_handler( | ||
| 6125 | _scsih_sas_control_complete); | ||
| 6126 | |||
| 5854 | mpt2sas_ctl_init(); | 6127 | mpt2sas_ctl_init(); |
| 5855 | 6128 | ||
| 5856 | error = pci_register_driver(&scsih_driver); | 6129 | error = pci_register_driver(&scsih_driver); |
| @@ -5881,6 +6154,9 @@ _scsih_exit(void) | |||
| 5881 | mpt2sas_base_release_callback_handler(config_cb_idx); | 6154 | mpt2sas_base_release_callback_handler(config_cb_idx); |
| 5882 | mpt2sas_base_release_callback_handler(ctl_cb_idx); | 6155 | mpt2sas_base_release_callback_handler(ctl_cb_idx); |
| 5883 | 6156 | ||
| 6157 | mpt2sas_base_release_callback_handler(tm_tr_cb_idx); | ||
| 6158 | mpt2sas_base_release_callback_handler(tm_sas_control_cb_idx); | ||
| 6159 | |||
| 5884 | mpt2sas_ctl_exit(); | 6160 | mpt2sas_ctl_exit(); |
| 5885 | } | 6161 | } |
| 5886 | 6162 | ||
diff --git a/drivers/scsi/mpt2sas/mpt2sas_transport.c b/drivers/scsi/mpt2sas/mpt2sas_transport.c index 4b7201a1e867..8bc57e315ce8 100644 --- a/drivers/scsi/mpt2sas/mpt2sas_transport.c +++ b/drivers/scsi/mpt2sas/mpt2sas_transport.c | |||
| @@ -218,9 +218,10 @@ _transport_set_identify(struct MPT2SAS_ADAPTER *ioc, u16 handle, | |||
| 218 | * Callback handler when sending internal generated transport cmds. | 218 | * Callback handler when sending internal generated transport cmds. |
| 219 | * The callback index passed is `ioc->transport_cb_idx` | 219 | * The callback index passed is `ioc->transport_cb_idx` |
| 220 | * | 220 | * |
| 221 | * Return nothing. | 221 | * Return 1 meaning mf should be freed from _base_interrupt |
| 222 | * 0 means the mf is freed from this function. | ||
| 222 | */ | 223 | */ |
| 223 | void | 224 | u8 |
| 224 | mpt2sas_transport_done(struct MPT2SAS_ADAPTER *ioc, u16 smid, u8 msix_index, | 225 | mpt2sas_transport_done(struct MPT2SAS_ADAPTER *ioc, u16 smid, u8 msix_index, |
| 225 | u32 reply) | 226 | u32 reply) |
| 226 | { | 227 | { |
| @@ -228,9 +229,9 @@ mpt2sas_transport_done(struct MPT2SAS_ADAPTER *ioc, u16 smid, u8 msix_index, | |||
| 228 | 229 | ||
| 229 | mpi_reply = mpt2sas_base_get_reply_virt_addr(ioc, reply); | 230 | mpi_reply = mpt2sas_base_get_reply_virt_addr(ioc, reply); |
| 230 | if (ioc->transport_cmds.status == MPT2_CMD_NOT_USED) | 231 | if (ioc->transport_cmds.status == MPT2_CMD_NOT_USED) |
| 231 | return; | 232 | return 1; |
| 232 | if (ioc->transport_cmds.smid != smid) | 233 | if (ioc->transport_cmds.smid != smid) |
| 233 | return; | 234 | return 1; |
| 234 | ioc->transport_cmds.status |= MPT2_CMD_COMPLETE; | 235 | ioc->transport_cmds.status |= MPT2_CMD_COMPLETE; |
| 235 | if (mpi_reply) { | 236 | if (mpi_reply) { |
| 236 | memcpy(ioc->transport_cmds.reply, mpi_reply, | 237 | memcpy(ioc->transport_cmds.reply, mpi_reply, |
| @@ -239,6 +240,7 @@ mpt2sas_transport_done(struct MPT2SAS_ADAPTER *ioc, u16 smid, u8 msix_index, | |||
| 239 | } | 240 | } |
| 240 | ioc->transport_cmds.status &= ~MPT2_CMD_PENDING; | 241 | ioc->transport_cmds.status &= ~MPT2_CMD_PENDING; |
| 241 | complete(&ioc->transport_cmds.done); | 242 | complete(&ioc->transport_cmds.done); |
| 243 | return 1; | ||
| 242 | } | 244 | } |
| 243 | 245 | ||
| 244 | /* report manufacture request structure */ | 246 | /* report manufacture request structure */ |
