Changeset a5de1ef in rtems for cpukit/libblock


Ignore:
Timestamp:
01/05/08 06:57:17 (16 years ago)
Author:
Chris Johns <chrisj@…>
Branches:
4.10, 4.11, 4.9, 5, master
Children:
a61cc6c
Parents:
74ee68d
Message:

2008-01-05 Chris Johns <chrisj@…>

  • configure.ac: Fix typo in the strict order mutex CPU OPTs test.
  • libmisc/shell/shell.c: Handle '#' comment characters correctly.
  • libblock/include/rtems/flashdisk.h: Add docmentation about the control fields. Add more control fields to handle the flash when full.
  • libblock/src/flashdisk.c: Fix the descriptor erase test so it detects a descriptor is erased. Add support for unavailable blocks the user can configure. Print the used list as a diag. Fix the bug when a page is detected as failed and present on more than one queue. Add a count to the queues so queue length can be used to manage compaction.
Location:
cpukit/libblock
Files:
2 edited

Legend:

Unmodified
Added
Removed
  • cpukit/libblock/include/rtems/flashdisk.h

    r74ee68d ra5de1ef  
    5858  uint32_t block_size;
    5959  uint32_t block_count;
     60  uint32_t unavail_blocks;
    6061  uint32_t device_count;
    6162  uint32_t segment_count;
     
    265266 * RTEMS Flash Disk configuration table used to initialise the
    266267 * driver.
     268 *
     269 * The unavailable blocks count is the number of blocks less than the
     270 * available number of blocks the file system is given. This means there
     271 * will always be that number of blocks available when the file system
     272 * thinks the disk is full. The compaction code needs blocks to compact
     273 * with so you will never be able to have all the blocks allocated to the
     274 * file system and be able to full the disk.
     275 *
     276 * The compacting segment count is the number of segments that are
     277 * moved into a new segment. A high number will mean more segments with
     278 * low active page counts and high used page counts will be moved into
     279 * avaliable pages how-ever this extends the compaction time due to
     280 * time it takes the erase the pages. There is no pont making this number
     281 * greater than the maximum number of pages in a segment.
     282 *
     283 * The available compacting segment count is the level when compaction occurs
     284 * when writing. If you set this to 0 then compaction will fail because
     285 * there will be no segments to compact into.
     286 *
     287 * The info level can be 0 for off with error, and abort messages allowed.
     288 * Level 1 is warning messages, level 1 is informational messages, and level 3
     289 * is debugging type prints. The info level can be turned off with a compile
     290 * time directive on the command line to the compiler of:
     291 *
     292 *     -DRTEMS_FDISK_TRACE=0
    267293 */
    268294typedef struct rtems_flashdisk_config
    269295{
    270   uint32_t                       block_size;   /**< The block size. */
    271   uint32_t                       device_count; /**< The number of devices. */
    272   const rtems_fdisk_device_desc* devices;      /**< The device descriptions. */
    273   uint32_t                       flags;        /**< Set of flags to control
    274                                                     driver. */
    275   uint32_t                       compact_segs; /**< Max number of segs to
    276                                                     compact in one pass. */
    277   uint32_t                       info_level;   /**< Default info level. */
     296  uint32_t                       block_size;     /**< The block size. */
     297  uint32_t                       device_count;   /**< The number of devices. */
     298  const rtems_fdisk_device_desc* devices;        /**< The device descriptions. */
     299  uint32_t                       flags;          /**< Set of flags to control
     300                                                      driver. */
     301  uint32_t                       unavail_blocks; /**< Number of blocks not
     302                                                      available to the file sys. */
     303  uint32_t                       compact_segs;   /**< Max number of segs to
     304                                                      compact in one pass. */
     305  uint32_t                       avail_compact_segs; /**< The number of segments
     306                                                          when compaction occurs
     307                                                          when writing. */
     308  uint32_t                       info_level;     /**< Default info level. */
    278309} rtems_flashdisk_config;
    279310
  • cpukit/libblock/src/flashdisk.c

    r74ee68d ra5de1ef  
    205205  uint32_t pages_bad;     /**< Number of pages detected as bad. */
    206206
     207  uint32_t failed;        /**< The segment has failed. */
     208
    207209  uint32_t erased;        /**< Counter to debugging. Wear support would
    208210                               remove this. */
     
    216218  rtems_fdisk_segment_ctl* head;
    217219  rtems_fdisk_segment_ctl* tail;
     220  uint32_t                 count;
    218221} rtems_fdisk_segment_ctl_queue;
    219222
     
    249252
    250253  uint32_t compact_segs;                   /**< Max segs to compact at once. */
     254  uint32_t avail_compact_segs;             /**< The number of segments when
     255                                                compaction occurs when writing. */
    251256 
    252257  uint32_t               block_size;       /**< The block size for this disk. */
    253258  rtems_fdisk_block_ctl* blocks;           /**< The block to segment-page
    254259                                                mappings. */
    255   uint32_t               block_count;      /**< The number of available
    256                                                 blocks. */
     260  uint32_t block_count;                    /**< The number of avail. blocks. */
     261  uint32_t unavail_blocks;                 /**< The number of unavail blocks. */
     262 
    257263  rtems_fdisk_device_ctl* devices;         /**< The flash devices for this
    258264                                                disk. */
     
    444450{
    445451  queue->head = queue->tail = 0;
     452  queue->count = 0;
     453}
     454
     455/**
     456 * Push to the head of the segment control queue.
     457 */
     458static void
     459rtems_fdisk_segment_queue_push_head (rtems_fdisk_segment_ctl_queue* queue,
     460                                     rtems_fdisk_segment_ctl*       sc)
     461{
     462  if (sc)
     463  {
     464    sc->next = queue->head;
     465    queue->head = sc;
     466 
     467    if (queue->tail == 0)
     468      queue->tail = sc;
     469    queue->count++;
     470  }
    446471}
    447472
     
    460485      queue->tail = 0;
    461486
     487    queue->count--;
     488
    462489    sc->next = 0;
    463490
     
    467494  return 0;
    468495}
    469 
    470 /**
    471  * Push to the head of the segment control queue.
    472  */
    473 #if 0
    474 static void
    475 rtems_fdisk_segment_queue_push_head (rtems_fdisk_segment_ctl_queue* queue,
    476                                      rtems_fdisk_segment_ctl*       sc)
    477 {
    478   if (sc)
    479   {
    480     if (queue->head)
    481       sc->next = queue->head;
    482     else
    483     {
    484       queue->tail = sc;
    485       sc->next = 0;
    486     }
    487 
    488     queue->head = sc;
    489   }
    490 }
    491 #endif
    492496
    493497/**
     
    511515      queue->head = queue->tail = sc;
    512516    }
     517
     518    queue->count++;
    513519  }
    514520}
     
    545551      }
    546552      sc->next = 0;
     553      queue->count--;
    547554      break;
    548555    }
     
    573580        sc->next = item;
    574581        *prev = sc;
     582        queue->count++;
    575583        return;
    576584      }
     
    590598rtems_fdisk_segment_queue_count (rtems_fdisk_segment_ctl_queue* queue)
    591599{
     600  return queue->count;
     601}
     602
     603/**
     604 * Count the number of elements on the list.
     605 */
     606static uint32_t
     607rtems_fdisk_segment_count_queue (rtems_fdisk_segment_ctl_queue* queue)
     608{
    592609  rtems_fdisk_segment_ctl* sc = queue->head;
    593610  uint32_t                 count = 0;
     
    605622 * See if a segment control is present on this queue.
    606623 */
    607 #if RTEMS_FDISK_TRACE
    608624static bool
    609625rtems_fdisk_segment_queue_present (rtems_fdisk_segment_ctl_queue* queue,
     
    621637  return false;
    622638}
    623 #endif
    624 
    625 /**
    626  * Check if the buffer is erased.
    627  */
    628 static bool
    629 rtems_fdisk_is_erased (const void* buffer, uint32_t size)
    630 {
    631   const uint8_t* p = buffer;
    632   uint32_t       c;
    633   for (c = 0; c < size; c++)
    634   {
    635     if (*p != 0xff)
    636       return false;
    637   }
    638   return true;
     639
     640/**
     641 * Format a string with the queue status.
     642 */
     643static void
     644rtems_fdisk_queue_status (rtems_flashdisk*         fd,
     645                          rtems_fdisk_segment_ctl* sc,
     646                          char                     queues[5])
     647{
     648  queues[0] = rtems_fdisk_segment_queue_present (&fd->available, sc) ? 'A' : '-';
     649  queues[1] = rtems_fdisk_segment_queue_present (&fd->used, sc)      ? 'U' : '-';
     650  queues[2] = rtems_fdisk_segment_queue_present (&fd->erase, sc)     ? 'E' : '-';
     651  queues[3] = rtems_fdisk_segment_queue_present (&fd->failed, sc)    ? 'F' : '-';
     652  queues[4] = '\0';
    639653}
    640654
     
    645659rtems_fdisk_page_desc_erased (const rtems_fdisk_page_desc* pd)
    646660{
    647   return rtems_fdisk_is_erased (pd, sizeof (rtems_fdisk_page_desc));
     661  return ((pd->crc == 0xffff) &&
     662          (pd->flags == 0xffff) &&
     663          (pd->block == 0xffffffff)) ? true : false;
    648664}
    649665
     
    11271143                       "segment erase failed: %s (%d)",
    11281144                       sc->device, sc->segment, strerror (ret), ret);
    1129     rtems_fdisk_segment_queue_push_tail (&fd->failed, sc);
     1145    sc->failed = true;
     1146    if (!rtems_fdisk_segment_queue_present (&fd->failed, sc))
     1147      rtems_fdisk_segment_queue_push_tail (&fd->failed, sc);
    11301148    return ret;
    11311149  }
     
    11381156  sc->pages_used   = 0;
    11391157  sc->pages_bad    = 0;
     1158 
     1159  sc->failed = false;
    11401160
    11411161  /*
     
    11841204{
    11851205#if RTEMS_FDISK_TRACE
    1186   rtems_fdisk_info (fd, " queue-seg:%02d-%03d: p=%d a=%d u=%d b=%d n=%s",
     1206  rtems_fdisk_info (fd, " queue-seg:%02d-%03d: p=%d a=%d u=%d b=%d f=%s n=%s",
    11871207                    sc->device, sc->segment,
    11881208                    sc->pages, sc->pages_active, sc->pages_used, sc->pages_bad,
    1189                     sc->next ? "set" : "null");
    1190 #endif
    1191 
     1209                    sc->failed ? "FAILED" : "no", sc->next ? "set" : "null");
     1210#endif
     1211
     1212  /*
     1213   * If the segment has failed then check the failed queue and append
     1214   * if not failed.
     1215   */
     1216  if (sc->failed)
     1217  {
     1218    if (!rtems_fdisk_segment_queue_present (&fd->failed, sc))
     1219      rtems_fdisk_segment_queue_push_tail (&fd->failed, sc);
     1220    return;
     1221  }
     1222 
    11921223  /*
    11931224   * Remove the queue from the available or used queue.
     
    12081239    {
    12091240      /*
    1210        * Keep the used queue sorted on the least number
    1211        * of pages. When we compact we want to move the
    1212        * pages into a new segment and cover more than one
    1213        * segment.
     1241       * Keep the used queue sorted by the most number of used
     1242       * pages. When we compact we want to move the pages into
     1243       * a new segment and cover more than one segment.
    12141244       */
    12151245      rtems_fdisk_segment_ctl* seg = fd->used.head;
     
    12941324  {
    12951325    rtems_fdisk_segment_ctl* dsc;
    1296 
     1326    rtems_fdisk_segment_ctl* ssc;
     1327    uint32_t                 dst_pages;
     1328    uint32_t                 segments;
     1329    uint32_t                 pages;
     1330
     1331#if RTEMS_FDISK_TRACE
     1332    rtems_fdisk_printf (fd, " compacting");
     1333#endif
     1334     
    12971335    dsc = rtems_fdisk_seg_most_available (&fd->available);
    12981336
    1299     if (dsc)
    1300     {
    1301       rtems_fdisk_segment_ctl* ssc = fd->used.head;
    1302       uint32_t                 dst_pages = rtems_fdisk_seg_pages_available (dsc);
    1303       uint32_t                 segments = 0;
    1304       uint32_t                 pages = 0;
    1305 
    1306 #if RTEMS_FDISK_TRACE
    1307       rtems_fdisk_printf (fd, "dsc: %d-%d", dsc->device, dsc->segment);
     1337    if (dsc == 0)
     1338    {
     1339      rtems_fdisk_error ("compacting: no available segments to compact too");
     1340      return EIO;
     1341    }
     1342   
     1343    ssc = fd->used.head;
     1344    dst_pages = rtems_fdisk_seg_pages_available (dsc);
     1345    segments = 0;
     1346    pages = 0;
     1347   
     1348#if RTEMS_FDISK_TRACE
     1349    rtems_fdisk_printf (fd, " dsc:%02d-%03d: most available",
     1350                        dsc->device, dsc->segment);
    13081351#endif
    13091352     
    1310       /*
    1311        * Count the number of segments that have active pages that fit into
    1312        * the destination segment. Also limit the number of segments that
    1313        * we handle during one compaction. A lower number means less aggressive
    1314        * compaction or less delay when compacting but it may mean the disk
    1315        * will fill.
    1316        */
     1353    /*
     1354     * Count the number of segments that have active pages that fit into
     1355     * the destination segment. Also limit the number of segments that
     1356     * we handle during one compaction. A lower number means less aggressive
     1357     * compaction or less delay when compacting but it may mean the disk
     1358     * will fill.
     1359     */
    13171360     
    1318       while (ssc &&
    1319              ((pages + ssc->pages_active) < dst_pages) &&
    1320              ((compacted_segs + segments) < fd->compact_segs))
     1361    while (ssc &&
     1362           ((pages + ssc->pages_active) < dst_pages) &&
     1363           ((compacted_segs + segments) < fd->compact_segs))
     1364    {
     1365      pages += ssc->pages_active;
     1366      segments++;
     1367      ssc = ssc->next;
     1368    }
     1369
     1370    /*
     1371     * We need a source segment and have pages to copy and
     1372     * compacting one segment to another is silly. Compaction needs
     1373     * to free at least one more segment.
     1374     */
     1375       
     1376    if (!ssc || (pages == 0) || ((compacted_segs + segments) == 1))
     1377      break;
     1378
     1379#if RTEMS_FDISK_TRACE
     1380    rtems_fdisk_printf (fd, " ssc scan: %d-%d: p=%ld, seg=%ld",
     1381                        ssc->device, ssc->segment,
     1382                        pages, segments);
     1383#endif
     1384     
     1385    rtems_fdisk_segment_queue_remove (&fd->available, dsc);
     1386
     1387    /*
     1388     * We now copy the pages to the new segment.
     1389     */
     1390     
     1391    while (pages)
     1392    {
     1393      uint32_t spage;
     1394      int      ret;
     1395
     1396      ssc = rtems_fdisk_segment_queue_pop_head (&fd->used);
     1397
     1398      if (ssc)
    13211399      {
    1322         pages += ssc->pages_active;
    1323         segments++;
    1324         ssc = ssc->next;
     1400        uint32_t used = 0;
     1401        uint32_t active = 0;
     1402        for (spage = 0; spage < ssc->pages; spage++)
     1403        {
     1404          rtems_fdisk_page_desc* spd = &ssc->page_descriptors[spage];
     1405
     1406          if (rtems_fdisk_page_desc_flags_set (spd, RTEMS_FDISK_PAGE_ACTIVE) &&
     1407              !rtems_fdisk_page_desc_flags_set (spd, RTEMS_FDISK_PAGE_USED))
     1408          {
     1409            rtems_fdisk_page_desc* dpd;
     1410            uint32_t               dpage;
     1411
     1412            dpage = rtems_fdisk_seg_next_available_page (dsc);
     1413            dpd   = &dsc->page_descriptors[dpage];
     1414             
     1415            active++;
     1416             
     1417            if (dpage >= dsc->pages)
     1418            {
     1419              rtems_fdisk_error ("compacting: %02d-%03d: " \
     1420                                 "no page desc available: %d",
     1421                                 dsc->device, dsc->segment,
     1422                                 rtems_fdisk_seg_pages_available (dsc));
     1423              dsc->failed = true;
     1424              rtems_fdisk_queue_segment (fd, dsc);
     1425              rtems_fdisk_segment_queue_push_head (&fd->used, ssc);
     1426              return EIO;
     1427            }
     1428           
     1429#if RTEMS_FDISK_TRACE
     1430            rtems_fdisk_info (fd, "compacting: %02d-%03d-%03d=>%02d-%03d-%03d",
     1431                              ssc->device, ssc->segment, spage,
     1432                              dsc->device, dsc->segment, dpage);
     1433#endif
     1434            ret = rtems_fdisk_seg_copy_page (fd, ssc->device, ssc->segment,
     1435                                             spage + ssc->pages_desc,
     1436                                             dsc->device, dsc->segment,
     1437                                             dpage + dsc->pages_desc);
     1438            if (ret)
     1439            {
     1440              rtems_fdisk_error ("compacting: %02d-%03d-%03d=>" \
     1441                                 "%02d-%03d-%03d: "             \
     1442                                 "copy page failed: %s (%d)",
     1443                                 ssc->device, ssc->segment, spage,
     1444                                 dsc->device, dsc->segment, dpage,
     1445                                 strerror (ret), ret);
     1446              dsc->failed = true;
     1447              rtems_fdisk_queue_segment (fd, dsc);
     1448              rtems_fdisk_segment_queue_push_head (&fd->used, ssc);
     1449              return ret;
     1450            }
     1451
     1452            *dpd = *spd;
     1453
     1454            ret = rtems_fdisk_seg_write_page_desc (fd,
     1455                                                   dsc->device, dsc->segment,
     1456                                                   dpage, dpd);
     1457
     1458            if (ret)
     1459            {
     1460              rtems_fdisk_error ("compacting: %02d-%03d-%03d=>"   \
     1461                                 "%02d-%03d-%03d: copy pd failed: %s (%d)",
     1462                                 ssc->device, ssc->segment, spage,
     1463                                 dsc->device, dsc->segment, dpage,
     1464                                 strerror (ret), ret);
     1465              dsc->failed = true;
     1466              rtems_fdisk_queue_segment (fd, dsc);
     1467              rtems_fdisk_segment_queue_push_head (&fd->used, ssc);
     1468              return ret;
     1469            }
     1470
     1471            dsc->pages_active++;
     1472
     1473            /*
     1474             * No need to set the used bit on the source page as the
     1475             * segment will be erased. Power down could be a problem.
     1476             * We do the stats to make sure everything is as it should
     1477             * be.
     1478             */
     1479           
     1480            ssc->pages_active--;
     1481            ssc->pages_used++;
     1482             
     1483            fd->blocks[spd->block].segment = dsc;
     1484            fd->blocks[spd->block].page    = dpage;
     1485
     1486            /*
     1487             * Place the segment on to the correct queue.
     1488             */
     1489            rtems_fdisk_queue_segment (fd, dsc);
     1490             
     1491            pages--;
     1492          }
     1493          else
     1494            used++;
     1495        }
     1496
     1497#if RTEMS_FDISK_TRACE
     1498        rtems_fdisk_printf (fd, "ssc end: %d-%d: p=%ld, a=%ld, u=%ld",
     1499                            ssc->device, ssc->segment,
     1500                            pages, active, used);
     1501#endif
     1502        if (ssc->pages_active != 0)
     1503        {
     1504          rtems_fdisk_error ("compacting: ssc pages not 0: %d",
     1505                             ssc->pages_active);
     1506        }
     1507         
     1508        ret = rtems_fdisk_erase_segment (fd, ssc);
     1509
     1510        if (ret)
     1511          return ret;
    13251512      }
    1326 
    1327       /*
    1328        * We need a source segment and have pages to copy and
    1329        * compacting one segment to another is silly. Compaction needs
    1330        * to free at least one more segment.
    1331        */
    1332        
    1333       if (!ssc || (pages == 0) || ((compacted_segs + segments) == 1))
    1334         break;
    1335 
    1336 #if RTEMS_FDISK_TRACE
    1337       rtems_fdisk_printf (fd, "ssc scan: %d-%d: p=%ld, seg=%ld",
    1338                           ssc->device, ssc->segment,
    1339                           pages, segments);
    1340 #endif
    1341      
    1342       rtems_fdisk_segment_queue_remove (&fd->available, dsc);
    1343 
    1344       /*
    1345        * We now copy the pages to the new segment.
    1346        */
    1347      
    1348       while (pages)
    1349       {
    1350         uint32_t spage;
    1351         int      ret;
    1352 
    1353         ssc = rtems_fdisk_segment_queue_pop_head (&fd->used);
    1354 
    1355         if (ssc)
    1356         {
    1357           uint32_t used = 0;
    1358           uint32_t active = 0;
    1359           for (spage = 0; spage < ssc->pages; spage++)
    1360           {
    1361             rtems_fdisk_page_desc* spd = &ssc->page_descriptors[spage];
    1362 
    1363             if (rtems_fdisk_page_desc_flags_set (spd, RTEMS_FDISK_PAGE_ACTIVE) &&
    1364                 !rtems_fdisk_page_desc_flags_set (spd, RTEMS_FDISK_PAGE_USED))
    1365             {
    1366               rtems_fdisk_page_desc* dpd;
    1367               uint32_t               dpage;
    1368 
    1369               dpage = rtems_fdisk_seg_next_available_page (dsc);
    1370               dpd   = &dsc->page_descriptors[dpage];
    1371              
    1372               active++;
    1373              
    1374               if (dpage >= dsc->pages)
    1375               {
    1376                 rtems_fdisk_error ("compacting: %02d-%03d: " \
    1377                                    "no page desc available: %d",
    1378                                    dsc->device, dsc->segment,
    1379                                    rtems_fdisk_seg_pages_available (dsc));
    1380                 rtems_fdisk_segment_queue_push_tail (&fd->failed, dsc);
    1381                 return EIO;
    1382               }
    1383            
    1384 #if RTEMS_FDISK_TRACE
    1385               rtems_fdisk_info (fd, "compacting: %02d-%03d-%03d=>%02d-%03d-%03d",
    1386                                 ssc->device, ssc->segment, spage,
    1387                                 dsc->device, dsc->segment, dpage);
    1388 #endif
    1389               ret = rtems_fdisk_seg_copy_page (fd, ssc->device, ssc->segment,
    1390                                                spage + ssc->pages_desc,
    1391                                                dsc->device, dsc->segment,
    1392                                                dpage + dsc->pages_desc);
    1393               if (ret)
    1394               {
    1395                 rtems_fdisk_error ("compacting: %02d-%03d-%03d=>" \
    1396                                    "%02d-%03d-%03d: "             \
    1397                                    "copy page failed: %s (%d)",
    1398                                    ssc->device, ssc->segment, spage,
    1399                                    dsc->device, dsc->segment, dpage,
    1400                                    strerror (ret), ret);
    1401                 rtems_fdisk_segment_queue_push_tail (&fd->failed, dsc);
    1402                 return ret;
    1403               }
    1404 
    1405               *dpd = *spd;
    1406 
    1407               ret = rtems_fdisk_seg_write_page_desc (fd,
    1408                                                      dsc->device, dsc->segment,
    1409                                                      dpage, dpd);
    1410 
    1411               if (ret)
    1412               {
    1413                 rtems_fdisk_error ("compacting: %02d-%03d-%03d=>"   \
    1414                                    "%02d-%03d-%03d: copy pd failed: %s (%d)",
    1415                                    ssc->device, ssc->segment, spage,
    1416                                    dsc->device, dsc->segment, dpage,
    1417                                    strerror (ret), ret);
    1418                 rtems_fdisk_segment_queue_push_tail (&fd->failed, dsc);
    1419                 return ret;
    1420               }
    1421 
    1422               dsc->pages_active++;
    1423 
    1424               /*
    1425                * No need to set the used bit on the source page as the
    1426                * segment will be erased. Power down could be a problem.
    1427                * We do the stats to make sure everything is as it should
    1428                * be.
    1429                */
    1430            
    1431               ssc->pages_active--;
    1432               ssc->pages_used++;
    1433              
    1434               fd->blocks[spd->block].segment = dsc;
    1435               fd->blocks[spd->block].page    = dpage;
    1436 
    1437               /*
    1438                * Place the segment on to the correct queue.
    1439                */
    1440               rtems_fdisk_queue_segment (fd, dsc);
    1441              
    1442               pages--;
    1443             }
    1444             else
    1445               used++;
    1446           }
    1447 
    1448 #if RTEMS_FDISK_TRACE
    1449           rtems_fdisk_printf (fd, "ssc end: %d-%d: p=%ld, a=%ld, u=%ld",
    1450                               ssc->device, ssc->segment,
    1451                               pages, active, used);
    1452 #endif
    1453           if (ssc->pages_active != 0)
    1454           {
    1455             rtems_fdisk_error ("compacting: ssc pages not 0: %d",
    1456                                ssc->pages_active);
    1457           }
    1458          
    1459           ret = rtems_fdisk_erase_segment (fd, ssc);
    1460 
    1461           if (ret)
    1462             return ret;
    1463         }
    1464       }
    1465 
    1466       compacted_segs += segments;
    1467     }
     1513    }
     1514
     1515    compacted_segs += segments;
    14681516  }
    14691517
     
    15171565      sc->pages_used   = 0;
    15181566      sc->pages_bad    = 0;
    1519    
     1567
     1568      sc->failed = false;
     1569     
    15201570      if (!sc->page_descriptors)
    15211571        sc->page_descriptors = malloc (sc->pages_desc * fd->block_size);
     
    15751625           
    15761626            if (ret)
     1627            {
    15771628              rtems_fdisk_error ("forcing page to used failed: %d-%d-%d",
    15781629                                 device, segment, page);
     1630              sc->failed = true;
     1631            }
    15791632           
    15801633            sc->pages_used++;
     
    16651718  rtems_fdisk_page_desc*   pd;
    16661719
     1720#if RTEMS_FDISK_TRACE
     1721  rtems_fdisk_info (fd, "read-block:%d", block);
     1722#endif
     1723
    16671724  /*
    16681725   * Broken out to allow info messages when testing.
    16691726   */
    16701727
    1671   if (block >= fd->block_count)
    1672   {
    1673     rtems_fdisk_error ("read-block: bad block: %d", block);
     1728  if (block >= (fd->block_count - fd->unavail_blocks))
     1729  {
     1730    rtems_fdisk_error ("read-block: block out of range: %d", block);
    16741731    return EIO;
    16751732  }
     
    16911748#if RTEMS_FDISK_TRACE
    16921749  rtems_fdisk_info (fd,
    1693                     "read-block:%d=>%02d-%03d-%03d: p=%d a=%d u=%d b=%d n=%s: " \
     1750                    " read:%d=>%02d-%03d-%03d: p=%d a=%d u=%d b=%d n=%s: " \
    16941751                    "f=%04x c=%04x b=%d",
    16951752                    block, sc->device, sc->segment, bc->page,
     
    17821839  int                      ret;
    17831840   
     1841#if RTEMS_FDISK_TRACE
     1842  rtems_fdisk_info (fd, "write-block:%d", block);
     1843#endif
    17841844
    17851845  /*
     
    17871847   */
    17881848
    1789   if (block >= fd->block_count)
    1790   {
    1791     rtems_fdisk_error ("write-block: bad block: %d", block);
     1849  if (block >= (fd->block_count - fd->unavail_blocks))
     1850  {
     1851    rtems_fdisk_error ("write-block: block out of range: %d", block);
    17921852    return EIO;
    17931853  }
     
    18021862    sc = bc->segment;
    18031863    pd = &sc->page_descriptors[bc->page];
     1864
     1865#if RTEMS_FDISK_TRACE
     1866    rtems_fdisk_info (fd, " write:%02d-%03d-%03d: flag used",
     1867                      sc->device, sc->segment, bc->page);
     1868#endif
    18041869
    18051870    /*
     
    18311896    {
    18321897#if RTEMS_FDISK_TRACE
    1833       rtems_fdisk_info (fd, "write-block:%02d-%03d-%03d: "      \
     1898      rtems_fdisk_info (fd, " write:%02d-%03d-%03d: "      \
    18341899                        "write used page desc failed: %s (%d)",
    18351900                        sc->device, sc->segment, bc->page,
    18361901                        strerror (ret), ret);
    18371902#endif
    1838     }
    1839 
    1840     sc->pages_active--;
    1841     sc->pages_used++;
    1842 
     1903      sc->failed = true;
     1904    }
     1905    else
     1906    {
     1907      sc->pages_active--;
     1908      sc->pages_used++;
     1909    }
     1910   
    18431911    /*
    18441912     * If possible reuse this segment. This will mean the segment
     
    18581926
    18591927  /*
     1928   * Is it time to compact the disk ?
     1929   *
     1930   * We override the background compaction configruation.
     1931   */
     1932  if (rtems_fdisk_segment_count_queue (&fd->available) <=
     1933      fd->avail_compact_segs)
     1934    rtems_fdisk_compact (fd);
     1935 
     1936  /*
    18601937   * Get the next avaliable segment.
    18611938   */
     
    18861963  }
    18871964
     1965#if RTEMS_FDISK_TRACE
     1966  if (fd->info_level >= 3)
     1967  {
     1968    char queues[5];
     1969    rtems_fdisk_queue_status (fd, sc, queues);
     1970    rtems_fdisk_info (fd, " write:%d=>%02d-%03d: queue check: %s",
     1971                      block, sc->device, sc->segment, queues);
     1972  }
     1973#endif
     1974 
    18881975  /*
    18891976   * Find the next avaliable page in the segment.
     
    19051992
    19061993#if RTEMS_FDISK_TRACE
    1907       rtems_fdisk_info (fd, "write-block:%d=>%02d-%03d-%03d: "          \
     1994      rtems_fdisk_info (fd, " write:%d=>%02d-%03d-%03d: write: " \
    19081995                        "p=%d a=%d u=%d b=%d n=%s: f=%04x c=%04x b=%d",
    19091996                        block, sc->device, sc->segment, page,
     
    19262013                          strerror (ret), ret);
    19272014#endif
    1928         rtems_fdisk_segment_queue_push_tail (&fd->failed, sc);
    1929         return ret;
     2015        sc->failed = true;
     2016      }
     2017      else
     2018      {
     2019        ret = rtems_fdisk_seg_write_page_desc (fd, sc->device, sc->segment,
     2020                                               page, pd);
     2021        if (ret)
     2022        {
     2023#if RTEMS_FDISK_TRACE
     2024          rtems_fdisk_info (fd, "write-block:%02d-%03d-%03d: "  \
     2025                            "write page desc failed: %s (%d)",
     2026                            sc->device, sc->segment, bc->page,
     2027                            strerror (ret), ret);
     2028#endif
     2029          sc->failed = true;
     2030        }
     2031        else
     2032        {
     2033          sc->pages_active++;
     2034        }
    19302035      }
    19312036     
    1932       ret = rtems_fdisk_seg_write_page_desc (fd, sc->device, sc->segment,
    1933                                              page, pd);
    1934       if (ret)
    1935       {
    1936 #if RTEMS_FDISK_TRACE
    1937         rtems_fdisk_info (fd, "write-block:%02d-%03d-%03d: "  \
    1938                           "write page desc failed: %s (%d)",
    1939                           sc->device, sc->segment, bc->page,
    1940                           strerror (ret), ret);
    1941 #endif
    1942         rtems_fdisk_segment_queue_push_tail (&fd->failed, sc);
    1943         return ret;
    1944       }
    1945    
    1946       sc->pages_active++;
    1947    
    19482037      rtems_fdisk_queue_segment (fd, sc);
    1949 
    1950       return 0;
     2038      return ret;
    19512039    }
    19522040  }
     
    19552043                     sc->device, sc->segment);
    19562044
    1957   rtems_fdisk_segment_queue_push_tail (&fd->failed, sc);
     2045  sc->failed = true;
     2046  rtems_fdisk_queue_segment (fd, sc);
    19582047
    19592048  return EIO;
     
    20842173  data->block_size     = fd->block_size;
    20852174  data->block_count    = fd->block_count;
     2175  data->unavail_blocks = fd->unavail_blocks;
    20862176  data->device_count   = fd->device_count;
    20872177
     
    20912181      data->blocks_used++;
    20922182
    2093   data->segs_available = rtems_fdisk_segment_queue_count (&fd->available);
    2094   data->segs_used      = rtems_fdisk_segment_queue_count (&fd->used);
    2095   data->segs_failed    = rtems_fdisk_segment_queue_count (&fd->failed);
     2183  data->segs_available = rtems_fdisk_segment_count_queue (&fd->available);
     2184  data->segs_used      = rtems_fdisk_segment_count_queue (&fd->used);
     2185  data->segs_failed    = rtems_fdisk_segment_count_queue (&fd->failed);
    20962186
    20972187  data->segment_count = 0;
     
    21422232
    21432233  rtems_fdisk_printf (fd, "Block count\t%d", fd->block_count);
    2144   count = rtems_fdisk_segment_queue_count (&fd->available);
     2234  rtems_fdisk_printf (fd, "Unavail blocks\t%d", fd->unavail_blocks);
     2235  count = rtems_fdisk_segment_count_queue (&fd->available);
    21452236  total = count;
    2146   rtems_fdisk_printf (fd, "Available queue\t%ld", count);
    2147   count = rtems_fdisk_segment_queue_count (&fd->used);
     2237  rtems_fdisk_printf (fd, "Available queue\t%ld (%ld)",
     2238                      count, rtems_fdisk_segment_queue_count (&fd->available));
     2239  count = rtems_fdisk_segment_count_queue (&fd->used);
    21482240  total += count;
    2149   rtems_fdisk_printf (fd, "Used queue\t%ld", count);
    2150   count = rtems_fdisk_segment_queue_count (&fd->erase);
     2241  rtems_fdisk_printf (fd, "Used queue\t%ld (%ld)",
     2242                      count, rtems_fdisk_segment_queue_count (&fd->used));
     2243  count = rtems_fdisk_segment_count_queue (&fd->erase);
    21512244  total += count;
    2152   rtems_fdisk_printf (fd, "Erase queue\t%ld", count);
    2153   count = rtems_fdisk_segment_queue_count (&fd->failed);
     2245  rtems_fdisk_printf (fd, "Erase queue\t%ld (%ld)",
     2246                      count, rtems_fdisk_segment_queue_count (&fd->erase));
     2247  count = rtems_fdisk_segment_count_queue (&fd->failed);
    21542248  total += count;
    2155   rtems_fdisk_printf (fd, "Failed queue\t%ld", count);
     2249  rtems_fdisk_printf (fd, "Failed queue\t%ld (%ld)",
     2250                      count, rtems_fdisk_segment_queue_count (&fd->failed));
    21562251
    21572252  count = 0;
     
    21832278      char                     queues[5];
    21842279
    2185       queues[0] = '-';
    2186       queues[1] = '-';
    2187       queues[2] = '-';
    2188       queues[3] = '-';
    2189       queues[4] = '\0';
    2190      
    2191       if (rtems_fdisk_segment_queue_present (&fd->available, sc))
    2192         queues[0] = 'A';
    2193       if (rtems_fdisk_segment_queue_present (&fd->used, sc))
    2194         queues[1] = 'U';
    2195       if (rtems_fdisk_segment_queue_present (&fd->erase, sc))
    2196         queues[2] = 'E';
    2197       if (rtems_fdisk_segment_queue_present (&fd->failed, sc))
    2198         queues[3] = 'F';
    2199                                              
     2280      rtems_fdisk_queue_status (fd, sc, queues);
     2281
    22002282      for (page = 0; page < sc->pages; page++)
    22012283      {
     
    22422324    }
    22432325  }
    2244  
     2326
     2327  {
     2328    rtems_fdisk_segment_ctl* sc = fd->used.head;
     2329    int count = 0;
     2330    rtems_fdisk_printf (fd, "Used List:");
     2331    while (sc)
     2332    {
     2333      rtems_fdisk_printf (fd, "  %3d %02d:%03d u:%3ld",
     2334                          count, sc->device, sc->segment, sc->pages_used);
     2335      sc = sc->next;
     2336      count++;
     2337    }
     2338  }
    22452339  fd->info_level = current_info_level;
    22462340
     
    23832477              RTEMS_FLASHDISK_DEVICE_BASE_NAME "%" PRIu32, minor);
    23842478 
    2385     fd->major        = major;
    2386     fd->minor        = minor;
    2387     fd->flags        = c->flags;
    2388     fd->compact_segs = c->compact_segs;
    2389     fd->block_size   = c->block_size;
    2390     fd->info_level   = c->info_level;
     2479    fd->major              = major;
     2480    fd->minor              = minor;
     2481    fd->flags              = c->flags;
     2482    fd->compact_segs       = c->compact_segs;
     2483    fd->avail_compact_segs = c->avail_compact_segs;
     2484    fd->block_size         = c->block_size;
     2485    fd->unavail_blocks     = c->unavail_blocks;
     2486    fd->info_level         = c->info_level;
    23912487 
    23922488    for (device = 0; device < c->device_count; device++)
     
    23942490                                              c->block_size);
    23952491 
    2396     sc = rtems_disk_create_phys(dev, c->block_size, blocks,
     2492    sc = rtems_disk_create_phys(dev, c->block_size,
     2493                                blocks - fd->unavail_blocks,
    23972494                                rtems_fdisk_ioctl, name);
    23982495    if (sc != RTEMS_SUCCESSFUL)
Note: See TracChangeset for help on using the changeset viewer.