xref: /plan9/sys/src/cmd/scuzz/cdaudio.c (revision fd362a73ff89ae80075dd82c9aad2a3468f0f3c9)
1 #include <u.h>
2 #include <libc.h>
3 #include <bio.h>
4 #include <disk.h>
5 #include "scsireq.h"
6 
7 extern Biobuf bout;
8 
9 long
SRcdpause(ScsiReq * rp,int resume)10 SRcdpause(ScsiReq *rp, int resume)
11 {
12 	uchar cmd[10];
13 
14 	memset(cmd, 0, sizeof(cmd));
15 	cmd[0] = ScmdCDpause;
16 	cmd[8] = resume;
17 	rp->cmd.p = cmd;
18 	rp->cmd.count = sizeof(cmd);
19 	rp->data.p = cmd;
20 	rp->data.count = 0;
21 	rp->data.write = 1;
22 	return SRrequest(rp);
23 }
24 
25 long
SRcdstop(ScsiReq * rp)26 SRcdstop(ScsiReq *rp)
27 {
28 	uchar cmd[10];
29 
30 	memset(cmd, 0, sizeof(cmd));
31 	cmd[0] = ScmdCDstop;
32 	rp->cmd.p = cmd;
33 	rp->cmd.count = sizeof(cmd);
34 	rp->data.p = cmd;
35 	rp->data.count = 0;
36 	rp->data.write = 1;
37 	return SRrequest(rp);
38 }
39 
40 static long
_SRcdplay(ScsiReq * rp,long lba,long length)41 _SRcdplay(ScsiReq *rp, long lba, long length)
42 {
43 	uchar cmd[12];
44 
45 	memset(cmd, 0, sizeof(cmd));
46 	cmd[0] = ScmdCDplay;
47 	cmd[2] = lba>>24;
48 	cmd[3] = lba>>16;
49 	cmd[4] = lba>>8;
50 	cmd[5] = lba;
51 	cmd[6] = length>>24;
52 	cmd[7] = length>>16;
53 	cmd[8] = length>>8;
54 	cmd[9] = length;
55 	rp->cmd.p = cmd;
56 	rp->cmd.count = sizeof(cmd);
57 	rp->data.p = cmd;
58 	rp->data.count = 0;
59 	rp->data.write = 1;
60 
61 	return SRrequest(rp);
62 }
63 
64 static struct {
65 	int	trackno;
66 	long	lba;
67 	long	length;
68 } tracks[100];
69 static int ntracks;
70 
71 long
SRcdplay(ScsiReq * rp,int raw,long start,long length)72 SRcdplay(ScsiReq *rp, int raw, long start, long length)
73 {
74 	uchar d[100*8+4], *p;
75 	int lba, n, tdl;
76 
77 	if(raw || start == 0)
78 		return _SRcdplay(rp, start, length);
79 
80 	ntracks = 0;
81 	if(SRTOC(rp, d, sizeof(d), 0, 0) == -1){
82 		if(rp->status == STok)
83 			Bprint(&bout, "\t(probably empty)\n");
84 		return -1;
85 	}
86 	tdl = (d[0]<<8)|d[1];
87 	for(p = &d[4], n = tdl-2; n; n -= 8, p += 8){
88 		tracks[ntracks].trackno = p[2];
89 		lba = (p[4]<<24)|(p[5]<<16)|(p[6]<<8)|p[7];
90 		tracks[ntracks].lba = lba;
91 		if(ntracks > 0)
92 			tracks[ntracks-1].length = lba-tracks[ntracks-1].lba;
93 		ntracks++;
94 	}
95 	if(ntracks > 0)
96 		tracks[ntracks-1].length = 0xFFFFFFFF;
97 
98 	for(n = 0; n < ntracks; n++){
99 		if(start != tracks[n].trackno)
100 			continue;
101 		return _SRcdplay(rp, tracks[n].lba, tracks[n].length);
102 	}
103 
104 	return -1;
105 }
106 
107 long
SRcdload(ScsiReq * rp,int load,int slot)108 SRcdload(ScsiReq *rp, int load, int slot)
109 {
110 	uchar cmd[12];
111 
112 	memset(cmd, 0, sizeof(cmd));
113 	cmd[0] = ScmdCDload;
114 	if(load)
115 		cmd[4] = 0x03;
116 	else
117 		cmd[4] = 0x02;
118 	cmd[8] = slot;
119 	rp->cmd.p = cmd;
120 	rp->cmd.count = sizeof(cmd);
121 	rp->data.p = cmd;
122 	rp->data.count = 0;
123 	rp->data.write = 1;
124 	return SRrequest(rp);
125 }
126 
127 long
SRcdstatus(ScsiReq * rp,uchar * list,int nbytes)128 SRcdstatus(ScsiReq *rp, uchar *list, int nbytes)
129 {
130 	uchar cmd[12];
131 
132 	memset(cmd, 0, sizeof(cmd));
133 	cmd[0] = ScmdCDstatus;
134 	cmd[8] = nbytes>>8;
135 	cmd[9] = nbytes;
136 	rp->cmd.p = cmd;
137 	rp->cmd.count = sizeof(cmd);
138 	rp->data.p = list;
139 	rp->data.count = nbytes;
140 	rp->data.write = 0;
141 	return SRrequest(rp);
142 }
143 
144 long
SRgetconf(ScsiReq * rp,uchar * list,int nbytes)145 SRgetconf(ScsiReq *rp, uchar *list, int nbytes)
146 {
147 	uchar cmd[10];
148 
149 	memset(cmd, 0, sizeof(cmd));
150 	cmd[0] = Scmdgetconf;
151 	cmd[7] = nbytes>>8;
152 	cmd[8] = nbytes;
153 	rp->cmd.p = cmd;
154 	rp->cmd.count = sizeof(cmd);
155 	rp->data.p = list;
156 	rp->data.count = nbytes;
157 	rp->data.write = 0;
158 	return SRrequest(rp);
159 }
160