/*
 * Compaq Hot Plug Controller Driver
 *
 * Copyright (C) 1995,2001 Compaq Computer Corporation
 * Copyright (C) 2001 Greg Kroah-Hartman (greg@kroah.com)
 * Copyright (C) 2001 IBM Corp.
 *
 * All rights reserved.
 *
 * 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, GOOD TITLE or
 * NON INFRINGEMENT.  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.
 *
 * Send feedback to <greg@kroah.com>
 *
 */

#include <linux/module.h>
#include <linux/kernel.h>
#include <linux/types.h>
#include <linux/proc_fs.h>
#include <linux/slab.h>
#include <linux/workqueue.h>
#include <linux/pci.h>
#include <linux/pci_hotplug.h>
#include <asm/uaccess.h>
#include "cpqphp.h"
#include "cpqphp_nvram.h"


#define ROM_INT15_PHY_ADDR		0x0FF859
#define READ_EV				0xD8A4
#define WRITE_EV			0xD8A5

struct register_foo {
	union {
		unsigned long lword;		/* eax */
		unsigned short word;		/* ax */

		struct {
			unsigned char low;	/* al */
			unsigned char high;	/* ah */
		} byte;
	} data;

	unsigned char opcode;	/* see below */
	unsigned long length;	/* if the reg. is a pointer, how much data */
} __attribute__ ((packed));

struct all_reg {
	struct register_foo eax_reg;
	struct register_foo ebx_reg;
	struct register_foo ecx_reg;
	struct register_foo edx_reg;
	struct register_foo edi_reg;
	struct register_foo esi_reg;
	struct register_foo eflags_reg;
} __attribute__ ((packed));


struct ev_hrt_header {
	u8 Version;
	u8 num_of_ctrl;
	u8 next;
};

struct ev_hrt_ctrl {
	u8 bus;
	u8 device;
	u8 function;
	u8 mem_avail;
	u8 p_mem_avail;
	u8 io_avail;
	u8 bus_avail;
	u8 next;
};


static u8 evbuffer_init;
static u8 evbuffer_length;
static u8 evbuffer[1024];

static void __iomem *compaq_int15_entry_point;

/* lock for ordering int15_bios_call() */
static spinlock_t int15_lock;


/* This is a series of function that deals with
 * setting & getting the hotplug resource table in some environment variable.
 */

/*
 * We really shouldn't be doing this unless there is a _very_ good reason to!!!
 * greg k-h
 */


static u32 add_byte(u32 **p_buffer, u8 value, u32 *used, u32 *avail)
{
	u8 **tByte;

	if ((*used + 1) > *avail)
		return(1);

	*((u8*)*p_buffer) = value;
	tByte = (u8**)p_buffer;
	(*tByte)++;
	*used+=1;
	return(0);
}


static u32 add_dword(u32 **p_buffer, u32 value, u32 *used, u32 *avail)
{
	if ((*used + 4) > *avail)
		return(1);

	**p_buffer = value;
	(*p_buffer)++;
	*used+=4;
	return(0);
}


/*
 * check_for_compaq_ROM
 *
 * this routine verifies that the ROM OEM string is 'COMPAQ'
 *
 * returns 0 for non-Compaq ROM, 1 for Compaq ROM
 */
static int check_for_compaq_ROM (void __iomem *rom_start)
{
	u8 temp1, temp2, temp3, temp4, temp5, temp6;
	int result = 0;

	temp1 = readb(rom_start + 0xffea + 0);
	temp2 = readb(rom_start + 0xffea + 1);
	temp3 = readb(rom_start + 0xffea + 2);
	temp4 = readb(rom_start + 0xffea + 3);
	temp5 = readb(rom_start + 0xffea + 4);
	temp6 = readb(rom_start + 0xffea + 5);
	if ((temp1 == 'C') &&
	    (temp2 == 'O') &&
	    (temp3 == 'M') &&
	    (temp4 == 'P') &&
	    (temp5 == 'A') &&
	    (temp6 == 'Q')) {
		result = 1;
	}
	dbg ("%s - returned %d\n", __func__, result);
	return result;
}


static u32 access_EV (u16 operation, u8 *ev_name, u8 *buffer, u32 *buf_size)
{
	unsigned long flags;
	int op = operation;
	int ret_val;

	if (!compaq_int15_entry_point)
		return -ENODEV;

	spin_lock_irqsave(&int15_lock, flags);
	__asm__ (
		"xorl   %%ebx,%%ebx\n" \
		"xorl    %%edx,%%edx\n" \
		"pushf\n" \
		"push %%cs\n" \
		"cli\n" \
		"call *%6\n"
		: "=c" (*buf_size), "=a" (ret_val)
		: "a" (op), "c" (*buf_size), "S" (ev_name),
		"D" (buffer), "m" (compaq_int15_entry_point)
		: "%ebx", "%edx");
	spin_unlock_irqrestore(&int15_lock, flags);

	return((ret_val & 0xFF00) >> 8);
}


/*
 * load_HRT
 *
 * Read the hot plug Resource Table from NVRAM
 */
static int load_HRT (void __iomem *rom_start)
{
	u32 available;
	u32 temp_dword;
	u8 temp_byte = 0xFF;
	u32 rc;

	if (!check_for_compaq_ROM(rom_start)) {
		return -ENODEV;
	}

	available = 1024;

	/* Now load the EV */
	temp_dword = available;

	rc = access_EV(READ_EV, "CQTHPS", evbuffer, &temp_dword);

	evbuffer_length = temp_dword;

	/* We're maintaining the resource lists so write FF to invalidate old
	 * info
	 */
	temp_dword = 1;

	rc = access_EV(WRITE_EV, "CQTHPS", &temp_byte, &temp_dword);

	return rc;
}


/*
 * store_HRT
 *
 * Save the hot plug Resource Table in NVRAM
 */
static u32 store_HRT (void __iomem *rom_start)
{
	u32 *buffer;
	u32 *pFill;
	u32 usedbytes;
	u32 available;
	u32 temp_dword;
	u32 rc;
	u8 loop;
	u8 numCtrl = 0;
	struct controller *ctrl;
	struct pci_resource *resNode;
	struct ev_hrt_header *p_EV_header;
	struct ev_hrt_ctrl *p_ev_ctrl;

	available = 1024;

	if (!check_for_compaq_ROM(rom_start)) {
		return(1);
	}

	buffer = (u32*) evbuffer;

	if (!buffer)
		return(1);

	pFill = buffer;
	usedbytes = 0;

	p_EV_header = (struct ev_hrt_header *) pFill;

	ctrl = cpqhp_ctrl_list;

	/* The revision of this structure */
	rc = add_byte(&pFill, 1 + ctrl->push_flag, &usedbytes, &available);
	if (rc)
		return(rc);

	/* The number of controllers */
	rc = add_byte(&pFill, 1, &usedbytes, &available);
	if (rc)
		return(rc);

	while (ctrl) {
		p_ev_ctrl = (struct ev_hrt_ctrl *) pFill;

		numCtrl++;

		/* The bus number */
		rc = add_byte(&pFill, ctrl->bus, &usedbytes, &available);
		if (rc)
			return(rc);

		/* The device Number */
		rc = add_byte(&pFill, PCI_SLOT(ctrl->pci_dev->devfn), &usedbytes, &available);
		if (rc)
			return(rc);

		/* The function Number */
		rc = add_byte(&pFill, PCI_FUNC(ctrl->pci_dev->devfn), &usedbytes, &available);
		if (rc)
			return(rc);

		/* Skip the number of available entries */
		rc = add_dword(&pFill, 0, &usedbytes, &available);
		if (rc)
			return(rc);

		/* Figure out memory Available */

		resNode = ctrl->mem_head;

		loop = 0;

		while (resNode) {
			loop ++;

			/* base */
			rc = add_dword(&pFill, resNode->base, &usedbytes, &available);
			if (rc)
				return(rc);

			/* length */
			rc = add_dword(&pFill, resNode->length, &usedbytes, &available);
			if (rc)
				return(rc);

			resNode = resNode->next;
		}

		/* Fill in the number of entries */
		p_ev_ctrl->mem_avail = loop;

		/* Figure out prefetchable memory Available */

		resNode = ctrl->p_mem_head;

		loop = 0;

		while (resNode) {
			loop ++;

			/* base */
			rc = add_dword(&pFill, resNode->base, &usedbytes, &available);
			if (rc)
				return(rc);

			/* length */
			rc = add_dword(&pFill, resNode->length, &usedbytes, &available);
			if (rc)
				return(rc);

			resNode = resNode->next;
		}

		/* Fill in the number of entries */
		p_ev_ctrl->p_mem_avail = loop;

		/* Figure out IO Available */

		resNode = ctrl->io_head;

		loop = 0;

		while (resNode) {
			loop ++;

			/* base */
			rc = add_dword(&pFill, resNode->base, &usedbytes, &available);
			if (rc)
				return(rc);

			/* length */
			rc = add_dword(&pFill, resNode->length, &usedbytes, &available);
			if (rc)
				return(rc);

			resNode = resNode->next;
		}

		/* Fill in the number of entries */
		p_ev_ctrl->io_avail = loop;

		/* Figure out bus Available */

		resNode = ctrl->bus_head;

		loop = 0;

		while (resNode) {
			loop ++;

			/* base */
			rc = add_dword(&pFill, resNode->base, &usedbytes, &available);
			if (rc)
				return(rc);

			/* length */
			rc = add_dword(&pFill, resNode->length, &usedbytes, &available);
			if (rc)
				return(rc);

			resNode = resNode->next;
		}

		/* Fill in the number of entries */
		p_ev_ctrl->bus_avail = loop;

		ctrl = ctrl->next;
	}

	p_EV_header->num_of_ctrl = numCtrl;

	/* Now store the EV */

	temp_dword = usedbytes;

	rc = access_EV(WRITE_EV, "CQTHPS", (u8*) buffer, &temp_dword);

	dbg("usedbytes = 0x%x, length = 0x%x\n", usedbytes, temp_dword);

	evbuffer_length = temp_dword;

	if (rc) {
		err(msg_unable_to_save);
		return(1);
	}

	return(0);
}


void compaq_nvram_init (void __iomem *rom_start)
{
	if (rom_start) {
		compaq_int15_entry_point = (rom_start + ROM_INT15_PHY_ADDR - ROM_PHY_ADDR);
	}
	dbg("int15 entry  = %p\n", compaq_int15_entry_point);

	/* initialize our int15 lock */
	spin_lock_init(&int15_lock);
}


int compaq_nvram_load (void __iomem *rom_start, struct controller *ctrl)
{
	u8 bus, device, function;
	u8 nummem, numpmem, numio, numbus;
	u32 rc;
	u8 *p_byte;
	struct pci_resource *mem_node;
	struct pci_resource *p_mem_node;
	struct pci_resource *io_node;
	struct pci_resource *bus_node;
	struct ev_hrt_ctrl *p_ev_ctrl;
	struct ev_hrt_header *p_EV_header;

	if (!evbuffer_init) {
		/* Read the resource list information in from NVRAM */
		if (load_HRT(rom_start))
			memset (evbuffer, 0, 1024);

		evbuffer_init = 1;
	}

	/* If we saved information in NVRAM, use it now */
	p_EV_header = (struct ev_hrt_header *) evbuffer;

	/* The following code is for systems where version 1.0 of this
	 * driver has been loaded, but doesn't support the hardware.
	 * In that case, the driver would incorrectly store something
	 * in NVRAM.
	 */
	if ((p_EV_header->Version == 2) ||
	    ((p_EV_header->Version == 1) && !ctrl->push_flag)) {
		p_byte = &(p_EV_header->next);

		p_ev_ctrl = (struct ev_hrt_ctrl *) &(p_EV_header->next);

		p_byte += 3;

		if (p_byte > ((u8*)p_EV_header + evbuffer_length))
			return 2;

		bus = p_ev_ctrl->bus;
		device = p_ev_ctrl->device;
		function = p_ev_ctrl->function;

		while ((bus != ctrl->bus) ||
		       (device != PCI_SLOT(ctrl->pci_dev->devfn)) ||
		       (function != PCI_FUNC(ctrl->pci_dev->devfn))) {
			nummem = p_ev_ctrl->mem_avail;
			numpmem = p_ev_ctrl->p_mem_avail;
			numio = p_ev_ctrl->io_avail;
			numbus = p_ev_ctrl->bus_avail;

			p_byte += 4;

			if (p_byte > ((u8*)p_EV_header + evbuffer_length))
				return 2;

			/* Skip forward to the next entry */
			p_byte += (nummem + numpmem + numio + numbus) * 8;

			if (p_byte > ((u8*)p_EV_header + evbuffer_length))
				return 2;

			p_ev_ctrl = (struct ev_hrt_ctrl *) p_byte;

			p_byte += 3;

			if (p_byte > ((u8*)p_EV_header + evbuffer_length))
				return 2;

			bus = p_ev_ctrl->bus;
			device = p_ev_ctrl->device;
			function = p_ev_ctrl->function;
		}

		nummem = p_ev_ctrl->mem_avail;
		numpmem = p_ev_ctrl->p_mem_avail;
		numio = p_ev_ctrl->io_avail;
		numbus = p_ev_ctrl->bus_avail;

		p_byte += 4;

		if (p_byte > ((u8*)p_EV_header + evbuffer_length))
			return 2;

		while (nummem--) {
			mem_node = kmalloc(sizeof(struct pci_resource), GFP_KERNEL);

			if (!mem_node)
				break;

			mem_node->base = *(u32*)p_byte;
			dbg("mem base = %8.8x\n",mem_node->base);
			p_byte += 4;

			if (p_byte > ((u8*)p_EV_header + evbuffer_length)) {
				kfree(mem_node);
				return 2;
			}

			mem_node->length = *(u32*)p_byte;
			dbg("mem length = %8.8x\n",mem_node->length);
			p_byte += 4;

			if (p_byte > ((u8*)p_EV_header + evbuffer_length)) {
				kfree(mem_node);
				return 2;
			}

			mem_node->next = ctrl->mem_head;
			ctrl->mem_head = mem_node;
		}

		while (numpmem--) {
			p_mem_node = kmalloc(sizeof(struct pci_resource), GFP_KERNEL);

			if (!p_mem_node)
				break;

			p_mem_node->base = *(u32*)p_byte;
			dbg("pre-mem base = %8.8x\n",p_mem_node->base);
			p_byte += 4;

			if (p_byte > ((u8*)p_EV_header + evbuffer_length)) {
				kfree(p_mem_node);
				return 2;
			}

			p_mem_node->length = *(u32*)p_byte;
			dbg("pre-mem length = %8.8x\n",p_mem_node->length);
			p_byte += 4;

			if (p_byte > ((u8*)p_EV_header + evbuffer_length)) {
				kfree(p_mem_node);
				return 2;
			}

			p_mem_node->next = ctrl->p_mem_head;
			ctrl->p_mem_head = p_mem_node;
		}

		while (numio--) {
			io_node = kmalloc(sizeof(struct pci_resource), GFP_KERNEL);

			if (!io_node)
				break;

			io_node->base = *(u32*)p_byte;
			dbg("io base = %8.8x\n",io_node->base);
			p_byte += 4;

			if (p_byte > ((u8*)p_EV_header + evbuffer_length)) {
				kfree(io_node);
				return 2;
			}

			io_node->length = *(u32*)p_byte;
			dbg("io length = %8.8x\n",io_node->length);
			p_byte += 4;

			if (p_byte > ((u8*)p_EV_header + evbuffer_length)) {
				kfree(io_node);
				return 2;
			}

			io_node->next = ctrl->io_head;
			ctrl->io_head = io_node;
		}

		while (numbus--) {
			bus_node = kmalloc(sizeof(struct pci_resource), GFP_KERNEL);

			if (!bus_node)
				break;

			bus_node->base = *(u32*)p_byte;
			p_byte += 4;

			if (p_byte > ((u8*)p_EV_header + evbuffer_length)) {
				kfree(bus_node);
				return 2;
			}

			bus_node->length = *(u32*)p_byte;
			p_byte += 4;

			if (p_byte > ((u8*)p_EV_header + evbuffer_length)) {
				kfree(bus_node);
				return 2;
			}

			bus_node->next = ctrl->bus_head;
			ctrl->bus_head = bus_node;
		}

		/* If all of the following fail, we don't have any resources for
		 * hot plug add
		 */
		rc = 1;
		rc &= cpqhp_resource_sort_and_combine(&(ctrl->mem_head));
		rc &= cpqhp_resource_sort_and_combine(&(ctrl->p_mem_head));
		rc &= cpqhp_resource_sort_and_combine(&(ctrl->io_head));
		rc &= cpqhp_resource_sort_and_combine(&(ctrl->bus_head));

		if (rc)
			return(rc);
	} else {
		if ((evbuffer[0] != 0) && (!ctrl->push_flag))
			return 1;
	}

	return 0;
}


int compaq_nvram_store (void __iomem *rom_start)
{
	int rc = 1;

	if (rom_start == NULL)
		return -ENODEV;

	if (evbuffer_init) {
		rc = store_HRT(rom_start);
		if (rc) {
			err(msg_unable_to_save);
		}
	}
	return rc;
}

