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

📄 ini9100u.c

📁 linux和2410结合开发 用他可以生成2410所需的zImage文件
💻 C
📖 第 1 页 / 共 2 页
字号:
			break;		case 3:			ok = request_irq(pHCB->HCS_Intr, i91u_intr3, SA_INTERRUPT | SA_SHIRQ, "i91u", hreg);			break;		case 4:			ok = request_irq(pHCB->HCS_Intr, i91u_intr4, SA_INTERRUPT | SA_SHIRQ, "i91u", hreg);			break;		case 5:			ok = request_irq(pHCB->HCS_Intr, i91u_intr5, SA_INTERRUPT | SA_SHIRQ, "i91u", hreg);			break;		case 6:			ok = request_irq(pHCB->HCS_Intr, i91u_intr6, SA_INTERRUPT | SA_SHIRQ, "i91u", hreg);			break;		case 7:			ok = request_irq(pHCB->HCS_Intr, i91u_intr7, SA_INTERRUPT | SA_SHIRQ, "i91u", hreg);			break;		default:			i91u_panic("i91u: Too many host adapters\n");			break;		}		if (ok < 0) {			if (ok == -EINVAL) {				printk("i91u: bad IRQ %d.\n", pHCB->HCS_Intr);				printk("         Contact author.\n");			} else if (ok == -EBUSY)				printk("i91u: IRQ %d already in use. Configure another.\n",				       pHCB->HCS_Intr);			else {				printk("\ni91u: Unexpected error code on requesting IRQ %d.\n",				       pHCB->HCS_Intr);				printk("         Contact author.\n");			}			i91u_panic("i91u: driver needs an IRQ.\n");		}	}	tpnt->this_id = -1;	tpnt->can_queue = 1;	return 1;}static void i91uBuildSCB(HCS * pHCB, SCB * pSCB, Scsi_Cmnd * SCpnt){				/* Create corresponding SCB     */	struct scatterlist *pSrbSG;	SG *pSG;		/* Pointer to SG list           */	int i;	long TotalLen;	pSCB->SCB_Post = i91uSCBPost;	/* i91u's callback routine      */	pSCB->SCB_Srb = SCpnt;	pSCB->SCB_Opcode = ExecSCSI;	pSCB->SCB_Flags = SCF_POST;	/* After SCSI done, call post routine */	pSCB->SCB_Target = SCpnt->target;	pSCB->SCB_Lun = SCpnt->lun;	pSCB->SCB_Ident = SCpnt->lun | DISC_ALLOW;	pSCB->SCB_Flags |= SCF_SENSE;	/* Turn on auto request sense   */	pSCB->SCB_SensePtr = (U32) VIRT_TO_BUS(SCpnt->sense_buffer);	pSCB->SCB_SenseLen = SENSE_SIZE;	pSCB->SCB_CDBLen = SCpnt->cmd_len;	pSCB->SCB_HaStat = 0;	pSCB->SCB_TaStat = 0;	memcpy(&pSCB->SCB_CDB[0], &SCpnt->cmnd, SCpnt->cmd_len);	if (SCpnt->device->tagged_supported) {	/* Tag Support                  */		pSCB->SCB_TagMsg = SIMPLE_QUEUE_TAG;	/* Do simple tag only   */	} else {		pSCB->SCB_TagMsg = 0;	/* No tag support               */	}	if (SCpnt->use_sg) {		pSrbSG = (struct scatterlist *) SCpnt->request_buffer;		if (SCpnt->use_sg == 1) {	/* If only one entry in the list *//*      treat it as regular I/O */			pSCB->SCB_BufPtr = (U32) VIRT_TO_BUS(pSrbSG->address);			TotalLen = pSrbSG->length;			pSCB->SCB_SGLen = 0;		} else {	/* Assign SG physical address   */			pSCB->SCB_BufPtr = pSCB->SCB_SGPAddr;			pSCB->SCB_Flags |= SCF_SG;	/* Turn on SG list flag       */			for (i = 0, TotalLen = 0, pSG = &pSCB->SCB_SGList[0];	/* 1.01g */			     i < SCpnt->use_sg;			     i++, pSG++, pSrbSG++) {				pSG->SG_Ptr = (U32) VIRT_TO_BUS(pSrbSG->address);				TotalLen += pSG->SG_Len = pSrbSG->length;			}			pSCB->SCB_SGLen = i;		}		pSCB->SCB_BufLen = (SCpnt->request_bufflen > TotalLen) ?		    TotalLen : SCpnt->request_bufflen;	} else {		/* Non SG                       */		pSCB->SCB_BufPtr = (U32) VIRT_TO_BUS(SCpnt->request_buffer);		pSCB->SCB_BufLen = SCpnt->request_bufflen;		pSCB->SCB_SGLen = 0;	}	return;}/*  *  Queue a command and setup interrupts for a free bus. */int i91u_queue(Scsi_Cmnd * SCpnt, void (*done) (Scsi_Cmnd *)){	register SCB *pSCB;	HCS *pHCB;		/* Point to Host adapter control block */	if (SCpnt->lun > 16) {	/* 07/22/98 */		SCpnt->result = (DID_TIME_OUT << 16);		done(SCpnt);	/* Notify system DONE           */		return (0);	}	pHCB = (HCS *) SCpnt->host->base;	SCpnt->scsi_done = done;	/* Get free SCSI control block  */	if ((pSCB = tul_alloc_scb(pHCB)) == NULL) {		i91uAppendSRBToQueue(pHCB, SCpnt);	/* Buffer this request  */		return (0);	}	i91uBuildSCB(pHCB, pSCB, SCpnt);	tul_exec_scb(pHCB, pSCB);	/* Start execute SCB            */	return (0);}/* *  We only support command in interrupt-driven fashion */int i91u_command(Scsi_Cmnd * SCpnt){	printk("i91u: interrupt driven driver; use i91u_queue()\n");	return -1;}/* *  Abort a queued command *  (commands that are on the bus can't be aborted easily) */int i91u_abort(Scsi_Cmnd * SCpnt){	HCS *pHCB;	pHCB = (HCS *) SCpnt->host->base;	return tul_abort_srb(pHCB, SCpnt);}/* *  Reset registers, reset a hanging bus and *  kill active and disconnected commands for target w/o soft reset */int i91u_reset(Scsi_Cmnd * SCpnt, unsigned int reset_flags){				/* I need Host Control Block Information */	HCS *pHCB;	pHCB = (HCS *) SCpnt->host->base;	if (reset_flags & (SCSI_RESET_SUGGEST_BUS_RESET | SCSI_RESET_SUGGEST_HOST_RESET))		return tul_reset_scsi_bus(pHCB);	else		return tul_device_reset(pHCB, (ULONG) SCpnt, SCpnt->target, reset_flags);}/* * Return the "logical geometry" */int i91u_biosparam(Scsi_Disk * disk, kdev_t dev, int *info_array){	HCS *pHcb;		/* Point to Host adapter control block */	TCS *pTcb;	pHcb = (HCS *) disk->device->host->base;	pTcb = &pHcb->HCS_Tcs[disk->device->id];	if (pTcb->TCS_DrvHead) {		info_array[0] = pTcb->TCS_DrvHead;		info_array[1] = pTcb->TCS_DrvSector;		info_array[2] = disk->capacity / pTcb->TCS_DrvHead / pTcb->TCS_DrvSector;	} else {		if (pTcb->TCS_DrvFlags & TCF_DRV_255_63) {			info_array[0] = 255;			info_array[1] = 63;			info_array[2] = disk->capacity / 255 / 63;		} else {			info_array[0] = 64;			info_array[1] = 32;			info_array[2] = disk->capacity >> 11;		}	}#if defined(DEBUG_BIOSPARAM)	if (i91u_debug & debug_biosparam) {		printk("bios geometry: head=%d, sec=%d, cyl=%d\n",		       info_array[0], info_array[1], info_array[2]);		printk("WARNING: check, if the bios geometry is correct.\n");	}#endif	return 0;}/***************************************************************************** Function name  : i91uSCBPost Description    : This is callback routine be called when tulip finish one			SCSI command. Input          : pHCB  -       Pointer to host adapter control block.		  pSCB  -       Pointer to SCSI control block. Output         : None. Return         : None.*****************************************************************************/static void i91uSCBPost(BYTE * pHcb, BYTE * pScb){	Scsi_Cmnd *pSRB;	/* Pointer to SCSI request block */	HCS *pHCB;	SCB *pSCB;	pHCB = (HCS *) pHcb;	pSCB = (SCB *) pScb;	if ((pSRB = pSCB->SCB_Srb) == 0) {		printk("i91uSCBPost: SRB pointer is empty\n");		tul_release_scb(pHCB, pSCB);	/* Release SCB for current channel */		return;	}	switch (pSCB->SCB_HaStat) {	case 0x0:	case 0xa:		/* Linked command complete without error and linked normally */	case 0xb:		/* Linked command complete without error interrupt generated */		pSCB->SCB_HaStat = 0;		break;	case 0x11:		/* Selection time out-The initiator selection or target				   reselection was not complete within the SCSI Time out period */		pSCB->SCB_HaStat = DID_TIME_OUT;		break;	case 0x14:		/* Target bus phase sequence failure-An invalid bus phase or bus				   phase sequence was requested by the target. The host adapter				   will generate a SCSI Reset Condition, notifying the host with				   a SCRD interrupt */		pSCB->SCB_HaStat = DID_RESET;		break;	case 0x1a:		/* SCB Aborted. 07/21/98 */		pSCB->SCB_HaStat = DID_ABORT;		break;	case 0x12:		/* Data overrun/underrun-The target attempted to transfer more data				   than was allocated by the Data Length field or the sum of the				   Scatter / Gather Data Length fields. */	case 0x13:		/* Unexpected bus free-The target dropped the SCSI BSY at an unexpected time. */	case 0x16:		/* Invalid SCB Operation Code. */	default:		printk("ini9100u: %x %x\n", pSCB->SCB_HaStat, pSCB->SCB_TaStat);		pSCB->SCB_HaStat = DID_ERROR;	/* Couldn't find any better */		break;	}	pSRB->result = pSCB->SCB_TaStat | (pSCB->SCB_HaStat << 16);	if (pSRB == NULL) {		printk("pSRB is NULL\n");	}	pSRB->scsi_done(pSRB);	/* Notify system DONE           */	if ((pSRB = i91uPopSRBFromQueue(pHCB)) != NULL)		/* Find the next pending SRB    */	{			/* Assume resend will success   */		/* Reuse old SCB                */		i91uBuildSCB(pHCB, pSCB, pSRB);		/* Create corresponding SCB     */		tul_exec_scb(pHCB, pSCB);	/* Start execute SCB            */	} else {		/* No Pending SRB               */		tul_release_scb(pHCB, pSCB);	/* Release SCB for current channel */	}	return;}/* * Interrupts handler (main routine of the driver) */static void i91u_intr0(int irqno, void *dev_id, struct pt_regs *regs){	unsigned long flags;	if (tul_hcs[0].HCS_Intr != irqno)		return;	spin_lock_irqsave(&io_request_lock, flags);	tul_isr(&tul_hcs[0]);	spin_unlock_irqrestore(&io_request_lock, flags);}static void i91u_intr1(int irqno, void *dev_id, struct pt_regs *regs){	unsigned long flags;	if (tul_hcs[1].HCS_Intr != irqno)		return;	spin_lock_irqsave(&io_request_lock, flags);	tul_isr(&tul_hcs[1]);	spin_unlock_irqrestore(&io_request_lock, flags);}static void i91u_intr2(int irqno, void *dev_id, struct pt_regs *regs){	unsigned long flags;	if (tul_hcs[2].HCS_Intr != irqno)		return;	spin_lock_irqsave(&io_request_lock, flags);	tul_isr(&tul_hcs[2]);	spin_unlock_irqrestore(&io_request_lock, flags);}static void i91u_intr3(int irqno, void *dev_id, struct pt_regs *regs){	unsigned long flags;	if (tul_hcs[3].HCS_Intr != irqno)		return;	spin_lock_irqsave(&io_request_lock, flags);	tul_isr(&tul_hcs[3]);	spin_unlock_irqrestore(&io_request_lock, flags);}static void i91u_intr4(int irqno, void *dev_id, struct pt_regs *regs){	unsigned long flags;	if (tul_hcs[4].HCS_Intr != irqno)		return;	spin_lock_irqsave(&io_request_lock, flags);	tul_isr(&tul_hcs[4]);	spin_unlock_irqrestore(&io_request_lock, flags);}static void i91u_intr5(int irqno, void *dev_id, struct pt_regs *regs){	unsigned long flags;	if (tul_hcs[5].HCS_Intr != irqno)		return;	spin_lock_irqsave(&io_request_lock, flags);	tul_isr(&tul_hcs[5]);	spin_unlock_irqrestore(&io_request_lock, flags);}static void i91u_intr6(int irqno, void *dev_id, struct pt_regs *regs){	unsigned long flags;	if (tul_hcs[6].HCS_Intr != irqno)		return;	spin_lock_irqsave(&io_request_lock, flags);	tul_isr(&tul_hcs[6]);	spin_unlock_irqrestore(&io_request_lock, flags);}static void i91u_intr7(int irqno, void *dev_id, struct pt_regs *regs){	unsigned long flags;	if (tul_hcs[7].HCS_Intr != irqno)		return;	spin_lock_irqsave(&io_request_lock, flags);	tul_isr(&tul_hcs[7]);	spin_unlock_irqrestore(&io_request_lock, flags);}/*  * Dump the current driver status and panic... */static void i91u_panic(char *msg){	printk("\ni91u_panic: %s\n", msg);	panic("i91u panic");}/* * Release ressources */int i91u_release(struct Scsi_Host *hreg){	free_irq(hreg->irq, hreg);	release_region(hreg->io_port, 256);	return 0;}MODULE_LICENSE("Dual BSD/GPL");

⌨️ 快捷键说明

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