1 /* Common Multimedia Command (MMC) routines.
2 Copyright (C) 2004-2008, 2010-2012, 2014
3 Rocky Bernstein <rocky@gnu.org>
4
5 This program is free software: you can redistribute it and/or modify
6 it under the terms of the GNU General Public License as published by
7 the Free Software Foundation, either version 3 of the License, or
8 (at your option) any later version.
9
10 This program is distributed in the hope that it will be useful,
11 but WITHOUT ANY WARRANTY; without even the implied warranty of
12 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 GNU General Public License for more details.
14
15 You should have received a copy of the GNU General Public License
16 along with this program. If not, see <http://www.gnu.org/licenses/>.
17 */
18
19 #ifdef HAVE_CONFIG_H
20 # include "config.h"
21 #endif
22
23 #ifdef HAVE_STDBOOL_H
24 # include <stdbool.h>
25 #endif
26
27 #include <cdio/cdio.h>
28 #include <cdio/logging.h>
29 #include <cdio/mmc.h>
30 #include <cdio/mmc_cmds.h>
31 #include <cdio/util.h>
32 #include "cdio_private.h"
33 #include "cdtext_private.h"
34
35 #ifdef HAVE_STRING_H
36 #include <string.h>
37 #endif
38
39 #ifdef HAVE_STDLIB_H
40 #include <stdlib.h>
41 #endif
42
43 #ifdef HAVE_STDIO_H
44 # include <stdio.h>
45 #endif
46
47 #ifdef HAVE_ERRNO_H
48 # include <errno.h>
49 #endif
50
51 const char
mmc_cmd2str(uint8_t command)52 *mmc_cmd2str(uint8_t command)
53 {
54 switch( command ) {
55 case CDIO_MMC_GPCMD_TEST_UNIT_READY:
56 return "TEST UNIT READY";
57
58 case CDIO_MMC_GPCMD_REQUEST_SENSE:
59 return "REQUEST SENSE";
60
61 case CDIO_MMC_GPCMD_FORMAT_UNIT:
62 return "FORMAT UNIT";
63
64 case CDIO_MMC_GPCMD_INQUIRY:
65 return "INQUIRY";
66
67 case CDIO_MMC_GPCMD_MODE_SELECT_6:
68 return "MODE SELECT (6)";
69
70 case CDIO_MMC_GPCMD_MODE_SENSE_6:
71 return "MODE SENSE (6)";
72
73 case CDIO_MMC_GPCMD_START_STOP_UNIT:
74 return "START STOP UNIT";
75
76 case CDIO_MMC_GPCMD_PREVENT_ALLOW_MEDIUM_REMOVAL:
77 return "PREVENT ALLOW MEDIUM REMOVAL";
78
79 case CDIO_MMC_GPCMD_READ_FORMAT_CAPACITIES:
80 return "READ FORMAT CAPACITIES";
81
82 case CDIO_MMC_GPCMD_READ_CAPACITIY:
83 return "READ_CAPACITIY";
84
85 case CDIO_MMC_GPCMD_READ_10:
86 return "READ (10)";
87
88 case CDIO_MMC_GPCMD_WRITE_10:
89 return "WRITE (10)";
90
91 case CDIO_MMC_GPCMD_SEEK_10:
92 return "SEEK (10)";
93
94 case CDIO_MMC_GPCMD_ERASE_10:
95 return "ERASE (10)";
96
97 case CDIO_MMC_GPCMD_WRITE_AND_VERIFY_10:
98 return "WRITE AND VERIFY (10)";
99
100 case CDIO_MMC_GPCMD_VERIFY_10:
101 return "VERIFY (10)";
102
103 case CDIO_MMC_GPCMD_SYNCHRONIZE_CACHE:
104 return "SYNCHRONIZE CACHE";
105
106 case CDIO_MMC_GPCMD_WRITE_BUFFER:
107 return "WRITE BUFFER";
108
109 case CDIO_MMC_GPCMD_READ_BUFFER:
110 return "READ_BUFFER";
111
112 case CDIO_MMC_GPCMD_READ_SUBCHANNEL:
113 return "READ_SUBCHANNEL";
114
115 case CDIO_MMC_GPCMD_READ_TOC:
116 return "READ TOC";
117
118 case CDIO_MMC_GPCMD_READ_HEADER:
119 return "READ_HEADER";
120
121 case CDIO_MMC_GPCMD_PLAY_AUDIO_10:
122 return "PLAY AUDIO (10)";
123
124 case CDIO_MMC_GPCMD_GET_CONFIGURATION:
125 return "GET_CONFIGURATION";
126
127 case CDIO_MMC_GPCMD_PLAY_AUDIO_MSF:
128 return "PLAY AUDIO MSF";
129
130 case CDIO_MMC_GPCMD_PLAY_AUDIO_TI:
131 return "PLAY_AUDIO TI";
132
133 case CDIO_MMC_GPCMD_PLAY_TRACK_REL_10:
134 return "PLAY TRACK REL (10)";
135
136 case CDIO_MMC_GPCMD_GET_EVENT_STATUS:
137 return "GET EVENT STATUS";
138
139 case CDIO_MMC_GPCMD_PAUSE_RESUME:
140 return "PAUSE RESUME";
141
142 case CDIO_MMC_GPCMD_READ_DISC_INFORMATION:
143 return "READ DISC INFORMATION";
144
145 case CDIO_MMC_GPCMD_READ_TRACK_INFORMATION:
146 return "READ TRACK INFORMATION";
147
148 case CDIO_MMC_GPCMD_RESERVE_TRACK:
149 return "RESERVE TRACK";
150
151 case CDIO_MMC_GPCMD_SEND_OPC_INFORMATION:
152 return "SEND OPC INFORMATION";
153
154 case CDIO_MMC_GPCMD_MODE_SELECT_10:
155 return "MODE SELECT (10)";
156
157 case CDIO_MMC_GPCMD_REPAIR_TRACK:
158 return "REPAIR_TRACK";
159
160 case CDIO_MMC_GPCMD_MODE_SENSE_10:
161 return "MODE SENSE (10)";
162
163 case CDIO_MMC_GPCMD_CLOSE_TRACK_SESSION:
164 return "CLOSE TRACK SESSION";
165
166 case CDIO_MMC_GPCMD_READ_BUFFER_CAPACITY:
167 return "READ_BUFFER CAPACITY";
168
169 case CDIO_MMC_GPCMD_SEND_CUE_SHEET:
170 return "SEND_CUE SHEET";
171
172 case CDIO_MMC_GPCMD_REPORT_LUNS:
173 return "REPORT LUNS";
174
175 case CDIO_MMC_GPCMD_BLANK:
176 return "BLANK";
177
178 case CDIO_MMC_GPCMD_SECURITY_PROTOCOL_IN:
179 return "SECURITY PROTOCOL IN";
180
181 case CDIO_MMC_GPCMD_SEND_KEY:
182 return "SEND KEY";
183
184 case CDIO_MMC_GPCMD_REPORT_KEY:
185 return "REPORT KEY";
186
187 case CDIO_MMC_GPCMD_PLAY_AUDIO_12:
188 return "PLAY_AUDIO (12)";
189
190 case CDIO_MMC_GPCMD_LOAD_UNLOAD:
191 return "LOAD UNLOAD";
192
193 case CDIO_MMC_GPCMD_SET_READ_AHEAD:
194 return "SET READ AHEAD";
195
196 case CDIO_MMC_GPCMD_READ_12:
197 return "READ (12)";
198
199 case CDIO_MMC_GPCMD_PLAY_TRACK_REL_12:
200 return "PLAY_TRACK REL (12)";
201
202 case CDIO_MMC_GPCMD_WRITE_12:
203 return "WRITE (12)";
204
205 case CDIO_MMC_GPCMD_READ_MEDIA_SERIAL_12:
206 return "READ MEDIA SERIAL (12)";
207
208 case CDIO_MMC_GPCMD_GET_PERFORMANCE:
209 return "GET PERFORMANCE";
210
211 case CDIO_MMC_GPCMD_READ_DVD_STRUCTURE:
212 return "READ DVD STRUCTURE";
213
214 case CDIO_MMC_GPCMD_SECURITY_PROTOCOL_OUT:
215 return "SECURITY PROTOCOL_OUT";
216
217 case CDIO_MMC_GPCMD_SET_STREAMING:
218 return "SET STREAMING";
219
220 case CDIO_MMC_GPCMD_READ_MSF:
221 return "READ MSF";
222
223 case CDIO_MMC_GPCMD_SET_SPEED:
224 return "SET SPEED";
225
226 case CDIO_MMC_GPCMD_MECHANISM_STATUS:
227 return "MECHANISM STATUS";
228
229 case CDIO_MMC_GPCMD_READ_CD:
230 return "READ CD";
231
232 case CDIO_MMC_GPCMD_SEND_DISC_STRUCTURE:
233 return "SEND DISC STRUCTURE";
234
235 case CDIO_MMC_GPCMD_CD_PLAYBACK_STATUS:
236 return "CD PLAYBACK STATUS";
237
238 case CDIO_MMC_GPCMD_PLAYBACK_CONTROL:
239 return "PLAYBACK CONTROL";
240
241 case CDIO_MMC_GPCMD_READ_CDDA:
242 return "READ CDDA";
243
244 case CDIO_MMC_GPCMD_READ_CDXA:
245 return "READ CDXA";
246
247 case CDIO_MMC_GPCMD_READ_ALL_SUBCODES:
248 return "READ ALL SUBCODES";
249
250 default:
251 {
252 char buf[30];
253 snprintf(buf, sizeof(buf), "Unknown 0x%x", command);
254 return strdup(buf);
255 }
256 }
257 }
258
259 /*************************************************************************
260 MMC CdIo Operations which a driver may use.
261 These are not accessible directly.
262
263 Most of these routines just pick out the cdio pointer and call the
264 corresponding publically-accessible routine.
265 *************************************************************************/
266
267 /**
268 Read Audio Subchannel information
269
270 @param p_user_data the CD object to be acted upon.
271
272 */
273 driver_return_code_t
audio_read_subchannel_mmc(void * p_user_data,cdio_subchannel_t * p_subchannel)274 audio_read_subchannel_mmc ( void *p_user_data, cdio_subchannel_t *p_subchannel)
275 {
276 generic_img_private_t *p_env = p_user_data;
277 if (!p_env) return DRIVER_OP_UNINIT;
278 return mmc_audio_read_subchannel(p_env->cdio, p_subchannel);
279 }
280
281 /**
282 Get the block size for subsequest read requests, via MMC.
283 @return the blocksize if > 0; error if <= 0
284 */
285 int
get_blocksize_mmc(void * p_user_data)286 get_blocksize_mmc (void *p_user_data)
287 {
288 generic_img_private_t *p_env = p_user_data;
289 if (!p_env) return DRIVER_OP_UNINIT;
290 return mmc_get_blocksize(p_env->cdio);
291 }
292
293 /**
294 Get the lsn of the end of the CD (via MMC).
295 */
296 lsn_t
get_disc_last_lsn_mmc(void * p_user_data)297 get_disc_last_lsn_mmc (void *p_user_data)
298 {
299 generic_img_private_t *p_env = p_user_data;
300 if (!p_env) return CDIO_INVALID_LSN;
301 return mmc_get_disc_last_lsn(p_env->cdio);
302 }
303
304 void
get_drive_cap_mmc(const void * p_user_data,cdio_drive_read_cap_t * p_read_cap,cdio_drive_write_cap_t * p_write_cap,cdio_drive_misc_cap_t * p_misc_cap)305 get_drive_cap_mmc (const void *p_user_data,
306 /*out*/ cdio_drive_read_cap_t *p_read_cap,
307 /*out*/ cdio_drive_write_cap_t *p_write_cap,
308 /*out*/ cdio_drive_misc_cap_t *p_misc_cap)
309 {
310 const generic_img_private_t *p_env = p_user_data;
311 mmc_get_drive_cap( p_env->cdio,
312 p_read_cap, p_write_cap, p_misc_cap );
313 }
314
315 /**
316 Find out if media has changed since the last call. @param
317 p_user_data the environment of the CD object to be acted upon.
318 @return 1 if media has changed since last call, 0 if not. Error
319 return codes are the same as driver_return_code_t
320 */
321 int
get_media_changed_mmc(const void * p_user_data)322 get_media_changed_mmc (const void *p_user_data)
323 {
324 const generic_img_private_t *p_env = p_user_data;
325 return mmc_get_media_changed( p_env->cdio );
326 }
327
328 char *
get_mcn_mmc(const void * p_user_data)329 get_mcn_mmc (const void *p_user_data)
330 {
331 const generic_img_private_t *p_env = p_user_data;
332 return mmc_get_mcn( p_env->cdio );
333 }
334
335 driver_return_code_t
get_tray_status(const void * p_user_data)336 get_tray_status (const void *p_user_data)
337 {
338 const generic_img_private_t *p_env = p_user_data;
339 return mmc_get_tray_status( p_env->cdio );
340 }
341
342 /**
343 Read sectors using SCSI-MMC GPCMD_READ_CD.
344 */
345 driver_return_code_t
mmc_read_data_sectors(CdIo_t * p_cdio,void * p_buf,lsn_t i_lsn,uint16_t i_blocksize,uint32_t i_blocks)346 mmc_read_data_sectors ( CdIo_t *p_cdio, void *p_buf,
347 lsn_t i_lsn, uint16_t i_blocksize,
348 uint32_t i_blocks )
349 {
350 return mmc_read_cd(p_cdio,
351 p_buf, /* place to store data */
352 i_lsn, /* lsn */
353 0, /* read_sector_type */
354 false, /* digital audio play */
355 false, /* return sync header */
356 0, /* header codes */
357 true, /* return user data */
358 false, /* return EDC ECC */
359 false, /* return C2 Error information */
360 0, /* subchannel selection bits */
361 ISO_BLOCKSIZE, /* blocksize*/
362 i_blocks /* Number of blocks. */);
363
364 }
365
366
367 /**
368 Read sectors using SCSI-MMC GPCMD_READ_CD.
369 Can read only up to 25 blocks.
370 */
371 driver_return_code_t
read_data_sectors_mmc(void * p_user_data,void * p_buf,lsn_t i_lsn,uint16_t i_blocksize,uint32_t i_blocks)372 read_data_sectors_mmc ( void *p_user_data, void *p_buf,
373 lsn_t i_lsn, uint16_t i_blocksize,
374 uint32_t i_blocks )
375 {
376 const generic_img_private_t *p_env = p_user_data;
377 return mmc_read_data_sectors( p_env->cdio, p_buf, i_lsn, i_blocksize,
378 i_blocks );
379 }
380
381 /**
382 Set read blocksize (via MMC)
383 */
384 driver_return_code_t
set_blocksize_mmc(void * p_user_data,uint16_t i_blocksize)385 set_blocksize_mmc (void *p_user_data, uint16_t i_blocksize)
386 {
387 generic_img_private_t *p_env = p_user_data;
388 if (!p_env) return DRIVER_OP_UNINIT;
389 return mmc_set_blocksize(p_env->cdio, i_blocksize);
390 }
391
392 /** Set the drive speed Set the drive speed in K bytes per second. (via
393 MMC).
394 */
395 driver_return_code_t
set_speed_mmc(void * p_user_data,int i_speed)396 set_speed_mmc (void *p_user_data, int i_speed)
397 {
398 generic_img_private_t *p_env = p_user_data;
399 if (!p_env) return DRIVER_OP_UNINIT;
400 return mmc_set_speed( p_env->cdio, i_speed, 0);
401 }
402
403 /**
404 Set the drive speed in CD-ROM speed units (via MMC).
405 */
406 driver_return_code_t
set_drive_speed_mmc(void * p_user_data,int i_Kbs_speed)407 set_drive_speed_mmc (void *p_user_data, int i_Kbs_speed)
408 {
409 generic_img_private_t *p_env = p_user_data;
410 if (!p_env) return DRIVER_OP_UNINIT;
411 return mmc_set_drive_speed( p_env->cdio, i_Kbs_speed );
412 }
413
414 /**
415 Get the output port volumes and port selections used on AUDIO PLAY
416 commands via a MMC MODE SENSE command using the CD Audio Control
417 Page.
418 */
419 driver_return_code_t
mmc_audio_get_volume(CdIo_t * p_cdio,mmc_audio_volume_t * p_volume)420 mmc_audio_get_volume( CdIo_t *p_cdio, /*out*/ mmc_audio_volume_t *p_volume )
421 {
422 uint8_t buf[16];
423 int i_rc = mmc_mode_sense(p_cdio, buf, sizeof(buf), CDIO_MMC_AUDIO_CTL_PAGE);
424
425 if ( DRIVER_OP_SUCCESS == i_rc ) {
426 p_volume->port[0].selection = 0xF & buf[8];
427 p_volume->port[0].volume = buf[9];
428 p_volume->port[1].selection = 0xF & buf[10];
429 p_volume->port[1].volume = buf[11];
430 p_volume->port[2].selection = 0xF & buf[12];
431 p_volume->port[2].volume = buf[13];
432 p_volume->port[3].selection = 0xF & buf[14];
433 p_volume->port[3].volume = buf[15];
434 return DRIVER_OP_SUCCESS;
435 }
436 return i_rc;
437 }
438
439 /**
440 Get the DVD type associated with cd object.
441 */
442 discmode_t
mmc_get_dvd_struct_physical_private(void * p_env,mmc_run_cmd_fn_t run_mmc_cmd,cdio_dvd_struct_t * s)443 mmc_get_dvd_struct_physical_private ( void *p_env,
444 mmc_run_cmd_fn_t run_mmc_cmd,
445 cdio_dvd_struct_t *s)
446 {
447 mmc_cdb_t cdb = {{0, }};
448 unsigned char buf[4 + 4 * 20], *base;
449 int i_status;
450 uint8_t layer_num = s->physical.layer_num;
451
452 cdio_dvd_layer_t *layer;
453
454 if (!p_env) return DRIVER_OP_UNINIT;
455 if (!run_mmc_cmd) return DRIVER_OP_UNSUPPORTED;
456
457 if (layer_num >= CDIO_DVD_MAX_LAYERS)
458 return -EINVAL;
459
460 CDIO_MMC_SET_COMMAND(cdb.field, CDIO_MMC_GPCMD_READ_DVD_STRUCTURE);
461 cdb.field[6] = layer_num;
462 cdb.field[7] = CDIO_DVD_STRUCT_PHYSICAL;
463 cdb.field[9] = sizeof(buf) & 0xff;
464
465 i_status = run_mmc_cmd(p_env, mmc_timeout_ms,
466 mmc_get_cmd_len(cdb.field[0]),
467 &cdb, SCSI_MMC_DATA_READ,
468 sizeof(buf), &buf);
469 if (0 != i_status)
470 return CDIO_DISC_MODE_ERROR;
471
472 base = &buf[4];
473 layer = &s->physical.layer[layer_num];
474
475 /*
476 * place the data... really ugly, but at least we won't have to
477 * worry about endianess in userspace.
478 */
479 memset(layer, 0, sizeof(*layer));
480 layer->book_version = base[0] & 0xf;
481 layer->book_type = base[0] >> 4;
482 layer->min_rate = base[1] & 0xf;
483 layer->disc_size = base[1] >> 4;
484 layer->layer_type = base[2] & 0xf;
485 layer->track_path = (base[2] >> 4) & 1;
486 layer->nlayers = (base[2] >> 5) & 3;
487 layer->track_density = base[3] & 0xf;
488 layer->linear_density = base[3] >> 4;
489 layer->start_sector = base[5] << 16 | base[6] << 8 | base[7];
490 layer->end_sector = base[9] << 16 | base[10] << 8 | base[11];
491 layer->end_sector_l0 = base[13] << 16 | base[14] << 8 | base[15];
492 layer->bca = base[16] >> 7;
493
494 return (discmode_t) DRIVER_OP_SUCCESS;
495 }
496
497 /**
498 Get the media catalog number (MCN) or the ISRC
499
500 Note: string is malloc'd so caller should free() then returned
501 string when done with it.
502
503 @param p_cdio
504 @param i_track track number
505 @param sub_chan_param 2 for MCN, 3 for ISRC
506
507 @return malloc'd string holding the MCN or ISRC on success
508 or NULL on failure
509 */
510 char *
mmc_get_mcn_isrc_private(const CdIo_t * p_cdio,track_t i_track,unsigned char sub_chan_param)511 mmc_get_mcn_isrc_private ( const CdIo_t *p_cdio,
512 track_t i_track,
513 unsigned char sub_chan_param
514 )
515 {
516 char buf[24]; /* 4 header + 20 data (MMC-4 tables 424, 431, 432) */
517 unsigned int num_data;
518 size_t length;
519 driver_return_code_t i_rc;
520
521 switch(sub_chan_param) {
522 case CDIO_SUBCHANNEL_MEDIA_CATALOG: /* MCN */
523 length = CDIO_MCN_SIZE;
524 break;
525 case CDIO_SUBCHANNEL_TRACK_ISRC: /* ISRC */
526 length = CDIO_ISRC_SIZE;
527 break;
528 default:
529 return NULL;
530 }
531
532 /* inquire number of available reply bytes
533 workaround for bad device drivers
534 */
535 num_data = 4; /* header only */
536 i_rc = mmc_read_subchannel (p_cdio, i_track,
537 sub_chan_param, &num_data, buf, 0);
538
539 if (i_rc != DRIVER_OP_SUCCESS)
540 return NULL;
541
542 if (num_data > sizeof(buf))
543 num_data = sizeof(buf);
544
545 if (num_data < 9 + length)
546 return NULL; /* Not enough data available */
547
548 i_rc = mmc_read_subchannel (p_cdio, i_track,
549 sub_chan_param, &num_data, buf, 0);
550 if (i_rc != DRIVER_OP_SUCCESS)
551 return NULL;
552
553 if (num_data < 9 + length)
554 return NULL; /* Not enough data returned */
555
556 if ( ! (buf[8] & 0x80) ) /* MCVAL / TCVAL bit indicates a valid response */
557 return NULL; /* MCN/ISRC not valid */
558 return strndup(&buf[9], length);
559 }
560
561
562
563 driver_return_code_t
mmc_set_blocksize_private(void * p_env,const mmc_run_cmd_fn_t run_mmc_cmd,uint16_t i_blocksize)564 mmc_set_blocksize_private ( void *p_env,
565 const mmc_run_cmd_fn_t run_mmc_cmd,
566 uint16_t i_blocksize)
567 {
568 mmc_cdb_t cdb = {{0, }};
569
570 struct
571 {
572 uint8_t reserved1;
573 uint8_t medium;
574 uint8_t reserved2;
575 uint8_t block_desc_length;
576 uint8_t density;
577 uint8_t number_of_blocks_hi;
578 uint8_t number_of_blocks_med;
579 uint8_t number_of_blocks_lo;
580 uint8_t reserved3;
581 uint8_t block_length_hi;
582 uint8_t block_length_med;
583 uint8_t block_length_lo;
584 } mh;
585
586 if ( ! p_env ) return DRIVER_OP_UNINIT;
587 if ( ! run_mmc_cmd ) return DRIVER_OP_UNSUPPORTED;
588
589 memset (&mh, 0, sizeof (mh));
590 mh.block_desc_length = 0x08;
591
592 /* while i_blocksize is uint16_t, this expression is always 0 */
593 mh.block_length_hi = (i_blocksize >> 16) & 0xff;
594
595 mh.block_length_med = (i_blocksize >> 8) & 0xff;
596 mh.block_length_lo = (i_blocksize >> 0) & 0xff;
597
598 CDIO_MMC_SET_COMMAND(cdb.field, CDIO_MMC_GPCMD_MODE_SELECT_6);
599
600 cdb.field[1] = 1 << 4;
601 cdb.field[4] = 12;
602
603 return run_mmc_cmd (p_env, mmc_timeout_ms,
604 mmc_get_cmd_len(cdb.field[0]), &cdb,
605 SCSI_MMC_DATA_WRITE, sizeof(mh), &mh);
606 }
607
608
609
610 /***********************************************************
611 User-accessible Operations.
612 ************************************************************/
613 /**
614 Read Audio Subchannel information
615
616 @param p_cdio the CD object to be acted upon.
617 */
618 driver_return_code_t
mmc_audio_read_subchannel(CdIo_t * p_cdio,cdio_subchannel_t * p_subchannel)619 mmc_audio_read_subchannel (CdIo_t *p_cdio, cdio_subchannel_t *p_subchannel)
620 {
621 mmc_cdb_t cdb;
622 driver_return_code_t i_rc;
623 cdio_mmc_subchannel_t mmc_subchannel;
624
625 if (!p_cdio) return DRIVER_OP_UNINIT;
626
627 memset(&mmc_subchannel, 0, sizeof(mmc_subchannel));
628 mmc_subchannel.format = CDIO_CDROM_MSF;
629 memset(&cdb, 0, sizeof(mmc_cdb_t));
630
631 CDIO_MMC_SET_COMMAND(cdb.field, CDIO_MMC_GPCMD_READ_SUBCHANNEL);
632 CDIO_MMC_SET_READ_LENGTH8(cdb.field, sizeof(cdio_mmc_subchannel_t));
633
634 cdb.field[1] = CDIO_CDROM_MSF;
635 cdb.field[2] = 0x40; /* subq */
636 cdb.field[3] = CDIO_SUBCHANNEL_CURRENT_POSITION;
637 cdb.field[6] = 0; /* track number (only in isrc mode, ignored) */
638
639 i_rc = mmc_run_cmd(p_cdio, mmc_timeout_ms, &cdb, SCSI_MMC_DATA_READ,
640 sizeof(cdio_mmc_subchannel_t), &mmc_subchannel);
641 if (DRIVER_OP_SUCCESS == i_rc) {
642 p_subchannel->format = mmc_subchannel.format;
643 p_subchannel->audio_status = mmc_subchannel.audio_status;
644 p_subchannel->address = mmc_subchannel.address;
645 p_subchannel->control = mmc_subchannel.control;
646 p_subchannel->track = mmc_subchannel.track;
647 p_subchannel->index = mmc_subchannel.index;
648 p_subchannel->abs_addr.m = cdio_to_bcd8(mmc_subchannel.abs_addr[1]);
649 p_subchannel->abs_addr.s = cdio_to_bcd8(mmc_subchannel.abs_addr[2]);
650 p_subchannel->abs_addr.f = cdio_to_bcd8(mmc_subchannel.abs_addr[3]);
651 p_subchannel->rel_addr.m = cdio_to_bcd8(mmc_subchannel.rel_addr[1]);
652 p_subchannel->rel_addr.s = cdio_to_bcd8(mmc_subchannel.rel_addr[2]);
653 p_subchannel->rel_addr.f = cdio_to_bcd8(mmc_subchannel.rel_addr[3]);
654 }
655 return i_rc;
656 }
657
658 /**
659 Get the block size used in read requests, via MMC (e.g. READ_10,
660 READ_MSF, ...)
661
662 @param p_cdio the CD object to be acted upon.
663 @return the blocksize if > 0; error if <= 0
664 */
665 int
mmc_get_blocksize(CdIo_t * p_cdio)666 mmc_get_blocksize ( CdIo_t *p_cdio)
667 {
668 int i_status;
669
670 uint8_t buf[255] = { 0, };
671 uint8_t *p;
672
673 /* First try using the 6-byte MODE SENSE command. */
674 i_status = mmc_mode_sense_6(p_cdio, buf, sizeof(buf),
675 CDIO_MMC_R_W_ERROR_PAGE);
676
677 if (DRIVER_OP_SUCCESS == i_status && buf[3]>=8) {
678 p = &buf[4+5];
679 return CDIO_MMC_GET_LEN16(p);
680 }
681
682 /* Next try using the 10-byte MODE SENSE command. */
683 i_status = mmc_mode_sense_10(p_cdio, buf, sizeof(buf),
684 CDIO_MMC_R_W_ERROR_PAGE);
685 p = &buf[6];
686 if (DRIVER_OP_SUCCESS == i_status && CDIO_MMC_GET_LEN16(p)>=8) {
687 return CDIO_MMC_GET_LEN16(p);
688 }
689
690 #ifdef IS_THIS_CORRECT
691 /* Lastly try using the READ CAPACITY command. */
692 {
693 lba_t lba = 0;
694 uint16_t i_blocksize;
695
696 i_status = mmc_read_capacity(p_cdio, &lba, &i_blocksize);
697 if ( DRIVER_OP_SUCCESS == i_status )
698 return i_blocksize;
699 #endif
700
701 return DRIVER_OP_UNSUPPORTED;
702 }
703
704 /**
705 Return the number of length in bytes of the Command Descriptor
706 buffer (CDB) for a given MMC command. The length will be
707 either 6, 10, or 12.
708 */
709 uint8_t
710 mmc_get_cmd_len(uint8_t scsi_cmd)
711 {
712 static const uint8_t scsi_cdblen[8] = {6, 10, 10, 12, 12, 12, 10, 10};
713 return scsi_cdblen[((scsi_cmd >> 5) & 7)];
714 }
715
716 /**
717 Return the size of the CD in logical block address (LBA) units.
718 @param p_cdio the CD object to be acted upon.
719 @return the lsn. On error 0 or CDIO_INVALD_LSN.
720 */
721 lsn_t
722 mmc_get_disc_last_lsn ( const CdIo_t *p_cdio )
723 {
724 mmc_cdb_t cdb = {{0, }};
725 uint8_t buf[12] = { 0, };
726
727 lsn_t retval = 0;
728 int i_status;
729
730 /* Operation code */
731 CDIO_MMC_SET_COMMAND(cdb.field, CDIO_MMC_GPCMD_READ_TOC);
732
733 cdb.field[1] = 0; /* lba; msf: 0x2 */
734
735 /* Format */
736 cdb.field[2] = CDIO_MMC_READTOC_FMT_TOC;
737
738 CDIO_MMC_SET_START_TRACK(cdb.field, CDIO_CDROM_LEADOUT_TRACK);
739
740 CDIO_MMC_SET_READ_LENGTH16(cdb.field, sizeof(buf));
741
742 i_status = mmc_run_cmd(p_cdio, mmc_timeout_ms, &cdb, SCSI_MMC_DATA_READ,
743 sizeof(buf), buf);
744
745 if (i_status) return CDIO_INVALID_LSN;
746
747 {
748 int i;
749 for (i = 8; i < 12; i++) {
750 retval <<= 8;
751 retval += buf[i];
752 }
753 }
754
755 return retval;
756 }
757
758 /**
759 Return the discmode as reported by the SCSI-MMC Read (FULL) TOC
760 command.
761
762 Information was obtained from Section 5.1.13 (Read TOC/PMA/ATIP)
763 pages 56-62 from the MMC draft specification, revision 10a
764 at http://www.t10.org/ftp/t10/drafts/mmc/mmc-r10a.pdf See
765 especially tables 72, 73 and 75.
766 */
767 discmode_t
768 mmc_get_discmode( const CdIo_t *p_cdio )
769
770 {
771 uint8_t buf[14] = { 0, };
772 mmc_cdb_t cdb;
773
774 memset(&cdb, 0, sizeof(mmc_cdb_t));
775
776 CDIO_MMC_SET_COMMAND(cdb.field, CDIO_MMC_GPCMD_READ_TOC);
777 CDIO_MMC_SET_READ_LENGTH8(cdb.field, sizeof(buf));
778
779 cdb.field[1] = CDIO_CDROM_MSF; /* The MMC-5 spec may require this. */
780 cdb.field[2] = CDIO_MMC_READTOC_FMT_FULTOC;
781
782 mmc_run_cmd(p_cdio, 2000, &cdb, SCSI_MMC_DATA_READ, sizeof(buf), buf);
783 if (buf[7] == 0xA0) {
784 if (buf[13] == 0x00) {
785 if (buf[5] & 0x04)
786 return CDIO_DISC_MODE_CD_DATA;
787 else
788 return CDIO_DISC_MODE_CD_DA;
789 }
790 else if (buf[13] == 0x10)
791 return CDIO_DISC_MODE_CD_I;
792 else if (buf[13] == 0x20)
793 return CDIO_DISC_MODE_CD_XA;
794 }
795 return CDIO_DISC_MODE_NO_INFO;
796 }
797
798 /**
799 Get drive capabilities for a device.
800 @param p_cdio the CD object to be acted upon.
801 @return the drive capabilities.
802 */
803 void
804 mmc_get_drive_cap (CdIo_t *p_cdio,
805 /*out*/ cdio_drive_read_cap_t *p_read_cap,
806 /*out*/ cdio_drive_write_cap_t *p_write_cap,
807 /*out*/ cdio_drive_misc_cap_t *p_misc_cap)
808 {
809 /* Largest buffer size we use. */
810 #define BUF_MAX 2048
811 uint8_t buf[BUF_MAX+2] = { 0, };
812
813 int i_status;
814 uint16_t i_data = BUF_MAX;
815 int page = CDIO_MMC_ALL_PAGES;
816
817 if ( ! p_cdio ) return;
818 retry:
819
820 /* In the first run we run MODE SENSE 10 we are trying to get the
821 length of the data features. */
822 i_status = mmc_mode_sense_10(p_cdio, buf, 8, CDIO_MMC_ALL_PAGES);
823
824 if (DRIVER_OP_SUCCESS == i_status) {
825 uint16_t i_data_try = (uint16_t) CDIO_MMC_GET_LEN16(buf);
826 if (i_data_try < BUF_MAX) i_data = i_data_try;
827 }
828
829 /* Now try getting all features with length set above, possibly
830 truncated or the default length if we couldn't get the proper
831 length. */
832 i_status = mmc_mode_sense_10(p_cdio, buf, i_data, CDIO_MMC_ALL_PAGES);
833 if (0 != i_status && CDIO_MMC_CAPABILITIES_PAGE != page) {
834 page = CDIO_MMC_CAPABILITIES_PAGE;
835 goto retry;
836 }
837
838 if (DRIVER_OP_SUCCESS == i_status) {
839 uint8_t *p;
840 uint8_t *p_max = buf + 256;
841
842 *p_read_cap = 0;
843 *p_write_cap = 0;
844 *p_misc_cap = 0;
845
846 /* set to first sense mask, and then walk through the masks */
847 p = buf + 8;
848 while( (p < &(buf[2+i_data])) && (p < p_max) ) {
849 uint8_t which_page;
850
851 which_page = p[0] & 0x3F;
852 switch( which_page )
853 {
854 case CDIO_MMC_AUDIO_CTL_PAGE:
855 case CDIO_MMC_R_W_ERROR_PAGE:
856 case CDIO_MMC_CDR_PARMS_PAGE:
857 /* Don't handle these yet. */
858 break;
859 case CDIO_MMC_CAPABILITIES_PAGE:
860 mmc_get_drive_cap_buf(p, p_read_cap, p_write_cap, p_misc_cap);
861 break;
862 default: ;
863 }
864 p += (p[1] + 2);
865 }
866 } else {
867 cdio_info("%s: %s\n", "error in MODE_SELECT", strerror(errno));
868 *p_read_cap = CDIO_DRIVE_CAP_ERROR;
869 *p_write_cap = CDIO_DRIVE_CAP_ERROR;
870 *p_misc_cap = CDIO_DRIVE_CAP_ERROR;
871 }
872 return;
873 }
874
875 /**
876 Get the MMC level supported by the device.
877 */
878 cdio_mmc_level_t
879 mmc_get_drive_mmc_cap(CdIo_t *p_cdio)
880 {
881 uint8_t buf[256] = { 0, };
882 uint8_t len;
883 int rc = mmc_mode_sense(p_cdio, buf, sizeof(buf),
884 CDIO_MMC_CAPABILITIES_PAGE);
885
886 if (DRIVER_OP_SUCCESS != rc) {
887 return CDIO_MMC_LEVEL_NONE;
888 }
889
890 len = buf[1];
891 if (16 > len) {
892 return CDIO_MMC_LEVEL_WEIRD;
893 } else if (28 <= len) {
894 return CDIO_MMC_LEVEL_3;
895 } else if (24 <= len) {
896 return CDIO_MMC_LEVEL_2;
897 } else if (20 <= len) {
898 return CDIO_MMC_LEVEL_1;
899 } else {
900 return CDIO_MMC_LEVEL_WEIRD;
901 }
902 }
903
904 /**
905 Get the DVD type associated with cd object.
906
907 @param p_cdio the CD object to be acted upon.
908 @return the DVD discmode.
909 */
910 discmode_t
911 mmc_get_dvd_struct_physical ( const CdIo_t *p_cdio, cdio_dvd_struct_t *s)
912 {
913 if ( ! p_cdio ) return -2;
914 return
915 mmc_get_dvd_struct_physical_private (p_cdio->env,
916 p_cdio->op.run_mmc_cmd,
917 s);
918 }
919
920 /**
921 Get the CD-ROM hardware info via a MMC INQUIRY command.
922 False is returned if we had an error getting the information.
923
924 @param p_cdio the CD object to be acted upon.
925 @return true if we were able to get hardware info, false if we had
926 an error.
927 */
928 bool
929 mmc_get_hwinfo ( const CdIo_t *p_cdio,
930 /*out*/ cdio_hwinfo_t *hw_info )
931 {
932 int i_status; /* Result of MMC command */
933 char buf[36] = { 0, }; /* Place to hold returned data */
934 mmc_cdb_t cdb = {{0, }}; /* Command Descriptor Block */
935
936 CDIO_MMC_SET_COMMAND(cdb.field, CDIO_MMC_GPCMD_INQUIRY);
937 cdb.field[4] = sizeof(buf);
938
939 if (! p_cdio || ! hw_info ) return false;
940
941 i_status = mmc_run_cmd(p_cdio, mmc_timeout_ms,
942 &cdb, SCSI_MMC_DATA_READ,
943 sizeof(buf), &buf);
944 if (i_status == 0) {
945
946 memcpy(hw_info->psz_vendor,
947 buf + 8,
948 sizeof(hw_info->psz_vendor)-1);
949 hw_info->psz_vendor[sizeof(hw_info->psz_vendor)-1] = '\0';
950 memcpy(hw_info->psz_model,
951 buf + 8 + CDIO_MMC_HW_VENDOR_LEN,
952 sizeof(hw_info->psz_model)-1);
953 hw_info->psz_model[sizeof(hw_info->psz_model)-1] = '\0';
954 memcpy(hw_info->psz_revision,
955 buf + 8 + CDIO_MMC_HW_VENDOR_LEN + CDIO_MMC_HW_MODEL_LEN,
956 sizeof(hw_info->psz_revision)-1);
957 hw_info->psz_revision[sizeof(hw_info->psz_revision)-1] = '\0';
958 return true;
959 }
960 return false;
961 }
962
963 /**
964 Find out if media has changed since the last call.
965 @param p_cdio the CD object to be acted upon.
966 @return 1 if media has changed since last call, 0 if not. Error
967 return codes are the same as driver_return_code_t
968 */
969 int mmc_get_media_changed(const CdIo_t *p_cdio)
970 {
971 uint8_t status_buf[2];
972 int i_status;
973
974 i_status = mmc_get_event_status(p_cdio, status_buf);
975 if (i_status != DRIVER_OP_SUCCESS)
976 return i_status;
977 return (status_buf[0] & 0x02) ? 1 : 0;
978 }
979
980 /**
981 Get the media catalog number (MCN) from the CD via MMC.
982
983 @param p_cdio the CD object to be acted upon.
984 @return the media catalog number r NULL if there is none or we
985 don't have the ability to get it.
986
987 Note: The caller must free the returned string with cdio_free()
988 when done with it.
989
990 */
991 char *
992 mmc_get_mcn ( const CdIo_t *p_cdio )
993 {
994 if ( ! p_cdio ) return NULL;
995 return mmc_get_mcn_isrc_private (p_cdio, 0, CDIO_SUBCHANNEL_MEDIA_CATALOG );
996 }
997
998 /**
999 Get the international standard recording code (ISRC) of the track via MMC.
1000 @param p_cdio the CD object to be acted upon.
1001 @param i_track the track to get the ISRC info for.
1002 @return the international standard recording code or NULL if there is
1003 none or we don't have the ability to get it.
1004
1005 Note: The caller must free the returned string with cdio_free()
1006 when done with it.
1007
1008 */
1009 char *
1010 mmc_get_track_isrc ( const CdIo_t *p_cdio, track_t i_track )
1011 {
1012 if ( ! p_cdio ) return NULL;
1013 return mmc_get_mcn_isrc_private (p_cdio, i_track, CDIO_SUBCHANNEL_TRACK_ISRC );
1014 }
1015
1016 /**
1017 Read cdtext information for a CdIo_t object .
1018
1019 @return pointer to data on success, NULL on error or CD-Text information does
1020 not exist.
1021
1022 Note: the caller must free the returned memory
1023
1024 */
1025 uint8_t *
1026 mmc_read_cdtext (const CdIo_t *p_cdio)
1027 {
1028
1029 unsigned char buf[4];
1030 unsigned char * wdata;
1031 int i_status;
1032 unsigned int i_cdtext;
1033
1034 if ( ! p_cdio )
1035 return NULL;
1036
1037 /* We may need to give CD-Text a little more time to complete. */
1038 /* First off, just try and read the size */
1039 i_cdtext = 4;
1040 i_status = mmc_read_toc_cdtext(p_cdio, &i_cdtext, buf, 0);
1041
1042 if (i_status != DRIVER_OP_SUCCESS) {
1043 return NULL;
1044 }
1045
1046 if (i_cdtext > CDTEXT_LEN_BINARY_MAX + 2)
1047 i_cdtext = CDTEXT_LEN_BINARY_MAX + 4;
1048 else
1049 i_cdtext += 2; /* data length does not include the data length field */
1050
1051 wdata = malloc(i_cdtext); /* is zeroed in mmc_toc_read_cdtext */
1052
1053 /* Read all of it */
1054 i_status = mmc_read_toc_cdtext(p_cdio, &i_cdtext, wdata, 0);
1055
1056 if (i_status != DRIVER_OP_SUCCESS) {
1057 free(wdata);
1058 return NULL;
1059 }
1060
1061 return wdata;
1062 }
1063
1064 /**
1065 Find out if media tray is open or closed.
1066 @param p_cdio the CD object to be acted upon.
1067 @return 1 if media is open, 0 if closed. Error
1068 return codes are the same as driver_return_code_t
1069 */
1070 int mmc_get_tray_status(const CdIo_t *p_cdio)
1071 {
1072 uint8_t status_buf[2];
1073 int i_status;
1074
1075 i_status = mmc_get_event_status(p_cdio, status_buf);
1076 if (i_status != DRIVER_OP_SUCCESS)
1077 return i_status;
1078 return (status_buf[1] & 0x01) ? 1 : 0;
1079 }
1080
1081 /* Added in version 0.83 by scdbackup */
1082 /**
1083 Obtain the SCSI sense reply of the most-recently-performed MMC command.
1084 These bytes give an indication of possible problems which occured in
1085 the drive while the command was performed. With some commands they tell
1086 about the current state of the drive (e.g. 00h TEST UNIT READY).
1087 @param p_cdio CD structure set by cdio_open().
1088
1089 @param sense returns the sense bytes received from the drive.
1090 This is allocated memory or NULL if no sense bytes are
1091 available. Dispose non-NULL pointers by cdio_free() when no longer
1092 needed. See SPC-3 4.5.3 Fixed format sense data. SCSI error
1093 codes as of SPC-3 Annex D, MMC-5 Annex F: sense[2]&15 = Key ,
1094 sense[12] = ASC , sense[13] = ASCQ
1095
1096 @return number of valid bytes in sense, 0 in case of no sense
1097 bytes available, <0 in case of internal error.
1098 */
1099 int
1100 mmc_last_cmd_sense(const CdIo_t *p_cdio, cdio_mmc_request_sense_t **pp_sense)
1101 {
1102 generic_img_private_t *gen;
1103
1104 if (!p_cdio) return DRIVER_OP_UNINIT;
1105 gen = p_cdio->env;
1106 *pp_sense = NULL;
1107 if (gen->scsi_mmc_sense_valid <= 0)
1108 return 0;
1109 *pp_sense = calloc(1, gen->scsi_mmc_sense_valid);
1110 if (*pp_sense == NULL)
1111 return DRIVER_OP_ERROR;
1112 memcpy(*pp_sense, gen->scsi_mmc_sense, gen->scsi_mmc_sense_valid);
1113 return gen->scsi_mmc_sense_valid;
1114 }
1115
1116 /**
1117 Run a MMC command.
1118
1119 @param cdio CD structure set by cdio_open().
1120 @param i_timeout time in milliseconds we will wait for the command
1121 to complete. If this value is -1, use the default
1122 time-out value.
1123 @param buf Buffer for data, both sending and receiving
1124 @param len Size of buffer
1125 @param e_direction direction the transfer is to go
1126 @param cdb CDB bytes. All values that are needed should be set on
1127 input. We'll figure out what the right CDB length
1128 should be.
1129 */
1130 driver_return_code_t
1131 mmc_run_cmd( const CdIo_t *p_cdio, unsigned int i_timeout_ms,
1132 const mmc_cdb_t *p_cdb,
1133 cdio_mmc_direction_t e_direction, unsigned int i_buf,
1134 /*in/out*/ void *p_buf )
1135 {
1136 if (!p_cdio) return DRIVER_OP_UNINIT;
1137 if (!p_cdio->op.run_mmc_cmd) return DRIVER_OP_UNSUPPORTED;
1138 return p_cdio->op.run_mmc_cmd(p_cdio->env, i_timeout_ms,
1139 mmc_get_cmd_len(p_cdb->field[0]),
1140 p_cdb, e_direction, i_buf, p_buf);
1141 }
1142
1143 /* Added by SukkoPera to allow CDB length to be specified manually */
1144 /**
1145 Run a Multimedia command (MMC) specifying the CDB length.
1146 The motivation here is for example ot use in is an undocumented
1147 debug command for LG drives (namely E7), whose length is being
1148 miscalculated by mmc_get_cmd_len(); it doesn't follow the usual
1149 code number to length conventions. Patch supplied by SukkoPera.
1150
1151 @param p_cdio CD structure set by cdio_open().
1152 @param i_timeout_ms time in milliseconds we will wait for the command
1153 to complete.
1154 @param p_cdb CDB bytes. All values that are needed should be set
1155 on input.
1156 @param i_cdb number of CDB bytes.
1157 @param e_direction direction the transfer is to go.
1158 @param i_buf Size of buffer
1159 @param p_buf Buffer for data, both sending and receiving.
1160
1161 @return 0 if command completed successfully.
1162 */
1163
1164 driver_return_code_t
1165 mmc_run_cmd_len( const CdIo_t *p_cdio, unsigned int i_timeout_ms,
1166 const mmc_cdb_t *p_cdb, unsigned int i_cdb,
1167 cdio_mmc_direction_t e_direction, unsigned int i_buf,
1168 /*in/out*/ void *p_buf )
1169 {
1170 if (!p_cdio) return DRIVER_OP_UNINIT;
1171 if (!p_cdio->op.run_mmc_cmd) return DRIVER_OP_UNSUPPORTED;
1172 return p_cdio->op.run_mmc_cmd(p_cdio->env, i_timeout_ms,
1173 i_cdb,
1174 p_cdb, e_direction, i_buf, p_buf);
1175 }
1176
1177 /**
1178 See if CD-ROM has feature with value value
1179 @return true if we have the feature and false if not.
1180 */
1181 bool_3way_t
1182 mmc_have_interface( CdIo_t *p_cdio, cdio_mmc_feature_interface_t e_interface )
1183 {
1184 int i_status; /* Result of MMC command */
1185 uint8_t buf[65530] = { 0, }; /* Place to hold returned data */
1186 mmc_cdb_t cdb = {{0, }}; /* Command Descriptor Buffer */
1187
1188 if (!p_cdio || !p_cdio->op.run_mmc_cmd) return nope;
1189
1190 CDIO_MMC_SET_COMMAND(cdb.field, CDIO_MMC_GPCMD_GET_CONFIGURATION);
1191 CDIO_MMC_SET_READ_LENGTH8(cdb.field, sizeof(buf));
1192
1193 cdb.field[1] = CDIO_MMC_GET_CONF_NAMED_FEATURE;
1194 cdb.field[3] = CDIO_MMC_FEATURE_CORE;
1195
1196 i_status = mmc_run_cmd(p_cdio, 0, &cdb, SCSI_MMC_DATA_READ, sizeof(buf),
1197 &buf);
1198 if (DRIVER_OP_SUCCESS == i_status) {
1199 uint8_t *p;
1200 uint32_t i_data;
1201 uint8_t *p_max = buf + 65530;
1202
1203 i_data = (unsigned int) CDIO_MMC_GET_LEN32(buf);
1204 /* set to first sense feature code, and then walk through the masks */
1205 p = buf + 8;
1206 while( (p < &(buf[i_data])) && (p < p_max) ) {
1207 uint16_t i_feature;
1208 uint8_t i_feature_additional = p[3];
1209
1210 i_feature = CDIO_MMC_GET_LEN16(p);
1211 if (CDIO_MMC_FEATURE_CORE == i_feature) {
1212 uint8_t *q = p+4;
1213 uint32_t i_interface_standard = CDIO_MMC_GET_LEN32(q);
1214 if (e_interface == i_interface_standard) return yep;
1215 }
1216 p += i_feature_additional + 4;
1217 }
1218 return nope;
1219 } else
1220 return dunno;
1221 }
1222
1223 /**
1224 Read sectors using SCSI-MMC GPCMD_READ_CD.
1225 Can read only up to 25 blocks.
1226 */
1227 driver_return_code_t
1228 mmc_read_sectors ( const CdIo_t *p_cdio, void *p_buf, lsn_t i_lsn,
1229 int sector_type, uint32_t i_blocks )
1230 {
1231 mmc_cdb_t cdb = {{0, }};
1232
1233 mmc_run_cmd_fn_t run_mmc_cmd;
1234
1235 if (!p_cdio) return DRIVER_OP_UNINIT;
1236 if (!p_cdio->op.run_mmc_cmd ) return DRIVER_OP_UNSUPPORTED;
1237
1238 run_mmc_cmd = p_cdio->op.run_mmc_cmd;
1239
1240 CDIO_MMC_SET_COMMAND(cdb.field, CDIO_MMC_GPCMD_READ_CD);
1241 CDIO_MMC_SET_READ_TYPE (cdb.field, sector_type);
1242 CDIO_MMC_SET_READ_LBA (cdb.field, i_lsn);
1243 CDIO_MMC_SET_READ_LENGTH24(cdb.field, i_blocks);
1244 CDIO_MMC_SET_MAIN_CHANNEL_SELECTION_BITS(cdb.field,
1245 CDIO_MMC_MCSB_ALL_HEADERS);
1246
1247 return run_mmc_cmd (p_cdio->env, mmc_timeout_ms,
1248 mmc_get_cmd_len(cdb.field[0]), &cdb,
1249 SCSI_MMC_DATA_READ,
1250 CDIO_CD_FRAMESIZE_RAW * i_blocks,
1251 p_buf);
1252 }
1253
1254 driver_return_code_t
1255 mmc_set_blocksize ( const CdIo_t *p_cdio, uint16_t i_blocksize)
1256 {
1257 if ( ! p_cdio ) return DRIVER_OP_UNINIT;
1258 return
1259 mmc_set_blocksize_private (p_cdio->env, p_cdio->op.run_mmc_cmd,
1260 i_blocksize);
1261 }
1262
1263
1264 /*
1265 * Local variables:
1266 * c-file-style: "gnu"
1267 * tab-width: 8
1268 * indent-tabs-mode: nil
1269 * End:
1270 */
1271