1 //---------------------------------------------------------------------- 2 // This software is part of the Haiku distribution and is covered 3 // by the MIT License. 4 // 5 // Copyright (c) 2003 Tyler Dauwalder, tyler@dauwalder.net 6 //--------------------------------------------------------------------- 7 #ifndef _SCSI_MMC_H 8 #define _SCSI_MMC_H 9 10 /*! 11 \file scsi-mmc.h 12 SCSI-3 MMC support structures. 13 14 The protocols followed in this module are based on information 15 taken from the "SCSI-3 Multimedia Commands" draft, revision 10A. 16 17 The SCSI command of interest is "READ TOC/PMA/ATIP", command 18 number \c 0x43. 19 20 The format of interest for said command is "Full TOC", format 21 number \c 0x2. 22 */ 23 24 #include <errno.h> 25 #include <new> 26 #include <stdlib.h> 27 #include <string.h> 28 #include <unistd.h> 29 30 #include <ByteOrder.h> 31 #include <KernelExport.h> 32 #include <scsi.h> 33 34 #include "Debug.h" 35 36 /*! \brief raw_device_command flags 37 38 This is the only combination of flags that works on my system. :-) 39 */ 40 const uint8 kScsiFlags = B_RAW_DEVICE_DATA_IN 41 | B_RAW_DEVICE_REPORT_RESIDUAL 42 | B_RAW_DEVICE_SHORT_READ_VALID; 43 44 /*! \brief Timeout value used when making scsi commands 45 46 I'm honestly not sure what value to use here. It's currently 47 1 second because I got sick of waiting for the timeout while 48 figuring out how to get the commands to work. 49 */ 50 const uint32 kScsiTimeout = 1000000; 51 52 //! SCSI "READ TOC/PMA/ATIP" command struct 53 typedef struct { 54 uint8 command; //!< 0x43 == READ TOC/PMA/ATIP 55 uint8 reserved2:1, 56 msf:1, //!< addressing format: 0 == LBA, 1 == MSF; try lba first, then msf if that fails 57 reserved1:3, 58 reserved0:3; 59 uint8 format:4, //!< sub-command: 0x0 == "TOC", 0x1 == "Session Info", 0x2 == "Full TOC", ... 60 reserved3:4; 61 uint8 reserved4; 62 uint8 reserved5; 63 uint8 reserved6; 64 uint8 number; //!< track/session number 65 uint16 length; //!< length of data buffer passed in raw_device_command.data; BIG-ENDIAN!!! 66 uint8 control; //!< control codes; 0x0 should be fine 67 } __attribute__((packed)) scsi_table_of_contents_command; 68 69 // Some of the possible "READ TOC/PMA/ATIP" formats 70 const uint8 kTableOfContentsFormat = 0x00; 71 const uint8 kSessionFormat = 0x01; 72 const uint8 kFullTableOfContentsFormat = 0x02; //!< "READ TOC/PMA/ATIP" format of interest 73 74 /*! \brief Minutes:Seconds:Frames format address 75 76 - Each msf frame corresponds to one logical block. 77 - Each msf second corresponds to 75 msf frames 78 - Each msf minute corresponds to 60 msf seconds 79 - Logical block 0 is at msf address 00:02:00 80 */ 81 typedef struct { 82 uint8 reserved; 83 uint8 minutes; 84 uint8 seconds; 85 uint8 frames; 86 } msf_address; 87 88 #define CDROM_FRAMES_PER_SECOND (75) 89 #define CDROM_FRAMES_PER_MINUTE (CDROM_FRAMES_PER_SECOND*60) 90 91 /*! \brief Returns an initialized \c msf_address struct 92 */ 93 static 94 inline 95 msf_address 96 make_msf_address(uint8 minutes, uint8 seconds, uint8 frames) 97 { 98 msf_address result; 99 result.reserved = 0; 100 result.minutes = minutes; 101 result.seconds = seconds; 102 result.frames = frames; 103 return result; 104 } 105 106 /*! \brief Converts the given msf address to lba format 107 */ 108 static 109 inline 110 off_t 111 msf_to_lba(msf_address msf) 112 { 113 return (CDROM_FRAMES_PER_MINUTE * msf.minutes) 114 + (CDROM_FRAMES_PER_SECOND * msf.seconds) 115 + msf.frames - 150; 116 } 117 118 /*! \brief Header for data returned by all formats of SCSI 119 "READ TOC/PMA/ATIP" command. 120 */ 121 typedef struct { 122 uint16 length; //!< Length of data in reply (not including these 2 bytes); BIG ENDIAN!!! 123 uint8 first; //!< First track/session in reply 124 uint8 last; //!< Last track/session in reply 125 } cdrom_table_of_contents_header; 126 127 /*! \brief Type of entries returned by "READ TOC/PMA/ATIP" when called with format 128 \c kTableOfContentsFormat == 0x00 129 */ 130 typedef struct { 131 uint8 reserved0; 132 uint8 control:4, 133 adr:4; 134 uint8 track_number; 135 uint8 reserved1; 136 uint32 address; 137 } cdrom_table_of_contents_entry; 138 139 /*! \brief Type of entries returned by "READ TOC/PMA/ATIP" when called with format 140 \c kFullTableOfContentsFormat == 0x02 141 */ 142 typedef struct { 143 uint8 session; 144 uint8 control:4, 145 adr:4; 146 uint8 tno; 147 uint8 point; 148 uint8 minutes; 149 uint8 seconds; 150 uint8 frames; 151 uint8 zero; 152 uint8 pminutes; 153 uint8 pseconds; 154 uint8 pframes; 155 } cdrom_full_table_of_contents_entry; 156 157 /*! \brief Bitflags for control entries 158 */ 159 enum { 160 kControlDataTrack = 0x4, 161 kControlCopyPermitted = 0x2, 162 }; 163 164 #endif // _SCSI_MMC_H 165