diff options
| -rw-r--r-- | drivers/s390/scsi/Makefile | 2 | ||||
| -rw-r--r-- | drivers/s390/scsi/zfcp_aux.c | 180 | ||||
| -rw-r--r-- | drivers/s390/scsi/zfcp_dbf.c | 988 | ||||
| -rw-r--r-- | drivers/s390/scsi/zfcp_def.h | 213 | ||||
| -rw-r--r-- | drivers/s390/scsi/zfcp_ext.h | 26 | ||||
| -rw-r--r-- | drivers/s390/scsi/zfcp_fsf.c | 241 | ||||
| -rw-r--r-- | drivers/s390/scsi/zfcp_fsf.h | 3 | ||||
| -rw-r--r-- | drivers/s390/scsi/zfcp_qdio.c | 30 | ||||
| -rw-r--r-- | drivers/s390/scsi/zfcp_scsi.c | 49 |
9 files changed, 1297 insertions, 435 deletions
diff --git a/drivers/s390/scsi/Makefile b/drivers/s390/scsi/Makefile index fc145307a7d4..d6a78f1a2f16 100644 --- a/drivers/s390/scsi/Makefile +++ b/drivers/s390/scsi/Makefile | |||
| @@ -3,7 +3,7 @@ | |||
| 3 | # | 3 | # |
| 4 | 4 | ||
| 5 | zfcp-objs := zfcp_aux.o zfcp_ccw.o zfcp_scsi.o zfcp_erp.o zfcp_qdio.o \ | 5 | zfcp-objs := zfcp_aux.o zfcp_ccw.o zfcp_scsi.o zfcp_erp.o zfcp_qdio.o \ |
| 6 | zfcp_fsf.o zfcp_sysfs_adapter.o zfcp_sysfs_port.o \ | 6 | zfcp_fsf.o zfcp_dbf.o zfcp_sysfs_adapter.o zfcp_sysfs_port.o \ |
| 7 | zfcp_sysfs_unit.o zfcp_sysfs_driver.o | 7 | zfcp_sysfs_unit.o zfcp_sysfs_driver.o |
| 8 | 8 | ||
| 9 | obj-$(CONFIG_ZFCP) += zfcp.o | 9 | obj-$(CONFIG_ZFCP) += zfcp.o |
diff --git a/drivers/s390/scsi/zfcp_aux.c b/drivers/s390/scsi/zfcp_aux.c index 17f9989238f8..0b5087f7cabc 100644 --- a/drivers/s390/scsi/zfcp_aux.c +++ b/drivers/s390/scsi/zfcp_aux.c | |||
| @@ -122,93 +122,6 @@ _zfcp_hex_dump(char *addr, int count) | |||
| 122 | 122 | ||
| 123 | #define ZFCP_LOG_AREA ZFCP_LOG_AREA_OTHER | 123 | #define ZFCP_LOG_AREA ZFCP_LOG_AREA_OTHER |
| 124 | 124 | ||
| 125 | static inline int | ||
| 126 | zfcp_fsf_req_is_scsi_cmnd(struct zfcp_fsf_req *fsf_req) | ||
| 127 | { | ||
| 128 | return ((fsf_req->fsf_command == FSF_QTCB_FCP_CMND) && | ||
| 129 | !(fsf_req->status & ZFCP_STATUS_FSFREQ_TASK_MANAGEMENT)); | ||
| 130 | } | ||
| 131 | |||
| 132 | void | ||
| 133 | zfcp_cmd_dbf_event_fsf(const char *text, struct zfcp_fsf_req *fsf_req, | ||
| 134 | void *add_data, int add_length) | ||
| 135 | { | ||
| 136 | struct zfcp_adapter *adapter = fsf_req->adapter; | ||
| 137 | struct scsi_cmnd *scsi_cmnd; | ||
| 138 | int level = 3; | ||
| 139 | int i; | ||
| 140 | unsigned long flags; | ||
| 141 | |||
| 142 | spin_lock_irqsave(&adapter->dbf_lock, flags); | ||
| 143 | if (zfcp_fsf_req_is_scsi_cmnd(fsf_req)) { | ||
| 144 | scsi_cmnd = (struct scsi_cmnd*) fsf_req->data; | ||
| 145 | debug_text_event(adapter->cmd_dbf, level, "fsferror"); | ||
| 146 | debug_text_event(adapter->cmd_dbf, level, text); | ||
| 147 | debug_event(adapter->cmd_dbf, level, &fsf_req, | ||
| 148 | sizeof (unsigned long)); | ||
| 149 | debug_event(adapter->cmd_dbf, level, &fsf_req->seq_no, | ||
| 150 | sizeof (u32)); | ||
| 151 | debug_event(adapter->cmd_dbf, level, &scsi_cmnd, | ||
| 152 | sizeof (unsigned long)); | ||
| 153 | debug_event(adapter->cmd_dbf, level, &scsi_cmnd->cmnd, | ||
| 154 | min(ZFCP_CMD_DBF_LENGTH, (int)scsi_cmnd->cmd_len)); | ||
| 155 | for (i = 0; i < add_length; i += ZFCP_CMD_DBF_LENGTH) | ||
| 156 | debug_event(adapter->cmd_dbf, | ||
| 157 | level, | ||
| 158 | (char *) add_data + i, | ||
| 159 | min(ZFCP_CMD_DBF_LENGTH, add_length - i)); | ||
| 160 | } | ||
| 161 | spin_unlock_irqrestore(&adapter->dbf_lock, flags); | ||
| 162 | } | ||
| 163 | |||
| 164 | /* XXX additionally log unit if available */ | ||
| 165 | /* ---> introduce new parameter for unit, see 2.4 code */ | ||
| 166 | void | ||
| 167 | zfcp_cmd_dbf_event_scsi(const char *text, struct scsi_cmnd *scsi_cmnd) | ||
| 168 | { | ||
| 169 | struct zfcp_adapter *adapter; | ||
| 170 | struct zfcp_fsf_req *fsf_req; | ||
| 171 | int level = ((host_byte(scsi_cmnd->result) != 0) ? 1 : 5); | ||
| 172 | unsigned long flags; | ||
| 173 | |||
| 174 | adapter = (struct zfcp_adapter *) scsi_cmnd->device->host->hostdata[0]; | ||
| 175 | fsf_req = (struct zfcp_fsf_req *) scsi_cmnd->host_scribble; | ||
| 176 | spin_lock_irqsave(&adapter->dbf_lock, flags); | ||
| 177 | debug_text_event(adapter->cmd_dbf, level, "hostbyte"); | ||
| 178 | debug_text_event(adapter->cmd_dbf, level, text); | ||
| 179 | debug_event(adapter->cmd_dbf, level, &scsi_cmnd->result, sizeof (u32)); | ||
| 180 | debug_event(adapter->cmd_dbf, level, &scsi_cmnd, | ||
| 181 | sizeof (unsigned long)); | ||
| 182 | debug_event(adapter->cmd_dbf, level, &scsi_cmnd->cmnd, | ||
| 183 | min(ZFCP_CMD_DBF_LENGTH, (int)scsi_cmnd->cmd_len)); | ||
| 184 | if (likely(fsf_req)) { | ||
| 185 | debug_event(adapter->cmd_dbf, level, &fsf_req, | ||
| 186 | sizeof (unsigned long)); | ||
| 187 | debug_event(adapter->cmd_dbf, level, &fsf_req->seq_no, | ||
| 188 | sizeof (u32)); | ||
| 189 | } else { | ||
| 190 | debug_text_event(adapter->cmd_dbf, level, ""); | ||
| 191 | debug_text_event(adapter->cmd_dbf, level, ""); | ||
| 192 | } | ||
| 193 | spin_unlock_irqrestore(&adapter->dbf_lock, flags); | ||
| 194 | } | ||
| 195 | |||
| 196 | void | ||
| 197 | zfcp_in_els_dbf_event(struct zfcp_adapter *adapter, const char *text, | ||
| 198 | struct fsf_status_read_buffer *status_buffer, int length) | ||
| 199 | { | ||
| 200 | int level = 1; | ||
| 201 | int i; | ||
| 202 | |||
| 203 | debug_text_event(adapter->in_els_dbf, level, text); | ||
| 204 | debug_event(adapter->in_els_dbf, level, &status_buffer->d_id, 8); | ||
| 205 | for (i = 0; i < length; i += ZFCP_IN_ELS_DBF_LENGTH) | ||
| 206 | debug_event(adapter->in_els_dbf, | ||
| 207 | level, | ||
| 208 | (char *) status_buffer->payload + i, | ||
| 209 | min(ZFCP_IN_ELS_DBF_LENGTH, length - i)); | ||
| 210 | } | ||
| 211 | |||
| 212 | /** | 125 | /** |
| 213 | * zfcp_device_setup - setup function | 126 | * zfcp_device_setup - setup function |
| 214 | * @str: pointer to parameter string | 127 | * @str: pointer to parameter string |
| @@ -1015,81 +928,6 @@ zfcp_free_low_mem_buffers(struct zfcp_adapter *adapter) | |||
| 1015 | mempool_destroy(adapter->pool.data_gid_pn); | 928 | mempool_destroy(adapter->pool.data_gid_pn); |
| 1016 | } | 929 | } |
| 1017 | 930 | ||
| 1018 | /** | ||
| 1019 | * zfcp_adapter_debug_register - registers debug feature for an adapter | ||
| 1020 | * @adapter: pointer to adapter for which debug features should be registered | ||
| 1021 | * return: -ENOMEM on error, 0 otherwise | ||
| 1022 | */ | ||
| 1023 | int | ||
| 1024 | zfcp_adapter_debug_register(struct zfcp_adapter *adapter) | ||
| 1025 | { | ||
| 1026 | char dbf_name[20]; | ||
| 1027 | |||
| 1028 | /* debug feature area which records SCSI command failures (hostbyte) */ | ||
| 1029 | spin_lock_init(&adapter->dbf_lock); | ||
| 1030 | |||
| 1031 | sprintf(dbf_name, ZFCP_CMD_DBF_NAME "%s", | ||
| 1032 | zfcp_get_busid_by_adapter(adapter)); | ||
| 1033 | adapter->cmd_dbf = debug_register(dbf_name, ZFCP_CMD_DBF_INDEX, | ||
| 1034 | ZFCP_CMD_DBF_AREAS, | ||
| 1035 | ZFCP_CMD_DBF_LENGTH); | ||
| 1036 | debug_register_view(adapter->cmd_dbf, &debug_hex_ascii_view); | ||
| 1037 | debug_set_level(adapter->cmd_dbf, ZFCP_CMD_DBF_LEVEL); | ||
| 1038 | |||
| 1039 | /* debug feature area which records SCSI command aborts */ | ||
| 1040 | sprintf(dbf_name, ZFCP_ABORT_DBF_NAME "%s", | ||
| 1041 | zfcp_get_busid_by_adapter(adapter)); | ||
| 1042 | adapter->abort_dbf = debug_register(dbf_name, ZFCP_ABORT_DBF_INDEX, | ||
| 1043 | ZFCP_ABORT_DBF_AREAS, | ||
| 1044 | ZFCP_ABORT_DBF_LENGTH); | ||
| 1045 | debug_register_view(adapter->abort_dbf, &debug_hex_ascii_view); | ||
| 1046 | debug_set_level(adapter->abort_dbf, ZFCP_ABORT_DBF_LEVEL); | ||
| 1047 | |||
| 1048 | /* debug feature area which records incoming ELS commands */ | ||
| 1049 | sprintf(dbf_name, ZFCP_IN_ELS_DBF_NAME "%s", | ||
| 1050 | zfcp_get_busid_by_adapter(adapter)); | ||
| 1051 | adapter->in_els_dbf = debug_register(dbf_name, ZFCP_IN_ELS_DBF_INDEX, | ||
| 1052 | ZFCP_IN_ELS_DBF_AREAS, | ||
| 1053 | ZFCP_IN_ELS_DBF_LENGTH); | ||
| 1054 | debug_register_view(adapter->in_els_dbf, &debug_hex_ascii_view); | ||
| 1055 | debug_set_level(adapter->in_els_dbf, ZFCP_IN_ELS_DBF_LEVEL); | ||
| 1056 | |||
| 1057 | /* debug feature area which records erp events */ | ||
| 1058 | sprintf(dbf_name, ZFCP_ERP_DBF_NAME "%s", | ||
| 1059 | zfcp_get_busid_by_adapter(adapter)); | ||
| 1060 | adapter->erp_dbf = debug_register(dbf_name, ZFCP_ERP_DBF_INDEX, | ||
| 1061 | ZFCP_ERP_DBF_AREAS, | ||
| 1062 | ZFCP_ERP_DBF_LENGTH); | ||
| 1063 | debug_register_view(adapter->erp_dbf, &debug_hex_ascii_view); | ||
| 1064 | debug_set_level(adapter->erp_dbf, ZFCP_ERP_DBF_LEVEL); | ||
| 1065 | |||
| 1066 | if (!(adapter->cmd_dbf && adapter->abort_dbf && | ||
| 1067 | adapter->in_els_dbf && adapter->erp_dbf)) { | ||
| 1068 | zfcp_adapter_debug_unregister(adapter); | ||
| 1069 | return -ENOMEM; | ||
| 1070 | } | ||
| 1071 | |||
| 1072 | return 0; | ||
| 1073 | |||
| 1074 | } | ||
| 1075 | |||
| 1076 | /** | ||
| 1077 | * zfcp_adapter_debug_unregister - unregisters debug feature for an adapter | ||
| 1078 | * @adapter: pointer to adapter for which debug features should be unregistered | ||
| 1079 | */ | ||
| 1080 | void | ||
| 1081 | zfcp_adapter_debug_unregister(struct zfcp_adapter *adapter) | ||
| 1082 | { | ||
| 1083 | debug_unregister(adapter->abort_dbf); | ||
| 1084 | debug_unregister(adapter->cmd_dbf); | ||
| 1085 | debug_unregister(adapter->erp_dbf); | ||
| 1086 | debug_unregister(adapter->in_els_dbf); | ||
| 1087 | adapter->abort_dbf = NULL; | ||
| 1088 | adapter->cmd_dbf = NULL; | ||
| 1089 | adapter->erp_dbf = NULL; | ||
| 1090 | adapter->in_els_dbf = NULL; | ||
| 1091 | } | ||
| 1092 | |||
| 1093 | void | 931 | void |
| 1094 | zfcp_dummy_release(struct device *dev) | 932 | zfcp_dummy_release(struct device *dev) |
| 1095 | { | 933 | { |
| @@ -1460,10 +1298,6 @@ zfcp_fsf_incoming_els_rscn(struct zfcp_adapter *adapter, | |||
| 1460 | /* see FC-FS */ | 1298 | /* see FC-FS */ |
| 1461 | no_entries = (fcp_rscn_head->payload_len / 4); | 1299 | no_entries = (fcp_rscn_head->payload_len / 4); |
| 1462 | 1300 | ||
| 1463 | zfcp_in_els_dbf_event(adapter, "##rscn", status_buffer, | ||
| 1464 | fcp_rscn_head->payload_len); | ||
| 1465 | |||
| 1466 | debug_text_event(adapter->erp_dbf, 1, "unsol_els_rscn:"); | ||
| 1467 | for (i = 1; i < no_entries; i++) { | 1301 | for (i = 1; i < no_entries; i++) { |
| 1468 | /* skip head and start with 1st element */ | 1302 | /* skip head and start with 1st element */ |
| 1469 | fcp_rscn_element++; | 1303 | fcp_rscn_element++; |
| @@ -1495,8 +1329,6 @@ zfcp_fsf_incoming_els_rscn(struct zfcp_adapter *adapter, | |||
| 1495 | (ZFCP_STATUS_PORT_DID_DID, &port->status)) { | 1329 | (ZFCP_STATUS_PORT_DID_DID, &port->status)) { |
| 1496 | ZFCP_LOG_INFO("incoming RSCN, trying to open " | 1330 | ZFCP_LOG_INFO("incoming RSCN, trying to open " |
| 1497 | "port 0x%016Lx\n", port->wwpn); | 1331 | "port 0x%016Lx\n", port->wwpn); |
| 1498 | debug_text_event(adapter->erp_dbf, 1, | ||
| 1499 | "unsol_els_rscnu:"); | ||
| 1500 | zfcp_erp_port_reopen(port, | 1332 | zfcp_erp_port_reopen(port, |
| 1501 | ZFCP_STATUS_COMMON_ERP_FAILED); | 1333 | ZFCP_STATUS_COMMON_ERP_FAILED); |
| 1502 | continue; | 1334 | continue; |
| @@ -1522,8 +1354,6 @@ zfcp_fsf_incoming_els_rscn(struct zfcp_adapter *adapter, | |||
| 1522 | */ | 1354 | */ |
| 1523 | ZFCP_LOG_INFO("incoming RSCN, trying to open " | 1355 | ZFCP_LOG_INFO("incoming RSCN, trying to open " |
| 1524 | "port 0x%016Lx\n", port->wwpn); | 1356 | "port 0x%016Lx\n", port->wwpn); |
| 1525 | debug_text_event(adapter->erp_dbf, 1, | ||
| 1526 | "unsol_els_rscnk:"); | ||
| 1527 | zfcp_test_link(port); | 1357 | zfcp_test_link(port); |
| 1528 | } | 1358 | } |
| 1529 | } | 1359 | } |
| @@ -1539,8 +1369,6 @@ zfcp_fsf_incoming_els_plogi(struct zfcp_adapter *adapter, | |||
| 1539 | struct zfcp_port *port; | 1369 | struct zfcp_port *port; |
| 1540 | unsigned long flags; | 1370 | unsigned long flags; |
| 1541 | 1371 | ||
| 1542 | zfcp_in_els_dbf_event(adapter, "##plogi", status_buffer, 28); | ||
| 1543 | |||
| 1544 | read_lock_irqsave(&zfcp_data.config_lock, flags); | 1372 | read_lock_irqsave(&zfcp_data.config_lock, flags); |
| 1545 | list_for_each_entry(port, &adapter->port_list_head, list) { | 1373 | list_for_each_entry(port, &adapter->port_list_head, list) { |
| 1546 | if (port->wwpn == (*(wwn_t *) & els_logi->nport_wwn)) | 1374 | if (port->wwpn == (*(wwn_t *) & els_logi->nport_wwn)) |
| @@ -1554,8 +1382,6 @@ zfcp_fsf_incoming_els_plogi(struct zfcp_adapter *adapter, | |||
| 1554 | status_buffer->d_id, | 1382 | status_buffer->d_id, |
| 1555 | zfcp_get_busid_by_adapter(adapter)); | 1383 | zfcp_get_busid_by_adapter(adapter)); |
| 1556 | } else { | 1384 | } else { |
| 1557 | debug_text_event(adapter->erp_dbf, 1, "unsol_els_plogi:"); | ||
| 1558 | debug_event(adapter->erp_dbf, 1, &els_logi->nport_wwn, 8); | ||
| 1559 | zfcp_erp_port_forced_reopen(port, 0); | 1385 | zfcp_erp_port_forced_reopen(port, 0); |
| 1560 | } | 1386 | } |
| 1561 | } | 1387 | } |
| @@ -1568,8 +1394,6 @@ zfcp_fsf_incoming_els_logo(struct zfcp_adapter *adapter, | |||
| 1568 | struct zfcp_port *port; | 1394 | struct zfcp_port *port; |
| 1569 | unsigned long flags; | 1395 | unsigned long flags; |
| 1570 | 1396 | ||
| 1571 | zfcp_in_els_dbf_event(adapter, "##logo", status_buffer, 16); | ||
| 1572 | |||
| 1573 | read_lock_irqsave(&zfcp_data.config_lock, flags); | 1397 | read_lock_irqsave(&zfcp_data.config_lock, flags); |
| 1574 | list_for_each_entry(port, &adapter->port_list_head, list) { | 1398 | list_for_each_entry(port, &adapter->port_list_head, list) { |
| 1575 | if (port->wwpn == els_logo->nport_wwpn) | 1399 | if (port->wwpn == els_logo->nport_wwpn) |
| @@ -1583,8 +1407,6 @@ zfcp_fsf_incoming_els_logo(struct zfcp_adapter *adapter, | |||
| 1583 | status_buffer->d_id, | 1407 | status_buffer->d_id, |
| 1584 | zfcp_get_busid_by_adapter(adapter)); | 1408 | zfcp_get_busid_by_adapter(adapter)); |
| 1585 | } else { | 1409 | } else { |
| 1586 | debug_text_event(adapter->erp_dbf, 1, "unsol_els_logo:"); | ||
| 1587 | debug_event(adapter->erp_dbf, 1, &els_logo->nport_wwpn, 8); | ||
| 1588 | zfcp_erp_port_forced_reopen(port, 0); | 1410 | zfcp_erp_port_forced_reopen(port, 0); |
| 1589 | } | 1411 | } |
| 1590 | } | 1412 | } |
| @@ -1593,7 +1415,6 @@ static void | |||
| 1593 | zfcp_fsf_incoming_els_unknown(struct zfcp_adapter *adapter, | 1415 | zfcp_fsf_incoming_els_unknown(struct zfcp_adapter *adapter, |
| 1594 | struct fsf_status_read_buffer *status_buffer) | 1416 | struct fsf_status_read_buffer *status_buffer) |
| 1595 | { | 1417 | { |
| 1596 | zfcp_in_els_dbf_event(adapter, "##undef", status_buffer, 24); | ||
| 1597 | ZFCP_LOG_NORMAL("warning: unknown incoming ELS 0x%08x " | 1418 | ZFCP_LOG_NORMAL("warning: unknown incoming ELS 0x%08x " |
| 1598 | "for adapter %s\n", *(u32 *) (status_buffer->payload), | 1419 | "for adapter %s\n", *(u32 *) (status_buffer->payload), |
| 1599 | zfcp_get_busid_by_adapter(adapter)); | 1420 | zfcp_get_busid_by_adapter(adapter)); |
| @@ -1611,6 +1432,7 @@ zfcp_fsf_incoming_els(struct zfcp_fsf_req *fsf_req) | |||
| 1611 | els_type = *(u32 *) (status_buffer->payload); | 1432 | els_type = *(u32 *) (status_buffer->payload); |
| 1612 | adapter = fsf_req->adapter; | 1433 | adapter = fsf_req->adapter; |
| 1613 | 1434 | ||
| 1435 | zfcp_san_dbf_event_incoming_els(fsf_req); | ||
| 1614 | if (els_type == LS_PLOGI) | 1436 | if (els_type == LS_PLOGI) |
| 1615 | zfcp_fsf_incoming_els_plogi(adapter, status_buffer); | 1437 | zfcp_fsf_incoming_els_plogi(adapter, status_buffer); |
| 1616 | else if (els_type == LS_LOGO) | 1438 | else if (els_type == LS_LOGO) |
diff --git a/drivers/s390/scsi/zfcp_dbf.c b/drivers/s390/scsi/zfcp_dbf.c new file mode 100644 index 000000000000..fff1537335c7 --- /dev/null +++ b/drivers/s390/scsi/zfcp_dbf.c | |||
| @@ -0,0 +1,988 @@ | |||
| 1 | /* | ||
| 2 | * | ||
| 3 | * linux/drivers/s390/scsi/zfcp_dbf.c | ||
| 4 | * | ||
| 5 | * FCP adapter driver for IBM eServer zSeries | ||
| 6 | * | ||
| 7 | * Debugging facilities | ||
| 8 | * | ||
| 9 | * (C) Copyright IBM Corp. 2005 | ||
| 10 | * | ||
| 11 | * This program is free software; you can redistribute it and/or modify | ||
| 12 | * it under the terms of the GNU General Public License as published by | ||
| 13 | * the Free Software Foundation; either version 2, or (at your option) | ||
| 14 | * any later version. | ||
| 15 | * | ||
| 16 | * This program is distributed in the hope that it will be useful, | ||
| 17 | * but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
| 18 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
| 19 | * GNU General Public License for more details. | ||
| 20 | * | ||
| 21 | * You should have received a copy of the GNU General Public License | ||
| 22 | * along with this program; if not, write to the Free Software | ||
| 23 | * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. | ||
| 24 | */ | ||
| 25 | |||
| 26 | #define ZFCP_DBF_REVISION "$Revision$" | ||
| 27 | |||
| 28 | #include <asm/debug.h> | ||
| 29 | #include <linux/ctype.h> | ||
| 30 | #include "zfcp_ext.h" | ||
| 31 | |||
| 32 | static u32 dbfsize = 4; | ||
| 33 | |||
| 34 | module_param(dbfsize, uint, 0400); | ||
| 35 | MODULE_PARM_DESC(dbfsize, | ||
| 36 | "number of pages for each debug feature area (default 4)"); | ||
| 37 | |||
| 38 | #define ZFCP_LOG_AREA ZFCP_LOG_AREA_OTHER | ||
| 39 | |||
| 40 | static inline int | ||
| 41 | zfcp_dbf_stck(char *out_buf, const char *label, unsigned long long stck) | ||
| 42 | { | ||
| 43 | unsigned long long sec; | ||
| 44 | struct timespec xtime; | ||
| 45 | int len = 0; | ||
| 46 | |||
| 47 | stck -= 0x8126d60e46000000LL - (0x3c26700LL * 1000000 * 4096); | ||
| 48 | sec = stck >> 12; | ||
| 49 | do_div(sec, 1000000); | ||
| 50 | xtime.tv_sec = sec; | ||
| 51 | stck -= (sec * 1000000) << 12; | ||
| 52 | xtime.tv_nsec = ((stck * 1000) >> 12); | ||
| 53 | len += sprintf(out_buf + len, "%-24s%011lu:%06lu\n", | ||
| 54 | label, xtime.tv_sec, xtime.tv_nsec); | ||
| 55 | |||
| 56 | return len; | ||
| 57 | } | ||
| 58 | |||
| 59 | static int zfcp_dbf_tag(char *out_buf, const char *label, const char *tag) | ||
| 60 | { | ||
| 61 | int len = 0, i; | ||
| 62 | |||
| 63 | len += sprintf(out_buf + len, "%-24s", label); | ||
| 64 | for (i = 0; i < ZFCP_DBF_TAG_SIZE; i++) | ||
| 65 | len += sprintf(out_buf + len, "%c", tag[i]); | ||
| 66 | len += sprintf(out_buf + len, "\n"); | ||
| 67 | |||
| 68 | return len; | ||
| 69 | } | ||
| 70 | |||
| 71 | static int | ||
| 72 | zfcp_dbf_view(char *out_buf, const char *label, const char *format, ...) | ||
| 73 | { | ||
| 74 | va_list arg; | ||
| 75 | int len = 0; | ||
| 76 | |||
| 77 | len += sprintf(out_buf + len, "%-24s", label); | ||
| 78 | va_start(arg, format); | ||
| 79 | len += vsprintf(out_buf + len, format, arg); | ||
| 80 | va_end(arg); | ||
| 81 | len += sprintf(out_buf + len, "\n"); | ||
| 82 | |||
| 83 | return len; | ||
| 84 | } | ||
| 85 | |||
| 86 | static int | ||
| 87 | zfcp_dbf_view_dump(char *out_buf, const char *label, | ||
| 88 | char *buffer, int buflen, int offset, int total_size) | ||
| 89 | { | ||
| 90 | int len = 0; | ||
| 91 | |||
| 92 | if (offset == 0) | ||
| 93 | len += sprintf(out_buf + len, "%-24s ", label); | ||
| 94 | |||
| 95 | while (buflen--) { | ||
| 96 | if (offset > 0) { | ||
| 97 | if ((offset % 32) == 0) | ||
| 98 | len += sprintf(out_buf + len, "\n%-24c ", ' '); | ||
| 99 | else if ((offset % 4) == 0) | ||
| 100 | len += sprintf(out_buf + len, " "); | ||
| 101 | } | ||
| 102 | len += sprintf(out_buf + len, "%02x", *buffer++); | ||
| 103 | if (++offset == total_size) { | ||
| 104 | len += sprintf(out_buf + len, "\n"); | ||
| 105 | break; | ||
| 106 | } | ||
| 107 | } | ||
| 108 | |||
| 109 | if (total_size == 0) | ||
| 110 | len += sprintf(out_buf + len, "\n"); | ||
| 111 | |||
| 112 | return len; | ||
| 113 | } | ||
| 114 | |||
| 115 | static inline int | ||
| 116 | zfcp_dbf_view_header(debug_info_t * id, struct debug_view *view, int area, | ||
| 117 | debug_entry_t * entry, char *out_buf) | ||
| 118 | { | ||
| 119 | struct zfcp_dbf_dump *dump = (struct zfcp_dbf_dump *)DEBUG_DATA(entry); | ||
| 120 | int len = 0; | ||
| 121 | |||
| 122 | if (strncmp(dump->tag, "dump", ZFCP_DBF_TAG_SIZE) != 0) { | ||
| 123 | len += zfcp_dbf_stck(out_buf + len, "timestamp", | ||
| 124 | entry->id.stck); | ||
| 125 | len += zfcp_dbf_view(out_buf + len, "cpu", "%02i", | ||
| 126 | entry->id.fields.cpuid); | ||
| 127 | } else { | ||
| 128 | len += zfcp_dbf_view_dump(out_buf + len, NULL, | ||
| 129 | dump->data, | ||
| 130 | dump->size, | ||
| 131 | dump->offset, dump->total_size); | ||
| 132 | if ((dump->offset + dump->size) == dump->total_size) | ||
| 133 | len += sprintf(out_buf + len, "\n"); | ||
| 134 | } | ||
| 135 | |||
| 136 | return len; | ||
| 137 | } | ||
| 138 | |||
| 139 | inline void zfcp_hba_dbf_event_fsf_response(struct zfcp_fsf_req *fsf_req) | ||
| 140 | { | ||
| 141 | struct zfcp_adapter *adapter = fsf_req->adapter; | ||
| 142 | struct fsf_qtcb *qtcb = fsf_req->qtcb; | ||
| 143 | union fsf_prot_status_qual *prot_status_qual = | ||
| 144 | &qtcb->prefix.prot_status_qual; | ||
| 145 | union fsf_status_qual *fsf_status_qual = &qtcb->header.fsf_status_qual; | ||
| 146 | struct scsi_cmnd *scsi_cmnd; | ||
| 147 | struct zfcp_port *port; | ||
| 148 | struct zfcp_unit *unit; | ||
| 149 | struct zfcp_send_els *send_els; | ||
| 150 | struct zfcp_hba_dbf_record *rec = &adapter->hba_dbf_buf; | ||
| 151 | struct zfcp_hba_dbf_record_response *response = &rec->type.response; | ||
| 152 | int level; | ||
| 153 | unsigned long flags; | ||
| 154 | |||
| 155 | spin_lock_irqsave(&adapter->hba_dbf_lock, flags); | ||
| 156 | memset(rec, 0, sizeof(struct zfcp_hba_dbf_record)); | ||
| 157 | strncpy(rec->tag, "resp", ZFCP_DBF_TAG_SIZE); | ||
| 158 | |||
| 159 | if ((qtcb->prefix.prot_status != FSF_PROT_GOOD) && | ||
| 160 | (qtcb->prefix.prot_status != FSF_PROT_FSF_STATUS_PRESENTED)) { | ||
| 161 | strncpy(rec->tag2, "perr", ZFCP_DBF_TAG_SIZE); | ||
| 162 | level = 1; | ||
| 163 | } else if (qtcb->header.fsf_status != FSF_GOOD) { | ||
| 164 | strncpy(rec->tag2, "ferr", ZFCP_DBF_TAG_SIZE); | ||
| 165 | level = 1; | ||
| 166 | } else if ((fsf_req->fsf_command == FSF_QTCB_OPEN_PORT_WITH_DID) || | ||
| 167 | (fsf_req->fsf_command == FSF_QTCB_OPEN_LUN)) { | ||
| 168 | strncpy(rec->tag2, "open", ZFCP_DBF_TAG_SIZE); | ||
| 169 | level = 4; | ||
| 170 | } else if ((prot_status_qual->doubleword[0] != 0) || | ||
| 171 | (prot_status_qual->doubleword[1] != 0) || | ||
| 172 | (fsf_status_qual->doubleword[0] != 0) || | ||
| 173 | (fsf_status_qual->doubleword[1] != 0)) { | ||
| 174 | strncpy(rec->tag2, "qual", ZFCP_DBF_TAG_SIZE); | ||
| 175 | level = 3; | ||
| 176 | } else { | ||
| 177 | strncpy(rec->tag2, "norm", ZFCP_DBF_TAG_SIZE); | ||
| 178 | level = 6; | ||
| 179 | } | ||
| 180 | |||
| 181 | response->fsf_command = fsf_req->fsf_command; | ||
| 182 | response->fsf_reqid = (unsigned long)fsf_req; | ||
| 183 | response->fsf_seqno = fsf_req->seq_no; | ||
| 184 | response->fsf_issued = fsf_req->issued; | ||
| 185 | response->fsf_prot_status = qtcb->prefix.prot_status; | ||
| 186 | response->fsf_status = qtcb->header.fsf_status; | ||
| 187 | memcpy(response->fsf_prot_status_qual, | ||
| 188 | prot_status_qual, FSF_PROT_STATUS_QUAL_SIZE); | ||
| 189 | memcpy(response->fsf_status_qual, | ||
| 190 | fsf_status_qual, FSF_STATUS_QUALIFIER_SIZE); | ||
| 191 | response->fsf_req_status = fsf_req->status; | ||
| 192 | response->sbal_first = fsf_req->sbal_first; | ||
| 193 | response->sbal_curr = fsf_req->sbal_curr; | ||
| 194 | response->sbal_last = fsf_req->sbal_last; | ||
| 195 | response->pool = fsf_req->pool != NULL; | ||
| 196 | response->erp_action = (unsigned long)fsf_req->erp_action; | ||
| 197 | |||
| 198 | switch (fsf_req->fsf_command) { | ||
| 199 | case FSF_QTCB_FCP_CMND: | ||
| 200 | if (fsf_req->status & ZFCP_STATUS_FSFREQ_TASK_MANAGEMENT) | ||
| 201 | break; | ||
| 202 | scsi_cmnd = (struct scsi_cmnd *)fsf_req->data; | ||
| 203 | if (scsi_cmnd != NULL) { | ||
| 204 | response->data.send_fcp.scsi_cmnd | ||
| 205 | = (unsigned long)scsi_cmnd; | ||
| 206 | response->data.send_fcp.scsi_serial | ||
| 207 | = scsi_cmnd->serial_number; | ||
| 208 | } | ||
| 209 | break; | ||
| 210 | |||
| 211 | case FSF_QTCB_OPEN_PORT_WITH_DID: | ||
| 212 | case FSF_QTCB_CLOSE_PORT: | ||
| 213 | case FSF_QTCB_CLOSE_PHYSICAL_PORT: | ||
| 214 | port = (struct zfcp_port *)fsf_req->data; | ||
| 215 | response->data.port.wwpn = port->wwpn; | ||
| 216 | response->data.port.d_id = port->d_id; | ||
| 217 | response->data.port.port_handle = qtcb->header.port_handle; | ||
| 218 | break; | ||
| 219 | |||
| 220 | case FSF_QTCB_OPEN_LUN: | ||
| 221 | case FSF_QTCB_CLOSE_LUN: | ||
| 222 | unit = (struct zfcp_unit *)fsf_req->data; | ||
| 223 | port = unit->port; | ||
| 224 | response->data.unit.wwpn = port->wwpn; | ||
| 225 | response->data.unit.fcp_lun = unit->fcp_lun; | ||
| 226 | response->data.unit.port_handle = qtcb->header.port_handle; | ||
| 227 | response->data.unit.lun_handle = qtcb->header.lun_handle; | ||
| 228 | break; | ||
| 229 | |||
| 230 | case FSF_QTCB_SEND_ELS: | ||
| 231 | send_els = (struct zfcp_send_els *)fsf_req->data; | ||
| 232 | response->data.send_els.d_id = qtcb->bottom.support.d_id; | ||
| 233 | response->data.send_els.ls_code = send_els->ls_code >> 24; | ||
| 234 | break; | ||
| 235 | |||
| 236 | case FSF_QTCB_ABORT_FCP_CMND: | ||
| 237 | case FSF_QTCB_SEND_GENERIC: | ||
| 238 | case FSF_QTCB_EXCHANGE_CONFIG_DATA: | ||
| 239 | case FSF_QTCB_EXCHANGE_PORT_DATA: | ||
| 240 | case FSF_QTCB_DOWNLOAD_CONTROL_FILE: | ||
| 241 | case FSF_QTCB_UPLOAD_CONTROL_FILE: | ||
| 242 | break; | ||
| 243 | } | ||
| 244 | |||
| 245 | debug_event(adapter->hba_dbf, level, | ||
| 246 | rec, sizeof(struct zfcp_hba_dbf_record)); | ||
| 247 | spin_unlock_irqrestore(&adapter->hba_dbf_lock, flags); | ||
| 248 | } | ||
| 249 | |||
| 250 | inline void | ||
| 251 | zfcp_hba_dbf_event_fsf_unsol(const char *tag, struct zfcp_adapter *adapter, | ||
| 252 | struct fsf_status_read_buffer *status_buffer) | ||
| 253 | { | ||
| 254 | struct zfcp_hba_dbf_record *rec = &adapter->hba_dbf_buf; | ||
| 255 | unsigned long flags; | ||
| 256 | |||
| 257 | spin_lock_irqsave(&adapter->hba_dbf_lock, flags); | ||
| 258 | memset(rec, 0, sizeof(struct zfcp_hba_dbf_record)); | ||
| 259 | strncpy(rec->tag, "stat", ZFCP_DBF_TAG_SIZE); | ||
| 260 | strncpy(rec->tag2, tag, ZFCP_DBF_TAG_SIZE); | ||
| 261 | |||
| 262 | rec->type.status.failed = adapter->status_read_failed; | ||
| 263 | if (status_buffer != NULL) { | ||
| 264 | rec->type.status.status_type = status_buffer->status_type; | ||
| 265 | rec->type.status.status_subtype = status_buffer->status_subtype; | ||
| 266 | memcpy(&rec->type.status.queue_designator, | ||
| 267 | &status_buffer->queue_designator, | ||
| 268 | sizeof(struct fsf_queue_designator)); | ||
| 269 | |||
| 270 | switch (status_buffer->status_type) { | ||
| 271 | case FSF_STATUS_READ_SENSE_DATA_AVAIL: | ||
| 272 | rec->type.status.payload_size = | ||
| 273 | ZFCP_DBF_UNSOL_PAYLOAD_SENSE_DATA_AVAIL; | ||
| 274 | break; | ||
| 275 | |||
| 276 | case FSF_STATUS_READ_BIT_ERROR_THRESHOLD: | ||
| 277 | rec->type.status.payload_size = | ||
| 278 | ZFCP_DBF_UNSOL_PAYLOAD_BIT_ERROR_THRESHOLD; | ||
| 279 | break; | ||
| 280 | |||
| 281 | case FSF_STATUS_READ_LINK_DOWN: | ||
| 282 | rec->type.status.payload_size = sizeof(u64); | ||
| 283 | break; | ||
| 284 | |||
| 285 | } | ||
| 286 | memcpy(&rec->type.status.payload, | ||
| 287 | &status_buffer->payload, rec->type.status.payload_size); | ||
| 288 | } | ||
| 289 | |||
| 290 | debug_event(adapter->hba_dbf, 2, | ||
| 291 | rec, sizeof(struct zfcp_hba_dbf_record)); | ||
| 292 | spin_unlock_irqrestore(&adapter->hba_dbf_lock, flags); | ||
| 293 | } | ||
| 294 | |||
| 295 | inline void | ||
| 296 | zfcp_hba_dbf_event_qdio(struct zfcp_adapter *adapter, unsigned int status, | ||
| 297 | unsigned int qdio_error, unsigned int siga_error, | ||
| 298 | int sbal_index, int sbal_count) | ||
| 299 | { | ||
| 300 | struct zfcp_hba_dbf_record *rec = &adapter->hba_dbf_buf; | ||
| 301 | unsigned long flags; | ||
| 302 | |||
| 303 | spin_lock_irqsave(&adapter->hba_dbf_lock, flags); | ||
| 304 | memset(rec, 0, sizeof(struct zfcp_hba_dbf_record)); | ||
| 305 | strncpy(rec->tag, "qdio", ZFCP_DBF_TAG_SIZE); | ||
| 306 | rec->type.qdio.status = status; | ||
| 307 | rec->type.qdio.qdio_error = qdio_error; | ||
| 308 | rec->type.qdio.siga_error = siga_error; | ||
| 309 | rec->type.qdio.sbal_index = sbal_index; | ||
| 310 | rec->type.qdio.sbal_count = sbal_count; | ||
| 311 | debug_event(adapter->hba_dbf, 0, | ||
| 312 | rec, sizeof(struct zfcp_hba_dbf_record)); | ||
| 313 | spin_unlock_irqrestore(&adapter->hba_dbf_lock, flags); | ||
| 314 | } | ||
| 315 | |||
| 316 | static inline int | ||
| 317 | zfcp_hba_dbf_view_response(char *out_buf, | ||
| 318 | struct zfcp_hba_dbf_record_response *rec) | ||
| 319 | { | ||
| 320 | int len = 0; | ||
| 321 | |||
| 322 | len += zfcp_dbf_view(out_buf + len, "fsf_command", "0x%08x", | ||
| 323 | rec->fsf_command); | ||
| 324 | len += zfcp_dbf_view(out_buf + len, "fsf_reqid", "0x%0Lx", | ||
| 325 | rec->fsf_reqid); | ||
| 326 | len += zfcp_dbf_view(out_buf + len, "fsf_seqno", "0x%08x", | ||
| 327 | rec->fsf_seqno); | ||
| 328 | len += zfcp_dbf_stck(out_buf + len, "fsf_issued", rec->fsf_issued); | ||
| 329 | len += zfcp_dbf_view(out_buf + len, "fsf_prot_status", "0x%08x", | ||
| 330 | rec->fsf_prot_status); | ||
| 331 | len += zfcp_dbf_view(out_buf + len, "fsf_status", "0x%08x", | ||
| 332 | rec->fsf_status); | ||
| 333 | len += zfcp_dbf_view_dump(out_buf + len, "fsf_prot_status_qual", | ||
| 334 | rec->fsf_prot_status_qual, | ||
| 335 | FSF_PROT_STATUS_QUAL_SIZE, | ||
| 336 | 0, FSF_PROT_STATUS_QUAL_SIZE); | ||
| 337 | len += zfcp_dbf_view_dump(out_buf + len, "fsf_status_qual", | ||
| 338 | rec->fsf_status_qual, | ||
| 339 | FSF_STATUS_QUALIFIER_SIZE, | ||
| 340 | 0, FSF_STATUS_QUALIFIER_SIZE); | ||
| 341 | len += zfcp_dbf_view(out_buf + len, "fsf_req_status", "0x%08x", | ||
| 342 | rec->fsf_req_status); | ||
| 343 | len += zfcp_dbf_view(out_buf + len, "sbal_first", "0x%02x", | ||
| 344 | rec->sbal_first); | ||
| 345 | len += zfcp_dbf_view(out_buf + len, "sbal_curr", "0x%02x", | ||
| 346 | rec->sbal_curr); | ||
| 347 | len += zfcp_dbf_view(out_buf + len, "sbal_last", "0x%02x", | ||
| 348 | rec->sbal_last); | ||
| 349 | len += zfcp_dbf_view(out_buf + len, "pool", "0x%02x", rec->pool); | ||
| 350 | |||
| 351 | switch (rec->fsf_command) { | ||
| 352 | case FSF_QTCB_FCP_CMND: | ||
| 353 | if (rec->fsf_req_status & ZFCP_STATUS_FSFREQ_TASK_MANAGEMENT) | ||
| 354 | break; | ||
| 355 | len += zfcp_dbf_view(out_buf + len, "scsi_cmnd", "0x%0Lx", | ||
| 356 | rec->data.send_fcp.scsi_cmnd); | ||
| 357 | len += zfcp_dbf_view(out_buf + len, "scsi_serial", "0x%016Lx", | ||
| 358 | rec->data.send_fcp.scsi_serial); | ||
| 359 | break; | ||
| 360 | |||
| 361 | case FSF_QTCB_OPEN_PORT_WITH_DID: | ||
| 362 | case FSF_QTCB_CLOSE_PORT: | ||
| 363 | case FSF_QTCB_CLOSE_PHYSICAL_PORT: | ||
| 364 | len += zfcp_dbf_view(out_buf + len, "wwpn", "0x%016Lx", | ||
| 365 | rec->data.port.wwpn); | ||
| 366 | len += zfcp_dbf_view(out_buf + len, "d_id", "0x%06x", | ||
| 367 | rec->data.port.d_id); | ||
| 368 | len += zfcp_dbf_view(out_buf + len, "port_handle", "0x%08x", | ||
| 369 | rec->data.port.port_handle); | ||
| 370 | break; | ||
| 371 | |||
| 372 | case FSF_QTCB_OPEN_LUN: | ||
| 373 | case FSF_QTCB_CLOSE_LUN: | ||
| 374 | len += zfcp_dbf_view(out_buf + len, "wwpn", "0x%016Lx", | ||
| 375 | rec->data.unit.wwpn); | ||
| 376 | len += zfcp_dbf_view(out_buf + len, "fcp_lun", "0x%016Lx", | ||
| 377 | rec->data.unit.fcp_lun); | ||
| 378 | len += zfcp_dbf_view(out_buf + len, "port_handle", "0x%08x", | ||
| 379 | rec->data.unit.port_handle); | ||
| 380 | len += zfcp_dbf_view(out_buf + len, "lun_handle", "0x%08x", | ||
| 381 | rec->data.unit.lun_handle); | ||
| 382 | break; | ||
| 383 | |||
| 384 | case FSF_QTCB_SEND_ELS: | ||
| 385 | len += zfcp_dbf_view(out_buf + len, "d_id", "0x%06x", | ||
| 386 | rec->data.send_els.d_id); | ||
| 387 | len += zfcp_dbf_view(out_buf + len, "ls_code", "0x%02x", | ||
| 388 | rec->data.send_els.ls_code); | ||
| 389 | break; | ||
| 390 | |||
| 391 | case FSF_QTCB_ABORT_FCP_CMND: | ||
| 392 | case FSF_QTCB_SEND_GENERIC: | ||
| 393 | case FSF_QTCB_EXCHANGE_CONFIG_DATA: | ||
| 394 | case FSF_QTCB_EXCHANGE_PORT_DATA: | ||
| 395 | case FSF_QTCB_DOWNLOAD_CONTROL_FILE: | ||
| 396 | case FSF_QTCB_UPLOAD_CONTROL_FILE: | ||
| 397 | break; | ||
| 398 | } | ||
| 399 | |||
| 400 | return len; | ||
| 401 | } | ||
| 402 | |||
| 403 | static inline int | ||
| 404 | zfcp_hba_dbf_view_status(char *out_buf, struct zfcp_hba_dbf_record_status *rec) | ||
| 405 | { | ||
| 406 | int len = 0; | ||
| 407 | |||
| 408 | len += zfcp_dbf_view(out_buf + len, "failed", "0x%02x", rec->failed); | ||
| 409 | len += zfcp_dbf_view(out_buf + len, "status_type", "0x%08x", | ||
| 410 | rec->status_type); | ||
| 411 | len += zfcp_dbf_view(out_buf + len, "status_subtype", "0x%08x", | ||
| 412 | rec->status_subtype); | ||
| 413 | len += zfcp_dbf_view_dump(out_buf + len, "queue_designator", | ||
| 414 | (char *)&rec->queue_designator, | ||
| 415 | sizeof(struct fsf_queue_designator), | ||
| 416 | 0, sizeof(struct fsf_queue_designator)); | ||
| 417 | len += zfcp_dbf_view_dump(out_buf + len, "payload", | ||
| 418 | (char *)&rec->payload, | ||
| 419 | rec->payload_size, 0, rec->payload_size); | ||
| 420 | |||
| 421 | return len; | ||
| 422 | } | ||
| 423 | |||
| 424 | static inline int | ||
| 425 | zfcp_hba_dbf_view_qdio(char *out_buf, struct zfcp_hba_dbf_record_qdio *rec) | ||
| 426 | { | ||
| 427 | int len = 0; | ||
| 428 | |||
| 429 | len += zfcp_dbf_view(out_buf + len, "status", "0x%08x", rec->status); | ||
| 430 | len += zfcp_dbf_view(out_buf + len, "qdio_error", "0x%08x", | ||
| 431 | rec->qdio_error); | ||
| 432 | len += zfcp_dbf_view(out_buf + len, "siga_error", "0x%08x", | ||
| 433 | rec->siga_error); | ||
| 434 | len += zfcp_dbf_view(out_buf + len, "sbal_index", "0x%02x", | ||
| 435 | rec->sbal_index); | ||
| 436 | len += zfcp_dbf_view(out_buf + len, "sbal_count", "0x%02x", | ||
| 437 | rec->sbal_count); | ||
| 438 | |||
| 439 | return len; | ||
| 440 | } | ||
| 441 | |||
| 442 | static int | ||
| 443 | zfcp_hba_dbf_view_format(debug_info_t * id, struct debug_view *view, | ||
| 444 | char *out_buf, const char *in_buf) | ||
| 445 | { | ||
| 446 | struct zfcp_hba_dbf_record *rec = (struct zfcp_hba_dbf_record *)in_buf; | ||
| 447 | int len = 0; | ||
| 448 | |||
| 449 | if (strncmp(rec->tag, "dump", ZFCP_DBF_TAG_SIZE) == 0) | ||
| 450 | return 0; | ||
| 451 | |||
| 452 | len += zfcp_dbf_tag(out_buf + len, "tag", rec->tag); | ||
| 453 | if (isalpha(rec->tag2[0])) | ||
| 454 | len += zfcp_dbf_tag(out_buf + len, "tag2", rec->tag2); | ||
| 455 | if (strncmp(rec->tag, "resp", ZFCP_DBF_TAG_SIZE) == 0) | ||
| 456 | len += zfcp_hba_dbf_view_response(out_buf + len, | ||
| 457 | &rec->type.response); | ||
| 458 | else if (strncmp(rec->tag, "stat", ZFCP_DBF_TAG_SIZE) == 0) | ||
| 459 | len += zfcp_hba_dbf_view_status(out_buf + len, | ||
| 460 | &rec->type.status); | ||
| 461 | else if (strncmp(rec->tag, "qdio", ZFCP_DBF_TAG_SIZE) == 0) | ||
| 462 | len += zfcp_hba_dbf_view_qdio(out_buf + len, &rec->type.qdio); | ||
| 463 | |||
| 464 | len += sprintf(out_buf + len, "\n"); | ||
| 465 | |||
| 466 | return len; | ||
| 467 | } | ||
| 468 | |||
| 469 | struct debug_view zfcp_hba_dbf_view = { | ||
| 470 | "structured", | ||
| 471 | NULL, | ||
| 472 | &zfcp_dbf_view_header, | ||
| 473 | &zfcp_hba_dbf_view_format, | ||
| 474 | NULL, | ||
| 475 | NULL | ||
| 476 | }; | ||
| 477 | |||
| 478 | inline void | ||
| 479 | _zfcp_san_dbf_event_common_ct(const char *tag, struct zfcp_fsf_req *fsf_req, | ||
| 480 | fc_id_t s_id, fc_id_t d_id, | ||
| 481 | void *buffer, int buflen) | ||
| 482 | { | ||
| 483 | struct zfcp_send_ct *send_ct = (struct zfcp_send_ct *)fsf_req->data; | ||
| 484 | struct zfcp_port *port = send_ct->port; | ||
| 485 | struct zfcp_adapter *adapter = port->adapter; | ||
| 486 | struct ct_hdr *header = (struct ct_hdr *)buffer; | ||
| 487 | struct zfcp_san_dbf_record *rec = &adapter->san_dbf_buf; | ||
| 488 | struct zfcp_san_dbf_record_ct *ct = &rec->type.ct; | ||
| 489 | unsigned long flags; | ||
| 490 | |||
| 491 | spin_lock_irqsave(&adapter->san_dbf_lock, flags); | ||
| 492 | memset(rec, 0, sizeof(struct zfcp_san_dbf_record)); | ||
| 493 | strncpy(rec->tag, tag, ZFCP_DBF_TAG_SIZE); | ||
| 494 | rec->fsf_reqid = (unsigned long)fsf_req; | ||
| 495 | rec->fsf_seqno = fsf_req->seq_no; | ||
| 496 | rec->s_id = s_id; | ||
| 497 | rec->d_id = d_id; | ||
| 498 | if (strncmp(tag, "octc", ZFCP_DBF_TAG_SIZE) == 0) { | ||
| 499 | ct->type.request.cmd_req_code = header->cmd_rsp_code; | ||
| 500 | ct->type.request.revision = header->revision; | ||
| 501 | ct->type.request.gs_type = header->gs_type; | ||
| 502 | ct->type.request.gs_subtype = header->gs_subtype; | ||
| 503 | ct->type.request.options = header->options; | ||
| 504 | ct->type.request.max_res_size = header->max_res_size; | ||
| 505 | } else if (strncmp(tag, "rctc", ZFCP_DBF_TAG_SIZE) == 0) { | ||
| 506 | ct->type.response.cmd_rsp_code = header->cmd_rsp_code; | ||
| 507 | ct->type.response.revision = header->revision; | ||
| 508 | ct->type.response.reason_code = header->reason_code; | ||
| 509 | ct->type.response.reason_code_expl = header->reason_code_expl; | ||
| 510 | ct->type.response.vendor_unique = header->vendor_unique; | ||
| 511 | } | ||
| 512 | ct->payload_size = | ||
| 513 | min(buflen - (int)sizeof(struct ct_hdr), ZFCP_DBF_CT_PAYLOAD); | ||
| 514 | memcpy(ct->payload, buffer + sizeof(struct ct_hdr), ct->payload_size); | ||
| 515 | debug_event(adapter->san_dbf, 3, | ||
| 516 | rec, sizeof(struct zfcp_san_dbf_record)); | ||
| 517 | spin_unlock_irqrestore(&adapter->san_dbf_lock, flags); | ||
| 518 | } | ||
| 519 | |||
| 520 | inline void zfcp_san_dbf_event_ct_request(struct zfcp_fsf_req *fsf_req) | ||
| 521 | { | ||
| 522 | struct zfcp_send_ct *ct = (struct zfcp_send_ct *)fsf_req->data; | ||
| 523 | struct zfcp_port *port = ct->port; | ||
| 524 | struct zfcp_adapter *adapter = port->adapter; | ||
| 525 | |||
| 526 | _zfcp_san_dbf_event_common_ct("octc", | ||
| 527 | fsf_req, adapter->s_id, port->d_id, | ||
| 528 | zfcp_sg_to_address(ct->req), | ||
| 529 | ct->req->length); | ||
| 530 | } | ||
| 531 | |||
| 532 | inline void zfcp_san_dbf_event_ct_response(struct zfcp_fsf_req *fsf_req) | ||
| 533 | { | ||
| 534 | struct zfcp_send_ct *ct = (struct zfcp_send_ct *)fsf_req->data; | ||
| 535 | struct zfcp_port *port = ct->port; | ||
| 536 | struct zfcp_adapter *adapter = port->adapter; | ||
| 537 | |||
| 538 | _zfcp_san_dbf_event_common_ct("rctc", | ||
| 539 | fsf_req, port->d_id, adapter->s_id, | ||
| 540 | zfcp_sg_to_address(ct->resp), | ||
| 541 | ct->resp->length); | ||
| 542 | } | ||
| 543 | |||
| 544 | static inline void | ||
| 545 | _zfcp_san_dbf_event_common_els(const char *tag, int level, | ||
| 546 | struct zfcp_fsf_req *fsf_req, | ||
| 547 | fc_id_t s_id, fc_id_t d_id, u8 ls_code, | ||
| 548 | void *buffer, int buflen) | ||
| 549 | { | ||
| 550 | struct zfcp_adapter *adapter = fsf_req->adapter; | ||
| 551 | struct zfcp_san_dbf_record *rec = &adapter->san_dbf_buf; | ||
| 552 | struct zfcp_dbf_dump *dump = (struct zfcp_dbf_dump *)rec; | ||
| 553 | unsigned long flags; | ||
| 554 | int offset = 0; | ||
| 555 | |||
| 556 | spin_lock_irqsave(&adapter->san_dbf_lock, flags); | ||
| 557 | do { | ||
| 558 | memset(rec, 0, sizeof(struct zfcp_san_dbf_record)); | ||
| 559 | if (offset == 0) { | ||
| 560 | strncpy(rec->tag, tag, ZFCP_DBF_TAG_SIZE); | ||
| 561 | rec->fsf_reqid = (unsigned long)fsf_req; | ||
| 562 | rec->fsf_seqno = fsf_req->seq_no; | ||
| 563 | rec->s_id = s_id; | ||
| 564 | rec->d_id = d_id; | ||
| 565 | rec->type.els.ls_code = ls_code; | ||
| 566 | buflen = min(buflen, ZFCP_DBF_ELS_MAX_PAYLOAD); | ||
| 567 | rec->type.els.payload_size = buflen; | ||
| 568 | memcpy(rec->type.els.payload, | ||
| 569 | buffer, min(buflen, ZFCP_DBF_ELS_PAYLOAD)); | ||
| 570 | offset += min(buflen, ZFCP_DBF_ELS_PAYLOAD); | ||
| 571 | } else { | ||
| 572 | strncpy(dump->tag, "dump", ZFCP_DBF_TAG_SIZE); | ||
| 573 | dump->total_size = buflen; | ||
| 574 | dump->offset = offset; | ||
| 575 | dump->size = min(buflen - offset, | ||
| 576 | (int)sizeof(struct zfcp_san_dbf_record) | ||
| 577 | - (int)sizeof(struct zfcp_dbf_dump)); | ||
| 578 | memcpy(dump->data, buffer + offset, dump->size); | ||
| 579 | offset += dump->size; | ||
| 580 | } | ||
| 581 | debug_event(adapter->san_dbf, level, | ||
| 582 | rec, sizeof(struct zfcp_san_dbf_record)); | ||
| 583 | } while (offset < buflen); | ||
| 584 | spin_unlock_irqrestore(&adapter->san_dbf_lock, flags); | ||
| 585 | } | ||
| 586 | |||
| 587 | inline void zfcp_san_dbf_event_els_request(struct zfcp_fsf_req *fsf_req) | ||
| 588 | { | ||
| 589 | struct zfcp_send_els *els = (struct zfcp_send_els *)fsf_req->data; | ||
| 590 | |||
| 591 | _zfcp_san_dbf_event_common_els("oels", 2, | ||
| 592 | fsf_req, els->adapter->s_id, els->d_id, | ||
| 593 | *(u8 *) zfcp_sg_to_address(els->req), | ||
| 594 | zfcp_sg_to_address(els->req), | ||
| 595 | els->req->length); | ||
| 596 | } | ||
| 597 | |||
| 598 | inline void zfcp_san_dbf_event_els_response(struct zfcp_fsf_req *fsf_req) | ||
| 599 | { | ||
| 600 | struct zfcp_send_els *els = (struct zfcp_send_els *)fsf_req->data; | ||
| 601 | |||
| 602 | _zfcp_san_dbf_event_common_els("rels", 2, | ||
| 603 | fsf_req, els->d_id, els->adapter->s_id, | ||
| 604 | *(u8 *) zfcp_sg_to_address(els->req), | ||
| 605 | zfcp_sg_to_address(els->resp), | ||
| 606 | els->resp->length); | ||
| 607 | } | ||
| 608 | |||
| 609 | inline void zfcp_san_dbf_event_incoming_els(struct zfcp_fsf_req *fsf_req) | ||
| 610 | { | ||
| 611 | struct zfcp_adapter *adapter = fsf_req->adapter; | ||
| 612 | struct fsf_status_read_buffer *status_buffer = | ||
| 613 | (struct fsf_status_read_buffer *)fsf_req->data; | ||
| 614 | int length = (int)status_buffer->length - | ||
| 615 | (int)((void *)&status_buffer->payload - (void *)status_buffer); | ||
| 616 | |||
| 617 | _zfcp_san_dbf_event_common_els("iels", 1, | ||
| 618 | fsf_req, status_buffer->d_id, | ||
| 619 | adapter->s_id, | ||
| 620 | *(u8 *) status_buffer->payload, | ||
| 621 | (void *)status_buffer->payload, length); | ||
| 622 | } | ||
| 623 | |||
| 624 | static int | ||
| 625 | zfcp_san_dbf_view_format(debug_info_t * id, struct debug_view *view, | ||
| 626 | char *out_buf, const char *in_buf) | ||
| 627 | { | ||
| 628 | struct zfcp_san_dbf_record *rec = (struct zfcp_san_dbf_record *)in_buf; | ||
| 629 | char *buffer = NULL; | ||
| 630 | int buflen = 0, total = 0; | ||
| 631 | int len = 0; | ||
| 632 | |||
| 633 | if (strncmp(rec->tag, "dump", ZFCP_DBF_TAG_SIZE) == 0) | ||
| 634 | return 0; | ||
| 635 | |||
| 636 | len += zfcp_dbf_tag(out_buf + len, "tag", rec->tag); | ||
| 637 | len += zfcp_dbf_view(out_buf + len, "fsf_reqid", "0x%0Lx", | ||
| 638 | rec->fsf_reqid); | ||
| 639 | len += zfcp_dbf_view(out_buf + len, "fsf_seqno", "0x%08x", | ||
| 640 | rec->fsf_seqno); | ||
| 641 | len += zfcp_dbf_view(out_buf + len, "s_id", "0x%06x", rec->s_id); | ||
| 642 | len += zfcp_dbf_view(out_buf + len, "d_id", "0x%06x", rec->d_id); | ||
| 643 | |||
| 644 | if (strncmp(rec->tag, "octc", ZFCP_DBF_TAG_SIZE) == 0) { | ||
| 645 | len += zfcp_dbf_view(out_buf + len, "cmd_req_code", "0x%04x", | ||
| 646 | rec->type.ct.type.request.cmd_req_code); | ||
| 647 | len += zfcp_dbf_view(out_buf + len, "revision", "0x%02x", | ||
| 648 | rec->type.ct.type.request.revision); | ||
| 649 | len += zfcp_dbf_view(out_buf + len, "gs_type", "0x%02x", | ||
| 650 | rec->type.ct.type.request.gs_type); | ||
| 651 | len += zfcp_dbf_view(out_buf + len, "gs_subtype", "0x%02x", | ||
| 652 | rec->type.ct.type.request.gs_subtype); | ||
| 653 | len += zfcp_dbf_view(out_buf + len, "options", "0x%02x", | ||
| 654 | rec->type.ct.type.request.options); | ||
| 655 | len += zfcp_dbf_view(out_buf + len, "max_res_size", "0x%04x", | ||
| 656 | rec->type.ct.type.request.max_res_size); | ||
| 657 | total = rec->type.ct.payload_size; | ||
| 658 | buffer = rec->type.ct.payload; | ||
| 659 | buflen = min(total, ZFCP_DBF_CT_PAYLOAD); | ||
| 660 | } else if (strncmp(rec->tag, "rctc", ZFCP_DBF_TAG_SIZE) == 0) { | ||
| 661 | len += zfcp_dbf_view(out_buf + len, "cmd_rsp_code", "0x%04x", | ||
| 662 | rec->type.ct.type.response.cmd_rsp_code); | ||
| 663 | len += zfcp_dbf_view(out_buf + len, "revision", "0x%02x", | ||
| 664 | rec->type.ct.type.response.revision); | ||
| 665 | len += zfcp_dbf_view(out_buf + len, "reason_code", "0x%02x", | ||
| 666 | rec->type.ct.type.response.reason_code); | ||
| 667 | len += | ||
| 668 | zfcp_dbf_view(out_buf + len, "reason_code_expl", "0x%02x", | ||
| 669 | rec->type.ct.type.response.reason_code_expl); | ||
| 670 | len += | ||
| 671 | zfcp_dbf_view(out_buf + len, "vendor_unique", "0x%02x", | ||
| 672 | rec->type.ct.type.response.vendor_unique); | ||
| 673 | total = rec->type.ct.payload_size; | ||
| 674 | buffer = rec->type.ct.payload; | ||
| 675 | buflen = min(total, ZFCP_DBF_CT_PAYLOAD); | ||
| 676 | } else if (strncmp(rec->tag, "oels", ZFCP_DBF_TAG_SIZE) == 0 || | ||
| 677 | strncmp(rec->tag, "rels", ZFCP_DBF_TAG_SIZE) == 0 || | ||
| 678 | strncmp(rec->tag, "iels", ZFCP_DBF_TAG_SIZE) == 0) { | ||
| 679 | len += zfcp_dbf_view(out_buf + len, "ls_code", "0x%02x", | ||
| 680 | rec->type.els.ls_code); | ||
| 681 | total = rec->type.els.payload_size; | ||
| 682 | buffer = rec->type.els.payload; | ||
| 683 | buflen = min(total, ZFCP_DBF_ELS_PAYLOAD); | ||
| 684 | } | ||
| 685 | |||
| 686 | len += zfcp_dbf_view_dump(out_buf + len, "payload", | ||
| 687 | buffer, buflen, 0, total); | ||
| 688 | |||
| 689 | if (buflen == total) | ||
| 690 | len += sprintf(out_buf + len, "\n"); | ||
| 691 | |||
| 692 | return len; | ||
| 693 | } | ||
| 694 | |||
| 695 | struct debug_view zfcp_san_dbf_view = { | ||
| 696 | "structured", | ||
| 697 | NULL, | ||
| 698 | &zfcp_dbf_view_header, | ||
| 699 | &zfcp_san_dbf_view_format, | ||
| 700 | NULL, | ||
| 701 | NULL | ||
| 702 | }; | ||
| 703 | |||
| 704 | static inline void | ||
| 705 | _zfcp_scsi_dbf_event_common(const char *tag, const char *tag2, int level, | ||
| 706 | struct zfcp_adapter *adapter, | ||
| 707 | struct scsi_cmnd *scsi_cmnd, | ||
| 708 | struct zfcp_fsf_req *new_fsf_req) | ||
| 709 | { | ||
| 710 | struct zfcp_fsf_req *fsf_req = | ||
| 711 | (struct zfcp_fsf_req *)scsi_cmnd->host_scribble; | ||
| 712 | struct zfcp_scsi_dbf_record *rec = &adapter->scsi_dbf_buf; | ||
| 713 | struct zfcp_dbf_dump *dump = (struct zfcp_dbf_dump *)rec; | ||
| 714 | unsigned long flags; | ||
| 715 | struct fcp_rsp_iu *fcp_rsp; | ||
| 716 | char *fcp_rsp_info = NULL, *fcp_sns_info = NULL; | ||
| 717 | int offset = 0, buflen = 0; | ||
| 718 | |||
| 719 | spin_lock_irqsave(&adapter->scsi_dbf_lock, flags); | ||
| 720 | do { | ||
| 721 | memset(rec, 0, sizeof(struct zfcp_scsi_dbf_record)); | ||
| 722 | if (offset == 0) { | ||
| 723 | strncpy(rec->tag, tag, ZFCP_DBF_TAG_SIZE); | ||
| 724 | strncpy(rec->tag2, tag2, ZFCP_DBF_TAG_SIZE); | ||
| 725 | if (scsi_cmnd->device) { | ||
| 726 | rec->scsi_id = scsi_cmnd->device->id; | ||
| 727 | rec->scsi_lun = scsi_cmnd->device->lun; | ||
| 728 | } | ||
| 729 | rec->scsi_result = scsi_cmnd->result; | ||
| 730 | rec->scsi_cmnd = (unsigned long)scsi_cmnd; | ||
| 731 | rec->scsi_serial = scsi_cmnd->serial_number; | ||
| 732 | memcpy(rec->scsi_opcode, | ||
| 733 | &scsi_cmnd->cmnd, | ||
| 734 | min((int)scsi_cmnd->cmd_len, | ||
| 735 | ZFCP_DBF_SCSI_OPCODE)); | ||
| 736 | rec->scsi_retries = scsi_cmnd->retries; | ||
| 737 | rec->scsi_allowed = scsi_cmnd->allowed; | ||
| 738 | if (fsf_req != NULL) { | ||
| 739 | fcp_rsp = (struct fcp_rsp_iu *) | ||
| 740 | &(fsf_req->qtcb->bottom.io.fcp_rsp); | ||
| 741 | fcp_rsp_info = | ||
| 742 | zfcp_get_fcp_rsp_info_ptr(fcp_rsp); | ||
| 743 | fcp_sns_info = | ||
| 744 | zfcp_get_fcp_sns_info_ptr(fcp_rsp); | ||
| 745 | |||
| 746 | rec->type.fcp.rsp_validity = | ||
| 747 | fcp_rsp->validity.value; | ||
| 748 | rec->type.fcp.rsp_scsi_status = | ||
| 749 | fcp_rsp->scsi_status; | ||
| 750 | rec->type.fcp.rsp_resid = fcp_rsp->fcp_resid; | ||
| 751 | if (fcp_rsp->validity.bits.fcp_rsp_len_valid) | ||
| 752 | rec->type.fcp.rsp_code = | ||
| 753 | *(fcp_rsp_info + 3); | ||
| 754 | if (fcp_rsp->validity.bits.fcp_sns_len_valid) { | ||
| 755 | buflen = min((int)fcp_rsp->fcp_sns_len, | ||
| 756 | ZFCP_DBF_SCSI_MAX_FCP_SNS_INFO); | ||
| 757 | rec->type.fcp.sns_info_len = buflen; | ||
| 758 | memcpy(rec->type.fcp.sns_info, | ||
| 759 | fcp_sns_info, | ||
| 760 | min(buflen, | ||
| 761 | ZFCP_DBF_SCSI_FCP_SNS_INFO)); | ||
| 762 | offset += min(buflen, | ||
| 763 | ZFCP_DBF_SCSI_FCP_SNS_INFO); | ||
| 764 | } | ||
| 765 | |||
| 766 | rec->fsf_reqid = (unsigned long)fsf_req; | ||
| 767 | rec->fsf_seqno = fsf_req->seq_no; | ||
| 768 | rec->fsf_issued = fsf_req->issued; | ||
| 769 | } | ||
| 770 | if (new_fsf_req != NULL) { | ||
| 771 | rec->type.new_fsf_req.fsf_reqid = | ||
| 772 | (unsigned long) | ||
| 773 | new_fsf_req; | ||
| 774 | rec->type.new_fsf_req.fsf_seqno = | ||
| 775 | new_fsf_req->seq_no; | ||
| 776 | rec->type.new_fsf_req.fsf_issued = | ||
| 777 | new_fsf_req->issued; | ||
| 778 | } | ||
| 779 | } else { | ||
| 780 | strncpy(dump->tag, "dump", ZFCP_DBF_TAG_SIZE); | ||
| 781 | dump->total_size = buflen; | ||
| 782 | dump->offset = offset; | ||
| 783 | dump->size = min(buflen - offset, | ||
| 784 | (int)sizeof(struct | ||
| 785 | zfcp_scsi_dbf_record) - | ||
| 786 | (int)sizeof(struct zfcp_dbf_dump)); | ||
| 787 | memcpy(dump->data, fcp_sns_info + offset, dump->size); | ||
| 788 | offset += dump->size; | ||
| 789 | } | ||
| 790 | debug_event(adapter->scsi_dbf, level, | ||
| 791 | rec, sizeof(struct zfcp_scsi_dbf_record)); | ||
| 792 | } while (offset < buflen); | ||
| 793 | spin_unlock_irqrestore(&adapter->scsi_dbf_lock, flags); | ||
| 794 | } | ||
| 795 | |||
| 796 | inline void | ||
| 797 | zfcp_scsi_dbf_event_result(const char *tag, int level, | ||
| 798 | struct zfcp_adapter *adapter, | ||
| 799 | struct scsi_cmnd *scsi_cmnd) | ||
| 800 | { | ||
| 801 | _zfcp_scsi_dbf_event_common("rslt", | ||
| 802 | tag, level, adapter, scsi_cmnd, NULL); | ||
| 803 | } | ||
| 804 | |||
| 805 | inline void | ||
| 806 | zfcp_scsi_dbf_event_abort(const char *tag, struct zfcp_adapter *adapter, | ||
| 807 | struct scsi_cmnd *scsi_cmnd, | ||
| 808 | struct zfcp_fsf_req *new_fsf_req) | ||
| 809 | { | ||
| 810 | _zfcp_scsi_dbf_event_common("abrt", | ||
| 811 | tag, 1, adapter, scsi_cmnd, new_fsf_req); | ||
| 812 | } | ||
| 813 | |||
| 814 | inline void | ||
| 815 | zfcp_scsi_dbf_event_devreset(const char *tag, u8 flag, struct zfcp_unit *unit, | ||
| 816 | struct scsi_cmnd *scsi_cmnd) | ||
| 817 | { | ||
| 818 | struct zfcp_adapter *adapter = unit->port->adapter; | ||
| 819 | |||
| 820 | _zfcp_scsi_dbf_event_common(flag == FCP_TARGET_RESET ? "trst" : "lrst", | ||
| 821 | tag, 1, adapter, scsi_cmnd, NULL); | ||
| 822 | } | ||
| 823 | |||
| 824 | static int | ||
| 825 | zfcp_scsi_dbf_view_format(debug_info_t * id, struct debug_view *view, | ||
| 826 | char *out_buf, const char *in_buf) | ||
| 827 | { | ||
| 828 | struct zfcp_scsi_dbf_record *rec = | ||
| 829 | (struct zfcp_scsi_dbf_record *)in_buf; | ||
| 830 | int len = 0; | ||
| 831 | |||
| 832 | if (strncmp(rec->tag, "dump", ZFCP_DBF_TAG_SIZE) == 0) | ||
| 833 | return 0; | ||
| 834 | |||
| 835 | len += zfcp_dbf_tag(out_buf + len, "tag", rec->tag); | ||
| 836 | len += zfcp_dbf_tag(out_buf + len, "tag2", rec->tag2); | ||
| 837 | len += zfcp_dbf_view(out_buf + len, "scsi_id", "0x%08x", rec->scsi_id); | ||
| 838 | len += zfcp_dbf_view(out_buf + len, "scsi_lun", "0x%08x", | ||
| 839 | rec->scsi_lun); | ||
| 840 | len += zfcp_dbf_view(out_buf + len, "scsi_result", "0x%08x", | ||
| 841 | rec->scsi_result); | ||
| 842 | len += zfcp_dbf_view(out_buf + len, "scsi_cmnd", "0x%0Lx", | ||
| 843 | rec->scsi_cmnd); | ||
| 844 | len += zfcp_dbf_view(out_buf + len, "scsi_serial", "0x%016Lx", | ||
| 845 | rec->scsi_serial); | ||
| 846 | len += zfcp_dbf_view_dump(out_buf + len, "scsi_opcode", | ||
| 847 | rec->scsi_opcode, | ||
| 848 | ZFCP_DBF_SCSI_OPCODE, | ||
| 849 | 0, ZFCP_DBF_SCSI_OPCODE); | ||
| 850 | len += zfcp_dbf_view(out_buf + len, "scsi_retries", "0x%02x", | ||
| 851 | rec->scsi_retries); | ||
| 852 | len += zfcp_dbf_view(out_buf + len, "scsi_allowed", "0x%02x", | ||
| 853 | rec->scsi_allowed); | ||
| 854 | len += zfcp_dbf_view(out_buf + len, "fsf_reqid", "0x%0Lx", | ||
| 855 | rec->fsf_reqid); | ||
| 856 | len += zfcp_dbf_view(out_buf + len, "fsf_seqno", "0x%08x", | ||
| 857 | rec->fsf_seqno); | ||
| 858 | len += zfcp_dbf_stck(out_buf + len, "fsf_issued", rec->fsf_issued); | ||
| 859 | if (strncmp(rec->tag, "rslt", ZFCP_DBF_TAG_SIZE) == 0) { | ||
| 860 | len += | ||
| 861 | zfcp_dbf_view(out_buf + len, "fcp_rsp_validity", "0x%02x", | ||
| 862 | rec->type.fcp.rsp_validity); | ||
| 863 | len += | ||
| 864 | zfcp_dbf_view(out_buf + len, "fcp_rsp_scsi_status", | ||
| 865 | "0x%02x", rec->type.fcp.rsp_scsi_status); | ||
| 866 | len += | ||
| 867 | zfcp_dbf_view(out_buf + len, "fcp_rsp_resid", "0x%08x", | ||
| 868 | rec->type.fcp.rsp_resid); | ||
| 869 | len += | ||
| 870 | zfcp_dbf_view(out_buf + len, "fcp_rsp_code", "0x%08x", | ||
| 871 | rec->type.fcp.rsp_code); | ||
| 872 | len += | ||
| 873 | zfcp_dbf_view(out_buf + len, "fcp_sns_info_len", "0x%08x", | ||
| 874 | rec->type.fcp.sns_info_len); | ||
| 875 | len += | ||
| 876 | zfcp_dbf_view_dump(out_buf + len, "fcp_sns_info", | ||
| 877 | rec->type.fcp.sns_info, | ||
| 878 | min((int)rec->type.fcp.sns_info_len, | ||
| 879 | ZFCP_DBF_SCSI_FCP_SNS_INFO), 0, | ||
| 880 | rec->type.fcp.sns_info_len); | ||
| 881 | } else if (strncmp(rec->tag, "abrt", ZFCP_DBF_TAG_SIZE) == 0) { | ||
| 882 | len += zfcp_dbf_view(out_buf + len, "fsf_reqid_abort", "0x%0Lx", | ||
| 883 | rec->type.new_fsf_req.fsf_reqid); | ||
| 884 | len += zfcp_dbf_view(out_buf + len, "fsf_seqno_abort", "0x%08x", | ||
| 885 | rec->type.new_fsf_req.fsf_seqno); | ||
| 886 | len += zfcp_dbf_stck(out_buf + len, "fsf_issued", | ||
| 887 | rec->type.new_fsf_req.fsf_issued); | ||
| 888 | } else if ((strncmp(rec->tag, "trst", ZFCP_DBF_TAG_SIZE) == 0) || | ||
| 889 | (strncmp(rec->tag, "lrst", ZFCP_DBF_TAG_SIZE) == 0)) { | ||
| 890 | len += zfcp_dbf_view(out_buf + len, "fsf_reqid_reset", "0x%0Lx", | ||
| 891 | rec->type.new_fsf_req.fsf_reqid); | ||
| 892 | len += zfcp_dbf_view(out_buf + len, "fsf_seqno_reset", "0x%08x", | ||
| 893 | rec->type.new_fsf_req.fsf_seqno); | ||
| 894 | len += zfcp_dbf_stck(out_buf + len, "fsf_issued", | ||
| 895 | rec->type.new_fsf_req.fsf_issued); | ||
| 896 | } | ||
| 897 | |||
| 898 | len += sprintf(out_buf + len, "\n"); | ||
| 899 | |||
| 900 | return len; | ||
| 901 | } | ||
| 902 | |||
| 903 | struct debug_view zfcp_scsi_dbf_view = { | ||
| 904 | "structured", | ||
| 905 | NULL, | ||
| 906 | &zfcp_dbf_view_header, | ||
| 907 | &zfcp_scsi_dbf_view_format, | ||
| 908 | NULL, | ||
| 909 | NULL | ||
| 910 | }; | ||
| 911 | |||
| 912 | /** | ||
| 913 | * zfcp_adapter_debug_register - registers debug feature for an adapter | ||
| 914 | * @adapter: pointer to adapter for which debug features should be registered | ||
| 915 | * return: -ENOMEM on error, 0 otherwise | ||
| 916 | */ | ||
| 917 | int zfcp_adapter_debug_register(struct zfcp_adapter *adapter) | ||
| 918 | { | ||
| 919 | char dbf_name[DEBUG_MAX_NAME_LEN]; | ||
| 920 | |||
| 921 | /* debug feature area which records recovery activity */ | ||
| 922 | spin_lock_init(&adapter->erp_dbf_lock); | ||
| 923 | sprintf(dbf_name, "zfcp_%s_erp", zfcp_get_busid_by_adapter(adapter)); | ||
| 924 | adapter->erp_dbf = debug_register(dbf_name, dbfsize, 2, | ||
| 925 | sizeof(struct zfcp_erp_dbf_record)); | ||
| 926 | if (!adapter->erp_dbf) | ||
| 927 | goto failed; | ||
| 928 | debug_register_view(adapter->erp_dbf, &debug_hex_ascii_view); | ||
| 929 | debug_set_level(adapter->erp_dbf, 3); | ||
| 930 | |||
| 931 | /* debug feature area which records HBA (FSF and QDIO) conditions */ | ||
| 932 | spin_lock_init(&adapter->hba_dbf_lock); | ||
| 933 | sprintf(dbf_name, "zfcp_%s_hba", zfcp_get_busid_by_adapter(adapter)); | ||
| 934 | adapter->hba_dbf = debug_register(dbf_name, dbfsize, 1, | ||
| 935 | sizeof(struct zfcp_hba_dbf_record)); | ||
| 936 | if (!adapter->hba_dbf) | ||
| 937 | goto failed; | ||
| 938 | debug_register_view(adapter->hba_dbf, &debug_hex_ascii_view); | ||
| 939 | debug_register_view(adapter->hba_dbf, &zfcp_hba_dbf_view); | ||
| 940 | debug_set_level(adapter->hba_dbf, 3); | ||
| 941 | |||
| 942 | /* debug feature area which records SAN command failures and recovery */ | ||
| 943 | spin_lock_init(&adapter->san_dbf_lock); | ||
| 944 | sprintf(dbf_name, "zfcp_%s_san", zfcp_get_busid_by_adapter(adapter)); | ||
| 945 | adapter->san_dbf = debug_register(dbf_name, dbfsize, 1, | ||
| 946 | sizeof(struct zfcp_san_dbf_record)); | ||
| 947 | if (!adapter->san_dbf) | ||
| 948 | goto failed; | ||
| 949 | debug_register_view(adapter->san_dbf, &debug_hex_ascii_view); | ||
| 950 | debug_register_view(adapter->san_dbf, &zfcp_san_dbf_view); | ||
| 951 | debug_set_level(adapter->san_dbf, 6); | ||
| 952 | |||
| 953 | /* debug feature area which records SCSI command failures and recovery */ | ||
| 954 | spin_lock_init(&adapter->scsi_dbf_lock); | ||
| 955 | sprintf(dbf_name, "zfcp_%s_scsi", zfcp_get_busid_by_adapter(adapter)); | ||
| 956 | adapter->scsi_dbf = debug_register(dbf_name, dbfsize, 1, | ||
| 957 | sizeof(struct zfcp_scsi_dbf_record)); | ||
| 958 | if (!adapter->scsi_dbf) | ||
| 959 | goto failed; | ||
| 960 | debug_register_view(adapter->scsi_dbf, &debug_hex_ascii_view); | ||
| 961 | debug_register_view(adapter->scsi_dbf, &zfcp_scsi_dbf_view); | ||
| 962 | debug_set_level(adapter->scsi_dbf, 3); | ||
| 963 | |||
| 964 | return 0; | ||
| 965 | |||
| 966 | failed: | ||
| 967 | zfcp_adapter_debug_unregister(adapter); | ||
| 968 | |||
| 969 | return -ENOMEM; | ||
| 970 | } | ||
| 971 | |||
| 972 | /** | ||
| 973 | * zfcp_adapter_debug_unregister - unregisters debug feature for an adapter | ||
| 974 | * @adapter: pointer to adapter for which debug features should be unregistered | ||
| 975 | */ | ||
| 976 | void zfcp_adapter_debug_unregister(struct zfcp_adapter *adapter) | ||
| 977 | { | ||
| 978 | debug_unregister(adapter->scsi_dbf); | ||
| 979 | debug_unregister(adapter->san_dbf); | ||
| 980 | debug_unregister(adapter->hba_dbf); | ||
| 981 | debug_unregister(adapter->erp_dbf); | ||
| 982 | adapter->scsi_dbf = NULL; | ||
| 983 | adapter->san_dbf = NULL; | ||
| 984 | adapter->hba_dbf = NULL; | ||
| 985 | adapter->erp_dbf = NULL; | ||
| 986 | } | ||
| 987 | |||
| 988 | #undef ZFCP_LOG_AREA | ||
diff --git a/drivers/s390/scsi/zfcp_def.h b/drivers/s390/scsi/zfcp_def.h index 9160e68c4a21..fc5bb6f31808 100644 --- a/drivers/s390/scsi/zfcp_def.h +++ b/drivers/s390/scsi/zfcp_def.h | |||
| @@ -66,7 +66,7 @@ | |||
| 66 | /********************* GENERAL DEFINES *********************************/ | 66 | /********************* GENERAL DEFINES *********************************/ |
| 67 | 67 | ||
| 68 | /* zfcp version number, it consists of major, minor, and patch-level number */ | 68 | /* zfcp version number, it consists of major, minor, and patch-level number */ |
| 69 | #define ZFCP_VERSION "4.3.0" | 69 | #define ZFCP_VERSION "4.4.0" |
| 70 | 70 | ||
| 71 | /** | 71 | /** |
| 72 | * zfcp_sg_to_address - determine kernel address from struct scatterlist | 72 | * zfcp_sg_to_address - determine kernel address from struct scatterlist |
| @@ -281,6 +281,171 @@ struct fcp_logo { | |||
| 281 | } __attribute__((packed)); | 281 | } __attribute__((packed)); |
| 282 | 282 | ||
| 283 | /* | 283 | /* |
| 284 | * DBF stuff | ||
| 285 | */ | ||
| 286 | #define ZFCP_DBF_TAG_SIZE 4 | ||
| 287 | |||
| 288 | struct zfcp_dbf_dump { | ||
| 289 | u8 tag[ZFCP_DBF_TAG_SIZE]; | ||
| 290 | u32 total_size; /* size of total dump data */ | ||
| 291 | u32 offset; /* how much data has being already dumped */ | ||
| 292 | u32 size; /* how much data comes with this record */ | ||
| 293 | u8 data[]; /* dump data */ | ||
| 294 | } __attribute__ ((packed)); | ||
| 295 | |||
| 296 | /* FIXME: to be inflated when reworking the erp dbf */ | ||
| 297 | struct zfcp_erp_dbf_record { | ||
| 298 | u8 dummy[16]; | ||
| 299 | } __attribute__ ((packed)); | ||
| 300 | |||
| 301 | struct zfcp_hba_dbf_record_response { | ||
| 302 | u32 fsf_command; | ||
| 303 | u64 fsf_reqid; | ||
| 304 | u32 fsf_seqno; | ||
| 305 | u64 fsf_issued; | ||
| 306 | u32 fsf_prot_status; | ||
| 307 | u32 fsf_status; | ||
| 308 | u8 fsf_prot_status_qual[FSF_PROT_STATUS_QUAL_SIZE]; | ||
| 309 | u8 fsf_status_qual[FSF_STATUS_QUALIFIER_SIZE]; | ||
| 310 | u32 fsf_req_status; | ||
| 311 | u8 sbal_first; | ||
| 312 | u8 sbal_curr; | ||
| 313 | u8 sbal_last; | ||
| 314 | u8 pool; | ||
| 315 | u64 erp_action; | ||
| 316 | union { | ||
| 317 | struct { | ||
| 318 | u64 scsi_cmnd; | ||
| 319 | u64 scsi_serial; | ||
| 320 | } send_fcp; | ||
| 321 | struct { | ||
| 322 | u64 wwpn; | ||
| 323 | u32 d_id; | ||
| 324 | u32 port_handle; | ||
| 325 | } port; | ||
| 326 | struct { | ||
| 327 | u64 wwpn; | ||
| 328 | u64 fcp_lun; | ||
| 329 | u32 port_handle; | ||
| 330 | u32 lun_handle; | ||
| 331 | } unit; | ||
| 332 | struct { | ||
| 333 | u32 d_id; | ||
| 334 | u8 ls_code; | ||
| 335 | } send_els; | ||
| 336 | } data; | ||
| 337 | } __attribute__ ((packed)); | ||
| 338 | |||
| 339 | struct zfcp_hba_dbf_record_status { | ||
| 340 | u8 failed; | ||
| 341 | u32 status_type; | ||
| 342 | u32 status_subtype; | ||
| 343 | struct fsf_queue_designator | ||
| 344 | queue_designator; | ||
| 345 | u32 payload_size; | ||
| 346 | #define ZFCP_DBF_UNSOL_PAYLOAD 80 | ||
| 347 | #define ZFCP_DBF_UNSOL_PAYLOAD_SENSE_DATA_AVAIL 32 | ||
| 348 | #define ZFCP_DBF_UNSOL_PAYLOAD_BIT_ERROR_THRESHOLD 56 | ||
| 349 | #define ZFCP_DBF_UNSOL_PAYLOAD_FEATURE_UPDATE_ALERT 2 * sizeof(u32) | ||
| 350 | u8 payload[ZFCP_DBF_UNSOL_PAYLOAD]; | ||
| 351 | } __attribute__ ((packed)); | ||
| 352 | |||
| 353 | struct zfcp_hba_dbf_record_qdio { | ||
| 354 | u32 status; | ||
| 355 | u32 qdio_error; | ||
| 356 | u32 siga_error; | ||
| 357 | u8 sbal_index; | ||
| 358 | u8 sbal_count; | ||
| 359 | } __attribute__ ((packed)); | ||
| 360 | |||
| 361 | struct zfcp_hba_dbf_record { | ||
| 362 | u8 tag[ZFCP_DBF_TAG_SIZE]; | ||
| 363 | u8 tag2[ZFCP_DBF_TAG_SIZE]; | ||
| 364 | union { | ||
| 365 | struct zfcp_hba_dbf_record_response response; | ||
| 366 | struct zfcp_hba_dbf_record_status status; | ||
| 367 | struct zfcp_hba_dbf_record_qdio qdio; | ||
| 368 | } type; | ||
| 369 | } __attribute__ ((packed)); | ||
| 370 | |||
| 371 | struct zfcp_san_dbf_record_ct { | ||
| 372 | union { | ||
| 373 | struct { | ||
| 374 | u16 cmd_req_code; | ||
| 375 | u8 revision; | ||
| 376 | u8 gs_type; | ||
| 377 | u8 gs_subtype; | ||
| 378 | u8 options; | ||
| 379 | u16 max_res_size; | ||
| 380 | } request; | ||
| 381 | struct { | ||
| 382 | u16 cmd_rsp_code; | ||
| 383 | u8 revision; | ||
| 384 | u8 reason_code; | ||
| 385 | u8 reason_code_expl; | ||
| 386 | u8 vendor_unique; | ||
| 387 | } response; | ||
| 388 | } type; | ||
| 389 | u32 payload_size; | ||
| 390 | #define ZFCP_DBF_CT_PAYLOAD 24 | ||
| 391 | u8 payload[ZFCP_DBF_CT_PAYLOAD]; | ||
| 392 | } __attribute__ ((packed)); | ||
| 393 | |||
| 394 | struct zfcp_san_dbf_record_els { | ||
| 395 | u8 ls_code; | ||
| 396 | u32 payload_size; | ||
| 397 | #define ZFCP_DBF_ELS_PAYLOAD 32 | ||
| 398 | #define ZFCP_DBF_ELS_MAX_PAYLOAD 1024 | ||
| 399 | u8 payload[ZFCP_DBF_ELS_PAYLOAD]; | ||
| 400 | } __attribute__ ((packed)); | ||
| 401 | |||
| 402 | struct zfcp_san_dbf_record { | ||
| 403 | u8 tag[ZFCP_DBF_TAG_SIZE]; | ||
| 404 | u64 fsf_reqid; | ||
| 405 | u32 fsf_seqno; | ||
| 406 | u32 s_id; | ||
| 407 | u32 d_id; | ||
| 408 | union { | ||
| 409 | struct zfcp_san_dbf_record_ct ct; | ||
| 410 | struct zfcp_san_dbf_record_els els; | ||
| 411 | } type; | ||
| 412 | } __attribute__ ((packed)); | ||
| 413 | |||
| 414 | struct zfcp_scsi_dbf_record { | ||
| 415 | u8 tag[ZFCP_DBF_TAG_SIZE]; | ||
| 416 | u8 tag2[ZFCP_DBF_TAG_SIZE]; | ||
| 417 | u32 scsi_id; | ||
| 418 | u32 scsi_lun; | ||
| 419 | u32 scsi_result; | ||
| 420 | u64 scsi_cmnd; | ||
| 421 | u64 scsi_serial; | ||
| 422 | #define ZFCP_DBF_SCSI_OPCODE 16 | ||
| 423 | u8 scsi_opcode[ZFCP_DBF_SCSI_OPCODE]; | ||
| 424 | u8 scsi_retries; | ||
| 425 | u8 scsi_allowed; | ||
| 426 | u64 fsf_reqid; | ||
| 427 | u32 fsf_seqno; | ||
| 428 | u64 fsf_issued; | ||
| 429 | union { | ||
| 430 | struct { | ||
| 431 | u64 fsf_reqid; | ||
| 432 | u32 fsf_seqno; | ||
| 433 | u64 fsf_issued; | ||
| 434 | } new_fsf_req; | ||
| 435 | struct { | ||
| 436 | u8 rsp_validity; | ||
| 437 | u8 rsp_scsi_status; | ||
| 438 | u32 rsp_resid; | ||
| 439 | u8 rsp_code; | ||
| 440 | #define ZFCP_DBF_SCSI_FCP_SNS_INFO 16 | ||
| 441 | #define ZFCP_DBF_SCSI_MAX_FCP_SNS_INFO 256 | ||
| 442 | u32 sns_info_len; | ||
| 443 | u8 sns_info[ZFCP_DBF_SCSI_FCP_SNS_INFO]; | ||
| 444 | } fcp; | ||
| 445 | } type; | ||
| 446 | } __attribute__ ((packed)); | ||
| 447 | |||
| 448 | /* | ||
| 284 | * FC-FS stuff | 449 | * FC-FS stuff |
| 285 | */ | 450 | */ |
| 286 | #define R_A_TOV 10 /* seconds */ | 451 | #define R_A_TOV 10 /* seconds */ |
| @@ -339,34 +504,6 @@ struct zfcp_rc_entry { | |||
| 339 | */ | 504 | */ |
| 340 | #define ZFCP_CT_TIMEOUT (3 * R_A_TOV) | 505 | #define ZFCP_CT_TIMEOUT (3 * R_A_TOV) |
| 341 | 506 | ||
| 342 | |||
| 343 | /***************** S390 DEBUG FEATURE SPECIFIC DEFINES ***********************/ | ||
| 344 | |||
| 345 | /* debug feature entries per adapter */ | ||
| 346 | #define ZFCP_ERP_DBF_INDEX 1 | ||
| 347 | #define ZFCP_ERP_DBF_AREAS 2 | ||
| 348 | #define ZFCP_ERP_DBF_LENGTH 16 | ||
| 349 | #define ZFCP_ERP_DBF_LEVEL 3 | ||
| 350 | #define ZFCP_ERP_DBF_NAME "zfcperp" | ||
| 351 | |||
| 352 | #define ZFCP_CMD_DBF_INDEX 2 | ||
| 353 | #define ZFCP_CMD_DBF_AREAS 1 | ||
| 354 | #define ZFCP_CMD_DBF_LENGTH 8 | ||
| 355 | #define ZFCP_CMD_DBF_LEVEL 3 | ||
| 356 | #define ZFCP_CMD_DBF_NAME "zfcpcmd" | ||
| 357 | |||
| 358 | #define ZFCP_ABORT_DBF_INDEX 2 | ||
| 359 | #define ZFCP_ABORT_DBF_AREAS 1 | ||
| 360 | #define ZFCP_ABORT_DBF_LENGTH 8 | ||
| 361 | #define ZFCP_ABORT_DBF_LEVEL 6 | ||
| 362 | #define ZFCP_ABORT_DBF_NAME "zfcpabt" | ||
| 363 | |||
| 364 | #define ZFCP_IN_ELS_DBF_INDEX 2 | ||
| 365 | #define ZFCP_IN_ELS_DBF_AREAS 1 | ||
| 366 | #define ZFCP_IN_ELS_DBF_LENGTH 8 | ||
| 367 | #define ZFCP_IN_ELS_DBF_LEVEL 6 | ||
| 368 | #define ZFCP_IN_ELS_DBF_NAME "zfcpels" | ||
| 369 | |||
| 370 | /******************** LOGGING MACROS AND DEFINES *****************************/ | 507 | /******************** LOGGING MACROS AND DEFINES *****************************/ |
| 371 | 508 | ||
| 372 | /* | 509 | /* |
| @@ -823,11 +960,18 @@ struct zfcp_adapter { | |||
| 823 | u32 erp_low_mem_count; /* nr of erp actions waiting | 960 | u32 erp_low_mem_count; /* nr of erp actions waiting |
| 824 | for memory */ | 961 | for memory */ |
| 825 | struct zfcp_port *nameserver_port; /* adapter's nameserver */ | 962 | struct zfcp_port *nameserver_port; /* adapter's nameserver */ |
| 826 | debug_info_t *erp_dbf; /* S/390 debug features */ | 963 | debug_info_t *erp_dbf; |
| 827 | debug_info_t *abort_dbf; | 964 | debug_info_t *hba_dbf; |
| 828 | debug_info_t *in_els_dbf; | 965 | debug_info_t *san_dbf; /* debug feature areas */ |
| 829 | debug_info_t *cmd_dbf; | 966 | debug_info_t *scsi_dbf; |
| 830 | spinlock_t dbf_lock; | 967 | spinlock_t erp_dbf_lock; |
| 968 | spinlock_t hba_dbf_lock; | ||
| 969 | spinlock_t san_dbf_lock; | ||
| 970 | spinlock_t scsi_dbf_lock; | ||
| 971 | struct zfcp_erp_dbf_record erp_dbf_buf; | ||
| 972 | struct zfcp_hba_dbf_record hba_dbf_buf; | ||
| 973 | struct zfcp_san_dbf_record san_dbf_buf; | ||
| 974 | struct zfcp_scsi_dbf_record scsi_dbf_buf; | ||
| 831 | struct zfcp_adapter_mempool pool; /* Adapter memory pools */ | 975 | struct zfcp_adapter_mempool pool; /* Adapter memory pools */ |
| 832 | struct qdio_initialize qdio_init_data; /* for qdio_establish */ | 976 | struct qdio_initialize qdio_init_data; /* for qdio_establish */ |
| 833 | struct device generic_services; /* directory for WKA ports */ | 977 | struct device generic_services; /* directory for WKA ports */ |
| @@ -902,6 +1046,7 @@ struct zfcp_fsf_req { | |||
| 902 | issued on behalf of erp */ | 1046 | issued on behalf of erp */ |
| 903 | mempool_t *pool; /* used if request was alloacted | 1047 | mempool_t *pool; /* used if request was alloacted |
| 904 | from emergency pool */ | 1048 | from emergency pool */ |
| 1049 | unsigned long long issued; /* request sent time (STCK) */ | ||
| 905 | struct zfcp_unit *unit; | 1050 | struct zfcp_unit *unit; |
| 906 | }; | 1051 | }; |
| 907 | 1052 | ||
diff --git a/drivers/s390/scsi/zfcp_ext.h b/drivers/s390/scsi/zfcp_ext.h index c400e3b9de97..104b7423fd4d 100644 --- a/drivers/s390/scsi/zfcp_ext.h +++ b/drivers/s390/scsi/zfcp_ext.h | |||
| @@ -181,9 +181,25 @@ extern void zfcp_erp_port_access_changed(struct zfcp_port *); | |||
| 181 | extern void zfcp_erp_unit_access_changed(struct zfcp_unit *); | 181 | extern void zfcp_erp_unit_access_changed(struct zfcp_unit *); |
| 182 | 182 | ||
| 183 | /******************************** AUX ****************************************/ | 183 | /******************************** AUX ****************************************/ |
| 184 | extern void zfcp_cmd_dbf_event_fsf(const char *, struct zfcp_fsf_req *, | 184 | extern void zfcp_hba_dbf_event_fsf_response(struct zfcp_fsf_req *); |
| 185 | void *, int); | 185 | extern void zfcp_hba_dbf_event_fsf_unsol(const char *, struct zfcp_adapter *, |
| 186 | extern void zfcp_cmd_dbf_event_scsi(const char *, struct scsi_cmnd *); | 186 | struct fsf_status_read_buffer *); |
| 187 | extern void zfcp_in_els_dbf_event(struct zfcp_adapter *, const char *, | 187 | extern void zfcp_hba_dbf_event_qdio(struct zfcp_adapter *, |
| 188 | struct fsf_status_read_buffer *, int); | 188 | unsigned int, unsigned int, unsigned int, |
| 189 | int, int); | ||
| 190 | |||
| 191 | extern void zfcp_san_dbf_event_ct_request(struct zfcp_fsf_req *); | ||
| 192 | extern void zfcp_san_dbf_event_ct_response(struct zfcp_fsf_req *); | ||
| 193 | extern void zfcp_san_dbf_event_els_request(struct zfcp_fsf_req *); | ||
| 194 | extern void zfcp_san_dbf_event_els_response(struct zfcp_fsf_req *); | ||
| 195 | extern void zfcp_san_dbf_event_incoming_els(struct zfcp_fsf_req *); | ||
| 196 | |||
| 197 | extern void zfcp_scsi_dbf_event_result(const char *, int, struct zfcp_adapter *, | ||
| 198 | struct scsi_cmnd *); | ||
| 199 | extern void zfcp_scsi_dbf_event_abort(const char *, struct zfcp_adapter *, | ||
| 200 | struct scsi_cmnd *, | ||
| 201 | struct zfcp_fsf_req *); | ||
| 202 | extern void zfcp_scsi_dbf_event_devreset(const char *, u8, struct zfcp_unit *, | ||
| 203 | struct scsi_cmnd *); | ||
| 204 | |||
| 189 | #endif /* ZFCP_EXT_H */ | 205 | #endif /* ZFCP_EXT_H */ |
diff --git a/drivers/s390/scsi/zfcp_fsf.c b/drivers/s390/scsi/zfcp_fsf.c index 929f6c9cad39..80ab721ddfff 100644 --- a/drivers/s390/scsi/zfcp_fsf.c +++ b/drivers/s390/scsi/zfcp_fsf.c | |||
| @@ -285,51 +285,51 @@ zfcp_fsf_protstatus_eval(struct zfcp_fsf_req *fsf_req) | |||
| 285 | { | 285 | { |
| 286 | int retval = 0; | 286 | int retval = 0; |
| 287 | struct zfcp_adapter *adapter = fsf_req->adapter; | 287 | struct zfcp_adapter *adapter = fsf_req->adapter; |
| 288 | struct fsf_qtcb *qtcb = fsf_req->qtcb; | ||
| 289 | union fsf_prot_status_qual *prot_status_qual = | ||
| 290 | &qtcb->prefix.prot_status_qual; | ||
| 288 | 291 | ||
| 289 | ZFCP_LOG_DEBUG("QTCB is at %p\n", fsf_req->qtcb); | 292 | zfcp_hba_dbf_event_fsf_response(fsf_req); |
| 290 | 293 | ||
| 291 | if (fsf_req->status & ZFCP_STATUS_FSFREQ_DISMISSED) { | 294 | if (fsf_req->status & ZFCP_STATUS_FSFREQ_DISMISSED) { |
| 292 | ZFCP_LOG_DEBUG("fsf_req 0x%lx has been dismissed\n", | 295 | ZFCP_LOG_DEBUG("fsf_req 0x%lx has been dismissed\n", |
| 293 | (unsigned long) fsf_req); | 296 | (unsigned long) fsf_req); |
| 294 | fsf_req->status |= ZFCP_STATUS_FSFREQ_ERROR | | 297 | fsf_req->status |= ZFCP_STATUS_FSFREQ_ERROR | |
| 295 | ZFCP_STATUS_FSFREQ_RETRY; /* only for SCSI cmnds. */ | 298 | ZFCP_STATUS_FSFREQ_RETRY; /* only for SCSI cmnds. */ |
| 296 | zfcp_cmd_dbf_event_fsf("dismiss", fsf_req, NULL, 0); | ||
| 297 | goto skip_protstatus; | 299 | goto skip_protstatus; |
| 298 | } | 300 | } |
| 299 | 301 | ||
| 300 | /* log additional information provided by FSF (if any) */ | 302 | /* log additional information provided by FSF (if any) */ |
| 301 | if (unlikely(fsf_req->qtcb->header.log_length)) { | 303 | if (unlikely(qtcb->header.log_length)) { |
| 302 | /* do not trust them ;-) */ | 304 | /* do not trust them ;-) */ |
| 303 | if (fsf_req->qtcb->header.log_start > sizeof(struct fsf_qtcb)) { | 305 | if (qtcb->header.log_start > sizeof(struct fsf_qtcb)) { |
| 304 | ZFCP_LOG_NORMAL | 306 | ZFCP_LOG_NORMAL |
| 305 | ("bug: ULP (FSF logging) log data starts " | 307 | ("bug: ULP (FSF logging) log data starts " |
| 306 | "beyond end of packet header. Ignored. " | 308 | "beyond end of packet header. Ignored. " |
| 307 | "(start=%i, size=%li)\n", | 309 | "(start=%i, size=%li)\n", |
| 308 | fsf_req->qtcb->header.log_start, | 310 | qtcb->header.log_start, |
| 309 | sizeof(struct fsf_qtcb)); | 311 | sizeof(struct fsf_qtcb)); |
| 310 | goto forget_log; | 312 | goto forget_log; |
| 311 | } | 313 | } |
| 312 | if ((size_t) (fsf_req->qtcb->header.log_start + | 314 | if ((size_t) (qtcb->header.log_start + qtcb->header.log_length) |
| 313 | fsf_req->qtcb->header.log_length) | ||
| 314 | > sizeof(struct fsf_qtcb)) { | 315 | > sizeof(struct fsf_qtcb)) { |
| 315 | ZFCP_LOG_NORMAL("bug: ULP (FSF logging) log data ends " | 316 | ZFCP_LOG_NORMAL("bug: ULP (FSF logging) log data ends " |
| 316 | "beyond end of packet header. Ignored. " | 317 | "beyond end of packet header. Ignored. " |
| 317 | "(start=%i, length=%i, size=%li)\n", | 318 | "(start=%i, length=%i, size=%li)\n", |
| 318 | fsf_req->qtcb->header.log_start, | 319 | qtcb->header.log_start, |
| 319 | fsf_req->qtcb->header.log_length, | 320 | qtcb->header.log_length, |
| 320 | sizeof(struct fsf_qtcb)); | 321 | sizeof(struct fsf_qtcb)); |
| 321 | goto forget_log; | 322 | goto forget_log; |
| 322 | } | 323 | } |
| 323 | ZFCP_LOG_TRACE("ULP log data: \n"); | 324 | ZFCP_LOG_TRACE("ULP log data: \n"); |
| 324 | ZFCP_HEX_DUMP(ZFCP_LOG_LEVEL_TRACE, | 325 | ZFCP_HEX_DUMP(ZFCP_LOG_LEVEL_TRACE, |
| 325 | (char *) fsf_req->qtcb + | 326 | (char *) qtcb + qtcb->header.log_start, |
| 326 | fsf_req->qtcb->header.log_start, | 327 | qtcb->header.log_length); |
| 327 | fsf_req->qtcb->header.log_length); | ||
| 328 | } | 328 | } |
| 329 | forget_log: | 329 | forget_log: |
| 330 | 330 | ||
| 331 | /* evaluate FSF Protocol Status */ | 331 | /* evaluate FSF Protocol Status */ |
| 332 | switch (fsf_req->qtcb->prefix.prot_status) { | 332 | switch (qtcb->prefix.prot_status) { |
| 333 | 333 | ||
| 334 | case FSF_PROT_GOOD: | 334 | case FSF_PROT_GOOD: |
| 335 | case FSF_PROT_FSF_STATUS_PRESENTED: | 335 | case FSF_PROT_FSF_STATUS_PRESENTED: |
| @@ -340,14 +340,9 @@ zfcp_fsf_protstatus_eval(struct zfcp_fsf_req *fsf_req) | |||
| 340 | "microcode of version 0x%x, the device driver " | 340 | "microcode of version 0x%x, the device driver " |
| 341 | "only supports 0x%x. Aborting.\n", | 341 | "only supports 0x%x. Aborting.\n", |
| 342 | zfcp_get_busid_by_adapter(adapter), | 342 | zfcp_get_busid_by_adapter(adapter), |
| 343 | fsf_req->qtcb->prefix.prot_status_qual. | 343 | prot_status_qual->version_error.fsf_version, |
| 344 | version_error.fsf_version, ZFCP_QTCB_VERSION); | 344 | ZFCP_QTCB_VERSION); |
| 345 | /* stop operation for this adapter */ | ||
| 346 | debug_text_exception(adapter->erp_dbf, 0, "prot_ver_err"); | ||
| 347 | zfcp_erp_adapter_shutdown(adapter, 0); | 345 | zfcp_erp_adapter_shutdown(adapter, 0); |
| 348 | zfcp_cmd_dbf_event_fsf("qverserr", fsf_req, | ||
| 349 | &fsf_req->qtcb->prefix.prot_status_qual, | ||
| 350 | sizeof (union fsf_prot_status_qual)); | ||
| 351 | fsf_req->status |= ZFCP_STATUS_FSFREQ_ERROR; | 346 | fsf_req->status |= ZFCP_STATUS_FSFREQ_ERROR; |
| 352 | break; | 347 | break; |
| 353 | 348 | ||
| @@ -355,16 +350,10 @@ zfcp_fsf_protstatus_eval(struct zfcp_fsf_req *fsf_req) | |||
| 355 | ZFCP_LOG_NORMAL("bug: Sequence number mismatch between " | 350 | ZFCP_LOG_NORMAL("bug: Sequence number mismatch between " |
| 356 | "driver (0x%x) and adapter %s (0x%x). " | 351 | "driver (0x%x) and adapter %s (0x%x). " |
| 357 | "Restarting all operations on this adapter.\n", | 352 | "Restarting all operations on this adapter.\n", |
| 358 | fsf_req->qtcb->prefix.req_seq_no, | 353 | qtcb->prefix.req_seq_no, |
| 359 | zfcp_get_busid_by_adapter(adapter), | 354 | zfcp_get_busid_by_adapter(adapter), |
| 360 | fsf_req->qtcb->prefix.prot_status_qual. | 355 | prot_status_qual->sequence_error.exp_req_seq_no); |
| 361 | sequence_error.exp_req_seq_no); | ||
| 362 | debug_text_exception(adapter->erp_dbf, 0, "prot_seq_err"); | ||
| 363 | /* restart operation on this adapter */ | ||
| 364 | zfcp_erp_adapter_reopen(adapter, 0); | 356 | zfcp_erp_adapter_reopen(adapter, 0); |
| 365 | zfcp_cmd_dbf_event_fsf("seqnoerr", fsf_req, | ||
| 366 | &fsf_req->qtcb->prefix.prot_status_qual, | ||
| 367 | sizeof (union fsf_prot_status_qual)); | ||
| 368 | fsf_req->status |= ZFCP_STATUS_FSFREQ_RETRY; | 357 | fsf_req->status |= ZFCP_STATUS_FSFREQ_RETRY; |
| 369 | fsf_req->status |= ZFCP_STATUS_FSFREQ_ERROR; | 358 | fsf_req->status |= ZFCP_STATUS_FSFREQ_ERROR; |
| 370 | break; | 359 | break; |
| @@ -375,22 +364,14 @@ zfcp_fsf_protstatus_eval(struct zfcp_fsf_req *fsf_req) | |||
| 375 | "that used on adapter %s. " | 364 | "that used on adapter %s. " |
| 376 | "Stopping all operations on this adapter.\n", | 365 | "Stopping all operations on this adapter.\n", |
| 377 | zfcp_get_busid_by_adapter(adapter)); | 366 | zfcp_get_busid_by_adapter(adapter)); |
| 378 | debug_text_exception(adapter->erp_dbf, 0, "prot_unsup_qtcb"); | ||
| 379 | zfcp_erp_adapter_shutdown(adapter, 0); | 367 | zfcp_erp_adapter_shutdown(adapter, 0); |
| 380 | zfcp_cmd_dbf_event_fsf("unsqtcbt", fsf_req, | ||
| 381 | &fsf_req->qtcb->prefix.prot_status_qual, | ||
| 382 | sizeof (union fsf_prot_status_qual)); | ||
| 383 | fsf_req->status |= ZFCP_STATUS_FSFREQ_ERROR; | 368 | fsf_req->status |= ZFCP_STATUS_FSFREQ_ERROR; |
| 384 | break; | 369 | break; |
| 385 | 370 | ||
| 386 | case FSF_PROT_HOST_CONNECTION_INITIALIZING: | 371 | case FSF_PROT_HOST_CONNECTION_INITIALIZING: |
| 387 | zfcp_cmd_dbf_event_fsf("hconinit", fsf_req, | ||
| 388 | &fsf_req->qtcb->prefix.prot_status_qual, | ||
| 389 | sizeof (union fsf_prot_status_qual)); | ||
| 390 | fsf_req->status |= ZFCP_STATUS_FSFREQ_ERROR; | 372 | fsf_req->status |= ZFCP_STATUS_FSFREQ_ERROR; |
| 391 | atomic_set_mask(ZFCP_STATUS_ADAPTER_HOST_CON_INIT, | 373 | atomic_set_mask(ZFCP_STATUS_ADAPTER_HOST_CON_INIT, |
| 392 | &(adapter->status)); | 374 | &(adapter->status)); |
| 393 | debug_text_event(adapter->erp_dbf, 3, "prot_con_init"); | ||
| 394 | break; | 375 | break; |
| 395 | 376 | ||
| 396 | case FSF_PROT_DUPLICATE_REQUEST_ID: | 377 | case FSF_PROT_DUPLICATE_REQUEST_ID: |
| @@ -413,11 +394,7 @@ zfcp_fsf_protstatus_eval(struct zfcp_fsf_req *fsf_req) | |||
| 413 | fsf_req, | 394 | fsf_req, |
| 414 | zfcp_get_busid_by_adapter(adapter)); | 395 | zfcp_get_busid_by_adapter(adapter)); |
| 415 | } | 396 | } |
| 416 | debug_text_exception(adapter->erp_dbf, 0, "prot_dup_id"); | ||
| 417 | zfcp_erp_adapter_shutdown(adapter, 0); | 397 | zfcp_erp_adapter_shutdown(adapter, 0); |
| 418 | zfcp_cmd_dbf_event_fsf("dupreqid", fsf_req, | ||
| 419 | &fsf_req->qtcb->prefix.prot_status_qual, | ||
| 420 | sizeof (union fsf_prot_status_qual)); | ||
| 421 | fsf_req->status |= ZFCP_STATUS_FSFREQ_ERROR; | 398 | fsf_req->status |= ZFCP_STATUS_FSFREQ_ERROR; |
| 422 | break; | 399 | break; |
| 423 | 400 | ||
| @@ -483,8 +460,7 @@ zfcp_fsf_protstatus_eval(struct zfcp_fsf_req *fsf_req) | |||
| 483 | break; | 460 | break; |
| 484 | 461 | ||
| 485 | case FSF_PROT_REEST_QUEUE: | 462 | case FSF_PROT_REEST_QUEUE: |
| 486 | debug_text_event(adapter->erp_dbf, 1, "prot_reest_queue"); | 463 | ZFCP_LOG_NORMAL("The local link to adapter with " |
| 487 | ZFCP_LOG_INFO("The local link to adapter with " | ||
| 488 | "%s was re-plugged. " | 464 | "%s was re-plugged. " |
| 489 | "Re-starting operations on this adapter.\n", | 465 | "Re-starting operations on this adapter.\n", |
| 490 | zfcp_get_busid_by_adapter(adapter)); | 466 | zfcp_get_busid_by_adapter(adapter)); |
| @@ -495,9 +471,6 @@ zfcp_fsf_protstatus_eval(struct zfcp_fsf_req *fsf_req) | |||
| 495 | zfcp_erp_adapter_reopen(adapter, | 471 | zfcp_erp_adapter_reopen(adapter, |
| 496 | ZFCP_STATUS_ADAPTER_LINK_UNPLUGGED | 472 | ZFCP_STATUS_ADAPTER_LINK_UNPLUGGED |
| 497 | | ZFCP_STATUS_COMMON_ERP_FAILED); | 473 | | ZFCP_STATUS_COMMON_ERP_FAILED); |
| 498 | zfcp_cmd_dbf_event_fsf("reestque", fsf_req, | ||
| 499 | &fsf_req->qtcb->prefix.prot_status_qual, | ||
| 500 | sizeof (union fsf_prot_status_qual)); | ||
| 501 | fsf_req->status |= ZFCP_STATUS_FSFREQ_ERROR; | 474 | fsf_req->status |= ZFCP_STATUS_FSFREQ_ERROR; |
| 502 | break; | 475 | break; |
| 503 | 476 | ||
| @@ -507,12 +480,7 @@ zfcp_fsf_protstatus_eval(struct zfcp_fsf_req *fsf_req) | |||
| 507 | "Restarting all operations on this " | 480 | "Restarting all operations on this " |
| 508 | "adapter.\n", | 481 | "adapter.\n", |
| 509 | zfcp_get_busid_by_adapter(adapter)); | 482 | zfcp_get_busid_by_adapter(adapter)); |
| 510 | debug_text_event(adapter->erp_dbf, 0, "prot_err_sta"); | ||
| 511 | /* restart operation on this adapter */ | ||
| 512 | zfcp_erp_adapter_reopen(adapter, 0); | 483 | zfcp_erp_adapter_reopen(adapter, 0); |
| 513 | zfcp_cmd_dbf_event_fsf("proterrs", fsf_req, | ||
| 514 | &fsf_req->qtcb->prefix.prot_status_qual, | ||
| 515 | sizeof (union fsf_prot_status_qual)); | ||
| 516 | fsf_req->status |= ZFCP_STATUS_FSFREQ_RETRY; | 484 | fsf_req->status |= ZFCP_STATUS_FSFREQ_RETRY; |
| 517 | fsf_req->status |= ZFCP_STATUS_FSFREQ_ERROR; | 485 | fsf_req->status |= ZFCP_STATUS_FSFREQ_ERROR; |
| 518 | break; | 486 | break; |
| @@ -524,11 +492,7 @@ zfcp_fsf_protstatus_eval(struct zfcp_fsf_req *fsf_req) | |||
| 524 | "Stopping all operations on this adapter. " | 492 | "Stopping all operations on this adapter. " |
| 525 | "(debug info 0x%x).\n", | 493 | "(debug info 0x%x).\n", |
| 526 | zfcp_get_busid_by_adapter(adapter), | 494 | zfcp_get_busid_by_adapter(adapter), |
| 527 | fsf_req->qtcb->prefix.prot_status); | 495 | qtcb->prefix.prot_status); |
| 528 | debug_text_event(adapter->erp_dbf, 0, "prot_inval:"); | ||
| 529 | debug_exception(adapter->erp_dbf, 0, | ||
| 530 | &fsf_req->qtcb->prefix.prot_status, | ||
| 531 | sizeof (u32)); | ||
| 532 | zfcp_erp_adapter_shutdown(adapter, 0); | 496 | zfcp_erp_adapter_shutdown(adapter, 0); |
| 533 | fsf_req->status |= ZFCP_STATUS_FSFREQ_ERROR; | 497 | fsf_req->status |= ZFCP_STATUS_FSFREQ_ERROR; |
| 534 | } | 498 | } |
| @@ -568,28 +532,18 @@ zfcp_fsf_fsfstatus_eval(struct zfcp_fsf_req *fsf_req) | |||
| 568 | "(debug info 0x%x).\n", | 532 | "(debug info 0x%x).\n", |
| 569 | zfcp_get_busid_by_adapter(fsf_req->adapter), | 533 | zfcp_get_busid_by_adapter(fsf_req->adapter), |
| 570 | fsf_req->qtcb->header.fsf_command); | 534 | fsf_req->qtcb->header.fsf_command); |
| 571 | debug_text_exception(fsf_req->adapter->erp_dbf, 0, | ||
| 572 | "fsf_s_unknown"); | ||
| 573 | zfcp_erp_adapter_shutdown(fsf_req->adapter, 0); | 535 | zfcp_erp_adapter_shutdown(fsf_req->adapter, 0); |
| 574 | zfcp_cmd_dbf_event_fsf("unknownc", fsf_req, | ||
| 575 | &fsf_req->qtcb->header.fsf_status_qual, | ||
| 576 | sizeof (union fsf_status_qual)); | ||
| 577 | fsf_req->status |= ZFCP_STATUS_FSFREQ_ERROR; | 536 | fsf_req->status |= ZFCP_STATUS_FSFREQ_ERROR; |
| 578 | break; | 537 | break; |
| 579 | 538 | ||
| 580 | case FSF_FCP_RSP_AVAILABLE: | 539 | case FSF_FCP_RSP_AVAILABLE: |
| 581 | ZFCP_LOG_DEBUG("FCP Sense data will be presented to the " | 540 | ZFCP_LOG_DEBUG("FCP Sense data will be presented to the " |
| 582 | "SCSI stack.\n"); | 541 | "SCSI stack.\n"); |
| 583 | debug_text_event(fsf_req->adapter->erp_dbf, 3, "fsf_s_rsp"); | ||
| 584 | break; | 542 | break; |
| 585 | 543 | ||
| 586 | case FSF_ADAPTER_STATUS_AVAILABLE: | 544 | case FSF_ADAPTER_STATUS_AVAILABLE: |
| 587 | debug_text_event(fsf_req->adapter->erp_dbf, 2, "fsf_s_astatus"); | ||
| 588 | zfcp_fsf_fsfstatus_qual_eval(fsf_req); | 545 | zfcp_fsf_fsfstatus_qual_eval(fsf_req); |
| 589 | break; | 546 | break; |
| 590 | |||
| 591 | default: | ||
| 592 | break; | ||
| 593 | } | 547 | } |
| 594 | 548 | ||
| 595 | skip_fsfstatus: | 549 | skip_fsfstatus: |
| @@ -617,44 +571,28 @@ zfcp_fsf_fsfstatus_qual_eval(struct zfcp_fsf_req *fsf_req) | |||
| 617 | 571 | ||
| 618 | switch (fsf_req->qtcb->header.fsf_status_qual.word[0]) { | 572 | switch (fsf_req->qtcb->header.fsf_status_qual.word[0]) { |
| 619 | case FSF_SQ_FCP_RSP_AVAILABLE: | 573 | case FSF_SQ_FCP_RSP_AVAILABLE: |
| 620 | debug_text_event(fsf_req->adapter->erp_dbf, 4, "fsf_sq_rsp"); | ||
| 621 | break; | 574 | break; |
| 622 | case FSF_SQ_RETRY_IF_POSSIBLE: | 575 | case FSF_SQ_RETRY_IF_POSSIBLE: |
| 623 | /* The SCSI-stack may now issue retries or escalate */ | 576 | /* The SCSI-stack may now issue retries or escalate */ |
| 624 | debug_text_event(fsf_req->adapter->erp_dbf, 2, "fsf_sq_retry"); | ||
| 625 | zfcp_cmd_dbf_event_fsf("sqretry", fsf_req, | ||
| 626 | &fsf_req->qtcb->header.fsf_status_qual, | ||
| 627 | sizeof (union fsf_status_qual)); | ||
| 628 | fsf_req->status |= ZFCP_STATUS_FSFREQ_ERROR; | 577 | fsf_req->status |= ZFCP_STATUS_FSFREQ_ERROR; |
| 629 | break; | 578 | break; |
| 630 | case FSF_SQ_COMMAND_ABORTED: | 579 | case FSF_SQ_COMMAND_ABORTED: |
| 631 | /* Carry the aborted state on to upper layer */ | 580 | /* Carry the aborted state on to upper layer */ |
| 632 | debug_text_event(fsf_req->adapter->erp_dbf, 2, "fsf_sq_abort"); | ||
| 633 | zfcp_cmd_dbf_event_fsf("sqabort", fsf_req, | ||
| 634 | &fsf_req->qtcb->header.fsf_status_qual, | ||
| 635 | sizeof (union fsf_status_qual)); | ||
| 636 | fsf_req->status |= ZFCP_STATUS_FSFREQ_ABORTED; | 581 | fsf_req->status |= ZFCP_STATUS_FSFREQ_ABORTED; |
| 637 | fsf_req->status |= ZFCP_STATUS_FSFREQ_ERROR; | 582 | fsf_req->status |= ZFCP_STATUS_FSFREQ_ERROR; |
| 638 | break; | 583 | break; |
| 639 | case FSF_SQ_NO_RECOM: | 584 | case FSF_SQ_NO_RECOM: |
| 640 | debug_text_exception(fsf_req->adapter->erp_dbf, 0, | ||
| 641 | "fsf_sq_no_rec"); | ||
| 642 | ZFCP_LOG_NORMAL("bug: No recommendation could be given for a" | 585 | ZFCP_LOG_NORMAL("bug: No recommendation could be given for a" |
| 643 | "problem on the adapter %s " | 586 | "problem on the adapter %s " |
| 644 | "Stopping all operations on this adapter. ", | 587 | "Stopping all operations on this adapter. ", |
| 645 | zfcp_get_busid_by_adapter(fsf_req->adapter)); | 588 | zfcp_get_busid_by_adapter(fsf_req->adapter)); |
| 646 | zfcp_erp_adapter_shutdown(fsf_req->adapter, 0); | 589 | zfcp_erp_adapter_shutdown(fsf_req->adapter, 0); |
| 647 | zfcp_cmd_dbf_event_fsf("sqnrecom", fsf_req, | ||
| 648 | &fsf_req->qtcb->header.fsf_status_qual, | ||
| 649 | sizeof (union fsf_status_qual)); | ||
| 650 | fsf_req->status |= ZFCP_STATUS_FSFREQ_ERROR; | 590 | fsf_req->status |= ZFCP_STATUS_FSFREQ_ERROR; |
| 651 | break; | 591 | break; |
| 652 | case FSF_SQ_ULP_PROGRAMMING_ERROR: | 592 | case FSF_SQ_ULP_PROGRAMMING_ERROR: |
| 653 | ZFCP_LOG_NORMAL("error: not enough SBALs for data transfer " | 593 | ZFCP_LOG_NORMAL("error: not enough SBALs for data transfer " |
| 654 | "(adapter %s)\n", | 594 | "(adapter %s)\n", |
| 655 | zfcp_get_busid_by_adapter(fsf_req->adapter)); | 595 | zfcp_get_busid_by_adapter(fsf_req->adapter)); |
| 656 | debug_text_exception(fsf_req->adapter->erp_dbf, 0, | ||
| 657 | "fsf_sq_ulp_err"); | ||
| 658 | fsf_req->status |= ZFCP_STATUS_FSFREQ_ERROR; | 596 | fsf_req->status |= ZFCP_STATUS_FSFREQ_ERROR; |
| 659 | break; | 597 | break; |
| 660 | case FSF_SQ_INVOKE_LINK_TEST_PROCEDURE: | 598 | case FSF_SQ_INVOKE_LINK_TEST_PROCEDURE: |
| @@ -668,13 +606,6 @@ zfcp_fsf_fsfstatus_qual_eval(struct zfcp_fsf_req *fsf_req) | |||
| 668 | ZFCP_HEX_DUMP(ZFCP_LOG_LEVEL_NORMAL, | 606 | ZFCP_HEX_DUMP(ZFCP_LOG_LEVEL_NORMAL, |
| 669 | (char *) &fsf_req->qtcb->header.fsf_status_qual, | 607 | (char *) &fsf_req->qtcb->header.fsf_status_qual, |
| 670 | sizeof (union fsf_status_qual)); | 608 | sizeof (union fsf_status_qual)); |
| 671 | debug_text_event(fsf_req->adapter->erp_dbf, 0, "fsf_sq_inval:"); | ||
| 672 | debug_exception(fsf_req->adapter->erp_dbf, 0, | ||
| 673 | &fsf_req->qtcb->header.fsf_status_qual.word[0], | ||
| 674 | sizeof (u32)); | ||
| 675 | zfcp_cmd_dbf_event_fsf("squndef", fsf_req, | ||
| 676 | &fsf_req->qtcb->header.fsf_status_qual, | ||
| 677 | sizeof (union fsf_status_qual)); | ||
| 678 | fsf_req->status |= ZFCP_STATUS_FSFREQ_ERROR; | 609 | fsf_req->status |= ZFCP_STATUS_FSFREQ_ERROR; |
| 679 | break; | 610 | break; |
| 680 | } | 611 | } |
| @@ -696,11 +627,6 @@ zfcp_fsf_req_dispatch(struct zfcp_fsf_req *fsf_req) | |||
| 696 | struct zfcp_adapter *adapter = fsf_req->adapter; | 627 | struct zfcp_adapter *adapter = fsf_req->adapter; |
| 697 | int retval = 0; | 628 | int retval = 0; |
| 698 | 629 | ||
| 699 | if (unlikely(fsf_req->status & ZFCP_STATUS_FSFREQ_ERROR)) { | ||
| 700 | ZFCP_LOG_TRACE("fsf_req=%p, QTCB=%p\n", fsf_req, fsf_req->qtcb); | ||
| 701 | ZFCP_HEX_DUMP(ZFCP_LOG_LEVEL_TRACE, | ||
| 702 | (char *) fsf_req->qtcb, sizeof(struct fsf_qtcb)); | ||
| 703 | } | ||
| 704 | 630 | ||
| 705 | switch (fsf_req->fsf_command) { | 631 | switch (fsf_req->fsf_command) { |
| 706 | 632 | ||
| @@ -760,13 +686,13 @@ zfcp_fsf_req_dispatch(struct zfcp_fsf_req *fsf_req) | |||
| 760 | fsf_req->status |= ZFCP_STATUS_FSFREQ_ERROR; | 686 | fsf_req->status |= ZFCP_STATUS_FSFREQ_ERROR; |
| 761 | ZFCP_LOG_NORMAL("bug: Command issued by the device driver is " | 687 | ZFCP_LOG_NORMAL("bug: Command issued by the device driver is " |
| 762 | "not supported by the adapter %s\n", | 688 | "not supported by the adapter %s\n", |
| 763 | zfcp_get_busid_by_adapter(fsf_req->adapter)); | 689 | zfcp_get_busid_by_adapter(adapter)); |
| 764 | if (fsf_req->fsf_command != fsf_req->qtcb->header.fsf_command) | 690 | if (fsf_req->fsf_command != fsf_req->qtcb->header.fsf_command) |
| 765 | ZFCP_LOG_NORMAL | 691 | ZFCP_LOG_NORMAL |
| 766 | ("bug: Command issued by the device driver differs " | 692 | ("bug: Command issued by the device driver differs " |
| 767 | "from the command returned by the adapter %s " | 693 | "from the command returned by the adapter %s " |
| 768 | "(debug info 0x%x, 0x%x).\n", | 694 | "(debug info 0x%x, 0x%x).\n", |
| 769 | zfcp_get_busid_by_adapter(fsf_req->adapter), | 695 | zfcp_get_busid_by_adapter(adapter), |
| 770 | fsf_req->fsf_command, | 696 | fsf_req->fsf_command, |
| 771 | fsf_req->qtcb->header.fsf_command); | 697 | fsf_req->qtcb->header.fsf_command); |
| 772 | } | 698 | } |
| @@ -774,8 +700,6 @@ zfcp_fsf_req_dispatch(struct zfcp_fsf_req *fsf_req) | |||
| 774 | if (!erp_action) | 700 | if (!erp_action) |
| 775 | return retval; | 701 | return retval; |
| 776 | 702 | ||
| 777 | debug_text_event(adapter->erp_dbf, 3, "a_frh"); | ||
| 778 | debug_event(adapter->erp_dbf, 3, &erp_action->action, sizeof (int)); | ||
| 779 | zfcp_erp_async_handler(erp_action, 0); | 703 | zfcp_erp_async_handler(erp_action, 0); |
| 780 | 704 | ||
| 781 | return retval; | 705 | return retval; |
| @@ -846,6 +770,7 @@ zfcp_fsf_status_read(struct zfcp_adapter *adapter, int req_flags) | |||
| 846 | failed_buf: | 770 | failed_buf: |
| 847 | zfcp_fsf_req_free(fsf_req); | 771 | zfcp_fsf_req_free(fsf_req); |
| 848 | failed_req_create: | 772 | failed_req_create: |
| 773 | zfcp_hba_dbf_event_fsf_unsol("fail", adapter, NULL); | ||
| 849 | out: | 774 | out: |
| 850 | write_unlock_irqrestore(&adapter->request_queue.queue_lock, lock_flags); | 775 | write_unlock_irqrestore(&adapter->request_queue.queue_lock, lock_flags); |
| 851 | return retval; | 776 | return retval; |
| @@ -921,35 +846,30 @@ zfcp_fsf_status_read_handler(struct zfcp_fsf_req *fsf_req) | |||
| 921 | (struct fsf_status_read_buffer *) fsf_req->data; | 846 | (struct fsf_status_read_buffer *) fsf_req->data; |
| 922 | 847 | ||
| 923 | if (fsf_req->status & ZFCP_STATUS_FSFREQ_DISMISSED) { | 848 | if (fsf_req->status & ZFCP_STATUS_FSFREQ_DISMISSED) { |
| 849 | zfcp_hba_dbf_event_fsf_unsol("dism", adapter, status_buffer); | ||
| 924 | mempool_free(status_buffer, adapter->pool.data_status_read); | 850 | mempool_free(status_buffer, adapter->pool.data_status_read); |
| 925 | zfcp_fsf_req_free(fsf_req); | 851 | zfcp_fsf_req_free(fsf_req); |
| 926 | goto out; | 852 | goto out; |
| 927 | } | 853 | } |
| 928 | 854 | ||
| 855 | zfcp_hba_dbf_event_fsf_unsol("read", adapter, status_buffer); | ||
| 856 | |||
| 929 | switch (status_buffer->status_type) { | 857 | switch (status_buffer->status_type) { |
| 930 | 858 | ||
| 931 | case FSF_STATUS_READ_PORT_CLOSED: | 859 | case FSF_STATUS_READ_PORT_CLOSED: |
| 932 | debug_text_event(adapter->erp_dbf, 3, "unsol_pclosed:"); | ||
| 933 | debug_event(adapter->erp_dbf, 3, | ||
| 934 | &status_buffer->d_id, sizeof (u32)); | ||
| 935 | zfcp_fsf_status_read_port_closed(fsf_req); | 860 | zfcp_fsf_status_read_port_closed(fsf_req); |
| 936 | break; | 861 | break; |
| 937 | 862 | ||
| 938 | case FSF_STATUS_READ_INCOMING_ELS: | 863 | case FSF_STATUS_READ_INCOMING_ELS: |
| 939 | debug_text_event(adapter->erp_dbf, 3, "unsol_els:"); | ||
| 940 | zfcp_fsf_incoming_els(fsf_req); | 864 | zfcp_fsf_incoming_els(fsf_req); |
| 941 | break; | 865 | break; |
| 942 | 866 | ||
| 943 | case FSF_STATUS_READ_SENSE_DATA_AVAIL: | 867 | case FSF_STATUS_READ_SENSE_DATA_AVAIL: |
| 944 | debug_text_event(adapter->erp_dbf, 3, "unsol_sense:"); | ||
| 945 | ZFCP_LOG_INFO("unsolicited sense data received (adapter %s)\n", | 868 | ZFCP_LOG_INFO("unsolicited sense data received (adapter %s)\n", |
| 946 | zfcp_get_busid_by_adapter(adapter)); | 869 | zfcp_get_busid_by_adapter(adapter)); |
| 947 | ZFCP_HEX_DUMP(ZFCP_LOG_LEVEL_NORMAL, (char *) status_buffer, | ||
| 948 | sizeof(struct fsf_status_read_buffer)); | ||
| 949 | break; | 870 | break; |
| 950 | 871 | ||
| 951 | case FSF_STATUS_READ_BIT_ERROR_THRESHOLD: | 872 | case FSF_STATUS_READ_BIT_ERROR_THRESHOLD: |
| 952 | debug_text_event(adapter->erp_dbf, 3, "unsol_bit_err:"); | ||
| 953 | ZFCP_LOG_NORMAL("Bit error threshold data received:\n"); | 873 | ZFCP_LOG_NORMAL("Bit error threshold data received:\n"); |
| 954 | ZFCP_HEX_DUMP(ZFCP_LOG_LEVEL_NORMAL, | 874 | ZFCP_HEX_DUMP(ZFCP_LOG_LEVEL_NORMAL, |
| 955 | (char *) status_buffer, | 875 | (char *) status_buffer, |
| @@ -980,35 +900,30 @@ zfcp_fsf_status_read_handler(struct zfcp_fsf_req *fsf_req) | |||
| 980 | break; | 900 | break; |
| 981 | 901 | ||
| 982 | case FSF_STATUS_READ_CFDC_UPDATED: | 902 | case FSF_STATUS_READ_CFDC_UPDATED: |
| 983 | debug_text_event(adapter->erp_dbf, 2, "unsol_cfdc_update:"); | 903 | ZFCP_LOG_NORMAL("CFDC has been updated on the adapter %s\n", |
| 984 | ZFCP_LOG_INFO("CFDC has been updated on the adapter %s\n", | ||
| 985 | zfcp_get_busid_by_adapter(adapter)); | 904 | zfcp_get_busid_by_adapter(adapter)); |
| 986 | zfcp_erp_adapter_access_changed(adapter); | 905 | zfcp_erp_adapter_access_changed(adapter); |
| 987 | break; | 906 | break; |
| 988 | 907 | ||
| 989 | case FSF_STATUS_READ_CFDC_HARDENED: | 908 | case FSF_STATUS_READ_CFDC_HARDENED: |
| 990 | debug_text_event(adapter->erp_dbf, 2, "unsol_cfdc_harden:"); | ||
| 991 | switch (status_buffer->status_subtype) { | 909 | switch (status_buffer->status_subtype) { |
| 992 | case FSF_STATUS_READ_SUB_CFDC_HARDENED_ON_SE: | 910 | case FSF_STATUS_READ_SUB_CFDC_HARDENED_ON_SE: |
| 993 | ZFCP_LOG_INFO("CFDC of adapter %s saved on SE\n", | 911 | ZFCP_LOG_NORMAL("CFDC of adapter %s saved on SE\n", |
| 994 | zfcp_get_busid_by_adapter(adapter)); | 912 | zfcp_get_busid_by_adapter(adapter)); |
| 995 | break; | 913 | break; |
| 996 | case FSF_STATUS_READ_SUB_CFDC_HARDENED_ON_SE2: | 914 | case FSF_STATUS_READ_SUB_CFDC_HARDENED_ON_SE2: |
| 997 | ZFCP_LOG_INFO("CFDC of adapter %s has been copied " | 915 | ZFCP_LOG_NORMAL("CFDC of adapter %s has been copied " |
| 998 | "to the secondary SE\n", | 916 | "to the secondary SE\n", |
| 999 | zfcp_get_busid_by_adapter(adapter)); | 917 | zfcp_get_busid_by_adapter(adapter)); |
| 1000 | break; | 918 | break; |
| 1001 | default: | 919 | default: |
| 1002 | ZFCP_LOG_INFO("CFDC of adapter %s has been hardened\n", | 920 | ZFCP_LOG_NORMAL("CFDC of adapter %s has been hardened\n", |
| 1003 | zfcp_get_busid_by_adapter(adapter)); | 921 | zfcp_get_busid_by_adapter(adapter)); |
| 1004 | } | 922 | } |
| 1005 | break; | 923 | break; |
| 1006 | 924 | ||
| 1007 | default: | 925 | default: |
| 1008 | debug_text_event(adapter->erp_dbf, 0, "unsol_unknown:"); | 926 | ZFCP_LOG_NORMAL("warning: An unsolicited status packet of unknown " |
| 1009 | debug_exception(adapter->erp_dbf, 0, | ||
| 1010 | &status_buffer->status_type, sizeof (u32)); | ||
| 1011 | ZFCP_LOG_NORMAL("bug: An unsolicited status packet of unknown " | ||
| 1012 | "type was received (debug info 0x%x)\n", | 927 | "type was received (debug info 0x%x)\n", |
| 1013 | status_buffer->status_type); | 928 | status_buffer->status_type); |
| 1014 | ZFCP_LOG_DEBUG("Dump of status_read_buffer %p:\n", | 929 | ZFCP_LOG_DEBUG("Dump of status_read_buffer %p:\n", |
| @@ -1418,6 +1333,8 @@ zfcp_fsf_send_ct(struct zfcp_send_ct *ct, mempool_t *pool, | |||
| 1418 | fsf_req->qtcb->bottom.support.timeout = ct->timeout; | 1333 | fsf_req->qtcb->bottom.support.timeout = ct->timeout; |
| 1419 | fsf_req->data = (unsigned long) ct; | 1334 | fsf_req->data = (unsigned long) ct; |
| 1420 | 1335 | ||
| 1336 | zfcp_san_dbf_event_ct_request(fsf_req); | ||
| 1337 | |||
| 1421 | /* start QDIO request for this FSF request */ | 1338 | /* start QDIO request for this FSF request */ |
| 1422 | ret = zfcp_fsf_req_send(fsf_req, ct->timer); | 1339 | ret = zfcp_fsf_req_send(fsf_req, ct->timer); |
| 1423 | if (ret) { | 1340 | if (ret) { |
| @@ -1476,6 +1393,7 @@ zfcp_fsf_send_ct_handler(struct zfcp_fsf_req *fsf_req) | |||
| 1476 | switch (header->fsf_status) { | 1393 | switch (header->fsf_status) { |
| 1477 | 1394 | ||
| 1478 | case FSF_GOOD: | 1395 | case FSF_GOOD: |
| 1396 | zfcp_san_dbf_event_ct_response(fsf_req); | ||
| 1479 | retval = 0; | 1397 | retval = 0; |
| 1480 | break; | 1398 | break; |
| 1481 | 1399 | ||
| @@ -1720,6 +1638,8 @@ zfcp_fsf_send_els(struct zfcp_send_els *els) | |||
| 1720 | 1638 | ||
| 1721 | sbale = zfcp_qdio_sbale_req(fsf_req, fsf_req->sbal_curr, 0); | 1639 | sbale = zfcp_qdio_sbale_req(fsf_req, fsf_req->sbal_curr, 0); |
| 1722 | 1640 | ||
| 1641 | zfcp_san_dbf_event_els_request(fsf_req); | ||
| 1642 | |||
| 1723 | /* start QDIO request for this FSF request */ | 1643 | /* start QDIO request for this FSF request */ |
| 1724 | ret = zfcp_fsf_req_send(fsf_req, els->timer); | 1644 | ret = zfcp_fsf_req_send(fsf_req, els->timer); |
| 1725 | if (ret) { | 1645 | if (ret) { |
| @@ -1777,6 +1697,7 @@ static int zfcp_fsf_send_els_handler(struct zfcp_fsf_req *fsf_req) | |||
| 1777 | switch (header->fsf_status) { | 1697 | switch (header->fsf_status) { |
| 1778 | 1698 | ||
| 1779 | case FSF_GOOD: | 1699 | case FSF_GOOD: |
| 1700 | zfcp_san_dbf_event_els_response(fsf_req); | ||
| 1780 | retval = 0; | 1701 | retval = 0; |
| 1781 | break; | 1702 | break; |
| 1782 | 1703 | ||
| @@ -3309,9 +3230,6 @@ zfcp_fsf_close_unit_handler(struct zfcp_fsf_req *fsf_req) | |||
| 3309 | debug_text_event(fsf_req->adapter->erp_dbf, 1, | 3230 | debug_text_event(fsf_req->adapter->erp_dbf, 1, |
| 3310 | "fsf_s_phand_nv"); | 3231 | "fsf_s_phand_nv"); |
| 3311 | zfcp_erp_adapter_reopen(unit->port->adapter, 0); | 3232 | zfcp_erp_adapter_reopen(unit->port->adapter, 0); |
| 3312 | zfcp_cmd_dbf_event_fsf("porthinv", fsf_req, | ||
| 3313 | &fsf_req->qtcb->header.fsf_status_qual, | ||
| 3314 | sizeof (union fsf_status_qual)); | ||
| 3315 | fsf_req->status |= ZFCP_STATUS_FSFREQ_ERROR; | 3233 | fsf_req->status |= ZFCP_STATUS_FSFREQ_ERROR; |
| 3316 | break; | 3234 | break; |
| 3317 | 3235 | ||
| @@ -3330,9 +3248,6 @@ zfcp_fsf_close_unit_handler(struct zfcp_fsf_req *fsf_req) | |||
| 3330 | debug_text_event(fsf_req->adapter->erp_dbf, 1, | 3248 | debug_text_event(fsf_req->adapter->erp_dbf, 1, |
| 3331 | "fsf_s_lhand_nv"); | 3249 | "fsf_s_lhand_nv"); |
| 3332 | zfcp_erp_port_reopen(unit->port, 0); | 3250 | zfcp_erp_port_reopen(unit->port, 0); |
| 3333 | zfcp_cmd_dbf_event_fsf("lunhinv", fsf_req, | ||
| 3334 | &fsf_req->qtcb->header.fsf_status_qual, | ||
| 3335 | sizeof (union fsf_status_qual)); | ||
| 3336 | fsf_req->status |= ZFCP_STATUS_FSFREQ_ERROR; | 3251 | fsf_req->status |= ZFCP_STATUS_FSFREQ_ERROR; |
| 3337 | break; | 3252 | break; |
| 3338 | 3253 | ||
| @@ -3763,10 +3678,6 @@ zfcp_fsf_send_fcp_command_handler(struct zfcp_fsf_req *fsf_req) | |||
| 3763 | debug_text_event(fsf_req->adapter->erp_dbf, 1, | 3678 | debug_text_event(fsf_req->adapter->erp_dbf, 1, |
| 3764 | "fsf_s_hand_mis"); | 3679 | "fsf_s_hand_mis"); |
| 3765 | zfcp_erp_adapter_reopen(unit->port->adapter, 0); | 3680 | zfcp_erp_adapter_reopen(unit->port->adapter, 0); |
| 3766 | zfcp_cmd_dbf_event_fsf("handmism", | ||
| 3767 | fsf_req, | ||
| 3768 | &header->fsf_status_qual, | ||
| 3769 | sizeof (union fsf_status_qual)); | ||
| 3770 | fsf_req->status |= ZFCP_STATUS_FSFREQ_ERROR; | 3681 | fsf_req->status |= ZFCP_STATUS_FSFREQ_ERROR; |
| 3771 | break; | 3682 | break; |
| 3772 | 3683 | ||
| @@ -3787,10 +3698,6 @@ zfcp_fsf_send_fcp_command_handler(struct zfcp_fsf_req *fsf_req) | |||
| 3787 | debug_text_exception(fsf_req->adapter->erp_dbf, 0, | 3698 | debug_text_exception(fsf_req->adapter->erp_dbf, 0, |
| 3788 | "fsf_s_class_nsup"); | 3699 | "fsf_s_class_nsup"); |
| 3789 | zfcp_erp_adapter_shutdown(unit->port->adapter, 0); | 3700 | zfcp_erp_adapter_shutdown(unit->port->adapter, 0); |
| 3790 | zfcp_cmd_dbf_event_fsf("unsclass", | ||
| 3791 | fsf_req, | ||
| 3792 | &header->fsf_status_qual, | ||
| 3793 | sizeof (union fsf_status_qual)); | ||
| 3794 | fsf_req->status |= ZFCP_STATUS_FSFREQ_ERROR; | 3701 | fsf_req->status |= ZFCP_STATUS_FSFREQ_ERROR; |
| 3795 | break; | 3702 | break; |
| 3796 | 3703 | ||
| @@ -3809,10 +3716,6 @@ zfcp_fsf_send_fcp_command_handler(struct zfcp_fsf_req *fsf_req) | |||
| 3809 | debug_text_event(fsf_req->adapter->erp_dbf, 1, | 3716 | debug_text_event(fsf_req->adapter->erp_dbf, 1, |
| 3810 | "fsf_s_fcp_lun_nv"); | 3717 | "fsf_s_fcp_lun_nv"); |
| 3811 | zfcp_erp_port_reopen(unit->port, 0); | 3718 | zfcp_erp_port_reopen(unit->port, 0); |
| 3812 | zfcp_cmd_dbf_event_fsf("fluninv", | ||
| 3813 | fsf_req, | ||
| 3814 | &header->fsf_status_qual, | ||
| 3815 | sizeof (union fsf_status_qual)); | ||
| 3816 | fsf_req->status |= ZFCP_STATUS_FSFREQ_ERROR; | 3719 | fsf_req->status |= ZFCP_STATUS_FSFREQ_ERROR; |
| 3817 | break; | 3720 | break; |
| 3818 | 3721 | ||
| @@ -3851,10 +3754,6 @@ zfcp_fsf_send_fcp_command_handler(struct zfcp_fsf_req *fsf_req) | |||
| 3851 | debug_text_event(fsf_req->adapter->erp_dbf, 0, | 3754 | debug_text_event(fsf_req->adapter->erp_dbf, 0, |
| 3852 | "fsf_s_dir_ind_nv"); | 3755 | "fsf_s_dir_ind_nv"); |
| 3853 | zfcp_erp_adapter_shutdown(unit->port->adapter, 0); | 3756 | zfcp_erp_adapter_shutdown(unit->port->adapter, 0); |
| 3854 | zfcp_cmd_dbf_event_fsf("dirinv", | ||
| 3855 | fsf_req, | ||
| 3856 | &header->fsf_status_qual, | ||
| 3857 | sizeof (union fsf_status_qual)); | ||
| 3858 | fsf_req->status |= ZFCP_STATUS_FSFREQ_ERROR; | 3757 | fsf_req->status |= ZFCP_STATUS_FSFREQ_ERROR; |
| 3859 | break; | 3758 | break; |
| 3860 | 3759 | ||
| @@ -3870,10 +3769,6 @@ zfcp_fsf_send_fcp_command_handler(struct zfcp_fsf_req *fsf_req) | |||
| 3870 | debug_text_event(fsf_req->adapter->erp_dbf, 0, | 3769 | debug_text_event(fsf_req->adapter->erp_dbf, 0, |
| 3871 | "fsf_s_cmd_len_nv"); | 3770 | "fsf_s_cmd_len_nv"); |
| 3872 | zfcp_erp_adapter_shutdown(unit->port->adapter, 0); | 3771 | zfcp_erp_adapter_shutdown(unit->port->adapter, 0); |
| 3873 | zfcp_cmd_dbf_event_fsf("cleninv", | ||
| 3874 | fsf_req, | ||
| 3875 | &header->fsf_status_qual, | ||
| 3876 | sizeof (union fsf_status_qual)); | ||
| 3877 | fsf_req->status |= ZFCP_STATUS_FSFREQ_ERROR; | 3772 | fsf_req->status |= ZFCP_STATUS_FSFREQ_ERROR; |
| 3878 | break; | 3773 | break; |
| 3879 | 3774 | ||
| @@ -4043,7 +3938,6 @@ zfcp_fsf_send_fcp_command_task_handler(struct zfcp_fsf_req *fsf_req) | |||
| 4043 | ZFCP_HEX_DUMP(ZFCP_LOG_LEVEL_DEBUG, | 3938 | ZFCP_HEX_DUMP(ZFCP_LOG_LEVEL_DEBUG, |
| 4044 | (char *) &fsf_req->qtcb-> | 3939 | (char *) &fsf_req->qtcb-> |
| 4045 | bottom.io.fcp_cmnd, FSF_FCP_CMND_SIZE); | 3940 | bottom.io.fcp_cmnd, FSF_FCP_CMND_SIZE); |
| 4046 | zfcp_cmd_dbf_event_fsf("clenmis", fsf_req, NULL, 0); | ||
| 4047 | set_host_byte(&scpnt->result, DID_ERROR); | 3941 | set_host_byte(&scpnt->result, DID_ERROR); |
| 4048 | goto skip_fsfstatus; | 3942 | goto skip_fsfstatus; |
| 4049 | case RSP_CODE_FIELD_INVALID: | 3943 | case RSP_CODE_FIELD_INVALID: |
| @@ -4062,7 +3956,6 @@ zfcp_fsf_send_fcp_command_task_handler(struct zfcp_fsf_req *fsf_req) | |||
| 4062 | (char *) &fsf_req->qtcb-> | 3956 | (char *) &fsf_req->qtcb-> |
| 4063 | bottom.io.fcp_cmnd, FSF_FCP_CMND_SIZE); | 3957 | bottom.io.fcp_cmnd, FSF_FCP_CMND_SIZE); |
| 4064 | set_host_byte(&scpnt->result, DID_ERROR); | 3958 | set_host_byte(&scpnt->result, DID_ERROR); |
| 4065 | zfcp_cmd_dbf_event_fsf("codeinv", fsf_req, NULL, 0); | ||
| 4066 | goto skip_fsfstatus; | 3959 | goto skip_fsfstatus; |
| 4067 | case RSP_CODE_RO_MISMATCH: | 3960 | case RSP_CODE_RO_MISMATCH: |
| 4068 | /* hardware bug */ | 3961 | /* hardware bug */ |
| @@ -4079,7 +3972,6 @@ zfcp_fsf_send_fcp_command_task_handler(struct zfcp_fsf_req *fsf_req) | |||
| 4079 | ZFCP_HEX_DUMP(ZFCP_LOG_LEVEL_DEBUG, | 3972 | ZFCP_HEX_DUMP(ZFCP_LOG_LEVEL_DEBUG, |
| 4080 | (char *) &fsf_req->qtcb-> | 3973 | (char *) &fsf_req->qtcb-> |
| 4081 | bottom.io.fcp_cmnd, FSF_FCP_CMND_SIZE); | 3974 | bottom.io.fcp_cmnd, FSF_FCP_CMND_SIZE); |
| 4082 | zfcp_cmd_dbf_event_fsf("codemism", fsf_req, NULL, 0); | ||
| 4083 | set_host_byte(&scpnt->result, DID_ERROR); | 3975 | set_host_byte(&scpnt->result, DID_ERROR); |
| 4084 | goto skip_fsfstatus; | 3976 | goto skip_fsfstatus; |
| 4085 | default: | 3977 | default: |
| @@ -4096,7 +3988,6 @@ zfcp_fsf_send_fcp_command_task_handler(struct zfcp_fsf_req *fsf_req) | |||
| 4096 | ZFCP_HEX_DUMP(ZFCP_LOG_LEVEL_DEBUG, | 3988 | ZFCP_HEX_DUMP(ZFCP_LOG_LEVEL_DEBUG, |
| 4097 | (char *) &fsf_req->qtcb-> | 3989 | (char *) &fsf_req->qtcb-> |
| 4098 | bottom.io.fcp_cmnd, FSF_FCP_CMND_SIZE); | 3990 | bottom.io.fcp_cmnd, FSF_FCP_CMND_SIZE); |
| 4099 | zfcp_cmd_dbf_event_fsf("undeffcp", fsf_req, NULL, 0); | ||
| 4100 | set_host_byte(&scpnt->result, DID_ERROR); | 3991 | set_host_byte(&scpnt->result, DID_ERROR); |
| 4101 | goto skip_fsfstatus; | 3992 | goto skip_fsfstatus; |
| 4102 | } | 3993 | } |
| @@ -4158,19 +4049,17 @@ zfcp_fsf_send_fcp_command_task_handler(struct zfcp_fsf_req *fsf_req) | |||
| 4158 | skip_fsfstatus: | 4049 | skip_fsfstatus: |
| 4159 | ZFCP_LOG_DEBUG("scpnt->result =0x%x\n", scpnt->result); | 4050 | ZFCP_LOG_DEBUG("scpnt->result =0x%x\n", scpnt->result); |
| 4160 | 4051 | ||
| 4161 | zfcp_cmd_dbf_event_scsi("response", scpnt); | 4052 | if (scpnt->result != 0) |
| 4053 | zfcp_scsi_dbf_event_result("erro", 3, fsf_req->adapter, scpnt); | ||
| 4054 | else if (scpnt->retries > 0) | ||
| 4055 | zfcp_scsi_dbf_event_result("retr", 4, fsf_req->adapter, scpnt); | ||
| 4056 | else | ||
| 4057 | zfcp_scsi_dbf_event_result("norm", 6, fsf_req->adapter, scpnt); | ||
| 4162 | 4058 | ||
| 4163 | /* cleanup pointer (need this especially for abort) */ | 4059 | /* cleanup pointer (need this especially for abort) */ |
| 4164 | scpnt->host_scribble = NULL; | 4060 | scpnt->host_scribble = NULL; |
| 4165 | 4061 | ||
| 4166 | /* | ||
| 4167 | * NOTE: | ||
| 4168 | * according to the outcome of a discussion on linux-scsi we | ||
| 4169 | * don't need to grab the io_request_lock here since we use | ||
| 4170 | * the new eh | ||
| 4171 | */ | ||
| 4172 | /* always call back */ | 4062 | /* always call back */ |
| 4173 | |||
| 4174 | (scpnt->scsi_done) (scpnt); | 4063 | (scpnt->scsi_done) (scpnt); |
| 4175 | 4064 | ||
| 4176 | /* | 4065 | /* |
| @@ -4563,15 +4452,16 @@ zfcp_fsf_req_sbal_check(unsigned long *flags, | |||
| 4563 | * set qtcb pointer in fsf_req and initialize QTCB | 4452 | * set qtcb pointer in fsf_req and initialize QTCB |
| 4564 | */ | 4453 | */ |
| 4565 | static inline void | 4454 | static inline void |
| 4566 | zfcp_fsf_req_qtcb_init(struct zfcp_fsf_req *fsf_req, u32 fsf_cmd) | 4455 | zfcp_fsf_req_qtcb_init(struct zfcp_fsf_req *fsf_req) |
| 4567 | { | 4456 | { |
| 4568 | if (likely(fsf_req->qtcb != NULL)) { | 4457 | if (likely(fsf_req->qtcb != NULL)) { |
| 4458 | fsf_req->qtcb->prefix.req_seq_no = fsf_req->adapter->fsf_req_seq_no; | ||
| 4569 | fsf_req->qtcb->prefix.req_id = (unsigned long)fsf_req; | 4459 | fsf_req->qtcb->prefix.req_id = (unsigned long)fsf_req; |
| 4570 | fsf_req->qtcb->prefix.ulp_info = ZFCP_ULP_INFO_VERSION; | 4460 | fsf_req->qtcb->prefix.ulp_info = ZFCP_ULP_INFO_VERSION; |
| 4571 | fsf_req->qtcb->prefix.qtcb_type = fsf_qtcb_type[fsf_cmd]; | 4461 | fsf_req->qtcb->prefix.qtcb_type = fsf_qtcb_type[fsf_req->fsf_command]; |
| 4572 | fsf_req->qtcb->prefix.qtcb_version = ZFCP_QTCB_VERSION; | 4462 | fsf_req->qtcb->prefix.qtcb_version = ZFCP_QTCB_VERSION; |
| 4573 | fsf_req->qtcb->header.req_handle = (unsigned long)fsf_req; | 4463 | fsf_req->qtcb->header.req_handle = (unsigned long)fsf_req; |
| 4574 | fsf_req->qtcb->header.fsf_command = fsf_cmd; | 4464 | fsf_req->qtcb->header.fsf_command = fsf_req->fsf_command; |
| 4575 | } | 4465 | } |
| 4576 | } | 4466 | } |
| 4577 | 4467 | ||
| @@ -4639,7 +4529,10 @@ zfcp_fsf_req_create(struct zfcp_adapter *adapter, u32 fsf_cmd, int req_flags, | |||
| 4639 | goto failed_fsf_req; | 4529 | goto failed_fsf_req; |
| 4640 | } | 4530 | } |
| 4641 | 4531 | ||
| 4642 | zfcp_fsf_req_qtcb_init(fsf_req, fsf_cmd); | 4532 | fsf_req->adapter = adapter; |
| 4533 | fsf_req->fsf_command = fsf_cmd; | ||
| 4534 | |||
| 4535 | zfcp_fsf_req_qtcb_init(fsf_req); | ||
| 4643 | 4536 | ||
| 4644 | /* initialize waitqueue which may be used to wait on | 4537 | /* initialize waitqueue which may be used to wait on |
| 4645 | this request completion */ | 4538 | this request completion */ |
| @@ -4661,8 +4554,10 @@ zfcp_fsf_req_create(struct zfcp_adapter *adapter, u32 fsf_cmd, int req_flags, | |||
| 4661 | goto failed_sbals; | 4554 | goto failed_sbals; |
| 4662 | } | 4555 | } |
| 4663 | 4556 | ||
| 4664 | fsf_req->adapter = adapter; /* pointer to "parent" adapter */ | 4557 | if (fsf_req->qtcb) { |
| 4665 | fsf_req->fsf_command = fsf_cmd; | 4558 | fsf_req->seq_no = adapter->fsf_req_seq_no; |
| 4559 | fsf_req->qtcb->prefix.req_seq_no = adapter->fsf_req_seq_no; | ||
| 4560 | } | ||
| 4666 | fsf_req->sbal_number = 1; | 4561 | fsf_req->sbal_number = 1; |
| 4667 | fsf_req->sbal_first = req_queue->free_index; | 4562 | fsf_req->sbal_first = req_queue->free_index; |
| 4668 | fsf_req->sbal_curr = req_queue->free_index; | 4563 | fsf_req->sbal_curr = req_queue->free_index; |
| @@ -4713,9 +4608,9 @@ zfcp_fsf_req_send(struct zfcp_fsf_req *fsf_req, struct timer_list *timer) | |||
| 4713 | struct zfcp_adapter *adapter; | 4608 | struct zfcp_adapter *adapter; |
| 4714 | struct zfcp_qdio_queue *req_queue; | 4609 | struct zfcp_qdio_queue *req_queue; |
| 4715 | volatile struct qdio_buffer_element *sbale; | 4610 | volatile struct qdio_buffer_element *sbale; |
| 4611 | int inc_seq_no; | ||
| 4716 | int new_distance_from_int; | 4612 | int new_distance_from_int; |
| 4717 | unsigned long flags; | 4613 | unsigned long flags; |
| 4718 | int inc_seq_no = 1; | ||
| 4719 | int retval = 0; | 4614 | int retval = 0; |
| 4720 | 4615 | ||
| 4721 | adapter = fsf_req->adapter; | 4616 | adapter = fsf_req->adapter; |
| @@ -4729,23 +4624,13 @@ zfcp_fsf_req_send(struct zfcp_fsf_req *fsf_req, struct timer_list *timer) | |||
| 4729 | ZFCP_HEX_DUMP(ZFCP_LOG_LEVEL_TRACE, (char *) sbale[1].addr, | 4624 | ZFCP_HEX_DUMP(ZFCP_LOG_LEVEL_TRACE, (char *) sbale[1].addr, |
| 4730 | sbale[1].length); | 4625 | sbale[1].length); |
| 4731 | 4626 | ||
| 4732 | /* set sequence counter in QTCB */ | ||
| 4733 | if (likely(fsf_req->qtcb)) { | ||
| 4734 | fsf_req->qtcb->prefix.req_seq_no = adapter->fsf_req_seq_no; | ||
| 4735 | fsf_req->seq_no = adapter->fsf_req_seq_no; | ||
| 4736 | ZFCP_LOG_TRACE("FSF request %p of adapter %s gets " | ||
| 4737 | "FSF sequence counter value of %i\n", | ||
| 4738 | fsf_req, | ||
| 4739 | zfcp_get_busid_by_adapter(adapter), | ||
| 4740 | fsf_req->qtcb->prefix.req_seq_no); | ||
| 4741 | } else | ||
| 4742 | inc_seq_no = 0; | ||
| 4743 | |||
| 4744 | /* put allocated FSF request at list tail */ | 4627 | /* put allocated FSF request at list tail */ |
| 4745 | spin_lock_irqsave(&adapter->fsf_req_list_lock, flags); | 4628 | spin_lock_irqsave(&adapter->fsf_req_list_lock, flags); |
| 4746 | list_add_tail(&fsf_req->list, &adapter->fsf_req_list_head); | 4629 | list_add_tail(&fsf_req->list, &adapter->fsf_req_list_head); |
| 4747 | spin_unlock_irqrestore(&adapter->fsf_req_list_lock, flags); | 4630 | spin_unlock_irqrestore(&adapter->fsf_req_list_lock, flags); |
| 4748 | 4631 | ||
| 4632 | inc_seq_no = (fsf_req->qtcb != NULL); | ||
| 4633 | |||
| 4749 | /* figure out expiration time of timeout and start timeout */ | 4634 | /* figure out expiration time of timeout and start timeout */ |
| 4750 | if (unlikely(timer)) { | 4635 | if (unlikely(timer)) { |
| 4751 | timer->expires += jiffies; | 4636 | timer->expires += jiffies; |
| @@ -4775,6 +4660,8 @@ zfcp_fsf_req_send(struct zfcp_fsf_req *fsf_req, struct timer_list *timer) | |||
| 4775 | req_queue->free_index %= QDIO_MAX_BUFFERS_PER_Q; /* wrap if needed */ | 4660 | req_queue->free_index %= QDIO_MAX_BUFFERS_PER_Q; /* wrap if needed */ |
| 4776 | new_distance_from_int = zfcp_qdio_determine_pci(req_queue, fsf_req); | 4661 | new_distance_from_int = zfcp_qdio_determine_pci(req_queue, fsf_req); |
| 4777 | 4662 | ||
| 4663 | fsf_req->issued = get_clock(); | ||
| 4664 | |||
| 4778 | retval = do_QDIO(adapter->ccw_device, | 4665 | retval = do_QDIO(adapter->ccw_device, |
| 4779 | QDIO_FLAG_SYNC_OUTPUT, | 4666 | QDIO_FLAG_SYNC_OUTPUT, |
| 4780 | 0, fsf_req->sbal_first, fsf_req->sbal_number, NULL); | 4667 | 0, fsf_req->sbal_first, fsf_req->sbal_number, NULL); |
| @@ -4813,15 +4700,11 @@ zfcp_fsf_req_send(struct zfcp_fsf_req *fsf_req, struct timer_list *timer) | |||
| 4813 | * routines resulting in missing sequence counter values | 4700 | * routines resulting in missing sequence counter values |
| 4814 | * otherwise, | 4701 | * otherwise, |
| 4815 | */ | 4702 | */ |
| 4703 | |||
| 4816 | /* Don't increase for unsolicited status */ | 4704 | /* Don't increase for unsolicited status */ |
| 4817 | if (likely(inc_seq_no)) { | 4705 | if (inc_seq_no) |
| 4818 | adapter->fsf_req_seq_no++; | 4706 | adapter->fsf_req_seq_no++; |
| 4819 | ZFCP_LOG_TRACE | 4707 | |
| 4820 | ("FSF sequence counter value of adapter %s " | ||
| 4821 | "increased to %i\n", | ||
| 4822 | zfcp_get_busid_by_adapter(adapter), | ||
| 4823 | adapter->fsf_req_seq_no); | ||
| 4824 | } | ||
| 4825 | /* count FSF requests pending */ | 4708 | /* count FSF requests pending */ |
| 4826 | atomic_inc(&adapter->fsf_reqs_active); | 4709 | atomic_inc(&adapter->fsf_reqs_active); |
| 4827 | } | 4710 | } |
diff --git a/drivers/s390/scsi/zfcp_fsf.h b/drivers/s390/scsi/zfcp_fsf.h index 07140dfda2a7..57ce0706007e 100644 --- a/drivers/s390/scsi/zfcp_fsf.h +++ b/drivers/s390/scsi/zfcp_fsf.h | |||
| @@ -116,6 +116,7 @@ | |||
| 116 | #define FSF_INVALID_COMMAND_OPTION 0x000000E5 | 116 | #define FSF_INVALID_COMMAND_OPTION 0x000000E5 |
| 117 | /* #define FSF_ERROR 0x000000FF */ | 117 | /* #define FSF_ERROR 0x000000FF */ |
| 118 | 118 | ||
| 119 | #define FSF_PROT_STATUS_QUAL_SIZE 16 | ||
| 119 | #define FSF_STATUS_QUALIFIER_SIZE 16 | 120 | #define FSF_STATUS_QUALIFIER_SIZE 16 |
| 120 | 121 | ||
| 121 | /* FSF status qualifier, recommendations */ | 122 | /* FSF status qualifier, recommendations */ |
| @@ -311,6 +312,7 @@ struct fsf_qual_locallink_error { | |||
| 311 | } __attribute__ ((packed)); | 312 | } __attribute__ ((packed)); |
| 312 | 313 | ||
| 313 | union fsf_prot_status_qual { | 314 | union fsf_prot_status_qual { |
| 315 | u64 doubleword[FSF_PROT_STATUS_QUAL_SIZE / sizeof(u64)]; | ||
| 314 | struct fsf_qual_version_error version_error; | 316 | struct fsf_qual_version_error version_error; |
| 315 | struct fsf_qual_sequence_error sequence_error; | 317 | struct fsf_qual_sequence_error sequence_error; |
| 316 | struct fsf_qual_locallink_error locallink_error; | 318 | struct fsf_qual_locallink_error locallink_error; |
| @@ -331,6 +333,7 @@ union fsf_status_qual { | |||
| 331 | u8 byte[FSF_STATUS_QUALIFIER_SIZE]; | 333 | u8 byte[FSF_STATUS_QUALIFIER_SIZE]; |
| 332 | u16 halfword[FSF_STATUS_QUALIFIER_SIZE / sizeof (u16)]; | 334 | u16 halfword[FSF_STATUS_QUALIFIER_SIZE / sizeof (u16)]; |
| 333 | u32 word[FSF_STATUS_QUALIFIER_SIZE / sizeof (u32)]; | 335 | u32 word[FSF_STATUS_QUALIFIER_SIZE / sizeof (u32)]; |
| 336 | u64 doubleword[FSF_STATUS_QUALIFIER_SIZE / sizeof(u64)]; | ||
| 334 | struct fsf_queue_designator fsf_queue_designator; | 337 | struct fsf_queue_designator fsf_queue_designator; |
| 335 | } __attribute__ ((packed)); | 338 | } __attribute__ ((packed)); |
| 336 | 339 | ||
diff --git a/drivers/s390/scsi/zfcp_qdio.c b/drivers/s390/scsi/zfcp_qdio.c index 24e16ec331d9..d719f66a29a4 100644 --- a/drivers/s390/scsi/zfcp_qdio.c +++ b/drivers/s390/scsi/zfcp_qdio.c | |||
| @@ -54,8 +54,7 @@ static inline int zfcp_qdio_sbals_from_buffer | |||
| 54 | static qdio_handler_t zfcp_qdio_request_handler; | 54 | static qdio_handler_t zfcp_qdio_request_handler; |
| 55 | static qdio_handler_t zfcp_qdio_response_handler; | 55 | static qdio_handler_t zfcp_qdio_response_handler; |
| 56 | static int zfcp_qdio_handler_error_check(struct zfcp_adapter *, | 56 | static int zfcp_qdio_handler_error_check(struct zfcp_adapter *, |
| 57 | unsigned int, | 57 | unsigned int, unsigned int, unsigned int, int, int); |
| 58 | unsigned int, unsigned int); | ||
| 59 | 58 | ||
| 60 | #define ZFCP_LOG_AREA ZFCP_LOG_AREA_QDIO | 59 | #define ZFCP_LOG_AREA ZFCP_LOG_AREA_QDIO |
| 61 | 60 | ||
| @@ -214,22 +213,12 @@ zfcp_qdio_allocate(struct zfcp_adapter *adapter) | |||
| 214 | * | 213 | * |
| 215 | */ | 214 | */ |
| 216 | static inline int | 215 | static inline int |
| 217 | zfcp_qdio_handler_error_check(struct zfcp_adapter *adapter, | 216 | zfcp_qdio_handler_error_check(struct zfcp_adapter *adapter, unsigned int status, |
| 218 | unsigned int status, | 217 | unsigned int qdio_error, unsigned int siga_error, |
| 219 | unsigned int qdio_error, unsigned int siga_error) | 218 | int first_element, int elements_processed) |
| 220 | { | 219 | { |
| 221 | int retval = 0; | 220 | int retval = 0; |
| 222 | 221 | ||
| 223 | if (ZFCP_LOG_CHECK(ZFCP_LOG_LEVEL_TRACE)) { | ||
| 224 | if (status & QDIO_STATUS_INBOUND_INT) { | ||
| 225 | ZFCP_LOG_TRACE("status is" | ||
| 226 | " QDIO_STATUS_INBOUND_INT \n"); | ||
| 227 | } | ||
| 228 | if (status & QDIO_STATUS_OUTBOUND_INT) { | ||
| 229 | ZFCP_LOG_TRACE("status is" | ||
| 230 | " QDIO_STATUS_OUTBOUND_INT \n"); | ||
| 231 | } | ||
| 232 | } | ||
| 233 | if (unlikely(status & QDIO_STATUS_LOOK_FOR_ERROR)) { | 222 | if (unlikely(status & QDIO_STATUS_LOOK_FOR_ERROR)) { |
| 234 | retval = -EIO; | 223 | retval = -EIO; |
| 235 | 224 | ||
| @@ -237,9 +226,10 @@ zfcp_qdio_handler_error_check(struct zfcp_adapter *adapter, | |||
| 237 | "qdio_error=0x%x, siga_error=0x%x)\n", | 226 | "qdio_error=0x%x, siga_error=0x%x)\n", |
| 238 | status, qdio_error, siga_error); | 227 | status, qdio_error, siga_error); |
| 239 | 228 | ||
| 240 | /* Restarting IO on the failed adapter from scratch */ | 229 | zfcp_hba_dbf_event_qdio(adapter, status, qdio_error, siga_error, |
| 241 | debug_text_event(adapter->erp_dbf, 1, "qdio_err"); | 230 | first_element, elements_processed); |
| 242 | /* | 231 | /* |
| 232 | * Restarting IO on the failed adapter from scratch. | ||
| 243 | * Since we have been using this adapter, it is save to assume | 233 | * Since we have been using this adapter, it is save to assume |
| 244 | * that it is not failed but recoverable. The card seems to | 234 | * that it is not failed but recoverable. The card seems to |
| 245 | * report link-up events by self-initiated queue shutdown. | 235 | * report link-up events by self-initiated queue shutdown. |
| @@ -282,7 +272,8 @@ zfcp_qdio_request_handler(struct ccw_device *ccw_device, | |||
| 282 | first_element, elements_processed); | 272 | first_element, elements_processed); |
| 283 | 273 | ||
| 284 | if (unlikely(zfcp_qdio_handler_error_check(adapter, status, qdio_error, | 274 | if (unlikely(zfcp_qdio_handler_error_check(adapter, status, qdio_error, |
| 285 | siga_error))) | 275 | siga_error, first_element, |
| 276 | elements_processed))) | ||
| 286 | goto out; | 277 | goto out; |
| 287 | /* | 278 | /* |
| 288 | * we stored address of struct zfcp_adapter data structure | 279 | * we stored address of struct zfcp_adapter data structure |
| @@ -334,7 +325,8 @@ zfcp_qdio_response_handler(struct ccw_device *ccw_device, | |||
| 334 | queue = &adapter->response_queue; | 325 | queue = &adapter->response_queue; |
| 335 | 326 | ||
| 336 | if (unlikely(zfcp_qdio_handler_error_check(adapter, status, qdio_error, | 327 | if (unlikely(zfcp_qdio_handler_error_check(adapter, status, qdio_error, |
| 337 | siga_error))) | 328 | siga_error, first_element, |
| 329 | elements_processed))) | ||
| 338 | goto out; | 330 | goto out; |
| 339 | 331 | ||
| 340 | /* | 332 | /* |
diff --git a/drivers/s390/scsi/zfcp_scsi.c b/drivers/s390/scsi/zfcp_scsi.c index eeb5152854ed..c1403a23174f 100644 --- a/drivers/s390/scsi/zfcp_scsi.c +++ b/drivers/s390/scsi/zfcp_scsi.c | |||
| @@ -44,7 +44,8 @@ static int zfcp_scsi_eh_abort_handler(struct scsi_cmnd *); | |||
| 44 | static int zfcp_scsi_eh_device_reset_handler(struct scsi_cmnd *); | 44 | static int zfcp_scsi_eh_device_reset_handler(struct scsi_cmnd *); |
| 45 | static int zfcp_scsi_eh_bus_reset_handler(struct scsi_cmnd *); | 45 | static int zfcp_scsi_eh_bus_reset_handler(struct scsi_cmnd *); |
| 46 | static int zfcp_scsi_eh_host_reset_handler(struct scsi_cmnd *); | 46 | static int zfcp_scsi_eh_host_reset_handler(struct scsi_cmnd *); |
| 47 | static int zfcp_task_management_function(struct zfcp_unit *, u8); | 47 | static int zfcp_task_management_function(struct zfcp_unit *, u8, |
| 48 | struct scsi_cmnd *); | ||
| 48 | 49 | ||
| 49 | static struct zfcp_unit *zfcp_unit_lookup(struct zfcp_adapter *, int, scsi_id_t, | 50 | static struct zfcp_unit *zfcp_unit_lookup(struct zfcp_adapter *, int, scsi_id_t, |
| 50 | scsi_lun_t); | 51 | scsi_lun_t); |
| @@ -242,7 +243,10 @@ static void | |||
| 242 | zfcp_scsi_command_fail(struct scsi_cmnd *scpnt, int result) | 243 | zfcp_scsi_command_fail(struct scsi_cmnd *scpnt, int result) |
| 243 | { | 244 | { |
| 244 | set_host_byte(&scpnt->result, result); | 245 | set_host_byte(&scpnt->result, result); |
| 245 | zfcp_cmd_dbf_event_scsi("failing", scpnt); | 246 | if ((scpnt->device != NULL) && (scpnt->device->host != NULL)) |
| 247 | zfcp_scsi_dbf_event_result("fail", 4, | ||
| 248 | (struct zfcp_adapter*) scpnt->device->host->hostdata[0], | ||
| 249 | scpnt); | ||
| 246 | /* return directly */ | 250 | /* return directly */ |
| 247 | scpnt->scsi_done(scpnt); | 251 | scpnt->scsi_done(scpnt); |
| 248 | } | 252 | } |
| @@ -434,7 +438,8 @@ zfcp_scsi_eh_abort_handler(struct scsi_cmnd *scpnt) | |||
| 434 | struct zfcp_adapter *adapter; | 438 | struct zfcp_adapter *adapter; |
| 435 | struct zfcp_unit *unit; | 439 | struct zfcp_unit *unit; |
| 436 | int retval = SUCCESS; | 440 | int retval = SUCCESS; |
| 437 | struct zfcp_fsf_req *new_fsf_req, *old_fsf_req; | 441 | struct zfcp_fsf_req *new_fsf_req = NULL; |
| 442 | struct zfcp_fsf_req *old_fsf_req; | ||
| 438 | unsigned long flags; | 443 | unsigned long flags; |
| 439 | 444 | ||
| 440 | scsi_host = scpnt->device->host; | 445 | scsi_host = scpnt->device->host; |
| @@ -457,11 +462,8 @@ zfcp_scsi_eh_abort_handler(struct scsi_cmnd *scpnt) | |||
| 457 | old_fsf_req = (struct zfcp_fsf_req *) scpnt->host_scribble; | 462 | old_fsf_req = (struct zfcp_fsf_req *) scpnt->host_scribble; |
| 458 | if (!old_fsf_req) { | 463 | if (!old_fsf_req) { |
| 459 | write_unlock_irqrestore(&adapter->abort_lock, flags); | 464 | write_unlock_irqrestore(&adapter->abort_lock, flags); |
| 460 | ZFCP_LOG_NORMAL("bug: no old fsf request found\n"); | 465 | zfcp_scsi_dbf_event_abort("lte1", adapter, scpnt, new_fsf_req); |
| 461 | ZFCP_LOG_NORMAL("scsi_cmnd:\n"); | 466 | retval = SUCCESS; |
| 462 | ZFCP_HEX_DUMP(ZFCP_LOG_LEVEL_NORMAL, | ||
| 463 | (char *) scpnt, sizeof (struct scsi_cmnd)); | ||
| 464 | retval = FAILED; | ||
| 465 | goto out; | 467 | goto out; |
| 466 | } | 468 | } |
| 467 | old_fsf_req->data = 0; | 469 | old_fsf_req->data = 0; |
| @@ -473,25 +475,27 @@ zfcp_scsi_eh_abort_handler(struct scsi_cmnd *scpnt) | |||
| 473 | new_fsf_req = zfcp_fsf_abort_fcp_command((unsigned long) old_fsf_req, | 475 | new_fsf_req = zfcp_fsf_abort_fcp_command((unsigned long) old_fsf_req, |
| 474 | adapter, unit, 0); | 476 | adapter, unit, 0); |
| 475 | if (!new_fsf_req) { | 477 | if (!new_fsf_req) { |
| 478 | ZFCP_LOG_INFO("error: initiation of Abort FCP Cmnd failed\n"); | ||
| 476 | retval = FAILED; | 479 | retval = FAILED; |
| 477 | ZFCP_LOG_NORMAL("error: initiation of Abort FCP Cmnd " | ||
| 478 | "failed\n"); | ||
| 479 | goto out; | 480 | goto out; |
| 480 | } | 481 | } |
| 481 | 482 | ||
| 482 | /* wait for completion of abort */ | 483 | /* wait for completion of abort */ |
| 483 | __wait_event(new_fsf_req->completion_wq, | 484 | __wait_event(new_fsf_req->completion_wq, |
| 484 | new_fsf_req->status & ZFCP_STATUS_FSFREQ_COMPLETED); | 485 | new_fsf_req->status & ZFCP_STATUS_FSFREQ_COMPLETED); |
| 485 | zfcp_fsf_req_free(new_fsf_req); | ||
| 486 | 486 | ||
| 487 | /* status should be valid since signals were not permitted */ | 487 | /* status should be valid since signals were not permitted */ |
| 488 | if (new_fsf_req->status & ZFCP_STATUS_FSFREQ_ABORTSUCCEEDED) { | 488 | if (new_fsf_req->status & ZFCP_STATUS_FSFREQ_ABORTSUCCEEDED) { |
| 489 | zfcp_scsi_dbf_event_abort("okay", adapter, scpnt, new_fsf_req); | ||
| 489 | retval = SUCCESS; | 490 | retval = SUCCESS; |
| 490 | } else if (new_fsf_req->status & ZFCP_STATUS_FSFREQ_ABORTNOTNEEDED) { | 491 | } else if (new_fsf_req->status & ZFCP_STATUS_FSFREQ_ABORTNOTNEEDED) { |
| 492 | zfcp_scsi_dbf_event_abort("lte2", adapter, scpnt, new_fsf_req); | ||
| 491 | retval = SUCCESS; | 493 | retval = SUCCESS; |
| 492 | } else { | 494 | } else { |
| 495 | zfcp_scsi_dbf_event_abort("fail", adapter, scpnt, new_fsf_req); | ||
| 493 | retval = FAILED; | 496 | retval = FAILED; |
| 494 | } | 497 | } |
| 498 | zfcp_fsf_req_free(new_fsf_req); | ||
| 495 | out: | 499 | out: |
| 496 | return retval; | 500 | return retval; |
| 497 | } | 501 | } |
| @@ -525,8 +529,9 @@ zfcp_scsi_eh_device_reset_handler(struct scsi_cmnd *scpnt) | |||
| 525 | */ | 529 | */ |
| 526 | if (!atomic_test_mask(ZFCP_STATUS_UNIT_NOTSUPPUNITRESET, | 530 | if (!atomic_test_mask(ZFCP_STATUS_UNIT_NOTSUPPUNITRESET, |
| 527 | &unit->status)) { | 531 | &unit->status)) { |
| 528 | retval = | 532 | retval = zfcp_task_management_function(unit, |
| 529 | zfcp_task_management_function(unit, FCP_LOGICAL_UNIT_RESET); | 533 | FCP_LOGICAL_UNIT_RESET, |
| 534 | scpnt); | ||
| 530 | if (retval) { | 535 | if (retval) { |
| 531 | ZFCP_LOG_DEBUG("unit reset failed (unit=%p)\n", unit); | 536 | ZFCP_LOG_DEBUG("unit reset failed (unit=%p)\n", unit); |
| 532 | if (retval == -ENOTSUPP) | 537 | if (retval == -ENOTSUPP) |
| @@ -542,7 +547,7 @@ zfcp_scsi_eh_device_reset_handler(struct scsi_cmnd *scpnt) | |||
| 542 | goto out; | 547 | goto out; |
| 543 | } | 548 | } |
| 544 | } | 549 | } |
| 545 | retval = zfcp_task_management_function(unit, FCP_TARGET_RESET); | 550 | retval = zfcp_task_management_function(unit, FCP_TARGET_RESET, scpnt); |
| 546 | if (retval) { | 551 | if (retval) { |
| 547 | ZFCP_LOG_DEBUG("target reset failed (unit=%p)\n", unit); | 552 | ZFCP_LOG_DEBUG("target reset failed (unit=%p)\n", unit); |
| 548 | retval = FAILED; | 553 | retval = FAILED; |
| @@ -555,7 +560,8 @@ zfcp_scsi_eh_device_reset_handler(struct scsi_cmnd *scpnt) | |||
| 555 | } | 560 | } |
| 556 | 561 | ||
| 557 | static int | 562 | static int |
| 558 | zfcp_task_management_function(struct zfcp_unit *unit, u8 tm_flags) | 563 | zfcp_task_management_function(struct zfcp_unit *unit, u8 tm_flags, |
| 564 | struct scsi_cmnd *scpnt) | ||
| 559 | { | 565 | { |
| 560 | struct zfcp_adapter *adapter = unit->port->adapter; | 566 | struct zfcp_adapter *adapter = unit->port->adapter; |
| 561 | struct zfcp_fsf_req *fsf_req; | 567 | struct zfcp_fsf_req *fsf_req; |
| @@ -569,6 +575,7 @@ zfcp_task_management_function(struct zfcp_unit *unit, u8 tm_flags) | |||
| 569 | "failed for unit 0x%016Lx on port 0x%016Lx on " | 575 | "failed for unit 0x%016Lx on port 0x%016Lx on " |
| 570 | "adapter %s\n", unit->fcp_lun, unit->port->wwpn, | 576 | "adapter %s\n", unit->fcp_lun, unit->port->wwpn, |
| 571 | zfcp_get_busid_by_adapter(adapter)); | 577 | zfcp_get_busid_by_adapter(adapter)); |
| 578 | zfcp_scsi_dbf_event_devreset("nres", tm_flags, unit, scpnt); | ||
| 572 | retval = -ENOMEM; | 579 | retval = -ENOMEM; |
| 573 | goto out; | 580 | goto out; |
| 574 | } | 581 | } |
| @@ -576,11 +583,17 @@ zfcp_task_management_function(struct zfcp_unit *unit, u8 tm_flags) | |||
| 576 | __wait_event(fsf_req->completion_wq, | 583 | __wait_event(fsf_req->completion_wq, |
| 577 | fsf_req->status & ZFCP_STATUS_FSFREQ_COMPLETED); | 584 | fsf_req->status & ZFCP_STATUS_FSFREQ_COMPLETED); |
| 578 | 585 | ||
| 579 | /* check completion status of task management function */ | 586 | /* |
| 580 | if (fsf_req->status & ZFCP_STATUS_FSFREQ_TMFUNCFAILED) | 587 | * check completion status of task management function |
| 588 | */ | ||
| 589 | if (fsf_req->status & ZFCP_STATUS_FSFREQ_TMFUNCFAILED) { | ||
| 590 | zfcp_scsi_dbf_event_devreset("fail", tm_flags, unit, scpnt); | ||
| 581 | retval = -EIO; | 591 | retval = -EIO; |
| 582 | else if (fsf_req->status & ZFCP_STATUS_FSFREQ_TMFUNCNOTSUPP) | 592 | } else if (fsf_req->status & ZFCP_STATUS_FSFREQ_TMFUNCNOTSUPP) { |
| 593 | zfcp_scsi_dbf_event_devreset("nsup", tm_flags, unit, scpnt); | ||
| 583 | retval = -ENOTSUPP; | 594 | retval = -ENOTSUPP; |
| 595 | } else | ||
| 596 | zfcp_scsi_dbf_event_devreset("okay", tm_flags, unit, scpnt); | ||
| 584 | 597 | ||
| 585 | zfcp_fsf_req_free(fsf_req); | 598 | zfcp_fsf_req_free(fsf_req); |
| 586 | out: | 599 | out: |
