/*============================================================================*
 *============================================================================*
 * Component:           plextor-tool-applet
 * Filename:            scsi-functions.c
 *                                                                             
 * Authors:             Georg Huettenegger
 *                                                                             
 * Date of Creation:    Thu Aug 12 17:53:27 1999
 *                                                                             
 * Last Modification:   Thu Aug 12 17:53:27 1999
 *                                                                             
 * Copyright:           Georg Huettenegger                             
 *                                                                             
 *
 * 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., 675 Mass Ave, Cambridge, MA 02139, USA.
 *                                                                             
 *============================================================================*
 *============================================================================*
 */

#include "scsi-functions.h"
#include "utility-functions.h"

#if (defined CALL_TRACE) || (defined VERBOSE_OUTPUT)
FILE * sfc_local_ptr;
#endif

static const char speed0[]    = "0x";
static const char speed1[]    = "1x";
static const char speed2[]    = "2x";
static const char speed4[]    = "4x";
static const char speed4_5[]  = "4.5x";
static const char speed6[]    = "6x";
static const char speed8[]    = "8x";
static const char speed12[]   = "12x";
static const char speed16[]   = "16x";
static const char speed20_1[] = "12-20x";
static const char speed20_2[] = "8-20x";
static const char speed20_3[] = "10-20x";
static const char speed24[]   = "-24x";
static const char speed32[]   = "14-32x";
static const char speed40[]   = "17-40x";

GList * return_avail_speed_list (int drive_type,
                                 int mmc_drive)
{
  static GList * plex0_speed = NULL;
  static GList * plex4_speed = NULL;
  static GList * plex4_5_speed = NULL;
  static GList * plex6_speed = NULL;
  static GList * plex8_speed = NULL;
  static GList * plex12_speed = NULL;
  static GList * plex20_speed = NULL;
  static GList * plex32_speed = NULL;
  static GList * plex40_speed = NULL;
  static GList * mmc1_speed = NULL;
  static GList * mmc2_speed = NULL;
  static GList * mmc6_speed = NULL;
  static GList * mmc16_speed = NULL;
  static GList * mmc24_speed = NULL;
  static int init = 0;
    
  if (!init)
  {
    plex0_speed = g_list_append (plex0_speed, (char *) speed0);

    plex4_speed = g_list_append (plex4_speed, (char *) speed1);
    plex4_speed = g_list_append (plex4_speed, (char *) speed2);
    plex4_speed = g_list_append (plex4_speed, (char *) speed4);

    plex4_5_speed = g_list_append (plex4_5_speed, (char *) speed1);
    plex4_5_speed = g_list_append (plex4_5_speed, (char *) speed2);
    plex4_5_speed = g_list_append (plex4_5_speed, (char *) speed4_5);

    plex6_speed = g_list_append (plex6_speed, (char *) speed1);
    plex6_speed = g_list_append (plex6_speed, (char *) speed2);
    plex6_speed = g_list_append (plex6_speed, (char *) speed6);

    plex8_speed = g_list_append (plex8_speed, (char *) speed1);
    plex8_speed = g_list_append (plex8_speed, (char *) speed2);
    plex8_speed = g_list_append (plex8_speed, (char *) speed4);
    plex8_speed = g_list_append (plex8_speed, (char *) speed8);

    plex12_speed = g_list_append (plex12_speed, (char *) speed1);
    plex12_speed = g_list_append (plex12_speed, (char *) speed2);
    plex12_speed = g_list_append (plex12_speed, (char *) speed4);
    plex12_speed = g_list_append (plex12_speed, (char *) speed8);
    plex12_speed = g_list_append (plex12_speed, (char *) speed12);

    plex20_speed = g_list_append (plex20_speed, (char *) speed1);
    plex20_speed = g_list_append (plex20_speed, (char *) speed2);
    plex20_speed = g_list_append (plex20_speed, (char *) speed4);
    plex20_speed = g_list_append (plex20_speed, (char *) speed8);
    plex20_speed = g_list_append (plex20_speed, (char *) speed20_1);

    plex32_speed = g_list_append (plex32_speed, (char *) speed1);
    plex32_speed = g_list_append (plex32_speed, (char *) speed2);
    plex32_speed = g_list_append (plex32_speed, (char *) speed4);
    plex32_speed = g_list_append (plex32_speed, (char *) speed8);
    plex32_speed = g_list_append (plex32_speed, (char *) speed20_2);
    plex32_speed = g_list_append (plex32_speed, (char *) speed32);

    plex40_speed = g_list_append (plex40_speed, (char *) speed1);
    plex40_speed = g_list_append (plex40_speed, (char *) speed2);
    plex40_speed = g_list_append (plex40_speed, (char *) speed4);
    plex40_speed = g_list_append (plex40_speed, (char *) speed8);
    plex40_speed = g_list_append (plex40_speed, (char *) speed20_3);
    plex40_speed = g_list_append (plex40_speed, (char *) speed40);

    mmc1_speed = g_list_append (mmc1_speed, (char *) speed1);

    mmc2_speed = g_list_append (mmc2_speed, (char *) speed1);
    mmc2_speed = g_list_append (mmc2_speed, (char *) speed2);

    mmc6_speed = g_list_append (mmc6_speed, (char *) speed1);
    mmc6_speed = g_list_append (mmc6_speed, (char *) speed2);
    mmc6_speed = g_list_append (mmc6_speed, (char *) speed4);
    mmc6_speed = g_list_append (mmc6_speed, (char *) speed6);

    mmc16_speed = g_list_append (mmc16_speed, (char *) speed1);
    mmc16_speed = g_list_append (mmc16_speed, (char *) speed2);
    mmc16_speed = g_list_append (mmc16_speed, (char *) speed4);
    mmc16_speed = g_list_append (mmc16_speed, (char *) speed8);
    mmc16_speed = g_list_append (mmc16_speed, (char *) speed12);
    mmc16_speed = g_list_append (mmc16_speed, (char *) speed20_1);

    mmc24_speed = g_list_append (mmc24_speed, (char *) speed1);
    mmc24_speed = g_list_append (mmc24_speed, (char *) speed2);
    mmc24_speed = g_list_append (mmc24_speed, (char *) speed4);
    mmc24_speed = g_list_append (mmc24_speed, (char *) speed8);
    mmc24_speed = g_list_append (mmc24_speed, (char *) speed12);
    mmc24_speed = g_list_append (mmc24_speed, (char *) speed24);

    init = 1;
  }

  if (!mmc_drive)
  { /* it's a plextor cd-rom */
    switch (drive_type)
    {
      case PLEX_4:
        return plex4_speed;
      case PLEX_6:
        return plex6_speed;
      case PLEX_8:
        return plex8_speed;
      case PLEX_12:
        return plex12_speed;
      case PLEX_20:
        return plex20_speed;
      case PLEX_32:
        return plex32_speed;
      case PLEX_40:
        return plex40_speed;
      default:
        return plex0_speed;
    }
    return plex0_speed;
  }
  else
  { /* it's a mmc drive */
    switch (mmc_drive)
    {
      case MMC_1:
        return mmc1_speed;
      case MMC_2:
        return mmc2_speed;
      case MMC_4:
        return plex4_speed;
      case MMC_6:
        return mmc6_speed;
      case MMC_8:
        return plex8_speed;
      case MMC_12:
        return plex12_speed;
      case MMC_16:
        return mmc16_speed;
      case MMC_20:
        return plex20_speed;
      case MMC_24:
        return mmc24_speed;
      case MMC_32:
        return plex32_speed;
      case MMC_0:
      default:
        return plex0_speed;
    }
    return plex0_speed;
  }
}

const char * return_speed_string (int act_speed, int drive_type,
                                  int mmc_drive)
{
  static char mmc_speed[20];
  if (mmc_drive)
  {
    switch (act_speed)
    {
      case 0:
        return speed0;
      case 1:
        return speed1;
      case 2:
        return speed2;
      case 4:
        return speed4;
      case 6:
        return speed6;
      case 8:
        return speed8;
      case 12:
        return speed12;
      case 16:
        return speed16;
      case 20:
        return speed20_1;
      case 24:
        return speed24;
      case 32:
        return speed32;
      default:
        sprintf (mmc_speed, "%dx\n", act_speed);
        return mmc_speed;
    }
  }
  switch (act_speed)
  {
    case 0:
      return speed1;
    case 1:
      if (drive_type == PLEX_6)
        return speed0;
      else
        return speed2;
    case 2:
      return speed4;
    case 3:
      switch (drive_type)
      {
        case PLEX_4:
          return speed4;
        case PLEX_6:
          return speed0;
        default:
          return speed8;
      }
    case 4:
      switch (drive_type)
      {
        case PLEX_4:
          return speed4;
        case PLEX_6:
          return speed6;
        default:
          return speed8;
      }
    case 5:
      switch (drive_type)
      {
        case PLEX_4:
          return speed4;
        case PLEX_6:
          return speed6;
        case PLEX_8:
          return speed8;
        case PLEX_12:
          return speed12;
        case PLEX_20:
          return speed0;
        case PLEX_32:
          return speed20_2;
        case PLEX_40:
          return speed20_3;
        default:
          return speed0;
      }
    default:
      switch (drive_type)
      {
        case PLEX_4:
          return speed4;
        case PLEX_6:
          return speed6;
        case PLEX_8:
          return speed8;
        case PLEX_12:
          return speed12;
        case PLEX_20:
          return speed20_1;
        case PLEX_32:
          return speed32;
        case PLEX_40:
          return speed40;
        default:
          return speed0;
      }
  }

  /* should never be reached */
  return speed0;
}

GList * return_avail_spindowns ()
{
  static GList * spindowns = NULL;
  static int init = 0;

  if (!init)
  {
    spindowns = g_list_append (spindowns, (char *) PrintInactivityString (0));
    spindowns = g_list_append (spindowns, (char *) PrintInactivityString (1));
    spindowns = g_list_append (spindowns, (char *) PrintInactivityString (2));
    spindowns = g_list_append (spindowns, (char *) PrintInactivityString (3));
    spindowns = g_list_append (spindowns, (char *) PrintInactivityString (4));
    spindowns = g_list_append (spindowns, (char *) PrintInactivityString (5));
    spindowns = g_list_append (spindowns, (char *) PrintInactivityString (6));
    spindowns = g_list_append (spindowns, (char *) PrintInactivityString (7));
    spindowns = g_list_append (spindowns, (char *) PrintInactivityString (8));
    spindowns = g_list_append (spindowns, (char *) PrintInactivityString (9));
    spindowns = g_list_append (spindowns, (char *) PrintInactivityString (10));
    spindowns = g_list_append (spindowns, (char *) PrintInactivityString (11));
    spindowns = g_list_append (spindowns, (char *) PrintInactivityString (12));
    spindowns = g_list_append (spindowns, (char *) PrintInactivityString (13));
    spindowns = g_list_append (spindowns, (char *) PrintInactivityString (14));
    spindowns = g_list_append (spindowns, (char *) PrintInactivityString (15));
    init = 1;
  }

  return spindowns;
}

void inquiry_drive (GPlextorToolData * gptd)
{
  const unsigned char * result;

  if (!gptd->ptd.mmc_drive)
  {
    result = ModeSenseSpeed ();
    gptd->ptd.act_speed = *(result+14);
    gptd->ptd.act_speed_mode = *(result+15) & 0x01;
    gptd->ptd.act_waiting_setting = *(result+15) & 0x2;
    gptd->ptd.act_avoid_vib_setting = *(result+15) & 0x4;
#ifdef VERBOSE_OUTPUT
    flushed_output_1_int (sfc_local_ptr, "Current speed setting: %d\n",
                          *(result+14) );
    flushed_output_1_int (sfc_local_ptr, "Current speed mode setting: %d\n",
                          *(result+15) & 0x1);
#endif
    if (drive_type > PLEX_12)
    {
#ifdef VERBOSE_OUTPUT
      flushed_output_1_int (sfc_local_ptr,
                            "Current disable avoid vibration setting: %d\n",
                            (*(result+15) & 0x4) ? 1 : 0);
      flushed_output_1_int (sfc_local_ptr, "Current waiting setting: %d\n",
                            (*(result+15) & 0x2) ? 0 : 1);
#endif
    }
  }
  else
  {
    result = ModeSenseMMCSpeeds ();
    gptd->ptd.act_speed = ((*(result+26) << 8) + (*(result+27))) / 176;
    gptd->ptd.max_speed = ((*(result+20) << 8) + (*(result+21))) / 176;
  }
  result = ModeSenseCDPars ();
  gptd->ptd.act_spindown = *(result+15);
#ifdef VERBOSE_OUTPUT
  flushed_output_1_int (sfc_local_ptr, "Current spin-down time: %d\n", 
                        *(result+15));
#endif
  result = ModeSenseAudioControl ();
  gptd->ptd.act_left_volume = *(result+21);
  gptd->ptd.act_right_volume = *(result+23);
#ifdef VERBOSE_OUTPUT
  flushed_output_2_int (sfc_local_ptr, "Current volume: %d,%d\n", 
                        *(result+21), *(result+23));
#endif
  gptd->avail_speeds = return_avail_speed_list (gptd->ptd.model,
                                                gptd->ptd.mmc_drive);
  gptd->avail_spindowns = return_avail_spindowns ();
}

void inquiry_all_drives (GPlextorToolAppletData * gptad)
{
  const unsigned char * result;
  char * dev_name;
  char ** dev_list;
  int found = 0;
  GPlextorToolData * gptd;

#if (defined CALL_TRACE) || (defined VERBOSE_OUTPUT)
  sfc_local_ptr = gptad->out_file_ptr;
#endif
  gptad->device_names = NULL;
  gptad->device_data = NULL;
  dev_list = default_number_dev_list;

  while ((dev_name = *dev_list++))
  {
    if ((result = open_and_check_drive (dev_name, dev_name)))
    {
#ifdef VERBOSE_OUTPUT
      flushed_output_2_string (sfc_local_ptr,
                               "Found Plextor/MMC drive: %s is a %.23s\n",
                               dev_name, result + INQUIRY_VENDOR);
#endif
      gptd = g_new0 (GPlextorToolData, 1);
      gptd->avail_speeds = NULL;
      gptd->avail_spindowns = NULL;
      gptd->act_lock_volume = TRUE;
      gptd->ptd.model = drive_type;
      gptd->ptd.mmc_drive = mmc_drive;
      inquiry_drive (gptd);
      gptd->ptd.device_name_ptr = g_strdup (dev_name);
      gptad->device_names = g_list_append (gptad->device_names,
                                           gptd->ptd.device_name_ptr+5);
      gptad->device_data = g_list_append (gptad->device_data, gptd);
      close (fd);
      found = 1;
    }
  }
  if (found)
  {
    return;
  }
  dev_list = default_letter_dev_list;
  while ((dev_name = *dev_list++))
  {
    if ((result = open_and_check_drive (dev_name, dev_name)))
    {
#ifdef VERBOSE_OUTPUT
      flushed_output_2_string (sfc_local_ptr,
                               "Found Plextor/MMC drive: %s is a %.23s\n",
                               dev_name, result + INQUIRY_VENDOR);
#endif      
      gptd = g_new0 (GPlextorToolData, 1);
      gptd->avail_speeds = NULL;
      gptd->avail_spindowns = NULL;
      gptd->act_lock_volume = TRUE;
      gptd->ptd.model = drive_type;
      gptd->ptd.mmc_drive = mmc_drive;
      inquiry_drive (gptd);
      gptd->ptd.device_name_ptr = g_strdup (dev_name);
      gptad->device_names = g_list_append (gptad->device_names,
                                           gptd->ptd.device_name_ptr+5);
      gptad->device_data = g_list_append (gptad->device_data, gptd);
      close (fd);
      found = 1;
    }
  }

}

int plextor_speed_value_for_speed (const char * speed_selection,
                                   int drive_type)
{
  if (!strcmp (speed_selection, speed1))
    return 0;
  if (!strcmp (speed_selection, speed2))
  {
    if (drive_type == PLEX_6)
      return -1;
    else
      return 1;
  }
  if (!strcmp (speed_selection, speed4))
  {
    if (drive_type < PLEX_6)
      return 0xFF;
    else
      return 2;
  }
  if (!strcmp (speed_selection, speed6))
  {
    if (drive_type != PLEX_6)
      return -1;
    else
      return 0xFF;
  }
  if (!strcmp (speed_selection, speed8))
  {
    if (drive_type < PLEX_8)
      return -1;
    else
      return 3;
  }
  if (!strcmp (speed_selection, speed12))
  {
    if (drive_type < PLEX_12)
      return -1;
    else
      return 3;
  }
  if ( (!strcmp (speed_selection, speed20_1)) || 
       (!strcmp (speed_selection, speed20_2)) ||
       (!strcmp (speed_selection, speed20_3)) )
  {
    if (drive_type < PLEX_20)
      return -1;
    if (drive_type == PLEX_20)
      return 0xFF;
    return 5;
  }
  if (!strcmp (speed_selection, speed32))
  {
    if (drive_type < PLEX_32)
      return -1;
    else
      return 0xFF;
  }
  if (!strcmp (speed_selection, speed40))
  {
    if (drive_type < PLEX_40)
      return -1;
    else
      return 0xFF;
  }
  return -1;
}

int mmc_value_for_speed (const char * speed_selection)
{
  if (!strcmp (speed_selection, speed1))
    return 1;
  if (!strcmp (speed_selection, speed2))
    return 2;
  if (!strcmp (speed_selection, speed4))
    return 4;
  if (!strcmp (speed_selection, speed6))
    return 6;
  if (!strcmp (speed_selection, speed8))
    return 8;
  if (!strcmp (speed_selection, speed12))
    return 12;
  if (!strcmp (speed_selection, speed16))
    return 16;
  if (!strcmp (speed_selection, speed20_1))
    return 20;
  if (!strcmp (speed_selection, speed24))
    return 24;
  if (!strcmp (speed_selection, speed32))
    return 32;
  /* maximum value => maxium speed will be set */
  return 372;
}

void change_speed_of_device (const char * new_speed_selection,
                             GPlextorToolData * gptd)
{
  const unsigned char * speed_sense_result;
  int speed_field_value;

#ifdef CALL_TRACE
  flushed_output_0 (sfc_local_ptr, "Trace: change_speed_of_device\n");
#endif

  if (open_and_check_drive (gptd->ptd.device_name_ptr,
                            gptd->ptd.device_name_ptr))
  {
    if (!gptd->ptd.mmc_drive)
    { /* plextor cd-rom case use page 31h */
      speed_sense_result = ModeSenseSpeed ();
      speed_field_value = plextor_speed_value_for_speed (new_speed_selection,
                                                         gptd->ptd.model);
      if (speed_field_value == -1)
      {
        gnome_error_dialog (_("Invalid Speed Setting!"));
        close (fd);
        return;
      }
      if (ModeSelectSpeed ((unsigned char) speed_field_value,
                           *(speed_sense_result+15)))
      {
        gnome_error_dialog (_("Speed Setting Failed!"));
        close (fd);
        return;
      }
      gptd->ptd.act_speed = speed_field_value;
    }
    else
    { /* mmc case use set speed */
      speed_field_value = mmc_value_for_speed (new_speed_selection);
      if (MMCSetReadSpeed (speed_field_value))
      {
        gnome_error_dialog(_("Speed Setting Failed!"));
        close (fd);
        return;
      }
      gptd->ptd.act_speed = speed_field_value;
    }
    close (fd);
  }
  else
  {
    gnome_error_dialog (_("Could Not Access Drive!"));
  }
}

void change_spindown_of_device (const char * new_spindown_selection,
                                GPlextorToolData * gptd)
{
  int spindown;
  const unsigned char *inactivity_sense_result;

#ifdef CALL_TRACE
  flushed_output_0 (sfc_local_ptr, "Trace: change_spindown_of_device\n");
#endif

  if (open_and_check_drive (gptd->ptd.device_name_ptr,
                            gptd->ptd.device_name_ptr))
  {
    inactivity_sense_result = ModeSenseCDPars ();
    spindown = FieldValueForInactivityString (new_spindown_selection);
    if (ModeSelectCDPars ((unsigned char) spindown,
                          inactivity_sense_result+16))
    {
      gnome_error_dialog (_("Could Not Set Spindown Time!"));
      close (fd);
      return;
    }
    gptd->ptd.act_spindown = spindown;
    close (fd);
  }
  else
  {
    gnome_error_dialog (_("Could Not Access Drive!"));
  }
}

void change_avoid_vibration_setting (GPlextorToolData * gptd)
{
  const unsigned char * speed_sense_result;

#ifdef CALL_TRACE
  flushed_output_0 (sfc_local_ptr, "Trace: change_set_avoid_vibration\n");
#endif

  if (gptd->ptd.mmc_drive)
  { /* no plextor cd-rom => not available (afaik)! */
    gnome_error_dialog (_("Internal Error, Setting Not Available For MMC"
                          " Drive!"));
    return;
  }

  if (gptd->ptd.model < PLEX_20)
  { /* setting not available */
    gnome_error_dialog (_("Internal Error, Setting Not Available For Plextor"
                          " Drive!"));
    return;
  }

  if (open_and_check_drive (gptd->ptd.device_name_ptr,
                            gptd->ptd.device_name_ptr))
  {
    speed_sense_result = ModeSenseSpeed ();
    if (ModeSelectSpeed (*(speed_sense_result+14),
                         (unsigned char)
                         ((*(speed_sense_result+15) & 0xFB) | 
                          ((gptd->ptd.act_avoid_vib_setting) << 2))))
    {
      gnome_error_dialog (_("Avoid Vibration Setting Failed!"));
      close (fd);
      return;
    }
    close (fd);
  }
  else
  {
    gnome_error_dialog (_("Could Not Access Drive!"));
  }
}

void change_waiting_for_speed_setting (GPlextorToolData * gptd)
{
  const unsigned char * speed_sense_result;

#ifdef CALL_TRACE
  flushed_output_0 (sfc_local_ptr, "Trace: change_set_waiting_for_speed\n");
#endif

  if ( gptd->ptd.mmc_drive)
  { /* no plextor cd-rom => not available (afaik)! */
    gnome_error_dialog (_("Internal Error, Setting Not Available For MMC"
                          " Drive!"));
    return;
  }

  if (gptd->ptd.model < PLEX_20)
  { /* setting not available */
    gnome_error_dialog (_("Internal Error, Setting Not Available For Plextor"
                          " Drive!"));
    return;
  }

  if (open_and_check_drive (gptd->ptd.device_name_ptr,
                            gptd->ptd.device_name_ptr))
  {
    speed_sense_result = ModeSenseSpeed ();
    if (ModeSelectSpeed (*(speed_sense_result+14),
                         (unsigned char)
                         ((*(speed_sense_result+15) & 0xFD) | 
                          ((gptd->ptd.act_waiting_setting) << 1))))
    {
      gnome_error_dialog (_("Waiting Mode Setting Failed!"));
      close (fd);
      return;
    }
    close (fd);
  }
  else
  {
    gnome_error_dialog (_("Could Not Access Drive!"));
  }
}

void change_speed_mode_setting (GPlextorToolData * gptd)
{
  const unsigned char * speed_sense_result;

#ifdef CALL_TRACE
  flushed_output_0 (sfc_local_ptr, "Trace: change_set_avoid_vibration\n");
#endif

  if ( gptd->ptd.mmc_drive)
  { /* no plextor cd-rom => not available (afaik)! */
    gnome_error_dialog (_("Internal Error, Setting Not Available For MMC"
                          " Drive!"));
    return;
  }

  if (open_and_check_drive (gptd->ptd.device_name_ptr,
                            gptd->ptd.device_name_ptr))
  {
    speed_sense_result = ModeSenseSpeed ();
    if (ModeSelectSpeed (*(speed_sense_result+14),
                         (unsigned char) ((*(speed_sense_result+15) & 0xFE) | 
                                          ((gptd->ptd.act_speed_mode)))))
    {
      gnome_error_dialog (_("Speed Mode Setting Failed!"));
      close (fd);
      return;
    }
    close (fd);
  }
  else
  {
    gnome_error_dialog (_("Could Not Access Drive!"));
  }
}

void change_volume_setting (GPlextorToolData * gptd)
{
  const unsigned char * audio_control_result;

#ifdef CALL_TRACE
  flushed_output_0 (sfc_local_ptr, "Trace: change_volume\n");
#endif

  if (open_and_check_drive (gptd->ptd.device_name_ptr,
                            gptd->ptd.device_name_ptr))
  {
    audio_control_result = ModeSenseAudioControl ();
    if (ModeSelectAudioControl ((int)gptd->ptd.act_left_volume,
				(int)gptd->ptd.act_right_volume,
				audio_control_result))
    {
      gnome_error_dialog (_("Changing Volume Failed!"));
      close (fd);
      return;
    }
    close (fd);
  }
  else
  {
    gnome_error_dialog (_("Could Not Access Drive!"));
  }
}

/*============================================================================*
 *============================================================================*
 * EOF scsi-functions.c
 *============================================================================*
 *============================================================================*
 */
