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

📄 aha152x.c

📁 基于组件方式开发操作系统的OSKIT源代码
💻 C
📖 第 1 页 / 共 5 页
字号:
				printk("messages (");				for (i = 0; i < MSGLEN; i += print_msg(&MSG(i)), printk(" "));				printk("), ");			}#endif			for (i = 0; i < MSGLEN && TESTLO(SSTAT1, PHASEMIS); i++) {#if defined(DEBUG_MSGO)				if (HOSTDATA(shpnt)->debug & debug_msgo)					printk("%x ", MSG(i));#endif				if (i == MSGLEN - 1) {					/* Leave MESSAGE OUT after transfer */					SETPORT(SSTAT1, CLRATNO);				}				SETPORT(SCSIDAT, MSG(i));				make_acklow(shpnt);				getphase(shpnt);				if (MSG(i) == IDENTIFY(HOSTDATA(shpnt)->reconnect, CURRENT_SC->lun))					identify++;				if (MSG(i) == ABORT)					abort++;			}			MSGLEN = 0;			if (identify)				CURRENT_SC->SCp.phase |= sent_ident;			if (abort) {				/* revive abort(); abort() enables interrupts */				HOSTDATA(shpnt)->abort_result = SCSI_ABORT_SUCCESS;				HOSTDATA(shpnt)->abortion_complete++;				CURRENT_SC->SCp.phase &= ~(P_MASK << 16);				/* exit */				SETBITS(DMACNTRL0, INTEN);#if defined(DEBUG_RACE)				leave_driver("(ABORT) intr");#endif				aha152x_done(shpnt, DID_ABORT << 16);				return;			}		}		break;	case P_CMD:		/* COMMAND phase */#if defined(DEBUG_INTR) || defined(DEBUG_CMD) || defined(DEBUG_PHASES)		if (HOSTDATA(shpnt)->debug & (debug_intr | debug_cmd | debug_phases))			printk("COMMAND, ");#endif		if (!(CURRENT_SC->SCp.sent_command)) {			int i;			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();			for (i = 0; i < CURRENT_SC->cmd_len && TESTLO(SSTAT1, PHASEMIS); i++) {				SETPORT(SCSIDAT, CURRENT_SC->cmnd[i]);				make_acklow(shpnt);				getphase(shpnt);			}			if (i < CURRENT_SC->cmd_len && TESTHI(SSTAT1, PHASEMIS))				aha152x_panic(shpnt, "target left COMMAND");			CURRENT_SC->SCp.sent_command++;		} else			aha152x_panic(shpnt, "Nothing to send while in COMMAND");		break;	case P_MSGI:		/* MESSAGE IN phase */		{			int start_sync = 0;#if defined(DEBUG_INTR) || defined(DEBUG_MSGI) || defined(DEBUG_PHASES)			if (HOSTDATA(shpnt)->debug & (debug_intr | debug_msgi | debug_phases))				printk("MESSAGE IN, ");#endif			SETPORT(SXFRCTL0, CH1);			SETPORT(SIMODE0, 0);			SETPORT(SIMODE1, ENBUSFREE);			while (phase == P_MSGI) {				CURRENT_SC->SCp.Message = GETPORT(SCSIDAT);				switch (CURRENT_SC->SCp.Message) {				case DISCONNECT:#if defined(DEBUG_MSGI) || defined(DEBUG_PHASES)					if (HOSTDATA(shpnt)->debug & (debug_msgi | debug_phases))						printk("target disconnected, ");#endif					CURRENT_SC->SCp.Message = 0;					CURRENT_SC->SCp.phase |= disconnected;					if (!HOSTDATA(shpnt)->reconnect)						aha152x_panic(shpnt, "target was not allowed to disconnect");					break;				case COMMAND_COMPLETE:#if defined(DEBUG_MSGI) || defined(DEBUG_PHASES)					if (HOSTDATA(shpnt)->debug & (debug_msgi | debug_phases))						printk("inbound message (COMMAND COMPLETE), ");#endif					done++;					break;				case MESSAGE_REJECT:					if (CURRENT_SC->SCp.phase & in_sync) {						CURRENT_SC->SCp.phase &= ~in_sync;						SYNCRATE = 0x80;						printk("synchronous rejected, ");					} else						printk("inbound message (MESSAGE REJECT), ");#if defined(DEBUG_MSGI)					if (HOSTDATA(shpnt)->debug & debug_msgi)						printk("inbound message (MESSAGE REJECT), ");#endif					break;				case SAVE_POINTERS:#if defined(DEBUG_MSGI)					if (HOSTDATA(shpnt)->debug & debug_msgi)						printk("inbound message (SAVE DATA POINTERS), ");#endif					break;				case RESTORE_POINTERS:#if defined(DEBUG_MSGI)					if (HOSTDATA(shpnt)->debug & debug_msgi)						printk("inbound message (RESTORE DATA POINTERS), ");#endif					break;				case EXTENDED_MESSAGE:					{						char buffer[16];						int i;#if defined(DEBUG_MSGI)						if (HOSTDATA(shpnt)->debug & debug_msgi)							printk("inbound message (EXTENDED MESSAGE), ");#endif						make_acklow(shpnt);						if (getphase(shpnt) != P_MSGI)							break;						buffer[0] = EXTENDED_MESSAGE;						buffer[1] = GETPORT(SCSIDAT);						for (i = 0; i < buffer[1] &&						     (make_acklow(shpnt), getphase(shpnt) == P_MSGI); i++)							buffer[2 + i] = GETPORT(SCSIDAT);#if defined(DEBUG_MSGI)						if (HOSTDATA(shpnt)->debug & debug_msgi)							print_msg(buffer);#endif						switch (buffer[2]) {						case EXTENDED_SDTR:							{								long ticks;								if (buffer[1] != 3)									aha152x_panic(shpnt, "SDTR message length != 3");								if (!HOSTDATA(shpnt)->synchronous)									break;								printk("inbound SDTR: ");								print_msg(buffer);								ticks = (buffer[3] * 4 + 49) / 50;								if (CURRENT_SC->SCp.phase & in_sync) {									/* we initiated SDTR */									if (ticks > 9 || buffer[4] < 1 || buffer[4] > 8)										aha152x_panic(shpnt, "received SDTR invalid");									SYNCRATE |= ((ticks - 2) << 4) + buffer[4];								} else if (ticks <= 9 && buffer[4] >= 1) {									if (buffer[4] > 8)										buffer[4] = 8;									ADDMSG(EXTENDED_MESSAGE);									ADDMSG(3);									ADDMSG(EXTENDED_SDTR);									if (ticks < 4) {										ticks = 4;										ADDMSG(50);									} else										ADDMSG(buffer[3]);									ADDMSG(buffer[4]);									printk("outbound SDTR: ");									print_msg(&MSG(MSGLEN - 5));									CURRENT_SC->SCp.phase |= in_sync;									SYNCRATE |= ((ticks - 2) << 4) + buffer[4];									start_sync++;								} else {									/* requested SDTR is too slow, do it asynchronously */									ADDMSG(MESSAGE_REJECT);									SYNCRATE = 0;								}								SETPORT(SCSIRATE, SYNCRATE & 0x7f);							}							break;						case EXTENDED_MODIFY_DATA_POINTER:						case EXTENDED_EXTENDED_IDENTIFY:						case EXTENDED_WDTR:						default:							ADDMSG(MESSAGE_REJECT);							break;						}					}					break;				default:					printk("unsupported inbound message %x, ", CURRENT_SC->SCp.Message);					break;				}				make_acklow(shpnt);				phase = getphase(shpnt);			}			if (start_sync)				CURRENT_SC->SCp.phase |= in_sync;			else				CURRENT_SC->SCp.phase &= ~in_sync;			if (MSGLEN > 0)				SETPORT(SCSISIG, P_MSGI | ATNO);			/* clear SCSI fifo on BUSFREE */			if (phase == P_BUSFREE)				SETPORT(SXFRCTL0, CH1 | CLRCH1);			if (CURRENT_SC->SCp.phase & disconnected) {				save_flags(flags);				cli();#if defined(DEBUG_QUEUES)				if (HOSTDATA(shpnt)->debug & debug_queues)					printk("d+, ");#endif				append_SC(&DISCONNECTED_SC, CURRENT_SC);				CURRENT_SC->SCp.phase |= 1 << 16;				CURRENT_SC = NULL;				restore_flags(flags);				SETBITS(SCSISEQ, ENRESELI);				SETPORT(SIMODE0, DISCONNECTED_SC ? ENSELDI : 0);				SETPORT(SIMODE1, ISSUE_SC ? ENBUSFREE : 0);				SETBITS(DMACNTRL0, INTEN);				return;			}		}		break;	case P_STATUS:		/* STATUS IN phase */#if defined(DEBUG_STATUS) || defined(DEBUG_INTR) || defined(DEBUG_PHASES)		if (HOSTDATA(shpnt)->debug & (debug_status | debug_intr | debug_phases))			printk("STATUS, ");#endif		SETPORT(SXFRCTL0, CH1);		SETPORT(SIMODE0, 0);		SETPORT(SIMODE1, ENREQINIT | ENBUSFREE);		if (TESTHI(SSTAT1, PHASEMIS))			printk("aha152x: passing STATUS phase");		CURRENT_SC->SCp.Status = GETPORT(SCSIBUS);		make_acklow(shpnt);		getphase(shpnt);#if defined(DEBUG_STATUS)		if (HOSTDATA(shpnt)->debug & debug_status) {			printk("inbound status ");			print_status(CURRENT_SC->SCp.Status);			printk(", ");		}#endif		break;	case P_DATAI:		/* DATA IN phase */		{			int fifodata, data_count, done;#if defined(DEBUG_DATAI) || defined(DEBUG_INTR) || defined(DEBUG_PHASES)			if (HOSTDATA(shpnt)->debug & (debug_datai | debug_intr | debug_phases))				printk("DATA IN, ");#endif#if 0			if (GETPORT(FIFOSTAT) || GETPORT(SSTAT2) & (SFULL | SFCNT))				printk("aha152x: P_DATAI: %d(%d) bytes left in FIFO, resetting\n",				       GETPORT(FIFOSTAT), GETPORT(SSTAT2) & (SFULL | SFCNT));#endif			/* reset host fifo */			SETPORT(DMACNTRL0, RSTFIFO);			SETPORT(DMACNTRL0, RSTFIFO | ENDMA);			SETPORT(SXFRCTL0, CH1 | SCSIEN | DMAEN);			SETPORT(SIMODE0, 0);			SETPORT(SIMODE1, ENPHASEMIS | ENBUSFREE);			/* done is set when the FIFO is empty after the target left DATA IN */			done = 0;			/* while the target stays in DATA to transfer data */			while (!done) {#if defined(DEBUG_DATAI)				if (HOSTDATA(shpnt)->debug & debug_datai)					printk("expecting data, ");#endif				/* wait for PHASEMIS or full FIFO */				while (TESTLO(DMASTAT, DFIFOFULL | INTSTAT))					barrier();#if defined(DEBUG_DATAI)				if (HOSTDATA(shpnt)->debug & debug_datai)					printk("ok, ");#endif				if (TESTHI(DMASTAT, DFIFOFULL))					fifodata = GETPORT(FIFOSTAT);				else {					/* wait for SCSI fifo to get empty */					while (TESTLO(SSTAT2, SEMPTY))						barrier();					/* rest of data in FIFO */					fifodata = GETPORT(FIFOSTAT);#if defined(DEBUG_DATAI)					if (HOSTDATA(shpnt)->debug & debug_datai)						printk("last transfer, ");#endif					done = 1;				}#if defined(DEBUG_DATAI)				if (HOSTDATA(shpnt)->debug & debug_datai)					printk("fifodata=%d, ", fifodata);#endif				while (fifodata && CURRENT_SC->SCp.this_residual) {					data_count = fifodata;					/* limit data transfer to size of first sg buffer */					if (data_count > CURRENT_SC->SCp.this_residual)						data_count = CURRENT_SC->SCp.this_residual;					fifodata -= data_count;#if defined(DEBUG_DATAI)					if (HOSTDATA(shpnt)->debug & debug_datai)						printk("data_count=%d, ", data_count);#endif					if (data_count & 1) {						/* get a single byte in byte mode */						SETBITS(DMACNTRL0, _8BIT);						*CURRENT_SC->SCp.ptr++ = GETPORT(DATAPORT);						CURRENT_SC->SCp.this_residual--;					}					if (data_count > 1) {						CLRBITS(DMACNTRL0, _8BIT);						data_count >>= 1;	/* Number of words */						insw(DATAPORT, CURRENT_SC->SCp.ptr, data_count);#if defined(DEBUG_DATAI)						if (HOSTDATA(shpnt)->debug & debug_datai)							/* show what comes with the last transfer */							if (done) {#if 0								int i;								unsigned char *data;#endif								printk("data on last transfer (%d bytes) ",								       2 * data_count);#if 0								printk("data on last transfer (%d bytes: ",								       2 * data_count);								data = (unsigned char *) CURRENT_SC->SCp.ptr;								for (i = 0; i < 2 * data_count; i++)									printk("%2x ", *data++);								printk("), ");#endif							}#endif						CURRENT_SC->SCp.ptr += 2 * data_count;						CURRENT_SC->SCp.this_residual -= 2 * data_count;					}					/* if this buffer is full and there are more buffers left */					if (!CURRENT_SC->SCp.this_residual &&					    CURRENT_SC->SCp.buffers_residual) {						/* advance to next buffer */						CURRENT_SC->SCp.buffers_residual--;						CURRENT_SC->SCp.buffer++;						CURRENT_SC->SCp.ptr = CURRENT_SC->SCp.buffer->address;						CURRENT_SC->SCp.this_residual = CURRENT_SC->SCp.buffer->length;					}				}				/*				 * FIFO should be empty				 */				if (fifodata > 0) {					printk("aha152x: more data than expected (%d bytes)\n",					       GETPORT(FIFOSTAT));					SETBITS(DMACNTRL0, _8BIT);					printk("aha152x: data (");					while (fifodata--)						printk("%2x ", GETPORT(DATAPORT));					printk(")\n");				}#if defined(DEBUG_DATAI)				if (HOSTDATA(shpnt)->debug & debug_datai)					if (!fifodata)						printk("fifo empty, ");					else						printk("something left in fifo, ");#endif			}#if defined(DEBUG_DATAI)			if ((HOSTDATA(shpnt)->debug & debug_datai) &&			    (CURRENT_SC->SCp.buffers_residual ||			     CURRENT_SC->SCp.this_residual))				printk("left buffers (buffers=%d, bytes=%d), ",				       CURRENT_SC->SCp.buffers_residual, CURRENT_SC->SCp.this_residual);#endif			/* transfer can be considered ended, when SCSIEN reads back zero */			CLRBITS(SXFRCTL0, SCSIEN | DMAEN);			while (TESTHI(SXFRCTL0, SCSIEN))				barrier();			CLRBITS(DMACNTRL0, ENDMA);#if defined(DEBUG_DATAI) || defined(DEBUG_INTR)			if (HOSTDATA(shpnt)->debug & (debug_datai | debug_intr))				printk("got %d bytes, ", GETSTCNT());#endif			CURRENT_SC->SCp.have_data_in++;		}		break;	case P_DATAO:		/* DATA OUT phase */		{			int data_count;#if defined(DEBUG_DATAO) || defined(DEBUG_INTR) || defined(DEBUG_PHASES)			if (HOSTDATA(shpnt)->debug & (debug_datao | debug_intr | debug_phases))				printk("DATA OUT, ");#endif#if defined(DEBUG_DATAO)			if (HOSTDATA(sh

⌨️ 快捷键说明

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