1 package org.jscsi.target.connection.stage.fullfeature;
2
3
4 import static org.jscsi.target.storage.IStorageModule.VIRTUAL_BLOCK_SIZE;
5
6 import java.io.IOException;
7 import java.security.DigestException;
8
9 import org.jscsi.exception.InternetSCSIException;
10 import org.jscsi.parser.BasicHeaderSegment;
11 import org.jscsi.parser.ProtocolDataUnit;
12 import org.jscsi.parser.scsi.SCSICommandParser;
13 import org.jscsi.target.connection.phase.TargetFullFeaturePhase;
14 import org.jscsi.target.scsi.cdb.ReadCapacity10Cdb;
15 import org.jscsi.target.scsi.cdb.ReadCapacity16Cdb;
16 import org.jscsi.target.scsi.cdb.ReadCapacityCdb;
17 import org.jscsi.target.scsi.cdb.ScsiOperationCode;
18 import org.jscsi.target.scsi.readCapacity.ReadCapacity10ParameterData;
19 import org.jscsi.target.scsi.readCapacity.ReadCapacity16ParameterData;
20 import org.jscsi.target.scsi.readCapacity.ReadCapacityParameterData;
21 import org.jscsi.target.scsi.sense.AdditionalSenseCodeAndQualifier;
22 import org.jscsi.target.scsi.sense.senseDataDescriptor.senseKeySpecific.FieldPointerSenseKeySpecificData;
23 import org.jscsi.target.settings.SettingsException;
24 import org.slf4j.Logger;
25 import org.slf4j.LoggerFactory;
26
27
28 public final class ReadCapacityStage extends TargetFullFeatureStage {
29
30 private static final Logger LOGGER = LoggerFactory.getLogger(ReadCapacityStage.class);
31
32 public ReadCapacityStage (final TargetFullFeaturePhase targetFullFeaturePhase) {
33 super(targetFullFeaturePhase);
34 }
35
36 @Override
37 public void execute (ProtocolDataUnit pdu) throws IOException , InterruptedException , InternetSCSIException , DigestException , SettingsException {
38
39
40 final BasicHeaderSegment bhs = pdu.getBasicHeaderSegment();
41 final SCSICommandParser parser = (SCSICommandParser) bhs.getParser();
42 final ScsiOperationCode opCode = ScsiOperationCode.valueOf(parser.getCDB().get(0));
43 ReadCapacityCdb cdb;
44 if (opCode == ScsiOperationCode.READ_CAPACITY_10)
45 cdb = new ReadCapacity10Cdb(parser.getCDB());
46 else if (opCode == ScsiOperationCode.READ_CAPACITY_16)
47 cdb = new ReadCapacity16Cdb(parser.getCDB());
48 else {
49
50 throw new InternetSCSIException("wrong SCSI Operation Code " + opCode + " in ReadCapacityStage");
51 }
52
53
54
55
56
57
58
59
60
61 if (session.getStorageModule().checkBounds(cdb.getLogicalBlockAddress(), 0) != 0) {
62
63 LOGGER.error("encountered " + cdb.getClass() + " in ReadCapacityStage with " + "LOGICAL BLOCK ADDRESS = " + cdb.getLogicalBlockAddress());
64
65 final FieldPointerSenseKeySpecificData fp = new FieldPointerSenseKeySpecificData(true,
66 true,
67 false,
68 0,
69 0);
70 final FieldPointerSenseKeySpecificData[] fpArray = new FieldPointerSenseKeySpecificData[] { fp };
71 final ProtocolDataUnit responsePdu = createFixedFormatErrorPdu(fpArray,
72 AdditionalSenseCodeAndQualifier.LOGICAL_BLOCK_ADDRESS_OUT_OF_RANGE,
73 bhs.getInitiatorTaskTag(),
74 parser.getExpectedDataTransferLength());
75 connection.sendPdu(responsePdu);
76 return;
77 } else {
78
79 ReadCapacityParameterData parameterData;
80 if (cdb instanceof ReadCapacity10Cdb)
81 parameterData = new ReadCapacity10ParameterData(session.getStorageModule().getSizeInBlocks(),
82 VIRTUAL_BLOCK_SIZE);
83 else
84 parameterData = new ReadCapacity16ParameterData(session.getStorageModule().getSizeInBlocks(),
85 VIRTUAL_BLOCK_SIZE);
86
87 sendResponse(bhs.getInitiatorTaskTag(),
88 parser.getExpectedDataTransferLength(),
89 parameterData);
90 }
91 }
92
93 }