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

📄 isp.c

📁 基于组件方式开发操作系统的OSKIT源代码
💻 C
📖 第 1 页 / 共 5 页
字号:
		((fcparam *) isp->isp_param)->isp_fwstate = FW_CONFIG_WAIT;		isp->isp_sendmarker = 1;		isp_mark_getpdb_all(isp);		isp_async(isp, ISPASYNC_LOOP_DOWN, NULL);		break;	case ASYNC_LOOP_RESET:		((fcparam *) isp->isp_param)->isp_fwstate = FW_CONFIG_WAIT;		isp->isp_sendmarker = 1;		isp_mark_getpdb_all(isp);		PRINTF("%s: Loop RESET\n", isp->isp_name);#ifdef	ISP_TARGET_MODE		isp_notify_ack(isp, NULL);#endif		break;	case ASYNC_PDB_CHANGED:		isp->isp_sendmarker = 1;		isp_mark_getpdb_all(isp);		PRINTF("%s: Port Database Changed\n", isp->isp_name);		break;	case ASYNC_CHANGE_NOTIFY:		break;	default:		PRINTF("%s: unknown async code 0x%x\n", isp->isp_name, mbox);		break;	}	return (fast_post_handle);}static intisp_handle_other_response(isp, sp, optrp)	struct ispsoftc *isp;	ispstatusreq_t *sp;	u_int8_t *optrp;{	u_int8_t iptr, optr;	int reqsize = 0;	void *ireqp = NULL;#ifdef	ISP_TARGET_MODE	union {		at_entry_t	*atio;		at2_entry_t	*at2io;		ct_entry_t	*ctio;		ct2_entry_t	*ct2io;		lun_entry_t	*lunen;		in_entry_t	*inot;		in_fcentry_t	*inot_fc;		na_entry_t	*nack;		na_fcentry_t	*nack_fc;		void		*voidp;#define	atio	un.atio#define	at2io	un.at2io#define	ctio	un.ctio#define	ct2io	un.ct2io#define	lunen	un.lunen#define	inot	un.inot#define	inot_fc	un.inot_fc#define	nack	un.nack#define	nack_fc	un.nack_fc	} un;	un.voidp = sp;#endif	switch (sp->req_header.rqs_entry_type) {	case RQSTYPE_REQUEST:		return (-1);#ifdef	ISP_TARGET_MODE	case RQSTYPE_NOTIFY_ACK:	{		static const char *f =			"%s: Notify Ack Status 0x%x Sequence Id 0x%x\n"		/*		 * The ISP is acknowleding our ack of an Immediate Notify.		 */		if (isp->isp_type & ISP_HA_FC) {			PRINTF(f, isp->isp_name,			    nack_fc->na-status, nack_fc->na_seqid);		} else {			PRINTF(f, isp->isp_name,			    nack->na_status, nack->na_seqid);		}		break;	}	case RQSTYPE_NOTIFY:	{		u_int16_t seqid, status;		/*		 * Either the ISP received a SCSI message it cannot handle		 * or some other out of band condition (e.g., Port Logout)		 * or it is returning an Immediate Notify entry we sent.		 */		if (isp->isp_type & ISP_HA_FC) {			status = inot_fc->status;			seqid = inot_fc->in_seqid;		} else {			status = inot->status;			seqid = inot->seqid & 0xff;		}		PRINTF("%s: Immediate Notify Status 0x%x Sequence Id 0x%x\n",		    isp->isp_name, status, seqid);		switch (status) {		case IN_MSG_RECEIVED:		case IN_IDE_RECEIVED:			ptisp_got_msg(ptp, &inot);			break;		case IN_RSRC_UNAVAIL:			PRINTF("%s: Firmware out of ATIOs\n", isp->isp_name);			break;		case IN_ABORT_TASK:			PRINTF("%s: Abort Task iid %d rx_id 0x%x\n",			    inot_fc->in_iid, seqid);			break;		case IN_PORT_LOGOUT:			PRINTF("%s: Port Logout for Initiator %d\n",			    isp->isp_name, inot_fc->in_iid);			break;		default:			PRINTF("%s: bad status (0x%x) in Immediate Notify\n",			    isp->isp_name, status);			break;		}		isp_notify_ack(isp, un.voidp);		reqsize = 0;		break;	}	case RQSTYPE_ENABLE_LUN:	case RQSTYPE_MODIFY_LUN:		if (lunen->req_status != 1) {		    PRINTF("%s: ENABLE/MODIFY LUN returned status 0x%x\n",			isp->isp_name, lunen->req_status);		}		break;	case RQSTYPE_ATIO2:	{		fcparam *fcp = isp->isp_param;		ispctiot2_t local, *ct2 = NULL;		ispatiot2_t *at2 = (ispatiot2_t *) sp;		int s, lun;#ifdef	ISP2100_SCCLUN		lun = at2->req_scclun;#else		lun = at2->req_lun;#endif		PRINTF("%s: atio2 loopid %d for lun %d rxid 0x%x flags0x%x "		    "tflags0x%x ecodes0x%x rqstatus0x%x\n", isp->isp_name,		    at2->req_initiator, lun, at2->req_rxid,		    at2->req_flags, at2->req_taskflags, at2->req_execodes,		    at2->req_status);		switch (at2->req_status & ~ATIO_SENSEVALID) {		case ATIO_PATH_INVALID:			PRINTF("%s: ATIO2 Path Invalid\n", isp->isp_name);			break;		case ATIO_NOCAP:			PRINTF("%s: ATIO2 No Cap\n", isp->isp_name);			break;		case ATIO_BDR_MSG:			PRINTF("%s: ATIO2 BDR Received\n", isp->isp_name);			break;		case ATIO_CDB_RECEIVED:			ct2 = &local;			break;		default:			PRINTF("%s: unknown req_status 0x%x\n", isp->isp_name,			    at2->req_status);			break;		}		if (ct2 == NULL) {			/*			 * Just do an ACCEPT on this fellow.			 */			at2->req_header.rqs_entry_type = RQSTYPE_ATIO2;			at2->req_header.rqs_flags = 0;			at2->req_flags = 1;			ireqp = at2;			reqsize = sizeof (*at2);			break;		}		PRINTF("%s: datalen %d cdb0=0x%x\n", isp->isp_name,		    at2->req_datalen, at2->req_cdb[0]);		MEMZERO((void *) ct2, sizeof (*ct2));		ct2->req_header.rqs_entry_type = RQSTYPE_CTIO2;		ct2->req_header.rqs_entry_count = 1;		ct2->req_header.rqs_flags = 0;		ct2->req_header.rqs_seqno = isp->isp_seqno++;		ct2->req_handle = (at2->req_initiator << 16) | lun;#ifndef	ISP2100_SCCLUN		ct2->req_lun = lun;#endif		ct2->req_initiator = at2->req_initiator;		ct2->req_rxid = at2->req_rxid;		ct2->req_flags = CTIO_SEND_STATUS;		switch (at2->req_cdb[0]) {		case 0x0:		/* TUR */			ct2->req_flags |= CTIO_NODATA | CTIO2_SMODE0;			ct2->req_m.mode0.req_scsi_status = CTIO2_STATUS_VALID;			break;		case 0x3:		/* REQUEST SENSE */		case 0x12:		/* INQUIRE */			ct2->req_flags |= CTIO_SEND_DATA | CTIO2_SMODE0;			ct2->req_m.mode0.req_scsi_status = CTIO2_STATUS_VALID;			ct2->req_seg_count = 1;			if (at2->req_cdb[0] == 0x12) {				s = sizeof (tgtiqd);				MEMCPY(fcp->isp_scratch, tgtiqd, s);			} else {				s = at2->req_datalen;				MEMZERO(fcp->isp_scratch, s);			}			ct2->req_m.mode0.req_dataseg[0].ds_base =			    fcp->isp_scdma;			ct2->req_m.mode0.req_dataseg[0].ds_count = s;			ct2->req_m.mode0.req_datalen = s;#if	1			if (at2->req_datalen < s) {				ct2->req_m.mode1.req_scsi_status |=				    CTIO2_RESP_VALID|CTIO2_RSPOVERUN;			} else if (at2->req_datalen > s) {				ct2->req_m.mode1.req_scsi_status |=				    CTIO2_RESP_VALID|CTIO2_RSPUNDERUN;			}#endif			break;		default:		/* ALL OTHERS */			ct2->req_flags |= CTIO_NODATA | CTIO2_SMODE1;			ct2->req_m.mode1.req_scsi_status = 0;#if	1			if (at2->req_datalen) {				ct2->req_m.mode1.req_scsi_status |=				    CTIO2_RSPUNDERUN;				ct2->req_resid[0] = at2->req_datalen & 0xff;				ct2->req_resid[1] =					(at2->req_datalen >> 8) & 0xff;				ct2->req_resid[2] =					(at2->req_datalen >> 16) & 0xff;				ct2->req_resid[3] =					(at2->req_datalen >> 24) & 0xff;			}#endif			if ((at2->req_status & ATIO_SENSEVALID) == 0) {				ct2->req_m.mode1.req_sense_len = 18;				ct2->req_m.mode1.req_scsi_status |= 2;				ct2->req_m.mode1.req_response[0] = 0x70;				ct2->req_m.mode1.req_response[2] = 0x2;			} else {				ct2->req_m.mode1.req_sense_len = 18;				ct2->req_m.mode1.req_scsi_status |=				    at2->req_scsi_status;				MEMCPY(ct2->req_m.mode1.req_response,				    at2->req_sense, sizeof (at2->req_sense));			}			break;		}		reqsize = sizeof (*ct2);		ireqp = ct2;		break;	}	case RQSTYPE_CTIO2:	{		ispatiot2_t *at2;		ispctiot2_t *ct2 = (ispctiot2_t *) sp;		PRINTF("%s: CTIO2 returned status 0x%x\n", isp->isp_name,		    ct2->req_status);		/*		 * Return the ATIO to the board.		 */		at2 = (ispatiot2_t *) sp;		at2->req_header.rqs_entry_type = RQSTYPE_ATIO2;		at2->req_header.rqs_entry_count = 1;		at2->req_header.rqs_flags = 0;		at2->req_header.rqs_seqno = isp->isp_seqno++;		at2->req_status = 1;		reqsize = sizeof (*at2);		ireqp = at2;		break;	}#undef	atio#undef	at2io#undef	ctio#undef	ct2io#undef	lunen#undef	inot#undef	inot_fc#undef	nack#undef	nack_fc#endif	default:		PRINTF("%s: other response type %x\n", isp->isp_name,		    sp->req_header.rqs_entry_type);		break;	}	if (reqsize) {		void *reqp;		optr = isp->isp_reqodx = ISP_READ(isp, OUTMAILBOX4);		iptr = isp->isp_reqidx;		reqp = (void *) ISP_QUEUE_ENTRY(isp->isp_rquest, iptr);		iptr = ISP_NXT_QENTRY(iptr, RQUEST_QUEUE_LEN);		if (iptr == optr) {			PRINTF("%s: Request Queue Overflow other response\n",			    isp->isp_name);		} else {			MEMCPY(reqp, ireqp, reqsize);			ISP_WRITE(isp, INMAILBOX4, iptr);			isp->isp_reqidx = iptr;		}	}	return (0);}#ifdef	ISP_TARGET_MODEstatic void isp_tmd_newcmd_dflt __P((void *, tmd_cmd_t *));static void isp_tmd_event_dflt __P((void *, int));static void isp_tmd_notify_dflt __P((void *, tmd_notify_t *));static void isp_tgt_data_xfer __P ((tmd_cmd_t *));static void isp_tgt_endcmd __P ((tmd_cmd_t *, u_int8_t));static void isp_tgt_done __P ((tmd_cmd_t *));static voidisp_tmd_newcmd_dflt(arg0, cmdp)	void *arg0;	tmd_cmd_t *cmdp;{}static voidisp_tmd_event_dflt(arg0, event)	void *arg0;	int event;{}static voidisp_tmd_notify_dflt(arg0, npt)	void *arg0;	tmd_notify_t *npt;{}/* * Locks held, and ints disabled (if FC). * * XXX: SETUP ONLY FOR INITIAL ENABLING RIGHT NOW */static intisp_modify_lun(isp, lun, icnt, ccnt)	struct ispsoftc *isp;	int lun;	/* logical unit to enable, modify, or disable */	int icnt;	/* immediate notify count */	int ccnt;	/* command count */{	isplun_t *ip = NULL;	u_int8_t iptr, optr;	optr = isp->isp_reqodx = ISP_READ(isp, OUTMAILBOX4);	iptr = isp->isp_reqidx;	ip = (isplun_t *) ISP_QUEUE_ENTRY(isp->isp_rquest, iptr);	iptr = ISP_NXT_QENTRY(iptr, RQUEST_QUEUE_LEN);	if (iptr == optr) {		PRINTF("%s: Request Queue Overflow in isp_modify_lun\n",		    isp->isp_name);		return (-1);	}	MEMZERO((void *) ip, sizeof (*ip));	ip->req_header.rqs_entry_type = RQSTYPE_ENABLE_LUN;	ip->req_header.rqs_entry_count = 1;	ip->req_header.rqs_seqno = isp->isp_seqno++;	ip->req_handle = RQSTYPE_ENABLE_LUN;	if (isp->isp_type & ISP_HA_SCSI) {		ip->req_lun = lun;	}	ip->req_cmdcount = ccnt;	ip->req_imcount = icnt;	ip->req_timeout = 0;	/* default 30 seconds */	ISP_WRITE(isp, INMAILBOX4, iptr);	isp->isp_reqidx = iptr;	return (0);}static voidisp_notify_ack(isp, ptrp)	struct ispsoftc *isp;	void *ptrp;{	void *reqp;	u_int8_t iptr, optr;	union {		na_fcentry_t _naf;		na_entry_t _nas;	} un;	MEMZERO((caddr_t)&un, sizeof (un));	un._nas.na_header.rqs_entry_type = RQSTYPE_NOTIFY_ACK;	un._nas.na_header.rqs_entry_count = 1;	if (isp->isp_type & ISP_HA_FC) {		na_fcentry_t *na = &un._nas;		if (ptrp) {			in_fcentry_t *inp = ptrp;			na->na_iid = inp->in_iid;			na->na_lun = inp->in_lun;			na->na_task_flags = inp->in_task_flags;			na->na_seqid = inp->in_seqid;			na->na_status = inp->in_status;		} else {			na->na_flags = NAFC_RST_CLRD;		}	} else {		na_entry_t *na = &un._nas;		if (ptrp) {			in_entry_t *inp = ptrp;			na->na_iid = inp->in_iid;			na->na_lun = inp->in_lun;			na->na_tgt = inp->in_tgt;			na->na_seqid = inp->in_seqid;		} else {			na->na_flags = NA_RST_CLRD;		}	}	optr = isp->isp_reqodx = ISP_READ(isp, OUTMAILBOX4);	iptr = isp->isp_reqidx;	reqp = (void *) ISP_QUEUE_ENTRY(isp->isp_rquest, iptr);	iptr = ISP_NXT_QENTRY(iptr, RQUEST_QUEUE_LEN);	if (iptr == optr) {		PRINTF("%s: Request Queue Overflow For isp_notify_ack\n",		    isp->isp_name);	} else {		MEMCPY(reqp, ireqp, sizeof (un));		ISP_WRITE(isp, INMAILBOX4, iptr);		isp->isp_reqidx = iptr;	}}/* * These are dummy stubs for now until the outside framework is plugged in. */static voidisp_handle_atio (isp, aep)	struct ispsoftc *isp;	at_entry_t *aep;{	int status, connected;	tmd_cmd_t local, *cdp = &local;	/*	 * Get the ATIO status and see if we're still connected.	 */	status = aep->at_status;	connected = ((aep->at_flags & AT_NODISC) != 0);	PRINTF("%s: ATIO status=0x%x, connected=%d\n", isp->isp_name,	    status, connected);	/*	 * The firmware status (except for the SenseValid bit) indicates	 * why this ATIO was sent to us.	 * If SenseValid is set, the firware has recommended Sense Data.	 * If the Disconnects Disabled bit is set in the flags field,	 * we're still connected on the SCSI bus - i.e. the initiator	 * did not set DiscPriv in the identify message. We don't care	 * about this so it's ignored.	 */	switch (status & ~TGTSVALID) {	case AT_PATH_INVALID:		/*		 * ATIO rejected by the firmware due to disabled lun.		 */		PRINTF("%s: Firmware rejected ATIO for disabled lun %d\n",		    isp->isp_name, aep->at_lun);		break;	case AT_PHASE_ERROR:		/*		 * Bus Pase Sequence error.		 *		 * The firmware should have filled in the correct		 * sense data.		 */		if (status & TGTSVALID) {			MEMCPY(&cdp->cd_sensedata, aep->at_sense,			    sizeof (cdp->cd_sensedata));			PRINTF("%s: Bus Phase Sequence error key 0x%x\n",			    isp->isp_name, cdp->cd_sensedata[2] & 0xf);		} else {			PRINTF("%s: Bus Phase Sequence With No Sense\n",			    isp->isp_name);		}		(*isp->isp_tm

⌨️ 快捷键说明

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