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

📄 pci2220i.c

📁 Linux内核源代码 为压缩文件 是<<Linux内核>>一书中的源代码
💻 C
📖 第 1 页 / 共 5 页
字号:
			memcpy (buff, padapter->kBuffer, padapter->currentSgCount);			break;				default:			if ( padapter->readCount )				WalkScatGath (padapter, TRUE, padapter->readCount);			break;		}	}/**************************************************************** *	Name:	Scsi2Atapi * *	Description:	Convert SCSI packet command to Atapi packet command. * *	Parameters:		padapter - Pointer adapter data structure. *					SCpnt	 - Pointer to SCSI command structure. * *	Returns:		Nothing. * ****************************************************************/static void Scsi2Atapi (PADAPTER2220I padapter, Scsi_Cmnd *SCpnt)	{	UCHAR	*cdb = SCpnt->cmnd;	UCHAR	*buff = padapter->currentSgBuffer;	switch (cdb[0]) 		{		case SCSIOP_READ6:            padapter->atapiCdb[0] = SCSIOP_READ;			padapter->atapiCdb[1] = cdb[1] & 0xE0;            padapter->atapiCdb[3] = cdb[1] & 0x1F;			padapter->atapiCdb[4] = cdb[2];			padapter->atapiCdb[5] = cdb[3];			padapter->atapiCdb[8] = cdb[4];			padapter->atapiCdb[9] = cdb[5];			break;		case SCSIOP_WRITE6:            padapter->atapiCdb[0] = SCSIOP_WRITE;			padapter->atapiCdb[1] = cdb[1] & 0xE0;            padapter->atapiCdb[3] = cdb[1] & 0x1F;			padapter->atapiCdb[4] = cdb[2];			padapter->atapiCdb[5] = cdb[3];			padapter->atapiCdb[8] = cdb[4];			padapter->atapiCdb[9] = cdb[5];			break;        case SCSIOP_MODE_SENSE:             padapter->atapiCdb[0] = SCSIOP_MODE_SENSE10;			padapter->atapiCdb[2] = cdb[2];			padapter->atapiCdb[8] = cdb[4] + 4;            break;        case SCSIOP_MODE_SELECT: 			padapter->atapiSpecial = TRUE;			padapter->atapiCdb[0] = SCSIOP_MODE_SELECT10;			padapter->atapiCdb[1] = cdb[1] | 0x10;			memcpy (padapter->kBuffer, buff, 4);			padapter->kBuffer[4] = padapter->kBuffer[5] = 0;			padapter->kBuffer[6] = padapter->kBuffer[7] = 0;			memcpy (&padapter->kBuffer[8], &buff[4], cdb[4] - 4);			padapter->atapiCdb[8] = cdb[4] + 4;			break;	    }	}/**************************************************************** *	Name:	AtapiSendCdb * *	Description:	Send the CDB packet to the device. * *	Parameters:		padapter - Pointer adapter data structure. *					pdev	 - Pointer to device. *					cdb		 - Pointer to 16 byte SCSI cdb. * *	Returns:		Nothing. * ****************************************************************/static void AtapiSendCdb (PADAPTER2220I padapter, POUR_DEVICE pdev, CHAR *cdb)	{	DEB (printk ("\nPCI2242I: CDB: %X %X %X %X %X %X %X %X %X %X %X %X", cdb[0], cdb[1], cdb[2], cdb[3], cdb[4], cdb[5], cdb[6], cdb[7], cdb[8], cdb[9], cdb[10], cdb[11]));	outsw (padapter->regData, cdb, pdev->packet);	}/**************************************************************** *	Name:	AtapiRequestSense * *	Description:	Send the CDB packet to the device. * *	Parameters:		padapter - Pointer adapter data structure. *					pdev	 - Pointer to device. *					SCpnt	 - Pointer to SCSI command structure. *					pass	 - If true then this is the second pass to send cdb. * *	Returns:		TRUE on error. * ****************************************************************/static int AtapiRequestSense (PADAPTER2220I padapter, POUR_DEVICE pdev, Scsi_Cmnd *SCpnt, UCHAR pass)	{	UCHAR	cdb[16] = {SCSIOP_REQUEST_SENSE,0,0,0,16,0,0,0,0,0,0,0,0,0,0,0};				DEB (printk ("\nPCI2242I: AUTO REQUEST SENSE"));	cdb[4] = (UCHAR)(sizeof (SCpnt->sense_buffer));	if ( !pass )		{		padapter->reqSense = TRUE;	 	AtapiCountLo (padapter, cdb[4]);								AtapiCountHi (padapter, 0);								outb_p (0, padapter->regError);								WriteCommand (padapter, IDE_COMMAND_ATAPI_PACKET);		if ( pdev->cmdDrqInt )			return FALSE;		if ( AtapiWaitDrq (padapter, 500) )			return TRUE;		}	AtapiSendCdb (padapter, pdev, cdb);		return FALSE;	}/**************************************************************** *	Name:	InlineReadSignature	:LOCAL * *	Description:	Do an inline read RAID sigature. * *	Parameters:		padapter - Pointer adapter data structure. *					pdev	 - Pointer to device. *					index	 - index of data to read. * *	Returns:		Zero if no error or status register contents on error. * ****************************************************************/static UCHAR InlineReadSignature (PADAPTER2220I padapter, POUR_DEVICE pdev, int index)	{	UCHAR	status;	ULONG	zl = pdev->lastsectorlba[index];	SelectSpigot (padapter, pdev->spigots[index] | SEL_IRQ_OFF);	// select the spigot without interrupts	outb_p (pdev->byte6 | ((UCHAR *)&zl)[3], padapter->regLba24);			status = WaitReady (padapter);	if ( !status )		{		outb_p (((UCHAR *)&zl)[2], padapter->regLba16);		outb_p (((UCHAR *)&zl)[1], padapter->regLba8); 		outb_p (((UCHAR *)&zl)[0], padapter->regLba0);		outb_p (1, padapter->regSectCount);		WriteCommand (padapter, IDE_COMMAND_READ);		status = WaitDrq (padapter);		if ( !status )			{			insw (padapter->regData, padapter->kBuffer, BYTES_PER_SECTOR / 2);			((ULONG *)(&pdev->DiskMirror[index]))[0] = ((ULONG *)(&padapter->kBuffer[DISK_MIRROR_POSITION]))[0];			((ULONG *)(&pdev->DiskMirror[index]))[1] = ((ULONG *)(&padapter->kBuffer[DISK_MIRROR_POSITION]))[1];			// some drives assert DRQ before IRQ so let's make sure we clear the IRQ			WaitReady (padapter);			return 0;						}		}	return status;	}/**************************************************************** *	Name:	DecodeError	:LOCAL * *	Description:	Decode and process device errors. * *	Parameters:		padapter - Pointer to adapter data. *					status - Status register code. * *	Returns:		The driver status code. * ****************************************************************/static ULONG DecodeError (PADAPTER2220I	padapter, UCHAR status)	{	UCHAR			error;	padapter->expectingIRQ = 0;	if ( status & IDE_STATUS_WRITE_FAULT )		{		return DID_PARITY << 16;		}	if ( status & IDE_STATUS_BUSY )		return DID_BUS_BUSY << 16;	error = inb_p (padapter->regError);	DEB(printk ("\npci2220i error register: %x", error));	switch ( error )		{		case IDE_ERROR_AMNF:		case IDE_ERROR_TKONF:		case IDE_ERROR_ABRT:		case IDE_ERROR_IDFN:		case IDE_ERROR_UNC:		case IDE_ERROR_BBK:		default:			return DID_ERROR << 16;		}	return DID_ERROR << 16;	}/**************************************************************** *	Name:	StartTimer	:LOCAL * *	Description:	Start the timer. * *	Parameters:		ipadapter - Pointer adapter data structure. * *	Returns:		Nothing. * ****************************************************************/static void StartTimer (PADAPTER2220I padapter)	{	padapter->timer.expires = jiffies + TIMEOUT_DATA;	add_timer (&padapter->timer);	}/**************************************************************** *	Name:	WriteSignature	:LOCAL * *	Description:	Start the timer. * *	Parameters:		padapter - Pointer adapter data structure. *					pdev	 - Pointer to our device. *					spigot	 - Selected spigot. *					index	 - index of mirror signature on device. * *	Returns:		TRUE on any error. * ****************************************************************/static int WriteSignature (PADAPTER2220I padapter, POUR_DEVICE pdev, UCHAR spigot, int index)	{	ULONG	zl;	SelectSpigot (padapter, spigot);	zl = pdev->lastsectorlba[index];	outb_p (pdev->byte6 | ((UCHAR *)&zl)[3], padapter->regLba24);			outb_p (((UCHAR *)&zl)[2], padapter->regLba16);	outb_p (((UCHAR *)&zl)[1], padapter->regLba8);	outb_p (((UCHAR *)&zl)[0], padapter->regLba0);	outb_p (1, padapter->regSectCount);	WriteCommand (padapter, IDE_COMMAND_WRITE);		if ( WaitDrq (padapter) )		return TRUE;	StartTimer (padapter);		padapter->expectingIRQ = TRUE;		((ULONG *)(&padapter->kBuffer[DISK_MIRROR_POSITION]))[0] = ((ULONG *)(&pdev->DiskMirror[index]))[0];	((ULONG *)(&padapter->kBuffer[DISK_MIRROR_POSITION]))[1] = ((ULONG *)(&pdev->DiskMirror[index]))[1];	outsw (padapter->regData, padapter->kBuffer, BYTES_PER_SECTOR / 2);	return FALSE;	}/******************************************************************************************************* *	Name:			InitFailover * *	Description:	This is the beginning of the failover routine * *	Parameters:		SCpnt	 - Pointer to SCSI command structure. *					padapter - Pointer adapter data structure. *					pdev	 - Pointer to our device. *	 *	Returns:		TRUE on error. * ******************************************************************************************************/static int InitFailover (PADAPTER2220I padapter, POUR_DEVICE pdev)	{	UCHAR	spigot;		DEB (printk ("\npci2220i:  Initialize failover process - survivor = %d", pdev->deviceID[padapter->survivor]));	pdev->raid = FALSE;									//initializes system for non raid mode	pdev->reconOn = FALSE;	spigot = pdev->spigots[padapter->survivor];		if ( pdev->DiskMirror[padapter->survivor].status & UCBF_REBUILD )		{		DEB (printk ("\n         failed, is survivor"));		return (TRUE); 		}	if ( HardReset (padapter, pdev, spigot) )		{		DEB (printk ("\n         failed, reset"));		return TRUE;		}	Alarm (padapter, pdev->deviceID[padapter->survivor ^ 1]);	pdev->DiskMirror[padapter->survivor].status = UCBF_MIRRORED | UCBF_SURVIVOR;	//clear present status		if ( WriteSignature (padapter, pdev, spigot, padapter->survivor) )		{		DEB (printk ("\n         failed, write signature"));		return TRUE;		}	padapter->failinprog = TRUE;	return FALSE;	}/**************************************************************** *	Name:	TimerExpiry	:LOCAL * *	Description:	Timer expiry routine. * *	Parameters:		data - Pointer adapter data structure. * *	Returns:		Nothing. * ****************************************************************/static void TimerExpiry (unsigned long data)	{	PADAPTER2220I	padapter = (PADAPTER2220I)data;	POUR_DEVICE		pdev = padapter->pdev;	UCHAR			status = IDE_STATUS_BUSY;	UCHAR			temp, temp1;    unsigned long		flags;    /*     * Disable interrupts, if they aren't already disabled and acquire     * the I/O spinlock.     */    spin_lock_irqsave (&io_request_lock, flags);	DEB (printk ("\nPCI2220I: Timeout expired "));	if ( padapter->failinprog )		{		DEB (printk ("in failover process"));		OpDone (padapter, DecodeError (padapter, inb_p (padapter->regStatCmd)));		goto timerExpiryDone;		}		while ( padapter->reconPhase )		{		DEB (printk ("in recon phase %X", padapter->reconPhase));		switch ( padapter->reconPhase )			{			case RECON_PHASE_MARKING:			case RECON_PHASE_LAST:				padapter->survivor = ( pdev->spigot == pdev->spigots[0] ) ? 1 : 0;				DEB (printk ("\npci2220i: FAILURE 1"));				if ( InitFailover (padapter, pdev) )					OpDone (padapter, DID_ERROR << 16);				goto timerExpiryDone;						case RECON_PHASE_READY:				OpDone (padapter, DID_ERROR << 16);				goto timerExpiryDone;			case RECON_PHASE_COPY:				padapter->survivor = ( pdev->spigot == pdev->spigots[0] ) ? 0 : 1;				DEB (printk ("\npci2220i: FAILURE 2"));				DEB (printk ("\n       spig/stat = %X", inb_p (padapter->regStatSel));				if ( InitFailover (padapter, pdev) )					OpDone (padapter, DID_ERROR << 16);				goto timerExpiryDone;			case RECON_PHASE_UPDATE:				padapter->survivor = ( pdev->spigot == pdev->spigots[0] ) ? 0 : 1;				DEB (printk ("\npci2220i: FAILURE 3")));				if ( InitFailover (padapter, pdev) )					OpDone (padapter, DID_ERROR << 16);				goto timerExpiryDone;			case RECON_PHASE_END:				padapter->survivor = ( pdev->spigot == pdev->spigots[0] ) ? 0 : 1;				DEB (printk ("\npci2220i: FAILURE 4"));				if ( InitFailover (padapter, pdev) )					OpDone (padapter, DID_ERROR << 16);				goto timerExpiryDone;						default:				goto timerExpiryDone;			}		}		while ( padapter->cmd )		{		outb_p (0x08, padapter->regDmaCmdStat);					// cancel interrupt from DMA engine		if ( pdev->raid )			{			if ( padapter->cmd == WRITE_CMD )				{				DEB (printk ("in RAID write operation"));				temp = ( pdev->spigot & (SEL_1 | SEL_2) ) ? SEL_1 : SEL_3;				if ( inb_p (padapter->regStatSel) & temp )					{					DEB (printk ("\npci2220i: Determined A OK"));					SelectSpigot (padapter, temp | SEL_IRQ_OFF); // Masking the interrupt during spigot select					temp = inb_p (padapter->regStatCmd);					}				else					temp = IDE_STATUS_BUSY;				temp1 = ( pdev->spigot & (SEL_1 | SEL_2) ) ? SEL_2 : SEL_4;				if ( inb (padapter->regStatSel) & temp1 )					{					DEB (printk ("\npci2220i: Determined B OK"));					SelectSpigot (padapter, temp1 | SEL_IRQ_OFF); // Masking the interrupt during spigot select					temp1 = inb_p (padapter->regStatCmd);					}				else					temp1 = IDE_STATUS_BUSY;							if ( (temp & IDE_STATUS_BUSY) || (temp1 & IDE_STATUS_BUSY) )					{					DEB (printk ("\npci2220i: Status A: %X   B: %X", temp & 0xFF, temp1 & 0xFF));	 				if ( (temp & IDE_STATUS_BUSY) && (temp1 & IDE_STATUS_BUSY) ) 						{						status = temp;						break;						}							else							{						if ( temp & IDE_STATUS_BUSY )							padapter->survivor = 1;						else							padapter->survivor = 0;						if ( InitFailover (padapter, pdev) )							{							status = inb_p (padapter->regStatCmd);							break;							}						goto timerExpiryDone;						}					}				}			else				{				DEB (printk ("in RAID read operation"));				padapter->survivor = ( pdev->spigot == pdev->spigots[0] ) ? 0 : 1;				DEB (printk ("\npci2220i: FAILURE 6"));				if ( InitFailover (padapter, pdev) )					{					status = inb_p (padapter->regStatCmd);					break;					}				goto timerExpiryDone;				}			}

⌨️ 快捷键说明

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