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

📄 psi240i.c

📁 Linux内核源代码 为压缩文件 是<<Linux内核>>一书中的源代码
💻 C
📖 第 1 页 / 共 2 页
字号:
		}irqerror:;	DEB(printk ("\npsi240i error  Device Status: %X\n", status));	SCpnt->result = DecodeError (shost, status);	SCpnt->scsi_done (SCpnt);	}static void do_Irq_Handler (int irq, void *dev_id, struct pt_regs *regs)	{	unsigned long flags;	spin_lock_irqsave(&io_request_lock, flags);	Irq_Handler(irq, dev_id, regs);	spin_unlock_irqrestore(&io_request_lock, flags);	}/**************************************************************** *	Name:	Psi240i_QueueCommand * *	Description:	Process a queued command from the SCSI manager. * *	Parameters:		SCpnt - Pointer to SCSI command structure. *					done  - Pointer to done function to call. * *	Returns:		Status code. * ****************************************************************/int Psi240i_QueueCommand (Scsi_Cmnd *SCpnt, void (*done)(Scsi_Cmnd *))	{	UCHAR		   *cdb = (UCHAR *)SCpnt->cmnd;					// Pointer to SCSI CDB	PADAPTER240I	padapter = HOSTDATA(SCpnt->host);			// Pointer to adapter control structure	POUR_DEVICE		pdev	 = &padapter->device[SCpnt->target];// Pointer to device information	UCHAR			rc;											// command return code	SCpnt->scsi_done = done;	padapter->ide.ide.ides.spigot = pdev->spigot;	padapter->buffer = SCpnt->request_buffer;	if (done)		{		if ( !pdev->device )			{			SCpnt->result = DID_BAD_TARGET << 16;			done (SCpnt);			return 0;			}		}	else		{		printk("psi240i_queuecommand: %02X: done can't be NULL\n", *cdb);		return 0;		}	switch ( *cdb )		{		case SCSIOP_INQUIRY:   					// inquiry CDB			{			padapter->ide.ide.ide[6] = pdev->byte6;			padapter->ide.ide.ides.cmd = IDE_COMMAND_IDENTIFY;			break;			}		case SCSIOP_TEST_UNIT_READY:			// test unit ready CDB			SCpnt->result = DID_OK << 16;			done (SCpnt);			return 0;		case SCSIOP_READ_CAPACITY:			  	// read capctiy CDB			{			PREAD_CAPACITY_DATA	pdata = (PREAD_CAPACITY_DATA)SCpnt->request_buffer;			pdata->blksiz = 0x20000;			XANY2SCSI ((UCHAR *)&pdata->blks, pdev->blocks);			SCpnt->result = DID_OK << 16;			done (SCpnt);			return 0;			}		case SCSIOP_VERIFY:						// verify CDB			*(ULONG *)padapter->ide.ide.ides.lba = XSCSI2LONG (&cdb[2]);			padapter->ide.ide.ide[6] |= pdev->byte6;			padapter->ide.ide.ide[2] = (UCHAR)((USHORT)cdb[8] | ((USHORT)cdb[7] << 8));			padapter->ide.ide.ides.cmd = IDE_COMMAND_VERIFY;			break;		case SCSIOP_READ:						// read10 CDB			padapter->startSector = XSCSI2LONG (&cdb[2]);			padapter->sectorCount = (USHORT)cdb[8] | ((USHORT)cdb[7] << 8);			SetupTransfer (padapter, pdev->byte6);			padapter->ide.ide.ides.cmd = IDE_CMD_READ_MULTIPLE;			break;		case SCSIOP_READ6:						// read6  CDB			padapter->startSector = SCSI2LONG (&cdb[1]);			padapter->sectorCount = cdb[4];			SetupTransfer (padapter, pdev->byte6);			padapter->ide.ide.ides.cmd = IDE_CMD_READ_MULTIPLE;			break;		case SCSIOP_WRITE:						// write10 CDB			padapter->startSector = XSCSI2LONG (&cdb[2]);			padapter->sectorCount = (USHORT)cdb[8] | ((USHORT)cdb[7] << 8);			SetupTransfer (padapter, pdev->byte6);			padapter->ide.ide.ides.cmd = IDE_CMD_WRITE_MULTIPLE;			break;		case SCSIOP_WRITE6:						// write6  CDB			padapter->startSector = SCSI2LONG (&cdb[1]);			padapter->sectorCount = cdb[4];			SetupTransfer (padapter, pdev->byte6);			padapter->ide.ide.ides.cmd = IDE_CMD_WRITE_MULTIPLE;			break;		default:			DEB (printk ("psi240i_queuecommand: Unsupported command %02X\n", *cdb));			SCpnt->result = DID_ERROR << 16;			done (SCpnt);			return 0;		}	padapter->SCpnt = SCpnt;  									// Save this command data	rc = IdeCmd (padapter);	if ( rc )		{		padapter->expectingIRQ = 0;		DEB (printk ("psi240i_queuecommand: %02X, %02X: Device failed to respond for command\n", *cdb, padapter->ide.ide.ides.cmd));		SCpnt->result = DID_ERROR << 16;		done (SCpnt);		return 0;		}	DEB (printk("psi240i_queuecommand: %02X, %02X now waiting for interrupt ", *cdb, padapter->ide.ide.ides.cmd));	return 0;	}static void internal_done(Scsi_Cmnd * SCpnt)	{	SCpnt->SCp.Status++;	}/**************************************************************** *	Name:	Psi240i_Command * *	Description:	Process a command from the SCSI manager. * *	Parameters:		SCpnt - Pointer to SCSI command structure. * *	Returns:		Status code. * ****************************************************************/int Psi240i_Command (Scsi_Cmnd *SCpnt)	{	DEB(printk("psi240i_command: ..calling psi240i_queuecommand\n"));	Psi240i_QueueCommand (SCpnt, internal_done);    SCpnt->SCp.Status = 0;	while (!SCpnt->SCp.Status)		barrier ();	return SCpnt->result;	}/*************************************************************************** *	Name:			ReadChipMemory * *	Description:	Read information from controller memory. * *	Parameters:		psetup	- Pointer to memory image of setup information. *					base	- base address of memory. *					length	- lenght of data space in bytes. *					port	- I/O address of data port. * *	Returns:		Nothing. * **************************************************************************/void ReadChipMemory (void *pdata, USHORT base, USHORT length, USHORT port)	{	USHORT	z, zz;	UCHAR	*pd = (UCHAR *)pdata;	outb_p (SEL_NONE, port + REG_SEL_FAIL);				// setup data port	zz = 0;	while ( zz < length )		{		outw_p (base, port + REG_ADDRESS);				// setup address		for ( z = 0;  z < 8;  z++ )			{			if ( (zz + z) < length )			*pd++ = inb_p (port + z);	// read data byte			}		zz += 8;		base += 8;		}	}/**************************************************************** *	Name:	Psi240i_Detect * *	Description:	Detect and initialize our boards. * *	Parameters:		tpnt - Pointer to SCSI host template structure. * *	Returns:		Number of adapters found. * ****************************************************************/int Psi240i_Detect (Scsi_Host_Template *tpnt)	{	int					board;	int					count = 0;	int					unit;	int					z;	USHORT				port;	CHIP_CONFIG_N		chipConfig;	CHIP_DEVICE_N		chipDevice[8];	struct Scsi_Host   *pshost;	ULONG				flags;	for ( board = 0;  board < 6;  board++ )					// scan for I/O ports		{		port = portAddr[board];								// get base address to test		if ( check_region (port, 16) )						// test for I/O addresses available			continue;										//   nope		if ( inb_p (port + REG_FAIL) != CHIP_ID )			// do the first test for likley hood that it is us			continue;		outb_p (SEL_NONE, port + REG_SEL_FAIL);				// setup EEPROM/RAM access		outw (0, port + REG_ADDRESS);						// setup EEPROM address zero		if ( inb_p (port) != 0x55 )							// test 1st byte			continue;										//   nope		if ( inb_p (port + 1) != 0xAA )						// test 2nd byte			continue;										//   nope		// at this point our board is found and can be accessed.  Now we need to initialize		// our informatation and register with the kernel.		ReadChipMemory (&chipConfig, CHIP_CONFIG, sizeof (chipConfig), port);		ReadChipMemory (&chipDevice, CHIP_DEVICE, sizeof (chipDevice), port);		ReadChipMemory (&ChipSetup, CHIP_EEPROM_DATA, sizeof (ChipSetup), port);		if ( !chipConfig.numDrives )						// if no devices on this board			continue;		pshost = scsi_register (tpnt, sizeof(ADAPTER240I));		if(pshost == NULL)			continue;		save_flags (flags);		cli ();		if ( request_irq (chipConfig.irq, do_Irq_Handler, 0, "psi240i", NULL) )			{			printk ("Unable to allocate IRQ for PSI-240I controller.\n");			restore_flags (flags);			goto unregister;			}		PsiHost[chipConfig.irq - 10] = pshost;		pshost->unique_id = port;		pshost->io_port = port;		pshost->n_io_port = 16;  /* Number of bytes of I/O space used */		pshost->irq = chipConfig.irq;		for ( z = 0;  z < 11;  z++ )						// build regester address array			HOSTDATA(pshost)->ports[z] = port + z;		HOSTDATA(pshost)->ports[11] = port + REG_FAIL;		HOSTDATA(pshost)->ports[12] = port + REG_ALT_STAT;		DEB (printk ("\nPorts ="));		DEB (for (z=0;z<13;z++) printk(" %#04X",HOSTDATA(pshost)->ports[z]););		for ( z = 0;  z < chipConfig.numDrives;  ++z )			{			unit = chipDevice[z].channel & 0x0F;			HOSTDATA(pshost)->device[unit].device	 = ChipSetup.setupDevice[unit].device;			HOSTDATA(pshost)->device[unit].byte6	 = (UCHAR)(((unit & 1) << 4) | 0xE0);			HOSTDATA(pshost)->device[unit].spigot	 = (UCHAR)(1 << (unit >> 1));			HOSTDATA(pshost)->device[unit].sectors	 = ChipSetup.setupDevice[unit].sectors;			HOSTDATA(pshost)->device[unit].heads	 = ChipSetup.setupDevice[unit].heads;			HOSTDATA(pshost)->device[unit].cylinders = ChipSetup.setupDevice[unit].cylinders;			HOSTDATA(pshost)->device[unit].blocks	 = ChipSetup.setupDevice[unit].blocks;			DEB (printk ("\nHOSTDATA->device    = %X", HOSTDATA(pshost)->device[unit].device));			DEB (printk ("\n          byte6     = %X", HOSTDATA(pshost)->device[unit].byte6));			DEB (printk ("\n          spigot    = %X", HOSTDATA(pshost)->device[unit].spigot));			DEB (printk ("\n          sectors   = %X", HOSTDATA(pshost)->device[unit].sectors));			DEB (printk ("\n          heads     = %X", HOSTDATA(pshost)->device[unit].heads));			DEB (printk ("\n          cylinders = %X", HOSTDATA(pshost)->device[unit].cylinders));			DEB (printk ("\n          blocks    = %lX", HOSTDATA(pshost)->device[unit].blocks));			}		restore_flags (flags);		printk("\nPSI-240I EIDE CONTROLLER: at I/O = %x  IRQ = %d\n", port, chipConfig.irq);		printk("(C) 1997 Perceptive Solutions, Inc. All rights reserved\n\n");		count++;		continue;unregister:;		scsi_unregister (pshost);		}	return count;	}/**************************************************************** *	Name:	Psi240i_Abort * *	Description:	Process the Abort command from the SCSI manager. * *	Parameters:		SCpnt - Pointer to SCSI command structure. * *	Returns:		Allways snooze. * ****************************************************************/int Psi240i_Abort (Scsi_Cmnd *SCpnt)	{	DEB (printk ("psi240i_abort\n"));	return SCSI_ABORT_SNOOZE;	}/**************************************************************** *	Name:	Psi240i_Reset * *	Description:	Process the Reset command from the SCSI manager. * *	Parameters:		SCpnt - Pointer to SCSI command structure. *					flags - Flags about the reset command * *	Returns:		No active command at this time, so this means *					that each time we got some kind of response the *					last time through.  Tell the mid-level code to *					request sense information in order to decide what *					to do next. * ****************************************************************/int Psi240i_Reset (Scsi_Cmnd *SCpnt, unsigned int reset_flags)	{	return SCSI_RESET_PUNT;	}#include "sd.h"/**************************************************************** *	Name:	Psi240i_BiosParam * *	Description:	Process the biosparam request from the SCSI manager to *					return C/H/S data. * *	Parameters:		disk - Pointer to SCSI disk structure. *					dev	 - Major/minor number from kernel. *					geom - Pointer to integer array to place geometry data. * *	Returns:		zero. * ****************************************************************/int Psi240i_BiosParam (Scsi_Disk *disk, kdev_t dev, int geom[])	{	POUR_DEVICE	pdev;	pdev = &(HOSTDATA(disk->device->host)->device[disk->device->id]);	geom[0] = pdev->heads;	geom[1] = pdev->sectors;	geom[2] = pdev->cylinders;	return 0;	}/* Eventually this will go into an include file, but this will be later */static Scsi_Host_Template driver_template = PSI240I;#include "scsi_module.c"

⌨️ 快捷键说明

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