/*
 * 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/config.h>
#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/init.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;

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


/* 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", __FUNCTION__, 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 = (struct pci_resource*) 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 = (struct pci_resource*) 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 = (struct pci_resource*) 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 = (struct pci_resource*) 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;
}

