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

📄 scsi_sii.c

📁 <B>Digital的Unix操作系统VAX 4.2源码</B>
💻 C
📖 第 1 页 / 共 5 页
字号:
		("sii_scsistart: COMMAND IN PROGRESS dma poll mode\n"));#endif SZDEBUG            siiaddr->sii_csr &= ~SII_IE;            SZWAIT_UNTIL((siiaddr->sii_dstat & (SII_DNE|SII_MIS)),sii_wait_count,retval);            SZWAIT_UNTIL((siiaddr->sii_dstat & (SII_DNE|SII_MIS)),sii_wait_count,retval);	    siiaddr->sii_comm &= ~(SII_INXFER | SII_DMA);	    siiaddr->sii_dstat = SII_DNE;	    sc->sc_szflags[targid] &= ~SZ_DID_DMA;	    /* Update the remaining dma count for this current transfer */	    if(sc->sc_siidmacount[targid] > SII_MAX_DMA_XFER_LENGTH)		sc->sc_siidmacount[targid] -= 			(SII_MAX_DMA_XFER_LENGTH - siiaddr->sii_dmlotc);	    else		sc->sc_siidmacount[targid] -= 			(sc->sc_siidmacount[targid] - siiaddr->sii_dmlotc);	    if(retval >= sii_wait_count)	        goto HANDLE_ERROR;	    else	    	goto BEGIN_LOOP;	}	/* Wait for interrupt to signal DMA completion */	else {#ifdef SZDEBUG            PRINTD(targid, 0x8,		("sii_scsistart: COMMAND IN PROGRESS dma interrupt mode\n"));#endif SZDEBUG	    return(SZ_IP);   	}    }HANDLE_ERROR:    /* Abort the current SCSI operation due to error */#ifdef SZDEBUG    PRINTD(targid, 0x4,	("sii_scsistart: command aborted (bus=%d target=%d cmd=0x%x)\n",	    cntlr, targid, sc->sc_curcmd[targid]));    PRINTD(targid, 0x4, ("", sii_dumpregs(cntlr, 0)));#endif SZDEBUG	flags = SZ_HARDERR | SZ_LOGCMD | SZ_LOGREGS;	scsi_logerr(sc, 0, targid, SZ_ET_CMDABRTD, 0, 0, flags);    if(!scsi_polled_mode) {	    scsi_logerr(sc, 0, -1, SZ_ET_RSTBUS, 2, 0, SZ_HARDERR);    }    sii_reset(sc);    return(SZ_RET_RESET);}/****************************************************************** * * Name:	sii_select_target * * Abstract:	Perform the arbitration/selection phases for the  *		SII chip. * * Inputs: * sc		Pointer to sz_softc structure for this controller. * targid	Target Id of device (0 - 7). * * Outputs:	None. * * Return values: * SZ_SUCCESS		Command completed successfully. * SZ_RET_ABORT		Command aborted. * SZ_BUSBUSY		Bus is busy, retry the command later. ******************************************************************/sii_select_target(sc, targid)register struct sz_softc *sc;int targid;{    int cntlr = sc - &sz_softc[0];    register struct sii_regs *siiaddr = (struct sii_regs *)cvqmsi + cntlr;    int retval, i;    int retries = 3;    int sii_select_wait = 2500;    /* Loop till retries exhausted */    for(i=0; i<retries; i++) {	/*	 * Check to see if the SII is already connected or is in	 * the selection process.	 */	if ((siiaddr->sii_cstat & (SII_CON | SII_SIP)) != 0)	{#ifdef SZDEBUG        PRINTD(targid, 0x1,	    ("sii_select_target: The SII is already connected\n"));#endif SZDEBUG	    return(SZ_BUSBUSY);	}        /*         * Begin the arbitration/selection phase on the SII chip with 	 * or without reselects. Setup the Selector Control Register    	 * and the Command Register on the SII to select a target on  	 * the SCSI bus.         */#ifdef SZDEBUG        PRINTD(targid, 0x1,	    ("sii_select_target: starting select of ID %d\n", targid));#endif SZDEBUG        siiaddr->sii_slcsr = targid;        siiaddr->sii_comm = (SII_SELECT|SII_ATN);    	/*         * Start timer to wait for a state change to occur on the	 * SII. Wait approximately 250 ms for the target to assert	 * BUSY on the SCSI BUS and for the state change interrupt	 * bit (SII_SCH) to be set on the SII. The 250 ms value is 	 * the selection timeout period as specified in the scsi 	 * specification. (250 milliseconds is recommended)	 */        SZWAIT_UNTIL((siiaddr->sii_cstat & SII_SCH),sii_select_wait,retval);#ifdef SZDEBUG        PRINTD(targid, 0x20,             ("sii_select_target: (STATE select wait) start=%d end=%d\n",	        sii_select_wait, (sii_select_wait - retval)));#endif SZDEBUG	/*	 * If a state change did occur (SII_SCH is set) then make 	 * sure we are connected. We got a state change so the SII	 * has successfully SELECTED a target or was RESELECTED by	 * a disconnected target.	 */	if((siiaddr->sii_cstat & SII_SCH) && !(siiaddr->sii_cstat & SII_CON))            SZWAIT_UNTIL((siiaddr->sii_cstat & SII_CON),sii_select_wait,retval);        /* Check for connection attempt */        if(siiaddr->sii_cstat & SII_CON) {            /* Check for a Reselection Attempt and handle it in "sii_intr" */            if(siiaddr->sii_cstat & SII_DST_ONBUS) {	        targid = (siiaddr->sii_destat & SII_IDMSK);#ifdef SZDEBUG          	PRINTD(targid, 0x1,		    ("sii_select_target: reselect of ID %d has occurred\n",				targid));#endif SZDEBUG    	        return(SZ_BUSBUSY);            }            /* Check for a Selection Attempt and handle it here */            else {    	        siiaddr->sii_cstat = SII_SCH;        	targid = (siiaddr->sii_slcsr & SII_IDMSK);#ifdef SZDEBUG                PRINTD(targid, 0x1,		    ("sii_select_target: select of ID %d succeeded\n",targid));#endif SZDEBUG                sc->sc_active = (1 << targid);                sc->sc_selstat[targid] = SZ_SELECT;		if(!scsi_polled_mode)		    siiaddr->sii_csr &= ~(SII_SLE | SII_RSE);    	        return(SZ_SUCCESS);            }        }	else {#ifdef SZDEBUG	    PRINTD(targid, 0x4,	        ("sii_select_target: select of ID %d timed out (%d TIMES)\n",			targid, i+1));#endif SZDEBUG    	    /* 	     * Selection timed out, clear necessary bus signals and	     * abort the selection if the selection_in_progress bit	     * (SII_SIP) is set. We abort the selection attempt by	     * sending the DISCONNECT command. If the (SII_SIP) bit	     * is not set then we most likely have a RESELECT from	     * another target occuring.	     */	    if(siiaddr->sii_cstat & SII_SIP) {    	        siiaddr->sii_cstat = SII_SCH;    	        siiaddr->sii_comm = SII_DISCON;    	        SZWAIT_UNTIL((siiaddr->sii_cstat & SII_SCH),sii_select_wait,retval);#ifdef SZDEBUG                PRINTD(targid, 0x20,                     ("sii_select_target: (STATE discon wait) start=%d end=%d\n",	                sii_select_wait, (sii_select_wait - retval)));#endif SZDEBUG    	        siiaddr->sii_cstat = SII_SCH;    	        siiaddr->sii_comm = 0;	    }	}    }    return(SZ_RET_ABORT);}/****************************************************************** * * Name:	sii_startdma * * Abstract:	Perform the DATA IN/DATA OUT PHASE on the SII chip. * * Inputs: * sc		Pointer to sz_softc structure for this controller. * iodir	The IO direction (DMA read or DMA write). * targid	Target Id of device (0 - 7). * * Outputs:	None. * * Return values: * SZ_SUCCESS		Command completed successfully. * SZ_RET_ABORT		Command aborted. ******************************************************************/sii_startdma(sc, iodir, targid)register struct sz_softc *sc;int iodir;int targid;{    int cntlr = sc - &sz_softc[0];    register struct sii_regs *siiaddr = (struct sii_regs *)cvqmsi + cntlr;    u_char *byteptr;    char *stv, *bufp;    int datacnt, i;    int retval, offset;     int tmp_phase;    int tmp_state;    int dmacount;    struct format_params *fp;    struct reassign_params *rp;    struct read_defect_params *rdp;    struct defect_descriptors *dd;    struct mode_sel_sns_params *msp;    struct io_uxfer *iox;    /*     * Handle non READ/WRITE scsi commands that transfer data.     */    if ( (sc->sz_opcode != SZ_WRITE) && (sc->sz_opcode != SZ_READ) &&         (sc->sz_opcode != SZ_WRITE_10) && (sc->sz_opcode != SZ_READ_10) ) {	byteptr = (u_char *)&sc->sz_dat[targid];	switch(sc->sz_opcode) {	case SZ_MODSEL:	    byteptr = (u_char *)&sc->sc_dat[0];	    datacnt = (int)sc->sz_modsel.pll;	    if(sc->sc_rzspecial[targid]) {	        msp = (struct mode_sel_sns_params *)sc->sc_rzparams[targid];                byteptr = (u_char *)sc->sc_rzaddr[targid];                datacnt = msp->msp_length;	    }#ifdef SZDEBUG    	    PRINTD(targid, 0x2, ("sii_startdma: mode select data:"));     	    for(i=0; i < datacnt; i++) {		PRINTD(targid, 0x2, (" %x", *(byteptr+i)));    	    }    	    PRINTD(targid, 0x2, ("\n"));#endif SZDEBUG	    break;		case SZ_RQSNS:	    byteptr = (u_char *)&sc->sc_sns[targid];	    datacnt = sc->sz_rqsns.alclen;	    break;	case SZ_INQ:	    datacnt = SZ_INQ_MAXLEN;	    if(sc->sc_rzspecial[targid])                byteptr = (u_char *)sc->sc_rzaddr[targid];	    break;	case SZ_RDCAP:	    datacnt = SZ_RDCAP_LEN;	    break;	case SZ_MODSNS:/* * Why was it this way? Fred -- 7/16/89	    if(sc->sc_devtyp[targid] & SZ_TAPE)	        datacnt = SZ_MODSNS_LEN;*/	    datacnt = (int) sc->sz_modsns.alclen;	    if(sc->sc_rzspecial[targid]) {	        msp = (struct mode_sel_sns_params *)sc->sc_rzparams[targid];                byteptr = (u_char *)sc->sc_rzaddr[targid];                datacnt = msp->msp_length;	    }	    break;	case SZ_RECDIAG:	    datacnt = SZ_RECDIAG_LEN;	    break;	case SZ_REASSIGN:            rp = (struct reassign_params *)sc->sc_rzparams[targid];            byteptr = (u_char *)sc->sc_rzparams[targid];            datacnt = ((rp->rp_header.defect_len0 << 0) & 0x00ff) +    		      ((rp->rp_header.defect_len1 << 8) & 0xff00) + 4;            break;	case SZ_FORMAT:            dd = (struct defect_descriptors *)sc->sc_rzaddr[targid];            byteptr = (u_char *)sc->sc_rzaddr[targid];            datacnt = ((dd->dd_header.fu_hdr.defect_len0 << 0) & 0x00ff) +    		      ((dd->dd_header.fu_hdr.defect_len1 << 8) & 0xff00) + 4;	    break;	case SZ_RDD:            rdp = (struct read_defect_params *)sc->sc_rzparams[targid];            byteptr = (u_char *)sc->sc_rzaddr[targid];            datacnt = rdp->rdp_alclen;            break;	case SZ_READL:	case SZ_WRITEL:	    iox = (struct io_uxfer *)sc->sc_rzparams[targid];            byteptr = (u_char *)sc->sc_rzaddr[targid];	    datacnt = iox->io_cnt;	    break;		default:#ifdef SZDEBUG	    PRINTD(targid, 0x4,		("sii_startdma: unknown scsi cmd 0x%x\n",sc->sz_opcode));#endif SZDEBUG	    return(SZ_RET_ABORT);	    break;	}	/*         * Setup softc structure entries for special SCSI DISK	 * commands that do dma. (FORMAT UNIT), (READ DEFECT DATA),	 * (REASSIGN BLOCK), (MODE SELECT), (MODE SENSE) and	 * (INQUIRY).	 */        if(sc->sc_rzspecial[targid] &&		(sc->sc_curcmd[targid] == sc->sc_actcmd[targid])) {	    if(!(sc->sc_szflags[targid] & SZ_DMA_DISCON)) {	        sc->sc_b_bcount[targid] = datacnt;	        sc->sc_bpcount[targid] = datacnt;	        sc->sc_bufp[targid] = (char *)byteptr;	        sc->sc_xfercnt[targid] = 0;	    }	    goto SETUP_DMA;        }	/* Put the data onto the scsi bus */	if(iodir == SZ_DMA_WRITE) {	    if(sii_senddata(sc, targid, byteptr, datacnt, 0) != SZ_SUCCESS)		return(SZ_RET_ABORT);	}	/* Get the data from the scsi bus */        else {	    if(sii_recvdata(sc, targid, byteptr, datacnt) != SZ_SUCCESS)		return(SZ_RET_ABORT);        }#ifdef SZDEBUG	if(sc->sz_opcode == SZ_RQSNS)    	    PRINTD(targid, 0x4, ("", sii_print_sense(sc,targid)));#endif SZDEBUG    }     else {SETUP_DMA:        /*         * Start of DMA code for a READ or WRITE scsi command, setup         * the count, the RAM buffer offset, and the DMA registers.         */	siiaddr->sii_comm &= ~(SII_INXFER | SII_DMA);        stv = sc->sc_rambuff + sc->sc_dboff[targid];	/* Handle the case of the DMA being disconnected */	if(sc->sc_szflags[targid] & SZ_DMA_DISCON) {#ifdef SZDEBUG            PRINTD(targid, 0x1,	    ("sii_startdma: continuing DMA %s transfer of %d bytes\n",	    (iodir == SZ_DMA_WRITE)?"WRITE":"READ",sc->sc_bpcount[targid]));#endif SZDEBUG	    sc->sc_szflags[targid] &= ~SZ_DMA_DISCON;            /* Setup the dmacount and the offset into the RAM buffer */	    offset = sc->sc_bpcount[targid] - sc->sc_siidmacount[targid];	    if(sc->sc_siidmacount[targid] > SII_MAX_DMA_XFER_LENGTH)		dmacount = SII_MAX_DMA_XFER_LENGTH;	    else		dmacount = sc->sc_siidmacount[targid];	}	/* Handle the case of the DMA just starting */        else {#ifdef SZDEBUG            PRINTD(targid, 0x1,	    ("sii_startdma: starting DMA %s transfer of %d bytes\n",	    (iodir == SZ_DMA_WRITE)?"WRITE":"READ",sc->sc_bpcount[targid]));#endif SZDEBUG	    /* Copy data to RAM buffer if DMA WRITE operation */    	    if(iodir == SZ_DMA_WRITE) {		bufp = sc->sc_bufp[targid] + sc->sc_xfercnt[targid];/*    	        bcopy (bufp, stv, sc->sc_b_bcount[targid]);	*/    	        blkcpy (bufp, stv, sc->sc_b_bcount[targid]);	    }            /* Setup the dmacount and the offset into the RAM buffer */	    sc->sc_siidmacount[targid] = sc->sc_bpcount[targid];	    offset = 0;	    if(sc->sc_siidmacount[targid] > SII_MAX_DMA_XFER_LENGTH)		dmacount = SII_MAX_DMA_XFER_LENGTH;	    else

⌨️ 快捷键说明

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