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

📄 pci2000.c

📁 Linux内核源代码 为压缩文件 是<<Linux内核>>一书中的源代码
💻 C
📖 第 1 页 / 共 2 页
字号:
	pdev->SCpnt = SCpnt;  									// Save this command data	if ( WaitReady (padapter) )		{		rc = DID_ERROR;		goto finished;		}	outw_p (pun | (lun << 8), padapter->mb0);	if ( bus )		{		DEB (if(*cdb) printk ("\nCDB: %X-  %X %X %X %X %X %X %X %X %X %X ", SCpnt->cmd_len, cdb[0], cdb[1], cdb[2], cdb[3], cdb[4], cdb[5], cdb[6], cdb[7], cdb[8], cdb[9]));		DEB (if(*cdb) printk ("\ntimeout_per_command: %d, timeout_total: %d, timeout: %d, internal_timout: %d", SCpnt->timeout_per_command,							  SCpnt->timeout_total, SCpnt->timeout, SCpnt->internal_timeout));		outl (SCpnt->timeout_per_command, padapter->mb1);		outb_p (CMD_SCSI_TIMEOUT, padapter->cmd);		if ( WaitReady (padapter) )			{			rc = DID_ERROR;			goto finished;			}		outw_p (pun | (lun << 8), padapter->mb0);		outw_p (SCpnt->cmd_len << 8, padapter->mb0 + 2);		memcpy (pdev->cdb, cdb, MAX_COMMAND_SIZE);		outl (pdev->cdbDma, padapter->mb1);		if ( BuildSgList (SCpnt, padapter, pdev) )			cmd = CMD_SCSI_THRU;		else			cmd = CMD_SCSI_THRU_SG;		if ( (pdev->tag = Command (padapter, cmd)) == 0 )			rc = DID_TIME_OUT;		goto finished;		}	else		{		if ( lun )			{			rc = DID_BAD_TARGET;			goto finished;			}		}	switch ( *cdb )		{		case SCSIOP_INQUIRY:   					// inquiry CDB			if ( cdb[2] == SC_MY_RAID )				{				switch ( cdb[3] ) 					{					case MY_SCSI_REBUILD:						OpDone (SCpnt, PsiRaidCmd (padapter, CMD_RAID_REBUILD) << 16);						return 0;					case MY_SCSI_ALARMMUTE:						OpDone (SCpnt, PsiRaidCmd (padapter, CMD_RAID_MUTE) << 16);						return 0;					case MY_SCSI_DEMOFAIL:						OpDone (SCpnt, PsiRaidCmd (padapter, CMD_RAID_FAIL) << 16);						return 0;					default:						if ( SCpnt->use_sg )							{							rc = DID_ERROR;							goto finished;							}						else							{							SCpnt->SCp.have_data_in = pci_map_single (padapter->pdev, SCpnt->request_buffer, SCpnt->request_bufflen,													  scsi_to_pci_dma_dir(SCpnt->sc_data_direction));							outl (SCpnt->SCp.have_data_in, padapter->mb2);							}						outl (cdb[5], padapter->mb0);						outl (cdb[3], padapter->mb3);						cmd = CMD_DASD_RAID_RQ;						break;					}				break;				}						if ( SCpnt->use_sg )				{				SCpnt->SCp.have_data_in = pci_map_single (padapter->pdev, ((struct scatterlist *)SCpnt->request_buffer)->address, 										  SCpnt->request_bufflen, scsi_to_pci_dma_dir (SCpnt->sc_data_direction));				}			else				{				SCpnt->SCp.have_data_in = pci_map_single (padapter->pdev, SCpnt->request_buffer, 										  SCpnt->request_bufflen, scsi_to_pci_dma_dir (SCpnt->sc_data_direction));				}			outl (SCpnt->SCp.have_data_in, padapter->mb2);			outl (SCpnt->request_bufflen, padapter->mb3);			cmd = CMD_DASD_SCSI_INQ;			break;		case SCSIOP_TEST_UNIT_READY:			// test unit ready CDB			SCpnt->SCp.have_data_in = pci_map_single (padapter->pdev, SCpnt->sense_buffer, sizeof (SCpnt->sense_buffer), PCI_DMA_FROMDEVICE);			outl (SCpnt->SCp.have_data_in, padapter->mb2);			outl (sizeof (SCpnt->sense_buffer), padapter->mb3);			cmd = CMD_TEST_READY;			break;		case SCSIOP_READ_CAPACITY:			  	// read capacity CDB			if ( SCpnt->use_sg )				{				SCpnt->SCp.have_data_in = pci_map_single (padapter->pdev, ((struct scatterlist *)(SCpnt->request_buffer))->address,										  8, PCI_DMA_FROMDEVICE);				}			else				SCpnt->SCp.have_data_in = pci_map_single (padapter->pdev, SCpnt->request_buffer, 8, PCI_DMA_FROMDEVICE);			outl (SCpnt->SCp.have_data_in, padapter->mb2);			outl (8, padapter->mb3);			cmd = CMD_DASD_CAP;			break;		case SCSIOP_VERIFY:						// verify CDB			outw_p ((USHORT)cdb[8] | ((USHORT)cdb[7] << 8), padapter->mb0 + 2);			outl (XSCSI2LONG (&cdb[2]), padapter->mb1);			cmd = CMD_READ_SG;			break;		case SCSIOP_READ:						// read10 CDB			outw_p ((USHORT)cdb[8] | ((USHORT)cdb[7] << 8), padapter->mb0 + 2);			outl (XSCSI2LONG (&cdb[2]), padapter->mb1);			if ( BuildSgList (SCpnt, padapter, pdev) )				cmd = CMD_READ;			else				cmd = CMD_READ_SG;			break;		case SCSIOP_READ6:						// read6  CDB			outw_p (cdb[4], padapter->mb0 + 2);			outl ((SCSI2LONG (&cdb[1])) & 0x001FFFFF, padapter->mb1);			if ( BuildSgList (SCpnt, padapter, pdev) )				cmd = CMD_READ;			else				cmd = CMD_READ_SG;			break;		case SCSIOP_WRITE:						// write10 CDB			outw_p ((USHORT)cdb[8] | ((USHORT)cdb[7] << 8), padapter->mb0 + 2);			outl (XSCSI2LONG (&cdb[2]), padapter->mb1);			if ( BuildSgList (SCpnt, padapter, pdev) )				cmd = CMD_WRITE;			else				cmd = CMD_WRITE_SG;			break;		case SCSIOP_WRITE6:						// write6  CDB			outw_p (cdb[4], padapter->mb0 + 2);			outl ((SCSI2LONG (&cdb[1])) & 0x001FFFFF, padapter->mb1);			if ( BuildSgList (SCpnt, padapter, pdev) )				cmd = CMD_WRITE;			else				cmd = CMD_WRITE_SG;			break;		case SCSIOP_START_STOP_UNIT:			cmd = CMD_EJECT_MEDIA;			break;		case SCSIOP_MEDIUM_REMOVAL:			switch ( cdb[4] )				{				case 0:					cmd = CMD_UNLOCK_DOOR;					break;				case 1:					cmd = CMD_LOCK_DOOR;					break;				default:					cmd = 0;					break;				}			if ( cmd )				break;		default:			DEB (printk ("pci2000_queuecommand: Unsupported command %02X\n", *cdb));			OpDone (SCpnt, DID_ERROR << 16);			return 0;		}	if ( (pdev->tag = Command (padapter, cmd)) == 0 )		rc = DID_TIME_OUT;finished:;	if ( rc != -1 )		OpDone (SCpnt, rc << 16);	return 0;	}/**************************************************************** *	Name:	internal_done :LOCAL * *	Description:	Done handler for non-queued commands * *	Parameters:		SCpnt - Pointer to SCSI command structure. * *	Returns:		Nothing. * ****************************************************************/static void internal_done (Scsi_Cmnd * SCpnt)	{	SCpnt->SCp.Status++;	}/**************************************************************** *	Name:	Pci2000_Command * *	Description:	Process a command from the SCSI manager. * *	Parameters:		SCpnt - Pointer to SCSI command structure. * *	Returns:		Status code. * ****************************************************************/int Pci2000_Command (Scsi_Cmnd *SCpnt)	{	DEB(printk("pci2000_command: ..calling pci2000_queuecommand\n"));	Pci2000_QueueCommand (SCpnt, internal_done);    SCpnt->SCp.Status = 0;	while (!SCpnt->SCp.Status)		barrier ();	return SCpnt->result;	}/**************************************************************** *	Name:	Pci2000_Detect * *	Description:	Detect and initialize our boards. * *	Parameters:		tpnt - Pointer to SCSI host template structure. * *	Returns:		Number of adapters installed. * ****************************************************************/int Pci2000_Detect (Scsi_Host_Template *tpnt)	{	int					found = 0;	int					installed = 0;	struct Scsi_Host   *pshost;	PADAPTER2000	    padapter;	int					z, zz;	int					setirq;	struct pci_dev	   *pdev = NULL;	UCHAR			   *consistent;	dma_addr_t			consistentDma;	if ( !pci_present () )		{		printk ("pci2000: PCI BIOS not present\n");		return 0;		}	while ( (pdev = pci_find_device (VENDOR_PSI, DEVICE_ROY_1, pdev)) != NULL )		{		if (pci_enable_device(pdev))			continue;		pshost = scsi_register (tpnt, sizeof(ADAPTER2000));		if(pshost == NULL)			continue;		padapter = HOSTDATA(pshost);		padapter->basePort = pci_resource_start (pdev, 1);		DEB (printk ("\nBase Regs = %#04X", padapter->basePort));			// get the base I/O port address		padapter->mb0	= padapter->basePort + RTR_MAILBOX;		   			// get the 32 bit mail boxes		padapter->mb1	= padapter->basePort + RTR_MAILBOX + 4;		padapter->mb2	= padapter->basePort + RTR_MAILBOX + 8;		padapter->mb3	= padapter->basePort + RTR_MAILBOX + 12;		padapter->mb4	= padapter->basePort + RTR_MAILBOX + 16;		padapter->cmd	= padapter->basePort + RTR_LOCAL_DOORBELL;			// command register		padapter->tag	= padapter->basePort + RTR_PCI_DOORBELL;			// tag/response register		padapter->pdev = pdev;		if ( WaitReady (padapter) )			goto unregister;		outb_p (0x84, padapter->mb0);		outb_p (CMD_SPECIFY, padapter->cmd);		if ( WaitReady (padapter) )			goto unregister;		consistent = pci_alloc_consistent (pdev, consistentLen, &consistentDma);		if ( !consistent )			{			printk ("Unable to allocate DMA memory for PCI-2000 controller.\n");			goto unregister;			}				pshost->irq = pdev->irq;		setirq = 1;		padapter->irqOwned = 0;		for ( z = 0;  z < installed;  z++ )									// scan for shared interrupts			{			if ( PsiHost[z]->irq == pshost->irq )							// if shared then, don't posses				setirq = 0;			}		if ( setirq )												// if not shared, posses			{			if ( request_irq (pshost->irq, Irq_Handler, SA_SHIRQ, "pci2000", padapter) < 0 )				{				if ( request_irq (pshost->irq, Irq_Handler, SA_INTERRUPT | SA_SHIRQ, "pci2000", padapter) < 0 )					{					printk ("Unable to allocate IRQ for PCI-2000 controller.\n");					pci_free_consistent (pdev, consistentLen, consistent, consistentDma);					goto unregister;					}				}			padapter->irqOwned = pshost->irq;						// set IRQ as owned			}		PsiHost[installed]	= pshost;										// save SCSI_HOST pointer		pshost->io_port		= padapter->basePort;		pshost->n_io_port	= 0xFF;		pshost->unique_id	= padapter->basePort;		pshost->max_id		= 16;		pshost->max_channel	= 1;		for ( zz = 0;  zz < MAX_BUS;  zz++ )			for ( z = 0; z < MAX_UNITS;  z++ )				{				padapter->dev[zz][z].tag = 0;				padapter->dev[zz][z].scatGath = (PSCATGATH)consistent;				padapter->dev[zz][z].scatGathDma = consistentDma;				consistent += 16 * sizeof (SCATGATH);				consistentDma += 16 * sizeof (SCATGATH);				padapter->dev[zz][z].cdb = (UCHAR *)consistent;				padapter->dev[zz][z].cdbDma = consistentDma;				consistent += MAX_COMMAND_SIZE;				consistentDma += MAX_COMMAND_SIZE;				}					printk("\nPSI-2000 Intelligent Storage SCSI CONTROLLER: at I/O = %lX  IRQ = %d\n", padapter->basePort, pshost->irq);		printk("Version %s, Compiled %s %s\n\n", PCI2000_VERSION,  __DATE__, __TIME__);		found++;		if ( ++installed < MAXADAPTER )			continue;		break;unregister:;		scsi_unregister (pshost);		found++;		}	NumAdapters = installed;	return installed;	}/**************************************************************** *	Name:	Pci2000_Abort * *	Description:	Process the Abort command from the SCSI manager. * *	Parameters:		SCpnt - Pointer to SCSI command structure. * *	Returns:		Allways snooze. * ****************************************************************/int Pci2000_Abort (Scsi_Cmnd *SCpnt)	{	DEB (printk ("pci2000_abort\n"));	return SCSI_ABORT_SNOOZE;	}/**************************************************************** *	Name:	Pci2000_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 Pci2000_Reset (Scsi_Cmnd *SCpnt, unsigned int reset_flags)	{	return SCSI_RESET_PUNT;	}/**************************************************************** *	Name:	Pci2000_Release * *	Description:	Release resources allocated for a single each adapter. * *	Parameters:		pshost - Pointer to SCSI command structure. * *	Returns:		zero. * ****************************************************************/int Pci2000_Release (struct Scsi_Host *pshost)	{    PADAPTER2000	padapter = HOSTDATA (pshost);	if ( padapter->irqOwned )		free_irq (pshost->irq, padapter);	pci_free_consistent (padapter->pdev, consistentLen, padapter->dev[0][0].scatGath, padapter->dev[0][0].scatGathDma);	release_region (pshost->io_port, pshost->n_io_port);    scsi_unregister(pshost);    return 0;	}#include "sd.h"/**************************************************************** *	Name:	Pci2000_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 Pci2000_BiosParam (Scsi_Disk *disk, kdev_t dev, int geom[])	{	PADAPTER2000	    padapter;	padapter = HOSTDATA(disk->device->host);	if ( WaitReady (padapter) )		return 0;	outb_p (disk->device->id, padapter->mb0);	outb_p (CMD_GET_PARMS, padapter->cmd);	if ( WaitReady (padapter) )		return 0;	geom[0] = inb_p (padapter->mb2 + 3);	geom[1] = inb_p (padapter->mb2 + 2);	geom[2] = inw_p (padapter->mb2);	return 0;	}/* Eventually this will go into an include file, but this will be later */static Scsi_Host_Template driver_template = PCI2000;#include "scsi_module.c"

⌨️ 快捷键说明

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