/*
 * eisa_enumerator.c - provide support for EISA adapters in PA-RISC machines
 *
 * 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.
 *
 * Copyright (c) 2002 Daniel Engstrom <5116@telia.com>
 *
 */

#include <linux/ioport.h>
#include <linux/init.h>
#include <linux/kernel.h>
#include <linux/slab.h>
#include <asm/io.h>
#include <linux/uaccess.h>
#include <asm/byteorder.h>

#include <asm/eisa_bus.h>
#include <asm/eisa_eeprom.h>


/*
 * Todo:
 * 
 * PORT init with MASK attr and other size than byte
 * MEMORY with other decode than 20 bit
 * CRC stuff
 * FREEFORM stuff
 */

#define EPI 0xc80
#define NUM_SLOT 16
#define SLOT2PORT(x) (x<<12)


/* macros to handle unaligned accesses and 
 * byte swapping. The data in the EEPROM is
 * little-endian on the big-endian PAROSC */
#define get_8(x) (*(u_int8_t*)(x))

static inline u_int16_t get_16(const unsigned char *x)
{ 
	return (x[1] << 8) | x[0];
}

static inline u_int32_t get_32(const unsigned char *x)
{
	return (x[3] << 24) | (x[2] << 16) | (x[1] << 8) | x[0];
}

static inline u_int32_t get_24(const unsigned char *x)
{
	return (x[2] << 24) | (x[1] << 16) | (x[0] << 8);
}

static void print_eisa_id(char *s, u_int32_t id)
{
	char vendor[4];
	int rev;
	int device;
	
	rev = id & 0xff;
	id >>= 8;
	device = id & 0xff;
	id >>= 8;
	vendor[3] = '\0';
	vendor[2] = '@' + (id & 0x1f);
	id >>= 5;	
	vendor[1] = '@' + (id & 0x1f);
	id >>= 5;	
	vendor[0] = '@' + (id & 0x1f);
	id >>= 5;	
	
	sprintf(s, "%s%02X%02X", vendor, device, rev);
}
       
static int configure_memory(const unsigned char *buf, 
		       struct resource *mem_parent,
		       char *name)
{
	int len;
	u_int8_t c;
	int i;
	struct resource *res;
	
	len=0;
	
	for (i=0;i<HPEE_MEMORY_MAX_ENT;i++) {
		c = get_8(buf+len);
		
		if (NULL != (res = kzalloc(sizeof(struct resource), GFP_KERNEL))) {
			int result;
			
			res->name = name;
			res->start = mem_parent->start + get_24(buf+len+2);
			res->end = res->start + get_16(buf+len+5)*1024;
			res->flags = IORESOURCE_MEM;
			printk("memory %lx-%lx ", (unsigned long)res->start, (unsigned long)res->end);
			result = request_resource(mem_parent, res);
			if (result < 0) {
				printk(KERN_ERR "EISA Enumerator: failed to claim EISA Bus address space!\n");
				return result;
			}
		}
		 	
		len+=7;      
	
		if (!(c & HPEE_MEMORY_MORE)) {
			break;
		}
	}
	
	return len;
}


static int configure_irq(const unsigned char *buf)
{
	int len;
	u_int8_t c;
	int i;
	
	len=0;
	
	for (i=0;i<HPEE_IRQ_MAX_ENT;i++) {
		c = get_8(buf+len);
		
		printk("IRQ %d ", c & HPEE_IRQ_CHANNEL_MASK);
		if (c & HPEE_IRQ_TRIG_LEVEL) {
			eisa_make_irq_level(c & HPEE_IRQ_CHANNEL_MASK);
		} else {
			eisa_make_irq_edge(c & HPEE_IRQ_CHANNEL_MASK);
		}
		
		len+=2; 
		/* hpux seems to allow for
		 * two bytes of irq data but only defines one of
		 * them, I think */
		if  (!(c & HPEE_IRQ_MORE)) {
			break;
		}
	}
	
	return len;
}


static int configure_dma(const unsigned char *buf)
{
	int len;
	u_int8_t c;
	int i;
	
	len=0;
	
	for (i=0;i<HPEE_DMA_MAX_ENT;i++) {
		c = get_8(buf+len);
		printk("DMA %d ", c&HPEE_DMA_CHANNEL_MASK);
		/* fixme: maybe initialize the dma channel withthe timing ? */
		len+=2;      
		if (!(c & HPEE_DMA_MORE)) {
			break;
		}
	}
	
	return len;
}

static int configure_port(const unsigned char *buf, struct resource *io_parent,
		     char *board)
{
	int len;
	u_int8_t c;
	int i;
	struct resource *res;
	int result;
	
	len=0;
	
	for (i=0;i<HPEE_PORT_MAX_ENT;i++) {
		c = get_8(buf+len);
		
		if (NULL != (res = kzalloc(sizeof(struct resource), GFP_KERNEL))) {
			res->name = board;
			res->start = get_16(buf+len+1);
			res->end = get_16(buf+len+1)+(c&HPEE_PORT_SIZE_MASK)+1;
			res->flags = IORESOURCE_IO;
			printk("ioports %lx-%lx ", (unsigned long)res->start, (unsigned long)res->end);
			result = request_resource(io_parent, res);
			if (result < 0) {
				printk(KERN_ERR "EISA Enumerator: failed to claim EISA Bus address space!\n");
				return result;
			}
		}

		len+=3;      
		if (!(c & HPEE_PORT_MORE)) {
			break;
		}
	}
	
	return len;
}


/* byte 1 and 2 is the port number to write
 * and at byte 3 the value to write starts.
 * I assume that there are and- and or- masks
 * here when HPEE_PORT_INIT_MASK is set but I have 
 * not yet encountered this. */
static int configure_port_init(const unsigned char *buf)
{
	int len=0;
	u_int8_t c;
	
	while (len<HPEE_PORT_INIT_MAX_LEN) {
		int s=0;
		c = get_8(buf+len);
		
		switch (c & HPEE_PORT_INIT_WIDTH_MASK)  {
		 case HPEE_PORT_INIT_WIDTH_BYTE:
			s=1;
			if (c & HPEE_PORT_INIT_MASK) {
				printk(KERN_WARNING "port_init: unverified mask attribute\n");
				outb((inb(get_16(buf+len+1) & 
					  get_8(buf+len+3)) | 
				      get_8(buf+len+4)), get_16(buf+len+1));
				      
			} else {
				outb(get_8(buf+len+3), get_16(buf+len+1));
				      
			}
			break;
		 case HPEE_PORT_INIT_WIDTH_WORD:
			s=2;
			if (c & HPEE_PORT_INIT_MASK) {
 				printk(KERN_WARNING "port_init: unverified mask attribute\n");
				       outw((inw(get_16(buf+len+1)) &
					     get_16(buf+len+3)) |
					    get_16(buf+len+5), 
					    get_16(buf+len+1));
			} else {
				outw(cpu_to_le16(get_16(buf+len+3)), get_16(buf+len+1));
			}
			break;
		 case HPEE_PORT_INIT_WIDTH_DWORD:
			s=4;
			if (c & HPEE_PORT_INIT_MASK) {
 				printk(KERN_WARNING "port_init: unverified mask attribute\n");
				outl((inl(get_16(buf+len+1) &
					  get_32(buf+len+3)) |
				      get_32(buf+len+7)), get_16(buf+len+1));
			} else {
				outl(cpu_to_le32(get_32(buf+len+3)), get_16(buf+len+1));
			}

			break;
		 default:
			printk(KERN_ERR "Invalid port init word %02x\n", c);
			return 0;
		}
		
		if (c & HPEE_PORT_INIT_MASK) {   
			s*=2;
		}
		
		len+=s+3;
		if (!(c & HPEE_PORT_INIT_MORE)) {
			break;
		}
	}
	
	return len;
}

static int configure_choise(const unsigned char *buf, u_int8_t *info)
{
	int len;
	
	/* theis record contain the value of the functions
	 * configuration choises and an info byte which 
	 * describes which other records to expect in this 
	 * function */
	len = get_8(buf);
	*info=get_8(buf+len+1);
	 
	return len+2;
}

static int configure_type_string(const unsigned char *buf) 
{
	int len;
	
	/* just skip past the type field */
	len = get_8(buf);
	if (len > 80) {
		printk(KERN_ERR "eisa_enumerator: type info field too long (%d, max is 80)\n", len);
	}
	
	return 1+len;
}

static int configure_function(const unsigned char *buf, int *more) 
{
	/* the init field seems to be a two-byte field
	 * which is non-zero if there are an other function following
	 * I think it is the length of the function def 
	 */
	*more = get_16(buf);
	
	return 2;
}

static int parse_slot_config(int slot,
			     const unsigned char *buf,
			     struct eeprom_eisa_slot_info *es, 
			     struct resource *io_parent,
			     struct resource *mem_parent)
{
	int res=0;
	int function_len;
	unsigned int pos=0;
	unsigned int maxlen;
	int num_func=0;
	u_int8_t flags;
	int p0;
	
	char *board;
	int id_string_used=0;
	
	if (NULL == (board = kmalloc(8, GFP_KERNEL))) {
		return -1;
	}
	print_eisa_id(board, es->eisa_slot_id);
	printk(KERN_INFO "EISA slot %d: %s %s ", 
	       slot, board, es->flags&HPEE_FLAG_BOARD_IS_ISA ? "ISA" : "EISA");
	
	maxlen = es->config_data_length < HPEE_MAX_LENGTH ?
			 es->config_data_length : HPEE_MAX_LENGTH;
	while ((pos < maxlen) && (num_func <= es->num_functions)) {
		pos+=configure_function(buf+pos, &function_len); 
		
		if (!function_len) {
			break;
		}
		num_func++;
		p0 = pos;
		pos += configure_choise(buf+pos, &flags);

		if (flags & HPEE_FUNCTION_INFO_F_DISABLED) {
			/* function disabled, skip silently */
			pos = p0 + function_len;
			continue;
		}
		if (flags & HPEE_FUNCTION_INFO_CFG_FREE_FORM) {
			/* I have no idea how to handle this */
			printk("function %d have free-form configuration, skipping ",
				num_func);
			pos = p0 + function_len;
			continue;
		}

		/* the ordering of the sections need
		 * more investigation.
		 * Currently I think that memory comaed before IRQ
		 * I assume the order is LSB to MSB in the 
		 * info flags 
		 * eg type, memory, irq, dma, port, HPEE_PORT_init 
		 */

		if (flags & HPEE_FUNCTION_INFO_HAVE_TYPE) {
			pos += configure_type_string(buf+pos);
		}
		
		if (flags & HPEE_FUNCTION_INFO_HAVE_MEMORY) {
			id_string_used=1;
			pos += configure_memory(buf+pos, mem_parent, board);
		} 
		
		if (flags & HPEE_FUNCTION_INFO_HAVE_IRQ) {
			pos += configure_irq(buf+pos);
		} 
		
		if (flags & HPEE_FUNCTION_INFO_HAVE_DMA) {
			pos += configure_dma(buf+pos);
		} 
		
		if (flags & HPEE_FUNCTION_INFO_HAVE_PORT) {
			id_string_used=1;
			pos += configure_port(buf+pos, io_parent, board);
		} 
		
		if (flags &  HPEE_FUNCTION_INFO_HAVE_PORT_INIT) {
			pos += configure_port_init(buf+pos);
		}
		
		if (p0 + function_len < pos) {
			printk(KERN_ERR "eisa_enumerator: function %d length mis-match "
			       "got %d, expected %d\n",
			       num_func, pos-p0, function_len);
			res=-1;
			break;
		}
		pos = p0 + function_len;
	}
	printk("\n");
	if (!id_string_used) {
		kfree(board);
	}
	
	if (pos != es->config_data_length) {
		printk(KERN_ERR "eisa_enumerator: config data length mis-match got %d, expected %d\n",
			pos, es->config_data_length);
		res=-1;
	}
	
	if (num_func != es->num_functions) {
		printk(KERN_ERR "eisa_enumerator: number of functions mis-match got %d, expected %d\n",
			num_func, es->num_functions);
		res=-2;
	}
	
	return res;
	
}

static int init_slot(int slot, struct eeprom_eisa_slot_info *es)
{
	unsigned int id;
	
	char id_string[8];
	
	if (!(es->slot_info&HPEE_SLOT_INFO_NO_READID)) {
		/* try to read the id of the board in the slot */
		id = le32_to_cpu(inl(SLOT2PORT(slot)+EPI));
		
		if (0xffffffff == id) {
			/* Maybe we didn't expect a card to be here... */
			if (es->eisa_slot_id == 0xffffffff)
				return -1;
			
			/* this board is not here or it does not 
			 * support readid 
			 */
			printk(KERN_ERR "EISA slot %d a configured board was not detected (", 
			       slot);
			
			print_eisa_id(id_string, es->eisa_slot_id);
			printk(" expected %s)\n", id_string);
		
			return -1;	

		}
		if (es->eisa_slot_id != id) {
			print_eisa_id(id_string, id);
			printk(KERN_ERR "EISA slot %d id mis-match: got %s", 
			       slot, id_string);
			
			print_eisa_id(id_string, es->eisa_slot_id);
			printk(" expected %s\n", id_string);
		
			return -1;	
			
		}
	}
	
	/* now: we need to enable the board if 
	 * it supports enabling and run through
	 * the port init sction if present
	 * and finally record any interrupt polarity
	 */
	if (es->slot_features & HPEE_SLOT_FEATURES_ENABLE) {
		/* enable board */
		outb(0x01| inb(SLOT2PORT(slot)+EPI+4),
		     SLOT2PORT(slot)+EPI+4);
	}
	
	return 0;
}


int eisa_enumerator(unsigned long eeprom_addr,
		    struct resource *io_parent, struct resource *mem_parent) 
{
	int i;
	struct eeprom_header *eh;
	static char eeprom_buf[HPEE_MAX_LENGTH];
	
	for (i=0; i < HPEE_MAX_LENGTH; i++) {
		eeprom_buf[i] = gsc_readb(eeprom_addr+i);
	}
	
	printk(KERN_INFO "Enumerating EISA bus\n");
		    	
	eh = (struct eeprom_header*)(eeprom_buf);
	for (i=0;i<eh->num_slots;i++) {
		struct eeprom_eisa_slot_info *es;
		
		es = (struct eeprom_eisa_slot_info*)
			(&eeprom_buf[HPEE_SLOT_INFO(i)]);
	        
		if (-1==init_slot(i+1, es)) {
			continue;
		}
		
		if (es->config_data_offset < HPEE_MAX_LENGTH) {
			if (parse_slot_config(i+1, &eeprom_buf[es->config_data_offset],
					      es, io_parent, mem_parent)) {
				return -1;
			}
		} else {
			printk (KERN_WARNING "EISA EEPROM offset 0x%x out of range\n",es->config_data_offset);
			return -1;
		}
	}
	return eh->num_slots;
}

