aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/scsi/qla2xxx/qla_os.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/scsi/qla2xxx/qla_os.c')
-rw-r--r--drivers/scsi/qla2xxx/qla_os.c443
1 files changed, 217 insertions, 226 deletions
diff --git a/drivers/scsi/qla2xxx/qla_os.c b/drivers/scsi/qla2xxx/qla_os.c
index 3c1b43356adb..8b33b163b1d4 100644
--- a/drivers/scsi/qla2xxx/qla_os.c
+++ b/drivers/scsi/qla2xxx/qla_os.c
@@ -1,6 +1,6 @@
1/* 1/*
2 * QLogic Fibre Channel HBA Driver 2 * QLogic Fibre Channel HBA Driver
3 * Copyright (c) 2003-2005 QLogic Corporation 3 * Copyright (c) 2003-2008 QLogic Corporation
4 * 4 *
5 * See LICENSE.qla2xxx for copyright and licensing details. 5 * See LICENSE.qla2xxx for copyright and licensing details.
6 */ 6 */
@@ -26,9 +26,6 @@ char qla2x00_version_str[40];
26 */ 26 */
27static struct kmem_cache *srb_cachep; 27static struct kmem_cache *srb_cachep;
28 28
29/*
30 * Ioctl related information.
31 */
32int num_hosts; 29int num_hosts;
33int ql2xlogintimeout = 20; 30int ql2xlogintimeout = 20;
34module_param(ql2xlogintimeout, int, S_IRUGO|S_IRUSR); 31module_param(ql2xlogintimeout, int, S_IRUGO|S_IRUSR);
@@ -103,9 +100,9 @@ static int qla24xx_queuecommand(struct scsi_cmnd *cmd,
103 void (*fn)(struct scsi_cmnd *)); 100 void (*fn)(struct scsi_cmnd *));
104static int qla2xxx_eh_abort(struct scsi_cmnd *); 101static int qla2xxx_eh_abort(struct scsi_cmnd *);
105static int qla2xxx_eh_device_reset(struct scsi_cmnd *); 102static int qla2xxx_eh_device_reset(struct scsi_cmnd *);
103static int qla2xxx_eh_target_reset(struct scsi_cmnd *);
106static int qla2xxx_eh_bus_reset(struct scsi_cmnd *); 104static int qla2xxx_eh_bus_reset(struct scsi_cmnd *);
107static int qla2xxx_eh_host_reset(struct scsi_cmnd *); 105static int qla2xxx_eh_host_reset(struct scsi_cmnd *);
108static int qla2x00_device_reset(scsi_qla_host_t *, fc_port_t *);
109 106
110static int qla2x00_change_queue_depth(struct scsi_device *, int); 107static int qla2x00_change_queue_depth(struct scsi_device *, int);
111static int qla2x00_change_queue_type(struct scsi_device *, int); 108static int qla2x00_change_queue_type(struct scsi_device *, int);
@@ -117,6 +114,7 @@ static struct scsi_host_template qla2x00_driver_template = {
117 114
118 .eh_abort_handler = qla2xxx_eh_abort, 115 .eh_abort_handler = qla2xxx_eh_abort,
119 .eh_device_reset_handler = qla2xxx_eh_device_reset, 116 .eh_device_reset_handler = qla2xxx_eh_device_reset,
117 .eh_target_reset_handler = qla2xxx_eh_target_reset,
120 .eh_bus_reset_handler = qla2xxx_eh_bus_reset, 118 .eh_bus_reset_handler = qla2xxx_eh_bus_reset,
121 .eh_host_reset_handler = qla2xxx_eh_host_reset, 119 .eh_host_reset_handler = qla2xxx_eh_host_reset,
122 120
@@ -148,6 +146,7 @@ struct scsi_host_template qla24xx_driver_template = {
148 146
149 .eh_abort_handler = qla2xxx_eh_abort, 147 .eh_abort_handler = qla2xxx_eh_abort,
150 .eh_device_reset_handler = qla2xxx_eh_device_reset, 148 .eh_device_reset_handler = qla2xxx_eh_device_reset,
149 .eh_target_reset_handler = qla2xxx_eh_target_reset,
151 .eh_bus_reset_handler = qla2xxx_eh_bus_reset, 150 .eh_bus_reset_handler = qla2xxx_eh_bus_reset,
152 .eh_host_reset_handler = qla2xxx_eh_host_reset, 151 .eh_host_reset_handler = qla2xxx_eh_host_reset,
153 152
@@ -253,9 +252,9 @@ qla24xx_pci_info_str(struct scsi_qla_host *ha, char *str)
253 252
254 strcpy(str, "PCIe ("); 253 strcpy(str, "PCIe (");
255 if (lspeed == 1) 254 if (lspeed == 1)
256 strcat(str, "2.5Gb/s "); 255 strcat(str, "2.5GT/s ");
257 else if (lspeed == 2) 256 else if (lspeed == 2)
258 strcat(str, "5.0Gb/s "); 257 strcat(str, "5.0GT/s ");
259 else 258 else
260 strcat(str, "<unknown> "); 259 strcat(str, "<unknown> ");
261 snprintf(lwstr, sizeof(lwstr), "x%d)", lwidth); 260 snprintf(lwstr, sizeof(lwstr), "x%d)", lwidth);
@@ -340,6 +339,8 @@ qla24xx_fw_version_str(struct scsi_qla_host *ha, char *str)
340 strcat(str, "[T10 CRC] "); 339 strcat(str, "[T10 CRC] ");
341 if (ha->fw_attributes & BIT_5) 340 if (ha->fw_attributes & BIT_5)
342 strcat(str, "[VI] "); 341 strcat(str, "[VI] ");
342 if (ha->fw_attributes & BIT_10)
343 strcat(str, "[84XX] ");
343 if (ha->fw_attributes & BIT_13) 344 if (ha->fw_attributes & BIT_13)
344 strcat(str, "[Experimental]"); 345 strcat(str, "[Experimental]");
345 return str; 346 return str;
@@ -570,8 +571,6 @@ qla2x00_wait_for_hba_online(scsi_qla_host_t *ha)
570 else 571 else
571 return_status = QLA_FUNCTION_FAILED; 572 return_status = QLA_FUNCTION_FAILED;
572 573
573 DEBUG2(printk("%s return_status=%d\n",__func__,return_status));
574
575 return (return_status); 574 return (return_status);
576} 575}
577 576
@@ -685,7 +684,6 @@ qla2xxx_eh_abort(struct scsi_cmnd *cmd)
685 684
686 DEBUG2(printk("%s(%ld): aborting sp %p from RISC. pid=%ld.\n", 685 DEBUG2(printk("%s(%ld): aborting sp %p from RISC. pid=%ld.\n",
687 __func__, ha->host_no, sp, serial)); 686 __func__, ha->host_no, sp, serial));
688 DEBUG3(qla2x00_print_scsi_cmd(cmd));
689 687
690 spin_unlock_irqrestore(&pha->hardware_lock, flags); 688 spin_unlock_irqrestore(&pha->hardware_lock, flags);
691 if (ha->isp_ops->abort_command(ha, sp)) { 689 if (ha->isp_ops->abort_command(ha, sp)) {
@@ -719,190 +717,122 @@ qla2xxx_eh_abort(struct scsi_cmnd *cmd)
719 return ret; 717 return ret;
720} 718}
721 719
722/************************************************************************** 720enum nexus_wait_type {
723* qla2x00_eh_wait_for_pending_target_commands 721 WAIT_HOST = 0,
724* 722 WAIT_TARGET,
725* Description: 723 WAIT_LUN,
726* Waits for all the commands to come back from the specified target. 724};
727* 725
728* Input:
729* ha - pointer to scsi_qla_host structure.
730* t - target
731* Returns:
732* Either SUCCESS or FAILED.
733*
734* Note:
735**************************************************************************/
736static int 726static int
737qla2x00_eh_wait_for_pending_target_commands(scsi_qla_host_t *ha, unsigned int t) 727qla2x00_eh_wait_for_pending_commands(scsi_qla_host_t *ha, unsigned int t,
728 unsigned int l, enum nexus_wait_type type)
738{ 729{
739 int cnt; 730 int cnt, match, status;
740 int status; 731 srb_t *sp;
741 srb_t *sp;
742 struct scsi_cmnd *cmd;
743 unsigned long flags; 732 unsigned long flags;
744 scsi_qla_host_t *pha = to_qla_parent(ha); 733 scsi_qla_host_t *pha = to_qla_parent(ha);
745 734
746 status = 0; 735 status = QLA_SUCCESS;
747 736 spin_lock_irqsave(&pha->hardware_lock, flags);
748 /* 737 for (cnt = 1; status == QLA_SUCCESS && cnt < MAX_OUTSTANDING_COMMANDS;
749 * Waiting for all commands for the designated target in the active 738 cnt++) {
750 * array
751 */
752 for (cnt = 1; cnt < MAX_OUTSTANDING_COMMANDS; cnt++) {
753 spin_lock_irqsave(&pha->hardware_lock, flags);
754 sp = pha->outstanding_cmds[cnt]; 739 sp = pha->outstanding_cmds[cnt];
755 if (sp) { 740 if (!sp)
756 cmd = sp->cmd; 741 continue;
757 spin_unlock_irqrestore(&pha->hardware_lock, flags); 742 if (ha->vp_idx != sp->ha->vp_idx)
758 if (cmd->device->id == t && 743 continue;
759 ha->vp_idx == sp->ha->vp_idx) { 744 match = 0;
760 if (!qla2x00_eh_wait_on_command(ha, cmd)) { 745 switch (type) {
761 status = 1; 746 case WAIT_HOST:
762 break; 747 match = 1;
763 } 748 break;
764 } 749 case WAIT_TARGET:
765 } else { 750 match = sp->cmd->device->id == t;
766 spin_unlock_irqrestore(&pha->hardware_lock, flags); 751 break;
752 case WAIT_LUN:
753 match = (sp->cmd->device->id == t &&
754 sp->cmd->device->lun == l);
755 break;
767 } 756 }
757 if (!match)
758 continue;
759
760 spin_unlock_irqrestore(&pha->hardware_lock, flags);
761 status = qla2x00_eh_wait_on_command(ha, sp->cmd);
762 spin_lock_irqsave(&pha->hardware_lock, flags);
768 } 763 }
769 return (status); 764 spin_unlock_irqrestore(&pha->hardware_lock, flags);
765
766 return status;
770} 767}
771 768
769static char *reset_errors[] = {
770 "HBA not online",
771 "HBA not ready",
772 "Task management failed",
773 "Waiting for command completions",
774};
772 775
773/**************************************************************************
774* qla2xxx_eh_device_reset
775*
776* Description:
777* The device reset function will reset the target and abort any
778* executing commands.
779*
780* NOTE: The use of SP is undefined within this context. Do *NOT*
781* attempt to use this value, even if you determine it is
782* non-null.
783*
784* Input:
785* cmd = Linux SCSI command packet of the command that cause the
786* bus device reset.
787*
788* Returns:
789* SUCCESS/FAILURE (defined as macro in scsi.h).
790*
791**************************************************************************/
792static int 776static int
793qla2xxx_eh_device_reset(struct scsi_cmnd *cmd) 777__qla2xxx_eh_generic_reset(char *name, enum nexus_wait_type type,
778 struct scsi_cmnd *cmd, int (*do_reset)(struct fc_port *, unsigned int))
794{ 779{
795 scsi_qla_host_t *ha = shost_priv(cmd->device->host); 780 scsi_qla_host_t *ha = shost_priv(cmd->device->host);
796 fc_port_t *fcport = (struct fc_port *) cmd->device->hostdata; 781 fc_port_t *fcport = (struct fc_port *) cmd->device->hostdata;
797 int ret = FAILED; 782 int err;
798 unsigned int id, lun;
799 unsigned long serial;
800 783
801 qla2x00_block_error_handler(cmd); 784 qla2x00_block_error_handler(cmd);
802 785
803 id = cmd->device->id;
804 lun = cmd->device->lun;
805 serial = cmd->serial_number;
806
807 if (!fcport) 786 if (!fcport)
808 return ret; 787 return FAILED;
809 788
810 qla_printk(KERN_INFO, ha, 789 qla_printk(KERN_INFO, ha, "scsi(%ld:%d:%d): %s RESET ISSUED.\n",
811 "scsi(%ld:%d:%d): DEVICE RESET ISSUED.\n", ha->host_no, id, lun); 790 ha->host_no, cmd->device->id, cmd->device->lun, name);
812 791
792 err = 0;
813 if (qla2x00_wait_for_hba_online(ha) != QLA_SUCCESS) 793 if (qla2x00_wait_for_hba_online(ha) != QLA_SUCCESS)
814 goto eh_dev_reset_done; 794 goto eh_reset_failed;
815 795 err = 1;
816 if (qla2x00_wait_for_loop_ready(ha) == QLA_SUCCESS) { 796 if (qla2x00_wait_for_loop_ready(ha) != QLA_SUCCESS)
817 if (qla2x00_device_reset(ha, fcport) == 0) 797 goto eh_reset_failed;
818 ret = SUCCESS; 798 err = 2;
819 799 if (do_reset(fcport, cmd->device->lun) != QLA_SUCCESS)
820#if defined(LOGOUT_AFTER_DEVICE_RESET) 800 goto eh_reset_failed;
821 if (ret == SUCCESS) { 801 err = 3;
822 if (fcport->flags & FC_FABRIC_DEVICE) { 802 if (qla2x00_eh_wait_for_pending_commands(ha, cmd->device->id,
823 ha->isp_ops->fabric_logout(ha, fcport->loop_id); 803 cmd->device->lun, type) != QLA_SUCCESS)
824 qla2x00_mark_device_lost(ha, fcport, 0, 0); 804 goto eh_reset_failed;
825 } 805
826 } 806 qla_printk(KERN_INFO, ha, "scsi(%ld:%d:%d): %s RESET SUCCEEDED.\n",
827#endif 807 ha->host_no, cmd->device->id, cmd->device->lun, name);
828 } else { 808
829 DEBUG2(printk(KERN_INFO 809 return SUCCESS;
830 "%s failed: loop not ready\n",__func__)); 810
831 } 811 eh_reset_failed:
832 812 qla_printk(KERN_INFO, ha, "scsi(%ld:%d:%d): %s RESET FAILED: %s.\n",
833 if (ret == FAILED) { 813 ha->host_no, cmd->device->id, cmd->device->lun, name,
834 DEBUG3(printk("%s(%ld): device reset failed\n", 814 reset_errors[err]);
835 __func__, ha->host_no)); 815 return FAILED;
836 qla_printk(KERN_INFO, ha, "%s: device reset failed\n", 816}
837 __func__);
838 817
839 goto eh_dev_reset_done; 818static int
840 } 819qla2xxx_eh_device_reset(struct scsi_cmnd *cmd)
820{
821 scsi_qla_host_t *ha = shost_priv(cmd->device->host);
841 822
842 /* Flush outstanding commands. */ 823 return __qla2xxx_eh_generic_reset("DEVICE", WAIT_LUN, cmd,
843 if (qla2x00_eh_wait_for_pending_target_commands(ha, id)) 824 ha->isp_ops->lun_reset);
844 ret = FAILED;
845 if (ret == FAILED) {
846 DEBUG3(printk("%s(%ld): failed while waiting for commands\n",
847 __func__, ha->host_no));
848 qla_printk(KERN_INFO, ha,
849 "%s: failed while waiting for commands\n", __func__);
850 } else
851 qla_printk(KERN_INFO, ha,
852 "scsi(%ld:%d:%d): DEVICE RESET SUCCEEDED.\n", ha->host_no,
853 id, lun);
854 eh_dev_reset_done:
855 return ret;
856} 825}
857 826
858/**************************************************************************
859* qla2x00_eh_wait_for_pending_commands
860*
861* Description:
862* Waits for all the commands to come back from the specified host.
863*
864* Input:
865* ha - pointer to scsi_qla_host structure.
866*
867* Returns:
868* 1 : SUCCESS
869* 0 : FAILED
870*
871* Note:
872**************************************************************************/
873static int 827static int
874qla2x00_eh_wait_for_pending_commands(scsi_qla_host_t *ha) 828qla2xxx_eh_target_reset(struct scsi_cmnd *cmd)
875{ 829{
876 int cnt; 830 scsi_qla_host_t *ha = shost_priv(cmd->device->host);
877 int status;
878 srb_t *sp;
879 struct scsi_cmnd *cmd;
880 unsigned long flags;
881
882 status = 1;
883 831
884 /* 832 return __qla2xxx_eh_generic_reset("TARGET", WAIT_TARGET, cmd,
885 * Waiting for all commands for the designated target in the active 833 ha->isp_ops->target_reset);
886 * array
887 */
888 for (cnt = 1; cnt < MAX_OUTSTANDING_COMMANDS; cnt++) {
889 spin_lock_irqsave(&ha->hardware_lock, flags);
890 sp = ha->outstanding_cmds[cnt];
891 if (sp) {
892 cmd = sp->cmd;
893 spin_unlock_irqrestore(&ha->hardware_lock, flags);
894 status = qla2x00_eh_wait_on_command(ha, cmd);
895 if (status == 0)
896 break;
897 }
898 else {
899 spin_unlock_irqrestore(&ha->hardware_lock, flags);
900 }
901 }
902 return (status);
903} 834}
904 835
905
906/************************************************************************** 836/**************************************************************************
907* qla2xxx_eh_bus_reset 837* qla2xxx_eh_bus_reset
908* 838*
@@ -953,7 +883,8 @@ qla2xxx_eh_bus_reset(struct scsi_cmnd *cmd)
953 goto eh_bus_reset_done; 883 goto eh_bus_reset_done;
954 884
955 /* Flush outstanding commands. */ 885 /* Flush outstanding commands. */
956 if (!qla2x00_eh_wait_for_pending_commands(pha)) 886 if (qla2x00_eh_wait_for_pending_commands(pha, 0, 0, WAIT_HOST) !=
887 QLA_SUCCESS)
957 ret = FAILED; 888 ret = FAILED;
958 889
959eh_bus_reset_done: 890eh_bus_reset_done:
@@ -1024,7 +955,8 @@ qla2xxx_eh_host_reset(struct scsi_cmnd *cmd)
1024 clear_bit(ABORT_ISP_ACTIVE, &pha->dpc_flags); 955 clear_bit(ABORT_ISP_ACTIVE, &pha->dpc_flags);
1025 956
1026 /* Waiting for our command in done_queue to be returned to OS.*/ 957 /* Waiting for our command in done_queue to be returned to OS.*/
1027 if (qla2x00_eh_wait_for_pending_commands(pha)) 958 if (qla2x00_eh_wait_for_pending_commands(pha, 0, 0, WAIT_HOST) ==
959 QLA_SUCCESS)
1028 ret = SUCCESS; 960 ret = SUCCESS;
1029 961
1030 if (ha->parent) 962 if (ha->parent)
@@ -1080,7 +1012,7 @@ qla2x00_loop_reset(scsi_qla_host_t *ha)
1080 if (fcport->port_type != FCT_TARGET) 1012 if (fcport->port_type != FCT_TARGET)
1081 continue; 1013 continue;
1082 1014
1083 ret = qla2x00_device_reset(ha, fcport); 1015 ret = ha->isp_ops->target_reset(fcport, 0);
1084 if (ret != QLA_SUCCESS) { 1016 if (ret != QLA_SUCCESS) {
1085 DEBUG2_3(printk("%s(%ld): bus_reset failed: " 1017 DEBUG2_3(printk("%s(%ld): bus_reset failed: "
1086 "target_reset=%d d_id=%x.\n", __func__, 1018 "target_reset=%d d_id=%x.\n", __func__,
@@ -1095,26 +1027,6 @@ qla2x00_loop_reset(scsi_qla_host_t *ha)
1095 return QLA_SUCCESS; 1027 return QLA_SUCCESS;
1096} 1028}
1097 1029
1098/*
1099 * qla2x00_device_reset
1100 * Issue bus device reset message to the target.
1101 *
1102 * Input:
1103 * ha = adapter block pointer.
1104 * t = SCSI ID.
1105 * TARGET_QUEUE_LOCK must be released.
1106 * ADAPTER_STATE_LOCK must be released.
1107 *
1108 * Context:
1109 * Kernel context.
1110 */
1111static int
1112qla2x00_device_reset(scsi_qla_host_t *ha, fc_port_t *reset_fcport)
1113{
1114 /* Abort Target command will clear Reservation */
1115 return ha->isp_ops->abort_target(reset_fcport);
1116}
1117
1118void 1030void
1119qla2x00_abort_all_cmds(scsi_qla_host_t *ha, int res) 1031qla2x00_abort_all_cmds(scsi_qla_host_t *ha, int res)
1120{ 1032{
@@ -1292,7 +1204,8 @@ static struct isp_operations qla2100_isp_ops = {
1292 .enable_intrs = qla2x00_enable_intrs, 1204 .enable_intrs = qla2x00_enable_intrs,
1293 .disable_intrs = qla2x00_disable_intrs, 1205 .disable_intrs = qla2x00_disable_intrs,
1294 .abort_command = qla2x00_abort_command, 1206 .abort_command = qla2x00_abort_command,
1295 .abort_target = qla2x00_abort_target, 1207 .target_reset = qla2x00_abort_target,
1208 .lun_reset = qla2x00_lun_reset,
1296 .fabric_login = qla2x00_login_fabric, 1209 .fabric_login = qla2x00_login_fabric,
1297 .fabric_logout = qla2x00_fabric_logout, 1210 .fabric_logout = qla2x00_fabric_logout,
1298 .calc_req_entries = qla2x00_calc_iocbs_32, 1211 .calc_req_entries = qla2x00_calc_iocbs_32,
@@ -1325,7 +1238,8 @@ static struct isp_operations qla2300_isp_ops = {
1325 .enable_intrs = qla2x00_enable_intrs, 1238 .enable_intrs = qla2x00_enable_intrs,
1326 .disable_intrs = qla2x00_disable_intrs, 1239 .disable_intrs = qla2x00_disable_intrs,
1327 .abort_command = qla2x00_abort_command, 1240 .abort_command = qla2x00_abort_command,
1328 .abort_target = qla2x00_abort_target, 1241 .target_reset = qla2x00_abort_target,
1242 .lun_reset = qla2x00_lun_reset,
1329 .fabric_login = qla2x00_login_fabric, 1243 .fabric_login = qla2x00_login_fabric,
1330 .fabric_logout = qla2x00_fabric_logout, 1244 .fabric_logout = qla2x00_fabric_logout,
1331 .calc_req_entries = qla2x00_calc_iocbs_32, 1245 .calc_req_entries = qla2x00_calc_iocbs_32,
@@ -1358,7 +1272,8 @@ static struct isp_operations qla24xx_isp_ops = {
1358 .enable_intrs = qla24xx_enable_intrs, 1272 .enable_intrs = qla24xx_enable_intrs,
1359 .disable_intrs = qla24xx_disable_intrs, 1273 .disable_intrs = qla24xx_disable_intrs,
1360 .abort_command = qla24xx_abort_command, 1274 .abort_command = qla24xx_abort_command,
1361 .abort_target = qla24xx_abort_target, 1275 .target_reset = qla24xx_abort_target,
1276 .lun_reset = qla24xx_lun_reset,
1362 .fabric_login = qla24xx_login_fabric, 1277 .fabric_login = qla24xx_login_fabric,
1363 .fabric_logout = qla24xx_fabric_logout, 1278 .fabric_logout = qla24xx_fabric_logout,
1364 .calc_req_entries = NULL, 1279 .calc_req_entries = NULL,
@@ -1391,7 +1306,8 @@ static struct isp_operations qla25xx_isp_ops = {
1391 .enable_intrs = qla24xx_enable_intrs, 1306 .enable_intrs = qla24xx_enable_intrs,
1392 .disable_intrs = qla24xx_disable_intrs, 1307 .disable_intrs = qla24xx_disable_intrs,
1393 .abort_command = qla24xx_abort_command, 1308 .abort_command = qla24xx_abort_command,
1394 .abort_target = qla24xx_abort_target, 1309 .target_reset = qla24xx_abort_target,
1310 .lun_reset = qla24xx_lun_reset,
1395 .fabric_login = qla24xx_login_fabric, 1311 .fabric_login = qla24xx_login_fabric,
1396 .fabric_logout = qla24xx_fabric_logout, 1312 .fabric_logout = qla24xx_fabric_logout,
1397 .calc_req_entries = NULL, 1313 .calc_req_entries = NULL,
@@ -1464,6 +1380,13 @@ qla2x00_set_isp_flags(scsi_qla_host_t *ha)
1464 ha->device_type |= DT_IIDMA; 1380 ha->device_type |= DT_IIDMA;
1465 ha->fw_srisc_address = RISC_START_ADDRESS_2400; 1381 ha->fw_srisc_address = RISC_START_ADDRESS_2400;
1466 break; 1382 break;
1383 case PCI_DEVICE_ID_QLOGIC_ISP8432:
1384 ha->device_type |= DT_ISP8432;
1385 ha->device_type |= DT_ZIO_SUPPORTED;
1386 ha->device_type |= DT_FWI2;
1387 ha->device_type |= DT_IIDMA;
1388 ha->fw_srisc_address = RISC_START_ADDRESS_2400;
1389 break;
1467 case PCI_DEVICE_ID_QLOGIC_ISP5422: 1390 case PCI_DEVICE_ID_QLOGIC_ISP5422:
1468 ha->device_type |= DT_ISP5422; 1391 ha->device_type |= DT_ISP5422;
1469 ha->device_type |= DT_FWI2; 1392 ha->device_type |= DT_FWI2;
@@ -1587,6 +1510,7 @@ qla2x00_probe_one(struct pci_dev *pdev, const struct pci_device_id *id)
1587 sht = &qla2x00_driver_template; 1510 sht = &qla2x00_driver_template;
1588 if (pdev->device == PCI_DEVICE_ID_QLOGIC_ISP2422 || 1511 if (pdev->device == PCI_DEVICE_ID_QLOGIC_ISP2422 ||
1589 pdev->device == PCI_DEVICE_ID_QLOGIC_ISP2432 || 1512 pdev->device == PCI_DEVICE_ID_QLOGIC_ISP2432 ||
1513 pdev->device == PCI_DEVICE_ID_QLOGIC_ISP8432 ||
1590 pdev->device == PCI_DEVICE_ID_QLOGIC_ISP5422 || 1514 pdev->device == PCI_DEVICE_ID_QLOGIC_ISP5422 ||
1591 pdev->device == PCI_DEVICE_ID_QLOGIC_ISP5432 || 1515 pdev->device == PCI_DEVICE_ID_QLOGIC_ISP5432 ||
1592 pdev->device == PCI_DEVICE_ID_QLOGIC_ISP2532) { 1516 pdev->device == PCI_DEVICE_ID_QLOGIC_ISP2532) {
@@ -1677,7 +1601,7 @@ qla2x00_probe_one(struct pci_dev *pdev, const struct pci_device_id *id)
1677 if (IS_QLA2322(ha) || IS_QLA6322(ha)) 1601 if (IS_QLA2322(ha) || IS_QLA6322(ha))
1678 ha->optrom_size = OPTROM_SIZE_2322; 1602 ha->optrom_size = OPTROM_SIZE_2322;
1679 ha->isp_ops = &qla2300_isp_ops; 1603 ha->isp_ops = &qla2300_isp_ops;
1680 } else if (IS_QLA24XX(ha) || IS_QLA54XX(ha)) { 1604 } else if (IS_QLA24XX_TYPE(ha)) {
1681 host->max_id = MAX_TARGETS_2200; 1605 host->max_id = MAX_TARGETS_2200;
1682 ha->mbx_count = MAILBOX_REGISTER_COUNT; 1606 ha->mbx_count = MAILBOX_REGISTER_COUNT;
1683 ha->request_q_length = REQUEST_ENTRY_CNT_24XX; 1607 ha->request_q_length = REQUEST_ENTRY_CNT_24XX;
@@ -1699,6 +1623,8 @@ qla2x00_probe_one(struct pci_dev *pdev, const struct pci_device_id *id)
1699 ha->gid_list_info_size = 8; 1623 ha->gid_list_info_size = 8;
1700 ha->optrom_size = OPTROM_SIZE_25XX; 1624 ha->optrom_size = OPTROM_SIZE_25XX;
1701 ha->isp_ops = &qla25xx_isp_ops; 1625 ha->isp_ops = &qla25xx_isp_ops;
1626 ha->hw_event_start = PCI_FUNC(pdev->devfn) ?
1627 FA_HW_EVENT1_ADDR: FA_HW_EVENT0_ADDR;
1702 } 1628 }
1703 host->can_queue = ha->request_q_length + 128; 1629 host->can_queue = ha->request_q_length + 128;
1704 1630
@@ -1713,6 +1639,7 @@ qla2x00_probe_one(struct pci_dev *pdev, const struct pci_device_id *id)
1713 INIT_LIST_HEAD(&ha->list); 1639 INIT_LIST_HEAD(&ha->list);
1714 INIT_LIST_HEAD(&ha->fcports); 1640 INIT_LIST_HEAD(&ha->fcports);
1715 INIT_LIST_HEAD(&ha->vp_list); 1641 INIT_LIST_HEAD(&ha->vp_list);
1642 INIT_LIST_HEAD(&ha->work_list);
1716 1643
1717 set_bit(0, (unsigned long *) ha->vp_idx_map); 1644 set_bit(0, (unsigned long *) ha->vp_idx_map);
1718 1645
@@ -1819,6 +1746,8 @@ qla2x00_remove_one(struct pci_dev *pdev)
1819 1746
1820 qla2x00_dfs_remove(ha); 1747 qla2x00_dfs_remove(ha);
1821 1748
1749 qla84xx_put_chip(ha);
1750
1822 qla2x00_free_sysfs_attr(ha); 1751 qla2x00_free_sysfs_attr(ha);
1823 1752
1824 fc_remove_host(ha->host); 1753 fc_remove_host(ha->host);
@@ -2206,6 +2135,97 @@ qla2x00_mem_free(scsi_qla_host_t *ha)
2206 kfree(ha->nvram); 2135 kfree(ha->nvram);
2207} 2136}
2208 2137
2138struct qla_work_evt *
2139qla2x00_alloc_work(struct scsi_qla_host *ha, enum qla_work_type type,
2140 int locked)
2141{
2142 struct qla_work_evt *e;
2143
2144 e = kzalloc(sizeof(struct qla_work_evt), locked ? GFP_ATOMIC:
2145 GFP_KERNEL);
2146 if (!e)
2147 return NULL;
2148
2149 INIT_LIST_HEAD(&e->list);
2150 e->type = type;
2151 e->flags = QLA_EVT_FLAG_FREE;
2152 return e;
2153}
2154
2155int
2156qla2x00_post_work(struct scsi_qla_host *ha, struct qla_work_evt *e, int locked)
2157{
2158 unsigned long flags;
2159
2160 if (!locked)
2161 spin_lock_irqsave(&ha->hardware_lock, flags);
2162 list_add_tail(&e->list, &ha->work_list);
2163 qla2xxx_wake_dpc(ha);
2164 if (!locked)
2165 spin_unlock_irqrestore(&ha->hardware_lock, flags);
2166 return QLA_SUCCESS;
2167}
2168
2169int
2170qla2x00_post_aen_work(struct scsi_qla_host *ha, enum fc_host_event_code code,
2171 u32 data)
2172{
2173 struct qla_work_evt *e;
2174
2175 e = qla2x00_alloc_work(ha, QLA_EVT_AEN, 1);
2176 if (!e)
2177 return QLA_FUNCTION_FAILED;
2178
2179 e->u.aen.code = code;
2180 e->u.aen.data = data;
2181 return qla2x00_post_work(ha, e, 1);
2182}
2183
2184int
2185qla2x00_post_hwe_work(struct scsi_qla_host *ha, uint16_t code, uint16_t d1,
2186 uint16_t d2, uint16_t d3)
2187{
2188 struct qla_work_evt *e;
2189
2190 e = qla2x00_alloc_work(ha, QLA_EVT_HWE_LOG, 1);
2191 if (!e)
2192 return QLA_FUNCTION_FAILED;
2193
2194 e->u.hwe.code = code;
2195 e->u.hwe.d1 = d1;
2196 e->u.hwe.d2 = d2;
2197 e->u.hwe.d3 = d3;
2198 return qla2x00_post_work(ha, e, 1);
2199}
2200
2201static void
2202qla2x00_do_work(struct scsi_qla_host *ha)
2203{
2204 struct qla_work_evt *e;
2205
2206 spin_lock_irq(&ha->hardware_lock);
2207 while (!list_empty(&ha->work_list)) {
2208 e = list_entry(ha->work_list.next, struct qla_work_evt, list);
2209 list_del_init(&e->list);
2210 spin_unlock_irq(&ha->hardware_lock);
2211
2212 switch (e->type) {
2213 case QLA_EVT_AEN:
2214 fc_host_post_event(ha->host, fc_get_event_number(),
2215 e->u.aen.code, e->u.aen.data);
2216 break;
2217 case QLA_EVT_HWE_LOG:
2218 qla2xxx_hw_event_log(ha, e->u.hwe.code, e->u.hwe.d1,
2219 e->u.hwe.d2, e->u.hwe.d3);
2220 break;
2221 }
2222 if (e->flags & QLA_EVT_FLAG_FREE)
2223 kfree(e);
2224 spin_lock_irq(&ha->hardware_lock);
2225 }
2226 spin_unlock_irq(&ha->hardware_lock);
2227}
2228
2209/************************************************************************** 2229/**************************************************************************
2210* qla2x00_do_dpc 2230* qla2x00_do_dpc
2211* This kernel thread is a task that is schedule by the interrupt handler 2231* This kernel thread is a task that is schedule by the interrupt handler
@@ -2257,6 +2277,8 @@ qla2x00_do_dpc(void *data)
2257 continue; 2277 continue;
2258 } 2278 }
2259 2279
2280 qla2x00_do_work(ha);
2281
2260 if (test_and_clear_bit(ISP_ABORT_NEEDED, &ha->dpc_flags)) { 2282 if (test_and_clear_bit(ISP_ABORT_NEEDED, &ha->dpc_flags)) {
2261 2283
2262 DEBUG(printk("scsi(%ld): dpc: sched " 2284 DEBUG(printk("scsi(%ld): dpc: sched "
@@ -2291,12 +2313,6 @@ qla2x00_do_dpc(void *data)
2291 if (test_and_clear_bit(FCPORT_UPDATE_NEEDED, &ha->dpc_flags)) 2313 if (test_and_clear_bit(FCPORT_UPDATE_NEEDED, &ha->dpc_flags))
2292 qla2x00_update_fcports(ha); 2314 qla2x00_update_fcports(ha);
2293 2315
2294 if (test_and_clear_bit(LOOP_RESET_NEEDED, &ha->dpc_flags)) {
2295 DEBUG(printk("scsi(%ld): dpc: sched loop_reset()\n",
2296 ha->host_no));
2297 qla2x00_loop_reset(ha);
2298 }
2299
2300 if (test_and_clear_bit(RESET_MARKER_NEEDED, &ha->dpc_flags) && 2316 if (test_and_clear_bit(RESET_MARKER_NEEDED, &ha->dpc_flags) &&
2301 (!(test_and_set_bit(RESET_ACTIVE, &ha->dpc_flags)))) { 2317 (!(test_and_set_bit(RESET_ACTIVE, &ha->dpc_flags)))) {
2302 2318
@@ -2367,19 +2383,6 @@ qla2x00_do_dpc(void *data)
2367 ha->host_no)); 2383 ha->host_no));
2368 } 2384 }
2369 2385
2370 if ((test_bit(LOGIN_RETRY_NEEDED, &ha->dpc_flags)) &&
2371 atomic_read(&ha->loop_state) != LOOP_DOWN) {
2372
2373 clear_bit(LOGIN_RETRY_NEEDED, &ha->dpc_flags);
2374 DEBUG(printk("scsi(%ld): qla2x00_login_retry()\n",
2375 ha->host_no));
2376
2377 set_bit(LOOP_RESYNC_NEEDED, &ha->dpc_flags);
2378
2379 DEBUG(printk("scsi(%ld): qla2x00_login_retry - end\n",
2380 ha->host_no));
2381 }
2382
2383 if (test_and_clear_bit(LOOP_RESYNC_NEEDED, &ha->dpc_flags)) { 2386 if (test_and_clear_bit(LOOP_RESYNC_NEEDED, &ha->dpc_flags)) {
2384 2387
2385 DEBUG(printk("scsi(%ld): qla2x00_loop_resync()\n", 2388 DEBUG(printk("scsi(%ld): qla2x00_loop_resync()\n",
@@ -2397,18 +2400,6 @@ qla2x00_do_dpc(void *data)
2397 ha->host_no)); 2400 ha->host_no));
2398 } 2401 }
2399 2402
2400 if (test_and_clear_bit(FCPORT_RESCAN_NEEDED, &ha->dpc_flags)) {
2401
2402 DEBUG(printk("scsi(%ld): Rescan flagged fcports...\n",
2403 ha->host_no));
2404
2405 qla2x00_rescan_fcports(ha);
2406
2407 DEBUG(printk("scsi(%ld): Rescan flagged fcports..."
2408 "end.\n",
2409 ha->host_no));
2410 }
2411
2412 if (!ha->interrupts_on) 2403 if (!ha->interrupts_on)
2413 ha->isp_ops->enable_intrs(ha); 2404 ha->isp_ops->enable_intrs(ha);
2414 2405
@@ -2586,7 +2577,8 @@ qla2x00_timer(scsi_qla_host_t *ha)
2586 set_bit(RESTART_QUEUES_NEEDED, &ha->dpc_flags); 2577 set_bit(RESTART_QUEUES_NEEDED, &ha->dpc_flags);
2587 start_dpc++; 2578 start_dpc++;
2588 2579
2589 if (!(ha->device_flags & DFLG_NO_CABLE)) { 2580 if (!(ha->device_flags & DFLG_NO_CABLE) &&
2581 !ha->parent) {
2590 DEBUG(printk("scsi(%ld): Loop down - " 2582 DEBUG(printk("scsi(%ld): Loop down - "
2591 "aborting ISP.\n", 2583 "aborting ISP.\n",
2592 ha->host_no)); 2584 ha->host_no));
@@ -2610,10 +2602,8 @@ qla2x00_timer(scsi_qla_host_t *ha)
2610 /* Schedule the DPC routine if needed */ 2602 /* Schedule the DPC routine if needed */
2611 if ((test_bit(ISP_ABORT_NEEDED, &ha->dpc_flags) || 2603 if ((test_bit(ISP_ABORT_NEEDED, &ha->dpc_flags) ||
2612 test_bit(LOOP_RESYNC_NEEDED, &ha->dpc_flags) || 2604 test_bit(LOOP_RESYNC_NEEDED, &ha->dpc_flags) ||
2613 test_bit(LOOP_RESET_NEEDED, &ha->dpc_flags) ||
2614 test_bit(FCPORT_UPDATE_NEEDED, &ha->dpc_flags) || 2605 test_bit(FCPORT_UPDATE_NEEDED, &ha->dpc_flags) ||
2615 start_dpc || 2606 start_dpc ||
2616 test_bit(LOGIN_RETRY_NEEDED, &ha->dpc_flags) ||
2617 test_bit(RESET_MARKER_NEEDED, &ha->dpc_flags) || 2607 test_bit(RESET_MARKER_NEEDED, &ha->dpc_flags) ||
2618 test_bit(BEACON_BLINK_NEEDED, &ha->dpc_flags) || 2608 test_bit(BEACON_BLINK_NEEDED, &ha->dpc_flags) ||
2619 test_bit(VP_DPC_NEEDED, &ha->dpc_flags) || 2609 test_bit(VP_DPC_NEEDED, &ha->dpc_flags) ||
@@ -2665,7 +2655,7 @@ qla2x00_request_firmware(scsi_qla_host_t *ha)
2665 blob = &qla_fw_blobs[FW_ISP2300]; 2655 blob = &qla_fw_blobs[FW_ISP2300];
2666 } else if (IS_QLA2322(ha) || IS_QLA6322(ha)) { 2656 } else if (IS_QLA2322(ha) || IS_QLA6322(ha)) {
2667 blob = &qla_fw_blobs[FW_ISP2322]; 2657 blob = &qla_fw_blobs[FW_ISP2322];
2668 } else if (IS_QLA24XX(ha) || IS_QLA54XX(ha)) { 2658 } else if (IS_QLA24XX_TYPE(ha)) {
2669 blob = &qla_fw_blobs[FW_ISP24XX]; 2659 blob = &qla_fw_blobs[FW_ISP24XX];
2670 } else if (IS_QLA25XX(ha)) { 2660 } else if (IS_QLA25XX(ha)) {
2671 blob = &qla_fw_blobs[FW_ISP25XX]; 2661 blob = &qla_fw_blobs[FW_ISP25XX];
@@ -2815,6 +2805,7 @@ static struct pci_device_id qla2xxx_pci_tbl[] = {
2815 { PCI_DEVICE(PCI_VENDOR_ID_QLOGIC, PCI_DEVICE_ID_QLOGIC_ISP6322) }, 2805 { PCI_DEVICE(PCI_VENDOR_ID_QLOGIC, PCI_DEVICE_ID_QLOGIC_ISP6322) },
2816 { PCI_DEVICE(PCI_VENDOR_ID_QLOGIC, PCI_DEVICE_ID_QLOGIC_ISP2422) }, 2806 { PCI_DEVICE(PCI_VENDOR_ID_QLOGIC, PCI_DEVICE_ID_QLOGIC_ISP2422) },
2817 { PCI_DEVICE(PCI_VENDOR_ID_QLOGIC, PCI_DEVICE_ID_QLOGIC_ISP2432) }, 2807 { PCI_DEVICE(PCI_VENDOR_ID_QLOGIC, PCI_DEVICE_ID_QLOGIC_ISP2432) },
2808 { PCI_DEVICE(PCI_VENDOR_ID_QLOGIC, PCI_DEVICE_ID_QLOGIC_ISP8432) },
2818 { PCI_DEVICE(PCI_VENDOR_ID_QLOGIC, PCI_DEVICE_ID_QLOGIC_ISP5422) }, 2809 { PCI_DEVICE(PCI_VENDOR_ID_QLOGIC, PCI_DEVICE_ID_QLOGIC_ISP5422) },
2819 { PCI_DEVICE(PCI_VENDOR_ID_QLOGIC, PCI_DEVICE_ID_QLOGIC_ISP5432) }, 2810 { PCI_DEVICE(PCI_VENDOR_ID_QLOGIC, PCI_DEVICE_ID_QLOGIC_ISP5432) },
2820 { PCI_DEVICE(PCI_VENDOR_ID_QLOGIC, PCI_DEVICE_ID_QLOGIC_ISP2532) }, 2811 { PCI_DEVICE(PCI_VENDOR_ID_QLOGIC, PCI_DEVICE_ID_QLOGIC_ISP2532) },