Blame lib/driver/aix.c

Packit dd8086
/*
Packit dd8086
  Copyright (C) 2004-2006, 2008, 2010, 2011-2013, 2017
Packit dd8086
  Rocky Bernstein <rocky@gnu.org>
Packit dd8086
Packit dd8086
  This program is free software: you can redistribute it and/or modify
Packit dd8086
  it under the terms of the GNU General Public License as published by
Packit dd8086
  the Free Software Foundation, either version 3 of the License, or
Packit dd8086
  (at your option) any later version.
Packit dd8086
Packit dd8086
  This program is distributed in the hope that it will be useful,
Packit dd8086
  but WITHOUT ANY WARRANTY; without even the implied warranty of
Packit dd8086
  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
Packit dd8086
  GNU General Public License for more details.
Packit dd8086
Packit dd8086
  You should have received a copy of the GNU General Public License
Packit dd8086
  along with this program.  If not, see <http://www.gnu.org/licenses/>.
Packit dd8086
*/
Packit dd8086

Packit dd8086
#ifdef HAVE_CONFIG_H
Packit dd8086
# include "config.h"
Packit dd8086
#endif
Packit dd8086
Packit dd8086
#ifdef HAVE_STDBOOL_H
Packit dd8086
# include <stdbool.h>
Packit dd8086
#endif
Packit dd8086
Packit dd8086
#ifdef HAVE_STRING_H
Packit dd8086
#include <string.h>
Packit dd8086
#endif
Packit dd8086
Packit dd8086
#include <cdio/logging.h>
Packit dd8086
#include <cdio/sector.h>
Packit dd8086
#include <cdio/util.h>
Packit dd8086
#include <cdio/mmc.h>
Packit dd8086
#include "cdio_assert.h"
Packit dd8086
#include "cdio_private.h"
Packit dd8086
Packit dd8086
#define DEFAULT_CDIO_DEVICE "/dev/rcd0"
Packit dd8086
Packit dd8086
#ifdef HAVE_AIX_CDROM
Packit dd8086
Packit dd8086
#ifdef HAVE_GLOB_H
Packit dd8086
#include <glob.h>
Packit dd8086
#endif
Packit dd8086
Packit dd8086
#include <stdio.h>
Packit dd8086
#include <stdlib.h>
Packit dd8086
#include <errno.h>
Packit dd8086
#include <unistd.h>
Packit dd8086
#include <fcntl.h>
Packit dd8086
Packit dd8086
#include <sys/scsi.h>
Packit dd8086
Packit dd8086
#include <sys/stat.h>
Packit dd8086
#include <sys/types.h>
Packit dd8086
#include <sys/ioctl.h>
Packit dd8086
#include <sys/devinfo.h>
Packit dd8086
#include <sys/ide.h>
Packit dd8086
#include <sys/idecdrom.h>
Packit dd8086
#include <sys/scdisk.h>
Packit dd8086
#include "cdtext_private.h"
Packit dd8086
Packit dd8086
typedef struct _TRACK_DATA {
Packit dd8086
    uchar Format;
Packit dd8086
    uchar Control : 4;
Packit dd8086
    uchar Adr : 4;
Packit dd8086
    uchar TrackNumber;
Packit dd8086
    uchar Reserved1;
Packit dd8086
    uchar Address[4];
Packit dd8086
} TRACK_DATA, *PTRACK_DATA;
Packit dd8086
Packit dd8086
typedef struct _CDROM_TOC {
Packit dd8086
    uchar Length[2];
Packit dd8086
    uchar FirstTrack;
Packit dd8086
    uchar LastTrack;
Packit dd8086
    TRACK_DATA TrackData[CDIO_CD_MAX_TRACKS+1];
Packit dd8086
} CDROM_TOC, *PCDROM_TOC;
Packit dd8086
Packit dd8086
Packit dd8086
typedef struct _TRACK_DATA_FULL {
Packit dd8086
    uchar SessionNumber;
Packit dd8086
    uchar Control : 4;
Packit dd8086
    uchar Adr : 4;
Packit dd8086
    uchar TNO;
Packit dd8086
    uchar POINT;  /* Tracknumber (of session?) or lead-out/in (0xA0, 0xA1, 0xA2)  */
Packit dd8086
    uchar Min;  /* Only valid if disctype is CDDA ? */
Packit dd8086
    uchar Sec;  /* Only valid if disctype is CDDA ? */
Packit dd8086
    uchar Frame;  /* Only valid if disctype is CDDA ? */
Packit dd8086
    uchar Zero;  /* Always zero */
Packit dd8086
    uchar PMIN;  /* start min, if POINT is a track; if lead-out/in 0xA0: First Track */
Packit dd8086
    uchar PSEC;
Packit dd8086
    uchar PFRAME;
Packit dd8086
} TRACK_DATA_FULL, *PTRACK_DATA_FULL;
Packit dd8086
Packit dd8086
typedef struct _CDROM_TOC_FULL {
Packit dd8086
    uchar Length[2];
Packit dd8086
    uchar FirstSession;
Packit dd8086
    uchar LastSession;
Packit dd8086
    TRACK_DATA_FULL TrackData[CDIO_CD_MAX_TRACKS+3];
Packit dd8086
} CDROM_TOC_FULL, *PCDROM_TOC_FULL;
Packit dd8086
Packit dd8086
Packit dd8086
/* reader */
Packit dd8086
Packit dd8086
typedef  enum {
Packit dd8086
    _AM_NONE,
Packit dd8086
    _AM_CTRL_SCSI
Packit dd8086
} access_mode_t;
Packit dd8086
Packit dd8086
Packit dd8086
typedef struct {
Packit dd8086
  lsn_t          start_lsn;
Packit dd8086
  uchar          Control : 4;
Packit dd8086
  uchar          Format;
Packit dd8086
} track_info_t;
Packit dd8086
Packit dd8086
typedef struct {
Packit dd8086
  /* Things common to all drivers like this.
Packit dd8086
     This must be first. */
Packit dd8086
  generic_img_private_t gen;
Packit dd8086
Packit dd8086
  access_mode_t access_mode;
Packit dd8086
Packit dd8086
  /* Some of the more OS specific things. */
Packit dd8086
  /* Entry info for each track, add 1 for leadout. */
Packit dd8086
  track_info_t tocent[CDIO_CD_MAX_TRACKS+1];
Packit dd8086
Packit dd8086
} _img_private_t;
Packit dd8086
Packit dd8086
static track_format_t get_track_format_aix(void *p_user_data,
Packit dd8086
                                               track_t i_track);
Packit dd8086
Packit dd8086
static access_mode_t
Packit dd8086
str_to_access_mode_aix(const char *psz_access_mode)
Packit dd8086
{
Packit dd8086
  const access_mode_t default_access_mode = _AM_CTRL_SCSI;
Packit dd8086
Packit dd8086
  if (NULL==psz_access_mode) return default_access_mode;
Packit dd8086
Packit dd8086
  if (!strcmp(psz_access_mode, "SCSI"))
Packit dd8086
    return _AM_CTRL_SCSI;
Packit dd8086
  else {
Packit dd8086
    cdio_warn ("unknown access type: %s. Default SCSI used.",
Packit dd8086
               psz_access_mode);
Packit dd8086
    return default_access_mode;
Packit dd8086
  }
Packit dd8086
}
Packit dd8086
Packit dd8086
Packit dd8086
/*!
Packit dd8086
  Initialize CD device.
Packit dd8086
 */
Packit dd8086
static bool
Packit dd8086
init_aix (_img_private_t *p_env)
Packit dd8086
{
Packit dd8086
Packit dd8086
  if (p_env->gen.init) {
Packit dd8086
    cdio_warn ("init called more than once");
Packit dd8086
    return false;
Packit dd8086
  }
Packit dd8086
Packit dd8086
  p_env->gen.fd = openx (p_env->gen.source_name, O_RDONLY, NULL,
Packit dd8086
                         SC_DIAGNOSTIC);
Packit dd8086
Packit dd8086
  /*p_env->gen.fd = openx (p_env->gen.source_name, O_RDONLY, NULL,
Packit dd8086
    IDE_SINGLE);*/
Packit dd8086
Packit dd8086
  if (p_env->gen.fd < 0)
Packit dd8086
    {
Packit dd8086
      cdio_warn ("open (%s): %s", p_env->gen.source_name, strerror (errno));
Packit dd8086
      return false;
Packit dd8086
    }
Packit dd8086
Packit dd8086
  p_env->gen.init = true;
Packit dd8086
  p_env->gen.toc_init = false;
Packit dd8086
  p_env->gen.u_joliet_level = 0;  /* Assume no Joliet extensions initally */
Packit dd8086
  p_env->access_mode = _AM_CTRL_SCSI;
Packit dd8086
Packit dd8086
  return true;
Packit dd8086
}
Packit dd8086
Packit dd8086
/*!
Packit dd8086
  Run a SCSI MMC command.
Packit dd8086
Packit dd8086
  p_user_data   internal CD structure.
Packit dd8086
  i_timeout_ms   time in milliseconds we will wait for the command
Packit dd8086
                to complete.
Packit dd8086
  i_cdb         Size of p_cdb
Packit dd8086
  p_cdb         CDB bytes.
Packit dd8086
  e_direction   direction the transfer is to go.
Packit dd8086
  i_buf         Size of buffer
Packit dd8086
  p_buf         Buffer for data, both sending and receiving
Packit dd8086
 */
Packit dd8086
static driver_return_code_t
Packit dd8086
run_mmc_cmd_aix( void *p_user_data, unsigned int i_timeout_ms,
Packit dd8086
                 unsigned int i_cdb, const mmc_cdb_t *p_cdb,
Packit dd8086
                 cdio_mmc_direction_t e_direction,
Packit dd8086
                 unsigned int i_buf, /*in/out*/ void *p_buf )
Packit dd8086
{
Packit dd8086
  const _img_private_t *p_env = p_user_data;
Packit dd8086
  struct sc_passthru cgc;
Packit dd8086
  int i_rc;
Packit dd8086
Packit dd8086
  memset (&cgc, 0, sizeof (cgc));
Packit dd8086
  memcpy(cgc.scsi_cdb,  p_cdb, sizeof(mmc_cdb_t));
Packit dd8086
Packit dd8086
#ifdef AIX_DISABLE_ASYNC
Packit dd8086
        /* This enables synchronous negotiation mode.  Some CD-ROM drives
Packit dd8086
         * don't handle this well.
Packit dd8086
         */
Packit dd8086
  cgc.flags = 0;
Packit dd8086
#else
Packit dd8086
  cgc.flags = SC_ASYNC;
Packit dd8086
#endif
Packit dd8086
Packit dd8086
  if (0 != i_buf)
Packit dd8086
    cgc.flags     |= MMC_DATA_READ == e_direction ? B_READ : B_WRITE;
Packit dd8086
Packit dd8086
  cgc.timeout_value = msecs2secs(i_timeout_ms);
Packit dd8086
  cgc.buffer        = p_buf;
Packit dd8086
  cgc.data_length   = i_buf;
Packit dd8086
  cgc.command_length= i_cdb;
Packit dd8086
Packit dd8086
  i_rc = ioctl(p_env->gen.fd, DK_PASSTHRU, &cgc);
Packit dd8086
  if (-1 == i_rc) {
Packit dd8086
    cdio_warn("DKIOCMD error: %s", strerror(errno));
Packit dd8086
  }
Packit dd8086
  return i_rc;
Packit dd8086
}
Packit dd8086
Packit dd8086
/*!
Packit dd8086
   Reads audio sectors from CD device into data starting from lsn.
Packit dd8086
   Returns 0 if no error.
Packit dd8086
Packit dd8086
   May have to check size of nblocks. There may be a limit that
Packit dd8086
   can be read in one go, e.g. 25 blocks.
Packit dd8086
*/
Packit dd8086
Packit dd8086
static driver_return_code_t
Packit dd8086
_read_audio_sectors_aix (void *p_user_data, void *data, lsn_t lsn,
Packit dd8086
                          unsigned int nblocks)
Packit dd8086
{
Packit dd8086
  char buf[CDIO_CD_FRAMESIZE_RAW] = { 0, };
Packit dd8086
Packit dd8086
#ifdef FINISHED
Packit dd8086
  struct cdrom_msf *msf = (struct cdrom_msf *) &buf;
Packit dd8086
  msf_t _msf;
Packit dd8086
  struct cdrom_cdda cdda;
Packit dd8086
Packit dd8086
  _img_private_t *env = p_user_data;
Packit dd8086
Packit dd8086
  cdio_lba_to_msf (cdio_lsn_to_lba(lsn), &_msf);
Packit dd8086
  msf->cdmsf_min0   = from_bcd8(_msf.m);
Packit dd8086
  msf->cdmsf_sec0   = from_bcd8(_msf.s);
Packit dd8086
  msf->cdmsf_frame0 = from_bcd8(_msf.f);
Packit dd8086
Packit dd8086
  if (env->gen.ioctls_debugged == 75)
Packit dd8086
    cdio_debug ("only displaying every 75th ioctl from now on");
Packit dd8086
Packit dd8086
  if (env->gen.ioctls_debugged == 30 * 75)
Packit dd8086
    cdio_debug ("only displaying every 30*75th ioctl from now on");
Packit dd8086
Packit dd8086
  if (env->gen.ioctls_debugged < 75
Packit dd8086
      || (env->gen.ioctls_debugged < (30 * 75)
Packit dd8086
          && env->gen.ioctls_debugged % 75 == 0)
Packit dd8086
      || env->gen.ioctls_debugged % (30 * 75) == 0)
Packit dd8086
    cdio_debug ("reading %d", lsn);
Packit dd8086
Packit dd8086
  env->gen.ioctls_debugged++;
Packit dd8086
Packit dd8086
  cdda.cdda_addr   = lsn;
Packit dd8086
  cdda.cdda_length = nblocks;
Packit dd8086
  cdda.cdda_data   = (caddr_t) data;
Packit dd8086
  if (ioctl (env->gen.fd, CDROMCDDA, &cdda) == -1) {
Packit dd8086
    perror ("ioctl(..,CDROMCDDA,..)");
Packit dd8086
        return 1;
Packit dd8086
        /* exit (EXIT_FAILURE); */
Packit dd8086
  }
Packit dd8086
#endif
Packit dd8086
  memcpy (data, buf, CDIO_CD_FRAMESIZE_RAW);
Packit dd8086
Packit dd8086
  return 0;
Packit dd8086
}
Packit dd8086
Packit dd8086
/*!
Packit dd8086
   Reads a single mode1 sector from cd device into data starting
Packit dd8086
   from lsn. Returns 0 if no error.
Packit dd8086
 */
Packit dd8086
static driver_return_code_t
Packit dd8086
_read_mode1_sector_aix (void *env, void *data, lsn_t lsn,
Packit dd8086
                            bool b_form2)
Packit dd8086
{
Packit dd8086
Packit dd8086
#if FIXED
Packit dd8086
  do something here.
Packit dd8086
#else
Packit dd8086
  return cdio_generic_read_form1_sector(env, data, lsn);
Packit dd8086
#endif
Packit dd8086
}
Packit dd8086
Packit dd8086
/*!
Packit dd8086
   Reads nblocks of mode2 sectors from cd device into data starting
Packit dd8086
   from lsn.
Packit dd8086
   Returns 0 if no error.
Packit dd8086
 */
Packit dd8086
static driver_return_code_t
Packit dd8086
_read_mode1_sectors_aix (void *p_user_data, void *p_data, lsn_t lsn,
Packit dd8086
                             bool b_form2, unsigned int nblocks)
Packit dd8086
{
Packit dd8086
  _img_private_t *p_env = p_user_data;
Packit dd8086
  unsigned int i;
Packit dd8086
  int retval;
Packit dd8086
  unsigned int blocksize = b_form2 ? M2RAW_SECTOR_SIZE : CDIO_CD_FRAMESIZE;
Packit dd8086
Packit dd8086
  for (i = 0; i < nblocks; i++) {
Packit dd8086
    if ( (retval = _read_mode1_sector_aix (p_env,
Packit dd8086
                                            ((char *)p_data) + (blocksize * i),
Packit dd8086
                                               lsn + i, b_form2)) )
Packit dd8086
      return retval;
Packit dd8086
  }
Packit dd8086
  return 0;
Packit dd8086
}
Packit dd8086
Packit dd8086
/*!
Packit dd8086
   Reads a single mode2 sector from cd device into data starting from lsn.
Packit dd8086
   Returns 0 if no error.
Packit dd8086
 */
Packit dd8086
static driver_return_code_t
Packit dd8086
_read_mode2_sector_aix (void *p_user_data, void *p_data, lsn_t lsn,
Packit dd8086
                            bool b_form2)
Packit dd8086
{
Packit dd8086
  char buf[CDIO_CD_FRAMESIZE_RAW] = { 0, };
Packit dd8086
  int offset = 0;
Packit dd8086
#ifdef FINISHED
Packit dd8086
  struct cdrom_msf *msf = (struct cdrom_msf *) &buf;
Packit dd8086
  msf_t _msf;
Packit dd8086
  struct cdrom_cdxa cd_read;
Packit dd8086
Packit dd8086
  _img_private_t *p_env = p_user_data;
Packit dd8086
Packit dd8086
  cdio_lba_to_msf (cdio_lsn_to_lba(lsn), &_msf);
Packit dd8086
  msf->cdmsf_min0 = from_bcd8(_msf.m);
Packit dd8086
  msf->cdmsf_sec0 = from_bcd8(_msf.s);
Packit dd8086
  msf->cdmsf_frame0 = from_bcd8(_msf.f);
Packit dd8086
Packit dd8086
  if (p_env->gen.ioctls_debugged == 75)
Packit dd8086
    cdio_debug ("only displaying every 75th ioctl from now on");
Packit dd8086
Packit dd8086
  if (p_env->gen.ioctls_debugged == 30 * 75)
Packit dd8086
    cdio_debug ("only displaying every 30*75th ioctl from now on");
Packit dd8086
Packit dd8086
  if (p_env->gen.ioctls_debugged < 75
Packit dd8086
      || (p_env->gen.ioctls_debugged < (30 * 75)
Packit dd8086
          && p_env->gen.ioctls_debugged % 75 == 0)
Packit dd8086
      || p_env->gen.ioctls_debugged % (30 * 75) == 0)
Packit dd8086
    cdio_debug ("reading %2.2d:%2.2d:%2.2d",
Packit dd8086
               msf->cdmsf_min0, msf->cdmsf_sec0, msf->cdmsf_frame0);
Packit dd8086
Packit dd8086
  p_env->gen.ioctls_debugged++;
Packit dd8086
Packit dd8086
  /* Using CDROMXA ioctl will actually use the same uscsi command
Packit dd8086
   * as ATAPI, except we don't need to be root
Packit dd8086
   */
Packit dd8086
  offset = CDIO_CD_XA_SYNC_HEADER;
Packit dd8086
  cd_read.cdxa_addr = lsn;
Packit dd8086
  cd_read.cdxa_data = buf;
Packit dd8086
  cd_read.cdxa_length = 1;
Packit dd8086
  cd_read.cdxa_format = CDROM_XA_SECTOR_DATA;
Packit dd8086
Packit dd8086
  if (ioctl (p_env->gen.fd, CDROMCDXA, &cd_read) == -1) {
Packit dd8086
    perror ("ioctl(..,CDROMCDXA,..)");
Packit dd8086
    return 1;
Packit dd8086
    /* exit (EXIT_FAILURE); */
Packit dd8086
  }
Packit dd8086
#endif
Packit dd8086
Packit dd8086
  if (b_form2)
Packit dd8086
    memcpy (p_data, buf + (offset-CDIO_CD_SUBHEADER_SIZE), M2RAW_SECTOR_SIZE);
Packit dd8086
  else
Packit dd8086
    memcpy (((char *)p_data), buf + offset, CDIO_CD_FRAMESIZE);
Packit dd8086
Packit dd8086
  return 0;
Packit dd8086
}
Packit dd8086
Packit dd8086
/*!
Packit dd8086
   Reads nblocks of mode2 sectors from cd device into data starting
Packit dd8086
   from lsn.
Packit dd8086
   Returns 0 if no error.
Packit dd8086
 */
Packit dd8086
static driver_return_code_t
Packit dd8086
_read_mode2_sectors_aix (void *p_user_data, void *data, lsn_t lsn,
Packit dd8086
                             bool b_form2, unsigned int nblocks)
Packit dd8086
{
Packit dd8086
  _img_private_t *env = p_user_data;
Packit dd8086
  unsigned int i;
Packit dd8086
  int retval;
Packit dd8086
  unsigned int blocksize = b_form2 ? M2RAW_SECTOR_SIZE : CDIO_CD_FRAMESIZE;
Packit dd8086
Packit dd8086
  for (i = 0; i < nblocks; i++) {
Packit dd8086
    if ( (retval = _read_mode2_sector_aix (env,
Packit dd8086
                                            ((char *)data) + (blocksize * i),
Packit dd8086
                                               lsn + i, b_form2)) )
Packit dd8086
      return retval;
Packit dd8086
  }
Packit dd8086
  return 0;
Packit dd8086
}
Packit dd8086
Packit dd8086
Packit dd8086
/*!
Packit dd8086
   Return the size of the CD in logical block address (LBA) units.
Packit dd8086
 */
Packit dd8086
static lsn_t
Packit dd8086
get_disc_last_lsn_aix (void *p_user_data)
Packit dd8086
{
Packit dd8086
  uint32_t i_size=0;
Packit dd8086
#ifdef FINISHED
Packit dd8086
  _img_private_t *env = p_user_data;
Packit dd8086
Packit dd8086
  struct cdrom_tocentry tocent;
Packit dd8086
Packit dd8086
  tocent.cdte_track  = CDIO_CDROM_LEADOUT_TRACK;
Packit dd8086
  tocent.cdte_format = CDIO_CDROM_LBA;
Packit dd8086
  if (ioctl (env->gen.fd, CDROMREADTOCENTRY, &tocent) == -1)
Packit dd8086
    {
Packit dd8086
      perror ("ioctl(CDROMREADTOCENTRY)");
Packit dd8086
      exit (EXIT_FAILURE);
Packit dd8086
    }
Packit dd8086
Packit dd8086
  i_size = tocent.cdte_addr.lba;
Packit dd8086
#endif
Packit dd8086
Packit dd8086
  return i_size;
Packit dd8086
}
Packit dd8086
Packit dd8086
/*!
Packit dd8086
  Set the arg "key" with "value" in the source device.
Packit dd8086
  Currently "source" and "access-mode" are valid keys.
Packit dd8086
  "source" sets the source device in I/O operations
Packit dd8086
  "access-mode" sets the the method of CD access
Packit dd8086
Packit dd8086
  0 is returned if no error was found, and nonzero if there as an error.
Packit dd8086
*/
Packit dd8086
static driver_return_code_t
Packit dd8086
_set_arg_aix (void *p_user_data, const char key[], const char value[])
Packit dd8086
{
Packit dd8086
  _img_private_t *p_env = p_user_data;
Packit dd8086
Packit dd8086
  if (!strcmp (key, "source"))
Packit dd8086
    {
Packit dd8086
      if (!value) return DRIVER_OP_ERROR;
Packit dd8086
      free (p_env->gen.source_name);
Packit dd8086
      p_env->gen.source_name = strdup (value);
Packit dd8086
    }
Packit dd8086
  else if (!strcmp (key, "access-mode"))
Packit dd8086
    {
Packit dd8086
      p_env->access_mode = str_to_access_mode_aix(key);
Packit dd8086
    }
Packit dd8086
  else return DRIVER_OP_ERROR;
Packit dd8086
Packit dd8086
  return DRIVER_OP_SUCCESS;
Packit dd8086
}
Packit dd8086
Packit dd8086
/*
Packit dd8086
 * aixioc_send
Packit dd8086
        Issue ioctl command.
Packit dd8086
Packit dd8086
  Args:
Packit dd8086
    p_env - environment
Packit dd8086
    cmd - ioctl command
Packit dd8086
    arg - ioctl argument
Packit dd8086
    b_print_err - whether an error message is to be displayed if the
Packit dd8086
    ioctl fails
Packit dd8086
Packit dd8086
  Return:
Packit dd8086
    true/false - ioctl successful
Packit dd8086
*/
Packit dd8086
static bool
Packit dd8086
aixioc_send(_img_private_t *p_env, int cmd, void *arg, bool b_print_err)
Packit dd8086
{
Packit dd8086
  struct cd_audio_cmd   *ac;
Packit dd8086
Packit dd8086
  if (p_env->gen.fd < 0)
Packit dd8086
    return false;
Packit dd8086
Packit dd8086
  if (cmd == DKAUDIO) {
Packit dd8086
    ac = (struct cd_audio_cmd *) arg;
Packit dd8086
    ac->status = 0;     /* Nuke status for audio cmds */
Packit dd8086
  }
Packit dd8086
Packit dd8086
  if (ioctl(p_env->gen.fd, cmd, arg) < 0) {
Packit dd8086
    if (b_print_err) {
Packit dd8086
      cdio_warn("errno=%d (%s)",  errno, strerror(errno));
Packit dd8086
    }
Packit dd8086
    return false;
Packit dd8086
  }
Packit dd8086
  return true;
Packit dd8086
}
Packit dd8086
Packit dd8086
/*!
Packit dd8086
  Read and cache the CD's Track Table of Contents and track info.
Packit dd8086
  via a SCSI MMC READ_TOC (FULTOC).  Return true if successful or
Packit dd8086
  false if an error.
Packit dd8086
*/
Packit dd8086
static bool
Packit dd8086
read_toc_ioctl_aix (void *p_user_data)
Packit dd8086
{
Packit dd8086
  _img_private_t *p_env = p_user_data;
Packit dd8086
  struct cd_audio_cmd   cmdbuf;
Packit dd8086
  int i;
Packit dd8086
Packit dd8086
  cmdbuf.msf_flag = false;
Packit dd8086
  cmdbuf.audio_cmds = CD_TRK_INFO_AUDIO;
Packit dd8086
  if (!aixioc_send(p_env, IDE_CDAUDIO, (void *) &cmdbuf, true))
Packit dd8086
    return false;
Packit dd8086
Packit dd8086
  p_env->gen.i_first_track = cmdbuf.indexing.track_index.first_track;
Packit dd8086
  p_env->gen.i_tracks      = ( cmdbuf.indexing.track_index.last_track
Packit dd8086
                               - p_env->gen.i_first_track ) + 1;
Packit dd8086
Packit dd8086
  /* Do it again to get the last MSF data */
Packit dd8086
  cmdbuf.msf_flag = true;
Packit dd8086
  if (!aixioc_send(p_env, IDE_CDAUDIO, (void *) &cmdbuf, true))
Packit dd8086
    return false;
Packit dd8086
Packit dd8086
  cmdbuf.audio_cmds = CD_GET_TRK_MSF;
Packit dd8086
Packit dd8086
  for (i = 0; i <= p_env->gen.i_tracks; i++) {
Packit dd8086
    int i_track = i + p_env->gen.i_first_track;
Packit dd8086
Packit dd8086
    /* Get the track info */
Packit dd8086
    cmdbuf.indexing.track_msf.track = i_track;
Packit dd8086
    if (!aixioc_send(p_env, IDE_CDAUDIO, (void *) &cmdbuf, TRUE))
Packit dd8086
      return false;
Packit dd8086
Packit dd8086
    p_env->tocent[ i_track ].start_lsn =
Packit dd8086
      cdio_msf3_to_lba(
Packit dd8086
                       cmdbuf.indexing.track_msf.mins,
Packit dd8086
                       cmdbuf.indexing.track_msf.secs,
Packit dd8086
                       cmdbuf.indexing.track_msf.frames );
Packit dd8086
  }
Packit dd8086
Packit dd8086
  return true;
Packit dd8086
}
Packit dd8086
Packit dd8086
/*!
Packit dd8086
  Read and cache the CD's Track Table of Contents and track info.
Packit dd8086
  via a SCSI MMC READ_TOC (FULTOC).  Return true if successful or
Packit dd8086
  false if an error.
Packit dd8086
*/
Packit dd8086
static bool
Packit dd8086
read_toc_aix (void *p_user_data)
Packit dd8086
{
Packit dd8086
  _img_private_t *p_env = p_user_data;
Packit dd8086
  mmc_cdb_t  cdb = {{0, }};
Packit dd8086
  CDROM_TOC_FULL  cdrom_toc_full;
Packit dd8086
  int             i_status, i, i_seen_flag;
Packit dd8086
  int             i_track_format = 0;
Packit dd8086
Packit dd8086
  /* Operation code */
Packit dd8086
  CDIO_MMC_SET_COMMAND(cdb.field, CDIO_MMC_GPCMD_READ_TOC);
Packit dd8086
Packit dd8086
  cdb.field[1] = 0x00;
Packit dd8086
Packit dd8086
  /* Format */
Packit dd8086
  cdb.field[2] = CDIO_MMC_READTOC_FMT_FULTOC;
Packit dd8086
Packit dd8086
  memset(&cdrom_toc_full, 0, sizeof(cdrom_toc_full));
Packit dd8086
Packit dd8086
  /* Setup to read header, to get length of data */
Packit dd8086
  CDIO_MMC_SET_READ_LENGTH16(cdb.field, sizeof(cdrom_toc_full));
Packit dd8086
Packit dd8086
  i_status = run_scsi_cmd_aix (p_env, 1000*60*3,
Packit dd8086
                               mmc_get_cmd_len(cdb.field[0]),
Packit dd8086
                               &cdb, MMC_DATA_READ,
Packit dd8086
                               sizeof(cdrom_toc_full), &cdrom_toc_full);
Packit dd8086
Packit dd8086
  if ( 0 != i_status ) {
Packit dd8086
    cdio_debug ("SCSI MMC READ_TOC failed\n");
Packit dd8086
    return read_toc_ioctl_aix(p_user_data);
Packit dd8086
  }
Packit dd8086
Packit dd8086
  i_seen_flag=0;
Packit dd8086
  for( i = 0 ; i <= CDIO_CD_MAX_TRACKS+3; i++ ) {
Packit dd8086
Packit dd8086
    if ( 0xA0 == cdrom_toc_full.TrackData[i].POINT ) {
Packit dd8086
      /* First track number */
Packit dd8086
      p_env->gen.i_first_track = cdrom_toc_full.TrackData[i].PMIN;
Packit dd8086
      i_track_format = cdrom_toc_full.TrackData[i].PSEC;
Packit dd8086
      i_seen_flag|=0x01;
Packit dd8086
    }
Packit dd8086
Packit dd8086
    if ( 0xA1 == cdrom_toc_full.TrackData[i].POINT ) {
Packit dd8086
      /* Last track number */
Packit dd8086
      p_env->gen.i_tracks =
Packit dd8086
        cdrom_toc_full.TrackData[i].PMIN - p_env->gen.i_first_track + 1;
Packit dd8086
      i_seen_flag|=0x02;
Packit dd8086
    }
Packit dd8086
Packit dd8086
    if ( 0xA2 == cdrom_toc_full.TrackData[i].POINT ) {
Packit dd8086
      /* Start position of the lead out */
Packit dd8086
      p_env->tocent[ p_env->gen.i_tracks ].start_lsn =
Packit dd8086
        cdio_msf3_to_lba(
Packit dd8086
                         cdrom_toc_full.TrackData[i].PMIN,
Packit dd8086
                         cdrom_toc_full.TrackData[i].PSEC,
Packit dd8086
                         cdrom_toc_full.TrackData[i].PFRAME );
Packit dd8086
      p_env->tocent[ p_env->gen.i_tracks ].Control
Packit dd8086
        = cdrom_toc_full.TrackData[i].Control;
Packit dd8086
      p_env->tocent[ p_env->gen.i_tracks ].Format  = i_track_format;
Packit dd8086
      i_seen_flag|=0x04;
Packit dd8086
    }
Packit dd8086
Packit dd8086
    if (cdrom_toc_full.TrackData[i].POINT > 0
Packit dd8086
        && cdrom_toc_full.TrackData[i].POINT <= p_env->gen.i_tracks) {
Packit dd8086
      p_env->tocent[ cdrom_toc_full.TrackData[i].POINT - 1 ].start_lsn =
Packit dd8086
        cdio_msf3_to_lba(
Packit dd8086
                         cdrom_toc_full.TrackData[i].PMIN,
Packit dd8086
                         cdrom_toc_full.TrackData[i].PSEC,
Packit dd8086
                         cdrom_toc_full.TrackData[i].PFRAME );
Packit dd8086
      p_env->tocent[ cdrom_toc_full.TrackData[i].POINT - 1 ].Control =
Packit dd8086
        cdrom_toc_full.TrackData[i].Control;
Packit dd8086
      p_env->tocent[ cdrom_toc_full.TrackData[i].POINT - 1 ].Format  =
Packit dd8086
        i_track_format;
Packit dd8086
Packit dd8086
      cdio_debug("p_sectors: %i, %lu", i,
Packit dd8086
                 (unsigned long int) (p_env->tocent[i].start_lsn));
Packit dd8086
Packit dd8086
      if (cdrom_toc_full.TrackData[i].POINT == p_env->gen.i_tracks)
Packit dd8086
        i_seen_flag|=0x08;
Packit dd8086
    }
Packit dd8086
Packit dd8086
    if ( 0x0F == i_seen_flag ) break;
Packit dd8086
  }
Packit dd8086
  if ( 0x0F == i_seen_flag ) {
Packit dd8086
    p_env->gen.toc_init = true;
Packit dd8086
    return true;
Packit dd8086
  }
Packit dd8086
  return false;
Packit dd8086
}
Packit dd8086
Packit dd8086
/*!
Packit dd8086
  Eject media in CD drive. If successful, as a side effect we
Packit dd8086
  also free obj.
Packit dd8086
 */
Packit dd8086
static driver_return_code_t
Packit dd8086
eject_media_aix (void *p_user_data) {
Packit dd8086
Packit dd8086
  _img_private_t *p_env = p_user_data;
Packit dd8086
  driver_return_code_t ret=DRIVER_OP_SUCCESS;
Packit dd8086
  int i_status;
Packit dd8086
Packit dd8086
  if (p_env->gen.fd <= -1) return DRIVER_OP_UNINIT;
Packit dd8086
  i_status = ioctl(p_env->gen.fd, DKEJECT);
Packit dd8086
  if ( i_status != 0) {
Packit dd8086
    cdio_generic_free((void *) p_env);
Packit dd8086
    cdio_warn ("DKEJECT failed: %s", strerror(errno));
Packit dd8086
    ret = DRIVER_OP_ERROR;
Packit dd8086
  }
Packit dd8086
  close(p_env->gen.fd);
Packit dd8086
  p_env->gen.fd = -1;
Packit dd8086
  return ret;
Packit dd8086
}
Packit dd8086
Packit dd8086
#if 0
Packit dd8086
static void *
Packit dd8086
_cdio_malloc_and_zero(size_t size) {
Packit dd8086
  void *ptr;
Packit dd8086
Packit dd8086
  if( !size ) size++;
Packit dd8086
Packit dd8086
  if((ptr = malloc(size)) == NULL) {
Packit dd8086
    cdio_warn("malloc() failed: %s", strerror(errno));
Packit dd8086
    return NULL;
Packit dd8086
  }
Packit dd8086
Packit dd8086
  memset(ptr, 0, size);
Packit dd8086
  return ptr;
Packit dd8086
}
Packit dd8086
#endif
Packit dd8086
Packit dd8086
static bool
Packit dd8086
is_mmc_supported(void *user_data)
Packit dd8086
{
Packit dd8086
    _img_private_t *env = user_data;
Packit dd8086
    return (_AM_NONE == env->access_mode) ? false : true;
Packit dd8086
}
Packit dd8086
Packit dd8086
/*!
Packit dd8086
  Return the value associated with the key "arg".
Packit dd8086
*/
Packit dd8086
static const char *
Packit dd8086
get_arg_aix (void *p_user_data, const char key[])
Packit dd8086
{
Packit dd8086
  _img_private_t *p_env = p_user_data;
Packit dd8086
Packit dd8086
  if (!strcmp (key, "source")) {
Packit dd8086
    return p_env->gen.source_name;
Packit dd8086
  } else if (!strcmp (key, "access-mode")) {
Packit dd8086
    switch (p_env->access_mode) {
Packit dd8086
    case _AM_CTRL_SCSI:
Packit dd8086
      return "SCSI";
Packit dd8086
    case _AM_NONE:
Packit dd8086
      return "no access method";
Packit dd8086
    }
Packit dd8086
  } else if (!strcmp (key, "mmc-supported?")) {
Packit dd8086
      return is_mmc_supported(env) ? "true" : "false";
Packit dd8086
  }
Packit dd8086
  return NULL;
Packit dd8086
}
Packit dd8086
Packit dd8086
/*!
Packit dd8086
  Return a string containing the default CD device if none is specified.
Packit dd8086
 */
Packit dd8086
char *
Packit dd8086
cdio_get_default_device_aix(void)
Packit dd8086
{
Packit dd8086
  return strdup(DEFAULT_CDIO_DEVICE);
Packit dd8086
}
Packit dd8086
Packit dd8086
/*!
Packit dd8086
  Get disc type associated with cd object.
Packit dd8086
*/
Packit dd8086
Packit dd8086
static discmode_t
Packit dd8086
get_discmode_aix (void *p_user_data)
Packit dd8086
{
Packit dd8086
  _img_private_t *p_env = p_user_data;
Packit dd8086
  struct mode_form_op media;
Packit dd8086
  int ret;
Packit dd8086
Packit dd8086
  memset(&media, 0, sizeof(media));
Packit dd8086
Packit dd8086
  /* Get the media info */
Packit dd8086
  media.action= CD_GET_MODE;
Packit dd8086
Packit dd8086
  if((ret = ioctl(p_env->gen.fd, DK_CD_MODE, &media)) != 0) {
Packit dd8086
     cdio_warn ("DK_CD_MODE failed: %s", strerror(errno));
Packit dd8086
         return CDIO_DISC_MODE_NO_INFO;
Packit dd8086
  }
Packit dd8086
  switch(media.cd_mode_form) {
Packit dd8086
  case CD_DA:
Packit dd8086
    return CDIO_DISC_MODE_CD_DA;
Packit dd8086
  case DVD_ROM:
Packit dd8086
    return CDIO_DISC_MODE_DVD_ROM;
Packit dd8086
  case DVD_RAM:
Packit dd8086
    return CDIO_DISC_MODE_DVD_RAM;
Packit dd8086
  case DVD_RW:
Packit dd8086
    return CDIO_DISC_MODE_DVD_RW;
Packit dd8086
  default: /* no valid match */
Packit dd8086
    return CDIO_DISC_MODE_NO_INFO;
Packit dd8086
  }
Packit dd8086
}
Packit dd8086
Packit dd8086
/*!
Packit dd8086
  Get format of track.
Packit dd8086
*/
Packit dd8086
static track_format_t
Packit dd8086
get_track_format_aix(void *p_user_data, track_t i_track)
Packit dd8086
{
Packit dd8086
  _img_private_t *p_env = p_user_data;
Packit dd8086
Packit dd8086
  if ( !p_env ) return TRACK_FORMAT_ERROR;
Packit dd8086
  if (!p_env->gen.init) init_aix(p_env);
Packit dd8086
  if (!p_env->gen.toc_init) read_toc_aix (p_user_data) ;
Packit dd8086
Packit dd8086
  if ( (i_track > p_env->gen.i_tracks+p_env->gen.i_first_track)
Packit dd8086
       || i_track < p_env->gen.i_first_track)
Packit dd8086
    return TRACK_FORMAT_ERROR;
Packit dd8086
Packit dd8086
  i_track -= p_env->gen.i_first_track;
Packit dd8086
Packit dd8086
#ifdef FINISHED
Packit dd8086
  /* This is pretty much copied from the "badly broken" cdrom_count_tracks
Packit dd8086
     in linux/cdrom.c.
Packit dd8086
   */
Packit dd8086
  if (p_env->tocent[i_track].cdte_ctrl & CDROM_DATA_TRACK) {
Packit dd8086
    if (p_env->tocent[i_track].cdte_format == CDIO_CDROM_CDI_TRACK)
Packit dd8086
      return TRACK_FORMAT_CDI;
Packit dd8086
    else if (p_env->tocent[i_track].cdte_format == CDIO_CDROM_XA_TRACK)
Packit dd8086
      return TRACK_FORMAT_XA;
Packit dd8086
    else
Packit dd8086
      return TRACK_FORMAT_DATA;
Packit dd8086
  } else
Packit dd8086
    return TRACK_FORMAT_AUDIO;
Packit dd8086
#else
Packit dd8086
  return TRACK_FORMAT_ERROR;
Packit dd8086
#endif
Packit dd8086
Packit dd8086
}
Packit dd8086
Packit dd8086
/*!
Packit dd8086
  Return true if we have XA data (green, mode2 form1) or
Packit dd8086
  XA data (green, mode2 form2). That is track begins:
Packit dd8086
  sync - header - subheader
Packit dd8086
  12     4      -  8
Packit dd8086
Packit dd8086
  FIXME: there's gotta be a better design for this and get_track_format?
Packit dd8086
*/
Packit dd8086
static bool
Packit dd8086
_cdio_get_track_green(void *p_user_data, track_t i_track)
Packit dd8086
{
Packit dd8086
  _img_private_t *p_env = p_user_data;
Packit dd8086
Packit dd8086
  if ( !p_env ) return false;
Packit dd8086
  if (!p_env->gen.init) init_aix(p_env);
Packit dd8086
  if (!p_env->gen.toc_init) read_toc_aix (p_env) ;
Packit dd8086
Packit dd8086
  if (i_track >= p_env->gen.i_tracks+p_env->gen.i_first_track
Packit dd8086
      || i_track < p_env->gen.i_first_track)
Packit dd8086
    return false;
Packit dd8086
Packit dd8086
  i_track -= p_env->gen.i_first_track;
Packit dd8086
Packit dd8086
  /* FIXME: Dunno if this is the right way, but it's what
Packit dd8086
     I was using in cd-info for a while.
Packit dd8086
   */
Packit dd8086
Packit dd8086
#ifdef FINISHED
Packit dd8086
  return ((p_env->tocent[i_track].cdte_ctrl & 2) != 0);
Packit dd8086
#else
Packit dd8086
  return false;
Packit dd8086
#endif
Packit dd8086
}
Packit dd8086
Packit dd8086
/*!
Packit dd8086
  Return the starting MSF (minutes/secs/frames) for track number
Packit dd8086
  track_num in obj.  Track numbers usually start at something
Packit dd8086
  greater than 0, usually 1.
Packit dd8086
Packit dd8086
  The "leadout" track is specified either by
Packit dd8086
  using track_num LEADOUT_TRACK or the total tracks+1.
Packit dd8086
  False is returned if there is no entry.
Packit dd8086
*/
Packit dd8086
static bool
Packit dd8086
_cdio_get_track_msf(void *p_user_data, track_t i_track, msf_t *msf)
Packit dd8086
{
Packit dd8086
  _img_private_t *p_env = p_user_data;
Packit dd8086
Packit dd8086
  if (NULL == msf) return false;
Packit dd8086
Packit dd8086
  if (!p_env->gen.init) init_aix(p_env);
Packit dd8086
  if (!p_env->gen.toc_init) read_toc_aix (p_env) ;
Packit dd8086
Packit dd8086
  if (i_track == CDIO_CDROM_LEADOUT_TRACK)
Packit dd8086
    i_track = p_env->gen.i_tracks + p_env->gen.i_first_track;
Packit dd8086
Packit dd8086
#ifdef FINISHED
Packit dd8086
  if (i_track > (p_env->gen.i_tracks+p_env->gen.i_first_track)
Packit dd8086
      || i_track < p_env->gen.i_first_track) {
Packit dd8086
    return false;
Packit dd8086
  } else {
Packit dd8086
    struct cdrom_tocentry *msf0 = &p_env->tocent[i_track-1];
Packit dd8086
    msf->m = to_bcd8(msf0->cdte_addr.msf.minute);
Packit dd8086
    msf->s = to_bcd8(msf0->cdte_addr.msf.second);
Packit dd8086
    msf->f = to_bcd8(msf0->cdte_addr.msf.frame);
Packit dd8086
    return true;
Packit dd8086
  }
Packit dd8086
#else
Packit dd8086
    return FALSE;
Packit dd8086
#endif
Packit dd8086
}
Packit dd8086
Packit dd8086
#else
Packit dd8086
/*!
Packit dd8086
  Return a string containing the default VCD device if none is specified.
Packit dd8086
 */
Packit dd8086
char *
Packit dd8086
cdio_get_default_device_aix(void)
Packit dd8086
{
Packit dd8086
  return strdup(DEFAULT_CDIO_DEVICE);
Packit dd8086
}
Packit dd8086
Packit dd8086
#endif /* HAVE_AIX_CDROM */
Packit dd8086
Packit dd8086
/*!
Packit dd8086
  Return an array of strings giving possible CD devices.
Packit dd8086
 */
Packit dd8086
char **
Packit dd8086
cdio_get_devices_aix (void)
Packit dd8086
{
Packit dd8086
#ifndef HAVE_AIX_CDROM
Packit dd8086
  return NULL;
Packit dd8086
#else
Packit dd8086
  struct stat st;
Packit dd8086
  char **drives = NULL;
Packit dd8086
  unsigned int i_files=0;
Packit dd8086
#ifdef HAVE_GLOB_H
Packit dd8086
  unsigned int i;
Packit dd8086
  glob_t globbuf;
Packit dd8086
Packit dd8086
  globbuf.gl_offs = 0;
Packit dd8086
  glob("/dev/rcd?", 0, NULL, &globbuf);
Packit dd8086
  for (i=0; i
Packit dd8086
    if(stat(globbuf.gl_pathv[i], &st) < 0)
Packit dd8086
      continue;
Packit dd8086
Packit dd8086
    /* Check if this is a block device; if so it's probably a AIX media */
Packit dd8086
    if(S_ISCHR(st.st_mode)) {
Packit dd8086
      cdio_add_device_list(&drives, globbuf.gl_pathv[i], &i_files);
Packit dd8086
    }
Packit dd8086
  }
Packit dd8086
  globfree(&globbuf);
Packit dd8086
#else
Packit dd8086
  char psz_device[30];
Packit dd8086
  for (i=0; i<9; i++) {
Packit dd8086
    sprintf(psz_device, "/dev/cd%d", i);
Packit dd8086
    if(stat(psz_device, &st) < 0)
Packit dd8086
      continue;
Packit dd8086
Packit dd8086
    /* Check if this is a block device; if so it's probably a AIX media */
Packit dd8086
    if(S_ISCHR(st.st_mode)) {
Packit dd8086
      cdio_add_device_list(&drives, psz_device, &i_files);
Packit dd8086
  }
Packit dd8086
#endif /*HAVE_GLOB_H*/
Packit dd8086
  cdio_add_device_list(&drives, NULL, &i_files);
Packit dd8086
  return drives;
Packit dd8086
#endif /*HAVE_AIX_CDROM*/
Packit dd8086
}
Packit dd8086
Packit dd8086
/*!
Packit dd8086
  Initialization routine. This is the only thing that doesn't
Packit dd8086
  get called via a function pointer. In fact *we* are the
Packit dd8086
  ones to set that up.
Packit dd8086
 */
Packit dd8086
CdIo_t *
Packit dd8086
cdio_open_aix (const char *psz_source_name)
Packit dd8086
{
Packit dd8086
  return cdio_open_am_aix(psz_source_name, NULL);
Packit dd8086
}
Packit dd8086
Packit dd8086
/*!
Packit dd8086
  Initialization routine. This is the only thing that doesn't
Packit dd8086
  get called via a function pointer. In fact *we* are the
Packit dd8086
  ones to set that up.
Packit dd8086
 */
Packit dd8086
CdIo_t *
Packit dd8086
cdio_open_am_aix (const char *psz_orig_source, const char *access_mode)
Packit dd8086
{
Packit dd8086
Packit dd8086
#ifdef HAVE_AIX_CDROM
Packit dd8086
  CdIo_t *ret;
Packit dd8086
  _img_private_t *_data;
Packit dd8086
  char *psz_source;
Packit dd8086
Packit dd8086
  cdio_funcs_t _funcs;
Packit dd8086
Packit dd8086
  _funcs.eject_media        = eject_media_aix;
Packit dd8086
  _funcs.free               = cdio_generic_free;
Packit dd8086
  _funcs.get_arg            = get_arg_aix;
Packit dd8086
  _funcs.get_cdtext         = get_cdtext_generic;
Packit dd8086
  _funcs.get_cdtext_raw     = read_cdtext_generic;
Packit dd8086
  _funcs.get_default_device = cdio_get_default_device_aix;
Packit dd8086
  _funcs.get_devices        = cdio_get_devices_aix;
Packit dd8086
  _funcs.get_disc_last_lsn  = get_disc_last_lsn_aix;
Packit dd8086
  _funcs.get_discmode       = get_discmode_aix;
Packit dd8086
  _funcs.get_drive_cap      = get_drive_cap_mmc;
Packit dd8086
  _funcs.get_first_track_num= get_first_track_num_generic;
Packit dd8086
  _funcs.get_hwinfo         = NULL;
Packit dd8086
  _funcs.get_mcn            = get_mcn_mmc,
Packit dd8086
  _funcs.get_num_tracks     = get_num_tracks_generic;
Packit dd8086
  _funcs.get_track_format   = get_track_format_aix;
Packit dd8086
  _funcs.get_track_green    = _cdio_get_track_green;
Packit dd8086
  _funcs.get_track_lba      = NULL; /* This could be implemented if need be. */
Packit dd8086
  _funcs.get_track_msf      = _cdio_get_track_msf;
Packit dd8086
  _funcs.get_track_isrc     = get_track_isrc_mmc;
Packit dd8086
  _funcs.lseek              = cdio_generic_lseek;
Packit dd8086
  _funcs.read               = cdio_generic_read;
Packit dd8086
  _funcs.read_audio_sectors = _read_audio_sectors_aix;
Packit dd8086
  _funcs.read_mode1_sector  = _read_mode1_sector_aix;
Packit dd8086
  _funcs.read_mode1_sectors = _read_mode1_sectors_aix;
Packit dd8086
  _funcs.read_mode2_sector  = _read_mode2_sector_aix;
Packit dd8086
  _funcs.read_mode2_sectors = _read_mode2_sectors_aix;
Packit dd8086
  _funcs.read_toc           = read_toc_aix;
Packit dd8086
  _funcs.run_mmc_cmd        = run_mmc_cmd_aix;
Packit dd8086
  _funcs.set_arg            = _set_arg_aix;
Packit dd8086
Packit dd8086
  _data                 = calloc (1, sizeof (_img_private_t));
Packit dd8086
Packit dd8086
  _data->access_mode    = _AM_CTRL_SCSI;
Packit dd8086
  _data->gen.init       = false;
Packit dd8086
  _data->gen.toc_init   = false;
Packit dd8086
  _data->gen.fd         = -1;
Packit dd8086
  _data->gen.b_cdtext_error = false;
Packit dd8086
Packit dd8086
  if (NULL == psz_orig_source) {
Packit dd8086
    psz_source = cdio_get_default_device_aix();
Packit dd8086
    if (NULL == psz_source) {
Packit dd8086
        free(_data);
Packit dd8086
        return NULL;
Packit dd8086
    }
Packit dd8086
    _set_arg_aix(_data, "source", psz_source);
Packit dd8086
    free(psz_source);
Packit dd8086
  } else {
Packit dd8086
    if (cdio_is_device_generic(psz_orig_source))
Packit dd8086
      _set_arg_aix(_data, "source", psz_orig_source);
Packit dd8086
    else {
Packit dd8086
      /* The below would be okay if all device drivers worked this way. */
Packit dd8086
#if 0
Packit dd8086
      cdio_info ("source %s is not a device", psz_orig_source);
Packit dd8086
#endif
Packit dd8086
      return NULL;
Packit dd8086
    }
Packit dd8086
  }
Packit dd8086
Packit dd8086
  ret = cdio_new ( (void *) _data, &_funcs );
Packit dd8086
  if (ret == NULL) return NULL;
Packit dd8086
Packit dd8086
  ret->driver_id = DRIVER_AIX;
Packit dd8086
Packit dd8086
  if (init_aix(_data))
Packit dd8086
    return ret;
Packit dd8086
  else {
Packit dd8086
    cdio_generic_free (_data);
Packit dd8086
    free(ret);
Packit dd8086
    return NULL;
Packit dd8086
  }
Packit dd8086
Packit dd8086
#else
Packit dd8086
  return NULL;
Packit dd8086
#endif /* HAVE_AIX_CDROM */
Packit dd8086
Packit dd8086
}
Packit dd8086
Packit dd8086
bool
Packit dd8086
cdio_have_aix (void)
Packit dd8086
{
Packit dd8086
#ifdef HAVE_AIX_CDROM
Packit dd8086
  return true;
Packit dd8086
#else
Packit dd8086
  return false;
Packit dd8086
#endif /* HAVE_AIX_CDROM */
Packit dd8086
}
Packit dd8086
Packit dd8086

Packit dd8086
/*
Packit dd8086
 * Local variables:
Packit dd8086
 *  c-file-style: "gnu"
Packit dd8086
 *  tab-width: 8
Packit dd8086
 *  indent-tabs-mode: nil
Packit dd8086
 * End:
Packit dd8086
 */