Added the generic block-splitting code to nvs.c
authorMichael Brown <mcb30@etherboot.org>
Mon, 4 Dec 2006 19:06:07 +0000 (19:06 +0000)
committerMichael Brown <mcb30@etherboot.org>
Mon, 4 Dec 2006 19:06:07 +0000 (19:06 +0000)
src/drivers/net/rtl8139.c
src/drivers/nvs/nvs.c
src/include/gpxe/nvs.h
src/include/gpxe/threewire.h

index 503cee2..fe4b5cc 100644 (file)
@@ -265,26 +265,6 @@ static struct bit_basher_operations rtl_basher_ops = {
        rtl->eeprom.bus = &rtl->spibit.bus;
 }
 
-/**
- * Read the MAC address
- *
- * @v rtl              RTL8139 NIC
- * @v mac_addr         Buffer to contain MAC address (ETH_ALEN bytes)
- */
-static void rtl_read_mac ( struct rtl8139_nic *rtl, uint8_t *mac_addr ) {
-
-       struct nvs_device *nvs = &rtl->eeprom.nvs;
-       int i;
-       
-       DBG ( "MAC address is " );
-       for ( i = EE_MAC ; i < ( EE_MAC + ( ETH_ALEN / 2 ) ) ; i++ ) {
-               nvs_read ( nvs, i, mac_addr, 2 );
-               DBG ( "%02x%02x", mac_addr[0], mac_addr[1] );
-               mac_addr += 2;
-       }
-       DBG ( "\n" );
-}
-
 /**
  * Reset NIC
  *
@@ -531,7 +511,7 @@ static int rtl_probe ( struct pci_device *pci,
        /* Reset the NIC, set up EEPROM access and read MAC address */
        rtl_reset ( rtl );
        rtl_init_eeprom ( rtl );
-       rtl_read_mac ( rtl, netdev->ll_addr );
+       nvs_read ( &rtl->eeprom.nvs, EE_MAC, netdev->ll_addr, ETH_ALEN );
        
        /* Point to NIC specific routines */
        //      netdev->open     = rtl_open;
index 55cd828..3f22a0e 100644 (file)
@@ -17,6 +17,7 @@
  */
 
 #include <stdint.h>
+#include <assert.h>
 #include <gpxe/nvs.h>
 
 /** @file
  *
  */
 
+/**
+ * Read from non-volatile storage device
+ *
+ * @v nvs              NVS device
+ * @v address          Address from which to read
+ * @v data             Data buffer
+ * @v len              Length of data buffer
+ * @ret rc             Return status code
+ */
 int nvs_read ( struct nvs_device *nvs, unsigned int address,
               void *data, size_t len ) {
-       return nvs->read ( nvs, address, data, len );
+       size_t frag_len;
+       int rc;
+
+       /* We don't even attempt to handle buffer lengths that aren't
+        * an integral number of words.
+        */
+       assert ( ( len & ( ( 1 << nvs->word_len_log2 ) - 1 ) ) == 0 );
+
+       while ( len ) {
+
+               /* Calculate space remaining up to next block boundary */
+               frag_len = ( ( nvs->block_size -
+                              ( address & ( nvs->block_size - 1 ) ) )
+                            << nvs->word_len_log2 );
+
+               /* Limit to space remaining in buffer */
+               if ( frag_len > len )
+                       frag_len = len;
+
+               /* Read this portion of the buffer from the device */
+               if ( ( rc = nvs->read ( nvs, address, data, frag_len ) ) != 0 )
+                       return rc;
+
+               /* Update parameters */
+               data += frag_len;
+               address += ( frag_len >> nvs->word_len_log2 );
+               len -= frag_len;
+       }
+
+       return 0;
 }
index 38bc9c5..b026dd4 100644 (file)
 
 /** A non-volatile storage device */
 struct nvs_device {
-       /** Word length, in bits */
-       unsigned int word_len;
+       /** Word length
+        *
+        * This is expressed as the base-2 logarithm of the word
+        * length in bytes.  A value of 0 therefore translates as
+        * 8-bit words, and a value of 1 translates as 16-bit words.
+        */
+       unsigned int word_len_log2;
        /** Device size (in words) */
        unsigned int size;
        /** Data block size (in words)
index cbf6180..d60e1a7 100644 (file)
@@ -32,7 +32,7 @@ extern int threewire_read ( struct nvs_device *nvs, unsigned int address,
 
 static inline __attribute__ (( always_inline )) void
 init_at93cx6 ( struct spi_device *device, unsigned int organisation ) {
-       device->nvs.word_len = organisation;
+       device->nvs.word_len_log2 = ( ( organisation == 8 ) ? 0 : 1 );
        device->nvs.block_size = 1;
        device->command_len = 3,
        device->nvs.read = threewire_read;