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

📄 pci2220i.c

📁 Linux内核源代码 为压缩文件 是<<Linux内核>>一书中的源代码
💻 C
📖 第 1 页 / 共 5 页
字号:
	udelay (125);	if ( AtapiWaitReady (padapter, 1000) )		return TRUE;	if ( inb_p (padapter->regStatCmd) || (inb_p (padapter->regLba8) != 0x14) || (inb_p (padapter->regLba16) != 0xEB) )		return TRUE;	return FALSE;	}/**************************************************************** *	Name:	WalkScatGath	:LOCAL * *	Description:	Transfer data to/from scatter/gather buffers. * *	Parameters:		padapter - Pointer adapter data structure. *					datain   - TRUE if data read. *					length   - Number of bytes to transfer. * *	Returns:		Nothing. * ****************************************************************/static void WalkScatGath (PADAPTER2220I padapter, UCHAR datain, ULONG length)	{	ULONG	 count;	UCHAR	*buffer = padapter->kBuffer;	while ( length )		{		count = ( length > padapter->currentSgCount ) ? padapter->currentSgCount : length; 				if ( datain )			memcpy (padapter->currentSgBuffer, buffer, count);		else			memcpy (buffer, padapter->currentSgBuffer, count);		padapter->currentSgCount -= count;		if ( !padapter->currentSgCount )			{			if ( padapter->nextSg < padapter->SCpnt->use_sg )				{				padapter->currentSgBuffer = ((struct scatterlist *)padapter->SCpnt->request_buffer)[padapter->nextSg].address;				padapter->currentSgCount = ((struct scatterlist *)padapter->SCpnt->request_buffer)[padapter->nextSg].length;				padapter->nextSg++;				}			}		else			padapter->currentSgBuffer += count;		length -= count;		buffer += count;		}	}/**************************************************************** *	Name:	BusMaster	:LOCAL * *	Description:	Do a bus master I/O. * *	Parameters:		padapter - Pointer adapter data structure. *					datain	 - TRUE if data read. *					irq		 - TRUE if bus master interrupt expected. * *	Returns:		Nothing. * ****************************************************************/static void BusMaster (PADAPTER2220I padapter, UCHAR datain, UCHAR irq)	{	ULONG zl;		zl = ( padapter->sectorCount > MAX_BUS_MASTER_BLOCKS ) ? MAX_BUS_MASTER_BLOCKS : padapter->sectorCount;	padapter->sectorCount -= zl;	zl *= (ULONG)BYTES_PER_SECTOR;	if ( datain )		{		padapter->readCount = zl;		outb_p (8, padapter->regDmaDesc);							// read operation		if ( padapter->bigD )			{			if ( irq && !padapter->sectorCount )				outb_p (0x0C, padapter->regDmaMode);				// interrupt on			else				outb_p (0x08, padapter->regDmaMode);				// no interrupt			}		else 			{			if ( irq && !padapter->sectorCount )				outb_p (0x05, padapter->regDmaMode);				// interrupt on			else				outb_p (0x01, padapter->regDmaMode);				// no interrupt			}		}	else		{		outb_p (0x00, padapter->regDmaDesc);						// write operation		if ( padapter->bigD )			outb_p (0x08, padapter->regDmaMode);					// no interrupt								else			outb_p (0x01, padapter->regDmaMode);					// no interrupt		WalkScatGath (padapter, FALSE, zl);			}		outl (padapter->timingAddress, padapter->regDmaAddrLoc);	outl (padapter->kBufferDma, padapter->regDmaAddrPci);	outl (zl, padapter->regDmaCount);	outb_p (0x03, padapter->regDmaCmdStat);							// kick the DMA engine in gear	}/**************************************************************** *	Name:	AtapiBusMaster	:LOCAL * *	Description:	Do a bus master I/O. * *	Parameters:		padapter - Pointer adapter data structure. *					datain	 - TRUE if data read. *					length	 - Number of bytes to transfer. * *	Returns:		Nothing. * ****************************************************************/static void AtapiBusMaster (PADAPTER2220I padapter, UCHAR datain, ULONG length)	{	outl (padapter->timingAddress, padapter->regDmaAddrLoc);	outl (padapter->kBufferDma, padapter->regDmaAddrPci);	outl (length, padapter->regDmaCount);	if ( datain )		{		if ( padapter->readCount )				WalkScatGath (padapter, TRUE, padapter->readCount);		outb_p (0x08, padapter->regDmaDesc);						// read operation		outb_p (0x08, padapter->regDmaMode);						// no interrupt		padapter->readCount = length;		}	else		{		outb_p (0x00, padapter->regDmaDesc);						// write operation		outb_p (0x08, padapter->regDmaMode);						// no interrupt								if ( !padapter->atapiSpecial )			WalkScatGath (padapter, FALSE, length);			}	outb_p (0x03, padapter->regDmaCmdStat);							// kick the DMA engine in gear	}/**************************************************************** *	Name:	WriteData	:LOCAL * *	Description:	Write data to device. * *	Parameters:		padapter - Pointer adapter data structure. * *	Returns:		TRUE if drive does not assert DRQ in time. * ****************************************************************/static int WriteData (PADAPTER2220I padapter)	{	ULONG	zl;		if ( !WaitDrq (padapter) )		{		if ( padapter->timingPIO )			{			zl = (padapter->sectorCount > MAX_BUS_MASTER_BLOCKS) ? MAX_BUS_MASTER_BLOCKS : padapter->sectorCount;			WalkScatGath (padapter, FALSE, zl * BYTES_PER_SECTOR);			outsw (padapter->regData, padapter->kBuffer, zl * (BYTES_PER_SECTOR / 2));			padapter->sectorCount -= zl;			}		else			BusMaster (padapter, 0, 0);		return 0;		}	padapter->cmd = 0;												// null out the command byte	return 1;	}/**************************************************************** *	Name:	WriteDataBoth	:LOCAL * *	Description:	Write data to device. * *	Parameters:		padapter - Pointer to adapter structure. *					pdev	 - Pointer to device structure * *	Returns:		Index + 1 of drive not failed or zero for OK. * ****************************************************************/static int WriteDataBoth (PADAPTER2220I padapter, POUR_DEVICE pdev)	{	ULONG	zl;	UCHAR	status0, status1;	SelectSpigot (padapter, pdev->spigots[0]);	status0 = WaitDrq (padapter);	if ( !status0 )		{		SelectSpigot (padapter, pdev->spigots[1]);		status1 = WaitDrq (padapter);		if ( !status1 )			{			SelectSpigot (padapter, pdev->spigots[0] | pdev->spigots[1] | padapter->bigD);			if ( padapter->timingPIO )				{				zl = (padapter->sectorCount > MAX_BUS_MASTER_BLOCKS) ? MAX_BUS_MASTER_BLOCKS : padapter->sectorCount;				WalkScatGath (padapter, FALSE, zl * BYTES_PER_SECTOR);				outsw (padapter->regData, padapter->kBuffer, zl * (BYTES_PER_SECTOR / 2));				padapter->sectorCount -= zl;				}			else				BusMaster (padapter, 0, 0);			return 0;			}		}	padapter->cmd = 0;												// null out the command byte	if ( status0 )		return 2;	return 1;	}/**************************************************************** *	Name:	IdeCmd	:LOCAL * *	Description:	Process an IDE command. * *	Parameters:		padapter - Pointer adapter data structure. *					pdev	 - Pointer to device. * *	Returns:		Zero if no error or status register contents on error. * ****************************************************************/static UCHAR IdeCmd (PADAPTER2220I padapter, POUR_DEVICE pdev)	{	UCHAR	status;	SelectSpigot (padapter, pdev->spigot | padapter->bigD);							// select the spigot	outb_p (pdev->byte6 | ((UCHAR *)(&padapter->startSector))[3], padapter->regLba24);			// select the drive	status = WaitReady (padapter);	if ( !status )		{		outb_p (padapter->sectorCount, padapter->regSectCount);		outb_p (((UCHAR *)(&padapter->startSector))[0], padapter->regLba0);		outb_p (((UCHAR *)(&padapter->startSector))[1], padapter->regLba8);		outb_p (((UCHAR *)(&padapter->startSector))[2], padapter->regLba16);		padapter->expectingIRQ = TRUE;		WriteCommand (padapter, padapter->cmd);		return 0;		}	padapter->cmd = 0;									// null out the command byte	return status;	}/**************************************************************** *	Name:	IdeCmdBoth	:LOCAL * *	Description:	Process an IDE command to both drivers. * *	Parameters:		padapter - Pointer adapter data structure. *					pdev	 - Pointer to device structure * *	Returns:		Index + 1 of drive not failed or zero for OK. * ****************************************************************/static UCHAR IdeCmdBoth (PADAPTER2220I padapter, POUR_DEVICE pdev)	{	UCHAR	status0;	UCHAR	status1;	SelectSpigot (padapter, pdev->spigots[0] | pdev->spigots[1]);								// select the spigots	outb_p (padapter->pdev->byte6 | ((UCHAR *)(&padapter->startSector))[3], padapter->regLba24);// select the drive	SelectSpigot (padapter, pdev->spigots[0]);	status0 = WaitReady (padapter);	if ( !status0 )		{		SelectSpigot (padapter, pdev->spigots[1]);		status1 = WaitReady (padapter);		if ( !status1 )			{			SelectSpigot (padapter, pdev->spigots[0] | pdev->spigots[1] | padapter->bigD);			outb_p (padapter->sectorCount, padapter->regSectCount);			outb_p (((UCHAR *)(&padapter->startSector))[0], padapter->regLba0);			outb_p (((UCHAR *)(&padapter->startSector))[1], padapter->regLba8);			outb_p (((UCHAR *)(&padapter->startSector))[2], padapter->regLba16);			padapter->expectingIRQ = TRUE;			WriteCommand (padapter, padapter->cmd);			return 0;			}		}	padapter->cmd = 0;									// null out the command byte	if ( status0 )		return 2;	return 1;	}/**************************************************************** *	Name:	OpDone	:LOCAL * *	Description:	Complete an operatoin done sequence. * *	Parameters:		padapter - Pointer to host data block. *					spigot	 - Spigot select code. *					device	 - Device byte code. * *	Returns:		Nothing. * ****************************************************************/static void OpDone (PADAPTER2220I padapter, ULONG result)	{	Scsi_Cmnd	   *SCpnt = padapter->SCpnt;		if ( padapter->reconPhase )		{		padapter->reconPhase = 0;		if ( padapter->SCpnt )			{			Pci2220i_QueueCommand (SCpnt, SCpnt->scsi_done);			}		else			{			if ( padapter->reconOn )				{				ReconTimerExpiry ((unsigned long)padapter);				}			}		}	else		{		padapter->cmd = 0;		padapter->SCpnt = NULL;			padapter->pdev = NULL;		SCpnt->result = result;		SCpnt->scsi_done (SCpnt);		if ( padapter->reconOn && !padapter->reconTimer.data )			{			padapter->reconTimer.expires = jiffies + (HZ / 4);	// start in 1/4 second			padapter->reconTimer.data = (unsigned long)padapter;			add_timer (&padapter->reconTimer);			}		}	}/**************************************************************** *	Name:	InlineIdentify	:LOCAL * *	Description:	Do an intline inquiry on a drive. * *	Parameters:		padapter - Pointer to host data block. *					spigot	 - Spigot select code. *					device	 - Device byte code. * *	Returns:		Last addressable sector or zero if none. * ****************************************************************/static ULONG InlineIdentify (PADAPTER2220I padapter, UCHAR spigot, UCHAR device)	{	PIDENTIFY_DATA	pid = (PIDENTIFY_DATA)padapter->kBuffer;	SelectSpigot (padapter, spigot | SEL_IRQ_OFF);					// select the spigot	outb_p ((device << 4) | 0xA0, padapter->regLba24);				// select the drive	if ( WaitReady (padapter) )		return 0;	WriteCommand (padapter, IDE_COMMAND_IDENTIFY);		if ( WaitDrq (padapter) )		return 0;	insw (padapter->regData, padapter->kBuffer, sizeof (IDENTIFY_DATA) >> 1);	return (pid->LBATotalSectors - 1);	}/**************************************************************** *	Name:	AtapiIdentify	:LOCAL * *	Description:	Do an intline inquiry on a drive. * *	Parameters:		padapter - Pointer to host data block. *					pdev	 - Pointer to device table. * *	Returns:		TRUE on error. * ****************************************************************/static ULONG AtapiIdentify (PADAPTER2220I padapter, POUR_DEVICE pdev)	{	ATAPI_GENERAL_0		ag0;	USHORT				zs;	int					z;	AtapiDevice (padapter, pdev->byte6);		WriteCommand (padapter, IDE_COMMAND_ATAPI_IDENTIFY);		if ( AtapiWaitDrq (padapter, 3000) )		return TRUE;	*(USHORT *)&ag0 = inw_p (padapter->regData);	for ( z = 0;  z < 255;  z++ )		zs = inw_p (padapter->regData);	if ( ag0.ProtocolType == 2 )		{		if ( ag0.CmdDrqType == 1 )			pdev->cmdDrqInt = TRUE;		switch ( ag0.CmdPacketSize )			{			case 0:				pdev->packet = 6;				break;			case 1:				pdev->packet = 8;				break;			default:				pdev->packet = 6;				break;			}		return FALSE;		}	return TRUE;	}/**************************************************************** *	Name:	Atapi2Scsi * *	Description:	Convert ATAPI data to SCSI data. * *	Parameters:		padapter - Pointer adapter data structure. *					SCpnt	 - Pointer to SCSI command structure. * *	Returns:		Nothing. * ****************************************************************/void Atapi2Scsi (PADAPTER2220I padapter, Scsi_Cmnd *SCpnt)	{	UCHAR	*buff = padapter->currentSgBuffer; 	switch ( SCpnt->cmnd[0] )		{		case SCSIOP_MODE_SENSE:			buff[0] = padapter->kBuffer[1];			buff[1] = padapter->kBuffer[2];			buff[2] = padapter->kBuffer[3];			buff[3] = padapter->kBuffer[7];			memcpy (&buff[4], &padapter->kBuffer[8], padapter->atapiCdb[8] - 8);			break;		case SCSIOP_INQUIRY:			padapter->kBuffer[2] = 2;

⌨️ 快捷键说明

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