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

📄 nsp_cs.c

📁 linux-2.6.15.6
💻 C
📖 第 1 页 / 共 4 页
字号:
		/* attention assert */		//nsp_dbg(NSP_DEBUG_INTR, "attention assert");		data->SelectionTimeOut = 0;		tmpSC->SCp.phase       = PH_SELECTED;		nsp_index_write(base, SCSIBUSCTRL, SCSI_ATN);		udelay(1);		nsp_index_write(base, SCSIBUSCTRL, SCSI_ATN | AUTODIRECTION | ACKENB);		return IRQ_HANDLED;		break;	case PH_RESELECT:		//nsp_dbg(NSP_DEBUG_INTR, "phase reselect");		// *sync_neg = SYNC_NOT_YET;		if ((phase & BUSMON_PHASE_MASK) != BUSPHASE_MESSAGE_IN) {			tmpSC->result	= DID_ABORT << 16;			nsp_scsi_done(tmpSC);			return IRQ_HANDLED;		}		/* fall thru */	default:		if ((irq_status & (IRQSTATUS_SCSI | IRQSTATUS_FIFO)) == 0) {			return IRQ_HANDLED;		}		break;	}	/*	 * SCSI sequencer	 */	//nsp_dbg(NSP_DEBUG_INTR, "start scsi seq");	/* normal disconnect */	if (((tmpSC->SCp.phase == PH_MSG_IN) || (tmpSC->SCp.phase == PH_MSG_OUT)) &&	    (irq_phase & LATCHED_BUS_FREE) != 0 ) {		nsp_dbg(NSP_DEBUG_INTR, "normal disconnect irq_status=0x%x, phase=0x%x, irq_phase=0x%x", irq_status, phase, irq_phase);		//*sync_neg       = SYNC_NOT_YET;		if ((tmpSC->SCp.Message == MSG_COMMAND_COMPLETE)) {     /* all command complete and return status */			tmpSC->result = (DID_OK		             << 16) |					((tmpSC->SCp.Message & 0xff) <<  8) |					((tmpSC->SCp.Status  & 0xff) <<  0);			nsp_dbg(NSP_DEBUG_INTR, "command complete result=0x%x", tmpSC->result);			nsp_scsi_done(tmpSC);			return IRQ_HANDLED;		}		return IRQ_HANDLED;	}	/* check unexpected bus free state */	if (phase == 0) {		nsp_msg(KERN_DEBUG, "unexpected bus free. irq_status=0x%x, phase=0x%x, irq_phase=0x%x", irq_status, phase, irq_phase);		*sync_neg       = SYNC_NG;		tmpSC->result   = DID_ERROR << 16;		nsp_scsi_done(tmpSC);		return IRQ_HANDLED;	}	switch (phase & BUSMON_PHASE_MASK) {	case BUSPHASE_COMMAND:		nsp_dbg(NSP_DEBUG_INTR, "BUSPHASE_COMMAND");		if ((phase & BUSMON_REQ) == 0) {			nsp_dbg(NSP_DEBUG_INTR, "REQ == 0");			return IRQ_HANDLED;		}		tmpSC->SCp.phase = PH_COMMAND;		nsp_nexus(tmpSC);		/* write scsi command */		nsp_dbg(NSP_DEBUG_INTR, "cmd_len=%d", tmpSC->cmd_len);		nsp_index_write(base, COMMANDCTRL, CLEAR_COMMAND_POINTER);		for (i = 0; i < tmpSC->cmd_len; i++) {			nsp_index_write(base, COMMANDDATA, tmpSC->cmnd[i]);		}		nsp_index_write(base, COMMANDCTRL, CLEAR_COMMAND_POINTER | AUTO_COMMAND_GO);		break;	case BUSPHASE_DATA_OUT:		nsp_dbg(NSP_DEBUG_INTR, "BUSPHASE_DATA_OUT");		tmpSC->SCp.phase        = PH_DATA;		tmpSC->SCp.have_data_in = IO_OUT;		nsp_pio_write(tmpSC);		break;	case BUSPHASE_DATA_IN:		nsp_dbg(NSP_DEBUG_INTR, "BUSPHASE_DATA_IN");		tmpSC->SCp.phase        = PH_DATA;		tmpSC->SCp.have_data_in = IO_IN;		nsp_pio_read(tmpSC);		break;	case BUSPHASE_STATUS:		nsp_dataphase_bypass(tmpSC);		nsp_dbg(NSP_DEBUG_INTR, "BUSPHASE_STATUS");		tmpSC->SCp.phase = PH_STATUS;		tmpSC->SCp.Status = nsp_index_read(base, SCSIDATAWITHACK);		nsp_dbg(NSP_DEBUG_INTR, "message=0x%x status=0x%x", tmpSC->SCp.Message, tmpSC->SCp.Status);		break;	case BUSPHASE_MESSAGE_OUT:		nsp_dbg(NSP_DEBUG_INTR, "BUSPHASE_MESSAGE_OUT");		if ((phase & BUSMON_REQ) == 0) {			goto timer_out;		}		tmpSC->SCp.phase = PH_MSG_OUT;		//*sync_neg = SYNC_NOT_YET;		data->MsgLen = i = 0;		data->MsgBuffer[i] = IDENTIFY(TRUE, lun); i++;		if (*sync_neg == SYNC_NOT_YET) {			data->Sync[target].SyncPeriod = 0;			data->Sync[target].SyncOffset = 0;			/**/			data->MsgBuffer[i] = MSG_EXTENDED; i++;			data->MsgBuffer[i] = 3;            i++;			data->MsgBuffer[i] = MSG_EXT_SDTR; i++;			data->MsgBuffer[i] = 0x0c;         i++;			data->MsgBuffer[i] = 15;           i++;			/**/		}		data->MsgLen = i;		nsp_analyze_sdtr(tmpSC);		show_message(data);		nsp_message_out(tmpSC);		break;	case BUSPHASE_MESSAGE_IN:		nsp_dataphase_bypass(tmpSC);		nsp_dbg(NSP_DEBUG_INTR, "BUSPHASE_MESSAGE_IN");		if ((phase & BUSMON_REQ) == 0) {			goto timer_out;		}		tmpSC->SCp.phase = PH_MSG_IN;		nsp_message_in(tmpSC);		/**/		if (*sync_neg == SYNC_NOT_YET) {			//nsp_dbg(NSP_DEBUG_INTR, "sync target=%d,lun=%d",target,lun);			if (data->MsgLen       >= 5            &&			    data->MsgBuffer[0] == MSG_EXTENDED &&			    data->MsgBuffer[1] == 3            &&			    data->MsgBuffer[2] == MSG_EXT_SDTR ) {				data->Sync[target].SyncPeriod = data->MsgBuffer[3];				data->Sync[target].SyncOffset = data->MsgBuffer[4];				//nsp_dbg(NSP_DEBUG_INTR, "sync ok, %d %d", data->MsgBuffer[3], data->MsgBuffer[4]);				*sync_neg = SYNC_OK;			} else {				data->Sync[target].SyncPeriod = 0;				data->Sync[target].SyncOffset = 0;				*sync_neg = SYNC_NG;			}			nsp_analyze_sdtr(tmpSC);		}		/**/		/* search last messeage byte */		tmp = -1;		for (i = 0; i < data->MsgLen; i++) {			tmp = data->MsgBuffer[i];			if (data->MsgBuffer[i] == MSG_EXTENDED) {				i += (1 + data->MsgBuffer[i+1]);			}		}		tmpSC->SCp.Message = tmp;		nsp_dbg(NSP_DEBUG_INTR, "message=0x%x len=%d", tmpSC->SCp.Message, data->MsgLen);		show_message(data);		break;	case BUSPHASE_SELECT:	default:		nsp_dbg(NSP_DEBUG_INTR, "BUSPHASE other");		break;	}	//nsp_dbg(NSP_DEBUG_INTR, "out");	return IRQ_HANDLED; 	timer_out:	nsp_start_timer(tmpSC, 1000/102);	return IRQ_HANDLED;}#ifdef NSP_DEBUG#include "nsp_debug.c"#endif	/* NSP_DEBUG *//*----------------------------------------------------------------*//* look for ninja3 card and init if found			  *//*----------------------------------------------------------------*/static struct Scsi_Host *nsp_detect(struct scsi_host_template *sht){	struct Scsi_Host *host;	/* registered host structure */	nsp_hw_data *data_b = &nsp_data_base, *data;	nsp_dbg(NSP_DEBUG_INIT, "this_id=%d", sht->this_id);#if (LINUX_VERSION_CODE > KERNEL_VERSION(2,5,73))	host = scsi_host_alloc(&nsp_driver_template, sizeof(nsp_hw_data));#else	host = scsi_register(sht, sizeof(nsp_hw_data));#endif	if (host == NULL) {		nsp_dbg(NSP_DEBUG_INIT, "host failed");		return NULL;	}	memcpy(host->hostdata, data_b, sizeof(nsp_hw_data));	data = (nsp_hw_data *)host->hostdata;	data->ScsiInfo->host = host;#ifdef NSP_DEBUG	data->CmdId = 0;#endif	nsp_dbg(NSP_DEBUG_INIT, "irq=%d,%d", data_b->IrqNumber, ((nsp_hw_data *)host->hostdata)->IrqNumber);	host->unique_id	  = data->BaseAddress;	host->io_port	  = data->BaseAddress;	host->n_io_port	  = data->NumAddress;	host->irq	  = data->IrqNumber;	host->base        = data->MmioAddress;	spin_lock_init(&(data->Lock));	snprintf(data->nspinfo,		 sizeof(data->nspinfo),		 "NinjaSCSI-3/32Bi Driver $Revision: 1.23 $ IO:0x%04lx-0x%04lx MMIO(virt addr):0x%04lx IRQ:%02d",		 host->io_port, host->io_port + host->n_io_port - 1,		 host->base,		 host->irq);	sht->name	  = data->nspinfo;	nsp_dbg(NSP_DEBUG_INIT, "end");	return host; /* detect done. */}#if (LINUX_VERSION_CODE < KERNEL_VERSION(2,5,0))static int nsp_detect_old(struct scsi_host_template *sht){	if (nsp_detect(sht) == NULL) {		return 0;	} else {		//MOD_INC_USE_COUNT;		return 1;	}}static int nsp_release_old(struct Scsi_Host *shpnt){	//nsp_hw_data *data = (nsp_hw_data *)shpnt->hostdata;	/* PCMCIA Card Service dose same things below. */	/* So we do nothing.                           */	//if (shpnt->irq) {	//	free_irq(shpnt->irq, data->ScsiInfo);	//}	//if (shpnt->io_port) {	//	release_region(shpnt->io_port, shpnt->n_io_port);	//}	//MOD_DEC_USE_COUNT;	return 0;}#endif/*----------------------------------------------------------------*//* return info string						  *//*----------------------------------------------------------------*/static const char *nsp_info(struct Scsi_Host *shpnt){	nsp_hw_data *data = (nsp_hw_data *)shpnt->hostdata;	return data->nspinfo;}#undef SPRINTF#define SPRINTF(args...) \        do { \		if(length > (pos - buffer)) { \			pos += snprintf(pos, length - (pos - buffer) + 1, ## args); \			nsp_dbg(NSP_DEBUG_PROC, "buffer=0x%p pos=0x%p length=%d %d\n", buffer, pos, length,  length - (pos - buffer));\		} \	} while(0)static intnsp_proc_info(#if (LINUX_VERSION_CODE > KERNEL_VERSION(2,5,73))	struct Scsi_Host *host,#endif	char  *buffer,	char **start,	off_t  offset,	int    length,#if !(LINUX_VERSION_CODE > KERNEL_VERSION(2,5,73))	int    hostno,#endif	int    inout){	int id;	char *pos = buffer;	int thislength;	int speed;	unsigned long flags;	nsp_hw_data *data;#if !(LINUX_VERSION_CODE > KERNEL_VERSION(2,5,73))	struct Scsi_Host *host;#else	int hostno;#endif	if (inout) {		return -EINVAL;	}#if (LINUX_VERSION_CODE > KERNEL_VERSION(2,5,73))	hostno = host->host_no;#else	/* search this HBA host */	host = scsi_host_hn_get(hostno);	if (host == NULL) {		return -ESRCH;	}#endif	data = (nsp_hw_data *)host->hostdata;	SPRINTF("NinjaSCSI status\n\n");	SPRINTF("Driver version:        $Revision: 1.23 $\n");	SPRINTF("SCSI host No.:         %d\n",          hostno);	SPRINTF("IRQ:                   %d\n",          host->irq);	SPRINTF("IO:                    0x%lx-0x%lx\n", host->io_port, host->io_port + host->n_io_port - 1);	SPRINTF("MMIO(virtual address): 0x%lx-0x%lx\n", host->base, host->base + data->MmioLength - 1);	SPRINTF("sg_tablesize:          %d\n",          host->sg_tablesize);	SPRINTF("burst transfer mode:   ");	switch (nsp_burst_mode) {	case BURST_IO8:		SPRINTF("io8");		break;	case BURST_IO32:		SPRINTF("io32");		break;	case BURST_MEM32:		SPRINTF("mem32");		break;	default:		SPRINTF("???");		break;	}	SPRINTF("\n");	spin_lock_irqsave(&(data->Lock), flags);	SPRINTF("CurrentSC:             0x%p\n\n",      data->CurrentSC);	spin_unlock_irqrestore(&(data->Lock), flags);	SPRINTF("SDTR status\n");	for(id = 0; id < ARRAY_SIZE(data->Sync); id++) {		SPRINTF("id %d: ", id);		if (id == host->this_id) {			SPRINTF("----- NinjaSCSI-3 host adapter\n");			continue;		}		switch(data->Sync[id].SyncNegotiation) {		case SYNC_OK:			SPRINTF(" sync");			break;		case SYNC_NG:			SPRINTF("async");			break;		case SYNC_NOT_YET:			SPRINTF(" none");			break;		default:			SPRINTF("?????");			break;		}		if (data->Sync[id].SyncPeriod != 0) {			speed = 1000000 / (data->Sync[id].SyncPeriod * 4);			SPRINTF(" transfer %d.%dMB/s, offset %d",				speed / 1000,				speed % 1000,				data->Sync[id].SyncOffset				);		}		SPRINTF("\n");	}	thislength = pos - (buffer + offset);	if(thislength < 0) {		*start = NULL;                return 0;        }	thislength = min(thislength, length);	*start = buffer + offset;	return thislength;}#undef SPRINTF/*---------------------------------------------------------------*//* error handler                                                 *//*---------------------------------------------------------------*//*static int nsp_eh_abort(Scsi_Cmnd *SCpnt){	nsp_dbg(NSP_DEBUG_BUSRESET, "SCpnt=0x%p", SCpnt);	return nsp_eh_bus_reset(SCpnt);}*/static int nsp_bus_reset(nsp_hw_data *data){	unsigned int base = data->BaseAddress;	int	     i;	nsp_write(base, IRQCONTROL, IRQCONTROL_ALLMASK);	nsp_index_write(base, SCSIBUSCTRL, SCSI_RST);	mdelay(100); /* 100ms */	nsp_index_write(base, SCSIBUSCTRL, 0);	for(i = 0; i < 5; i++) {		nsp_index_read(base, IRQPHASESENCE); /* dummy read */	}	nsphw_init_sync(data);	nsp_write(base, IRQCONTROL, IRQCONTROL_ALLCLEAR);	return SUCCESS;}static int nsp_eh_bus_reset(Scsi_Cmnd *SCpnt){	nsp_hw_data *data = (nsp_hw_data *)SCpnt->device->host->hostdata;	nsp_dbg(NSP_DEBUG_BUSRESET, "SCpnt=0x%p", SCpnt);	return nsp_bus_reset(data);}static int nsp_eh_host_reset(Scsi_Cmnd *SCpnt){	nsp_hw_data *data = (nsp_hw_data *)SCpnt->device->host->hostdata;	nsp_dbg(NSP_DEBUG_BUSRESET, "in");	nsphw_init(data);	return SUCCESS;}/**********************************************************************  PCMCIA functions**********************************************************************//*======================================================================    nsp_cs_attach() creates an "instance" of the driver, allocating    local data structures for one device.  The device is registered    with Card Services.    The dev_link structure is initialized, but we don't actually    configure the card at this point -- we wait until we receive a    card insertion event.======================================================================*/static dev_link_t *nsp_cs_attach(void){	scsi_info_t  *info;	client_reg_t  client_reg;	dev_link_t   *link;	int	      ret;	nsp_hw_data  *data = &nsp_data_base;	nsp_dbg(NSP_DEBUG_INIT, "in");	/* Create new SCSI device */	info = kmalloc(sizeof(*info), GFP_KERNEL);	if (info == NULL) { return NULL; }	memset(info, 0, sizeof(*info));	link = &info->link;	link->priv = info;	data->ScsiInfo = info;	nsp_dbg(NSP_DEBUG_INIT, "info=0x%p", info);	/* The io structure describes IO port mapping */	link->io.NumPorts1	 = 0x10;	link->io.Attributes1	 = IO_DATA_PATH_WIDTH_AUTO;	link->io.IOAddrLines	 = 10;	/* not used */	/* Interrupt setup */	link->irq.Attributes	 = IRQ_TYPE_EXCLUSIVE | IRQ_HANDLE_PRESENT;	link->irq.IRQInfo1	 = IRQ_LEVEL_ID;	/* Interrupt handler */	link->irq.Handler	 = &nspintr;	link->irq.Instance       = info;	link->irq.Attributes     |= (SA_SHIRQ | SA_SAMPLE_RANDOM);	/* General socket configuration */	link->conf.Attributes	 = CONF_ENABLE_IRQ;	link->conf.Vcc		 = 50;	link->conf.IntType	 = INT_MEMORY_AND_IO;	link->conf.Present	 = PRESENT_OPTION;	/* Register with Card Services */	link->next               = dev_list;	dev_list                 = link;	client_reg.dev_info	 = &dev_info;	client_reg.Version	 = 0x0210;

⌨️ 快捷键说明

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