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

📄 aha152x.c

📁 基于组件方式开发操作系统的OSKIT源代码
💻 C
📖 第 1 页 / 共 5 页
字号:
	info_array[2] = disk->capacity / (64 * 32);	/* for disks >1GB do some guessing */	if (info_array[2] >= 1024) {		int info[3];		/* try to figure out the geometry from the partition table */		if (scsicam_bios_param(disk, dev, info) < 0 ||		    !((info[0] == 64 && info[1] == 32) || (info[0] == 255 && info[1] == 63))) {			if (EXT_TRANS) {				printk("aha152x: unable to verify geometry for disk with >1GB.\n"				"         using extended translation.\n");				info_array[0] = 255;				info_array[1] = 63;				info_array[2] = disk->capacity / (255 * 63);			} else {				printk("aha152x: unable to verify geometry for disk with >1GB.\n"				       "         Using default translation. Please verify yourself.\n"				       "         Perhaps you need to enable extended translation in the driver.\n"				       "         See /usr/src/linux/drivers/scsi/aha152x.c for details.\n");			}		} else {			info_array[0] = info[0];			info_array[1] = info[1];			info_array[2] = info[2];			if (info[0] == 255 && !EXT_TRANS) {				printk("aha152x: current partition table is using extended translation.\n"				       "         using it also, although it's not explicty enabled.\n");			}		}	}#if defined(DEBUG_BIOSPARAM)	if (HOSTDATA(shpnt)->debug & debug_biosparam) {		printk("bios geometry: head=%d, sec=%d, cyl=%d\n",		       info_array[0], info_array[1], info_array[2]);		printk("WARNING: check, if the bios geometry is correct.\n");	}#endif	return 0;}/* *  Internal done function */void aha152x_done(struct Scsi_Host *shpnt, int error){	unsigned long flags;	Scsi_Cmnd *done_SC;#if defined(DEBUG_DONE)	if (HOSTDATA(shpnt)->debug & debug_done) {		printk("\naha152x: done(), ");		disp_ports(shpnt);	}#endif	if (CURRENT_SC) {#if defined(DEBUG_DONE)		if (HOSTDATA(shpnt)->debug & debug_done)			printk("done(%x), ", error);#endif		save_flags(flags);		cli();		done_SC = CURRENT_SC;		CURRENT_SC = NULL;		/* turn led off, when no commands are in the driver */		HOSTDATA(shpnt)->commands--;		if (!HOSTDATA(shpnt)->commands)			SETPORT(PORTA, 0);	/* turn led off */#if defined(DEBUG_QUEUES)		if (HOSTDATA(shpnt)->debug & debug_queues)			printk("ok (%d), ", HOSTDATA(shpnt)->commands);#endif		restore_flags(flags);		SETPORT(SIMODE0, DISCONNECTED_SC ? ENSELDI : 0);		SETPORT(SIMODE1, ISSUE_SC ? ENBUSFREE : 0);#if 0/* Why poll for the BUS FREE phase, when we have setup the interrupt!? */#if defined(DEBUG_PHASES)		if (HOSTDATA(shpnt)->debug & debug_phases)			printk("BUS FREE loop, ");#endif		while (TESTLO(SSTAT1, BUSFREE))			barrier();#if defined(DEBUG_PHASES)		if (HOSTDATA(shpnt)->debug & debug_phases)			printk("BUS FREE\n");#endif#endif		done_SC->result = error;		if (done_SC->scsi_done) {#if defined(DEBUG_DONE)			if (HOSTDATA(shpnt)->debug & debug_done)				printk("calling scsi_done, ");#endif			spin_lock_irqsave(&io_request_lock, flags);			done_SC->scsi_done(done_SC);			spin_unlock_irqrestore(&io_request_lock, flags);#if defined(DEBUG_DONE)			if (HOSTDATA(shpnt)->debug & debug_done)				printk("done returned, ");#endif		} else			panic("aha152x: current_SC->scsi_done() == NULL");	} else		aha152x_panic(shpnt, "done() called outside of command");}static void aha152x_complete(struct Scsi_Host *);static struct tq_struct aha152x_tq;/* *    Run service completions on the card with interrupts enabled. */static void aha152x_run(void){	int i;	for (i = 0; i < IRQS; i++) {		struct Scsi_Host *shpnt = aha152x_host[i];		if (shpnt && HOSTDATA(shpnt)->service) {			HOSTDATA(shpnt)->service = 0;			aha152x_complete(shpnt);		}	}}/* *    Interrupts handler (main routine of the driver) */static void aha152x_intr(int irqno, void *dev_id, struct pt_regs *regs){	struct Scsi_Host *shpnt = aha152x_host[irqno - IRQ_MIN];#if defined(DEBUG_RACE)	enter_driver("intr");#else#if defined(DEBUG_INTR)	if (HOSTDATA(shpnt)->debug & debug_intr)		printk("\naha152x: intr(), ");#endif#endif	if (!shpnt)		panic("aha152x: catched interrupt for unknown controller.\n");	/* no more interrupts from the controller, while we're busy.	   INTEN is restored by the BH handler */	CLRBITS(DMACNTRL0, INTEN);	/* Poke the BH handler */	HOSTDATA(shpnt)->service = 1;	aha152x_tq.routine = (void *) aha152x_run;	queue_task(&aha152x_tq, &tq_immediate);	mark_bh(IMMEDIATE_BH);}static void aha152x_complete(struct Scsi_Host *shpnt){	unsigned int flags;	int done = 0, phase;	/* disconnected target is trying to reconnect.	   Only possible, if we have disconnected nexuses and	   nothing is occupying the bus.	 */	if (TESTHI(SSTAT0, SELDI) &&	    DISCONNECTED_SC &&	    (!CURRENT_SC || (CURRENT_SC->SCp.phase & in_selection))) {		int identify_msg, target, i;		/* Avoid conflicts when a target reconnects		   while we are trying to connect to another. */		if (CURRENT_SC) {#if defined(DEBUG_QUEUES)			if (HOSTDATA(shpnt)->debug & debug_queues)				printk("i+, ");#endif			save_flags(flags);			cli();			append_SC(&ISSUE_SC, CURRENT_SC);			CURRENT_SC = NULL;			restore_flags(flags);		}		/* disable sequences */		SETPORT(SCSISEQ, 0);		SETPORT(SSTAT0, CLRSELDI);		SETPORT(SSTAT1, CLRBUSFREE);#if defined(DEBUG_QUEUES) || defined(DEBUG_PHASES)		if (HOSTDATA(shpnt)->debug & (debug_queues | debug_phases))			printk("reselected, ");#endif		i = GETPORT(SELID) & ~(1 << shpnt->this_id);		target = 0;		if (i == 0)			aha152x_panic(shpnt, "reconnecting target unknown");		for (; (i & 1) == 0; target++, i >>= 1);#if defined(DEBUG_QUEUES)		if (HOSTDATA(shpnt)->debug & debug_queues)			printk("SELID=%02x, target=%d, ", GETPORT(SELID), target);#endif		SETPORT(SCSIID, (shpnt->this_id << OID_) | target);		SETPORT(SCSISEQ, ENRESELI);		if (TESTLO(SSTAT0, SELDI))			aha152x_panic(shpnt, "RESELI failed");		SETPORT(SCSIRATE, HOSTDATA(shpnt)->syncrate[target] & 0x7f);		SETPORT(SCSISIG, P_MSGI);		/* Get identify message */		if ((i = getphase(shpnt)) != P_MSGI) {			printk("target doesn't enter MSGI to identify (phase=%02x)\n", i);			aha152x_panic(shpnt, "unknown lun");		}		SETPORT(SCSISEQ, 0);		SETPORT(SXFRCTL0, CH1);		identify_msg = GETPORT(SCSIBUS);		if (!(identify_msg & IDENTIFY_BASE)) {			printk("target=%d, inbound message (%02x) != IDENTIFY\n",			       target, identify_msg);			aha152x_panic(shpnt, "unknown lun");		}#if defined(DEBUG_QUEUES)		if (HOSTDATA(shpnt)->debug & debug_queues)			printk("identify=%02x, lun=%d, ", identify_msg, identify_msg & 0x3f);#endif		save_flags(flags);		cli();#if defined(DEBUG_QUEUES)		if (HOSTDATA(shpnt)->debug & debug_queues)			printk("d-, ");#endif		CURRENT_SC = remove_SC(&DISCONNECTED_SC, target, identify_msg & 0x3f);		if (!CURRENT_SC) {			printk("lun=%d, ", identify_msg & 0x3f);			aha152x_panic(shpnt, "no disconnected command for that lun");		}		CURRENT_SC->SCp.phase &= ~disconnected;		restore_flags(flags);		make_acklow(shpnt);		if (getphase(shpnt) != P_MSGI) {			SETPORT(SIMODE0, 0);			SETPORT(SIMODE1, ENPHASEMIS | ENBUSFREE);#if defined(DEBUG_RACE)			leave_driver("(reselected) intr");#endif			SETBITS(DMACNTRL0, INTEN);			return;		}	}	/* Check, if we aren't busy with a command */	if (!CURRENT_SC) {		/* bus is free to issue a queued command */		if (TESTHI(SSTAT1, BUSFREE) && ISSUE_SC) {			save_flags(flags);			cli();#if defined(DEBUG_QUEUES)			if (HOSTDATA(shpnt)->debug & debug_queues)				printk("i-, ");#endif			CURRENT_SC = remove_first_SC(&ISSUE_SC);			restore_flags(flags);#if defined(DEBUG_INTR) || defined(DEBUG_SELECTION) || defined(DEBUG_PHASES)			if (HOSTDATA(shpnt)->debug & (debug_intr | debug_selection | debug_phases))				printk("issuing command, ");#endif			CURRENT_SC->SCp.phase = in_selection;#if defined(DEBUG_INTR) || defined(DEBUG_SELECTION) || defined(DEBUG_PHASES)			if (HOSTDATA(shpnt)->debug & (debug_intr | debug_selection | debug_phases))				printk("selecting %d, ", CURRENT_SC->target);#endif			SETPORT(SCSIID, (shpnt->this_id << OID_) | CURRENT_SC->target);			/* Enable interrupts for SELECTION OUT DONE and SELECTION OUT INITIATED */			SETPORT(SXFRCTL1, HOSTDATA(shpnt)->parity ? (ENSPCHK | ENSTIMER) : ENSTIMER);			/* enable interrupts for SELECTION OUT DONE and SELECTION TIME OUT */			SETPORT(SIMODE0, ENSELDO | (DISCONNECTED_SC ? ENSELDI : 0));			SETPORT(SIMODE1, ENSELTIMO);			/* Enable SELECTION OUT sequence */			SETBITS(SCSISEQ, ENSELO | ENAUTOATNO);		} else {			/* No command we are busy with and no new to issue */			printk("aha152x: ignoring spurious interrupt, nothing to do\n");			if (TESTHI(DMACNTRL0, SWINT)) {				printk("aha152x: SWINT is set!  Why?\n");				CLRBITS(DMACNTRL0, SWINT);			}			show_queues(shpnt);		}#if defined(DEBUG_RACE)		leave_driver("(selecting) intr");#endif		SETBITS(DMACNTRL0, INTEN);		return;	}	/* the bus is busy with something */#if defined(DEBUG_INTR)	if (HOSTDATA(shpnt)->debug & debug_intr)		disp_ports(shpnt);#endif	/* we are waiting for the result of a selection attempt */	if (CURRENT_SC->SCp.phase & in_selection) {		if (TESTLO(SSTAT1, SELTO)) {			/* no timeout */			if (TESTHI(SSTAT0, SELDO)) {				/* clear BUS FREE interrupt */				SETPORT(SSTAT1, CLRBUSFREE);				/* Disable SELECTION OUT sequence */				CLRBITS(SCSISEQ, ENSELO | ENAUTOATNO);				/* Disable SELECTION OUT DONE interrupt */				CLRBITS(SIMODE0, ENSELDO);				CLRBITS(SIMODE1, ENSELTIMO);				if (TESTLO(SSTAT0, SELDO)) {					printk("aha152x: passing bus free condition\n");#if defined(DEBUG_RACE)					leave_driver("(passing bus free) intr");#endif					SETBITS(DMACNTRL0, INTEN);					if (CURRENT_SC->SCp.phase & aborted) {						HOSTDATA(shpnt)->abort_result = SCSI_ABORT_ERROR;						HOSTDATA(shpnt)->abortion_complete++;					}					aha152x_done(shpnt, DID_NO_CONNECT << 16);					return;				}#if defined(DEBUG_SELECTION) || defined(DEBUG_PHASES)				if (HOSTDATA(shpnt)->debug & (debug_selection | debug_phases))					printk("SELDO (SELID=%x), ", GETPORT(SELID));#endif				/* selection was done */				SETPORT(SSTAT0, CLRSELDO);#if defined(DEBUG_ABORT)				if ((HOSTDATA(shpnt)->debug & debug_abort) && (CURRENT_SC->SCp.phase & aborted))					printk("(ABORT) target selected, ");#endif				CURRENT_SC->SCp.phase &= ~in_selection;				CURRENT_SC->SCp.phase |= in_other;				ADDMSG(IDENTIFY(HOSTDATA(shpnt)->reconnect, CURRENT_SC->lun));				if (!(SYNCRATE & 0x80) && HOSTDATA(shpnt)->synchronous) {					ADDMSG(EXTENDED_MESSAGE);					ADDMSG(3);					ADDMSG(EXTENDED_SDTR);					ADDMSG(50);					ADDMSG(8);					printk("outbound SDTR: ");					print_msg(&MSG(MSGLEN - 5));					SYNCRATE = 0x80;					CURRENT_SC->SCp.phase |= in_sync;				}#if defined(DEBUG_RACE)				leave_driver("(SELDO) intr");#endif				SETPORT(SCSIRATE, SYNCRATE & 0x7f);				SETPORT(SCSISIG, P_MSGO);				SETPORT(SIMODE0, 0);				SETPORT(SIMODE1, ENREQINIT | ENBUSFREE);				SETBITS(DMACNTRL0, INTEN);				return;			} else				aha152x_panic(shpnt, "neither timeout nor selection\007");		} else {#if defined(DEBUG_SELECTION) || defined(DEBUG_PHASES)			if (HOSTDATA(shpnt)->debug & (debug_selection | debug_phases))				printk("SELTO, ");#endif			/* end selection attempt */			CLRBITS(SCSISEQ, ENSELO | ENAUTOATNO);			/* timeout */			SETPORT(SSTAT1, CLRSELTIMO);			SETPORT(SIMODE0, DISCONNECTED_SC ? ENSELDI : 0);			SETPORT(SIMODE1, ISSUE_SC ? ENBUSFREE : 0);			SETBITS(DMACNTRL0, INTEN);#if defined(DEBUG_RACE)			leave_driver("(SELTO) intr");#endif			if (CURRENT_SC->SCp.phase & aborted) {#if defined(DEBUG_ABORT)				if (HOSTDATA(shpnt)->debug & debug_abort)					printk("(ABORT) selection timeout, ");#endif				HOSTDATA(shpnt)->abort_result = SCSI_ABORT_ERROR;				HOSTDATA(shpnt)->abortion_complete++;			}			if (TESTLO(SSTAT0, SELINGO))				/* ARBITRATION not won */				aha152x_done(shpnt, DID_BUS_BUSY << 16);			else				/* ARBITRATION won, but SELECTION failed */				aha152x_done(shpnt, DID_NO_CONNECT << 16);			return;		}	}	/* enable interrupt, when target leaves current phase */	phase = getphase(shpnt);	if (!(phase & ~P_MASK))	/* "real" phase */		SETPORT(SCSISIG, phase);	SETPORT(SSTAT1, CLRPHASECHG);	CURRENT_SC->SCp.phase =	    (CURRENT_SC->SCp.phase & ~((P_MASK | 1) << 16)) | (phase << 16);	/* information transfer phase */	switch (phase) {	case P_MSGO:		/* MESSAGE OUT */		{			int i, identify = 0, abort = 0;#if defined(DEBUG_INTR) || defined(DEBUG_MSGO) || defined(DEBUG_PHASES)			if (HOSTDATA(shpnt)->debug & (debug_intr | debug_msgo | debug_phases))				printk("MESSAGE OUT, ");#endif			if (MSGLEN == 0) {				ADDMSG(MESSAGE_REJECT);#if defined(DEBUG_MSGO)				if (HOSTDATA(shpnt)->debug & debug_msgo)					printk("unexpected MESSAGE OUT phase; rejecting, ");#endif			}			CLRBITS(SXFRCTL0, ENDMA);			SETPORT(SIMODE0, 0);			SETPORT(SIMODE1, ENPHASEMIS | ENREQINIT | ENBUSFREE);			/* wait for data latch to become ready or a phase change */			while (TESTLO(DMASTAT, INTSTAT))				barrier();#if defined(DEBUG_MSGO)			if (HOSTDATA(shpnt)->debug & debug_msgo) {				int i;

⌨️ 快捷键说明

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