MCPcopy Create free account
hub / github.com/PiSCSI/piscsi / ModeSelect

Method ModeSelect

cpp/devices/scsi_streamer.cpp:164–225  ·  view source on GitHub ↗

Source from the content-addressed store, hash-verified

162}
163
164void SCSIST::ModeSelect(scsi_command cmd, cdb_t cdb, span<const uint8_t> buff, int length)
165{
166 /*
167+=====-========-========-========-========-========-========-========-========+
168| Bit| 7 | 6 | 5 | 4 | 3 | 2 | 1 | 0 |
169|Byte | | | | | | | | |
170|=====+=======================================================================|
171| 0 | Operation code (15h) |
172|-----+-----------------------------------------------------------------------|
173| 1 | Logical unit number | PF | Reserved | SP |
174|-----+-----------------------------------------------------------------------|
175| 2 | Reserved |
176|-----+-----------------------------------------------------------------------|
177| 3 | Reserved |
178|-----+-----------------------------------------------------------------------|
179| 4 | Parameter list length |
180|-----+-----------------------------------------------------------------------|
181| 5 | Control |
182+=============================================================================+
183*/
184 if (cmd != scsi_command::eCmdModeSelect6 || length < 12)
185 throw scsi_exception(sense_key::illegal_request, asc::invalid_command_operation_code);
186
187 // If the PF-bit is set to zero, the
188 // Drive will not accept any Mode Pages in the parameter list; only the
189 // Header List and a Block Descriptor List will be accepted. If the Drive
190 // receives a parameter list containing bytes beyond the Header List and a
191 // Block Descriptor List, it will terminate the MODE SELECT command
192 // with CHECK CONDITION and set the Sense Key to ILLEGAL REQUEST and the AS/AQ sense bytes to PARAMETER LIST LENGTH
193 // ERROR. The Error Code will be set to E$STE_PLEN.
194 bool pf = cdb[1] & 0x10;
195
196
197 // A Save Page (SP) bit of zero indicates that the Drive will perform the
198 // specified MODE SELECT operation, but not save any mode parameters.
199 // A SP bit of one indicates that the Drive will perform the specified
200 // MODE SELECT operation and also save all saveable MODE SELECT
201 // parameters received during the DATA OUT phase.
202 bool sp = cdb[1] & 0x01;// this one is tricky, should we have two sets of settings ?!?!?
203
204
205 // This field specifies the length in bytes of the MODE SELECT parameter
206 // list that will be transferred from the Initiator to the Drive during the
207 // DATA OUT phase. A Parameter List Length of zero indicates that no
208 // data will be transferred. No mode selection parameters are then
209 // changed. A parameter list length must never result in the truncation of
210 // any header, descriptor or page of parameters.
211 uint8_t params_list_len = cdb[4] & 0xff;
212 if ((!pf && params_list_len != 12) || params_list_len < 12 || params_list_len > length)
213 throw scsi_exception(sense_key::illegal_request, asc::parameter_list_length_error);
214
215 // Header List
216
217 // Check Block Descriptor Length
218 if (buff[3] != 0x08)
219 throw scsi_exception(sense_key::illegal_request, asc::invalid_field_in_parameter_list);
220
221 // Block Descriptor List

Callers

nothing calls this directly

Calls 2

scsi_exceptionClass · 0.85
GetInt24Function · 0.85

Tested by

no test coverage detected