#include <u.h>
#include <libc.h>
#include <disk.h>
#include "scsireq.h"

long
SRblank(ScsiReq *rp, uchar type, uchar track)
{
	uchar cmd[12];

	memset(cmd, 0, sizeof(cmd));
	cmd[0] = ScmdBlank;
	cmd[1] = type;
	cmd[2] = track>>24;
	cmd[3] = track>>16;
	cmd[4] = track>>8;
	cmd[5] = track;
	rp->cmd.p = cmd;
	rp->cmd.count = sizeof(cmd);
	rp->data.p = cmd;
	rp->data.count = 0;
	rp->data.write = 1;
	return SRrequest(rp);
}

long
SRsynccache(ScsiReq *rp)
{
	uchar cmd[10];

	memset(cmd, 0, sizeof(cmd));
	cmd[0] = ScmdSynccache;
	rp->cmd.p = cmd;
	rp->cmd.count = sizeof(cmd);
	rp->data.p = cmd;
	rp->data.count = 0;
	rp->data.write = 1;
	return SRrequest(rp);
}

long
SRTOC(ScsiReq *rp, void *data, int nbytes, uchar format, uchar track)
{
	uchar cmd[10];

	memset(cmd, 0, sizeof(cmd));
	cmd[0] = ScmdRTOC;
	cmd[2] = format;
	cmd[6] = track;
	cmd[7] = nbytes>>8;
	cmd[8] = nbytes;
	rp->cmd.p = cmd;
	rp->cmd.count = sizeof(cmd);
	rp->data.p = data;
	rp->data.count = nbytes;
	rp->data.write = 0;
	return SRrequest(rp);
}

long
SRrdiscinfo(ScsiReq *rp, void *data, int nbytes)
{
	uchar cmd[10];

	memset(cmd, 0, sizeof(cmd));
	cmd[0] = ScmdRdiscinfo;
	cmd[7] = nbytes>>8;
	cmd[8] = nbytes;
	rp->cmd.p = cmd;
	rp->cmd.count = sizeof(cmd);
	rp->data.p = data;
	rp->data.count = nbytes;
	rp->data.write = 0;
	return SRrequest(rp);
}

long
SRrtrackinfo(ScsiReq *rp, void *data, int nbytes, int track)
{
	uchar cmd[10];

	memset(cmd, 0, sizeof(cmd));
	cmd[0] = ScmdRtrackinfo;
	cmd[1] = 0x01;
	cmd[2] = track>>24;
	cmd[3] = track>>16;
	cmd[4] = track>>8;
	cmd[5] = track;
	cmd[7] = nbytes>>8;
	cmd[8] = nbytes;
	rp->cmd.p = cmd;
	rp->cmd.count = sizeof(cmd);
	rp->data.p = data;
	rp->data.count = nbytes;
	rp->data.write = 0;
	return SRrequest(rp);
}

long
SRfwaddr(ScsiReq *rp, uchar track, uchar mode, uchar npa, uchar *data)
{
	uchar cmd[10];

	memset(cmd, 0, sizeof(cmd));
	cmd[0] = ScmdFwaddr;
	cmd[2] = track;
	cmd[3] = mode;
	cmd[7] = npa;
	rp->cmd.p = cmd;
	rp->cmd.count = sizeof(cmd);
	rp->data.p = data;
	rp->data.count = MaxDirData;
	rp->data.write = 0;
	return SRrequest(rp);
}

long
SRtreserve(ScsiReq *rp, long nbytes)
{
	uchar cmd[10];
	long n;

	if((nbytes % rp->lbsize)){
		rp->status = Status_BADARG;
		return -1;
	}
	memset(cmd, 0, sizeof(cmd));
	cmd[0] = ScmdTreserve;
	n = nbytes/rp->lbsize;
	cmd[5] = n>>24;
	cmd[6] = n>>16;
	cmd[7] = n>>8;
	cmd[8] = n;
	rp->cmd.p = cmd;
	rp->cmd.count = sizeof(cmd);
	rp->data.p = cmd;
	rp->data.count = 0;
	rp->data.write = 1;
	return SRrequest(rp);
}

long
SRtinfo(ScsiReq *rp, uchar track, uchar *data)
{
	uchar cmd[10];

	memset(cmd, 0, sizeof(cmd));
	cmd[0] = ScmdTinfo;
	cmd[5] = track;
	cmd[8] = MaxDirData;
	rp->cmd.p = cmd;
	rp->cmd.count = sizeof(cmd);
	rp->data.p = data;
	rp->data.count = MaxDirData;
	rp->data.write = 0;
	return SRrequest(rp);
}

long
SRwtrack(ScsiReq *rp, void *buf, long nbytes, uchar track, uchar mode)
{
	uchar cmd[10];
	long m, n;

	if((nbytes % rp->lbsize) || nbytes > maxiosize){
		rp->status = Status_BADARG;
		return -1;
	}
	memset(cmd, 0, sizeof(cmd));
	cmd[0] = ScmdTwrite;
	cmd[5] = track;
	cmd[6] = mode;
	n = nbytes/rp->lbsize;
	cmd[7] = n>>8;
	cmd[8] = n;
	rp->cmd.p = cmd;
	rp->cmd.count = sizeof(cmd);
	rp->data.p = buf;
	rp->data.count = nbytes;
	rp->data.write = 1;
	m = SRrequest(rp);
	if(m < 0)
		return -1;
	rp->offset += n;
	return m;
}

long
SRmload(ScsiReq *rp, uchar code)
{
	uchar cmd[12];

	memset(cmd, 0, sizeof(cmd));
	cmd[0] = ScmdMload;
	cmd[8] = code;
	rp->cmd.p = cmd;
	rp->cmd.count = sizeof(cmd);
	rp->data.p = cmd;
	rp->data.count = 0;
	rp->data.write = 1;
	return SRrequest(rp);
}

long
SRfixation(ScsiReq *rp, uchar type)
{
	uchar cmd[10];

	memset(cmd, 0, sizeof(cmd));
	cmd[0] = ScmdFixation;
	cmd[8] = type;
	rp->cmd.p = cmd;
	rp->cmd.count = sizeof(cmd);
	rp->data.p = cmd;
	rp->data.count = 0;
	rp->data.write = 1;
	return SRrequest(rp);
}
