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