瀏覽代碼

[nvo] Remove the non-volatile options fragment list

Since its implementation several years ago, no driver has used a
fragment list containing more than a single fragment.  Simplify the
NVO core and the drivers that use it by removing the whole concept of
the fragment list, and using a simple (address,length) pair instead.

Signed-off-by: Michael Brown <mcb30@ipxe.org>
tags/v1.20.1
Michael Brown 13 年之前
父節點
當前提交
1651d4f6d7
共有 6 個檔案被更改,包括 50 行新增111 行删除
  1. 24
    49
      src/core/nvo.c
  2. 3
    8
      src/drivers/net/etherfabric.c
  3. 4
    12
      src/drivers/net/myri10ge.c
  4. 7
    11
      src/drivers/net/natsemi.c
  5. 7
    13
      src/drivers/net/rtl8139.c
  6. 5
    18
      src/include/ipxe/nvo.h

+ 24
- 49
src/core/nvo.c 查看文件

@@ -43,7 +43,7 @@ static unsigned int nvo_checksum ( struct nvo_block *nvo ) {
43 43
 	uint8_t sum = 0;
44 44
 	unsigned int i;
45 45
 
46
-	for ( i = 0 ; i < nvo->total_len ; i++ ) {
46
+	for ( i = 0 ; i < nvo->len ; i++ ) {
47 47
 		sum += *(data++);
48 48
 	}
49 49
 	return sum;
@@ -56,19 +56,14 @@ static unsigned int nvo_checksum ( struct nvo_block *nvo ) {
56 56
  * @ret rc		Return status code
57 57
  */
58 58
 static int nvo_load ( struct nvo_block *nvo ) {
59
-	void *data = nvo->data;
60
-	struct nvo_fragment *frag;
61 59
 	int rc;
62 60
 
63
-	/* Read data a fragment at a time */
64
-	for ( frag = nvo->fragments ; frag->len ; frag++ ) {
65
-		if ( ( rc = nvs_read ( nvo->nvs, frag->address, data,
66
-				       frag->len ) ) != 0 ) {
67
-			DBGC ( nvo, "NVO %p could not read %zd bytes at "
68
-			       "%#04x\n", nvo, frag->len, frag->address );
69
-			return rc;
70
-		}
71
-		data += frag->len;
61
+	/* Read data */
62
+	if ( ( rc = nvs_read ( nvo->nvs, nvo->address, nvo->data,
63
+			       nvo->len ) ) != 0 ) {
64
+		DBGC ( nvo, "NVO %p could not read %zd bytes at %#04x: %s\n",
65
+		       nvo, nvo->len, nvo->address, strerror ( rc ) );
66
+		return rc;
72 67
 	}
73 68
 
74 69
 	DBGC ( nvo, "NVO %p loaded from non-volatile storage\n", nvo );
@@ -82,23 +77,18 @@ static int nvo_load ( struct nvo_block *nvo ) {
82 77
  * @ret rc		Return status code
83 78
  */
84 79
 static int nvo_save ( struct nvo_block *nvo ) {
85
-	void *data = nvo->data;
86
-	uint8_t *checksum = data;
87
-	struct nvo_fragment *frag;
80
+	uint8_t *checksum = nvo->data;
88 81
 	int rc;
89 82
 
90 83
 	/* Recalculate checksum */
91 84
 	*checksum -= nvo_checksum ( nvo );
92 85
 
93
-	/* Write data a fragment at a time */
94
-	for ( frag = nvo->fragments ; frag->len ; frag++ ) {
95
-		if ( ( rc = nvs_write ( nvo->nvs, frag->address, data,
96
-					frag->len ) ) != 0 ) {
97
-			DBGC ( nvo, "NVO %p could not write %zd bytes at "
98
-			       "%#04x\n", nvo, frag->len, frag->address );
99
-			return rc;
100
-		}
101
-		data += frag->len;
86
+	/* Write data */
87
+	if ( ( rc = nvs_write ( nvo->nvs, nvo->address, nvo->data,
88
+				nvo->len ) ) != 0 ) {
89
+		DBGC ( nvo, "NVO %p could not write %zd bytes at %#04x: %s\n",
90
+		       nvo, nvo->len, nvo->address, strerror ( rc ) );
91
+		return rc;
102 92
 	}
103 93
 
104 94
 	DBGC ( nvo, "NVO %p saved to non-volatile storage\n", nvo );
@@ -120,7 +110,7 @@ static void nvo_init_dhcpopts ( struct nvo_block *nvo ) {
120 110
 
121 111
 	/* Steal one byte for the checksum */
122 112
 	options_data = ( nvo->data + 1 );
123
-	options_len = ( nvo->total_len - 1 );
113
+	options_len = ( nvo->len - 1 );
124 114
 
125 115
 	/* If checksum fails, or options data starts with a zero,
126 116
 	 * assume the whole block is invalid.  This should capture the
@@ -130,7 +120,7 @@ static void nvo_init_dhcpopts ( struct nvo_block *nvo ) {
130 120
 		DBGC ( nvo, "NVO %p has checksum %02x and initial byte %02x; "
131 121
 		       "assuming empty\n", nvo, nvo_checksum ( nvo ),
132 122
 		       options_data[0] );
133
-		memset ( nvo->data, 0, nvo->total_len );
123
+		memset ( nvo->data, 0, nvo->len );
134 124
 	}
135 125
 
136 126
 	dhcpopt_init ( &nvo->dhcpopts, options_data, options_len,
@@ -198,13 +188,15 @@ static struct settings_operations nvo_settings_operations = {
198 188
  *
199 189
  * @v nvo		Non-volatile options block
200 190
  * @v nvs		Underlying non-volatile storage device
201
- * @v fragments		List of option-containing fragments, or NULL
191
+ * @v address		Address within NVS device
192
+ * @v len		Length of non-volatile options data
202 193
  * @v refcnt		Containing object reference counter, or NULL
203 194
  */
204 195
 void nvo_init ( struct nvo_block *nvo, struct nvs_device *nvs,
205
-		struct nvo_fragment *fragments, struct refcnt *refcnt ) {
196
+		size_t address, size_t len, struct refcnt *refcnt ) {
206 197
 	nvo->nvs = nvs;
207
-	nvo->fragments = fragments;
198
+	nvo->address = address;
199
+	nvo->len = len;
208 200
 	settings_init ( &nvo->settings, &nvo_settings_operations, refcnt, 0 );
209 201
 }
210 202
 
@@ -216,34 +208,17 @@ void nvo_init ( struct nvo_block *nvo, struct nvs_device *nvs,
216 208
  * @ret rc		Return status code
217 209
  */
218 210
 int register_nvo ( struct nvo_block *nvo, struct settings *parent ) {
219
-	struct nvo_fragment *fragment = nvo->fragments;
220 211
 	int rc;
221 212
 
222
-	/* Calculate total length of all fragments, if applicable */
223
-	if ( fragment ) {
224
-		for ( ; fragment->len ; fragment++ )
225
-			nvo->total_len += fragment->len;
226
-	} else {
227
-		nvo->total_len = nvo->nvs->size;
228
-	}
229
-
230
-	/* Allocate memory for options (and fragment list, if applicable) */
231
-	nvo->data = zalloc ( nvo->total_len +
232
-			     ( fragment ? 0 : ( 2 * sizeof ( *fragment ) ) ) );
213
+	/* Allocate memory for options */
214
+	nvo->data = zalloc ( nvo->len );
233 215
 	if ( ! nvo->data ) {
234 216
 		DBGC ( nvo, "NVO %p could not allocate %zd bytes\n",
235
-		       nvo, nvo->total_len );
217
+		       nvo, nvo->len );
236 218
 		rc = -ENOMEM;
237 219
 		goto err_malloc;
238 220
 	}
239 221
 
240
-	/* Create fragment list, if applicable */
241
-	if ( ! fragment ) {
242
-		fragment = ( nvo->data + nvo->total_len );
243
-		fragment->len = nvo->total_len;
244
-		nvo->fragments = fragment;
245
-	}
246
-
247 222
 	/* Read data from NVS */
248 223
 	if ( ( rc = nvo_load ( nvo ) ) != 0 )
249 224
 		goto err_load;

+ 3
- 8
src/drivers/net/etherfabric.c 查看文件

@@ -1492,12 +1492,6 @@ fail1:
1492 1492
 	return rc;
1493 1493
 }
1494 1494
 
1495
-/** Portion of EEPROM available for non-volatile options */
1496
-static struct nvo_fragment falcon_nvo_fragments[] = {
1497
-	{ 0x100, 0xf0 },
1498
-	{ 0, 0 }
1499
-};
1500
-
1501 1495
 /*******************************************************************************
1502 1496
  *
1503 1497
  *
@@ -3277,9 +3271,10 @@ falcon_probe_spi ( struct efab_nic *efab )
3277 3271
 	}
3278 3272
 
3279 3273
 	/* If the device has EEPROM attached, then advertise NVO space */
3280
-	if ( has_eeprom )
3281
-		nvo_init ( &efab->nvo, &efab->spi_eeprom.nvs, falcon_nvo_fragments,
3274
+	if ( has_eeprom ) {
3275
+		nvo_init ( &efab->nvo, &efab->spi_eeprom.nvs, 0x100, 0xf0,
3282 3276
 			   &efab->netdev->refcnt );
3277
+	}
3283 3278
 
3284 3279
 	return 0;
3285 3280
 }

+ 4
- 12
src/drivers/net/myri10ge.c 查看文件

@@ -183,8 +183,8 @@ struct myri10ge_private
183 183
 	 */
184 184
 
185 185
 	struct nvs_device	nvs;
186
-	struct nvo_fragment	nvo_fragment[2];
187 186
 	struct nvo_block	nvo;
187
+	unsigned int		nvo_registered;
188 188
 
189 189
 	/* Cached PCI capability locations. */
190 190
 
@@ -727,28 +727,20 @@ static int myri10ge_nv_init ( struct myri10ge_private *priv )
727 727
 	priv->nvs.read		= myri10ge_nvs_read;
728 728
 	priv->nvs.write		= myri10ge_nvs_write;
729 729
 
730
-	/* Build the NonVolatile storage fragment list.  We would like
731
-	   to use the whole last EEPROM block for this, but we must
732
-	   reduce the block size lest malloc fail in
733
-	   src/core/nvo.o. */
734
-
735
-	priv->nvo_fragment[0].address = nvo_fragment_pos;
736
-	priv->nvo_fragment[0].len     = 0x200;
737
-
738 730
 	/* Register the NonVolatile Options storage. */
739 731
 
740 732
 	nvo_init ( &priv->nvo,
741 733
 		   &priv->nvs,
742
-		   priv->nvo_fragment,
734
+		   nvo_fragment_pos, 0x200,
743 735
 		   & myri10ge_netdev (priv) -> refcnt );
744 736
 	rc = register_nvo ( &priv->nvo,
745 737
 			    netdev_settings ( myri10ge_netdev ( priv ) ) );
746 738
 	if ( rc ) {
747 739
 		DBG ("register_nvo failed");
748
-		priv->nvo_fragment[0].len = 0;
749 740
 		return rc;
750 741
 	}
751 742
 
743
+	priv->nvo_registered = 1;
752 744
 	DBG2 ( "NVO supported\n" );
753 745
 	return 0;
754 746
 }
@@ -758,7 +750,7 @@ myri10ge_nv_fini ( struct myri10ge_private *priv )
758 750
 {
759 751
 	/* Simply return if nonvolatile access is not supported. */
760 752
 
761
-	if ( 0 == priv->nvo_fragment[0].len )
753
+	if ( 0 == priv->nvo_registered )
762 754
 		return;
763 755
 
764 756
 	unregister_nvo ( &priv->nvo );

+ 7
- 11
src/drivers/net/natsemi.c 查看文件

@@ -130,15 +130,6 @@ static struct bit_basher_operations natsemi_basher_ops = {
130 130
 	.write = natsemi_spi_write_bit,
131 131
 };
132 132
 
133
-/* It looks that this portion of EEPROM can be used for 
134
- * non-volatile stored options. Data sheet does not talk about this region.
135
- * Currently it is not working. But with some efforts it can.
136
- */
137
-static struct nvo_fragment natsemi_nvo_fragments[] = {
138
-	{ 0x0c, 0x68 },
139
-	{ 0, 0 }
140
-};
141
-
142 133
 /*
143 134
  * Set up for EEPROM access
144 135
  *
@@ -157,8 +148,13 @@ static void natsemi_init_eeprom ( struct natsemi_private *np ) {
157 148
 	 */
158 149
 	init_at93c46 ( &np->eeprom, 16 );
159 150
 	np->eeprom.bus = &np->spibit.bus;
160
-	np->nvo.nvs = &np->eeprom.nvs;
161
-	np->nvo.fragments = natsemi_nvo_fragments;
151
+
152
+	/* It looks that this portion of EEPROM can be used for
153
+	 * non-volatile stored options. Data sheet does not talk about
154
+	 * this region.  Currently it is not working. But with some
155
+	 * efforts it can.
156
+	 */
157
+	nvo_init ( &np->nvo, &np->eeprom.nvs, 0x0c, 0x68, NULL );
162 158
 }
163 159
 
164 160
 /**

+ 7
- 13
src/drivers/net/rtl8139.c 查看文件

@@ -251,17 +251,6 @@ static struct bit_basher_operations rtl_basher_ops = {
251 251
 	.write = rtl_spi_write_bit,
252 252
 };
253 253
 
254
-/** Portion of EEPROM available for non-volatile stored options
255
- *
256
- * We use offset 0x40 (i.e. address 0x20), length 0x40.  This block is
257
- * marked as VPD in the rtl8139 datasheets, so we use it only if we
258
- * detect that the card is not supporting VPD.
259
- */
260
-static struct nvo_fragment rtl_nvo_fragments[] = {
261
-	{ 0x20, 0x40 },
262
-	{ 0, 0 }
263
-};
264
-
265 254
 /**
266 255
  * Set up for EEPROM access
267 256
  *
@@ -288,13 +277,18 @@ static void rtl_init_eeprom ( struct net_device *netdev ) {
288 277
 	}
289 278
 	rtl->eeprom.bus = &rtl->spibit.bus;
290 279
 
291
-	/* Initialise space for non-volatile options, if available */
280
+	/* Initialise space for non-volatile options, if available
281
+	 *
282
+	 * We use offset 0x40 (i.e. address 0x20), length 0x40.  This
283
+	 * block is marked as VPD in the rtl8139 datasheets, so we use
284
+	 * it only if we detect that the card is not supporting VPD.
285
+	 */
292 286
 	vpd = ( inw ( rtl->ioaddr + Config1 ) & VPDEnable );
293 287
 	if ( vpd ) {
294 288
 		DBGC ( rtl, "rtl8139 %p EEPROM in use for VPD; cannot use "
295 289
 		       "for options\n", rtl );
296 290
 	} else {
297
-		nvo_init ( &rtl->nvo, &rtl->eeprom.nvs, rtl_nvo_fragments,
291
+		nvo_init ( &rtl->nvo, &rtl->eeprom.nvs, 0x20, 0x40,
298 292
 			   &netdev->refcnt );
299 293
 	}
300 294
 }

+ 5
- 18
src/include/ipxe/nvo.h 查看文件

@@ -16,16 +16,6 @@ FILE_LICENCE ( GPL2_OR_LATER );
16 16
 struct nvs_device;
17 17
 struct refcnt;
18 18
 
19
-/**
20
- * A fragment of a non-volatile storage device used for stored options
21
- */
22
-struct nvo_fragment {
23
-	/** Starting address of fragment within NVS device */
24
-	unsigned int address;
25
-	/** Length of fragment */
26
-	size_t len;
27
-};
28
-
29 19
 /**
30 20
  * A block of non-volatile stored options
31 21
  */
@@ -34,13 +24,10 @@ struct nvo_block {
34 24
 	struct settings settings;
35 25
 	/** Underlying non-volatile storage device */
36 26
 	struct nvs_device *nvs;
37
-	/** List of option-containing fragments
38
-	 *
39
-	 * The list is terminated by a fragment with a length of zero.
40
-	 */
41
-	struct nvo_fragment *fragments;
42
-	/** Total length of option-containing fragments */
43
-	size_t total_len;
27
+	/** Address within NVS device */
28
+	unsigned int address;
29
+	/** Length of options data */
30
+	size_t len;
44 31
 	/** Option-containing data */
45 32
 	void *data;
46 33
 	/** DHCP options block */
@@ -48,7 +35,7 @@ struct nvo_block {
48 35
 };
49 36
 
50 37
 extern void nvo_init ( struct nvo_block *nvo, struct nvs_device *nvs,
51
-		       struct nvo_fragment *fragments, struct refcnt *refcnt );
38
+		       size_t address, size_t len, struct refcnt *refcnt );
52 39
 extern int register_nvo ( struct nvo_block *nvo, struct settings *parent );
53 40
 extern void unregister_nvo ( struct nvo_block *nvo );
54 41
 

Loading…
取消
儲存