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

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
-/*
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
 			const void *data_out, void *data_in, size_t len ) {
147
 			const void *data_out, void *data_in, size_t len ) {
148
 	struct spi_bit_basher *spibit
148
 	struct spi_bit_basher *spibit
149
 		= container_of ( bus, struct spi_bit_basher, bus );
149
 		= container_of ( bus, struct spi_bit_basher, bus );
150
-	struct spi_device_type *devtype = device->type;
151
 	uint32_t tmp;
150
 	uint32_t tmp;
152
 
151
 
153
 	/* Assert chip select on specified slave */
152
 	/* Assert chip select on specified slave */
154
 	spi_bit_set_slave_select ( spibit, device->slave, SELECT_SLAVE );
153
 	spi_bit_set_slave_select ( spibit, device->slave, SELECT_SLAVE );
155
 
154
 
156
 	/* Transmit command */
155
 	/* Transmit command */
157
-	assert ( devtype->command_len <= ( 8 * sizeof ( tmp ) ) );
156
+	assert ( device->command_len <= ( 8 * sizeof ( tmp ) ) );
158
 	tmp = cpu_to_le32 ( command );
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
 	/* Transmit address, if present */
160
 	/* Transmit address, if present */
162
 	if ( address >= 0 ) {
161
 	if ( address >= 0 ) {
163
-		assert ( devtype->address_len <= ( 8 * sizeof ( tmp ) ) );
162
+		assert ( device->address_len <= ( 8 * sizeof ( tmp ) ) );
164
 		tmp = cpu_to_le32 ( address );
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
 	/* Transmit/receive data */
167
 	/* Transmit/receive data */

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

2388
 	return 0;
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
 /** RX descriptor */
2391
 /** RX descriptor */
2397
 typedef efab_qword_t falcon_rx_desc_t;
2392
 typedef efab_qword_t falcon_rx_desc_t;
2398
 
2393
 
3046
 
3041
 
3047
 	/* Register non-volatile storage */
3042
 	/* Register non-volatile storage */
3048
 	if ( efab->has_eeprom ) {
3043
 	if ( efab->has_eeprom ) {
3044
+		/*
3049
 		efab->nvs.op = &falcon_nvs_operations;
3045
 		efab->nvs.op = &falcon_nvs_operations;
3050
 		efab->nvs.len = 0x100;
3046
 		efab->nvs.len = 0x100;
3051
 		if ( nvs_register ( &efab->nvs ) != 0 )
3047
 		if ( nvs_register ( &efab->nvs ) != 0 )
3052
 			return 0;
3048
 			return 0;
3049
+		*/
3053
 	}
3050
 	}
3054
 
3051
 
3055
 	return 1;
3052
 	return 1;

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

240
 	.write = rtl_spi_write_bit,
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
  * Set up for EEPROM access
244
  * Set up for EEPROM access
248
  *
245
  *
249
  * @v rtl		RTL8139 NIC
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
 	int ee9356;
249
 	int ee9356;
253
 
250
 
254
 	/* Initialise three-wire bus */
251
 	/* Initialise three-wire bus */
258
 
255
 
259
 	/* Detect EEPROM type and initialise three-wire device */
256
 	/* Detect EEPROM type and initialise three-wire device */
260
 	ee9356 = ( inw ( rtl->ioaddr + RxConfig ) & Eeprom9356 );
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
 	rtl->eeprom.bus = &rtl->spibit.bus;
265
 	rtl->eeprom.bus = &rtl->spibit.bus;
264
 }
266
 }
265
 
267
 
271
  */
273
  */
272
 static void rtl_read_mac ( struct rtl8139_nic *rtl, uint8_t *mac_addr ) {
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
 	int i;
277
 	int i;
276
 	
278
 	
277
 	DBG ( "MAC address is " );
279
 	DBG ( "MAC address is " );
278
 	for ( i = EE_MAC ; i < ( EE_MAC + ( ETH_ALEN / 2 ) ) ; i++ ) {
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
 		DBG ( "%02x%02x", mac_addr[0], mac_addr[1] );
282
 		DBG ( "%02x%02x", mac_addr[0], mac_addr[1] );
281
 		mac_addr += 2;
283
 		mac_addr += 2;
282
 	}
284
 	}

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

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

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

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
 
9
 
10
 #include <stdint.h>
10
 #include <stdint.h>
11
 
11
 
12
-struct nvs_operations;
13
-
12
+/** A non-volatile storage device */
14
 struct nvs_device {
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
 			 void *data, size_t len );
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
 			  const void *data, size_t len );
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
 #endif /* _GPXE_NVS_H */
61
 #endif /* _GPXE_NVS_H */

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

7
  *
7
  *
8
  */
8
  */
9
 
9
 
10
-#include <gpxe/bitbash.h>
10
+#include <gpxe/nvs.h>
11
 
11
 
12
 /**
12
 /**
13
  * @defgroup spicmds SPI commands
13
  * @defgroup spicmds SPI commands
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
 	/** Command length, in bits */
91
 	/** Command length, in bits */
105
 	unsigned int command_len;
92
 	unsigned int command_len;
106
 	/** Address length, in bits */
93
 	/** Address length, in bits */
113
 	 * commands should be munged in this way.
100
 	 * commands should be munged in this way.
114
 	 */
101
 	 */
115
 	unsigned int munge_address : 1;
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
  * An SPI bus
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
 struct spi_bus {
116
 struct spi_bus {
176
 	/** SPI interface mode
117
 	/** SPI interface mode

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

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

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

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
 #endif /* _GPXE_THREEWIRE_H */
69
 #endif /* _GPXE_THREEWIRE_H */

Loading…
Cancel
Save