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

📄 bs.c

📁 freebsd v4.4内核源码
💻 C
📖 第 1 页 / 共 3 页
字号:
		}		bs_hostque_head(bsc, ti);		BS_SELECTION_TERMINATE		BS_SETUP_PHASE(HOSTQUEUE)#ifdef	BS_STATICS		bs_statics[ti->ti_id].select_miss_by_reselect++;		bs_statics[ti->ti_id].select_miss++;#endif	/* BS_STATICS */	}	/* who are you ? */	target = bshw_get_src_id(bsc);	if ((ti = bsc->sc_ti[target]) == NULL)	{		bs_debug_print_all(bsc);		printf("reselect: miss reselect. target(%d)\n", target);		bs_reset_nexus(bsc);		return NULL;	}	/* confirm nexus */	BS_HOST_START	bshw_setup_ctrl_reg(bsc, ti->ti_cfgflags);	if (ti->ti_ctab.tqh_first == NULL || ti->ti_phase != DISCONNECTED)	{		bs_printf(ti, "reselect", "phase mismatch");		BS_SETUP_PHASE(UNDEF)		bs_force_abort(ti);		bs_hostque_delete(bsc, ti);	}	else		bsc->sc_dtgnum --;	/* recover host */	bshw_set_dst_id(bsc, ti->ti_id, ti->ti_lun);	bshw_set_sync_reg(bsc, ti->ti_sync);	BS_RESTORE_SDP	BS_SETUP_PHASE(RESELECTED)#ifdef	BS_STATICS	bs_statics[ti->ti_id].reselect++;#endif	/* BS_STATICS */	return ti;}static BS_INLINE voidbs_sat_continue(bsc, ti, cb)	struct bs_softc *bsc;	struct targ_info *ti;	struct ccb *cb;{	BS_SETUP_PHASE(SATRESEL);	bshw_set_dst_id(bsc, ti->ti_id, ti->ti_lun);	bshw_cmd_pass(bsc, 0x44);	bshw_set_sync_reg(bsc, ti->ti_sync);	bshw_issue_satcmd(bsc, cb, 0);	if (bs_check_smit(ti) || bsc->sc_p.datalen <= 0)		bshw_set_count(bsc, 0);	else		bs_dma_xfer(ti, BSHW_CMD_CHECK(cb, BSREAD));	bshw_set_lun(bsc, ti->ti_lun);		/* XXX */	bshw_start_sat(bsc, 0);}/************************************************* * <DATA PHASE> *************************************************/#define	DR	(STR_BSY | STR_DBR)voidbs_poll_timeout(bsc, s)	struct bs_softc *bsc;	char *s;{	struct targ_info *ti;	bs_printf(NULL, s, "timeout");	bsc->sc_flags |= BSRESET;	if ((ti = bsc->sc_nexus) && ti->ti_ctab.tqh_first)		ti->ti_error |= BSTIMEOUT;}static BS_INLINE u_int8_tbs_read_1byte(bsc)	struct bs_softc *bsc;{	register u_int wc;	bshw_start_sxfer(bsc);	for (wc = bsc->sc_wc; (bshw_get_auxstat(bsc) & DR) != DR && --wc; );	if (wc)		return bshw_read_data(bsc);	else		bs_poll_timeout(bsc, "read_1byte");	return 0;}static BS_INLINE voidbs_write_1byte(bsc, data)	struct bs_softc *bsc;	u_int8_t data;{	register u_int wc;	bshw_start_sxfer(bsc);	for (wc = bsc->sc_wc; (bshw_get_auxstat(bsc) & DR) != DR && --wc; );	if (wc)		bshw_write_data(bsc, data);	else		bs_poll_timeout(bsc, "write_1byte");}static intbs_xfer(bsc, data, len)	struct bs_softc *bsc;	char *data;	int len;{	u_int8_t aux;	u_int count, wc;	bshw_set_count(bsc, len);	bshw_start_xfer(bsc);	for (count = 0, wc = bsc->sc_wc; count < len && --wc; )	{		if (((aux = bshw_get_auxstat(bsc)) & DR) == DR)		{			if (bsc->sc_busstat & BSHW_READ)				*(data++) = bshw_read_data(bsc);			else				bshw_write_data(bsc, *(data++));			count++;			wc = bsc->sc_wc;		}		if (aux & STR_INT)			break;	}	if (wc == 0)		bs_poll_timeout(bsc, "bs_xfer");	return count;}#undef	DRstatic voidbs_io_xfer(ti)	struct targ_info *ti;{	struct bs_softc *bsc = ti->ti_bsc;	struct sc_p *sp = &bsc->sc_p;	u_int count, dummy;	/* switch dma trasnfr mode */	bshw_set_poll_trans(bsc, ti->ti_cfgflags);	sp->seglen = 0;	sp->bufp = NULL;	if (sp->datalen <= 0)	{		ti->ti_error |= BSDMAABNORMAL;		dummy = 0;		count = bs_xfer(bsc, (u_int8_t *) &dummy, 1);	}	else		count = bs_xfer(bsc, sp->data, sp->datalen);	sp->data += count;	sp->datalen -= count;}/************************************************ * <COMMAND PHASE> ************************************************/static BS_INLINE voidbs_commandout(bsc, ti, cb)	struct bs_softc *bsc;	struct targ_info *ti;	struct ccb *cb;{	u_int8_t scsi_cmd[16];	int len;	BS_SETUP_PHASE(CMDPHASE);	if (bs_check_link(ti, cb))	{		bcopy(cb->cmd, scsi_cmd, cb->cmdlen);		scsi_cmd[cb->cmdlen - 1] |= 0x01;		len = bs_xfer(bsc, scsi_cmd, cb->cmdlen);	}	else		len = bs_xfer(bsc, cb->cmd, cb->cmdlen);	if (len != cb->cmdlen)		ti->ti_error |= BSCMDABNORMAL;}/************************************************ * <STATUS IN> ************************************************/static BS_INLINE voidbs_status_check(bsc, ti)	struct bs_softc *bsc;	struct targ_info *ti;{	if (ti->ti_status == ST_GOOD || ti->ti_status == ST_INTERGOOD)		return;	switch (ti->ti_status)	{	case ST_MET:	case ST_INTERMET:	case ST_CHKCOND:		ti->ti_error |= BSREQSENSE;		break;	case ST_BUSY:		ti->ti_error |= BSTARGETBUSY;		break;	default:		ti->ti_error |= BSSTATUSERROR;		break;	}}/************************************************ * <MSG IN> ************************************************/#define	MSGWAIT(cnt) { if (ti->ti_msginptr < (cnt)) return; }static voidbs_quick_abort(ti, msg)	struct targ_info *ti;	u_int msg;{	struct ccb *cb;	if ((cb = ti->ti_ctab.tqh_first) == NULL)		return;	cb->msgoutlen = 1;	cb->msgout[0] = msg;	cb->rcnt++;	ti->ti_error |= BSMSGERROR;}static voidbs_msgin_error(ti, count)	struct targ_info *ti;	u_int count;{	int n;	MSGWAIT(count);	bs_printf(ti, "msgin", "illegal msg");	for (n = 0; n < ti->ti_msginptr; n ++)		printf("[0x%x] ", (u_int) ti->ti_msgin[n]);	printf("\n");	bs_quick_abort(ti, MSG_REJECT);	ti->ti_msginptr = 0;}static voidbs_msgin_ext(ti)	struct targ_info *ti;{	struct bs_softc *bsc = ti->ti_bsc;	struct ccb *cb = ti->ti_ctab.tqh_first;	int count;	u_int reqlen;	u_int32_t *ptr;	struct msgbase msg;	MSGWAIT(2);	reqlen = ti->ti_msgin[1];	if (reqlen == 0)		reqlen = 256;	if (ti->ti_msginptr >= MAXMSGLEN)		ti->ti_msginptr = 3;	/* XXX */	MSGWAIT(reqlen + 2);	switch (MKMSG_EXTEND(ti->ti_msgin[1], ti->ti_msgin[2]))	{	case MKMSG_EXTEND(MSG_EXTEND_MDPLEN, MSG_EXTEND_MDPCODE):		ptr = (u_int32_t *)(&ti->ti_msgin[3]);		count = (int) htonl((long) (*ptr));		bsc->sc_p.seglen = ti->ti_scsp.seglen = 0;		if (bsc->sc_p.datalen - count >= 0 &&		    bsc->sc_p.datalen - count <= cb->datalen)		{			bsc->sc_p.datalen -= count;			bsc->sc_p.data += count;		}		else			bs_msgin_error(ti, 7);		break;	case MKMSG_EXTEND(MSG_EXTEND_SYNCHLEN, MSG_EXTEND_SYNCHCODE):		ti->ti_syncnow.period = ti->ti_msgin[3];		ti->ti_syncnow.offset = ti->ti_msgin[4];		if (ti->ti_syncnow.offset == 0)			ti->ti_syncnow.period = 0;		if (ti->ti_syncnow.state != BS_SYNCMSG_ASSERT)		{			bs_start_syncmsg(ti, NULL, BS_SYNCMSG_REQUESTED);			bscmdstart(ti, BSCMDSTART);		}		else			BS_SETUP_SYNCSTATE(BS_SYNCMSG_ACCEPT)		break;	case MKMSG_EXTEND(MSG_EXTEND_WIDELEN, MSG_EXTEND_WIDECODE):		msg.msglen = MSG_EXTEND_WIDELEN + 2;		msg.msg[0] = MSG_EXTEND;		msg.msg[1] = MSG_EXTEND_WIDELEN;		msg.msg[2] = MSG_EXTEND_WIDECODE;		msg.msg[3] = 0;		msg.flag = 0;		bs_make_msg_ccb(ti, cb->lun, cb, &msg, 0);		break;	default:		bs_msgin_error(ti, 0);		return;	}	ti->ti_msginptr = 0;	return;}static voidbs_msg_reject(ti)	struct targ_info *ti;{	struct bs_softc *bsc = ti->ti_bsc;	struct ccb *cb = ti->ti_ctab.tqh_first;	char *s = "unexpected msg reject";	switch (ti->ti_ophase)	{	case CMDPHASE:		s = "cmd rejected";		cb->flags &= ~BSLINK;		BS_SETUP_MSGPHASE(IOCOMPLETED);		break;	case MSGOUT:		if (ti->ti_msgout & 0x80)		{			s = "identify msg rejected";			cb->flags &= ~BSDISC;			BS_SETUP_MSGPHASE(IOCOMPLETED);		}		else if (ti->ti_msgout == MSG_EXTEND)		{			switch (ti->ti_emsgout)			{			case MSG_EXTEND_SYNCHCODE:				BS_SETUP_SYNCSTATE(BS_SYNCMSG_REJECT);				return;			default:				break;			}		}		break;	default:		break;	}	bs_debug_print(bsc, ti);	bs_printf(ti, "msgin", s);	ti->ti_error |= BSMSGERROR;}static BS_INLINE voidbs_msgin(bsc, ti)	struct bs_softc *bsc;	struct targ_info *ti;{	BS_SETUP_PHASE(MSGIN);	switch (ti->ti_msgin[0])	{	case MSG_SAVESP:		BS_SAVE_SDP		break;	case MSG_RESTORESP:		BS_RESTORE_SDP		bs_printf(ti, "msgin", "restore scsi pointer");		break;	case MSG_REJECT:		bs_msg_reject(ti);		break;	case 0xf:		break;	case MSG_I_ERROR:/* all I -> T : nothing to do*/	case MSG_ABORT:	case MSG_PARITY:	case MSG_RESET:	case 0xe:		bs_msgin_error(ti, 1);		goto resume;	case MSG_NOOP:		break;	case MSG_EXTEND:		bs_msgin_ext(ti);		goto resume;	case 0xd:		bs_msgin_error(ti, 2);		goto resume;	case MSG_DISCON:		BS_SETUP_MSGPHASE(DISCONNECTASSERT);		break;	case MSG_COMP:		BS_SETUP_MSGPHASE(IOCOMPLETED);		break;	case MSG_LCOMP:	case MSG_LCOMP_F:		bs_status_check(bsc, ti);		if (bscmddone(ti) == NULL)		{			if (bscmdstart(ti, BSCMDSTART) == 0)			{				bs_printf(ti, "msgin", "cmd line miss");				bs_force_abort(ti);			}		}		else			bscmdstart(ti, BSCMDRESTART);#ifdef	BS_STATICS		bs_linkcmd_count[ti->ti_id]++;#endif	/* BS_STATICS */		BS_LOAD_SDP		ti->ti_status = ST_UNK;		break;	default:		if (ti->ti_msgin[0] & 0x80)		{			if ((ti->ti_msgin[0] & 0x07) != ti->ti_lun)			{				ti->ti_lun = (ti->ti_msgin[0] & 0x07);				bshw_set_dst_id(bsc, ti->ti_id, ti->ti_lun);				bshw_set_sync_reg(bsc, ti->ti_sync);				bs_printf(ti, "msgin", "lun error");				bs_quick_abort(ti, MSG_ABORT);			}			break;		}		else if (ti->ti_msgin[0] < 0x20)			bs_msgin_error(ti, 1);		else if (ti->ti_msgin[0] < 0x30)			bs_msgin_error(ti, 2);		else			bs_msgin_error(ti, 1);		goto resume;	}	ti->ti_msginptr = 0;resume:	return;}/************************************************ * <MSG OUT> ************************************************/static BS_INLINE voidbs_msgout(bsc, ti, cb)	struct bs_softc *bsc;	struct targ_info *ti;	struct ccb *cb;{	u_int8_t msg[MAXMSGLEN + 1];	if (ti->ti_phase == MSGOUT)	{		if (cb->rcnt ++ < bsc->sc_retry)			cb->msgoutlen = ti->ti_omsgoutlen;	}	else		BS_SETUP_PHASE(MSGOUT);	if (ti->ti_ophase == SELECTED)	{identify:		if (cb->msgoutlen == 0)		{			ti->ti_msgout = bs_identify_msg(ti);			ti->ti_omsgoutlen = 0;			bs_write_1byte(bsc, ti->ti_msgout);		}		else		{			if (cb->msgout[0] != MSG_RESET &&			    cb->msgout[0] != MSG_ABORT)			{				msg[0] = bs_identify_msg(ti);				bcopy(cb->msgout, &msg[1], cb->msgoutlen);				bs_xfer(bsc, msg, cb->msgoutlen + 1);			}			else				bs_xfer(bsc, cb->msgout, cb->msgoutlen);			ti->ti_msgout = cb->msgout[0];			ti->ti_emsgout = cb->msgout[2];			ti->ti_omsgoutlen = cb->msgoutlen;			cb->msgoutlen = 0;		}		return;	}

⌨️ 快捷键说明

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