|
|
1.1 root 1: /* $Id: scsi-cdrom.c,v 1.2 2007/03/29 01:19:41 fredette Exp $ */
2:
3: /* scsi/scsi-cdrom.c - implementation of SCSI CD-ROM emulation: */
4:
5: /*
6: * Copyright (c) 2007 Matt Fredette
7: * All rights reserved.
8: *
9: * Redistribution and use in source and binary forms, with or without
10: * modification, are permitted provided that the following conditions
11: * are met:
12: * 1. Redistributions of source code must retain the above copyright
13: * notice, this list of conditions and the following disclaimer.
14: * 2. Redistributions in binary form must reproduce the above copyright
15: * notice, this list of conditions and the following disclaimer in the
16: * documentation and/or other materials provided with the distribution.
17: * 3. All advertising materials mentioning features or use of this software
18: * must display the following acknowledgement:
19: * This product includes software developed by Matt Fredette.
20: * 4. The name of the author may not be used to endorse or promote products
21: * derived from this software without specific prior written permission.
22: *
23: * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
24: * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
25: * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
26: * DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT,
27: * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
28: * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
29: * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
30: * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
31: * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
32: * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
33: * POSSIBILITY OF SUCH DAMAGE.
34: */
35:
36: #include <tme/common.h>
37: _TME_RCSID("$Id: scsi-cdrom.c,v 1.2 2007/03/29 01:19:41 fredette Exp $");
38:
39: /* includes: */
40: #include <tme/scsi/scsi-cdrom.h>
41: #ifdef HAVE_STDARG_H
42: #include <stdarg.h>
43: #else /* HAVE_STDARG_H */
44: #include <varargs.h>
45: #endif /* HAVE_STDARG_H */
46:
47: /* macros: */
48:
49: /* globals: */
50:
51: /* the list of cdroms that we emulate: */
52: const struct {
53:
54: /* the type name: */
55: const char *_tme_scsi_cdrom_list_type;
56:
57: /* the initialization function: */
58: int (*_tme_scsi_cdrom_list_init) _TME_P((struct tme_scsi_cdrom *));
59: } _tme_scsi_cdrom_list[] = {
60:
61: /* the generic TME SCSI-1 cdrom: */
62: { "tme-scsi-1", tme_scsi_cdrom_tme_init },
63: };
64:
65: /* this implements the CD-ROM INQUIRY command: */
66: _TME_SCSI_DEVICE_CDB_DECL(tme_scsi_cdrom_cdb_inquiry)
67: {
68: int lun;
69: struct tme_scsi_device_inquiry inquiry;
70: tme_uint8_t *data;
71:
72: /* get the active LUN: */
73: lun = scsi_device->tme_scsi_device_addressed_lun;
74:
75: /* this is a CD-ROM: */
76: inquiry.tme_scsi_device_inquiry_type = TME_SCSI_TYPE_CDROM;
77:
78: /* if this LUN is defined: */
79: inquiry.tme_scsi_device_inquiry_lun_state
80: = ((scsi_device->tme_scsi_device_luns
81: & TME_BIT(lun))
82: ? TME_SCSI_LUN_PRESENT
83: : TME_SCSI_LUN_UNSUPPORTED);
84:
85: /* the device type qualifier: */
86: inquiry.tme_scsi_device_inquiry_type_qualifier = 0x00;
87:
88: /* nonzero iff the LUN is removable: */
89: inquiry.tme_scsi_device_inquiry_lun_removable = TRUE;
90:
91: /* the various standards versions: */
92: inquiry.tme_scsi_device_inquiry_std_ansi = 1;
93: inquiry.tme_scsi_device_inquiry_std_ecma = 1;
94: inquiry.tme_scsi_device_inquiry_std_iso = 1;
95:
96: /* the response format: */
97: inquiry.tme_scsi_device_response_format = TME_SCSI_FORMAT_CCS;
98:
99: /* make the inquiry data: */
100: data
101: = tme_scsi_device_make_inquiry_data(scsi_device,
102: &inquiry);
103: scsi_device->tme_scsi_device_dma.tme_scsi_dma_resid
104: = TME_MIN((data
105: - scsi_device->tme_scsi_device_dma.tme_scsi_dma_out),
106: scsi_device->tme_scsi_device_cdb[4]);
107:
108: /* finish the command: */
109: tme_scsi_device_target_do_dsmf(scsi_device,
110: TME_SCSI_STATUS_GOOD,
111: TME_SCSI_MSG_CMD_COMPLETE);
112: }
113:
114: /* this implements the CD-ROM READ TOC command: */
115: _TME_SCSI_DEVICE_CDB_DECL(tme_scsi_cdrom_cdb_read_toc)
116: {
117: struct tme_scsi_cdrom *scsi_cdrom;
118: struct tme_scsi_cdrom_connection *conn_scsi_cdrom;
119: struct tme_disk_connection *conn_disk;
120: tme_uint8_t *data;
121: tme_uint32_t space;
122: tme_uint32_t length;
123: int lun;
124:
125: /* recover our CD-ROM: */
126: scsi_cdrom = (struct tme_scsi_cdrom *) scsi_device;
127:
128: /* get the active LUN: */
129: lun = scsi_device->tme_scsi_device_addressed_lun;
130:
131: /* get the CD-ROM connection: */
132: conn_scsi_cdrom
133: = scsi_cdrom->tme_scsi_cdrom_connections[lun];
134: conn_disk
135: = ((struct tme_disk_connection *)
136: conn_scsi_cdrom->tme_scsi_disk_connection.tme_disk_connection.tme_connection_other);
137:
138: /* we require that the MSF bit be zero: */
139: if (scsi_device->tme_scsi_device_cdb[1] & 0x02) {
140: tme_scsi_device_check_condition(scsi_device,
141: TME_SCSI_SENSE_EXT_KEY_ILLEGAL_REQUEST,
142: TME_SCSI_SENSE_EXT_ASC_ASCQ_INVALID_FIELD_CDB);
143: return;
144: }
145:
146: /* "If the starting track field is not valid for the currently
147: installed medium, the command shall be terminated with CHECK
148: CONDITION status. The sense key shall be set to ILLEGAL REQUEST
149: and the additional sense code set to INVALID FIELD IN CDB." */
150: /* NB: for now, we support only one track: */
151: if (scsi_device->tme_scsi_device_cdb[6] > 1) {
152: tme_scsi_device_check_condition(scsi_device,
153: TME_SCSI_SENSE_EXT_KEY_ILLEGAL_REQUEST,
154: TME_SCSI_SENSE_EXT_ASC_ASCQ_INVALID_FIELD_CDB);
155: return;
156: }
157:
158: /* start returning the data: */
159: data = &scsi_device->tme_scsi_device_data[0];
160:
161: /* bytes 0 and 1 are the TOC data length. we will fill this in later: */
162: data += 2;
163:
164: /* the first and last track numbers: */
165: /* NB: for now, we support only one track: */
166: *(data++) = 1;
167: *(data++) = 1;
168:
169: /* one TOC track descriptor: */
170:
171: /* a reserved byte: */
172: data++;
173:
174: /* the ADR and control byte: */
175: /* NB: this specifies no sub-channel Q mode, and a data track: */
176: *(data++) = (0x0 << 4) | (1 << 2);
177:
178: /* the track number: */
179: *(data++) = 1;
180:
181: /* this track begins at block zero: */
182: *(data++) = 0;
183: *(data++) = 0;
184: *(data++) = 0;
185: *(data++) = 0;
186:
187: /* fill in the TOC data length, which does not include the TOC data
188: length field itself: */
189: length = (data - (&scsi_device->tme_scsi_device_data[0] + sizeof(tme_uint16_t)));
190: scsi_device->tme_scsi_device_data[0] = (length >> 8);
191: scsi_device->tme_scsi_device_data[1] = length;
192:
193: /* set the DMA pointer and length: */
194: space = scsi_device->tme_scsi_device_cdb[7];
195: space = (space << 8) + scsi_device->tme_scsi_device_cdb[8];
196: scsi_device->tme_scsi_device_dma.tme_scsi_dma_resid
197: = TME_MIN((unsigned long) (data - &scsi_device->tme_scsi_device_data[0]),
198: space);
199: scsi_device->tme_scsi_device_dma.tme_scsi_dma_out
200: = &scsi_device->tme_scsi_device_data[0];
201: scsi_device->tme_scsi_device_dma.tme_scsi_dma_in
202: = NULL;
203:
204: /* finish the command: */
205: tme_scsi_device_target_do_dsmf(scsi_device,
206: TME_SCSI_STATUS_GOOD,
207: TME_SCSI_MSG_CMD_COMPLETE);
208: }
209:
210: /* this implements the CD-ROM MODE SENSE command: */
211: _TME_SCSI_DEVICE_CDB_DECL(tme_scsi_cdrom_cdb_mode_sense)
212: {
213: struct tme_scsi_cdrom *scsi_cdrom;
214: struct tme_scsi_cdrom_connection *conn_scsi_cdrom;
215: tme_uint8_t *data;
216: tme_uint32_t block_size;
217: tme_uint32_t length;
218: int is_group0_cmd;
219: int lun;
220:
221: /* see if this is a Group 0 MODE SELECT: */
222: is_group0_cmd
223: = ((scsi_device->tme_scsi_device_cdb[0]
224: & TME_SCSI_CDB_GROUP_MASK)
225: == TME_SCSI_CDB_GROUP_0);
226:
227: /* recover our CD-ROM: */
228: scsi_cdrom = (struct tme_scsi_cdrom *) scsi_device;
229:
230: /* get the active LUN: */
231: lun = scsi_device->tme_scsi_device_addressed_lun;
232:
233: /* get the CD-ROM connection: */
234: conn_scsi_cdrom
235: = scsi_cdrom->tme_scsi_cdrom_connections[lun];
236:
237: data = &scsi_device->tme_scsi_device_data[0];
238:
239: /* the Mode Data Length is one byte for the Group 0 command and two
240: bytes otherwise. we will fill this in later: */
241: data += (is_group0_cmd ? 1 : 2);
242:
243: /* the Medium Type is one byte: */
244: *(data++) = 0x00; /* default (only one medium type supported) */
245:
246: /* the Device Specific Parameter is one byte: */
247: *(data++) = 0x00; /* no DPO/FUA support */
248:
249: /* if this is not the Group 0 command, skip two reserved bytes: */
250: if (!is_group0_cmd) {
251: data += 2;
252: }
253:
254: /* the Block Descriptor Length is one byte for the Group 0 command
255: and two bytes otherwise. we will fill this in later: */
256: data += (is_group0_cmd ? 1 : 2);
257:
258: /* the first Block Descriptor: */
259:
260: /* the Block Descriptor density code: */
261: *(data++) = 0x01; /* User Data only - 2048 bytes per physical sector */
262:
263: /* the Number of Blocks: */
264: /* "A value of zero indicates that all of the remaining logical
265: blocks of the logical unit shall have the medium characteristics
266: specified." */
267: *(data++) = 0x00;
268: *(data++) = 0x00;
269: *(data++) = 0x00;
270:
271: /* a reserved byte: */
272: data++;
273:
274: /* the Block Length: */
275: block_size
276: = conn_scsi_cdrom->tme_scsi_disk_connection_block_size.tme_value64_uint32_lo;
277: *(data++) = (block_size >> 16) & 0xff;
278: *(data++) = (block_size >> 8) & 0xff;
279: *(data++) = (block_size >> 0) & 0xff;
280:
281: /* fill in the Block Descriptor Length: */
282: if (is_group0_cmd) {
283: length = (data - &scsi_device->tme_scsi_device_data[4]);
284: scsi_device->tme_scsi_device_data[3] = length;
285: }
286: else {
287: length = (data - &scsi_device->tme_scsi_device_data[8]);
288: scsi_device->tme_scsi_device_data[6] = (length >> 8);
289: scsi_device->tme_scsi_device_data[7] = length;
290: }
291:
292: /* there are no vendor-unique bytes: */
293:
294: /* fill in the Mode Data Length: */
295: if (is_group0_cmd) {
296: length = (data - &scsi_device->tme_scsi_device_data[1]);
297: scsi_device->tme_scsi_device_data[0] = length;
298: }
299: else {
300: length = (data - &scsi_device->tme_scsi_device_data[2]);
301: scsi_device->tme_scsi_device_data[0] = (length >> 8);
302: scsi_device->tme_scsi_device_data[1] = length;
303: }
304:
305: /* set the DMA pointer and length: */
306: if (is_group0_cmd) {
307: length = scsi_device->tme_scsi_device_cdb[4];
308: }
309: else {
310: length = scsi_device->tme_scsi_device_cdb[7];
311: length = (length << 8) + scsi_device->tme_scsi_device_cdb[8];
312: }
313: scsi_device->tme_scsi_device_dma.tme_scsi_dma_resid
314: = TME_MIN((unsigned long)
315: (data
316: - &scsi_device->tme_scsi_device_data[0]),
317: length);
318: scsi_device->tme_scsi_device_dma.tme_scsi_dma_out
319: = &scsi_device->tme_scsi_device_data[0];
320: scsi_device->tme_scsi_device_dma.tme_scsi_dma_in
321: = NULL;
322:
323: /* finish the command: */
324: tme_scsi_device_target_do_dsmf(scsi_device,
325: TME_SCSI_STATUS_GOOD,
326: TME_SCSI_MSG_CMD_COMPLETE);
327: }
328:
329: /* this handles block descriptors from a MODE SELECT command: */
330: static int
331: _tme_scsi_cdrom_do_mode_select_blocks(struct tme_scsi_device *scsi_device,
332: const struct tme_scsi_device_mode_blocks *blocks)
333: {
334: struct tme_scsi_cdrom *scsi_cdrom;
335: struct tme_scsi_cdrom_connection *conn_scsi_cdrom;
336: int lun;
337:
338: /* recover our CD-ROM: */
339: scsi_cdrom = (struct tme_scsi_cdrom *) scsi_device;
340:
341: /* get the active LUN: */
342: lun = scsi_device->tme_scsi_device_addressed_lun;
343:
344: /* get the CD-ROM connection: */
345: conn_scsi_cdrom
346: = scsi_cdrom->tme_scsi_cdrom_connections[lun];
347:
348: /* XXX FIXME - this needs to be implemented correctly: */
349:
350: /* if this block descriptor doesn't describe the entire CD-ROM: */
351: if (blocks->tme_scsi_device_mode_blocks_number != 0) {
352: tme_scsi_device_check_condition(scsi_device,
353: TME_SCSI_SENSE_EXT_KEY_ILLEGAL_REQUEST,
354: TME_SCSI_SENSE_EXT_ASC_ASCQ_PARAMETER_VALUE_INVALID);
355: return (-1);
356: }
357:
358: /* dispatch on the density code: */
359: switch (blocks->tme_scsi_device_mode_blocks_density_code) {
360: case 0x00: /* Default density code */
361: case 0x01: /* User Data Only, 2048 bytes per physical sector */
362: break;
363: default:
364: tme_scsi_device_check_condition(scsi_device,
365: TME_SCSI_SENSE_EXT_KEY_ILLEGAL_REQUEST,
366: TME_SCSI_SENSE_EXT_ASC_ASCQ_PARAMETER_VALUE_INVALID);
367: return (-1);
368: }
369:
370: /* the logical block size must be an exact divisor or an integral
371: multiple of 2048: */
372: if (blocks->tme_scsi_device_mode_blocks_length == 0
373: || ((blocks->tme_scsi_device_mode_blocks_length
374: < 2048)
375: ? (2048 % blocks->tme_scsi_device_mode_blocks_length)
376: : (blocks->tme_scsi_device_mode_blocks_length % 2048))) {
377: tme_scsi_device_check_condition(scsi_device,
378: TME_SCSI_SENSE_EXT_KEY_ILLEGAL_REQUEST,
379: TME_SCSI_SENSE_EXT_ASC_ASCQ_PARAMETER_VALUE_INVALID);
380: return (-1);
381: }
382:
383: /* update the logical block size: */
384: conn_scsi_cdrom->tme_scsi_disk_connection_block_size.tme_value64_uint32_lo
385: = blocks->tme_scsi_device_mode_blocks_length;
386:
387: return (0);
388: }
389:
390: /* this handles a mode page from a CD-ROM MODE SELECT command: */
391: static int
392: _tme_scsi_cdrom_do_mode_select_page(struct tme_scsi_device *scsi_device,
393: const tme_uint8_t *mode_page)
394: {
395: return (0);
396: }
397:
398: /* this processes the parameter list from a CD-ROM MODE SELECT command: */
399: static
400: _TME_SCSI_DEVICE_PHASE_DECL(_tme_scsi_cdrom_mode_select_data)
401: {
402: tme_scsi_device_mode_select_data(scsi_device,
403: _tme_scsi_cdrom_do_mode_select_blocks,
404: _tme_scsi_cdrom_do_mode_select_page);
405: }
406:
407: /* this implements the CD-ROM MODE SELECT command: */
408: _TME_SCSI_DEVICE_CDB_DECL(tme_scsi_cdrom_cdb_mode_select)
409: {
410: tme_uint32_t length;
411: int is_group0_cmd;
412:
413: /* see if this is a Group 0 MODE SELECT: */
414: is_group0_cmd
415: = ((scsi_device->tme_scsi_device_cdb[0]
416: & TME_SCSI_CDB_GROUP_MASK)
417: == TME_SCSI_CDB_GROUP_0);
418:
419: /* read in the parameter list: */
420: if (is_group0_cmd) {
421: length = scsi_device->tme_scsi_device_cdb[4];
422: }
423: else {
424: length = scsi_device->tme_scsi_device_cdb[7];
425: length = (length << 8) + scsi_device->tme_scsi_device_cdb[8];
426: }
427: scsi_device->tme_scsi_device_dma.tme_scsi_dma_resid
428: = TME_MIN(sizeof(scsi_device->tme_scsi_device_data),
429: length);
430: scsi_device->tme_scsi_device_dma.tme_scsi_dma_in
431: = &scsi_device->tme_scsi_device_data[0];
432: scsi_device->tme_scsi_device_dma.tme_scsi_dma_out
433: = NULL;
434:
435: /* transfer the parameter list: */
436: tme_scsi_device_target_phase(scsi_device,
437: (TME_SCSI_SIGNAL_BSY
438: | TME_SCSI_PHASE_DATA_OUT));
439: scsi_device->tme_scsi_device_phase
440: = _tme_scsi_cdrom_mode_select_data;
441: }
442:
443: /* the new SCSI CD-ROM function: */
444: TME_ELEMENT_SUB_NEW_DECL(tme_scsi,cdrom) {
445: int id;
446: const char *cdrom_type;
447: const char *vendor;
448: const char *product;
449: const char *revision;
450: struct tme_scsi_cdrom *scsi_cdrom;
451: struct tme_scsi_device *scsi_device;
452: int arg_i;
453: int usage;
454: unsigned int cdrom_list_i;
455: int (*cdrom_init) _TME_P((struct tme_scsi_cdrom *));
456: int rc;
457:
458: /* check our arguments: */
459: id = -1;
460: cdrom_type = NULL;
461: vendor = NULL;
462: product = NULL;
463: revision = NULL;
464: arg_i = 1;
465: usage = FALSE;
466:
467: /* loop reading our arguments: */
468: for (;;) {
469:
470: /* the SCSI ID: */
471: if (TME_ARG_IS(args[arg_i], "id")
472: && id < 0
473: && (id = tme_scsi_id_parse(args[arg_i + 1])) >= 0) {
474: arg_i += 2;
475: }
476:
477: /* the CD-ROM type: */
478: else if (TME_ARG_IS(args[arg_i], "type")
479: && cdrom_type == NULL
480: && args[arg_i + 1] != NULL) {
481: cdrom_type = args[arg_i + 1];
482: arg_i += 2;
483: }
484:
485: /* any inquiry vendor, product, or revision: */
486: else if (TME_ARG_IS(args[arg_i], "vendor")
487: && vendor == NULL
488: && args[arg_i + 1] != NULL) {
489: vendor = args[arg_i + 1];
490: arg_i += 2;
491: }
492: else if (TME_ARG_IS(args[arg_i], "product")
493: && product == NULL
494: && args[arg_i + 1] != NULL) {
495: product = args[arg_i + 1];
496: arg_i += 2;
497: }
498: else if (TME_ARG_IS(args[arg_i], "revision")
499: && revision == NULL
500: && args[arg_i + 1] != NULL) {
501: revision = args[arg_i + 1];
502: arg_i += 2;
503: }
504:
505: /* if we've run out of arguments: */
506: else if (args[arg_i + 0] == NULL) {
507:
508: /* we must have been given an ID and a type: */
509: if (id < 0
510: || cdrom_type == NULL) {
511: usage = TRUE;
512: }
513: break;
514: }
515:
516: /* this is a bad argument: */
517: else {
518: tme_output_append_error(_output,
519: "%s %s",
520: args[arg_i],
521: _("unexpected"));
522: usage = TRUE;
523: break;
524: }
525: }
526:
527: if (usage) {
528: tme_output_append_error(_output,
529: "%s %s id %s type %s [ vendor %s ] [ product %s ] [ revision %s ]",
530: _("usage:"),
531: args[0],
532: _("TYPE"),
533: _("ID"),
534: _("VENDOR"),
535: _("PRODUCT"),
536: _("REVISION"));
537: return (EINVAL);
538: }
539:
540: /* make sure that this CD-ROM type is known: */
541: cdrom_init = NULL;
542: for (cdrom_list_i = 0;
543: cdrom_list_i < TME_ARRAY_ELS(_tme_scsi_cdrom_list);
544: cdrom_list_i++) {
545: if (!strcmp(_tme_scsi_cdrom_list[cdrom_list_i]._tme_scsi_cdrom_list_type,
546: cdrom_type)) {
547: cdrom_init = _tme_scsi_cdrom_list[cdrom_list_i]._tme_scsi_cdrom_list_init;
548: break;
549: }
550: }
551: if (cdrom_init == NULL) {
552: tme_output_append_error(_output, "%s", cdrom_type);
553: return (ENOENT);
554: }
555:
556: /* start the CD-ROM structure: */
557: scsi_cdrom = tme_new0(struct tme_scsi_cdrom, 1);
558: scsi_cdrom->tme_scsi_cdrom_element = element;
559: scsi_cdrom->tme_scsi_cdrom_type = tme_strdup(cdrom_type);
560:
561: /* initialize the generic SCSI device structure: */
562: scsi_device = &scsi_cdrom->tme_scsi_cdrom_device;
563: rc = tme_scsi_device_new(scsi_device, id);
564: assert (rc == TME_OK);
565:
566: scsi_device->tme_scsi_device_vendor
567: = tme_strdup((vendor == NULL)
568: ? "TME"
569: : vendor);
570: scsi_device->tme_scsi_device_product
571: = tme_strdup((product == NULL)
572: ? "CDROM"
573: : product);
574: scsi_device->tme_scsi_device_revision
575: = tme_strdup((revision == NULL)
576: ? "0000"
577: : revision);
578:
579: /* set the commands for CD-ROMs: */
580: TME_SCSI_DEVICE_DO_CDB(scsi_device,
581: TME_SCSI_CDB_INQUIRY,
582: tme_scsi_cdrom_cdb_inquiry);
583: TME_SCSI_DEVICE_DO_CDB(scsi_device,
584: TME_SCSI_CDB_CDROM_READ0,
585: tme_scsi_cdrom_cdb_read0);
586: TME_SCSI_DEVICE_DO_CDB(scsi_device,
587: TME_SCSI_CDB_CDROM_MODE_SELECT0,
588: tme_scsi_cdrom_cdb_mode_select);
589: TME_SCSI_DEVICE_DO_CDB(scsi_device,
590: TME_SCSI_CDB_CDROM_MODE_SENSE0,
591: tme_scsi_cdrom_cdb_mode_sense);
592: TME_SCSI_DEVICE_DO_CDB(scsi_device,
593: TME_SCSI_CDB_CDROM_START_STOP,
594: tme_scsi_cdrom_cdb_start_stop);
595: TME_SCSI_DEVICE_DO_CDB(scsi_device,
596: TME_SCSI_CDB_CDROM_PREVENT_ALLOW,
597: tme_scsi_cdrom_cdb_prevent_allow);
598: TME_SCSI_DEVICE_DO_CDB(scsi_device,
599: TME_SCSI_CDB_CDROM_READ_CAPACITY,
600: tme_scsi_cdrom_cdb_read_capacity);
601: TME_SCSI_DEVICE_DO_CDB(scsi_device,
602: TME_SCSI_CDB_CDROM_READ1,
603: tme_scsi_cdrom_cdb_read1);
604: TME_SCSI_DEVICE_DO_CDB(scsi_device,
605: TME_SCSI_CDB_CDROM_READ_SUBCHANNEL,
606: tme_scsi_device_cdb_illegal);
607: TME_SCSI_DEVICE_DO_CDB(scsi_device,
608: TME_SCSI_CDB_CDROM_READ_TOC,
609: tme_scsi_cdrom_cdb_read_toc);
610: TME_SCSI_DEVICE_DO_CDB(scsi_device,
611: TME_SCSI_CDB_CDROM_PLAY_AUDIO2,
612: tme_scsi_device_cdb_illegal);
613:
614: /* call the type-specific initialization function: */
615: rc = (*cdrom_init)(scsi_cdrom);
616: assert (rc == TME_OK);
617:
618: /* fill the element: */
619: element->tme_element_private = scsi_cdrom;
620: element->tme_element_connections_new = tme_scsi_cdrom_connections_new;
621:
622: return (TME_OK);
623: }
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.