Commit 8a36e453 authored by Maxim Shchetynin's avatar Maxim Shchetynin Committed by James Bottomley
Browse files

[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: default avatarAndreas Herrmann <aherrman@de.ibm.com>
Signed-off-by: default avatarJames Bottomley <James.Bottomley@SteelEye.com>
parent 810f1e3e
Loading
Loading
Loading
Loading
+1 −1
Original line number Diff line number Diff line
@@ -3,7 +3,7 @@
#

zfcp-objs := zfcp_aux.o zfcp_ccw.o zfcp_scsi.o zfcp_erp.o zfcp_qdio.o \
	     zfcp_fsf.o zfcp_sysfs_adapter.o zfcp_sysfs_port.o \
	     zfcp_fsf.o zfcp_dbf.o zfcp_sysfs_adapter.o zfcp_sysfs_port.o \
	     zfcp_sysfs_unit.o zfcp_sysfs_driver.o

obj-$(CONFIG_ZFCP) += zfcp.o
+1 −179
Original line number Diff line number Diff line
@@ -122,93 +122,6 @@ _zfcp_hex_dump(char *addr, int count)

#define ZFCP_LOG_AREA			ZFCP_LOG_AREA_OTHER

static inline int
zfcp_fsf_req_is_scsi_cmnd(struct zfcp_fsf_req *fsf_req)
{
	return ((fsf_req->fsf_command == FSF_QTCB_FCP_CMND) &&
		!(fsf_req->status & ZFCP_STATUS_FSFREQ_TASK_MANAGEMENT));
}

void
zfcp_cmd_dbf_event_fsf(const char *text, struct zfcp_fsf_req *fsf_req,
		       void *add_data, int add_length)
{
	struct zfcp_adapter *adapter = fsf_req->adapter;
	struct scsi_cmnd *scsi_cmnd;
	int level = 3;
	int i;
	unsigned long flags;

	spin_lock_irqsave(&adapter->dbf_lock, flags);
	if (zfcp_fsf_req_is_scsi_cmnd(fsf_req)) {
		scsi_cmnd = (struct scsi_cmnd*) fsf_req->data;
		debug_text_event(adapter->cmd_dbf, level, "fsferror");
		debug_text_event(adapter->cmd_dbf, level, text);
		debug_event(adapter->cmd_dbf, level, &fsf_req,
			    sizeof (unsigned long));
		debug_event(adapter->cmd_dbf, level, &fsf_req->seq_no,
			    sizeof (u32));
		debug_event(adapter->cmd_dbf, level, &scsi_cmnd,
			    sizeof (unsigned long));
		debug_event(adapter->cmd_dbf, level, &scsi_cmnd->cmnd,
			    min(ZFCP_CMD_DBF_LENGTH, (int)scsi_cmnd->cmd_len));
		for (i = 0; i < add_length; i += ZFCP_CMD_DBF_LENGTH)
			debug_event(adapter->cmd_dbf,
				    level,
				    (char *) add_data + i,
				    min(ZFCP_CMD_DBF_LENGTH, add_length - i));
	}
	spin_unlock_irqrestore(&adapter->dbf_lock, flags);
}

/* XXX additionally log unit if available */
/* ---> introduce new parameter for unit, see 2.4 code */
void
zfcp_cmd_dbf_event_scsi(const char *text, struct scsi_cmnd *scsi_cmnd)
{
	struct zfcp_adapter *adapter;
	struct zfcp_fsf_req *fsf_req;
	int level = ((host_byte(scsi_cmnd->result) != 0) ? 1 : 5);
	unsigned long flags;

	adapter = (struct zfcp_adapter *) scsi_cmnd->device->host->hostdata[0];
	fsf_req = (struct zfcp_fsf_req  *) scsi_cmnd->host_scribble;
	spin_lock_irqsave(&adapter->dbf_lock, flags);
	debug_text_event(adapter->cmd_dbf, level, "hostbyte");
	debug_text_event(adapter->cmd_dbf, level, text);
	debug_event(adapter->cmd_dbf, level, &scsi_cmnd->result, sizeof (u32));
	debug_event(adapter->cmd_dbf, level, &scsi_cmnd,
		    sizeof (unsigned long));
	debug_event(adapter->cmd_dbf, level, &scsi_cmnd->cmnd,
		    min(ZFCP_CMD_DBF_LENGTH, (int)scsi_cmnd->cmd_len));
	if (likely(fsf_req)) {
		debug_event(adapter->cmd_dbf, level, &fsf_req,
			    sizeof (unsigned long));
		debug_event(adapter->cmd_dbf, level, &fsf_req->seq_no,
			    sizeof (u32));
	} else {
		debug_text_event(adapter->cmd_dbf, level, "");
		debug_text_event(adapter->cmd_dbf, level, "");
	}
	spin_unlock_irqrestore(&adapter->dbf_lock, flags);
}

void
zfcp_in_els_dbf_event(struct zfcp_adapter *adapter, const char *text,
		      struct fsf_status_read_buffer *status_buffer, int length)
{
	int level = 1;
	int i;

	debug_text_event(adapter->in_els_dbf, level, text);
	debug_event(adapter->in_els_dbf, level, &status_buffer->d_id, 8);
	for (i = 0; i < length; i += ZFCP_IN_ELS_DBF_LENGTH)
		debug_event(adapter->in_els_dbf,
			    level,
			    (char *) status_buffer->payload + i,
			    min(ZFCP_IN_ELS_DBF_LENGTH, length - i));
}

/**
 * zfcp_device_setup - setup function
 * @str: pointer to parameter string
@@ -1015,81 +928,6 @@ zfcp_free_low_mem_buffers(struct zfcp_adapter *adapter)
		mempool_destroy(adapter->pool.data_gid_pn);
}

/**
 * zfcp_adapter_debug_register - registers debug feature for an adapter
 * @adapter: pointer to adapter for which debug features should be registered
 * return: -ENOMEM on error, 0 otherwise
 */
int
zfcp_adapter_debug_register(struct zfcp_adapter *adapter)
{
	char dbf_name[20];

	/* debug feature area which records SCSI command failures (hostbyte) */
	spin_lock_init(&adapter->dbf_lock);

	sprintf(dbf_name, ZFCP_CMD_DBF_NAME "%s",
		zfcp_get_busid_by_adapter(adapter));
	adapter->cmd_dbf = debug_register(dbf_name, ZFCP_CMD_DBF_INDEX,
					  ZFCP_CMD_DBF_AREAS,
					  ZFCP_CMD_DBF_LENGTH);
	debug_register_view(adapter->cmd_dbf, &debug_hex_ascii_view);
	debug_set_level(adapter->cmd_dbf, ZFCP_CMD_DBF_LEVEL);

	/* debug feature area which records SCSI command aborts */
	sprintf(dbf_name, ZFCP_ABORT_DBF_NAME "%s",
		zfcp_get_busid_by_adapter(adapter));
	adapter->abort_dbf = debug_register(dbf_name, ZFCP_ABORT_DBF_INDEX,
					    ZFCP_ABORT_DBF_AREAS,
					    ZFCP_ABORT_DBF_LENGTH);
	debug_register_view(adapter->abort_dbf, &debug_hex_ascii_view);
	debug_set_level(adapter->abort_dbf, ZFCP_ABORT_DBF_LEVEL);

	/* debug feature area which records incoming ELS commands */
	sprintf(dbf_name, ZFCP_IN_ELS_DBF_NAME "%s",
		zfcp_get_busid_by_adapter(adapter));
	adapter->in_els_dbf = debug_register(dbf_name, ZFCP_IN_ELS_DBF_INDEX,
					     ZFCP_IN_ELS_DBF_AREAS,
					     ZFCP_IN_ELS_DBF_LENGTH);
	debug_register_view(adapter->in_els_dbf, &debug_hex_ascii_view);
	debug_set_level(adapter->in_els_dbf, ZFCP_IN_ELS_DBF_LEVEL);

	/* debug feature area which records erp events */
	sprintf(dbf_name, ZFCP_ERP_DBF_NAME "%s",
		zfcp_get_busid_by_adapter(adapter));
	adapter->erp_dbf = debug_register(dbf_name, ZFCP_ERP_DBF_INDEX,
					  ZFCP_ERP_DBF_AREAS,
					  ZFCP_ERP_DBF_LENGTH);
	debug_register_view(adapter->erp_dbf, &debug_hex_ascii_view);
	debug_set_level(adapter->erp_dbf, ZFCP_ERP_DBF_LEVEL);

	if (!(adapter->cmd_dbf && adapter->abort_dbf &&
	      adapter->in_els_dbf && adapter->erp_dbf)) {
		zfcp_adapter_debug_unregister(adapter);
		return -ENOMEM;
	}

	return 0;

}

/**
 * zfcp_adapter_debug_unregister - unregisters debug feature for an adapter
 * @adapter: pointer to adapter for which debug features should be unregistered
 */
void
zfcp_adapter_debug_unregister(struct zfcp_adapter *adapter)
{
 	debug_unregister(adapter->abort_dbf);
 	debug_unregister(adapter->cmd_dbf);
 	debug_unregister(adapter->erp_dbf);
 	debug_unregister(adapter->in_els_dbf);
	adapter->abort_dbf = NULL;
	adapter->cmd_dbf = NULL;
	adapter->erp_dbf = NULL;
	adapter->in_els_dbf = NULL;
}

void
zfcp_dummy_release(struct device *dev)
{
@@ -1460,10 +1298,6 @@ zfcp_fsf_incoming_els_rscn(struct zfcp_adapter *adapter,
	/* see FC-FS */
	no_entries = (fcp_rscn_head->payload_len / 4);

	zfcp_in_els_dbf_event(adapter, "##rscn", status_buffer,
			      fcp_rscn_head->payload_len);

	debug_text_event(adapter->erp_dbf, 1, "unsol_els_rscn:");
	for (i = 1; i < no_entries; i++) {
		/* skip head and start with 1st element */
		fcp_rscn_element++;
@@ -1495,8 +1329,6 @@ zfcp_fsf_incoming_els_rscn(struct zfcp_adapter *adapter,
			    (ZFCP_STATUS_PORT_DID_DID, &port->status)) {
				ZFCP_LOG_INFO("incoming RSCN, trying to open "
					      "port 0x%016Lx\n", port->wwpn);
				debug_text_event(adapter->erp_dbf, 1,
						 "unsol_els_rscnu:");
				zfcp_erp_port_reopen(port,
						     ZFCP_STATUS_COMMON_ERP_FAILED);
				continue;
@@ -1522,8 +1354,6 @@ zfcp_fsf_incoming_els_rscn(struct zfcp_adapter *adapter,
				 */
				ZFCP_LOG_INFO("incoming RSCN, trying to open "
					      "port 0x%016Lx\n", port->wwpn);
				debug_text_event(adapter->erp_dbf, 1,
						 "unsol_els_rscnk:");
				zfcp_test_link(port);
			}
		}
@@ -1539,8 +1369,6 @@ zfcp_fsf_incoming_els_plogi(struct zfcp_adapter *adapter,
	struct zfcp_port *port;
	unsigned long flags;

	zfcp_in_els_dbf_event(adapter, "##plogi", status_buffer, 28);

	read_lock_irqsave(&zfcp_data.config_lock, flags);
	list_for_each_entry(port, &adapter->port_list_head, list) {
		if (port->wwpn == (*(wwn_t *) & els_logi->nport_wwn))
@@ -1554,8 +1382,6 @@ zfcp_fsf_incoming_els_plogi(struct zfcp_adapter *adapter,
			       status_buffer->d_id,
			       zfcp_get_busid_by_adapter(adapter));
	} else {
		debug_text_event(adapter->erp_dbf, 1, "unsol_els_plogi:");
		debug_event(adapter->erp_dbf, 1, &els_logi->nport_wwn, 8);
		zfcp_erp_port_forced_reopen(port, 0);
	}
}
@@ -1568,8 +1394,6 @@ zfcp_fsf_incoming_els_logo(struct zfcp_adapter *adapter,
	struct zfcp_port *port;
	unsigned long flags;

	zfcp_in_els_dbf_event(adapter, "##logo", status_buffer, 16);

	read_lock_irqsave(&zfcp_data.config_lock, flags);
	list_for_each_entry(port, &adapter->port_list_head, list) {
		if (port->wwpn == els_logo->nport_wwpn)
@@ -1583,8 +1407,6 @@ zfcp_fsf_incoming_els_logo(struct zfcp_adapter *adapter,
			       status_buffer->d_id,
			       zfcp_get_busid_by_adapter(adapter));
	} else {
		debug_text_event(adapter->erp_dbf, 1, "unsol_els_logo:");
		debug_event(adapter->erp_dbf, 1, &els_logo->nport_wwpn, 8);
		zfcp_erp_port_forced_reopen(port, 0);
	}
}
@@ -1593,7 +1415,6 @@ static void
zfcp_fsf_incoming_els_unknown(struct zfcp_adapter *adapter,
			      struct fsf_status_read_buffer *status_buffer)
{
	zfcp_in_els_dbf_event(adapter, "##undef", status_buffer, 24);
	ZFCP_LOG_NORMAL("warning: unknown incoming ELS 0x%08x "
			"for adapter %s\n", *(u32 *) (status_buffer->payload),
			zfcp_get_busid_by_adapter(adapter));
@@ -1611,6 +1432,7 @@ zfcp_fsf_incoming_els(struct zfcp_fsf_req *fsf_req)
	els_type = *(u32 *) (status_buffer->payload);
	adapter = fsf_req->adapter;

	zfcp_san_dbf_event_incoming_els(fsf_req);
	if (els_type == LS_PLOGI)
		zfcp_fsf_incoming_els_plogi(adapter, status_buffer);
	else if (els_type == LS_LOGO)
Loading