⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 zfcp_dbf.c

📁 linux-2.6.15.6
💻 C
📖 第 1 页 / 共 3 页
字号:
/* * * linux/drivers/s390/scsi/zfcp_dbf.c * * FCP adapter driver for IBM eServer zSeries * * Debugging facilities * * (C) Copyright IBM Corp. 2005 * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2, or (at your option) * any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */#define ZFCP_DBF_REVISION "$Revision$"#include <asm/debug.h>#include <linux/ctype.h>#include "zfcp_ext.h"static u32 dbfsize = 4;module_param(dbfsize, uint, 0400);MODULE_PARM_DESC(dbfsize,		 "number of pages for each debug feature area (default 4)");#define ZFCP_LOG_AREA			ZFCP_LOG_AREA_OTHERstatic inline intzfcp_dbf_stck(char *out_buf, const char *label, unsigned long long stck){	unsigned long long sec;	struct timespec xtime;	int len = 0;	stck -= 0x8126d60e46000000LL - (0x3c26700LL * 1000000 * 4096);	sec = stck >> 12;	do_div(sec, 1000000);	xtime.tv_sec = sec;	stck -= (sec * 1000000) << 12;	xtime.tv_nsec = ((stck * 1000) >> 12);	len += sprintf(out_buf + len, "%-24s%011lu:%06lu\n",		       label, xtime.tv_sec, xtime.tv_nsec);	return len;}static int zfcp_dbf_tag(char *out_buf, const char *label, const char *tag){	int len = 0, i;	len += sprintf(out_buf + len, "%-24s", label);	for (i = 0; i < ZFCP_DBF_TAG_SIZE; i++)		len += sprintf(out_buf + len, "%c", tag[i]);	len += sprintf(out_buf + len, "\n");	return len;}static intzfcp_dbf_view(char *out_buf, const char *label, const char *format, ...){	va_list arg;	int len = 0;	len += sprintf(out_buf + len, "%-24s", label);	va_start(arg, format);	len += vsprintf(out_buf + len, format, arg);	va_end(arg);	len += sprintf(out_buf + len, "\n");	return len;}static intzfcp_dbf_view_dump(char *out_buf, const char *label,		   char *buffer, int buflen, int offset, int total_size){	int len = 0;	if (offset == 0)		len += sprintf(out_buf + len, "%-24s  ", label);	while (buflen--) {		if (offset > 0) {			if ((offset % 32) == 0)				len += sprintf(out_buf + len, "\n%-24c  ", ' ');			else if ((offset % 4) == 0)				len += sprintf(out_buf + len, " ");		}		len += sprintf(out_buf + len, "%02x", *buffer++);		if (++offset == total_size) {			len += sprintf(out_buf + len, "\n");			break;		}	}	if (total_size == 0)		len += sprintf(out_buf + len, "\n");	return len;}static inline intzfcp_dbf_view_header(debug_info_t * id, struct debug_view *view, int area,		     debug_entry_t * entry, char *out_buf){	struct zfcp_dbf_dump *dump = (struct zfcp_dbf_dump *)DEBUG_DATA(entry);	int len = 0;	if (strncmp(dump->tag, "dump", ZFCP_DBF_TAG_SIZE) != 0) {		len += zfcp_dbf_stck(out_buf + len, "timestamp",				     entry->id.stck);		len += zfcp_dbf_view(out_buf + len, "cpu", "%02i",				     entry->id.fields.cpuid);	} else {		len += zfcp_dbf_view_dump(out_buf + len, NULL,					  dump->data,					  dump->size,					  dump->offset, dump->total_size);		if ((dump->offset + dump->size) == dump->total_size)			len += sprintf(out_buf + len, "\n");	}	return len;}inline void zfcp_hba_dbf_event_fsf_response(struct zfcp_fsf_req *fsf_req){	struct zfcp_adapter *adapter = fsf_req->adapter;	struct fsf_qtcb *qtcb = fsf_req->qtcb;	union fsf_prot_status_qual *prot_status_qual =	    &qtcb->prefix.prot_status_qual;	union fsf_status_qual *fsf_status_qual = &qtcb->header.fsf_status_qual;	struct scsi_cmnd *scsi_cmnd;	struct zfcp_port *port;	struct zfcp_unit *unit;	struct zfcp_send_els *send_els;	struct zfcp_hba_dbf_record *rec = &adapter->hba_dbf_buf;	struct zfcp_hba_dbf_record_response *response = &rec->type.response;	int level;	unsigned long flags;	spin_lock_irqsave(&adapter->hba_dbf_lock, flags);	memset(rec, 0, sizeof(struct zfcp_hba_dbf_record));	strncpy(rec->tag, "resp", ZFCP_DBF_TAG_SIZE);	if ((qtcb->prefix.prot_status != FSF_PROT_GOOD) &&	    (qtcb->prefix.prot_status != FSF_PROT_FSF_STATUS_PRESENTED)) {		strncpy(rec->tag2, "perr", ZFCP_DBF_TAG_SIZE);		level = 1;	} else if (qtcb->header.fsf_status != FSF_GOOD) {		strncpy(rec->tag2, "ferr", ZFCP_DBF_TAG_SIZE);		level = 1;	} else if ((fsf_req->fsf_command == FSF_QTCB_OPEN_PORT_WITH_DID) ||		   (fsf_req->fsf_command == FSF_QTCB_OPEN_LUN)) {		strncpy(rec->tag2, "open", ZFCP_DBF_TAG_SIZE);		level = 4;	} else if ((prot_status_qual->doubleword[0] != 0) ||		   (prot_status_qual->doubleword[1] != 0) ||		   (fsf_status_qual->doubleword[0] != 0) ||		   (fsf_status_qual->doubleword[1] != 0)) {		strncpy(rec->tag2, "qual", ZFCP_DBF_TAG_SIZE);		level = 3;	} else {		strncpy(rec->tag2, "norm", ZFCP_DBF_TAG_SIZE);		level = 6;	}	response->fsf_command = fsf_req->fsf_command;	response->fsf_reqid = (unsigned long)fsf_req;	response->fsf_seqno = fsf_req->seq_no;	response->fsf_issued = fsf_req->issued;	response->fsf_prot_status = qtcb->prefix.prot_status;	response->fsf_status = qtcb->header.fsf_status;	memcpy(response->fsf_prot_status_qual,	       prot_status_qual, FSF_PROT_STATUS_QUAL_SIZE);	memcpy(response->fsf_status_qual,	       fsf_status_qual, FSF_STATUS_QUALIFIER_SIZE);	response->fsf_req_status = fsf_req->status;	response->sbal_first = fsf_req->sbal_first;	response->sbal_curr = fsf_req->sbal_curr;	response->sbal_last = fsf_req->sbal_last;	response->pool = fsf_req->pool != NULL;	response->erp_action = (unsigned long)fsf_req->erp_action;	switch (fsf_req->fsf_command) {	case FSF_QTCB_FCP_CMND:		if (fsf_req->status & ZFCP_STATUS_FSFREQ_TASK_MANAGEMENT)			break;		scsi_cmnd = (struct scsi_cmnd *)fsf_req->data;		if (scsi_cmnd != NULL) {			response->data.send_fcp.scsi_cmnd			    = (unsigned long)scsi_cmnd;			response->data.send_fcp.scsi_serial			    = scsi_cmnd->serial_number;		}		break;	case FSF_QTCB_OPEN_PORT_WITH_DID:	case FSF_QTCB_CLOSE_PORT:	case FSF_QTCB_CLOSE_PHYSICAL_PORT:		port = (struct zfcp_port *)fsf_req->data;		response->data.port.wwpn = port->wwpn;		response->data.port.d_id = port->d_id;		response->data.port.port_handle = qtcb->header.port_handle;		break;	case FSF_QTCB_OPEN_LUN:	case FSF_QTCB_CLOSE_LUN:		unit = (struct zfcp_unit *)fsf_req->data;		port = unit->port;		response->data.unit.wwpn = port->wwpn;		response->data.unit.fcp_lun = unit->fcp_lun;		response->data.unit.port_handle = qtcb->header.port_handle;		response->data.unit.lun_handle = qtcb->header.lun_handle;		break;	case FSF_QTCB_SEND_ELS:		send_els = (struct zfcp_send_els *)fsf_req->data;		response->data.send_els.d_id = qtcb->bottom.support.d_id;		response->data.send_els.ls_code = send_els->ls_code >> 24;		break;	case FSF_QTCB_ABORT_FCP_CMND:	case FSF_QTCB_SEND_GENERIC:	case FSF_QTCB_EXCHANGE_CONFIG_DATA:	case FSF_QTCB_EXCHANGE_PORT_DATA:	case FSF_QTCB_DOWNLOAD_CONTROL_FILE:	case FSF_QTCB_UPLOAD_CONTROL_FILE:		break;	}	debug_event(adapter->hba_dbf, level,		    rec, sizeof(struct zfcp_hba_dbf_record));	spin_unlock_irqrestore(&adapter->hba_dbf_lock, flags);}inline voidzfcp_hba_dbf_event_fsf_unsol(const char *tag, struct zfcp_adapter *adapter,			     struct fsf_status_read_buffer *status_buffer){	struct zfcp_hba_dbf_record *rec = &adapter->hba_dbf_buf;	unsigned long flags;	spin_lock_irqsave(&adapter->hba_dbf_lock, flags);	memset(rec, 0, sizeof(struct zfcp_hba_dbf_record));	strncpy(rec->tag, "stat", ZFCP_DBF_TAG_SIZE);	strncpy(rec->tag2, tag, ZFCP_DBF_TAG_SIZE);	rec->type.status.failed = adapter->status_read_failed;	if (status_buffer != NULL) {		rec->type.status.status_type = status_buffer->status_type;		rec->type.status.status_subtype = status_buffer->status_subtype;		memcpy(&rec->type.status.queue_designator,		       &status_buffer->queue_designator,		       sizeof(struct fsf_queue_designator));		switch (status_buffer->status_type) {		case FSF_STATUS_READ_SENSE_DATA_AVAIL:			rec->type.status.payload_size =			    ZFCP_DBF_UNSOL_PAYLOAD_SENSE_DATA_AVAIL;			break;		case FSF_STATUS_READ_BIT_ERROR_THRESHOLD:			rec->type.status.payload_size =			    ZFCP_DBF_UNSOL_PAYLOAD_BIT_ERROR_THRESHOLD;			break;		case FSF_STATUS_READ_LINK_DOWN:			switch (status_buffer->status_subtype) {			case FSF_STATUS_READ_SUB_NO_PHYSICAL_LINK:			case FSF_STATUS_READ_SUB_FDISC_FAILED:				rec->type.status.payload_size =					sizeof(struct fsf_link_down_info);			}			break;		case FSF_STATUS_READ_FEATURE_UPDATE_ALERT:			rec->type.status.payload_size =			    ZFCP_DBF_UNSOL_PAYLOAD_FEATURE_UPDATE_ALERT;			break;		}		memcpy(&rec->type.status.payload,		       &status_buffer->payload, rec->type.status.payload_size);	}	debug_event(adapter->hba_dbf, 2,		    rec, sizeof(struct zfcp_hba_dbf_record));	spin_unlock_irqrestore(&adapter->hba_dbf_lock, flags);}inline voidzfcp_hba_dbf_event_qdio(struct zfcp_adapter *adapter, unsigned int status,			unsigned int qdio_error, unsigned int siga_error,			int sbal_index, int sbal_count){	struct zfcp_hba_dbf_record *rec = &adapter->hba_dbf_buf;	unsigned long flags;	spin_lock_irqsave(&adapter->hba_dbf_lock, flags);	memset(rec, 0, sizeof(struct zfcp_hba_dbf_record));	strncpy(rec->tag, "qdio", ZFCP_DBF_TAG_SIZE);	rec->type.qdio.status = status;	rec->type.qdio.qdio_error = qdio_error;	rec->type.qdio.siga_error = siga_error;	rec->type.qdio.sbal_index = sbal_index;	rec->type.qdio.sbal_count = sbal_count;	debug_event(adapter->hba_dbf, 0,		    rec, sizeof(struct zfcp_hba_dbf_record));	spin_unlock_irqrestore(&adapter->hba_dbf_lock, flags);}static inline intzfcp_hba_dbf_view_response(char *out_buf,			   struct zfcp_hba_dbf_record_response *rec){	int len = 0;	len += zfcp_dbf_view(out_buf + len, "fsf_command", "0x%08x",

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -