FreeBSD/Linux Kernel Cross Reference
sys/scsi/scsi_rom.c
1 /*
2 * Mach Operating System
3 * Copyright (c) 1991,1990 Carnegie Mellon University
4 * All Rights Reserved.
5 *
6 * Permission to use, copy, modify and distribute this software and its
7 * documentation is hereby granted, provided that both the copyright
8 * notice and this permission notice appear in all copies of the
9 * software, derivative works or modified versions, and any portions
10 * thereof, and that both notices appear in supporting documentation.
11 *
12 * CARNEGIE MELLON ALLOWS FREE USE OF THIS SOFTWARE IN ITS "AS IS"
13 * CONDITION. CARNEGIE MELLON DISCLAIMS ANY LIABILITY OF ANY KIND FOR
14 * ANY DAMAGES WHATSOEVER RESULTING FROM THE USE OF THIS SOFTWARE.
15 *
16 * Carnegie Mellon requests users of this software to return to
17 *
18 * Software Distribution Coordinator or Software.Distribution@CS.CMU.EDU
19 * School of Computer Science
20 * Carnegie Mellon University
21 * Pittsburgh PA 15213-3890
22 *
23 * any improvements or extensions that they make and grant Carnegie Mellon
24 * the rights to redistribute these changes.
25 */
26 /*
27 * HISTORY
28 * $Log: scsi_rom.c,v $
29 * Revision 2.11 93/03/26 23:28:22 mrt
30 * Changed and made work scsi_read_subchannel, now strictly
31 * standard-abiding.
32 * [93/03/26 af]
33 *
34 * Revision 2.10 93/03/09 10:58:32 danner
35 * Implemented missing commands.
36 * Code tested on a "DEC RRD42(C)DEC 4.5d" drive.
37 * [93/03/06 af]
38 *
39 * Revision 2.9 92/08/03 17:55:22 jfriedl
40 * removed silly prototypes
41 * [92/08/02 jfriedl]
42 *
43 * Revision 2.8 92/05/21 17:24:47 jfriedl
44 * tried prototypes.
45 * [92/05/20 jfriedl]
46 *
47 * Revision 2.7 91/06/19 11:58:05 rvb
48 * File moved here from mips/PMAX since it is now "MI" code, also
49 * used by Vax3100 and soon -- the omron luna88k.
50 * [91/06/04 rvb]
51 *
52 * Revision 2.6 91/05/14 17:31:08 mrt
53 * Correcting copyright
54 *
55 * Revision 2.5 91/05/13 06:05:46 af
56 * Removed unused code, added sccdrom_name().
57 * [91/05/12 16:18:49 af]
58 *
59 * Revision 2.4 91/02/05 17:46:14 mrt
60 * Added author notices
61 * [91/02/04 11:20:04 mrt]
62 *
63 * Changed to use new Mach copyright
64 * [91/02/02 12:18:53 mrt]
65 *
66 * Revision 2.3 90/12/05 23:35:39 af
67 *
68 *
69 * Revision 2.1.1.1 90/11/01 03:40:19 af
70 * Created, from the SCSI specs:
71 * "Small Computer Systems Interface (SCSI)", ANSI Draft
72 * X3T9.2/82-2 - Rev 17B December 1985
73 * "Small Computer System Interface - 2 (SCSI-II)", ANSI Draft
74 * X3T9.2/86-109 - Rev 10C March 1990
75 * [90/10/11 af]
76 */
77 /*
78 * File: scsi_rom.c
79 * Author: Alessandro Forin, Carnegie Mellon University
80 * Date: 10/90
81 *
82 * Middle layer of the SCSI driver: SCSI protocol implementation
83 *
84 * This file contains code for SCSI commands for CD-ROM devices.
85 */
86
87 #include <mach/std_types.h>
88 #include <scsi/compat_30.h>
89
90 #include <scsi/scsi.h>
91 #include <scsi/scsi2.h>
92 #include <scsi/scsi_defs.h>
93
94
95
96 char *sccdrom_name(
97 boolean_t internal)
98 {
99 return internal ? "rz" : "CD-ROM";
100 }
101
102 int scsi_pause_resume(
103 target_info_t *tgt,
104 boolean_t stop_it,
105 io_req_t ior)
106 {
107 scsi_cmd_pausres_t *cmd;
108
109 cmd = (scsi_cmd_pausres_t*) (tgt->cmd_ptr);
110 cmd->scsi_cmd_code = SCSI_CMD_PAUSE_RESUME;
111 cmd->scsi_cmd_lun_and_relbit = 0;
112 cmd->scsi_cmd_lba1 = 0;
113 cmd->scsi_cmd_lba2 = 0;
114 cmd->scsi_cmd_lba3 = 0;
115 cmd->scsi_cmd_lba4 = 0;
116 cmd->scsi_cmd_xxx = 0;
117 cmd->scsi_cmd_xfer_len_1 = 0;
118 cmd->scsi_cmd_pausres_res = stop_it ? 0 : SCSI_CMD_PAUSRES_RESUME;
119 cmd->scsi_cmd_ctrl_byte = 0; /* not linked */
120
121 tgt->cur_cmd = SCSI_CMD_PAUSE_RESUME;
122
123 scsi_go_and_wait(tgt, sizeof(*cmd), 0, ior);
124
125 return tgt->done;
126 }
127
128 scsi_play_audio(
129 target_info_t *tgt,
130 unsigned int start,
131 unsigned int len,
132 boolean_t relative_address,
133 io_req_t ior)
134 {
135 scsi_cmd_play_audio_t *cmd;
136
137 cmd = (scsi_cmd_play_audio_t*) (tgt->cmd_ptr);
138 cmd->scsi_cmd_code = SCSI_CMD_PLAY_AUDIO;
139 cmd->scsi_cmd_lun_and_relbit = relative_address ? SCSI_RELADR : 0;
140 cmd->scsi_cmd_lba1 = start >> 24;
141 cmd->scsi_cmd_lba2 = start >> 16;
142 cmd->scsi_cmd_lba3 = start >> 8;
143 cmd->scsi_cmd_lba4 = start >> 0;
144 cmd->scsi_cmd_xxx = 0;
145 cmd->scsi_cmd_xfer_len_1 = len >> 8;
146 cmd->scsi_cmd_xfer_len_2 = len >> 0;
147 cmd->scsi_cmd_ctrl_byte = 0; /* not linked */
148
149 tgt->cur_cmd = SCSI_CMD_PLAY_AUDIO;
150
151 scsi_go_and_wait(tgt, sizeof(*cmd), 0, ior);
152
153 return tgt->done;
154 }
155
156 scsi_play_audio_long(
157 target_info_t *tgt,
158 unsigned int start,
159 unsigned int len,
160 boolean_t relative_address,
161 io_req_t ior)
162 {
163 scsi_cmd_play_audio_l_t *cmd;
164
165 cmd = (scsi_cmd_play_audio_l_t*) (tgt->cmd_ptr);
166 cmd->scsi_cmd_code = SCSI_CMD_PLAY_AUDIO_LONG;
167 cmd->scsi_cmd_lun_and_relbit = relative_address ? SCSI_RELADR : 0;
168 cmd->scsi_cmd_lba1 = start >> 24;
169 cmd->scsi_cmd_lba2 = start >> 16;
170 cmd->scsi_cmd_lba3 = start >> 8;
171 cmd->scsi_cmd_lba4 = start >> 0;
172 cmd->scsi_cmd_xfer_len_1 = len >> 24;
173 cmd->scsi_cmd_xfer_len_2 = len >> 16;
174 cmd->scsi_cmd_xfer_len_3 = len >> 8;
175 cmd->scsi_cmd_xfer_len_4 = len >> 0;
176 cmd->scsi_cmd_xxx1 = 0;
177 cmd->scsi_cmd_ctrl_byte = 0; /* not linked */
178
179 tgt->cur_cmd = SCSI_CMD_PLAY_AUDIO_LONG;
180
181 scsi_go_and_wait(tgt, sizeof(*cmd), 0, ior);
182
183 return tgt->done;
184 }
185
186 scsi_play_audio_msf(
187 target_info_t *tgt,
188 int sm,
189 int ss,
190 int sf,
191 int em,
192 int es,
193 int ef,
194 io_req_t ior)
195 {
196 scsi_cmd_play_audio_msf_t *cmd;
197
198 cmd = (scsi_cmd_play_audio_msf_t*) (tgt->cmd_ptr);
199 cmd->scsi_cmd_code = SCSI_CMD_PLAY_AUDIO_MSF;
200 cmd->scsi_cmd_lun_and_relbit = 0;
201 cmd->scsi_cmd_lba1 = 0;
202 cmd->scsi_cmd_pamsf_startM = sm;
203 cmd->scsi_cmd_pamsf_startS = ss;
204 cmd->scsi_cmd_pamsf_startF = sf;
205 cmd->scsi_cmd_pamsf_endM = em;
206 cmd->scsi_cmd_pamsf_endS = es;
207 cmd->scsi_cmd_pamsf_endF = ef;
208 cmd->scsi_cmd_ctrl_byte = 0; /* not linked */
209
210 tgt->cur_cmd = SCSI_CMD_PLAY_AUDIO_MSF;
211
212 scsi_go_and_wait(tgt, sizeof(*cmd), 0, ior);
213
214 return tgt->done;
215 }
216
217 scsi_play_audio_track_index(
218 target_info_t *tgt,
219 int st,
220 int si,
221 int et,
222 int ei,
223 io_req_t ior)
224 {
225 scsi_cmd_play_audio_ti_t *cmd;
226
227 cmd = (scsi_cmd_play_audio_ti_t*) (tgt->cmd_ptr);
228 cmd->scsi_cmd_code = SCSI_CMD_PLAY_AUDIO_TI;
229 cmd->scsi_cmd_lun_and_relbit = 0;
230 cmd->scsi_cmd_lba1 = 0;
231 cmd->scsi_cmd_lba2 = 0;
232 cmd->scsi_cmd_pati_startT = st;
233 cmd->scsi_cmd_pati_startI = si;
234 cmd->scsi_cmd_xxx = 0;
235 cmd->scsi_cmd_pati_endT = et;
236 cmd->scsi_cmd_pati_endI = ei;
237 cmd->scsi_cmd_ctrl_byte = 0; /* not linked */
238
239 tgt->cur_cmd = SCSI_CMD_PLAY_AUDIO_TI;
240
241 scsi_go_and_wait(tgt, sizeof(*cmd), 0, ior);
242
243 return tgt->done;
244 }
245
246 scsi_play_audio_track_relative(
247 target_info_t *tgt,
248 unsigned int lba,
249 int st,
250 unsigned int len,
251 io_req_t ior)
252 {
253 scsi_cmd_play_audio_tr_t *cmd;
254
255 cmd = (scsi_cmd_play_audio_tr_t*) (tgt->cmd_ptr);
256 cmd->scsi_cmd_code = SCSI_CMD_PLAY_AUDIO_TR;
257 cmd->scsi_cmd_lun_and_relbit = 0;
258 cmd->scsi_cmd_lba1 = lba >> 24;
259 cmd->scsi_cmd_lba2 = lba >> 16;
260 cmd->scsi_cmd_lba3 = lba >> 8;
261 cmd->scsi_cmd_lba4 = lba >> 0;
262 cmd->scsi_cmd_patr_startT = st;
263 cmd->scsi_cmd_xfer_len_1 = len >> 8;
264 cmd->scsi_cmd_xfer_len_2 = len >> 0;
265 cmd->scsi_cmd_ctrl_byte = 0; /* not linked */
266
267 tgt->cur_cmd = SCSI_CMD_PLAY_AUDIO_TR;
268
269 scsi_go_and_wait(tgt, sizeof(*cmd), 0, ior);
270
271 return tgt->done;
272 }
273
274 scsi_play_audio_track_relative_long(
275 target_info_t *tgt,
276 unsigned int lba,
277 int st,
278 unsigned int len,
279 io_req_t ior)
280 {
281 scsi_cmd_play_audio_tr_l_t *cmd;
282
283 cmd = (scsi_cmd_play_audio_tr_l_t*) (tgt->cmd_ptr);
284 cmd->scsi_cmd_code = SCSI_CMD_PLAY_AUDIO_TR_LONG;
285 cmd->scsi_cmd_lun_and_relbit = 0;
286 cmd->scsi_cmd_lba1 = lba >> 24;
287 cmd->scsi_cmd_lba2 = lba >> 16;
288 cmd->scsi_cmd_lba3 = lba >> 8;
289 cmd->scsi_cmd_lba4 = lba >> 0;
290 cmd->scsi_cmd_xfer_len_1 = len >> 24;
291 cmd->scsi_cmd_xfer_len_2 = len >> 16;
292 cmd->scsi_cmd_xfer_len_3 = len >> 8;
293 cmd->scsi_cmd_xfer_len_4 = len >> 0;
294 cmd->scsi_cmd_patrl_startT = st;
295 cmd->scsi_cmd_ctrl_byte = 0; /* not linked */
296
297 tgt->cur_cmd = SCSI_CMD_PLAY_AUDIO_TR_LONG;
298
299 scsi_go_and_wait(tgt, sizeof(*cmd), 0, ior);
300
301 return tgt->done;
302 }
303
304 scsi_read_header(
305 target_info_t *tgt,
306 boolean_t msf_format,
307 unsigned int lba,
308 unsigned int allocsize,
309 io_req_t ior)
310 {
311 scsi_cmd_read_header_t *cmd;
312
313 cmd = (scsi_cmd_read_header_t*) (tgt->cmd_ptr);
314 cmd->scsi_cmd_code = SCSI_CMD_READ_HEADER;
315 cmd->scsi_cmd_lun_and_relbit = msf_format ? SCSI_CMD_CD_MSF : 0;
316 cmd->scsi_cmd_lba1 = lba >> 24;
317 cmd->scsi_cmd_lba2 = lba >> 16;
318 cmd->scsi_cmd_lba3 = lba >> 8;
319 cmd->scsi_cmd_lba4 = lba >> 0;
320 cmd->scsi_cmd_xxx = 0;
321 cmd->scsi_cmd_xfer_len_1 = allocsize >> 8;
322 cmd->scsi_cmd_xfer_len_2 = allocsize >> 0;
323 cmd->scsi_cmd_ctrl_byte = 0; /* not linked */
324
325 tgt->cur_cmd = SCSI_CMD_READ_HEADER;
326
327 scsi_go_and_wait(tgt, sizeof(*cmd), allocsize, ior);
328
329 return tgt->done;
330 }
331
332 scsi_read_subchannel(
333 target_info_t *tgt,
334 boolean_t msf_format,
335 unsigned int data_format,
336 unsigned int trackno,
337 io_req_t ior)
338 {
339 scsi_cmd_read_subch_t *cmd;
340 int allocsize;
341
342 switch (data_format) {
343 case SCSI_CMD_RS_FMT_SUBQ:
344 allocsize = sizeof(cdrom_chan_data_t);
345 trackno = 0; break;
346 case SCSI_CMD_RS_FMT_CURPOS:
347 allocsize = sizeof(cdrom_chan_curpos_t);
348 trackno = 0; break;
349 case SCSI_CMD_RS_FMT_CATALOG:
350 allocsize = sizeof(cdrom_chan_catalog_t);
351 trackno = 0; break;
352 case SCSI_CMD_RS_FMT_ISRC:
353 allocsize = sizeof(cdrom_chan_isrc_t); break;
354 }
355
356 cmd = (scsi_cmd_read_subch_t*) (tgt->cmd_ptr);
357 cmd->scsi_cmd_code = SCSI_CMD_READ_SUBCH;
358 cmd->scsi_cmd_lun_and_relbit = msf_format ? SCSI_CMD_CD_MSF : 0;
359 cmd->scsi_cmd_lba1 = SCSI_CMD_RS_SUBQ;
360 cmd->scsi_cmd_rs_format = data_format;
361 cmd->scsi_cmd_lba3 = 0;
362 cmd->scsi_cmd_lba4 = 0;
363 cmd->scsi_cmd_rs_trackno = trackno;
364 cmd->scsi_cmd_xfer_len_1 = allocsize >> 8;
365 cmd->scsi_cmd_xfer_len_2 = allocsize >> 0;
366 cmd->scsi_cmd_ctrl_byte = 0; /* not linked */
367
368 tgt->cur_cmd = SCSI_CMD_READ_SUBCH;
369
370 scsi_go_and_wait(tgt, sizeof(*cmd), allocsize, ior);
371
372 return tgt->done;
373 }
374
375 scsi_read_toc(
376 target_info_t *tgt,
377 boolean_t msf_format,
378 int trackno,
379 int allocsize,
380 io_req_t ior)
381 {
382 scsi_cmd_read_toc_t *cmd;
383
384 cmd = (scsi_cmd_read_toc_t*) (tgt->cmd_ptr);
385 cmd->scsi_cmd_code = SCSI_CMD_READ_TOC;
386 cmd->scsi_cmd_lun_and_relbit = msf_format ? SCSI_CMD_CD_MSF : 0;
387 cmd->scsi_cmd_lba1 = 0;
388 cmd->scsi_cmd_lba2 = 0;
389 cmd->scsi_cmd_lba3 = 0;
390 cmd->scsi_cmd_lba4 = 0;
391 cmd->scsi_cmd_rtoc_startT = trackno;
392 cmd->scsi_cmd_xfer_len_1 = allocsize >> 8;
393 cmd->scsi_cmd_xfer_len_2 = allocsize >> 0;
394 cmd->scsi_cmd_ctrl_byte = 0; /* not linked */
395
396 tgt->cur_cmd = SCSI_CMD_READ_TOC;
397
398 scsi_go_and_wait(tgt, sizeof(*cmd), allocsize, ior);
399
400 return tgt->done;
401 }
402
403 /* move elsewhere ifworks */
404 scsi2_mode_select(
405 target_info_t *tgt,
406 boolean_t save,
407 unsigned char *page,
408 int pagesize,
409 io_req_t ior)
410 {
411 scsi_cmd_mode_select_t *cmd;
412 scsi2_mode_param_t *parm;
413
414 bzero(tgt->cmd_ptr, sizeof(*cmd) + sizeof(*parm));
415 cmd = (scsi_cmd_mode_select_t*) (tgt->cmd_ptr);
416 cmd->scsi_cmd_code = SCSI_CMD_MODE_SELECT;
417 cmd->scsi_cmd_lun_and_lba1 = SCSI_CMD_MSL_PF | (save ? SCSI_CMD_MSL_SP : 0);
418 cmd->scsi_cmd_xfer_len = pagesize;
419
420 parm = (scsi2_mode_param_t*) (cmd + 1);
421
422 bcopy(page, parm, pagesize);
423
424 tgt->cur_cmd = SCSI_CMD_MODE_SELECT;
425
426 scsi_go_and_wait(tgt, sizeof(*cmd) + pagesize, 0, ior);
427
428 return tgt->done;
429 }
430
431 /*
432 * obnoxious
433 */
434 cdrom_vendor_specific(
435 target_info_t *tgt,
436 scsi_command_group_2 *cmd,
437 unsigned char *params,
438 int paramlen,
439 int retlen,
440 io_req_t ior)
441 {
442 bcopy(cmd, tgt->cmd_ptr, sizeof(*cmd));
443 if (paramlen)
444 bcopy(params, tgt->cmd_ptr + sizeof(*cmd), paramlen);
445
446 tgt->cur_cmd = cmd->scsi_cmd_code;
447
448 scsi_go_and_wait(tgt, sizeof(*cmd) + paramlen, retlen, ior);
449
450 return tgt->done;
451 }
Cache object: fdac283605785bb972bf2ffe325a400a
|