aboutsummaryrefslogtreecommitdiffstats
path: root/drivers
diff options
context:
space:
mode:
authorKashyap, Desai <kashyap.desai@lsi.com>2009-09-14 01:34:23 -0400
committerJames Bottomley <James.Bottomley@suse.de>2009-10-02 10:48:38 -0400
commit77e63ed44305e89c0564f8292f9cd5764d4fddfb (patch)
tree66aab9af95be1daadf6e648b008f9c1d77cf1ac0 /drivers
parent595bb0bd62edb28a965993d90e0fa1285560ce53 (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>
Diffstat (limited to 'drivers')
-rw-r--r--drivers/scsi/mpt2sas/mpt2sas_base.c35
-rw-r--r--drivers/scsi/mpt2sas/mpt2sas_base.h41
-rw-r--r--drivers/scsi/mpt2sas/mpt2sas_config.c10
-rw-r--r--drivers/scsi/mpt2sas/mpt2sas_ctl.c16
-rw-r--r--drivers/scsi/mpt2sas/mpt2sas_scsih.c314
-rw-r--r--drivers/scsi/mpt2sas/mpt2sas_transport.c10
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 */
580void 581u8
581mpt2sas_base_done(struct MPT2SAS_ADAPTER *ioc, u16 smid, u8 msix_index, 582mpt2sas_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 */
610static void 613static 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 */
452struct _tr_list {
453 struct list_head list;
454 u16 handle;
455 u16 state;
456};
457
446typedef void (*MPT_ADD_SGE)(void *paddr, u32 flags_length, dma_addr_t dma_addr); 458typedef 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
741typedef void (*MPT_CALLBACK)(struct MPT2SAS_ADAPTER *ioc, u16 smid, 757typedef 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,
757void *mpt2sas_base_get_msg_frame(struct MPT2SAS_ADAPTER *ioc, u16 smid); 773void *mpt2sas_base_get_msg_frame(struct MPT2SAS_ADAPTER *ioc, u16 smid);
758void *mpt2sas_base_get_sense_buffer(struct MPT2SAS_ADAPTER *ioc, u16 smid); 774void *mpt2sas_base_get_sense_buffer(struct MPT2SAS_ADAPTER *ioc, u16 smid);
759void mpt2sas_base_build_zero_len_sge(struct MPT2SAS_ADAPTER *ioc, void *paddr); 775void mpt2sas_base_build_zero_len_sge(struct MPT2SAS_ADAPTER *ioc, void *paddr);
760dma_addr_t mpt2sas_base_get_sense_buffer_dma(struct MPT2SAS_ADAPTER *ioc, u16 smid); 776dma_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 */
763u16 mpt2sas_base_get_smid_hpr(struct MPT2SAS_ADAPTER *ioc, u8 cb_idx); 780u16 mpt2sas_base_get_smid_hpr(struct MPT2SAS_ADAPTER *ioc, u8 cb_idx);
@@ -776,7 +793,7 @@ void mpt2sas_base_initialize_callback_handler(void);
776u8 mpt2sas_base_register_callback_handler(MPT_CALLBACK cb_func); 793u8 mpt2sas_base_register_callback_handler(MPT_CALLBACK cb_func);
777void mpt2sas_base_release_callback_handler(u8 cb_idx); 794void mpt2sas_base_release_callback_handler(u8 cb_idx);
778 795
779void mpt2sas_base_done(struct MPT2SAS_ADAPTER *ioc, u16 smid, u8 msix_index, 796u8 mpt2sas_base_done(struct MPT2SAS_ADAPTER *ioc, u16 smid, u8 msix_index,
780 u32 reply); 797 u32 reply);
781void *mpt2sas_base_get_reply_virt_addr(struct MPT2SAS_ADAPTER *ioc, u32 phys_addr); 798void *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,
791void mpt2sas_base_validate_event_type(struct MPT2SAS_ADAPTER *ioc, u32 *event_type); 808void mpt2sas_base_validate_event_type(struct MPT2SAS_ADAPTER *ioc, u32 *event_type);
792 809
793/* scsih shared API */ 810/* scsih shared API */
811u8 mpt2sas_scsih_event_callback(struct MPT2SAS_ADAPTER *ioc, u8 msix_index,
812 u32 reply);
794void mpt2sas_scsih_issue_tm(struct MPT2SAS_ADAPTER *ioc, u16 handle, uint lun, 813void 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);
796void mpt2sas_scsih_set_tm_flag(struct MPT2SAS_ADAPTER *ioc, u16 handle); 815void 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
802struct _sas_device *mpt2sas_scsih_sas_device_find_by_sas_address( 821struct _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
805void mpt2sas_scsih_event_callback(struct MPT2SAS_ADAPTER *ioc, u8 msix_index,
806 u32 reply);
807void mpt2sas_scsih_reset_handler(struct MPT2SAS_ADAPTER *ioc, int reset_phase); 824void mpt2sas_scsih_reset_handler(struct MPT2SAS_ADAPTER *ioc, int reset_phase);
808 825
809/* config shared API */ 826/* config shared API */
810void mpt2sas_config_done(struct MPT2SAS_ADAPTER *ioc, u16 smid, u8 msix_index, 827u8 mpt2sas_config_done(struct MPT2SAS_ADAPTER *ioc, u16 smid, u8 msix_index,
811 u32 reply); 828 u32 reply);
812int mpt2sas_config_get_number_hba_phys(struct MPT2SAS_ADAPTER *ioc, u8 *num_phys); 829int mpt2sas_config_get_number_hba_phys(struct MPT2SAS_ADAPTER *ioc, u8 *num_phys);
813int mpt2sas_config_get_manufacturing_pg0(struct MPT2SAS_ADAPTER *ioc, 830int mpt2sas_config_get_manufacturing_pg0(struct MPT2SAS_ADAPTER *ioc,
@@ -861,17 +878,17 @@ extern struct device_attribute *mpt2sas_host_attrs[];
861extern struct device_attribute *mpt2sas_dev_attrs[]; 878extern struct device_attribute *mpt2sas_dev_attrs[];
862void mpt2sas_ctl_init(void); 879void mpt2sas_ctl_init(void);
863void mpt2sas_ctl_exit(void); 880void mpt2sas_ctl_exit(void);
864void mpt2sas_ctl_done(struct MPT2SAS_ADAPTER *ioc, u16 smid, u8 msix_index, 881u8 mpt2sas_ctl_done(struct MPT2SAS_ADAPTER *ioc, u16 smid, u8 msix_index,
865 u32 reply); 882 u32 reply);
866void mpt2sas_ctl_reset_handler(struct MPT2SAS_ADAPTER *ioc, int reset_phase); 883void mpt2sas_ctl_reset_handler(struct MPT2SAS_ADAPTER *ioc, int reset_phase);
867void mpt2sas_ctl_event_callback(struct MPT2SAS_ADAPTER *ioc, u8 msix_index, 884u8 mpt2sas_ctl_event_callback(struct MPT2SAS_ADAPTER *ioc, u8 msix_index,
868 u32 reply); 885 u32 reply);
869void mpt2sas_ctl_add_to_event_log(struct MPT2SAS_ADAPTER *ioc, 886void 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 */
873void mpt2sas_transport_done(struct MPT2SAS_ADAPTER *ioc, u16 smid, 890u8 mpt2sas_transport_done(struct MPT2SAS_ADAPTER *ioc, u16 smid, u8 msix_index,
874 u8 msix_index, u32 reply); 891 u32 reply);
875struct _sas_port *mpt2sas_transport_port_add(struct MPT2SAS_ADAPTER *ioc, 892struct _sas_port *mpt2sas_transport_port_add(struct MPT2SAS_ADAPTER *ioc,
876 u16 handle, u16 parent_handle); 893 u16 handle, u16 parent_handle);
877void mpt2sas_transport_port_remove(struct MPT2SAS_ADAPTER *ioc, u64 sas_address, 894void 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,
885extern struct sas_function_template mpt2sas_transport_functions; 902extern struct sas_function_template mpt2sas_transport_functions;
886extern struct scsi_transport_template *mpt2sas_transport_template; 903extern struct scsi_transport_template *mpt2sas_transport_template;
887extern int scsi_internal_device_block(struct scsi_device *sdev); 904extern int scsi_internal_device_block(struct scsi_device *sdev);
905extern u8 mpt2sas_stm_zero_smid_handler(struct MPT2SAS_ADAPTER *ioc,
906 u8 msix_index, u32 reply);
888extern int scsi_internal_device_unblock(struct scsi_device *sdev); 907extern 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 */
238void 239u8
239mpt2sas_config_done(struct MPT2SAS_ADAPTER *ioc, u16 smid, u8 msix_index, 240mpt2sas_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 */
230void 231u8
231mpt2sas_ctl_done(struct MPT2SAS_ADAPTER *ioc, u16 smid, u8 msix_index, 232mpt2sas_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 */
341void 344u8
342mpt2sas_ctl_event_callback(struct MPT2SAS_ADAPTER *ioc, u8 msix_index, 345mpt2sas_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;
79static u8 config_cb_idx = -1; 79static u8 config_cb_idx = -1;
80static int mpt_ids; 80static int mpt_ids;
81 81
82static u8 tm_tr_cb_idx = -1 ;
83static u8 tm_sas_control_cb_idx = -1;
84
82/* command line options */ 85/* command line options */
83static u32 logging_level; 86static u32 logging_level;
84MODULE_PARM_DESC(logging_level, " bits for enabling additional logging info " 87MODULE_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 */
1646static void 1650static 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 */
2334static 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 */
2415static 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 */
2463static 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 */
2922static void 3168static 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 */
5240void 5503u8
5241mpt2sas_scsih_event_callback(struct MPT2SAS_ADAPTER *ioc, u8 msix_index, 5504mpt2sas_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 */
223void 224u8
224mpt2sas_transport_done(struct MPT2SAS_ADAPTER *ioc, u16 smid, u8 msix_index, 225mpt2sas_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 */