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

📄 qlogicisp.c

📁 讲述linux的初始化过程
💻 C
📖 第 1 页 / 共 4 页
字号:
	isp_outw(HCCR_CLEAR_RISC_INTR, host, HOST_HCCR);	if ((isp_inw(host, PCI_SEMAPHORE) & ASYNC_EVENT_INTERRUPT)) {		status = isp_inw(host, MBOX0);		DEBUG_INTR(printk("qlogicisp : mbox completion status: %x\n",				  status));		switch (status) {		      case ASYNC_SCSI_BUS_RESET:		      case EXECUTION_TIMEOUT_RESET:			hostdata->send_marker = 1;			break;		      case INVALID_COMMAND:		      case HOST_INTERFACE_ERROR:		      case COMMAND_ERROR:		      case COMMAND_PARAM_ERROR:			printk("qlogicisp : bad mailbox return status\n");			break;		}		isp_outw(0x0, host, PCI_SEMAPHORE);	}	out_ptr = hostdata->res_out_ptr;	DEBUG_INTR(printk("qlogicisp : response queue update\n"));	DEBUG_INTR(printk("qlogicisp : response queue depth %d\n",			  QUEUE_DEPTH(in_ptr, out_ptr, RES_QUEUE_LEN)));	while (out_ptr != in_ptr) {		u_int cmd_slot;		sts = (struct Status_Entry *) &hostdata->res_cpu[out_ptr];		out_ptr = (out_ptr + 1) & RES_QUEUE_LEN;		cmd_slot = sts->handle;		Cmnd = hostdata->cmd_slots[cmd_slot];		hostdata->cmd_slots[cmd_slot] = NULL;		TRACE("done", out_ptr, Cmnd);		if (le16_to_cpu(sts->completion_status) == CS_RESET_OCCURRED		    || le16_to_cpu(sts->completion_status) == CS_ABORTED		    || (le16_to_cpu(sts->status_flags) & STF_BUS_RESET))			hostdata->send_marker = 1;		if (le16_to_cpu(sts->state_flags) & SF_GOT_SENSE)			memcpy(Cmnd->sense_buffer, sts->req_sense_data,			       sizeof(Cmnd->sense_buffer));		DEBUG_INTR(isp1020_print_status_entry(sts));		if (sts->hdr.entry_type == ENTRY_STATUS)			Cmnd->result = isp1020_return_status(sts);		else			Cmnd->result = DID_ERROR << 16;		if (Cmnd->use_sg)			pci_unmap_sg(hostdata->pci_dev,				     (struct scatterlist *)Cmnd->buffer,				     Cmnd->use_sg,				     scsi_to_pci_dma_dir(Cmnd->sc_data_direction));		else if (Cmnd->request_bufflen)			pci_unmap_single(hostdata->pci_dev,#ifdef CONFIG_QL_ISP_A64					 (dma_addr_t)((long)Cmnd->SCp.ptr),#else					 (u32)((long)Cmnd->SCp.ptr),#endif					 Cmnd->request_bufflen,					 scsi_to_pci_dma_dir(Cmnd->sc_data_direction));		isp_outw(out_ptr, host, MBOX5);		(*Cmnd->scsi_done)(Cmnd);	}	hostdata->res_out_ptr = out_ptr;	LEAVE_INTR("isp1020_intr_handler");}static int isp1020_return_status(struct Status_Entry *sts){	int host_status = DID_ERROR;#if DEBUG_ISP1020_INTR	static char *reason[] = {		"DID_OK",		"DID_NO_CONNECT",		"DID_BUS_BUSY",		"DID_TIME_OUT",		"DID_BAD_TARGET",		"DID_ABORT",		"DID_PARITY",		"DID_ERROR",		"DID_RESET",		"DID_BAD_INTR"	};#endif /* DEBUG_ISP1020_INTR */	ENTER("isp1020_return_status");	DEBUG(printk("qlogicisp : completion status = 0x%04x\n",		     le16_to_cpu(sts->completion_status)));	switch(le16_to_cpu(sts->completion_status)) {	      case CS_COMPLETE:		host_status = DID_OK;		break;	      case CS_INCOMPLETE:		if (!(le16_to_cpu(sts->state_flags) & SF_GOT_BUS))			host_status = DID_NO_CONNECT;		else if (!(le16_to_cpu(sts->state_flags) & SF_GOT_TARGET))			host_status = DID_BAD_TARGET;		else if (!(le16_to_cpu(sts->state_flags) & SF_SENT_CDB))			host_status = DID_ERROR;		else if (!(le16_to_cpu(sts->state_flags) & SF_TRANSFERRED_DATA))			host_status = DID_ERROR;		else if (!(le16_to_cpu(sts->state_flags) & SF_GOT_STATUS))			host_status = DID_ERROR;		else if (!(le16_to_cpu(sts->state_flags) & SF_GOT_SENSE))			host_status = DID_ERROR;		break;	      case CS_DMA_ERROR:	      case CS_TRANSPORT_ERROR:		host_status = DID_ERROR;		break;	      case CS_RESET_OCCURRED:		host_status = DID_RESET;		break;	      case CS_ABORTED:		host_status = DID_ABORT;		break;	      case CS_TIMEOUT:		host_status = DID_TIME_OUT;		break;	      case CS_DATA_OVERRUN:	      case CS_COMMAND_OVERRUN:	      case CS_STATUS_OVERRUN:	      case CS_BAD_MESSAGE:	      case CS_NO_MESSAGE_OUT:	      case CS_EXT_ID_FAILED:	      case CS_IDE_MSG_FAILED:	      case CS_ABORT_MSG_FAILED:	      case CS_NOP_MSG_FAILED:	      case CS_PARITY_ERROR_MSG_FAILED:	      case CS_DEVICE_RESET_MSG_FAILED:	      case CS_ID_MSG_FAILED:	      case CS_UNEXP_BUS_FREE:		host_status = DID_ERROR;		break;	      case CS_DATA_UNDERRUN:		host_status = DID_OK;		break;	      default:		printk("qlogicisp : unknown completion status 0x%04x\n",		       le16_to_cpu(sts->completion_status));		host_status = DID_ERROR;		break;	}	DEBUG_INTR(printk("qlogicisp : host status (%s) scsi status %x\n",			  reason[host_status], le16_to_cpu(sts->scsi_status)));	LEAVE("isp1020_return_status");	return (le16_to_cpu(sts->scsi_status) & STATUS_MASK) | (host_status << 16);}int isp1020_abort(Scsi_Cmnd *Cmnd){	u_short param[6];	struct Scsi_Host *host;	struct isp1020_hostdata *hostdata;	int return_status = SCSI_ABORT_SUCCESS;	u_int cmd_cookie;	int i;	ENTER("isp1020_abort");	host = Cmnd->host;	hostdata = (struct isp1020_hostdata *) host->hostdata;	for (i = 0; i < QLOGICISP_REQ_QUEUE_LEN + 1; i++)		if (hostdata->cmd_slots[i] == Cmnd)			break;	cmd_cookie = i;	isp1020_disable_irqs(host);	param[0] = MBOX_ABORT;	param[1] = (((u_short) Cmnd->target) << 8) | Cmnd->lun;	param[2] = cmd_cookie >> 16;	param[3] = cmd_cookie & 0xffff;	isp1020_mbox_command(host, param);	if (param[0] != MBOX_COMMAND_COMPLETE) {		printk("qlogicisp : scsi abort failure: %x\n", param[0]);		return_status = SCSI_ABORT_ERROR;	}	isp1020_enable_irqs(host);	LEAVE("isp1020_abort");	return return_status;}int isp1020_reset(Scsi_Cmnd *Cmnd, unsigned int reset_flags){	u_short param[6];	struct Scsi_Host *host;	struct isp1020_hostdata *hostdata;	int return_status = SCSI_RESET_SUCCESS;	ENTER("isp1020_reset");	host = Cmnd->host;	hostdata = (struct isp1020_hostdata *) host->hostdata;	param[0] = MBOX_BUS_RESET;	param[1] = hostdata->host_param.bus_reset_delay;	isp1020_disable_irqs(host);	isp1020_mbox_command(host, param);	if (param[0] != MBOX_COMMAND_COMPLETE) {		printk("qlogicisp : scsi bus reset failure: %x\n", param[0]);		return_status = SCSI_RESET_ERROR;	}	isp1020_enable_irqs(host);	LEAVE("isp1020_reset");	return return_status;;}int isp1020_biosparam(Disk *disk, kdev_t n, int ip[]){	int size = disk->capacity;	ENTER("isp1020_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]);#if 0		if (ip[2] > 1023)			ip[2] = 1023;#endif				}	LEAVE("isp1020_biosparam");	return 0;}static int isp1020_reset_hardware(struct Scsi_Host *host){	u_short param[6];	int loop_count;	ENTER("isp1020_reset_hardware");	isp_outw(ISP_RESET, host, PCI_INTF_CTL);	udelay(100);	isp_outw(HCCR_RESET, host, HOST_HCCR);	udelay(100);	isp_outw(HCCR_RELEASE, host, HOST_HCCR);	isp_outw(HCCR_BIOS_DISABLE, host, HOST_HCCR);	loop_count = DEFAULT_LOOP_COUNT;	while (--loop_count && isp_inw(host, HOST_HCCR) == RISC_BUSY)		barrier();	if (!loop_count)		printk("qlogicisp: reset_hardware loop timeout\n");	isp_outw(0, host, ISP_CFG1);#if DEBUG_ISP1020	printk("qlogicisp : mbox 0 0x%04x \n", isp_inw(host, MBOX0));	printk("qlogicisp : mbox 1 0x%04x \n", isp_inw(host, MBOX1));	printk("qlogicisp : mbox 2 0x%04x \n", isp_inw(host, MBOX2));	printk("qlogicisp : mbox 3 0x%04x \n", isp_inw(host, MBOX3));	printk("qlogicisp : mbox 4 0x%04x \n", isp_inw(host, MBOX4));	printk("qlogicisp : mbox 5 0x%04x \n", isp_inw(host, MBOX5));#endif /* DEBUG_ISP1020 */	param[0] = MBOX_NO_OP;	isp1020_mbox_command(host, param);	if (param[0] != MBOX_COMMAND_COMPLETE) {		printk("qlogicisp : NOP test failed\n");		return 1;	}	DEBUG(printk("qlogicisp : loading risc ram\n"));#if RELOAD_FIRMWARE	for (loop_count = 0; loop_count < risc_code_length01; loop_count++) {		param[0] = MBOX_WRITE_RAM_WORD;		param[1] = risc_code_addr01 + loop_count;		param[2] = risc_code01[loop_count];		isp1020_mbox_command(host, param);		if (param[0] != MBOX_COMMAND_COMPLETE) {			printk("qlogicisp : firmware load failure at %d\n",			    loop_count);			return 1;		}	}#endif /* RELOAD_FIRMWARE */	DEBUG(printk("qlogicisp : verifying checksum\n"));	param[0] = MBOX_VERIFY_CHECKSUM;	param[1] = risc_code_addr01;	isp1020_mbox_command(host, param);	if (param[0] != MBOX_COMMAND_COMPLETE) {		printk("qlogicisp : ram checksum failure\n");		return 1;	}	DEBUG(printk("qlogicisp : executing firmware\n"));	param[0] = MBOX_EXEC_FIRMWARE;	param[1] = risc_code_addr01;	isp1020_mbox_command(host, param);	param[0] = MBOX_ABOUT_FIRMWARE;	isp1020_mbox_command(host, param);	if (param[0] != MBOX_COMMAND_COMPLETE) {		printk("qlogicisp : about firmware failure\n");		return 1;	}	DEBUG(printk("qlogicisp : firmware major revision %d\n", param[1]));	DEBUG(printk("qlogicisp : firmware minor revision %d\n", param[2]));	LEAVE("isp1020_reset_hardware");	return 0;}static int isp1020_init(struct Scsi_Host *sh){	u_long io_base, mem_base, io_flags, mem_flags;	struct isp1020_hostdata *hostdata;	u_char revision;	u_int irq;	u_short command;	struct pci_dev *pdev;	ENTER("isp1020_init");	hostdata = (struct isp1020_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("qlogicisp : error reading PCI configuration\n");		return 1;	}	io_base = pci_resource_start(pdev, 0);	mem_base = pci_resource_start(pdev, 1);	io_flags = pci_resource_flags(pdev, 0);	mem_flags = pci_resource_flags(pdev, 1);	irq = pdev->irq;	if (pdev->vendor != PCI_VENDOR_ID_QLOGIC) {		printk("qlogicisp : 0x%04x is not QLogic vendor ID\n",		       pdev->vendor);		return 1;	}	if (pdev->device != PCI_DEVICE_ID_QLOGIC_ISP1020) {		printk("qlogicisp : 0x%04x does not match ISP1020 device id\n",		       pdev->device);		return 1;	}#ifdef __alpha__	/* Force ALPHA to use bus I/O and not bus MEM.	   This is to avoid having to use HAE_MEM registers,	   which is broken on some platforms and with SMP.  */	command &= ~PCI_COMMAND_MEMORY; #endif	if (!(command & PCI_COMMAND_MASTER)) {		printk("qlogicisp : bus mastering is disabled\n");		return 1;	}	sh->io_port = io_base;	if (check_region(sh->io_port, 0xff)) {		printk("qlogicisp : i/o region 0x%lx-0x%lx already "		       "in use\n",		       sh->io_port, sh->io_port + 0xff);		return 1;	}	request_region(sh->io_port, 0xff, "qlogicisp"); 	if ((command & PCI_COMMAND_MEMORY) && 	    ((mem_flags & 1) == 0)) { 		mem_base = (u_long) ioremap(mem_base, PAGE_SIZE); 		hostdata->memaddr = mem_base; 	} else { 		if (command & PCI_COMMAND_IO && (io_flags & 3) != 1) 		{ 			printk("qlogicisp : i/o mapping is disabled\n");			release_region(sh->io_port, 0xff); 			return 1; 		} 		hostdata->memaddr = 0; /* zero to signify no i/o mapping */ 		mem_base = 0;	}	if (revision != ISP1020_REV_ID)		printk("qlogicisp : new isp1020 revision ID (%d)\n", revision);	if (isp_inw(sh,  PCI_ID_LOW) != PCI_VENDOR_ID_QLOGIC	    || isp_inw(sh, PCI_ID_HIGH) != PCI_DEVICE_ID_QLOGIC_ISP1020)	{		printk("qlogicisp : can't decode %s address space 0x%lx\n",		       (io_base ? "I/O" : "MEM"),		       (io_base ? io_base : mem_base));		iounmap((void *)hostdata->memaddr);		release_region(sh->io_port, 0xff);		return 1;	}	hostdata->revision = revision;	sh->irq = irq;	sh->max_id = MAX_TARGETS;	sh->max_lun = MAX_LUNS;	hostdata->res_cpu = pci_alloc_consistent(hostdata->pci_dev,						 QSIZE(RES_QUEUE_LEN),						 &hostdata->res_dma);	if (hostdata->res_cpu == NULL) {		printk("qlogicisp : can't allocate response queue\n");		return 1;	}	hostdata->req_cpu = pci_alloc_consistent(hostdata->pci_dev,						 QSIZE(QLOGICISP_REQ_QUEUE_LEN),						 &hostdata->req_dma);	if (hostdata->req_cpu == NULL) {		pci_free_consistent(hostdata->pci_dev,				    QSIZE(RES_QUEUE_LEN),				    hostdata->res_cpu,				    hostdata->res_dma);		printk("qlogicisp : can't allocate request queue\n");		return 1;	}	LEAVE("isp1020_init");	return 0;}#if USE_NVRAM_DEFAULTSstatic int isp1020_get_defaults(struct Scsi_Host *host){	int i;	u_short value;	struct isp1020_hostdata *hostdata =		(struct isp1020_hostdata *) host->hostdata;	ENTER("isp1020_get_defaults");	if (!isp1020_verify_nvram(host)) {		printk("qlogicisp : nvram checksum failure\n");		printk("qlogicisp : attempting to use default parameters\n");		return isp1020_set_defaults(host);	}	value = isp1020_read_nvram_word(host, 2);	hostdata->host_param.fifo_threshold = (value >> 8) & 0x03;

⌨️ 快捷键说明

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