qla_dbg.c

来自「linux 内核源代码」· C语言 代码 · 共 1,528 行 · 第 1/3 页

C
1,528
字号
/* * 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 inline voidqla2xxx_prep_dump(scsi_qla_host_t *ha, struct qla2xxx_fw_dump *fw_dump){	fw_dump->fw_major_version = htonl(ha->fw_major_version);	fw_dump->fw_minor_version = htonl(ha->fw_minor_version);	fw_dump->fw_subminor_version = htonl(ha->fw_subminor_version);	fw_dump->fw_attributes = htonl(ha->fw_attributes);	fw_dump->vendor = htonl(ha->pdev->vendor);	fw_dump->device = htonl(ha->pdev->device);	fw_dump->subsystem_vendor = htonl(ha->pdev->subsystem_vendor);	fw_dump->subsystem_device = htonl(ha->pdev->subsystem_device);}static inline void *qla2xxx_copy_queues(scsi_qla_host_t *ha, void *ptr){	/* Request queue. */	memcpy(ptr, ha->request_ring, ha->request_q_length *	    sizeof(request_t));	/* Response queue. */	ptr += ha->request_q_length * sizeof(request_t);	memcpy(ptr, ha->response_ring, ha->response_q_length  *	    sizeof(response_t));	return ptr + (ha->response_q_length * sizeof(response_t));}static intqla24xx_dump_memory(scsi_qla_host_t *ha, uint32_t *code_ram,    uint32_t cram_size, uint32_t *ext_mem, void **nxt){	int rval;	uint32_t cnt, stat, timer, risc_address, ext_mem_cnt;	uint16_t mb[4];	struct device_reg_24xx __iomem *reg = &ha->iobase->isp24;	rval = QLA_SUCCESS;	risc_address = ext_mem_cnt = 0;	memset(mb, 0, sizeof(mb));	/* Code RAM. */	risc_address = 0x20000;	WRT_REG_WORD(&reg->mailbox0, MBC_READ_RAM_EXTENDED);	clear_bit(MBX_INTERRUPT, &ha->mbx_cmd_flags);	for (cnt = 0; cnt < cram_size / 4 && rval == QLA_SUCCESS;	    cnt++, risc_address++) {		WRT_REG_WORD(&reg->mailbox1, LSW(risc_address));		WRT_REG_WORD(&reg->mailbox8, MSW(risc_address));		RD_REG_WORD(&reg->mailbox8);		WRT_REG_DWORD(&reg->hccr, HCCRX_SET_HOST_INT);		for (timer = 6000000; timer; timer--) {			/* Check for pending interrupts. */			stat = RD_REG_DWORD(&reg->host_status);			if (stat & HSRX_RISC_INT) {				stat &= 0xff;				if (stat == 0x1 || stat == 0x2 ||				    stat == 0x10 || stat == 0x11) {					set_bit(MBX_INTERRUPT,					    &ha->mbx_cmd_flags);					mb[0] = RD_REG_WORD(&reg->mailbox0);					mb[2] = RD_REG_WORD(&reg->mailbox2);					mb[3] = RD_REG_WORD(&reg->mailbox3);					WRT_REG_DWORD(&reg->hccr,					    HCCRX_CLR_RISC_INT);					RD_REG_DWORD(&reg->hccr);					break;				}				/* Clear this intr; it wasn't a mailbox intr */				WRT_REG_DWORD(&reg->hccr, HCCRX_CLR_RISC_INT);				RD_REG_DWORD(&reg->hccr);			}			udelay(5);		}		if (test_and_clear_bit(MBX_INTERRUPT, &ha->mbx_cmd_flags)) {			rval = mb[0] & MBS_MASK;			code_ram[cnt] = htonl((mb[3] << 16) | mb[2]);		} else {			rval = QLA_FUNCTION_FAILED;		}	}	if (rval == QLA_SUCCESS) {		/* External Memory. */		risc_address = 0x100000;		ext_mem_cnt = ha->fw_memory_size - 0x100000 + 1;		WRT_REG_WORD(&reg->mailbox0, MBC_READ_RAM_EXTENDED);		clear_bit(MBX_INTERRUPT, &ha->mbx_cmd_flags);	}	for (cnt = 0; cnt < ext_mem_cnt && rval == QLA_SUCCESS;	    cnt++, risc_address++) {		WRT_REG_WORD(&reg->mailbox1, LSW(risc_address));		WRT_REG_WORD(&reg->mailbox8, MSW(risc_address));		RD_REG_WORD(&reg->mailbox8);		WRT_REG_DWORD(&reg->hccr, HCCRX_SET_HOST_INT);		for (timer = 6000000; timer; timer--) {			/* Check for pending interrupts. */			stat = RD_REG_DWORD(&reg->host_status);			if (stat & HSRX_RISC_INT) {				stat &= 0xff;				if (stat == 0x1 || stat == 0x2 ||				    stat == 0x10 || stat == 0x11) {					set_bit(MBX_INTERRUPT,					    &ha->mbx_cmd_flags);					mb[0] = RD_REG_WORD(&reg->mailbox0);					mb[2] = RD_REG_WORD(&reg->mailbox2);					mb[3] = RD_REG_WORD(&reg->mailbox3);					WRT_REG_DWORD(&reg->hccr,					    HCCRX_CLR_RISC_INT);					RD_REG_DWORD(&reg->hccr);					break;				}				/* Clear this intr; it wasn't a mailbox intr */				WRT_REG_DWORD(&reg->hccr, HCCRX_CLR_RISC_INT);				RD_REG_DWORD(&reg->hccr);			}			udelay(5);		}		if (test_and_clear_bit(MBX_INTERRUPT, &ha->mbx_cmd_flags)) {			rval = mb[0] & MBS_MASK;			ext_mem[cnt] = htonl((mb[3] << 16) | mb[2]);		} else {			rval = QLA_FUNCTION_FAILED;		}	}	*nxt = rval == QLA_SUCCESS ? &ext_mem[cnt]: NULL;	return rval;}static uint32_t *qla24xx_read_window(struct device_reg_24xx __iomem *reg, uint32_t iobase,    uint32_t count, uint32_t *buf){	uint32_t __iomem *dmp_reg;	WRT_REG_DWORD(&reg->iobase_addr, iobase);	dmp_reg = &reg->iobase_window;	while (count--)		*buf++ = htonl(RD_REG_DWORD(dmp_reg++));	return buf;}static inline intqla24xx_pause_risc(struct device_reg_24xx __iomem *reg){	int rval = QLA_SUCCESS;	uint32_t cnt;	if (RD_REG_DWORD(&reg->hccr) & HCCRX_RISC_PAUSE)		return rval;	WRT_REG_DWORD(&reg->hccr, HCCRX_SET_RISC_PAUSE);	for (cnt = 30000; (RD_REG_DWORD(&reg->hccr) & HCCRX_RISC_PAUSE) == 0 &&	    rval == QLA_SUCCESS; cnt--) {		if (cnt)			udelay(100);		else			rval = QLA_FUNCTION_TIMEOUT;	}	return rval;}static intqla24xx_soft_reset(scsi_qla_host_t *ha){	int rval = QLA_SUCCESS;	uint32_t cnt;	uint16_t mb0, wd;	struct device_reg_24xx __iomem *reg = &ha->iobase->isp24;	/* Reset RISC. */	WRT_REG_DWORD(&reg->ctrl_status, CSRX_DMA_SHUTDOWN|MWB_4096_BYTES);	for (cnt = 0; cnt < 30000; cnt++) {		if ((RD_REG_DWORD(&reg->ctrl_status) & CSRX_DMA_ACTIVE) == 0)			break;		udelay(10);	}	WRT_REG_DWORD(&reg->ctrl_status,	    CSRX_ISP_SOFT_RESET|CSRX_DMA_SHUTDOWN|MWB_4096_BYTES);	pci_read_config_word(ha->pdev, PCI_COMMAND, &wd);	udelay(100);	/* Wait for firmware to complete NVRAM accesses. */	mb0 = (uint32_t) RD_REG_WORD(&reg->mailbox0);	for (cnt = 10000 ; cnt && mb0; cnt--) {		udelay(5);		mb0 = (uint32_t) RD_REG_WORD(&reg->mailbox0);		barrier();	}	/* Wait for soft-reset to complete. */	for (cnt = 0; cnt < 30000; cnt++) {		if ((RD_REG_DWORD(&reg->ctrl_status) &		    CSRX_ISP_SOFT_RESET) == 0)			break;		udelay(10);	}	WRT_REG_DWORD(&reg->hccr, HCCRX_CLR_RISC_RESET);	RD_REG_DWORD(&reg->hccr);             /* PCI Posting. */	for (cnt = 30000; RD_REG_WORD(&reg->mailbox0) != 0 &&	    rval == QLA_SUCCESS; cnt--) {		if (cnt)			udelay(100);		else			rval = QLA_FUNCTION_TIMEOUT;	}	return rval;}static inline voidqla2xxx_read_window(struct device_reg_2xxx __iomem *reg, uint32_t count,    uint16_t *buf){	uint16_t __iomem *dmp_reg = &reg->u.isp2300.fb_cmd;	while (count--)		*buf++ = htons(RD_REG_WORD(dmp_reg++));}/** * 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	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) {		qla_printk(KERN_WARNING, ha,		    "No buffer available for dump!!!\n");		goto qla2300_fw_dump_failed;	}	if (ha->fw_dumped) {		qla_printk(KERN_WARNING, ha,		    "Firmware has been previously dumped (%p) -- ignoring "		    "request...\n", ha->fw_dump);		goto qla2300_fw_dump_failed;	}	fw = &ha->fw_dump->isp.isp23;	qla2xxx_prep_dump(ha, ha->fw_dump);	rval = QLA_SUCCESS;	fw->hccr = htons(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 = &reg->flash_address;		for (cnt = 0; cnt < sizeof(fw->pbiu_reg) / 2; cnt++)			fw->pbiu_reg[cnt] = htons(RD_REG_WORD(dmp_reg++));		dmp_reg = &reg->u.isp2300.req_q_in;		for (cnt = 0; cnt < sizeof(fw->risc_host_reg) / 2; cnt++)			fw->risc_host_reg[cnt] = htons(RD_REG_WORD(dmp_reg++));		dmp_reg = &reg->u.isp2300.mailbox0;		for (cnt = 0; cnt < sizeof(fw->mailbox_reg) / 2; cnt++)			fw->mailbox_reg[cnt] = htons(RD_REG_WORD(dmp_reg++));		WRT_REG_WORD(&reg->ctrl_status, 0x40);		qla2xxx_read_window(reg, 32, fw->resp_dma_reg);		WRT_REG_WORD(&reg->ctrl_status, 0x50);		qla2xxx_read_window(reg, 48, fw->dma_reg);		WRT_REG_WORD(&reg->ctrl_status, 0x00);		dmp_reg = &reg->risc_hw;		for (cnt = 0; cnt < sizeof(fw->risc_hdw_reg) / 2; cnt++)			fw->risc_hdw_reg[cnt] = htons(RD_REG_WORD(dmp_reg++));		WRT_REG_WORD(&reg->pcr, 0x2000);		qla2xxx_read_window(reg, 16, fw->risc_gp0_reg);		WRT_REG_WORD(&reg->pcr, 0x2200);		qla2xxx_read_window(reg, 16, fw->risc_gp1_reg);		WRT_REG_WORD(&reg->pcr, 0x2400);		qla2xxx_read_window(reg, 16, fw->risc_gp2_reg);		WRT_REG_WORD(&reg->pcr, 0x2600);		qla2xxx_read_window(reg, 16, fw->risc_gp3_reg);		WRT_REG_WORD(&reg->pcr, 0x2800);		qla2xxx_read_window(reg, 16, fw->risc_gp4_reg);		WRT_REG_WORD(&reg->pcr, 0x2A00);		qla2xxx_read_window(reg, 16, fw->risc_gp5_reg);		WRT_REG_WORD(&reg->pcr, 0x2C00);		qla2xxx_read_window(reg, 16, fw->risc_gp6_reg);		WRT_REG_WORD(&reg->pcr, 0x2E00);		qla2xxx_read_window(reg, 16, fw->risc_gp7_reg);		WRT_REG_WORD(&reg->ctrl_status, 0x10);		qla2xxx_read_window(reg, 64, fw->frame_buf_hdw_reg);		WRT_REG_WORD(&reg->ctrl_status, 0x20);		qla2xxx_read_window(reg, 64, fw->fpm_b0_reg);		WRT_REG_WORD(&reg->ctrl_status, 0x30);		qla2xxx_read_window(reg, 64, fw->fpm_b1_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] = htons(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] = htons(mb2);		} else {			rval = QLA_FUNCTION_FAILED;		}	}	if (rval == QLA_SUCCESS) {		/* Get data SRAM. */		risc_address = 0x11000;

⌨️ 快捷键说明

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