// SPDX-License-Identifier: GPL-2.0-or-later
/*
 * eisa_enumerator.c - provide support for EISA adapters in PA-RISC machines
 *
 * 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;
			pr_cont("memory %pR ", res);
			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);
		
		pr_cont("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);
		pr_cont("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;
			pr_cont("ioports %pR ", res);
			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 mismatch "
			       "got %d, expected %d\n",
			       num_func, pos-p0, function_len);
			res=-1;
			break;
		}
		pos = p0 + function_len;
	}
	pr_cont("\n");
	if (!id_string_used) {
		kfree(board);
	}
	
	if (pos != es->config_data_length) {
		printk(KERN_ERR "eisa_enumerator: config data length mismatch 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 mismatch 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 mismatch: 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;
}

