PageRenderTime 48ms CodeModel.GetById 26ms RepoModel.GetById 1ms app.codeStats 0ms

/plugins/CDVDlinuz/Src/Linux/device.c

https://github.com/alexsharoff/pcsx2-online
C | 420 lines | 291 code | 86 blank | 43 comment | 117 complexity | 45daf6c03a851d108e82dd499aa2d085 MD5 | raw file
  1. /* device.c
  2. * Copyright (C) 2002-2005 PCSX2 Team
  3. *
  4. * This program is free software; you can redistribute it and/or modify
  5. * it under the terms of the GNU General Public License as published by
  6. * the Free Software Foundation; either version 2 of the License, or
  7. * (at your option) any later version.
  8. *
  9. * This program is distributed in the hope that it will be useful,
  10. * but WITHOUT ANY WARRANTY; without even the implied warranty of
  11. * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  12. * GNU General Public License for more details.
  13. *
  14. * You should have received a copy of the GNU General Public License
  15. * along with this program; if not, write to the Free Software
  16. * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
  17. *
  18. * PCSX2 members can be contacted through their website at www.pcsx2.net.
  19. */
  20. #include <errno.h> // errno
  21. #include <fcntl.h> // open()
  22. #include <stddef.h> // NULL
  23. #include <stdlib.h> // getenv()
  24. #include <string.h> // strerror()
  25. #include <sys/ioctl.h> // ioctl()
  26. #include <sys/stat.h> // open()
  27. #include <sys/types.h> // open()
  28. #include <time.h> // time_t, time(), struct timeval
  29. #include <unistd.h> // close(), select()
  30. #include <linux/cdrom.h> // CD/DVD based ioctl() and defines.
  31. // missing on some files for some reason.........
  32. #ifndef CDC_IOCTLS
  33. #define CDC_IOCTLS 0x400
  34. #endif
  35. #include "logfile.h"
  36. #include "conf.h"
  37. #include "CD.h"
  38. #include "DVD.h"
  39. #include "device.h"
  40. #include "../PS2Etypes.h" // u32, u8, s32
  41. // Globals
  42. int devicehandle; // File Handle for the device/drive
  43. s32 devicecapability; // Capability Flags
  44. time_t lasttime; // Time marker (in case something gets called too often)
  45. s32 traystatus; // Is the CD/DVD tray open?
  46. s32 disctype; // Type of disc in drive (Video DVD, PSX CD, etc.)
  47. u8 tocbuffer[2048];
  48. void DeviceInit() {
  49. devicehandle = -1;
  50. devicecapability = 0;
  51. lasttime = time(NULL);
  52. InitDisc();
  53. } // END DeviceInit()
  54. // Called by DeviceOpen(), DeviceGetDiskType()
  55. void InitDisc() {
  56. int i;
  57. #ifdef VERBOSE_FUNCTION_DEVICE
  58. PrintLog("CDVD device: InitDisc()");
  59. #endif /* VERBOSE_FUNCTION_DEVICE */
  60. if((disctype == CDVD_TYPE_PS2DVD) ||
  61. (disctype == CDVD_TYPE_DVDV)) {
  62. InitDVDInfo();
  63. } // ENDIF- Clean out DVD Disc Info?
  64. if((disctype == CDVD_TYPE_PS2CD) ||
  65. (disctype == CDVD_TYPE_PS2CDDA) ||
  66. (disctype == CDVD_TYPE_PSCD) ||
  67. (disctype == CDVD_TYPE_PSCDDA) ||
  68. (disctype == CDVD_TYPE_CDDA)) {
  69. InitCDInfo();
  70. } // ENDIF- Clean out DVD Disc Info?
  71. disctype = CDVD_TYPE_NODISC;
  72. for(i = 0; i > sizeof(tocbuffer); i++) tocbuffer[i] = 0x00;
  73. } // END InitDisc()
  74. s32 DiscInserted() {
  75. if(devicehandle == -1) return(-1);
  76. if(traystatus == CDVD_TRAY_OPEN) return(-1);
  77. if(disctype == CDVD_TYPE_ILLEGAL) return(-1);
  78. // if(disctype == CDVD_TYPE_UNKNOWN) return(-1); // Hmm. Let this one through?
  79. if(disctype == CDVD_TYPE_DETCTDVDD) return(-1);
  80. if(disctype == CDVD_TYPE_DETCTDVDS) return(-1);
  81. if(disctype == CDVD_TYPE_DETCTCD) return(-1);
  82. if(disctype == CDVD_TYPE_DETCT) return(-1);
  83. if(disctype == CDVD_TYPE_NODISC) return(-1);
  84. #ifdef VERBOSE_FUNCTION_DEVICE
  85. PrintLog("CDVD device: DiscInserted()");
  86. #endif /* VERBOSE_FUNCTION_DEVICE */
  87. return(0);
  88. } // END DiscInserted()
  89. // Called by DeviceTrayStatus() and CDVDopen()
  90. s32 DeviceOpen() {
  91. // s32 s32result;
  92. errno = 0;
  93. if(devicehandle != -1) {
  94. #ifdef VERBOSE_WARNING_DEVICE
  95. PrintLog("CDVD device: Device already open!");
  96. #endif /* VERBOSE_WARNING_DEVICE */
  97. return(0);
  98. } // ENDIF- Is the CD/DVD already in use? That's fine.
  99. #ifdef VERBOSE_FUNCTION_DEVICE
  100. PrintLog("CDVD device: DeviceOpen()");
  101. #endif /* VERBOSE_FUNCTION_DEVICE */
  102. // InitConf();
  103. // LoadConf(); // Should be done once before making this call
  104. devicehandle = open(conf.devicename, O_RDONLY | O_NONBLOCK);
  105. if(devicehandle == -1) {
  106. #ifdef VERBOSE_WARNINGS
  107. PrintLog("CDVD device: Error opening device: %i:%s", errno, strerror(errno));
  108. #endif /* VERBOSE_WARNINGS */
  109. return(-1);
  110. } // ENDIF- Failed to open device? Abort
  111. // Note: Hmm. Need a minimum capability in case this fails?
  112. devicecapability = ioctl(devicehandle, CDROM_GET_CAPABILITY);
  113. if(errno != 0) {
  114. #ifdef VERBOSE_WARNINGS
  115. PrintLog("CDVD device: Error getting device capabilities: %i:%s", errno, strerror(errno));
  116. #endif /* VERBOSE_WARNINGS */
  117. close(devicehandle);
  118. devicehandle = -1;
  119. devicecapability = 0;
  120. return(-1);
  121. } // ENDIF- Can't read drive capabilities? Close and Abort.
  122. #ifdef VERBOSE_DISC_TYPE
  123. PrintLog("CDVD device: Device Type(s)");
  124. if(devicecapability < CDC_CD_R) PrintLog("CDVD device: CD");
  125. if(devicecapability & CDC_CD_R) PrintLog("CDVD device: CD-R");
  126. if(devicecapability & CDC_CD_RW) PrintLog("CDVD device: CD-RW");
  127. if(devicecapability & CDC_DVD) PrintLog("CDVD device: DVD");
  128. if(devicecapability & CDC_DVD_R) PrintLog("CDVD device: DVD-R");
  129. if(devicecapability & CDC_DVD_RAM) PrintLog("CDVD device: DVD-RAM");
  130. #endif /* VERBOSE_DISC_TYPE */
  131. #ifdef VERBOSE_DISC_INFO
  132. PrintLog("CDVD device: Device Capabilities:");
  133. if(devicecapability & CDC_CLOSE_TRAY) PrintLog("CDVD device: Can close a tray");
  134. if(devicecapability & CDC_OPEN_TRAY) PrintLog("CDVD device: Can open a tray");
  135. // if(devicecapability & CDC_LOCK) PrintLog("CDVD device: Can lock the drive door");
  136. if(devicecapability & CDC_SELECT_SPEED) PrintLog("CDVD device: Can change spin speed");
  137. // if(devicecapability & CDC_SELECT_DISC) PrintLog("CDVD device: Can change disks (multi-disk tray)");
  138. // if(devicecapability & CDC_MULTI_SESSION) PrintLog("CDVD device: Can read multi-session disks");
  139. // if(devicecapability & CDC_MCN) PrintLog("CDVD device: Can read Medium Catalog Numbers (maybe)");
  140. if(devicecapability & CDC_MEDIA_CHANGED) PrintLog("CDVD device: Can tell if the disc was changed");
  141. if(devicecapability & CDC_PLAY_AUDIO) PrintLog("CDVD device: Can play audio disks");
  142. // if(devicecapability & CDC_RESET) PrintLog("CDVD device: Can reset the device");
  143. if(devicecapability & CDC_IOCTLS) PrintLog("CDVD device: Odd IOCTLs. Not sure of compatability");
  144. if(devicecapability & CDC_DRIVE_STATUS) PrintLog("CDVD device: Can monitor the drive tray");
  145. #endif /* VERBOSE_DISC_INFO */
  146. ////// Should be called after an open (instead of inside of one)
  147. // InitDisc();
  148. // traystatus = CDVD_TRAY_OPEN; // Start with Tray Open
  149. // DeviceTrayStatus(); // Now find out for sure.
  150. return(0); // Device opened and ready for use.
  151. } // END DeviceOpen()
  152. // Called by DeviceTrayStatus(), CDVDclose(), and CDVDshutdown()
  153. void DeviceClose() {
  154. if(devicehandle == -1) {
  155. #ifdef VERBOSE_FUNCTION_DEVICE
  156. PrintLog("CDVD device: Device already closed");
  157. #endif /* VERBOSE_FUNCTION_DEVICE */
  158. return;
  159. } // ENDIF- Device already closed? Ok.
  160. #ifdef VERBOSE_FUNCTION_DEVICE
  161. PrintLog("CDVD device: DeviceClose()");
  162. #endif /* VERBOSE_FUNCTION_DEVICE */
  163. InitDisc();
  164. close(devicehandle);
  165. devicehandle = -1;
  166. devicecapability = 0;
  167. return;
  168. } // END CDVDclose()
  169. s32 DeviceReadTrack(u32 lsn, int mode, u8 *buffer) {
  170. s32 s32result;
  171. #ifdef VERBOSE_FUNCTION_DEVICE
  172. PrintLog("CDVD device: DeviceReadTrack(%i)", lsn);
  173. #endif /* VERBOSE_FUNCTION_DEVICE */
  174. if(DiscInserted() == -1) return(-1);
  175. // Get that data
  176. if((disctype == CDVD_TYPE_PS2DVD) || (disctype == CDVD_TYPE_DVDV)) {
  177. s32result = DVDreadTrack(lsn, mode, buffer);
  178. } else {
  179. s32result = CDreadTrack(lsn, mode, buffer);
  180. } //ENDIF- Read a DVD sector or a CD sector?
  181. return(s32result);
  182. } // END DeviceReadTrack()
  183. s32 DeviceBufferOffset() {
  184. #ifdef VERBOSE_FUNCTION_DEVICE
  185. PrintLog("CDVD device: DeviceBufferOffset()");
  186. #endif /* VERBOSE_FUNCTION_DEVICE */
  187. if(DiscInserted() == -1) return(-1);
  188. if((disctype == CDVD_TYPE_PS2DVD) || (disctype == CDVD_TYPE_DVDV)) {
  189. return(0);
  190. } else {
  191. return(CDgetBufferOffset());
  192. } // ENDIF- Is this a DVD?
  193. } // END DeviceBufferOffset()
  194. s32 DeviceGetTD(u8 track, cdvdTD *cdvdtd) {
  195. if(DiscInserted() == -1) return(-1);
  196. if((disctype == CDVD_TYPE_PS2DVD) || (disctype == CDVD_TYPE_DVDV)) {
  197. return(DVDgetTD(track, cdvdtd));
  198. } else {
  199. return(CDgetTD(track, cdvdtd));
  200. } // ENDIF- Is this a DVD?
  201. } // END DeviceGetTD()
  202. // Called by DeviceTrayStatus()
  203. s32 DeviceGetDiskType() {
  204. s32 s32result;
  205. s32 ioctldisktype;
  206. errno = 0;
  207. if(devicehandle == -1) {
  208. return(-1);
  209. } // ENDIF- Someone forget to open the device?
  210. if(traystatus == CDVD_TRAY_OPEN) {
  211. return(disctype);
  212. } // ENDIF- Is the device tray open? No disc to check yet.
  213. if(disctype != CDVD_TYPE_NODISC) {
  214. return(disctype);
  215. } // ENDIF- Already checked? Drive still closed? Disc hasn't changed.
  216. #ifdef VERBOSE_FUNCTION_DEVICE
  217. PrintLog("CDVD device: DeviceGetDiskType()");
  218. #endif /* VERBOSE_FUNCTION_DEVICE */
  219. disctype = CDVD_TYPE_DETCT;
  220. ioctldisktype = ioctl(devicehandle, CDROM_DISC_STATUS);
  221. if(errno != 0) {
  222. #ifdef VERBOSE_WARNINGS
  223. PrintLog("CDVD device: Trouble reading Disc Type!");
  224. PrintLog("CDVD device: Error: %i:%s", errno, strerror(errno));
  225. #endif /* VERBOSE_WARNINGS */
  226. disctype = CDVD_TYPE_UNKNOWN;
  227. return(disctype);
  228. } // ENDIF- Trouble probing for a disc?
  229. s32result = DVDgetDiskType(ioctldisktype);
  230. if(s32result != -1) {
  231. return(disctype);
  232. } // ENDIF- Did we find a disc type?
  233. s32result = CDgetDiskType(ioctldisktype);
  234. if(s32result != -1) {
  235. return(disctype);
  236. } // ENDIF- Did we find a disc type?
  237. disctype = CDVD_TYPE_UNKNOWN; // Not a CD? Not a DVD? Is is peanut butter?
  238. return(disctype);
  239. } // END CDVDgetDiskType()
  240. // Called by PollLoop() and CDVDgetTrayStatus()
  241. s32 DeviceTrayStatus() {
  242. s32 s32result;
  243. errno = 0;
  244. #ifdef VERBOSE_FUNCTION_DEVICE
  245. PrintLog("CDVD device: DeviceTrayStatus()");
  246. #endif /* VERBOSE_FUNCTION_DEVICE */
  247. if(devicehandle == -1) {
  248. return(-1);
  249. } // ENDIF- Someone forget to open the device?
  250. if((devicecapability & CDC_DRIVE_STATUS) != 0) {
  251. s32result = ioctl(devicehandle, CDROM_DRIVE_STATUS);
  252. if(s32result < 0) {
  253. #ifdef VERBOSE_WARNINGS
  254. PrintLog("CDVD device: Trouble reading Drive Status!");
  255. PrintLog("CDVD device: Error: (%i) %i:%s", s32result, errno, strerror(errno));
  256. #endif /* VERBOSE_WARNINGS */
  257. s32result = CDS_TRAY_OPEN;
  258. } // ENDIF- Failure to get status? Assume it's open.
  259. errno = 0;
  260. } else {
  261. s32result = ioctl(devicehandle, CDROM_DISC_STATUS);
  262. if(errno != 0) {
  263. #ifdef VERBOSE_WARNINGS
  264. PrintLog("CDVD device: Trouble detecting Disc Status presense!");
  265. PrintLog("CDVD device: Error: (%i) %i:%s", s32result, errno, strerror(errno));
  266. #endif /* VERBOSE_WARNINGS */
  267. s32result = CDS_TRAY_OPEN;
  268. errno = 0;
  269. } // ENDIF- Trouble?
  270. if(s32result == CDS_NO_DISC) {
  271. s32result = CDS_TRAY_OPEN;
  272. } // ENDIF- Is there no disc in the device? Guess the tray is open
  273. } // ENDIF- Can we poll the tray directly? (Or look at disc status instead?)
  274. if(s32result == CDS_TRAY_OPEN) {
  275. traystatus = CDVD_TRAY_OPEN;
  276. if(disctype != CDVD_TYPE_NODISC) {
  277. DeviceClose(); // Kind of severe way of flushing all buffers.
  278. DeviceOpen();
  279. InitDisc();
  280. } // ENDIF- Tray just opened... clear disc info
  281. } else {
  282. traystatus = CDVD_TRAY_CLOSE;
  283. if(disctype == CDVD_TYPE_NODISC) {
  284. DeviceGetDiskType();
  285. } // ENDIF- Tray just closed? Get disc information
  286. } // ENDIF- Do we detect an open tray?
  287. return(traystatus);
  288. } // END CDVD_getTrayStatus()
  289. s32 DeviceTrayOpen() {
  290. s32 s32result;
  291. errno = 0;
  292. if(devicehandle == -1) {
  293. return(-1);
  294. } // ENDIF- Someone forget to open the device?
  295. if((devicecapability & CDC_OPEN_TRAY) == 0) {
  296. return(-1);
  297. } // ENDIF- Don't have open capability? Error out.
  298. // Tray already open? Exit.
  299. if(traystatus == CDVD_TRAY_OPEN) return(0);
  300. #ifdef VERBOSE_FUNCTION_DEVICE
  301. PrintLog("CDVD device: DeviceTrayOpen()");
  302. #endif /* VERBOSE_FUNCTION_DEVICE */
  303. s32result = ioctl(devicehandle, CDROMEJECT);
  304. #ifdef VERBOSE_WARNINGS
  305. if((s32result != 0) || (errno != 0)) {
  306. PrintLog("CDVD device: Could not open the tray!");
  307. PrintLog("CDVD device: Error: (%i) %i:%s", s32result, errno, strerror(errno));
  308. } // ENDIF- Trouble?
  309. #endif /* VERBOSE_WARNINGS */
  310. return(s32result);
  311. } // END DeviceTrayOpen()
  312. s32 DeviceTrayClose() {
  313. s32 s32result;
  314. errno = 0;
  315. if(devicehandle == -1) {
  316. return(-1);
  317. } // ENDIF- Someone forget to open the device?
  318. if((devicecapability & CDC_CLOSE_TRAY) == 0) {
  319. return(-1);
  320. } // ENDIF- Don't have close capability? Error out.
  321. // Tray already closed? Exit.
  322. if(traystatus == CDVD_TRAY_CLOSE) return(0);
  323. #ifdef VERBOSE_FUNCTION_DEVICE
  324. PrintLog("CDVD device: DeviceTrayClose()");
  325. #endif /* VERBOSE_FUNCTION_DEVICE */
  326. s32result = ioctl(devicehandle, CDROMCLOSETRAY);
  327. #ifdef VERBOSE_WARNINGS
  328. if((s32result != 0) || (errno != 0)) {
  329. PrintLog("CDVD device: Could not close the tray!");
  330. PrintLog("CDVD device: Error: (%i) %i:%s", s32result, errno, strerror(errno));
  331. } // ENDIF- Trouble?
  332. #endif /* VERBOSE_WARNINGS */
  333. return(s32result);
  334. } // END DeviceTrayClose()