Browse Source

Abstracted out part of the concept of an SPI device to a generalised NVS

device.

Separated the mechanisms of non-volatile storage access and non-volatile
stored options.
tags/v0.9.3
Michael Brown 18 years ago
parent
commit
946967f09c

+ 109
- 0
src/core/nvo.c View File

@@ -0,0 +1,109 @@
1
+/*
2
+ * Copyright (C) 2006 Michael Brown <mbrown@fensystems.co.uk>.
3
+ *
4
+ * This program is free software; you can redistribute it and/or
5
+ * modify it under the terms of the GNU General Public License as
6
+ * published by the Free Software Foundation; either version 2 of the
7
+ * License, or any later version.
8
+ *
9
+ * This program is distributed in the hope that it will be useful, but
10
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
11
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
12
+ * General Public License for more details.
13
+ *
14
+ * You should have received a copy of the GNU General Public License
15
+ * along with this program; if not, write to the Free Software
16
+ * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
17
+ */
18
+
19
+#include <stdint.h>
20
+#include <string.h>
21
+#include <gpxe/dhcp.h>
22
+#include <gpxe/nvs.h>
23
+#include <gpxe/nvo.h>
24
+
25
+/** @file
26
+ *
27
+ * Non-volatile stored options
28
+ *
29
+ */
30
+
31
+static size_t nvo_options_len ( struct nvs_options *nvo ) {
32
+	struct dhcp_option *option;
33
+	uint8_t sum;
34
+	unsigned int i;
35
+	size_t len;
36
+
37
+	for ( sum = 0, i = 0 ; i < nvo->nvs->size ; i++ ) {
38
+		sum += * ( ( uint8_t * ) ( nvo->options->data + i ) );
39
+	}
40
+	if ( sum != 0 ) {
41
+		DBG ( "NVO %p has bad checksum %02x; assuming empty\n",
42
+		      nvo, sum );
43
+		return 0;
44
+	}
45
+
46
+	option = nvo->options->data;
47
+	if ( option->tag == DHCP_PAD ) {
48
+		DBG ( "NVO %p has bad start; assuming empty\n", nvo );
49
+		return 0;
50
+	}
51
+	
52
+	option = find_dhcp_option ( nvo->options, DHCP_END );
53
+	if ( ! option ) {
54
+		DBG ( "NVO %p has no end tag; assuming empty\n", nvo );
55
+		return 0;
56
+	}
57
+
58
+	len = ( ( void * ) option - nvo->options->data + 1 );
59
+	DBG ( "NVO %p contains %zd bytes of options (maximum %zd)\n",
60
+	      nvo, len, nvo->nvs->size );
61
+
62
+	return len;
63
+}
64
+
65
+int nvo_register ( struct nvs_options *nvo ) {
66
+	struct dhcp_option *option;
67
+	int rc;
68
+
69
+	nvo->options = alloc_dhcp_options ( nvo->nvs->size );
70
+	if ( ! nvo->options ) {
71
+		DBG ( "NVO %p could not allocate %zd bytes\n",
72
+		      nvo, nvo->nvs->size );
73
+		rc = -ENOMEM;
74
+		goto err;
75
+	}
76
+
77
+	if ( ( rc = nvo->nvs->read ( nvo->nvs, 0, nvo->options->data,
78
+				     nvo->nvs->size ) ) != 0 ) {
79
+		DBG ( "NVO %p could not read [0,%zd)\n",
80
+		      nvo, nvo->nvs->size );
81
+		goto err;
82
+	}
83
+
84
+	nvo->options->len = nvo->options->max_len;
85
+	nvo->options->len = nvo_options_len ( nvo );
86
+	if ( ! nvo->options->len ) {
87
+		option = nvo->options->data;
88
+		option->tag = DHCP_END;
89
+		nvo->options->len = 1;
90
+	}
91
+
92
+	register_dhcp_options ( nvo->options );
93
+
94
+	return 0;
95
+	
96
+ err:
97
+	
98
+	free_dhcp_options ( nvo->options );
99
+	nvo->options = NULL;
100
+	return rc;
101
+}
102
+
103
+void nvo_unregister ( struct nvs_options *nvo ) {
104
+	if ( nvo->options ) {
105
+		unregister_dhcp_options ( nvo->options );
106
+		free_dhcp_options ( nvo->options );
107
+		nvo->options = NULL;
108
+	}
109
+}

+ 0
- 106
src/core/nvs.c View File

@@ -1,106 +0,0 @@
1
-/*
2
- * Copyright (C) 2006 Michael Brown <mbrown@fensystems.co.uk>.
3
- *
4
- * This program is free software; you can redistribute it and/or
5
- * modify it under the terms of the GNU General Public License as
6
- * published by the Free Software Foundation; either version 2 of the
7
- * License, or any later version.
8
- *
9
- * This program is distributed in the hope that it will be useful, but
10
- * WITHOUT ANY WARRANTY; without even the implied warranty of
11
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
12
- * General Public License for more details.
13
- *
14
- * You should have received a copy of the GNU General Public License
15
- * along with this program; if not, write to the Free Software
16
- * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
17
- */
18
-
19
-#include <stdint.h>
20
-#include <string.h>
21
-#include <gpxe/dhcp.h>
22
-#include <gpxe/nvs.h>
23
-
24
-/** @file
25
- *
26
- * Non-volatile storage
27
- *
28
- */
29
-
30
-static size_t nvs_options_len ( struct nvs_device *nvs ) {
31
-	struct dhcp_option *option;
32
-	uint8_t sum;
33
-	unsigned int i;
34
-	size_t len;
35
-
36
-	for ( sum = 0, i = 0 ; i < nvs->len ; i++ ) {
37
-		sum += * ( ( uint8_t * ) ( nvs->options->data + i ) );
38
-	}
39
-	if ( sum != 0 ) {
40
-		DBG ( "NVS %p has bad checksum %02x; assuming empty\n",
41
-		      nvs, sum );
42
-		return 0;
43
-	}
44
-
45
-	option = nvs->options->data;
46
-	if ( option->tag == DHCP_PAD ) {
47
-		DBG ( "NVS %p has bad start; assuming empty\n", nvs );
48
-		return 0;
49
-	}
50
-	
51
-	option = find_dhcp_option ( nvs->options, DHCP_END );
52
-	if ( ! option ) {
53
-		DBG ( "NVS %p has no end tag; assuming empty\n", nvs );
54
-		return 0;
55
-	}
56
-
57
-	len = ( ( void * ) option - nvs->options->data + 1 );
58
-	DBG ( "NVS %p contains %zd bytes of options (maximum %zd)\n",
59
-	      nvs, len, nvs->len );
60
-
61
-	return len;
62
-}
63
-
64
-int nvs_register ( struct nvs_device *nvs ) {
65
-	struct dhcp_option *option;
66
-	int rc;
67
-
68
-	nvs->options = alloc_dhcp_options ( nvs->len );
69
-	if ( ! nvs->options ) {
70
-		DBG ( "NVS %p could not allocate %zd bytes\n", nvs, nvs->len );
71
-		rc = -ENOMEM;
72
-		goto err;
73
-	}
74
-
75
-	if ( ( rc = nvs->op->read ( nvs, 0, nvs->options->data,
76
-				    nvs->len ) ) != 0 ) {
77
-		DBG ( "NVS %p could not read [0,%zd)\n", nvs, nvs->len );
78
-		goto err;
79
-	}
80
-
81
-	nvs->options->len = nvs->options->max_len;
82
-	nvs->options->len = nvs_options_len ( nvs );
83
-	if ( ! nvs->options->len ) {
84
-		option = nvs->options->data;
85
-		option->tag = DHCP_END;
86
-		nvs->options->len = 1;
87
-	}
88
-
89
-	register_dhcp_options ( nvs->options );
90
-
91
-	return 0;
92
-	
93
- err:
94
-	
95
-	free_dhcp_options ( nvs->options );
96
-	nvs->options = NULL;
97
-	return rc;
98
-}
99
-
100
-void nvs_unregister ( struct nvs_device *nvs ) {
101
-	if ( nvs->options ) {
102
-		unregister_dhcp_options ( nvs->options );
103
-		free_dhcp_options ( nvs->options );
104
-		nvs->options = NULL;
105
-	}
106
-}

+ 4
- 5
src/drivers/bitbash/spi_bit.c View File

@@ -147,22 +147,21 @@ static int spi_bit_rw ( struct spi_bus *bus, struct spi_device *device,
147 147
 			const void *data_out, void *data_in, size_t len ) {
148 148
 	struct spi_bit_basher *spibit
149 149
 		= container_of ( bus, struct spi_bit_basher, bus );
150
-	struct spi_device_type *devtype = device->type;
151 150
 	uint32_t tmp;
152 151
 
153 152
 	/* Assert chip select on specified slave */
154 153
 	spi_bit_set_slave_select ( spibit, device->slave, SELECT_SLAVE );
155 154
 
156 155
 	/* Transmit command */
157
-	assert ( devtype->command_len <= ( 8 * sizeof ( tmp ) ) );
156
+	assert ( device->command_len <= ( 8 * sizeof ( tmp ) ) );
158 157
 	tmp = cpu_to_le32 ( command );
159
-	spi_bit_transfer ( spibit, &tmp, NULL, devtype->command_len );
158
+	spi_bit_transfer ( spibit, &tmp, NULL, device->command_len );
160 159
 
161 160
 	/* Transmit address, if present */
162 161
 	if ( address >= 0 ) {
163
-		assert ( devtype->address_len <= ( 8 * sizeof ( tmp ) ) );
162
+		assert ( device->address_len <= ( 8 * sizeof ( tmp ) ) );
164 163
 		tmp = cpu_to_le32 ( address );
165
-		spi_bit_transfer ( spibit, &tmp, NULL, devtype->address_len );
164
+		spi_bit_transfer ( spibit, &tmp, NULL, device->address_len );
166 165
 	}
167 166
 
168 167
 	/* Transmit/receive data */

+ 2
- 5
src/drivers/net/etherfabric.c View File

@@ -2388,11 +2388,6 @@ static int falcon_write_nvs ( struct nvs_device *nvs, unsigned int offset,
2388 2388
 	return 0;
2389 2389
 }
2390 2390
 
2391
-static struct nvs_operations falcon_nvs_operations = {
2392
-	.read = falcon_read_nvs,
2393
-	.write = falcon_write_nvs,
2394
-};
2395
-
2396 2391
 /** RX descriptor */
2397 2392
 typedef efab_qword_t falcon_rx_desc_t;
2398 2393
 
@@ -3046,10 +3041,12 @@ static int falcon_init_nic ( struct efab_nic *efab ) {
3046 3041
 
3047 3042
 	/* Register non-volatile storage */
3048 3043
 	if ( efab->has_eeprom ) {
3044
+		/*
3049 3045
 		efab->nvs.op = &falcon_nvs_operations;
3050 3046
 		efab->nvs.len = 0x100;
3051 3047
 		if ( nvs_register ( &efab->nvs ) != 0 )
3052 3048
 			return 0;
3049
+		*/
3053 3050
 	}
3054 3051
 
3055 3052
 	return 1;

+ 10
- 8
src/drivers/net/rtl8139.c View File

@@ -240,15 +240,12 @@ static struct bit_basher_operations rtl_basher_ops = {
240 240
 	.write = rtl_spi_write_bit,
241 241
 };
242 242
 
243
-static struct spi_device_type rtl_ee9346 = AT93C46 ( 16 );
244
-static struct spi_device_type rtl_ee9356 = AT93C56 ( 16 );
245
-
246 243
 /**
247 244
  * Set up for EEPROM access
248 245
  *
249 246
  * @v rtl		RTL8139 NIC
250 247
  */
251
-static void rtl_init_eeprom ( struct rtl8139_nic *rtl ) {
248
+ void rtl_init_eeprom ( struct rtl8139_nic *rtl ) {
252 249
 	int ee9356;
253 250
 
254 251
 	/* Initialise three-wire bus */
@@ -258,8 +255,13 @@ static void rtl_init_eeprom ( struct rtl8139_nic *rtl ) {
258 255
 
259 256
 	/* Detect EEPROM type and initialise three-wire device */
260 257
 	ee9356 = ( inw ( rtl->ioaddr + RxConfig ) & Eeprom9356 );
261
-	DBG ( "EEPROM is an %s\n", ( ee9356 ? "AT93C56" : "AT93C46" ) );
262
-	rtl->eeprom.type = ( ee9356 ? &rtl_ee9356 : &rtl_ee9346 );
258
+	if ( ee9356 ) {
259
+		DBG ( "EEPROM is an AT93C56\n" );
260
+		init_at93c56 ( &rtl->eeprom, 16 );
261
+	} else {
262
+		DBG ( "EEPROM is an AT93C46\n" );
263
+		init_at93c46 ( &rtl->eeprom, 16 );
264
+	}
263 265
 	rtl->eeprom.bus = &rtl->spibit.bus;
264 266
 }
265 267
 
@@ -271,12 +273,12 @@ static void rtl_init_eeprom ( struct rtl8139_nic *rtl ) {
271 273
  */
272 274
 static void rtl_read_mac ( struct rtl8139_nic *rtl, uint8_t *mac_addr ) {
273 275
 
274
-	struct spi_device *device = &rtl->eeprom;
276
+	struct nvs_device *nvs = &rtl->eeprom.nvs;
275 277
 	int i;
276 278
 	
277 279
 	DBG ( "MAC address is " );
278 280
 	for ( i = EE_MAC ; i < ( EE_MAC + ( ETH_ALEN / 2 ) ) ; i++ ) {
279
-		device->type->read ( device, i, mac_addr, 2 );
281
+		nvs_read ( nvs, i, mac_addr, 2 );
280 282
 		DBG ( "%02x%02x", mac_addr[0], mac_addr[1] );
281 283
 		mac_addr += 2;
282 284
 	}

+ 31
- 0
src/drivers/nvs/nvs.c View File

@@ -0,0 +1,31 @@
1
+/*
2
+ * Copyright (C) 2006 Michael Brown <mbrown@fensystems.co.uk>.
3
+ *
4
+ * This program is free software; you can redistribute it and/or
5
+ * modify it under the terms of the GNU General Public License as
6
+ * published by the Free Software Foundation; either version 2 of the
7
+ * License, or any later version.
8
+ *
9
+ * This program is distributed in the hope that it will be useful, but
10
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
11
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
12
+ * General Public License for more details.
13
+ *
14
+ * You should have received a copy of the GNU General Public License
15
+ * along with this program; if not, write to the Free Software
16
+ * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
17
+ */
18
+
19
+#include <stdint.h>
20
+#include <gpxe/nvs.h>
21
+
22
+/** @file
23
+ *
24
+ * Non-volatile storage
25
+ *
26
+ */
27
+
28
+int nvs_read ( struct nvs_device *nvs, unsigned int address,
29
+	       void *data, size_t len ) {
30
+	return nvs->read ( nvs, address, data, len );
31
+}

+ 3
- 2
src/drivers/nvs/threewire.c View File

@@ -28,14 +28,15 @@
28 28
 
29 29
 /** Read data from three-wire device
30 30
  *
31
- * @v device		SPI device
31
+ * @v nvs		NVS device
32 32
  * @v address		Address from which to read
33 33
  * @v data		Data buffer
34 34
  * @v len		Length of data buffer
35 35
  * @ret rc		Return status code
36 36
  */
37
-int threewire_read ( struct spi_device *device, unsigned int address,
37
+int threewire_read ( struct nvs_device *nvs, unsigned int address,
38 38
 		     void *data, size_t len ) {
39
+	struct spi_device *device = nvs_to_spi ( nvs );
39 40
 	struct spi_bus *bus = device->bus;
40 41
 
41 42
 	assert ( bus->mode == SPI_MODE_THREEWIRE );

+ 21
- 0
src/include/gpxe/nvo.h View File

@@ -0,0 +1,21 @@
1
+#ifndef _GPXE_NVO_H
2
+#define _GPXE_NVO_H
3
+
4
+/** @file
5
+ *
6
+ * Non-volatile stored options
7
+ *
8
+ */
9
+
10
+struct nvs_device;
11
+struct dhcp_option_block;
12
+
13
+struct nvs_options {
14
+	struct nvs_device *nvs;
15
+	struct dhcp_option_block *options;
16
+};
17
+
18
+extern int nvo_register ( struct nvs_options *nvo );
19
+extern void nvo_unregister ( struct nvs_options *nvo );
20
+
21
+#endif /* _GPXE_NVO_H */

+ 43
- 12
src/include/gpxe/nvs.h View File

@@ -9,22 +9,53 @@
9 9
 
10 10
 #include <stdint.h>
11 11
 
12
-struct nvs_operations;
13
-
12
+/** A non-volatile storage device */
14 13
 struct nvs_device {
15
-	struct dhcp_option_block *options;
16
-	size_t len;
17
-	struct nvs_operations *op;
18
-};
19
-
20
-struct nvs_operations {
21
-	int ( * read ) ( struct nvs_device *nvs, unsigned int offset,
14
+	/** Word length, in bits */
15
+	unsigned int word_len;
16
+	/** Device size (in words) */
17
+	unsigned int size;
18
+	/** Data block size (in words)
19
+	 *
20
+	 * This is the block size used by the device.  It must be a
21
+	 * power of two.  Data reads and writes must not cross a block
22
+	 * boundary.
23
+	 *
24
+	 * Many devices allow reads to cross a block boundary, and
25
+	 * restrict only writes.  For the sake of simplicity, we
26
+	 * assume that the same restriction applies to both reads and
27
+	 * writes.
28
+	 */
29
+	unsigned int block_size;
30
+	/** Read data from device
31
+	 *
32
+	 * @v nvs		NVS device
33
+	 * @v address		Address from which to read
34
+	 * @v data		Data buffer
35
+	 * @v len		Length of data buffer
36
+	 * @ret rc		Return status code
37
+	 *
38
+	 * Reads may not cross a block boundary.
39
+	 */
40
+	int ( * read ) ( struct nvs_device *nvs, unsigned int address,
22 41
 			 void *data, size_t len );
23
-	int ( * write ) ( struct nvs_device *nvs, unsigned int offset,
42
+	/** Write data to device
43
+	 *
44
+	 * @v nvs		NVS device
45
+	 * @v address		Address to which to write
46
+	 * @v data		Data buffer
47
+	 * @v len		Length of data buffer
48
+	 * @ret rc		Return status code
49
+	 *
50
+	 * Writes may not cross a block boundary.
51
+	 */
52
+	int ( * write ) ( struct nvs_device *nvs, unsigned int address,
24 53
 			  const void *data, size_t len );
25 54
 };
26 55
 
27
-extern int nvs_register ( struct nvs_device *nvs );
28
-extern void nvs_unregister ( struct nvs_device *nvs );
56
+extern int nvs_read ( struct nvs_device *nvs, unsigned int address,
57
+		      void *data, size_t len );
58
+extern int nvs_write ( struct nvs_device *nvs, unsigned int address,
59
+		       const void *data, size_t len );
29 60
 
30 61
 #endif /* _GPXE_NVS_H */

+ 17
- 76
src/include/gpxe/spi.h View File

@@ -7,7 +7,7 @@
7 7
  *
8 8
  */
9 9
 
10
-#include <gpxe/bitbash.h>
10
+#include <gpxe/nvs.h>
11 11
 
12 12
 /**
13 13
  * @defgroup spicmds SPI commands
@@ -75,32 +75,19 @@
75 75
 
76 76
 /** @} */
77 77
 
78
-struct spi_device;
79
-
80 78
 /**
81
- * An SPI device type
79
+ * An SPI device
82 80
  *
83
- * This data structure represents all the characteristics belonging to
84
- * a particular type of SPI device, e.g. "an Atmel 251024 serial flash",
85
- * or "a Microchip 25040 serial EEPROM".
81
+ * This data structure represents a physical SPI device attached to an
82
+ * SPI bus.
86 83
  */
87
-struct spi_device_type {
88
-	/** Word length, in bits */
89
-	unsigned int word_len;
90
-	/** Device size (in words) */
91
-	unsigned int size;
92
-	/** Data block size (in words)
93
-	 *
94
-	 * This is the block size used by the device.  It must be a
95
-	 * power of two.  Data reads and writes must not cross a block
96
-	 * boundary.
97
-	 *
98
-	 * Many devices allow reads to cross a block boundary, and
99
-	 * restrict only writes.  For the sake of simplicity, we
100
-	 * assume that the same restriction applies to both reads and
101
-	 * writes.
102
-	 */
103
-	unsigned int block_size;
84
+struct spi_device {
85
+	/** NVS device */
86
+	struct nvs_device nvs;
87
+	/** SPI bus to which device is attached */
88
+	struct spi_bus *bus;
89
+	/** Slave number */
90
+	unsigned int slave;
104 91
 	/** Command length, in bits */
105 92
 	unsigned int command_len;
106 93
 	/** Address length, in bits */
@@ -113,64 +100,18 @@ struct spi_device_type {
113 100
 	 * commands should be munged in this way.
114 101
 	 */
115 102
 	unsigned int munge_address : 1;
116
-	/** Read data from device
117
-	 *
118
-	 * @v device		SPI device
119
-	 * @v address		Address from which to read
120
-	 * @v data		Data buffer
121
-	 * @v len		Length of data buffer
122
-	 * @ret rc		Return status code
123
-	 */
124
-	int ( * read ) ( struct spi_device *device, unsigned int address,
125
-			 void *data, size_t len );
126
-	/** Write data to device
127
-	 *
128
-	 * @v device		SPI device
129
-	 * @v address		Address to which to write
130
-	 * @v data		Data buffer
131
-	 * @v len		Length of data buffer
132
-	 * @ret rc		Return status code
133
-	 */
134
-	int ( * write ) ( struct spi_device *device, unsigned int address,
135
-			  const void *data, size_t len );
136 103
 };
137 104
 
138
-/**
139
- * @defgroup spidevs SPI device types
140
- * @{
141
- */
142
-
143
-/** Atmel AT25010 serial EEPROM */
144
-#define AT25010 {		\
145
-	.word_len = 8,		\
146
-	.size = 128,		\
147
-	.block_size = 8,	\
148
-	.command_len = 8,	\
149
-	.address_len = 8,	\
150
-	}
151
-
152
-/** @} */
153
-
154
-/**
155
- * An SPI device
156
- *
157
- * This data structure represents a real, physical SPI device attached
158
- * to an SPI controller.  It comprises the device type plus
159
- * instantiation-specific information such as the slave number.
160
- */
161
-struct spi_device {
162
-	/** SPI device type */
163
-	struct spi_device_type *type;
164
-	/** SPI bus to which device is attached */
165
-	struct spi_bus *bus;
166
-	/** Slave number */
167
-	unsigned int slave;
168
-};
105
+static inline __attribute__ (( always_inline )) struct spi_device *
106
+nvs_to_spi ( struct nvs_device *nvs ) {
107
+	return container_of ( nvs, struct spi_device, nvs );
108
+}
169 109
 
170 110
 /**
171 111
  * An SPI bus
172 112
  *
173
- * 
113
+ * This data structure represents an SPI bus controller capable of
114
+ * issuing commands to attached SPI devices.
174 115
  */
175 116
 struct spi_bus {
176 117
 	/** SPI interface mode

+ 1
- 0
src/include/gpxe/spi_bit.h View File

@@ -8,6 +8,7 @@
8 8
  */
9 9
 
10 10
 #include <gpxe/spi.h>
11
+#include <gpxe/bitbash.h>
11 12
 
12 13
 /** A bit-bashing SPI bus */
13 14
 struct spi_bit_basher {

+ 33
- 25
src/include/gpxe/threewire.h View File

@@ -22,40 +22,48 @@
22 22
 
23 23
 /** @} */
24 24
 
25
+extern int threewire_read ( struct nvs_device *nvs, unsigned int address,
26
+			    void *data, size_t len );
27
+
25 28
 /**
26
- * @defgroup spidevs SPI device types
29
+ * @defgroup tdevs Three-wire device types
27 30
  * @{
28 31
  */
29 32
 
30
-/** Atmel AT93C46 serial EEPROM
33
+static inline __attribute__ (( always_inline )) void
34
+init_at93cx6 ( struct spi_device *device, unsigned int organisation ) {
35
+	device->nvs.word_len = organisation;
36
+	device->nvs.block_size = 1;
37
+	device->command_len = 3,
38
+	device->nvs.read = threewire_read;
39
+}
40
+
41
+/**
42
+ * Initialise Atmel AT93C46 serial EEPROM
31 43
  *
32
- * @v org	Word size (8 or 16)
44
+ * @v device		SPI device
45
+ * @v organisation	Word organisation (8 or 16)
33 46
  */
34
-#define AT93C46( org ) {				\
35
-	.word_len = (org),				\
36
-	.size = ( 1024 / (org) ),			\
37
-	.block_size = 1,				\
38
-	.command_len = 3,				\
39
-	.address_len = ( ( (org) == 8 ) ? 7 : 6 ),	\
40
-	.read = threewire_read,				\
41
-	}
42
-
43
-/** Atmel AT93C56 serial EEPROM
47
+static inline __attribute__ (( always_inline )) void
48
+init_at93c46 ( struct spi_device *device, unsigned int organisation ) {
49
+	device->nvs.size = ( 1024 / organisation );
50
+	device->address_len = ( ( organisation == 8 ) ? 7 : 6 );
51
+	init_at93cx6 ( device, organisation );
52
+}
53
+
54
+/**
55
+ * Initialise Atmel AT93C56 serial EEPROM
44 56
  *
45
- * @v org	Word size (8 or 16)
57
+ * @v device		SPI device
58
+ * @v organisation	Word organisation (8 or 16)
46 59
  */
47
-#define AT93C56( org ) {				\
48
-	.word_len = (org),				\
49
-	.size = ( 2048 / (org) ),			\
50
-	.block_size = 1,				\
51
-	.command_len = 3,				\
52
-	.address_len = ( ( (org) == 8 ) ? 9 : 8 ),	\
53
-	.read = threewire_read,				\
54
-	}
60
+static inline __attribute__ (( always_inline )) void
61
+init_at93c56 ( struct spi_device *device, unsigned int organisation ) {
62
+	device->nvs.size = ( 2048 / organisation );
63
+	device->address_len = ( ( organisation == 8 ) ? 9 : 8 );
64
+	init_at93cx6 ( device, organisation );
65
+}
55 66
 
56 67
 /** @} */
57 68
 
58
-extern int threewire_read ( struct spi_device *device, unsigned int address,
59
-			    void *data, size_t len );
60
-
61 69
 #endif /* _GPXE_THREEWIRE_H */

Loading…
Cancel
Save