File:  [DragonFly] / src / sys / dev / disk / i386 / bs / Attic / bsfunc.c
Revision 1.5: download - view: text, annotated - select for diffs
Fri Feb 13 01:04:14 2004 UTC (10 years, 6 months ago) by joerg
Branches: MAIN
CVS tags: HEAD
Add __DragonFly__

    1: /*	$NecBSD: bsfunc.c,v 1.2 1997/10/31 17:43:37 honda Exp $	*/
    2: /*	$NetBSD$	*/
    3: /* $FreeBSD: src/sys/i386/isa/bs/bsfunc.c,v 1.7.2.2 2001/07/26 02:32:18 nyan Exp $ */
    4: /* $DragonFly: src/sys/dev/disk/i386/bs/bsfunc.c,v 1.5 2004/02/13 01:04:14 joerg Exp $ */
    5: /*
    6:  * [NetBSD for NEC PC98 series]
    7:  *  Copyright (c) 1994, 1995, 1996 NetBSD/pc98 porting staff.
    8:  *  All rights reserved.
    9:  * 
   10:  *  Redistribution and use in source and binary forms, with or without
   11:  *  modification, are permitted provided that the following conditions
   12:  *  are met:
   13:  *  1. Redistributions of source code must retain the above copyright
   14:  *     notice, this list of conditions and the following disclaimer.
   15:  *  2. Redistributions in binary form must reproduce the above copyright
   16:  *     notice, this list of conditions and the following disclaimer in the
   17:  *     documentation and/or other materials provided with the distribution.
   18:  *  3. The name of the author may not be used to endorse or promote products
   19:  *     derived from this software without specific prior written permission.
   20:  * 
   21:  * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
   22:  * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
   23:  * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
   24:  * DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT,
   25:  * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
   26:  * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
   27:  * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
   28:  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
   29:  * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
   30:  * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
   31:  * POSSIBILITY OF SUCH DAMAGE.
   32:  */
   33: /*
   34:  * Copyright (c) 1994, 1995, 1996 Naofumi HONDA.  All rights reserved.
   35:  */
   36: 
   37: #ifdef	__NetBSD__
   38: #include <i386/Cbus/dev/bs/bsif.h>
   39: #endif
   40: #if defined(__DragonFly__) || defined(__FreeBSD__)
   41: #include "bsif.h"
   42: #endif
   43: 
   44: #ifdef	BS_STATICS
   45: struct bs_statics bs_statics[NTARGETS];
   46: u_int bs_linkcmd_count[NTARGETS];
   47: u_int bs_bounce_used[NTARGETS];
   48: #endif	/* BS_STATICS */
   49: 
   50: #ifdef	BS_DEBUG
   51: int bs_debug_flag = 0;
   52: #endif	/* BS_DEBUG */
   53: 
   54: static void bs_print_syncmsg (struct targ_info *, char*);
   55: static void bs_timeout_target (struct targ_info *);
   56: static void bs_kill_msg (struct bsccb *cb);
   57: 
   58: static int bs_start_target (struct targ_info *);
   59: static int bs_check_target (struct targ_info *);
   60: 
   61: /*************************************************************
   62:  * CCB
   63:  ************************************************************/
   64: GENERIC_CCB_STATIC_ALLOC(bs, bsccb)
   65: GENERIC_CCB(bs, bsccb, ccb_chain)
   66: 
   67: /*************************************************************
   68:  * TIMEOUT
   69:  ************************************************************/
   70: static void
   71: bs_timeout_target(ti)
   72: 	struct targ_info *ti;
   73: {
   74: 	struct bs_softc *bsc = ti->ti_bsc;
   75: 
   76: 	ti->ti_error |= BSTIMEOUT;
   77: 	bsc->sc_flags |= BSRESET;
   78: 
   79: 	if (ti->ti_herrcnt ++ >= HARDRETRIES)
   80: 	{
   81: 		bs_printf(ti, "timeout", "async transfer!");
   82: 		ti->ti_syncmax.period = ti->ti_syncmax.offset = 0;
   83: 	}
   84: }
   85: 
   86: void
   87: bstimeout(arg)
   88: 	void *arg;
   89: {
   90: 	struct bs_softc *bsc = (struct bs_softc *) arg;
   91: 	struct targ_info *ti;
   92: 	struct bsccb *cb;
   93: 	int s;
   94: 
   95: 	s = splcam();
   96: 	bsc->sc_flags &= ~BSSTARTTIMEOUT;
   97: 
   98: 	/* check */
   99: 	if ((ti = bsc->sc_nexus) && (cb = ti->ti_ctab.tqh_first))
  100: 	{
  101: 		if ((cb->tc -= BS_TIMEOUT_CHECK_INTERVAL) < 0)
  102: 			bs_timeout_target(ti);
  103: 	}
  104: 	else for (ti = bsc->sc_titab.tqh_first; ti; ti = ti->ti_tchain.tqe_next)
  105: 	{
  106: 		if (bsc->sc_dtgnum && ti->ti_phase < DISCONNECTED)
  107: 			continue;
  108: 
  109: 		cb = ti->ti_ctab.tqh_first;
  110: 		if (cb && ((cb->tc -= BS_TIMEOUT_CHECK_INTERVAL) < 0))
  111: 			bs_timeout_target(ti);
  112: 	}
  113: 
  114: 	/* try to recover */
  115: 	if (bsc->sc_flags & BSRESET)
  116: 	{
  117: 		bs_debug_print_all(bsc);
  118: 		bs_printf(ti, "timeout", "bus hang up");
  119: 		bs_reset_nexus(bsc);
  120: 	}
  121: 
  122: 	bs_start_timeout(bsc);
  123: 	splx(s);
  124: }
  125: 
  126: /**************************************************
  127:  * MAKE CCB & MSG CCB
  128:  *************************************************/
  129: static u_int8_t cmd_unit_ready[6];
  130: 
  131: struct bsccb *
  132: bs_make_internal_ccb(ti, lun, cmd, cmdlen, data, datalen, flags, timeout)
  133: 	struct targ_info *ti;
  134: 	u_int lun;
  135: 	u_int8_t *cmd;
  136: 	u_int cmdlen;
  137: 	u_int8_t *data;
  138: 	u_int datalen;
  139: 	u_int flags;
  140: 	int timeout;
  141: {
  142: 	struct bsccb *cb;
  143: 
  144: 	if ((cb = bs_get_ccb()) == NULL)
  145: 		bs_panic(ti->ti_bsc, "can not get ccb mem");
  146: 
  147: 	cb->ccb = NULL;
  148: 	cb->lun = lun;
  149: 	cb->cmd = (cmd ? cmd : cmd_unit_ready);
  150: 	cb->cmdlen = (cmd ? cmdlen : sizeof(cmd_unit_ready));
  151: 	cb->data = data;
  152: 	cb->datalen = (data ? datalen : 0);
  153: 	cb->msgoutlen = 0;
  154: 	cb->bsccb_flags = flags & BSCFLAGSMASK;
  155: 	bs_targ_flags(ti, cb);
  156: 	cb->rcnt = 0;
  157: 	cb->tcmax = (timeout > BS_DEFAULT_TIMEOUT_SECOND ? timeout :
  158: 				BS_DEFAULT_TIMEOUT_SECOND);
  159: 
  160: 	TAILQ_INSERT_HEAD(&ti->ti_ctab, cb, ccb_chain);
  161: 
  162: 	return cb;
  163: }
  164: 
  165: struct bsccb *
  166: bs_make_msg_ccb(ti, lun, cb, msg, timex)
  167: 	struct targ_info *ti;
  168: 	u_int lun;
  169: 	struct bsccb *cb;
  170: 	struct msgbase *msg;
  171: 	u_int timex;
  172: {
  173: 	u_int flags;
  174: 
  175: 	flags = BSFORCEIOPOLL | msg->flag;
  176: 	if (cb == NULL)
  177: 		cb = bs_make_internal_ccb(ti, lun, NULL, 0, NULL, 0,
  178: 					   flags, timex);
  179: 	else
  180: 		cb->bsccb_flags |= flags & BSCFLAGSMASK;
  181: 
  182: 	cb->msgoutlen = msg->msglen;
  183: 	bcopy(msg->msg, cb->msgout, msg->msglen);
  184: 	return cb;
  185: }
  186: 
  187: int
  188: bs_send_msg(ti, lun, msg, timex)
  189: 	struct targ_info *ti;
  190: 	u_int lun;
  191: 	struct msgbase *msg;
  192: 	int timex;
  193: {
  194: 	struct bsccb *cb;
  195: 
  196: 	cb = bs_make_msg_ccb(ti, lun, NULL, msg, timex);
  197: 	bscmdstart(ti, BSCMDSTART);
  198: 	return bs_scsi_cmd_poll(ti, cb);
  199: }
  200: 
  201: static void
  202: bs_kill_msg(cb)
  203: 	struct bsccb *cb;
  204: {
  205: 	cb->msgoutlen = 0;
  206: }
  207: 
  208: /**************************************************
  209:  * MAKE SENSE CCB
  210:  **************************************************/
  211: struct bsccb *
  212: bs_request_sense(ti)
  213: 	struct targ_info *ti;
  214: {
  215: 	struct bsccb *cb;
  216: 
  217: 	bzero(ti->scsi_cmd, sizeof(struct scsi_sense));
  218: 	bzero(&ti->sense, sizeof(struct scsi_sense_data));
  219: 	ti->scsi_cmd[0] = REQUEST_SENSE;
  220: 	ti->scsi_cmd[1] = (ti->ti_lun << 5);
  221: 	ti->scsi_cmd[4] = sizeof(struct scsi_sense_data);
  222: 	cb = bs_make_internal_ccb(ti, ti->ti_lun, ti->scsi_cmd,
  223: 				     sizeof(struct scsi_sense),
  224: 				     (u_int8_t *) & ti->sense,
  225: 				     sizeof(struct scsi_sense_data),
  226: 				     BSFORCEIOPOLL,
  227: 				     BS_DEFAULT_TIMEOUT_SECOND);
  228: 	cb->bsccb_flags |= BSSENSECCB;
  229: 	return cb;
  230: }
  231: 
  232: /**************************************************
  233:  * SYNC MSG
  234:  *************************************************/
  235: /* sync neg */
  236: int
  237: bs_start_syncmsg(ti, cb, flag)
  238: 	struct targ_info *ti;
  239: 	struct bsccb *cb;
  240: 	int flag;
  241: {
  242: 	struct syncdata *negp, *maxp;
  243: 	struct msgbase msg;
  244: 	u_int lun;
  245: 
  246: 	negp = &ti->ti_syncnow;
  247: 	maxp = &ti->ti_syncmax;
  248: 
  249: 	ti->ti_state = BS_TARG_SYNCH;
  250: 
  251: 	if (flag == BS_SYNCMSG_REQUESTED)
  252: 	{
  253: 		if (negp->offset > maxp->offset)
  254: 			negp->offset = maxp->offset;
  255: 		if (negp->offset != 0 && negp->period < maxp->period)
  256: 			negp->period = maxp->period;
  257: 
  258: 		msg.flag = 0;
  259: 		lun = ti->ti_lun;
  260: 		if (cb == NULL)
  261: 			cb = ti->ti_ctab.tqh_first;
  262: 	}
  263: 	else if (ti->ti_cfgflags & BS_SCSI_SYNC)
  264: 	{
  265: 		negp->offset = maxp->offset;
  266: 		negp->period = maxp->period;
  267: 
  268: 		msg.flag = BSERROROK;
  269: 		lun = 0;
  270: 	}
  271: 	else
  272: 	{
  273: 		ti->ti_state = BS_TARG_RDY;
  274: 		return COMPLETE;
  275: 	}
  276: 
  277: 	BS_SETUP_SYNCSTATE(flag);
  278: 	msg.msg[0] = MSG_EXTEND;
  279: 	msg.msg[1] = MSG_EXTEND_SYNCHLEN;
  280: 	msg.msg[2] = MSG_EXTEND_SYNCHCODE;
  281: 	msg.msg[3] = negp->period;
  282: 	msg.msg[4] = negp->offset;
  283: 	msg.msglen = MSG_EXTEND_SYNCHLEN + 2;
  284: 
  285: 	bs_make_msg_ccb(ti, lun, cb, &msg, BS_SYNC_TIMEOUT);
  286: 	return COMPLETE;
  287: }
  288: 
  289: static void
  290: bs_print_syncmsg(ti, s)
  291: 	struct targ_info *ti;
  292: 	char *s;
  293: {
  294: 	struct bs_softc *bsc = ti->ti_bsc;
  295: 	struct syncdata *negp;
  296: 	u_int speed;
  297: 
  298: 	negp = &ti->ti_syncnow;
  299: 	speed = (negp->offset && negp->period) ?
  300: 		(2500 / ((u_int) negp->period)) : 0;
  301: 
  302: 	printf("%s(%d:%d): <%s> ", bsc->sc_dvname, ti->ti_id, ti->ti_lun, s);
  303: 	printf("period 0x%x offset %d chip (0x%x)", negp->period, negp->offset,
  304: 		ti->ti_sync);
  305: 	if (speed)
  306: 		printf(" %d.%d M/s", speed / 10, speed % 10);
  307: 	printf("\n");
  308: }
  309: 
  310: int
  311: bs_analyze_syncmsg(ti, cb)
  312: 	struct targ_info *ti;
  313: 	struct bsccb *cb;
  314: {
  315: 	struct bs_softc *bsc = ti->ti_bsc;
  316: 	u_int8_t ans = ti->ti_syncnow.state;
  317: 	struct syncdata *negp, *maxp;
  318: 	struct syncdata bdata;
  319: 	char *s = NULL;
  320: 	u_int8_t period;
  321: 
  322: 	negp = &ti->ti_syncnow;
  323: 	bdata = *negp;
  324: 	maxp = &ti->ti_syncmax;
  325: 
  326: 	switch(ans)
  327: 	{
  328: 	case BS_SYNCMSG_REJECT:
  329: 		period = 0;
  330: 		s = "msg reject";
  331: 		break;
  332: 
  333: 	case BS_SYNCMSG_ASSERT:
  334: 		period = 0;
  335: 		s = "no msg";
  336: 		break;
  337: 
  338: 	default:
  339: 		if (negp->offset != 0 && negp->period < maxp->period)
  340: 		{
  341: 			period = 0xff;
  342: 			s = "illegal(period)";
  343: 		}
  344: 		else if (negp->offset > maxp->offset)
  345: 		{
  346: 			period = 0xff;
  347: 			s = "illegal(offset)";
  348: 		}
  349: 		else
  350: 			period = negp->offset ? negp->period : 0;
  351: 		break;
  352: 	}
  353: 
  354: 	if (s == NULL)
  355: 	{
  356: 		bshw_adj_syncdata(negp);
  357: 		*maxp = *negp;
  358: 
  359: 		if (ans == BS_SYNCMSG_REQUESTED)
  360: 			s = "requested";
  361: 		else
  362: 			s = negp->offset ? "synchronous" : "async";
  363: 	}
  364: 	else
  365: 	{
  366: 		negp->offset = maxp->offset = 0;
  367: 		bshw_adj_syncdata(negp);
  368: 		bshw_adj_syncdata(maxp);
  369: 	}
  370: 
  371: 	/* really setup hardware */
  372: 	bshw_set_synchronous(bsc, ti);
  373: 	if (cb == NULL || (period >= negp->period && period <= negp->period + 2))
  374: 	{
  375: 		bs_print_syncmsg(ti, s);
  376: 		BS_SETUP_TARGSTATE(BS_TARG_RDY);
  377: 		BS_SETUP_SYNCSTATE(BS_SYNCMSG_NULL);
  378: 		if (cb)
  379: 			bs_kill_msg(cb);
  380: 
  381: 		return 0;
  382: 	}
  383: 	else
  384: 	{
  385: 		bs_printf(ti, "bs_analyze_syncmsg",
  386: 			  "sync(period) mismatch, retry neg...");
  387: 		printf("expect(%d:0x%x) => reply(%d:0x%x)\n",
  388: 			bdata.offset, bdata.period, negp->offset, negp->period);
  389: 
  390: 		bs_start_syncmsg(ti, cb, BS_SYNCMSG_ASSERT);
  391: 		return EINVAL;
  392: 	}
  393: }
  394: 
  395: /**************************************************
  396:  * ABORT AND RESET MSG
  397:  **************************************************/
  398: /* send device reset msg and wait */
  399: void
  400: bs_reset_device(ti)
  401: 	struct targ_info *ti;
  402: {
  403: 	struct msgbase msg;
  404: 
  405: 	msg.msglen = 1;
  406: 	msg.msg[0] = MSG_RESET;
  407: 	msg.flag = 0;
  408: 
  409: 	bs_send_msg(ti, 0, &msg, 0);
  410: 
  411: 	delay(ti->ti_bsc->sc_RSTdelay);
  412: 	bs_check_target(ti);
  413: }
  414: 
  415: /* send abort msg */
  416: struct bsccb *
  417: bs_force_abort(ti)
  418: 	struct targ_info *ti;
  419: {
  420: 	struct bs_softc *bsc = ti->ti_bsc;
  421: 	struct msgbase msg;
  422: 	struct bsccb *cb = ti->ti_ctab.tqh_first;
  423: 	u_int lun;
  424: 
  425: 	if (cb)
  426: 	{
  427: 		lun = cb->lun;
  428: 		cb->rcnt++;
  429: 	}
  430: 	else
  431: 		lun = 0;
  432: 
  433: 	msg.msglen = 1;
  434: 	msg.msg[0] = MSG_ABORT;
  435: 	msg.flag = 0;
  436: 
  437: 	cb = bs_make_msg_ccb(ti, lun, NULL, &msg, 0);
  438: 	bscmdstart(ti, BSCMDSTART);
  439: 
  440: 	if (bsc->sc_nexus == ti)
  441: 		BS_LOAD_SDP
  442: 
  443: 	return cb;
  444: }
  445: 
  446: /**************************************************
  447:  * COMPLETE SCSI BUS RESET
  448:  *************************************************/
  449: /*
  450:  * XXX:
  451:  * 1) reset scsi bus (ie. all target reseted).
  452:  * 2) chip reset.
  453:  * 3) check target status.
  454:  * 4) sync neg with all targets.
  455:  * 5) setup sync reg in host.
  456:  * 6) recover previous nexus.
  457:  */
  458: void
  459: bs_scsibus_start(bsc)
  460: 	struct bs_softc *bsc;
  461: {
  462: 	struct targ_info *ti, *nextti = NULL;
  463: 	int error = HASERROR;
  464: 	u_int querm, bits, skip = 0;
  465: 
  466: 	querm = (bsc->sc_hstate == BSC_BOOTUP);
  467: 	bsc->sc_hstate = BSC_TARG_CHECK;
  468: 
  469: 	/* target check */
  470: 	do
  471: 	{
  472: 		if (error != COMPLETE)
  473: 		{
  474: 			printf("%s: scsi bus reset and try to restart ...",
  475: 			       bsc->sc_dvname);
  476: 			bshw_smitabort(bsc);
  477: 			bshw_dmaabort(bsc, NULL);
  478: 			bshw_chip_reset(bsc);
  479: 			bshw_bus_reset(bsc);
  480: 			bshw_chip_reset(bsc);
  481: 			printf(" done. scsi bus ready.\n");
  482: 			nextti = bsc->sc_titab.tqh_first;
  483: 			error = COMPLETE;
  484: 		}
  485: 
  486: 		if ((ti = nextti) == NULL)
  487: 			break;
  488: 		nextti = ti->ti_tchain.tqe_next;
  489: 
  490: 		bits = (1 << ti->ti_id);
  491: 		if (skip & bits)
  492: 			continue;
  493: 
  494: 		if ((error = bs_check_target(ti)) != COMPLETE)
  495: 		{
  496: 			if (querm)
  497: 			{
  498: 				TAILQ_REMOVE(&bsc->sc_titab, ti, ti_tchain);
  499: 				bsc->sc_openf &= ~bits;
  500: 			}
  501: 
  502: 			if (error == NOTARGET)
  503: 				error = COMPLETE;
  504: 
  505: 			skip |= bits;
  506: 		}
  507: 	}
  508: 	while (1);
  509: 
  510: 	/* ok now ready */
  511: 	bsc->sc_hstate = BSC_RDY;
  512: 
  513: 	/* recover */
  514: 	for (ti = bsc->sc_titab.tqh_first; ti; ti = ti->ti_tchain.tqe_next)
  515: 	{
  516: 		ti->ti_ctab = ti->ti_bctab;
  517: 		TAILQ_INIT(&ti->ti_bctab);
  518: 		if (ti->ti_ctab.tqh_first)
  519: 			bscmdstart(ti, BSCMDSTART);
  520: 	}
  521: }
  522: 
  523: void
  524: bs_reset_nexus(bsc)
  525: 	struct bs_softc *bsc;
  526: {
  527: 	struct targ_info *ti;
  528: 	struct bsccb *cb;
  529: 
  530: 	bsc->sc_flags &= ~(BSRESET | BSUNDERRESET);
  531: 	if (bsc->sc_poll)
  532: 	{
  533: 		bsc->sc_flags |= BSUNDERRESET;
  534: 		return;
  535: 	}
  536: 
  537: 	/* host state clear */
  538: 	BS_HOST_TERMINATE
  539: 	BS_SETUP_MSGPHASE(FREE)
  540: 	bsc->sc_dtgnum = 0;
  541: 
  542: 	/* target state clear */
  543: 	for (ti = bsc->sc_titab.tqh_first; ti; ti = ti->ti_tchain.tqe_next)
  544: 	{
  545: 		if (ti->ti_state == BS_TARG_SYNCH)
  546: 			bs_analyze_syncmsg(ti, NULL);
  547: 		if (ti->ti_state > BS_TARG_START)
  548: 			BS_SETUP_TARGSTATE(BS_TARG_START);
  549: 
  550: 		BS_SETUP_PHASE(UNDEF)
  551: 		bs_hostque_delete(bsc, ti);
  552: 		if ((cb = ti->ti_ctab.tqh_first) != NULL)
  553: 		{
  554: 			if (bsc->sc_hstate == BSC_TARG_CHECK)
  555: 			{
  556: 				ti->ti_error |= BSFATALIO;
  557: 				bscmddone(ti);
  558: 			}
  559: 			else if (cb->rcnt >= bsc->sc_retry)
  560: 			{
  561: 				ti->ti_error |= BSABNORMAL;
  562: 				bscmddone(ti);
  563: 			}
  564: 			else if (ti->ti_error)
  565: 				cb->rcnt++;
  566: 		}
  567: 
  568: 		/* target state clear */
  569: 		BS_SETUP_PHASE(FREE)
  570: 		BS_SETUP_SYNCSTATE(BS_SYNCMSG_NULL);
  571: 		ti->ti_flags &= ~BSCFLAGSMASK;
  572: 		ti->ti_msgout = 0;
  573: #ifdef	BS_DIAG
  574: 		ti->ti_flags &= ~BSNEXUS;
  575: #endif	/* BS_DIAG */
  576: 
  577: 		for ( ; cb; cb = cb->ccb_chain.tqe_next)
  578: 		{
  579: 			bs_kill_msg(cb);
  580: 			cb->bsccb_flags &= ~(BSITSDONE | BSCASTAT);
  581: 			cb->error = 0;
  582: 		}
  583: 
  584: 		if (bsc->sc_hstate != BSC_TARG_CHECK &&
  585: 		    ti->ti_bctab.tqh_first == NULL)
  586: 			ti->ti_bctab = ti->ti_ctab;
  587: 
  588: 		TAILQ_INIT(&ti->ti_ctab);
  589: 	}
  590: 
  591: 	if (bsc->sc_hstate != BSC_TARG_CHECK)
  592: 		bs_scsibus_start(bsc);
  593: }
  594: 
  595: /**************************************************
  596:  * CHECK TARGETS AND START TARGETS
  597:  *************************************************/
  598: static int
  599: bs_start_target(ti)
  600: 	struct targ_info *ti;
  601: {
  602: 	struct bsccb *cb;
  603: 	struct scsi_start_stop_unit cmd;
  604: 
  605: 	bzero(&cmd, sizeof(struct scsi_start_stop_unit));
  606: 	cmd.opcode = START_STOP;
  607: 	cmd.how = SSS_START;
  608: 	ti->ti_lun = 0;
  609: 	cb = bs_make_internal_ccb(ti, 0, (u_int8_t *) &cmd,
  610: 				   sizeof(struct scsi_start_stop_unit),
  611: 				   NULL, 0, BSFORCEIOPOLL, BS_MOTOR_TIMEOUT);
  612: 	bscmdstart(ti, BSCMDSTART);
  613: 	return bs_scsi_cmd_poll(ti, cb);
  614: }
  615: 
  616: /* test unit ready and check ATN msgout response */
  617: static int
  618: bs_check_target(ti)
  619: 	struct targ_info *ti;
  620: {
  621: 	struct bs_softc *bsc = ti->ti_bsc;
  622: 	struct scsi_inquiry scsi_cmd;
  623: 	struct scsi_inquiry_data scsi_inquiry_data;
  624: 	struct bsccb *cb;
  625: 	int count, retry = bsc->sc_retry;
  626: 	int s, error = COMPLETE;
  627: 
  628: 	ti->ti_lun = 0;
  629: 	bsc->sc_retry = 2;
  630: 	s = splcam();
  631: 
  632: 	/* inquiry */
  633: 	bzero(&scsi_cmd, sizeof(scsi_cmd));
  634: 	scsi_cmd.opcode = INQUIRY;
  635: 	scsi_cmd.length = (u_int8_t) sizeof(struct scsi_inquiry_data);
  636: 	cb = bs_make_internal_ccb(ti, 0,
  637: 				   (u_int8_t *) &scsi_cmd, sizeof(scsi_cmd),
  638: 				   (u_int8_t *) &scsi_inquiry_data,
  639: 				   sizeof(scsi_inquiry_data),
  640: 				   BSFORCEIOPOLL, BS_STARTUP_TIMEOUT);
  641: 	bscmdstart(ti, BSCMDSTART);
  642: 	error = bs_scsi_cmd_poll(ti, cb);
  643: 	if (error != COMPLETE || (ti->ti_error & BSSELTIMEOUT))
  644: 		goto done;
  645: 	ti->targ_type = scsi_inquiry_data.device;
  646: 	ti->targ_support = scsi_inquiry_data.flags;
  647: 
  648: 	/* test unit ready twice */
  649: 	for (count = 0; count < 2; count++)
  650: 	{
  651: 		cb = bs_make_internal_ccb(ti, 0, NULL, 0, NULL, 0,
  652: 					 BSFORCEIOPOLL, BS_STARTUP_TIMEOUT);
  653: 		bscmdstart(ti, BSCMDSTART);
  654: 		error = bs_scsi_cmd_poll(ti, cb);
  655: 		if (error != COMPLETE || (ti->ti_error & BSSELTIMEOUT))
  656: 			goto done;
  657: 	}
  658: 
  659: 	if (cb->bsccb_flags & BSCASTAT)
  660: 		bs_printf(ti, "check", "could not clear CA state");
  661: 	ti->ti_error = 0;
  662: 
  663: done:
  664: 	bsc->sc_retry = retry;
  665: 
  666: 	if (ti->ti_error & BSSELTIMEOUT)
  667: 		error = NOTARGET;
  668: 
  669: 	if (error == COMPLETE)
  670: 		error = bs_start_target(ti);
  671: 
  672: 	splx(s);
  673: 	return error;
  674: }
  675: 
  676: /**************************************************
  677:  * TARGET CONTROL
  678:  **************************************************/
  679: struct targ_info *
  680: bs_init_target_info(bsc, target)
  681: 	struct bs_softc *bsc;
  682: 	int target;
  683: {
  684: 	struct targ_info *ti;
  685: 
  686: 	ti = malloc(sizeof(struct targ_info), M_DEVBUF, M_NOWAIT);
  687: 	if (ti == NULL)
  688: 	{
  689: 		bs_printf(NULL, "bs_init_targ_info", "no target info memory");
  690: 		return ti;
  691: 	}
  692: 
  693: 	bzero(ti, sizeof(*ti));
  694: 
  695: 	ti->ti_bsc = bsc;
  696: 	ti->ti_id = target;
  697: 	ti->sm_offset = 0;
  698: 	ti->ti_cfgflags = BS_SCSI_NOPARITY | BS_SCSI_NOSAT;
  699: 	ti->ti_mflags = ~(BSSAT | BSDISC | BSSMIT | BSLINK);
  700: 	BS_SETUP_TARGSTATE(BS_TARG_CTRL);
  701: 
  702: 	TAILQ_INIT(&ti->ti_ctab);
  703: 
  704: 	bs_alloc_buf(ti);
  705: 	if (ti->bounce_addr == NULL)
  706: 	{
  707: 		free(ti, M_DEVBUF);
  708: 		return NULL;
  709: 	}
  710: 
  711: 	TAILQ_INSERT_TAIL(&bsc->sc_titab, ti, ti_tchain);
  712: 	bsc->sc_ti[target] = ti;
  713: 	bsc->sc_openf |= (1 << target);
  714: 
  715: 	return ti;
  716: }
  717: 
  718: void
  719: bs_setup_ctrl(ti, quirks, flags)
  720: 	struct targ_info *ti;
  721: 	u_int quirks;
  722: 	u_int flags;
  723: {
  724: 	struct bs_softc *bsc = ti->ti_bsc;
  725: 	u_int offset, period, maxperiod;
  726: 
  727: 	if (ti->ti_state == BS_TARG_CTRL)
  728: 	{
  729: 		ti->ti_cfgflags = BS_SCSI_POSITIVE;
  730: 		ti->ti_syncmax.offset = BSHW_MAX_OFFSET;
  731: 		BS_SETUP_TARGSTATE(BS_TARG_START);
  732: 	}
  733: 	else
  734: 		flags |= ti->ti_cfgflags & BS_SCSI_NEGATIVE;
  735: 
  736: #ifdef	BS_TARG_SAFEMODE
  737: 	if (ti->targ_type != 0)
  738: 	{
  739: 		flags &= ~(BS_SCSI_DISC | BS_SCSI_SYNC);
  740: 		flags |= BS_SCSI_NOPARITY;
  741: 	}
  742: #endif
  743: 
  744: #ifdef	SDEV_NODISC
  745: 	if (quirks & SDEV_NODISC)
  746: 		flags &= ~BS_SCSI_DISC;
  747: #endif
  748: #ifdef	SDEV_NOPARITY
  749: 	if (quirks & SDEV_NOPARITY)
  750: 		flags |= BS_SCSI_NOPARITY;
  751: #endif
  752: #ifdef	SDEV_NOCMDLNK
  753: 	if (quirks & SDEV_NOCMDLNK)
  754: 		flags &= ~BS_SCSI_LINK;
  755: #endif
  756: #ifdef	SDEV_ASYNC
  757: 	if (quirks & SDEV_ASYNC)
  758: 		flags &= ~BS_SCSI_SYNC;
  759: #endif
  760: #ifdef	SDEV_AUTOSAVE
  761: 	if (quirks & SDEV_AUTOSAVE)
  762: 		flags |= BS_SCSI_SAVESP;
  763: #endif
  764: #ifdef	SD_Q_NO_SYNC
  765: 	if (quirks & SD_Q_NO_SYNC)
  766: 		flags &= ~BS_SCSI_SYNC;
  767: #endif
  768: 
  769: 	if ((flags & BS_SCSI_DISC) == 0 ||
  770: 	    (ti->targ_support & SID_Linked) == 0)
  771: 		flags &= ~BS_SCSI_LINK;
  772: 
  773: 	ti->sm_offset = (flags & BS_SCSI_NOSMIT) ?  0 : bsc->sm_offset;
  774: 	if (ti->sm_offset == 0)
  775: 		flags |= BS_SCSI_NOSMIT;
  776: 	else if (bsc->sc_cfgflags & BSC_SMITSAT_DISEN)
  777: 		flags |= BS_SCSI_NOSAT;
  778: 
  779: 	flags &= (ti->ti_cfgflags & BS_SCSI_POSITIVE) | (~BS_SCSI_POSITIVE);
  780: 	ti->ti_cfgflags = flags;
  781: 
  782: 	/* calculate synch setup */
  783: 	period = BS_SCSI_PERIOD(flags);
  784: 	offset = (flags & BS_SCSI_SYNC) ? BS_SCSI_OFFSET(flags) : 0;
  785: 
  786: 	maxperiod = (bsc->sc_cspeed & IDR_FS_16_20) ? 100 : 50;
  787: 	if (period > maxperiod)
  788: 		period = maxperiod;
  789: 
  790: 	if (period)
  791: 		period = 2500 / period;
  792: 
  793: 	if (ti->ti_syncmax.offset > offset)
  794: 		ti->ti_syncmax.offset = offset;
  795: 	if (ti->ti_syncmax.period < period)
  796: 		ti->ti_syncmax.period = period;
  797: 
  798: 	bshw_adj_syncdata(&ti->ti_syncmax);
  799: 
  800: 	/* finally report our info */
  801: 	printf("%s(%d:%d): {%d:0x%x:0x%x:%s} flags 0x%b\n",
  802: 		bsc->sc_dvname, ti->ti_id, ti->ti_lun,
  803: 	       (u_int) ti->targ_type,
  804: 	       (u_int) ti->targ_support,
  805: 	       (u_int) ti->bounce_size,
  806: 	       (flags & BS_SCSI_NOSMIT) ? "dma" : "pdma",
  807: 		flags, BS_SCSI_BITS);
  808: 
  809: 	/* internal representation */
  810: 	ti->ti_mflags = ~0;
  811: 	if ((ti->ti_cfgflags & BS_SCSI_DISC) == 0)
  812: 		ti->ti_mflags &= ~BSDISC;
  813: 	if ((ti->ti_cfgflags & BS_SCSI_LINK) == 0)
  814: 		ti->ti_mflags &= ~BSLINK;
  815: 	if (ti->ti_cfgflags & BS_SCSI_NOSAT)
  816: 		ti->ti_mflags &= ~BSSAT;
  817: 	if (ti->ti_cfgflags & BS_SCSI_NOSMIT)
  818: 		ti->ti_mflags &= ~BSSMIT;
  819: }
  820: 
  821: /**************************************************
  822:  * MISC
  823:  **************************************************/
  824: void
  825: bs_printf(ti, ph, c)
  826: 	struct targ_info *ti;
  827: 	char *ph;
  828: 	char *c;
  829: {
  830: 
  831: 	if (ti)
  832: 		printf("%s(%d:%d): <%s> %s\n",
  833: 		       ti->ti_bsc->sc_dvname, ti->ti_id, ti->ti_lun, ph, c);
  834: 	else
  835: 		printf("bs*(*:*): <%s> %s\n", ph, c);
  836: }
  837: 
  838: void
  839: bs_panic(bsc, c)
  840: 	struct bs_softc *bsc;
  841: 	u_char *c;
  842: {
  843: 
  844: 	panic("%s %s\n", bsc->sc_dvname, c);
  845: }
  846: 
  847: /**************************************************
  848:  * DEBUG FUNC
  849:  **************************************************/
  850: #ifdef	BS_DEBUG_ROUTINE
  851: u_int
  852: bsr(addr)
  853: 	u_int addr;
  854: {
  855: 
  856: 	outb(0xcc0, addr);
  857: 	return inb(0xcc2);
  858: }
  859: 
  860: u_int
  861: bsw(addr, data)
  862: 	u_int addr;
  863: 	int data;
  864: {
  865: 
  866: 	outb(0xcc0, addr);
  867: 	outb(0xcc2, data);
  868: 	return 0;
  869: }
  870: #endif	/* BS_DEBUG_ROUTINE */
  871: 
  872: void
  873: bs_debug_print_all(bsc)
  874: 	struct bs_softc *bsc;
  875: {
  876: 	struct targ_info *ti;
  877: 
  878: 	for (ti = bsc->sc_titab.tqh_first; ti; ti = ti->ti_tchain.tqe_next)
  879: 		bs_debug_print(bsc, ti);
  880: }
  881: 
  882: static u_char *phase[] =
  883: {
  884: 	"FREE", "HOSTQUE", "DISC", "COMPMSG", "ATN", "DISCMSG", "SELECT",
  885: 	"SELECTED", "RESELECTED", "MSGIN", "MSGOUT", "STATIN", "CMDOUT",
  886: 	"DATA", "SATSEL", "SATRESEL", "SATSDP", "SATCOMPSEQ", "UNDEF",
  887: };
  888: 
  889: void
  890: bs_debug_print(bsc, ti)
  891: 	struct bs_softc *bsc;
  892: 	struct targ_info *ti;
  893: {
  894: 	struct bsccb *cb;
  895: 
  896: 	/* host stat */
  897: 	printf("%s <DEBUG INFO> nexus %lx bs %lx bus status %lx \n",
  898: 	       bsc->sc_dvname, (u_long) ti, (u_long) bsc->sc_nexus, (u_long) bsc->sc_busstat);
  899: 
  900: 	/* target stat */
  901: 	if (ti)
  902: 	{
  903: 		struct sc_p *sp = &bsc->sc_p;
  904: 
  905: 		printf("%s(%d:%d) ph<%s> ", bsc->sc_dvname, ti->ti_id,
  906: 		       ti->ti_lun, phase[(int) ti->ti_phase]);
  907: 		printf("msgptr %x msg[0] %x status %x tqh %lx fl %x\n",
  908: 		       (u_int) (ti->ti_msginptr), (u_int) (ti->ti_msgin[0]),
  909: 		       ti->ti_status, (u_long) (cb = ti->ti_ctab.tqh_first),
  910: 		       ti->ti_flags);
  911: 		if (cb)
  912: 			printf("cmdlen %x cmdaddr %lx cmd[0] %x\n",
  913: 			       cb->cmdlen, (u_long) cb->cmd, (int) cb->cmd[0]);
  914: 		printf("datalen %x dataaddr %lx seglen %x ",
  915: 		       sp->datalen, (u_long) sp->data, sp->seglen);
  916: 		if (cb)
  917: 			printf("odatalen %x flags %x\n",
  918: 				cb->datalen, cb->bsccb_flags);
  919: 		else
  920: 			printf("\n");
  921: 		printf("error flags %b\n", ti->ti_error, BSERRORBITS);
  922: 	}
  923: }