/plugins/CDVDlinuz/Src/Linux/device.c
C | 420 lines | 291 code | 86 blank | 43 comment | 117 complexity | 45daf6c03a851d108e82dd499aa2d085 MD5 | raw file
- /* device.c
- * Copyright (C) 2002-2005 PCSX2 Team
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
- *
- * PCSX2 members can be contacted through their website at www.pcsx2.net.
- */
- #include <errno.h> // errno
- #include <fcntl.h> // open()
- #include <stddef.h> // NULL
- #include <stdlib.h> // getenv()
- #include <string.h> // strerror()
- #include <sys/ioctl.h> // ioctl()
- #include <sys/stat.h> // open()
- #include <sys/types.h> // open()
- #include <time.h> // time_t, time(), struct timeval
- #include <unistd.h> // close(), select()
- #include <linux/cdrom.h> // CD/DVD based ioctl() and defines.
- // missing on some files for some reason.........
- #ifndef CDC_IOCTLS
- #define CDC_IOCTLS 0x400
- #endif
- #include "logfile.h"
- #include "conf.h"
- #include "CD.h"
- #include "DVD.h"
- #include "device.h"
- #include "../PS2Etypes.h" // u32, u8, s32
- // Globals
- int devicehandle; // File Handle for the device/drive
- s32 devicecapability; // Capability Flags
- time_t lasttime; // Time marker (in case something gets called too often)
- s32 traystatus; // Is the CD/DVD tray open?
- s32 disctype; // Type of disc in drive (Video DVD, PSX CD, etc.)
- u8 tocbuffer[2048];
- void DeviceInit() {
- devicehandle = -1;
- devicecapability = 0;
- lasttime = time(NULL);
- InitDisc();
- } // END DeviceInit()
- // Called by DeviceOpen(), DeviceGetDiskType()
- void InitDisc() {
- int i;
- #ifdef VERBOSE_FUNCTION_DEVICE
- PrintLog("CDVD device: InitDisc()");
- #endif /* VERBOSE_FUNCTION_DEVICE */
- if((disctype == CDVD_TYPE_PS2DVD) ||
- (disctype == CDVD_TYPE_DVDV)) {
- InitDVDInfo();
- } // ENDIF- Clean out DVD Disc Info?
- if((disctype == CDVD_TYPE_PS2CD) ||
- (disctype == CDVD_TYPE_PS2CDDA) ||
- (disctype == CDVD_TYPE_PSCD) ||
- (disctype == CDVD_TYPE_PSCDDA) ||
- (disctype == CDVD_TYPE_CDDA)) {
- InitCDInfo();
- } // ENDIF- Clean out DVD Disc Info?
- disctype = CDVD_TYPE_NODISC;
- for(i = 0; i > sizeof(tocbuffer); i++) tocbuffer[i] = 0x00;
- } // END InitDisc()
- s32 DiscInserted() {
- if(devicehandle == -1) return(-1);
- if(traystatus == CDVD_TRAY_OPEN) return(-1);
- if(disctype == CDVD_TYPE_ILLEGAL) return(-1);
- // if(disctype == CDVD_TYPE_UNKNOWN) return(-1); // Hmm. Let this one through?
- if(disctype == CDVD_TYPE_DETCTDVDD) return(-1);
- if(disctype == CDVD_TYPE_DETCTDVDS) return(-1);
- if(disctype == CDVD_TYPE_DETCTCD) return(-1);
- if(disctype == CDVD_TYPE_DETCT) return(-1);
- if(disctype == CDVD_TYPE_NODISC) return(-1);
- #ifdef VERBOSE_FUNCTION_DEVICE
- PrintLog("CDVD device: DiscInserted()");
- #endif /* VERBOSE_FUNCTION_DEVICE */
- return(0);
- } // END DiscInserted()
- // Called by DeviceTrayStatus() and CDVDopen()
- s32 DeviceOpen() {
- // s32 s32result;
- errno = 0;
- if(devicehandle != -1) {
- #ifdef VERBOSE_WARNING_DEVICE
- PrintLog("CDVD device: Device already open!");
- #endif /* VERBOSE_WARNING_DEVICE */
- return(0);
- } // ENDIF- Is the CD/DVD already in use? That's fine.
- #ifdef VERBOSE_FUNCTION_DEVICE
- PrintLog("CDVD device: DeviceOpen()");
- #endif /* VERBOSE_FUNCTION_DEVICE */
- // InitConf();
- // LoadConf(); // Should be done once before making this call
- devicehandle = open(conf.devicename, O_RDONLY | O_NONBLOCK);
- if(devicehandle == -1) {
- #ifdef VERBOSE_WARNINGS
- PrintLog("CDVD device: Error opening device: %i:%s", errno, strerror(errno));
- #endif /* VERBOSE_WARNINGS */
- return(-1);
- } // ENDIF- Failed to open device? Abort
- // Note: Hmm. Need a minimum capability in case this fails?
- devicecapability = ioctl(devicehandle, CDROM_GET_CAPABILITY);
- if(errno != 0) {
- #ifdef VERBOSE_WARNINGS
- PrintLog("CDVD device: Error getting device capabilities: %i:%s", errno, strerror(errno));
- #endif /* VERBOSE_WARNINGS */
- close(devicehandle);
- devicehandle = -1;
- devicecapability = 0;
- return(-1);
- } // ENDIF- Can't read drive capabilities? Close and Abort.
- #ifdef VERBOSE_DISC_TYPE
- PrintLog("CDVD device: Device Type(s)");
- if(devicecapability < CDC_CD_R) PrintLog("CDVD device: CD");
- if(devicecapability & CDC_CD_R) PrintLog("CDVD device: CD-R");
- if(devicecapability & CDC_CD_RW) PrintLog("CDVD device: CD-RW");
- if(devicecapability & CDC_DVD) PrintLog("CDVD device: DVD");
- if(devicecapability & CDC_DVD_R) PrintLog("CDVD device: DVD-R");
- if(devicecapability & CDC_DVD_RAM) PrintLog("CDVD device: DVD-RAM");
- #endif /* VERBOSE_DISC_TYPE */
- #ifdef VERBOSE_DISC_INFO
- PrintLog("CDVD device: Device Capabilities:");
- if(devicecapability & CDC_CLOSE_TRAY) PrintLog("CDVD device: Can close a tray");
- if(devicecapability & CDC_OPEN_TRAY) PrintLog("CDVD device: Can open a tray");
- // if(devicecapability & CDC_LOCK) PrintLog("CDVD device: Can lock the drive door");
- if(devicecapability & CDC_SELECT_SPEED) PrintLog("CDVD device: Can change spin speed");
- // if(devicecapability & CDC_SELECT_DISC) PrintLog("CDVD device: Can change disks (multi-disk tray)");
- // if(devicecapability & CDC_MULTI_SESSION) PrintLog("CDVD device: Can read multi-session disks");
- // if(devicecapability & CDC_MCN) PrintLog("CDVD device: Can read Medium Catalog Numbers (maybe)");
- if(devicecapability & CDC_MEDIA_CHANGED) PrintLog("CDVD device: Can tell if the disc was changed");
- if(devicecapability & CDC_PLAY_AUDIO) PrintLog("CDVD device: Can play audio disks");
- // if(devicecapability & CDC_RESET) PrintLog("CDVD device: Can reset the device");
- if(devicecapability & CDC_IOCTLS) PrintLog("CDVD device: Odd IOCTLs. Not sure of compatability");
- if(devicecapability & CDC_DRIVE_STATUS) PrintLog("CDVD device: Can monitor the drive tray");
- #endif /* VERBOSE_DISC_INFO */
- ////// Should be called after an open (instead of inside of one)
- // InitDisc();
- // traystatus = CDVD_TRAY_OPEN; // Start with Tray Open
- // DeviceTrayStatus(); // Now find out for sure.
- return(0); // Device opened and ready for use.
- } // END DeviceOpen()
- // Called by DeviceTrayStatus(), CDVDclose(), and CDVDshutdown()
- void DeviceClose() {
- if(devicehandle == -1) {
- #ifdef VERBOSE_FUNCTION_DEVICE
- PrintLog("CDVD device: Device already closed");
- #endif /* VERBOSE_FUNCTION_DEVICE */
- return;
- } // ENDIF- Device already closed? Ok.
- #ifdef VERBOSE_FUNCTION_DEVICE
- PrintLog("CDVD device: DeviceClose()");
- #endif /* VERBOSE_FUNCTION_DEVICE */
- InitDisc();
- close(devicehandle);
- devicehandle = -1;
- devicecapability = 0;
- return;
- } // END CDVDclose()
- s32 DeviceReadTrack(u32 lsn, int mode, u8 *buffer) {
- s32 s32result;
- #ifdef VERBOSE_FUNCTION_DEVICE
- PrintLog("CDVD device: DeviceReadTrack(%i)", lsn);
- #endif /* VERBOSE_FUNCTION_DEVICE */
- if(DiscInserted() == -1) return(-1);
- // Get that data
- if((disctype == CDVD_TYPE_PS2DVD) || (disctype == CDVD_TYPE_DVDV)) {
- s32result = DVDreadTrack(lsn, mode, buffer);
- } else {
- s32result = CDreadTrack(lsn, mode, buffer);
- } //ENDIF- Read a DVD sector or a CD sector?
- return(s32result);
- } // END DeviceReadTrack()
- s32 DeviceBufferOffset() {
- #ifdef VERBOSE_FUNCTION_DEVICE
- PrintLog("CDVD device: DeviceBufferOffset()");
- #endif /* VERBOSE_FUNCTION_DEVICE */
- if(DiscInserted() == -1) return(-1);
- if((disctype == CDVD_TYPE_PS2DVD) || (disctype == CDVD_TYPE_DVDV)) {
- return(0);
- } else {
- return(CDgetBufferOffset());
- } // ENDIF- Is this a DVD?
- } // END DeviceBufferOffset()
- s32 DeviceGetTD(u8 track, cdvdTD *cdvdtd) {
- if(DiscInserted() == -1) return(-1);
- if((disctype == CDVD_TYPE_PS2DVD) || (disctype == CDVD_TYPE_DVDV)) {
- return(DVDgetTD(track, cdvdtd));
- } else {
- return(CDgetTD(track, cdvdtd));
- } // ENDIF- Is this a DVD?
- } // END DeviceGetTD()
- // Called by DeviceTrayStatus()
- s32 DeviceGetDiskType() {
- s32 s32result;
- s32 ioctldisktype;
- errno = 0;
- if(devicehandle == -1) {
- return(-1);
- } // ENDIF- Someone forget to open the device?
- if(traystatus == CDVD_TRAY_OPEN) {
- return(disctype);
- } // ENDIF- Is the device tray open? No disc to check yet.
- if(disctype != CDVD_TYPE_NODISC) {
- return(disctype);
- } // ENDIF- Already checked? Drive still closed? Disc hasn't changed.
- #ifdef VERBOSE_FUNCTION_DEVICE
- PrintLog("CDVD device: DeviceGetDiskType()");
- #endif /* VERBOSE_FUNCTION_DEVICE */
- disctype = CDVD_TYPE_DETCT;
- ioctldisktype = ioctl(devicehandle, CDROM_DISC_STATUS);
- if(errno != 0) {
- #ifdef VERBOSE_WARNINGS
- PrintLog("CDVD device: Trouble reading Disc Type!");
- PrintLog("CDVD device: Error: %i:%s", errno, strerror(errno));
- #endif /* VERBOSE_WARNINGS */
- disctype = CDVD_TYPE_UNKNOWN;
- return(disctype);
- } // ENDIF- Trouble probing for a disc?
- s32result = DVDgetDiskType(ioctldisktype);
- if(s32result != -1) {
- return(disctype);
- } // ENDIF- Did we find a disc type?
- s32result = CDgetDiskType(ioctldisktype);
- if(s32result != -1) {
- return(disctype);
- } // ENDIF- Did we find a disc type?
- disctype = CDVD_TYPE_UNKNOWN; // Not a CD? Not a DVD? Is is peanut butter?
- return(disctype);
- } // END CDVDgetDiskType()
- // Called by PollLoop() and CDVDgetTrayStatus()
- s32 DeviceTrayStatus() {
- s32 s32result;
- errno = 0;
- #ifdef VERBOSE_FUNCTION_DEVICE
- PrintLog("CDVD device: DeviceTrayStatus()");
- #endif /* VERBOSE_FUNCTION_DEVICE */
- if(devicehandle == -1) {
- return(-1);
- } // ENDIF- Someone forget to open the device?
- if((devicecapability & CDC_DRIVE_STATUS) != 0) {
- s32result = ioctl(devicehandle, CDROM_DRIVE_STATUS);
- if(s32result < 0) {
- #ifdef VERBOSE_WARNINGS
- PrintLog("CDVD device: Trouble reading Drive Status!");
- PrintLog("CDVD device: Error: (%i) %i:%s", s32result, errno, strerror(errno));
- #endif /* VERBOSE_WARNINGS */
- s32result = CDS_TRAY_OPEN;
- } // ENDIF- Failure to get status? Assume it's open.
- errno = 0;
- } else {
- s32result = ioctl(devicehandle, CDROM_DISC_STATUS);
- if(errno != 0) {
- #ifdef VERBOSE_WARNINGS
- PrintLog("CDVD device: Trouble detecting Disc Status presense!");
- PrintLog("CDVD device: Error: (%i) %i:%s", s32result, errno, strerror(errno));
- #endif /* VERBOSE_WARNINGS */
- s32result = CDS_TRAY_OPEN;
- errno = 0;
- } // ENDIF- Trouble?
- if(s32result == CDS_NO_DISC) {
- s32result = CDS_TRAY_OPEN;
- } // ENDIF- Is there no disc in the device? Guess the tray is open
- } // ENDIF- Can we poll the tray directly? (Or look at disc status instead?)
- if(s32result == CDS_TRAY_OPEN) {
- traystatus = CDVD_TRAY_OPEN;
- if(disctype != CDVD_TYPE_NODISC) {
- DeviceClose(); // Kind of severe way of flushing all buffers.
- DeviceOpen();
- InitDisc();
- } // ENDIF- Tray just opened... clear disc info
- } else {
- traystatus = CDVD_TRAY_CLOSE;
- if(disctype == CDVD_TYPE_NODISC) {
- DeviceGetDiskType();
- } // ENDIF- Tray just closed? Get disc information
- } // ENDIF- Do we detect an open tray?
- return(traystatus);
- } // END CDVD_getTrayStatus()
- s32 DeviceTrayOpen() {
- s32 s32result;
- errno = 0;
- if(devicehandle == -1) {
- return(-1);
- } // ENDIF- Someone forget to open the device?
- if((devicecapability & CDC_OPEN_TRAY) == 0) {
- return(-1);
- } // ENDIF- Don't have open capability? Error out.
- // Tray already open? Exit.
- if(traystatus == CDVD_TRAY_OPEN) return(0);
- #ifdef VERBOSE_FUNCTION_DEVICE
- PrintLog("CDVD device: DeviceTrayOpen()");
- #endif /* VERBOSE_FUNCTION_DEVICE */
- s32result = ioctl(devicehandle, CDROMEJECT);
- #ifdef VERBOSE_WARNINGS
- if((s32result != 0) || (errno != 0)) {
- PrintLog("CDVD device: Could not open the tray!");
- PrintLog("CDVD device: Error: (%i) %i:%s", s32result, errno, strerror(errno));
- } // ENDIF- Trouble?
- #endif /* VERBOSE_WARNINGS */
- return(s32result);
- } // END DeviceTrayOpen()
- s32 DeviceTrayClose() {
- s32 s32result;
- errno = 0;
- if(devicehandle == -1) {
- return(-1);
- } // ENDIF- Someone forget to open the device?
- if((devicecapability & CDC_CLOSE_TRAY) == 0) {
- return(-1);
- } // ENDIF- Don't have close capability? Error out.
- // Tray already closed? Exit.
- if(traystatus == CDVD_TRAY_CLOSE) return(0);
- #ifdef VERBOSE_FUNCTION_DEVICE
- PrintLog("CDVD device: DeviceTrayClose()");
- #endif /* VERBOSE_FUNCTION_DEVICE */
- s32result = ioctl(devicehandle, CDROMCLOSETRAY);
- #ifdef VERBOSE_WARNINGS
- if((s32result != 0) || (errno != 0)) {
- PrintLog("CDVD device: Could not close the tray!");
- PrintLog("CDVD device: Error: (%i) %i:%s", s32result, errno, strerror(errno));
- } // ENDIF- Trouble?
- #endif /* VERBOSE_WARNINGS */
- return(s32result);
- } // END DeviceTrayClose()