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

📄 bsfunc.c

📁 freebsd v4.4内核源码
💻 C
📖 第 1 页 / 共 2 页
字号:
	/* target check */	do	{		if (error != COMPLETE)		{			printf("%s: scsi bus reset and try to restart ...",			       bsc->sc_dvname);			bshw_smitabort(bsc);			bshw_dmaabort(bsc, NULL);			bshw_chip_reset(bsc);			bshw_bus_reset(bsc);			bshw_chip_reset(bsc);			printf(" done. scsi bus ready.\n");			nextti = bsc->sc_titab.tqh_first;			error = COMPLETE;		}		if ((ti = nextti) == NULL)			break;		nextti = ti->ti_tchain.tqe_next;		bits = (1 << ti->ti_id);		if (skip & bits)			continue;		if ((error = bs_check_target(ti)) != COMPLETE)		{			if (querm)			{				TAILQ_REMOVE(&bsc->sc_titab, ti, ti_tchain);				bsc->sc_openf &= ~bits;			}			if (error == NOTARGET)				error = COMPLETE;			skip |= bits;		}	}	while (1);	/* ok now ready */	bsc->sc_hstate = BSC_RDY;	/* recover */	for (ti = bsc->sc_titab.tqh_first; ti; ti = ti->ti_tchain.tqe_next)	{		ti->ti_ctab = ti->ti_bctab;		TAILQ_INIT(&ti->ti_bctab);		if (ti->ti_ctab.tqh_first)			bscmdstart(ti, BSCMDSTART);	}}voidbs_reset_nexus(bsc)	struct bs_softc *bsc;{	struct targ_info *ti;	struct ccb *cb;	bsc->sc_flags &= ~(BSRESET | BSUNDERRESET);	if (bsc->sc_poll)	{		bsc->sc_flags |= BSUNDERRESET;		return;	}	/* host state clear */	BS_HOST_TERMINATE	BS_SETUP_MSGPHASE(FREE)	bsc->sc_dtgnum = 0;	/* target state clear */	for (ti = bsc->sc_titab.tqh_first; ti; ti = ti->ti_tchain.tqe_next)	{		if (ti->ti_state == BS_TARG_SYNCH)			bs_analyze_syncmsg(ti, NULL);		if (ti->ti_state > BS_TARG_START)			BS_SETUP_TARGSTATE(BS_TARG_START);		BS_SETUP_PHASE(UNDEF)		bs_hostque_delete(bsc, ti);		if ((cb = ti->ti_ctab.tqh_first) != NULL)		{			if (bsc->sc_hstate == BSC_TARG_CHECK)			{				ti->ti_error |= BSFATALIO;				bscmddone(ti);			}			else if (cb->rcnt >= bsc->sc_retry)			{				ti->ti_error |= BSABNORMAL;				bscmddone(ti);			}			else if (ti->ti_error)				cb->rcnt++;		}		/* target state clear */		BS_SETUP_PHASE(FREE)		BS_SETUP_SYNCSTATE(BS_SYNCMSG_NULL);		ti->ti_flags &= ~BSCFLAGSMASK;		ti->ti_msgout = 0;#ifdef	BS_DIAG		ti->ti_flags &= ~BSNEXUS;#endif	/* BS_DIAG */		for ( ; cb; cb = cb->ccb_chain.tqe_next)		{			bs_kill_msg(cb);			cb->flags &= ~(BSITSDONE | BSCASTAT);			cb->error = 0;		}		if (bsc->sc_hstate != BSC_TARG_CHECK &&		    ti->ti_bctab.tqh_first == NULL)			ti->ti_bctab = ti->ti_ctab;		TAILQ_INIT(&ti->ti_ctab);	}	if (bsc->sc_hstate != BSC_TARG_CHECK)		bs_scsibus_start(bsc);}/************************************************** * CHECK TARGETS AND START TARGETS *************************************************/static intbs_start_target(ti)	struct targ_info *ti;{	struct ccb *cb;	struct scsi_start_stop cmd;	bzero(&cmd, sizeof(struct scsi_start_stop));#ifdef __NetBSD__	cmd.opcode = START_STOP;#else	cmd.op_code = START_STOP;#endif	cmd.how = SSS_START;	ti->ti_lun = 0;	cb = bs_make_internal_ccb(ti, 0, (u_int8_t *) &cmd,				   sizeof(struct scsi_start_stop),				   NULL, 0, BSFORCEIOPOLL, BS_MOTOR_TIMEOUT);	bscmdstart(ti, BSCMDSTART);	return bs_scsi_cmd_poll(ti, cb);}/* test unit ready and check ATN msgout response */static intbs_check_target(ti)	struct targ_info *ti;{	struct bs_softc *bsc = ti->ti_bsc;	struct scsi_inquiry scsi_cmd;	struct scsi_inquiry_data scsi_inquiry_data;	struct ccb *cb;	int count, retry = bsc->sc_retry;	int s, error = COMPLETE;	ti->ti_lun = 0;	bsc->sc_retry = 2;	s = splbio();	/* inquiry */	bzero(&scsi_cmd, sizeof(scsi_cmd));#ifdef __NetBSD__	scsi_cmd.opcode = INQUIRY;#else	scsi_cmd.op_code = INQUIRY;#endif	scsi_cmd.length = sizeof(struct scsi_inquiry_data);	cb = bs_make_internal_ccb(ti, 0,				   (u_int8_t *) &scsi_cmd, sizeof(scsi_cmd),				   (u_int8_t *) &scsi_inquiry_data,				   sizeof(scsi_inquiry_data),				   BSFORCEIOPOLL, BS_STARTUP_TIMEOUT);	bscmdstart(ti, BSCMDSTART);	error = bs_scsi_cmd_poll(ti, cb);	if (error != COMPLETE || (ti->ti_error & BSSELTIMEOUT))		goto done;	ti->targ_type = scsi_inquiry_data.device;	ti->targ_support = scsi_inquiry_data.flags;	/* test unit ready twice */	for (count = 0; count < 2; count++)	{		cb = bs_make_internal_ccb(ti, 0, NULL, 0, NULL, 0,					 BSFORCEIOPOLL, BS_STARTUP_TIMEOUT);		bscmdstart(ti, BSCMDSTART);		error = bs_scsi_cmd_poll(ti, cb);		if (error != COMPLETE || (ti->ti_error & BSSELTIMEOUT))			goto done;	}	if (cb->flags & BSCASTAT)		bs_printf(ti, "check", "could not clear CA state");	ti->ti_error = 0;done:	bsc->sc_retry = retry;	if (ti->ti_error & BSSELTIMEOUT)		error = NOTARGET;	if (error == COMPLETE)		error = bs_start_target(ti);	splx(s);	return error;}/************************************************** * TARGET CONTROL **************************************************/struct targ_info *bs_init_target_info(bsc, target)	struct bs_softc *bsc;	int target;{	struct targ_info *ti;	ti = malloc(sizeof(struct targ_info), M_DEVBUF, M_NOWAIT);	if (ti == NULL)	{		bs_printf(NULL, "bs_init_targ_info", "no target info memory");		return ti;	}	bzero(ti, sizeof(*ti));	ti->ti_bsc = bsc;	ti->ti_id = target;	ti->sm_offset = 0;	ti->ti_cfgflags = BS_SCSI_NOPARITY | BS_SCSI_NOSAT;	ti->ti_mflags = ~(BSSAT | BSDISC | BSSMIT | BSLINK);	BS_SETUP_TARGSTATE(BS_TARG_CTRL);	TAILQ_INIT(&ti->ti_ctab);	bs_alloc_buf(ti);	if (ti->bounce_addr == NULL)	{		free(ti, M_DEVBUF);		return NULL;	}	TAILQ_INSERT_TAIL(&bsc->sc_titab, ti, ti_tchain);	bsc->sc_ti[target] = ti;	bsc->sc_openf |= (1 << target);	return ti;}voidbs_setup_ctrl(ti, quirks, flags)	struct targ_info *ti;	u_int quirks;	u_int flags;{	struct bs_softc *bsc = ti->ti_bsc;	u_int offset, period, maxperiod;	if (ti->ti_state == BS_TARG_CTRL)	{		ti->ti_cfgflags = BS_SCSI_POSITIVE;		ti->ti_syncmax.offset = BSHW_MAX_OFFSET;		BS_SETUP_TARGSTATE(BS_TARG_START);	}	else		flags |= ti->ti_cfgflags & BS_SCSI_NEGATIVE;#ifdef	BS_TARG_SAFEMODE	if (ti->targ_type != 0)	{		flags &= ~(BS_SCSI_DISC | BS_SCSI_SYNC);		flags |= BS_SCSI_NOPARITY;	}#endif#ifdef	SDEV_NODISC	if (quirks & SDEV_NODISC)		flags &= ~BS_SCSI_DISC;#endif#ifdef	SDEV_NOPARITY	if (quirks & SDEV_NOPARITY)		flags |= BS_SCSI_NOPARITY;#endif#ifdef	SDEV_NOCMDLNK	if (quirks & SDEV_NOCMDLNK)		flags &= ~BS_SCSI_LINK;#endif#ifdef	SDEV_ASYNC	if (quirks & SDEV_ASYNC)		flags &= ~BS_SCSI_SYNC;#endif#ifdef	SDEV_AUTOSAVE	if (quirks & SDEV_AUTOSAVE)		flags |= BS_SCSI_SAVESP;#endif#ifdef	SD_Q_NO_SYNC	if (quirks & SD_Q_NO_SYNC)		flags &= ~BS_SCSI_SYNC;#endif	if ((flags & BS_SCSI_DISC) == 0 ||	    (ti->targ_support & SID_Linked) == 0)		flags &= ~BS_SCSI_LINK;	ti->sm_offset = (flags & BS_SCSI_NOSMIT) ?  0 : bsc->sm_offset;	if (ti->sm_offset == 0)		flags |= BS_SCSI_NOSMIT;	else if (bsc->sc_cfgflags & BSC_SMITSAT_DISEN)		flags |= BS_SCSI_NOSAT;	flags &= (ti->ti_cfgflags & BS_SCSI_POSITIVE) | (~BS_SCSI_POSITIVE);	ti->ti_cfgflags = flags;	/* calculate synch setup */	period = BS_SCSI_PERIOD(flags);	offset = (flags & BS_SCSI_SYNC) ? BS_SCSI_OFFSET(flags) : 0;	maxperiod = (bsc->sc_cspeed & IDR_FS_15_20) ? 100 : 50;	if (period > maxperiod)		period = maxperiod;	if (period)		period = 2500 / period;	if (ti->ti_syncmax.offset > offset)		ti->ti_syncmax.offset = offset;	if (ti->ti_syncmax.period < period)		ti->ti_syncmax.period = period;	bshw_adj_syncdata(&ti->ti_syncmax);	/* finally report our info */	printf("%s(%d:%d): {%d:0x%x:0x%x:%s} flags 0x%b\n",		bsc->sc_dvname, ti->ti_id, ti->ti_lun,	       (u_int) ti->targ_type,	       (u_int) ti->targ_support,	       (u_int) ti->bounce_size,	       (flags & BS_SCSI_NOSMIT) ? "dma" : "pdma",		flags, BS_SCSI_BITS);	/* internal representation */	ti->ti_mflags = ~0;	if ((ti->ti_cfgflags & BS_SCSI_DISC) == 0)		ti->ti_mflags &= ~BSDISC;	if ((ti->ti_cfgflags & BS_SCSI_LINK) == 0)		ti->ti_mflags &= ~BSLINK;	if (ti->ti_cfgflags & BS_SCSI_NOSAT)		ti->ti_mflags &= ~BSSAT;	if (ti->ti_cfgflags & BS_SCSI_NOSMIT)		ti->ti_mflags &= ~BSSMIT;}/************************************************** * MISC **************************************************/voidbs_printf(ti, ph, c)	struct targ_info *ti;	char *ph;	char *c;{	if (ti)		printf("%s(%d:%d): <%s> %s\n",		       ti->ti_bsc->sc_dvname, ti->ti_id, ti->ti_lun, ph, c);	else		printf("bs*(*:*): <%s> %s\n", ph, c);}voidbs_panic(bsc, c)	struct bs_softc *bsc;	u_char *c;{	panic("%s %s\n", bsc->sc_dvname, c);}/************************************************** * DEBUG FUNC **************************************************/#ifdef	BS_DEBUG_ROUTINEu_intbsr(addr)	u_int addr;{	outb(0xcc0, addr);	return inb(0xcc2);}u_intbsw(addr, data)	u_int addr;	int data;{	outb(0xcc0, addr);	outb(0xcc2, data);	return 0;}#endif	/* BS_DEBUG_ROUTINE */voidbs_debug_print_all(bsc)	struct bs_softc *bsc;{	struct targ_info *ti;	for (ti = bsc->sc_titab.tqh_first; ti; ti = ti->ti_tchain.tqe_next)		bs_debug_print(bsc, ti);}static u_char *phase[] ={	"FREE", "HOSTQUE", "DISC", "COMPMSG", "ATN", "DISCMSG", "SELECT",	"SELECTED", "RESELECTED", "MSGIN", "MSGOUT", "STATIN", "CMDOUT",	"DATA", "SATSEL", "SATRESEL", "SATSDP", "SATCOMPSEQ", "UNDEF",};voidbs_debug_print(bsc, ti)	struct bs_softc *bsc;	struct targ_info *ti;{	struct ccb *cb;	/* host stat */	printf("%s <DEBUG INFO> nexus %lx bs %lx bus status %lx \n",	       bsc->sc_dvname, (u_long) ti, (u_long) bsc->sc_nexus, (u_long) bsc->sc_busstat);	/* target stat */	if (ti)	{		struct sc_p *sp = &bsc->sc_p;		printf("%s(%d:%d) ph<%s> ", bsc->sc_dvname, ti->ti_id,		       ti->ti_lun, phase[(int) ti->ti_phase]);		printf("msgptr %x msg[0] %x status %x tqh %lx fl %x\n",		       (u_int) (ti->ti_msginptr), (u_int) (ti->ti_msgin[0]),		       ti->ti_status, (u_long) (cb = ti->ti_ctab.tqh_first),		       ti->ti_flags);		if (cb)			printf("cmdlen %x cmdaddr %lx cmd[0] %x\n",			       cb->cmdlen, (u_long) cb->cmd, (int) cb->cmd[0]);		printf("datalen %x dataaddr %lx seglen %x ",		       sp->datalen, (u_long) sp->data, sp->seglen);		if (cb)			printf("odatalen %x flags %x\n",				cb->datalen, cb->flags);		else			printf("\n");		printf("error flags %b\n", ti->ti_error, BSERRORBITS);	}}

⌨️ 快捷键说明

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