/*
 *  scsi_linux.cpp - SCSI Manager, Linux specific stuff
 *
 *  Basilisk II (C) 1997-2008 Christian Bauer
 *
 *  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., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
 */

#include "sysdeps.h"

#include <sys/ioctl.h>
#include <linux/param.h>
#include <linux/../scsi/sg.h>	// workaround for broken RedHat 6.0 /usr/include/scsi
#include <unistd.h>
#include <errno.h>

#define DRIVER_SENSE 0x08

#include "main.h"
#include "prefs.h"
#include "user_strings.h"
#include "scsi.h"

#define DEBUG 0
#include "debug.h"


// Global variables
static int fds[8];				// fd's for 8 units
static int fd;					// Active fd (selected target)

static uint32 buffer_size;		// Size of data buffer
static uint8 *buffer = NULL;	// Pointer to data buffer

static uint8 the_cmd[12];		// Active SCSI command
static int the_cmd_len;


/*
 *  Initialization
 */

void SCSIInit(void)
{
	int id;

	// Allocate buffer
	buffer = (uint8 *)malloc(buffer_size = 0x10000);

	// Open generic SCSI driver for all 8 units
    for (id=0; id<8; id++) {
		char prefs_name[16];
		sprintf(prefs_name, "scsi%d", id);
		const char *str = PrefsFindString(prefs_name);
		if (str) {
			int fd = fds[id] = open(str, O_RDWR | O_EXCL);
			if (fd > 0) {
				// Is it really a Generic SCSI device?
				int timeout = ioctl(fd, SG_GET_TIMEOUT);
				if (timeout < 0) {
					// Error with SG_GET_TIMEOUT, doesn't seem to be a Generic SCSI device
					char msg[256];
					sprintf(msg, GetString(STR_SCSI_DEVICE_NOT_SCSI_WARN), str);
					WarningAlert(msg);
					close(fd);
					fds[id] = -1;
				} else {
					// Flush unwanted garbage from previous use of device
					uint8 reply[256];
					int old_fl = fcntl(fd, F_GETFL);
					fcntl(fd, F_SETFL, old_fl | O_NONBLOCK);
					while (read(fd, reply, sizeof(reply)) != -1 || errno != EAGAIN) ;
					fcntl(fd, F_SETFL, old_fl);
				}
			} else {
				char msg[256];
				sprintf(msg, GetString(STR_SCSI_DEVICE_OPEN_WARN), str, strerror(errno));
				WarningAlert(msg);
			}
		}
    }

	// Reset SCSI bus
	SCSIReset();
}


/*
 *  Deinitialization
 */

void SCSIExit(void)
{
	// Close all devices
	for (int i=0; i<8; i++) {
		int fd = fds[i];
		if (fd > 0)
			close(fd);
	}

	// Free buffer
	if (buffer) {
		free(buffer);
		buffer = NULL;
	}
}


/*
 *  Check if requested data size fits into buffer, allocate new buffer if needed
 */

static bool try_buffer(uint32 size)
{
	size += sizeof(sg_header) + 12;
	if (size <= buffer_size)
		return true;

	uint8 *new_buffer = (uint8 *)malloc(size);
	if (new_buffer == NULL)
		return false;
	free(buffer);
	buffer = new_buffer;
	buffer_size = size;
	return true;
}


/*
 *  Set SCSI command to be sent by scsi_send_cmd()
 */

void scsi_set_cmd(int cmd_length, uint8 *cmd)
{
	memcpy(the_cmd, cmd, the_cmd_len = cmd_length);
}


/*
 *  Check for presence of SCSI target
 */

bool scsi_is_target_present(int id)
{
	return fds[id] > 0;
}


/*
 *  Set SCSI target (returns false on error)
 */

bool scsi_set_target(int id, int lun)
{
	int new_fd = fds[id];
	if (new_fd < 0)
		return false;
	if (new_fd != fd) {
		// New target, clear autosense data
		sg_header *h = (sg_header *)buffer;
		h->driver_status &= ~DRIVER_SENSE;
	}
	fd = new_fd;
	return true;
}


/*
 *  Send SCSI command to active target (scsi_set_command() must have been called),
 *  read/write data according to S/G table (returns false on error); timeout is in 1/60 sec
 */

bool scsi_send_cmd(size_t data_length, bool reading, int sg_size, uint8 **sg_ptr, uint32 *sg_len, uint16 *stat, uint32 timeout)
{
	static int pack_id = 0;

	// Check if buffer is large enough, allocate new buffer if needed
	if (!try_buffer(data_length)) {
		char str[256];
		sprintf(str, GetString(STR_SCSI_BUFFER_ERR), data_length);
		ErrorAlert(str);
		return false;
	}

	// Process S/G table when writing
	if (!reading) {
		D(bug(" writing to buffer\n"));
		uint8 *buffer_ptr = buffer + sizeof(sg_header) + the_cmd_len;
		for (int i=0; i<sg_size; i++) {
			uint32 len = sg_len[i];
			D(bug("  %d bytes from %08lx\n", len, sg_ptr[i]));
			memcpy(buffer_ptr, sg_ptr[i], len);
			buffer_ptr += len;
		}
	}

	// Request Sense and autosense data valid?
	sg_header *h = (sg_header *)buffer;
	int res;
	if (reading && the_cmd[0] == 0x03 && (h->target_status & DRIVER_SENSE)) {

		// Yes, fake command
		D(bug(" autosense\n"));
		memcpy(buffer + sizeof(sg_header), h->sense_buffer, 16);
		h->target_status &= ~DRIVER_SENSE;
		res = 0;
		*stat = 0;

	} else {

		// No, send regular command
		if (timeout) {
			int to = timeout * HZ / 60;
			ioctl(fd, SG_SET_TIMEOUT, &to);
		}
		ioctl(fd, SG_NEXT_CMD_LEN, &the_cmd_len);

		D(bug(" sending command, length %d\n", data_length));

		int request_size, reply_size;
		if (reading) {
			h->pack_len = request_size = sizeof(sg_header) + the_cmd_len;
			h->reply_len = reply_size = sizeof(sg_header) + data_length;
		} else {
			h->pack_len = request_size = sizeof(sg_header) + the_cmd_len + data_length;
			h->reply_len = reply_size = sizeof(sg_header);
		}
		h->pack_id = pack_id++;
		h->result = 0;
		h->twelve_byte = (the_cmd_len == 12);
		h->target_status = 0;
		h->host_status = 0;
		h->driver_status = 0;
		h->other_flags = 0;
		memcpy(buffer + sizeof(sg_header), the_cmd, the_cmd_len);

		res = write(fd, buffer, request_size);
		D(bug(" request sent, actual %d, result %d\n", res, h->result));
		if (res >= 0) {
			res = read(fd, buffer, reply_size);
			D(bug(" reply read, actual %d, result %d, status %02x\n", res, h->result, h->target_status << 1));
		}

		*stat = h->target_status << 1;
	}

	// Process S/G table when reading
	if (reading && h->result == 0) {
		D(bug(" reading from buffer\n"));
		uint8 *buffer_ptr = buffer + sizeof(sg_header);
		for (int i=0; i<sg_size; i++) {
			uint32 len = sg_len[i];
			D(bug("  %d bytes to %08lx\n", len, sg_ptr[i]));
			memcpy(sg_ptr[i], buffer_ptr, len);
			buffer_ptr += len;
		}
	}
	return res >= 0;
}
