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

📄 qla_init.c

📁 linux-2.6.15.6
💻 C
📖 第 1 页 / 共 5 页
字号:
	/* Wait for RISC to recover from reset. */	if (IS_QLA2100(ha) || IS_QLA2200(ha) || IS_QLA2300(ha)) {		/*		 * It is necessary to for a delay here since the card doesn't		 * respond to PCI reads during a reset. On some architectures		 * this will result in an MCA.		 */		udelay(20);		for (cnt = 30000; cnt; cnt--) {			if ((RD_REG_WORD(&reg->ctrl_status) &			    CSR_ISP_SOFT_RESET) == 0)				break;			udelay(100);		}	} else		udelay(10);	/* Reset RISC processor. */	WRT_REG_WORD(&reg->hccr, HCCR_RESET_RISC);	WRT_REG_WORD(&reg->semaphore, 0);	/* Release RISC processor. */	WRT_REG_WORD(&reg->hccr, HCCR_RELEASE_RISC);	RD_REG_WORD(&reg->hccr);			/* PCI Posting. */	if (IS_QLA2100(ha) || IS_QLA2200(ha) || IS_QLA2300(ha)) {		for (cnt = 0; cnt < 30000; cnt++) {			if (!(test_bit(ABORT_ISP_ACTIVE, &ha->dpc_flags)))				spin_lock_irqsave(&ha->mbx_reg_lock, mbx_flags);			if (RD_MAILBOX_REG(ha, reg, 0) != MBS_BUSY) {				if (!(test_bit(ABORT_ISP_ACTIVE,				    &ha->dpc_flags)))					spin_unlock_irqrestore(					    &ha->mbx_reg_lock, mbx_flags);				break;			}			if (!(test_bit(ABORT_ISP_ACTIVE, &ha->dpc_flags)))				spin_unlock_irqrestore(&ha->mbx_reg_lock,				    mbx_flags);			udelay(100);		}	} else		udelay(100);	/* Turn on master enable */	cmd |= PCI_COMMAND_MASTER;	pci_write_config_word(ha->pdev, PCI_COMMAND, cmd);	/* Disable RISC pause on FPM parity error. */	if (!IS_QLA2100(ha)) {		WRT_REG_WORD(&reg->hccr, HCCR_DISABLE_PARITY_PAUSE);		RD_REG_WORD(&reg->hccr);		/* PCI Posting. */	}	spin_unlock_irqrestore(&ha->hardware_lock, flags);}/** * qla24xx_reset_risc() - Perform full reset of ISP24xx RISC. * @ha: HA context * * Returns 0 on success. */static inline voidqla24xx_reset_risc(scsi_qla_host_t *ha){	unsigned long flags = 0;	struct device_reg_24xx __iomem *reg = &ha->iobase->isp24;	uint32_t cnt, d2;	uint16_t wd;	spin_lock_irqsave(&ha->hardware_lock, flags);	/* 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. */	d2 = (uint32_t) RD_REG_WORD(&reg->mailbox0);	for (cnt = 10000 ; cnt && d2; cnt--) {		udelay(5);		d2 = (uint32_t) RD_REG_WORD(&reg->mailbox0);		barrier();	}	/* Wait for soft-reset to complete. */	d2 = RD_REG_DWORD(&reg->ctrl_status);	for (cnt = 6000000 ; cnt && (d2 & CSRX_ISP_SOFT_RESET); cnt--) {		udelay(5);		d2 = RD_REG_DWORD(&reg->ctrl_status);		barrier();	}	WRT_REG_DWORD(&reg->hccr, HCCRX_SET_RISC_RESET);	RD_REG_DWORD(&reg->hccr);	WRT_REG_DWORD(&reg->hccr, HCCRX_REL_RISC_PAUSE);	RD_REG_DWORD(&reg->hccr);	WRT_REG_DWORD(&reg->hccr, HCCRX_CLR_RISC_RESET);	RD_REG_DWORD(&reg->hccr);	d2 = (uint32_t) RD_REG_WORD(&reg->mailbox0);	for (cnt = 6000000 ; cnt && d2; cnt--) {		udelay(5);		d2 = (uint32_t) RD_REG_WORD(&reg->mailbox0);		barrier();	}	spin_unlock_irqrestore(&ha->hardware_lock, flags);}/** * qla24xx_reset_chip() - Reset ISP24xx chip. * @ha: HA context * * Returns 0 on success. */voidqla24xx_reset_chip(scsi_qla_host_t *ha){	ha->isp_ops.disable_intrs(ha);	/* Perform RISC reset. */	qla24xx_reset_risc(ha);}/** * qla2x00_chip_diag() - Test chip for proper operation. * @ha: HA context * * Returns 0 on success. */intqla2x00_chip_diag(scsi_qla_host_t *ha){	int		rval;	struct device_reg_2xxx __iomem *reg = &ha->iobase->isp;	unsigned long	flags = 0;	uint16_t	data;	uint32_t	cnt;	uint16_t	mb[5];	/* Assume a failed state */	rval = QLA_FUNCTION_FAILED;	DEBUG3(printk("scsi(%ld): Testing device at %lx.\n",	    ha->host_no, (u_long)&reg->flash_address));	spin_lock_irqsave(&ha->hardware_lock, flags);	/* Reset ISP chip. */	WRT_REG_WORD(&reg->ctrl_status, CSR_ISP_SOFT_RESET);	/*	 * We need to have a delay here since the card will not respond while	 * in reset causing an MCA on some architectures.	 */	udelay(20);	data = qla2x00_debounce_register(&reg->ctrl_status);	for (cnt = 6000000 ; cnt && (data & CSR_ISP_SOFT_RESET); cnt--) {		udelay(5);		data = RD_REG_WORD(&reg->ctrl_status);		barrier();	}	if (!cnt)		goto chip_diag_failed;	DEBUG3(printk("scsi(%ld): Reset register cleared by chip reset\n",	    ha->host_no));	/* Reset RISC processor. */	WRT_REG_WORD(&reg->hccr, HCCR_RESET_RISC);	WRT_REG_WORD(&reg->hccr, HCCR_RELEASE_RISC);	/* Workaround for QLA2312 PCI parity error */	if (IS_QLA2100(ha) || IS_QLA2200(ha) || IS_QLA2300(ha)) {		data = qla2x00_debounce_register(MAILBOX_REG(ha, reg, 0));		for (cnt = 6000000; cnt && (data == MBS_BUSY); cnt--) {			udelay(5);			data = RD_MAILBOX_REG(ha, reg, 0);			barrier();		}	} else		udelay(10);	if (!cnt)		goto chip_diag_failed;	/* Check product ID of chip */	DEBUG3(printk("scsi(%ld): Checking product ID of chip\n", ha->host_no));	mb[1] = RD_MAILBOX_REG(ha, reg, 1);	mb[2] = RD_MAILBOX_REG(ha, reg, 2);	mb[3] = RD_MAILBOX_REG(ha, reg, 3);	mb[4] = qla2x00_debounce_register(MAILBOX_REG(ha, reg, 4));	if (mb[1] != PROD_ID_1 || (mb[2] != PROD_ID_2 && mb[2] != PROD_ID_2a) ||	    mb[3] != PROD_ID_3) {		qla_printk(KERN_WARNING, ha,		    "Wrong product ID = 0x%x,0x%x,0x%x\n", mb[1], mb[2], mb[3]);		goto chip_diag_failed;	}	ha->product_id[0] = mb[1];	ha->product_id[1] = mb[2];	ha->product_id[2] = mb[3];	ha->product_id[3] = mb[4];	/* Adjust fw RISC transfer size */	if (ha->request_q_length > 1024)		ha->fw_transfer_size = REQUEST_ENTRY_SIZE * 1024;	else		ha->fw_transfer_size = REQUEST_ENTRY_SIZE *		    ha->request_q_length;	if (IS_QLA2200(ha) &&	    RD_MAILBOX_REG(ha, reg, 7) == QLA2200A_RISC_ROM_VER) {		/* Limit firmware transfer size with a 2200A */		DEBUG3(printk("scsi(%ld): Found QLA2200A chip.\n",		    ha->host_no));		ha->fw_transfer_size = 128;	}	/* Wrap Incoming Mailboxes Test. */	spin_unlock_irqrestore(&ha->hardware_lock, flags);	DEBUG3(printk("scsi(%ld): Checking mailboxes.\n", ha->host_no));	rval = qla2x00_mbx_reg_test(ha);	if (rval) {		DEBUG(printk("scsi(%ld): Failed mailbox send register test\n",		    ha->host_no));		qla_printk(KERN_WARNING, ha,		    "Failed mailbox send register test\n");	}	else {		/* Flag a successful rval */		rval = QLA_SUCCESS;	}	spin_lock_irqsave(&ha->hardware_lock, flags);chip_diag_failed:	if (rval)		DEBUG2_3(printk("scsi(%ld): Chip diagnostics **** FAILED "		    "****\n", ha->host_no));	spin_unlock_irqrestore(&ha->hardware_lock, flags);	return (rval);}/** * qla24xx_chip_diag() - Test ISP24xx for proper operation. * @ha: HA context * * Returns 0 on success. */intqla24xx_chip_diag(scsi_qla_host_t *ha){	int rval;	/* Perform RISC reset. */	qla24xx_reset_risc(ha);	ha->fw_transfer_size = REQUEST_ENTRY_SIZE * 1024;	rval = qla2x00_mbx_reg_test(ha);	if (rval) {		DEBUG(printk("scsi(%ld): Failed mailbox send register test\n",		    ha->host_no));		qla_printk(KERN_WARNING, ha,		    "Failed mailbox send register test\n");	} else {		/* Flag a successful rval */		rval = QLA_SUCCESS;	}	return rval;}static voidqla2x00_alloc_fw_dump(scsi_qla_host_t *ha){	ha->fw_dumped = 0;	ha->fw_dump24_len = sizeof(struct qla24xx_fw_dump);	ha->fw_dump24_len += (ha->fw_memory_size - 0x100000) * sizeof(uint32_t);	ha->fw_dump24 = vmalloc(ha->fw_dump24_len);	if (ha->fw_dump24)		qla_printk(KERN_INFO, ha, "Allocated (%d KB) for firmware "		    "dump...\n", ha->fw_dump24_len / 1024);	else		qla_printk(KERN_WARNING, ha, "Unable to allocate (%d KB) for "		    "firmware dump!!!\n", ha->fw_dump24_len / 1024);}/** * qla2x00_resize_request_q() - Resize request queue given available ISP memory. * @ha: HA context * * Returns 0 on success. */static voidqla2x00_resize_request_q(scsi_qla_host_t *ha){	int rval;	uint16_t fw_iocb_cnt = 0;	uint16_t request_q_length = REQUEST_ENTRY_CNT_2XXX_EXT_MEM;	dma_addr_t request_dma;	request_t *request_ring;	/* Valid only on recent ISPs. */	if (IS_QLA2100(ha) || IS_QLA2200(ha))		return;	if (IS_QLA24XX(ha) || IS_QLA25XX(ha))		qla2x00_alloc_fw_dump(ha);	/* Retrieve IOCB counts available to the firmware. */	rval = qla2x00_get_resource_cnts(ha, NULL, NULL, NULL, &fw_iocb_cnt);	if (rval)		return;	/* No point in continuing if current settings are sufficient. */	if (fw_iocb_cnt < 1024)		return;	if (ha->request_q_length >= request_q_length)		return;	/* Attempt to claim larger area for request queue. */	request_ring = dma_alloc_coherent(&ha->pdev->dev,	    (request_q_length + 1) * sizeof(request_t), &request_dma,	    GFP_KERNEL);	if (request_ring == NULL)		return;	/* Resize successful, report extensions. */	qla_printk(KERN_INFO, ha, "Extended memory detected (%d KB)...\n",	    (ha->fw_memory_size + 1) / 1024);	qla_printk(KERN_INFO, ha, "Resizing request queue depth "	    "(%d -> %d)...\n", ha->request_q_length, request_q_length);	/* Clear old allocations. */	dma_free_coherent(&ha->pdev->dev,	    (ha->request_q_length + 1) * sizeof(request_t), ha->request_ring,	    ha->request_dma);	/* Begin using larger queue. */	ha->request_q_length = request_q_length;	ha->request_ring = request_ring;	ha->request_dma = request_dma;}/** * qla2x00_setup_chip() - Load and start RISC firmware. * @ha: HA context * * Returns 0 on success. */static intqla2x00_setup_chip(scsi_qla_host_t *ha){	int rval;	uint32_t srisc_address = 0;	/* Load firmware sequences */	rval = ha->isp_ops.load_risc(ha, &srisc_address);	if (rval == QLA_SUCCESS) {		DEBUG(printk("scsi(%ld): Verifying Checksum of loaded RISC "		    "code.\n", ha->host_no));		rval = qla2x00_verify_checksum(ha, srisc_address);		if (rval == QLA_SUCCESS) {			/* Start firmware execution. */			DEBUG(printk("scsi(%ld): Checksum OK, start "			    "firmware.\n", ha->host_no));			rval = qla2x00_execute_fw(ha, srisc_address);			/* Retrieve firmware information. */			if (rval == QLA_SUCCESS && ha->fw_major_version == 0) {				qla2x00_get_fw_version(ha,				    &ha->fw_major_version,				    &ha->fw_minor_version,				    &ha->fw_subminor_version,				    &ha->fw_attributes, &ha->fw_memory_size);				qla2x00_resize_request_q(ha);			}		} else {			DEBUG2(printk(KERN_INFO			    "scsi(%ld): ISP Firmware failed checksum.\n",			    ha->host_no));		}	}	if (rval) {		DEBUG2_3(printk("scsi(%ld): Setup chip **** FAILED ****.\n",		    ha->host_no));	}	return (rval);}/** * qla2x00_init_response_q_entries() - Initializes response queue entries. * @ha: HA context * * Beginning of request ring has initialization control block already built * by nvram config routine. * * Returns 0 on success. */static voidqla2x00_init_response_q_entries(scsi_qla_host_t *ha){	uint16_t cnt;	response_t *pkt;	pkt = ha->response_ring_ptr;	for (cnt = 0; cnt < ha->response_q_length; cnt++) {		pkt->signature = RESPONSE_PROCESSED;		pkt++;	}}/** * qla2x00_update_fw_options() - Read and process firmware options. * @ha: HA context * * Returns 0 on success. */voidqla2x00_update_fw_options(scsi_qla_host_t *ha){	uint16_t swing, emphasis, tx_sens, rx_sens;	memset(ha->fw_options, 0, sizeof(ha->fw_options));	qla2x00_get_fw_options(ha, ha->fw_options);	if (IS_QLA2100(ha) || IS_QLA2200(ha))		return;	/* Serial Link options. */	DEBUG3(printk("scsi(%ld): Serial link options:\n",	    ha->host_no));	DEBUG3(qla2x00_dump_buffer((uint8_t *)&ha->fw_seriallink_options,	    sizeof(ha->fw_seriallink_options)));	ha->fw_options[1] &= ~FO1_SET_EMPHASIS_SWING;	if (ha->fw_seriallink_options[3] & BIT_2) {		ha->fw_options[1] |= FO1_SET_EMPHASIS_SWING;		/*  1G settings */		swing = ha->fw_seriallink_options[2] & (BIT_2 | BIT_1 | BIT_0);		emphasis = (ha->fw_seriallink_options[2] &		    (BIT_4 | BIT_3)) >> 3;		tx_sens = ha->fw_seriallink_options[0] &		    (BIT_3 | BIT_2 | BIT_1 | BIT_0);		rx_sens = (ha->fw_seriallink_options[0] &		    (BIT_7 | BIT_6 | BIT_5 | BIT_4)) >> 4;		ha->fw_options[10] = (emphasis << 14) | (swing << 8);		if (IS_QLA2300(ha) || IS_QLA2312(ha) || IS_QLA6312(ha)) {			if (rx_sens == 0x0)				rx_sens = 0x3;			ha->fw_options[10] |= (tx_sens << 4) | rx_sens;		} else if (IS_QLA2322(ha) || IS_QLA6322(ha))			ha->fw_options[10] |= BIT_5 |			    ((rx_sens & (BIT_1 | BIT_0)) << 2) |			    (tx_sens & (BIT_1 | BIT_0));		/*  2G settings */		swing = (ha->fw_seriallink_options[2] &		    (BIT_7 | BIT_6 | BIT_5)) >> 5;		emphasis = ha->fw_seriallink_options[3] & (BIT_1 | BIT_0);		tx_sens = ha->fw_seriallink_options[1] &		    (BIT_3 | BIT_2 | BIT_1 | BIT_0);		rx_sens = (ha->fw_seriallink_options[1] &		    (BIT_7 | BIT_6 | BIT_5 | BIT_4)) >> 4;		ha->fw_options[11] = (emphasis << 14) | (swing << 8);		if (IS_QLA2300(ha) || IS_QLA2312(ha) || IS_QLA6312(ha)) {

⌨️ 快捷键说明

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