diff --git a/example/sample10.c b/example/sample10.c index f7606b9e..8552fc4f 100644 --- a/example/sample10.c +++ b/example/sample10.c @@ -1,5 +1,5 @@ /* - $Id: sample10.c,v 1.1 2004/08/06 22:05:16 rocky Exp $ + $Id: sample10.c,v 1.2 2004/08/07 01:48:36 rocky Exp $ Copyright (C) 2004 Rocky Bernstein @@ -61,7 +61,7 @@ main(int argc, const char *argv[]) /* set to first sense feature code, and then walk through the masks */ p = buf + 8; - while( (p < &(buf[8+lenData])) && (p < pMax) ) { + while( (p < &(buf[lenData])) && (p < pMax) ) { uint16_t i_feature; uint8_t i_feature_len = p[3]; @@ -172,6 +172,32 @@ main(int argc, const char *argv[]) } case CDIO_MMC_FEATURE_REMOVABLE_MEDIUM: printf("Removable Medium Feature\n"); + switch(p[4] >> 5) { + case 0: + printf("\tCaddy/Slot type loading mechanism\n"); + break; + case 1: + printf("\tTray type loading mechanism\n"); + break; + case 2: + printf("\tPop-up type loading mechanism\n"); + break; + case 4: + printf("\tEmbedded changer with individually changeable discs\n"); + break; + case 5: + printf("\tEmbedded changer using a magazine mechanism\n"); + break; + default: + printf("\tUnknown changer mechanism\n"); + } + + printf("\tcan%s eject the medium or magazine via the normal " + "START/STOP command\n", + (p[4] & 8) ? "": "not"); + printf("\tcan%s be locked into the Logical Unit\n", + (p[4] & 1) ? "": "not"); + printf("\n"); break; case CDIO_MMC_FEATURE_WRITE_PROTECT: printf("Write Protect Feature\n"); diff --git a/include/cdio/scsi_mmc.h b/include/cdio/scsi_mmc.h index c260dc92..000ae1db 100644 --- a/include/cdio/scsi_mmc.h +++ b/include/cdio/scsi_mmc.h @@ -1,5 +1,5 @@ /* - $Id: scsi_mmc.h,v 1.28 2004/08/06 22:13:14 rocky Exp $ + $Id: scsi_mmc.h,v 1.29 2004/08/07 01:48:36 rocky Exp $ Copyright (C) 2003, 2004 Rocky Bernstein @@ -117,24 +117,39 @@ /*! FEATURE codes used in GET CONFIGURATION. */ -#define CDIO_MMC_FEATURE_PROFILE_LIST 0x000 -#define CDIO_MMC_FEATURE_CORE 0x001 -#define CDIO_MMC_FEATURE_REMOVABLE_MEDIUM 0x002 -#define CDIO_MMC_FEATURE_WRITE_PROTECT 0x003 -#define CDIO_MMC_FEATURE_RANDOM_READABLE 0x010 -#define CDIO_MMC_FEATURE_MULTI_READ 0x01D -#define CDIO_MMC_FEATURE_CD_READ 0x01E -#define CDIO_MMC_FEATURE_DVD_READ 0x01F -#define CDIO_MMC_FEATURE_RANDOM_WRITABLE 0x020 -#define CDIO_MMC_FEATURE_INCR_WRITE 0x021 -#define CDIO_MMC_FEATURE_SECTOR_ERASE 0x022 -#define CDIO_MMC_FEATURE_FORMATABLE 0x023 -#define CDIO_MMC_FEATURE_WRITE_ONCE 0x025 -#define CDIO_MMC_FEATURE_RESTRICT_OVERW 0x026 -#define CDIO_MMC_FEATURE_CD_RW_CAV 0x027 -#define CDIO_MMC_FEATURE_MRW 0x028 -#define CDIO_MMC_FEATURE_DVD_PRW 0x02A -#define CDIO_MMC_FEATURE_DVD_PR 0x02B +#define CDIO_MMC_FEATURE_PROFILE_LIST 0x000 /**< Profile List Feature */ +#define CDIO_MMC_FEATURE_CORE 0x001 +#define CDIO_MMC_FEATURE_REMOVABLE_MEDIUM 0x002 /**< Removable Medium + Feature */ +#define CDIO_MMC_FEATURE_WRITE_PROTECT 0x003 /**< Write Protect + Feature */ +#define CDIO_MMC_FEATURE_RANDOM_READABLE 0x010 /**< Random Readable + Feature */ +#define CDIO_MMC_FEATURE_MULTI_READ 0x01D /**< Multi-Read + Feature */ +#define CDIO_MMC_FEATURE_CD_READ 0x01E /**< CD Read + Feature */ +#define CDIO_MMC_FEATURE_DVD_READ 0x01F /**< DVD Read + Feature */ +#define CDIO_MMC_FEATURE_RANDOM_WRITABLE 0x020 /**< Random Writable + Feature */ +#define CDIO_MMC_FEATURE_INCR_WRITE 0x021 /**< Incremental + Streaming Writable + Feature */ +#define CDIO_MMC_FEATURE_SECTOR_ERASE 0x022 /**< Sector Erasable + Feature */ +#define CDIO_MMC_FEATURE_FORMATABLE 0x023 /**< Formattable + Feature */ +#define CDIO_MMC_FEATURE_WRITE_ONCE 0x025 /**< Write Once + Feature */ +#define CDIO_MMC_FEATURE_RESTRICT_OVERW 0x026 /**< Restricted + Overwrite + Feature */ +#define CDIO_MMC_FEATURE_CD_RW_CAV 0x027 /**< CD-RW CAV Write + Feature */ +#define CDIO_MMC_FEATURE_MRW 0x028 /**< MRW Feature */ +#define CDIO_MMC_FEATURE_DVD_PRW 0x02A /**< DVD+RW Feature */ +#define CDIO_MMC_FEATURE_DVD_PR 0x02B /**< DVD+R Feature */ #define CDIO_MMC_FEATURE_CD_TAO 0x02D #define CDIO_MMC_FEATURE_CD_SAO 0x02E #define CDIO_MMC_FEATURE_CDDA_EXT_PLAY 0x103 @@ -142,25 +157,65 @@ #define CDIO_MMC_FEATURE_LU_SN 0x108 /*! Profile codes used in GET_CONFIGURATION - PROFILE LIST. */ -#define CDIO_MMC_FEATURE_PROF_NON_REMOVABLE 0x0001 -#define CDIO_MMC_FEATURE_PROF_REMOVABLE 0x0002 -#define CDIO_MMC_FEATURE_PROF_MO_ERASABLE 0x0003 -#define CDIO_MMC_FEATURE_PROF_MO_WRITE_ONCE 0x0004 -#define CDIO_MMC_FEATURE_PROF_AS_MO 0x0005 -#define CDIO_MMC_FEATURE_PROF_CD_ROM 0x0008 -#define CDIO_MMC_FEATURE_PROF_CD_R 0x0009 -#define CDIO_MMC_FEATURE_PROF_CD_RW 0x000A -#define CDIO_MMC_FEATURE_PROF_DVD_ROM 0x0010 -#define CDIO_MMC_FEATURE_PROF_DVD_R_SEQ 0x0011 -#define CDIO_MMC_FEATURE_PROF_DVD_RAM 0x0012 -#define CDIO_MMC_FEATURE_PROF_DVD_RW_RO 0x0013 -#define CDIO_MMC_FEATURE_PROF_DVD_RW_SEQ 0x0014 -#define CDIO_MMC_FEATURE_PROF_DVD_PRW 0x001A -#define CDIO_MMC_FEATURE_PROF_DVD_PR 0x001B -#define CDIO_MMC_FEATURE_PROF_DDCD_ROM 0x0020 -#define CDIO_MMC_FEATURE_PROF_DDCD_R 0x0021 -#define CDIO_MMC_FEATURE_PROF_DDCD_RW 0x0022 -#define CDIO_MMC_FEATURE_PROF_NON_CONFORM 0xFFFF +#define CDIO_MMC_FEATURE_PROF_NON_REMOVABLE 0x0001 /**< Re-writable + disk, capable of + changing + behavior */ +#define CDIO_MMC_FEATURE_PROF_REMOVABLE 0x0002 /**< disk + Re-writable; + with removable + media */ +#define CDIO_MMC_FEATURE_PROF_MO_ERASABLE 0x0003 /**< Erasable + Magneto-Optical + disk with sector + erase + capability */ +#define CDIO_MMC_FEATURE_PROF_MO_WRITE_ONCE 0x0004 /**< Write Once + Magneto-Optical + write once */ +#define CDIO_MMC_FEATURE_PROF_AS_MO 0x0005 /**< Advance + Storage + Magneto-Optical */ +#define CDIO_MMC_FEATURE_PROF_CD_ROM 0x0008 /**< Read only + Compact Disc + capable */ +#define CDIO_MMC_FEATURE_PROF_CD_R 0x0009 /**< Write once + Compact Disc + capable */ +#define CDIO_MMC_FEATURE_PROF_CD_RW 0x000A /**< CD-RW + Re-writable + Compact Disc + capable */ +#define CDIO_MMC_FEATURE_PROF_DVD_ROM 0x0010 /**< Read only + DVD */ +#define CDIO_MMC_FEATURE_PROF_DVD_R_SEQ 0x0011 /**< Re-recordable + DVD using + Sequential + recording */ +#define CDIO_MMC_FEATURE_PROF_DVD_RAM 0x0012 /**< Re-writable + DVD */ +#define CDIO_MMC_FEATURE_PROF_DVD_RW_RO 0x0013 /**< Re-recordable + DVD using + Restricted + Overwrite */ +#define CDIO_MMC_FEATURE_PROF_DVD_RW_SEQ 0x0014 /**< Re-recordable + DVD using + Sequential + recording */ +#define CDIO_MMC_FEATURE_PROF_DVD_PRW 0x001A /**< DVD+RW - DVD + ReWritable */ +#define CDIO_MMC_FEATURE_PROF_DVD_PR 0x001B /**< DVD+R - DVD + Recordable */ +#define CDIO_MMC_FEATURE_PROF_DDCD_ROM 0x0020 /**< Read only + DDCD */ +#define CDIO_MMC_FEATURE_PROF_DDCD_R 0x0021 /**< DDCD-R Write + only DDCD */ +#define CDIO_MMC_FEATURE_PROF_DDCD_RW 0x0022 /**< Re-Write only + DDCD */ +#define CDIO_MMC_FEATURE_PROF_NON_CONFORM 0xFFFF /**< The Logical + Unit does not + conform to any + Profile. */ /*! Size of fields returned by an INQUIRY command */ #define CDIO_MMC_HW_VENDOR_LEN 8 /**< length of vendor field */ diff --git a/src/cd-drive.c b/src/cd-drive.c index 1828a135..8ec3ae78 100644 --- a/src/cd-drive.c +++ b/src/cd-drive.c @@ -1,5 +1,5 @@ /* - $Id: cd-drive.c,v 1.4 2004/07/31 07:43:26 rocky Exp $ + $Id: cd-drive.c,v 1.5 2004/08/07 01:48:36 rocky Exp $ Copyright (C) 2004 Rocky Bernstein @@ -245,6 +245,7 @@ main(int argc, const char *argv[]) "Model" , scsi_mmc_hwinfo.model, "Revision", scsi_mmc_hwinfo.revision); } + print_mmc_drive_features(p_cdio); print_drive_capabilities(i_read_cap, i_write_cap, i_misc_cap); printf("\n"); if (p_cdio) cdio_destroy(p_cdio); @@ -258,11 +259,22 @@ main(int argc, const char *argv[]) cdio_drive_read_cap_t i_read_cap; cdio_drive_write_cap_t i_write_cap; cdio_drive_misc_cap_t i_misc_cap; + scsi_mmc_hwinfo_t scsi_mmc_hwinfo; + + printf("Drive %s\n", source_name); + p_cdio = cdio_open (source_name, DRIVER_UNKNOWN); + if (NULL != p_cdio) { + if (scsi_mmc_get_hwinfo(p_cdio, &scsi_mmc_hwinfo)) { + printf("%-28s: %s\n%-28s: %s\n%-28s: %s\n", + "Vendor" , scsi_mmc_hwinfo.vendor, + "Model" , scsi_mmc_hwinfo.model, + "Revision", scsi_mmc_hwinfo.revision); + } + print_mmc_drive_features(p_cdio); + } cdio_get_drive_cap_dev(source_name, &i_read_cap, &i_write_cap, &i_misc_cap); - - printf("Drive %s\n", source_name); print_drive_capabilities(i_read_cap, i_write_cap, i_misc_cap); printf("\n"); } diff --git a/src/util.c b/src/util.c index 83acf3d6..b89ac777 100644 --- a/src/util.c +++ b/src/util.c @@ -1,5 +1,5 @@ /* - $Id: util.c,v 1.13 2004/08/06 14:27:33 rocky Exp $ + $Id: util.c,v 1.14 2004/08/07 01:48:36 rocky Exp $ Copyright (C) 2003, 2004 Rocky Bernstein @@ -21,6 +21,7 @@ /* Miscellaneous things common to standalone programs. */ #include "util.h" +#include cdio_log_handler_t gl_default_cdio_log_handler = NULL; char *source_name = NULL; @@ -86,10 +87,261 @@ fillout_device_name(const char *device_name) #endif } +/*! Prints out SCSI-MMC drive features */ +void +print_mmc_drive_features(CdIo *p_cdio) +{ + + int i_status; /* Result of SCSI MMC command */ + uint8_t buf[500] = { 0, }; /* Place to hold returned data */ + scsi_mmc_cdb_t cdb = {{0, }}; /* Command Descriptor Block */ + + CDIO_MMC_SET_COMMAND(cdb.field, CDIO_MMC_GPCMD_GET_CONFIGURATION); + CDIO_MMC_SET_READ_LENGTH8(cdb.field, sizeof(buf)); + cdb.field[1] = CDIO_MMC_GET_CONF_ALL_FEATURES; + cdb.field[3] = 0x0; + + i_status = scsi_mmc_run_cmd(p_cdio, 0, + &cdb, SCSI_MMC_DATA_READ, + sizeof(buf), &buf); + if (i_status == 0) { + uint8_t *p; + uint32_t lenData = (unsigned int) CDIO_MMC_GET_LEN32(buf); + uint8_t *pMax = buf + 65530; + + /* set to first sense feature code, and then walk through the masks */ + p = buf + 8; + while( (p < &(buf[lenData])) && (p < pMax) ) { + uint16_t i_feature; + uint8_t i_feature_len = p[3]; + + i_feature = CDIO_MMC_GET_LEN16(p); + switch( i_feature ) + { + uint8_t *q; + case CDIO_MMC_FEATURE_PROFILE_LIST: + printf("Profile List Feature\n"); + for ( q = p+4 ; q < p + i_feature_len ; q += 4 ) { + int i_profile=CDIO_MMC_GET_LEN16(q); + switch (i_profile) { + case CDIO_MMC_FEATURE_PROF_NON_REMOVABLE: + printf("\tRe-writable disk, capable of changing behavior"); + break; + case CDIO_MMC_FEATURE_PROF_REMOVABLE: + printf("\tdisk Re-writable; with removable media"); + break; + case CDIO_MMC_FEATURE_PROF_MO_ERASABLE: + printf("\tErasable Magneto-Optical disk with sector erase capability"); + break; + case CDIO_MMC_FEATURE_PROF_MO_WRITE_ONCE: + printf("\tWrite Once Magneto-Optical write once"); + break; + case CDIO_MMC_FEATURE_PROF_AS_MO: + printf("\tAdvance Storage Magneto-Optical"); + break; + case CDIO_MMC_FEATURE_PROF_CD_ROM: + printf("\tRead only Compact Disc capable"); + break; + case CDIO_MMC_FEATURE_PROF_CD_R: + printf("\tWrite once Compact Disc capable"); + break; + case CDIO_MMC_FEATURE_PROF_CD_RW: + printf("\tCD-RW Re-writable Compact Disc capable"); + break; + case CDIO_MMC_FEATURE_PROF_DVD_ROM: + printf("\tRead only DVD"); + break; + case CDIO_MMC_FEATURE_PROF_DVD_R_SEQ: + printf("\tRe-recordable DVD using Sequential recording"); + break; + case CDIO_MMC_FEATURE_PROF_DVD_RAM: + printf("\tRe-writable DVD"); + break; + case CDIO_MMC_FEATURE_PROF_DVD_RW_RO: + printf("\tRe-recordable DVD using Restricted Overwrite"); + break; + case CDIO_MMC_FEATURE_PROF_DVD_RW_SEQ: + printf("\tRe-recordable DVD using Sequential recording"); + break; + case CDIO_MMC_FEATURE_PROF_DVD_PRW: + printf("\tDVD+RW - DVD ReWritable"); + break; + case CDIO_MMC_FEATURE_PROF_DVD_PR: + printf("\tDVD+R - DVD Recordable"); + break; + case CDIO_MMC_FEATURE_PROF_DDCD_ROM: + printf("\tRead only DDCD"); + break; + case CDIO_MMC_FEATURE_PROF_DDCD_R: + printf("\tDDCD-R Write only DDCD"); + break; + case CDIO_MMC_FEATURE_PROF_DDCD_RW: + printf("\tRe-Write only DDCD"); + break; + case CDIO_MMC_FEATURE_PROF_NON_CONFORM: + printf("\tThe Logical Unit does not conform to any Profile."); + break; + default: + printf("\tUnknown Profile %x", i_profile); + break; + } + if (q[2] & 1) { + printf(" - on"); + } + printf("\n"); + } + printf("\n"); + + break; + case CDIO_MMC_FEATURE_CORE: + { + uint8_t *q = p+4; + uint32_t i_interface_standard = CDIO_MMC_GET_LEN32(q); + printf("Core Feature\n"); + switch(i_interface_standard) { + case 0: + printf("\tunspecified interface\n"); + break; + case 1: + printf("\tSCSI interface\n"); + break; + case 2: + printf("\tATAPI interface\n"); + break; + case 3: + printf("\tIEEE 1394 interface\n"); + break; + case 4: + printf("\tIEEE 1394A interface\n"); + break; + case 5: + printf("\tFibre Channel interface\n"); + } + printf("\n"); + break; + } + case CDIO_MMC_FEATURE_REMOVABLE_MEDIUM: + printf("Removable Medium Feature\n"); + switch(p[4] >> 5) { + case 0: + printf("\tCaddy/Slot type loading mechanism\n"); + break; + case 1: + printf("\tTray type loading mechanism\n"); + break; + case 2: + printf("\tPop-up type loading mechanism\n"); + break; + case 4: + printf("\tEmbedded changer with individually changeable discs\n"); + break; + case 5: + printf("\tEmbedded changer using a magazine mechanism\n"); + break; + default: + printf("\tUnknown changer mechanism\n"); + } + + printf("\tcan%s eject the medium or magazine via the normal " + "START/STOP command\n", + (p[4] & 8) ? "": "not"); + printf("\tcan%s be locked into the Logical Unit\n", + (p[4] & 1) ? "": "not"); + printf("\n"); + break; + case CDIO_MMC_FEATURE_WRITE_PROTECT: + printf("Write Protect Feature\n"); + break; + case CDIO_MMC_FEATURE_RANDOM_READABLE: + printf("Random Readable Feature\n"); + break; + case CDIO_MMC_FEATURE_MULTI_READ: + printf("Multi-Read Feature\n"); + break; + case CDIO_MMC_FEATURE_CD_READ: + printf("CD Read Feature\n"); + printf("\tC2 Error pointers are %ssupported\n", + (p[4] & 2) ? "": "not "); + printf("\tCD-Text is %ssupported\n", + (p[4] & 1) ? "": "not "); + printf("\n"); + break; + case CDIO_MMC_FEATURE_DVD_READ: + printf("DVD Read Feature\n"); + break; + case CDIO_MMC_FEATURE_RANDOM_WRITABLE: + printf("Random Writable Feature\n"); + break; + case CDIO_MMC_FEATURE_INCR_WRITE: + printf("Incremental Streaming Writable Feature\n"); + break; + case CDIO_MMC_FEATURE_SECTOR_ERASE: + printf("Sector Erasable Feature\n"); + break; + case CDIO_MMC_FEATURE_FORMATABLE: + printf("Formattable Feature\n"); + break; + case CDIO_MMC_FEATURE_WRITE_ONCE: + printf("Write Once Feature\n"); + break; + case CDIO_MMC_FEATURE_MRW: + printf("MRW Feature\n"); + break; + case CDIO_MMC_FEATURE_DVD_PRW: + printf("DVD+RW Feature\n"); + break; + case CDIO_MMC_FEATURE_DVD_PR: + printf("DVD+R Feature\n"); + break; + case CDIO_MMC_FEATURE_CD_RW_CAV: + printf("CD-RW CAV Write Feature\n"); + break; + case CDIO_MMC_FEATURE_RESTRICT_OVERW: + printf("Restricted Overwrite Feature\n"); + break; + case CDIO_MMC_FEATURE_LU_SN: + printf("Logical Unit Serial Number Feature\n"); + break; + case CDIO_MMC_FEATURE_MCODE_UPGRADE: + printf("Microcode Upgrade Feature\n"); + break; + case CDIO_MMC_FEATURE_CD_TAO: + printf("CD Track at Once Feature\n"); + break; + case CDIO_MMC_FEATURE_CD_SAO: + printf("CD Mastering (Session at Once) Feature\n"); + break; + case CDIO_MMC_FEATURE_CDDA_EXT_PLAY: + printf("CD Audio External Play Feature\n"); + printf("\tSCAN command is %ssupported\n", + (p[4] & 4) ? "": "not "); + printf("\taudio channels can %sbe muted separately\n", + (p[4] & 2) ? "": "not "); + printf("\taudio channels can %shave separate volume levels\n", + (p[4] & 1) ? "": "not "); + { + uint8_t *q = p+6; + uint16_t i_vol_levels = CDIO_MMC_GET_LEN16(q); + printf("\t%d volume levels can be set\n", i_vol_levels); + } + printf("\n"); + break; + default: + printf("Unknown feature code %x\n", i_feature); + } + p += i_feature_len + 4; + } + } else { + printf("Didn't get all feature codes\n"); + } +} + + /* Prints out drive capabilities */ -void print_drive_capabilities(cdio_drive_read_cap_t i_read_cap, - cdio_drive_write_cap_t i_write_cap, - cdio_drive_misc_cap_t i_misc_cap) +void +print_drive_capabilities(cdio_drive_read_cap_t i_read_cap, + cdio_drive_write_cap_t i_write_cap, + cdio_drive_misc_cap_t i_misc_cap) { if (CDIO_DRIVE_CAP_ERROR == i_misc_cap) { printf("Error in getting drive hardware properties\n"); diff --git a/src/util.h b/src/util.h index 6c2a0a4c..9da63ec0 100644 --- a/src/util.h +++ b/src/util.h @@ -1,5 +1,5 @@ /* - $Id: util.h,v 1.6 2004/07/31 07:43:26 rocky Exp $ + $Id: util.h,v 1.7 2004/08/07 01:48:36 rocky Exp $ Copyright (C) 2003, 2004 Rocky Bernstein @@ -100,7 +100,10 @@ void print_version (char *program_name, const char *version, char *fillout_device_name(const char *device_name); -/* Prints out drive capabilities */ +/*! Prints out SCSI-MMC drive features */ +void print_mmc_drive_features(CdIo *p_cdio); + +/*! Prints out drive capabilities */ void print_drive_capabilities(cdio_drive_read_cap_t p_read_cap, cdio_drive_write_cap_t p_write_cap, cdio_drive_misc_cap_t p_misc_cap);