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

📄 qla1280.c

📁 Linux Kernel 2.6.9 for OMAP1710
💻 C
📖 第 1 页 / 共 5 页
字号:
	default:		host_status = DID_ERROR;		break;	}#if DEBUG_QLA1280_INTR	dprintk(1, "qla1280 ISP status: host status (%s) scsi status %x\n",		reason[host_status], scsi_status);#endif	LEAVE("qla1280_return_status");	return (scsi_status & 0xff) | (host_status << 16);}/****************************************************************************//*                QLogic ISP1280 Hardware Support Functions.                *//****************************************************************************/ /*  * qla2100_enable_intrs  * qla2100_disable_intrs  *  * Input:  *      ha = adapter block pointer.  *  * Returns:  *      None  */static inline voidqla1280_enable_intrs(struct scsi_qla_host *ha){	struct device_reg *reg;	reg = ha->iobase;	/* enable risc and host interrupts */	WRT_REG_WORD(&reg->ictrl, (ISP_EN_INT | ISP_EN_RISC));	RD_REG_WORD(&reg->ictrl);	/* PCI Posted Write flush */	ha->flags.ints_enabled = 1;}static inline voidqla1280_disable_intrs(struct scsi_qla_host *ha){	struct device_reg *reg;	reg = ha->iobase;	/* disable risc and host interrupts */	WRT_REG_WORD(&reg->ictrl, 0);	RD_REG_WORD(&reg->ictrl);	/* PCI Posted Write flush */	ha->flags.ints_enabled = 0;}/* * qla1280_initialize_adapter *      Initialize board. * * Input: *      ha = adapter block pointer. * * Returns: *      0 = success */static int __devinitqla1280_initialize_adapter(struct scsi_qla_host *ha){	struct device_reg *reg;	int status;	int bus;#if LINUX_VERSION_CODE > 0x020500	unsigned long flags;#endif	ENTER("qla1280_initialize_adapter");	/* Clear adapter flags. */	ha->flags.online = 0;	ha->flags.disable_host_adapter = 0;	ha->flags.reset_active = 0;	ha->flags.abort_isp_active = 0;	ha->flags.ints_enabled = 0;#if defined(CONFIG_IA64_GENERIC) || defined(CONFIG_IA64_SGI_SN2)	if (ia64_platform_is("sn2")) {		int count1, count2;		int c;		count1 = 3;		count2 = 3;		printk(KERN_INFO "scsi(%li): Enabling SN2 PCI DMA "		       "dual channel lockup workaround\n", ha->host_no);		if ((c = snia_pcibr_rrb_alloc(ha->pdev, &count1, &count2)) < 0)			printk(KERN_ERR "scsi(%li): Unable to allocate SN2 "			       "virtual DMA channels\n", ha->host_no);		else			ha->flags.use_pci_vchannel = 1;		driver_setup.no_nvram = 1;	}#endif	dprintk(1, "Configure PCI space for adapter...\n");	reg = ha->iobase;	/* Insure mailbox registers are free. */	WRT_REG_WORD(&reg->semaphore, 0);	WRT_REG_WORD(&reg->host_cmd, HC_CLR_RISC_INT);	WRT_REG_WORD(&reg->host_cmd, HC_CLR_HOST_INT);	RD_REG_WORD(&reg->host_cmd);	if (qla1280_read_nvram(ha)) {		dprintk(2, "qla1280_initialize_adapter: failed to read "			"NVRAM\n");	}#if LINUX_VERSION_CODE >= 0x020500	/*	 * It's necessary to grab the spin here as qla1280_mailbox_command	 * needs to be able to drop the lock unconditionally to wait	 * for completion.	 * In 2.4 ->detect is called with the io_request_lock held.	 */	spin_lock_irqsave(HOST_LOCK, flags);#endif	status = qla1280_load_firmware(ha);	if (status) {		printk(KERN_ERR "scsi(%li): initialize: pci probe failed!\n",		       ha->host_no);		goto out;	}	/* Setup adapter based on NVRAM parameters. */	dprintk(1, "scsi(%ld): Configure NVRAM parameters\n", ha->host_no);	qla1280_nvram_config(ha);	if (ha->flags.disable_host_adapter) {		status = 1;		goto out;	}	status = qla1280_init_rings(ha);	if (status)		goto out;	/* Issue SCSI reset, if we can't reset twice then bus is dead */	for (bus = 0; bus < ha->ports; bus++) {		if (!ha->bus_settings[bus].disable_scsi_reset &&		    qla1280_bus_reset(ha, bus) &&		    qla1280_bus_reset(ha, bus))			ha->bus_settings[bus].scsi_bus_dead = 1;	}	ha->flags.online = 1; out:#if LINUX_VERSION_CODE >= 0x020500	spin_unlock_irqrestore(HOST_LOCK, flags);#endif	if (status)		dprintk(2, "qla1280_initialize_adapter: **** FAILED ****\n");	LEAVE("qla1280_initialize_adapter");	return status;}/* * ISP Firmware Test *      Checks if present version of RISC firmware is older than *      driver firmware. * * Input: *      ha = adapter block pointer. * * Returns: *      0 = firmware does not need to be loaded. */static intqla1280_isp_firmware(struct scsi_qla_host *ha){	struct nvram *nv = (struct nvram *) ha->response_ring;	int status = 0;		/* dg 2/27 always loads RISC */	uint16_t mb[MAILBOX_REGISTER_COUNT];	ENTER("qla1280_isp_firmware");	dprintk(1, "scsi(%li): Determining if RISC is loaded\n", ha->host_no);	/* Bad NVRAM data, load RISC code. */	if (!ha->nvram_valid) {		ha->flags.disable_risc_code_load = 0;	} else		ha->flags.disable_risc_code_load =			nv->cntr_flags_1.disable_loading_risc_code;	if (ha->flags.disable_risc_code_load) {		dprintk(3, "qla1280_isp_firmware: Telling RISC to verify "			"checksum of loaded BIOS code.\n");		/* Verify checksum of loaded RISC code. */		mb[0] = MBC_VERIFY_CHECKSUM;		/* mb[1] = ql12_risc_code_addr01; */		mb[1] = *ql1280_board_tbl[ha->devnum].fwstart;		if (!(status =		      qla1280_mailbox_command(ha, BIT_1 | BIT_0, &mb[0]))) {			/* Start firmware execution. */			dprintk(3, "qla1280_isp_firmware: Startng F/W "				"execution.\n");			mb[0] = MBC_EXECUTE_FIRMWARE;			/* mb[1] = ql12_risc_code_addr01; */			mb[1] = *ql1280_board_tbl[ha->devnum].fwstart;			qla1280_mailbox_command(ha, BIT_1 | BIT_0, &mb[0]);		} else			printk(KERN_INFO "qla1280: RISC checksum failed.\n");	} else {		dprintk(1, "qla1280: NVRAM configured to load RISC load.\n");		status = 1;	}	if (status)		dprintk(2, "qla1280_isp_firmware: **** Load RISC code ****\n");	LEAVE("qla1280_isp_firmware");	return status;}/* * Chip diagnostics *      Test chip for proper operation. * * Input: *      ha = adapter block pointer. * * Returns: *      0 = success. */static intqla1280_chip_diag(struct scsi_qla_host *ha){	uint16_t mb[MAILBOX_REGISTER_COUNT];	struct device_reg *reg = ha->iobase;	int status = 0;	int cnt;	uint16_t data;	dprintk(3, "qla1280_chip_diag: testing device at 0x%p \n", &reg->id_l);	dprintk(1, "scsi(%ld): Verifying chip\n", ha->host_no);	/* Soft reset chip and wait for it to finish. */	WRT_REG_WORD(&reg->ictrl, ISP_RESET);	/*	 * We can't do a traditional PCI write flush here by reading	 * back the register. The card will not respond once the reset	 * is in action and we end up with a machine check exception	 * instead. Nothing to do but wait and hope for the best.	 * A portable pci_write_flush(pdev) call would be very useful here.	 */	udelay(20);	data = qla1280_debounce_register(&reg->ictrl);	/*	 * Yet another QLogic gem ;-(	 */	for (cnt = 1000000; cnt && data & ISP_RESET; cnt--) {		udelay(5);		data = RD_REG_WORD(&reg->ictrl);	}	if (!cnt)		goto fail;	/* Reset register cleared by chip reset. */	dprintk(3, "qla1280_chip_diag: reset register cleared by chip reset\n");	WRT_REG_WORD(&reg->cfg_1, 0);	/* Reset RISC and disable BIOS which	   allows RISC to execute out of RAM. */	WRT_REG_WORD(&reg->host_cmd, HC_RESET_RISC |		     HC_RELEASE_RISC | HC_DISABLE_BIOS);	RD_REG_WORD(&reg->id_l);	/* Flush PCI write */	data = qla1280_debounce_register(&reg->mailbox0);	/*	 * I *LOVE* this code!	 */	for (cnt = 1000000; cnt && data == MBS_BUSY; cnt--) {		udelay(5);		data = RD_REG_WORD(&reg->mailbox0);	}	if (!cnt)		goto fail;	/* Check product ID of chip */	dprintk(3, "qla1280_chip_diag: Checking product ID of chip\n");	if (RD_REG_WORD(&reg->mailbox1) != PROD_ID_1 ||	    (RD_REG_WORD(&reg->mailbox2) != PROD_ID_2 &&	     RD_REG_WORD(&reg->mailbox2) != PROD_ID_2a) ||	    RD_REG_WORD(&reg->mailbox3) != PROD_ID_3 ||	    RD_REG_WORD(&reg->mailbox4) != PROD_ID_4) {		printk(KERN_INFO "qla1280: Wrong product ID = "		       "0x%x,0x%x,0x%x,0x%x\n",		       RD_REG_WORD(&reg->mailbox1),		       RD_REG_WORD(&reg->mailbox2),		       RD_REG_WORD(&reg->mailbox3),		       RD_REG_WORD(&reg->mailbox4));		goto fail;	}	/*	 * Enable ints early!!!	 */	qla1280_enable_intrs(ha);	dprintk(1, "qla1280_chip_diag: Checking mailboxes of chip\n");	/* Wrap Incoming Mailboxes Test. */	mb[0] = MBC_MAILBOX_REGISTER_TEST;	mb[1] = 0xAAAA;	mb[2] = 0x5555;	mb[3] = 0xAA55;	mb[4] = 0x55AA;	mb[5] = 0xA5A5;	mb[6] = 0x5A5A;	mb[7] = 0x2525;	status = qla1280_mailbox_command(ha, 0xff, mb);	if (status)		goto fail;	if (mb[1] != 0xAAAA || mb[2] != 0x5555 || mb[3] != 0xAA55 ||	    mb[4] != 0x55AA || mb[5] != 0xA5A5 || mb[6] != 0x5A5A ||	    mb[7] != 0x2525) {		printk(KERN_INFO "qla1280: Failed mbox check\n");		goto fail;	}	dprintk(3, "qla1280_chip_diag: exiting normally\n");	return 0; fail:	dprintk(2, "qla1280_chip_diag: **** FAILED ****\n");	return status;}static intqla1280_load_firmware_pio(struct scsi_qla_host *ha){	uint16_t risc_address, *risc_code_address, risc_code_size;	uint16_t mb[MAILBOX_REGISTER_COUNT], i;	int err;	/* Load RISC code. */	risc_address = *ql1280_board_tbl[ha->devnum].fwstart;	risc_code_address = ql1280_board_tbl[ha->devnum].fwcode;	risc_code_size = *ql1280_board_tbl[ha->devnum].fwlen;	for (i = 0; i < risc_code_size; i++) {		mb[0] = MBC_WRITE_RAM_WORD;		mb[1] = risc_address + i;		mb[2] = risc_code_address[i];		err = qla1280_mailbox_command(ha, BIT_0 | BIT_1 | BIT_2, mb);		if (err) {			printk(KERN_ERR "scsi(%li): Failed to load firmware\n",					ha->host_no);			return err;		}	}	return 0;}#define DUMP_IT_BACK 0		/* for debug of RISC loading */static intqla1280_load_firmware_dma(struct scsi_qla_host *ha){	uint16_t risc_address, *risc_code_address, risc_code_size;	uint16_t mb[MAILBOX_REGISTER_COUNT], cnt;	int err = 0, num, i;#if DUMP_IT_BACK	uint8_t *sp, *tbuf;	dma_addr_t p_tbuf;	tbuf = pci_alloc_consistent(ha->pdev, 8000, &p_tbuf);	if (!tbuf)		return -ENOMEM;#endif	/* Load RISC code. */	risc_address = *ql1280_board_tbl[ha->devnum].fwstart;	risc_code_address = ql1280_board_tbl[ha->devnum].fwcode;	risc_code_size = *ql1280_board_tbl[ha->devnum].fwlen;	dprintk(1, "%s: DMA RISC code (%i) words\n",			__FUNCTION__, risc_code_size);	num = 0;	while (risc_code_size > 0) {		int warn __attribute__((unused)) = 0;		cnt = 2000 >> 1;		if (cnt > risc_code_size)			cnt = risc_code_size;		dprintk(2, "qla1280_setup_chip:  loading risc @ =(0x%p),"			"%d,%d(0x%x)\n",			risc_code_address, cnt, num, risc_address);		for(i = 0; i < cnt; i++)			((uint16_t *)ha->request_ring)[i] =				c

⌨️ 快捷键说明

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