diff options
author | Maxim Shchetynin <maxim@de.ibm.com> | 2005-09-13 15:50:38 -0400 |
---|---|---|
committer | James Bottomley <jejb@mulgrave.(none)> | 2005-09-19 14:03:00 -0400 |
commit | 8a36e4532ea10471f0a8605207d071361d7be2c3 (patch) | |
tree | f34e5928de7d73b9aaf385f3fb0847a6c52c297b | |
parent | 810f1e3ea5cc0a812816af97020a27c73441f8e9 (diff) |
[SCSI] zfcp: enhancement of zfcp debug features
Debug features (DBFs) els_dbf, cmd_dbf and abt_dbf were removed and
san_dbf, hba_dbf and scsi_dbf were introduced. The erp_dbf did not
change.
The new traces improve debugging of problems with zfcp, scsi-stack,
multipath and hardware in the SAN. san_dbf traces things like ELS and
CT commands, hba_dbf saves HBA specific information of requests, and
scsi_dbf saves FCP and SCSI specific information of requests. Common
to all new DBFs is that they provide a so called structured view. This
significantly improves readability of the traces.
Signed-off-by: Andreas Herrmann <aherrman@de.ibm.com>
Signed-off-by: James Bottomley <James.Bottomley@SteelEye.com>
-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: |