diff options
author | Michael Reed <mdr@sgi.com> | 2009-04-08 15:34:33 -0400 |
---|---|---|
committer | James Bottomley <James.Bottomley@HansenPartnership.com> | 2009-05-20 18:21:13 -0400 |
commit | 413e6e18b483de272bdafa56e5c086c75f11d681 (patch) | |
tree | 89a61e76f63b3c5c0b51e3115b7e5eaef78f2893 /drivers/scsi/qla1280.c | |
parent | fd65e5e93cbd9d2f34bbb0f0b2f46a30a1d20915 (diff) |
[SCSI] qla1280: error recovery rewrite
The driver now waits for the scsi commands associated with a
particular error recovery step to be returned to the mid-layer,
and returns the appropriate SUCCESS or FAILED status. Removes
unneeded polling of chip for interrupts.
This patch also bumps the driver version number.
Signed-off-by: Michael Reed <mdr@sgi.com>
Signed-off-by: James Bottomley <James.Bottomley@HansenPartnership.com>
Diffstat (limited to 'drivers/scsi/qla1280.c')
-rw-r--r-- | drivers/scsi/qla1280.c | 290 |
1 files changed, 157 insertions, 133 deletions
diff --git a/drivers/scsi/qla1280.c b/drivers/scsi/qla1280.c index 0cbad4982db9..8371d917a9a2 100644 --- a/drivers/scsi/qla1280.c +++ b/drivers/scsi/qla1280.c | |||
@@ -17,9 +17,12 @@ | |||
17 | * General Public License for more details. | 17 | * General Public License for more details. |
18 | * | 18 | * |
19 | ******************************************************************************/ | 19 | ******************************************************************************/ |
20 | #define QLA1280_VERSION "3.26" | 20 | #define QLA1280_VERSION "3.27" |
21 | /***************************************************************************** | 21 | /***************************************************************************** |
22 | Revision History: | 22 | Revision History: |
23 | Rev 3.27, February 10, 2009, Michael Reed | ||
24 | - General code cleanup. | ||
25 | - Improve error recovery. | ||
23 | Rev 3.26, January 16, 2006 Jes Sorensen | 26 | Rev 3.26, January 16, 2006 Jes Sorensen |
24 | - Ditch all < 2.6 support | 27 | - Ditch all < 2.6 support |
25 | Rev 3.25.1, February 10, 2005 Christoph Hellwig | 28 | Rev 3.25.1, February 10, 2005 Christoph Hellwig |
@@ -718,6 +721,8 @@ qla1280_queuecommand(struct scsi_cmnd *cmd, void (*fn)(struct scsi_cmnd *)) | |||
718 | cmd->scsi_done = fn; | 721 | cmd->scsi_done = fn; |
719 | sp->cmd = cmd; | 722 | sp->cmd = cmd; |
720 | sp->flags = 0; | 723 | sp->flags = 0; |
724 | sp->wait = NULL; | ||
725 | CMD_HANDLE(cmd) = (unsigned char *)NULL; | ||
721 | 726 | ||
722 | qla1280_print_scsi_cmd(5, cmd); | 727 | qla1280_print_scsi_cmd(5, cmd); |
723 | 728 | ||
@@ -742,14 +747,6 @@ enum action { | |||
742 | ADAPTER_RESET, | 747 | ADAPTER_RESET, |
743 | }; | 748 | }; |
744 | 749 | ||
745 | /* timer action for error action processor */ | ||
746 | static void qla1280_error_wait_timeout(unsigned long __data) | ||
747 | { | ||
748 | struct scsi_cmnd *cmd = (struct scsi_cmnd *)__data; | ||
749 | struct srb *sp = (struct srb *)CMD_SP(cmd); | ||
750 | |||
751 | complete(sp->wait); | ||
752 | } | ||
753 | 750 | ||
754 | static void qla1280_mailbox_timeout(unsigned long __data) | 751 | static void qla1280_mailbox_timeout(unsigned long __data) |
755 | { | 752 | { |
@@ -764,6 +761,65 @@ static void qla1280_mailbox_timeout(unsigned long __data) | |||
764 | complete(ha->mailbox_wait); | 761 | complete(ha->mailbox_wait); |
765 | } | 762 | } |
766 | 763 | ||
764 | static int | ||
765 | _qla1280_wait_for_single_command(struct scsi_qla_host *ha, struct srb *sp, | ||
766 | struct completion *wait) | ||
767 | { | ||
768 | int status = FAILED; | ||
769 | struct scsi_cmnd *cmd = sp->cmd; | ||
770 | |||
771 | spin_unlock_irq(ha->host->host_lock); | ||
772 | wait_for_completion_timeout(wait, 4*HZ); | ||
773 | spin_lock_irq(ha->host->host_lock); | ||
774 | sp->wait = NULL; | ||
775 | if(CMD_HANDLE(cmd) == COMPLETED_HANDLE) { | ||
776 | status = SUCCESS; | ||
777 | (*cmd->scsi_done)(cmd); | ||
778 | } | ||
779 | return status; | ||
780 | } | ||
781 | |||
782 | static int | ||
783 | qla1280_wait_for_single_command(struct scsi_qla_host *ha, struct srb *sp) | ||
784 | { | ||
785 | DECLARE_COMPLETION_ONSTACK(wait); | ||
786 | |||
787 | sp->wait = &wait; | ||
788 | return _qla1280_wait_for_single_command(ha, sp, &wait); | ||
789 | } | ||
790 | |||
791 | static int | ||
792 | qla1280_wait_for_pending_commands(struct scsi_qla_host *ha, int bus, int target) | ||
793 | { | ||
794 | int cnt; | ||
795 | int status; | ||
796 | struct srb *sp; | ||
797 | struct scsi_cmnd *cmd; | ||
798 | |||
799 | status = SUCCESS; | ||
800 | |||
801 | /* | ||
802 | * Wait for all commands with the designated bus/target | ||
803 | * to be completed by the firmware | ||
804 | */ | ||
805 | for (cnt = 0; cnt < MAX_OUTSTANDING_COMMANDS; cnt++) { | ||
806 | sp = ha->outstanding_cmds[cnt]; | ||
807 | if (sp) { | ||
808 | cmd = sp->cmd; | ||
809 | |||
810 | if (bus >= 0 && SCSI_BUS_32(cmd) != bus) | ||
811 | continue; | ||
812 | if (target >= 0 && SCSI_TCN_32(cmd) != target) | ||
813 | continue; | ||
814 | |||
815 | status = qla1280_wait_for_single_command(ha, sp); | ||
816 | if (status == FAILED) | ||
817 | break; | ||
818 | } | ||
819 | } | ||
820 | return status; | ||
821 | } | ||
822 | |||
767 | /************************************************************************** | 823 | /************************************************************************** |
768 | * qla1280_error_action | 824 | * qla1280_error_action |
769 | * The function will attempt to perform a specified error action and | 825 | * The function will attempt to perform a specified error action and |
@@ -777,11 +833,6 @@ static void qla1280_mailbox_timeout(unsigned long __data) | |||
777 | * Returns: | 833 | * Returns: |
778 | * SUCCESS or FAILED | 834 | * SUCCESS or FAILED |
779 | * | 835 | * |
780 | * Note: | ||
781 | * Resetting the bus always succeeds - is has to, otherwise the | ||
782 | * kernel will panic! Try a surgical technique - sending a BUS | ||
783 | * DEVICE RESET message - on the offending target before pulling | ||
784 | * the SCSI bus reset line. | ||
785 | **************************************************************************/ | 836 | **************************************************************************/ |
786 | static int | 837 | static int |
787 | qla1280_error_action(struct scsi_cmnd *cmd, enum action action) | 838 | qla1280_error_action(struct scsi_cmnd *cmd, enum action action) |
@@ -789,15 +840,19 @@ qla1280_error_action(struct scsi_cmnd *cmd, enum action action) | |||
789 | struct scsi_qla_host *ha; | 840 | struct scsi_qla_host *ha; |
790 | int bus, target, lun; | 841 | int bus, target, lun; |
791 | struct srb *sp; | 842 | struct srb *sp; |
792 | uint16_t data; | 843 | int i, found; |
793 | unsigned char *handle; | 844 | int result=FAILED; |
794 | int result, i; | 845 | int wait_for_bus=-1; |
846 | int wait_for_target = -1; | ||
795 | DECLARE_COMPLETION_ONSTACK(wait); | 847 | DECLARE_COMPLETION_ONSTACK(wait); |
796 | struct timer_list timer; | ||
797 | 848 | ||
798 | ENTER("qla1280_error_action"); | 849 | ENTER("qla1280_error_action"); |
799 | 850 | ||
800 | ha = (struct scsi_qla_host *)(CMD_HOST(cmd)->hostdata); | 851 | ha = (struct scsi_qla_host *)(CMD_HOST(cmd)->hostdata); |
852 | sp = (struct srb *)CMD_SP(cmd); | ||
853 | bus = SCSI_BUS_32(cmd); | ||
854 | target = SCSI_TCN_32(cmd); | ||
855 | lun = SCSI_LUN_32(cmd); | ||
801 | 856 | ||
802 | dprintk(4, "error_action %i, istatus 0x%04x\n", action, | 857 | dprintk(4, "error_action %i, istatus 0x%04x\n", action, |
803 | RD_REG_WORD(&ha->iobase->istatus)); | 858 | RD_REG_WORD(&ha->iobase->istatus)); |
@@ -811,73 +866,42 @@ qla1280_error_action(struct scsi_cmnd *cmd, enum action action) | |||
811 | "Handle=0x%p, action=0x%x\n", | 866 | "Handle=0x%p, action=0x%x\n", |
812 | ha->host_no, cmd, CMD_HANDLE(cmd), action); | 867 | ha->host_no, cmd, CMD_HANDLE(cmd), action); |
813 | 868 | ||
814 | sp = (struct srb *)CMD_SP(cmd); | ||
815 | handle = CMD_HANDLE(cmd); | ||
816 | |||
817 | /* Check for pending interrupts. */ | ||
818 | data = qla1280_debounce_register(&ha->iobase->istatus); | ||
819 | /* | ||
820 | * The io_request_lock is held when the reset handler is called, hence | ||
821 | * the interrupt handler cannot be running in parallel as it also | ||
822 | * grabs the lock. /Jes | ||
823 | */ | ||
824 | if (data & RISC_INT) | ||
825 | qla1280_isr(ha, &ha->done_q); | ||
826 | |||
827 | /* | 869 | /* |
828 | * Determine the suggested action that the mid-level driver wants | 870 | * Check to see if we have the command in the outstanding_cmds[] |
829 | * us to perform. | 871 | * array. If not then it must have completed before this error |
872 | * action was initiated. If the error_action isn't ABORT_COMMAND | ||
873 | * then the driver must proceed with the requested action. | ||
830 | */ | 874 | */ |
831 | if (handle == (unsigned char *)INVALID_HANDLE || handle == NULL) { | 875 | found = -1; |
832 | if(action == ABORT_COMMAND) { | 876 | for (i = 0; i < MAX_OUTSTANDING_COMMANDS; i++) { |
833 | /* we never got this command */ | 877 | if (sp == ha->outstanding_cmds[i]) { |
834 | printk(KERN_INFO "qla1280: Aborting a NULL handle\n"); | 878 | found = i; |
835 | return SUCCESS; /* no action - we don't have command */ | 879 | sp->wait = &wait; /* we'll wait for it to complete */ |
880 | break; | ||
836 | } | 881 | } |
837 | } else { | ||
838 | sp->wait = &wait; | ||
839 | } | 882 | } |
840 | 883 | ||
841 | bus = SCSI_BUS_32(cmd); | 884 | if (found < 0) { /* driver doesn't have command */ |
842 | target = SCSI_TCN_32(cmd); | 885 | result = SUCCESS; |
843 | lun = SCSI_LUN_32(cmd); | 886 | if (qla1280_verbose) { |
887 | printk(KERN_INFO | ||
888 | "scsi(%ld:%d:%d:%d): specified command has " | ||
889 | "already completed.\n", ha->host_no, bus, | ||
890 | target, lun); | ||
891 | } | ||
892 | } | ||
844 | 893 | ||
845 | /* Overloading result. Here it means the success or fail of the | ||
846 | * *issue* of the action. When we return from the routine, it must | ||
847 | * mean the actual success or fail of the action */ | ||
848 | result = FAILED; | ||
849 | switch (action) { | 894 | switch (action) { |
850 | case ABORT_COMMAND: | ||
851 | if ((sp->flags & SRB_ABORT_PENDING)) { | ||
852 | printk(KERN_WARNING | ||
853 | "scsi(): Command has a pending abort " | ||
854 | "message - ABORT_PENDING.\n"); | ||
855 | /* This should technically be impossible since we | ||
856 | * now wait for abort completion */ | ||
857 | break; | ||
858 | } | ||
859 | 895 | ||
860 | for (i = 0; i < MAX_OUTSTANDING_COMMANDS; i++) { | 896 | case ABORT_COMMAND: |
861 | if (sp == ha->outstanding_cmds[i]) { | 897 | dprintk(1, "qla1280: RISC aborting command\n"); |
862 | dprintk(1, "qla1280: RISC aborting command\n"); | 898 | /* |
863 | if (qla1280_abort_command(ha, sp, i) == 0) | 899 | * The abort might fail due to race when the host_lock |
864 | result = SUCCESS; | 900 | * is released to issue the abort. As such, we |
865 | else { | 901 | * don't bother to check the return status. |
866 | /* | 902 | */ |
867 | * Since we don't know what might | 903 | if (found >= 0) |
868 | * have happend to the command, it | 904 | qla1280_abort_command(ha, sp, found); |
869 | * is unsafe to remove it from the | ||
870 | * device's queue at this point. | ||
871 | * Wait and let the escalation | ||
872 | * process take care of it. | ||
873 | */ | ||
874 | printk(KERN_WARNING | ||
875 | "scsi(%li:%i:%i:%i): Unable" | ||
876 | " to abort command!\n", | ||
877 | ha->host_no, bus, target, lun); | ||
878 | } | ||
879 | } | ||
880 | } | ||
881 | break; | 905 | break; |
882 | 906 | ||
883 | case DEVICE_RESET: | 907 | case DEVICE_RESET: |
@@ -885,16 +909,21 @@ qla1280_error_action(struct scsi_cmnd *cmd, enum action action) | |||
885 | printk(KERN_INFO | 909 | printk(KERN_INFO |
886 | "scsi(%ld:%d:%d:%d): Queueing device reset " | 910 | "scsi(%ld:%d:%d:%d): Queueing device reset " |
887 | "command.\n", ha->host_no, bus, target, lun); | 911 | "command.\n", ha->host_no, bus, target, lun); |
888 | if (qla1280_device_reset(ha, bus, target) == 0) | 912 | if (qla1280_device_reset(ha, bus, target) == 0) { |
889 | result = SUCCESS; | 913 | /* issued device reset, set wait conditions */ |
914 | wait_for_bus = bus; | ||
915 | wait_for_target = target; | ||
916 | } | ||
890 | break; | 917 | break; |
891 | 918 | ||
892 | case BUS_RESET: | 919 | case BUS_RESET: |
893 | if (qla1280_verbose) | 920 | if (qla1280_verbose) |
894 | printk(KERN_INFO "qla1280(%ld:%d): Issued bus " | 921 | printk(KERN_INFO "qla1280(%ld:%d): Issued bus " |
895 | "reset.\n", ha->host_no, bus); | 922 | "reset.\n", ha->host_no, bus); |
896 | if (qla1280_bus_reset(ha, bus) == 0) | 923 | if (qla1280_bus_reset(ha, bus) == 0) { |
897 | result = SUCCESS; | 924 | /* issued bus reset, set wait conditions */ |
925 | wait_for_bus = bus; | ||
926 | } | ||
898 | break; | 927 | break; |
899 | 928 | ||
900 | case ADAPTER_RESET: | 929 | case ADAPTER_RESET: |
@@ -907,55 +936,48 @@ qla1280_error_action(struct scsi_cmnd *cmd, enum action action) | |||
907 | "continue automatically\n", ha->host_no); | 936 | "continue automatically\n", ha->host_no); |
908 | } | 937 | } |
909 | ha->flags.reset_active = 1; | 938 | ha->flags.reset_active = 1; |
910 | /* | 939 | |
911 | * We restarted all of the commands automatically, so the | 940 | if (qla1280_abort_isp(ha) != 0) { /* it's dead */ |
912 | * mid-level code can expect completions momentitarily. | 941 | result = FAILED; |
913 | */ | 942 | } |
914 | if (qla1280_abort_isp(ha) == 0) | ||
915 | result = SUCCESS; | ||
916 | 943 | ||
917 | ha->flags.reset_active = 0; | 944 | ha->flags.reset_active = 0; |
918 | } | 945 | } |
919 | 946 | ||
920 | if (!list_empty(&ha->done_q)) | 947 | /* |
921 | qla1280_done(ha); | 948 | * At this point, the host_lock has been released and retaken |
922 | 949 | * by the issuance of the mailbox command. | |
923 | /* If we didn't manage to issue the action, or we have no | 950 | * Wait for the command passed in by the mid-layer if it |
924 | * command to wait for, exit here */ | 951 | * was found by the driver. It might have been returned |
925 | if (result == FAILED || handle == NULL || | 952 | * between eh recovery steps, hence the check of the "found" |
926 | handle == (unsigned char *)INVALID_HANDLE) { | 953 | * variable. |
927 | /* | 954 | */ |
928 | * Clear completion queue to avoid qla1280_done() trying | ||
929 | * to complete the command at a later stage after we | ||
930 | * have exited the current context | ||
931 | */ | ||
932 | sp->wait = NULL; | ||
933 | goto leave; | ||
934 | } | ||
935 | 955 | ||
936 | /* set up a timer just in case we're really jammed */ | 956 | if (found >= 0) |
937 | init_timer(&timer); | 957 | result = _qla1280_wait_for_single_command(ha, sp, &wait); |
938 | timer.expires = jiffies + 4*HZ; | ||
939 | timer.data = (unsigned long)cmd; | ||
940 | timer.function = qla1280_error_wait_timeout; | ||
941 | add_timer(&timer); | ||
942 | 958 | ||
943 | /* wait for the action to complete (or the timer to expire) */ | 959 | if (action == ABORT_COMMAND && result != SUCCESS) { |
944 | spin_unlock_irq(ha->host->host_lock); | 960 | printk(KERN_WARNING |
945 | wait_for_completion(&wait); | 961 | "scsi(%li:%i:%i:%i): " |
946 | del_timer_sync(&timer); | 962 | "Unable to abort command!\n", |
947 | spin_lock_irq(ha->host->host_lock); | 963 | ha->host_no, bus, target, lun); |
948 | sp->wait = NULL; | 964 | } |
949 | 965 | ||
950 | /* the only action we might get a fail for is abort */ | 966 | /* |
951 | if (action == ABORT_COMMAND) { | 967 | * If the command passed in by the mid-layer has been |
952 | if(sp->flags & SRB_ABORTED) | 968 | * returned by the board, then wait for any additional |
953 | result = SUCCESS; | 969 | * commands which are supposed to complete based upon |
954 | else | 970 | * the error action. |
955 | result = FAILED; | 971 | * |
972 | * All commands are unconditionally returned during a | ||
973 | * call to qla1280_abort_isp(), ADAPTER_RESET. No need | ||
974 | * to wait for them. | ||
975 | */ | ||
976 | if (result == SUCCESS && wait_for_bus >= 0) { | ||
977 | result = qla1280_wait_for_pending_commands(ha, | ||
978 | wait_for_bus, wait_for_target); | ||
956 | } | 979 | } |
957 | 980 | ||
958 | leave: | ||
959 | dprintk(1, "RESET returning %d\n", result); | 981 | dprintk(1, "RESET returning %d\n", result); |
960 | 982 | ||
961 | LEAVE("qla1280_error_action"); | 983 | LEAVE("qla1280_error_action"); |
@@ -1258,7 +1280,8 @@ qla1280_done(struct scsi_qla_host *ha) | |||
1258 | switch ((CMD_RESULT(cmd) >> 16)) { | 1280 | switch ((CMD_RESULT(cmd) >> 16)) { |
1259 | case DID_RESET: | 1281 | case DID_RESET: |
1260 | /* Issue marker command. */ | 1282 | /* Issue marker command. */ |
1261 | qla1280_marker(ha, bus, target, 0, MK_SYNC_ID); | 1283 | if (!ha->flags.abort_isp_active) |
1284 | qla1280_marker(ha, bus, target, 0, MK_SYNC_ID); | ||
1262 | break; | 1285 | break; |
1263 | case DID_ABORT: | 1286 | case DID_ABORT: |
1264 | sp->flags &= ~SRB_ABORT_PENDING; | 1287 | sp->flags &= ~SRB_ABORT_PENDING; |
@@ -1272,12 +1295,11 @@ qla1280_done(struct scsi_qla_host *ha) | |||
1272 | scsi_dma_unmap(cmd); | 1295 | scsi_dma_unmap(cmd); |
1273 | 1296 | ||
1274 | /* Call the mid-level driver interrupt handler */ | 1297 | /* Call the mid-level driver interrupt handler */ |
1275 | CMD_HANDLE(sp->cmd) = (unsigned char *)INVALID_HANDLE; | ||
1276 | ha->actthreads--; | 1298 | ha->actthreads--; |
1277 | 1299 | ||
1278 | (*(cmd)->scsi_done)(cmd); | 1300 | if (sp->wait == NULL) |
1279 | 1301 | (*(cmd)->scsi_done)(cmd); | |
1280 | if(sp->wait != NULL) | 1302 | else |
1281 | complete(sp->wait); | 1303 | complete(sp->wait); |
1282 | } | 1304 | } |
1283 | LEAVE("qla1280_done"); | 1305 | LEAVE("qla1280_done"); |
@@ -3415,6 +3437,7 @@ qla1280_isr(struct scsi_qla_host *ha, struct list_head *done_q) | |||
3415 | 3437 | ||
3416 | /* Save ISP completion status */ | 3438 | /* Save ISP completion status */ |
3417 | CMD_RESULT(sp->cmd) = 0; | 3439 | CMD_RESULT(sp->cmd) = 0; |
3440 | CMD_HANDLE(sp->cmd) = COMPLETED_HANDLE; | ||
3418 | 3441 | ||
3419 | /* Place block on done queue */ | 3442 | /* Place block on done queue */ |
3420 | list_add_tail(&sp->list, done_q); | 3443 | list_add_tail(&sp->list, done_q); |
@@ -3681,6 +3704,8 @@ qla1280_status_entry(struct scsi_qla_host *ha, struct response *pkt, | |||
3681 | } | 3704 | } |
3682 | } | 3705 | } |
3683 | 3706 | ||
3707 | CMD_HANDLE(sp->cmd) = COMPLETED_HANDLE; | ||
3708 | |||
3684 | /* Place command on done queue. */ | 3709 | /* Place command on done queue. */ |
3685 | list_add_tail(&sp->list, done_q); | 3710 | list_add_tail(&sp->list, done_q); |
3686 | out: | 3711 | out: |
@@ -3736,6 +3761,8 @@ qla1280_error_entry(struct scsi_qla_host *ha, struct response *pkt, | |||
3736 | CMD_RESULT(sp->cmd) = DID_ERROR << 16; | 3761 | CMD_RESULT(sp->cmd) = DID_ERROR << 16; |
3737 | } | 3762 | } |
3738 | 3763 | ||
3764 | CMD_HANDLE(sp->cmd) = COMPLETED_HANDLE; | ||
3765 | |||
3739 | /* Place command on done queue. */ | 3766 | /* Place command on done queue. */ |
3740 | list_add_tail(&sp->list, done_q); | 3767 | list_add_tail(&sp->list, done_q); |
3741 | } | 3768 | } |
@@ -3786,19 +3813,16 @@ qla1280_abort_isp(struct scsi_qla_host *ha) | |||
3786 | struct scsi_cmnd *cmd; | 3813 | struct scsi_cmnd *cmd; |
3787 | sp = ha->outstanding_cmds[cnt]; | 3814 | sp = ha->outstanding_cmds[cnt]; |
3788 | if (sp) { | 3815 | if (sp) { |
3789 | |||
3790 | cmd = sp->cmd; | 3816 | cmd = sp->cmd; |
3791 | CMD_RESULT(cmd) = DID_RESET << 16; | 3817 | CMD_RESULT(cmd) = DID_RESET << 16; |
3792 | 3818 | CMD_HANDLE(cmd) = COMPLETED_HANDLE; | |
3793 | sp->cmd = NULL; | ||
3794 | ha->outstanding_cmds[cnt] = NULL; | 3819 | ha->outstanding_cmds[cnt] = NULL; |
3795 | 3820 | list_add_tail(&sp->list, &ha->done_q); | |
3796 | (*cmd->scsi_done)(cmd); | ||
3797 | |||
3798 | sp->flags = 0; | ||
3799 | } | 3821 | } |
3800 | } | 3822 | } |
3801 | 3823 | ||
3824 | qla1280_done(ha); | ||
3825 | |||
3802 | status = qla1280_load_firmware(ha); | 3826 | status = qla1280_load_firmware(ha); |
3803 | if (status) | 3827 | if (status) |
3804 | goto out; | 3828 | goto out; |