revision 237:6f1a429c9d12
summary |
tree |
shortlog |
changelog |
graph |
changeset |
raw | bz2 | zip | gz changeset | 237:6f1a429c9d12 |
parent | 236:581a9f8bf6a6 |
child | 238:6af4cc93b137 |
author | nkeynes |
date | Thu Dec 14 12:31:38 2006 +0000 (17 years ago) |
Add preliminary linux native CD driver support
src/Makefile.am | view | annotate | diff | log | ||
src/Makefile.in | view | annotate | diff | log | ||
src/gdrom/gdrom.c | view | annotate | diff | log | ||
src/gdrom/gdrom.h | view | annotate | diff | log | ||
src/gdrom/linux.c | view | annotate | diff | log |
1.1 --- a/src/Makefile.am Thu Dec 14 11:58:18 2006 +00001.2 +++ b/src/Makefile.am Thu Dec 14 12:31:38 2006 +00001.3 @@ -14,7 +14,7 @@1.4 asic.c asic.h \1.5 syscall.c syscall.h bios.c dcload.c \1.6 gdrom/ide.c gdrom/ide.h gdrom/packet.h \1.7 - gdrom/gdrom.c gdrom/gdrom.h gdrom/nrg.c gdrom/cdi.c \1.8 + gdrom/gdrom.c gdrom/gdrom.h gdrom/nrg.c gdrom/cdi.c gdrom/linux.c \1.9 dreamcast.c dreamcast.h \1.10 sh4/intc.c sh4/intc.h sh4/sh4mem.c sh4/timer.c sh4/dmac.c \1.11 sh4/sh4core.c sh4/sh4core.h sh4/sh4dasm.c sh4/sh4dasm.h \
2.1 --- a/src/Makefile.in Thu Dec 14 11:58:18 2006 +00002.2 +++ b/src/Makefile.in Thu Dec 14 12:31:38 2006 +00002.3 @@ -62,6 +62,7 @@2.4 GETTEXT_PACKAGE = @GETTEXT_PACKAGE@2.5 GMOFILES = @GMOFILES@2.6 GMSGFMT = @GMSGFMT@2.7 +GREP = @GREP@2.8 INSTALL_DATA = @INSTALL_DATA@2.9 INSTALL_PROGRAM = @INSTALL_PROGRAM@2.10 INSTALL_SCRIPT = @INSTALL_SCRIPT@2.11 @@ -100,8 +101,6 @@2.12 VERSION = @VERSION@2.13 XGETTEXT = @XGETTEXT@2.14 ac_ct_CC = @ac_ct_CC@2.15 -ac_ct_STRIP = @ac_ct_STRIP@2.16 -ac_pt_PKG_CONFIG = @ac_pt_PKG_CONFIG@2.17 am__fastdepCC_FALSE = @am__fastdepCC_FALSE@2.18 am__fastdepCC_TRUE = @am__fastdepCC_TRUE@2.19 am__include = @am__include@2.20 @@ -110,18 +109,25 @@2.21 bindir = @bindir@2.22 build_alias = @build_alias@2.23 datadir = @datadir@2.24 +datarootdir = @datarootdir@2.25 +docdir = @docdir@2.26 +dvidir = @dvidir@2.27 exec_prefix = @exec_prefix@2.28 host_alias = @host_alias@2.29 +htmldir = @htmldir@2.30 includedir = @includedir@2.31 infodir = @infodir@2.32 install_sh = @install_sh@2.33 libdir = @libdir@2.34 libexecdir = @libexecdir@2.35 +localedir = @localedir@2.36 localstatedir = @localstatedir@2.37 mandir = @mandir@2.38 oldincludedir = @oldincludedir@2.39 +pdfdir = @pdfdir@2.40 prefix = @prefix@2.41 program_transform_name = @program_transform_name@2.42 +psdir = @psdir@2.43 sbindir = @sbindir@2.44 sharedstatedir = @sharedstatedir@2.45 sysconfdir = @sysconfdir@2.46 @@ -142,7 +148,7 @@2.47 asic.c asic.h \2.48 syscall.c syscall.h bios.c dcload.c \2.49 gdrom/ide.c gdrom/ide.h gdrom/packet.h \2.50 - gdrom/gdrom.c gdrom/gdrom.h gdrom/nrg.c gdrom/cdi.c \2.51 + gdrom/gdrom.c gdrom/gdrom.h gdrom/nrg.c gdrom/cdi.c gdrom/linux.c \2.52 dreamcast.c dreamcast.h \2.53 sh4/intc.c sh4/intc.h sh4/sh4mem.c sh4/timer.c sh4/dmac.c \2.54 sh4/sh4core.c sh4/sh4core.h sh4/sh4dasm.c sh4/sh4dasm.h \2.55 @@ -180,8 +186,8 @@2.56 am_lxdream_OBJECTS = main.$(OBJEXT) mem.$(OBJEXT) watch.$(OBJEXT) \2.57 asic.$(OBJEXT) syscall.$(OBJEXT) bios.$(OBJEXT) \2.58 dcload.$(OBJEXT) ide.$(OBJEXT) gdrom.$(OBJEXT) nrg.$(OBJEXT) \2.59 - cdi.$(OBJEXT) dreamcast.$(OBJEXT) intc.$(OBJEXT) \2.60 - sh4mem.$(OBJEXT) timer.$(OBJEXT) dmac.$(OBJEXT) \2.61 + cdi.$(OBJEXT) linux.$(OBJEXT) dreamcast.$(OBJEXT) \2.62 + intc.$(OBJEXT) sh4mem.$(OBJEXT) timer.$(OBJEXT) dmac.$(OBJEXT) \2.63 sh4core.$(OBJEXT) sh4dasm.$(OBJEXT) sh4mmio.$(OBJEXT) \2.64 scif.$(OBJEXT) armcore.$(OBJEXT) armdasm.$(OBJEXT) \2.65 armmem.$(OBJEXT) aica.$(OBJEXT) audio.$(OBJEXT) pvr2.$(OBJEXT) \2.66 @@ -212,19 +218,20 @@2.67 @AMDEP_TRUE@ ./$(DEPDIR)/dump_win.Po ./$(DEPDIR)/gdrom.Po \2.68 @AMDEP_TRUE@ ./$(DEPDIR)/gui.Po ./$(DEPDIR)/ide.Po \2.69 @AMDEP_TRUE@ ./$(DEPDIR)/intc.Po ./$(DEPDIR)/interface.Po \2.70 -@AMDEP_TRUE@ ./$(DEPDIR)/loader.Po ./$(DEPDIR)/main.Po \2.71 -@AMDEP_TRUE@ ./$(DEPDIR)/maple.Po ./$(DEPDIR)/mem.Po \2.72 -@AMDEP_TRUE@ ./$(DEPDIR)/mmr_win.Po ./$(DEPDIR)/nrg.Po \2.73 -@AMDEP_TRUE@ ./$(DEPDIR)/pvr2.Po ./$(DEPDIR)/rendbkg.Po \2.74 -@AMDEP_TRUE@ ./$(DEPDIR)/rendcore.Po ./$(DEPDIR)/render.Po \2.75 -@AMDEP_TRUE@ ./$(DEPDIR)/rendsort.Po ./$(DEPDIR)/scif.Po \2.76 -@AMDEP_TRUE@ ./$(DEPDIR)/sh4core.Po ./$(DEPDIR)/sh4dasm.Po \2.77 -@AMDEP_TRUE@ ./$(DEPDIR)/sh4mem.Po ./$(DEPDIR)/sh4mmio.Po \2.78 -@AMDEP_TRUE@ ./$(DEPDIR)/support.Po ./$(DEPDIR)/syscall.Po \2.79 -@AMDEP_TRUE@ ./$(DEPDIR)/tacore.Po ./$(DEPDIR)/texcache.Po \2.80 -@AMDEP_TRUE@ ./$(DEPDIR)/timer.Po ./$(DEPDIR)/util.Po \2.81 -@AMDEP_TRUE@ ./$(DEPDIR)/video_gtk.Po ./$(DEPDIR)/video_null.Po \2.82 -@AMDEP_TRUE@ ./$(DEPDIR)/video_x11.Po ./$(DEPDIR)/watch.Po2.83 +@AMDEP_TRUE@ ./$(DEPDIR)/linux.Po ./$(DEPDIR)/loader.Po \2.84 +@AMDEP_TRUE@ ./$(DEPDIR)/main.Po ./$(DEPDIR)/maple.Po \2.85 +@AMDEP_TRUE@ ./$(DEPDIR)/mem.Po ./$(DEPDIR)/mmr_win.Po \2.86 +@AMDEP_TRUE@ ./$(DEPDIR)/nrg.Po ./$(DEPDIR)/pvr2.Po \2.87 +@AMDEP_TRUE@ ./$(DEPDIR)/rendbkg.Po ./$(DEPDIR)/rendcore.Po \2.88 +@AMDEP_TRUE@ ./$(DEPDIR)/render.Po ./$(DEPDIR)/rendsort.Po \2.89 +@AMDEP_TRUE@ ./$(DEPDIR)/scif.Po ./$(DEPDIR)/sh4core.Po \2.90 +@AMDEP_TRUE@ ./$(DEPDIR)/sh4dasm.Po ./$(DEPDIR)/sh4mem.Po \2.91 +@AMDEP_TRUE@ ./$(DEPDIR)/sh4mmio.Po ./$(DEPDIR)/support.Po \2.92 +@AMDEP_TRUE@ ./$(DEPDIR)/syscall.Po ./$(DEPDIR)/tacore.Po \2.93 +@AMDEP_TRUE@ ./$(DEPDIR)/texcache.Po ./$(DEPDIR)/timer.Po \2.94 +@AMDEP_TRUE@ ./$(DEPDIR)/util.Po ./$(DEPDIR)/video_gtk.Po \2.95 +@AMDEP_TRUE@ ./$(DEPDIR)/video_null.Po ./$(DEPDIR)/video_x11.Po \2.96 +@AMDEP_TRUE@ ./$(DEPDIR)/watch.Po2.97 COMPILE = $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) \2.98 $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS)2.99 CCLD = $(CC)2.100 @@ -300,6 +307,7 @@2.101 @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/ide.Po@am__quote@2.102 @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/intc.Po@am__quote@2.103 @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/interface.Po@am__quote@2.104 +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/linux.Po@am__quote@2.105 @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/loader.Po@am__quote@2.106 @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/main.Po@am__quote@2.107 @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/maple.Po@am__quote@2.108 @@ -437,6 +445,28 @@2.109 @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@2.110 @am__fastdepCC_FALSE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o cdi.obj `if test -f 'gdrom/cdi.c'; then $(CYGPATH_W) 'gdrom/cdi.c'; else $(CYGPATH_W) '$(srcdir)/gdrom/cdi.c'; fi`2.112 +linux.o: gdrom/linux.c2.113 +@am__fastdepCC_TRUE@ if $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT linux.o -MD -MP -MF "$(DEPDIR)/linux.Tpo" \2.114 +@am__fastdepCC_TRUE@ -c -o linux.o `test -f 'gdrom/linux.c' || echo '$(srcdir)/'`gdrom/linux.c; \2.115 +@am__fastdepCC_TRUE@ then mv -f "$(DEPDIR)/linux.Tpo" "$(DEPDIR)/linux.Po"; \2.116 +@am__fastdepCC_TRUE@ else rm -f "$(DEPDIR)/linux.Tpo"; exit 1; \2.117 +@am__fastdepCC_TRUE@ fi2.118 +@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='gdrom/linux.c' object='linux.o' libtool=no @AMDEPBACKSLASH@2.119 +@AMDEP_TRUE@@am__fastdepCC_FALSE@ depfile='$(DEPDIR)/linux.Po' tmpdepfile='$(DEPDIR)/linux.TPo' @AMDEPBACKSLASH@2.120 +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@2.121 +@am__fastdepCC_FALSE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o linux.o `test -f 'gdrom/linux.c' || echo '$(srcdir)/'`gdrom/linux.c2.122 +2.123 +linux.obj: gdrom/linux.c2.124 +@am__fastdepCC_TRUE@ if $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT linux.obj -MD -MP -MF "$(DEPDIR)/linux.Tpo" \2.125 +@am__fastdepCC_TRUE@ -c -o linux.obj `if test -f 'gdrom/linux.c'; then $(CYGPATH_W) 'gdrom/linux.c'; else $(CYGPATH_W) '$(srcdir)/gdrom/linux.c'; fi`; \2.126 +@am__fastdepCC_TRUE@ then mv -f "$(DEPDIR)/linux.Tpo" "$(DEPDIR)/linux.Po"; \2.127 +@am__fastdepCC_TRUE@ else rm -f "$(DEPDIR)/linux.Tpo"; exit 1; \2.128 +@am__fastdepCC_TRUE@ fi2.129 +@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='gdrom/linux.c' object='linux.obj' libtool=no @AMDEPBACKSLASH@2.130 +@AMDEP_TRUE@@am__fastdepCC_FALSE@ depfile='$(DEPDIR)/linux.Po' tmpdepfile='$(DEPDIR)/linux.TPo' @AMDEPBACKSLASH@2.131 +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@2.132 +@am__fastdepCC_FALSE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o linux.obj `if test -f 'gdrom/linux.c'; then $(CYGPATH_W) 'gdrom/linux.c'; else $(CYGPATH_W) '$(srcdir)/gdrom/linux.c'; fi`2.133 +2.134 intc.o: sh4/intc.c2.135 @am__fastdepCC_TRUE@ if $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT intc.o -MD -MP -MF "$(DEPDIR)/intc.Tpo" \2.136 @am__fastdepCC_TRUE@ -c -o intc.o `test -f 'sh4/intc.c' || echo '$(srcdir)/'`sh4/intc.c; \
3.1 --- a/src/gdrom/gdrom.c Thu Dec 14 11:58:18 2006 +00003.2 +++ b/src/gdrom/gdrom.c Thu Dec 14 12:31:38 2006 +00003.3 @@ -1,5 +1,5 @@3.4 /**3.5 - * $Id: gdrom.c,v 1.9 2006-06-26 10:30:42 nkeynes Exp $3.6 + * $Id: gdrom.c,v 1.10 2006-12-14 12:31:38 nkeynes Exp $3.7 *3.8 * GD-Rom access functions.3.9 *3.10 @@ -17,6 +17,7 @@3.11 */3.13 #include <stdio.h>3.14 +#include <fcntl.h>3.15 #include <errno.h>3.16 #include "gdrom/ide.h"3.17 #include "gdrom/gdrom.h"3.18 @@ -26,7 +27,7 @@3.19 static void gdrom_image_destroy( gdrom_disc_t );3.20 static gdrom_error_t gdrom_image_read_sectors( gdrom_disc_t, uint32_t, uint32_t, int, char *, uint32_t * );3.22 -gdrom_image_class_t gdrom_image_classes[] = { &nrg_image_class, &cdi_image_class, NULL };3.23 +gdrom_image_class_t gdrom_image_classes[] = { &linux_device_class, &nrg_image_class, &cdi_image_class, NULL };3.25 gdrom_disc_t gdrom_disc = NULL;3.27 @@ -37,20 +38,26 @@3.28 {3.29 const gchar *ext = strrchr(filename, '.');3.30 gdrom_disc_t disc = NULL;3.31 - FILE *f = fopen(filename, "ro");3.32 +3.33 + int fd = open( filename, O_RDONLY | O_NONBLOCK );3.34 + FILE *f;3.35 int i,j;3.36 gdrom_image_class_t extclz = NULL;3.38 - if( f == NULL ) {3.39 + if( fd == -1 ) {3.40 ERROR("Unable to open file '%s': %s", filename, strerror(errno));3.41 return NULL;3.42 }3.44 + f = fdopen(fd, "ro");3.45 +3.46 +3.47 /* try extensions */3.48 if( ext != NULL ) {3.49 ext++; /* Skip the '.' */3.50 for( i=0; gdrom_image_classes[i] != NULL; i++ ) {3.51 - if( strcasecmp( gdrom_image_classes[i]->extension, ext ) == 0 ) {3.52 + if( gdrom_image_classes[i]->extension != NULL &&3.53 + strcasecmp( gdrom_image_classes[i]->extension, ext ) == 0 ) {3.54 extclz = gdrom_image_classes[i];3.55 if( extclz->is_valid_file(f) ) {3.56 disc = extclz->open_image_file(filename, f);3.57 @@ -63,15 +70,20 @@3.58 }3.60 /* Okay, fall back to magic */3.61 + gboolean recognized = FALSE;3.62 for( i=0; gdrom_image_classes[i] != NULL; i++ ) {3.63 if( gdrom_image_classes[i] != extclz &&3.64 gdrom_image_classes[i]->is_valid_file(f) ) {3.65 + recognized = TRUE;3.66 disc = gdrom_image_classes[i]->open_image_file(filename, f);3.67 if( disc != NULL )3.68 return disc;3.69 }3.70 }3.72 + if( !recognized ) {3.73 + ERROR( "Unable to open disc %s: Unsupported format", filename );3.74 + }3.75 fclose(f);3.76 return NULL;3.77 }
4.1 --- a/src/gdrom/gdrom.h Thu Dec 14 11:58:18 2006 +00004.2 +++ b/src/gdrom/gdrom.h Thu Dec 14 12:31:38 2006 +00004.3 @@ -1,5 +1,5 @@4.4 /**4.5 - * $Id: gdrom.h,v 1.7 2006-06-26 10:30:42 nkeynes Exp $4.6 + * $Id: gdrom.h,v 1.8 2006-12-14 12:31:38 nkeynes Exp $4.7 *4.8 * This file defines the structures and functions used by the GD-Rom4.9 * disc driver. (ie, the modules that supply a CD image to be used by the4.10 @@ -95,6 +95,7 @@4.12 extern struct gdrom_image_class nrg_image_class;4.13 extern struct gdrom_image_class cdi_image_class;4.14 +extern struct gdrom_image_class linux_device_class;4.16 /**4.17 * Construct a new image file using the default methods.
5.1 --- /dev/null Thu Jan 01 00:00:00 1970 +00005.2 +++ b/src/gdrom/linux.c Thu Dec 14 12:31:38 2006 +00005.3 @@ -0,0 +1,256 @@5.4 +/**5.5 + * $Id: linux.c,v 1.1 2006-12-14 12:31:38 nkeynes Exp $5.6 + *5.7 + * Linux cd-rom device driver5.8 + *5.9 + * Copyright (c) 2005 Nathan Keynes.5.10 + *5.11 + * This program is free software; you can redistribute it and/or modify5.12 + * it under the terms of the GNU General Public License as published by5.13 + * the Free Software Foundation; either version 2 of the License, or5.14 + * (at your option) any later version.5.15 + *5.16 + * This program is distributed in the hope that it will be useful,5.17 + * but WITHOUT ANY WARRANTY; without even the implied warranty of5.18 + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the5.19 + * GNU General Public License for more details.5.20 + */5.21 +#include <stdlib.h>5.22 +#include <stdio.h>5.23 +#include <string.h>5.24 +#include <errno.h>5.25 +#include <linux/cdrom.h>5.26 +#include <sys/stat.h>5.27 +#include <sys/ioctl.h>5.28 +5.29 +#include "gdrom/gdrom.h"5.30 +#include "gdrom/packet.h"5.31 +#include "dream.h"5.32 +5.33 +#define MAXTOCENTRIES 600 /* This is a fairly generous overestimate really */5.34 +#define MAXTOCSIZE 4 + (MAXTOCENTRIES*11)5.35 +5.36 +#define MSFTOLBA( m,s,f ) (f + (s*CD_FRAMES) + (m*CD_FRAMES*CD_SECS))5.37 +5.38 +static uint32_t inline lbatomsf( uint32_t lba ) {5.39 + union cdrom_addr addr;5.40 + lba = lba + CD_MSF_OFFSET;5.41 + addr.msf.frame = lba % CD_FRAMES;5.42 + int seconds = lba / CD_FRAMES;5.43 + addr.msf.second = seconds % CD_SECS;5.44 + addr.msf.minute = seconds / CD_SECS;5.45 + return addr.lba;5.46 +}5.47 +5.48 +#define LBATOMSF( lba ) lbatomsf(lba)5.49 +5.50 +5.51 +static gboolean linux_image_is_valid( FILE *f );5.52 +static gdrom_disc_t linux_open_device( const gchar *filename, FILE *f );5.53 +static gdrom_error_t linux_read_disc_toc( gdrom_disc_t disc );5.54 +static gdrom_error_t linux_read_sectors( gdrom_disc_t disc, uint32_t sector,5.55 + uint32_t sector_count, int mode, char *buf,5.56 + uint32_t *length );5.57 +static gdrom_error_t linux_send_command( int fd, char *cmd, char *buffer, size_t buflen,5.58 + int direction );5.59 +5.60 +5.61 +struct gdrom_image_class linux_device_class = { "Linux", NULL,5.62 + linux_image_is_valid, linux_open_device };5.63 +5.64 +static gboolean linux_image_is_valid( FILE *f )5.65 +{5.66 + struct stat st;5.67 + struct cdrom_tochdr tochdr;5.68 +5.69 + if( fstat(fileno(f), &st) == -1 ) {5.70 + return FALSE; /* can't stat device? */5.71 + }5.72 + if( !S_ISBLK(st.st_mode) ) {5.73 + return FALSE; /* Not a block device */5.74 + }5.75 +5.76 + if( ioctl(fileno(f), CDROMREADTOCHDR, &tochdr) == -1 ) {5.77 + /* Quick check that this is really a CD */5.78 + return FALSE;5.79 + }5.80 +5.81 + return TRUE;5.82 +}5.83 +5.84 +static gdrom_disc_t linux_open_device( const gchar *filename, FILE *f )5.85 +{5.86 + gdrom_disc_t disc;5.87 + int fd = fileno(f);5.88 +5.89 + disc = gdrom_image_new(f);5.90 + if( disc == NULL ) {5.91 + ERROR("Unable to allocate memory!");5.92 + return NULL;5.93 + }5.94 +5.95 + gdrom_error_t status = linux_read_disc_toc( disc );5.96 + if( status != 0 ) {5.97 + free(disc);5.98 + if( status == 0xFFFF ) {5.99 + ERROR("Unable to load disc table of contents (%s)", strerror(errno));5.100 + } else {5.101 + ERROR("Unable to load disc table of contents (sense %d,%d)",5.102 + status &0xFF, status >> 8 );5.103 + }5.104 + return NULL;5.105 + }5.106 + disc->read_sectors = linux_read_sectors;5.107 + disc->disc_type = IDE_DISC_CDROM;5.108 + return disc;5.109 +}5.110 +5.111 +/**5.112 + * Read the full table of contents into the disc from the device.5.113 + */5.114 +static gdrom_error_t linux_read_disc_toc( gdrom_disc_t disc )5.115 +{5.116 + int fd = fileno(disc->file);5.117 + unsigned char buf[MAXTOCSIZE];5.118 + char cmd[12] = { 0x43, 0, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0 };5.119 +5.120 + cmd[7] = (sizeof(buf))>>8;5.121 + cmd[8] = (sizeof(buf))&0xFF;5.122 + memset( buf, 0, sizeof(buf) );5.123 + gdrom_error_t status = linux_send_command( fd, cmd, buf, sizeof(buf), CGC_DATA_READ );5.124 + if( status != 0 ) {5.125 + return status;5.126 + }5.127 +5.128 + int max_track = 0;5.129 + int last_track = -1;5.130 + int leadout = -1;5.131 + int len = (buf[0] << 8) | buf[1];5.132 + int session_type = GDROM_MODE1;5.133 + int i;5.134 + for( i = 4; i<len; i+=11 ) {5.135 + int session = buf[i];5.136 + int adr = buf[i+1] >> 4;5.137 + int point = buf[i+3];5.138 + if( adr == 0x01 && point > 0 && point < 100 ) {5.139 + /* Track info */5.140 + int trackno = point-1;5.141 + if( point > max_track ) {5.142 + max_track = point;5.143 + }5.144 + disc->track[trackno].flags = (buf[i+1] & 0x0F) << 4;5.145 + disc->track[trackno].session = session - 1;5.146 + disc->track[trackno].lba = MSFTOLBA(buf[i+8],buf[i+9],buf[i+10]);5.147 + if( disc->track[trackno].flags & TRACK_DATA ) {5.148 + disc->track[trackno].mode = GDROM_MODE1;5.149 + } else {5.150 + disc->track[trackno].mode = GDROM_CDDA;5.151 + }5.152 + if( last_track != -1 ) {5.153 + disc->track[last_track].sector_count = disc->track[trackno].lba -5.154 + disc->track[last_track].lba;5.155 + }5.156 + last_track = trackno;5.157 + } else switch( (adr << 8) | point ) {5.158 + case 0x1A0: /* session info */5.159 + if( buf[i+9] == 0x20 ) {5.160 + session_type = GDROM_MODE2;5.161 + } else {5.162 + session_type = GDROM_MODE1;5.163 + }5.164 + case 0x1A2: /* leadout */5.165 + leadout = MSFTOLBA(buf[i+8], buf[i+9], buf[i+10]);5.166 + break;5.167 + }5.168 + }5.169 + disc->track_count = max_track;5.170 +5.171 + if( leadout != -1 && last_track != -1 ) {5.172 + disc->track[last_track].sector_count = leadout - disc->track[last_track].lba;5.173 + }5.174 + return 0;5.175 +}5.176 +5.177 +static gdrom_error_t linux_read_sectors_ioctl( gdrom_disc_t disc, uint32_t sector,5.178 + uint32_t sector_count, int mode, char *buf,5.179 + uint32_t *length )5.180 +{5.181 + int fd = fileno(disc->file);5.182 + int call;5.183 + struct cdrom_read read;5.184 + read.cdread_lba = LBATOMSF(sector);5.185 + read.cdread_bufaddr = buf;5.186 + switch(mode) {5.187 + case GDROM_MODE1:5.188 + call = CDROMREADMODE1;5.189 + read.cdread_buflen = sector_count * 2048;5.190 + break;5.191 + case GDROM_MODE2:5.192 + call = CDROMREADMODE2;5.193 + read.cdread_buflen = sector_count * 2336;5.194 + break;5.195 + default:5.196 + return PKT_ERR_BADREADMODE;5.197 + }5.198 +5.199 + if( ioctl( fd, call, &read ) == -1 ) {5.200 + ERROR( "Error reading disc (%s)", strerror(errno) );5.201 + return PKT_ERR_BADREAD;5.202 + }5.203 + *length = read.cdread_buflen;5.204 + return PKT_ERR_OK;5.205 +}5.206 +5.207 +static gdrom_error_t linux_read_sectors( gdrom_disc_t disc, uint32_t sector,5.208 + uint32_t sector_count, int mode, char *buf,5.209 + uint32_t *length )5.210 +{5.211 + int fd = fileno(disc->file);5.212 + uint32_t real_sector = sector - CD_MSF_OFFSET;5.213 + int buflen = sector_count * 2048;5.214 + char cmd[12] = { 0xBE, 0x10, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 };5.215 + cmd[2] = (real_sector >> 24) & 0xFF;5.216 + cmd[3] = (real_sector >> 16) & 0xFF;5.217 + cmd[4] = (real_sector >> 8) & 0xFF;5.218 + cmd[5] = real_sector & 0xFF;5.219 + cmd[6] = (sector_count >> 16) & 0xFF;5.220 + cmd[7] = (sector_count >> 8) & 0xFF;5.221 + cmd[8] = sector_count & 0xFF;5.222 + cmd[9] = 0x10;5.223 +5.224 + gdrom_error_t status = linux_send_command( fd, cmd, buf, buflen, CGC_DATA_READ );5.225 + if( status == 0 ) {5.226 + *length = buflen;5.227 + }5.228 + return status;5.229 +}5.230 +5.231 +/**5.232 + * Send a packet command to the device and wait for a response.5.233 + * @return 0 on success, -1 on an operating system error, or a sense error5.234 + * code on a device error.5.235 + */5.236 +static gdrom_error_t linux_send_command( int fd, char *cmd, char *buffer, size_t buflen,5.237 + int direction )5.238 +{5.239 + struct request_sense sense;5.240 + struct cdrom_generic_command cgc;5.241 +5.242 + memset( &cgc, 0, sizeof(cgc) );5.243 + memset( &sense, 0, sizeof(sense) );5.244 + memcpy( cgc.cmd, cmd, 12 );5.245 + cgc.buffer = buffer;5.246 + cgc.buflen = buflen;5.247 + cgc.sense = &sense;5.248 + cgc.data_direction = direction;5.249 +5.250 + if( ioctl(fd, CDROM_SEND_PACKET, &cgc) == -1 ) {5.251 + if( sense.sense_key == 0 ) {5.252 + return -1;5.253 + } else {5.254 + return sense.sense_key | (sense.asc<<8);5.255 + }5.256 + } else {5.257 + return 0;5.258 + }5.259 +}
.