#include <u.h>
#include <libc.h>
#include <bio.h>
#include <disk.h>
#include "scsireq.h"
extern Biobuf bout;
long
SRcdpause(ScsiReq *rp, int resume)
{
uchar cmd[10];
memset(cmd, 0, sizeof(cmd));
cmd[0] = ScmdCDpause;
cmd[8] = resume;
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
SRcdstop(ScsiReq *rp)
{
uchar cmd[10];
memset(cmd, 0, sizeof(cmd));
cmd[0] = ScmdCDstop;
rp->cmd.p = cmd;
rp->cmd.count = sizeof(cmd);
rp->data.p = cmd;
rp->data.count = 0;
rp->data.write = 1;
return SRrequest(rp);
}
static long
_SRcdplay(ScsiReq *rp, long lba, long length)
{
uchar cmd[12];
memset(cmd, 0, sizeof(cmd));
cmd[0] = ScmdCDplay;
cmd[2] = lba>>24;
cmd[3] = lba>>16;
cmd[4] = lba>>8;
cmd[5] = lba;
cmd[6] = length>>24;
cmd[7] = length>>16;
cmd[8] = length>>8;
cmd[9] = length;
rp->cmd.p = cmd;
rp->cmd.count = sizeof(cmd);
rp->data.p = cmd;
rp->data.count = 0;
rp->data.write = 1;
return SRrequest(rp);
}
static struct {
int trackno;
long lba;
long length;
} tracks[100];
static int ntracks;
long
SRcdplay(ScsiReq *rp, int raw, long start, long length)
{
uchar d[100*8+4], *p;
int lba, n, tdl;
if(raw || start == 0)
return _SRcdplay(rp, start, length);
ntracks = 0;
if(SRTOC(rp, d, sizeof(d), 0, 0) == -1){
if(rp->status == STok)
Bprint(&bout, "\t(probably empty)\n");
return -1;
}
tdl = (d[0]<<8)|d[1];
for(p = &d[4], n = tdl-2; n; n -= 8, p += 8){
tracks[ntracks].trackno = p[2];
lba = (p[4]<<24)|(p[5]<<16)|(p[6]<<8)|p[7];
tracks[ntracks].lba = lba;
if(ntracks > 0)
tracks[ntracks-1].length = lba-tracks[ntracks-1].lba;
ntracks++;
}
if(ntracks > 0)
tracks[ntracks-1].length = 0xFFFFFFFF;
for(n = 0; n < ntracks; n++){
if(start != tracks[n].trackno)
continue;
return _SRcdplay(rp, tracks[n].lba, tracks[n].length);
}
return -1;
}
long
SRcdload(ScsiReq *rp, int load, int slot)
{
uchar cmd[12];
memset(cmd, 0, sizeof(cmd));
cmd[0] = ScmdCDload;
if(load)
cmd[4] = 0x03;
else
cmd[4] = 0x02;
cmd[8] = slot;
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
SRcdstatus(ScsiReq *rp, uchar *list, int nbytes)
{
uchar cmd[12];
memset(cmd, 0, sizeof(cmd));
cmd[0] = ScmdCDstatus;
cmd[8] = nbytes>>8;
cmd[9] = nbytes;
rp->cmd.p = cmd;
rp->cmd.count = sizeof(cmd);
rp->data.p = list;
rp->data.count = nbytes;
rp->data.write = 0;
return SRrequest(rp);
}
long
SRgetconf(ScsiReq *rp, uchar *list, int nbytes)
{
uchar cmd[10];
memset(cmd, 0, sizeof(cmd));
cmd[0] = Scmdgetconf;
cmd[7] = nbytes>>8;
cmd[8] = nbytes;
rp->cmd.p = cmd;
rp->cmd.count = sizeof(cmd);
rp->data.p = list;
rp->data.count = nbytes;
rp->data.write = 0;
return SRrequest(rp);
}
|