/**************************************************************************
 * ASPI routines
 * Copyright (C) 2000 David Elliott <dfe@infinite-internet.net>
 *
 * This library is free software; you can redistribute it and/or
 * modify it under the terms of the GNU Lesser General Public
 * License as published by the Free Software Foundation; either
 * version 2.1 of the License, or (at your option) any later version.
 *
 * This library 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
 * Lesser General Public License for more details.
 *
 * You should have received a copy of the GNU Lesser General Public
 * License along with this library; if not, write to the Free Software
 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
 */

/* These routines are to be called from either WNASPI32 or WINASPI */

/* FIXME:
 * - Registry format is stupid for now.. fix that later
 * - No way to override automatic /proc detection, maybe provide an
 *   HKEY_LOCAL_MACHINE\Software\Wine\Wine\Scsi regkey
 * - Somewhat debating an #ifdef linux... technically all this code will
 *   run on another UNIX.. it will fail nicely.
 * - Please add support for mapping multiple channels on host adapters to
 *   aspi controllers, e-mail me if you need help.
 */

/*
Registry format is currently:
HKEY_DYN_DATA
	WineScsi
		(default)=number of host adapters
		hHHcCCtTTdDD=linux device name
*/

#include "config.h"

#include <stdio.h>
#include <stdarg.h>
#include <sys/types.h>
#ifdef HAVE_SYS_IOCTL_H
#include <sys/ioctl.h>
#endif
#include <fcntl.h>
#include <dirent.h>
#ifdef HAVE_UNISTD_H
# include <unistd.h>
#endif
#include <errno.h>
#include <string.h>

#include "windef.h"
#include "winbase.h"
#include "winreg.h"
#include "winerror.h"
#include "winescsi.h"

#include "wine/debug.h"

WINE_DEFAULT_DEBUG_CHANNEL(aspi);

/* Internal function prototypes */
static void
SCSI_GetProcinfo(void);

#ifdef linux
static void
SCSI_MapHCtoController(void);
#endif

static void set_last_error(void)
{
    int save_errno = errno; /* errno gets overwritten by printf */
    switch (errno)
    {
    case EAGAIN:
        SetLastError( ERROR_SHARING_VIOLATION );
        break;
    case EBADF:
        SetLastError( ERROR_INVALID_HANDLE );
        break;
    case ENOSPC:
        SetLastError( ERROR_HANDLE_DISK_FULL );
        break;
    case EACCES:
    case EPERM:
    case EROFS:
        SetLastError( ERROR_ACCESS_DENIED );
        break;
    case EBUSY:
        SetLastError( ERROR_LOCK_VIOLATION );
        break;
    case ENOENT:
        SetLastError( ERROR_FILE_NOT_FOUND );
        break;
    case EISDIR:
        SetLastError( ERROR_CANNOT_MAKE );
        break;
    case ENFILE:
    case EMFILE:
        SetLastError( ERROR_NO_MORE_FILES );
        break;
    case EEXIST:
        SetLastError( ERROR_FILE_EXISTS );
        break;
    case EINVAL:
    case ESPIPE:
        SetLastError( ERROR_SEEK );
        break;
    case ENOTEMPTY:
        SetLastError( ERROR_DIR_NOT_EMPTY );
        break;
    case ENOEXEC:
        SetLastError( ERROR_BAD_FORMAT );
        break;
    default:
        WARN( "unknown file error: %s\n", strerror(save_errno) );
        SetLastError( ERROR_GEN_FAILURE );
        break;
    }
    errno = save_errno;
}

/* Exported functions */
void
SCSI_Init()
{
	/* For now we just call SCSI_GetProcinfo */
	SCSI_GetProcinfo();
#ifdef linux
	SCSI_MapHCtoController();
#endif
}

int
ASPI_GetNumControllers()
{
	HKEY hkeyScsi;
	HKEY hkeyControllerMap;
	DWORD error;
	DWORD type = REG_DWORD;
	DWORD num_ha = 0;
	DWORD cbData = sizeof(num_ha);

	if( RegOpenKeyExA(HKEY_DYN_DATA, KEYNAME_SCSI, 0, KEY_ALL_ACCESS, &hkeyScsi ) != ERROR_SUCCESS )
	{
		ERR("Could not open HKEY_DYN_DATA\\%s\n",KEYNAME_SCSI);
		return 0;
	}

	if( (error=RegOpenKeyExA(hkeyScsi, KEYNAME_SCSI_CONTROLLERMAP, 0, KEY_ALL_ACCESS, &hkeyControllerMap )) != ERROR_SUCCESS )
	{
		ERR("Could not open HKEY_DYN_DATA\\%s\\%s\n", KEYNAME_SCSI, KEYNAME_SCSI_CONTROLLERMAP);
		RegCloseKey(hkeyScsi);
		SetLastError(error);
		return 0;
	}
	if( RegQueryValueExA(hkeyControllerMap, NULL, NULL, &type, (LPBYTE)&num_ha, &cbData ) != ERROR_SUCCESS )
	{
		ERR("Could not query value HKEY_DYN_DATA\\%s\n",KEYNAME_SCSI);
		num_ha=0;
	}
	RegCloseKey(hkeyControllerMap);
	RegCloseKey(hkeyScsi);
	TRACE("Returning %ld host adapters\n", num_ha );
	return num_ha;
}

BOOL
SCSI_GetDeviceName( int h, int c, int t, int d, LPSTR devstr, LPDWORD lpcbData )
{

	char idstr[20];
	HKEY hkeyScsi;
	DWORD type;

	if( RegOpenKeyExA(HKEY_DYN_DATA, KEYNAME_SCSI, 0, KEY_ALL_ACCESS, &hkeyScsi ) != ERROR_SUCCESS )
	{
		ERR("Could not open HKEY_DYN_DATA\\%s\n",KEYNAME_SCSI);
		return FALSE;
	}


	sprintf(idstr, "h%02dc%02dt%02dd%02d", h, c, t, d);

	if( RegQueryValueExA(hkeyScsi, idstr, NULL, &type, devstr, lpcbData) != ERROR_SUCCESS )
	{
		WARN("Could not query value HKEY_DYN_DATA\\%s\\%s\n",KEYNAME_SCSI, idstr);
		RegCloseKey(hkeyScsi);
		return FALSE;
	}
	RegCloseKey(hkeyScsi);

	TRACE("scsi %s: Device name: %s\n",idstr,devstr);
	return TRUE;
}

/* SCSI_GetHCforController
 * RETURNS
 * 	HIWORD: Host Adapter
 * 	LOWORD: Channel
 */
DWORD
ASPI_GetHCforController( int controller )
{
	DWORD hc = 0xFFFFFFFF;
	char cstr[20];
	DWORD error;
	HKEY hkeyScsi;
	HKEY hkeyControllerMap;
	DWORD type = REG_DWORD;
	DWORD cbData = sizeof(DWORD);
	DWORD disposition;
#if 0
	FIXME("Please fix to map each channel of each host adapter to the proper ASPI controller number!\n");
	hc = (controller << 16);
	return hc;
#endif
	if( (error=RegCreateKeyExA(HKEY_DYN_DATA, KEYNAME_SCSI, 0, NULL, REG_OPTION_VOLATILE, KEY_ALL_ACCESS, NULL, &hkeyScsi, &disposition )) != ERROR_SUCCESS )
	{
		ERR("Could not open HKEY_DYN_DATA\\%s\n",KEYNAME_SCSI);
		SetLastError(error);
		return hc;
	}
	if( disposition != REG_OPENED_EXISTING_KEY )
	{
		WARN("Created HKEY_DYN_DATA\\%s\n",KEYNAME_SCSI);
	}
	if( (error=RegCreateKeyExA(hkeyScsi, KEYNAME_SCSI_CONTROLLERMAP, 0, NULL, REG_OPTION_VOLATILE, KEY_ALL_ACCESS, NULL, &hkeyControllerMap, &disposition )) != ERROR_SUCCESS )
	{
		ERR("Could not open HKEY_DYN_DATA\\%s\\%s\n", KEYNAME_SCSI, KEYNAME_SCSI_CONTROLLERMAP);
		RegCloseKey(hkeyScsi);
		SetLastError(error);
		return hc;
	}
	if( disposition != REG_OPENED_EXISTING_KEY )
	{
		WARN("Created HKEY_DYN_DATA\\%s\\%s\n",KEYNAME_SCSI, KEYNAME_SCSI_CONTROLLERMAP);
	}

	sprintf(cstr, "c%02d", controller);
	if( (error=RegQueryValueExA( hkeyControllerMap, cstr, 0, &type, (LPBYTE)&hc, &cbData)) != ERROR_SUCCESS )
	{
		ERR("Could not open HKEY_DYN_DATA\\%s\\%s\\%s, error=%lx\n", KEYNAME_SCSI, KEYNAME_SCSI_CONTROLLERMAP, cstr, error );
		SetLastError( error );
	}
	RegCloseKey(hkeyControllerMap);
	RegCloseKey(hkeyScsi);
	return hc;

};

int
SCSI_OpenDevice( int h, int c, int t, int d )
{
	char devstr[20];
	DWORD cbData = 20;
	int fd = -1;
	char dainbread_linux_hack = 1;

	if(!SCSI_GetDeviceName( h, c, t, d, devstr, &cbData ))
	{
		WARN("Could not get device name for h%02dc%02dt%02dd%02d\n", h, c, t, d);
		return -1;
	}

linux_hack:
	TRACE("Opening device %s mode O_RDWR\n",devstr);
	fd = open(devstr, O_RDWR);

	if( fd < 0 )
	{
		int len = strlen(devstr);
		set_last_error(); /* SetLastError() to errno */
		TRACE("Open failed (%s)\n", strerror(errno));

		/* in case of "/dev/sgX", convert from sga to sg0
		 * and the other way around.
		 * FIXME: remove it if the distributions
		 * finally manage to agree on something.
		 * The best would probably be a complete
		 * rewrite of the Linux SCSI layer
		 * to use CAM + devfs :-) */
		if ( (dainbread_linux_hack) &&
		     (len >= 3) &&
		     (devstr[len-3] == 's') && (devstr[len-2] == 'g') )
		{
			char *p = &devstr[len-1];
			*p = (*p >= 'a') ? *p - 'a' + '0' : *p - '0' + 'a';
			dainbread_linux_hack = 0;
			TRACE("Retry with \"equivalent\" Linux device '%s'\n", devstr);
			goto linux_hack;
		}
	}
	return fd;
}

#ifdef linux
/* SCSI_Fix_CMD_LEN
 * 	Checks to make sure the CMD_LEN is correct
 */
void
SCSI_Fix_CMD_LEN(int fd, int cmd, int len)
{
	/* This is what the linux kernel thinks.... */
	static const unsigned char scsi_command_size[8] =
	{
        	6, 10, 10, 12,
        	12, 12, 10, 10
	};

	int index=(cmd>>5)&7;

	if (len!=scsi_command_size[index])
	{
		TRACE("CDBLen for command %d claims to be %d, expected %d\n",
				cmd, len, scsi_command_size[index]);
		ioctl(fd,SG_NEXT_CMD_LEN,&len);
	}
}

int
SCSI_LinuxSetTimeout( int fd, int timeout )
{
	int retval;
	TRACE("Setting timeout to %d jiffies\n", timeout);
	retval=ioctl(fd,SG_SET_TIMEOUT,&timeout);
	if(retval)
	{
		WARN("Could not set timeout ! (%s)\n", strerror(errno));
	}
	return retval;

}

/* This function takes care of the write/read to the linux sg device.
 * It returns TRUE or FALSE and uses set_last_error() to convert
 * UNIX errno to Windows GetLastError().  The reason for that is that
 * several programs will check that error and we might as well set
 * it here.  We also return the value of the read call in
 * lpcbBytesReturned.
 */
BOOL /* NOTE: This function SHOULD BLOCK */
SCSI_LinuxDeviceIo( int fd,
		struct sg_header * lpInBuffer, DWORD cbInBuffer,
		struct sg_header * lpOutBuffer, DWORD cbOutBuffer,
		LPDWORD lpcbBytesReturned )
{
	DWORD dwBytes;
	DWORD save_error;

	TRACE("Writing to Linux sg device\n");
	dwBytes = write( fd, lpInBuffer, cbInBuffer );
	if( dwBytes != cbInBuffer )
	{
		set_last_error();
		save_error = GetLastError();
		WARN("Not enough bytes written to scsi device. bytes=%ld .. %ld\n", cbInBuffer, dwBytes );
                /* FIXME: set_last_error() never sets error to ERROR_NOT_ENOUGH_MEMORY... */
		if( save_error == ERROR_NOT_ENOUGH_MEMORY )
			MESSAGE("Your Linux kernel was not able to handle the amount of data sent to the scsi device. Try recompiling with a larger SG_BIG_BUFF value (kernel 2.0.x sg.h)");
		WARN("error= %ld\n", save_error );
		*lpcbBytesReturned = 0;
		return FALSE;
	}

	TRACE("Reading reply from Linux sg device\n");
	*lpcbBytesReturned = read( fd, lpOutBuffer, cbOutBuffer );
	if( *lpcbBytesReturned != cbOutBuffer )
	{
		set_last_error();
		save_error = GetLastError();
		WARN("Not enough bytes read from scsi device. bytes=%ld .. %ld\n", cbOutBuffer, *lpcbBytesReturned);
		WARN("error= %ld\n", save_error );
		return FALSE;
	}
	return TRUE;
}

/* Internal functions */
struct LinuxProcScsiDevice
{
	int host;
	int channel;
	int target;
	int lun;
	char vendor[9];
	char model[17];
	char rev[5];
	char type[33];
	int ansirev;
};

/*
 * we need to declare white spaces explicitly via %*1[ ],
 * as there are very dainbread CD-ROM devices out there
 * which have their manufacturer name blanked out via spaces,
 * which confuses fscanf's parsing (skips all blank spaces)
 */
static int
SCSI_getprocentry( FILE * procfile, struct LinuxProcScsiDevice * dev )
{
	int result;
	result = fscanf( procfile,
		"Host:%*1[ ]scsi%d%*1[ ]Channel:%*1[ ]%d%*1[ ]Id:%*1[ ]%d%*1[ ]Lun:%*1[ ]%d\n",
		&dev->host,
		&dev->channel,
		&dev->target,
		&dev->lun );
	if( result == EOF )
	{
		/* "end of entries" return, so no TRACE() here */
		return EOF;
	}
	if( result != 4 )
	{
		ERR("bus id line scan count error\n");
		return 0;
	}
	result = fscanf( procfile,
		"  Vendor:%*1[ ]%8c%*1[ ]Model:%*1[ ]%16c%*1[ ]Rev:%*1[ ]%4c\n",
		dev->vendor,
		dev->model,
		dev->rev );
	if( result != 3 )
	{
		ERR("model line scan count error\n");
		return 0;
	}

	result = fscanf( procfile,
		"  Type:%*3[ ]%32c%*1[ ]ANSI%*1[ ]SCSI%*1[ ]revision:%*1[ ]%d\n",
		dev->type,
		&dev->ansirev );
	if( result != 2 )
	{
		ERR("SCSI type line scan count error\n");
		return 0;
	}
	/* Since we fscanf with %XXc instead of %s.. put a NULL at end */
	dev->vendor[8] = 0;
	dev->model[16] = 0;
	dev->rev[4] = 0;
	dev->type[32] = 0;

	return 1;
}

static void
SCSI_printprocentry( const struct LinuxProcScsiDevice * dev )
{
	TRACE( "Host: scsi%d Channel: %02d Id: %02d Lun: %02d\n",
		dev->host,
		dev->channel,
		dev->target,
		dev->lun );
	TRACE( "  Vendor: %s Model: %s Rev: %s\n",
		dev->vendor,
		dev->model,
		dev->rev );
	TRACE( "  Type:   %s ANSI SCSI revision: %02d\n",
		dev->type,
		dev->ansirev );
}

static BOOL
SCSI_PutRegControllerMap( HKEY hkeyControllerMap, int num_controller, int ha, int chan)
{
	DWORD error;
	char cstr[20];
	DWORD hc;
	hc = (ha << 16) + chan;
	sprintf(cstr, "c%02d", num_controller);
	if( (error=RegSetValueExA( hkeyControllerMap, cstr, 0, REG_DWORD, (LPBYTE)&hc, sizeof(DWORD))) != ERROR_SUCCESS )
	{
		ERR("Could not create HKEY_DYN_DATA\\%s\\%s\\%s\n", KEYNAME_SCSI, KEYNAME_SCSI_CONTROLLERMAP, cstr );
	}
	return error;
}

static void
SCSI_MapHCtoController()
{
	HKEY hkeyScsi;
	HKEY hkeyControllerMap;
	DWORD disposition;

	char idstr[20];
	DWORD cbIdStr;
	int i = 0;
	DWORD type = 0;
	DWORD error;

	DWORD num_controller = 0;
	int last_ha = -1;
	int last_chan = -1;

	int ha = 0;
	int chan = 0;

	if( RegCreateKeyExA(HKEY_DYN_DATA, KEYNAME_SCSI, 0, NULL, REG_OPTION_VOLATILE, KEY_ALL_ACCESS, NULL, &hkeyScsi, &disposition ) != ERROR_SUCCESS )
	{
		ERR("Could not open HKEY_DYN_DATA\\%s\n",KEYNAME_SCSI);
		return;
	}
	if( disposition != REG_OPENED_EXISTING_KEY )
	{
		WARN("Created HKEY_DYN_DATA\\%s\n",KEYNAME_SCSI);
	}
	if( RegCreateKeyExA(hkeyScsi, KEYNAME_SCSI_CONTROLLERMAP, 0, NULL, REG_OPTION_VOLATILE, KEY_ALL_ACCESS, NULL, &hkeyControllerMap, &disposition ) != ERROR_SUCCESS )
	{
		ERR("Could not create HKEY_DYN_DATA\\%s\\%s\n", KEYNAME_SCSI, KEYNAME_SCSI_CONTROLLERMAP);
		RegCloseKey(hkeyScsi);
		return;
	}

	for( i=0; cbIdStr = sizeof(idstr), (error=RegEnumValueA( hkeyScsi, i, idstr, &cbIdStr, NULL, &type, NULL, NULL )) == ERROR_SUCCESS; i++ )
	{
	        if(idstr[0] == '\0') continue; /* skip the default value */

		if(sscanf(idstr, "h%02dc%02dt%*02dd%*02d", &ha, &chan) != 2) {
			ERR("incorrect reg. value %s\n", debugstr_a(idstr));
			continue;
		}

		if( last_ha < ha )
		{	/* Next HA */
			last_ha = ha;
			last_chan = chan;
			SCSI_PutRegControllerMap( hkeyControllerMap, num_controller, ha, chan);
			num_controller++;
		}
		else if( last_ha > ha )
		{
			FIXME("Expected registry to be sorted\n");
		}
		/* last_ha == ha */
		else if( last_chan < chan )
		{
			last_chan = chan;
			SCSI_PutRegControllerMap( hkeyControllerMap, num_controller, ha, chan);
			num_controller++;
		}
		else if( last_chan > chan )
		{
			FIXME("Expected registry to be sorted\n");
		}
		/* else last_ha == ha && last_chan == chan so do nothing */
	}
	/* Set (default) value to number of controllers */
	if( RegSetValueExA(hkeyControllerMap, NULL, 0, REG_DWORD, (LPBYTE)&num_controller, sizeof(DWORD) ) != ERROR_SUCCESS )
	{
		ERR("Could not set value HKEY_DYN_DATA\\%s\\%s\n",KEYNAME_SCSI, KEYNAME_SCSI_CONTROLLERMAP);
	}
	RegCloseKey(hkeyControllerMap);
	RegCloseKey(hkeyScsi);
	return;
}
#endif

int SCSI_Linux_CheckDevices(void)
{
    DIR *devdir;
    struct dirent *dent = NULL;

    devdir = opendir("/dev");
    for (dent=readdir(devdir);dent;dent=readdir(devdir))
    {
        if (!(strncmp(dent->d_name, "sg", 2)))
            break;
    }
    closedir(devdir);

    if (dent == NULL)
    {
	TRACE("WARNING: You don't have any /dev/sgX generic scsi devices ! \"man MAKEDEV\" !\n");
	return 0;
    }
    return 1;
}

static void
SCSI_GetProcinfo()
/* I'll admit, this function is somewhat of a mess... it was originally
 * designed to make some sort of linked list then I realized that
 * HKEY_DYN_DATA would be a lot less messy
 */
{
#ifdef linux
	static const char procname[] = "/proc/scsi/scsi";
	FILE * procfile = NULL;

	char read_line[40], read1[10] = "\0", read2[10] = "\0";
	int result = 0;

	struct LinuxProcScsiDevice dev;

	char idstr[20];
	char devstr[20];

	int devnum=0;
	int num_ha = 0;

	HKEY hkeyScsi;
	DWORD disposition;

	/* Check whether user has generic scsi devices at all */
	if (!(SCSI_Linux_CheckDevices()))
	    return;

	procfile = fopen( procname, "r" );
	if( !procfile )
	{
		ERR("Could not open %s\n", procname);
		return;
	}

	fgets(read_line, 40, procfile);
	sscanf( read_line, "Attached %9s %9s", read1, read2);

	if(strcmp(read1, "devices:"))
	{
		ERR("Incorrect %s format\n", procname);
		return;
	}

	if(!(strcmp(read2, "none")))
	{
		ERR("No devices found in %s. Make sure you loaded your SCSI driver or set up ide-scsi emulation for your IDE device if this app needs it !\n", procname);
		return;
	}

	if( RegCreateKeyExA(HKEY_DYN_DATA, KEYNAME_SCSI, 0, NULL, REG_OPTION_VOLATILE, KEY_ALL_ACCESS, NULL, &hkeyScsi, &disposition ) != ERROR_SUCCESS )
	{
		ERR("Could not create HKEY_DYN_DATA\\%s\n",KEYNAME_SCSI);
		return;
	}

	/* Read info for one device */
	while( (result = SCSI_getprocentry(procfile, &dev)) > 0 )
	{
		/* Add to registry */

		sprintf(idstr, "h%02dc%02dt%02dd%02d", dev.host, dev.channel, dev.target, dev.lun);
		sprintf(devstr, "/dev/sg%c", 'a'+devnum);
		if( RegSetValueExA(hkeyScsi, idstr, 0, REG_SZ, devstr, strlen(devstr)+1 ) != ERROR_SUCCESS )
		{
			ERR("Could not set value HKEY_DYN_DATA\\%s\\%s\n",KEYNAME_SCSI, idstr);
		}

		/* Debug output */
		SCSI_printprocentry( &dev );

		/* FIXME: We *REALLY* need number of controllers.. not ha */
		/* num of hostadapters is highest ha + 1 */
		if( dev.host >= num_ha )
			num_ha = dev.host+1;
		devnum++;
	} /* while(1) */
	if( result != EOF )
	{
		ERR("Sorry, incorrect %s format\n", procname);
	}
	fclose( procfile );
	if( RegSetValueExA(hkeyScsi, NULL, 0, REG_DWORD, (LPBYTE)&num_ha, sizeof(num_ha) ) != ERROR_SUCCESS )
	{
		ERR("Could not set value HKEY_DYN_DATA\\%s\n",KEYNAME_SCSI);
	}
	RegCloseKey(hkeyScsi);
	return;
#endif
}
