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 /drivers/scsi/mpt2sas/mpt2sas_base.c | |
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>
Diffstat (limited to 'drivers/scsi/mpt2sas/mpt2sas_base.c')
-rw-r--r-- | drivers/scsi/mpt2sas/mpt2sas_base.c | 35 |
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 | */ |
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); |