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

📄 pci2220i.c

📁 Linux内核源代码 为压缩文件 是<<Linux内核>>一书中的源代码
💻 C
📖 第 1 页 / 共 5 页
字号:
		else			{			DEB (printk ("in I/O operation"));			status = inb_p (padapter->regStatCmd);			}		break;		}		OpDone (padapter, DecodeError (padapter, status));timerExpiryDone:;    /*     * Release the I/O spinlock and restore the original flags     * which will enable interrupts if and only if they were     * enabled on entry.     */    spin_unlock_irqrestore (&io_request_lock, flags);	}/**************************************************************** *	Name:			SetReconstruct	:LOCAL * *	Description:	Set the reconstruct up. * *	Parameters:		pdev	- Pointer to device structure. *					index	- Mirror index number. * *	Returns:		Number of sectors on new disk required. * ****************************************************************/static LONG SetReconstruct (POUR_DEVICE pdev, int index)	{	pdev->DiskMirror[index].status = UCBF_MIRRORED;							// setup the flags	pdev->DiskMirror[index ^ 1].status = UCBF_MIRRORED | UCBF_REBUILD;	pdev->DiskMirror[index ^ 1].reconstructPoint = 0;						// start the reconstruct	pdev->reconCount = 1990;												// mark target drive early	return pdev->DiskMirror[index].reconstructPoint;	}/**************************************************************** *	Name:	ReconTimerExpiry	:LOCAL * *	Description:	Reconstruct timer expiry routine. * *	Parameters:		data - Pointer adapter data structure. * *	Returns:		Nothing. * ****************************************************************/static void ReconTimerExpiry (unsigned long data)	{	PADAPTER2220I	padapter;	POUR_DEVICE		pdev;	ULONG			testsize = 0;	PIDENTIFY_DATA	pid;	USHORT			minmode;	ULONG			zl;	UCHAR			zc;	USHORT			z;    unsigned long	flags;    /*     * Disable interrupts, if they aren't already disabled and acquire     * the I/O spinlock.     */    spin_lock_irqsave (&io_request_lock, flags);	padapter = (PADAPTER2220I)data;	if ( padapter->SCpnt )		goto reconTimerExpiry;	padapter->reconTimer.data = 0;	for ( z = padapter->devInReconIndex + 1;  z < BIGD_MAXDRIVES;  z++ )		{		if ( padapter->device[z].reconOn )			break;		}	if ( z < BIGD_MAXDRIVES )		pdev = &padapter->device[z];	else		{		for ( z = 0;  z < BIGD_MAXDRIVES;  z++ )			{			if ( padapter->device[z].reconOn )				break;			}		if ( z < BIGD_MAXDRIVES )			pdev = &padapter->device[z];		else			{			padapter->reconOn = FALSE;			goto reconTimerExpiry;			}		}	padapter->devInReconIndex = z;	pid = (PIDENTIFY_DATA)padapter->kBuffer;	padapter->pdev = pdev;	if ( pdev->reconIsStarting )		{		pdev->reconIsStarting = FALSE;		pdev->reconOn = FALSE;		while ( (pdev->DiskMirror[0].signature == SIGNATURE) && (pdev->DiskMirror[1].signature == SIGNATURE) &&			 (pdev->DiskMirror[0].pairIdentifier == (pdev->DiskMirror[1].pairIdentifier ^ 1)) )			{			if ( (pdev->DiskMirror[0].status & UCBF_MATCHED) && (pdev->DiskMirror[1].status & UCBF_MATCHED) )				break;;			if ( pdev->DiskMirror[0].status & UCBF_SURVIVOR )				// is first drive survivor?				testsize = SetReconstruct (pdev, 0);			else				if ( pdev->DiskMirror[1].status & UCBF_SURVIVOR )			// is second drive survivor?					testsize = SetReconstruct (pdev, 1);			if ( (pdev->DiskMirror[0].status & UCBF_REBUILD) || (pdev->DiskMirror[1].status & UCBF_REBUILD) )				{				if ( pdev->DiskMirror[0].status & UCBF_REBUILD )					pdev->mirrorRecon = 0;				else					pdev->mirrorRecon = 1;				pdev->reconOn = TRUE;				}			break;			}		if ( !pdev->reconOn )			goto reconTimerExpiry;		if ( padapter->bigD )			{			padapter->failRegister = 0;			outb_p (~padapter->failRegister, padapter->regFail);			}		else			{			zc = ((inb_p (padapter->regStatSel) >> 3) | inb_p (padapter->regStatSel)) & 0x83;		// mute the alarm			outb_p (0xFF, padapter->regFail);			}		while ( 1 )			{			DEB (printk ("\npci2220i: hard reset issue"));			if ( HardReset (padapter, pdev, pdev->spigots[pdev->mirrorRecon]) )				{				DEB (printk ("\npci2220i: sub 1"));				break;				}			pdev->lastsectorlba[pdev->mirrorRecon] = InlineIdentify (padapter, pdev->spigots[pdev->mirrorRecon], pdev->deviceID[pdev->mirrorRecon] & 1);			if ( pdev->lastsectorlba[pdev->mirrorRecon] < testsize )				{				DEB (printk ("\npci2220i: sub 2 %ld %ld", pdev->lastsectorlba[pdev->mirrorRecon], testsize));				break;				}	        // test LBA and multiper sector transfer compatability			if (!pid->SupportLBA || (pid->NumSectorsPerInt < SECTORSXFER) || !pid->Valid_64_70 )				{				DEB (printk ("\npci2220i: sub 3"));				break;				}	        // test PIO/bus matering mode compatability			if ( (pid->MinPIOCycleWithoutFlow > 240) && !pid->SupportIORDYDisable && !padapter->timingPIO )				{				DEB (printk ("\npci2220i: sub 4"));				break;				}			if ( pid->MinPIOCycleWithoutFlow <= 120 )	// setup timing mode of drive				minmode = 5;			else				{				if ( pid->MinPIOCylceWithFlow <= 150 )					minmode = 4;				else					{					if ( pid->MinPIOCylceWithFlow <= 180 )						minmode = 3;					else						{						if ( pid->MinPIOCylceWithFlow <= 240 )							minmode = 2;						else							{							DEB (printk ("\npci2220i: sub 5"));							break;							}						}					}				}			if ( padapter->timingMode > minmode )									// set minimum timing mode				padapter->timingMode = minmode;			if ( padapter->timingMode >= 2 )				padapter->timingAddress	= ModeArray[padapter->timingMode - 2];			else				padapter->timingPIO = TRUE;			padapter->reconOn = TRUE;			break;			}		if ( !pdev->reconOn )			{					padapter->survivor = pdev->mirrorRecon ^ 1;			padapter->reconPhase = RECON_PHASE_FAILOVER;			DEB (printk ("\npci2220i: FAILURE 7"));			InitFailover (padapter, pdev);			goto reconTimerExpiry;			}		pdev->raid = TRUE;			if ( WriteSignature (padapter, pdev, pdev->spigot, pdev->mirrorRecon ^ 1) )			goto reconTimerExpiry;		padapter->reconPhase = RECON_PHASE_MARKING;		goto reconTimerExpiry;		}	//**********************************	// reconstruct copy starts here		//**********************************	if ( pdev->reconCount++ > 2000 )		{		pdev->reconCount = 0;		if ( WriteSignature (padapter, pdev, pdev->spigots[pdev->mirrorRecon], pdev->mirrorRecon) )			{			padapter->survivor = pdev->mirrorRecon ^ 1;			padapter->reconPhase = RECON_PHASE_FAILOVER;			DEB (printk ("\npci2220i: FAILURE 8"));			InitFailover (padapter, pdev);			goto reconTimerExpiry;			}		padapter->reconPhase = RECON_PHASE_UPDATE;		goto reconTimerExpiry;		}	zl = pdev->DiskMirror[pdev->mirrorRecon].reconstructPoint;		padapter->reconSize = pdev->DiskMirror[pdev->mirrorRecon ^ 1].reconstructPoint - zl;	if ( padapter->reconSize > MAX_BUS_MASTER_BLOCKS )		padapter->reconSize = MAX_BUS_MASTER_BLOCKS;	if ( padapter->reconSize )		{		SelectSpigot (padapter, pdev->spigots[0] | pdev->spigots[1]);	// select the spigots		outb_p (pdev->byte6 | ((UCHAR *)(&zl))[3], padapter->regLba24);	// select the drive		SelectSpigot (padapter, pdev->spigot);		if ( WaitReady (padapter) )			goto reconTimerExpiry;		SelectSpigot (padapter, pdev->spigots[pdev->mirrorRecon]);		if ( WaitReady (padapter) )			{			padapter->survivor = pdev->mirrorRecon ^ 1;			padapter->reconPhase = RECON_PHASE_FAILOVER;			DEB (printk ("\npci2220i: FAILURE 9"));			InitFailover (padapter, pdev);			goto reconTimerExpiry;			}			SelectSpigot (padapter, pdev->spigots[0] | pdev->spigots[1]);		outb_p (padapter->reconSize & 0xFF, padapter->regSectCount);		outb_p (((UCHAR *)(&zl))[0], padapter->regLba0);		outb_p (((UCHAR *)(&zl))[1], padapter->regLba8);		outb_p (((UCHAR *)(&zl))[2], padapter->regLba16);		padapter->expectingIRQ = TRUE;		padapter->reconPhase = RECON_PHASE_READY;		SelectSpigot (padapter, pdev->spigots[pdev->mirrorRecon]);		WriteCommand (padapter, WRITE_CMD);		StartTimer (padapter);		SelectSpigot (padapter, pdev->spigot);		WriteCommand (padapter, READ_CMD);		goto reconTimerExpiry;		}	pdev->DiskMirror[pdev->mirrorRecon].status = UCBF_MIRRORED | UCBF_MATCHED;	pdev->DiskMirror[pdev->mirrorRecon ^ 1].status = UCBF_MIRRORED | UCBF_MATCHED;	if ( WriteSignature (padapter, pdev, pdev->spigot, pdev->mirrorRecon ^ 1) )		goto reconTimerExpiry;	padapter->reconPhase = RECON_PHASE_LAST;reconTimerExpiry:;    /*     * Release the I/O spinlock and restore the original flags     * which will enable interrupts if and only if they were     * enabled on entry.     */    spin_unlock_irqrestore (&io_request_lock, flags);	}/**************************************************************** *	Name:	Irq_Handler	:LOCAL * *	Description:	Interrupt handler. * *	Parameters:		irq		- Hardware IRQ number. *					dev_id	- *					regs	- * *	Returns:		TRUE if drive is not ready in time. * ****************************************************************/static void Irq_Handler (int irq, void *dev_id, struct pt_regs *regs)	{	struct Scsi_Host   *shost = NULL;	// Pointer to host data block	PADAPTER2220I		padapter;		// Pointer to adapter control structure	POUR_DEVICE			pdev;	Scsi_Cmnd		   *SCpnt;	UCHAR				status;	UCHAR				status1;	ATAPI_STATUS		statusa;	ATAPI_REASON		reasona;	ATAPI_ERROR			errora;	int					z;	ULONG				zl;    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 received interrupt\n"));	for ( z = 0; z < NumAdapters;  z++ )								// scan for interrupt to process		{		if ( PsiHost[z]->irq == (UCHAR)(irq & 0xFF) )			{			if ( inw_p (HOSTDATA(PsiHost[z])->regIrqControl) & 0x8000 )				{				shost = PsiHost[z];				break;				}			}		}	if ( !shost )		{		DEB (printk ("\npci2220i: not my interrupt"));		goto irq_return;		}	padapter = HOSTDATA(shost);	pdev = padapter->pdev;	SCpnt = padapter->SCpnt;	outb_p (0x08, padapter->regDmaCmdStat);									// cancel interrupt from DMA engine	if ( padapter->atapi && SCpnt )		{		*(char *)&statusa = inb_p (padapter->regStatCmd);						// read the device status		*(char *)&reasona = inb_p (padapter->regSectCount);						// read the device interrupt reason			if ( !statusa.bsy )			{			if ( statusa.drq )													// test for transfer phase				{				if ( !reasona.cod )												// test for data phase					{					z = (ULONG)inb_p (padapter->regLba8) | (ULONG)(inb_p (padapter->regLba16) << 8);					if ( padapter->reqSense )						insw (padapter->regData, SCpnt->sense_buffer, z / 2);					else						AtapiBusMaster (padapter, reasona.io, z);					goto irq_return;					}				if ( reasona.cod && !reasona.io )								// test for command packet phase					{					if ( padapter->reqSense )						AtapiRequestSense (padapter, pdev, SCpnt, TRUE);					else						AtapiSendCdb (padapter, pdev, padapter->atapiCdb);					goto irq_return;					}				}			else				{				if ( reasona.io && statusa.drdy )								// test for status phase					{					Atapi2Scsi (padapter, SCpnt);					if ( statusa.check )						{						*(UCHAR *)&errora = inb_p (padapter->regError);			// read the device error						if ( errora.senseKey )							{							if ( padapter->reqSense || AtapiRequestSense (padapter, pdev, SCpnt, FALSE) )								OpDone (padapter, DID_ERROR << 16);							}						else							{							if ( errora.ili || errora.abort )								OpDone (padapter, DID_ERROR << 16);							else								OpDone (padapter, DID_OK << 16);								}						}					else						if ( padapter->reqSense )							{							DEB (printk ("PCI2242I: Sense codes - %X %X %X ", ((UCHAR *)SCpnt->sense_buffer)[0], ((UCHAR *)SCpnt->sense_buffer)[12], ((UCHAR *)SCpnt->sense_buffer)[13]));							OpDone (padapter, (DRIVER_SENSE << 24) | (DID_OK << 16) | 2);							}						else							OpDone (padapter, DID_OK << 16);						}				}			}				goto irq_return;		}		if ( !padapter->expectingIRQ || !(SCpnt || padapter->reconPhase) )		{		DEB(printk ("\npci2220i Unsolicited interrupt\n"));		STOP_HERE ();		goto irq_return;		}	padapter->expectingIRQ = 0;	if ( padapter->failinprog )		{		DEB (printk ("\npci2220i interrupt failover complete"));		padapter->failinprog = FALSE;		status = inb_p (padapter->regStatCmd);								// read the device status		if ( status & (IDE_STATUS_ERROR | IDE_STATUS_WRITE_FAULT) )			{			DEB (printk ("\npci2220i: interrupt failover error from drive %X", status));			padapter->cmd = 0;

⌨️ 快捷键说明

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