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