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

📄 qlogicfc.c

📁 Linux内核源代码 为压缩文件 是<<Linux内核>>一书中的源代码
💻 C
📖 第 1 页 / 共 5 页
字号:
	if (return_status != SUCCESS){		param[0] = MBOX_GET_FIRMWARE_STATE;		isp2x00_mbox_command(host, param);		printk("qlogicfc%d : abort failed\n", hostdata->host_id);		printk("qlogicfc%d : firmware status is %x %x\n", hostdata->host_id, param[0], param[1]);	}	isp2x00_enable_irqs(host);	LEAVE("isp2x00_abort");	return return_status;}int isp2x00_reset(Scsi_Cmnd * Cmnd, unsigned int reset_flags){	u_short param[8];	struct Scsi_Host *host;	struct isp2x00_hostdata *hostdata;	int return_status = SCSI_RESET_SUCCESS;	ENTER("isp2x00_reset");	host = Cmnd->host;	hostdata = (struct isp2x00_hostdata *) host->hostdata;	param[0] = MBOX_BUS_RESET;	param[1] = 3;	isp2x00_disable_irqs(host);	isp2x00_mbox_command(host, param);	if (param[0] != MBOX_COMMAND_COMPLETE) {		printk("qlogicfc%d : scsi bus reset failure: %x\n", hostdata->host_id, param[0]);		return_status = SCSI_RESET_ERROR;	}	isp2x00_enable_irqs(host);	LEAVE("isp2x00_reset");	return return_status;;}int isp2x00_biosparam(Disk * disk, kdev_t n, int ip[]){	int size = disk->capacity;	ENTER("isp2x00_biosparam");	ip[0] = 64;	ip[1] = 32;	ip[2] = size >> 11;	if (ip[2] > 1024) {		ip[0] = 255;		ip[1] = 63;		ip[2] = size / (ip[0] * ip[1]);	}	LEAVE("isp2x00_biosparam");	return 0;}static int isp2x00_reset_hardware(struct Scsi_Host *host){	u_short param[8];	struct isp2x00_hostdata *hostdata;	int loop_count;	dma64_addr_t busaddr;	ENTER("isp2x00_reset_hardware");	hostdata = (struct isp2x00_hostdata *) host->hostdata;	outw(0x01, host->io_port + ISP_CTRL_STATUS);	outw(HCCR_RESET, host->io_port + HOST_HCCR);	outw(HCCR_RELEASE, host->io_port + HOST_HCCR);	outw(HCCR_BIOS_DISABLE, host->io_port + HOST_HCCR);	loop_count = DEFAULT_LOOP_COUNT;	while (--loop_count && inw(host->io_port + HOST_HCCR) == RISC_BUSY)		barrier();	if (!loop_count)		printk("qlogicfc%d : reset_hardware loop timeout\n", hostdata->host_id);#if DEBUG_ISP2x00	printk("qlogicfc%d : mbox 0 0x%04x \n", hostdata->host_id,  inw(host->io_port + MBOX0));	printk("qlogicfc%d : mbox 1 0x%04x \n", hostdata->host_id,  inw(host->io_port + MBOX1));	printk("qlogicfc%d : mbox 2 0x%04x \n", hostdata->host_id,  inw(host->io_port + MBOX2));	printk("qlogicfc%d : mbox 3 0x%04x \n", hostdata->host_id,  inw(host->io_port + MBOX3));	printk("qlogicfc%d : mbox 4 0x%04x \n", hostdata->host_id,  inw(host->io_port + MBOX4));	printk("qlogicfc%d : mbox 5 0x%04x \n", hostdata->host_id,  inw(host->io_port + MBOX5));	printk("qlogicfc%d : mbox 6 0x%04x \n", hostdata->host_id,  inw(host->io_port + MBOX6));	printk("qlogicfc%d : mbox 7 0x%04x \n", hostdata->host_id,  inw(host->io_port + MBOX7));#endif				/* DEBUG_ISP2x00 */	DEBUG(printk("qlogicfc%d : verifying checksum\n", hostdata->host_id));#if RELOAD_FIRMWARE	{		int i;		unsigned short * risc_code = NULL;		unsigned short risc_code_len = 0;		if (hostdata->pci_dev->device == PCI_DEVICE_ID_QLOGIC_ISP2100){		        risc_code = risc_code2100;			risc_code_len = risc_code_length2100;		}		else if (hostdata->pci_dev->device == PCI_DEVICE_ID_QLOGIC_ISP2200){		        risc_code = risc_code2200;			risc_code_len = risc_code_length2200;		}		for (i = 0; i < risc_code_len; i++) {			param[0] = MBOX_WRITE_RAM_WORD;			param[1] = risc_code_addr01 + i;			param[2] = risc_code[i];			isp2x00_mbox_command(host, param);			if (param[0] != MBOX_COMMAND_COMPLETE) {				printk("qlogicfc%d : firmware load failure\n", hostdata->host_id);				return 1;			}		}	}#endif				/* RELOAD_FIRMWARE */	param[0] = MBOX_VERIFY_CHECKSUM;	param[1] = risc_code_addr01;	isp2x00_mbox_command(host, param);	if (param[0] != MBOX_COMMAND_COMPLETE) {		printk("qlogicfc%d : ram checksum failure\n", hostdata->host_id);		return 1;	}	DEBUG(printk("qlogicfc%d : executing firmware\n", hostdata->host_id));	param[0] = MBOX_EXEC_FIRMWARE;	param[1] = risc_code_addr01;	isp2x00_mbox_command(host, param);	param[0] = MBOX_ABOUT_FIRMWARE;	isp2x00_mbox_command(host, param);	if (param[0] != MBOX_COMMAND_COMPLETE) {		printk("qlogicfc%d : about firmware failure\n", hostdata->host_id);		return 1;	}	DEBUG(printk("qlogicfc%d : firmware major revision %d\n", hostdata->host_id,  param[1]));	DEBUG(printk("qlogicfc%d : firmware minor revision %d\n", hostdata->host_id,  param[2]));#ifdef USE_NVRAM_DEFAULTS	if (isp2x00_get_nvram_defaults(host, &hostdata->control_block) != 0) {		printk("qlogicfc%d : Could not read from NVRAM\n", hostdata->host_id);	}#endif	hostdata->wwn = (u64) (cpu_to_le16(hostdata->control_block.node_name[0])) << 56;	hostdata->wwn |= (u64) (cpu_to_le16(hostdata->control_block.node_name[0]) & 0xff00) << 48;	hostdata->wwn |= (u64) (cpu_to_le16(hostdata->control_block.node_name[1]) & 0xff00) << 24;	hostdata->wwn |= (u64) (cpu_to_le16(hostdata->control_block.node_name[1]) & 0x00ff) << 48;	hostdata->wwn |= (u64) (cpu_to_le16(hostdata->control_block.node_name[2]) & 0x00ff) << 24;	hostdata->wwn |= (u64) (cpu_to_le16(hostdata->control_block.node_name[2]) & 0xff00) << 8;	hostdata->wwn |= (u64) (cpu_to_le16(hostdata->control_block.node_name[3]) & 0x00ff) << 8;	hostdata->wwn |= (u64) (cpu_to_le16(hostdata->control_block.node_name[3]) & 0xff00) >> 8;	/* FIXME: If the DMA transfer goes one way only, this should use PCI_DMA_TODEVICE and below as well. */	busaddr = pci64_map_single(hostdata->pci_dev, &hostdata->control_block, sizeof(hostdata->control_block),				   PCI_DMA_BIDIRECTIONAL);	param[0] = MBOX_INIT_FIRMWARE;	param[2] = (u_short) (pci64_dma_lo32(busaddr) >> 16);	param[3] = (u_short) (pci64_dma_lo32(busaddr) & 0xffff);	param[4] = 0;	param[5] = 0;	param[6] = (u_short) (pci64_dma_hi32(busaddr) >> 16);	param[7] = (u_short) (pci64_dma_hi32(busaddr) & 0xffff);	isp2x00_mbox_command(host, param);	if (param[0] != MBOX_COMMAND_COMPLETE) {		printk("qlogicfc%d.c: Ouch 0x%04x\n", hostdata->host_id,  param[0]);		pci64_unmap_single(hostdata->pci_dev, busaddr, sizeof(hostdata->control_block),				   PCI_DMA_BIDIRECTIONAL);		return 1;	}	param[0] = MBOX_GET_FIRMWARE_STATE;	isp2x00_mbox_command(host, param);	if (param[0] != MBOX_COMMAND_COMPLETE) {		printk("qlogicfc%d.c: 0x%04x\n", hostdata->host_id,  param[0]);		pci64_unmap_single(hostdata->pci_dev, busaddr, sizeof(hostdata->control_block),				   PCI_DMA_BIDIRECTIONAL);		return 1;	}	pci64_unmap_single(hostdata->pci_dev, busaddr, sizeof(hostdata->control_block),			   PCI_DMA_BIDIRECTIONAL);	LEAVE("isp2x00_reset_hardware");	return 0;}#ifdef USE_NVRAM_DEFAULTSstatic int isp2x00_get_nvram_defaults(struct Scsi_Host *host, struct init_cb *control_block){	u_short value;	if (isp2x00_read_nvram_word(host, 0) != 0x5349)		return 1;	value = isp2x00_read_nvram_word(host, 8);	control_block->node_name[0] = cpu_to_le16(isp2x00_read_nvram_word(host, 9));	control_block->node_name[1] = cpu_to_le16(isp2x00_read_nvram_word(host, 10));	control_block->node_name[2] = cpu_to_le16(isp2x00_read_nvram_word(host, 11));	control_block->node_name[3] = cpu_to_le16(isp2x00_read_nvram_word(host, 12));	control_block->hard_addr = cpu_to_le16(isp2x00_read_nvram_word(host, 13));	return 0;}#endifstatic int isp2x00_init(struct Scsi_Host *sh){	u_long io_base;	struct isp2x00_hostdata *hostdata;	u_char revision;	u_int irq;	u_short command;	struct pci_dev *pdev;	ENTER("isp2x00_init");	hostdata = (struct isp2x00_hostdata *) sh->hostdata;	pdev = hostdata->pci_dev;	if (pci_read_config_word(pdev, PCI_COMMAND, &command)	  || pci_read_config_byte(pdev, PCI_CLASS_REVISION, &revision)) {		printk("qlogicfc%d : error reading PCI configuration\n", hostdata->host_id);		return 1;	}	io_base = pci_resource_start(pdev, 0);	irq = pdev->irq;	if (pdev->vendor != PCI_VENDOR_ID_QLOGIC) {		printk("qlogicfc%d : 0x%04x is not QLogic vendor ID\n", hostdata->host_id, 		       pdev->vendor);		return 1;	}	if (pdev->device != PCI_DEVICE_ID_QLOGIC_ISP2100 && pdev->device != PCI_DEVICE_ID_QLOGIC_ISP2200) {		printk("qlogicfc%d : 0x%04x does not match ISP2100 or ISP2200 device id\n", hostdata->host_id, 		       pdev->device);		return 1;	}	if (!(command & PCI_COMMAND_IO) ||	    !(pdev->resource[0].flags & IORESOURCE_IO)) {		printk("qlogicfc%d : i/o mapping is disabled\n", hostdata->host_id);		return 1;	}	if (!(command & PCI_COMMAND_MASTER)) {		printk("qlogicfc%d : bus mastering is disabled\n", hostdata->host_id);		return 1;	}	if (revision != ISP2100_REV_ID1 && revision != ISP2100_REV_ID3 && revision != ISP2200_REV_ID5)		printk("qlogicfc%d : new isp2x00 revision ID (%d)\n", hostdata->host_id,  revision);	hostdata->revision = revision;	sh->irq = irq;	sh->io_port = io_base;	LEAVE("isp2x00_init");	return 0;}#if USE_NVRAM_DEFAULTS#define NVRAM_DELAY() udelay(10)	/* 10 microsecond delay */u_short isp2x00_read_nvram_word(struct Scsi_Host * host, u_short byte){	int i;	u_short value, output, input;	outw(0x2, host->io_port + PCI_NVRAM);	NVRAM_DELAY();	outw(0x3, host->io_port + PCI_NVRAM);	NVRAM_DELAY();	byte &= 0xff;	byte |= 0x0600;	for (i = 10; i >= 0; i--) {		output = ((byte >> i) & 0x1) ? 0x4 : 0x0;		outw(output | 0x2, host->io_port + PCI_NVRAM);		NVRAM_DELAY();		outw(output | 0x3, host->io_port + PCI_NVRAM);		NVRAM_DELAY();		outw(output | 0x2, host->io_port + PCI_NVRAM);		NVRAM_DELAY();	}	for (i = 0xf, value = 0; i >= 0; i--) {		value <<= 1;		outw(0x3, host->io_port + PCI_NVRAM);		NVRAM_DELAY();		input = inw(host->io_port + PCI_NVRAM);		NVRAM_DELAY();		outw(0x2, host->io_port + PCI_NVRAM);		NVRAM_DELAY();		if (input & 0x8)			value |= 1;	}	outw(0x0, host->io_port + PCI_NVRAM);	NVRAM_DELAY();	return value;}#endif				/* USE_NVRAM_DEFAULTS *//* * currently, this is only called during initialization or abort/reset, * at which times interrupts are disabled, so polling is OK, I guess... */static int isp2x00_mbox_command(struct Scsi_Host *host, u_short param[]){	int loop_count;	struct isp2x00_hostdata *hostdata = (struct isp2x00_hostdata *) host->hostdata;	if (mbox_param[param[0]] == 0 || hostdata->adapter_state == AS_FIRMWARE_DEAD)		return 1;	loop_count = DEFAULT_LOOP_COUNT;	while (--loop_count && inw(host->io_port + HOST_HCCR) & 0x0080)		barrier();	if (!loop_count) {		printk("qlogicfc%d : mbox_command loop timeout #1\n", hostdata->host_id);		param[0] = 0x4006;		hostdata->adapter_state = AS_FIRMWARE_DEAD;		return 1;	}	hostdata->mbox_done = 0;	if (mbox_param[param[0]] == 0)		printk("qlogicfc%d : invalid mbox command\n", hostdata->host_id);	if (mbox_param[param[0]] & 0x80)		outw(param[7], host->io_port + MBOX7);	if (mbox_param[param[0]] & 0x40)		outw(param[6], host->io_port + MBOX6);	if (mbox_param[param[0]] & 0x20)		outw(param[5], host->io_port + MBOX5);	if (mbox_param[param[0]] & 0x10)		outw(param[4], host->io_port + MBOX4);	if (mbox_param[param[0]] & 0x08)		outw(param[3], host->io_port + MBOX3);	if (mbox_param[param[0]] & 0x04)		outw(param[2], host->io_port + MBOX2);	if (mbox_param[param[0]] & 0x02)		outw(param[1], host->io_port + MBOX1);	if (mbox_param[param[0]] & 0x01)		outw(param[0], host->io_port + MBOX0);	outw(HCCR_SET_HOST_INTR, host->io_port + HOST_HCCR);	while (1) {		loop_count = DEFAULT_LOOP_COUNT;		while (--loop_count && !(inw(host->io_port + PCI_INTER_STS) & 0x08)) {			barrier();		}		if (!loop_count) {			hostdata->adapter_state = AS_FIRMWARE_DEAD;			printk("qlogicfc%d : mbox_command loop timeout #2\n", hostdata->host_id);			break;		}		isp2x00_intr_handler(host->irq, host, NULL);		if (hostdata->mbox_done == 1)			break;	}	loop_count = DEFAULT_LOOP_COUNT;	while (--loop_count && inw(host->io_port + MBOX0) == 0x04) {		barrier();	}	if (!loop_count)		printk("qlogicfc%d : mbox_command loop timeout #3\n", hostdata->host_id);	param[7] = inw(host->io_port + MBOX7);	param[6] = inw(host->io_port + MBOX6);	param[5] = inw(host->io_port + MBOX5);	param[4] = inw(host->io_port + MBOX4);	param[3] = inw(host->io_port + MBOX3);	param[2] = inw(host->io_port + MBOX2);	param[1] = inw(host->io_port + MBOX1);	param[0] = inw(host->io_port + MBOX0);	outw(0x0, host->io_port + PCI_SEMAPHORE);	if (inw(host->io_port + HOST_HCCR) & 0x0080) {		hostdata->adapter_state = AS_FIRMWARE_DEAD;		printk("qlogicfc%d : mbox op is still pending\n", hostdata->host_id);	}	return 0;}#if DEBUG_ISP2x00_INTRvoid isp2x00_print_status_entry(struct Status_Entry *status){	printk("qlogicfc : entry count = 0x%02x, type = 0x%02x, flags = 0x%02x\n", 	status->hdr.entry_cnt, status->hdr.entry_type, status->hdr.flags);	printk("qlogicfc : scsi status = 0x%04x, completion status = 0x%04x\n",	       le16_to_cpu(status->scsi_status), le16_to_cpu(status->completion_status));	printk("qlogicfc : state flags = 0x%04x, status flags = 0x%04x\n", 	       le16_to_cpu(status->state_flags), le16_to_cpu(status->status_flags));	printk("qlogicfc : response info length = 0x%04x, request sense length = 0x%04x\n",	       le16_to_cpu(status->res_info_len), le16_to_cpu(status->req_sense_len));	printk("qlogicfc : residual transfer length = 0x%08x, response = 0x%02x\n", le32_to_cpu(status->residual), sta

⌨️ 快捷键说明

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