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

📄 aha152x.c

📁 Linux内核源代码 为压缩文件 是<<Linux内核>>一书中的源代码
💻 C
📖 第 1 页 / 共 5 页
字号:
			setup[setup_count].io_port     = aha152x[0];			setup[setup_count].irq         = aha152x[1];			setup[setup_count].scsiid      = aha152x[2];			setup[setup_count].reconnect   = aha152x[3];			setup[setup_count].parity      = aha152x[4];			setup[setup_count].synchronous = aha152x[5];			setup[setup_count].delay       = aha152x[6];			setup[setup_count].ext_trans   = aha152x[7];#if defined(AHA152X_DEBUG)			setup[setup_count].debug       = aha152x[8];#endif	  	} else if(io[0]!=0 || irq[0]!=0) {			if(io[0]!=0)  setup[setup_count].io_port = io[0];			if(irq[0]!=0) setup[setup_count].irq     = irq[0];	    		setup[setup_count].scsiid      = scsiid[0];	    		setup[setup_count].reconnect   = reconnect[0];	    		setup[setup_count].parity      = parity[0];	    		setup[setup_count].synchronous = sync[0];	    		setup[setup_count].delay       = delay[0];	    		setup[setup_count].ext_trans   = exttrans[0];#if defined(AHA152X_DEBUG)			setup[setup_count].debug       = debug[0];#endif		}          	if (checksetup(&setup[setup_count]))			setup_count++;		else			printk(KERN_ERR "aha152x: invalid module params io=0x%x, irq=%d,scsiid=%d,reconnect=%d,parity=%d,sync=%d,delay=%d,exttrans=%d\n",			       setup[setup_count].io_port,			       setup[setup_count].irq,			       setup[setup_count].scsiid,			       setup[setup_count].reconnect,			       setup[setup_count].parity,			       setup[setup_count].synchronous,			       setup[setup_count].delay,			       setup[setup_count].ext_trans);	}	if (setup_count < 2 && (aha152x1[0]!=0 || io[1]!=0 || irq[1]!=0)) {		if(aha152x1[0]!=0) {			setup[setup_count].conf        = "";			setup[setup_count].io_port     = aha152x1[0];			setup[setup_count].irq         = aha152x1[1];			setup[setup_count].scsiid      = aha152x1[2];			setup[setup_count].reconnect   = aha152x1[3];			setup[setup_count].parity      = aha152x1[4];			setup[setup_count].synchronous = aha152x1[5];			setup[setup_count].delay       = aha152x1[6];			setup[setup_count].ext_trans   = aha152x1[7];#if defined(AHA152X_DEBUG)			setup[setup_count].debug       = aha152x1[8];#endif	  	} else if(io[1]!=0 || irq[1]!=0) {			if(io[1]!=0)  setup[setup_count].io_port = io[1];			if(irq[1]!=0) setup[setup_count].irq     = irq[1];	    		setup[setup_count].scsiid      = scsiid[1];	    		setup[setup_count].reconnect   = reconnect[1];	    		setup[setup_count].parity      = parity[1];	    		setup[setup_count].synchronous = sync[1];	    		setup[setup_count].delay       = delay[1];	    		setup[setup_count].ext_trans   = exttrans[1];#if defined(AHA152X_DEBUG)			setup[setup_count].debug       = debug[1];#endif		}		if (checksetup(&setup[setup_count]))			setup_count++;		else			printk(KERN_ERR "aha152x: invalid module params io=0x%x, irq=%d,scsiid=%d,reconnect=%d,parity=%d,sync=%d,delay=%d,exttrans=%d\n",			       setup[setup_count].io_port,			       setup[setup_count].irq,			       setup[setup_count].scsiid,			       setup[setup_count].reconnect,			       setup[setup_count].parity,			       setup[setup_count].synchronous,			       setup[setup_count].delay,			       setup[setup_count].ext_trans);	}#endif#if defined(AUTOCONF)	if (setup_count < 2) {#if !defined(SKIP_BIOSTEST)		ok = 0;		for (i = 0; i < ADDRESS_COUNT && !ok; i++)			for (j = 0; (j < SIGNATURE_COUNT) && !ok; j++)				ok = isa_check_signature(addresses[i] + signatures[j].sig_offset,								signatures[j].signature, signatures[j].sig_length);		if (!ok && setup_count == 0)			return 0;		printk(KERN_INFO "aha152x: BIOS test: passed, ");#else		printk(KERN_INFO "aha152x: ");#endif				/* !SKIP_BIOSTEST */		ok = 0;		for (i = 0; i < PORT_COUNT && setup_count < 2; i++) {			if ((setup_count == 1) && (setup[0].io_port == ports[i]))				continue;			if (aha152x_porttest(ports[i])) {				ok++;				setup[setup_count].io_port = ports[i];				setup[setup_count].tc1550  = 0;				conf.cf_port =				    (GETPORT(ports[i] + O_PORTA) << 8) + GETPORT(ports[i] + O_PORTB);				setup[setup_count].irq = IRQ_MIN + conf.cf_irq;				setup[setup_count].scsiid = conf.cf_id;				setup[setup_count].reconnect = conf.cf_tardisc;				setup[setup_count].parity = !conf.cf_parity;				setup[setup_count].synchronous = conf.cf_syncneg;				setup[setup_count].delay = DELAY_DEFAULT;				setup[setup_count].ext_trans = 0;#if defined(AHA152X_DEBUG)				setup[setup_count].debug = DEBUG_DEFAULT;#endif				setup_count++;			} else if (tc1550_porttest(ports[i])) {				ok++;				setup[setup_count].io_port = ports[i];				setup[setup_count].tc1550  = 1;				conf.cf_port =				    (GETPORT(ports[i] + O_PORTA) << 8) + GETPORT(ports[i] + O_PORTB);				setup[setup_count].irq = IRQ_MIN + conf.cf_irq;				setup[setup_count].scsiid = conf.cf_id;				setup[setup_count].reconnect = conf.cf_tardisc;				setup[setup_count].parity = !conf.cf_parity;				setup[setup_count].synchronous = conf.cf_syncneg;				setup[setup_count].delay = DELAY_DEFAULT;				setup[setup_count].ext_trans = 0;#if defined(AHA152X_DEBUG)				setup[setup_count].debug = DEBUG_DEFAULT;#endif				setup_count++;			}		}		if (ok)			printk("auto configuration: ok, ");	}#endif	printk("detected %d controller(s)\n", setup_count);	for (i=0; i<setup_count; i++) {		struct Scsi_Host *shpnt;		aha152x_host[setup[i].irq - IRQ_MIN] = shpnt =		    scsi_register(tpnt, sizeof(struct aha152x_hostdata));		if(!shpnt) {			printk(KERN_ERR "aha152x: scsi_register failed\n");			continue;		}		registered_count++;		shpnt->io_port   = setup[i].io_port;		shpnt->n_io_port = IO_RANGE;		shpnt->irq       = setup[i].irq;		if(!setup[i].tc1550) {			HOSTIOPORT0 = setup[i].io_port;			HOSTIOPORT1 = setup[i].io_port;		} else {			HOSTIOPORT0 = setup[i].io_port+0x10;			HOSTIOPORT1 = setup[i].io_port-0x10;		}		ISSUE_SC	= 0;		CURRENT_SC	= 0;		DONE_SC		= 0;		DISCONNECTED_SC	= 0;		QLOCK		= SPIN_LOCK_UNLOCKED;		STATE		= 0;		PREVSTATE	= 0;		LASTSTATE	= 0;		MSGILEN		= 0;		MSGOLEN		= 0;		RECONNECT	= setup[i].reconnect;		SYNCHRONOUS	= setup[i].synchronous;		PARITY		= setup[i].parity;		DELAY		= setup[i].delay;		EXT_TRANS	= setup[i].ext_trans;#if defined(AHA152X_DEBUG)		HOSTDATA(shpnt)->debug = setup[i].debug;#endif		HOSTDATA(shpnt)->in_intr = 0;		HOSTDATA(shpnt)->commands = 0;#if defined(AHA152X_STAT)		HOSTDATA(shpnt)->total_commands=0;		HOSTDATA(shpnt)->disconnections=0;		HOSTDATA(shpnt)->busfree_without_any_action=0;		HOSTDATA(shpnt)->busfree_without_old_command=0;		HOSTDATA(shpnt)->busfree_without_new_command=0;		HOSTDATA(shpnt)->busfree_without_done_command=0;		HOSTDATA(shpnt)->busfree_with_check_condition=0;		for (j = idle; j<maxstate; j++) {			HOSTDATA(shpnt)->count[j]=0;			HOSTDATA(shpnt)->count_trans[j]=0;			HOSTDATA(shpnt)->time[j]=0;		}#endif		for (j = 0; j < 8; j++) {			HOSTDATA(shpnt)->syncrate[j] = 0;			HOSTDATA(shpnt)->syncneg[j] = 0;		}		SETPORT(SCSIID, setup[i].scsiid << 4);		shpnt->this_id = setup[i].scsiid;		if (setup[i].reconnect)			shpnt->can_queue = AHA152X_MAXQUEUE;#if 0		if(!shpnt->hostt->use_new_eh_code) {#endif			/* RESET OUT */			printk("aha152x: resetting bus...\n");			SETPORT(SCSISEQ, SCSIRSTO);			mdelay(256);			SETPORT(SCSISEQ, 0);			mdelay(DELAY);#if 0		}#endif		reset_ports(shpnt);		printk(KERN_INFO		       "aha152x%d%s: "		       "vital data: rev=%x, "		       "io=0x%03lx (0x%03lx/0x%03lx), "		       "irq=%d, "		       "scsiid=%d, "		       "reconnect=%s, "		       "parity=%s, "		       "synchronous=%s, "		       "delay=%d, "		       "extended translation=%s\n",		       HOSTNO, setup[i].tc1550 ? " (tc1550 mode)" : "",		       GETPORT(REV) & 0x7,		       shpnt->io_port, HOSTIOPORT0, HOSTIOPORT1,		       shpnt->irq,		       shpnt->this_id,		       RECONNECT ? "enabled" : "disabled",		       PARITY ? "enabled" : "disabled",		       SYNCHRONOUS ? "enabled" : "disabled",		       DELAY,		       EXT_TRANS ? "enabled" : "disabled");		request_region(shpnt->io_port, IO_RANGE, "aha152x");		/* not expecting any interrupts */		SETPORT(SIMODE0, 0);		SETPORT(SIMODE1, 0);		ok = request_irq(shpnt->irq, swintr, SA_INTERRUPT, "aha152x", shpnt);		if (ok < 0) {			if (ok==-EINVAL)				printk(KERN_ERR "aha152x%d: bad IRQ %d.\n", HOSTNO, shpnt->irq);			else if(ok==-EBUSY)				printk(KERN_ERR "aha152x%d: IRQ %d already in use.\n", HOSTNO, shpnt->irq);			else				printk(KERN_ERR "aha152x%d: Unexpected error code %d on requesting IRQ %d.\n", HOSTNO, ok, shpnt->irq);			printk(KERN_ERR "aha152x%d: driver needs an IRQ.\n", HOSTNO);			scsi_unregister(shpnt);			registered_count--;			release_region(shpnt->io_port, IO_RANGE);			aha152x_host[shpnt->irq - IRQ_MIN] = 0;			shpnt = 0;			continue;		}		HOSTDATA(shpnt)->swint = 0;		printk(KERN_INFO "aha152x%d: trying software interrupt, ", HOSTNO);		SETPORT(DMACNTRL0, SWINT|INTEN);		spin_unlock_irq(&io_request_lock);		mdelay(1000);		spin_lock_irq(&io_request_lock);		free_irq(shpnt->irq, shpnt);		if (!HOSTDATA(shpnt)->swint) {			if (TESTHI(DMASTAT, INTSTAT)) {				printk("lost.\n");			} else {				printk("failed.\n");			}			printk(KERN_ERR "aha152x%d: IRQ %d possibly wrong.  Please verify.\n", HOSTNO, shpnt->irq);			registered_count--;			release_region(shpnt->io_port, IO_RANGE);			aha152x_host[shpnt->irq - IRQ_MIN] = 0;			scsi_unregister(shpnt);			shpnt=NULL;			continue;		}		printk("ok.\n");		SETPORT(DMACNTRL0, INTEN);		/* clear interrupts */		SETPORT(SSTAT0, 0x7f);		SETPORT(SSTAT1, 0xef);		if (request_irq(shpnt->irq, intr, SA_INTERRUPT, "aha152x", shpnt) < 0) {			printk(KERN_ERR "aha152x%d: failed to reassign interrupt.\n", HOSTNO);			scsi_unregister(shpnt);			registered_count--;			release_region(shpnt->io_port, IO_RANGE);			shpnt = aha152x_host[shpnt->irq - IRQ_MIN] = 0;			continue;		}	}	return registered_count>0;}int aha152x_release(struct Scsi_Host *shpnt){	if (shpnt->irq)		free_irq(shpnt->irq, shpnt);	if (shpnt->io_port)		release_region(shpnt->io_port, IO_RANGE);	scsi_unregister(shpnt);	return 0;}/* * setup controller to generate interrupts depending * on current state (lock has to be acquired) * */ static int setup_expected_interrupts(struct Scsi_Host *shpnt){	ASSERT_LOCK(&QLOCK,1);	if(CURRENT_SC) {		CURRENT_SC->SCp.phase |= 1 << 16;			if(CURRENT_SC->SCp.phase & selecting) {			DPRINTK(debug_intr, DEBUG_LEAD "expecting: (seldo) (seltimo) (seldi)\n", CMDINFO(CURRENT_SC));			SETPORT(SSTAT1, SELTO);			SETPORT(SIMODE0, ENSELDO | (DISCONNECTED_SC ? ENSELDI : 0));			SETPORT(SIMODE1, ENSELTIMO);		} else {			DPRINTK(debug_intr, DEBUG_LEAD "expecting: (phase change) (busfree) %s\n", CMDINFO(CURRENT_SC), CURRENT_SC->SCp.phase & spiordy ? "(spiordy)" : "");			SETPORT(SIMODE0, (CURRENT_SC->SCp.phase & spiordy) ? ENSPIORDY : 0);			SETPORT(SIMODE1, ENPHASEMIS | ENSCSIRST | ENSCSIPERR | ENBUSFREE); 		}	} else if(STATE==seldi) {		DPRINTK(debug_intr, DEBUG_LEAD "expecting: (phase change) (identify)\n", CMDINFO(CURRENT_SC));		SETPORT(SIMODE0, 0);		SETPORT(SIMODE1, ENPHASEMIS | ENSCSIRST | ENSCSIPERR | ENBUSFREE); 	} else {		DPRINTK(debug_intr, DEBUG_LEAD "expecting: %s %s\n",			CMDINFO(CURRENT_SC),			DISCONNECTED_SC ? "(reselection)" : "",			ISSUE_SC ? "(busfree)" : "");		SETPORT(SIMODE0, DISCONNECTED_SC ? ENSELDI : 0);		SETPORT(SIMODE1, ENSCSIRST | ( (ISSUE_SC||DONE_SC) ? ENBUSFREE : 0));	}	if(!HOSTDATA(shpnt)->in_intr)		SETBITS(DMACNTRL0, INTEN);	return TESTHI(DMASTAT, INTSTAT);}/*  *  Queue a command and setup interrupts for a free bus. */int aha152x_internal_queue(Scsi_Cmnd *SCpnt, struct semaphore *sem, int phase, Scsi_Cmnd *done_SC, void (*done)(Scsi_Cmnd *)){	struct Scsi_Host *shpnt = SCpnt->host;	unsigned long flags;#if defined(AHA152X_DEBUG)	if (HOSTDATA(shpnt)->debug & debug_queue) {		printk(INFO_LEAD "queue: cmd_len=%d pieces=%d size=%u cmnd=",		       CMDINFO(SCpnt), SCpnt->cmd_len, SCpnt->use_sg, SCpnt->request_bufflen);		print_command(SCpnt->cmnd);	}#endif	SCpnt->scsi_done	= done;	SCpnt->resid 		= SCpnt->request_bufflen;	SCpnt->SCp.phase	= not_issued | phase;	SCpnt->SCp.Status	= CHECK_CONDITION;	SCpnt->SCp.Message	= 0;	SCpnt->SCp.have_data_in	= 0;	SCpnt->SCp.sent_command	= 0;	SCpnt->host_scribble    = kmalloc(sizeof(struct aha152x_scdata), GFP_ATOMIC);	if(!SCpnt->host_scribble) {		printk(ERR_LEAD "allocation failed\n", CMDINFO(SCpnt));		return FAILED;	}	SCNEXT(SCpnt)		= 0;	SCDONE(SCpnt)		= done_SC;	SCSEM(SCpnt)		= sem;	/* setup scratch area	   SCp.ptr              : buffer pointer	   SCp.this_residual    : buffer length	   SCp.buffer           : next buffer	   SCp.buffers_residual : left buffers in list	   SCp.phase            : current state of the command */	if (SCpnt->use_sg) {		SCpnt->SCp.buffer           = (struct scatterlist *) SCpnt->request_buffer;		SCpnt->SCp.ptr              = SCpnt->SCp.buffer->address;		SCpnt->SCp.this_residual    = SCpnt->SCp.buffer->length;		SCpnt->SCp.buffers_residual = SCpnt->use_sg - 1;	} else {		SCpnt->SCp.ptr              = (char *) SCpnt->request_buffer;		SCpnt->SCp.this_residual    = SCpnt->request_bufflen;		SCpnt->SCp.buffer           = NULL;		SCpnt->SCp.buffers_residual = 0;	}	DO_LOCK(flags);#if defined(AHA152X_STAT)	HOSTDATA(shpnt)->total_commands++;#endif	/* Turn led on, when this is the first command. */	HOSTDATA(shpnt)->commands++;	if (HOSTDATA(shpnt)->commands==1)		SETPORT(PORTA, 1);	append_SC(&ISSUE_SC, SCpnt);	if(!HOSTDATA(shpnt)->in_intr)		setup_expected_interrupts(shpnt);	DO_UNLOCK(flags);	return 0;}int aha152x_queue(Scsi_Cmnd *SCpnt, void (*done)(Scsi_Cmnd *)){	if(*SCpnt->cmnd == REQUEST_SENSE) {		SCpnt->result = 0;		done(SCpnt);		return SUCCESS;	}	return aha152x_internal_queue(SCpnt, 0, 0, 0, done);}/* *  run a command * */void internal_done(Scsi_Cmnd *SCpnt){#if 0	struct Scsi_Host *shpnt = SCpnt->host;	DPRINTK(debug_eh, INFO_LEAD "internal_done called\n", CMDINFO(SCpnt));#endif	if(SCSEM(SCpnt))		up(SCSEM(SCpnt));}int aha152x_command(Scsi_Cmnd * SCpnt){	DECLARE_MUTEX_LOCKED(sem);	aha152x_internal_queue(SCpnt, &sem, 0, 0, internal_done);	down(&sem);	return SUCCESS;}

⌨️ 快捷键说明

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