]> oss.titaniummirror.com Git - tinyos-2.x.git/blobdiff - tos/chips/stm25p/Stm25pLogP.nc
stm25p: fix seek error
[tinyos-2.x.git] / tos / chips / stm25p / Stm25pLogP.nc
index 7ccde10fe9b4a7b31f6a3556f05f3bf555f560fe..b63cf3f71f5baa507b20b7d2de2b3460337d1b89 100644 (file)
@@ -87,8 +87,8 @@ implementation {
   stm25p_log_state_t m_req;
   stm25p_log_info_t m_log_info[ NUM_LOGS ];
   stm25p_addr_t m_addr;
+  bool m_records_lost;
   uint8_t m_header;
-  uint8_t m_remaining;
   uint8_t m_len;
 
   typedef enum {
@@ -161,8 +161,8 @@ implementation {
     
     // don't allow appends larger than maximum record size
     if ( len > MAX_RECORD_SIZE )
-      return ESIZE;
-
+      return EINVAL;
+    
     // move to next block if current block doesn't have enough space
     if ( sizeof( m_header ) + len > bytes_left )
       m_log_info[ id ].write_addr += bytes_left;
@@ -172,7 +172,8 @@ implementation {
         ( (uint8_t)(m_log_info[ id ].write_addr >> STM25P_SECTOR_SIZE_LOG2) >=
           call Sector.getNumSectors[ id ]() ) )
       return ESIZE;
-
+    
+    m_records_lost = FALSE;
     m_req.req = S_APPEND;
     m_req.buf = buf;
     m_req.len = len;
@@ -198,6 +199,18 @@ implementation {
     
   }
   
+  uint8_t calcSector( uint8_t client, stm25p_addr_t addr ) {
+    uint8_t sector = call Sector.getNumSectors[ client ]();
+    return (uint8_t)(( addr >> STM25P_SECTOR_SIZE_LOG2 ) % sector);
+  }
+
+  stm25p_addr_t calcAddr( uint8_t client, stm25p_addr_t addr  ) {
+    stm25p_addr_t result = calcSector( client, addr );
+    result <<= STM25P_SECTOR_SIZE_LOG2;
+    result |= addr & STM25P_SECTOR_MASK;
+    return result;
+  }
+
   event void ClientResource.granted[ uint8_t id ]() {
 
     // log never used, need to find start and end of log
@@ -217,9 +230,9 @@ implementation {
        {
          // make sure the cookie is still within the range of valid data
          uint8_t numSectors = call Sector.getNumSectors[ id ]();
-         uint8_t readSector = 
+         uint16_t readSector =
            (m_log_state[ id ].cookie >> STM25P_SECTOR_SIZE_LOG2);
-         uint8_t writeSector =
+         uint16_t writeSector =
            ((m_log_info[ id ].write_addr-1)>>STM25P_SECTOR_SIZE_LOG2)+1;
          // if cookie is overwritten, advance to beginning of log
          if ( (writeSector - readSector) > numSectors ) {
@@ -227,12 +240,14 @@ implementation {
              (storage_cookie_t)(writeSector-numSectors)
                <<STM25P_SECTOR_SIZE_LOG2;
          }
-         m_log_info[ id ].read_addr = m_log_state[ id ].cookie & BLOCK_MASK;
+         m_log_info[ id ].read_addr = m_log_state[ id ].cookie & ~BLOCK_MASK;
          m_log_info[ id ].remaining = 0;
          m_rw_state = S_SEARCH_SEEK;
-         if ( m_log_info[ id ].read_addr != m_log_state[ id ].cookie )
-           call Sector.read[ id ]( m_log_info[ id ].read_addr, &m_header,
-                                   sizeof( m_header ) );
+         if ( m_log_info[ id ].read_addr != m_log_state[ id ].cookie ) {
+           m_log_info[ id ].read_addr += sizeof( m_addr );
+           call Sector.read[ id ]( calcAddr( id, m_log_info[ id ].read_addr ),
+                                   &m_header, sizeof( m_header ) );
+         }
          else
            signalDone( id, SUCCESS );
        }
@@ -254,18 +269,6 @@ implementation {
     
   }
 
-  uint8_t calcSector( uint8_t client, stm25p_addr_t addr ) {
-    uint8_t sector = call Sector.getNumSectors[ client ]();
-    return (uint8_t)( addr >> STM25P_SECTOR_SIZE_LOG2 ) % sector;
-  }
-
-  stm25p_addr_t calcAddr( uint8_t client, stm25p_addr_t addr  ) {
-    stm25p_addr_t result = calcSector( client, addr );
-    result <<= STM25P_SECTOR_SIZE_LOG2;
-    result |= addr & STM25P_SECTOR_MASK;
-    return result;
-  }
-
   void continueReadOp( uint8_t client ) {
     
     stm25p_addr_t read_addr = m_log_info[ client ].read_addr;
@@ -279,7 +282,7 @@ implementation {
     }
     
     buf = &m_header;
-    len = sizeof( len );
+    len = sizeof( m_header );
 
     if ( m_rw_state == S_DATA ) {
       // if header is invalid, move to next block
@@ -289,17 +292,18 @@ implementation {
        read_addr &= ~BLOCK_MASK;
       }
       else {
-       buf = m_log_state[ client ].buf;
+       buf = m_log_state[ client ].buf + m_log_state[ client ].len - m_len;
        // truncate if record is shorter than requested length
-       if ( m_remaining < m_len )
-         m_log_state[ client ].len = m_remaining;
-       len = m_len;
+       if ( m_log_info[ client ].remaining < m_len )
+         len = m_log_info[ client ].remaining;
+       else
+         len = m_len;
       }
     }
     
     // if on block boundary
     if ( !((uint16_t)read_addr & BLOCK_MASK ) )
-      read_addr += sizeof( storage_addr_t );
+      read_addr += sizeof( m_addr );
     
     m_log_info[ client ].read_addr = read_addr;
     call Sector.read[ client ]( calcAddr( client, read_addr ), buf, len );
@@ -315,7 +319,7 @@ implementation {
     switch( m_rw_state ) {
     case S_SEARCH_BLOCKS: 
       {
-       uint8_t block = addr >> BLOCK_SIZE_LOG2;
+       uint16_t block = addr >> BLOCK_SIZE_LOG2;
        // record potential starting and ending addresses
        if ( m_addr != STM25P_INVALID_ADDRESS ) {
          if ( m_addr < log_info->read_addr )
@@ -324,8 +328,7 @@ implementation {
            log_info->write_addr = m_addr;
        }
        // move on to next log block
-       if ( (uint16_t)m_addr == 0 &&
-            ++block < (call Sector.getNumSectors[ id ]()*BLOCKS_PER_SECTOR)) {
+       if (++block < (call Sector.getNumSectors[ id ]()*BLOCKS_PER_SECTOR)) {
          addr += BLOCK_SIZE;
          call Sector.read[ id ]( addr, (uint8_t*)&m_addr, sizeof( m_addr ) );
        }
@@ -339,7 +342,7 @@ implementation {
        else {
          log_info->write_addr += sizeof( m_addr );
          m_rw_state = S_SEARCH_RECORDS;
-         call Sector.read[ id ]( log_info->write_addr, &m_header,
+         call Sector.read[ id ]( calcAddr(id, log_info->write_addr), &m_header,
                                  sizeof( m_header ) );
        }
       }
@@ -354,8 +357,8 @@ implementation {
        // if header is valid and is on same block, move to next record
        if ( m_header != INVALID_HEADER && cur_block == new_block ) {
          log_info->write_addr += sizeof( m_header ) + m_header;
-         call Sector.read[ id ]( log_info->write_addr, &m_header,
-                                 sizeof( m_header ) );
+         call Sector.read[ id ]( calcAddr( id, log_info->write_addr ), 
+                                 &m_header, sizeof( m_header ) );
        }
        // found last record
        else {
@@ -369,8 +372,8 @@ implementation {
        // searching for last log record to read
        log_info->read_addr += sizeof( m_header ) + m_header;
        // if not yet at cookie, keep searching
-       if ( log_info->read_addr < m_log_state->cookie ) {
-         call Sector.read[ id ]( log_info->read_addr, &m_header,
+       if ( log_info->read_addr < m_log_state[ id ].cookie ) {
+         call Sector.read[ id ]( calcAddr(id, log_info->read_addr), &m_header,
                                  sizeof( m_header ) );
        }
        // at or passed cookie, stop
@@ -415,14 +418,19 @@ implementation {
   void continueAppendOp( uint8_t client ) {
     
     stm25p_addr_t write_addr = m_log_info[ client ].write_addr;
-    uint8_t* buf;
+    void* buf;
     uint8_t len;
     
     if ( !(uint16_t)write_addr ) {
+      m_records_lost = TRUE;
       call Sector.erase[ client ]( calcSector( client, write_addr ), 1 );
     }
     else {
-      if ( m_rw_state == S_HEADER ) {
+      if ( !((uint16_t)write_addr & BLOCK_MASK) ) {
+       buf = &m_log_info[ client ].write_addr;
+       len = sizeof( m_addr );
+      }
+      else if ( m_rw_state == S_HEADER ) {
        buf = &m_log_state[ client ].len;
        len = sizeof( m_log_state[ client ].len );
       }
@@ -448,7 +456,7 @@ implementation {
       // (the log could have cycled around)
       stm25p_addr_t volume_size = 
        STM25P_SECTOR_SIZE * ( call Sector.getNumSectors[ id ]() - 1 );
-      if ( m_log_info[ id ].write_addr >= volume_size ) {
+      if ( m_log_info[ id ].write_addr > volume_size ) {
        stm25p_addr_t read_addr = m_log_info[ id ].write_addr - volume_size;
        if ( m_log_info[ id ].read_addr < read_addr )
          m_log_info[ id ].read_addr = read_addr;
@@ -495,7 +503,7 @@ implementation {
       signal Write.eraseDone[ id ]( error );
       break;
     case S_APPEND:
-      signal Write.appendDone[ id ]( buf, len, error );
+      signal Write.appendDone[ id ]( buf, len, m_records_lost, error );
       break;
     case S_SYNC:
       signal Write.syncDone[ id ]( error );
@@ -508,7 +516,7 @@ implementation {
   default event void Read.readDone[ uint8_t id ]( void* data, storage_len_t len, error_t error ) {}
   default event void Read.seekDone[ uint8_t id ]( error_t error ) {}
   default event void Write.eraseDone[ uint8_t id ]( error_t error ) {}
-  default event void Write.appendDone[ uint8_t id ]( void* data, storage_len_t len, error_t error ) {}
+  default event void Write.appendDone[ uint8_t id ]( void* data, storage_len_t len, bool recordsLost, error_t error ) {}
   default event void Write.syncDone[ uint8_t id ]( error_t error ) {}
 
   default command storage_addr_t Sector.getPhysicalAddress[ uint8_t id ]( storage_addr_t addr ) { return 0xffffffff; }
@@ -518,7 +526,7 @@ implementation {
   default command error_t Sector.erase[ uint8_t id ]( uint8_t sector, uint8_t num_sectors ) { return FAIL; }
   default command error_t Sector.computeCrc[ uint8_t id ]( uint16_t crc, storage_addr_t addr, storage_len_t len ) { return FAIL; }
   default async command error_t ClientResource.request[ uint8_t id ]() { return FAIL; }
-  default async command void ClientResource.release[ uint8_t id ]() {}
+  default async command error_t ClientResource.release[ uint8_t id ]() { return FAIL; }
   default command bool Circular.get[ uint8_t id ]() { return FALSE; }
   
 }