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

📄 inia100.c

📁 linux和2410结合开发 用他可以生成2410所需的zImage文件
💻 C
📖 第 1 页 / 共 2 页
字号:
		hreg->this_id = pHCB->HCS_SCSI_ID;	/* Assign HCS index           */		hreg->base = (unsigned long)pHCB;#if 1		hreg->sg_tablesize = TOTAL_SG_ENTRY;	/* Maximun support is 32 */#else		hreg->sg_tablesize = SG_NONE;	/* No SG                        */#endif		/* Initial orc chip           */		switch (i) {		case 0:			ok = request_irq(pHCB->HCS_Intr, inia100_intr0, SA_INTERRUPT | SA_SHIRQ, "inia100", hreg);			break;		case 1:			ok = request_irq(pHCB->HCS_Intr, inia100_intr1, SA_INTERRUPT | SA_SHIRQ, "inia100", hreg);			break;		case 2:			ok = request_irq(pHCB->HCS_Intr, inia100_intr2, SA_INTERRUPT | SA_SHIRQ, "inia100", hreg);			break;		case 3:			ok = request_irq(pHCB->HCS_Intr, inia100_intr3, SA_INTERRUPT | SA_SHIRQ, "inia100", hreg);			break;		case 4:			ok = request_irq(pHCB->HCS_Intr, inia100_intr4, SA_INTERRUPT | SA_SHIRQ, "inia100", hreg);			break;		case 5:			ok = request_irq(pHCB->HCS_Intr, inia100_intr5, SA_INTERRUPT | SA_SHIRQ, "inia100", hreg);			break;		case 6:			ok = request_irq(pHCB->HCS_Intr, inia100_intr6, SA_INTERRUPT | SA_SHIRQ, "inia100", hreg);			break;		case 7:			ok = request_irq(pHCB->HCS_Intr, inia100_intr7, SA_INTERRUPT | SA_SHIRQ, "inia100", hreg);			break;		default:			inia100_panic("inia100: Too many host adapters\n");			break;		}		if (ok < 0) {			if (ok == -EINVAL) {				printk("inia100: bad IRQ %d.\n", pHCB->HCS_Intr);				printk("         Contact author.\n");			} else {				if (ok == -EBUSY)					printk("inia100: IRQ %d already in use. Configure another.\n", pHCB->HCS_Intr);				else {					printk("\ninia100: Unexpected error code on requesting IRQ %d.\n",					       pHCB->HCS_Intr);					printk("         Contact author.\n");				}			}			inia100_panic("inia100: driver needs an IRQ.\n");		}	}	tpnt->this_id = -1;	tpnt->can_queue = 1;	return 1;}/***************************************************************************** Function name  : inia100BuildSCB Description    :  Input          : pHCB  -       Pointer to host adapter structure Output         : None. Return         : pSRB  -       Pointer to SCSI request block.*****************************************************************************/static void inia100BuildSCB(ORC_HCS * pHCB, ORC_SCB * pSCB, Scsi_Cmnd * SCpnt){				/* Create corresponding SCB     */	struct scatterlist *pSrbSG;	ORC_SG *pSG;		/* Pointer to SG list           */	int i;	U32 TotalLen;	ESCB *pEScb;	pEScb = pSCB->SCB_EScb;	pEScb->SCB_Srb = SCpnt;	pSG = NULL;	pSCB->SCB_Opcode = ORC_EXECSCSI;	pSCB->SCB_Flags = SCF_NO_DCHK;	/* Clear done bit               */	pSCB->SCB_Target = SCpnt->target;	pSCB->SCB_Lun = SCpnt->lun;	pSCB->SCB_Reserved0 = 0;	pSCB->SCB_Reserved1 = 0;	pSCB->SCB_SGLen = 0;	if ((pSCB->SCB_XferLen = (U32) SCpnt->request_bufflen)) {		pSG = (ORC_SG *) & pEScb->ESCB_SGList[0];		if (SCpnt->use_sg) {			TotalLen = 0;			pSCB->SCB_SGLen = (U32) (SCpnt->use_sg * 8);			pSrbSG = (struct scatterlist *) SCpnt->request_buffer;			for (i = 0; i < SCpnt->use_sg; i++, pSG++, pSrbSG++) {				pSG->SG_Ptr = (U32) (VIRT_TO_BUS(pSrbSG->address));				pSG->SG_Len = (U32) pSrbSG->length;				TotalLen += (U32) pSrbSG->length;			}		} else {	/* Non SG                       */			pSCB->SCB_SGLen = 0x8;			pSG->SG_Ptr = (U32) (VIRT_TO_BUS(SCpnt->request_buffer));			pSG->SG_Len = (U32) SCpnt->request_bufflen;		}	}	pSCB->SCB_SGPAddr = (U32) pSCB->SCB_SensePAddr;	pSCB->SCB_HaStat = 0;	pSCB->SCB_TaStat = 0;	pSCB->SCB_Link = 0xFF;	pSCB->SCB_SenseLen = SENSE_SIZE;	pSCB->SCB_CDBLen = SCpnt->cmd_len;	if (pSCB->SCB_CDBLen >= IMAX_CDB) {		printk("max cdb length= %x\b", SCpnt->cmd_len);		pSCB->SCB_CDBLen = IMAX_CDB;	}	pSCB->SCB_Ident = SCpnt->lun | DISC_ALLOW;	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               */	}	memcpy(&pSCB->SCB_CDB[0], &SCpnt->cmnd, pSCB->SCB_CDBLen);	return;}/***************************************************************************** Function name  : inia100_queue Description    : Queue a command and setup interrupts for a free bus. Input          : pHCB  -       Pointer to host adapter structure Output         : None. Return         : pSRB  -       Pointer to SCSI request block.*****************************************************************************/int inia100_queue(Scsi_Cmnd * SCpnt, void (*done) (Scsi_Cmnd *)){	register ORC_SCB *pSCB;	ORC_HCS *pHCB;		/* Point to Host adapter control block */	if (SCpnt->lun > 16) {		SCpnt->result = (DID_TIME_OUT << 16);		done(SCpnt);	/* Notify system DONE           */		return (0);	}	pHCB = (ORC_HCS *) SCpnt->host->base;	SCpnt->scsi_done = done;	/* Get free SCSI control block  */	if ((pSCB = orc_alloc_scb(pHCB)) == NULL) {		inia100AppendSRBToQueue(pHCB, SCpnt);	/* Buffer this request  */		/* printk("inia100_entry: can't allocate SCB\n"); */		return (0);	}	inia100BuildSCB(pHCB, pSCB, SCpnt);	orc_exec_scb(pHCB, pSCB);	/* Start execute SCB            */	return (0);}/***************************************************************************** Function name  : inia100_command Description    : We only support command in interrupt-driven fashion Input          : pHCB  -       Pointer to host adapter structure Output         : None. Return         : pSRB  -       Pointer to SCSI request block.*****************************************************************************/int inia100_command(Scsi_Cmnd * SCpnt){	printk("inia100: interrupt driven driver; use inia100_queue()\n");	return -1;}/***************************************************************************** Function name  : inia100_abort Description    : Abort a queued command.	                 (commands that are on the bus can't be aborted easily) Input          : pHCB  -       Pointer to host adapter structure Output         : None. Return         : pSRB  -       Pointer to SCSI request block.*****************************************************************************/int inia100_abort(Scsi_Cmnd * SCpnt){	ORC_HCS *hcsp;	hcsp = (ORC_HCS *) SCpnt->host->base;	return orc_abort_srb(hcsp, (ULONG) SCpnt);}/***************************************************************************** Function name  : inia100_reset Description    : Reset registers, reset a hanging bus and                  kill active and disconnected commands for target w/o soft reset Input          : pHCB  -       Pointer to host adapter structure Output         : None. Return         : pSRB  -       Pointer to SCSI request block.*****************************************************************************/int inia100_reset(Scsi_Cmnd * SCpnt, unsigned int reset_flags){				/* I need Host Control Block Information */	ORC_HCS *pHCB;	pHCB = (ORC_HCS *) SCpnt->host->base;	if (reset_flags & (SCSI_RESET_SUGGEST_BUS_RESET | SCSI_RESET_SUGGEST_HOST_RESET))		return orc_reset_scsi_bus(pHCB);	else		return orc_device_reset(pHCB, (ULONG) SCpnt, SCpnt->target, reset_flags);}/***************************************************************************** Function name  : inia100SCBPost Description    : This is callback routine be called when orc finish one			SCSI command. Input          : pHCB  -       Pointer to host adapter control block.		  pSCB  -       Pointer to SCSI control block. Output         : None. Return         : None.*****************************************************************************/void inia100SCBPost(BYTE * pHcb, BYTE * pScb){	Scsi_Cmnd *pSRB;	/* Pointer to SCSI request block */	ORC_HCS *pHCB;	ORC_SCB *pSCB;	ESCB *pEScb;	pHCB = (ORC_HCS *) pHcb;	pSCB = (ORC_SCB *) pScb;	pEScb = pSCB->SCB_EScb;	if ((pSRB = (Scsi_Cmnd *) pEScb->SCB_Srb) == 0) {		printk("inia100SCBPost: SRB pointer is empty\n");		orc_release_scb(pHCB, pSCB);	/* Release SCB for current channel */		return;	}	pEScb->SCB_Srb = NULL;	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 CCB Operation Code-The first byte of the CCB was invalid. */	default:		printk("inia100: %x %x\n", pSCB->SCB_HaStat, pSCB->SCB_TaStat);		pSCB->SCB_HaStat = DID_ERROR;	/* Couldn't find any better */		break;	}	if (pSCB->SCB_TaStat == 2) {	/* Check condition              */		memcpy((unsigned char *) &pSRB->sense_buffer[0],		   (unsigned char *) &pEScb->ESCB_SGList[0], SENSE_SIZE);	}	pSRB->result = pSCB->SCB_TaStat | (pSCB->SCB_HaStat << 16);	pSRB->scsi_done(pSRB);	/* Notify system DONE           */	/* Find the next pending SRB    */	if ((pSRB = inia100PopSRBFromQueue(pHCB)) != NULL) {	/* Assume resend will success   */		/* Reuse old SCB                */		inia100BuildSCB(pHCB, pSCB, pSRB);	/* Create corresponding SCB     */		orc_exec_scb(pHCB, pSCB);	/* Start execute SCB            */	} else {		/* No Pending SRB               */		orc_release_scb(pHCB, pSCB);	/* Release SCB for current channel */	}	return;}/***************************************************************************** Function name  : inia100_biosparam Description    : Return the "logical geometry" Input          : pHCB  -       Pointer to host adapter structure Output         : None. Return         : pSRB  -       Pointer to SCSI request block.*****************************************************************************/int inia100_biosparam(Scsi_Disk * disk, kdev_t dev, int *info_array){	ORC_HCS *pHcb;		/* Point to Host adapter control block */	ORC_TCS *pTcb;	pHcb = (ORC_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;		}	}	return 0;}static void subIntr(ORC_HCS * pHCB, int irqno){	unsigned long flags;	spin_lock_irqsave(&io_request_lock, flags);	if (pHCB->HCS_Intr != irqno) {		spin_unlock_irqrestore(&io_request_lock, flags);		return;	}	orc_interrupt(pHCB);	spin_unlock_irqrestore(&io_request_lock, flags);}/* * Interrupts handler (main routine of the driver) */static void inia100_intr0(int irqno, void *dev_id, struct pt_regs *regs){	subIntr(&orc_hcs[0], irqno);}static void inia100_intr1(int irqno, void *dev_id, struct pt_regs *regs){	subIntr(&orc_hcs[1], irqno);}static void inia100_intr2(int irqno, void *dev_id, struct pt_regs *regs){	subIntr(&orc_hcs[2], irqno);}static void inia100_intr3(int irqno, void *dev_id, struct pt_regs *regs){	subIntr(&orc_hcs[3], irqno);}static void inia100_intr4(int irqno, void *dev_id, struct pt_regs *regs){	subIntr(&orc_hcs[4], irqno);}static void inia100_intr5(int irqno, void *dev_id, struct pt_regs *regs){	subIntr(&orc_hcs[5], irqno);}static void inia100_intr6(int irqno, void *dev_id, struct pt_regs *regs){	subIntr(&orc_hcs[6], irqno);}static void inia100_intr7(int irqno, void *dev_id, struct pt_regs *regs){	subIntr(&orc_hcs[7], irqno);}/*  * Dump the current driver status and panic... */static void inia100_panic(char *msg){	printk("\ninia100_panic: %s\n", msg);	panic("inia100 panic");}/* * Release ressources */int inia100_release(struct Scsi_Host *hreg){        free_irq(hreg->irq, hreg);        release_region(hreg->io_port, 256);        return 0;} MODULE_LICENSE("Dual BSD/GPL");/*#include "inia100scsi.c" */

⌨️ 快捷键说明

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