1 /* -*- linux-c -*- */
2 /*
3  * Copyright (C) 2001 By Joachim Martillo, Telford Tools, Inc.
4  *
5  * This program is free software; you can redistribute it and/or
6  * modify it under the terms of the GNU General Public License
7  * as published by the Free Software Foundation; either version
8  * 2 of the License, or (at your option) any later version.
9  *
10  */
11 				/* This file is linked in, but I am
12 				   not sure there is ever any
13 				   reason directly to read the
14 				   serial eprom on the multichannel
15 				   server host card. */
16 
17 /* We handle PCI devices */
18 #include <linux/pci.h>
19 
20 /* We need to use ioremap */
21 #include <asm/io.h>
22 
23 #include <linux/delay.h>
24 
25 #include "8253xmcs.h"
26 #include "8253xctl.h"
27 
28 /* read a byte out of the serial eeprom/nvram by means of
29  * 16 short commands */
30 
amcc_nvram_breadw(unsigned char * bridge_space,unsigned short address,unsigned char * value)31 static unsigned int amcc_nvram_breadw(unsigned char *bridge_space,
32 				      unsigned short address,
33 				      unsigned char *value)
34 {
35 	unsigned int count;
36 	unsigned rhr;
37 
38 	for(count = 0; count < 20000; ++count)
39 	{
40 		rhr = readl(bridge_space + AMCC_RCR);
41 		if((rhr & AMCC_NVRBUSY) == 0)
42 		{
43 			break;
44 		}
45 		udelay(1);
46 	}
47 	if(count >= 20000)
48 	{
49 		return FALSE;
50 	}
51 	rhr = AMCC_NVRWRLA | ((address & 0x00FF) << 16);
52 	writel(rhr, bridge_space + AMCC_RCR);
53 	rhr = AMCC_NVRWRHA | ((address & 0xFF00) << 8);
54 	writel(rhr, bridge_space + AMCC_RCR);
55 	writel(AMCC_NVRRDDB, bridge_space + AMCC_RCR);
56 	for(count = 0; count < 20000; ++count)
57 	{
58 		rhr = readl(bridge_space + AMCC_RCR);
59 		if((rhr & AMCC_NVRBUSY) == 0)
60 		{
61 			break;
62 		}
63 		udelay(1);
64 	}
65 	if(count >= 20000)
66 	{
67 		return FALSE;
68 	}
69 	if(rhr & AMCC_NVRACCFAIL)
70 	{
71 		return FALSE;
72 	}
73 	*value = (unsigned char) (rhr >> 16);
74 	return TRUE;
75 }
76 
77 /* read the whole serial eeprom from the host card */
78 
amcc_read_nvram(unsigned char * buffer,unsigned length,unsigned char * bridge_space)79 unsigned int amcc_read_nvram(unsigned char* buffer, unsigned length, unsigned char *bridge_space)
80 {
81 	unsigned int count;
82 	length <<= 1;			/* covert words to bytes */
83 
84 	for(count = 0; count < length; ++count)
85 	{
86 		if(amcc_nvram_breadw(bridge_space, count, &buffer[count]) == FALSE)
87 		{
88 			return FALSE;
89 		}
90 	}
91 	return TRUE;
92 }
93