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

📄 qla_dbg.c

📁 linux-2.6.15.6
💻 C
📖 第 1 页 / 共 5 页
字号:
/* * QLogic Fibre Channel HBA Driver * Copyright (c)  2003-2005 QLogic Corporation * * See LICENSE.qla2xxx for copyright and licensing details. */#include "qla_def.h"#include <linux/delay.h>static int qla_uprintf(char **, char *, ...);/** * qla2300_fw_dump() - Dumps binary data from the 2300 firmware. * @ha: HA context * @hardware_locked: Called with the hardware_lock */voidqla2300_fw_dump(scsi_qla_host_t *ha, int hardware_locked){	int		rval;	uint32_t	cnt, timer;	uint32_t	risc_address;	uint16_t	mb0, mb2;	uint32_t	stat;	struct device_reg_2xxx __iomem *reg = &ha->iobase->isp;	uint16_t __iomem *dmp_reg;	unsigned long	flags;	struct qla2300_fw_dump	*fw;	uint32_t	dump_size, data_ram_cnt;	risc_address = data_ram_cnt = 0;	mb0 = mb2 = 0;	flags = 0;	if (!hardware_locked)		spin_lock_irqsave(&ha->hardware_lock, flags);	if (ha->fw_dump != NULL) {		qla_printk(KERN_WARNING, ha,		    "Firmware has been previously dumped (%p) -- ignoring "		    "request...\n", ha->fw_dump);		goto qla2300_fw_dump_failed;	}	/* Allocate (large) dump buffer. */	dump_size = sizeof(struct qla2300_fw_dump);	dump_size += (ha->fw_memory_size - 0x11000) * sizeof(uint16_t);	ha->fw_dump_order = get_order(dump_size);	ha->fw_dump = (struct qla2300_fw_dump *) __get_free_pages(GFP_ATOMIC,	    ha->fw_dump_order);	if (ha->fw_dump == NULL) {		qla_printk(KERN_WARNING, ha,		    "Unable to allocated memory for firmware dump (%d/%d).\n",		    ha->fw_dump_order, dump_size);		goto qla2300_fw_dump_failed;	}	fw = ha->fw_dump;	rval = QLA_SUCCESS;	fw->hccr = RD_REG_WORD(&reg->hccr);	/* Pause RISC. */	WRT_REG_WORD(&reg->hccr, HCCR_PAUSE_RISC);	if (IS_QLA2300(ha)) {		for (cnt = 30000;		    (RD_REG_WORD(&reg->hccr) & HCCR_RISC_PAUSE) == 0 &&			rval == QLA_SUCCESS; cnt--) {			if (cnt)				udelay(100);			else				rval = QLA_FUNCTION_TIMEOUT;		}	} else {		RD_REG_WORD(&reg->hccr);		/* PCI Posting. */		udelay(10);	}	if (rval == QLA_SUCCESS) {		dmp_reg = (uint16_t __iomem *)(reg + 0);		for (cnt = 0; cnt < sizeof(fw->pbiu_reg) / 2; cnt++)			fw->pbiu_reg[cnt] = RD_REG_WORD(dmp_reg++);		dmp_reg = (uint16_t __iomem *)((uint8_t __iomem *)reg + 0x10);		for (cnt = 0; cnt < sizeof(fw->risc_host_reg) / 2; cnt++)			fw->risc_host_reg[cnt] = RD_REG_WORD(dmp_reg++);		dmp_reg = (uint16_t __iomem *)((uint8_t __iomem *)reg + 0x40);		for (cnt = 0; cnt < sizeof(fw->mailbox_reg) / 2; cnt++)			fw->mailbox_reg[cnt] = RD_REG_WORD(dmp_reg++);		WRT_REG_WORD(&reg->ctrl_status, 0x40);		dmp_reg = (uint16_t __iomem *)((uint8_t __iomem *)reg + 0x80);		for (cnt = 0; cnt < sizeof(fw->resp_dma_reg) / 2; cnt++)			fw->resp_dma_reg[cnt] = RD_REG_WORD(dmp_reg++);		WRT_REG_WORD(&reg->ctrl_status, 0x50);		dmp_reg = (uint16_t __iomem *)((uint8_t __iomem *)reg + 0x80);		for (cnt = 0; cnt < sizeof(fw->dma_reg) / 2; cnt++)			fw->dma_reg[cnt] = RD_REG_WORD(dmp_reg++);		WRT_REG_WORD(&reg->ctrl_status, 0x00);		dmp_reg = (uint16_t __iomem *)((uint8_t __iomem *)reg + 0xA0);		for (cnt = 0; cnt < sizeof(fw->risc_hdw_reg) / 2; cnt++)			fw->risc_hdw_reg[cnt] = RD_REG_WORD(dmp_reg++);		WRT_REG_WORD(&reg->pcr, 0x2000);		dmp_reg = (uint16_t __iomem *)((uint8_t __iomem *)reg + 0x80);		for (cnt = 0; cnt < sizeof(fw->risc_gp0_reg) / 2; cnt++)			fw->risc_gp0_reg[cnt] = RD_REG_WORD(dmp_reg++);		WRT_REG_WORD(&reg->pcr, 0x2200);		dmp_reg = (uint16_t __iomem *)((uint8_t __iomem *)reg + 0x80);		for (cnt = 0; cnt < sizeof(fw->risc_gp1_reg) / 2; cnt++)			fw->risc_gp1_reg[cnt] = RD_REG_WORD(dmp_reg++);		WRT_REG_WORD(&reg->pcr, 0x2400);		dmp_reg = (uint16_t __iomem *)((uint8_t __iomem *)reg + 0x80);		for (cnt = 0; cnt < sizeof(fw->risc_gp2_reg) / 2; cnt++)			fw->risc_gp2_reg[cnt] = RD_REG_WORD(dmp_reg++);		WRT_REG_WORD(&reg->pcr, 0x2600);		dmp_reg = (uint16_t __iomem *)((uint8_t __iomem *)reg + 0x80);		for (cnt = 0; cnt < sizeof(fw->risc_gp3_reg) / 2; cnt++)			fw->risc_gp3_reg[cnt] = RD_REG_WORD(dmp_reg++);		WRT_REG_WORD(&reg->pcr, 0x2800);		dmp_reg = (uint16_t __iomem *)((uint8_t __iomem *)reg + 0x80);		for (cnt = 0; cnt < sizeof(fw->risc_gp4_reg) / 2; cnt++)			fw->risc_gp4_reg[cnt] = RD_REG_WORD(dmp_reg++);		WRT_REG_WORD(&reg->pcr, 0x2A00);		dmp_reg = (uint16_t __iomem *)((uint8_t __iomem *)reg + 0x80);		for (cnt = 0; cnt < sizeof(fw->risc_gp5_reg) / 2; cnt++)			fw->risc_gp5_reg[cnt] = RD_REG_WORD(dmp_reg++);		WRT_REG_WORD(&reg->pcr, 0x2C00);		dmp_reg = (uint16_t __iomem *)((uint8_t __iomem *)reg + 0x80);		for (cnt = 0; cnt < sizeof(fw->risc_gp6_reg) / 2; cnt++)			fw->risc_gp6_reg[cnt] = RD_REG_WORD(dmp_reg++);		WRT_REG_WORD(&reg->pcr, 0x2E00);		dmp_reg = (uint16_t __iomem *)((uint8_t __iomem *)reg + 0x80);		for (cnt = 0; cnt < sizeof(fw->risc_gp7_reg) / 2; cnt++)			fw->risc_gp7_reg[cnt] = RD_REG_WORD(dmp_reg++);		WRT_REG_WORD(&reg->ctrl_status, 0x10);		dmp_reg = (uint16_t __iomem *)((uint8_t __iomem *)reg + 0x80);		for (cnt = 0; cnt < sizeof(fw->frame_buf_hdw_reg) / 2; cnt++)			fw->frame_buf_hdw_reg[cnt] = RD_REG_WORD(dmp_reg++);		WRT_REG_WORD(&reg->ctrl_status, 0x20);		dmp_reg = (uint16_t __iomem *)((uint8_t __iomem *)reg + 0x80);		for (cnt = 0; cnt < sizeof(fw->fpm_b0_reg) / 2; cnt++)			fw->fpm_b0_reg[cnt] = RD_REG_WORD(dmp_reg++);		WRT_REG_WORD(&reg->ctrl_status, 0x30);		dmp_reg = (uint16_t __iomem *)((uint8_t __iomem *)reg + 0x80);		for (cnt = 0; cnt < sizeof(fw->fpm_b1_reg) / 2; cnt++)			fw->fpm_b1_reg[cnt] = RD_REG_WORD(dmp_reg++);		/* Reset RISC. */		WRT_REG_WORD(&reg->ctrl_status, CSR_ISP_SOFT_RESET);		for (cnt = 0; cnt < 30000; cnt++) {			if ((RD_REG_WORD(&reg->ctrl_status) &			    CSR_ISP_SOFT_RESET) == 0)				break;			udelay(10);		}	}	if (!IS_QLA2300(ha)) {		for (cnt = 30000; RD_MAILBOX_REG(ha, reg, 0) != 0 &&		    rval == QLA_SUCCESS; cnt--) {			if (cnt)				udelay(100);			else				rval = QLA_FUNCTION_TIMEOUT;		}	}	if (rval == QLA_SUCCESS) {		/* Get RISC SRAM. */		risc_address = 0x800; 		WRT_MAILBOX_REG(ha, reg, 0, MBC_READ_RAM_WORD);		clear_bit(MBX_INTERRUPT, &ha->mbx_cmd_flags);	}	for (cnt = 0; cnt < sizeof(fw->risc_ram) / 2 && rval == QLA_SUCCESS;	    cnt++, risc_address++) { 		WRT_MAILBOX_REG(ha, reg, 1, (uint16_t)risc_address);		WRT_REG_WORD(&reg->hccr, HCCR_SET_HOST_INT);		for (timer = 6000000; timer; timer--) {			/* Check for pending interrupts. */ 			stat = RD_REG_DWORD(&reg->u.isp2300.host_status);			if (stat & HSR_RISC_INT) {				stat &= 0xff;				if (stat == 0x1 || stat == 0x2) {					set_bit(MBX_INTERRUPT,					    &ha->mbx_cmd_flags);					mb0 = RD_MAILBOX_REG(ha, reg, 0);					mb2 = RD_MAILBOX_REG(ha, reg, 2);					/* Release mailbox registers. */					WRT_REG_WORD(&reg->semaphore, 0);					WRT_REG_WORD(&reg->hccr,					    HCCR_CLR_RISC_INT);					RD_REG_WORD(&reg->hccr);					break;				} else if (stat == 0x10 || stat == 0x11) {					set_bit(MBX_INTERRUPT,					    &ha->mbx_cmd_flags);					mb0 = RD_MAILBOX_REG(ha, reg, 0);					mb2 = RD_MAILBOX_REG(ha, reg, 2);					WRT_REG_WORD(&reg->hccr,					    HCCR_CLR_RISC_INT);					RD_REG_WORD(&reg->hccr);					break;				}				/* clear this intr; it wasn't a mailbox intr */				WRT_REG_WORD(&reg->hccr, HCCR_CLR_RISC_INT);				RD_REG_WORD(&reg->hccr);			}			udelay(5);		}		if (test_and_clear_bit(MBX_INTERRUPT, &ha->mbx_cmd_flags)) {			rval = mb0 & MBS_MASK;			fw->risc_ram[cnt] = mb2;		} else {			rval = QLA_FUNCTION_FAILED;		}	}	if (rval == QLA_SUCCESS) {		/* Get stack SRAM. */		risc_address = 0x10000; 		WRT_MAILBOX_REG(ha, reg, 0, MBC_READ_RAM_EXTENDED);		clear_bit(MBX_INTERRUPT, &ha->mbx_cmd_flags);	}	for (cnt = 0; cnt < sizeof(fw->stack_ram) / 2 && rval == QLA_SUCCESS;	    cnt++, risc_address++) { 		WRT_MAILBOX_REG(ha, reg, 1, LSW(risc_address)); 		WRT_MAILBOX_REG(ha, reg, 8, MSW(risc_address));		WRT_REG_WORD(&reg->hccr, HCCR_SET_HOST_INT);		for (timer = 6000000; timer; timer--) {			/* Check for pending interrupts. */ 			stat = RD_REG_DWORD(&reg->u.isp2300.host_status);			if (stat & HSR_RISC_INT) {				stat &= 0xff;				if (stat == 0x1 || stat == 0x2) {					set_bit(MBX_INTERRUPT,					    &ha->mbx_cmd_flags);					mb0 = RD_MAILBOX_REG(ha, reg, 0);					mb2 = RD_MAILBOX_REG(ha, reg, 2);					/* Release mailbox registers. */					WRT_REG_WORD(&reg->semaphore, 0);					WRT_REG_WORD(&reg->hccr,					    HCCR_CLR_RISC_INT);					RD_REG_WORD(&reg->hccr);					break;				} else if (stat == 0x10 || stat == 0x11) {					set_bit(MBX_INTERRUPT,					    &ha->mbx_cmd_flags);					mb0 = RD_MAILBOX_REG(ha, reg, 0);					mb2 = RD_MAILBOX_REG(ha, reg, 2);					WRT_REG_WORD(&reg->hccr,					    HCCR_CLR_RISC_INT);					RD_REG_WORD(&reg->hccr);					break;				}				/* clear this intr; it wasn't a mailbox intr */				WRT_REG_WORD(&reg->hccr, HCCR_CLR_RISC_INT);				RD_REG_WORD(&reg->hccr);			}			udelay(5);		}		if (test_and_clear_bit(MBX_INTERRUPT, &ha->mbx_cmd_flags)) {			rval = mb0 & MBS_MASK;			fw->stack_ram[cnt] = mb2;		} else {			rval = QLA_FUNCTION_FAILED;		}	}	if (rval == QLA_SUCCESS) {		/* Get data SRAM. */		risc_address = 0x11000;		data_ram_cnt = ha->fw_memory_size - risc_address + 1; 		WRT_MAILBOX_REG(ha, reg, 0, MBC_READ_RAM_EXTENDED);		clear_bit(MBX_INTERRUPT, &ha->mbx_cmd_flags);	}	for (cnt = 0; cnt < data_ram_cnt && rval == QLA_SUCCESS;	    cnt++, risc_address++) { 		WRT_MAILBOX_REG(ha, reg, 1, LSW(risc_address)); 		WRT_MAILBOX_REG(ha, reg, 8, MSW(risc_address));		WRT_REG_WORD(&reg->hccr, HCCR_SET_HOST_INT);		for (timer = 6000000; timer; timer--) {			/* Check for pending interrupts. */ 			stat = RD_REG_DWORD(&reg->u.isp2300.host_status);			if (stat & HSR_RISC_INT) {				stat &= 0xff;				if (stat == 0x1 || stat == 0x2) {					set_bit(MBX_INTERRUPT,					    &ha->mbx_cmd_flags);					mb0 = RD_MAILBOX_REG(ha, reg, 0);					mb2 = RD_MAILBOX_REG(ha, reg, 2);					/* Release mailbox registers. */					WRT_REG_WORD(&reg->semaphore, 0);					WRT_REG_WORD(&reg->hccr,					    HCCR_CLR_RISC_INT);					RD_REG_WORD(&reg->hccr);					break;				} else if (stat == 0x10 || stat == 0x11) {					set_bit(MBX_INTERRUPT,					    &ha->mbx_cmd_flags);					mb0 = RD_MAILBOX_REG(ha, reg, 0);					mb2 = RD_MAILBOX_REG(ha, reg, 2);					WRT_REG_WORD(&reg->hccr,					    HCCR_CLR_RISC_INT);					RD_REG_WORD(&reg->hccr);					break;				}				/* clear this intr; it wasn't a mailbox intr */				WRT_REG_WORD(&reg->hccr, HCCR_CLR_RISC_INT);				RD_REG_WORD(&reg->hccr);			}			udelay(5);		}		if (test_and_clear_bit(MBX_INTERRUPT, &ha->mbx_cmd_flags)) {			rval = mb0 & MBS_MASK;			fw->data_ram[cnt] = mb2;		} else {			rval = QLA_FUNCTION_FAILED;		}	}	if (rval != QLA_SUCCESS) {		qla_printk(KERN_WARNING, ha,		    "Failed to dump firmware (%x)!!!\n", rval);		free_pages((unsigned long)ha->fw_dump, ha->fw_dump_order);		ha->fw_dump = NULL;	} else {		qla_printk(KERN_INFO, ha,		    "Firmware dump saved to temp buffer (%ld/%p).\n",		    ha->host_no, ha->fw_dump);	}qla2300_fw_dump_failed:	if (!hardware_locked)		spin_unlock_irqrestore(&ha->hardware_lock, flags);}/** * qla2300_ascii_fw_dump() - Converts a binary firmware dump to ASCII. * @ha: HA context */voidqla2300_ascii_fw_dump(scsi_qla_host_t *ha){	uint32_t cnt;	char *uiter;	char fw_info[30];	struct qla2300_fw_dump *fw;	uint32_t data_ram_cnt;	uiter = ha->fw_dump_buffer;	fw = ha->fw_dump;	qla_uprintf(&uiter, "%s Firmware Version %s\n", ha->model_number,	    ha->isp_ops.fw_version_str(ha, fw_info));	qla_uprintf(&uiter, "\n[==>BEG]\n");	qla_uprintf(&uiter, "HCCR Register:\n%04x\n\n", fw->hccr);	qla_uprintf(&uiter, "PBIU Registers:");	for (cnt = 0; cnt < sizeof (fw->pbiu_reg) / 2; cnt++) {		if (cnt % 8 == 0) {			qla_uprintf(&uiter, "\n");		}		qla_uprintf(&uiter, "%04x ", fw->pbiu_reg[cnt]);	}	qla_uprintf(&uiter, "\n\nReqQ-RspQ-Risc2Host Status registers:");	for (cnt = 0; cnt < sizeof (fw->risc_host_reg) / 2; cnt++) {		if (cnt % 8 == 0) {			qla_uprintf(&uiter, "\n");		}		qla_uprintf(&uiter, "%04x ", fw->risc_host_reg[cnt]);	}	qla_uprintf(&uiter, "\n\nMailbox Registers:");	for (cnt = 0; cnt < sizeof (fw->mailbox_reg) / 2; cnt++) {		if (cnt % 8 == 0) {

⌨️ 快捷键说明

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