/*============================================================================*
 *============================================================================*
 * Component:           plextor-tool
 * Filename:            plextor-tool.h
 *                                                                             
 * Authors:             Georg Huettenegger
 *                                                                             
 * Date of Creation:    Fri Jul 30 16:04:02 1999
 *                                                                             
 * Last Modification:   Fri Jul 30 16:04:02 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.
 *
 *============================================================================*
 *============================================================================*
 */
#ifndef ___PLEXTOR_TOOL_H
#define ___PLEXTOR_TOOL_H

#include <stdio.h>
#include <fcntl.h>
#include <stdlib.h>
#include <errno.h>
#include <string.h>

#ifdef __linux__

#include <unistd.h>
#include <sys/ioctl.h>
#include <linux/../scsi/sg.h>  /* cope with silly includes */
#include <linux/../scsi/scsi.h>
#include <linux/../scsi/scsi_ioctl.h>

#define DTYPE_CDROM 0x5

#endif

/*============================================================================*
 *                                                                             
 * DESCRIPTION:                                                                
 * ------------                                                                
 * Common defines for SCSI commands, buffer lengths, strings ....
 *                                                                             
 *----------------------------------------------------------------------------*
 */

#define VERSION "0.5.0"

#define PLEXTOR_STRING "PLEXTOR "
#define PLEXTOR_CDROM_COMMON "CD-ROM PX-"

#define INQUIRY_CMD     0x12
#define INQUIRY_CMDLEN  6
#define INQUIRY_REPLY_LEN 96
#define INQUIRY_VENDOR  8       /* Offset in reply data to vendor name
                                 */
#define INQUIRY_PRODUCT 16      /* Offset in reply data to product string
                                 */
#define INQUIRY_BIOS_VER 32     /* Offset in reply data to bios version
                                 */
#define INQUIRY_SPEED 26        /* Offset in reply data to product speed
                                 */

#define MODE_SENSE_CMD 0x1A
#define MODE_SENSE_CMDLEN 6
#define MODE_SENSE_REPLY_LEN 0xFF

#define MODE_SELECT_CMD 0x15
#define MS_CMDLEN 6
/* PAR_LEN is the page length in bytes + 4 */
#define MS_31_PAR_LEN 8
#define MS_D_PAR_LEN 12
#define MS_E_PAR_LEN 20

#define SET_SPEED_CMD 0xBB
#define SP_CMDLEN 18

#ifdef __linux__

#define SCSI_OFF sizeof(struct sg_header)

#endif

/*============================================================================*
 *                                                                             
 * DESCRIPTION:                                                                
 * ------------                                                                
 * Basic structure for storing all information for one device (only used
 * for Linux GNOME applet).
 *                                                                             
 *----------------------------------------------------------------------------*
 */

typedef struct
{
  int mmc_drive;                                /* whether it is a mmc drive */
  char * device_name_ptr;                       /* the device name */
  int model;                                    /* the model */
  int act_speed;                                /* current speed setting */
  int max_speed;                                /* stores max. mmc speed */
  int act_spindown;                             /* current spin-down time */
  int act_speed_mode;                           /* current speed mode setting*/
  int act_waiting_setting;                      /* current waiting setting */
  int act_avoid_vib_setting;                    /* current avoid vibration
                                                 * setting */
  float act_left_volume;                        /* current left volume
						 * setting */
  float act_right_volume;                       /* current right volume
						 * setting */
} PlextorToolData;

/*============================================================================*
 *                                                                             
 * DESCRIPTION:                                                                
 * ------------                                                                
 * Enumerations for all supported Plextor and MMC drive types.
 *                                                                             
 *----------------------------------------------------------------------------*
 */

enum PlextorDrive { PLEX_0, PLEX_4, PLEX_4_5, PLEX_6, PLEX_8, PLEX_12,
                    PLEX_20, PLEX_32, PLEX_40 };
enum MMCDrive { MMC_0, MMC_1, MMC_2, MMC_4, MMC_6, MMC_8, MMC_12, MMC_16,
                MMC_20, MMC_24, MMC_32 };

#ifdef __linux__

extern int fd;                               /* SCSI device/file descriptor */

/*============================================================================*
 *                                                                             
 * DESCRIPTION:                                                                
 * ------------                                                                
 * Contains the /dev/sgx strings that are searched for supported devices
 *                                                                             
 *----------------------------------------------------------------------------*
 */

extern char *default_number_dev_list[];
extern char *default_letter_dev_list[];

#endif

/*============================================================================*
 *                                                                             
 * DESCRIPTION:                                                                
 * ------------                                                                
 * Four global varialbes used for the console tools (to determine the drive
 * type and for output.
 *                                                                             
 *----------------------------------------------------------------------------*
 */

extern int drive_type;
extern int mmc_drive;

extern char *prog_name;
extern int verbose;

#ifdef __linux__

/* new wrapper function for the scsi calls.
   at the moment used for the mode select calls. uses the new scsi generic
   interface if available.
*/
int perform_SCSI_cmd(unsigned cmd_len,         /* command length */
                     unsigned char *cmd_buff,  /* command buffer */
                     unsigned in_size,         /* input data size */
                     unsigned char *i_buff,    /* input buffer */
                     unsigned out_size,        /* output data size */
                     unsigned char *o_buff     /* output buffer */
                     );

/* function executing a scsi command using the new scsi generic interface.
 */
int execute_new_SCSI_cmd(unsigned cmd_len,          /* command length */
                         unsigned char * cmd_buff,  /* command buffer */
                         unsigned in_size,          /* input data size */
                         unsigned char * i_buff,    /* input buffer */
                         unsigned out_size,         /* output data size */
                         unsigned char * o_buff     /* output buffer */
                         );

/* old function does a direct call to the old sg interface.
   used for everything except the mode select commands at the moment.
*/
int handle_SCSI_cmd(unsigned cmd_len,         /* command length */
                    unsigned in_size,         /* input data size */
                    unsigned char *i_buff,    /* input buffer */
                    unsigned out_size,        /* output data size */
                    unsigned char *o_buff     /* output buffer */
                    );

#endif

#if (defined WIN32) || (defined _WIN32)

extern int force;                       /* if set retries scsi init. */

#define STRICT
#include <windows.h>

#include "WnASPI32.h"
#include "SCSIDefs.h"

#endif

#if (defined WIN32) || (defined _WIN32)

#ifndef DWORD
#define DWORD int
#endif

#define SIZE_INQUIRYBUF 36              /* SCSI Inquiry buffer size */
#define SIZE_READCAPBUF 8               /* Size of READ CAPACITY buffer */


typedef struct tag_BENCHTARGET
{
  BYTE                    byHaId;
  BYTE                    byTarget;
}
BENCHTARGET, *PBENCHTARGET;

HINSTANCE       ghinstWNASPI32;                 /* Handle to ASPI for Win32 */
PBENCHTARGET    pbt;                            /* Pointer to device struct */

/*============================================================================*
 *                                                                             
 * DESCRIPTION:                                                                
 * ------------                                                                
 * Definitions for the ASPI functions
 *                                                                             
 *----------------------------------------------------------------------------*
 */

DWORD           (*gpfnGetASPI32SupportInfo)( VOID );
DWORD           (*gpfnSendASPI32Command)( LPSRB );
BOOL            (*gpfnGetASPI32Buffer)( PASPI32BUFF );
BOOL            (*gpfnFreeASPI32Buffer)( PASPI32BUFF );
BOOL            (*gpfnTranslateASPI32Address)( PDWORD, PDWORD );

/*============================================================================*
 *                                                                             
 * DESCRIPTION:                                                                
 * ------------                                                                
 * Used to initialize ASPI for Windows (uses InitASPI). Checks for OS version;
 * and allocates needed memory if InitASPI is successful.
 *                                                                             
 *----------------------------------------------------------------------------*
 */
int windows_initialize_scsi ();

/*============================================================================*
 *                                                                             
 * DESCRIPTION:                                                                
 * ------------                                                                
 * Searches for Plextor/MMC drives, prints all found devices to stdout.
 *                                                                             
 *----------------------------------------------------------------------------*
 */
void windows_list_plextor_mmc_drives ();

/*============================================================================*
 *                                                                             
 * DESCRIPTION:                                                                
 * ------------                                                                
 * Initializes ASPI for Windows (loading the library). This function uses
 * the force global variable to try again as long as necessary (until an
 * error code or success is returned, ASPI sometimes does neither)
 *                                                                             
 *----------------------------------------------------------------------------*
 */
BOOL InitASPI( VOID );

/*============================================================================*
 *                                                                             
 * DESCRIPTION:                                                                
 * ------------                                                                
 * For Unloading the ASPI library.
 *                                                                             
 *----------------------------------------------------------------------------*
 */
VOID TermASPI( VOID );

/*============================================================================*
 *                                                                             
 * DESCRIPTION:                                                                
 * ------------                                                                
 * Executes a SCSI command, retries as long as necessary.
 *                                                                             
 *----------------------------------------------------------------------------*
 */
BOOL SyncExecWithRetry( PBENCHTARGET, BYTE, DWORD, PBYTE, BYTE, PBYTE );

#endif

/*============================================================================*
 *                                                                             
 * DESCRIPTION:                                                                
 * ------------                                                                
 * Returns the drive type for the given Plextor CD-ROM (according to the
 * product name).
 *                                                                             
 *----------------------------------------------------------------------------*
 */
int ReturnPlextorDriveType (const unsigned char * product_string);

/*============================================================================*
 *                                                                             
 * DESCRIPTION:                                                                
 * ------------                                                                
 * Returns the numerical value for the spindown time denoted by
 * spindown_string.
 *                                                                             
 *----------------------------------------------------------------------------*
 */
int FieldValueForInactivityString (const char * spindown_string);

/*============================================================================*
 *                                                                             
 * DESCRIPTION:                                                                
 * ------------                                                                
 * Returns a printable string for the given numerical spindown time.
 *                                                                             
 *----------------------------------------------------------------------------*
 */
const char * PrintInactivityString (int spindown);

/*============================================================================*
 *                                                                             
 * DESCRIPTION:                                                                
 * ------------                                                                
 * Uses the SCSI Set Speed Command to set the read speed of a MMC drive.
 *                                                                             
 *----------------------------------------------------------------------------*
 */
int MMCSetReadSpeed ( int read_speed );

/*============================================================================*
 *                                                                             
 * DESCRIPTION:                                                                
 * ------------                                                                
 * Executes an Inquiry command and returns the result.
 *                                                                             
 *----------------------------------------------------------------------------*
 */
const unsigned char *Inquiry ( void );

/*============================================================================*
 *                                                                             
 * DESCRIPTION:                                                                
 * ------------                                                                
 * Returns a buffer containing all mode pages supported by a device.
 * (The buffer stores up to 255 bytes, could be error if device with
 * more mode pages is encountered).
 *                                                                             
 *----------------------------------------------------------------------------*
 */
const unsigned char *ModeSenseAllPages ( void );

/*============================================================================*
 *                                                                             
 * DESCRIPTION:                                                                
 * ------------                                                                
 * Performs a mode select with code page 0x2a to retrieve the speed
 * settings of a MMC drive.
 *                                                                             
 *----------------------------------------------------------------------------*
 */
const unsigned char *ModeSenseMMCSpeeds ( void );

/*============================================================================*
 *                                                                             
 * DESCRIPTION:                                                                
 * ------------                                                                
 * Queries the mode page 0x31 of Plextor CD-ROM drives containing the
 * speed setting and the three possible bits.
 *                                                                             
 *----------------------------------------------------------------------------*
 */
const unsigned char *ModeSenseSpeed ( void );

/*============================================================================*
 *                                                                             
 * DESCRIPTION:                                                                
 * ------------                                                                
 * Queries the 0xD mode page (standard mode page for CD-ROM/CD-R(W) drives).
 * Containing the inactivity timer.
 *                                                                             
 *----------------------------------------------------------------------------*
 */
const unsigned char *ModeSenseCDPars ( void );

/*============================================================================*
 *                                                                             
 * DESCRIPTION:                                                                
 * ------------                                                                
 * Queries the 0xE mode page (standard mode page for CD-ROM/CD-R(W) drives).
 * Containing the port0-3 volumes (assuming port0 is left and port1 is right).
 *                                                                             
 *----------------------------------------------------------------------------*
 */
const unsigned char *ModeSenseAudioControl ( void );

/*============================================================================*
 *                                                                             
 * DESCRIPTION:                                                                
 * ------------                                                                
 * Used to change the speed of Plextor CD-ROM drives (does a select with
 * mode page 0x31). When only one parameter should be changed first perform a
 * ModeSenseSpeed to retrieve the old values for the other parameter.
 *                                                                             
 *----------------------------------------------------------------------------*
 */
int ModeSelectSpeed (unsigned char speed, unsigned char speed_settings );

/*============================================================================*
 *                                                                             
 * DESCRIPTION:                                                                
 * ------------                                                                
 * Used to change the inactivity timer. msf_numbers should be acquired
 * using ModeSenseCDPars first.
 *                                                                             
 *----------------------------------------------------------------------------*
 */
int ModeSelectCDPars (unsigned char inactivity,
                      const unsigned char * msf_numbers );

/*============================================================================*
 *                                                                             
 * DESCRIPTION:                                                                
 * ------------                                                                
 * Used to change left/right volumes. sense_result should be acquired
 * using ModeSenseAudioControl first.
 *                                                                             
 *----------------------------------------------------------------------------*
 */
int ModeSelectAudioControl (unsigned char left_volume,
			    unsigned char right_volume,
			    const unsigned char * sense_result );

/*============================================================================*
 *                                                                             
 * DESCRIPTION:                                                                
 * ------------                                                                
 * Used to open and check whether the drive can be controlled by
 * plextor-tool (else NULL is returned). Does open the device without
 * closing fd. Sets drive_type and mmc_drive.
 *                                                                             
 *----------------------------------------------------------------------------*
 */
const unsigned char * open_and_check_drive (const char *drive_name_part1,
                                            const char *drive_name_part2);

/*============================================================================*
 *                                                                             
 * DESCRIPTION:                                                                
 * ------------                                                                
 * Functions that prints all available drives to stdout (on Linux).
 *                                                                             
 *----------------------------------------------------------------------------*
 */
void linux_list_plextor_mmc_drives ();

#endif

/*============================================================================*
 *============================================================================*
 * EOF plextor-tool.h
 *============================================================================*
 *============================================================================*
 */
