Blame example/mmc2.c

Packit dd8086
/*
Packit dd8086
  Copyright (C) 2004-2005, 2008-2009, 2012, 2014, 2017
Packit dd8086
  Rocky Bernstein <rocky@gnu.org>
Packit dd8086
Packit dd8086
  This program is free software: you can redistribute it and/or modify
Packit dd8086
  it under the terms of the GNU General Public License as published by
Packit dd8086
  the Free Software Foundation, either version 3 of the License, or
Packit dd8086
  (at your option) any later version.
Packit dd8086
Packit dd8086
  This program is distributed in the hope that it will be useful,
Packit dd8086
  but WITHOUT ANY WARRANTY; without even the implied warranty of
Packit dd8086
  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
Packit dd8086
  GNU General Public License for more details.
Packit dd8086
Packit dd8086
  You should have received a copy of the GNU General Public License
Packit dd8086
  along with this program.  If not, see <http://www.gnu.org/licenses/>.
Packit dd8086
*/
Packit dd8086
Packit dd8086
/* A program to using the MMC interface to list CD and drive features
Packit dd8086
   from the MMC GET_CONFIGURATION command . */
Packit dd8086
#ifdef HAVE_CONFIG_H
Packit dd8086
#include "config.h"
Packit dd8086
#define __CDIO_CONFIG_H__ 1
Packit dd8086
#endif
Packit dd8086
Packit dd8086
#ifdef HAVE_STDIO_H
Packit dd8086
#include <stdio.h>
Packit dd8086
#endif
Packit dd8086
#ifdef HAVE_SYS_TYPES_H
Packit dd8086
#include <sys/types.h>
Packit dd8086
#endif
Packit dd8086
#ifdef HAVE_STRING_H
Packit dd8086
#include <string.h>
Packit dd8086
#endif
Packit dd8086
Packit dd8086
#include <cdio/cdio.h>
Packit dd8086
#include <cdio/mmc.h>
Packit dd8086
Packit dd8086
int
Packit dd8086
main(int argc, const char *argv[])
Packit dd8086
{
Packit dd8086
  CdIo_t *p_cdio;
Packit dd8086
Packit dd8086
  const char *psz_drive = NULL;
Packit dd8086
Packit dd8086
  if (argc > 1) psz_drive = argv[1];
Packit dd8086
  p_cdio = cdio_open (psz_drive, DRIVER_DEVICE);
Packit dd8086
Packit dd8086
  if (NULL == p_cdio) {
Packit dd8086
    printf("-- Couldn't find CD\n");
Packit dd8086
    return 77;
Packit dd8086
  } else {
Packit dd8086
    int i_status;              /* Result of MMC command */
Packit dd8086
    uint8_t buf[65530] = { 0, }; /* Place to hold returned data */
Packit dd8086
    mmc_cdb_t cdb = {{0, }};   /* Command Descriptor Buffer */
Packit dd8086
Packit dd8086
    CDIO_MMC_SET_COMMAND(cdb.field, CDIO_MMC_GPCMD_GET_CONFIGURATION);
Packit dd8086
    CDIO_MMC_SET_READ_LENGTH8(cdb.field, sizeof(buf));
Packit dd8086
    cdb.field[1] = CDIO_MMC_GET_CONF_ALL_FEATURES;
Packit dd8086
    cdb.field[3] = 0x0;
Packit dd8086
Packit dd8086
    i_status = mmc_run_cmd(p_cdio, 0, &cdb, SCSI_MMC_DATA_READ, sizeof(buf),
Packit dd8086
			   &buf;;
Packit dd8086
    if (i_status == 0) {
Packit dd8086
      uint8_t *p;
Packit dd8086
      uint32_t i_data;
Packit dd8086
      uint8_t *p_max = buf + sizeof(buf);
Packit dd8086
Packit dd8086
      i_data = (unsigned int) CDIO_MMC_GET_LEN32(buf);
Packit dd8086
      /* set to first sense feature code, and then walk through the masks */
Packit dd8086
      p = buf + 8;
Packit dd8086
      while( (p < &(buf[i_data])) && (p < p_max) ) {
Packit dd8086
	uint16_t i_feature;
Packit dd8086
	uint8_t i_feature_additional = p[3];
Packit dd8086
Packit dd8086
	i_feature = CDIO_MMC_GET_LEN16(p);
Packit dd8086
	{
Packit dd8086
	  const char *feature_str = mmc_feature2str(i_feature);
Packit dd8086
	  printf("-- %s Feature\n", feature_str);
Packit dd8086
	  switch( i_feature )
Packit dd8086
	    {
Packit dd8086
	    case CDIO_MMC_FEATURE_PROFILE_LIST:
Packit dd8086
	      {
Packit dd8086
		uint8_t *q;
Packit dd8086
		for ( q = p+4 ; q < p + i_feature_additional ; q += 4 ) {
Packit dd8086
		  int i_profile=CDIO_MMC_GET_LEN16(q);
Packit dd8086
		  const char *feature_profile_str =
Packit dd8086
		    mmc_feature_profile2str(i_profile);
Packit dd8086
		  printf( "-- \t%s", feature_profile_str );
Packit dd8086
		  if (q[2] & 1) {
Packit dd8086
		    printf(" - on");
Packit dd8086
		  }
Packit dd8086
		  printf("\n");
Packit dd8086
		}
Packit dd8086
		printf("\n");
Packit dd8086
Packit dd8086
		break;
Packit dd8086
	      }
Packit dd8086
	    case CDIO_MMC_FEATURE_CORE:
Packit dd8086
	      {
Packit dd8086
		uint8_t *q = p+4;
Packit dd8086
		uint32_t 	i_interface_standard = CDIO_MMC_GET_LEN32(q);
Packit dd8086
		switch(i_interface_standard) {
Packit dd8086
		case 0:
Packit dd8086
		  printf("-- \tunspecified interface.\n");
Packit dd8086
		  break;
Packit dd8086
		case 1:
Packit dd8086
		  printf("-- \tSCSI interface.\n");
Packit dd8086
		  break;
Packit dd8086
		case 2:
Packit dd8086
		  printf("-- \tATAPI interface.\n");
Packit dd8086
		  break;
Packit dd8086
		case 3:
Packit dd8086
		  printf("-- \tIEEE 1394 interface.\n");
Packit dd8086
		  break;
Packit dd8086
		case 4:
Packit dd8086
		  printf("-- \tIEEE 1394A interface.\n");
Packit dd8086
		  break;
Packit dd8086
		case 5:
Packit dd8086
		  printf("-- \tFibre Channel interface.\n");
Packit dd8086
		}
Packit dd8086
		printf("\n");
Packit dd8086
		break;
Packit dd8086
	      }
Packit dd8086
	    case CDIO_MMC_FEATURE_REMOVABLE_MEDIUM:
Packit dd8086
	      switch(p[4] >> 5) {
Packit dd8086
	      case 0:
Packit dd8086
		printf("-- \tCaddy/Slot type loading mechanism,\n");
Packit dd8086
		break;
Packit dd8086
	      case 1:
Packit dd8086
		printf("-- \tTray type loading mechanism,\n");
Packit dd8086
		break;
Packit dd8086
	      case 2:
Packit dd8086
		printf("-- \tPop-up type loading mechanism,\n");
Packit dd8086
		break;
Packit dd8086
	      case 4:
Packit dd8086
		printf("-- \tEmbedded changer with individually changeable discs,\n");
Packit dd8086
		break;
Packit dd8086
	      case 5:
Packit dd8086
		printf("-- \tEmbedded changer using a magazine mechanism,\n");
Packit dd8086
		break;
Packit dd8086
	      default:
Packit dd8086
		printf("-- \tUnknown changer mechanism,\n");
Packit dd8086
	      }
Packit dd8086
Packit dd8086
	      printf("-- \tcan%s eject the medium or magazine via the normal "
Packit dd8086
		     "START/STOP command,\n",
Packit dd8086
		     (p[4] & 8) ? "": "not");
Packit dd8086
	      printf("-- \tcan%s be locked into the Logical Unit.\n",
Packit dd8086
		     (p[4] & 1) ? "": "not");
Packit dd8086
	      printf("\n");
Packit dd8086
	      break;
Packit dd8086
	    case CDIO_MMC_FEATURE_CD_READ:
Packit dd8086
	      printf("-- CD Read Feature\n");
Packit dd8086
	      printf("-- \tC2 Error pointers are %ssupported,\n",
Packit dd8086
		     (p[4] & 2) ? "": "not ");
Packit dd8086
	      printf("-- \tCD-Text is %ssupported.\n",
Packit dd8086
		     (p[4] & 1) ? "": "not ");
Packit dd8086
	      printf("\n");
Packit dd8086
	      break;
Packit dd8086
	    case CDIO_MMC_FEATURE_CDDA_EXT_PLAY:
Packit dd8086
	      printf("\tSCAN command is %ssupported,\n",
Packit dd8086
		     (p[4] & 4) ? "": "not ");
Packit dd8086
	      printf("\taudio channels can %sbe muted separately,\n",
Packit dd8086
		     (p[4] & 2) ? "": "not ");
Packit dd8086
	      printf("\taudio channels can %shave separate volume levels.\n",
Packit dd8086
		     (p[4] & 1) ? "": "not ");
Packit dd8086
	      {
Packit dd8086
		uint8_t *q = p+6;
Packit dd8086
		uint16_t i_vol_levels = CDIO_MMC_GET_LEN16(q);
Packit dd8086
		printf("\t%d volume levels can be set\n", i_vol_levels);
Packit dd8086
	      }
Packit dd8086
	      printf("\n");
Packit dd8086
	      break;
Packit dd8086
	    case CDIO_MMC_FEATURE_LU_SN: {
Packit dd8086
	      uint8_t i_serial = *(p+3);
Packit dd8086
	      char serial[257] = { '\0', };
Packit dd8086
	      memcpy(serial, p+4, i_serial);
Packit dd8086
	      printf("\t%s\n\n", serial);
Packit dd8086
	      break;
Packit dd8086
	    }
Packit dd8086
	    default:
Packit dd8086
	      printf("\n");
Packit dd8086
	      break;
Packit dd8086
	    }
Packit dd8086
	  p += i_feature_additional + 4;
Packit dd8086
	}
Packit dd8086
      }
Packit dd8086
    } else {
Packit dd8086
      printf("-- Didn't get all feature codes.\n");
Packit dd8086
    }
Packit dd8086
  }
Packit dd8086
Packit dd8086
  if (mmc_have_interface(p_cdio, CDIO_MMC_FEATURE_INTERFACE_ATAPI))
Packit dd8086
    printf("-- CD-ROM is an ATAPI interface.\n");
Packit dd8086
  else
Packit dd8086
    printf("-- CD-ROM is not an ATAPI interface.\n");
Packit dd8086
Packit dd8086
  cdio_destroy(p_cdio);
Packit dd8086
Packit dd8086
  return 0;
Packit dd8086
}