1 package org.jscsi.target.scsi.modeSense; 2 3 4 import java.nio.ByteBuffer; 5 6 import org.jscsi.target.util.BitManip; 7 import org.jscsi.target.util.ReadWrite; 8 9 10 /** 11 * The Caching mode page defines the parameters that affect the use of the data cache by the storage medium. 12 * 13 * @author Andreas Ergenzinger 14 */ 15 public final class CachingModePage extends Page_0FormatModePage { 16 17 /** 18 * An initiator control (IC) enable bit set to one specifies that the device server use one of the following fields 19 * to control the caching algorithm rather than the device server’s own adaptive algorithm: 20 * <ol> 21 * <li> 22 * the NUMBER OF CACHE SEGMENTS field, if the SIZE bit is set to zero; or</li> 23 * <li> 24 * the CACHE SEGMENT SIZE field, if the SIZE bit is set to one.</li> 25 * </ol> 26 */ 27 private final boolean initiatorControl; 28 29 /** 30 * An abort pre-fetch (ABPF) bit set to one when the DRA bit is set to zero specifies that the device server abort a 31 * pre-fetch upon receipt of a new command. An ABPF bit set to one takes precedence over the value specified in the 32 * MINIMUM PRE-FETCH field. An ABPF bit set to zero when the DRA bit set to zero specifies that the termination of 33 * any active pre-fetch is dependent upon Caching mode page bytes 4 through 11 and is vendor specific. 34 */ 35 private final boolean abortPrefetch; 36 37 /** 38 * A caching analysis permitted (CAP) bit set to one specifies that the device server perform caching analysis 39 * during subsequent operations. A CAP bit set to zero specifies that caching analysis be disabled (e.g., to reduce 40 * overhead time or to prevent nonpertinent operations from impacting tuning values). 41 */ 42 private final boolean cachingAnalysisPermitted; 43 44 /** 45 * A discontinuity (DISC) bit set to one specifies that the device server continue the pre-fetch across time 46 * discontinuities (e.g., across cylinders) up to the limits of the buffer, or segment, space available for the 47 * pre-fetch. A DISC bit set to zero specifies that pre-fetches be truncated or wrapped at time discontinuities. 48 */ 49 private final boolean discontinuity; 50 51 /** 52 * A size enable (SIZE) bit set to one specifies that the CACHE SEGMENT SIZE field be used to control caching 53 * segmentation. A SIZE bit set to zero specifies that the NUMBER OF CACHE SEGMENTS field be used to control caching 54 * segmentation. Simultaneous use of both the number of segments and the segment size is vendor specific. 55 */ 56 private final boolean sizeEnable; 57 58 /** 59 * A writeback cache enable (WCE) bit set to zero specifies that the device server shall complete a WRITE command 60 * with GOOD status only after writing all of the data to the medium without error. A WCE bit set to one specifies 61 * that the device server may complete a WRITE command with GOOD status after receiving the data without error and 62 * prior to having written the data to the medium. 63 */ 64 private final boolean writebackCacheEnable; 65 66 /** 67 * A multiplication factor (MF) bit set to zero specifies that the device server shall interpret the MINIMUM 68 * PRE-FETCH field and the MAXIMUM PRE-FETCH field in terms of the number of logical blocks for each of the 69 * respective types of pre-fetch. An MF bit set to one specifies that the device server shall interpret the MINIMUM 70 * PRE-FETCH field and the MAXIMUM PRE-FETCH field to be specified in terms of a scalar number that, when multiplied 71 * by the number of logical blocks to be transferred for the current command, yields the number of logical blocks 72 * for each of the respective types of pre-fetch. 73 */ 74 private final boolean multiplicationFactor; 75 76 /** 77 * A read cache disable (RCD) bit set to zero specifies that the device server may return data requested by a READ 78 * command by accessing either the cache or medium. A RCD bit set to one specifies that the device server shall 79 * transfer all of the data requested by a READ command from the medium (i.e., data shall not be transferred from 80 * the cache). 81 */ 82 private final boolean readCacheDisable; 83 84 /** 85 * The DEMAND READ RETENTION PRIORITY field specifies the retention priority the device server should assign for 86 * data read into the cache that has also been transferred to the data-in buffer. 87 * <table border="1"> 88 * <tr> 89 * <th>Code</th> 90 * <th>Description</th> 91 * </tr> 92 * <tr> 93 * <td>0x0</td> 94 * <td>The device server should not distinguish between retaining the<br/> 95 * indicated data and data placed into the cache by other means <br/> 96 * (e.g., pre-fetch).</td> 97 * </tr> 98 * <tr> 99 * <td>0x1</td> 100 * <td>The device server should replace data put into the cache via a<br/> 101 * READ command sooner (i.e., read data has lower priority) than data<br/> 102 * placed into the cache by other means (e.g., pre-fetch).</td> 103 * </tr> 104 * <tr> 105 * <td>0x2 to 0xE</td> 106 * <td>Reserved</td> 107 * </tr> 108 * </tr> 109 * <tr> 110 * <td>0xF</td> 111 * <td>The device server should not replace data put into the cache<br/> 112 * via a READ command if there is other data in the cache that was<br/> 113 * placed into the cache by other means (e.g., pre-fetch) and the<br/> 114 * data in the cache may be replaced.</td> 115 * </tr> 116 * </table> 117 */ 118 private final byte demandReadRetentionPriority; 119 120 /** 121 * The WRITE RETENTION PRIORITY field (see table 155) specifies the retention priority the device server should 122 * assign for data written into the cache that has also been transferred from the cache to the medium. 123 * <table border="1"> 124 * <tr> 125 * <th>Code</th> 126 * <th>Description</th> 127 * </tr> 128 * <tr> 129 * <td>0x0</td> 130 * <td>The device server should not distinguish between retaining the<br/> 131 * indicated data and data placed into the cache by other means<br/> 132 * (e.g., pre-fetch).</td> 133 * </tr> 134 * <tr> 135 * <td>0x1</td> 136 * <td>The device server should replace data put into the cache during a<br/> 137 * WRITE command or a WRITE AND VERIFY command sooner (i.e., has lower<br/> 138 * priority) than data placed into the cache by other means (e.g., pre-fetch).</td> 139 * </tr> 140 * <tr> 141 * <td>0x2 to 0xE</td> 142 * <td>Reserved</td> 143 * </tr> 144 * </tr> 145 * <tr> 146 * <td>0xF</td> 147 * <td>The device server should not replace data put into the cache during<br/> 148 * a WRITE command or a WRITE AND VERIFY command if there is other data in<br/> 149 * the cache that was placed into the cache by other means (e.g., pre-fetch) <br/> 150 * and the data in the cache may be replaced.</td> 151 * </tr> 152 * </table> 153 */ 154 private final byte writeRetentionPriority; 155 156 /** 157 * The DISABLE PRE-FETCH TRANSFER LENGTH field specifies the selective disabling of anticipatory pre-fetch on long 158 * transfer lengths. The value in this field is compared to the transfer length requested by a READ command. If the 159 * transfer length is greater than the disable pre-fetch transfer length, then an anticipatory pre-fetch is not done 160 * for the command. Otherwise the device server should attempt an anticipatory pre-fetch. If the DISABLE PRE-FETCH 161 * TRANSFER LENGTH field is set to zero, then all anticipatory pre-fetching is disabled for any request for data, 162 * including those with a transfer length of zero. 163 * <p> 164 * An anticipatory pre-fetch occurs when data is placed in the cache that has not been requested. This may happen in 165 * conjunction with the reading of data that has been requested. The DISABLE PRE-FETCH TRANSFER LENGTH field, the 166 * MINIMUM PRE-FETCH field, the MAXIMUM PRE-FETCH field, and the MAXIMUM PRE-FETCH CEILING field give an indication 167 * to the device server how it should manage the cache based on the most recent READ command. An anticipatory 168 * pre-fetch may occur based on other information. These fields are only recommendations to the device server and 169 * should not cause a CHECK CONDITION to occur if the device server is not able to satisfy the request. 170 */ 171 private final int disablePrefetchTransferLength; 172 173 /** 174 * The MINIMUM PRE-FETCH field specifies the number of logical blocks to pre-fetch regardless of the delays it might 175 * cause in processing subsequent commands. The field contains either: 176 * <ol> 177 * <li>a number of logical blocks, if the MF bit is set to zero; or</li> 178 * <li>a scalar multiplier of the value in the TRANSFER LENGTH field, if the MF bit is set to one.</li> 179 * </ol> 180 * The pre-fetching operation begins at the logical block after the last logical block of a READ command. 181 * <p> 182 * Pre-fetching shall always halt when it reaches the last logical block on the medium. Errors that occur during the 183 * pre-fetching operation shall not be reported to the application client unless the device server is unable to 184 * process subsequent commands correctly as a result of the error. In this case the error may be reported either as 185 * an error for that subsequent command, or as a deferred error, at the discretion of the device server and 186 * according to the rules for reporting deferred errors (see SPC-4). 187 * <p> 188 * If the pre-fetch has read more than the amount of data specified by the MINIMUM PRE-FETCH field, then 189 * pre-fetching should be terminated whenever another command enters the enabled state (see SAM-4). This requirement 190 * is ignored when the MINIMUM PRE-FETCH field value is equal to the MAXIMUM PRE-FETCH field value. 191 * 192 * @see #disablePrefetchTransferLength 193 */ 194 private final int minimumPrefetch; 195 196 /** 197 * A complementary field to the {@link #minimumPrefetch} field. 198 * 199 * @see #disablePrefetchTransferLength 200 * @see #minimumPrefetch 201 */ 202 private final int maximumPrefetch; 203 204 /** 205 * The MAXIMUM PRE-FETCH CEILING field specifies an upper limit on the number of logical blocks computed as the 206 * maximum pre-fetch. If this number of logical blocks is greater than the value in the MAXIMUM PRE-FETCH field, 207 * then the number of logical blocks to pre-fetch shall be truncated to the value stored in the MAXIMUM PRE-FETCH 208 * CEILING field. 209 * 210 * @see #disablePrefetchTransferLength 211 */ 212 private final int maximumPrefetchCeiling; 213 214 /** 215 * A force sequential write (FSW) bit set to one specifies that, for commands writing to more than one logical 216 * block, the device server shall write the logical blocks to the medium in ascending sequential order. An FSW bit 217 * set to zero specifies that the device server may reorder the sequence of writing logical blocks (e.g., in order 218 * to achieve faster command completion). 219 */ 220 private final boolean forceSequentialWrite; 221 222 /** 223 * A logical block cache segment size (LBCSS) bit set to one specifies that the CACHE SEGMENT SIZE field units shall 224 * be interpreted as logical blocks. An LBCSS bit set to zero specifies that the CACHE SEGMENT SIZE field units 225 * shall be interpreted as bytes. The LBCSS shall not impact the units of other fields. 226 */ 227 private final boolean logicalBlockCacheSegmentSize; 228 229 /** 230 * A disable read-ahead (DRA) bit set to one specifies that the device server shall not read into the pre-fetch 231 * buffer any logical blocks beyond the addressed logical block(s). A DRA bit set to zero specifies that the device 232 * server may continue to read logical blocks into the pre-fetch buffer beyond the addressed logical block(s). 233 */ 234 private final boolean disableReadAhead; 235 236 /** 237 * An NV_DIS bit set to one specifies that the device server shall disable a non-volatile cache and indicates that a 238 * non-volatile cache is supported but disabled. An NV_DIS bit set to zero specifies that the device server may use 239 * a non-volatile cache and indicates that a non-volatile cache may be present and enabled. 240 */ 241 private final boolean nonVolatileCacheDisabled; 242 243 /** 244 * The NUMBER OF CACHE SEGMENTS field specifies the number of segments into which the device server shall divide the 245 * cache. 246 */ 247 private final short numberOfCacheSegments; 248 249 /** 250 * The CACHE SEGMENT SIZE field specifies the segment size in bytes if the LBCSS bit is set to zero or in logical 251 * blocks if the LBCSS bit is set to one. The CACHE SEGMENT SIZE field is valid only when the SIZE bit is set to 252 * one. 253 */ 254 private final int cacheSegmentSize; 255 256 /** 257 * The constructor. 258 * <p> 259 * The meaning of all parameters is described in the member descriptions of the variables with the same name. 260 * 261 * @param parametersSaveable 262 * @param initiatorControl 263 * @param abortPrefetch 264 * @param cachingAnalysisPermitted 265 * @param discontinuity 266 * @param sizeEnable 267 * @param writebackCacheEnable 268 * @param multiplicationFactor 269 * @param readCacheDisable 270 * @param demandReadRetentionPriority 271 * @param writeRetentionPriority 272 * @param disablePrefetchTransferLength 273 * @param minimumPrefetch 274 * @param maximumPrefetch 275 * @param maximumPrefetchCeiling 276 * @param forceSequentialWrite 277 * @param logicalBlockCacheSegmentSize 278 * @param disableReadAhead 279 * @param nonVolatileCacheDisabled 280 * @param numberOfCacheSegments 281 * @param cacheSegmentSize 282 */ 283 public CachingModePage (final boolean parametersSaveable, final boolean initiatorControl, final boolean abortPrefetch, final boolean cachingAnalysisPermitted, final boolean discontinuity, final boolean sizeEnable, final boolean writebackCacheEnable, final boolean multiplicationFactor, final boolean readCacheDisable, final int demandReadRetentionPriority, final int writeRetentionPriority, final int disablePrefetchTransferLength, final int minimumPrefetch, final int maximumPrefetch, final int maximumPrefetchCeiling, final boolean forceSequentialWrite, final boolean logicalBlockCacheSegmentSize, final boolean disableReadAhead, final boolean nonVolatileCacheDisabled, final int numberOfCacheSegments, final int cacheSegmentSize) { 284 super(parametersSaveable,// PS 285 0x08,// pageCode 286 0x12);// pageLength 287 this.initiatorControl = initiatorControl; 288 this.abortPrefetch = abortPrefetch; 289 this.cachingAnalysisPermitted = cachingAnalysisPermitted; 290 this.discontinuity = discontinuity; 291 this.sizeEnable = sizeEnable; 292 this.writebackCacheEnable = writebackCacheEnable; 293 this.multiplicationFactor = multiplicationFactor; 294 this.readCacheDisable = readCacheDisable; 295 this.demandReadRetentionPriority = (byte) (demandReadRetentionPriority & 0xf); 296 this.writeRetentionPriority = (byte) (writeRetentionPriority & 0xf); 297 this.disablePrefetchTransferLength = disablePrefetchTransferLength & 0xffff; 298 this.minimumPrefetch = minimumPrefetch & 0xffff; 299 this.maximumPrefetch = maximumPrefetch & 0xffff; 300 this.maximumPrefetchCeiling = maximumPrefetchCeiling & 0xffff; 301 this.forceSequentialWrite = forceSequentialWrite; 302 this.logicalBlockCacheSegmentSize = logicalBlockCacheSegmentSize; 303 this.disableReadAhead = disableReadAhead; 304 this.nonVolatileCacheDisabled = nonVolatileCacheDisabled; 305 this.numberOfCacheSegments = (short) (numberOfCacheSegments & 0xff); 306 this.cacheSegmentSize = cacheSegmentSize & 0xffff; 307 } 308 309 @Override 310 protected void serializeModeParameters (ByteBuffer buffer, int index) { 311 // serialize byte 2 312 buffer.position(index + 2); 313 byte b = 0; 314 b = BitManip.getByteWithBitSet(b, 7, initiatorControl); 315 b = BitManip.getByteWithBitSet(b, 6, abortPrefetch); 316 b = BitManip.getByteWithBitSet(b, 5, cachingAnalysisPermitted); 317 b = BitManip.getByteWithBitSet(b, 4, discontinuity); 318 b = BitManip.getByteWithBitSet(b, 3, sizeEnable); 319 b = BitManip.getByteWithBitSet(b, 2, writebackCacheEnable); 320 b = BitManip.getByteWithBitSet(b, 1, multiplicationFactor); 321 b = BitManip.getByteWithBitSet(b, 0, readCacheDisable); 322 buffer.put(b); 323 // serialize byte 3 324 b = (byte) ((demandReadRetentionPriority << 4) | writeRetentionPriority); 325 buffer.put(b); 326 // bytes 4 to 11 (unsigned short fields) 327 ReadWrite.writeTwoByteInt(buffer,// buffer 328 disablePrefetchTransferLength,// value 329 index + 4);// index 330 ReadWrite.writeTwoByteInt(buffer,// buffer 331 minimumPrefetch,// value 332 index + 6);// index 333 ReadWrite.writeTwoByteInt(buffer,// buffer 334 maximumPrefetch,// value 335 index + 8);// index 336 ReadWrite.writeTwoByteInt(buffer,// buffer 337 maximumPrefetchCeiling,// value 338 index + 10);// index 339 // byte 12 340 b = 0; 341 b = BitManip.getByteWithBitSet(b, 7, forceSequentialWrite); 342 b = BitManip.getByteWithBitSet(b, 6, logicalBlockCacheSegmentSize); 343 b = BitManip.getByteWithBitSet(b, 5, disableReadAhead); 344 b = BitManip.getByteWithBitSet(b, 0, nonVolatileCacheDisabled); 345 buffer.position(index + 12); 346 buffer.put(b); 347 // byte 13 348 buffer.put((byte) numberOfCacheSegments); 349 // bytes 14 and 15 350 ReadWrite.writeTwoByteInt(buffer,// buffer 351 cacheSegmentSize,// value 352 index + 14);// index 353 // the remaining bytes are reserved or obsolete 354 } 355 356 }