aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/scsi/mpt2sas/mpt2sas_base.c
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/scsi/mpt2sas/mpt2sas_base.c
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/scsi/mpt2sas/mpt2sas_base.c')
-rw-r--r--drivers/scsi/mpt2sas/mpt2sas_base.c35
1 files changed, 25 insertions, 10 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);