示例#1
0
/*
 * (Try to) put the drive online. This is done the first time the
 * drive is opened, or if it har fallen offline.
 */
int
rx_putonline(struct rx_softc *rx)
{
	struct	mscp *mp;
	struct	mscp_softc *mi = device_private(device_parent(rx->ra_dev));

	rx->ra_state = DK_CLOSED;
	mp = mscp_getcp(mi, MSCP_WAIT);
	mp->mscp_opcode = M_OP_ONLINE;
	mp->mscp_unit = rx->ra_hwunit;
	mp->mscp_cmdref = 1;
	*mp->mscp_addr |= MSCP_OWN | MSCP_INT;

	/* Poll away */
	bus_space_read_2(mi->mi_iot, mi->mi_iph, 0);
	if (tsleep(&rx->ra_state, PRIBIO, "rxonline", 100*100))
		rx->ra_state = DK_CLOSED;

	if (rx->ra_state == DK_CLOSED)
		return MSCP_FAILED;

	return MSCP_DONE;
}
示例#2
0
/*
 * (Try to) put the drive online. This is done the first time the
 * drive is opened, or if it has fallen offline.
 */
int
mt_putonline(struct mt_softc *mt)
{
	struct	mscp *mp;
	struct	mscp_softc *mi =
	    device_private(device_parent(mt->mt_dev));

	((volatile struct mt_softc *) mt)->mt_state = MT_OFFLINE;
	mp = mscp_getcp(mi, MSCP_WAIT);
	mp->mscp_opcode = M_OP_ONLINE;
	mp->mscp_unit = mt->mt_hwunit;
	mp->mscp_cmdref = (long)&mt->mt_state;
	*mp->mscp_addr |= MSCP_OWN | MSCP_INT;

	/* Poll away */
	bus_space_read_2(mi->mi_iot, mi->mi_iph, 0);
	if (tsleep(&mt->mt_state, PRIBIO, "mtonline", 240 * hz))
		return MSCP_FAILED;

	if ((volatile int)mt->mt_state != MT_ONLINE)
		return MSCP_FAILED;

	return MSCP_DONE;
}
示例#3
0
/*
 * Send a command to the tape drive. Wait until the command is
 * finished before returning.
 * This routine must only be called when there are no data transfer
 * active on this device. Can we be sure of this? Or does the ctlr
 * queue up all command packets and take them in sequential order?
 * It sure would be nice if my manual stated this... /ragge
 */
int
mtcmd(struct mt_softc *mt, int cmd, int count, int complete)
{
	struct mscp *mp;
	struct mscp_softc *mi = device_private(device_parent(mt->mt_dev));

	mp = mscp_getcp(mi, MSCP_WAIT);

	mt->mt_ioctlerr = 0;
	mp->mscp_unit = mt->mt_hwunit;
	mp->mscp_cmdref = -1;
	*mp->mscp_addr |= MSCP_OWN | MSCP_INT;

	switch (cmd) {
	case MTWEOF:
		mp->mscp_opcode = M_OP_WRITM;
		break;

	case MTBSF:
		mp->mscp_modifier = M_MD_REVERSE;
	case MTFSF:
		mp->mscp_opcode = M_OP_POS;
		mp->mscp_seq.seq_buffer = count;
		break;

	case MTBSR:
		mp->mscp_modifier = M_MD_REVERSE;
	case MTFSR:
		mp->mscp_opcode = M_OP_POS;
		mp->mscp_modifier |= M_MD_OBJCOUNT;
		mp->mscp_seq.seq_bytecount = count;
		break;

	case MTREW:
		mp->mscp_opcode = M_OP_POS;
		mp->mscp_modifier = M_MD_REWIND | M_MD_CLSEX;
		if (complete)
			mp->mscp_modifier |= M_MD_IMMEDIATE;
		mt->mt_serex = 0;
		break;

	case MTOFFL:
		mp->mscp_opcode = M_OP_AVAILABLE;
		mp->mscp_modifier = M_MD_UNLOAD | M_MD_CLSEX;
		mt->mt_serex = 0;
		break;

	case MTNOP:
		mp->mscp_opcode = M_OP_GETUNITST;
		break;

	case -1: /* Clear serious exception only */
		mp->mscp_opcode = M_OP_POS;
		mp->mscp_modifier = M_MD_CLSEX;
		mt->mt_serex = 0;
		break;

	default:
		printf("Bad ioctl %x\n", cmd);
		mp->mscp_opcode = M_OP_POS;
		break;
	}

	bus_space_read_2(mi->mi_iot, mi->mi_iph, 0);
	tsleep(&mt->mt_inuse, PRIBIO, "mtioctl", 0);
	return mt->mt_ioctlerr;
}