1# Copyright (c) 2010 The Chromium OS Authors. All rights reserved. 2# Use of this source code is governed by a BSD-style license that can be 3# found in the LICENSE file. 4 5import logging 6import os 7 8from autotest_lib.client.bin import test, utils 9from autotest_lib.client.common_lib import error 10 11DEFAULT_MIN_GB = 16 12# Allowable amount of bits eMMC vendor can use in firmware to support bad block 13# replacement and metadata. 14EMMC_VENDOR_ALLOWED_GB = 0.25 15# Amount of data available for user data in device, the rest is left for 16# over provisioning. 17# Typically a SATA device will use 7% over provisioning [the difference 18# between GB and GiB], but some eMMC device can use 9%. 19# With Flash becoming more error prone as lithography shrinks, the trend 20# is to increase over provisioning. 21DEFAULT_USER_DENSITY = 0.9 22 23 24class hardware_DiskSize(test.test): 25 """ 26 Check that disk size is around 16GB at least. 27 """ 28 29 version = 1 30 31 def _is_emmc(self): 32 path = os.path.join("/sys/class/block/", self._device, 33 "device", "type") 34 if not os.path.exists(path): 35 return False 36 return utils.read_one_line(path) == 'MMC' 37 38 39 @classmethod 40 def _gib_to_gb(cls, gib): 41 return float(gib) * (1 << 30) / (10 ** 9) 42 43 def _compute_min_gb(self): 44 """Computes minimum size allowed primary storage device. 45 46 TODO(tbroch): Add computation of raw bytes in eMMC using 'Chip Specific 47 Data' (CSD & EXT_CSD) defined by JEDEC JESD84-A44.pdf if possible. 48 49 CSD :: /sys/class/block/<device>/device/csd 50 EXT_CSD :: debugfs 51 52 Algorithm should look something like this: 53 CSD[C_SIZE] = 0xfff == eMMC > 2GB 54 EXT_CSD[SEC_COUNT] = # of 512byte sectors 55 56 Now for existing eMMC I've examined I do see the C_SIZE == 0xfff. 57 Unfortunately the SEC_COUNT appears to have excluded the sectors 58 reserved for metadata & repair. Perhaps thats by design in which case 59 there is no mechanism to determine the actual raw sectors. 60 61 For now I use 0.25GB as an acceptable fudge. 62 63 Returns: 64 integer, in GB of minimum storage size. 65 """ 66 67 min_gb = DEFAULT_MIN_GB 68 if self._is_emmc(): 69 min_gb -= EMMC_VENDOR_ALLOWED_GB 70 min_gb *= DEFAULT_USER_DENSITY 71 return self._gib_to_gb(min_gb) 72 73 74 def run_once(self): 75 root_dev = utils.get_root_device() 76 self._device = os.path.basename(root_dev) 77 disk_size = utils.get_disk_size(root_dev) 78 if not disk_size: 79 raise error.TestError('Unable to determine main disk size') 80 81 # Capacity of a hard disk is quoted with SI prefixes, incrementing by 82 # powers of 1000, instead of powers of 1024. 83 gb = float(disk_size) / (10 ** 9) 84 85 self.write_perf_keyval({"gb_main_disk_size": gb}) 86 min_gb = self._compute_min_gb() 87 logging.info("DiskSize: %.3f GB MinDiskSize: %.3f GB", gb, min_gb) 88 if (gb < min_gb): 89 raise error.TestError("DiskSize %.3f GB below minimum (%.3f GB)" \ 90 % (gb, min_gb)) 91 92