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

📄 acornscsi.c.2

📁 arm平台上的uclinux系统全部源代码
💻 2
📖 第 1 页 / 共 5 页
字号:
	    DBG(host->SCpnt, printk ("scsi%d.%c: had to move command "		    "to disconnected queue\n",		    host->host->host_no, acornscsi_target (host)));#endif	    host->SCpnt = NULL;	}    }    if (!host->SCpnt) {	host->SCpnt = queue_remove_tgtluntag (&host->queues.disconnected,				host->scsi.reconnected.target,				host->scsi.reconnected.lun,				host->scsi.reconnected.tag);#if (DEBUG & (DEBUG_QUEUES|DEBUG_DISCON))	DBG(host->SCpnt, printk ("scsi%d.%c: had to get command",		host->host->host_no, acornscsi_target (host)));#endif    }    if (!host->SCpnt) {	acornscsi_abortcmd (host, host->scsi.reconnected.tag);	host->scsi.phase = PHASE_ABORTED;    } else {	/*	 * Restore data pointer from SAVED pointers.	 */	host->scsi.SCp = host->SCpnt->SCp;#if (DEBUG & (DEBUG_QUEUES|DEBUG_DISCON))	printk (", data pointers: [%p, %X]",		host->scsi.SCp.ptr, host->scsi.SCp.this_residual);#endif    }#if (DEBUG & (DEBUG_QUEUES|DEBUG_DISCON))    printk ("\n");#endif    host->dma.transferred = host->scsi.SCp.have_data_in;    return host->SCpnt != NULL;}/* * Function: void acornscsi_disconnect_unexpected (AS_Host *host) * Purpose : handle an unexpected disconnect * Params  : host - host on which disconnect occurred */staticvoid acornscsi_disconnect_unexpected (AS_Host *host){    printk (KERN_ERR "scsi%d.%c: unexpected disconnect\n",	    host->host->host_no, acornscsi_target (host));#if (DEBUG & DEBUG_ABORT)    acornscsi_dumplog (host, 8);#endif    acornscsi_done (host, &host->SCpnt, DID_ABORT);}/* * Function: void acornscsi_abortcmd (AS_host *host, unsigned char tag) * Purpose : abort a currently executing command * Params  : host - host with connected command to abort *	     tag  - tag to abort */staticvoid acornscsi_abortcmd (AS_Host *host, unsigned char tag){    sbic_arm_write (host->scsi.io_port, CMND, CMND_ASSERTATN);    msgqueue_flush (&host->scsi.msgs);#ifdef SCSI2_TAG    if (tag)	msgqueue_addmsg (&host->scsi.msgs, 2, ABORT_TAG, tag);    else#endif	msgqueue_addmsg (&host->scsi.msgs, 1, ABORT);}/* ========================================================================================== * Interrupt routines. *//* * Function: int acornscsi_sbicintr (AS_Host *host) * Purpose : handle interrupts from SCSI device * Params  : host - host to process * Returns : INTR_PROCESS if expecting another SBIC interrupt *	     INTR_IDLE if no interrupt *	     INTR_NEXT_COMMAND if we have finished processing the command */staticintr_ret_t acornscsi_sbicintr (AS_Host *host, int in_irq){    unsigned int asr, ssr;    asr = sbic_arm_read (host->scsi.io_port, ASR);    if (!(asr & ASR_INT))	return INTR_IDLE;    ssr = sbic_arm_read (host->scsi.io_port, SSR);#if (DEBUG & DEBUG_PHASES)    print_sbic_status(asr, ssr, host->scsi.phase);#endif    ADD_STATUS(8, ssr, host->scsi.phase, in_irq);    if (host->SCpnt && !host->scsi.disconnectable)	ADD_STATUS(host->SCpnt->target, ssr, host->scsi.phase, in_irq);    switch (ssr) {    case 0x00:				/* reset state - not advanced			*/	printk (KERN_ERR "scsi%d: reset in standard mode but wanted advanced mode.\n",		host->host->host_no);	/* setup sbic - WD33C93A */	sbic_arm_write (host->scsi.io_port, OWNID, OWNID_EAF | host->host->this_id);	sbic_arm_write (host->scsi.io_port, CMND, CMND_RESET);	return INTR_IDLE;    case 0x01:				/* reset state - advanced			*/	sbic_arm_write (host->scsi.io_port, CTRL, INIT_SBICDMA | CTRL_IDI);	sbic_arm_write (host->scsi.io_port, TIMEOUT, TIMEOUT_TIME);	sbic_arm_write (host->scsi.io_port, SYNCHTRANSFER, SYNCHTRANSFER_2DBA);	sbic_arm_write (host->scsi.io_port, SOURCEID, SOURCEID_ER | SOURCEID_DSP);	msgqueue_flush (&host->scsi.msgs);	return INTR_IDLE;    case 0x41:				/* unexpected disconnect aborted command	*/	acornscsi_disconnect_unexpected (host);	return INTR_NEXT_COMMAND;    }    switch (host->scsi.phase) {    case PHASE_CONNECTING:		/* STATE: command removed from issue queue	*/	switch (ssr) {	case 0x11:			/* -> PHASE_CONNECTED				*/	    /* BUS FREE -> SELECTION */	    host->scsi.phase = PHASE_CONNECTED;	    msgqueue_flush (&host->scsi.msgs);	    host->dma.transferred = host->scsi.SCp.have_data_in;	    /* 33C93 gives next interrupt indicating bus phase */	    asr = sbic_arm_read (host->scsi.io_port, ASR);	    if (!(asr & ASR_INT))		break;	    ssr = sbic_arm_read (host->scsi.io_port, SSR);	    ADD_STATUS(8, ssr, host->scsi.phase, 1);	    ADD_STATUS(host->SCpnt->target, ssr, host->scsi.phase, 1);	    goto connected;	    	case 0x42:			/* select timed out				*/					/* -> PHASE_IDLE				*/	    acornscsi_done (host, &host->SCpnt, DID_NO_CONNECT);	    return INTR_NEXT_COMMAND;	case 0x81:			/* -> PHASE_RECONNECTED or PHASE_ABORTED	*/	    /* BUS FREE -> RESELECTION */	    host->origSCpnt = host->SCpnt;	    host->SCpnt = NULL;	    msgqueue_flush (&host->scsi.msgs);	    acornscsi_reconnect (host);	    break;	default:	    printk (KERN_ERR "scsi%d.%c: PHASE_CONNECTING, SSR %02X?\n",		    host->host->host_no, acornscsi_target (host), ssr);	    acornscsi_dumplog (host, host->SCpnt ? host->SCpnt->target : 8);	    acornscsi_abortcmd (host, host->SCpnt->tag);	}	return INTR_PROCESSING;    connected:    case PHASE_CONNECTED:		/* STATE: device selected ok			*/	switch (ssr) {#ifdef NONSTANDARD	case 0x8a:			/* -> PHASE_COMMAND, PHASE_COMMANDPAUSED	*/	    /* SELECTION -> COMMAND */	    acornscsi_sendcommand (host);	    break;	case 0x8b:			/* -> PHASE_STATUS				*/	    /* SELECTION -> STATUS */	    acornscsi_readstatusbyte (host);	    break;#endif	case 0x8e:			/* -> PHASE_MSGOUT				*/	    /* SELECTION ->MESSAGE OUT */	    host->scsi.phase = PHASE_MSGOUT;	    acornscsi_buildmessages (host);	    acornscsi_sendmessage (host);	    break;	/* these should not happen */	case 0x85:			/* target disconnected				*/	    acornscsi_done (host, &host->SCpnt, DID_ERROR);	    break;	default:	    printk (KERN_ERR "scsi%d.%c: PHASE_CONNECTED, SSR %02X?\n",		    host->host->host_no, acornscsi_target (host), ssr);	    acornscsi_dumplog (host, host->SCpnt ? host->SCpnt->target : 8);	    acornscsi_abortcmd (host, host->SCpnt->tag);	}	return INTR_PROCESSING;    case PHASE_MSGOUT:			/* STATE: connected & sent IDENTIFY message	*/	/*	 * SCSI standard says th at a MESSAGE OUT phases can be followed by a DATA phase	 */	switch (ssr) {	case 0x8a:	case 0x1a:			/* -> PHASE_COMMAND, PHASE_COMMANDPAUSED	*/	    /* MESSAGE OUT -> COMMAND */	    acornscsi_sendcommand (host);	    break;	case 0x1b:			/* -> PHASE_STATUS				*/	    /* MESSAGE OUT -> STATUS */	    acornscsi_readstatusbyte (host);	    break;        case 0x4f:	case 0x1f:			/* -> PHASE_MSGIN, PHASE_DISCONNECT		*/	    /* MESSAGE OUT -> MESSAGE IN */	    acornscsi_message (host);	    break;	default:	    printk (KERN_ERR "scsi%d.%c: PHASE_MSGOUT, SSR %02X?\n",		    host->host->host_no, acornscsi_target (host), ssr);	    acornscsi_dumplog (host, host->SCpnt ? host->SCpnt->target : 8);	}	return INTR_PROCESSING;    case PHASE_COMMAND: 		/* STATE: connected & command sent		*/	switch (ssr) {	case 0x18:			/* -> PHASE_DATAOUT				*/	    /* COMMAND -> DATA OUT */	    if (host->scsi.SCp.sent_command != host->SCpnt->cmd_len)		acornscsi_abortcmd (host, host->SCpnt->tag);	    acornscsi_dma_setup (host, DMA_OUT);	    if (!acornscsi_starttransfer (host))		acornscsi_abortcmd (host, host->SCpnt->tag);	    host->scsi.phase = PHASE_DATAOUT;	    return INTR_IDLE;	case 0x19:			/* -> PHASE_DATAIN				*/	    /* COMMAND -> DATA IN */	    if (host->scsi.SCp.sent_command != host->SCpnt->cmd_len)		acornscsi_abortcmd (host, host->SCpnt->tag);	    acornscsi_dma_setup (host, DMA_IN);	    if (!acornscsi_starttransfer (host))		acornscsi_abortcmd (host, host->SCpnt->tag);	    host->scsi.phase = PHASE_DATAIN;	    return INTR_IDLE;	case 0x1b:			/* -> PHASE_STATUS				*/	    /* COMMAND -> STATUS */	    acornscsi_readstatusbyte (host);	    break;	case 0x1e:			/* -> PHASE_MSGOUT				*/	    /* COMMAND -> MESSAGE OUT */	    acornscsi_sendmessage (host);	    break;	case 0x1f:			/* -> PHASE_MSGIN, PHASE_DISCONNECT		*/	    /* COMMAND -> MESSAGE IN */	    acornscsi_message (host);	    break;	default:	    printk (KERN_ERR "scsi%d.%c: PHASE_COMMAND, SSR %02X?\n",		    host->host->host_no, acornscsi_target (host), ssr);	    acornscsi_dumplog (host, host->SCpnt ? host->SCpnt->target : 8);	}	return INTR_PROCESSING;    case PHASE_DISCONNECT:		/* STATE: connected, received DISCONNECT msg	*/	if (ssr == 0x85) {		/* -> PHASE_IDLE				*/	    host->scsi.disconnectable = 1;	    host->scsi.reconnected.tag = 0;	    host->scsi.phase = PHASE_IDLE;	    host->stats.disconnects += 1;	} else {	    printk (KERN_ERR "scsi%d.%c: PHASE_DISCONNECT, SSR %02X instead of disconnect?\n",		    host->host->host_no, acornscsi_target (host), ssr);	    acornscsi_dumplog (host, host->SCpnt ? host->SCpnt->target : 8);	}	return INTR_NEXT_COMMAND;    case PHASE_IDLE:			/* STATE: disconnected				*/	if (ssr == 0x81)		/* -> PHASE_RECONNECTED or PHASE_ABORTED	*/	    acornscsi_reconnect (host);	else {	    printk (KERN_ERR "scsi%d.%c: PHASE_IDLE, SSR %02X while idle?\n",		    host->host->host_no, acornscsi_target (host), ssr);	    acornscsi_dumplog (host, host->SCpnt ? host->SCpnt->target : 8);	}	return INTR_PROCESSING;    case PHASE_RECONNECTED:		/* STATE: device reconnected to initiator	*/	/*	 * Command reconnected - if MESGIN, get message - it may be	 * the tag.  If not, get command out of disconnected queue	 */	/*	 * If we reconnected and we're not in MESSAGE IN phase after IDENTIFY,	 * reconnect I_T_L command	 */	if (ssr != 0x8f && !acornscsi_reconnect_finish (host))	    return INTR_IDLE;	ADD_STATUS(host->SCpnt->target, ssr, host->scsi.phase, in_irq);	switch (ssr) {	case 0x88:			/* data out phase				*/					/* -> PHASE_DATAOUT				*/	    /* MESSAGE IN -> DATA OUT */	    acornscsi_dma_setup (host, DMA_OUT);	    if (!acornscsi_starttransfer (host))		acornscsi_abortcmd (host, host->SCpnt->tag);	    host->scsi.phase = PHASE_DATAOUT;	    return INTR_IDLE;	case 0x89:			/* data in phase				*/					/* -> PHASE_DATAIN				*/	    /* MESSAGE IN -> DATA IN */	    acornscsi_dma_setup (host, DMA_IN);	    if (!acornscsi_starttransfer (host))		acornscsi_abortcmd (host, host->SCpnt->tag);	    host->scsi.phase = PHASE_DATAIN;	    return INTR_IDLE;	case 0x8a:			/* command out					*/	    /* MESSAGE IN -> COMMAND */	    acornscsi_sendcommand (host);/* -> PHASE_COMMAND, PHASE_COMMANDPAUSED	*/	    break;	case 0x8b:			/* status in					*/					/* -> PHASE_STATUSIN				*/	    /* MESSAGE IN -> STATUS */	    acornscsi_readstatusbyte (host);	    break;	case 0x8e:			/* message out					*/					/* -> PHASE_MSGOUT				*/	    /* MESSAGE IN -> MESSAGE OUT */	    acornscsi_sendmessage (host);	    break;	case 0x8f:			/* message in					*/	    acornscsi_message (host);	/* -> PHASE_MSGIN, PHASE_DISCONNECT		*/	    break;	default:	    printk (KERN_ERR "scsi%d.%c: PHASE_RECONNECTED, SSR %02X after reconnect?\n",		    host->host->host_no, acornscsi_target (host), ssr);	    acornscsi_dumplog (host, host->SCpnt ? host->SCpnt->target : 8);	}	return INTR_PROCESSING;    case PHASE_DATAIN:			/* STATE: transferred data in			*/	/*	 * This is simple - if we disconnect then the DMA address & count is	 * correct.	 */	switch (ssr) {	case 0x19:			/* -> PHASE_DATAIN				*/	    acornscsi_abortcmd (host, host->SCpnt->tag);	    return INTR_IDLE;	case 0x4b:			/* -> PHASE_STATUSIN				*/	case 0x1b:			/* -> PHASE_STATUSIN				*/	    /* DATA IN -> STATUS */	    host->scsi.SCp.have_data_in = host->SCpnt->request_bufflen -					  acornscsi_sbic_xfcount (host);	    acornscsi_dma_stop (host);	    acornscsi_readstatusbyte (host);	    break;	case 0x1e:			/* -> PHASE_MSGOUT				*/	case 0x4e:			/* -> PHASE_MSGOUT				*/	    /* DATA IN -> MESSAGE OUT */	    host->scsi.SCp.have_data_in = host->SCpnt->request_bufflen -					  acornscsi_sbic_xfcount (host);	    acornscsi_dma_stop (host);	    acornscsi_sendmessage (host);	    break;	case 0x1f:			/* message in					*/	case 0x4f:			/* message in					*/	    /* DATA IN -> MESSAGE IN */	    host->scsi.SCp.have_data_in = host->SCpnt->request_bufflen -					  acornscsi_sbic_xfcount (host);	    acornscsi_dma_stop (host);	    acornscsi_message (host);	/* -> PHASE_MSGIN, PHASE_DISCONNECT		*/	    break;	default:	    printk (KERN_ERR "scsi%d.%c: PHASE_DATAIN, SSR %02X?\n",		    host->host->host_no, acornscsi_target (host), ssr);	    acornscsi_dumplog (host, host->SCpnt ? host->SCpnt->target : 8);	}	return INTR_PROCESSING;    case PHASE_DATAOUT: 		/* STATE: transferred data out			*/	/*	 * This is more complicated - if we disconnect, the DMA could be 12	 * bytes ahead of us.  We need to correct this.	 */	switch (ssr) {	case 0x18:			/* -> PHASE_DATAOUT				*/	    acornscsi_abortcmd (host, host->SCpnt->tag);	    return INTR_IDLE;	case 0x4b:			/* -> PHASE_STATUSIN				*/	case 0x1b:			/* -> PHASE_STATUSIN				*/	    /* DATA OUT -> STATUS */	    host->scsi.SCp.have_data_in = host->SCpnt->request_bufflen -					  acornscsi_sbic_xfcount (host);	    acornscsi_dma_stop (host);	    acornscsi_dma_adjust (host);	    acornscsi_readstatusbyte (host);	    break;	case 0x1e:			/* -> PHASE_MSGOUT				*/	case 0x4e:			/* -> PHASE_MSGOUT				*/	    /* DATA OUT -> MESSAGE OUT */	    host->scsi.SCp.have_data_in = host->SCpnt->request_bufflen -					  acornscsi_sbic_xfcount (host);	    acornscsi_dma_stop (host);	    acornscsi_dma_adjust (host);	    acornscsi_sendmessage (host);	    break;	case 0x1f:			/* message in					*/	case 0x4f:			/* message in					*/	    /* DATA OUT -> MESSAGE IN */	    host->scsi.SCp.have_data_in = host->SCpnt->request_bufflen -					  acornscsi_sbic_xfcount (host);	    acornscsi_dma_stop (host);	    acornscsi_dma_adjust (host

⌨️ 快捷键说明

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