#ifndef __SOLARISSCSI_H__
#define __SOLARISSCSI_H__


#include <iostream>
#include <pthread.h>
#include <sys/signal.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <sys/wait.h>
#include <sys/time.h>
#include <sys/stat.h>
#include <fcntl.h>          /* File control definitions */
#include <errno.h>          /* Error number definitions */
#include <unistd.h>         /* fork() */
#include <netinet/in.h>
#include <netdb.h>
#include <stdarg.h>
#ifdef __linux__
#include <scsi/sg.h>
#include <scsi/scsi.h>
#include <scsi/scsi_ioctl.h>
#include <sys/ipc.h>
#include <sys/shm.h>
#endif
#include <sys/ioctl.h>
#include <unistd.h>

#include "commdef.h"
#include "interface.h"
#include "arclib.h"

#define SCSI_INQUIRY    0x12
#define SCSI_WRITE_BUF  0x3B
#define SCSI_READ_BUF   0x3C
#define	SENSE_LEN		14
#define CDB_SIZE        10
#define BUF_SIZE        2048

                                      
typedef struct
{
    int inlen;              // [i] Length of data written to device
    int outlen;             // [i] Length of data read from device
    char cdb[CDB_SIZE];     // [i] SCSI command (6 <= x <= 16)
                            // [o] Data read from device starts here
                            // [o] On error, sense buffer starts here
    char buf[4100];     // [i] Data written to device starts here
}sSRB_BUF, *pSRB_BUF;

typedef struct
{
    BYTE    ErrorCode;          // Error Code (70H or 71H)
    BYTE    SegmentNum;         // Number of current segment descriptor
    BYTE    SenseKey;           // Sense Key(See bit definitions too)
    BYTE    InfoByte0;          // Information MSB
    BYTE    InfoByte1;          // Information MID
    BYTE    InfoByte2;          // Information MID
    BYTE    InfoByte3;          // Information LSB
    BYTE    AddSenLen;          // Additional Sense Length
    BYTE    ComSpecInf0;        // Command Specific Information MSB
    BYTE    ComSpecInf1;        // Command Specific Information MID
    BYTE    ComSpecInf2;        // Command Specific Information MID
    BYTE    ComSpecInf3;        // Command Specific Information LSB
    BYTE    AddSenseCode;       // Additional Sense Code
    BYTE    AddSenQual;         // Additional Sense Code Qualifier
    BYTE    FieldRepUCode;      // Field Replaceable Unit Code
    BYTE    SenKeySpec15;       // Sense Key Specific 15th byte
    BYTE    SenKeySpec16;       // Sense Key Specific 16th byte
    BYTE    SenKeySpec17;       // Sense Key Specific 17th byte
    BYTE    AddSenseBytes;      // Additional Sense Bytes
} sSENSE_DATA_FMT, *pSENSE_DATA_FMT;

class SolarisSCSIInterface : public ArcInterface
{
public:
	SolarisSCSIInterface();
	~SolarisSCSIInterface();
	bool init(const int nScsiPort);
	int send(sIF_CMD_BLOCK *ifData);
	int recv(sIF_CMD_BLOCK *ifData);
	int syncSend(sIF_CMD_BLOCK *ifData);
	int	getMTU();
	void *getDeviceHandle();

private:
	
	HANDLE	m_hScsi;
	//pthread_mutex_t  *m_LOCK;
    int fd;
};

#endif
