Remove MIN and MAX defines, which GLib provides.
[obnox/wireshark/wip.git] / epan / dissectors / packet-scsi.c
1 /* packet-scsi.c
2  * Routines for decoding SCSI CDBs and responses
3  * Author: Dinesh G Dutt (ddutt@cisco.com)
4  *
5  * $Id$
6  *
7  * Ethereal - Network traffic analyzer
8  * By Gerald Combs <gerald@ethereal.com>
9  * Copyright 2002 Gerald Combs
10  *
11  * This program is free software; you can redistribute it and/or
12  * modify it under the terms of the GNU General Public License
13  * as published by the Free Software Foundation; either version 2
14  * of the License, or (at your option) any later version.
15  *
16  * This program is distributed in the hope that it will be useful,
17  * but WITHOUT ANY WARRANTY; without even the implied warranty of
18  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
19  * GNU General Public License for more details.
20  *
21  * You should have received a copy of the GNU General Public License
22  * along with this program; if not, write to the Free Software
23  * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
24  */
25
26 /*
27  * Some Notes on using the SCSI Decoder:
28  *
29  * The SCSI decoder has been built right now that it is invoked directly by the
30  * SCSI transport layers as compared to the standard mechanism of being invoked
31  * via a dissector chain. There are multiple reasons for this:
32  * - The SCSI CDB is typically embedded inside the transport along with other
33  *   header fields that have nothing to do with SCSI. So, it is required to be
34  *   invoked on a embedded subset of the packet.
35  * - Originally, Ethereal couldn't do filtering on protocol trees that were not
36  *   on the top level.
37  *
38  * There are four main routines that are provided:
39  * o dissect_scsi_cdb - invoked on receiving a SCSI Command
40  *   void dissect_scsi_cdb (tvbuff_t *, packet_info *, proto_tree *,
41  *   guint, guint16);
42  * o dissect_scsi_payload - invoked to decode SCSI responses
43  *   void dissect_scsi_payload (tvbuff_t *, packet_info *, proto_tree *, guint,
44  *                              gboolean, guint32, guint16);
45  *   The final parameter is the length of the response field that is negotiated
46  *   as part of the SCSI transport layer. If this is not tracked by the
47  *   transport, it can be set to 0.
48  * o dissect_scsi_rsp - invoked to destroy the data structures associated with a
49  *                      SCSI task.
50  *   void dissect_scsi_rsp (tvbuff_t *, packet_info *, proto_tree *, guint16,
51  *                          guint8);
52  * o dissect_scsi_snsinfo - invoked to decode the sense data provided in case of
53  *                          an error.
54  *   void dissect_scsi_snsinfo (tvbuff_t *, packet_info *, proto_tree *, guint,
55  *   guint, guint16);
56  *
57  * In addition to this, the other requirement made from the transport is to
58  * provide a unique way to determine a SCSI task. In Fibre Channel networks,
59  * this is the exchange ID pair alongwith the source/destination addresses; in
60  * iSCSI it is the initiator task tag along with the src/dst address and port
61  * numbers. This is to be provided to the SCSI decoder via the private_data
62  * field in the packet_info data structure. The private_data field is treated
63  * as a pointer to a "scsi_task_id_t" structure, containing a conversation
64  * ID (a number uniquely identifying a conversation between a particular
65  * initiator and target, e.g. between two Fibre Channel addresses or between
66  * two TCP address/port pairs for iSCSI or NDMP) and a task ID (a number
67  * uniquely identifying a task within that conversation).
68  *
69  * This decoder attempts to track the type of SCSI device based on the response
70  * to the Inquiry command. If the trace does not contain an Inquiry command,
71  * the decoding of the commands is done as per a user preference. Currently,
72  * only SBC (disks) and SSC (tapes) are the alternatives offered. The basic
73  * SCSI command set (SPC-2/3) is decoded for all SCSI devices. If there is a
74  * mixture of devices in the trace, some with Inquiry response and some
75  * without, the user preference is used only for those devices whose type the
76  * decoder has not been able to determine.
77  *
78  */
79 #ifdef HAVE_CONFIG_H
80 # include "config.h"
81 #endif
82
83 #include <glib.h>
84 #include <string.h>
85 #include <epan/strutil.h>
86 #include <epan/packet.h>
87 #include <epan/prefs.h>
88 #include <epan/emem.h>
89 #include "packet-scsi.h"
90
91 static int proto_scsi                    = -1;
92 static int hf_scsi_lun                   = -1;
93 static int hf_scsi_status                = -1;
94 static int hf_scsi_spcopcode             = -1;
95 static int hf_scsi_mmcopcode             = -1;
96 static int hf_scsi_sbcopcode             = -1;
97 static int hf_scsi_sscopcode             = -1;
98 static int hf_scsi_smcopcode             = -1;
99 static int hf_scsi_control               = -1;
100 static int hf_scsi_inquiry_flags         = -1;
101 static int hf_scsi_inquiry_evpd_page     = -1;
102 static int hf_scsi_inquiry_cmdt_page     = -1;
103 static int hf_scsi_alloclen              = -1;
104 static int hf_scsi_logsel_flags          = -1;
105 static int hf_scsi_logsel_pc             = -1;
106 static int hf_scsi_paramlen              = -1;
107 static int hf_scsi_logsns_flags          = -1;
108 static int hf_scsi_logsns_pc             = -1;
109 static int hf_scsi_logsns_pagecode       = -1;
110 static int hf_scsi_paramlen16            = -1;
111 static int hf_scsi_modesel_flags         = -1;
112 static int hf_scsi_alloclen16            = -1;
113 static int hf_scsi_modesns_pc            = -1;
114 static int hf_scsi_spcpagecode           = -1;
115 static int hf_scsi_sbcpagecode           = -1;
116 static int hf_scsi_sscpagecode           = -1;
117 static int hf_scsi_smcpagecode           = -1;
118 static int hf_scsi_mmcpagecode           = -1;
119 static int hf_scsi_modesns_flags         = -1;
120 static int hf_scsi_persresvin_svcaction  = -1;
121 static int hf_scsi_persresvout_svcaction = -1;
122 static int hf_scsi_persresv_scope        = -1;
123 static int hf_scsi_persresv_type         = -1;
124 static int hf_scsi_release_flags         = -1;
125 static int hf_scsi_release_thirdpartyid  = -1;
126 static int hf_scsi_alloclen32            = -1;
127 static int hf_scsi_select_report         = -1;
128 static int hf_scsi_formatunit_flags      = -1;
129 static int hf_scsi_formatunit_interleave = -1;
130 static int hf_scsi_formatunit_vendor     = -1;
131 static int hf_scsi_rdwr6_lba             = -1;
132 static int hf_scsi_rdwr6_xferlen         = -1;
133 static int hf_scsi_rdwr10_lba            = -1;
134 static int hf_scsi_read_flags            = -1;
135 static int hf_scsi_rdwr12_xferlen        = -1;
136 static int hf_scsi_rdwr16_lba            = -1;
137 static int hf_scsi_readcapacity_flags    = -1;
138 static int hf_scsi_readcapacity_lba      = -1;
139 static int hf_scsi_readcapacity_pmi      = -1;
140 static int hf_scsi_rdwr10_xferlen        = -1;
141 static int hf_scsi_readdefdata_flags     = -1;
142 static int hf_scsi_cdb_defectfmt         = -1;
143 static int hf_scsi_reassignblks_flags    = -1;
144 static int hf_scsi_inq_qualifier         = -1;
145 static int hf_scsi_inq_devtype           = -1;
146 static int hf_scsi_inq_rmb               = -1;
147 static int hf_scsi_inq_version           = -1;
148 static int hf_scsi_rluns_lun             = -1;
149 static int hf_scsi_rluns_multilun        = -1;
150 static int hf_scsi_modesns_errrep        = -1;
151 static int hf_scsi_modesns_tst           = -1;
152 static int hf_scsi_modesns_qmod          = -1;
153 static int hf_scsi_modesns_qerr          = -1;
154 static int hf_scsi_modesns_rac           = -1;
155 static int hf_scsi_modesns_tas           = -1;
156 static int hf_scsi_protocol              = -1;
157 static int hf_scsi_sns_errtype           = -1;
158 static int hf_scsi_snskey                = -1;
159 static int hf_scsi_snsinfo               = -1;
160 static int hf_scsi_addlsnslen            = -1;
161 static int hf_scsi_asc                   = -1;
162 static int hf_scsi_ascascq               = -1;
163 static int hf_scsi_ascq                  = -1;
164 static int hf_scsi_fru                   = -1;
165 static int hf_scsi_sksv                  = -1;
166 static int hf_scsi_inq_normaca           = -1;
167 static int hf_scsi_persresv_key          = -1;
168 static int hf_scsi_persresv_scopeaddr    = -1;
169 static int hf_scsi_add_cdblen = -1;
170 static int hf_scsi_svcaction = -1;
171 static int hf_scsi_ssu_immed = -1;
172 static int hf_scsi_ssu_pwr_cond = -1;
173 static int hf_scsi_ssu_loej = -1;
174 static int hf_scsi_ssu_start = -1;
175 static int hf_scsi_wb_mode = -1;
176 static int hf_scsi_wb_bufferid = -1;
177 static int hf_scsi_wb_bufoffset = -1;
178 static int hf_scsi_paramlen24 = -1;
179 static int hf_scsi_senddiag_st_code = -1;
180 static int hf_scsi_senddiag_pf = -1;
181 static int hf_scsi_senddiag_st = -1;
182 static int hf_scsi_senddiag_devoff = -1;
183 static int hf_scsi_senddiag_unitoff = -1;
184 static int hf_scsi_key_class = -1;
185 static int hf_scsi_key_format = -1;
186 static int hf_scsi_agid = -1;
187 static int hf_scsi_lba             = -1;
188 static int hf_scsi_read_compatibility_lba             = -1;
189 static int hf_scsi_num_blocks      = -1;
190 static int hf_scsi_data_length = -1;
191 static int hf_scsi_report_key_type_code = -1;
192 static int hf_scsi_report_key_vendor_resets = -1;
193 static int hf_scsi_report_key_user_changes = -1;
194 static int hf_scsi_report_key_region_mask = -1;
195 static int hf_scsi_report_key_rpc_scheme = -1;
196 static int hf_scsi_getconf_rt = -1;
197 static int hf_scsi_getconf_starting_feature = -1;
198 static int hf_scsi_getconf_current_profile = -1;
199 static int hf_scsi_feature = -1;
200 static int hf_scsi_feature_version = -1;
201 static int hf_scsi_feature_persistent = -1;
202 static int hf_scsi_feature_current = -1;
203 static int hf_scsi_feature_additional_length = -1;
204 static int hf_scsi_feature_lun_sn = -1;
205 static int hf_scsi_feature_cdread_dap = -1;
206 static int hf_scsi_feature_cdread_c2flag = -1;
207 static int hf_scsi_feature_cdread_cdtext = -1;
208 static int hf_scsi_feature_dvdrw_write = -1;
209 static int hf_scsi_feature_dvdrw_quickstart = -1;
210 static int hf_scsi_feature_dvdrw_closeonly = -1;
211 static int hf_scsi_feature_dvdr_write = -1;
212 static int hf_scsi_feature_tao_buf = -1;
213 static int hf_scsi_feature_tao_rwraw = -1;
214 static int hf_scsi_feature_tao_rwpack = -1;
215 static int hf_scsi_feature_tao_testwrite = -1;
216 static int hf_scsi_feature_tao_cdrw = -1;
217 static int hf_scsi_feature_tao_rwsubcode = -1;
218 static int hf_scsi_feature_dts = -1;
219 static int hf_scsi_feature_sao_buf = -1;
220 static int hf_scsi_feature_sao_sao = -1;
221 static int hf_scsi_feature_sao_rawms = -1;
222 static int hf_scsi_feature_sao_raw = -1;
223 static int hf_scsi_feature_sao_testwrite = -1;
224 static int hf_scsi_feature_sao_cdrw = -1;
225 static int hf_scsi_feature_sao_rw = -1;
226 static int hf_scsi_feature_sao_mcsl = -1;
227 static int hf_scsi_feature_dvdr_buf = -1;
228 static int hf_scsi_feature_dvdr_testwrite = -1;
229 static int hf_scsi_feature_dvdr_dvdrw = -1;
230 static int hf_scsi_feature_profile = -1;
231 static int hf_scsi_feature_profile_current = -1;
232 static int hf_scsi_feature_isw_buf = -1;
233 static int hf_scsi_feature_isw_num_linksize = -1;
234 static int hf_scsi_feature_isw_linksize = -1;
235 static int hf_scsi_readtoc_time = -1;
236 static int hf_scsi_readtoc_format = -1;
237 static int hf_scsi_track = -1;
238 static int hf_scsi_track_size = -1;
239 static int hf_scsi_session = -1;
240 static int hf_scsi_first_track = -1;
241 static int hf_scsi_readtoc_first_session = -1;
242 static int hf_scsi_readtoc_last_track = -1;
243 static int hf_scsi_readtoc_last_session = -1;
244 static int hf_scsi_q_subchannel_adr = -1;
245 static int hf_scsi_q_subchannel_control = -1;
246 static int hf_scsi_track_start_address = -1;
247 static int hf_scsi_next_writable_address = -1;
248 static int hf_scsi_track_start_time = -1;
249 static int hf_scsi_synccache_immed = -1;
250 static int hf_scsi_synccache_reladr = -1;
251 static int hf_scsi_rbc_block = -1;
252 static int hf_scsi_rbc_lob_blocks = -1;
253 static int hf_scsi_rbc_alob_blocks = -1;
254 static int hf_scsi_rbc_lob_bytes = -1;
255 static int hf_scsi_rbc_alob_bytes = -1;
256 static int hf_scsi_setstreaming_type = -1;
257 static int hf_scsi_setstreaming_param_len = -1;
258 static int hf_scsi_setstreaming_wrc = -1;
259 static int hf_scsi_setstreaming_rdd = -1;
260 static int hf_scsi_setstreaming_exact = -1;
261 static int hf_scsi_setstreaming_ra = -1;
262 static int hf_scsi_setstreaming_start_lba = -1;
263 static int hf_scsi_setstreaming_end_lba = -1;
264 static int hf_scsi_setstreaming_read_size = -1;
265 static int hf_scsi_setstreaming_read_time = -1;
266 static int hf_scsi_setstreaming_write_size = -1;
267 static int hf_scsi_setstreaming_write_time = -1;
268 static int hf_scsi_reservation_size = -1;
269 static int hf_scsi_rti_address_type = -1;
270 static int hf_scsi_rti_damage = -1;
271 static int hf_scsi_rti_copy = -1;
272 static int hf_scsi_rti_track_mode = -1;
273 static int hf_scsi_rti_rt = -1;
274 static int hf_scsi_rti_blank = -1;
275 static int hf_scsi_rti_packet = -1;
276 static int hf_scsi_rti_fp = -1;
277 static int hf_scsi_rti_data_mode = -1;
278 static int hf_scsi_rti_lra_v = -1;
279 static int hf_scsi_rti_nwa_v = -1;
280 static int hf_scsi_free_blocks = -1;
281 static int hf_scsi_fixed_packet_size = -1;
282 static int hf_scsi_last_recorded_address = -1;
283 static int hf_scsi_disc_info_erasable = -1;
284 static int hf_scsi_disc_info_state_of_last_session = -1;
285 static int hf_scsi_disc_info_disk_status = -1;
286 static int hf_scsi_disc_info_number_of_sessions = -1;
287 static int hf_scsi_disc_info_first_track_in_last_session = -1;
288 static int hf_scsi_disc_info_last_track_in_last_session = -1;
289 static int hf_scsi_disc_info_did_v = -1;
290 static int hf_scsi_disc_info_dbc_v = -1;
291 static int hf_scsi_disc_info_uru = -1;
292 static int hf_scsi_disc_info_dac_v = -1;
293 static int hf_scsi_disc_info_dbit = -1;
294 static int hf_scsi_disc_info_bgfs = -1;
295 static int hf_scsi_disc_info_disc_type = -1;
296 static int hf_scsi_disc_info_disc_identification = -1;
297 static int hf_scsi_disc_info_last_session_lead_in_start_address = -1;
298 static int hf_scsi_disc_info_last_possible_lead_out_start_address = -1;
299 static int hf_scsi_disc_info_disc_bar_code = -1;
300 static int hf_sbc2_verify_lba = -1;
301 static int hf_sbc2_verify_vlen = -1;
302 static int hf_sbc2_verify_dpo = -1;
303 static int hf_sbc2_verify_blkvfy = -1;
304 static int hf_sbc2_verify_reladdr = -1;
305 static int hf_sbc2_verify_vlen32 = -1;
306 static int hf_sbc2_verify_lba64 = -1;
307 static int hf_sbc2_wrverify_ebp = -1;
308 static int hf_sbc2_wrverify_lba = -1;
309 static int hf_sbc2_wrverify_xferlen = -1;
310 static int hf_sbc2_wrverify_lba64 = -1;
311 static int hf_sbc2_wrverify_xferlen32 = -1;
312 static int hf_sbc2_verify_bytchk = -1;
313 static int hf_ssc3_space6_count = -1;
314 static int hf_ssc3_space16_count = -1;
315 static int hf_ssc3_locate10_loid = -1;
316 static int hf_ssc3_locate16_loid = -1;
317
318 static gint ett_scsi         = -1;
319 static gint ett_scsi_page    = -1;
320
321 typedef guint32 scsi_cmnd_type;
322 typedef guint32 scsi_device_type;
323
324 /* Valid SCSI Command Types */
325 #define SCSI_CMND_SPC2                   1
326 #define SCSI_CMND_SBC2                   2
327 #define SCSI_CMND_SSC2                   3
328 #define SCSI_CMND_SMC2                   4
329 #define SCSI_CMND_MMC                    5
330
331 /* SPC and SPC-2 Commands */
332
333 #define SCSI_SPC_CHANGE_DEFINITION       0x40
334 #define SCSI_SPC_COMPARE                 0x39
335 #define SCSI_SPC_COPY                    0x18
336 #define SCSI_SPC_COPY_AND_VERIFY         0x3A
337 #define SCSI_SPC2_INQUIRY                0x12
338 #define SCSI_SPC2_EXTCOPY                0x83
339 #define SCSI_SPC2_LOGSELECT              0x4C
340 #define SCSI_SPC2_LOGSENSE               0x4D
341 #define SCSI_SPC2_MODESELECT6            0x15
342 #define SCSI_SPC2_MODESELECT10           0x55
343 #define SCSI_SPC2_MODESENSE6             0x1A
344 #define SCSI_SPC2_MODESENSE10            0x5A
345 #define SCSI_SPC2_PERSRESVIN             0x5E
346 #define SCSI_SPC2_PERSRESVOUT            0x5F
347 #define SCSI_SPC2_PREVMEDREMOVAL         0x1E
348 #define SCSI_SPC2_READBUFFER             0x3C
349 #define SCSI_SPC2_RCVCOPYRESULTS         0x84
350 #define SCSI_SPC2_RCVDIAGRESULTS         0x1C
351 #define SCSI_SPC2_RELEASE6               0x17
352 #define SCSI_SPC2_RELEASE10              0x57
353 #define SCSI_SPC2_REPORTDEVICEID         0xA3
354 #define SCSI_SPC2_REPORTLUNS             0xA0
355 #define SCSI_SPC2_REQSENSE               0x03
356 #define SCSI_SPC2_RESERVE6               0x16
357 #define SCSI_SPC2_RESERVE10              0x56
358 #define SCSI_SPC2_SENDDIAG               0x1D
359 #define SCSI_SPC2_SETDEVICEID            0xA4
360 #define SCSI_SPC2_TESTUNITRDY            0x00
361 #define SCSI_SPC2_WRITEBUFFER            0x3B
362 #define SCSI_SPC2_VARLENCDB              0x7F
363
364 static const value_string scsi_spc2_val[] = {
365     {SCSI_SPC_CHANGE_DEFINITION  , "Change Definition"},
366     {SCSI_SPC_COMPARE            , "Compare"},
367     {SCSI_SPC_COPY               , "Copy"},
368     {SCSI_SPC_COPY_AND_VERIFY    , "Copy And Verify"},
369     {SCSI_SPC2_EXTCOPY           , "Extended Copy"},
370     {SCSI_SPC2_INQUIRY           , "Inquiry"},
371     {SCSI_SPC2_LOGSELECT         , "Log Select"},
372     {SCSI_SPC2_LOGSENSE          , "Log Sense"},
373     {SCSI_SPC2_MODESELECT6       , "Mode Select(6)"},
374     {SCSI_SPC2_MODESELECT10      , "Mode Select(10)"},
375     {SCSI_SPC2_MODESENSE6        , "Mode Sense(6)"},
376     {SCSI_SPC2_MODESENSE10       , "Mode Sense(10)"},
377     {SCSI_SPC2_PERSRESVIN        , "Persistent Reserve In"},
378     {SCSI_SPC2_PERSRESVOUT       , "Persistent Reserve Out"},
379     {SCSI_SPC2_PREVMEDREMOVAL    , "Prevent/Allow Medium Removal"},
380     {SCSI_SPC2_RCVCOPYRESULTS    , "Receive Copy Results"},
381     {SCSI_SPC2_RCVDIAGRESULTS    , "Receive Diagnostics Results"},
382     {SCSI_SPC2_READBUFFER        , "Read Buffer"},
383     {SCSI_SPC2_RELEASE6          , "Release(6)"},
384     {SCSI_SPC2_RELEASE10         , "Release(10)"},
385     {SCSI_SPC2_REPORTDEVICEID    , "Report Device ID"},
386     {SCSI_SPC2_REPORTLUNS        , "Report LUNs"},
387     {SCSI_SPC2_REQSENSE          , "Request Sense"},
388     {SCSI_SPC2_RESERVE6          , "Reserve(6)"},
389     {SCSI_SPC2_RESERVE10         , "Reserve(10)"},
390     {SCSI_SPC2_SENDDIAG          , "Send Diagnostic"},
391     {SCSI_SPC2_TESTUNITRDY       , "Test Unit Ready"},
392     {SCSI_SPC2_WRITEBUFFER       , "Write Buffer"},
393     {SCSI_SPC2_VARLENCDB         , "Variable Length CDB"},
394     {0, NULL},
395 };
396
397 /* SBC-2 Commands */
398 #define SCSI_SBC2_FORMATUNIT             0x04
399 #define SCSI_SBC2_LOCKUNLKCACHE10        0x36
400 #define SCSI_SBC2_LOCKUNLKCACHE16        0x92
401 #define SCSI_SBC2_PREFETCH10             0x34
402 #define SCSI_SBC2_PREFETCH16             0x90
403 #define SCSI_SBC2_READ6                  0x08
404 #define SCSI_SBC2_READ10                 0x28
405 #define SCSI_SBC2_READ12                 0xA8
406 #define SCSI_SBC2_READ16                 0x88
407 #define SCSI_SBC2_READCAPACITY10         0x25
408 #define SCSI_SBC2_SERVICEACTIONIN16      0x9E
409 #define SCSI_SBC2_READDEFDATA10          0x37
410 #define SCSI_SBC2_READDEFDATA12          0xB7
411 #define SCSI_SBC2_READLONG               0x3E
412 #define SCSI_SBC2_REASSIGNBLKS           0x07
413 #define SCSI_SBC2_REBUILD16              0x81
414 #define SCSI_SBC2_REBUILD32              0x7F
415 #define SCSI_SBC2_REGENERATE16           0x82
416 #define SCSI_SBC2_REGENERATE32           0x7F
417 #define SCSI_SBC2_SEEK10                 0x2B
418 #define SCSI_SBC2_SETLIMITS10            0x33
419 #define SCSI_SBC2_SETLIMITS12            0xB3
420 #define SCSI_SBC2_STARTSTOPUNIT          0x1B
421 #define SCSI_SBC2_SYNCCACHE10            0x35
422 #define SCSI_SBC2_SYNCCACHE16            0x91
423 #define SCSI_SBC2_VERIFY10               0x2F
424 #define SCSI_SBC2_VERIFY12               0xAF
425 #define SCSI_SBC2_VERIFY16               0x8F
426 #define SCSI_SBC2_WRITE6                 0x0A
427 #define SCSI_SBC2_WRITE10                0x2A
428 #define SCSI_SBC2_WRITE12                0xAA
429 #define SCSI_SBC2_WRITE16                0x8A
430 #define SCSI_SBC2_WRITENVERIFY10         0x2E
431 #define SCSI_SBC2_WRITENVERIFY12         0xAE
432 #define SCSI_SBC2_WRITENVERIFY16         0x8E
433 #define SCSI_SBC2_WRITELONG              0x3F
434 #define SCSI_SBC2_WRITESAME10            0x41
435 #define SCSI_SBC2_WRITESAME16            0x93
436 #define SCSI_SBC2_XDREAD10               0x52
437 #define SCSI_SBC2_XDREAD32               0x7F
438 #define SCSI_SBC2_XDWRITE10              0x50
439 #define SCSI_SBC2_XDWRITE32              0x7F
440 #define SCSI_SBC2_XDWRITEREAD10          0x53
441 #define SCSI_SBC2_XDWRITEREAD32          0x7F
442 #define SCSI_SBC2_XDWRITEEXTD16          0x80
443 #define SCSI_SBC2_XDWRITEEXTD32          0x7F
444 #define SCSI_SBC2_XPWRITE10              0x51
445 #define SCSI_SBC2_XPWRITE32              0x7F
446
447
448 static const value_string scsi_sbc2_val[] = {
449     {SCSI_SBC2_FORMATUNIT    , "Format Unit"},
450     {SCSI_SBC2_LOCKUNLKCACHE10, "Lock Unlock Cache(10)"},
451     {SCSI_SBC2_LOCKUNLKCACHE16, "Lock Unlock Cache(16)"},
452     {SCSI_SBC2_PREFETCH10, "Pre-Fetch(10)"},
453     {SCSI_SBC2_PREFETCH16, "Pre-Fetch(16)"},
454     {SCSI_SBC2_READ6         , "Read(6)"},
455     {SCSI_SBC2_READ10        , "Read(10)"},
456     {SCSI_SBC2_READ12        , "Read(12)"},
457     {SCSI_SBC2_READ16        , "Read(16)"},
458     {SCSI_SBC2_READCAPACITY10, "Read Capacity(10)"},
459     {SCSI_SBC2_SERVICEACTIONIN16, "Service Action In(16)"},
460     {SCSI_SBC2_READDEFDATA10 , "Read Defect Data(10)"},
461     {SCSI_SBC2_READDEFDATA12 , "Read Defect Data(12)"},
462     {SCSI_SBC2_READLONG, "Read Long"},
463     {SCSI_SBC2_REASSIGNBLKS  , "Reassign Blocks"},
464     {SCSI_SBC2_REBUILD16, "Rebuild(16)"},
465     {SCSI_SBC2_REBUILD32, "Rebuild(32)"},
466     {SCSI_SBC2_REGENERATE16, "Regenerate(16)"},
467     {SCSI_SBC2_REGENERATE32, "Regenerate(32)"},
468     {SCSI_SBC2_SEEK10, "Seek(10)"},
469     {SCSI_SBC2_SETLIMITS10, "Set Limits(10)"},
470     {SCSI_SBC2_SETLIMITS12, "Set Limits(12)"},
471     {SCSI_SBC2_STARTSTOPUNIT, "Start Stop Unit"},
472     {SCSI_SBC2_SYNCCACHE10, "Synchronize Cache(10)"},
473     {SCSI_SBC2_SYNCCACHE16, "Synchronize Cache(16)"},
474     {SCSI_SBC2_VERIFY10, "Verify(10)"},
475     {SCSI_SBC2_VERIFY12, "Verify(12)"},
476     {SCSI_SBC2_VERIFY16, "Verify(16)"},
477     {SCSI_SBC2_WRITE6        , "Write(6)"},
478     {SCSI_SBC2_WRITE10       , "Write(10)"},
479     {SCSI_SBC2_WRITE12       , "Write(12)"},
480     {SCSI_SBC2_WRITE16       , "Write(16)"},
481     {SCSI_SBC2_WRITENVERIFY10, "Write & Verify(10)"},
482     {SCSI_SBC2_WRITENVERIFY12, "Write & Verify(12)"},
483     {SCSI_SBC2_WRITENVERIFY16, "Write & Verify(16)"},
484     {SCSI_SBC2_WRITELONG, "Write Long"},
485     {SCSI_SBC2_WRITESAME10, "Write Same(10)"},
486     {SCSI_SBC2_WRITESAME16, "Write Same(16)"},
487     {SCSI_SBC2_XDREAD10, "XdRead(10)"},
488     {SCSI_SBC2_XDREAD32, "XdRead(32)"},
489     {SCSI_SBC2_XDWRITE10, "XdWrite(10)"},
490     {SCSI_SBC2_XDWRITE32, "XdWrite(32)"},
491     {SCSI_SBC2_XDWRITEREAD10, "XdWriteRead(10)"},
492     {SCSI_SBC2_XDWRITEREAD32, "XdWriteRead(32)"},
493     {SCSI_SBC2_XDWRITEEXTD16, "XdWrite Extended(16)"},
494     {SCSI_SBC2_XDWRITEEXTD32, "XdWrite Extended(32)"},
495     {SCSI_SBC2_XPWRITE10, "XpWrite(10)"},
496     {SCSI_SBC2_XPWRITE32, "XpWrite(32)"},
497     {0, NULL},
498 };
499
500 /* MMC Commands */
501 #define SCSI_MMC_READCAPACITY10         0x25
502 #define SCSI_MMC_READ10                 0x28
503 #define SCSI_MMC_WRITE10                0x2a
504 #define SCSI_MMC_SYNCHRONIZECACHE       0x35
505 #define SCSI_MMC_READTOCPMAATIP         0x43
506 #define SCSI_MMC_GETCONFIGURATION       0x46
507 #define SCSI_MMC_GETEVENTSTATUSNOTIFY   0x4a
508 #define SCSI_MMC_READDISCINFORMATION    0x51
509 #define SCSI_MMC_READTRACKINFORMATION   0x52
510 #define SCSI_MMC_RESERVETRACK           0x53
511 #define SCSI_MMC_READBUFFERCAPACITY     0x5c
512 #define SCSI_MMC_REPORTKEY              0xa4
513 #define SCSI_MMC_READ12                 0xa8
514 #define SCSI_MMC_WRITE12                0xaa
515 #define SCSI_MMC_SETSTREAMING           0xb6
516 static const value_string scsi_mmc_val[] = {
517     {SCSI_SBC2_STARTSTOPUNIT, "Start Stop Unit"},
518     {SCSI_MMC_READCAPACITY10,   "Read Capacity(10)"},
519     {SCSI_MMC_READ10,           "Read(10)"},
520     {SCSI_MMC_WRITE10,          "Write(10)"},
521     {SCSI_MMC_SYNCHRONIZECACHE, "Synchronize Cache"},
522     {SCSI_MMC_READTOCPMAATIP,   "Read TOC/PMA/ATIP"},
523     {SCSI_MMC_GETCONFIGURATION, "Get Configuraion"},
524     {SCSI_MMC_GETEVENTSTATUSNOTIFY, "Get Event Status Notification"},
525     {SCSI_MMC_READDISCINFORMATION, "Read Disc Information"},
526     {SCSI_MMC_READTRACKINFORMATION, "Read Track Information"},
527     {SCSI_MMC_RESERVETRACK,     "Reserve Track"},
528     {SCSI_MMC_READBUFFERCAPACITY,"Read Buffer Capacity"},
529     {SCSI_MMC_REPORTKEY,        "Report Key"},
530     {SCSI_MMC_READ12,           "Read(12)"},
531     {SCSI_MMC_WRITE12,          "Write(12)"},
532     {SCSI_MMC_SETSTREAMING,     "Set Streaming"},
533     {0, NULL},
534 };
535
536 /* SMC2 Commands */
537 #define SCSI_SMC2_EXCHANGE_MEDIUM                 0x40
538 #define SCSI_SMC2_INITIALIZE_ELEMENT_STATUS       0x07
539 #define SCSI_SMC2_INITIALIZE_ELEMENT_STATUS_RANGE 0x37
540 #define SCSI_SMC2_MOVE_MEDIUM                     0xA5
541 #define SCSI_SMC2_MOVE_MEDIUM_ATTACHED            0xA7
542 #define SCSI_SMC2_POSITION_TO_ELEMENT             0x2B
543 #define SCSI_SMC2_READ_ATTRIBUTE                  0x8C
544 #define SCSI_SMC2_READ_ELEMENT_STATUS             0xB8
545 #define SCSI_SMC2_READ_ELEMENT_STATUS_ATTACHED    0xB4
546 #define SCSI_SMC2_REQUEST_VOLUME_ELEMENT_ADDRESS  0xB5
547 #define SCSI_SMC2_SEND_VOLUME_TAG                 0xB6
548 #define SCSI_SMC2_WRITE_ATTRIBUTE                 0x8D
549
550 static const value_string scsi_smc2_val[] = {
551     {SCSI_SMC2_EXCHANGE_MEDIUM                , "Exchange Medium"},
552     {SCSI_SMC2_INITIALIZE_ELEMENT_STATUS      , "Initialize Element Status"},
553     {SCSI_SMC2_INITIALIZE_ELEMENT_STATUS_RANGE, "Initialize Element Status With Range"},
554     {SCSI_SMC2_MOVE_MEDIUM                    , "Move Medium"},
555     {SCSI_SMC2_MOVE_MEDIUM_ATTACHED           , "Move Medium Attached"},
556     {SCSI_SMC2_POSITION_TO_ELEMENT            , "Position To Element"},
557     {SCSI_SMC2_READ_ATTRIBUTE                 , "Read Attribute"},
558     {SCSI_SMC2_READ_ELEMENT_STATUS            , "Read Element Status"},
559     {SCSI_SMC2_READ_ELEMENT_STATUS_ATTACHED   , "Read Element Status Attached"},
560     {SCSI_SMC2_REQUEST_VOLUME_ELEMENT_ADDRESS , "Request Volume Element Address"},
561     {SCSI_SMC2_SEND_VOLUME_TAG                , "Send Volume Tag"},
562     {SCSI_SMC2_WRITE_ATTRIBUTE                , "Write Attribute"},
563     {0, NULL},
564 };
565
566
567 /* SSC2 Commands */
568 #define SCSI_SSC2_REWIND                        0x01
569 #define SCSI_SSC2_FORMAT_MEDIUM                 0x04
570 #define SCSI_SSC2_READ_BLOCK_LIMITS             0x05
571 #define SCSI_SSC2_READ6                         0x08
572 #define SCSI_SSC2_WRITE6                        0x0A
573 #define SCSI_SSC2_SET_CAPACITY                  0x0B
574 #define SCSI_SSC2_READ_REVERSE_6                0x0F
575 #define SCSI_SSC2_WRITE_FILEMARKS_6             0x10
576 #define SCSI_SSC2_SPACE_6                       0x11
577 #define SCSI_SSC2_VERIFY_6                      0x13
578 #define SCSI_SSC2_RECOVER_BUFFERED_DATA         0x14
579 #define SCSI_SSC2_ERASE_6                       0x19
580 #define SCSI_SSC2_LOAD_UNLOAD                   0x1B
581 #define SCSI_SSC2_LOCATE_10                     0x2B
582 #define SCSI_SSC2_READ_POSITION                 0x34
583 #define SCSI_SSC2_REPORT_DENSITY_SUPPORT        0x44
584 #define SCSI_SSC2_WRITE_FILEMARKS_16            0x80
585 #define SCSI_SSC2_READ_REVERSE_16               0x81
586 #define SCSI_SSC2_READ_16                       0x88
587 #define SCSI_SSC2_WRITE_16                      0x8A
588 #define SCSI_SSC2_VERIFY_16                     0x8F
589 #define SCSI_SSC2_SPACE_16                      0x91
590 #define SCSI_SSC2_LOCATE_16                     0x92
591 #define SCSI_SSC2_ERASE_16                      0x93
592
593 /* For commands from SPC we have automatic fallback, for all
594  * commands not in SSC and not from SPC we must add them to this
595  * value string for proper prettyprinting.
596  */
597 static const value_string scsi_ssc2_val[] = {
598     {SCSI_SSC2_ERASE_16                    , "Erase(16)"},
599     {SCSI_SSC2_FORMAT_MEDIUM               , "Format Medium"},
600     {SCSI_SSC2_LOAD_UNLOAD                 , "Load Unload"},
601     {SCSI_SSC2_LOCATE_16                   , "Locate(16)"},
602     {SCSI_SSC2_READ_16                     , "Read(16)"},
603     {SCSI_SSC2_READ_BLOCK_LIMITS           , "Read Block Limits"},
604     {SCSI_SSC2_READ_POSITION               , "Read Position"},
605     {SCSI_SSC2_READ_REVERSE_16             , "Read Reverse(16)"},
606     {SCSI_SSC2_RECOVER_BUFFERED_DATA       , "Recover Buffered Data"},
607     {SCSI_SSC2_REPORT_DENSITY_SUPPORT      , "Report Density Support"},
608     {SCSI_SSC2_REWIND                      , "Rewind"},
609     {SCSI_SSC2_SET_CAPACITY                , "Set Capacity"},
610     {SCSI_SSC2_SPACE_16                    , "Space(16)"},
611     {SCSI_SSC2_VERIFY_16                   , "Verify(16)"},
612     {SCSI_SSC2_WRITE_16                    , "Write(16)"},
613     {SCSI_SSC2_WRITE_FILEMARKS_16          , "Write Filemarks(16)"},
614     {SCSI_SSC2_ERASE_6                     , "Erase(6)"},
615     {SCSI_SSC2_LOCATE_10                   , "Locate(10)"},
616     {SCSI_SSC2_LOCATE_16                   , "Locate(16)"},
617     {SCSI_SSC2_READ6                       , "Read(6)"},
618     {SCSI_SSC2_READ_REVERSE_6              , "Read Reverse(6)"},
619     {SCSI_SSC2_SPACE_6                     , "Space(6)"},
620     {SCSI_SSC2_VERIFY_6                    , "Verify(6)"},
621     {SCSI_SSC2_WRITE6                      , "Write(6)"},
622     {SCSI_SSC2_WRITE_FILEMARKS_6           , "Write Filemarks(6)"},
623     {SCSI_SMC2_MOVE_MEDIUM                 , "Move Medium"},
624     {SCSI_SMC2_MOVE_MEDIUM_ATTACHED        , "Move Medium Attached"},
625     {SCSI_SMC2_READ_ELEMENT_STATUS         , "Read Element Status"},
626     {SCSI_SMC2_READ_ELEMENT_STATUS_ATTACHED, "Read Element Status Attached"},
627     {0, NULL},
628 };
629
630 static const value_string scsi_select_report_val[] = {
631     {0, "Select All LUNs" },
632     {1, "Select Well-Known LUNs" },
633     {2, "Select All LUNs accessible to this I_T nexus" },
634     {0, NULL},
635 };
636
637 #define SCSI_EVPD_SUPPPG          0x00
638 #define SCSI_EVPD_DEVSERNUM       0x80
639 #define SCSI_EVPD_OPER            0x81
640 #define SCSI_EVPD_ASCIIOPER       0x82
641 #define SCSI_EVPD_DEVID           0x83
642 #define SCSI_EVPD_BLKLIMITS       0xb0
643
644 static const value_string scsi_evpd_pagecode_val[] = {
645     {SCSI_EVPD_SUPPPG,    "Supported Vital Product Data Pages"},
646     {0x01,                "ASCII Information Page"},
647     {0x02,                "ASCII Information Page"},
648     {0x03,                "ASCII Information Page"},
649     {0x04,                "ASCII Information Page"},
650     {0x05,                "ASCII Information Page"},
651     {0x06,                "ASCII Information Page"},
652     {0x07,                "ASCII Information Page"},
653     /* XXX - 0x01 through 0x7F are all ASCII information pages */
654     {SCSI_EVPD_DEVSERNUM, "Unit Serial Number Page"},
655     {SCSI_EVPD_OPER,      "Implemented Operating Definition Page"},
656     {SCSI_EVPD_ASCIIOPER, "ASCII Implemented Operating Definition Page"},
657     {SCSI_EVPD_DEVID,     "Device Identification Page"},
658     {SCSI_EVPD_BLKLIMITS, "Block Limits Page"},
659     {0, NULL},
660 };
661
662 static const value_string scsi_logsel_pc_val[] = {
663     {0, "Current Threshold Values"},
664     {1, "Current Cumulative Values"},
665     {2, "Default Threshold Values"},
666     {3, "Default Cumulative Values"},
667     {0, NULL},
668 };
669
670 static const value_string scsi_logsns_pc_val[] = {
671     {0, "Threshold Values"},
672     {1, "Cumulative Values"},
673     {2, "Default Threshold Values"},
674     {3, "Default Cumulative Values"},
675     {0, NULL},
676 };
677
678 static const value_string scsi_logsns_page_val[] = {
679     {0xF, "Application Client Page"},
680     {0x1, "Buffer Overrun/Underrun Page"},
681     {0x3, "Error Counter (read) Page"},
682     {0x4, "Error Counter (read reverse) Page"},
683     {0x5, "Error Counter (verify) Page"},
684     {0x1, "Error Counter (write) Page"},
685     {0xB, "Last n Deferred Errors or Async Events Page"},
686     {0x7, "Last n Error Events Page"},
687     {0x6, "Non-medium Error Page"},
688     {0x10, "Self-test Results Page"},
689     {0xE, "Start-Stop Cycle Counter Page"},
690     {0x0, "Supported Log Pages"},
691     {0xD, "Temperature Page"},
692     {0, NULL},
693 };
694
695 static const value_string scsi_modesns_pc_val[] = {
696     {0, "Current Values"},
697     {1, "Changeable Values"},
698     {2, "Default Values"},
699     {3, "Saved Values"},
700     {0, NULL},
701 };
702
703 #define SCSI_SPC2_MODEPAGE_CTL      0x0A
704 #define SCSI_SPC2_MODEPAGE_DISCON   0x02
705 #define SCSI_SCSI2_MODEPAGE_PERDEV  0x09  /* Obsolete in SPC-2; generic in SCSI-2 */
706 #define SCSI_SPC2_MODEPAGE_INFOEXCP 0x1C
707 #define SCSI_SPC2_MODEPAGE_PWR      0x1A
708 #define SCSI_SPC2_MODEPAGE_LUN      0x18
709 #define SCSI_SPC2_MODEPAGE_PORT     0x19
710 #define SCSI_SPC2_MODEPAGE_VEND     0x00
711
712 static const value_string scsi_spc2_modepage_val[] = {
713     {SCSI_SPC2_MODEPAGE_CTL,      "Control"},
714     {SCSI_SPC2_MODEPAGE_DISCON,   "Disconnect-Reconnect"},
715     {SCSI_SCSI2_MODEPAGE_PERDEV,  "Peripheral Device"},
716     {SCSI_SPC2_MODEPAGE_INFOEXCP, "Informational Exceptions Control"},
717     {SCSI_SPC2_MODEPAGE_PWR,      "Power Condition"},
718     {SCSI_SPC2_MODEPAGE_LUN,      "Protocol Specific LUN"},
719     {SCSI_SPC2_MODEPAGE_PORT,     "Protocol-Specific Port"},
720     {SCSI_SPC2_MODEPAGE_VEND,     "Vendor Specific Page"},
721     {0x3F,                        "Return All Mode Pages"},
722     {0, NULL},
723 };
724
725 #define SCSI_SBC2_MODEPAGE_RDWRERR  0x01
726 #define SCSI_SBC2_MODEPAGE_FMTDEV   0x03
727 #define SCSI_SBC2_MODEPAGE_DISKGEOM 0x04
728 #define SCSI_SBC2_MODEPAGE_FLEXDISK 0x05
729 #define SCSI_SBC2_MODEPAGE_VERERR   0x07
730 #define SCSI_SBC2_MODEPAGE_CACHE    0x08
731 #define SCSI_SBC2_MODEPAGE_MEDTYPE  0x0B
732 #define SCSI_SBC2_MODEPAGE_NOTPART  0x0C
733 #define SCSI_SBC2_MODEPAGE_XORCTL   0x10
734
735 static const value_string scsi_sbc2_modepage_val[] = {
736     {SCSI_SBC2_MODEPAGE_RDWRERR,  "Read/Write Error Recovery"},
737     {SCSI_SBC2_MODEPAGE_FMTDEV,   "Format Device"},
738     {SCSI_SBC2_MODEPAGE_DISKGEOM, "Rigid Disk Geometry"},
739     {SCSI_SBC2_MODEPAGE_FLEXDISK, "Flexible Disk"},
740     {SCSI_SBC2_MODEPAGE_VERERR,   "Verify Error Recovery"},
741     {SCSI_SBC2_MODEPAGE_CACHE,    "Caching"},
742     {SCSI_SBC2_MODEPAGE_MEDTYPE,  "Medium Types Supported"},
743     {SCSI_SBC2_MODEPAGE_NOTPART,  "Notch & Partition"},
744     {SCSI_SBC2_MODEPAGE_XORCTL,   "XOR Control"},
745     {0x3F,                        "Return All Mode Pages"},
746     {0, NULL},
747 };
748
749 #define SCSI_SSC2_MODEPAGE_DATACOMP 0x0F  /* data compression */
750 #define SCSI_SSC2_MODEPAGE_DEVCONF  0x10  /* device configuration */
751 #define SCSI_SSC2_MODEPAGE_MEDPAR1  0x11  /* medium partition (1) */
752 #define SCSI_SSC2_MODEPAGE_MEDPAR2  0x12  /* medium partition (2) */
753 #define SCSI_SSC2_MODEPAGE_MEDPAR3  0x13  /* medium partition (3) */
754 #define SCSI_SSC2_MODEPAGE_MEDPAR4  0x14  /* medium partition (4) */
755
756 static const value_string scsi_ssc2_modepage_val[] = {
757     {SCSI_SSC2_MODEPAGE_DATACOMP, "Data Compression"},
758     {SCSI_SSC2_MODEPAGE_DEVCONF,  "Device Configuration"},
759     {SCSI_SSC2_MODEPAGE_MEDPAR1,  "Medium Partition (1)"},
760     {SCSI_SSC2_MODEPAGE_MEDPAR2,  "Medium Partition (2)"},
761     {SCSI_SSC2_MODEPAGE_MEDPAR3,  "Medium Partition (3)"},
762     {SCSI_SSC2_MODEPAGE_MEDPAR4,  "Medium Partition (4)"},
763     {0x3F,                        "Return All Mode Pages"},
764     {0, NULL},
765 };
766
767 #define SCSI_SMC2_MODEPAGE_EAA      0x1D  /* element address assignment */
768 #define SCSI_SMC2_MODEPAGE_TRANGEOM 0x1E  /* transport geometry parameters */
769 #define SCSI_SMC2_MODEPAGE_DEVCAP   0x1F  /* device capabilities */
770
771 static const value_string scsi_smc2_modepage_val[] = {
772     {SCSI_SMC2_MODEPAGE_EAA,      "Element Address Assignment"},
773     {SCSI_SMC2_MODEPAGE_TRANGEOM, "Transport Geometry Parameters"},
774     {SCSI_SMC2_MODEPAGE_DEVCAP,   "Device Capabilities"},
775     {0x3F,                        "Return All Mode Pages"},
776     {0, NULL},
777 };
778
779 #define SCSI_MMC3_MODEPAGE_MMCAP   0x2A  /* device capabilities */
780
781 static const value_string scsi_mmc5_modepage_val[] = {
782     {SCSI_MMC3_MODEPAGE_MMCAP,   "MM Capabilities and Mechanical Status"},
783     {0x3F,                        "Return All Mode Pages"},
784     {0, NULL},
785 };
786
787 #define SCSI_SPC2_RESVIN_SVCA_RDKEYS 0
788 #define SCSI_SPC2_RESVIN_SVCA_RDRESV 1
789
790 static const value_string scsi_persresvin_svcaction_val[] = {
791     {SCSI_SPC2_RESVIN_SVCA_RDKEYS, "Read Keys"},
792     {SCSI_SPC2_RESVIN_SVCA_RDRESV, "Read Reservation"},
793     {0, NULL},
794 };
795
796 static const value_string scsi_persresvout_svcaction_val[] = {
797     {0, "Register"},
798     {1, "Reserve"},
799     {2, "Release"},
800     {3, "Clear"},
801     {4, "Preempt"},
802     {5, "Preempt & Abort"},
803     {6, "Register & Ignore Existing Key"},
804     {0, NULL},
805 };
806
807 static const value_string scsi_persresv_scope_val[] = {
808     {0, "LU Scope"},
809     {1, "Obsolete"},
810     {2, "Element Scope"},
811     {0, NULL},
812 };
813
814 static const value_string scsi_persresv_type_val[] = {
815     {1, "Write Excl"},
816     {3, "Excl Access"},
817     {5, "Write Excl, Registrants Only"},
818     {7, "Excl Access, Registrants Only"},
819     {0, NULL},
820 };
821
822 static const value_string scsi_qualifier_val[] = {
823     {0x0, "Device type is connected to logical unit"},
824     {0x1, "Device type is supported by server but is not connected to logical unit"},
825     {0x3, "Device type is not supported by server"},
826     { 0, NULL }
827 };
828
829 static const value_string scsi_devtype_val[] = {
830     {SCSI_DEV_SBC   , "Direct Access Device"},
831     {SCSI_DEV_SSC   , "Sequential Access Device"},
832     {SCSI_DEV_PRNT  , "Printer"},
833     {SCSI_DEV_PROC  , "Processor"},
834     {SCSI_DEV_WORM  , "WORM"},
835     {SCSI_DEV_CDROM , "CD-ROM"},
836     {SCSI_DEV_SCAN  , "Scanner"},
837     {SCSI_DEV_OPTMEM, "Optical Memory"},
838     {SCSI_DEV_SMC   , "Medium Changer"},
839     {SCSI_DEV_COMM  , "Communication"},
840     {SCSI_DEV_RAID  , "Storage Array"},
841     {SCSI_DEV_SES   , "Enclosure Services"},
842     {SCSI_DEV_RBC   , "Simplified Block Device"},
843     {SCSI_DEV_OCRW  , "Optical Card Reader/Writer"},
844     {SCSI_DEV_OSD   , "Object-based Storage Device"},
845     {SCSI_DEV_ADC   , "Automation/Drive Interface"},
846     {0x1E           , "Well known logical unit"},
847     {SCSI_DEV_NOLUN , "Unknown or no device type"},
848     {0, NULL},
849 };
850
851 static const enum_val_t scsi_devtype_options[] = {
852     {"block", "Block Device", SCSI_DEV_SBC},
853     {"sequential", "Sequential Device", SCSI_DEV_SSC},
854     {NULL, NULL, -1},
855 };
856
857 static const value_string scsi_inquiry_vers_val[] = {
858     {0, "No Compliance to any Standard"},
859     {2, "Compliance to ANSI X3.131:1994"},
860     {3, "Compliance to ANSI X3.301:1997"},
861     {4, "Compliance to SPC-2"},
862     {0x80, "Compliance to ISO/IEC 9316:1995"},
863     {0x82, "Compliance to ISO/IEC 9316:1995 and to ANSI X3.131:1994"},
864     {0x83, "Compliance to ISO/IEC 9316:1995 and to ANSI X3.301:1997"},
865     {0x84, "Compliance to ISO/IEC 9316:1995 and SPC-2"},
866     {0, NULL},
867 };
868
869 static const value_string scsi_modesense_medtype_sbc_val[] = {
870     {0x00, "Default"},
871     {0x01, "Flexible disk, single-sided; unspecified medium"},
872     {0x02, "Flexible disk, double-sided; unspecified medium"},
873     {0x05, "Flexible disk, single-sided, single density; 200mm/8in diameter"},
874     {0x06, "Flexible disk, double-sided, single density; 200mm/8in diameter"},
875     {0x09, "Flexible disk, single-sided, double density; 200mm/8in diameter"},
876     {0x0A, "Flexible disk, double-sided, double density; 200mm/8in diameter"},
877     {0x0D, "Flexible disk, single-sided, single density; 130mm/5.25in diameter"},
878     {0x12, "Flexible disk, double-sided, single density; 130mm/5.25in diameter"},
879     {0x16, "Flexible disk, single-sided, double density; 130mm/5.25in diameter"},
880     {0x1A, "Flexible disk, double-sided, double density; 130mm/5.25in diameter"},
881     {0x1E, "Flexible disk, double-sided; 90mm/3.5in diameter"},
882     {0x40, "Direct-access magnetic tape, 12 tracks"},
883     {0x44, "Direct-access magnetic tape, 24 tracks"},
884     {0, NULL},
885 };
886
887 static const value_string scsi_verdesc_val[] = {
888     {0x0d40, "FC-AL (No Version)"},
889     {0x0d5c, "FC-AL ANSI X3.272:1996"},
890     {0x0d60, "FC-AL-2 (no version claimed)"},
891     {0x0d7c, "FC-AL-2 ANSI NCITS.332:1999"},
892     {0x0d61, "FC-AL-2 T11/1133 revision 7.0"},
893     {0x1320, "FC-FLA (no version claimed)"},
894     {0x133c, "FC-FLA ANSI NCITS TR-20:1998"},
895     {0x133b, "FC-FLA T11/1235 revision 7"},
896     {0x0da0, "FC-FS (no version claimed)"},
897     {0x0db7, "FC-FS T11/1331 revision 1.2"},
898     {0x08c0, "FCP (no version claimed)"},
899     {0x08dc, "FCP ANSI X3.269:1996"},
900     {0x08db, "FCP T10/0993 revision 12"},
901     {0x1340, "FC-PLDA (no version claimed)"},
902     {0x135c, "FC-PLDA ANSI NCITS TR-19:1998"},
903     {0x135b, "FC-PLDA T11/1162 revision 2.1"},
904     {0x0900, "FCP-2 (no version claimed)"},
905     {0x0901, "FCP-2 T10/1144 revision 4"},
906     {0x003c, "SAM ANSI X3.270:1996"},
907     {0x003b, "SAM T10/0994 revision 18"},
908     {0x0040, "SAM-2 (no version claimed)"},
909     {0x0020, "SAM (no version claimed)"},
910     {0x0180, "SBC (no version claimed)"},
911     {0x019c, "SBC ANSI NCITS.306:1998"},
912     {0x019b, "SBC T10/0996 revision 08c"},
913     {0x0320, "SBC-2 (no version claimed)"},
914     {0x01c0, "SES (no version claimed)"},
915     {0x01dc, "SES ANSI NCITS.305:1998"},
916     {0x01db, "SES T10/1212 revision 08b"},
917     {0x01de, "SES ANSI NCITS.305:1998 w/ Amendment ANSI NCITS.305/AM1:2000"},
918     {0x01dd, "SES T10/1212 revision 08b w/ Amendment ANSI NCITS.305/AM1:2000"},
919     {0x0120, "SPC (no version claimed)"},
920     {0x013c, "SPC ANSI X3.301:1997"},
921     {0x013b, "SPC T10/0995 revision 11a"},
922     {0x0260, "SPC-2 (no version claimed)"},
923     {0x0267, "SPC-2 T10/1236 revision 12"},
924     {0x0269, "SPC-2 T10/1236 revision 18"},
925     {0x0300, "SPC-3 (no version claimed)"},
926     {0x0960, "iSCSI (no version claimed)"},
927     {0x0d80, "FC-PH-3 (no version claimed)"},
928     {0x0d9c, "FC-PH-3 ANSI X3.303-1998"},
929     {0x0d20, "FC-PH (no version claimed)"},
930     {0, NULL},
931 };
932
933 /* Command Support Data "Support" field definitions */
934 static const value_string scsi_cmdt_supp_val[] = {
935     {0, "Data not currently available"},
936     {1, "SCSI Command not supported"},
937     {2, "Reserved"},
938     {3, "SCSI Command supported in conformance with a SCSI standard"},
939     {4, "Vendor Specific"},
940     {5, "SCSI Command supported in a vendor specific manner"},
941     {6, "Vendor Specific"},
942     {7, "Reserved"},
943     {0, NULL},
944 };
945
946 #define CODESET_BINARY  1
947 #define CODESET_ASCII   2
948
949 static const value_string scsi_devid_codeset_val[] = {
950     {0,              "Reserved"},
951     {CODESET_BINARY, "Identifier field contains binary values"},
952     {CODESET_ASCII,  "Identifier field contains ASCII graphic codes"},
953     {0,              NULL},
954 };
955
956 static const value_string scsi_devid_assoc_val[] = {
957     {0, "Identifier is associated with addressed logical/physical device"},
958     {1, "Identifier is associated with the port that received the request"},
959     {0, NULL},
960 };
961
962 static const value_string scsi_devid_idtype_val[] = {
963     {0, "Vendor-specific ID (non-globally unique)"},
964     {1, "Vendor-ID + vendor-specific ID (globally unique)"},
965     {2, "EUI-64 ID"},
966     {3, "WWN"},
967     {4, "4-byte Binary Number/Reserved"},
968     {0, NULL},
969 };
970
971 static const value_string scsi_modesns_mrie_val[] = {
972     {0, "No Reporting of Informational Exception Condition"},
973     {1, "Asynchronous Error Reporting"},
974     {2, "Generate Unit Attention"},
975     {3, "Conditionally Generate Recovered Error"},
976     {4, "Unconditionally Generate Recovered Error"},
977     {5, "Generate No Sense"},
978     {6, "Only Report Informational Exception Condition on Request"},
979     {0, NULL},
980 };
981
982 static const value_string scsi_modesns_tst_val[] = {
983     {0, "Task Set Per LU For All Initiators"},
984     {1, "Task Set Per Initiator Per LU"},
985     {0, NULL},
986 };
987
988 static const value_string scsi_modesns_qmod_val[] = {
989     {0, "Restricted reordering"},
990     {1, "Unrestricted reordering"},
991     {0, NULL},
992 };
993
994 static const true_false_string scsi_modesns_qerr_val = {
995     "All blocked tasks shall be aborted on CHECK CONDITION",
996     "Blocked tasks shall resume after ACA/CA is cleared",
997 };
998
999 static const true_false_string scsi_removable_val = {
1000     "This is a REMOVABLE device",
1001     "This device is NOT removable",
1002 };
1003
1004 static const true_false_string scsi_modesns_tas_val = {
1005     "Terminated tasks aborted without informing initiators",
1006     "Tasks aborted by another initiator terminated with TASK ABORTED",
1007 };
1008
1009 static const true_false_string scsi_modesns_rac_val = {
1010     "Report a CHECK CONDITION Instead of Long Busy Condition",
1011     "Long Busy Conditions Maybe Reported",
1012 };
1013
1014 /* SCSI Transport Protocols */
1015 #define SCSI_PROTO_FCP          0
1016 #define SCSI_PROTO_iSCSI        5
1017
1018 static const value_string scsi_proto_val[] = {
1019     {0, "FCP"},
1020     {5, "iSCSI"},
1021     {0, NULL},
1022 };
1023
1024 static const value_string scsi_fcp_rrtov_val[] = {
1025     {0, "No Timer Specified"},
1026     {1, "0.001 secs"},
1027     {3, "0.1 secs"},
1028     {5, "10 secs"},
1029     {0, NULL},
1030 };
1031
1032 static const value_string scsi_sensekey_val[] = {
1033     {0x0, "No Sense"},
1034     {0x1, "Recovered Error"},
1035     {0x2, "Not Ready"},
1036     {0x3, "Medium Error"},
1037     {0x4, "Hardware Error"},
1038     {0x5, "Illegal Request"},
1039     {0x6, "Unit Attention"},
1040     {0x7, "Data Protection"},
1041     {0x8, "Blank Check"},
1042     {0x9, "Vendor Specific"},
1043     {0xA, "Copy Aborted"},
1044     {0xB, "Command Aborted"},
1045     {0xC, "Obsolete Error Code"},
1046     {0xD, "Overflow Command"},
1047     {0xE, "Miscompare"},
1048     {0xF, "Reserved"},
1049     {0, NULL},
1050 };
1051
1052 static const value_string scsi_sns_errtype_val[] = {
1053     {0x70, "Current Error"},
1054     {0x71, "Deferred Error"},
1055     {0x72, "Current Error"},
1056     {0x73, "Deferred Error"},
1057     {0x7F, "Vendor Specific"},
1058     {0, NULL},
1059 };
1060
1061 static const value_string scsi_asc_val[] = {
1062     {0x0000,  "No Additional Sense Information"},
1063     {0x0006,  "I/O Process Terminated"},
1064     {0x0016,  "Operation In Progress"},
1065     {0x0017,  "Cleaning Requested"},
1066     {0x0100,  "No Index/Sector Signal"},
1067     {0x0200,  "No Seek Complete"},
1068     {0x0300,  "Peripheral Device Write Fault"},
1069     {0x0400,  "Logical Unit Not Ready, Cause Not Reportable"},
1070     {0x0401,  "Logical Unit Is In Process Of Becoming Ready"},
1071     {0x0402,  "Logical Unit Not Ready, Initializing Cmd. Required"},
1072     {0x0403,  "Logical Unit Not Ready, Manual Intervention Required"},
1073     {0x0404,  "Logical Unit Not Ready, Format In Progress"},
1074     {0x0405,  "Logical Unit Not Ready, Rebuild In Progress"},
1075     {0x0406,  "Logical Unit Not Ready, Recalculation In Progress"},
1076     {0x0407,  "Logical Unit Not Ready, Operation In Progress"},
1077     {0x0409,  "Logical Unit Not Ready, Self-Test In Progress"},
1078     {0x0500,  "Logical Unit Does Not Respond To Selection"},
1079     {0x0600,  "No Reference Position Found"},
1080     {0x0700,  "Multiple Peripheral Devices Selected"},
1081     {0x0800,  "Logical Unit Communication Failure"},
1082     {0x0801,  "Logical Unit Communication Time-Out"},
1083     {0x0802,  "Logical Unit Communication Parity Error"},
1084     {0x0803,  "Logical Unit Communication Crc Error (Ultra-Dma/32)"},
1085     {0x0804,  "Unreachable Copy Target"},
1086     {0x0900,  "Track Following Error"},
1087     {0x0904,  "Head Select Fault"},
1088     {0x0A00,  "Error Log Overflow"},
1089     {0x0B00,  "Warning"},
1090     {0x0B01,  "Warning - Specified Temperature Exceeded"},
1091     {0x0B02,  "Warning - Enclosure Degraded"},
1092     {0x0C02,  "Write Error - Auto Reallocation Failed"},
1093     {0x0C03,  "Write Error - Recommend Reassignment"},
1094     {0x0C04,  "Compression Check Miscompare Error"},
1095     {0x0C05,  "Data Expansion Occurred During Compression"},
1096     {0x0C06,  "Block Not Compressible"},
1097     {0x0D00,  "Error Detected By Third Party Temporary Initiator"},
1098     {0x0D01,  "Third Party Device Failure"},
1099     {0x0D02,  "Copy Target Device Not Reachable"},
1100     {0x0D03,  "Incorrect Copy Target Device Type"},
1101     {0x0D04,  "Copy Target Device Data Underrun"},
1102     {0x0D05,  "Copy Target Device Data Overrun"},
1103     {0x1000,  "Id Crc Or Ecc Error"},
1104     {0x1100,  "Unrecovered Read Error"},
1105     {0x1101,  "Read Retries Exhausted"},
1106     {0x1102,  "Error Too Long To Correct"},
1107     {0x1103,  "Multiple Read Errors"},
1108     {0x1104,  "Unrecovered Read Error - Auto Reallocate Failed"},
1109     {0x110A,  "Miscorrected Error"},
1110     {0x110B,  "Unrecovered Read Error - Recommend Reassignment"},
1111     {0x110C,  "Unrecovered Read Error - Recommend Rewrite The Data"},
1112     {0x110D,  "De-Compression Crc Error"},
1113     {0x110E,  "Cannot Decompress Using Declared Algorithm"},
1114     {0x1200,  "Address Mark Not Found For Id Field"},
1115     {0x1300,  "Address Mark Not Found For Data Field"},
1116     {0x1400,  "Recorded Entity Not Found"},
1117     {0x1401,  "Record Not Found"},
1118     {0x1405,  "Record Not Found - Recommend Reassignment"},
1119     {0x1406,  "Record Not Found - Data Auto-Reallocated"},
1120     {0x1500,  "Random Positioning Error"},
1121     {0x1501,  "Mechanical Positioning Error"},
1122     {0x1502,  "Positioning Error Detected By Read Of Medium"},
1123     {0x1600,  "Data Synchronization Mark Error"},
1124     {0x1601,  "Data Sync Error - Data Rewritten"},
1125     {0x1602,  "Data Sync Error - Recommend Rewrite"},
1126     {0x1603,  "Data Sync Error - Data Auto-Reallocated"},
1127     {0x1604,  "Data Sync Error - Recommend Reassignment"},
1128     {0x1700,  "Recovered Data With No Error Correction Applied"},
1129     {0x1701,  "Recovered Data With Retries"},
1130     {0x1702,  "Recovered Data With Positive Head Offset"},
1131     {0x1703,  "Recovered Data With Negative Head Offset"},
1132     {0x1705,  "Recovered Data Using Previous Sector Id"},
1133     {0x1706,  "Recovered Data Without Ecc - Data Auto-Reallocated"},
1134     {0x1707,  "Recovered Data Without Ecc - Recommend Reassignment"},
1135     {0x1708,  "Recovered Data Without Ecc - Recommend Rewrite"},
1136     {0x1709,  "Recovered Data Without Ecc - Data Rewritten"},
1137     {0x1800,  "Recovered Data With Error Correction Applied"},
1138     {0x1801,  "Recovered Data With Error Corr. & Retries Applied"},
1139     {0x1802,  "Recovered Data - Data Auto-Reallocated"},
1140     {0x1805,  "Recovered Data - Recommend Reassignment"},
1141     {0x1806,  "Recovered Data - Recommend Rewrite"},
1142     {0x1807,  "Recovered Data With Ecc - Data Rewritten"},
1143     {0x1900,  "List Error"},
1144     {0x1901,  "List Not Available"},
1145     {0x1902,  "List Error In Primary List"},
1146     {0x1903,  "List Error In Grown List"},
1147     {0x1A00,  "Parameter List Length Error"},
1148     {0x1B00,  "Synchronous Data Transfer Error"},
1149     {0x1C00,  "Defect List Not Found"},
1150     {0x1C01,  "Primary Defect List Not Found"},
1151     {0x1C02,  "Grown Defect List Not Found"},
1152     {0x1D00,  "Miscompare During Verify Operation"},
1153     {0x1E00,  "Recovered Id With Ecc Correction"},
1154     {0x1F00,  "Defect List Transfer"},
1155     {0x2000,  "Invalid Command Operation Code"},
1156     {0x2100,  "Logical Block Address Out Of Range"},
1157     {0x2101,  "Invalid Element Address"},
1158     {0x2400,  "Invalid Field In Cdb"},
1159     {0x2401,  "Cdb Decryption Error"},
1160     {0x2500,  "Logical Unit Not Supported"},
1161     {0x2600,  "Invalid Field In Parameter List"},
1162     {0x2601,  "Parameter Not Supported"},
1163     {0x2602,  "Parameter Value Invalid"},
1164     {0x2603,  "Threshold Parameters Not Supported"},
1165     {0x2604,  "Invalid Release Of Persistent Reservation"},
1166     {0x2605,  "Data Decryption Error"},
1167     {0x2606,  "Too Many Target Descriptors"},
1168     {0x2607,  "Unsupported Target Descriptor Type Code"},
1169     {0x2608,  "Too Many Segment Descriptors"},
1170     {0x2609,  "Unsupported Segment Descriptor Type Code"},
1171     {0x260A,  "Unexpected Inexact Segment"},
1172     {0x260B,  "Inline Data Length Exceeded"},
1173     {0x260C,  "Invalid Operation For Copy Source Or Destination"},
1174     {0x260D,  "Copy Segment Granularity Violation"},
1175     {0x2700,  "Write Protected"},
1176     {0x2701,  "Hardware Write Protected"},
1177     {0x2702,  "Logical Unit Software Write Protected"},
1178     {0x2800,  "Not Ready To Ready Change, Medium May Have Changed"},
1179     {0x2801,  "Import Or Export Element Accessed"},
1180     {0x2900,  "Power On, Reset, Or Bus Device Reset Occurred"},
1181     {0x2901,  "Power On Occurred"},
1182     {0x2902,  "Scsi Bus Reset Occurred"},
1183     {0x2903,  "Bus Device Reset Function Occurred"},
1184     {0x2904,  "Device Internal Reset"},
1185     {0x2905,  "Transceiver Mode Changed To Single-Ended"},
1186     {0x2906,  "Transceiver Mode Changed To Lvd"},
1187     {0x2A00,  "Parameters Changed"},
1188     {0x2A01,  "Mode Parameters Changed"},
1189     {0x2A02,  "Log Parameters Changed"},
1190     {0x2A03,  "Reservations Preempted"},
1191     {0x2A04,  "Reservations Released"},
1192     {0x2A05,  "Registrations Preempted"},
1193     {0x2B00,  "Copy Cannot Execute Since Host Cannot Disconnect"},
1194     {0x2C00,  "Command Sequence Error"},
1195     {0x2F00,  "Commands Cleared By Another Initiator"},
1196     {0x3000,  "Incompatible Medium Installed"},
1197     {0x3001,  "Cannot Read Medium - Unknown Format"},
1198     {0x3002,  "Cannot Read Medium - Incompatible Format"},
1199     {0x3003,  "Cleaning Cartridge Installed"},
1200     {0x3004,  "Cannot Write Medium - Unknown Format"},
1201     {0x3005,  "Cannot Write Medium - Incompatible Format"},
1202     {0x3006,  "Cannot Format Medium - Incompatible Medium"},
1203     {0x3007,  "Cleaning Failure"},
1204     {0x3100,  "Medium Format Corrupted"},
1205     {0x3101,  "Format Command Failed"},
1206     {0x3200,  "No Defect Spare Location Available"},
1207     {0x3201,  "Defect List Update Failure"},
1208     {0x3400,  "Enclosure Failure"},
1209     {0x3500,  "Enclosure Services Failure"},
1210     {0x3501,  "Unsupported Enclosure Function"},
1211     {0x3502,  "Enclosure Services Unavailable"},
1212     {0x3503,  "Enclosure Services Transfer Failure"},
1213     {0x3504,  "Enclosure Services Transfer Refused"},
1214     {0x3700,  "Rounded Parameter"},
1215     {0x3900,  "Saving Parameters Not Supported"},
1216     {0x3A00,  "Medium Not Present"},
1217     {0x3A01,  "Medium Not Present - Tray Closed"},
1218     {0x3A02,  "Medium Not Present - Tray Open"},
1219     {0x3A03,  "Medium Not Present - Loadable"},
1220     {0x3A04,  "Medium Not Present - Medium Auxiliary Memory Accessible"},
1221     {0x3B0D,  "Medium Destination Element Full"},
1222     {0x3B0E,  "Medium Source Element Empty"},
1223     {0x3B11,  "Medium Magazine Not Accessible"},
1224     {0x3B12,  "Medium Magazine Removed"},
1225     {0x3B13,  "Medium Magazine Inserted"},
1226     {0x3B14,  "Medium Magazine Locked"},
1227     {0x3B15,  "Medium Magazine Unlocked"},
1228     {0x3D00,  "Invalid Bits In Identify Message"},
1229     {0x3E00,  "Logical Unit Has Not Self-Configured Yet"},
1230     {0x3E01,  "Logical Unit Failure"},
1231     {0x3E02,  "Timeout On Logical Unit"},
1232     {0x3E03,  "Logical Unit Failed Self-Test"},
1233     {0x3E04,  "Logical Unit Unable To Update Self-Test Log"},
1234     {0x3F00,  "Target Operating Conditions Have Changed"},
1235     {0x3F01,  "Microcode Has Been Changed"},
1236     {0x3F02,  "Changed Operating Definition"},
1237     {0x3F03,  "Inquiry Data Has Changed"},
1238     {0x3F04,  "Component Device Attached"},
1239     {0x3F05,  "Device Identifier Changed"},
1240     {0x3F06,  "Redundancy Group Created Or Modified"},
1241     {0x3F07,  "Redundancy Group Deleted"},
1242     {0x3F08,  "Spare Created Or Modified"},
1243     {0x3F09,  "Spare Deleted"},
1244     {0x3F0A,  "Volume Set Created Or Modified"},
1245     {0x3F0B,  "Volume Set Deleted"},
1246     {0x3F0C,  "Volume Set Deassigned"},
1247     {0x3F0D,  "Volume Set Reassigned"},
1248     {0x3F0E,  "Reported Luns Data Has Changed"},
1249     {0x3F0F,  "Echo Buffer Overwritten"},
1250     {0x3F10,  "Medium Loadable"},
1251     {0x3F11,  "Medium Auxiliary Memory Accessible"},
1252     {0x4200,  "Self-Test Failure (Should Use 40 Nn)"},
1253     {0x4300,  "Message Error"},
1254     {0x4400,  "Internal Target Failure"},
1255     {0x4500,  "Select Or Reselect Failure"},
1256     {0x4600,  "Unsuccessful Soft Reset"},
1257     {0x4700,  "Scsi Parity Error"},
1258     {0x4701,  "Data Phase Crc Error Detected"},
1259     {0x4702,  "Scsi Parity Error Detected During St Data Phase"},
1260     {0x4703,  "Information Unit Crc Error Detected"},
1261     {0x4704,  "Asynchronous Information Protection Error Detected"},
1262     {0x4800,  "Initiator Detected Error Message Received"},
1263     {0x4900,  "Invalid Message Error"},
1264     {0x4A00,  "Command Phase Error"},
1265     {0x4B00,  "Data Phase Error"},
1266     {0x4C00,  "Logical Unit Failed Self-Configuration"},
1267     {0x4D00,  "Tagged Overlapped Commands (Nn = Queue Tag)"},
1268     {0x4E00,  "Overlapped Commands Attempted"},
1269     {0x5300,  "Media Load Or Eject Failed"},
1270     {0x5302,  "Medium Removal Prevented"},
1271     {0x5501,  "System Buffer Full"},
1272     {0x5502,  "Insufficient Reservation Resources"},
1273     {0x5503,  "Insufficient Resources"},
1274     {0x5504,  "Insufficient Registration Resources"},
1275     {0x5A00,  "Operator Request Or State Change Input"},
1276     {0x5A01,  "Operator Medium Removal Request"},
1277     {0x5A02,  "Operator Selected Write Protect"},
1278     {0x5A03,  "Operator Selected Write Permit"},
1279     {0x5B00,  "Log Exception"},
1280     {0x5B01,  "Threshold Condition Met"},
1281     {0x5B02,  "Log Counter At Maximum"},
1282     {0x5B03,  "Log List Codes Exhausted"},
1283     {0x5C00,  "Change"},
1284     {0x5C02,  "Synchronized"},
1285     {0x5D00,  "Failure Prediction Threshold Exceeded"},
1286     {0x5D10,  "Failure General Hard Drive Failure"},
1287     {0x5D11,  "Failure Drive Error Rate Too High"},
1288     {0x5D12,  "Failure Data Error Rate Too High"},
1289     {0x5D13,  "Failure Seek Error Rate Too High"},
1290     {0x5D14,  "Failure Too Many Block Reassigns"},
1291     {0x5D15,  "Failure Access Times Too High"},
1292     {0x5D16,  "Failure Start Unit Times Too High"},
1293     {0x5D17,  "Failure Channel Parametrics"},
1294     {0x5D18,  "Failure Controller Detected"},
1295     {0x5D19,  "Failure Throughput Performance"},
1296     {0x5D1A,  "Failure Seek Time Performance"},
1297     {0x5D1B,  "Failure Spin-Up Retry Count"},
1298     {0x5D1C,  "Failure Drive Calibration Retry"},
1299     {0x5D20,  "Failure General Hard Drive Failure"},
1300     {0x5D21,  "Failure Drive Error Rate Too High"},
1301     {0x5D22,  "Failure Data Error Rate Too High"},
1302     {0x5D23,  "Failure Seek Error Rate Too High"},
1303     {0x5D24,  "Failure Too Many Block Reassigns"},
1304     {0x5D25,  "Failure Access Times Too High"},
1305     {0x5D26,  "Failure Start Unit Times Too High"},
1306     {0x5D27,  "Failure Channel Parametrics"},
1307     {0x5D28,  "Failure Controller Detected"},
1308     {0x5D29,  "Failure Throughput Performance"},
1309     {0x5D2A,  "Failure Seek Time Performance"},
1310     {0x5D2B,  "Failure Spin-Up Retry Count"},
1311     {0x5D2C,  "Failure Drive Calibration Retry"},
1312     {0x5D30,  "Impending Failure General Hard Drive"},
1313     {0x5D31,  "Impending Failure Drive Error Rate Too High"},
1314     {0x5D32,  "Impending Failure Data Error Rate Too High"},
1315     {0x5D33,  "Impending Failure Seek Error Rate Too High"},
1316     {0x5D34,  "Impending Failure Too Many Block Reassigns"},
1317     {0x5D35,  "Impending Failure Access Times Too High"},
1318     {0x5D36,  "Impending Failure Start Unit Times Too High"},
1319     {0x5D37,  "Impending Failure Channel Parametrics"},
1320     {0x5D38,  "Impending Failure Controller Detected"},
1321     {0x5D39,  "Impending Failure Throughput Performance"},
1322     {0x5D3A,  "Impending Failure Seek Time Performance"},
1323     {0x5D3B,  "Impending Failure Spin-Up Retry Count"},
1324     {0x5D3C,  "Impending Failure Drive Calibration Retry"},
1325     {0x5D40,  "Failure General Hard Drive Failure"},
1326     {0x5D41,  "Failure Drive Error Rate Too High"},
1327     {0x5D42,  "Failure Data Error Rate Too High"},
1328     {0x5D43,  "Failure Seek Error Rate Too High"},
1329     {0x5D44,  "Failure Too Many Block Reassigns"},
1330     {0x5D45,  "Failure Access Times Too High"},
1331     {0x5D46,  "Failure Start Unit Times Too High"},
1332     {0x5D47,  "Failure Channel Parametrics"},
1333     {0x5D48,  "Failure Controller Detected"},
1334     {0x5D49,  "Failure Throughput Performance"},
1335     {0x5D4A,  "Failure Seek Time Performance"},
1336     {0x5D4B,  "Failure Spin-Up Retry Count"},
1337     {0x5D4C,  "Failure Drive Calibration Retry Count"},
1338     {0x5D50,  "Failure General Hard Drive Failure"},
1339     {0x5D51,  "Failure Drive Error Rate Too High"},
1340     {0x5D52,  "Failure Data Error Rate Too High"},
1341     {0x5D53,  "Failure Seek Error Rate Too High"},
1342     {0x5D54,  "Failure Too Many Block Reassigns"},
1343     {0x5D55,  "Failure Access Times Too High"},
1344     {0x5D56,  "Failure Start Unit Times Too High"},
1345     {0x5D57,  "Failure Channel Parametrics"},
1346     {0x5D58,  "Failure Controller Detected"},
1347     {0x5D59,  "Failure Throughput Performance"},
1348     {0x5D5A,  "Failure Seek Time Performance"},
1349     {0x5D5B,  "Failure Spin-Up Retry Count"},
1350     {0x5D5C,  "Failure Drive Calibration Retry Count"},
1351     {0x5D60,  "Failure General Hard Drive Failure"},
1352     {0x5D61,  "Failure Drive Error Rate Too High"},
1353     {0x5D62,  "Failure Data Error Rate Too High"},
1354     {0x5D63,  "Failure Seek Error Rate Too High"},
1355     {0x5D64,  "Failure Too Many Block Reassigns"},
1356     {0x5D65,  "Failure Access Times Too High"},
1357     {0x5D66,  "Failure Start Unit Times Too High"},
1358     {0x5D67,  "Failure Channel Parametrics"},
1359     {0x5D68,  "Failure Controller Detected"},
1360     {0x5D69,  "Failure Throughput Performance"},
1361     {0x5D6A,  "Failure Seek Time Performance"},
1362     {0x5D6B,  "Failure Spin-Up Retry Count"},
1363     {0x5D6C,  "Failure Drive Calibration Retry Count"},
1364     {0x5DFF,  "Failure Prediction Threshold Exceeded (False)"},
1365     {0x5E00,  "Low Power Condition On"},
1366     {0x5E01,  "Idle Condition Activated By Timer"},
1367     {0x5E02,  "Standby Condition Activated By Timer"},
1368     {0x5E03,  "Idle Condition Activated By Command"},
1369     {0x5E04,  "Standby Condition Activated By Command"},
1370     {0x6500,  "Voltage Fault"},
1371     {0, NULL},
1372 };
1373
1374 /* SCSI Status Codes */
1375 const value_string scsi_status_val[] = {
1376     {0x00, "Good"},
1377     {0x02, "Check Condition"},
1378     {0x04, "Condition Met"},
1379     {0x08, "Busy"},
1380     {0x10, "Intermediate"},
1381     {0x14, "Intermediate Condition Met"},
1382     {0x18, "Reservation Conflict"},
1383     {0x28, "Task Set Full"},
1384     {0x30, "ACA Active"},
1385     {0x40, "Task Aborted"},
1386     {0, NULL},
1387 };
1388
1389 const value_string scsi_ssu_pwrcnd_val[] = {
1390     {0x0, "No Change"},
1391     {0x1, "Place Device In Active Condition"},
1392     {0x2, "Place device into Idle condition"},
1393     {0x3, "Place device into Standby condition"},
1394     {0x4, "Reserved"},
1395     {0x5, "Place device into Sleep condition"},
1396     {0x6, "Reserved"},
1397     {0x7, "Transfer control of power conditions to block device"},
1398     {0x8, "Reserved"},
1399     {0x9, "Reserved"},
1400     {0xA, "Force Idle Condition Timer to zero"},
1401     {0xB, "Force Standby Condition Timer to zero"},
1402     {0, NULL},
1403 };
1404
1405 const value_string scsi_wb_mode_val[] = {
1406     {0x0, "Write combined header and data"},
1407     {0x1, "Vendor specific"},
1408     {0x2, "Write data"},
1409     {0x3, "Reserved"},
1410     {0x4, "Download microcode"},
1411     {0x5, "Download microcode and save"},
1412     {0x6, "Download microcode with offsets"},
1413     {0x7, "Download microcode with offsets and save"},
1414     {0x8, "Reserved"},
1415     {0x9, "Reserved"},
1416     {0xA, "Echo buffer"},
1417     {0, NULL},
1418 };
1419
1420 const value_string scsi_senddiag_st_code_val[] = {
1421     {0, ""},
1422     {0x1, "Start short self-test in background"},
1423     {0x2, "Start extended self-test in background"},
1424     {0x3, "Reserved"},
1425     {0x4, "Abort background self-test"},
1426     {0x5, "Foreground short self-test"},
1427     {0x6, "Foreground extended self-test"},
1428     {0x7, "Reserved"},
1429     {0, NULL},
1430 };
1431
1432 const true_false_string scsi_senddiag_pf_val = {
1433     "Vendor-specific Page Format",
1434     "Standard Page Format",
1435 };
1436
1437 static gint scsi_def_devtype = SCSI_DEV_SBC;
1438
1439 /*
1440  * We track SCSI requests and responses with a hash table.
1441  * The key is a "scsi_task_id_t" structure; the data is a
1442  * "scsi_task_data_t" structure.
1443  *
1444  * We remember:
1445  *
1446  *    the command code and type of command (it's not present in the
1447  *        response, and we need it to dissect the response);
1448  *    the type of device it's on;
1449  *
1450  * and we also have a field to record flags in case the interpretation
1451  * of the response data depends on data from the command.
1452  */
1453 typedef struct _scsi_task_data {
1454     guint32 opcode;
1455     scsi_cmnd_type cmd;
1456     scsi_device_type devtype;
1457     guint16 flags;
1458     struct _scsi_cdb_table_t *cdb_table;
1459     const value_string *cdb_vals;
1460 } scsi_task_data_t;
1461
1462 /*
1463  * The next two data structures are used to track SCSI device type.
1464  *
1465  * XXX - it might not be sufficient to use the address of the server
1466  * to which SCSI CDBs are being sent to identify the device, as
1467  *
1468  *      1) a server might have multiple targets or logical units;
1469  *
1470  *      2) a server might make a different logical unit refer to
1471  *         different devices for different clients;
1472  *
1473  * so we should really base this on the connection index for the
1474  * connection and on a device identifier supplied to us by our caller,
1475  * not on a network-layer address.
1476  */
1477 typedef struct _scsi_devtype_key {
1478     address devid;
1479 } scsi_devtype_key_t;
1480
1481 typedef struct _scsi_devtype_data {
1482     scsi_device_type devtype;
1483 } scsi_devtype_data_t;
1484
1485 static GHashTable *scsi_req_hash = NULL;
1486
1487 static GHashTable *scsidev_req_hash = NULL;
1488
1489 static dissector_handle_t data_handle;
1490
1491 /*
1492  * Hash Functions
1493  */
1494 static gint
1495 scsi_equal(gconstpointer v, gconstpointer w)
1496 {
1497   const scsi_task_id_t *v1 = (const scsi_task_id_t *)v;
1498   const scsi_task_id_t *v2 = (const scsi_task_id_t *)w;
1499
1500   return (v1->conv_id == v2->conv_id && v1->task_id == v2->task_id);
1501 }
1502
1503 static guint
1504 scsi_hash (gconstpointer v)
1505 {
1506         const scsi_task_id_t *key = (const scsi_task_id_t *)v;
1507         guint val;
1508
1509         val = key->conv_id + key->task_id;
1510
1511         return val;
1512 }
1513
1514 static gint
1515 scsidev_equal (gconstpointer v, gconstpointer w)
1516 {
1517     const scsi_devtype_key_t *k1 = (const scsi_devtype_key_t *)v;
1518     const scsi_devtype_key_t *k2 = (const scsi_devtype_key_t *)w;
1519
1520     if (ADDRESSES_EQUAL (&k1->devid, &k2->devid))
1521         return 1;
1522     else
1523         return 0;
1524 }
1525
1526 static guint
1527 scsidev_hash (gconstpointer v)
1528 {
1529     const scsi_devtype_key_t *key = (const scsi_devtype_key_t *)v;
1530     guint val;
1531     int i;
1532
1533     val = 0;
1534     for (i = 0; i < key->devid.len; i++)
1535         val += key->devid.data[i];
1536     val += key->devid.type;
1537
1538     return val;
1539 }
1540
1541 static scsi_task_data_t *
1542 scsi_new_task (packet_info *pinfo)
1543 {
1544     scsi_task_data_t *cdata = NULL;
1545     scsi_task_id_t ckey, *req_key;
1546
1547     if ((pinfo != NULL) && (pinfo->private_data)) {
1548         ckey = *(scsi_task_id_t *)pinfo->private_data;
1549
1550         cdata = (scsi_task_data_t *)g_hash_table_lookup (scsi_req_hash,
1551                                                          &ckey);
1552         if (!cdata) {
1553             req_key = se_alloc (sizeof(scsi_task_id_t));
1554             *req_key = *(scsi_task_id_t *)pinfo->private_data;
1555
1556             cdata = se_alloc (sizeof(scsi_task_data_t));
1557
1558             g_hash_table_insert (scsi_req_hash, req_key, cdata);
1559         }
1560     }
1561     return (cdata);
1562 }
1563
1564 static scsi_task_data_t *
1565 scsi_find_task (packet_info *pinfo)
1566 {
1567     scsi_task_data_t *cdata = NULL;
1568     scsi_task_id_t ckey;
1569
1570     if ((pinfo != NULL) && (pinfo->private_data)) {
1571         ckey = *(scsi_task_id_t *)pinfo->private_data;
1572
1573         cdata = (scsi_task_data_t *)g_hash_table_lookup (scsi_req_hash,
1574                                                          &ckey);
1575     }
1576     return (cdata);
1577 }
1578
1579 static void
1580 scsi_end_task (packet_info *pinfo)
1581 {
1582     scsi_task_data_t *cdata = NULL;
1583     scsi_task_id_t ckey;
1584
1585     if ((pinfo != NULL) && (pinfo->private_data)) {
1586         ckey = *(scsi_task_id_t *)pinfo->private_data;
1587         cdata = (scsi_task_data_t *)g_hash_table_lookup (scsi_req_hash,
1588                                                          &ckey);
1589         if (cdata) {
1590             g_hash_table_remove (scsi_req_hash, &ckey);
1591         }
1592     }
1593 }
1594
1595 /*
1596  * Protocol initialization
1597  */
1598 static void
1599 free_devtype_key_dev_info(gpointer key_arg, gpointer value_arg _U_,
1600     gpointer user_data _U_)
1601 {
1602         scsi_devtype_key_t *key = key_arg;
1603
1604         if (key->devid.data != NULL) {
1605                 g_free((gpointer)key->devid.data);
1606                 key->devid.data = NULL;
1607         }
1608 }
1609
1610
1611
1612 static void
1613 scsi_init_protocol(void)
1614 {
1615         /*
1616          * First, free up the data for the addresses attached to
1617          * scsi_devtype_key_t structures.  Do so before we free
1618          * those structures or destroy the hash table in which
1619          * they're stored.
1620          */
1621         if (scsidev_req_hash != NULL) {
1622                 g_hash_table_foreach(scsidev_req_hash, free_devtype_key_dev_info,
1623                     NULL);
1624         }
1625
1626         if (scsi_req_hash)
1627             g_hash_table_destroy(scsi_req_hash);
1628         if (scsidev_req_hash)
1629             g_hash_table_destroy (scsidev_req_hash);
1630
1631         scsi_req_hash = g_hash_table_new(scsi_hash, scsi_equal);
1632         scsidev_req_hash = g_hash_table_new (scsidev_hash, scsidev_equal);
1633 }
1634
1635 static void
1636 dissect_scsi_evpd (tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *tree,
1637                    guint offset, guint tot_len _U_)
1638 {
1639     proto_tree *evpd_tree;
1640     proto_item *ti;
1641     guint pcode, plen, i, idlen;
1642     guint8 codeset, flags;
1643
1644     if (tree) {
1645         pcode = tvb_get_guint8 (tvb, offset+1);
1646         plen = tvb_get_guint8 (tvb, offset+3);
1647         ti = proto_tree_add_text (tree, tvb, offset, plen+4, "Page Code: %s",
1648                                   val_to_str (pcode, scsi_evpd_pagecode_val,
1649                                               "Unknown (0x%08x)"));
1650         evpd_tree = proto_item_add_subtree (ti, ett_scsi_page);
1651
1652         proto_tree_add_item (evpd_tree, hf_scsi_inq_qualifier, tvb, offset,
1653                              1, 0);
1654         proto_tree_add_item (evpd_tree, hf_scsi_inq_devtype, tvb, offset,
1655                              1, 0);
1656         proto_tree_add_text (evpd_tree, tvb, offset+1, 1,
1657                              "Page Code: %s",
1658                              val_to_str (pcode, scsi_evpd_pagecode_val,
1659                                          "Unknown (0x%02x)"));
1660         proto_tree_add_text (evpd_tree, tvb, offset+3, 1,
1661                              "Page Length: %u", plen);
1662         offset += 4;
1663         switch (pcode) {
1664         case SCSI_EVPD_SUPPPG:
1665             for (i = 0; i < plen; i++) {
1666                 proto_tree_add_text (evpd_tree, tvb, offset+i, 1,
1667                                      "Supported Page: %s",
1668                                      val_to_str (tvb_get_guint8 (tvb, offset+i),
1669                                                  scsi_evpd_pagecode_val,
1670                                                  "Unknown (0x%02x)"));
1671             }
1672             break;
1673         case SCSI_EVPD_DEVID:
1674             while (plen != 0) {
1675                 codeset = tvb_get_guint8 (tvb, offset) & 0x0F;
1676                 proto_tree_add_text (evpd_tree, tvb, offset, 1,
1677                                      "Code Set: %s",
1678                                      val_to_str (codeset,
1679                                                  scsi_devid_codeset_val,
1680                                                  "Unknown (0x%02x)"));
1681                 plen -= 1;
1682                 offset += 1;
1683
1684                 if (plen < 1) {
1685                     proto_tree_add_text (evpd_tree, tvb, offset, 0,
1686                                          "Product data goes past end of page");
1687                     break;
1688                 }
1689                 flags = tvb_get_guint8 (tvb, offset);
1690                 proto_tree_add_text (evpd_tree, tvb, offset, 1,
1691                                      "Association: %s",
1692                                      val_to_str ((flags & 0x30) >> 4,
1693                                                  scsi_devid_assoc_val,
1694                                                  "Unknown (0x%02x)"));
1695                 proto_tree_add_text (evpd_tree, tvb, offset, 1,
1696                                      "Identifier Type: %s",
1697                                      val_to_str ((flags & 0x0F),
1698                                                  scsi_devid_idtype_val,
1699                                                  "Unknown (0x%02x)"));
1700                 plen -= 1;
1701                 offset += 1;
1702
1703                 /* Skip reserved byte */
1704                 if (plen < 1) {
1705                     proto_tree_add_text (evpd_tree, tvb, offset, 0,
1706                                          "Product data goes past end of page");
1707                     break;
1708                 }
1709                 plen -= 1;
1710                 offset += 1;
1711
1712                 if (plen < 1) {
1713                     proto_tree_add_text (evpd_tree, tvb, offset, 0,
1714                                          "Product data goes past end of page");
1715                     break;
1716                 }
1717                 idlen = tvb_get_guint8 (tvb, offset);
1718                 proto_tree_add_text (evpd_tree, tvb, offset, 1,
1719                                      "Identifier Length: %u", idlen);
1720                 plen -= 1;
1721                 offset += 1;
1722
1723                 if (idlen != 0) {
1724                     if (plen < idlen) {
1725                         proto_tree_add_text (evpd_tree, tvb, offset, 0,
1726                                              "Product data goes past end of page");
1727                         break;
1728                     }
1729                     if (codeset == CODESET_ASCII) {
1730                         proto_tree_add_text (evpd_tree, tvb, offset, idlen,
1731                                              "Identifier: %s",
1732                                              tvb_format_text (tvb, offset,
1733                                                               idlen));
1734                     } else {
1735                         /*
1736                          * XXX - decode this based on the identifier type,
1737                          * if the codeset is CODESET_BINARY?
1738                          */
1739                         proto_tree_add_text (evpd_tree, tvb, offset, idlen,
1740                                              "Identifier: %s",
1741                                              tvb_bytes_to_str (tvb, offset,
1742                                                                idlen));
1743                     }
1744                     plen -= idlen;
1745                     offset += idlen;
1746                 }
1747             }
1748             break;
1749         case SCSI_EVPD_DEVSERNUM:
1750             if (plen > 0) {
1751                 proto_tree_add_text (evpd_tree, tvb, offset, plen,
1752                                      "Product Serial Number: %s",
1753                                      tvb_format_text (tvb, offset, plen));
1754             }
1755             break;
1756         }
1757     }
1758 }
1759
1760 static void
1761 dissect_scsi_cmddt (tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *tree,
1762                     guint offset, guint tot_len _U_)
1763 {
1764     proto_tree *cmdt_tree;
1765     proto_item *ti;
1766     guint plen;
1767
1768     if (tree) {
1769         plen = tvb_get_guint8 (tvb, offset+5);
1770         ti = proto_tree_add_text (tree, tvb, offset, plen, "Command Data");
1771         cmdt_tree = proto_item_add_subtree (ti, ett_scsi_page);
1772
1773         proto_tree_add_item (cmdt_tree, hf_scsi_inq_qualifier, tvb, offset,
1774                              1, 0);
1775         proto_tree_add_item (cmdt_tree, hf_scsi_inq_devtype, tvb, offset,
1776                              1, 0);
1777         proto_tree_add_text (cmdt_tree, tvb, offset+1, 1, "Support: %s",
1778                              match_strval (tvb_get_guint8 (tvb, offset+1) & 0x7,
1779                                            scsi_cmdt_supp_val));
1780         proto_tree_add_text (cmdt_tree, tvb, offset+2, 1, "Version: %s",
1781                              val_to_str (tvb_get_guint8 (tvb, offset+2),
1782                                          scsi_verdesc_val,
1783                                          "Unknown (0x%02x)"));
1784         proto_tree_add_text (cmdt_tree, tvb, offset+5, 1, "CDB Size: %u",
1785                              plen);
1786     }
1787 }
1788
1789 static void
1790 dissect_spc3_inquiry (tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree,
1791                       guint offset, gboolean isreq, gboolean iscdb,
1792                       guint32 payload_len, scsi_task_data_t *cdata)
1793 {
1794     guint8 flags, i, devtype;
1795     guint tot_len;
1796     scsi_devtype_data_t *devdata = NULL;
1797     scsi_devtype_key_t dkey, *req_key;
1798
1799     if (!isreq && (cdata == NULL || !(cdata->flags & 0x3))) {
1800         /*
1801          * INQUIRY response with device type information; add device type
1802          * to list of known devices & their types if not already known.
1803          *
1804          * We don't use COPY_ADDRESS because "dkey.devid" isn't
1805          * persistent, and therefore it can point to the stuff
1806          * in "pinfo->src".  (Were we to use COPY_ADDRESS, we'd
1807          * have to free the address data it allocated before we return.)
1808          */
1809         dkey.devid = pinfo->src;
1810         devdata = (scsi_devtype_data_t *)g_hash_table_lookup (scsidev_req_hash,
1811                                                               &dkey);
1812         if (!devdata) {
1813             req_key = se_alloc (sizeof(scsi_devtype_key_t));
1814             COPY_ADDRESS (&(req_key->devid), &(pinfo->src));
1815
1816             devdata = se_alloc (sizeof(scsi_devtype_data_t));
1817             devdata->devtype = tvb_get_guint8 (tvb, offset) & SCSI_DEV_BITS;
1818
1819             g_hash_table_insert (scsidev_req_hash, req_key, devdata);
1820         }
1821         else {
1822             devtype = tvb_get_guint8 (tvb, offset);
1823             if ((devtype & SCSI_DEV_BITS) != SCSI_DEV_NOLUN) {
1824                 /* Some initiators probe more than the available LUNs which
1825                  * results in Inquiry data being returned indicating that a LUN
1826                  * is not supported. We don't want to overwrite the device type
1827                  * with such responses.
1828                  */
1829                 devdata->devtype = (devtype & SCSI_DEV_BITS);
1830             }
1831         }
1832     }
1833
1834     if (!tree)
1835         return;
1836
1837     if (isreq && iscdb) {
1838         flags = tvb_get_guint8 (tvb, offset);
1839         if (cdata != NULL) {
1840             cdata->flags = flags;
1841         }
1842
1843         proto_tree_add_uint_format (tree, hf_scsi_inquiry_flags, tvb, offset, 1,
1844                                     flags, "CMDT = %u, EVPD = %u",
1845                                     flags & 0x2, flags & 0x1);
1846         if (flags & 0x1) {
1847             proto_tree_add_item (tree, hf_scsi_inquiry_evpd_page, tvb, offset+1,
1848                                  1, 0);
1849         }
1850         else if (flags & 0x2) {
1851             proto_tree_add_item (tree, hf_scsi_inquiry_cmdt_page, tvb, offset+1,
1852                                  1, 0);
1853         }
1854
1855         proto_tree_add_item (tree, hf_scsi_alloclen, tvb, offset+3, 1, 0);
1856         flags = tvb_get_guint8 (tvb, offset+4);
1857         proto_tree_add_uint_format (tree, hf_scsi_control, tvb, offset+4, 1,
1858                                     flags,
1859                                     "Vendor Unique = %u, NACA = %u, Link = %u",
1860                                     flags & 0xC0, flags & 0x4, flags & 0x1);
1861     }
1862     else if (!isreq) {
1863         if (cdata && (cdata->flags & 0x1)) {
1864             dissect_scsi_evpd (tvb, pinfo, tree, offset, payload_len);
1865             return;
1866         }
1867         else if (cdata && (cdata->flags & 0x2)) {
1868             dissect_scsi_cmddt (tvb, pinfo, tree, offset, payload_len);
1869             return;
1870         }
1871
1872         proto_tree_add_item (tree, hf_scsi_inq_qualifier, tvb, offset,
1873                              1, 0);
1874         proto_tree_add_item (tree, hf_scsi_inq_devtype, tvb, offset, 1, 0);
1875         proto_tree_add_item (tree, hf_scsi_inq_rmb,  tvb, offset+1, 1, 0);
1876         proto_tree_add_item (tree, hf_scsi_inq_version, tvb, offset+2, 1, 0);
1877
1878         flags = tvb_get_guint8 (tvb, offset+3);
1879         proto_tree_add_item_hidden (tree, hf_scsi_inq_normaca, tvb,
1880                                     offset+3, 1, 0);
1881         proto_tree_add_text (tree, tvb, offset+3, 1, "NormACA: %u, HiSup: %u",
1882                              ((flags & 0x20) >> 5), ((flags & 0x10) >> 4));
1883         tot_len = tvb_get_guint8 (tvb, offset+4);
1884         proto_tree_add_text (tree, tvb, offset+4, 1, "Additional Length: %u",
1885                              tot_len);
1886         flags = tvb_get_guint8 (tvb, offset+6);
1887         proto_tree_add_text (tree, tvb, offset+6, 1,
1888                              "BQue: %u, SES: %u, MultiP: %u, Addr16: %u",
1889                              ((flags & 0x80) >> 7), (flags & 0x40) >> 6,
1890                              (flags & 0x10) >> 4, (flags & 0x01));
1891         flags = tvb_get_guint8 (tvb, offset+7);
1892         proto_tree_add_text (tree, tvb, offset+7, 1,
1893                              "RelAdr: %u, Linked: %u, CmdQue: %u",
1894                              (flags & 0x80) >> 7, (flags & 0x08) >> 3,
1895                              (flags & 0x02) >> 1);
1896         proto_tree_add_text (tree, tvb, offset+8, 8, "Vendor Id: %s",
1897                              tvb_format_stringzpad (tvb, offset+8, 8));
1898         proto_tree_add_text (tree, tvb, offset+16, 16, "Product ID: %s",
1899                              tvb_format_stringzpad (tvb, offset+16, 16));
1900         proto_tree_add_text (tree, tvb, offset+32, 4, "Product Revision: %s",
1901                              tvb_format_stringzpad (tvb, offset+32, 4));
1902
1903         offset += 58;
1904         if ((tot_len > 58) && tvb_bytes_exist (tvb, offset, 16)) {
1905             for (i = 0; i < 8; i++) {
1906                 proto_tree_add_text (tree, tvb, offset, 2,
1907                                      "Vendor Descriptor %u: %s",
1908                                      i,
1909                                      val_to_str (tvb_get_ntohs (tvb, offset),
1910                                                  scsi_verdesc_val,
1911                                                  "Unknown (0x%04x)"));
1912                 offset += 2;
1913             }
1914         }
1915     }
1916 }
1917
1918 static void
1919 dissect_spc3_extcopy (tvbuff_t *tvb _U_, packet_info *pinfo _U_,
1920                       proto_tree *tree _U_, guint offset _U_,
1921                       gboolean isreq _U_, gboolean iscdb _U_,
1922                       guint payload_len _U_, scsi_task_data_t *cdata _U_)
1923 {
1924
1925 }
1926
1927 static void
1928 dissect_spc3_logselect (tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *tree,
1929                         guint offset, gboolean isreq, gboolean iscdb,
1930                         guint payload_len _U_, scsi_task_data_t *cdata _U_)
1931 {
1932     guint8 flags;
1933
1934     if (!tree)
1935         return;
1936
1937     if (isreq && iscdb) {
1938         flags = tvb_get_guint8 (tvb, offset);
1939
1940         proto_tree_add_uint_format (tree, hf_scsi_logsel_flags, tvb, offset, 1,
1941                                     flags, "PCR = %u, SP = %u", flags & 0x2,
1942                                     flags & 0x1);
1943         proto_tree_add_uint_format (tree, hf_scsi_logsel_pc, tvb, offset+1, 1,
1944                                     tvb_get_guint8 (tvb, offset+1),
1945                                     "PC: 0x%x", flags & 0xC0);
1946         proto_tree_add_item (tree, hf_scsi_paramlen16, tvb, offset+6, 2, 0);
1947
1948         flags = tvb_get_guint8 (tvb, offset+8);
1949         proto_tree_add_uint_format (tree, hf_scsi_control, tvb, offset+8, 1,
1950                                     flags,
1951                                     "Vendor Unique = %u, NACA = %u, Link = %u",
1952                                     flags & 0xC0, flags & 0x4, flags & 0x1);
1953     }
1954     else {
1955     }
1956 }
1957
1958 static void
1959 dissect_spc3_logsense (tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *tree,
1960                        guint offset, gboolean isreq, gboolean iscdb,
1961                        guint payload_len _U_, scsi_task_data_t *cdata _U_)
1962 {
1963     guint8 flags;
1964
1965     if (!tree)
1966         return;
1967
1968     if (isreq && iscdb) {
1969         flags = tvb_get_guint8 (tvb, offset);
1970
1971         proto_tree_add_uint_format (tree, hf_scsi_logsns_flags, tvb, offset, 1,
1972                                     flags, "PPC = %u, SP = %u", flags & 0x2,
1973                                     flags & 0x1);
1974         proto_tree_add_uint_format (tree, hf_scsi_logsns_pc, tvb, offset+1, 1,
1975                                     tvb_get_guint8 (tvb, offset+1),
1976                                     "PC: 0x%x", flags & 0xC0);
1977         proto_tree_add_item (tree, hf_scsi_logsns_pagecode, tvb, offset+1,
1978                              1, 0);
1979         proto_tree_add_text (tree, tvb, offset+4, 2, "Parameter Pointer: 0x%04x",
1980                              tvb_get_ntohs (tvb, offset+4));
1981         proto_tree_add_item (tree, hf_scsi_alloclen16, tvb, offset+6, 2, 0);
1982
1983         flags = tvb_get_guint8 (tvb, offset+8);
1984         proto_tree_add_uint_format (tree, hf_scsi_control, tvb, offset+8, 1,
1985                                     flags,
1986                                     "Vendor Unique = %u, NACA = %u, Link = %u",
1987                                     flags & 0xC0, flags & 0x4, flags & 0x1);
1988     }
1989     else {
1990     }
1991 }
1992
1993 static void
1994 dissect_scsi_blockdescs (tvbuff_t *tvb, packet_info *pinfo _U_,
1995                         proto_tree *scsi_tree,
1996                         scsi_task_data_t *cdata, gboolean longlba)
1997 {
1998     int offset=0;
1999
2000     /* without cdata there is no point in continuing */
2001     if (!cdata)
2002         return;
2003
2004     while (tvb_length_remaining(tvb, offset)) {
2005         if (longlba) {
2006             if(tvb_length_remaining(tvb, offset)<8)
2007                 return;
2008             proto_tree_add_text (scsi_tree, tvb, offset, 8, "No. of Blocks: %" PRIu64,
2009                                  tvb_get_ntoh64 (tvb, offset));
2010             offset += 8;
2011
2012             if(tvb_length_remaining(tvb, offset)<1)
2013                 return;
2014             proto_tree_add_text (scsi_tree, tvb, offset, 1, "Density Code: 0x%02x",
2015                                  tvb_get_guint8 (tvb, offset));
2016             offset += 1;
2017
2018             /* 3 reserved bytes */
2019             offset += 3;
2020
2021             if(tvb_length_remaining(tvb, offset)<4)
2022                 return;
2023             proto_tree_add_text (scsi_tree, tvb, offset, 4, "Block Length: %u",
2024                                      tvb_get_ntohl (tvb, offset));
2025             offset += 4;
2026         } else {
2027             if (cdata->devtype == SCSI_DEV_SBC) {
2028                 if(tvb_length_remaining(tvb, offset)<4)
2029                     return;
2030                 proto_tree_add_text (scsi_tree, tvb, offset, 4, "No. of Blocks: %u",
2031                                      tvb_get_ntohl (tvb, offset));
2032                 offset += 4;
2033
2034                 offset++;  /* reserved */
2035
2036                 if(tvb_length_remaining(tvb, offset)<3)
2037                     return;
2038                 proto_tree_add_text (scsi_tree, tvb, offset, 3, "Block Length: %u",
2039                                          tvb_get_ntoh24 (tvb, offset));
2040                 offset += 3;
2041             } else {
2042                 if(tvb_length_remaining(tvb, offset)<1)
2043                     return;
2044                 proto_tree_add_text (scsi_tree, tvb, offset, 1, "Density Code: 0x%02x",
2045                                      tvb_get_guint8 (tvb, offset));
2046                 offset += 1;
2047
2048                 if(tvb_length_remaining(tvb, offset)<3)
2049                     return;
2050                 proto_tree_add_text (scsi_tree, tvb, offset, 3, "No. of Blocks: %u",
2051                                      tvb_get_ntohl (tvb, offset));
2052                 offset += 3;
2053
2054                 offset++; /* reserved */
2055
2056                 if(tvb_length_remaining(tvb, offset)<3)
2057                     return;
2058                 proto_tree_add_text (scsi_tree, tvb, offset, 3, "Block Length: %u",
2059                                          tvb_get_ntoh24 (tvb, offset));
2060                 offset += 3;
2061             }
2062         }
2063     }
2064 }
2065
2066 static gboolean
2067 dissect_scsi_spc2_modepage (tvbuff_t *tvb, packet_info *pinfo _U_,
2068                             proto_tree *tree, guint offset, guint8 pcode)
2069 {
2070     guint8 flags, proto;
2071
2072     switch (pcode) {
2073     case SCSI_SPC2_MODEPAGE_CTL:
2074         flags = tvb_get_guint8 (tvb, offset+2);
2075         proto_tree_add_item (tree, hf_scsi_modesns_tst, tvb, offset+2, 1, 0);
2076         proto_tree_add_text (tree, tvb, offset+2, 1,
2077                              "Global Logging Target Save Disable: %u, Report Log Exception Condition: %u",
2078                              (flags & 0x2) >> 1, (flags & 0x1));
2079         flags = tvb_get_guint8 (tvb, offset+3);
2080         proto_tree_add_item (tree, hf_scsi_modesns_qmod, tvb, offset+3, 1, 0);
2081         proto_tree_add_item (tree, hf_scsi_modesns_qerr, tvb, offset+3, 1, 0);
2082         proto_tree_add_text (tree, tvb, offset+3, 1, "Disable Queuing: %u",
2083                              flags & 0x1);
2084         flags = tvb_get_guint8 (tvb, offset+4);
2085         proto_tree_add_item (tree, hf_scsi_modesns_rac, tvb, offset+4, 1, 0);
2086         proto_tree_add_item (tree, hf_scsi_modesns_tas, tvb, offset+4, 1, 0);
2087         proto_tree_add_text (tree, tvb, offset+4, 1,
2088                              "SWP: %u, RAERP: %u, UAAERP: %u, EAERP: %u",
2089                              (flags & 0x8) >> 3, (flags & 0x4) >> 2,
2090                              (flags & 0x2) >> 2, (flags & 0x1));
2091         proto_tree_add_text (tree, tvb, offset+5, 1, "Autoload Mode: 0x%x",
2092                              tvb_get_guint8 (tvb, offset+5) & 0x7);
2093         proto_tree_add_text (tree, tvb, offset+6, 2,
2094                              "Ready AER Holdoff Period: %u ms",
2095                              tvb_get_ntohs (tvb, offset+6));
2096         proto_tree_add_text (tree, tvb, offset+8, 2,
2097                              "Busy Timeout Period: %u ms",
2098                              tvb_get_ntohs (tvb, offset+8)*100);
2099         proto_tree_add_text (tree, tvb, offset+10, 2,
2100                              "Extended Self-Test Completion Time: %u",
2101                              tvb_get_ntohs (tvb, offset+10));
2102         break;
2103     case SCSI_SPC2_MODEPAGE_DISCON:
2104         proto_tree_add_text (tree, tvb, offset+2, 1, "Buffer Full Ratio: %u",
2105                              tvb_get_guint8 (tvb, offset+2));
2106         proto_tree_add_text (tree, tvb, offset+3, 1, "Buffer Empty Ratio: %u",
2107                              tvb_get_guint8 (tvb, offset+3));
2108         proto_tree_add_text (tree, tvb, offset+4, 2, "Bus Inactivity Limit: %u",
2109                              tvb_get_ntohs (tvb, offset+4));
2110         proto_tree_add_text (tree, tvb, offset+6, 2, "Disconnect Time Limit: %u",
2111                              tvb_get_ntohs (tvb, offset+6));
2112         proto_tree_add_text (tree, tvb, offset+8, 2, "Connect Time Limit: %u",
2113                              tvb_get_ntohs (tvb, offset+8));
2114         proto_tree_add_text (tree, tvb, offset+10, 2,
2115                              "Maximum Burst Size: %u bytes",
2116                              tvb_get_ntohs (tvb, offset+10)*512);
2117         flags = tvb_get_guint8 (tvb, offset+12);
2118         proto_tree_add_text (tree, tvb, offset+12, 1,
2119                              "EMDP: %u, FAA: %u, FAB: %u, FAC: %u",
2120                              (flags & 0x80) >> 7, (flags & 0x40) >> 6,
2121                              (flags & 0x20) >> 5, (flags & 0x10) >> 4);
2122         proto_tree_add_text (tree, tvb, offset+14, 2,
2123                              "First Burst Size: %u bytes",
2124                              tvb_get_ntohs (tvb, offset+14)*512);
2125         break;
2126     case SCSI_SPC2_MODEPAGE_INFOEXCP:
2127         flags = tvb_get_guint8 (tvb, offset+2);
2128         proto_tree_add_text (tree, tvb, offset+2, 1,
2129                              "Perf: %u, EBF: %u, EWasc: %u, DExcpt: %u, Test: %u, LogErr: %u",
2130                              (flags & 0x80) >> 7, (flags & 0x20) >> 5,
2131                              (flags & 0x10) >> 4, (flags & 0x08) >> 3,
2132                              (flags & 0x04) >> 2, (flags & 0x01));
2133         if (!((flags & 0x10) >> 4) && ((flags & 0x08) >> 3)) {
2134             proto_tree_add_item_hidden (tree, hf_scsi_modesns_errrep, tvb,
2135                                         offset+3, 1, 0);
2136         }
2137         else {
2138             proto_tree_add_item (tree, hf_scsi_modesns_errrep, tvb, offset+3, 1, 0);
2139         }
2140         proto_tree_add_text (tree, tvb, offset+4, 4, "Interval Timer: %u",
2141                              tvb_get_ntohl (tvb, offset+4));
2142         proto_tree_add_text (tree, tvb, offset+8, 4, "Report Count: %u",
2143                              tvb_get_ntohl (tvb, offset+8));
2144         break;
2145     case SCSI_SPC2_MODEPAGE_PWR:
2146         flags = tvb_get_guint8 (tvb, offset+3);
2147         proto_tree_add_text (tree, tvb, offset+3, 1, "Idle: %u, Standby: %u",
2148                              (flags & 0x2) >> 1, (flags & 0x1));
2149         proto_tree_add_text (tree, tvb, offset+4, 2,
2150                              "Idle Condition Timer: %u ms",
2151                              tvb_get_ntohs (tvb, offset+4) * 100);
2152         proto_tree_add_text (tree, tvb, offset+6, 2,
2153                              "Standby Condition Timer: %u ms",
2154                              tvb_get_ntohs (tvb, offset+6) * 100);
2155         break;
2156     case SCSI_SPC2_MODEPAGE_LUN:
2157         return FALSE;
2158     case SCSI_SPC2_MODEPAGE_PORT:
2159         proto = tvb_get_guint8 (tvb, offset+2) & 0x0F;
2160         proto_tree_add_item (tree, hf_scsi_protocol, tvb, offset+2, 1, 0);
2161         if (proto == SCSI_PROTO_FCP) {
2162             flags = tvb_get_guint8 (tvb, offset+3);
2163             proto_tree_add_text (tree, tvb, offset+3, 1,
2164                                  "DTFD: %u, PLPB: %u, DDIS: %u, DLM: %u, RHA: %u, ALWI: %u, DTIPE: %u, DTOLI:%u",
2165                                  (flags & 0x80) >> 7, (flags & 0x40) >> 6,
2166                                  (flags & 0x20) >> 5, (flags & 0x10) >> 4,
2167                                  (flags & 0x08) >> 3, (flags & 0x04) >> 2,
2168                                  (flags & 0x02) >> 1, (flags & 0x1));
2169             proto_tree_add_text (tree, tvb, offset+6, 1, "RR_TOV Units: %s",
2170                                  val_to_str (tvb_get_guint8 (tvb, offset+6) & 0x7,
2171                                              scsi_fcp_rrtov_val,
2172                                              "Unknown (0x%02x)"));
2173             proto_tree_add_text (tree, tvb, offset+7, 1, "RR_TOV: %u",
2174                                  tvb_get_guint8 (tvb, offset+7));
2175         }
2176         else if (proto == SCSI_PROTO_iSCSI) {
2177             return FALSE;
2178         }
2179         else {
2180             return FALSE;
2181         }
2182         break;
2183     case SCSI_SCSI2_MODEPAGE_PERDEV:
2184         return FALSE;
2185     default:
2186         return FALSE;
2187     }
2188     return TRUE;
2189 }
2190
2191 static gboolean
2192 dissect_scsi_sbc2_modepage (tvbuff_t *tvb, packet_info *pinfo _U_,
2193                             proto_tree *tree, guint offset, guint8 pcode)
2194 {
2195     guint8 flags;
2196
2197     switch (pcode) {
2198     case SCSI_SBC2_MODEPAGE_FMTDEV:
2199         proto_tree_add_text (tree, tvb, offset+2, 2, "Tracks Per Zone: %u",
2200                              tvb_get_ntohs (tvb, offset+2));
2201         proto_tree_add_text (tree, tvb, offset+4, 2,
2202                              "Alternate Sectors Per Zone: %u",
2203                              tvb_get_ntohs (tvb, offset+4));
2204         proto_tree_add_text (tree, tvb, offset+6, 2,
2205                              "Alternate Tracks Per Zone: %u",
2206                              tvb_get_ntohs (tvb, offset+6));
2207         proto_tree_add_text (tree, tvb, offset+8, 2,
2208                              "Alternate Tracks Per LU: %u",
2209                              tvb_get_ntohs (tvb, offset+8));
2210         proto_tree_add_text (tree, tvb, offset+10, 2, "Sectors Per Track: %u",
2211                              tvb_get_ntohs (tvb, offset+10));
2212         proto_tree_add_text (tree, tvb, offset+12, 2,
2213                              "Data Bytes Per Physical Sector: %u",
2214                              tvb_get_ntohs (tvb, offset+12));
2215         proto_tree_add_text (tree, tvb, offset+14, 2, "Interleave: %u",
2216                              tvb_get_ntohs (tvb, offset+14));
2217         proto_tree_add_text (tree, tvb, offset+16, 2, "Track Skew Factor: %u",
2218                              tvb_get_ntohs (tvb, offset+16));
2219         proto_tree_add_text (tree, tvb, offset+18, 2,
2220                              "Cylinder Skew Factor: %u",
2221                              tvb_get_ntohs (tvb, offset+18));
2222         flags = tvb_get_guint8 (tvb, offset+20);
2223         proto_tree_add_text (tree, tvb, offset+20, 1,
2224                              "SSEC: %u, HSEC: %u, RMB: %u, SURF: %u",
2225                              (flags & 0x80) >> 7, (flags & 0x40) >> 6,
2226                              (flags & 0x20) >> 5, (flags & 0x10) >> 4);
2227         break;
2228     case SCSI_SBC2_MODEPAGE_RDWRERR:
2229         flags = tvb_get_guint8 (tvb, offset+2);
2230         proto_tree_add_text (tree, tvb, offset+2, 1,
2231                              "AWRE: %u, ARRE: %u, TB: %u, RC: %u, EER: %u, PER: %u, DTE: %u, DCR: %u",
2232                              (flags & 0x80) >> 7, (flags & 0x40) >> 6,
2233                              (flags & 0x20) >> 5, (flags & 0x10) >> 4,
2234                              (flags & 0x08) >> 3, (flags & 0x04) >> 2,
2235                              (flags & 0x02) >> 1, (flags & 0x01));
2236         proto_tree_add_text (tree, tvb, offset+3, 1, "Read Retry Count: %u",
2237                              tvb_get_guint8 (tvb, offset+3));
2238         proto_tree_add_text (tree, tvb, offset+4, 1, "Correction Span: %u",
2239                              tvb_get_guint8 (tvb, offset+4));
2240         proto_tree_add_text (tree, tvb, offset+5, 1, "Head Offset Count: %u",
2241                              tvb_get_guint8 (tvb, offset+5));
2242         proto_tree_add_text (tree, tvb, offset+6, 1,
2243                              "Data Strobe Offset Count: %u",
2244                              tvb_get_guint8 (tvb, offset+6));
2245         proto_tree_add_text (tree, tvb, offset+8, 1, "Write Retry Count: %u",
2246                              tvb_get_guint8 (tvb, offset+8));
2247         proto_tree_add_text (tree, tvb, offset+10, 2,
2248                              "Recovery Time Limit: %u ms",
2249                              tvb_get_ntohs (tvb, offset+10));
2250         break;
2251    case SCSI_SBC2_MODEPAGE_DISKGEOM:
2252         proto_tree_add_text (tree, tvb, offset+2, 3, "Number of Cylinders: %u",
2253                              tvb_get_ntoh24 (tvb, offset+2));
2254         proto_tree_add_text (tree, tvb, offset+5, 1, "Number of Heads: %u",
2255                              tvb_get_guint8 (tvb, offset+5));
2256         proto_tree_add_text (tree, tvb, offset+6, 3,
2257                              "Starting Cyl Pre-compensation: %u",
2258                              tvb_get_ntoh24 (tvb, offset+6));
2259         proto_tree_add_text (tree, tvb, offset+9, 3,
2260                              "Starting Cyl-reduced Write Current: %u",
2261                              tvb_get_ntoh24 (tvb, offset+9));
2262         proto_tree_add_text (tree, tvb, offset+12, 2, "Device Step Rate: %u",
2263                              tvb_get_ntohs (tvb, offset+12));
2264         proto_tree_add_text (tree, tvb, offset+14, 3, "Landing Zone Cyl: %u",
2265                              tvb_get_ntoh24 (tvb, offset+14));
2266         proto_tree_add_text (tree, tvb, offset+18, 1, "Rotational Offset: %u",
2267                              tvb_get_guint8 (tvb, offset+18));
2268         proto_tree_add_text (tree, tvb, offset+20, 2,
2269                              "Medium Rotation Rate: %u",
2270                              tvb_get_ntohs (tvb, offset+20));
2271         break;
2272     case SCSI_SBC2_MODEPAGE_FLEXDISK:
2273         return FALSE;
2274     case SCSI_SBC2_MODEPAGE_VERERR:
2275         return FALSE;
2276     case SCSI_SBC2_MODEPAGE_CACHE:
2277         flags = tvb_get_guint8 (tvb, offset+2);
2278         proto_tree_add_text (tree, tvb, offset+2, 1,
2279                              "IC: %u, ABPF: %u, CAP %u, Disc: %u, Size: %u, WCE: %u, MF: %u, RCD: %u",
2280                              (flags & 0x80) >> 7, (flags & 0x40) >> 6,
2281                              (flags & 0x20) >> 5, (flags & 0x10) >> 4,
2282                              (flags & 0x08) >> 3, (flags & 0x04) >> 2,
2283                              (flags & 0x02) >> 1, (flags & 0x01));
2284         flags = tvb_get_guint8 (tvb, offset+3);
2285         proto_tree_add_text (tree, tvb, offset+3, 1,
2286                              "Demand Read Retention Priority: %u, Write Retention Priority: %u",
2287                              (flags & 0xF0) >> 4, (flags & 0x0F));
2288         proto_tree_add_text (tree, tvb, offset+4, 2,
2289                              "Disable Pre-fetch Xfer Len: %u",
2290                              tvb_get_ntohs (tvb, offset+4));
2291         proto_tree_add_text (tree, tvb, offset+6, 2, "Minimum Pre-Fetch: %u",
2292                              tvb_get_ntohs (tvb, offset+6));
2293         proto_tree_add_text (tree, tvb, offset+8, 2, "Maximum Pre-Fetch: %u",
2294                              tvb_get_ntohs (tvb, offset+8));
2295         proto_tree_add_text (tree, tvb, offset+10, 2,
2296                              "Maximum Pre-Fetch Ceiling: %u",
2297                              tvb_get_ntohs (tvb, offset+10));
2298         flags = tvb_get_guint8 (tvb, offset+12);
2299         proto_tree_add_text (tree, tvb, offset+12, 1,
2300                              "FSW: %u, LBCSS: %u, DRA: %u, Vendor Specific: %u",
2301                              (flags & 0x80) >> 7, (flags & 0x40) >> 6,
2302                              (flags & 0x20) >> 5, (flags & 0x1F) >> 4);
2303         proto_tree_add_text (tree, tvb, offset+13, 1,
2304                              "Number of Cache Segments: %u",
2305                              tvb_get_guint8 (tvb, offset+13));
2306         proto_tree_add_text (tree, tvb, offset+14, 2, "Cache Segment Size: %u",
2307                              tvb_get_ntohs (tvb, offset+14));
2308         proto_tree_add_text (tree, tvb, offset+17, 3,
2309                              "Non-Cache Segment Size: %u",
2310                              tvb_get_ntoh24 (tvb, offset+17));
2311         break;
2312     case SCSI_SBC2_MODEPAGE_MEDTYPE:
2313         return FALSE;
2314     case SCSI_SBC2_MODEPAGE_NOTPART:
2315         return FALSE;
2316     case SCSI_SBC2_MODEPAGE_XORCTL:
2317         return FALSE;
2318     default:
2319         return FALSE;
2320     }
2321     return TRUE;
2322 }
2323
2324 static const value_string compression_algorithm_vals[] = {
2325         {0x00, "No algorithm selected"},
2326         {0x01, "Default algorithm"},
2327         {0x03, "IBM ALDC with 512-byte buffer"},
2328         {0x04, "IBM ALDC with 1024-byte buffer"},
2329         {0x05, "IBM ALDC with 2048-byte buffer"},
2330         {0x10, "IBM IDRC"},
2331         {0x20, "DCLZ"},
2332         {0xFF, "Unregistered algorithm"},
2333         {0, NULL}
2334 };
2335
2336 static gboolean
2337 dissect_scsi_ssc2_modepage (tvbuff_t *tvb _U_, packet_info *pinfo _U_,
2338                             proto_tree *tree _U_, guint offset _U_,
2339                             guint8 pcode)
2340 {
2341     guint8 flags;
2342
2343     switch (pcode) {
2344     case SCSI_SSC2_MODEPAGE_DATACOMP:
2345         flags = tvb_get_guint8 (tvb, offset+2);
2346         proto_tree_add_text (tree, tvb, offset+2, 1,
2347                              "DCE: %u, DCC: %u",
2348                              (flags & 0x80) >> 7, (flags & 0x40) >> 6);
2349         flags = tvb_get_guint8 (tvb, offset+3);
2350         proto_tree_add_text (tree, tvb, offset+3, 1,
2351                              "DDE: %u, RED: %u",
2352                              (flags & 0x80) >> 7, (flags & 0x60) >> 5);
2353         proto_tree_add_text (tree, tvb, offset+4, 4,
2354                              "Compression algorithm: %s",
2355                              val_to_str (tvb_get_ntohl (tvb, offset+4),
2356                                          compression_algorithm_vals,
2357                                          "Unknown (0x%08x)"));
2358         proto_tree_add_text (tree, tvb, offset+8, 4,
2359                              "Decompression algorithm: %s",
2360                              val_to_str (tvb_get_ntohl (tvb, offset+4),
2361                                          compression_algorithm_vals,
2362                                          "Unknown (0x%08x)"));
2363         break;
2364     case SCSI_SSC2_MODEPAGE_DEVCONF:
2365         flags = tvb_get_guint8 (tvb, offset+2);
2366         proto_tree_add_text (tree, tvb, offset+2, 1,
2367                              "CAF: %u, Active Format: %u",
2368                              (flags & 0x20) >> 5, (flags & 0x1f));
2369         flags = tvb_get_guint8 (tvb, offset+3);
2370         proto_tree_add_text (tree, tvb, offset+3, 1,
2371                              "Active Partition: %u",
2372                              flags);
2373         flags = tvb_get_guint8 (tvb, offset+4);
2374         proto_tree_add_text (tree, tvb, offset+4, 1,
2375                              "Write Object Buffer Full Ratio: %u",
2376                              flags);
2377         flags = tvb_get_guint8 (tvb, offset+5);
2378         proto_tree_add_text (tree, tvb, offset+5, 1,
2379                              "Read Object Buffer Empty Ratio: %u",
2380                              flags);
2381         proto_tree_add_text (tree, tvb, offset+6, 2,
2382                              "Write Delay time: %u 100ms",
2383                              tvb_get_ntohs (tvb, offset+6));
2384         flags = tvb_get_guint8 (tvb, offset+8);
2385         proto_tree_add_text (tree, tvb, offset+8, 1,
2386                              "OBR: %u, LOIS: %u, RSMK: %u, AVC: %u, SOCF: %u, ROBO: %u, REW: %u",
2387                              (flags & 0x80) >> 7, (flags & 0x40) >> 6,
2388                              (flags & 0x20) >> 5, (flags & 0x10) >> 4,
2389                              (flags & 0x0c) >> 2, (flags & 0x02) >> 1,
2390                              (flags & 0x01));
2391         flags = tvb_get_guint8 (tvb, offset+9);
2392         proto_tree_add_text (tree, tvb, offset+9, 1,
2393                              "Gap Size: %u",
2394                              flags);
2395         flags = tvb_get_guint8 (tvb, offset+10);
2396         proto_tree_add_text (tree, tvb, offset+10, 1,
2397                              "EOD Defined: %u, EEG: %u, SEW: %u, SWP: %u, BAML: %u, BAM: %u",
2398                              (flags & 0xe0) >> 5, (flags & 0x10) >> 4,
2399                              (flags & 0x08) >> 3, (flags & 0x04) >> 2,
2400                              (flags & 0x02) >> 1, (flags & 0x01));
2401         proto_tree_add_text (tree, tvb, offset+11, 3,
2402                              "Object Buffer Size At Early Warning: %u",
2403                              tvb_get_ntohs (tvb, offset+11));
2404         flags = tvb_get_guint8 (tvb, offset+14);
2405         proto_tree_add_text (tree, tvb, offset+14, 1,
2406                              "Select Data Compression Algorithm: %u",
2407                              flags);
2408         flags = tvb_get_guint8 (tvb, offset+15);
2409         proto_tree_add_text (tree, tvb, offset+15, 1,
2410                              "OIR: %u, ReWind on Reset: %u, ASOCWP: %u, PERSWP: %u, PRMWP: %u",
2411                              (flags & 0x20) >> 5, (flags & 0x18) >> 3,
2412                              (flags & 0x04) >> 2, (flags & 0x02) >> 1,
2413                              (flags & 0x01));
2414         break;
2415     case SCSI_SSC2_MODEPAGE_MEDPAR1:
2416         return FALSE;
2417     case SCSI_SSC2_MODEPAGE_MEDPAR2:
2418         return FALSE;
2419     case SCSI_SSC2_MODEPAGE_MEDPAR3:
2420         return FALSE;
2421     case SCSI_SSC2_MODEPAGE_MEDPAR4:
2422         return FALSE;
2423     default:
2424         return FALSE;
2425     }
2426     return TRUE;
2427 }
2428
2429 static gboolean
2430 dissect_scsi_mmc5_modepage (tvbuff_t *tvb, packet_info *pinfo _U_,
2431                             proto_tree *tree, guint offset, guint8 pcode)
2432 {
2433     switch (pcode) {
2434     case SCSI_MMC3_MODEPAGE_MMCAP:
2435         break;
2436     default:
2437         return FALSE;
2438     }
2439     return TRUE;
2440 }
2441
2442 static gboolean
2443 dissect_scsi_smc2_modepage (tvbuff_t *tvb, packet_info *pinfo _U_,
2444                             proto_tree *tree, guint offset, guint8 pcode)
2445 {
2446     guint8 flags;
2447     guint8 param_list_len;
2448
2449     switch (pcode) {
2450     case SCSI_SMC2_MODEPAGE_EAA:
2451         param_list_len = tvb_get_guint8 (tvb, offset+2);
2452         proto_tree_add_text (tree, tvb, offset+2, 1, "Parameter List Length: %u",
2453                              param_list_len);
2454         if (param_list_len < 2)
2455             break;
2456         proto_tree_add_text (tree, tvb, offset+3, 2, "First Medium Transport Element Address: %u",
2457                              tvb_get_ntohs (tvb, offset+3));
2458         param_list_len -= 2;
2459         if (param_list_len < 2)
2460             break;
2461         proto_tree_add_text (tree, tvb, offset+5, 2, "Number of Medium Transport Elements: %u",
2462                              tvb_get_ntohs (tvb, offset+5));
2463         param_list_len -= 2;
2464         if (param_list_len < 2)
2465             break;
2466         proto_tree_add_text (tree, tvb, offset+7, 2, "First Storage Element Address: %u",
2467                              tvb_get_ntohs (tvb, offset+7));
2468         param_list_len -= 2;
2469         if (param_list_len < 2)
2470             break;
2471         proto_tree_add_text (tree, tvb, offset+9, 2, "Number of Storage Elements: %u",
2472                              tvb_get_ntohs (tvb, offset+9));
2473         param_list_len -= 2;
2474         if (param_list_len < 2)
2475             break;
2476         proto_tree_add_text (tree, tvb, offset+11, 2, "First Import/Export Element Address: %u",
2477                              tvb_get_ntohs (tvb, offset+11));
2478         param_list_len -= 2;
2479         if (param_list_len < 2)
2480             break;
2481         proto_tree_add_text (tree, tvb, offset+13, 2, "Number of Import/Export Elements: %u",
2482                              tvb_get_ntohs (tvb, offset+13));
2483         param_list_len -= 2;
2484         if (param_list_len < 2)
2485             break;
2486         proto_tree_add_text (tree, tvb, offset+15, 2, "First Data Transfer Element Address: %u",
2487                              tvb_get_ntohs (tvb, offset+15));
2488         param_list_len -= 2;
2489         if (param_list_len < 2)
2490             break;
2491         proto_tree_add_text (tree, tvb, offset+17, 2, "Number of Data Transfer Elements: %u",
2492                              tvb_get_ntohs (tvb, offset+17));
2493         break;
2494     case SCSI_SMC2_MODEPAGE_TRANGEOM:
2495         return FALSE;
2496     case SCSI_SMC2_MODEPAGE_DEVCAP:
2497         flags = tvb_get_guint8 (tvb, offset+2);
2498         proto_tree_add_text (tree, tvb, offset+2, 1,
2499                              "STORDT: %u, STORI/E: %u, STORST: %u, STORMT: %u",
2500                              (flags & 0x08) >> 3, (flags & 0x04) >> 2,
2501                              (flags & 0x02) >> 1, (flags & 0x01));
2502         flags = tvb_get_guint8 (tvb, offset+4);
2503         proto_tree_add_text (tree, tvb, offset+4, 1,
2504                              "MT->DT: %u, MT->I/E: %u, MT->ST: %u, MT->MT: %u",
2505                              (flags & 0x08) >> 3, (flags & 0x04) >> 2,
2506                              (flags & 0x02) >> 1, (flags & 0x01));
2507         flags = tvb_get_guint8 (tvb, offset+5);
2508         proto_tree_add_text (tree, tvb, offset+5, 1,
2509                              "ST->DT: %u, ST->I/E: %u, ST->ST: %u, ST->MT: %u",
2510                              (flags & 0x08) >> 3, (flags & 0x04) >> 2,
2511                              (flags & 0x02) >> 1, (flags & 0x01));
2512         flags = tvb_get_guint8 (tvb, offset+6);
2513         proto_tree_add_text (tree, tvb, offset+6, 1,
2514                              "I/E->DT: %u, I/E->I/E: %u, I/E->ST: %u, I/E->MT: %u",
2515                              (flags & 0x08) >> 3, (flags & 0x04) >> 2,
2516                              (flags & 0x02) >> 1, (flags & 0x01));
2517         flags = tvb_get_guint8 (tvb, offset+7);
2518         proto_tree_add_text (tree, tvb, offset+7, 1,
2519                              "DT->DT: %u, DT->I/E: %u, DT->ST: %u, DT->MT: %u",
2520                              (flags & 0x08) >> 3, (flags & 0x04) >> 2,
2521                              (flags & 0x02) >> 1, (flags & 0x01));
2522         flags = tvb_get_guint8 (tvb, offset+12);
2523         proto_tree_add_text (tree, tvb, offset+12, 1,
2524                              "MT<>DT: %u, MT<>I/E: %u, MT<>ST: %u, MT<>MT: %u",
2525                              (flags & 0x08) >> 3, (flags & 0x04) >> 2,
2526                              (flags & 0x02) >> 1, (flags & 0x01));
2527         flags = tvb_get_guint8 (tvb, offset+13);
2528         proto_tree_add_text (tree, tvb, offset+13, 1,
2529                              "ST<>DT: %u, ST<>I/E: %u, ST<>ST: %u, ST<>MT: %u",
2530                              (flags & 0x08) >> 3, (flags & 0x04) >> 2,
2531                              (flags & 0x02) >> 1, (flags & 0x01));
2532         flags = tvb_get_guint8 (tvb, offset+14);
2533         proto_tree_add_text (tree, tvb, offset+14, 1,
2534                              "I/E<>DT: %u, I/E<>I/E: %u, I/E<>ST: %u, I/E<>MT: %u",
2535                              (flags & 0x08) >> 3, (flags & 0x04) >> 2,
2536                              (flags & 0x02) >> 1, (flags & 0x01));
2537         flags = tvb_get_guint8 (tvb, offset+15);
2538         proto_tree_add_text (tree, tvb, offset+15, 1,
2539                              "DT<>DT: %u, DT<>I/E: %u, DT<>ST: %u, DT<>MT: %u",
2540                              (flags & 0x08) >> 3, (flags & 0x04) >> 2,
2541                              (flags & 0x02) >> 1, (flags & 0x01));
2542         break;
2543     default:
2544         return FALSE;
2545     }
2546     return TRUE;
2547 }
2548
2549 static guint
2550 dissect_scsi_modepage (tvbuff_t *tvb, packet_info *pinfo,
2551                        proto_tree *scsi_tree, guint offset,
2552                        scsi_device_type devtype)
2553 {
2554     guint8 pcode, plen;
2555     proto_tree *tree;
2556     proto_item *ti;
2557     const value_string *modepage_val;
2558     int hf_pagecode;
2559     gboolean (*dissect_modepage)(tvbuff_t *, packet_info *, proto_tree *,
2560                                  guint, guint8);
2561
2562     pcode = tvb_get_guint8 (tvb, offset);
2563     plen = tvb_get_guint8 (tvb, offset+1);
2564
2565     if (match_strval (pcode & SCSI_MS_PCODE_BITS,
2566                       scsi_spc2_modepage_val) == NULL) {
2567         /*
2568          * This isn't a generic mode page that applies to all SCSI
2569          * device types; try to interpret it based on what we deduced,
2570          * or were told, the device type is.
2571          */
2572         switch (devtype) {
2573         case SCSI_DEV_SBC:
2574             modepage_val = scsi_sbc2_modepage_val;
2575             hf_pagecode = hf_scsi_sbcpagecode;
2576             dissect_modepage = dissect_scsi_sbc2_modepage;
2577             break;
2578
2579         case SCSI_DEV_SSC:
2580             modepage_val = scsi_ssc2_modepage_val;
2581             hf_pagecode = hf_scsi_sscpagecode;
2582             dissect_modepage = dissect_scsi_ssc2_modepage;
2583             break;
2584
2585         case SCSI_DEV_SMC:
2586             modepage_val = scsi_smc2_modepage_val;
2587             hf_pagecode = hf_scsi_smcpagecode;
2588             dissect_modepage = dissect_scsi_smc2_modepage;
2589             break;
2590
2591         case SCSI_DEV_CDROM:
2592             modepage_val = scsi_mmc5_modepage_val;
2593             hf_pagecode = hf_scsi_mmcpagecode;
2594             dissect_modepage = dissect_scsi_mmc5_modepage;
2595             break;
2596
2597         default:
2598             /*
2599              * The "val_to_str()" lookup will fail in this table
2600              * (it failed in "match_strval()"), so it'll return
2601              * "Unknown (XXX)", which is what we want.
2602              */
2603             modepage_val = scsi_spc2_modepage_val;
2604             hf_pagecode = hf_scsi_spcpagecode;
2605             dissect_modepage = dissect_scsi_spc2_modepage;
2606             break;
2607         }
2608     } else {
2609         modepage_val = scsi_spc2_modepage_val;
2610         hf_pagecode = hf_scsi_spcpagecode;
2611         dissect_modepage = dissect_scsi_spc2_modepage;
2612     }
2613     ti = proto_tree_add_text (scsi_tree, tvb, offset, plen+2, "%s Mode Page",
2614                               val_to_str (pcode & SCSI_MS_PCODE_BITS,
2615                                           modepage_val, "Unknown (0x%08x)"));
2616     tree = proto_item_add_subtree (ti, ett_scsi_page);
2617     proto_tree_add_text (tree, tvb, offset, 1, "PS: %u", (pcode & 0x80) >> 7);
2618
2619     proto_tree_add_item (tree, hf_pagecode, tvb, offset, 1, 0);
2620     proto_tree_add_text (tree, tvb, offset+1, 1, "Page Length: %u",
2621                          plen);
2622
2623     if (!tvb_bytes_exist (tvb, offset, plen)) {
2624         /* XXX - why not just drive on and throw an exception? */
2625         return (plen + 2);
2626     }
2627
2628     if (!(*dissect_modepage)(tvb, pinfo, tree, offset,
2629                              (guint8) (pcode & SCSI_MS_PCODE_BITS))) {
2630         proto_tree_add_text (tree, tvb, offset+2, plen,
2631                              "Unknown Page");
2632     }
2633     return (plen+2);
2634 }
2635
2636 static void
2637 dissect_spc3_modeselect6 (tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree,
2638                           guint offset, gboolean isreq, gboolean iscdb,
2639                           guint payload_len, scsi_task_data_t *cdata)
2640 {
2641     guint8 flags;
2642     guint plen;
2643     gint tot_len, desclen;
2644     tvbuff_t *blockdesc_tvb;
2645
2646     if (!tree)
2647         return;
2648
2649     if (isreq && iscdb) {
2650         flags = tvb_get_guint8 (tvb, offset);
2651
2652         proto_tree_add_uint_format (tree, hf_scsi_modesel_flags, tvb, offset, 1,
2653                                     flags, "PF = %u, SP = %u", flags & 0x10,
2654                                     flags & 0x1);
2655         proto_tree_add_item (tree, hf_scsi_paramlen, tvb, offset+3, 1, 0);
2656
2657         flags = tvb_get_guint8 (tvb, offset+4);
2658         proto_tree_add_uint_format (tree, hf_scsi_control, tvb, offset+4, 1,
2659                                     flags,
2660                                     "Vendor Unique = %u, NACA = %u, Link = %u",
2661                                     flags & 0xC0, flags & 0x4, flags & 0x1);
2662     }
2663     else {
2664         /* Mode Parameter has the following format:
2665          * Mode Parameter Header
2666          *    - Mode Data Len, Medium Type, Dev Specific Parameter,
2667          *      Blk Desc Len
2668          * Block Descriptor (s)
2669          *    - Number of blocks, density code, block length
2670          * Page (s)
2671          *    - Page code, Page length, Page Parameters
2672          */
2673         if (payload_len < 1)
2674             return;
2675         tot_len = tvb_get_guint8 (tvb, offset);
2676         proto_tree_add_text (tree, tvb, offset, 1, "Mode Data Length: %d",
2677                              tot_len);
2678         offset += 1;
2679         payload_len -= 1;
2680         /* The mode data length is reserved for MODE SELECT, so we just
2681            use the payload length. */
2682
2683         if (payload_len < 1)
2684             return;
2685         switch (cdata->devtype) {
2686
2687         case SCSI_DEV_SBC:
2688             proto_tree_add_text (tree, tvb, offset, 1, "Medium Type: %s",
2689                                  val_to_str(tvb_get_guint8 (tvb, offset),
2690                                             scsi_modesense_medtype_sbc_val,
2691                                             "Unknown (0x%02x)"));
2692             break;
2693
2694         default:
2695             proto_tree_add_text (tree, tvb, offset, 1, "Medium Type: 0x%02x",
2696                                  tvb_get_guint8 (tvb, offset));
2697             break;
2698         }
2699         offset += 1;
2700         payload_len -= 1;
2701
2702         if (payload_len < 1)
2703             return;
2704         proto_tree_add_text (tree, tvb, offset, 1,
2705                              "Device-Specific Parameter: 0x%02x",
2706                              tvb_get_guint8 (tvb, offset));
2707         offset += 1;
2708         payload_len -= 1;
2709
2710         if (payload_len < 1)
2711             return;
2712         desclen = tvb_get_guint8 (tvb, offset);
2713         proto_tree_add_text (tree, tvb, offset, 1,
2714                              "Block Descriptor Length: %d", desclen);
2715         offset += 1;
2716         payload_len -= 1;
2717
2718         if(tvb_length_remaining(tvb, offset)>0){
2719             blockdesc_tvb=tvb_new_subset(tvb, offset, MIN(tvb_length_remaining(tvb, offset),desclen), desclen);
2720             dissect_scsi_blockdescs (blockdesc_tvb, pinfo, tree, cdata, FALSE);
2721         }
2722         offset += desclen;
2723         payload_len -= desclen;
2724
2725         /* offset points to the start of the mode page */
2726         while ((payload_len > 0) && tvb_bytes_exist (tvb, offset, 2)) {
2727             plen = dissect_scsi_modepage (tvb, pinfo, tree, offset, cdata->devtype);
2728             offset += plen;
2729             payload_len -= plen;
2730         }
2731     }
2732 }
2733
2734 static void
2735 dissect_spc3_modeselect10 (tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree,
2736                            guint offset, gboolean isreq, gboolean iscdb,
2737                            guint payload_len, scsi_task_data_t *cdata)
2738 {
2739     guint8 flags;
2740     gboolean longlba;
2741     gint tot_len, desclen;
2742     guint plen;
2743     tvbuff_t *blockdesc_tvb;
2744
2745     if (!tree)
2746         return;
2747
2748     if (isreq && iscdb) {
2749         flags = tvb_get_guint8 (tvb, offset);
2750
2751         proto_tree_add_uint_format (tree, hf_scsi_modesel_flags, tvb, offset, 1,
2752                                     flags, "PF = %u, SP = %u", flags & 0x10,
2753                                     flags & 0x1);
2754         proto_tree_add_item (tree, hf_scsi_paramlen16, tvb, offset+6, 2, 0);
2755
2756         flags = tvb_get_guint8 (tvb, offset+8);
2757         proto_tree_add_uint_format (tree, hf_scsi_control, tvb, offset+8, 1,
2758                                     flags,
2759                                     "Vendor Unique = %u, NACA = %u, Link = %u",
2760                                     flags & 0xC0, flags & 0x4, flags & 0x1);
2761     }
2762     else {
2763         /* Mode Parameter has the following format:
2764          * Mode Parameter Header
2765          *    - Mode Data Len, Medium Type, Dev Specific Parameter,
2766          *      Blk Desc Len
2767          * Block Descriptor (s)
2768          *    - Number of blocks, density code, block length
2769          * Page (s)
2770          *    - Page code, Page length, Page Parameters
2771          */
2772         if (payload_len < 1)
2773             return;
2774         tot_len = tvb_get_ntohs (tvb, offset);
2775         proto_tree_add_text (tree, tvb, offset, 2, "Mode Data Length: %u",
2776                              tot_len);
2777         offset += 2;
2778         payload_len -= 2;
2779         /* The mode data length is reserved for MODE SELECT, so we just
2780            use the payload length. */
2781
2782         if (payload_len < 1)
2783             return;
2784         switch (cdata->devtype) {
2785
2786         case SCSI_DEV_SBC:
2787             proto_tree_add_text (tree, tvb, offset, 1, "Medium Type: %s",
2788                                  val_to_str(tvb_get_guint8 (tvb, offset),
2789                                             scsi_modesense_medtype_sbc_val,
2790                                             "Unknown (0x%02x)"));
2791             break;
2792
2793         default:
2794             proto_tree_add_text (tree, tvb, offset, 1, "Medium Type: 0x%02x",
2795                                  tvb_get_guint8 (tvb, offset));
2796             break;
2797         }
2798         offset += 1;
2799         payload_len -= 1;
2800
2801         if (payload_len < 1)
2802             return;
2803         proto_tree_add_text (tree, tvb, offset, 1,
2804                              "Device-Specific Parameter: 0x%02x",
2805                              tvb_get_guint8 (tvb, offset));
2806         offset += 1;
2807         payload_len -= 1;
2808
2809         if (payload_len < 1)
2810             return;
2811         longlba = tvb_get_guint8 (tvb, offset) & 0x1;
2812         proto_tree_add_text (tree, tvb, offset, 1, "LongLBA: %u", longlba);
2813         offset += 2;    /* skip LongLBA byte and reserved byte */
2814         payload_len -= 2;
2815
2816         if (payload_len < 1)
2817             return;
2818         desclen = tvb_get_guint8 (tvb, offset);
2819         proto_tree_add_text (tree, tvb, offset, 1,
2820                              "Block Descriptor Length: %u", desclen);
2821         offset += 2;
2822         payload_len -= 2;
2823
2824         if(tvb_length_remaining(tvb, offset)>0){
2825             blockdesc_tvb=tvb_new_subset(tvb, offset, MIN(tvb_length_remaining(tvb, offset),desclen), desclen);
2826             dissect_scsi_blockdescs (blockdesc_tvb, pinfo, tree, cdata, longlba);
2827         }
2828         offset += desclen;
2829         payload_len -= desclen;
2830
2831         /* offset points to the start of the mode page */
2832         while ((payload_len > 0) && tvb_bytes_exist (tvb, offset, 2)) {
2833             plen = dissect_scsi_modepage (tvb, pinfo, tree, offset, cdata->devtype);
2834             offset += plen;
2835             payload_len -= plen;
2836         }
2837     }
2838 }
2839
2840 static void
2841 dissect_scsi_pagecode (tvbuff_t *tvb, packet_info *pinfo _U_,
2842                        proto_tree *tree, guint offset,
2843                        scsi_task_data_t *cdata)
2844 {
2845     guint8 pcode;
2846     const gchar *valstr;
2847     int hf_pagecode;
2848
2849     /* unless we have cdata there is not much point in continuing */
2850     if (!cdata)
2851         return;
2852
2853     pcode = tvb_get_guint8 (tvb, offset);
2854     if ((valstr = match_strval (pcode & SCSI_MS_PCODE_BITS,
2855                                 scsi_spc2_modepage_val)) == NULL) {
2856         /*
2857          * This isn't a generic mode page that applies to all SCSI
2858          * device types; try to interpret it based on what we deduced,
2859          * or were told, the device type is.
2860          */
2861         switch (cdata->devtype) {
2862         case SCSI_DEV_SBC:
2863             hf_pagecode = hf_scsi_sbcpagecode;
2864             break;
2865
2866         case SCSI_DEV_SSC:
2867             hf_pagecode = hf_scsi_sscpagecode;
2868             break;
2869
2870         case SCSI_DEV_SMC:
2871             hf_pagecode = hf_scsi_smcpagecode;
2872             break;
2873
2874         case SCSI_DEV_CDROM:
2875             hf_pagecode = hf_scsi_mmcpagecode;
2876             break;
2877
2878         default:
2879             hf_pagecode = hf_scsi_spcpagecode;
2880             break;
2881         }
2882     } else {
2883         hf_pagecode = hf_scsi_spcpagecode;
2884     }
2885     proto_tree_add_uint (tree, hf_pagecode, tvb, offset, 1, pcode);
2886 }
2887
2888 static void
2889 dissect_spc3_modesense6 (tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree,
2890                          guint offset, gboolean isreq, gboolean iscdb,
2891                          guint payload_len, scsi_task_data_t *cdata)
2892 {
2893     guint8 flags;
2894     guint plen;
2895     gint tot_len, desclen;
2896     tvbuff_t *blockdesc_tvb;
2897
2898     if (!tree)
2899         return;
2900
2901     if (isreq && iscdb) {
2902         flags = tvb_get_guint8 (tvb, offset);
2903
2904         proto_tree_add_uint_format (tree, hf_scsi_modesns_flags, tvb, offset, 1,
2905                                     flags, "DBD = %u", flags & 0x8);
2906         proto_tree_add_item (tree, hf_scsi_modesns_pc, tvb, offset+1, 1, 0);
2907         dissect_scsi_pagecode (tvb, pinfo, tree, offset+1, cdata);
2908         proto_tree_add_item (tree, hf_scsi_alloclen, tvb, offset+3, 1, 0);
2909
2910         flags = tvb_get_guint8 (tvb, offset+4);
2911         proto_tree_add_uint_format (tree, hf_scsi_control, tvb, offset+4, 1,
2912                                     flags,
2913                                     "Vendor Unique = %u, NACA = %u, Link = %u",
2914                                     flags & 0xC0, flags & 0x4, flags & 0x1);
2915     }
2916     else {
2917         /* Mode sense response has the following format:
2918          * Mode Parameter Header
2919          *    - Mode Data Len, Medium Type, Dev Specific Parameter,
2920          *      Blk Desc Len
2921          * Block Descriptor (s)
2922          *    - Number of blocks, density code, block length
2923          * Page (s)
2924          *    - Page code, Page length, Page Parameters
2925          */
2926         tot_len = tvb_get_guint8 (tvb, offset);
2927         proto_tree_add_text (tree, tvb, offset, 1, "Mode Data Length: %u",
2928                              tot_len);
2929         offset += 1;
2930
2931         /* The actual payload is the min of the length in the response & the
2932          * space allocated by the initiator as specified in the request.
2933          *
2934          * XXX - the payload length includes the length field, so we
2935          * really should subtract the length of the length field from
2936          * the payload length - but can it really be zero here?
2937          */
2938         if (payload_len && (tot_len > (gint)payload_len))
2939             tot_len = payload_len;
2940
2941         if (tot_len < 1)
2942             return;
2943         proto_tree_add_text (tree, tvb, offset, 1, "Medium Type: 0x%02x",
2944                              tvb_get_guint8 (tvb, offset));
2945         offset += 1;
2946         tot_len -= 1;
2947
2948         if (tot_len < 1)
2949             return;
2950         proto_tree_add_text (tree, tvb, offset, 1,
2951                              "Device-Specific Parameter: 0x%02x",
2952                              tvb_get_guint8 (tvb, offset));
2953         offset += 1;
2954         tot_len -= 1;
2955
2956         if (tot_len < 1)
2957             return;
2958         desclen = tvb_get_guint8 (tvb, offset);
2959         proto_tree_add_text (tree, tvb, offset, 1,
2960                              "Block Descriptor Length: %d", desclen);
2961         offset += 1;
2962         tot_len -= 1;
2963
2964
2965         if(tvb_length_remaining(tvb, offset)>0){
2966             blockdesc_tvb=tvb_new_subset(tvb, offset, MIN(tvb_length_remaining(tvb, offset),desclen), desclen);
2967             dissect_scsi_blockdescs (blockdesc_tvb, pinfo, tree, cdata, FALSE);
2968         }
2969         offset += desclen;
2970         tot_len -= desclen;
2971
2972         /* offset points to the start of the mode page */
2973         while ((tot_len > 0) && tvb_bytes_exist (tvb, offset, 2)) {
2974             plen = dissect_scsi_modepage (tvb, pinfo, tree, offset, cdata->devtype);
2975             offset += plen;
2976             tot_len -= plen;
2977         }
2978     }
2979 }
2980
2981 static void
2982 dissect_spc3_modesense10 (tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree,
2983                           guint offset, gboolean isreq, gboolean iscdb,
2984                           guint payload_len, scsi_task_data_t *cdata)
2985 {
2986     guint8 flags;
2987     gboolean longlba;
2988     gint tot_len, desclen;
2989     guint plen;
2990     tvbuff_t *blockdesc_tvb;
2991
2992     if (!tree)
2993         return;
2994
2995     if (isreq && iscdb) {
2996         flags = tvb_get_guint8 (tvb, offset);
2997
2998         proto_tree_add_uint_format (tree, hf_scsi_modesns_flags, tvb, offset, 1,
2999                                     flags, "LLBAA = %u, DBD = %u", flags & 0x10,
3000                                     flags & 0x8);
3001         proto_tree_add_item (tree, hf_scsi_modesns_pc, tvb, offset+1, 1, 0);
3002         dissect_scsi_pagecode (tvb, pinfo, tree, offset+1, cdata);
3003         proto_tree_add_item (tree, hf_scsi_alloclen16, tvb, offset+6, 2, 0);
3004
3005         flags = tvb_get_guint8 (tvb, offset+8);
3006         proto_tree_add_uint_format (tree, hf_scsi_control, tvb, offset+8, 1,
3007                                     flags,
3008                                     "Vendor Unique = %u, NACA = %u, Link = %u",
3009                                     flags & 0xC0, flags & 0x4, flags & 0x1);
3010     }
3011     else {
3012         /* Mode sense response has the following format:
3013          * Mode Parameter Header
3014          *    - Mode Data Len, Medium Type, Dev Specific Parameter,
3015          *      Blk Desc Len
3016          * Block Descriptor (s)
3017          *    - Number of blocks, density code, block length
3018          * Page (s)
3019          *    - Page code, Page length, Page Parameters
3020          */
3021         tot_len = tvb_get_ntohs (tvb, offset);
3022         proto_tree_add_text (tree, tvb, offset, 2, "Mode Data Length: %u",
3023                              tot_len);
3024         offset += 2;
3025         /* The actual payload is the min of the length in the response & the
3026          * space allocated by the initiator as specified in the request.
3027          *
3028          * XXX - the payload length includes the length field, so we
3029          * really should subtract the length of the length field from
3030          * the payload length - but can it really be zero here?
3031          */
3032         if (payload_len && (tot_len > (gint)payload_len))
3033             tot_len = payload_len;
3034
3035         if (tot_len < 1)
3036             return;
3037         proto_tree_add_text (tree, tvb, offset, 1, "Medium Type: 0x%02x",
3038                              tvb_get_guint8 (tvb, offset));
3039         offset += 1;
3040         tot_len -= 1;
3041
3042         if (tot_len < 1)
3043             return;
3044         proto_tree_add_text (tree, tvb, offset, 1,
3045                              "Device-Specific Parameter: 0x%02x",
3046                              tvb_get_guint8 (tvb, offset));
3047         offset += 1;
3048         tot_len -= 1;
3049
3050         if (tot_len < 1)
3051             return;
3052         longlba = tvb_get_guint8 (tvb, offset) & 0x1;
3053         proto_tree_add_text (tree, tvb, offset, 1, "LongLBA: %u", longlba);
3054         offset += 2;    /* skip LongLBA byte and reserved byte */
3055         tot_len -= 2;
3056
3057         if (tot_len < 1)
3058             return;
3059         desclen = tvb_get_guint8 (tvb, offset);
3060         proto_tree_add_text (tree, tvb, offset, 1,
3061                              "Block Descriptor Length: %u", desclen);
3062         offset += 2;
3063         tot_len -= 2;
3064
3065         if(tvb_length_remaining(tvb, offset)>0){
3066             blockdesc_tvb=tvb_new_subset(tvb, offset, MIN(tvb_length_remaining(tvb, offset),desclen), desclen);
3067             dissect_scsi_blockdescs (blockdesc_tvb, pinfo, tree, cdata, longlba);
3068         }
3069         offset += desclen;
3070         tot_len -= desclen;
3071
3072         /* offset points to the start of the mode page */
3073         while ((tot_len > 0) && tvb_bytes_exist (tvb, offset, 2)) {
3074             plen = dissect_scsi_modepage (tvb, pinfo, tree, offset, cdata->devtype);
3075             offset += plen;
3076             tot_len -= plen;
3077         }
3078     }
3079 }
3080
3081 static void
3082 dissect_spc3_persistentreservein (tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *tree,
3083                          guint offset, gboolean isreq, gboolean iscdb,
3084                          guint payload_len, scsi_task_data_t *cdata)
3085 {
3086     guint16 flags;
3087     int numrec, i;
3088     guint len;
3089
3090     if (!tree)
3091         return;
3092
3093     if (isreq && iscdb) {
3094         proto_tree_add_item (tree, hf_scsi_persresvin_svcaction, tvb, offset+1,
3095                              1, 0);
3096         proto_tree_add_item (tree, hf_scsi_alloclen16, tvb, offset+6, 2, 0);
3097
3098         flags = tvb_get_guint8 (tvb, offset+8);
3099         proto_tree_add_uint_format (tree, hf_scsi_control, tvb, offset+8, 1,
3100                                     flags,
3101                                     "Vendor Unique = %u, NACA = %u, Link = %u",
3102                                     flags & 0xC0, flags & 0x4, flags & 0x1);
3103         /* We store the service action since we want to interpret the data */
3104         cdata->flags = tvb_get_guint8 (tvb, offset+1);
3105     }
3106     else {
3107         if (cdata) {
3108             flags = cdata->flags;
3109         }
3110         else {
3111             flags = 0xFF;
3112         }
3113         proto_tree_add_text (tree, tvb, offset, 4, "Generation Number: 0x%08x",
3114                              tvb_get_ntohl (tvb, offset));
3115         len = tvb_get_ntohl (tvb, offset+4);
3116         proto_tree_add_text (tree, tvb, offset, 4, "Additional Length: %u",
3117                              len);
3118         len = (payload_len > len) ? len : payload_len;
3119
3120         if ((flags & 0x1F) == SCSI_SPC2_RESVIN_SVCA_RDKEYS) {
3121             /* XXX - what if len is < 8?  That may be illegal, but
3122                that doesn't make it impossible.... */
3123             numrec = (len - 8)/8;
3124             offset += 8;
3125
3126             for (i = 0; i < numrec; i++) {
3127                 proto_tree_add_item (tree, hf_scsi_persresv_key, tvb, offset,
3128                                      8, 0);
3129                 offset -= 8;
3130             }
3131         }
3132         else if ((flags & 0x1F) == SCSI_SPC2_RESVIN_SVCA_RDRESV) {
3133             proto_tree_add_item (tree, hf_scsi_persresv_key, tvb, offset+8,
3134                                  8, 0);
3135             proto_tree_add_item (tree, hf_scsi_persresv_scopeaddr, tvb,
3136                                  offset+8, 4, 0);
3137             proto_tree_add_item (tree, hf_scsi_persresv_scope, tvb, offset+13,
3138                                  1, 0);
3139             proto_tree_add_item (tree, hf_scsi_persresv_type, tvb, offset+13,
3140                                  1, 0);
3141         }
3142     }
3143 }
3144
3145 static void
3146 dissect_spc3_persistentreserveout (tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *tree,
3147                           guint offset, gboolean isreq, gboolean iscdb,
3148                           guint payload_len _U_, scsi_task_data_t *cdata _U_)
3149 {
3150     guint8 flags;
3151
3152     if (!tree)
3153         return;
3154
3155     if (isreq && iscdb) {
3156         proto_tree_add_item (tree, hf_scsi_persresvin_svcaction, tvb, offset,
3157                              1, 0);
3158         proto_tree_add_item (tree, hf_scsi_persresv_scope, tvb, offset+1, 1, 0);
3159         proto_tree_add_item (tree, hf_scsi_persresv_type, tvb, offset+1, 1, 0);
3160         proto_tree_add_item (tree, hf_scsi_paramlen16, tvb, offset+6, 2, 0);
3161
3162         flags = tvb_get_guint8 (tvb, offset+8);
3163         proto_tree_add_uint_format (tree, hf_scsi_control, tvb, offset+8, 1,
3164                                     flags,
3165                                     "Vendor Unique = %u, NACA = %u, Link = %u",
3166                                     flags & 0xC0, flags & 0x4, flags & 0x1);
3167     }
3168     else {
3169     }
3170 }
3171
3172 static void
3173 dissect_spc2_release6 (tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *tree,
3174                        guint offset, gboolean isreq, gboolean iscdb,
3175                        guint payload_len _U_, scsi_task_data_t *cdata _U_)
3176 {
3177     guint8 flags;
3178
3179     if (!tree)
3180         return;
3181
3182     if (isreq && iscdb) {
3183         flags = tvb_get_guint8 (tvb, offset+4);
3184         proto_tree_add_uint_format (tree, hf_scsi_control, tvb, offset+4, 1,
3185                                     flags,
3186                                     "Vendor Unique = %u, NACA = %u, Link = %u",
3187                                     flags & 0xC0, flags & 0x4, flags & 0x1);
3188     }
3189 }
3190
3191 static void
3192 dissect_spc2_release10 (tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *tree,
3193                         guint offset, gboolean isreq, gboolean iscdb,
3194                         guint payload_len _U_, scsi_task_data_t *cdata _U_)
3195 {
3196     guint8 flags;
3197
3198     if (!tree)
3199         return;
3200
3201     if (isreq && iscdb) {
3202         flags = tvb_get_guint8 (tvb, offset);
3203
3204         proto_tree_add_uint_format (tree, hf_scsi_release_flags, tvb, offset, 1,
3205                                     flags,
3206                                     "Flags: 3rd Party ID = %u, LongID = %u",
3207                                     flags & 0x10, flags & 0x2);
3208         if ((flags & 0x12) == 0x10) {
3209             proto_tree_add_item (tree, hf_scsi_release_thirdpartyid, tvb,
3210                                  offset+2, 1, 0);
3211         }
3212         proto_tree_add_item (tree, hf_scsi_paramlen16, tvb, offset+6, 2, 0);
3213
3214         flags = tvb_get_guint8 (tvb, offset+8);
3215         proto_tree_add_uint_format (tree, hf_scsi_control, tvb, offset+8, 1,
3216                                     flags,
3217                                     "Vendor Unique = %u, NACA = %u, Link = %u",
3218                                     flags & 0xC0, flags & 0x4, flags & 0x1);
3219     }
3220 }
3221
3222 static void
3223 dissect_spc3_reportdeviceidentifier (tvbuff_t *tvb _U_, packet_info *pinfo _U_,
3224 proto_tree *tree _U_,
3225                   guint offset _U_, gboolean isreq _U_, gboolean iscdb _U_,
3226                   guint payload_len _U_, scsi_task_data_t *cdata _U_)
3227 {
3228
3229 }
3230
3231 static void
3232 dissect_spc3_reportluns (tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *tree,
3233                          guint offset, gboolean isreq, gboolean iscdb,
3234                          guint payload_len, scsi_task_data_t *cdata _U_)
3235 {
3236     guint8 flags;
3237     guint listlen, i;
3238
3239     if (!tree)
3240         return;
3241
3242     if (isreq && iscdb) {
3243         proto_tree_add_item (tree, hf_scsi_select_report, tvb, offset+1, 1, 0);
3244
3245         proto_tree_add_item (tree, hf_scsi_alloclen32, tvb, offset+5, 4, 0);
3246
3247         flags = tvb_get_guint8 (tvb, offset+10);
3248         proto_tree_add_uint_format (tree, hf_scsi_control, tvb, offset+10, 1,
3249                                     flags,
3250                                     "Vendor Unique = %u, NACA = %u, Link = %u",
3251                                     flags & 0xC0, flags & 0x4, flags & 0x1);
3252     }
3253     else if (!isreq) {
3254         listlen = tvb_get_ntohl (tvb, offset);
3255         proto_tree_add_text (tree, tvb, offset, 4, "LUN List Length: %u",
3256                              listlen);
3257         offset += 8;
3258         payload_len -= 8;
3259         if (payload_len != 0) {
3260             listlen = (listlen < payload_len) ? listlen : payload_len;
3261         }
3262
3263         for (i = 0; i < listlen/8; i++) {
3264             if (!tvb_get_guint8 (tvb, offset))
3265                 proto_tree_add_item (tree, hf_scsi_rluns_lun, tvb, offset+1, 1,
3266                                      0);
3267             else
3268                 proto_tree_add_item (tree, hf_scsi_rluns_multilun, tvb, offset,
3269                                      8, 0);
3270             offset += 8;
3271         }
3272     }
3273 }
3274
3275 static void
3276 dissect_scsi_fix_snsinfo (tvbuff_t *tvb, proto_tree *sns_tree, guint offset)
3277 {
3278     guint8 flags;
3279
3280     flags = tvb_get_guint8 (tvb, offset);
3281     proto_tree_add_text (sns_tree, tvb, offset, 1, "Valid: %u",
3282                          (flags & 0x80) >> 7);
3283     proto_tree_add_item (sns_tree, hf_scsi_sns_errtype, tvb, offset, 1, 0);
3284     flags = tvb_get_guint8 (tvb, offset+2);
3285     proto_tree_add_text (sns_tree, tvb, offset+2, 1,
3286                              "Filemark: %u, EOM: %u, ILI: %u",
3287                              (flags & 0x80) >> 7, (flags & 0x40) >> 6,
3288                              (flags & 0x20) >> 5);
3289     proto_tree_add_item (sns_tree, hf_scsi_snskey, tvb, offset+2, 1, 0);
3290     proto_tree_add_item (sns_tree, hf_scsi_snsinfo, tvb, offset+3, 4, 0);
3291     proto_tree_add_item (sns_tree, hf_scsi_addlsnslen, tvb, offset+7, 1, 0);
3292     proto_tree_add_text (sns_tree, tvb, offset+8, 4,
3293                              "Command-Specific Information: %s",
3294                              tvb_bytes_to_str (tvb, offset+8, 4));
3295     proto_tree_add_item (sns_tree, hf_scsi_ascascq, tvb, offset+12, 2, 0);
3296     proto_tree_add_item_hidden (sns_tree, hf_scsi_asc, tvb, offset+12, 1, 0);
3297     proto_tree_add_item_hidden (sns_tree, hf_scsi_ascq, tvb, offset+13,
3298                                     1, 0);
3299     proto_tree_add_item (sns_tree, hf_scsi_fru, tvb, offset+14, 1, 0);
3300     proto_tree_add_item (sns_tree, hf_scsi_sksv, tvb, offset+15, 1, 0);
3301     proto_tree_add_text (sns_tree, tvb, offset+15, 3,
3302                              "Sense Key Specific: %s",
3303                              tvb_bytes_to_str (tvb, offset+15, 3));
3304 }
3305
3306 static void
3307 dissect_spc3_requestsense (tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *tree,
3308                        guint offset, gboolean isreq, gboolean iscdb,
3309                        guint payload_len _U_, scsi_task_data_t *cdata _U_)
3310 {
3311     guint8 flags;
3312
3313     if (!tree)
3314         return;
3315
3316     if (isreq && iscdb) {
3317         proto_tree_add_item (tree, hf_scsi_alloclen, tvb, offset+3, 1, 0);
3318
3319         flags = tvb_get_guint8 (tvb, offset+4);
3320         proto_tree_add_uint_format (tree, hf_scsi_control, tvb, offset+4, 1,
3321                                     flags,
3322                                     "Vendor Unique = %u, NACA = %u, Link = %u",
3323                                     flags & 0xC0, flags & 0x4, flags & 0x1);
3324     }
3325     else if (!isreq)
3326         dissect_scsi_fix_snsinfo(tvb, tree, offset);
3327 }
3328
3329 static void
3330 dissect_spc2_reserve6 (tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *tree,
3331                        guint offset, gboolean isreq, gboolean iscdb,
3332                        guint payload_len _U_, scsi_task_data_t *cdata _U_)
3333 {
3334     guint8 flags;
3335
3336     if (!tree)
3337         return;
3338
3339     if (isreq && iscdb) {
3340         flags = tvb_get_guint8 (tvb, offset+4);
3341         proto_tree_add_uint_format (tree, hf_scsi_control, tvb, offset+4, 1,
3342                                     flags,
3343                                     "Vendor Unique = %u, NACA = %u, Link = %u",
3344                                     flags & 0xC0, flags & 0x4, flags & 0x1);
3345     }
3346 }
3347
3348 static void
3349 dissect_spc2_reserve10 (tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *tree,
3350                         guint offset, gboolean isreq, gboolean iscdb,
3351                         guint payload_len _U_, scsi_task_data_t *cdata _U_)
3352 {
3353     guint8 flags;
3354
3355     if (!tree)
3356         return;
3357
3358     if (isreq && iscdb) {
3359         flags = tvb_get_guint8 (tvb, offset);
3360
3361         proto_tree_add_uint_format (tree, hf_scsi_release_flags, tvb, offset, 1,
3362                                     flags,
3363                                     "Flags: 3rd Party ID = %u, LongID = %u",
3364                                     flags & 0x10, flags & 0x2);
3365         if ((flags & 0x12) == 0x10) {
3366             proto_tree_add_item (tree, hf_scsi_release_thirdpartyid, tvb,
3367                                  offset+2, 1, 0);
3368         }
3369         proto_tree_add_item (tree, hf_scsi_paramlen16, tvb, offset+6, 2, 0);
3370
3371         flags = tvb_get_guint8 (tvb, offset+8);
3372         proto_tree_add_uint_format (tree, hf_scsi_control, tvb, offset+8, 1,
3373                                     flags,
3374                                     "Vendor Unique = %u, NACA = %u, Link = %u",
3375                                     flags & 0xC0, flags & 0x4, flags & 0x1);
3376     }
3377 }
3378
3379 static void
3380 dissect_sbc2_startstopunit (tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *tree,
3381                             guint offset, gboolean isreq _U_, gboolean iscdb,
3382                             guint payload_len _U_, scsi_task_data_t *cdata _U_)
3383 {
3384     guint8 flags;
3385
3386     if (!tree || !iscdb)
3387         return;
3388
3389     proto_tree_add_boolean (tree, hf_scsi_ssu_immed, tvb, offset, 1, 0);
3390     proto_tree_add_uint (tree, hf_scsi_ssu_pwr_cond, tvb, offset+3, 1, 0);
3391     proto_tree_add_boolean (tree, hf_scsi_ssu_loej, tvb, offset+3, 1, 0);
3392     proto_tree_add_boolean (tree, hf_scsi_ssu_start, tvb, offset+3, 1, 0);
3393
3394     flags = tvb_get_guint8 (tvb, offset+4);
3395     proto_tree_add_uint_format (tree, hf_scsi_control, tvb, offset+4, 1,
3396                                 flags,
3397                                 "Vendor Unique = %u, NACA = %u, Link = %u",
3398                                 flags & 0xC0, flags & 0x4, flags & 0x1);
3399 }
3400
3401 static void
3402 dissect_spc3_testunitready (tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *tree,
3403                           guint offset, gboolean isreq, gboolean iscdb,
3404                           guint payload_len _U_, scsi_task_data_t *cdata _U_)
3405 {
3406     guint8 flags;
3407
3408     if (!tree)
3409         return;
3410
3411     if (isreq && iscdb) {
3412         flags = tvb_get_guint8 (tvb, offset+4);
3413         proto_tree_add_uint_format (tree, hf_scsi_control, tvb, offset+4, 1,
3414                                     flags,
3415                                     "Vendor Unique = %u, NACA = %u, Link = %u",
3416                                     flags & 0xC0, flags & 0x4, flags & 0x1);
3417     }
3418 }
3419
3420 static void
3421 dissect_sbc2_formatunit (tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *tree,
3422                          guint offset, gboolean isreq, gboolean iscdb,
3423                          guint payload_len _U_, scsi_task_data_t *cdata _U_)
3424 {
3425     guint8 flags;
3426
3427     if (!tree)
3428         return;
3429
3430     if (isreq && iscdb) {
3431         flags = tvb_get_guint8 (tvb, offset);
3432         proto_tree_add_uint_format (tree, hf_scsi_formatunit_flags, tvb, offset,
3433                                     1, flags,
3434                                     "Flags: Longlist = %u, FMTDATA = %u, CMPLIST = %u",
3435                                     flags & 0x20, flags & 0x8, flags & 0x4);
3436         proto_tree_add_item (tree, hf_scsi_cdb_defectfmt, tvb, offset, 1, 0);
3437         proto_tree_add_item (tree, hf_scsi_formatunit_vendor, tvb, offset+1,
3438                              1, 0);
3439         proto_tree_add_item (tree, hf_scsi_formatunit_interleave, tvb, offset+2,
3440                              2, 0);
3441         flags = tvb_get_guint8 (tvb, offset+4);
3442         proto_tree_add_uint_format (tree, hf_scsi_control, tvb, offset+4, 1,
3443                                     flags,
3444                                     "Vendor Unique = %u, NACA = %u, Link = %u",
3445                                     flags & 0xC0, flags & 0x4, flags & 0x1);
3446     }
3447 }
3448
3449 static void
3450 dissect_sbc2_readwrite6 (tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *tree,
3451                     guint offset, gboolean isreq, gboolean iscdb,
3452                     guint payload_len _U_, scsi_task_data_t *cdata _U_)
3453 {
3454     guint8 flags;
3455
3456     if (isreq && iscdb) {
3457         if (check_col (pinfo->cinfo, COL_INFO))
3458             col_append_fstr (pinfo->cinfo, COL_INFO, "(LBA: 0x%06x, Len: %u)",
3459                              tvb_get_ntoh24 (tvb, offset),
3460                              tvb_get_guint8 (tvb, offset+3));
3461     }
3462
3463     if (tree && isreq && iscdb) {
3464         proto_tree_add_item (tree, hf_scsi_rdwr6_lba, tvb, offset, 3, 0);
3465         proto_tree_add_item (tree, hf_scsi_rdwr6_xferlen, tvb, offset+3, 1, 0);
3466         flags = tvb_get_guint8 (tvb, offset+4);
3467         proto_tree_add_uint_format (tree, hf_scsi_control, tvb, offset+4, 1,
3468                                     flags,
3469                                     "Vendor Unique = %u, NACA = %u, Link = %u",
3470                                     flags & 0xC0, flags & 0x4, flags & 0x1);
3471     }
3472 }
3473
3474 static void
3475 dissect_sbc2_readwrite10 (tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *tree,
3476                      guint offset, gboolean isreq, gboolean iscdb,
3477                      guint payload_len _U_, scsi_task_data_t *cdata _U_)
3478
3479 {
3480     guint8 flags;
3481
3482     if (isreq && iscdb) {
3483         if (check_col (pinfo->cinfo, COL_INFO))
3484             col_append_fstr (pinfo->cinfo, COL_INFO, "(LBA: 0x%08x, Len: %u)",
3485                              tvb_get_ntohl (tvb, offset+1),
3486                              tvb_get_ntohs (tvb, offset+6));
3487     }
3488
3489     if (tree && isreq && iscdb) {
3490         flags = tvb_get_guint8 (tvb, offset);
3491
3492         proto_tree_add_uint_format (tree, hf_scsi_read_flags, tvb, offset, 1,
3493                                     flags,
3494                                     "DPO = %u, FUA = %u, RelAddr = %u",
3495                                     flags & 0x10, flags & 0x8, flags & 0x1);
3496         proto_tree_add_item (tree, hf_scsi_rdwr10_lba, tvb, offset+1, 4, 0);
3497         proto_tree_add_item (tree, hf_scsi_rdwr10_xferlen, tvb, offset+6, 2, 0);
3498         flags = tvb_get_guint8 (tvb, offset+8);
3499         proto_tree_add_uint_format (tree, hf_scsi_control, tvb, offset+8, 1,
3500                                     flags,
3501                                     "Vendor Unique = %u, NACA = %u, Link = %u",
3502                                     flags & 0xC0, flags & 0x4, flags & 0x1);
3503     }
3504 }
3505
3506 static void
3507 dissect_sbc2_readwrite12 (tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *tree,
3508                      guint offset, gboolean isreq, gboolean iscdb,
3509                      guint payload_len _U_, scsi_task_data_t *cdata _U_)
3510 {
3511     guint8 flags;
3512
3513     if (isreq && iscdb) {
3514         if (check_col (pinfo->cinfo, COL_INFO))
3515             col_append_fstr (pinfo->cinfo, COL_INFO, "(LBA: 0x%08x, Len: %u)",
3516                              tvb_get_ntohl (tvb, offset+1),
3517                              tvb_get_ntohl (tvb, offset+5));
3518     }
3519
3520     if (tree && isreq && iscdb) {
3521         flags = tvb_get_guint8 (tvb, offset);
3522
3523         proto_tree_add_uint_format (tree, hf_scsi_read_flags, tvb, offset, 1,
3524                                     flags,
3525                                     "DPO = %u, FUA = %u, RelAddr = %u",
3526                                     flags & 0x10, flags & 0x8, flags & 0x1);
3527         proto_tree_add_item (tree, hf_scsi_rdwr10_lba, tvb, offset+1, 4, 0);
3528         proto_tree_add_item (tree, hf_scsi_rdwr12_xferlen, tvb, offset+5, 4, 0);
3529         flags = tvb_get_guint8 (tvb, offset+10);
3530         proto_tree_add_uint_format (tree, hf_scsi_control, tvb, offset+10, 1,
3531                                     flags,
3532                                     "Vendor Unique = %u, NACA = %u, Link = %u",
3533                                     flags & 0xC0, flags & 0x4, flags & 0x1);
3534     }
3535 }
3536
3537 static void
3538 dissect_sbc2_readwrite16 (tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *tree,
3539                      guint offset, gboolean isreq, gboolean iscdb,
3540                      guint payload_len _U_, scsi_task_data_t *cdata _U_)
3541 {
3542     guint8 flags;
3543
3544     if (isreq && iscdb) {
3545         if (check_col (pinfo->cinfo, COL_INFO))
3546             col_append_fstr (pinfo->cinfo, COL_INFO, "(LBA: %" PRIu64 ", Len: %u)",
3547                              tvb_get_ntoh64 (tvb, offset+1),
3548                              tvb_get_ntohl (tvb, offset+9));
3549     }
3550
3551     if (tree && isreq && iscdb) {
3552         flags = tvb_get_guint8 (tvb, offset);
3553
3554         proto_tree_add_uint_format (tree, hf_scsi_read_flags, tvb, offset, 1,
3555                                     flags,
3556                                     "DPO = %u, FUA = %u, RelAddr = %u",
3557                                     flags & 0x10, flags & 0x8, flags & 0x1);
3558         proto_tree_add_item (tree, hf_scsi_rdwr16_lba, tvb, offset+1, 8, 0);
3559         proto_tree_add_item (tree, hf_scsi_rdwr12_xferlen, tvb, offset+9, 4, 0);
3560         flags = tvb_get_guint8 (tvb, offset+14);
3561         proto_tree_add_uint_format (tree, hf_scsi_control, tvb, offset+14, 1,
3562                                     flags,
3563                                     "Vendor Unique = %u, NACA = %u, Link = %u",
3564                                     flags & 0xC0, flags & 0x4, flags & 0x1);
3565     }
3566 }
3567
3568 static void
3569 dissect_sbc2_verify10 (tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *tree,
3570                        guint offset, gboolean isreq, gboolean iscdb,
3571                        guint payload_len _U_, scsi_task_data_t *cdata _U_)
3572
3573 {
3574     guint8 flags;
3575
3576     if (isreq && iscdb) {
3577         if (check_col (pinfo->cinfo, COL_INFO))
3578             col_append_fstr (pinfo->cinfo, COL_INFO, "(LBA: 0x%08x, Len: %u)",
3579                              tvb_get_ntohl (tvb, offset+2),
3580                              tvb_get_ntohs (tvb, offset+7));
3581     }
3582
3583     if (tree && isreq && iscdb) {
3584          proto_tree_add_item (tree, hf_sbc2_verify_dpo, tvb, offset+1, 1, 0);
3585          proto_tree_add_item (tree, hf_sbc2_verify_blkvfy, tvb, offset+1, 1, 0);
3586          proto_tree_add_item (tree, hf_sbc2_verify_bytchk, tvb, offset+1, 1, 0);
3587          proto_tree_add_item (tree, hf_sbc2_verify_reladdr, tvb, offset+1, 1,
3588                               0);
3589          proto_tree_add_item (tree, hf_sbc2_verify_lba, tvb, offset+2, 4, 0);
3590          proto_tree_add_item (tree, hf_sbc2_verify_vlen, tvb, offset+7, 2, 0);
3591          flags = tvb_get_guint8 (tvb, offset+9);
3592          proto_tree_add_uint_format (tree, hf_scsi_control, tvb, offset+9, 1,
3593                                      flags,
3594                                      "Vendor Unique = %u, NACA = %u, Link = %u",
3595                                      flags & 0xC0, flags & 0x4, flags & 0x1);
3596     }
3597 }
3598
3599 static void
3600 dissect_sbc2_verify12 (tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *tree,
3601                        guint offset, gboolean isreq, gboolean iscdb,
3602                        guint payload_len _U_, scsi_task_data_t *cdata _U_)
3603
3604 {
3605     guint8 flags;
3606
3607     if (isreq && iscdb) {
3608         if (check_col (pinfo->cinfo, COL_INFO))
3609             col_append_fstr (pinfo->cinfo, COL_INFO, "(LBA: 0x%08x, Len: %u)",
3610                              tvb_get_ntohl (tvb, offset+2),
3611                              tvb_get_ntohl (tvb, offset+6));
3612     }
3613
3614     if (tree && isreq && iscdb) {
3615          proto_tree_add_item (tree, hf_sbc2_verify_dpo, tvb, offset+1, 1, 0);
3616          proto_tree_add_item (tree, hf_sbc2_verify_blkvfy, tvb, offset+1, 1, 0);
3617          proto_tree_add_item (tree, hf_sbc2_verify_bytchk, tvb, offset+1, 1, 0);
3618          proto_tree_add_item (tree, hf_sbc2_verify_reladdr, tvb, offset+1, 1,
3619                               0);
3620          proto_tree_add_item (tree, hf_sbc2_verify_lba, tvb, offset+2, 4, 0);
3621          proto_tree_add_item (tree, hf_sbc2_verify_vlen32, tvb, offset+6, 4, 0);
3622          flags = tvb_get_guint8 (tvb, offset+11);
3623          proto_tree_add_uint_format (tree, hf_scsi_control, tvb, offset+11, 1,
3624                                      flags,
3625                                      "Vendor Unique = %u, NACA = %u, Link = %u",
3626                                      flags & 0xC0, flags & 0x4, flags & 0x1);
3627     }
3628 }
3629
3630 static void
3631 dissect_sbc2_verify16 (tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *tree,
3632                        guint offset, gboolean isreq, gboolean iscdb,
3633                        guint payload_len _U_, scsi_task_data_t *cdata _U_)
3634
3635 {
3636     guint8 flags;
3637
3638     if (isreq && iscdb) {
3639         if (check_col (pinfo->cinfo, COL_INFO))
3640             col_append_fstr (pinfo->cinfo, COL_INFO, "(LBA: %" PRIu64 ", Len: %u)",
3641                              tvb_get_ntoh64 (tvb, offset+2),
3642                              tvb_get_ntohl (tvb, offset+10));
3643     }
3644
3645     if (tree && isreq && iscdb) {
3646          proto_tree_add_item (tree, hf_sbc2_verify_dpo, tvb, offset+1, 1, 0);
3647          proto_tree_add_item (tree, hf_sbc2_verify_blkvfy, tvb, offset+1, 1, 0);
3648          proto_tree_add_item (tree, hf_sbc2_verify_bytchk, tvb, offset+1, 1, 0);
3649          proto_tree_add_item (tree, hf_sbc2_verify_reladdr, tvb, offset+1, 1,
3650                               0);
3651          proto_tree_add_item (tree, hf_sbc2_verify_lba, tvb, offset+2, 8, 0);
3652          proto_tree_add_item (tree, hf_sbc2_verify_vlen, tvb, offset+10, 4, 0);
3653          flags = tvb_get_guint8 (tvb, offset+15);
3654          proto_tree_add_uint_format (tree, hf_scsi_control, tvb, offset+15, 1,
3655                                      flags,
3656                                      "Vendor Unique = %u, NACA = %u, Link = %u",
3657                                      flags & 0xC0, flags & 0x4, flags & 0x1);
3658     }
3659 }
3660
3661 static void
3662 dissect_sbc2_wrverify10 (tvbuff_t *tvb, packet_info *pinfo _U_,
3663                          proto_tree *tree, guint offset, gboolean isreq,
3664                          gboolean iscdb, guint payload_len _U_,
3665                          scsi_task_data_t *cdata _U_)
3666
3667 {
3668     guint8 flags;
3669
3670     if (isreq && iscdb) {
3671         if (check_col (pinfo->cinfo, COL_INFO))
3672             col_append_fstr (pinfo->cinfo, COL_INFO, "(LBA: 0x%08x, Len: %u)",
3673                              tvb_get_ntohl (tvb, offset+2),
3674                              tvb_get_ntohs (tvb, offset+7));
3675     }
3676
3677     if (tree && isreq && iscdb) {
3678          proto_tree_add_item (tree, hf_sbc2_verify_dpo, tvb, offset+1, 1, 0);
3679          proto_tree_add_item (tree, hf_sbc2_wrverify_ebp, tvb, offset+1, 1, 0);
3680          proto_tree_add_item (tree, hf_sbc2_verify_bytchk, tvb, offset+1, 1, 0);
3681          proto_tree_add_item (tree, hf_sbc2_verify_reladdr, tvb, offset+1, 1,
3682                               0);
3683          proto_tree_add_item (tree, hf_sbc2_wrverify_lba, tvb, offset+2, 4, 0);
3684          proto_tree_add_item (tree, hf_sbc2_wrverify_xferlen, tvb, offset+7,
3685                               2, 0);
3686          flags = tvb_get_guint8 (tvb, offset+9);
3687          proto_tree_add_uint_format (tree, hf_scsi_control, tvb, offset+9, 1,
3688                                      flags,
3689                                      "Vendor Unique = %u, NACA = %u, Link = %u",
3690                                      flags & 0xC0, flags & 0x4, flags & 0x1);
3691     }
3692 }
3693
3694 static void
3695 dissect_sbc2_wrverify12 (tvbuff_t *tvb, packet_info *pinfo _U_,
3696                          proto_tree *tree, guint offset, gboolean isreq,
3697                          gboolean iscdb, guint payload_len _U_,
3698                          scsi_task_data_t *cdata _U_)
3699 {
3700     guint8 flags;
3701
3702     if (isreq && iscdb) {
3703         if (check_col (pinfo->cinfo, COL_INFO))
3704             col_append_fstr (pinfo->cinfo, COL_INFO, "(LBA: 0x%08x, Len: %u)",
3705                              tvb_get_ntohl (tvb, offset+2),
3706                              tvb_get_ntohl (tvb, offset+6));
3707     }
3708
3709     if (tree && isreq && iscdb) {
3710          proto_tree_add_item (tree, hf_sbc2_verify_dpo, tvb, offset+1, 1, 0);
3711          proto_tree_add_item (tree, hf_sbc2_wrverify_ebp, tvb, offset+1, 1, 0);
3712          proto_tree_add_item (tree, hf_sbc2_verify_bytchk, tvb, offset+1, 1, 0);
3713          proto_tree_add_item (tree, hf_sbc2_verify_reladdr, tvb, offset+1, 1,
3714                               0);
3715          proto_tree_add_item (tree, hf_sbc2_wrverify_lba, tvb, offset+2, 4, 0);
3716          proto_tree_add_item (tree, hf_sbc2_wrverify_xferlen32, tvb, offset+6,
3717                               4, 0);
3718          flags = tvb_get_guint8 (tvb, offset+11);
3719          proto_tree_add_uint_format (tree, hf_scsi_control, tvb, offset+11, 1,
3720                                      flags,
3721                                      "Vendor Unique = %u, NACA = %u, Link = %u",
3722                                      flags & 0xC0, flags & 0x4, flags & 0x1);
3723     }
3724 }
3725
3726 static void
3727 dissect_sbc2_wrverify16 (tvbuff_t *tvb, packet_info *pinfo _U_,
3728                          proto_tree *tree, guint offset, gboolean isreq,
3729                          gboolean iscdb, guint payload_len _U_,
3730                          scsi_task_data_t *cdata _U_)
3731 {
3732     guint8 flags;
3733
3734     if (isreq && iscdb) {
3735         if (check_col (pinfo->cinfo, COL_INFO))
3736             col_append_fstr (pinfo->cinfo, COL_INFO, "(LBA: %" PRIu64 ", Len: %u)",
3737                              tvb_get_ntoh64 (tvb, offset+2),
3738                              tvb_get_ntohl (tvb, offset+10));
3739     }
3740
3741     if (tree && isreq && iscdb) {
3742          proto_tree_add_item (tree, hf_sbc2_verify_dpo, tvb, offset+1, 1, 0);
3743          proto_tree_add_item (tree, hf_sbc2_wrverify_ebp, tvb, offset+1, 1, 0);
3744          proto_tree_add_item (tree, hf_sbc2_verify_bytchk, tvb, offset+1, 1, 0);
3745          proto_tree_add_item (tree, hf_sbc2_verify_reladdr, tvb, offset+1, 1,
3746                               0);
3747          proto_tree_add_item (tree, hf_sbc2_wrverify_lba64, tvb, offset+2, 8, 0);
3748          proto_tree_add_item (tree, hf_sbc2_wrverify_xferlen32, tvb, offset+10,
3749                               4, 0);
3750          flags = tvb_get_guint8 (tvb, offset+15);
3751          proto_tree_add_uint_format (tree, hf_scsi_control, tvb, offset+15, 1,
3752                                      flags,
3753                                      "Vendor Unique = %u, NACA = %u, Link = %u",
3754                                      flags & 0xC0, flags & 0x4, flags & 0x1);
3755     }
3756 }
3757
3758 static const value_string scsi_key_class_val[] = {
3759     {0x00, "DVD CSS/CPPM or CPRM"},
3760     {0x01, "ReWriteable Security Service - A"},
3761     {0,NULL}
3762 };
3763 static const value_string scsi_key_format_val[] = {
3764     {0x00,      "AGID for CSS/CPPM"},
3765     {0x01,      "Challenge Key"},
3766     {0x02,      "Key 1"},
3767     {0x04,      "Title Key"},
3768     {0x05,      "Authentication Success Flag"},
3769     {0x08,      "RPC State"},
3770     {0x11,      "AGID for CPRM"},
3771     {0x3f,      "None"},
3772     {0,NULL}
3773 };
3774 static const value_string scsi_report_key_type_code_val[] = {
3775     {0x00,      "NONE"},
3776     {0x01,      "SET"},
3777     {0x02,      "LAST CHANCE"},
3778     {0x03,      "PERM"},
3779     {0,NULL}
3780 };
3781 static const value_string scsi_report_key_rpc_scheme_val[] = {
3782     {0x00,      "Unknown (RPC not enforced)"},
3783     {0x01,      "RPC Phase II"},
3784     {0,NULL}
3785 };
3786
3787 static void
3788 dissect_mmc4_reportkey (tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *tree,
3789                      guint offset, gboolean isreq, gboolean iscdb,
3790                      guint payload_len _U_, scsi_task_data_t *cdata _U_)
3791
3792 {
3793     guint8 flags, agid, key_format, key_class;
3794     proto_item *ti;
3795
3796     if (tree && isreq && iscdb) {
3797         proto_tree_add_item (tree, hf_scsi_lba, tvb, offset+1,
3798                              4, 0);
3799         key_class=tvb_get_guint8(tvb, offset+6);
3800         proto_tree_add_item (tree, hf_scsi_key_class, tvb, offset+6,
3801                              1, 0);
3802         proto_tree_add_item (tree, hf_scsi_alloclen16, tvb, offset+7, 2, 0);
3803
3804         agid=tvb_get_guint8(tvb, offset+9)&0xc0;
3805         key_format=tvb_get_guint8(tvb, offset+9)&0x3f;
3806         switch(key_format){
3807         case 0x01:
3808         case 0x02:
3809         case 0x04:
3810         case 0x3f:
3811             /* agid is only valid for some formats */
3812             proto_tree_add_uint (tree, hf_scsi_agid, tvb, offset+9, 1, agid);
3813             break;
3814         }
3815         proto_tree_add_uint (tree, hf_scsi_key_format, tvb, offset+9, 1, key_format);
3816         /* save key_class/key_format so we can decode the response */
3817         cdata->flags=(key_format<<8)|key_class;
3818
3819         flags = tvb_get_guint8 (tvb, offset+14);
3820         proto_tree_add_uint_format (tree, hf_scsi_control, tvb, offset+14, 1,
3821                                     flags,
3822                                     "Vendor Unique = %u, NACA = %u, Link = %u",
3823                                     flags & 0xC0, flags & 0x4, flags & 0x1);
3824     }
3825     if(tree && (!isreq)) {
3826         switch(cdata->flags){
3827         case 0x0800: /* format:RPC State  class:00 */
3828             proto_tree_add_item (tree, hf_scsi_data_length, tvb, offset, 2, 0);
3829             proto_tree_add_item (tree, hf_scsi_report_key_type_code, tvb, offset+4, 1, 0);
3830             proto_tree_add_item (tree, hf_scsi_report_key_vendor_resets, tvb, offset+4, 1, 0);
3831             proto_tree_add_item (tree, hf_scsi_report_key_user_changes, tvb, offset+4, 1, 0);
3832             proto_tree_add_item (tree, hf_scsi_report_key_region_mask, tvb, offset+5, 1, 0);
3833             proto_tree_add_item (tree, hf_scsi_report_key_rpc_scheme, tvb, offset+6, 1, 0);
3834             break;
3835         default:
3836             ti = proto_tree_add_text (tree, tvb, 0, 0,
3837                 "SCSI/MMC Unknown Format:0x%02x/Class:0x%02x combination",
3838                 cdata->flags>>8,cdata->flags&0xff);
3839             PROTO_ITEM_SET_GENERATED(ti);
3840             break;
3841         }
3842     }
3843 }
3844
3845 static const value_string scsi_setstreaming_type_val[] = {
3846     {0x00,      "Performance Descriptor"},
3847     {0x05,      "DBI cache zone descriptor"},
3848     {0,NULL}
3849 };
3850 static void
3851 dissect_mmc4_setstreaming (tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *tree,
3852                      guint offset, gboolean isreq, gboolean iscdb,
3853                      guint payload_len _U_, scsi_task_data_t *cdata _U_)
3854
3855 {
3856     guint8 flags, type;
3857     proto_item *ti;
3858
3859     if (tree && isreq && iscdb) {
3860         type=tvb_get_guint8(tvb, offset+7);
3861         cdata->flags=type;
3862         proto_tree_add_item (tree, hf_scsi_setstreaming_type, tvb, offset+7, 1, 0);
3863         proto_tree_add_item (tree, hf_scsi_setstreaming_param_len, tvb, offset+8, 2, 0);
3864
3865         flags = tvb_get_guint8 (tvb, offset+10);
3866         proto_tree_add_uint_format (tree, hf_scsi_control, tvb, offset+10, 1,
3867                                     flags,
3868                                     "Vendor Unique = %u, NACA = %u, Link = %u",
3869                                     flags & 0xC0, flags & 0x4, flags & 0x1);
3870     }
3871     if(tree && isreq && (!iscdb)) {
3872         switch(cdata->flags){
3873         case 0x00: /* performance descriptor */
3874             proto_tree_add_item (tree, hf_scsi_setstreaming_wrc, tvb, offset+0, 1, 0);
3875             proto_tree_add_item (tree, hf_scsi_setstreaming_rdd, tvb, offset+0, 1, 0);
3876             proto_tree_add_item (tree, hf_scsi_setstreaming_exact, tvb, offset+0, 1, 0);
3877             proto_tree_add_item (tree, hf_scsi_setstreaming_ra, tvb, offset+0, 1, 0);
3878             proto_tree_add_item (tree, hf_scsi_setstreaming_start_lba, tvb, offset+4, 4, 0);
3879             proto_tree_add_item (tree, hf_scsi_setstreaming_end_lba, tvb, offset+8, 4, 0);
3880             proto_tree_add_item (tree, hf_scsi_setstreaming_read_size, tvb, offset+12, 4, 0);
3881             proto_tree_add_item (tree, hf_scsi_setstreaming_read_time, tvb, offset+16, 4, 0);
3882             proto_tree_add_item (tree, hf_scsi_setstreaming_write_size, tvb, offset+20, 4, 0);
3883             proto_tree_add_item (tree, hf_scsi_setstreaming_write_time, tvb, offset+24, 4, 0);
3884             break;
3885         default:
3886             ti = proto_tree_add_text (tree, tvb, 0, 0,
3887                 "SCSI/MMC Unknown SetStreaming Type:0x%02x",cdata->flags);
3888             PROTO_ITEM_SET_GENERATED(ti);
3889             break;
3890         }
3891     }
3892 }
3893
3894 static const value_string scsi_getconf_rt_val[] = {
3895     {0x00,      "Return all features"},
3896     {0x01,      "Return all current features"},
3897     {0x02,      "Return all identified by Starting Feature"},
3898     {0,NULL}
3899 };
3900 static const value_string scsi_getconf_current_profile_val[] = {
3901     {0x0000,    "Reserved"},
3902     {0x0001,    "Non-removable disk"},
3903     {0x0002,    "Removable disk"},
3904     {0x0003,    "MO Erasable"},
3905     {0x0004,    "Optical Write Once"},
3906     {0x0005,    "AS-MO"},
3907     {0x0008,    "CD-ROM"},
3908     {0x0009,    "CD-R"},
3909     {0x000a,    "CD-RW"},
3910     {0x0010,    "DVD-ROM"},
3911     {0x0011,    "DVD-R"},
3912     {0x0012,    "DVD-RAM"},
3913     {0x0013,    "DVD-RW Restricted Overwrite"},
3914     {0x0014,    "DVD-RW Sequential recording"},
3915     {0x001a,    "DVD+RW"},
3916     {0x001b,    "DVD+R"},
3917     {0x0020,    "DDCD-ROM"},
3918     {0x0021,    "DDCD-R"},
3919     {0x0022,    "DDCD-RW"},
3920     {0xffff,    "Logical unit not conforming to a standard profile"},
3921     {0,NULL}
3922 };
3923
3924 static const value_string scsi_feature_val[] = {
3925     {0x0000,    "Profile List"},
3926     {0x0001,    "Core"},
3927     {0x0002,    "Morphing"},
3928     {0x0003,    "Removable Medium"},
3929     {0x0004,    "Write Protect"},
3930     {0x0010,    "Random Readable"},
3931     {0x001d,    "Multi-read"},
3932     {0x001e,    "CD Read"},
3933     {0x001f,    "DVD Read"},
3934     {0x0020,    "Random Writeable"},
3935     {0x0021,    "Incremental Streaming Writeable"},
3936     {0x0022,    "Sector Erasable"},
3937     {0x0023,    "Formattable"},
3938     {0x0024,    "Defect Management"},
3939     {0x0025,    "Write Once"},
3940     {0x0026,    "Restricted Overwrite"},
3941     {0x0027,    "CD-RW CAV Write"},
3942     {0x0028,    "MRW"},
3943     {0x0029,    "Enhanced Defect Reporting"},
3944     {0x002a,    "DVD+RW"},
3945     {0x002b,    "DVD+R"},
3946     {0x002c,    "Rigid Restricted Overwrite"},
3947     {0x002d,    "CD Track At Once"},
3948     {0x002e,    "CD Mastering"},
3949     {0x002f,    "DVD-R/-RW Write"},
3950     {0x0030,    "DDCD Read"},
3951     {0x0031,    "DDCD-R Write"},
3952     {0x0032,    "DDCD-RW Write"},
3953     {0x0037,    "CD-RW Media Write Support"},
3954     {0x0100,    "Power Management"},
3955     {0x0101,    "SMART"},
3956     {0x0102,    "Embedded Changer"},
3957     {0x0103,    "CD Audio analog play"},
3958     {0x0104,    "Microcode Upgrade"},
3959     {0x0105,    "Timeout"},
3960     {0x0106,    "DVD-CSS"},
3961     {0x0107,    "Real Time Streaming"},
3962     {0x0108,    "Logical Unit serial number"},
3963     {0x010a,    "Disc control Block"},
3964     {0x010b,    "DVD CPRM"},
3965     {0x010c,    "Firmware Information"},
3966     {0,NULL}
3967 };
3968
3969 static void
3970 dissect_mmc4_getconfiguration (tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *tree,
3971                      guint offset, gboolean isreq, gboolean iscdb,
3972                      guint payload_len _U_, scsi_task_data_t *cdata _U_)
3973
3974 {
3975     guint8 flags;
3976     gint32 len;
3977     guint old_offset;
3978
3979     if (tree && isreq && iscdb) {
3980         proto_tree_add_item (tree, hf_scsi_getconf_rt, tvb, offset+0, 1, 0);
3981         proto_tree_add_item (tree, hf_scsi_getconf_starting_feature, tvb, offset+1, 2, 0);
3982
3983         proto_tree_add_item (tree, hf_scsi_alloclen16, tvb, offset+6, 2, 0);
3984
3985         flags = tvb_get_guint8 (tvb, offset+8);
3986         proto_tree_add_uint_format (tree, hf_scsi_control, tvb, offset+8, 1,
3987                                     flags,
3988                                     "Vendor Unique = %u, NACA = %u, Link = %u",
3989                                     flags & 0xC0, flags & 0x4, flags & 0x1);
3990     }
3991     if(tree && (!isreq)) {
3992         len=tvb_get_ntohl(tvb, offset+0);
3993         proto_tree_add_item (tree, hf_scsi_data_length, tvb, offset+0, 4, 0);
3994         proto_tree_add_item (tree, hf_scsi_getconf_current_profile, tvb, offset+6, 2, 0);
3995         offset+=8;
3996         len-=4;
3997         while(len>0){
3998                 guint16 feature;
3999                 guint8 additional_length;
4000                 guint8 num_linksize;
4001
4002                 feature=tvb_get_ntohs(tvb, offset);
4003                 proto_tree_add_item (tree, hf_scsi_feature, tvb, offset, 2, 0);
4004                 offset+=2;
4005                 proto_tree_add_item (tree, hf_scsi_feature_version, tvb, offset, 1, 0);
4006                 proto_tree_add_item (tree, hf_scsi_feature_persistent, tvb, offset, 1, 0);
4007                 proto_tree_add_item (tree, hf_scsi_feature_current, tvb, offset, 1, 0);
4008                 offset+=1;
4009                 additional_length=tvb_get_guint8(tvb, offset);
4010                 proto_tree_add_item (tree, hf_scsi_feature_additional_length, tvb, offset, 1, 0);
4011                 offset+=1;
4012                 old_offset=offset;
4013                 switch(feature){
4014                 case 0x0000: /* profile list */
4015                     while(offset<(old_offset+additional_length)){
4016                         proto_tree_add_item (tree, hf_scsi_feature_profile, tvb, offset, 2, 0);
4017                         proto_tree_add_item (tree, hf_scsi_feature_profile_current, tvb, offset+2, 1, 0);
4018                         offset+=4;
4019                     }
4020                     break;
4021                 case 0x001d: /* multi-read */
4022                 case 0x001f: /* dvd read feature */
4023                     /* no data for this one */
4024                     break;
4025                 case 0x001e: /* cd read */
4026                     proto_tree_add_item (tree, hf_scsi_feature_cdread_dap, tvb, offset, 1, 0);
4027                     proto_tree_add_item (tree, hf_scsi_feature_cdread_c2flag, tvb, offset, 1, 0);
4028                     proto_tree_add_item (tree, hf_scsi_feature_cdread_cdtext, tvb, offset, 1, 0);
4029                     break;
4030                 case 0x0021: /* incremental streaming writeable */
4031                     proto_tree_add_item (tree, hf_scsi_feature_dts, tvb, offset, 2, 0);
4032                     offset+=2;
4033                     proto_tree_add_item (tree, hf_scsi_feature_isw_buf, tvb, offset, 1, 0);
4034                     offset+=1;
4035                     num_linksize=tvb_get_guint8(tvb, offset);
4036                     proto_tree_add_item (tree, hf_scsi_feature_isw_num_linksize, tvb, offset, 1, 0);
4037                     offset+=1;
4038                     while(num_linksize--){
4039                         proto_tree_add_item (tree, hf_scsi_feature_isw_linksize, tvb, offset, 1, 0);
4040                         offset+=1;
4041                     }
4042                     break;
4043                 case 0x002a: /* dvd-rw */
4044                     proto_tree_add_item (tree, hf_scsi_feature_dvdrw_write, tvb, offset, 1, 0);
4045                     proto_tree_add_item (tree, hf_scsi_feature_dvdrw_quickstart, tvb, offset, 2, 0);
4046                     proto_tree_add_item (tree, hf_scsi_feature_dvdrw_closeonly, tvb, offset, 2, 0);
4047                     break;
4048                 case 0x002b: /* dvd-r */
4049                     proto_tree_add_item (tree, hf_scsi_feature_dvdr_write, tvb, offset, 1, 0);
4050                     break;
4051                 case 0x002d: /* track at once */
4052                     proto_tree_add_item (tree, hf_scsi_feature_tao_buf, tvb, offset, 1, 0);
4053                     proto_tree_add_item (tree, hf_scsi_feature_tao_rwraw, tvb, offset, 1, 0);
4054                     proto_tree_add_item (tree, hf_scsi_feature_tao_rwpack, tvb, offset, 1, 0);
4055                     proto_tree_add_item (tree, hf_scsi_feature_tao_testwrite, tvb, offset, 1, 0);
4056                     proto_tree_add_item (tree, hf_scsi_feature_tao_cdrw, tvb, offset, 1, 0);
4057                     proto_tree_add_item (tree, hf_scsi_feature_tao_rwsubcode, tvb, offset, 1, 0);
4058                     proto_tree_add_item (tree, hf_scsi_feature_dts, tvb, offset+2, 2, 0);
4059                     break;
4060                 case 0x002e: /* session at once */
4061                     proto_tree_add_item (tree, hf_scsi_feature_sao_buf, tvb, offset, 1, 0);
4062                     proto_tree_add_item (tree, hf_scsi_feature_sao_sao, tvb, offset, 1, 0);
4063                     proto_tree_add_item (tree, hf_scsi_feature_sao_rawms, tvb, offset, 1, 0);
4064                     proto_tree_add_item (tree, hf_scsi_feature_sao_raw, tvb, offset, 1, 0);
4065                     proto_tree_add_item (tree, hf_scsi_feature_sao_testwrite, tvb, offset, 1, 0);
4066                     proto_tree_add_item (tree, hf_scsi_feature_sao_cdrw, tvb, offset, 1, 0);
4067                     proto_tree_add_item (tree, hf_scsi_feature_sao_rw, tvb, offset, 1, 0);
4068                     proto_tree_add_item (tree, hf_scsi_feature_sao_mcsl, tvb, offset+1, 3, 0);
4069                     break;
4070                 case 0x002f: /* dvd-r/-rw*/
4071                     proto_tree_add_item (tree, hf_scsi_feature_dvdr_buf, tvb, offset, 1, 0);
4072                     proto_tree_add_item (tree, hf_scsi_feature_dvdr_testwrite, tvb, offset, 1, 0);
4073                     proto_tree_add_item (tree, hf_scsi_feature_dvdr_dvdrw, tvb, offset, 1, 0);
4074                     break;
4075                 case 0x0108: /* logical unit serial number */
4076                     proto_tree_add_item (tree, hf_scsi_feature_lun_sn, tvb, offset, additional_length, 0);
4077                     break;
4078                 default:
4079                     proto_tree_add_text (tree, tvb, offset, additional_length,
4080                         "SCSI/MMC Unknown Feature:0x%04x",feature);
4081                     break;
4082                 }
4083                 old_offset+=additional_length;
4084                 len-=4+additional_length;
4085         }
4086     }
4087 }
4088
4089 static void
4090 dissect_mmc4_geteventstatusnotification (tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *tree,
4091                      guint offset, gboolean isreq, gboolean iscdb,
4092                      guint payload_len _U_, scsi_task_data_t *cdata _U_)
4093
4094 {
4095     guint8 flags;
4096
4097     if (tree && isreq && iscdb) {
4098         flags = tvb_get_guint8 (tvb, offset);
4099         proto_tree_add_text (tree, tvb, offset, 1,
4100                              "Polled: %u",
4101                              flags & 0x01);
4102
4103         flags = tvb_get_guint8 (tvb, offset+3);
4104         proto_tree_add_text (tree, tvb, offset+3, 1,
4105                              "Notification Class Request: %u",
4106                              flags);
4107
4108         proto_tree_add_item (tree, hf_scsi_alloclen16, tvb, offset+6, 2, 0);
4109
4110         flags = tvb_get_guint8 (tvb, offset+8);
4111         proto_tree_add_uint_format (tree, hf_scsi_control, tvb, offset+8, 1,
4112                                     flags,
4113                                     "Vendor Unique = %u, NACA = %u, Link = %u",
4114                                     flags & 0xC0, flags & 0x4, flags & 0x1);
4115     }
4116 }
4117
4118 static const value_string scsi_q_subchannel_adr_val[] = {
4119     {0x0,       "Q-Subchannel mode info not supplied"},
4120     {0x1,       "Q-Subchannel encodes current position data"},
4121     {0x2,       "Q-Subchannel encodes media catalog number"},
4122     {0x3,       "Q-Subchannel encodes ISRC"},
4123     {0,NULL}
4124 };
4125 static const value_string scsi_q_subchannel_control_val[] = {
4126     {0x0,       "2 Audio channels without pre-emphasis (digital copy prohibited)"},
4127     {0x2,       "2 Audio channels without pre-emphasis (digital copy permitted)"},
4128     {0x1,       "2 Audio channels with pre-emphasis of 50/15us (digital copy prohibited)"},
4129     {0x3,       "2 Audio channels with pre-emphasis of 50/15us (digital copy permitted)"},
4130     {0x8,       "audio channels without pre-emphasis (digital copy prohibited)"},
4131     {0xa,       "audio channels without pre-emphasis (digital copy permitted)"},
4132     {0x9,       "2 Audio channels with pre-emphasis of 50/15us (digital copy prohibited)"},
4133     {0xb,       "2 Audio channels with pre-emphasis of 50/15us (digital copy permitted)"},
4134     {0x4,       "Data track, recorded uninterrupted (digital copy prohibited)"},
4135     {0x6,       "Data track, recorded uninterrupted (digital copy permitted)"},
4136     {0x5,       "Data track, recorded incremental (digital copy prohibited)"},
4137     {0x7,       "Data track, recorded incremental (digital copy permitted)"},
4138     {0,NULL}
4139 };
4140
4141 static void
4142 dissect_mmc4_readtocpmaatip (tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *tree,
4143                      guint offset, gboolean isreq, gboolean iscdb,
4144                      guint payload_len _U_, scsi_task_data_t *cdata _U_)
4145
4146 {
4147     guint8 flags, format;
4148     gint16 len;
4149
4150     if (tree && isreq && iscdb) {
4151         format=tvb_get_guint8(tvb, offset+1)&0x0f;
4152         /* save format so we can decode the response */
4153         cdata->flags=format;
4154
4155         switch(format){
4156         case 0x00:
4157         case 0x01:
4158             proto_tree_add_item (tree, hf_scsi_readtoc_time, tvb, offset, 1, 0);
4159             /* save time so we can pick it up in the response */
4160             if(tvb_get_guint8(tvb, offset)&0x02){
4161                 cdata->flags|=0x0100;
4162             }
4163             break;
4164         }
4165         proto_tree_add_item (tree, hf_scsi_readtoc_format, tvb, offset+1, 1, 0);
4166
4167         switch(format){
4168         case 0x00:
4169             proto_tree_add_item (tree, hf_scsi_track, tvb, offset+5, 1, 0);
4170             /* save track so we can pick it up in the response */
4171             cdata->flags|=0x0200;
4172             break;
4173         case 0x02:
4174             proto_tree_add_item (tree, hf_scsi_session, tvb, offset+5, 1, 0);
4175             /* save session so we can pick it up in the response */
4176             cdata->flags|=0x0400;
4177             break;
4178         }
4179
4180         proto_tree_add_item (tree, hf_scsi_alloclen16, tvb, offset+6, 2, 0);
4181
4182         flags = tvb_get_guint8 (tvb, offset+8);
4183         proto_tree_add_uint_format (tree, hf_scsi_control, tvb, offset+8, 1,
4184                                     flags,
4185                                     "Vendor Unique = %u, NACA = %u, Link = %u",
4186                                     flags & 0xC0, flags & 0x4, flags & 0x1);
4187
4188     }
4189     if(tree && (!isreq)) {
4190         len=tvb_get_ntohs(tvb, offset);
4191         proto_tree_add_item (tree, hf_scsi_data_length, tvb, offset, 2, 0);
4192         if(cdata->flags&0x0200){
4193             proto_tree_add_item (tree, hf_scsi_first_track, tvb, offset+2, 1, 0);
4194             proto_tree_add_item (tree, hf_scsi_readtoc_last_track, tvb, offset+3, 1, 0);
4195         }
4196         if(cdata->flags&0x0400){
4197             proto_tree_add_item (tree, hf_scsi_readtoc_first_session, tvb, offset+2, 1, 0);
4198             proto_tree_add_item (tree, hf_scsi_readtoc_last_session, tvb, offset+3, 1, 0);
4199         }
4200         offset+=4;
4201         len-=2;
4202         switch(cdata->flags&0x000f){
4203         case 0x0:
4204             while(len>0){
4205                 proto_tree_add_item (tree, hf_scsi_q_subchannel_adr, tvb, offset+1, 1, 0);
4206                 proto_tree_add_item (tree, hf_scsi_q_subchannel_control, tvb, offset+1, 1, 0);
4207                 proto_tree_add_item (tree, hf_scsi_track, tvb, offset+2, 4, 0);
4208                 if(cdata->flags&0x0100){
4209                     proto_tree_add_item (tree, hf_scsi_track_start_time, tvb, offset+4, 4, 0);
4210                 } else {
4211                     proto_tree_add_item (tree, hf_scsi_track_start_address, tvb, offset+4, 4, 0);
4212                 }
4213                 offset+=8;
4214                 len-=8;
4215             }
4216             break;
4217         default:
4218             proto_tree_add_text (tree, tvb, offset, len,
4219                 "SCSI/MMC Unknown READ TOC Format:0x%04x",cdata->flags&0x000f);
4220             break;
4221         }
4222     }
4223 }
4224
4225
4226 static void
4227 dissect_mmc4_synchronizecache (tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *tree,
4228                      guint offset, gboolean isreq, gboolean iscdb,
4229                      guint payload_len _U_, scsi_task_data_t *cdata _U_)
4230
4231 {
4232     guint8 flags;
4233
4234     if (tree && isreq && iscdb) {
4235         proto_tree_add_item (tree, hf_scsi_synccache_immed, tvb, offset, 1, 0);
4236         proto_tree_add_item (tree, hf_scsi_synccache_reladr, tvb, offset, 1, 0);
4237         proto_tree_add_item (tree, hf_scsi_lba, tvb, offset+1, 4, 0);
4238         proto_tree_add_item (tree, hf_scsi_num_blocks, tvb, offset+6, 2, 0);
4239
4240         flags = tvb_get_guint8 (tvb, offset+8);
4241         proto_tree_add_uint_format (tree, hf_scsi_control, tvb, offset+8, 1,
4242                                     flags,
4243                                     "Vendor Unique = %u, NACA = %u, Link = %u",
4244                                     flags & 0xC0, flags & 0x4, flags & 0x1);
4245
4246     }
4247 }
4248 static void
4249 dissect_mmc4_readbuffercapacity (tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *tree,
4250                      guint offset, gboolean isreq, gboolean iscdb,
4251                      guint payload_len _U_, scsi_task_data_t *cdata _U_)
4252
4253 {
4254     guint8 flags;
4255     gint16 len;
4256
4257     if (tree && isreq && iscdb) {
4258         cdata->flags=0;
4259         proto_tree_add_item (tree, hf_scsi_rbc_block, tvb, offset, 1, 0);
4260         if(tvb_get_guint8(tvb, offset)&0x01){
4261             cdata->flags=1;
4262         }
4263
4264         proto_tree_add_item (tree, hf_scsi_alloclen16, tvb, offset+6, 2, 0);
4265
4266         flags = tvb_get_guint8 (tvb, offset+8);
4267         proto_tree_add_uint_format (tree, hf_scsi_control, tvb, offset+8, 1,
4268                                     flags,
4269                                     "Vendor Unique = %u, NACA = %u, Link = %u",
4270                                     flags & 0xC0, flags & 0x4, flags & 0x1);
4271
4272     }
4273     if(tree && (!isreq)) {
4274         len=tvb_get_ntohs(tvb, offset);
4275         proto_tree_add_item (tree, hf_scsi_data_length, tvb, offset, 2, 0);
4276         if(cdata->flags){
4277             proto_tree_add_item (tree, hf_scsi_rbc_lob_blocks, tvb, offset+4, 4, 0);
4278             proto_tree_add_item (tree, hf_scsi_rbc_alob_blocks, tvb, offset+8, 4, 0);
4279         } else {
4280             proto_tree_add_item (tree, hf_scsi_rbc_lob_bytes, tvb, offset+4, 4, 0);
4281             proto_tree_add_item (tree, hf_scsi_rbc_alob_bytes, tvb, offset+8, 4, 0);
4282         }
4283     }
4284 }
4285 static void
4286 dissect_mmc4_reservetrack (tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *tree,
4287                      guint offset, gboolean isreq, gboolean iscdb,
4288                      guint payload_len _U_, scsi_task_data_t *cdata _U_)
4289
4290 {
4291     guint8 flags;
4292
4293     if (tree && isreq && iscdb) {
4294         proto_tree_add_item (tree, hf_scsi_reservation_size, tvb, offset+4, 4, 0);
4295
4296         flags = tvb_get_guint8 (tvb, offset+8);
4297         proto_tree_add_uint_format (tree, hf_scsi_control, tvb, offset+8, 1,
4298                                     flags,
4299                                     "Vendor Unique = %u, NACA = %u, Link = %u",
4300                                     flags & 0xC0, flags & 0x4, flags & 0x1);
4301
4302     }
4303 }
4304
4305 static const value_string scsi_rti_address_type_val[] = {
4306     {0x00,      "Logical Block Address"},
4307     {0x01,      "Logical Track Number"},
4308     {0x02,      "Session Number"},
4309     {0,NULL}
4310 };
4311 static void
4312 dissect_mmc4_readtrackinformation (tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *tree,
4313                      guint offset, gboolean isreq, gboolean iscdb,
4314                      guint payload_len _U_, scsi_task_data_t *cdata _U_)
4315
4316 {
4317     guint8 flags, addresstype;
4318
4319     if (tree && isreq && iscdb) {
4320         addresstype=tvb_get_guint8(tvb, offset)&0x03;
4321         proto_tree_add_item (tree, hf_scsi_rti_address_type, tvb, offset+0, 1, 0);
4322         switch(addresstype){
4323         case 0x00: /* logical block address */
4324             proto_tree_add_item (tree, hf_scsi_lba, tvb, offset+1,
4325                              4, 0);
4326             break;
4327         case 0x01: /* logical track number */
4328             proto_tree_add_item (tree, hf_scsi_track, tvb, offset+1,
4329                              4, 0);
4330             break;
4331         case 0x02: /* logical session number */
4332             proto_tree_add_item (tree, hf_scsi_session, tvb, offset+1,
4333                              4, 0);
4334             break;
4335         }
4336
4337         proto_tree_add_item (tree, hf_scsi_alloclen16, tvb, offset+6, 2, 0);
4338
4339         flags = tvb_get_guint8 (tvb, offset+8);
4340         proto_tree_add_uint_format (tree, hf_scsi_control, tvb, offset+8, 1,
4341                                     flags,
4342                                     "Vendor Unique = %u, NACA = %u, Link = %u",
4343                                     flags & 0xC0, flags & 0x4, flags & 0x1);
4344
4345     }
4346     if(tree && (!isreq)) {
4347         proto_tree_add_item (tree, hf_scsi_data_length, tvb, 0, 2, 0);
4348         /* track  offset+2 and offset+32 */
4349         proto_tree_add_uint (tree, hf_scsi_track, tvb, 2, 1, (tvb_get_guint8(tvb, offset+32)<<8)|tvb_get_guint8(tvb, offset+2));
4350         /* session  offset+3 and offset+33 */
4351         proto_tree_add_uint (tree, hf_scsi_session, tvb, 3, 1, (tvb_get_guint8(tvb, offset+33)<<8)|tvb_get_guint8(tvb, offset+3));
4352         proto_tree_add_item (tree, hf_scsi_rti_damage, tvb, 5, 1, 0);
4353         proto_tree_add_item (tree, hf_scsi_rti_copy, tvb, 5, 1, 0);
4354         proto_tree_add_item (tree, hf_scsi_rti_track_mode, tvb, 5, 1, 0);
4355         proto_tree_add_item (tree, hf_scsi_rti_rt, tvb, 6, 1, 0);
4356         proto_tree_add_item (tree, hf_scsi_rti_blank, tvb, 6, 1, 0);
4357         proto_tree_add_item (tree, hf_scsi_rti_packet, tvb, 6, 1, 0);
4358         proto_tree_add_item (tree, hf_scsi_rti_fp, tvb, 6, 1, 0);
4359         proto_tree_add_item (tree, hf_scsi_rti_data_mode, tvb, 6, 1, 0);
4360         proto_tree_add_item (tree, hf_scsi_rti_lra_v, tvb, 7, 1, 0);
4361         proto_tree_add_item (tree, hf_scsi_rti_nwa_v, tvb, 7, 1, 0);
4362         proto_tree_add_item (tree, hf_scsi_track_start_address, tvb, offset+8, 4, 0);
4363         proto_tree_add_item (tree, hf_scsi_next_writable_address, tvb, offset+12, 4, 0);
4364         proto_tree_add_item (tree, hf_scsi_free_blocks, tvb, offset+16, 4, 0);
4365         proto_tree_add_item (tree, hf_scsi_fixed_packet_size, tvb, offset+20, 4, 0);
4366         proto_tree_add_item (tree, hf_scsi_track_size, tvb, offset+24, 4, 0);
4367         proto_tree_add_item (tree, hf_scsi_last_recorded_address, tvb, offset+28, 4, 0);
4368         proto_tree_add_item (tree, hf_scsi_read_compatibility_lba, tvb, offset+36, 4, 0);
4369     }
4370 }
4371
4372 static const value_string scsi_disc_info_sols_val[] = {
4373     {0x00,      "Empty Session"},
4374     {0x01,      "Incomplete Session"},
4375     {0x02,      "Reserved/Damaged Session"},
4376     {0x03,      "Complete Session"},
4377     {0,NULL}
4378 };
4379 static const value_string scsi_disc_info_disc_status_val[] = {
4380     {0x00,      "Empty Disc"},
4381     {0x01,      "Incomplete Disc"},
4382     {0x02,      "Finalized Disc"},
4383     {0x03,      "Others"},
4384     {0,NULL}
4385 };
4386 static const value_string scsi_disc_info_bgfs_val[] = {
4387     {0x00,      "Blank or not CD-RW/DVD-RW"},
4388     {0x01,      "Background Format started but is not running nor complete"},
4389     {0x02,      "Backgroung Format in progress"},
4390     {0x03,      "Backgroung Format has completed"},
4391     {0,NULL}
4392 };
4393 static const value_string scsi_disc_info_disc_type_val[] = {
4394     {0x00,      "CD-DA or CD-ROM Disc"},
4395     {0x10,      "CD-I Disc"},
4396     {0x20,      "CD-ROM XA Disc or DDCD"},
4397     {0xff,      "Undefined"},
4398     {0,NULL}
4399 };
4400
4401 static void
4402 dissect_mmc4_readdiscinformation (tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *tree,
4403                      guint offset, gboolean isreq, gboolean iscdb,
4404                      guint payload_len _U_, scsi_task_data_t *cdata _U_)
4405
4406 {
4407     guint8 flags;
4408
4409     if (tree && isreq && iscdb) {
4410         proto_tree_add_item (tree, hf_scsi_alloclen16, tvb, offset+6, 2, 0);
4411
4412         flags = tvb_get_guint8 (tvb, offset+8);
4413         proto_tree_add_uint_format (tree, hf_scsi_control, tvb, offset+8, 1,
4414                                     flags,
4415                                     "Vendor Unique = %u, NACA = %u, Link = %u",
4416                                     flags & 0xC0, flags & 0x4, flags & 0x1);
4417
4418     }
4419     if(tree && (!isreq)) {
4420         proto_tree_add_item (tree, hf_scsi_data_length, tvb, 0, 2, 0);
4421         proto_tree_add_item (tree, hf_scsi_disc_info_erasable, tvb, 2, 1, 0);
4422         proto_tree_add_item (tree, hf_scsi_disc_info_state_of_last_session, tvb, 2, 1, 0);
4423         proto_tree_add_item (tree, hf_scsi_disc_info_disk_status, tvb, 2, 1, 0);
4424         proto_tree_add_item (tree, hf_scsi_first_track, tvb, offset+3, 1, 0);
4425         /* number of session  offset+4 and offset+9 */
4426         proto_tree_add_uint (tree, hf_scsi_disc_info_number_of_sessions, tvb, 4, 1, (tvb_get_guint8(tvb, offset+9)<<8)|tvb_get_guint8(tvb, offset+4));
4427         /* first track in last session  offset+5 and offset+10 */
4428         proto_tree_add_uint (tree, hf_scsi_disc_info_first_track_in_last_session, tvb, 5, 1, (tvb_get_guint8(tvb, offset+10)<<8)|tvb_get_guint8(tvb, offset+5));
4429         /*  last track in last session  offset+6 and offset+11 */
4430         proto_tree_add_uint (tree, hf_scsi_disc_info_last_track_in_last_session, tvb, 6, 1, (tvb_get_guint8(tvb, offset+11)<<8)|tvb_get_guint8(tvb, offset+6));
4431         proto_tree_add_item (tree, hf_scsi_disc_info_did_v, tvb, offset+7, 1, 0);
4432         proto_tree_add_item (tree, hf_scsi_disc_info_dbc_v, tvb, offset+7, 1, 0);
4433         proto_tree_add_item (tree, hf_scsi_disc_info_uru, tvb, offset+7, 1, 0);
4434         proto_tree_add_item (tree, hf_scsi_disc_info_dac_v, tvb, offset+7, 1, 0);
4435         proto_tree_add_item (tree, hf_scsi_disc_info_dbit, tvb, offset+7, 1, 0);
4436         proto_tree_add_item (tree, hf_scsi_disc_info_bgfs, tvb, offset+7, 1, 0);
4437         proto_tree_add_item (tree, hf_scsi_disc_info_disc_type, tvb, offset+8, 1, 0);
4438         proto_tree_add_item (tree, hf_scsi_disc_info_disc_identification, tvb, offset+12, 4, 0);
4439         proto_tree_add_item (tree, hf_scsi_disc_info_last_session_lead_in_start_address, tvb, offset+16, 4, 0);
4440         proto_tree_add_item (tree, hf_scsi_disc_info_last_possible_lead_out_start_address, tvb, offset+20, 4, 0);
4441         proto_tree_add_item (tree, hf_scsi_disc_info_disc_bar_code, tvb, offset+24, 8, 0);
4442         /* XXX should add OPC table decoding here ... */
4443     }
4444 }
4445
4446 static void
4447 dissect_sbc2_readcapacity10 (tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *tree,
4448                            guint offset, gboolean isreq, gboolean iscdb,
4449                            guint payload_len _U_, scsi_task_data_t *cdata _U_)
4450 {
4451     guint8 flags;
4452     guint32 len, block_len, tot_len;
4453     const char *un;
4454
4455     if (!tree)
4456         return;
4457
4458     if (isreq && iscdb) {
4459         flags = tvb_get_guint8 (tvb, offset);
4460
4461         proto_tree_add_uint_format (tree, hf_scsi_readcapacity_flags, tvb,
4462                                     offset, 1, flags,
4463                                     "LongLBA = %u, RelAddr = %u",
4464                                     flags & 0x2, flags & 0x1);
4465         proto_tree_add_item (tree, hf_scsi_readcapacity_lba, tvb, offset+1,
4466                              4, 0);
4467         proto_tree_add_item (tree, hf_scsi_readcapacity_pmi, tvb, offset+7,
4468                              1, 0);
4469
4470         flags = tvb_get_guint8 (tvb, offset+8);
4471         proto_tree_add_uint_format (tree, hf_scsi_control, tvb, offset+8, 1,
4472                                     flags,
4473                                     "Vendor Unique = %u, NACA = %u, Link = %u",
4474                                     flags & 0xC0, flags & 0x4, flags & 0x1);
4475     }
4476     else if (!iscdb) {
4477         len = tvb_get_ntohl (tvb, offset);
4478         block_len = tvb_get_ntohl (tvb, offset+4);
4479         tot_len=((len/1024)*block_len)/1024; /*MB*/
4480         un="MB";
4481         if(tot_len>20000){
4482             tot_len/=1024;
4483             un="GB";
4484         }
4485         proto_tree_add_text (tree, tvb, offset, 4, "LBA: %u (%u %s)",
4486                              len, tot_len, un);
4487         proto_tree_add_text (tree, tvb, offset+4, 4, "Block Length: %u bytes",
4488                              block_len);
4489     }
4490 }
4491
4492 #define SHORT_FORM_BLOCK_ID        0x00
4493 #define SHORT_FORM_VENDOR_SPECIFIC 0x01
4494 #define LONG_FORM                  0x06
4495 #define EXTENDED_FORM              0x08
4496 #define SERVICE_READ_CAPACITY16 0x10
4497 #define SERVICE_READ_LONG16     0x11
4498
4499 static const value_string service_action_vals[] = {
4500         {SHORT_FORM_BLOCK_ID,        "Short Form - Block ID"},
4501         {SHORT_FORM_VENDOR_SPECIFIC, "Short Form - Vendor-Specific"},
4502         {LONG_FORM,                  "Long Form"},
4503         {EXTENDED_FORM,              "Extended Form"},
4504         {SERVICE_READ_CAPACITY16,    "Read Capacity(16)"},
4505         {SERVICE_READ_LONG16,        "Read Long(16)"},
4506         {0, NULL}
4507 };
4508
4509
4510 /* this is either readcapacity16  or  readlong16  depending of what service
4511    action is set to.   for now we only implement readcapacity16
4512 */
4513 static void
4514 dissect_sbc2_serviceactionin16 (tvbuff_t *tvb, packet_info *pinfo _U_,
4515                            proto_tree *tree, guint offset, gboolean isreq,
4516                            gboolean iscdb,
4517                            guint payload_len _U_, scsi_task_data_t *cdata _U_)
4518 {
4519     guint8 service_action, flags;
4520     guint32 block_len;
4521     guint64 len, tot_len;
4522     char *un;
4523
4524     if (!tree)
4525         return;
4526
4527     if (isreq && iscdb) {
4528         service_action = tvb_get_guint8 (tvb, offset) & 0x1F;
4529         /* we should store this one for later so the data in can be decoded */
4530         switch(service_action){
4531         case SERVICE_READ_CAPACITY16:
4532                 proto_tree_add_text (tree, tvb, offset, 1,
4533                              "Service Action: %s",
4534                              val_to_str (service_action,
4535                                          service_action_vals,
4536                                          "Unknown (0x%02x)"));
4537                 offset++;
4538
4539                 proto_tree_add_text (tree, tvb, offset, 8,
4540                              "Logical Block Address: %" PRIu64,
4541                               tvb_get_ntoh64 (tvb, offset));
4542                 offset += 8;
4543
4544                 proto_tree_add_item (tree, hf_scsi_alloclen32, tvb, offset, 4, 0);
4545                 offset += 4;
4546
4547                 proto_tree_add_item (tree, hf_scsi_readcapacity_pmi, tvb, offset, 1, 0);
4548                 offset++;
4549
4550                 flags = tvb_get_guint8 (tvb, offset);
4551                 proto_tree_add_uint_format (tree, hf_scsi_control, tvb, offset, 1,
4552                                     flags,
4553                                     "Vendor Unique = %u, NACA = %u, Link = %u",
4554                                     flags & 0xC0, flags & 0x4, flags & 0x1);
4555                 offset++;
4556
4557                 break;
4558         };
4559     } else if (!iscdb) {
4560         /* assuming for now that all such data in PDUs are read capacity16 */
4561         len = tvb_get_ntoh64 (tvb, offset);
4562         block_len = tvb_get_ntohl (tvb, offset+8);
4563         tot_len=((len/1024)*block_len)/1024; /*MB*/
4564         un="MB";
4565         if(tot_len>20000){
4566             tot_len/=1024;
4567             un="GB";
4568         }
4569         proto_tree_add_text (tree, tvb, offset, 8, "LBA: %" PRIu64 " (%" PRIu64 " %s)",
4570                              len, tot_len, un);
4571         proto_tree_add_text (tree, tvb, offset+8, 4, "Block Length: %u bytes",
4572                              block_len);
4573     }
4574 }
4575
4576 static void
4577 dissect_sbc2_readdefectdata10 (tvbuff_t *tvb, packet_info *pinfo _U_,
4578                             proto_tree *tree, guint offset, gboolean isreq,
4579                             gboolean iscdb,
4580                             guint payload_len _U_, scsi_task_data_t *cdata _U_)
4581 {
4582     guint8 flags;
4583
4584     if (!tree)
4585         return;
4586
4587     if (isreq && iscdb) {
4588         flags = tvb_get_guint8 (tvb, offset);
4589
4590         proto_tree_add_uint_format (tree, hf_scsi_readdefdata_flags, tvb,
4591                                     offset, 1, flags, "PLIST = %u, GLIST = %u",
4592                                     flags & 0x10, flags & 0x8);
4593         proto_tree_add_item (tree, hf_scsi_cdb_defectfmt, tvb, offset, 1, 0);
4594         proto_tree_add_item (tree, hf_scsi_alloclen16, tvb, offset+6, 2, 0);
4595         flags = tvb_get_guint8 (tvb, offset+8);
4596         proto_tree_add_uint_format (tree, hf_scsi_control, tvb, offset+8, 1,
4597                                     flags,
4598                                     "Vendor Unique = %u, NACA = %u, Link = %u",
4599                                     flags & 0xC0, flags & 0x4, flags & 0x1);
4600     }
4601 }
4602
4603 static void
4604 dissect_sbc2_readdefectdata12 (tvbuff_t *tvb, packet_info *pinfo _U_,
4605                             proto_tree *tree, guint offset, gboolean isreq,
4606                             gboolean iscdb,
4607                             guint payload_len _U_, scsi_task_data_t *cdata _U_)
4608 {
4609     guint8 flags;
4610
4611     if (!tree)
4612         return;
4613
4614     if (isreq && iscdb) {
4615         flags = tvb_get_guint8 (tvb, offset);
4616
4617         proto_tree_add_uint_format (tree, hf_scsi_readdefdata_flags, tvb,
4618                                     offset, 1, flags, "PLIST = %u, GLIST = %u",
4619                                     flags & 0x10, flags & 0x8);
4620         proto_tree_add_item (tree, hf_scsi_cdb_defectfmt, tvb, offset, 1, 0);
4621         proto_tree_add_item (tree, hf_scsi_alloclen32, tvb, offset+5, 4, 0);
4622         flags = tvb_get_guint8 (tvb, offset+10);
4623         proto_tree_add_uint_format (tree, hf_scsi_control, tvb, offset+10, 1,
4624                                     flags,
4625                                     "Vendor Unique = %u, NACA = %u, Link = %u",
4626                                     flags & 0xC0, flags & 0x4, flags & 0x1);
4627     }
4628 }
4629
4630 static void
4631 dissect_sbc2_reassignblocks (tvbuff_t *tvb, packet_info *pinfo _U_,
4632                            proto_tree *tree, guint offset, gboolean isreq,
4633                            gboolean iscdb,
4634                            guint payload_len _U_, scsi_task_data_t *cdata _U_)
4635 {
4636     guint8 flags;
4637
4638     if (!tree)
4639         return;
4640
4641     if (isreq && iscdb) {
4642         flags = tvb_get_guint8 (tvb, offset);
4643
4644         proto_tree_add_uint_format (tree, hf_scsi_reassignblks_flags, tvb,
4645                                     offset, 1, flags,
4646                                     "LongLBA = %u, LongList = %u",
4647                                     flags & 0x2, flags & 0x1);
4648         flags = tvb_get_guint8 (tvb, offset+4);
4649         proto_tree_add_uint_format (tree, hf_scsi_control, tvb, offset+4, 1,
4650                                     flags,
4651                                     "Vendor Unique = %u, NACA = %u, Link = %u",
4652                                     flags & 0xC0, flags & 0x4, flags & 0x1);
4653     }
4654 }
4655
4656 static void
4657 dissect_spc3_senddiagnostic (tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *tree,
4658                           guint offset, gboolean isreq, gboolean iscdb _U_,
4659                           guint payload_len _U_, scsi_task_data_t *cdata _U_)
4660 {
4661     guint8 flags;
4662
4663     if (!tree && !isreq)
4664         return;
4665
4666     proto_tree_add_uint (tree, hf_scsi_senddiag_st_code, tvb, offset, 1, 0);
4667     proto_tree_add_boolean (tree, hf_scsi_senddiag_pf, tvb, offset, 1, 0);
4668     proto_tree_add_boolean (tree, hf_scsi_senddiag_st, tvb, offset, 1, 0);
4669     proto_tree_add_boolean (tree, hf_scsi_senddiag_devoff, tvb, offset, 1, 0);
4670     proto_tree_add_boolean (tree, hf_scsi_senddiag_unitoff, tvb, offset, 1, 0);
4671     proto_tree_add_uint (tree, hf_scsi_paramlen16, tvb, offset+2, 2, 0);
4672
4673     flags = tvb_get_guint8 (tvb, offset+4);
4674     proto_tree_add_uint_format (tree, hf_scsi_control, tvb, offset+8, 1,
4675                                 flags,
4676                                 "Vendor Unique = %u, NACA = %u, Link = %u",
4677                                 flags & 0xC0, flags & 0x4, flags & 0x1);
4678 }
4679
4680 static void
4681 dissect_spc3_writebuffer (tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *tree,
4682                           guint offset, gboolean isreq, gboolean iscdb _U_,
4683                           guint payload_len _U_, scsi_task_data_t *cdata _U_)
4684 {
4685     guint8 flags;
4686
4687     if (!tree && !isreq)
4688         return;
4689
4690     proto_tree_add_uint (tree, hf_scsi_wb_mode, tvb, offset, 1, 0);
4691     proto_tree_add_uint (tree, hf_scsi_wb_bufferid, tvb, offset+1, 1, 0);
4692     proto_tree_add_uint (tree, hf_scsi_wb_bufoffset, tvb, offset+2, 3, 0);
4693     proto_tree_add_uint (tree, hf_scsi_paramlen24, tvb, offset+5, 3, 0);
4694
4695     flags = tvb_get_guint8 (tvb, offset+8);
4696     proto_tree_add_uint_format (tree, hf_scsi_control, tvb, offset+8, 1,
4697                                 flags,
4698                                 "Vendor Unique = %u, NACA = %u, Link = %u",
4699                                 flags & 0xC0, flags & 0x4, flags & 0x1);
4700 }
4701
4702 static void
4703 dissect_scsi_varlencdb (tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *tree,
4704                         guint offset, gboolean isreq, gboolean iscdb,
4705                         guint payload_len _U_, scsi_task_data_t *cdata _U_)
4706 {
4707     if (!tree)
4708         return;
4709
4710     if (isreq && iscdb) {
4711         proto_tree_add_item (tree, hf_scsi_control, tvb, offset, 1, 0);
4712         proto_tree_add_item (tree, hf_scsi_add_cdblen, tvb, offset+6, 1, 0);
4713         proto_tree_add_item (tree, hf_scsi_svcaction, tvb, offset+7, 2, 0);
4714
4715     }
4716 }
4717
4718 static void
4719 dissect_ssc2_read6 (tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *tree,
4720                     guint offset, gboolean isreq, gboolean iscdb,
4721                     guint payload_len _U_, scsi_task_data_t *cdata _U_)
4722 {
4723     guint8 flags;
4724
4725     if (isreq) {
4726         if (check_col (pinfo->cinfo, COL_INFO))
4727             col_append_fstr (pinfo->cinfo, COL_INFO, "(Len: %u)",
4728                              tvb_get_ntoh24 (tvb, offset+1));
4729     }
4730
4731     if (tree && isreq && iscdb) {
4732         flags = tvb_get_guint8 (tvb, offset);
4733         proto_tree_add_text (tree, tvb, offset, 1,
4734                              "SILI: %u, FIXED: %u",
4735                              (flags & 0x02) >> 1, flags & 0x01);
4736         proto_tree_add_item (tree, hf_scsi_rdwr6_xferlen, tvb, offset+1, 3, 0);
4737         flags = tvb_get_guint8 (tvb, offset+4);
4738         proto_tree_add_uint_format (tree, hf_scsi_control, tvb, offset+4, 1,
4739                                     flags,
4740                                     "Vendor Unique = %u, NACA = %u, Link = %u",
4741                                     flags & 0xC0, flags & 0x4, flags & 0x1);
4742     }
4743 }
4744
4745 static void
4746 dissect_ssc2_write6 (tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *tree,
4747                     guint offset, gboolean isreq, gboolean iscdb,
4748                     guint payload_len _U_, scsi_task_data_t *cdata _U_)
4749 {
4750     guint8 flags;
4751
4752     if (isreq && iscdb) {
4753         if (check_col (pinfo->cinfo, COL_INFO))
4754             col_append_fstr (pinfo->cinfo, COL_INFO, "(Len: %u)",
4755                              tvb_get_ntoh24 (tvb, offset+1));
4756     }
4757
4758     if (tree && isreq && iscdb) {
4759         flags = tvb_get_guint8 (tvb, offset);
4760         proto_tree_add_text (tree, tvb, offset, 1,
4761                              "FIXED: %u", flags & 0x01);
4762         proto_tree_add_item (tree, hf_scsi_rdwr6_xferlen, tvb, offset+1, 3,
4763                              FALSE);
4764         flags = tvb_get_guint8 (tvb, offset+4);
4765         proto_tree_add_uint_format (tree, hf_scsi_control, tvb, offset+4, 1,
4766                                     flags,
4767                                     "Vendor Unique = %u, NACA = %u, Link = %u",
4768                                     flags & 0xC0, flags & 0x4, flags & 0x1);
4769     }
4770 }
4771
4772 static void
4773 dissect_ssc2_writefilemarks6 (tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *tree,
4774                     guint offset, gboolean isreq, gboolean iscdb,
4775                     guint payload_len _U_, scsi_task_data_t *cdata _U_)
4776 {
4777     guint8 flags;
4778
4779     if (isreq) {
4780         if (check_col (pinfo->cinfo, COL_INFO))
4781             col_append_fstr (pinfo->cinfo, COL_INFO, "(Len: %u)",
4782                              tvb_get_ntoh24 (tvb, offset+1));
4783     }
4784
4785     if (tree && isreq && iscdb) {
4786         flags = tvb_get_guint8 (tvb, offset);
4787         proto_tree_add_text (tree, tvb, offset, 1,
4788                              "WSMK: %u, IMMED: %u",
4789                              (flags & 0x02) >> 1, flags & 0x01);
4790         proto_tree_add_item (tree, hf_scsi_rdwr6_xferlen, tvb, offset+1, 3,
4791                              FALSE);
4792         flags = tvb_get_guint8 (tvb, offset+4);
4793         proto_tree_add_uint_format (tree, hf_scsi_control, tvb, offset+4, 1,
4794                                     flags,
4795                                     "Vendor Unique = %u, NACA = %u, Link = %u",
4796                                     flags & 0xC0, flags & 0x4, flags & 0x1);
4797     }
4798 }
4799
4800 static void
4801 dissect_ssc2_loadunload (tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *tree,
4802                     guint offset, gboolean isreq, gboolean iscdb,
4803                     guint payload_len _U_, scsi_task_data_t *cdata _U_)
4804 {
4805     guint8 flags;
4806
4807     if (isreq && iscdb) {
4808         if (check_col (pinfo->cinfo, COL_INFO))
4809             col_append_fstr (pinfo->cinfo, COL_INFO, "(Immed: %u)",
4810                              tvb_get_guint8 (tvb, offset) & 0x01);
4811
4812         if (!tree)
4813             return;
4814
4815         proto_tree_add_text (tree, tvb, offset, 1,
4816                              "Immed: %u", tvb_get_guint8 (tvb, offset) & 0x01);
4817         flags = tvb_get_guint8 (tvb, offset+3);
4818         proto_tree_add_text (tree, tvb, offset+3, 1,
4819                              "Hold: %u, EOT: %u, Reten: %u, Load: %u",
4820                              (flags & 0x08) >> 3, (flags & 0x04) >> 2,
4821                              (flags & 0x02) >> 1, (flags & 0x01));
4822         flags = tvb_get_guint8 (tvb, offset+4);
4823         proto_tree_add_uint_format (tree, hf_scsi_control, tvb, offset+4, 1,
4824                                     flags,
4825                                     "Vendor Unique = %u, NACA = %u, Link = %u",
4826                                     flags & 0xC0, flags & 0x4, flags & 0x1);
4827     }
4828 }
4829
4830 static void
4831 dissect_ssc2_readblocklimits (tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *tree,
4832                     guint offset, gboolean isreq, gboolean iscdb,
4833                     guint payload_len _U_, scsi_task_data_t *cdata _U_)
4834 {
4835     guint8 flags, granularity;
4836
4837     if (!tree)
4838         return;
4839
4840     if (isreq && iscdb) {
4841         flags = tvb_get_guint8 (tvb, offset+4);
4842         proto_tree_add_uint_format (tree, hf_scsi_control, tvb, offset+4, 1,
4843                                     flags,
4844                                     "Vendor Unique = %u, NACA = %u, Link = %u",
4845                                     flags & 0xC0, flags & 0x4, flags & 0x1);
4846     }
4847     else if (!iscdb) {
4848         granularity = tvb_get_guint8 (tvb, offset);
4849         proto_tree_add_text (tree, tvb, offset, 1, "Granularity: %u (%u %s)",
4850                              granularity, 1 << granularity,
4851                              plurality(1 << granularity, "byte", "bytes"));
4852         proto_tree_add_text (tree, tvb, offset+1, 3, "Maximum Block Length Limit: %u bytes",
4853                              tvb_get_ntoh24 (tvb, offset+1));
4854         proto_tree_add_text (tree, tvb, offset+4, 2, "Minimum Block Length Limit: %u bytes",
4855                              tvb_get_ntohs (tvb, offset+4));
4856     }
4857 }
4858
4859 #define BCU  0x20
4860 #define BYCU 0x10
4861 #define MPU  0x08
4862 #define BPU  0x04
4863
4864 static void
4865 dissect_ssc2_readposition (tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *tree,
4866                     guint offset, gboolean isreq, gboolean iscdb,
4867                     guint payload_len _U_, scsi_task_data_t *cdata)
4868 {
4869     gint service_action;
4870     guint8 flags;
4871
4872     if (!tree)
4873         return;
4874
4875     if (isreq && iscdb) {
4876         service_action = tvb_get_guint8 (tvb, offset) & 0x1F;
4877         proto_tree_add_text (tree, tvb, offset, 1,
4878                              "Service Action: %s",
4879                              val_to_str (service_action,
4880                                          service_action_vals,
4881                                          "Unknown (0x%02x)"));
4882         /* Remember the service action so we can decode the reply */
4883         if (cdata != NULL) {
4884             cdata->flags = service_action;
4885         }
4886         proto_tree_add_text (tree, tvb, offset+6, 2,
4887                              "Parameter Len: %u",
4888                              tvb_get_ntohs (tvb, offset+6));
4889         flags = tvb_get_guint8 (tvb, offset+8);
4890         proto_tree_add_uint_format (tree, hf_scsi_control, tvb, offset+8, 1,
4891                                     flags,
4892                                     "Vendor Unique = %u, NACA = %u, Link = %u",
4893                                     flags & 0xC0, flags & 0x4, flags & 0x1);
4894     }
4895     else if (!isreq) {
4896         if (cdata)
4897             service_action = cdata->flags;
4898         else
4899             service_action = -1; /* unknown */
4900         switch (service_action) {
4901         case SHORT_FORM_BLOCK_ID:
4902         case SHORT_FORM_VENDOR_SPECIFIC:
4903             flags = tvb_get_guint8 (tvb, offset);
4904             proto_tree_add_text (tree, tvb, offset, 1,
4905                              "BOP: %u, EOP: %u, BCU: %u, BYCU: %u, BPU: %u, PERR: %u",
4906                              (flags & 0x80) >> 7, (flags & 0x40) >> 6,
4907                              (flags & BCU) >> 5, (flags & BYCU) >> 4,
4908                              (flags & BPU) >> 2, (flags & 0x02) >> 1);
4909             offset += 1;
4910
4911             proto_tree_add_text (tree, tvb, offset, 1,
4912                                  "Partition Number: %u",
4913                                  tvb_get_guint8 (tvb, offset));
4914             offset += 1;
4915
4916             offset += 2; /* reserved */
4917
4918             if (!(flags & BPU)) {
4919                 proto_tree_add_text (tree, tvb, offset, 4,
4920                                      "First Block Location: %u",
4921                                      tvb_get_ntohl (tvb, offset));
4922                 offset += 4;
4923
4924                 proto_tree_add_text (tree, tvb, offset, 4,
4925                                      "Last Block Location: %u",
4926                                      tvb_get_ntohl (tvb, offset));
4927                 offset += 4;
4928             } else
4929                 offset += 8;
4930
4931             offset += 1; /* reserved */
4932
4933             if (!(flags & BCU)) {
4934                 proto_tree_add_text (tree, tvb, offset, 3,
4935                                      "Number of Blocks in Buffer: %u",
4936                                      tvb_get_ntoh24 (tvb, offset));
4937             }
4938             offset += 3;
4939
4940             if (!(flags & BYCU)) {
4941                 proto_tree_add_text (tree, tvb, offset, 4,
4942                                      "Number of Bytes in Buffer: %u",
4943                                      tvb_get_ntohl (tvb, offset));
4944             }
4945             offset += 4;
4946             break;
4947
4948         case LONG_FORM:
4949             flags = tvb_get_guint8 (tvb, offset);
4950             proto_tree_add_text (tree, tvb, offset, 1,
4951                              "BOP: %u, EOP: %u, MPU: %u, BPU: %u",
4952                              (flags & 0x80) >> 7, (flags & 0x40) >> 6,
4953                              (flags & MPU) >> 3, (flags & BPU) >> 2);
4954             offset += 1;
4955
4956             offset += 3; /* reserved */
4957
4958             if (!(flags & BPU)) {
4959                 proto_tree_add_text (tree, tvb, offset, 4,
4960                                      "Partition Number: %u",
4961                                      tvb_get_ntohl (tvb, offset));
4962                 offset += 4;
4963
4964                 proto_tree_add_text (tree, tvb, offset, 8,
4965                                      "Block Number: %" PRIu64,
4966                                      tvb_get_ntoh64 (tvb, offset));
4967                  offset += 8;
4968             } else
4969                 offset += 12;
4970
4971             if (!(flags & MPU)) {
4972                 proto_tree_add_text (tree, tvb, offset, 8,
4973                                      "File Number: %" PRIu64,
4974                                      tvb_get_ntoh64 (tvb, offset));
4975                 offset += 8;
4976
4977                 proto_tree_add_text (tree, tvb, offset, 8,
4978                                      "Set Number: %" PRIu64,
4979                                      tvb_get_ntoh64 (tvb, offset));
4980                 offset += 8;
4981             } else
4982                 offset += 16;
4983             break;
4984
4985         case EXTENDED_FORM:
4986             flags = tvb_get_guint8 (tvb, offset);
4987             proto_tree_add_text (tree, tvb, offset, 1,
4988                              "BOP: %u, EOP: %u, BCU: %u, BYCU: %u, MPU: %u, BPU: %u, PERR: %u",
4989                              (flags & 0x80) >> 7, (flags & 0x40) >> 6,
4990                              (flags & BCU) >> 5, (flags & BYCU) >> 4,
4991                              (flags & MPU) >> 3, (flags & BPU) >> 2,
4992                              (flags & 0x02) >> 1);
4993             offset += 1;
4994
4995             proto_tree_add_text (tree, tvb, offset, 1,
4996                                  "Partition Number: %u",
4997                                  tvb_get_guint8 (tvb, offset));
4998             offset += 1;
4999
5000             proto_tree_add_text (tree, tvb, offset, 2,
5001                                  "Additional Length: %u",
5002                                  tvb_get_ntohs (tvb, offset));
5003             offset += 2;
5004
5005             offset += 1; /* reserved */
5006
5007             if (!(flags & BCU)) {
5008                 proto_tree_add_text (tree, tvb, offset, 3,
5009                                      "Number of Blocks in Buffer: %u",
5010                                      tvb_get_ntoh24 (tvb, offset));
5011             }
5012             offset += 3;
5013
5014             if (!(flags & BPU)) {
5015                 proto_tree_add_text (tree, tvb, offset, 8,
5016                                      "First Block Location: %" PRIu64,
5017                                      tvb_get_ntoh64 (tvb, offset));
5018                 offset += 8;
5019
5020                 proto_tree_add_text (tree, tvb, offset, 8,
5021                                      "Last Block Location: %" PRIu64,
5022                                      tvb_get_ntoh64 (tvb, offset));
5023                 offset += 8;
5024             } else
5025                 offset += 16;
5026
5027             offset += 1; /* reserved */
5028
5029             if (!(flags & BYCU)) {
5030                 proto_tree_add_text (tree, tvb, offset, 8,
5031                                      "Number of Bytes in Buffer: %" PRIu64,
5032                                      tvb_get_ntoh64 (tvb, offset));
5033             }
5034             offset += 8;
5035             break;
5036
5037         default:
5038             break;
5039         }
5040     }
5041 }
5042
5043
5044 static void
5045 dissect_ssc2_rewind (tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *tree,
5046                     guint offset, gboolean isreq, gboolean iscdb,
5047                     guint payload_len _U_, scsi_task_data_t *cdata _U_)
5048 {
5049     guint8 flags;
5050
5051     if (isreq && iscdb) {
5052         if (check_col (pinfo->cinfo, COL_INFO))
5053             col_append_fstr (pinfo->cinfo, COL_INFO, "(Immed: %u)",
5054                              tvb_get_guint8 (tvb, offset) & 0x01);
5055
5056         if (!tree)
5057             return;
5058
5059         proto_tree_add_text (tree, tvb, offset, 1,
5060                              "Immed: %u", tvb_get_guint8 (tvb, offset) & 0x01);
5061         flags = tvb_get_guint8 (tvb, offset+4);
5062         proto_tree_add_uint_format (tree, hf_scsi_control, tvb, offset+4, 1,
5063                                     flags,
5064                                     "Vendor Unique = %u, NACA = %u, Link = %u",
5065                                     flags & 0xC0, flags & 0x4, flags & 0x1);
5066     }
5067 }
5068
5069 static void
5070 dissect_ssc2_locate10 (tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *tree,
5071                     guint offset, gboolean isreq, gboolean iscdb,
5072                     guint payload_len _U_, scsi_task_data_t *cdata _U_)
5073 {
5074     guint8 flags;
5075
5076     if (isreq && iscdb) {
5077         if (!tree)
5078             return;
5079
5080         flags = tvb_get_guint8 (tvb, offset);
5081         proto_tree_add_text (tree, tvb, offset, 1,
5082                              "BT: %u, CP: %u, IMMED: %u",
5083                              (flags & 0x04) >> 2,
5084                              (flags & 0x02) >> 1,
5085                              flags & 0x01);
5086
5087         proto_tree_add_item (tree, hf_ssc3_locate10_loid, tvb, offset+2, 4, 0);
5088
5089         flags = tvb_get_guint8 (tvb, offset+7);
5090         proto_tree_add_text (tree, tvb, offset+7, 1,
5091                              "Partition: %u",
5092                             flags);
5093
5094         flags = tvb_get_guint8 (tvb, offset+8);
5095         proto_tree_add_uint_format (tree, hf_scsi_control, tvb, offset+8, 1,
5096                                     flags,
5097                                     "Vendor Unique = %u, NACA = %u, Link = %u",
5098                                     flags & 0xC0, flags & 0x4, flags & 0x1);
5099     }
5100 }
5101
5102 static void
5103 dissect_ssc2_locate16 (tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *tree,
5104                     guint offset, gboolean isreq, gboolean iscdb,
5105                     guint payload_len _U_, scsi_task_data_t *cdata _U_)
5106 {
5107     guint8 flags;
5108
5109     if (isreq && iscdb) {
5110         if (!tree)
5111             return;
5112
5113         flags = tvb_get_guint8 (tvb, offset);
5114         proto_tree_add_text (tree, tvb, offset, 1,
5115                              "DEST_TYPE: %u, CP: %u, IMMED: %u",
5116                              (flags & 0x18) >> 3,
5117                              (flags & 0x02) >> 1,
5118                              flags & 0x01);
5119
5120         flags = tvb_get_guint8 (tvb, offset+2);
5121         proto_tree_add_text (tree, tvb, offset+2, 1,
5122                              "Partition: %u",
5123                             flags);
5124
5125         proto_tree_add_item (tree, hf_ssc3_locate16_loid, tvb, offset+3, 8, 0);
5126
5127         flags = tvb_get_guint8 (tvb, offset+14);
5128         proto_tree_add_uint_format (tree, hf_scsi_control, tvb, offset+14, 1,
5129                                     flags,
5130                                     "Vendor Unique = %u, NACA = %u, Link = %u",
5131                                     flags & 0xC0, flags & 0x4, flags & 0x1);
5132     }
5133 }
5134
5135 static void
5136 dissect_ssc2_erase6 (tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *tree,
5137                     guint offset, gboolean isreq, gboolean iscdb,
5138                     guint payload_len _U_, scsi_task_data_t *cdata _U_)
5139 {
5140     guint8 flags;
5141
5142     if (isreq && iscdb) {
5143         if (!tree)
5144             return;
5145
5146         flags = tvb_get_guint8 (tvb, offset);
5147         proto_tree_add_text (tree, tvb, offset, 1,
5148                              "IMMED: %u, LONG: %u",
5149                              (flags & 0x02) >> 1,
5150                              flags & 0x01);
5151
5152         flags = tvb_get_guint8 (tvb, offset+4);
5153         proto_tree_add_uint_format (tree, hf_scsi_control, tvb, offset+4, 1,
5154                                     flags,
5155                                     "Vendor Unique = %u, NACA = %u, Link = %u",
5156                                     flags & 0xC0, flags & 0x4, flags & 0x1);
5157     }
5158 }
5159
5160 static void
5161 dissect_ssc2_erase16 (tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *tree,
5162                     guint offset, gboolean isreq, gboolean iscdb,
5163                     guint payload_len _U_, scsi_task_data_t *cdata _U_)
5164 {
5165     guint8 flags;
5166
5167     if (isreq && iscdb) {
5168         if (!tree)
5169             return;
5170
5171         flags = tvb_get_guint8 (tvb, offset);
5172         proto_tree_add_text (tree, tvb, offset, 1,
5173                              "FCS: %u, LCS: %u, IMMED: %u, LONG: %u",
5174                              (flags & 0x08) >> 3,
5175                              (flags & 0x04) >> 2,
5176                              (flags & 0x02) >> 1,
5177                              flags & 0x01);
5178
5179         proto_tree_add_text (tree, tvb, offset+2, 1,
5180                              "Partition: %u", tvb_get_guint8(tvb,offset+2));
5181
5182         proto_tree_add_text (tree, tvb, offset+3, 8,
5183                              "Logical Object Identifier: 0x%02x%02x%02x%02x%02x%02x%02x%02x",
5184                              tvb_get_guint8(tvb,offset+3),
5185                              tvb_get_guint8(tvb,offset+4),
5186                              tvb_get_guint8(tvb,offset+5),
5187                              tvb_get_guint8(tvb,offset+6),
5188                              tvb_get_guint8(tvb,offset+7),
5189                              tvb_get_guint8(tvb,offset+8),
5190                              tvb_get_guint8(tvb,offset+9),
5191                              tvb_get_guint8(tvb,offset+10));
5192
5193         flags = tvb_get_guint8 (tvb, offset+14);
5194         proto_tree_add_uint_format (tree, hf_scsi_control, tvb, offset+14, 1,
5195                                     flags,
5196                                     "Vendor Unique = %u, NACA = %u, Link = %u",
5197                                     flags & 0xC0, flags & 0x4, flags & 0x1);
5198     }
5199 }
5200
5201 static void
5202 dissect_ssc2_space6 (tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *tree,
5203                     guint offset, gboolean isreq, gboolean iscdb,
5204                     guint payload_len _U_, scsi_task_data_t *cdata _U_)
5205 {
5206     guint8 flags;
5207
5208     if (isreq && iscdb) {
5209         if (!tree)
5210             return;
5211
5212         flags = tvb_get_guint8 (tvb, offset);
5213         proto_tree_add_text (tree, tvb, offset, 1,
5214                              "CODE: %u",
5215                              flags & 0x0f);
5216
5217         proto_tree_add_item (tree, hf_ssc3_space6_count, tvb, offset+1, 3, 0);
5218
5219         flags = tvb_get_guint8 (tvb, offset+4);
5220         proto_tree_add_uint_format (tree, hf_scsi_control, tvb, offset+4, 1,
5221                                     flags,
5222                                     "Vendor Unique = %u, NACA = %u, Link = %u",
5223                                     flags & 0xC0, flags & 0x4, flags & 0x1);
5224     }
5225 }
5226
5227 static void
5228 dissect_ssc2_space16 (tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *tree,
5229                     guint offset, gboolean isreq, gboolean iscdb,
5230                     guint payload_len _U_, scsi_task_data_t *cdata _U_)
5231 {
5232     guint8 flags;
5233
5234     if (isreq && iscdb) {
5235         if (!tree)
5236             return;
5237
5238         flags = tvb_get_guint8 (tvb, offset);
5239         proto_tree_add_text (tree, tvb, offset, 1,
5240                              "CODE: %u",
5241                              flags & 0x0f);
5242
5243         proto_tree_add_item (tree, hf_ssc3_space16_count, tvb, offset+3, 8, 0);
5244
5245         proto_tree_add_text (tree, tvb, offset+11, 2,
5246                              "Parameter Len: %u",
5247                              tvb_get_ntohs (tvb, offset+11));
5248
5249         flags = tvb_get_guint8 (tvb, offset+14);
5250         proto_tree_add_uint_format (tree, hf_scsi_control, tvb, offset+14, 1,
5251                                     flags,
5252                                     "Vendor Unique = %u, NACA = %u, Link = %u",
5253                                     flags & 0xC0, flags & 0x4, flags & 0x1);
5254     }
5255 }
5256
5257 static void
5258 dissect_ssc2_formatmedium (tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *tree,
5259                     guint offset, gboolean isreq, gboolean iscdb,
5260                     guint payload_len _U_, scsi_task_data_t *cdata _U_)
5261 {
5262     guint8 flags;
5263
5264     if (isreq && iscdb) {
5265         if (!tree)
5266             return;
5267
5268         flags = tvb_get_guint8 (tvb, offset);
5269         proto_tree_add_text (tree, tvb, offset, 1,
5270                              "VERIFY: %u, IMMED: %u",
5271                              (flags & 0x02) >> 1,
5272                              flags & 0x01);
5273
5274         proto_tree_add_text (tree, tvb, offset+1, 1,
5275                              "Format: 0x%02x", tvb_get_guint8(tvb,offset+1)&0x0f);
5276
5277         proto_tree_add_item (tree, hf_scsi_rdwr10_xferlen, tvb, offset+2, 2, 0);
5278
5279         flags = tvb_get_guint8 (tvb, offset+4);
5280         proto_tree_add_uint_format (tree, hf_scsi_control, tvb, offset+4, 1,
5281                                     flags,
5282                                     "Vendor Unique = %u, NACA = %u, Link = %u",
5283                                     flags & 0xC0, flags & 0x4, flags & 0x1);
5284     }
5285 }
5286
5287 static void
5288 dissect_smc2_movemedium (tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *tree,
5289                     guint offset, gboolean isreq, gboolean iscdb,
5290                     guint payload_len _U_, scsi_task_data_t *cdata _U_)
5291 {
5292     guint8 flags;
5293
5294     if (tree && isreq && iscdb) {
5295         proto_tree_add_text (tree, tvb, offset+1, 2,
5296                              "Medium Transport Address: %u",
5297                              tvb_get_ntohs (tvb, offset+1));
5298         proto_tree_add_text (tree, tvb, offset+3, 2,
5299                              "Source Address: %u",
5300                              tvb_get_ntohs (tvb, offset+3));
5301         proto_tree_add_text (tree, tvb, offset+5, 2,
5302                              "Destination Address: %u",
5303                              tvb_get_ntohs (tvb, offset+5));
5304         flags = tvb_get_guint8 (tvb, offset+9);
5305         proto_tree_add_text (tree, tvb, offset+9, 1,
5306                              "INV: %u", flags & 0x01);
5307         flags = tvb_get_guint8 (tvb, offset+10);
5308         proto_tree_add_uint_format (tree, hf_scsi_control, tvb, offset+10, 1,
5309                                     flags,
5310                                     "Vendor Unique = %u, NACA = %u, Link = %u",
5311                                     flags & 0xC0, flags & 0x4, flags & 0x1);
5312     }
5313 }
5314
5315 #define MT_ELEM  0x1
5316 #define ST_ELEM  0x2
5317 #define I_E_ELEM 0x3
5318 #define DT_ELEM  0x4
5319
5320 static const value_string element_type_code_vals[] = {
5321     {0x0,      "All element types"},
5322     {MT_ELEM,  "Medium transport element"},
5323     {ST_ELEM,  "Storage element"},
5324     {I_E_ELEM, "Import/export element"},
5325     {DT_ELEM,  "Data transfer element"},
5326     {0, NULL}
5327 };
5328
5329 #define PVOLTAG 0x80
5330 #define AVOLTAG 0x40
5331
5332 #define EXCEPT 0x04
5333
5334 #define ID_VALID 0x20
5335 #define LU_VALID 0x10
5336
5337 #define SVALID 0x80
5338
5339 static void
5340 dissect_scsi_smc2_volume_tag (tvbuff_t *tvb, packet_info *pinfo _U_,
5341                               proto_tree *tree, guint offset,
5342                               const char *name)
5343 {
5344     char volid[32+1];
5345     char *p;
5346
5347     tvb_memcpy (tvb, (guint8 *)volid, offset, 32);
5348     p = &volid[32];
5349     for (;;) {
5350         *p = '\0';
5351         if (p == volid)
5352             break;
5353         if (*(p - 1) != ' ')
5354             break;
5355         p--;
5356     }
5357     proto_tree_add_text (tree, tvb, offset, 36,
5358                          "%s: Volume Identification = \"%s\", Volume Sequence Number = %u",
5359                          name, volid, tvb_get_ntohs (tvb, offset+34));
5360 }
5361
5362 static void
5363 dissect_scsi_smc2_element (tvbuff_t *tvb, packet_info *pinfo _U_,
5364                          proto_tree *tree, guint offset,
5365                          guint elem_bytecnt, guint8 elem_type,
5366                          guint8 voltag_flags)
5367 {
5368     guint8 flags;
5369     guint8 ident_len;
5370
5371     if (elem_bytecnt < 2)
5372         return;
5373     proto_tree_add_text (tree, tvb, offset, 2,
5374                          "Element Address: %u",
5375                          tvb_get_ntohs (tvb, offset));
5376     offset += 2;
5377     elem_bytecnt -= 2;
5378
5379     if (elem_bytecnt < 1)
5380         return;
5381     flags = tvb_get_guint8 (tvb, offset);
5382     switch (elem_type) {
5383
5384     case MT_ELEM:
5385         proto_tree_add_text (tree, tvb, offset, 1,
5386                             "EXCEPT: %u, FULL: %u",
5387                              (flags & EXCEPT) >> 2, flags & 0x01);
5388         break;
5389
5390     case ST_ELEM:
5391     case DT_ELEM:
5392         proto_tree_add_text (tree, tvb, offset, 1,
5393                              "ACCESS: %u, EXCEPT: %u, FULL: %u",
5394                              (flags & 0x08) >> 3,
5395                              (flags & EXCEPT) >> 2, flags & 0x01);
5396         break;
5397
5398     case I_E_ELEM:
5399         proto_tree_add_text (tree, tvb, offset, 1,
5400                              "cmc: %u, INENAB: %u, EXENAB: %u, ACCESS: %u, EXCEPT: %u, IMPEXP: %u, FULL: %u",
5401                              (flags & 0x40) >> 6,
5402                              (flags & 0x20) >> 5,
5403                              (flags & 0x10) >> 4,
5404                              (flags & 0x08) >> 3,
5405                              (flags & EXCEPT) >> 2,
5406                              (flags & 0x02) >> 1,
5407                              flags & 0x01);
5408         break;
5409     }
5410     offset += 1;
5411     elem_bytecnt -= 1;
5412
5413     if (elem_bytecnt < 1)
5414         return;
5415     offset += 1; /* reserved */
5416     elem_bytecnt -= 1;
5417
5418     if (elem_bytecnt < 2)
5419         return;
5420     if (flags & EXCEPT) {
5421         proto_tree_add_text (tree, tvb, offset, 2,
5422                              "Additional Sense Code+Qualifier: %s",
5423                              val_to_str (tvb_get_ntohs (tvb, offset),
5424                                          scsi_asc_val, "Unknown (0x%04x)"));
5425     }
5426     offset += 2;
5427     elem_bytecnt -= 2;
5428
5429     if (elem_bytecnt < 3)
5430         return;
5431     switch (elem_type) {
5432
5433     case DT_ELEM:
5434         flags = tvb_get_guint8 (tvb, offset);
5435         if (flags & LU_VALID) {
5436             proto_tree_add_text (tree, tvb, offset, 1,
5437                                  "NOT BUS: %u, ID VALID: %u, LU VALID: 1, LUN: %u",
5438                                  (flags & 0x80) >> 7,
5439                                  (flags & ID_VALID) >> 5,
5440                                  flags & 0x07);
5441         } else if (flags & ID_VALID) {
5442             proto_tree_add_text (tree, tvb, offset, 1,
5443                                  "ID VALID: 1, LU VALID: 0");
5444         } else {
5445             proto_tree_add_text (tree, tvb, offset, 1,
5446                                  "ID VALID: 0, LU VALID: 0");
5447         }
5448         offset += 1;
5449         if (flags & ID_VALID) {
5450             proto_tree_add_text (tree, tvb, offset, 1,
5451                                  "SCSI Bus Address: %u",
5452                                  tvb_get_guint8 (tvb, offset));
5453         }
5454         offset += 1;
5455         offset += 1; /* reserved */
5456         break;
5457
5458     default:
5459         offset += 3; /* reserved */
5460         break;
5461     }
5462     elem_bytecnt -= 3;
5463
5464     if (elem_bytecnt < 3)
5465         return;
5466     flags = tvb_get_guint8 (tvb, offset);
5467     if (flags & SVALID) {
5468         proto_tree_add_text (tree, tvb, offset, 1,
5469                              "SVALID: 1, INVERT: %u",
5470                              (flags & 0x40) >> 6);
5471         offset += 1;
5472         proto_tree_add_text (tree, tvb, offset, 2,
5473                              "Source Storage Element Address: %u",
5474                              tvb_get_ntohs (tvb, offset));
5475         offset += 2;
5476     } else {
5477         proto_tree_add_text (tree, tvb, offset, 1,
5478                              "SVALID: 0");
5479         offset += 3;
5480     }
5481     elem_bytecnt -= 3;
5482
5483     if (voltag_flags & PVOLTAG) {
5484         if (elem_bytecnt < 36)
5485             return;
5486         dissect_scsi_smc2_volume_tag (tvb, pinfo, tree, offset,
5487                                       "Primary Volume Tag Information");
5488         offset += 36;
5489         elem_bytecnt -= 36;
5490     }
5491
5492     if (voltag_flags & AVOLTAG) {
5493         if (elem_bytecnt < 36)
5494             return;
5495         dissect_scsi_smc2_volume_tag (tvb, pinfo, tree, offset,
5496                                       "Alternate Volume Tag Information");
5497         offset += 36;
5498         elem_bytecnt -= 36;
5499     }
5500
5501     if (elem_bytecnt < 1)
5502         return;
5503     flags = tvb_get_guint8 (tvb, offset);
5504     proto_tree_add_text (tree, tvb, offset, 1,
5505                          "Code Set: %s",
5506                          val_to_str (flags & 0x0F,
5507                                      scsi_devid_codeset_val,
5508                                      "Unknown (0x%02x)"));
5509     offset += 1;
5510     elem_bytecnt -= 1;
5511
5512     if (elem_bytecnt < 1)
5513         return;
5514     flags = tvb_get_guint8 (tvb, offset);
5515     proto_tree_add_text (tree, tvb, offset, 1,
5516                          "Identifier Type: %s",
5517                          val_to_str ((flags & 0x0F),
5518                                      scsi_devid_idtype_val,
5519                                      "Unknown (0x%02x)"));
5520     offset += 1;
5521     elem_bytecnt -= 1;
5522
5523     if (elem_bytecnt < 1)
5524         return;
5525     offset += 1; /* reserved */
5526     elem_bytecnt -= 1;
5527
5528     if (elem_bytecnt < 1)
5529         return;
5530     ident_len = tvb_get_guint8 (tvb, offset);
5531     proto_tree_add_text (tree, tvb, offset, 1,
5532                          "Identifier Length: %u",
5533                          ident_len);
5534     offset += 1;
5535     elem_bytecnt -= 1;
5536
5537     if (ident_len != 0) {
5538         if (elem_bytecnt < ident_len)
5539             return;
5540         proto_tree_add_text (tree, tvb, offset, ident_len,
5541                              "Identifier: %s",
5542                              tvb_bytes_to_str (tvb, offset, ident_len));
5543         offset += ident_len;
5544         elem_bytecnt -= ident_len;
5545     }
5546     if (elem_bytecnt != 0) {
5547         proto_tree_add_text (tree, tvb, offset, elem_bytecnt,
5548                              "Vendor-specific Data: %s",
5549                              tvb_bytes_to_str (tvb, offset, elem_bytecnt));
5550     }
5551 }
5552
5553 static void
5554 dissect_scsi_smc2_elements (tvbuff_t *tvb, packet_info *pinfo,
5555                             proto_tree *tree, guint offset,
5556                             guint desc_bytecnt, guint8 elem_type,
5557                             guint8 voltag_flags, guint16 elem_desc_len)
5558 {
5559     guint elem_bytecnt;
5560
5561     while (desc_bytecnt != 0) {
5562         elem_bytecnt = elem_desc_len;
5563         if (elem_bytecnt > desc_bytecnt)
5564             elem_bytecnt = desc_bytecnt;
5565         dissect_scsi_smc2_element (tvb, pinfo, tree, offset, elem_bytecnt,
5566                                    elem_type, voltag_flags);
5567         offset += elem_bytecnt;
5568         desc_bytecnt -= elem_bytecnt;
5569     }
5570 }
5571
5572 static void
5573 dissect_smc2_readelementstatus (tvbuff_t *tvb, packet_info *pinfo,
5574                          proto_tree *tree, guint offset, gboolean isreq,
5575                          gboolean iscdb,
5576                          guint payload_len _U_, scsi_task_data_t *cdata _U_)
5577 {
5578     guint8 flags;
5579     guint numelem, bytecnt, desc_bytecnt;
5580     guint8 elem_type;
5581     guint8 voltag_flags;
5582     guint16 elem_desc_len;
5583
5584     if (!tree)
5585         return;
5586
5587     if (isreq && iscdb) {
5588         flags = tvb_get_guint8 (tvb, offset);
5589         proto_tree_add_text (tree, tvb, offset, 1,
5590                              "VOLTAG: %u, Element Type Code: %s",
5591                              (flags & 0x10) >> 4,
5592                              val_to_str (flags & 0xF, element_type_code_vals,
5593                                          "Unknown (0x%x)"));
5594         proto_tree_add_text (tree, tvb, offset+1, 2,
5595                              "Starting Element Address: %u",
5596                              tvb_get_ntohs (tvb, offset+1));
5597         proto_tree_add_text (tree, tvb, offset+3, 2,
5598                              "Number of Elements: %u",
5599                              tvb_get_ntohs (tvb, offset+3));
5600         flags = tvb_get_guint8 (tvb, offset+4);
5601         proto_tree_add_text (tree, tvb, offset+4, 1,
5602                              "CURDATA: %u, DVCID: %u",
5603                              (flags & 0x02) >> 1, flags & 0x01);
5604         proto_tree_add_text (tree, tvb, offset+6, 3,
5605                              "Allocation Length: %u",
5606                              tvb_get_ntoh24 (tvb, offset+6));
5607         flags = tvb_get_guint8 (tvb, offset+10);
5608         proto_tree_add_uint_format (tree, hf_scsi_control, tvb, offset+10, 1,
5609                                     flags,
5610                                     "Vendor Unique = %u, NACA = %u, Link = %u",
5611                                     flags & 0xC0, flags & 0x4, flags & 0x1);
5612     }
5613     else if (!isreq) {
5614         proto_tree_add_text (tree, tvb, offset, 2,
5615                              "First Element Address Reported: %u",
5616                              tvb_get_ntohs (tvb, offset));
5617         offset += 2;
5618         numelem = tvb_get_ntohs (tvb, offset);
5619         proto_tree_add_text (tree, tvb, offset, 2,
5620                              "Number of Elements Available: %u", numelem);
5621         offset += 2;
5622         offset += 1; /* reserved */
5623         bytecnt = tvb_get_ntoh24 (tvb, offset);
5624         proto_tree_add_text (tree, tvb, offset, 3,
5625                              "Byte Count of Report Available: %u", bytecnt);
5626         offset += 3;
5627         while (bytecnt != 0) {
5628             if (bytecnt < 1)
5629                 break;
5630             elem_type = tvb_get_guint8 (tvb, offset);
5631             proto_tree_add_text (tree, tvb, offset, 1,
5632                                  "Element Type Code: %s",
5633                                  val_to_str (elem_type, element_type_code_vals,
5634                                              "Unknown (0x%x)"));
5635             offset += 1;
5636             bytecnt -= 1;
5637
5638             if (bytecnt < 1)
5639                 break;
5640             voltag_flags = tvb_get_guint8 (tvb, offset);
5641             proto_tree_add_text (tree, tvb, offset, 1,
5642                                  "PVOLTAG: %u, AVOLTAG: %u",
5643                                  (voltag_flags & PVOLTAG) >> 7,
5644                                  (voltag_flags & AVOLTAG) >> 6);
5645             offset += 1;
5646             bytecnt -= 1;
5647
5648             if (bytecnt < 2)
5649                 break;
5650             elem_desc_len = tvb_get_ntohs (tvb, offset);
5651             proto_tree_add_text (tree, tvb, offset, 2,
5652                                  "Element Descriptor Length: %u",
5653                                  elem_desc_len);
5654             offset += 2;
5655             bytecnt -= 2;
5656
5657             if (bytecnt < 1)
5658                 break;
5659             offset += 1; /* reserved */
5660             bytecnt -= 1;
5661
5662             if (bytecnt < 3)
5663                 break;
5664             desc_bytecnt = tvb_get_ntoh24 (tvb, offset);
5665             proto_tree_add_text (tree, tvb, offset, 3,
5666                                  "Byte Count Of Descriptor Data Available: %u",
5667                                  desc_bytecnt);
5668             offset += 3;
5669             bytecnt -= 3;
5670
5671             if (desc_bytecnt > bytecnt)
5672                 desc_bytecnt = bytecnt;
5673             dissect_scsi_smc2_elements (tvb, pinfo, tree, offset,
5674                                         desc_bytecnt, elem_type,
5675                                         voltag_flags, elem_desc_len);
5676             offset += desc_bytecnt;
5677             bytecnt -= desc_bytecnt;
5678         }
5679     }
5680 }
5681
5682 void
5683 dissect_scsi_rsp (tvbuff_t *tvb, packet_info *pinfo _U_,
5684                   proto_tree *tree, guint16 lun, guint8 scsi_status)
5685 {
5686     proto_item *ti;
5687     proto_tree *scsi_tree = NULL;
5688
5689     /* Nothing really to do here, just print some stuff passed to us
5690      * and blow up the data structures for this SCSI task.
5691      */
5692     if (tree) {
5693         ti = proto_tree_add_protocol_format (tree, proto_scsi, tvb, 0,
5694                                              0, "SCSI Response");
5695         scsi_tree = proto_item_add_subtree (ti, ett_scsi);
5696
5697         ti=proto_tree_add_uint(scsi_tree, hf_scsi_lun, tvb, 0, 0, lun);
5698         PROTO_ITEM_SET_GENERATED(ti);
5699         ti=proto_tree_add_uint(scsi_tree, hf_scsi_status, tvb, 0, 0, scsi_status);
5700         PROTO_ITEM_SET_GENERATED(ti);
5701     }
5702     if (check_col (pinfo->cinfo, COL_INFO)) {
5703          col_add_fstr (pinfo->cinfo, COL_INFO, "SCSI: Response LUN: 0x%02x (%s)", lun, val_to_str(scsi_status, scsi_status_val, "Unknown (0x%08x)"));
5704      }
5705
5706 }
5707
5708 void
5709 dissect_scsi_snsinfo (tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree,
5710                       guint offset, guint snslen, guint16 lun)
5711 {
5712     proto_item *ti;
5713     proto_tree *sns_tree=NULL;
5714
5715     scsi_end_task (pinfo);
5716
5717     if (tree) {
5718         ti = proto_tree_add_protocol_format (tree, proto_scsi, tvb, offset,
5719                                              snslen, "SCSI: SNS Info");
5720         sns_tree = proto_item_add_subtree (ti, ett_scsi);
5721     }
5722
5723
5724     ti=proto_tree_add_uint(sns_tree, hf_scsi_lun, tvb, 0, 0, lun);
5725     PROTO_ITEM_SET_GENERATED(ti);
5726     if (check_col (pinfo->cinfo, COL_INFO)) {
5727          col_append_fstr (pinfo->cinfo, COL_INFO, " LUN:0x%02x ", lun);
5728     }
5729
5730     dissect_scsi_fix_snsinfo (tvb, sns_tree, offset);
5731 }
5732
5733
5734 /* list of commands for each commandset */
5735 typedef void (*scsi_dissector_t)(tvbuff_t *tvb, packet_info *pinfo,
5736                 proto_tree *tree, guint offset,
5737                 gboolean isreq, gboolean iscdb,
5738                 guint32 payload_len, scsi_task_data_t *cdata);
5739
5740 typedef struct _scsi_cdb_table_t {
5741         scsi_dissector_t        func;
5742 } scsi_cdb_table_t;
5743
5744 static scsi_cdb_table_t spc[256] = {
5745 /*SPC 0x00*/{dissect_spc3_testunitready},
5746 /*SPC 0x01*/{NULL},
5747 /*SPC 0x02*/{NULL},
5748 /*SPC 0x03*/{dissect_spc3_requestsense},
5749 /*SPC 0x04*/{NULL},
5750 /*SPC 0x05*/{NULL},
5751 /*SPC 0x06*/{NULL},
5752 /*SPC 0x07*/{NULL},
5753 /*SPC 0x08*/{NULL},
5754 /*SPC 0x09*/{NULL},
5755 /*SPC 0x0a*/{NULL},
5756 /*SPC 0x0b*/{NULL},
5757 /*SPC 0x0c*/{NULL},
5758 /*SPC 0x0d*/{NULL},
5759 /*SPC 0x0e*/{NULL},
5760 /*SPC 0x0f*/{NULL},
5761 /*SPC 0x10*/{NULL},
5762 /*SPC 0x11*/{NULL},
5763 /*SPC 0x12*/{dissect_spc3_inquiry},
5764 /*SPC 0x13*/{NULL},
5765 /*SPC 0x14*/{NULL},
5766 /*SPC 0x15*/{dissect_spc3_modeselect6},
5767 /*SPC 0x16*/{dissect_spc2_reserve6},
5768 /*SPC 0x17*/{dissect_spc2_release6},
5769 /*SPC 0x18*/{NULL},
5770 /*SPC 0x19*/{NULL},
5771 /*SPC 0x1a*/{dissect_spc3_modesense6},
5772 /*SPC 0x1b*/{NULL},
5773 /*SPC 0x1c*/{NULL},
5774 /*SPC 0x1d*/{dissect_spc3_senddiagnostic},
5775 /*SPC 0x1e*/{NULL},
5776 /*SPC 0x1f*/{NULL},
5777 /*SPC 0x20*/{NULL},
5778 /*SPC 0x21*/{NULL},
5779 /*SPC 0x22*/{NULL},
5780 /*SPC 0x23*/{NULL},
5781 /*SPC 0x24*/{NULL},
5782 /*SPC 0x25*/{NULL},
5783 /*SPC 0x26*/{NULL},
5784 /*SPC 0x27*/{NULL},
5785 /*SPC 0x28*/{NULL},
5786 /*SPC 0x29*/{NULL},
5787 /*SPC 0x2a*/{NULL},
5788 /*SPC 0x2b*/{NULL},
5789 /*SPC 0x2c*/{NULL},
5790 /*SPC 0x2d*/{NULL},
5791 /*SPC 0x2e*/{NULL},
5792 /*SPC 0x2f*/{NULL},
5793 /*SPC 0x30*/{NULL},
5794 /*SPC 0x31*/{NULL},
5795 /*SPC 0x32*/{NULL},
5796 /*SPC 0x33*/{NULL},
5797 /*SPC 0x34*/{NULL},
5798 /*SPC 0x35*/{NULL},
5799 /*SPC 0x36*/{NULL},
5800 /*SPC 0x37*/{NULL},
5801 /*SPC 0x38*/{NULL},
5802 /*SPC 0x39*/{NULL},
5803 /*SPC 0x3a*/{NULL},
5804 /*SPC 0x3b*/{dissect_spc3_writebuffer},
5805 /*SPC 0x3c*/{NULL},
5806 /*SPC 0x3d*/{NULL},
5807 /*SPC 0x3e*/{NULL},
5808 /*SPC 0x3f*/{NULL},
5809 /*SPC 0x40*/{NULL},
5810 /*SPC 0x41*/{NULL},
5811 /*SPC 0x42*/{NULL},
5812 /*SPC 0x43*/{NULL},
5813 /*SPC 0x44*/{NULL},
5814 /*SPC 0x45*/{NULL},
5815 /*SPC 0x46*/{NULL},
5816 /*SPC 0x47*/{NULL},
5817 /*SPC 0x48*/{NULL},
5818 /*SPC 0x49*/{NULL},
5819 /*SPC 0x4a*/{NULL},
5820 /*SPC 0x4b*/{NULL},
5821 /*SPC 0x4c*/{dissect_spc3_logselect},
5822 /*SPC 0x4d*/{dissect_spc3_logsense},
5823 /*SPC 0x4e*/{NULL},
5824 /*SPC 0x4f*/{NULL},
5825 /*SPC 0x50*/{NULL},
5826 /*SPC 0x51*/{NULL},
5827 /*SPC 0x52*/{NULL},
5828 /*SPC 0x53*/{NULL},
5829 /*SPC 0x54*/{NULL},
5830 /*SPC 0x55*/{dissect_spc3_modeselect10},
5831 /*SPC 0x56*/{dissect_spc2_reserve10},
5832 /*SPC 0x57*/{dissect_spc2_release10},
5833 /*SPC 0x58*/{NULL},
5834 /*SPC 0x59*/{NULL},
5835 /*SPC 0x5a*/{dissect_spc3_modesense10},
5836 /*SPC 0x5b*/{NULL},
5837 /*SPC 0x5c*/{NULL},
5838 /*SPC 0x5d*/{NULL},
5839 /*SPC 0x5e*/{dissect_spc3_persistentreservein},
5840 /*SPC 0x5f*/{dissect_spc3_persistentreserveout},
5841 /*SPC 0x60*/{NULL},
5842 /*SPC 0x61*/{NULL},
5843 /*SPC 0x62*/{NULL},
5844 /*SPC 0x63*/{NULL},
5845 /*SPC 0x64*/{NULL},
5846 /*SPC 0x65*/{NULL},
5847 /*SPC 0x66*/{NULL},
5848 /*SPC 0x67*/{NULL},
5849 /*SPC 0x68*/{NULL},
5850 /*SPC 0x69*/{NULL},
5851 /*SPC 0x6a*/{NULL},
5852 /*SPC 0x6b*/{NULL},
5853 /*SPC 0x6c*/{NULL},
5854 /*SPC 0x6d*/{NULL},
5855 /*SPC 0x6e*/{NULL},
5856 /*SPC 0x6f*/{NULL},
5857 /*SPC 0x70*/{NULL},
5858 /*SPC 0x71*/{NULL},
5859 /*SPC 0x72*/{NULL},
5860 /*SPC 0x73*/{NULL},
5861 /*SPC 0x74*/{NULL},
5862 /*SPC 0x75*/{NULL},
5863 /*SPC 0x76*/{NULL},
5864 /*SPC 0x77*/{NULL},
5865 /*SPC 0x78*/{NULL},
5866 /*SPC 0x79*/{NULL},
5867 /*SPC 0x7a*/{NULL},
5868 /*SPC 0x7b*/{NULL},
5869 /*SPC 0x7c*/{NULL},
5870 /*SPC 0x7d*/{NULL},
5871 /*SPC 0x7e*/{NULL},
5872 /*SPC 0x7f*/{dissect_scsi_varlencdb},
5873 /*SPC 0x80*/{NULL},
5874 /*SPC 0x81*/{NULL},
5875 /*SPC 0x82*/{NULL},
5876 /*SPC 0x83*/{dissect_spc3_extcopy},
5877 /*SPC 0x84*/{NULL},
5878 /*SPC 0x85*/{NULL},
5879 /*SPC 0x86*/{NULL},
5880 /*SPC 0x87*/{NULL},
5881 /*SPC 0x88*/{NULL},
5882 /*SPC 0x89*/{NULL},
5883 /*SPC 0x8a*/{NULL},
5884 /*SPC 0x8b*/{NULL},
5885 /*SPC 0x8c*/{NULL},
5886 /*SPC 0x8d*/{NULL},
5887 /*SPC 0x8e*/{NULL},
5888 /*SPC 0x8f*/{NULL},
5889 /*SPC 0x90*/{NULL},
5890 /*SPC 0x91*/{NULL},
5891 /*SPC 0x92*/{NULL},
5892 /*SPC 0x93*/{NULL},
5893 /*SPC 0x94*/{NULL},
5894 /*SPC 0x95*/{NULL},
5895 /*SPC 0x96*/{NULL},
5896 /*SPC 0x97*/{NULL},
5897 /*SPC 0x98*/{NULL},
5898 /*SPC 0x99*/{NULL},
5899 /*SPC 0x9a*/{NULL},
5900 /*SPC 0x9b*/{NULL},
5901 /*SPC 0x9c*/{NULL},
5902 /*SPC 0x9d*/{NULL},
5903 /*SPC 0x9e*/{NULL},
5904 /*SPC 0x9f*/{NULL},
5905 /*SPC 0xa0*/{dissect_spc3_reportluns},
5906 /*SPC 0xa1*/{NULL},
5907 /*SPC 0xa2*/{NULL},
5908 /*SPC 0xa3*/{dissect_spc3_reportdeviceidentifier},
5909 /*SPC 0xa4*/{NULL},
5910 /*SPC 0xa5*/{NULL},
5911 /*SPC 0xa6*/{NULL},
5912 /*SPC 0xa7*/{NULL},
5913 /*SPC 0xa8*/{NULL},
5914 /*SPC 0xa9*/{NULL},
5915 /*SPC 0xaa*/{NULL},
5916 /*SPC 0xab*/{NULL},
5917 /*SPC 0xac*/{NULL},
5918 /*SPC 0xad*/{NULL},
5919 /*SPC 0xae*/{NULL},
5920 /*SPC 0xaf*/{NULL},
5921 /*SPC 0xb0*/{NULL},
5922 /*SPC 0xb1*/{NULL},
5923 /*SPC 0xb2*/{NULL},
5924 /*SPC 0xb3*/{NULL},
5925 /*SPC 0xb4*/{NULL},
5926 /*SPC 0xb5*/{NULL},
5927 /*SPC 0xb6*/{NULL},
5928 /*SPC 0xb7*/{NULL},
5929 /*SPC 0xb8*/{NULL},
5930 /*SPC 0xb9*/{NULL},
5931 /*SPC 0xba*/{NULL},
5932 /*SPC 0xbb*/{NULL},
5933 /*SPC 0xbc*/{NULL},
5934 /*SPC 0xbd*/{NULL},
5935 /*SPC 0xbe*/{NULL},
5936 /*SPC 0xbf*/{NULL},
5937 /*SPC 0xc0*/{NULL},
5938 /*SPC 0xc1*/{NULL},
5939 /*SPC 0xc2*/{NULL},
5940 /*SPC 0xc3*/{NULL},
5941 /*SPC 0xc4*/{NULL},
5942 /*SPC 0xc5*/{NULL},
5943 /*SPC 0xc6*/{NULL},
5944 /*SPC 0xc7*/{NULL},
5945 /*SPC 0xc8*/{NULL},
5946 /*SPC 0xc9*/{NULL},
5947 /*SPC 0xca*/{NULL},
5948 /*SPC 0xcb*/{NULL},
5949 /*SPC 0xcc*/{NULL},
5950 /*SPC 0xcd*/{NULL},
5951 /*SPC 0xce*/{NULL},
5952 /*SPC 0xcf*/{NULL},
5953 /*SPC 0xd0*/{NULL},
5954 /*SPC 0xd1*/{NULL},
5955 /*SPC 0xd2*/{NULL},
5956 /*SPC 0xd3*/{NULL},
5957 /*SPC 0xd4*/{NULL},
5958 /*SPC 0xd5*/{NULL},
5959 /*SPC 0xd6*/{NULL},
5960 /*SPC 0xd7*/{NULL},
5961 /*SPC 0xd8*/{NULL},
5962 /*SPC 0xd9*/{NULL},
5963 /*SPC 0xda*/{NULL},
5964 /*SPC 0xdb*/{NULL},
5965 /*SPC 0xdc*/{NULL},
5966 /*SPC 0xdd*/{NULL},
5967 /*SPC 0xde*/{NULL},
5968 /*SPC 0xdf*/{NULL},
5969 /*SPC 0xe0*/{NULL},
5970 /*SPC 0xe1*/{NULL},
5971 /*SPC 0xe2*/{NULL},
5972 /*SPC 0xe3*/{NULL},
5973 /*SPC 0xe4*/{NULL},
5974 /*SPC 0xe5*/{NULL},
5975 /*SPC 0xe6*/{NULL},
5976 /*SPC 0xe7*/{NULL},
5977 /*SPC 0xe8*/{NULL},
5978 /*SPC 0xe9*/{NULL},
5979 /*SPC 0xea*/{NULL},
5980 /*SPC 0xeb*/{NULL},
5981 /*SPC 0xec*/{NULL},
5982 /*SPC 0xed*/{NULL},
5983 /*SPC 0xee*/{NULL},
5984 /*SPC 0xef*/{NULL},
5985 /*SPC 0xf0*/{NULL},
5986 /*SPC 0xf1*/{NULL},
5987 /*SPC 0xf2*/{NULL},
5988 /*SPC 0xf3*/{NULL},
5989 /*SPC 0xf4*/{NULL},
5990 /*SPC 0xf5*/{NULL},
5991 /*SPC 0xf6*/{NULL},
5992 /*SPC 0xf7*/{NULL},
5993 /*SPC 0xf8*/{NULL},
5994 /*SPC 0xf9*/{NULL},
5995 /*SPC 0xfa*/{NULL},
5996 /*SPC 0xfb*/{NULL},
5997 /*SPC 0xfc*/{NULL},
5998 /*SPC 0xfd*/{NULL},
5999 /*SPC 0xfe*/{NULL},
6000 /*SPC 0xff*/{NULL}
6001 };
6002
6003 static scsi_cdb_table_t sbc[256] = {
6004 /*SBC 0x00*/{NULL},
6005 /*SBC 0x01*/{NULL},
6006 /*SBC 0x02*/{NULL},
6007 /*SBC 0x03*/{NULL},
6008 /*SBC 0x04*/{dissect_sbc2_formatunit},
6009 /*SBC 0x05*/{NULL},
6010 /*SBC 0x06*/{NULL},
6011 /*SBC 0x07*/{dissect_sbc2_reassignblocks},
6012 /*SBC 0x08*/{dissect_sbc2_readwrite6},
6013 /*SBC 0x09*/{NULL},
6014 /*SBC 0x0a*/{dissect_sbc2_readwrite6},
6015 /*SBC 0x0b*/{NULL},
6016 /*SBC 0x0c*/{NULL},
6017 /*SBC 0x0d*/{NULL},
6018 /*SBC 0x0e*/{NULL},
6019 /*SBC 0x0f*/{NULL},
6020 /*SBC 0x10*/{NULL},
6021 /*SBC 0x11*/{NULL},
6022 /*SBC 0x12*/{NULL},
6023 /*SBC 0x13*/{NULL},
6024 /*SBC 0x14*/{NULL},
6025 /*SBC 0x15*/{NULL},
6026 /*SBC 0x16*/{NULL},
6027 /*SBC 0x17*/{NULL},
6028 /*SBC 0x18*/{NULL},
6029 /*SBC 0x19*/{NULL},
6030 /*SBC 0x1a*/{NULL},
6031 /*SBC 0x1b*/{dissect_sbc2_startstopunit},
6032 /*SBC 0x1c*/{NULL},
6033 /*SBC 0x1d*/{NULL},
6034 /*SBC 0x1e*/{NULL},
6035 /*SBC 0x1f*/{NULL},
6036 /*SBC 0x20*/{NULL},
6037 /*SBC 0x21*/{NULL},
6038 /*SBC 0x22*/{NULL},
6039 /*SBC 0x23*/{NULL},
6040 /*SBC 0x24*/{NULL},
6041 /*SBC 0x25*/{dissect_sbc2_readcapacity10},
6042 /*SBC 0x26*/{NULL},
6043 /*SBC 0x27*/{NULL},
6044 /*SBC 0x28*/{dissect_sbc2_readwrite10},
6045 /*SBC 0x29*/{NULL},
6046 /*SBC 0x2a*/{dissect_sbc2_readwrite10},
6047 /*SBC 0x2b*/{NULL},
6048 /*SBC 0x2c*/{NULL},
6049 /*SBC 0x2d*/{NULL},
6050 /*SBC 0x2e*/{dissect_sbc2_wrverify10},
6051 /*SBC 0x2f*/{dissect_sbc2_verify10},
6052 /*SBC 0x30*/{NULL},
6053 /*SBC 0x31*/{NULL},
6054 /*SBC 0x32*/{NULL},
6055 /*SBC 0x33*/{NULL},
6056 /*SBC 0x34*/{NULL},
6057 /*SBC 0x35*/{NULL},
6058 /*SBC 0x36*/{NULL},
6059 /*SBC 0x37*/{dissect_sbc2_readdefectdata10},
6060 /*SBC 0x38*/{NULL},
6061 /*SBC 0x39*/{NULL},
6062 /*SBC 0x3a*/{NULL},
6063 /*SBC 0x3b*/{NULL},
6064 /*SBC 0x3c*/{NULL},
6065 /*SBC 0x3d*/{NULL},
6066 /*SBC 0x3e*/{NULL},
6067 /*SBC 0x3f*/{NULL},
6068 /*SBC 0x40*/{NULL},
6069 /*SBC 0x41*/{NULL},
6070 /*SBC 0x42*/{NULL},
6071 /*SBC 0x43*/{NULL},
6072 /*SBC 0x44*/{NULL},
6073 /*SBC 0x45*/{NULL},
6074 /*SBC 0x46*/{NULL},
6075 /*SBC 0x47*/{NULL},
6076 /*SBC 0x48*/{NULL},
6077 /*SBC 0x49*/{NULL},
6078 /*SBC 0x4a*/{NULL},
6079 /*SBC 0x4b*/{NULL},
6080 /*SBC 0x4c*/{NULL},
6081 /*SBC 0x4d*/{NULL},
6082 /*SBC 0x4e*/{NULL},
6083 /*SBC 0x4f*/{NULL},
6084 /*SBC 0x50*/{NULL},
6085 /*SBC 0x51*/{NULL},
6086 /*SBC 0x52*/{NULL},
6087 /*SBC 0x53*/{NULL},
6088 /*SBC 0x54*/{NULL},
6089 /*SBC 0x55*/{NULL},
6090 /*SBC 0x56*/{NULL},
6091 /*SBC 0x57*/{NULL},
6092 /*SBC 0x58*/{NULL},
6093 /*SBC 0x59*/{NULL},
6094 /*SBC 0x5a*/{NULL},
6095 /*SBC 0x5b*/{NULL},
6096 /*SBC 0x5c*/{NULL},
6097 /*SBC 0x5d*/{NULL},
6098 /*SBC 0x5e*/{NULL},
6099 /*SBC 0x5f*/{NULL},
6100 /*SBC 0x60*/{NULL},
6101 /*SBC 0x61*/{NULL},
6102 /*SBC 0x62*/{NULL},
6103 /*SBC 0x63*/{NULL},
6104 /*SBC 0x64*/{NULL},
6105 /*SBC 0x65*/{NULL},
6106 /*SBC 0x66*/{NULL},
6107 /*SBC 0x67*/{NULL},
6108 /*SBC 0x68*/{NULL},
6109 /*SBC 0x69*/{NULL},
6110 /*SBC 0x6a*/{NULL},
6111 /*SBC 0x6b*/{NULL},
6112 /*SBC 0x6c*/{NULL},
6113 /*SBC 0x6d*/{NULL},
6114 /*SBC 0x6e*/{NULL},
6115 /*SBC 0x6f*/{NULL},
6116 /*SBC 0x70*/{NULL},
6117 /*SBC 0x71*/{NULL},
6118 /*SBC 0x72*/{NULL},
6119 /*SBC 0x73*/{NULL},
6120 /*SBC 0x74*/{NULL},
6121 /*SBC 0x75*/{NULL},
6122 /*SBC 0x76*/{NULL},
6123 /*SBC 0x77*/{NULL},
6124 /*SBC 0x78*/{NULL},
6125 /*SBC 0x79*/{NULL},
6126 /*SBC 0x7a*/{NULL},
6127 /*SBC 0x7b*/{NULL},
6128 /*SBC 0x7c*/{NULL},
6129 /*SBC 0x7d*/{NULL},
6130 /*SBC 0x7e*/{NULL},
6131 /*SBC 0x7f*/{NULL},
6132 /*SBC 0x80*/{NULL},
6133 /*SBC 0x81*/{NULL},
6134 /*SBC 0x82*/{NULL},
6135 /*SBC 0x83*/{NULL},
6136 /*SBC 0x84*/{NULL},
6137 /*SBC 0x85*/{NULL},
6138 /*SBC 0x86*/{NULL},
6139 /*SBC 0x87*/{NULL},
6140 /*SBC 0x88*/{dissect_sbc2_readwrite16},
6141 /*SBC 0x89*/{NULL},
6142 /*SBC 0x8a*/{dissect_sbc2_readwrite16},
6143 /*SBC 0x8b*/{NULL},
6144 /*SBC 0x8c*/{NULL},
6145 /*SBC 0x8d*/{NULL},
6146 /*SBC 0x8e*/{dissect_sbc2_wrverify16},
6147 /*SBC 0x8f*/{dissect_sbc2_verify16},
6148 /*SBC 0x90*/{NULL},
6149 /*SBC 0x91*/{NULL},
6150 /*SBC 0x92*/{NULL},
6151 /*SBC 0x93*/{NULL},
6152 /*SBC 0x94*/{NULL},
6153 /*SBC 0x95*/{NULL},
6154 /*SBC 0x96*/{NULL},
6155 /*SBC 0x97*/{NULL},
6156 /*SBC 0x98*/{NULL},
6157 /*SBC 0x99*/{NULL},
6158 /*SBC 0x9a*/{NULL},
6159 /*SBC 0x9b*/{NULL},
6160 /*SBC 0x9c*/{NULL},
6161 /*SBC 0x9d*/{NULL},
6162 /*SBC 0x9e*/{dissect_sbc2_serviceactionin16},
6163 /*SBC 0x9f*/{NULL},
6164 /*SBC 0xa0*/{NULL},
6165 /*SBC 0xa1*/{NULL},
6166 /*SBC 0xa2*/{NULL},
6167 /*SBC 0xa3*/{NULL},
6168 /*SBC 0xa4*/{NULL},
6169 /*SBC 0xa5*/{NULL},
6170 /*SBC 0xa6*/{NULL},
6171 /*SBC 0xa7*/{NULL},
6172 /*SBC 0xa8*/{dissect_sbc2_readwrite12},
6173 /*SBC 0xa9*/{NULL},
6174 /*SBC 0xaa*/{dissect_sbc2_readwrite12},
6175 /*SBC 0xab*/{NULL},
6176 /*SBC 0xac*/{NULL},
6177 /*SBC 0xad*/{NULL},
6178 /*SBC 0xae*/{dissect_sbc2_wrverify12},
6179 /*SBC 0xaf*/{dissect_sbc2_verify12},
6180 /*SBC 0xb0*/{NULL},
6181 /*SBC 0xb1*/{NULL},
6182 /*SBC 0xb2*/{NULL},
6183 /*SBC 0xb3*/{NULL},
6184 /*SBC 0xb4*/{NULL},
6185 /*SBC 0xb5*/{NULL},
6186 /*SBC 0xb6*/{NULL},
6187 /*SBC 0xb7*/{dissect_sbc2_readdefectdata12},
6188 /*SBC 0xb8*/{NULL},
6189 /*SBC 0xb9*/{NULL},
6190 /*SBC 0xba*/{NULL},
6191 /*SBC 0xbb*/{NULL},
6192 /*SBC 0xbc*/{NULL},
6193 /*SBC 0xbd*/{NULL},
6194 /*SBC 0xbe*/{NULL},
6195 /*SBC 0xbf*/{NULL},
6196 /*SBC 0xc0*/{NULL},
6197 /*SBC 0xc1*/{NULL},
6198 /*SBC 0xc2*/{NULL},
6199 /*SBC 0xc3*/{NULL},
6200 /*SBC 0xc4*/{NULL},
6201 /*SBC 0xc5*/{NULL},
6202 /*SBC 0xc6*/{NULL},
6203 /*SBC 0xc7*/{NULL},
6204 /*SBC 0xc8*/{NULL},
6205 /*SBC 0xc9*/{NULL},
6206 /*SBC 0xca*/{NULL},
6207 /*SBC 0xcb*/{NULL},
6208 /*SBC 0xcc*/{NULL},
6209 /*SBC 0xcd*/{NULL},
6210 /*SBC 0xce*/{NULL},
6211 /*SBC 0xcf*/{NULL},
6212 /*SBC 0xd0*/{NULL},
6213 /*SBC 0xd1*/{NULL},
6214 /*SBC 0xd2*/{NULL},
6215 /*SBC 0xd3*/{NULL},
6216 /*SBC 0xd4*/{NULL},
6217 /*SBC 0xd5*/{NULL},
6218 /*SBC 0xd6*/{NULL},
6219 /*SBC 0xd7*/{NULL},
6220 /*SBC 0xd8*/{NULL},
6221 /*SBC 0xd9*/{NULL},
6222 /*SBC 0xda*/{NULL},
6223 /*SBC 0xdb*/{NULL},
6224 /*SBC 0xdc*/{NULL},
6225 /*SBC 0xdd*/{NULL},
6226 /*SBC 0xde*/{NULL},
6227 /*SBC 0xdf*/{NULL},
6228 /*SBC 0xe0*/{NULL},
6229 /*SBC 0xe1*/{NULL},
6230 /*SBC 0xe2*/{NULL},
6231 /*SBC 0xe3*/{NULL},
6232 /*SBC 0xe4*/{NULL},
6233 /*SBC 0xe5*/{NULL},
6234 /*SBC 0xe6*/{NULL},
6235 /*SBC 0xe7*/{NULL},
6236 /*SBC 0xe8*/{NULL},
6237 /*SBC 0xe9*/{NULL},
6238 /*SBC 0xea*/{NULL},
6239 /*SBC 0xeb*/{NULL},
6240 /*SBC 0xec*/{NULL},
6241 /*SBC 0xed*/{NULL},
6242 /*SBC 0xee*/{NULL},
6243 /*SBC 0xef*/{NULL},
6244 /*SBC 0xf0*/{NULL},
6245 /*SBC 0xf1*/{NULL},
6246 /*SBC 0xf2*/{NULL},
6247 /*SBC 0xf3*/{NULL},
6248 /*SBC 0xf4*/{NULL},
6249 /*SBC 0xf5*/{NULL},
6250 /*SBC 0xf6*/{NULL},
6251 /*SBC 0xf7*/{NULL},
6252 /*SBC 0xf8*/{NULL},
6253 /*SBC 0xf9*/{NULL},
6254 /*SBC 0xfa*/{NULL},
6255 /*SBC 0xfb*/{NULL},
6256 /*SBC 0xfc*/{NULL},
6257 /*SBC 0xfd*/{NULL},
6258 /*SBC 0xfe*/{NULL},
6259 /*SBC 0xff*/{NULL}
6260 };
6261
6262 static scsi_cdb_table_t ssc[256] = {
6263 /*SSC 0x00*/{NULL},
6264 /*SSC 0x01*/{dissect_ssc2_rewind},
6265 /*SSC 0x02*/{NULL},
6266 /*SSC 0x03*/{NULL},
6267 /*SSC 0x04*/{dissect_ssc2_formatmedium},
6268 /*SSC 0x05*/{dissect_ssc2_readblocklimits},
6269 /*SSC 0x06*/{NULL},
6270 /*SSC 0x07*/{NULL},
6271 /*SSC 0x08*/{dissect_ssc2_read6},
6272 /*SSC 0x09*/{NULL},
6273 /*SSC 0x0a*/{dissect_ssc2_write6},
6274 /*SSC 0x0b*/{NULL},
6275 /*SSC 0x0c*/{NULL},
6276 /*SSC 0x0d*/{NULL},
6277 /*SSC 0x0e*/{NULL},
6278 /*SSC 0x0f*/{NULL},
6279 /*SSC 0x10*/{dissect_ssc2_writefilemarks6},
6280 /*SSC 0x11*/{dissect_ssc2_space6},
6281 /*SSC 0x12*/{NULL},
6282 /*SSC 0x13*/{NULL},
6283 /*SSC 0x14*/{NULL},
6284 /*SSC 0x15*/{NULL},
6285 /*SSC 0x16*/{NULL},
6286 /*SSC 0x17*/{NULL},
6287 /*SSC 0x18*/{NULL},
6288 /*SSC 0x19*/{dissect_ssc2_erase6},
6289 /*SSC 0x1a*/{NULL},
6290 /*SSC 0x1b*/{dissect_ssc2_loadunload},
6291 /*SSC 0x1c*/{NULL},
6292 /*SSC 0x1d*/{NULL},
6293 /*SSC 0x1e*/{NULL},
6294 /*SSC 0x1f*/{NULL},
6295 /*SSC 0x20*/{NULL},
6296 /*SSC 0x21*/{NULL},
6297 /*SSC 0x22*/{NULL},
6298 /*SSC 0x23*/{NULL},
6299 /*SSC 0x24*/{NULL},
6300 /*SSC 0x25*/{NULL},
6301 /*SSC 0x26*/{NULL},
6302 /*SSC 0x27*/{NULL},
6303 /*SSC 0x28*/{NULL},
6304 /*SSC 0x29*/{NULL},
6305 /*SSC 0x2a*/{NULL},
6306 /*SSC 0x2b*/{dissect_ssc2_locate10},
6307 /*SSC 0x2c*/{NULL},
6308 /*SSC 0x2d*/{NULL},
6309 /*SSC 0x2e*/{NULL},
6310 /*SSC 0x2f*/{NULL},
6311 /*SSC 0x30*/{NULL},
6312 /*SSC 0x31*/{NULL},
6313 /*SSC 0x32*/{NULL},
6314 /*SSC 0x33*/{NULL},
6315 /*SSC 0x34*/{dissect_ssc2_readposition},
6316 /*SSC 0x35*/{NULL},
6317 /*SSC 0x36*/{NULL},
6318 /*SSC 0x37*/{NULL},
6319 /*SSC 0x38*/{NULL},
6320 /*SSC 0x39*/{NULL},
6321 /*SSC 0x3a*/{NULL},
6322 /*SSC 0x3b*/{NULL},
6323 /*SSC 0x3c*/{NULL},
6324 /*SSC 0x3d*/{NULL},
6325 /*SSC 0x3e*/{NULL},
6326 /*SSC 0x3f*/{NULL},
6327 /*SSC 0x40*/{NULL},
6328 /*SSC 0x41*/{NULL},
6329 /*SSC 0x42*/{NULL},
6330 /*SSC 0x43*/{NULL},
6331 /*SSC 0x44*/{NULL},
6332 /*SSC 0x45*/{NULL},
6333 /*SSC 0x46*/{NULL},
6334 /*SSC 0x47*/{NULL},
6335 /*SSC 0x48*/{NULL},
6336 /*SSC 0x49*/{NULL},
6337 /*SSC 0x4a*/{NULL},
6338 /*SSC 0x4b*/{NULL},
6339 /*SSC 0x4c*/{NULL},
6340 /*SSC 0x4d*/{NULL},
6341 /*SSC 0x4e*/{NULL},
6342 /*SSC 0x4f*/{NULL},
6343 /*SSC 0x50*/{NULL},
6344 /*SSC 0x51*/{NULL},
6345 /*SSC 0x52*/{NULL},
6346 /*SSC 0x53*/{NULL},
6347 /*SSC 0x54*/{NULL},
6348 /*SSC 0x55*/{NULL},
6349 /*SSC 0x56*/{NULL},
6350 /*SSC 0x57*/{NULL},
6351 /*SSC 0x58*/{NULL},
6352 /*SSC 0x59*/{NULL},
6353 /*SSC 0x5a*/{NULL},
6354 /*SSC 0x5b*/{NULL},
6355 /*SSC 0x5c*/{NULL},
6356 /*SSC 0x5d*/{NULL},
6357 /*SSC 0x5e*/{NULL},
6358 /*SSC 0x5f*/{NULL},
6359 /*SSC 0x60*/{NULL},
6360 /*SSC 0x61*/{NULL},
6361 /*SSC 0x62*/{NULL},
6362 /*SSC 0x63*/{NULL},
6363 /*SSC 0x64*/{NULL},
6364 /*SSC 0x65*/{NULL},
6365 /*SSC 0x66*/{NULL},
6366 /*SSC 0x67*/{NULL},
6367 /*SSC 0x68*/{NULL},
6368 /*SSC 0x69*/{NULL},
6369 /*SSC 0x6a*/{NULL},
6370 /*SSC 0x6b*/{NULL},
6371 /*SSC 0x6c*/{NULL},
6372 /*SSC 0x6d*/{NULL},
6373 /*SSC 0x6e*/{NULL},
6374 /*SSC 0x6f*/{NULL},
6375 /*SSC 0x70*/{NULL},
6376 /*SSC 0x71*/{NULL},
6377 /*SSC 0x72*/{NULL},
6378 /*SSC 0x73*/{NULL},
6379 /*SSC 0x74*/{NULL},
6380 /*SSC 0x75*/{NULL},
6381 /*SSC 0x76*/{NULL},
6382 /*SSC 0x77*/{NULL},
6383 /*SSC 0x78*/{NULL},
6384 /*SSC 0x79*/{NULL},
6385 /*SSC 0x7a*/{NULL},
6386 /*SSC 0x7b*/{NULL},
6387 /*SSC 0x7c*/{NULL},
6388 /*SSC 0x7d*/{NULL},
6389 /*SSC 0x7e*/{NULL},
6390 /*SSC 0x7f*/{NULL},
6391 /*SSC 0x80*/{NULL},
6392 /*SSC 0x81*/{NULL},
6393 /*SSC 0x82*/{NULL},
6394 /*SSC 0x83*/{NULL},
6395 /*SSC 0x84*/{NULL},
6396 /*SSC 0x85*/{NULL},
6397 /*SSC 0x86*/{NULL},
6398 /*SSC 0x87*/{NULL},
6399 /*SSC 0x88*/{NULL},
6400 /*SSC 0x89*/{NULL},
6401 /*SSC 0x8a*/{NULL},
6402 /*SSC 0x8b*/{NULL},
6403 /*SSC 0x8c*/{NULL},
6404 /*SSC 0x8d*/{NULL},
6405 /*SSC 0x8e*/{NULL},
6406 /*SSC 0x8f*/{NULL},
6407 /*SSC 0x90*/{NULL},
6408 /*SSC 0x91*/{dissect_ssc2_space16},
6409 /*SSC 0x92*/{dissect_ssc2_locate16},
6410 /*SSC 0x93*/{dissect_ssc2_erase16},
6411 /*SSC 0x94*/{NULL},
6412 /*SSC 0x95*/{NULL},
6413 /*SSC 0x96*/{NULL},
6414 /*SSC 0x97*/{NULL},
6415 /*SSC 0x98*/{NULL},
6416 /*SSC 0x99*/{NULL},
6417 /*SSC 0x9a*/{NULL},
6418 /*SSC 0x9b*/{NULL},
6419 /*SSC 0x9c*/{NULL},
6420 /*SSC 0x9d*/{NULL},
6421 /*SSC 0x9e*/{NULL},
6422 /*SSC 0x9f*/{NULL},
6423 /*SSC 0xa0*/{NULL},
6424 /*SSC 0xa1*/{NULL},
6425 /*SSC 0xa2*/{NULL},
6426 /*SSC 0xa3*/{NULL},
6427 /*SSC 0xa4*/{NULL},
6428 /*SSC 0xa5*/{dissect_smc2_movemedium},
6429 /*SSC 0xa6*/{NULL},
6430 /*SSC 0xa7*/{dissect_smc2_movemedium},
6431 /*SSC 0xa8*/{NULL},
6432 /*SSC 0xa9*/{NULL},
6433 /*SSC 0xaa*/{NULL},
6434 /*SSC 0xab*/{NULL},
6435 /*SSC 0xac*/{NULL},
6436 /*SSC 0xad*/{NULL},
6437 /*SSC 0xae*/{NULL},
6438 /*SSC 0xaf*/{NULL},
6439 /*SSC 0xb0*/{NULL},
6440 /*SSC 0xb1*/{NULL},
6441 /*SSC 0xb2*/{NULL},
6442 /*SSC 0xb3*/{NULL},
6443 /*SSC 0xb4*/{dissect_smc2_readelementstatus},
6444 /*SSC 0xb5*/{NULL},
6445 /*SSC 0xb6*/{NULL},
6446 /*SSC 0xb7*/{NULL},
6447 /*SSC 0xb8*/{dissect_smc2_readelementstatus},
6448 /*SSC 0xb9*/{NULL},
6449 /*SSC 0xba*/{NULL},
6450 /*SSC 0xbb*/{NULL},
6451 /*SSC 0xbc*/{NULL},
6452 /*SSC 0xbd*/{NULL},
6453 /*SSC 0xbe*/{NULL},
6454 /*SSC 0xbf*/{NULL},
6455 /*SSC 0xc0*/{NULL},
6456 /*SSC 0xc1*/{NULL},
6457 /*SSC 0xc2*/{NULL},
6458 /*SSC 0xc3*/{NULL},
6459 /*SSC 0xc4*/{NULL},
6460 /*SSC 0xc5*/{NULL},
6461 /*SSC 0xc6*/{NULL},
6462 /*SSC 0xc7*/{NULL},
6463 /*SSC 0xc8*/{NULL},
6464 /*SSC 0xc9*/{NULL},
6465 /*SSC 0xca*/{NULL},
6466 /*SSC 0xcb*/{NULL},
6467 /*SSC 0xcc*/{NULL},
6468 /*SSC 0xcd*/{NULL},
6469 /*SSC 0xce*/{NULL},
6470 /*SSC 0xcf*/{NULL},
6471 /*SSC 0xd0*/{NULL},
6472 /*SSC 0xd1*/{NULL},
6473 /*SSC 0xd2*/{NULL},
6474 /*SSC 0xd3*/{NULL},
6475 /*SSC 0xd4*/{NULL},
6476 /*SSC 0xd5*/{NULL},
6477 /*SSC 0xd6*/{NULL},
6478 /*SSC 0xd7*/{NULL},
6479 /*SSC 0xd8*/{NULL},
6480 /*SSC 0xd9*/{NULL},
6481 /*SSC 0xda*/{NULL},
6482 /*SSC 0xdb*/{NULL},
6483 /*SSC 0xdc*/{NULL},
6484 /*SSC 0xdd*/{NULL},
6485 /*SSC 0xde*/{NULL},
6486 /*SSC 0xdf*/{NULL},
6487 /*SSC 0xe0*/{NULL},
6488 /*SSC 0xe1*/{NULL},
6489 /*SSC 0xe2*/{NULL},
6490 /*SSC 0xe3*/{NULL},
6491 /*SSC 0xe4*/{NULL},
6492 /*SSC 0xe5*/{NULL},
6493 /*SSC 0xe6*/{NULL},
6494 /*SSC 0xe7*/{NULL},
6495 /*SSC 0xe8*/{NULL},
6496 /*SSC 0xe9*/{NULL},
6497 /*SSC 0xea*/{NULL},
6498 /*SSC 0xeb*/{NULL},
6499 /*SSC 0xec*/{NULL},
6500 /*SSC 0xed*/{NULL},
6501 /*SSC 0xee*/{NULL},
6502 /*SSC 0xef*/{NULL},
6503 /*SSC 0xf0*/{NULL},
6504 /*SSC 0xf1*/{NULL},
6505 /*SSC 0xf2*/{NULL},
6506 /*SSC 0xf3*/{NULL},
6507 /*SSC 0xf4*/{NULL},
6508 /*SSC 0xf5*/{NULL},
6509 /*SSC 0xf6*/{NULL},
6510 /*SSC 0xf7*/{NULL},
6511 /*SSC 0xf8*/{NULL},
6512 /*SSC 0xf9*/{NULL},
6513 /*SSC 0xfa*/{NULL},
6514 /*SSC 0xfb*/{NULL},
6515 /*SSC 0xfc*/{NULL},
6516 /*SSC 0xfd*/{NULL},
6517 /*SSC 0xfe*/{NULL},
6518 /*SSC 0xff*/{NULL}
6519 };
6520
6521 static scsi_cdb_table_t smc[256] = {
6522 /*SMC 0x00*/{NULL},
6523 /*SMC 0x01*/{NULL},
6524 /*SMC 0x02*/{NULL},
6525 /*SMC 0x03*/{NULL},
6526 /*SMC 0x04*/{NULL},
6527 /*SMC 0x05*/{NULL},
6528 /*SMC 0x06*/{NULL},
6529 /*SMC 0x07*/{NULL},
6530 /*SMC 0x08*/{NULL},
6531 /*SMC 0x09*/{NULL},
6532 /*SMC 0x0a*/{NULL},
6533 /*SMC 0x0b*/{NULL},
6534 /*SMC 0x0c*/{NULL},
6535 /*SMC 0x0d*/{NULL},
6536 /*SMC 0x0e*/{NULL},
6537 /*SMC 0x0f*/{NULL},
6538 /*SMC 0x10*/{NULL},
6539 /*SMC 0x11*/{NULL},
6540 /*SMC 0x12*/{NULL},
6541 /*SMC 0x13*/{NULL},
6542 /*SMC 0x14*/{NULL},
6543 /*SMC 0x15*/{NULL},
6544 /*SMC 0x16*/{NULL},
6545 /*SMC 0x17*/{NULL},
6546 /*SMC 0x18*/{NULL},
6547 /*SMC 0x19*/{NULL},
6548 /*SMC 0x1a*/{NULL},
6549 /*SMC 0x1b*/{NULL},
6550 /*SMC 0x1c*/{NULL},
6551 /*SMC 0x1d*/{NULL},
6552 /*SMC 0x1e*/{NULL},
6553 /*SMC 0x1f*/{NULL},
6554 /*SMC 0x20*/{NULL},
6555 /*SMC 0x21*/{NULL},
6556 /*SMC 0x22*/{NULL},
6557 /*SMC 0x23*/{NULL},
6558 /*SMC 0x24*/{NULL},
6559 /*SMC 0x25*/{NULL},
6560 /*SMC 0x26*/{NULL},
6561 /*SMC 0x27*/{NULL},
6562 /*SMC 0x28*/{NULL},
6563 /*SMC 0x29*/{NULL},
6564 /*SMC 0x2a*/{NULL},
6565 /*SMC 0x2b*/{NULL},
6566 /*SMC 0x2c*/{NULL},
6567 /*SMC 0x2d*/{NULL},
6568 /*SMC 0x2e*/{NULL},
6569 /*SMC 0x2f*/{NULL},
6570 /*SMC 0x30*/{NULL},
6571 /*SMC 0x31*/{NULL},
6572 /*SMC 0x32*/{NULL},
6573 /*SMC 0x33*/{NULL},
6574 /*SMC 0x34*/{NULL},
6575 /*SMC 0x35*/{NULL},
6576 /*SMC 0x36*/{NULL},
6577 /*SMC 0x37*/{NULL},
6578 /*SMC 0x38*/{NULL},
6579 /*SMC 0x39*/{NULL},
6580 /*SMC 0x3a*/{NULL},
6581 /*SMC 0x3b*/{NULL},
6582 /*SMC 0x3c*/{NULL},
6583 /*SMC 0x3d*/{NULL},
6584 /*SMC 0x3e*/{NULL},
6585 /*SMC 0x3f*/{NULL},
6586 /*SMC 0x40*/{NULL},
6587 /*SMC 0x41*/{NULL},
6588 /*SMC 0x42*/{NULL},
6589 /*SMC 0x43*/{NULL},
6590 /*SMC 0x44*/{NULL},
6591 /*SMC 0x45*/{NULL},
6592 /*SMC 0x46*/{NULL},
6593 /*SMC 0x47*/{NULL},
6594 /*SMC 0x48*/{NULL},
6595 /*SMC 0x49*/{NULL},
6596 /*SMC 0x4a*/{NULL},
6597 /*SMC 0x4b*/{NULL},
6598 /*SMC 0x4c*/{NULL},
6599 /*SMC 0x4d*/{NULL},
6600 /*SMC 0x4e*/{NULL},
6601 /*SMC 0x4f*/{NULL},
6602 /*SMC 0x50*/{NULL},
6603 /*SMC 0x51*/{NULL},
6604 /*SMC 0x52*/{NULL},
6605 /*SMC 0x53*/{NULL},
6606 /*SMC 0x54*/{NULL},
6607 /*SMC 0x55*/{NULL},
6608 /*SMC 0x56*/{NULL},
6609 /*SMC 0x57*/{NULL},
6610 /*SMC 0x58*/{NULL},
6611 /*SMC 0x59*/{NULL},
6612 /*SMC 0x5a*/{NULL},
6613 /*SMC 0x5b*/{NULL},
6614 /*SMC 0x5c*/{NULL},
6615 /*SMC 0x5d*/{NULL},
6616 /*SMC 0x5e*/{NULL},
6617 /*SMC 0x5f*/{NULL},
6618 /*SMC 0x60*/{NULL},
6619 /*SMC 0x61*/{NULL},
6620 /*SMC 0x62*/{NULL},
6621 /*SMC 0x63*/{NULL},
6622 /*SMC 0x64*/{NULL},
6623 /*SMC 0x65*/{NULL},
6624 /*SMC 0x66*/{NULL},
6625 /*SMC 0x67*/{NULL},
6626 /*SMC 0x68*/{NULL},
6627 /*SMC 0x69*/{NULL},
6628 /*SMC 0x6a*/{NULL},
6629 /*SMC 0x6b*/{NULL},
6630 /*SMC 0x6c*/{NULL},
6631 /*SMC 0x6d*/{NULL},
6632 /*SMC 0x6e*/{NULL},
6633 /*SMC 0x6f*/{NULL},
6634 /*SMC 0x70*/{NULL},
6635 /*SMC 0x71*/{NULL},
6636 /*SMC 0x72*/{NULL},
6637 /*SMC 0x73*/{NULL},
6638 /*SMC 0x74*/{NULL},
6639 /*SMC 0x75*/{NULL},
6640 /*SMC 0x76*/{NULL},
6641 /*SMC 0x77*/{NULL},
6642 /*SMC 0x78*/{NULL},
6643 /*SMC 0x79*/{NULL},
6644 /*SMC 0x7a*/{NULL},
6645 /*SMC 0x7b*/{NULL},
6646 /*SMC 0x7c*/{NULL},
6647 /*SMC 0x7d*/{NULL},
6648 /*SMC 0x7e*/{NULL},
6649 /*SMC 0x7f*/{NULL},
6650 /*SMC 0x80*/{NULL},
6651 /*SMC 0x81*/{NULL},
6652 /*SMC 0x82*/{NULL},
6653 /*SMC 0x83*/{NULL},
6654 /*SMC 0x84*/{NULL},
6655 /*SMC 0x85*/{NULL},
6656 /*SMC 0x86*/{NULL},
6657 /*SMC 0x87*/{NULL},
6658 /*SMC 0x88*/{NULL},
6659 /*SMC 0x89*/{NULL},
6660 /*SMC 0x8a*/{NULL},
6661 /*SMC 0x8b*/{NULL},
6662 /*SMC 0x8c*/{NULL},
6663 /*SMC 0x8d*/{NULL},
6664 /*SMC 0x8e*/{NULL},
6665 /*SMC 0x8f*/{NULL},
6666 /*SMC 0x90*/{NULL},
6667 /*SMC 0x91*/{NULL},
6668 /*SMC 0x92*/{NULL},
6669 /*SMC 0x93*/{NULL},
6670 /*SMC 0x94*/{NULL},
6671 /*SMC 0x95*/{NULL},
6672 /*SMC 0x96*/{NULL},
6673 /*SMC 0x97*/{NULL},
6674 /*SMC 0x98*/{NULL},
6675 /*SMC 0x99*/{NULL},
6676 /*SMC 0x9a*/{NULL},
6677 /*SMC 0x9b*/{NULL},
6678 /*SMC 0x9c*/{NULL},
6679 /*SMC 0x9d*/{NULL},
6680 /*SMC 0x9e*/{NULL},
6681 /*SMC 0x9f*/{NULL},
6682 /*SMC 0xa0*/{NULL},
6683 /*SMC 0xa1*/{NULL},
6684 /*SMC 0xa2*/{NULL},
6685 /*SMC 0xa3*/{NULL},
6686 /*SMC 0xa4*/{NULL},
6687 /*SMC 0xa5*/{dissect_smc2_movemedium},
6688 /*SMC 0xa6*/{NULL},
6689 /*SMC 0xa7*/{dissect_smc2_movemedium},
6690 /*SMC 0xa8*/{NULL},
6691 /*SMC 0xa9*/{NULL},
6692 /*SMC 0xaa*/{NULL},
6693 /*SMC 0xab*/{NULL},
6694 /*SMC 0xac*/{NULL},
6695 /*SMC 0xad*/{NULL},
6696 /*SMC 0xae*/{NULL},
6697 /*SMC 0xaf*/{NULL},
6698 /*SMC 0xb0*/{NULL},
6699 /*SMC 0xb1*/{NULL},
6700 /*SMC 0xb2*/{NULL},
6701 /*SMC 0xb3*/{NULL},
6702 /*SMC 0xb4*/{dissect_smc2_readelementstatus},
6703 /*SMC 0xb5*/{NULL},
6704 /*SMC 0xb6*/{NULL},
6705 /*SMC 0xb7*/{NULL},
6706 /*SMC 0xb8*/{dissect_smc2_readelementstatus},
6707 /*SMC 0xb9*/{NULL},
6708 /*SMC 0xba*/{NULL},
6709 /*SMC 0xbb*/{NULL},
6710 /*SMC 0xbc*/{NULL},
6711 /*SMC 0xbd*/{NULL},
6712 /*SMC 0xbe*/{NULL},
6713 /*SMC 0xbf*/{NULL},
6714 /*SMC 0xc0*/{NULL},
6715 /*SMC 0xc1*/{NULL},
6716 /*SMC 0xc2*/{NULL},
6717 /*SMC 0xc3*/{NULL},
6718 /*SMC 0xc4*/{NULL},
6719 /*SMC 0xc5*/{NULL},
6720 /*SMC 0xc6*/{NULL},
6721 /*SMC 0xc7*/{NULL},
6722 /*SMC 0xc8*/{NULL},
6723 /*SMC 0xc9*/{NULL},
6724 /*SMC 0xca*/{NULL},
6725 /*SMC 0xcb*/{NULL},
6726 /*SMC 0xcc*/{NULL},
6727 /*SMC 0xcd*/{NULL},
6728 /*SMC 0xce*/{NULL},
6729 /*SMC 0xcf*/{NULL},
6730 /*SMC 0xd0*/{NULL},
6731 /*SMC 0xd1*/{NULL},
6732 /*SMC 0xd2*/{NULL},
6733 /*SMC 0xd3*/{NULL},
6734 /*SMC 0xd4*/{NULL},
6735 /*SMC 0xd5*/{NULL},
6736 /*SMC 0xd6*/{NULL},
6737 /*SMC 0xd7*/{NULL},
6738 /*SMC 0xd8*/{NULL},
6739 /*SMC 0xd9*/{NULL},
6740 /*SMC 0xda*/{NULL},
6741 /*SMC 0xdb*/{NULL},
6742 /*SMC 0xdc*/{NULL},
6743 /*SMC 0xdd*/{NULL},
6744 /*SMC 0xde*/{NULL},
6745 /*SMC 0xdf*/{NULL},
6746 /*SMC 0xe0*/{NULL},
6747 /*SMC 0xe1*/{NULL},
6748 /*SMC 0xe2*/{NULL},
6749 /*SMC 0xe3*/{NULL},
6750 /*SMC 0xe4*/{NULL},
6751 /*SMC 0xe5*/{NULL},
6752 /*SMC 0xe6*/{NULL},
6753 /*SMC 0xe7*/{NULL},
6754 /*SMC 0xe8*/{NULL},
6755 /*SMC 0xe9*/{NULL},
6756 /*SMC 0xea*/{NULL},
6757 /*SMC 0xeb*/{NULL},
6758 /*SMC 0xec*/{NULL},
6759 /*SMC 0xed*/{NULL},
6760 /*SMC 0xee*/{NULL},
6761 /*SMC 0xef*/{NULL},
6762 /*SMC 0xf0*/{NULL},
6763 /*SMC 0xf1*/{NULL},
6764 /*SMC 0xf2*/{NULL},
6765 /*SMC 0xf3*/{NULL},
6766 /*SMC 0xf4*/{NULL},
6767 /*SMC 0xf5*/{NULL},
6768 /*SMC 0xf6*/{NULL},
6769 /*SMC 0xf7*/{NULL},
6770 /*SMC 0xf8*/{NULL},
6771 /*SMC 0xf9*/{NULL},
6772 /*SMC 0xfa*/{NULL},
6773 /*SMC 0xfb*/{NULL},
6774 /*SMC 0xfc*/{NULL},
6775 /*SMC 0xfd*/{NULL},
6776 /*SMC 0xfe*/{NULL},
6777 /*SMC 0xff*/{NULL}
6778 };
6779
6780 static scsi_cdb_table_t mmc[256] = {
6781 /*MMC 0x00*/{NULL},
6782 /*MMC 0x01*/{NULL},
6783 /*MMC 0x02*/{NULL},
6784 /*MMC 0x03*/{NULL},
6785 /*MMC 0x04*/{NULL},
6786 /*MMC 0x05*/{NULL},
6787 /*MMC 0x06*/{NULL},
6788 /*MMC 0x07*/{NULL},
6789 /*MMC 0x08*/{NULL},
6790 /*MMC 0x09*/{NULL},
6791 /*MMC 0x0a*/{NULL},
6792 /*MMC 0x0b*/{NULL},
6793 /*MMC 0x0c*/{NULL},
6794 /*MMC 0x0d*/{NULL},
6795 /*MMC 0x0e*/{NULL},
6796 /*MMC 0x0f*/{NULL},
6797 /*MMC 0x10*/{NULL},
6798 /*MMC 0x11*/{NULL},
6799 /*MMC 0x12*/{NULL},
6800 /*MMC 0x13*/{NULL},
6801 /*MMC 0x14*/{NULL},
6802 /*MMC 0x15*/{NULL},
6803 /*MMC 0x16*/{NULL},
6804 /*MMC 0x17*/{NULL},
6805 /*MMC 0x18*/{NULL},
6806 /*MMC 0x19*/{NULL},
6807 /*MMC 0x1a*/{NULL},
6808 /*MMC 0x1b*/{dissect_sbc2_startstopunit},
6809 /*MMC 0x1c*/{NULL},
6810 /*MMC 0x1d*/{NULL},
6811 /*MMC 0x1e*/{NULL},
6812 /*MMC 0x1f*/{NULL},
6813 /*MMC 0x20*/{NULL},
6814 /*MMC 0x21*/{NULL},
6815 /*MMC 0x22*/{NULL},
6816 /*MMC 0x23*/{NULL},
6817 /*MMC 0x24*/{NULL},
6818 /*MMC 0x25*/{dissect_sbc2_readcapacity10},
6819 /*MMC 0x26*/{NULL},
6820 /*MMC 0x27*/{NULL},
6821 /*MMC 0x28*/{dissect_sbc2_readwrite10},
6822 /*MMC 0x29*/{NULL},
6823 /*MMC 0x2a*/{dissect_sbc2_readwrite10},
6824 /*MMC 0x2b*/{NULL},
6825 /*MMC 0x2c*/{NULL},
6826 /*MMC 0x2d*/{NULL},
6827 /*MMC 0x2e*/{NULL},
6828 /*MMC 0x2f*/{NULL},
6829 /*MMC 0x30*/{NULL},
6830 /*MMC 0x31*/{NULL},
6831 /*MMC 0x32*/{NULL},
6832 /*MMC 0x33*/{NULL},
6833 /*MMC 0x34*/{NULL},
6834 /*MMC 0x35*/{dissect_mmc4_synchronizecache},
6835 /*MMC 0x36*/{NULL},
6836 /*MMC 0x37*/{NULL},
6837 /*MMC 0x38*/{NULL},
6838 /*MMC 0x39*/{NULL},
6839 /*MMC 0x3a*/{NULL},
6840 /*MMC 0x3b*/{NULL},
6841 /*MMC 0x3c*/{NULL},
6842 /*MMC 0x3d*/{NULL},
6843 /*MMC 0x3e*/{NULL},
6844 /*MMC 0x3f*/{NULL},
6845 /*MMC 0x40*/{NULL},
6846 /*MMC 0x41*/{NULL},
6847 /*MMC 0x42*/{NULL},
6848 /*MMC 0x43*/{dissect_mmc4_readtocpmaatip},
6849 /*MMC 0x44*/{NULL},
6850 /*MMC 0x45*/{NULL},
6851 /*MMC 0x46*/{dissect_mmc4_getconfiguration},
6852 /*MMC 0x47*/{NULL},
6853 /*MMC 0x48*/{NULL},
6854 /*MMC 0x49*/{NULL},
6855 /*MMC 0x4a*/{dissect_mmc4_geteventstatusnotification},
6856 /*MMC 0x4b*/{NULL},
6857 /*MMC 0x4c*/{NULL},
6858 /*MMC 0x4d*/{NULL},
6859 /*MMC 0x4e*/{NULL},
6860 /*MMC 0x4f*/{NULL},
6861 /*MMC 0x50*/{NULL},
6862 /*MMC 0x51*/{dissect_mmc4_readdiscinformation},
6863 /*MMC 0x52*/{dissect_mmc4_readtrackinformation},
6864 /*MMC 0x53*/{dissect_mmc4_reservetrack},
6865 /*MMC 0x54*/{NULL},
6866 /*MMC 0x55*/{NULL},
6867 /*MMC 0x56*/{NULL},
6868 /*MMC 0x57*/{NULL},
6869 /*MMC 0x58*/{NULL},
6870 /*MMC 0x59*/{NULL},
6871 /*MMC 0x5a*/{NULL},
6872 /*MMC 0x5b*/{NULL},
6873 /*MMC 0x5c*/{dissect_mmc4_readbuffercapacity},
6874 /*MMC 0x5d*/{NULL},
6875 /*MMC 0x5e*/{NULL},
6876 /*MMC 0x5f*/{NULL},
6877 /*MMC 0x60*/{NULL},
6878 /*MMC 0x61*/{NULL},
6879 /*MMC 0x62*/{NULL},
6880 /*MMC 0x63*/{NULL},
6881 /*MMC 0x64*/{NULL},
6882 /*MMC 0x65*/{NULL},
6883 /*MMC 0x66*/{NULL},
6884 /*MMC 0x67*/{NULL},
6885 /*MMC 0x68*/{NULL},
6886 /*MMC 0x69*/{NULL},
6887 /*MMC 0x6a*/{NULL},
6888 /*MMC 0x6b*/{NULL},
6889 /*MMC 0x6c*/{NULL},
6890 /*MMC 0x6d*/{NULL},
6891 /*MMC 0x6e*/{NULL},
6892 /*MMC 0x6f*/{NULL},
6893 /*MMC 0x70*/{NULL},
6894 /*MMC 0x71*/{NULL},
6895 /*MMC 0x72*/{NULL},
6896 /*MMC 0x73*/{NULL},
6897 /*MMC 0x74*/{NULL},
6898 /*MMC 0x75*/{NULL},
6899 /*MMC 0x76*/{NULL},
6900 /*MMC 0x77*/{NULL},
6901 /*MMC 0x78*/{NULL},
6902 /*MMC 0x79*/{NULL},
6903 /*MMC 0x7a*/{NULL},
6904 /*MMC 0x7b*/{NULL},
6905 /*MMC 0x7c*/{NULL},
6906 /*MMC 0x7d*/{NULL},
6907 /*MMC 0x7e*/{NULL},
6908 /*MMC 0x7f*/{NULL},
6909 /*MMC 0x80*/{NULL},
6910 /*MMC 0x81*/{NULL},
6911 /*MMC 0x82*/{NULL},
6912 /*MMC 0x83*/{NULL},
6913 /*MMC 0x84*/{NULL},
6914 /*MMC 0x85*/{NULL},
6915 /*MMC 0x86*/{NULL},
6916 /*MMC 0x87*/{NULL},
6917 /*MMC 0x88*/{NULL},
6918 /*MMC 0x89*/{NULL},
6919 /*MMC 0x8a*/{NULL},
6920 /*MMC 0x8b*/{NULL},
6921 /*MMC 0x8c*/{NULL},
6922 /*MMC 0x8d*/{NULL},
6923 /*MMC 0x8e*/{NULL},
6924 /*MMC 0x8f*/{NULL},
6925 /*MMC 0x90*/{NULL},
6926 /*MMC 0x91*/{NULL},
6927 /*MMC 0x92*/{NULL},
6928 /*MMC 0x93*/{NULL},
6929 /*MMC 0x94*/{NULL},
6930 /*MMC 0x95*/{NULL},
6931 /*MMC 0x96*/{NULL},
6932 /*MMC 0x97*/{NULL},
6933 /*MMC 0x98*/{NULL},
6934 /*MMC 0x99*/{NULL},
6935 /*MMC 0x9a*/{NULL},
6936 /*MMC 0x9b*/{NULL},
6937 /*MMC 0x9c*/{NULL},
6938 /*MMC 0x9d*/{NULL},
6939 /*MMC 0x9e*/{NULL},
6940 /*MMC 0x9f*/{NULL},
6941 /*MMC 0xa0*/{NULL},
6942 /*MMC 0xa1*/{NULL},
6943 /*MMC 0xa2*/{NULL},
6944 /*MMC 0xa3*/{NULL},
6945 /*MMC 0xa4*/{dissect_mmc4_reportkey},
6946 /*MMC 0xa5*/{NULL},
6947 /*MMC 0xa6*/{NULL},
6948 /*MMC 0xa7*/{NULL},
6949 /*MMC 0xa8*/{dissect_sbc2_readwrite12},
6950 /*MMC 0xa9*/{NULL},
6951 /*MMC 0xaa*/{dissect_sbc2_readwrite12},
6952 /*MMC 0xab*/{NULL},
6953 /*MMC 0xac*/{NULL},
6954 /*MMC 0xad*/{NULL},
6955 /*MMC 0xae*/{NULL},
6956 /*MMC 0xaf*/{NULL},
6957 /*MMC 0xb0*/{NULL},
6958 /*MMC 0xb1*/{NULL},
6959 /*MMC 0xb2*/{NULL},
6960 /*MMC 0xb3*/{NULL},
6961 /*MMC 0xb4*/{NULL},
6962 /*MMC 0xb5*/{NULL},
6963 /*MMC 0xb6*/{dissect_mmc4_setstreaming},
6964 /*MMC 0xb7*/{NULL},
6965 /*MMC 0xb8*/{NULL},
6966 /*MMC 0xb9*/{NULL},
6967 /*MMC 0xba*/{NULL},
6968 /*MMC 0xbb*/{NULL},
6969 /*MMC 0xbc*/{NULL},
6970 /*MMC 0xbd*/{NULL},
6971 /*MMC 0xbe*/{NULL},
6972 /*MMC 0xbf*/{NULL},
6973 /*MMC 0xc0*/{NULL},
6974 /*MMC 0xc1*/{NULL},
6975 /*MMC 0xc2*/{NULL},
6976 /*MMC 0xc3*/{NULL},
6977 /*MMC 0xc4*/{NULL},
6978 /*MMC 0xc5*/{NULL},
6979 /*MMC 0xc6*/{NULL},
6980 /*MMC 0xc7*/{NULL},
6981 /*MMC 0xc8*/{NULL},
6982 /*MMC 0xc9*/{NULL},
6983 /*MMC 0xca*/{NULL},
6984 /*MMC 0xcb*/{NULL},
6985 /*MMC 0xcc*/{NULL},
6986 /*MMC 0xcd*/{NULL},
6987 /*MMC 0xce*/{NULL},
6988 /*MMC 0xcf*/{NULL},
6989 /*MMC 0xd0*/{NULL},
6990 /*MMC 0xd1*/{NULL},
6991 /*MMC 0xd2*/{NULL},
6992 /*MMC 0xd3*/{NULL},
6993 /*MMC 0xd4*/{NULL},
6994 /*MMC 0xd5*/{NULL},
6995 /*MMC 0xd6*/{NULL},
6996 /*MMC 0xd7*/{NULL},
6997 /*MMC 0xd8*/{NULL},
6998 /*MMC 0xd9*/{NULL},
6999 /*MMC 0xda*/{NULL},
7000 /*MMC 0xdb*/{NULL},
7001 /*MMC 0xdc*/{NULL},
7002 /*MMC 0xdd*/{NULL},
7003 /*MMC 0xde*/{NULL},
7004 /*MMC 0xdf*/{NULL},
7005 /*MMC 0xe0*/{NULL},
7006 /*MMC 0xe1*/{NULL},
7007 /*MMC 0xe2*/{NULL},
7008 /*MMC 0xe3*/{NULL},
7009 /*MMC 0xe4*/{NULL},
7010 /*MMC 0xe5*/{NULL},
7011 /*MMC 0xe6*/{NULL},
7012 /*MMC 0xe7*/{NULL},
7013 /*MMC 0xe8*/{NULL},
7014 /*MMC 0xe9*/{NULL},
7015 /*MMC 0xea*/{NULL},
7016 /*MMC 0xeb*/{NULL},
7017 /*MMC 0xec*/{NULL},
7018 /*MMC 0xed*/{NULL},
7019 /*MMC 0xee*/{NULL},
7020 /*MMC 0xef*/{NULL},
7021 /*MMC 0xf0*/{NULL},
7022 /*MMC 0xf1*/{NULL},
7023 /*MMC 0xf2*/{NULL},
7024 /*MMC 0xf3*/{NULL},
7025 /*MMC 0xf4*/{NULL},
7026 /*MMC 0xf5*/{NULL},
7027 /*MMC 0xf6*/{NULL},
7028 /*MMC 0xf7*/{NULL},
7029 /*MMC 0xf8*/{NULL},
7030 /*MMC 0xf9*/{NULL},
7031 /*MMC 0xfa*/{NULL},
7032 /*MMC 0xfb*/{NULL},
7033 /*MMC 0xfc*/{NULL},
7034 /*MMC 0xfd*/{NULL},
7035 /*MMC 0xfe*/{NULL},
7036 /*MMC 0xff*/{NULL}
7037 };
7038
7039 void
7040 dissect_scsi_cdb (tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree,
7041                   gint devtype_arg, guint16 lun)
7042 {
7043     int offset = 0;
7044     proto_item *ti;
7045     proto_tree *scsi_tree = NULL;
7046     guint8 opcode;
7047     scsi_device_type devtype;
7048     scsi_cmnd_type cmd = 0;     /* 0 is undefined type */
7049     const gchar *valstr;
7050     scsi_task_data_t *cdata;
7051     scsi_devtype_key_t dkey;
7052     scsi_devtype_data_t *devdata;
7053     scsi_cdb_table_t *cdb_table=NULL;
7054     const value_string *cdb_vals = NULL;
7055     int hf_opcode=-1;
7056
7057     opcode = tvb_get_guint8 (tvb, offset);
7058
7059     if (devtype_arg != SCSI_DEV_UNKNOWN) {
7060         devtype = devtype_arg;
7061     } else {
7062         /*
7063          * Try to look up the device data for this device.
7064          *
7065          * We don't use COPY_ADDRESS because "dkey.devid" isn't
7066          * persistent, and therefore it can point to the stuff
7067          * in "pinfo->src".  (Were we to use COPY_ADDRESS, we'd
7068          * have to free the address data it allocated before we return.)
7069          */
7070         dkey.devid = pinfo->dst;
7071
7072         devdata = (scsi_devtype_data_t *)g_hash_table_lookup (scsidev_req_hash,
7073                                                               &dkey);
7074         if (devdata != NULL) {
7075             devtype = devdata->devtype;
7076         } else {
7077             devtype = (scsi_device_type)scsi_def_devtype;
7078         }
7079     }
7080
7081     if ((valstr = match_strval (opcode, scsi_spc2_val)) == NULL) {
7082         /*
7083          * This isn't a generic command that applies to all SCSI
7084          * device types; try to interpret it based on what we deduced,
7085          * or were told, the device type is.
7086          *
7087          * Right now, the only choices are SBC or SSC. If we ever expand
7088          * this to decode other device types, this piece of code needs to
7089          * be modified.
7090          */
7091         switch (devtype) {
7092         case SCSI_DEV_SBC:
7093             valstr = match_strval (opcode, scsi_sbc2_val);
7094             cmd = SCSI_CMND_SBC2;
7095             cdb_table=sbc;
7096             cdb_vals=scsi_sbc2_val;
7097             hf_opcode=hf_scsi_sbcopcode;
7098             break;
7099
7100         case SCSI_DEV_CDROM:
7101             valstr = match_strval (opcode, scsi_mmc_val);
7102             cmd = SCSI_CMND_MMC;
7103             cdb_table=mmc;
7104             cdb_vals=scsi_mmc_val;
7105             hf_opcode=hf_scsi_mmcopcode;
7106             break;
7107
7108         case SCSI_DEV_SSC:
7109             valstr = match_strval (opcode, scsi_ssc2_val);
7110             cmd = SCSI_CMND_SSC2;
7111             cdb_table=ssc;
7112             cdb_vals=scsi_ssc2_val;
7113             hf_opcode=hf_scsi_sscopcode;
7114             break;
7115
7116         case SCSI_DEV_SMC:
7117             valstr = match_strval (opcode, scsi_smc2_val);
7118             cmd = SCSI_CMND_SMC2;
7119             cdb_table=smc;
7120             cdb_vals=scsi_smc2_val;
7121             hf_opcode=hf_scsi_smcopcode;
7122             break;
7123
7124         default:
7125             cmd = SCSI_CMND_SPC2;
7126             cdb_table=spc;
7127             cdb_vals=scsi_spc2_val;
7128             hf_opcode=hf_scsi_spcopcode;
7129             break;
7130         }
7131     } else {
7132         cmd = SCSI_CMND_SPC2;
7133         cdb_table=spc;
7134         cdb_vals=scsi_spc2_val;
7135         hf_opcode=hf_scsi_spcopcode;
7136     }
7137
7138     if (valstr != NULL) {
7139         if (check_col (pinfo->cinfo, COL_INFO)) {
7140             col_add_fstr (pinfo->cinfo, COL_INFO, "SCSI: %s LUN: 0x%02x ", valstr, lun);
7141         }
7142     } else {
7143         if (check_col (pinfo->cinfo, COL_INFO)) {
7144             col_add_fstr (pinfo->cinfo, COL_INFO, "SCSI Command: 0x%02x LUN:0x%02x ", opcode, lun);
7145         }
7146     }
7147
7148     cdata = scsi_new_task (pinfo);
7149
7150     if (cdata) {
7151         cdata->opcode = opcode;
7152         cdata->cmd = cmd;
7153         cdata->devtype = devtype;
7154         cdata->flags = 0;
7155         cdata->cdb_table = cdb_table;
7156         cdata->cdb_vals = cdb_vals;
7157     }
7158
7159     if (tree) {
7160         ti = proto_tree_add_protocol_format (tree, proto_scsi, tvb, 0,
7161                                              -1, "SCSI CDB %s",
7162                                              val_to_str (opcode,
7163                                                          cdb_vals,
7164                                                          "0x%02x")
7165                                              );
7166         scsi_tree = proto_item_add_subtree (ti, ett_scsi);
7167
7168         ti=proto_tree_add_uint(scsi_tree, hf_scsi_lun, tvb, 0, 0, lun);
7169         PROTO_ITEM_SET_GENERATED(ti);
7170
7171
7172         if (valstr != NULL) {
7173             proto_tree_add_uint_format (scsi_tree, hf_opcode, tvb,
7174                                         offset, 1,
7175                                         tvb_get_guint8 (tvb, offset),
7176                                         "Opcode: %s (0x%02x)", valstr,
7177                                         opcode);
7178         } else {
7179             proto_tree_add_item (scsi_tree, hf_scsi_spcopcode, tvb, offset, 1, 0);
7180         }
7181     }
7182
7183     /*
7184        All commandsets support SPC?
7185     */
7186     if(cdb_table && cdb_table[opcode].func){
7187         cdb_table[opcode].func(tvb, pinfo, scsi_tree, offset+1,
7188                                TRUE, TRUE, 0, cdata);
7189     } else if(spc[opcode].func){
7190         spc[opcode].func(tvb, pinfo, scsi_tree, offset+1,
7191                                TRUE, TRUE, 0, cdata);
7192     } else {
7193         call_dissector (data_handle, tvb, pinfo, scsi_tree);
7194     }
7195 }
7196
7197 void
7198 dissect_scsi_payload (tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree,
7199                       gboolean isreq, guint16 lun)
7200 {
7201     int offset=0;
7202     proto_item *ti;
7203     proto_tree *scsi_tree = NULL;
7204     guint8 opcode = 0xFF;
7205     scsi_device_type devtype;
7206     scsi_task_data_t *cdata = NULL;
7207     int payload_len;
7208
7209     payload_len=tvb_length(tvb);
7210     cdata = scsi_find_task (pinfo);
7211
7212     if (!cdata) {
7213         /* we have no record of this exchange and so we can't dissect the
7214          * payload
7215          */
7216         return;
7217     }
7218
7219     opcode = cdata->opcode;
7220     devtype = cdata->devtype;
7221
7222     if (tree) {
7223         ti = proto_tree_add_protocol_format (tree, proto_scsi, tvb, offset,
7224                                              payload_len,
7225                                              "SCSI Payload (%s %s)",
7226                                              val_to_str (opcode,
7227                                                          cdata->cdb_vals,
7228                                                          "0x%02x"),
7229                                              isreq ? "Request" : "Response");
7230         if (check_col (pinfo->cinfo, COL_INFO)) {
7231             col_add_fstr (pinfo->cinfo, COL_INFO,
7232                         "SCSI: Data %s LUN: 0x%02x (%s %s) ",
7233                         isreq ? "Out" : "In",
7234                         lun,
7235                         val_to_str (opcode, cdata->cdb_vals, "0x%02x"),
7236                         isreq ? "Request" : "Response");
7237         }
7238         scsi_tree = proto_item_add_subtree (ti, ett_scsi);
7239     }
7240
7241     if(tree){
7242         ti=proto_tree_add_uint(scsi_tree, hf_scsi_lun, tvb, 0, 0, lun);
7243         PROTO_ITEM_SET_GENERATED(ti);
7244     }
7245
7246     if (tree == NULL) {
7247         /*
7248          * We have to dissect INQUIRY responses, in order to determine the
7249          * types of devices.
7250          *
7251          * We don't bother dissecting other payload if we're not buildng
7252          * a protocol tree.
7253          *
7254          * We assume opcode 0x12 is always INQUIRY regardless of the
7255          * commandset used.
7256          */
7257         if (opcode == SCSI_SPC2_INQUIRY) {
7258             dissect_spc3_inquiry (tvb, pinfo, scsi_tree, offset, isreq,
7259                                   FALSE, payload_len, cdata);
7260         }
7261     } else {
7262         /*
7263            All commandsets support SPC?
7264         */
7265         if(cdata->cdb_table && (cdata->cdb_table)[opcode].func){
7266             (cdata->cdb_table)[opcode].func(tvb, pinfo, scsi_tree, offset,
7267                                isreq, FALSE, payload_len, cdata);
7268         } else if(spc[opcode].func){
7269             spc[opcode].func(tvb, pinfo, scsi_tree, offset,
7270                                isreq, FALSE, payload_len, cdata);
7271         } else { /* dont know this CDB */
7272             call_dissector (data_handle, tvb, pinfo, scsi_tree);
7273         }
7274     }
7275 }
7276
7277 void
7278 proto_register_scsi (void)
7279 {
7280     /* Setup list of header fields  See Section 1.6.1 for details*/
7281     static hf_register_info hf[] = {
7282         /*16 bit to print something useful for weirdo
7283                 volume set addressing hosts*/
7284        { &hf_scsi_lun,
7285           {"LUN", "scsi.lun", FT_UINT16, BASE_HEX,
7286            NULL, 0x0, "LUN", HFILL}},
7287         { &hf_scsi_status,
7288           { "Status", "scsi.status", FT_UINT8, BASE_HEX,
7289            VALS(scsi_status_val), 0, "SCSI command status value", HFILL }},
7290         { &hf_scsi_spcopcode,
7291           {"SPC-2 Opcode", "scsi.spc.opcode", FT_UINT8, BASE_HEX,
7292            VALS (scsi_spc2_val), 0x0, "", HFILL}},
7293         { &hf_scsi_mmcopcode,
7294           {"MMC Opcode", "scsi.mmc.opcode", FT_UINT8, BASE_HEX,
7295            VALS (scsi_mmc_val), 0x0, "", HFILL}},
7296         { &hf_scsi_sbcopcode,
7297           {"SBC-2 Opcode", "scsi.sbc.opcode", FT_UINT8, BASE_HEX,
7298            VALS (scsi_sbc2_val), 0x0, "", HFILL}},
7299         { &hf_scsi_sscopcode,
7300           {"SSC-2 Opcode", "scsi.ssc.opcode", FT_UINT8, BASE_HEX,
7301            VALS (scsi_ssc2_val), 0x0, "", HFILL}},
7302         { &hf_scsi_smcopcode,
7303           {"SMC-2 Opcode", "scsi.smc.opcode", FT_UINT8, BASE_HEX,
7304            VALS (scsi_smc2_val), 0x0, "", HFILL}},
7305         { &hf_scsi_control,
7306           {"Control", "scsi.cdb.control", FT_UINT8, BASE_HEX, NULL, 0x0, "",
7307            HFILL}},
7308         { &hf_scsi_inquiry_flags,
7309           {"Flags", "scsi.inquiry.flags", FT_UINT8, BASE_HEX, NULL, 0x0, "",
7310            HFILL}},
7311         { &hf_scsi_inquiry_evpd_page,
7312           {"EVPD Page Code", "scsi.inquiry.evpd.pagecode", FT_UINT8, BASE_HEX,
7313            VALS (scsi_evpd_pagecode_val), 0x0, "", HFILL}},
7314         { &hf_scsi_inquiry_cmdt_page,
7315           {"CMDT Page Code", "scsi.inquiry.cmdt.pagecode", FT_UINT8, BASE_HEX,
7316            NULL, 0x0, "", HFILL}},
7317         { &hf_scsi_alloclen,
7318           {"Allocation Length", "scsi.cdb.alloclen", FT_UINT8, BASE_DEC, NULL,
7319            0x0, "", HFILL}},
7320         { &hf_scsi_logsel_flags,
7321           {"Flags", "scsi.logsel.flags", FT_UINT8, BASE_HEX, NULL, 0x0, "",
7322            HFILL}},
7323         { &hf_scsi_logsel_pc,
7324           {"Page Control", "scsi.logsel.pc", FT_UINT8, BASE_DEC,
7325            VALS (scsi_logsel_pc_val), 0xC0, "", HFILL}},
7326         { &hf_scsi_paramlen,
7327           {"Parameter Length", "scsi.cdb.paramlen", FT_UINT8, BASE_DEC, NULL,
7328            0x0, "", HFILL}},
7329         { &hf_scsi_logsns_flags,
7330           {"Flags", "scsi.logsns.flags", FT_UINT16, BASE_HEX, NULL, 0x0, "",
7331            HFILL}},
7332         { &hf_scsi_logsns_pc,
7333           {"Page Control", "scsi.logsns.pc", FT_UINT8, BASE_DEC,
7334            VALS (scsi_logsns_pc_val), 0xC0, "", HFILL}},
7335         { &hf_scsi_logsns_pagecode,
7336           {"Page Code", "scsi.logsns.pagecode", FT_UINT8, BASE_HEX,
7337            VALS (scsi_logsns_page_val), 0x3F0, "", HFILL}},
7338         { &hf_scsi_paramlen16,
7339           {"Parameter Length", "scsi.cdb.paramlen16", FT_UINT16, BASE_DEC, NULL,
7340            0x0, "", HFILL}},
7341         { &hf_scsi_modesel_flags,
7342           {"Mode Sense/Select Flags", "scsi.cdb.mode.flags", FT_UINT8, BASE_HEX,
7343            NULL, 0x0, "", HFILL}},
7344         { &hf_scsi_alloclen16,
7345           {"Allocation Length", "scsi.cdb.alloclen16", FT_UINT16, BASE_DEC,
7346            NULL, 0x0, "", HFILL}},
7347         { &hf_scsi_modesns_pc,
7348           {"Page Control", "scsi.mode.pc", FT_UINT8, BASE_DEC,
7349            VALS (scsi_modesns_pc_val), 0xC0, "", HFILL}},
7350         { &hf_scsi_spcpagecode,
7351           {"SPC-2 Page Code", "scsi.mode.spc.pagecode", FT_UINT8, BASE_HEX,
7352            VALS (scsi_spc2_modepage_val), 0x3F, "", HFILL}},
7353         { &hf_scsi_sbcpagecode,
7354           {"SBC-2 Page Code", "scsi.mode.sbc.pagecode", FT_UINT8, BASE_HEX,
7355            VALS (scsi_sbc2_modepage_val), 0x3F, "", HFILL}},
7356         { &hf_scsi_sscpagecode,
7357           {"SSC-2 Page Code", "scsi.mode.ssc.pagecode", FT_UINT8, BASE_HEX,
7358            VALS (scsi_ssc2_modepage_val), 0x3F, "", HFILL}},
7359         { &hf_scsi_mmcpagecode,
7360           {"MMC-5 Page Code", "scsi.mode.mmc.pagecode", FT_UINT8, BASE_HEX,
7361            VALS (scsi_mmc5_modepage_val), 0x3F, "", HFILL}},
7362         { &hf_scsi_smcpagecode,
7363           {"SMC-2 Page Code", "scsi.mode.smc.pagecode", FT_UINT8, BASE_HEX,
7364            VALS (scsi_smc2_modepage_val), 0x3F, "", HFILL}},
7365         { &hf_scsi_modesns_flags,
7366           {"Flags", "scsi.mode.flags", FT_UINT8, BASE_HEX, NULL, 0x0, "",
7367            HFILL}},
7368         { &hf_scsi_persresvin_svcaction,
7369           {"Service Action", "scsi.persresvin.svcaction", FT_UINT8, BASE_HEX,
7370            VALS (scsi_persresvin_svcaction_val), 0x0F, "", HFILL}},
7371         { &hf_scsi_persresvout_svcaction,
7372           {"Service Action", "scsi.persresvout.svcaction", FT_UINT8, BASE_HEX,
7373            VALS (scsi_persresvout_svcaction_val), 0x0F, "", HFILL}},
7374         { &hf_scsi_persresv_scope,
7375           {"Reservation Scope", "scsi.persresv.scope", FT_UINT8, BASE_HEX,
7376            VALS (scsi_persresv_scope_val), 0xF0, "", HFILL}},
7377         { &hf_scsi_persresv_type,
7378           {"Reservation Type", "scsi.persresv.type", FT_UINT8, BASE_HEX,
7379            VALS (scsi_persresv_type_val), 0x0F, "", HFILL}},
7380         { &hf_scsi_release_flags,
7381           {"Release Flags", "scsi.release.flags", FT_UINT8, BASE_HEX, NULL,
7382            0x0, "", HFILL}},
7383         { &hf_scsi_release_thirdpartyid,
7384           {"Third-Party ID", "scsi.release.thirdpartyid", FT_BYTES, BASE_HEX,
7385            NULL, 0x0, "", HFILL}},
7386         { &hf_scsi_alloclen32,
7387           {"Allocation Length", "scsi.cdb.alloclen32", FT_UINT32, BASE_DEC,
7388            NULL, 0x0, "", HFILL}},
7389         { &hf_scsi_formatunit_flags,
7390           {"Flags", "scsi.formatunit.flags", FT_UINT8, BASE_HEX, NULL, 0xF8,
7391            "", HFILL}},
7392         { &hf_scsi_cdb_defectfmt,
7393           {"Defect List Format", "scsi.cdb.defectfmt", FT_UINT8, BASE_DEC,
7394            NULL, 0x7, "", HFILL}},
7395         { &hf_scsi_formatunit_interleave,
7396           {"Interleave", "scsi.formatunit.interleave", FT_UINT16, BASE_HEX,
7397            NULL, 0x0, "", HFILL}},
7398         { &hf_scsi_formatunit_vendor,
7399           {"Vendor Unique", "scsi.formatunit.vendor", FT_UINT8, BASE_HEX, NULL,
7400            0x0, "", HFILL}},
7401         { &hf_scsi_rdwr6_lba,
7402           {"Logical Block Address (LBA)", "scsi.rdwr6.lba", FT_UINT24, BASE_DEC,
7403            NULL, 0x0FFFFF, "", HFILL}},
7404         { &hf_scsi_rdwr6_xferlen,
7405           {"Transfer Length", "scsi.rdwr6.xferlen", FT_UINT24, BASE_DEC, NULL, 0x0,
7406            "", HFILL}},
7407         { &hf_scsi_rdwr10_lba,
7408           {"Logical Block Address (LBA)", "scsi.rdwr10.lba", FT_UINT32, BASE_DEC,
7409            NULL, 0x0, "", HFILL}},
7410         { &hf_scsi_rdwr10_xferlen,
7411           {"Transfer Length", "scsi.rdwr10.xferlen", FT_UINT16, BASE_DEC, NULL,
7412            0x0, "", HFILL}},
7413         { &hf_scsi_read_flags,
7414           {"Flags", "scsi.read.flags", FT_UINT8, BASE_HEX, NULL, 0x0, "",
7415            HFILL}},
7416         { &hf_scsi_rdwr12_xferlen,
7417           {"Transfer Length", "scsi.rdwr12.xferlen", FT_UINT32, BASE_DEC, NULL,
7418            0x0, "", HFILL}},
7419         { &hf_scsi_rdwr16_lba,
7420           {"Logical Block Address (LBA)", "scsi.rdwr16.lba", FT_BYTES, BASE_DEC,
7421            NULL, 0x0, "", HFILL}},
7422         { &hf_scsi_readcapacity_flags,
7423           {"Flags", "scsi.readcapacity.flags", FT_UINT8, BASE_HEX, NULL, 0x0,
7424            "", HFILL}},
7425         { &hf_scsi_readcapacity_lba,
7426           {"Logical Block Address", "scsi.readcapacity.lba", FT_UINT32, BASE_DEC,
7427            NULL, 0x0, "", HFILL}},
7428         { &hf_scsi_readcapacity_pmi,
7429           {"PMI", "scsi.readcapacity.pmi", FT_UINT8, BASE_DEC, NULL, 0x1, "",
7430            HFILL}},
7431         { &hf_scsi_readdefdata_flags,
7432           {"Flags", "scsi.readdefdata.flags", FT_UINT8, BASE_HEX, NULL, 0x0, "",
7433            HFILL}},
7434         { &hf_scsi_reassignblks_flags,
7435           {"Flags", "scsi.reassignblks.flags", FT_UINT8, BASE_HEX, NULL, 0x0, "",
7436            HFILL}},
7437         { &hf_scsi_inq_qualifier,
7438           {"Peripheral Qualifier", "scsi.inquiry.qualifier", FT_UINT8, BASE_HEX,
7439            VALS (scsi_qualifier_val), 0xE0, "", HFILL}},
7440         { &hf_scsi_inq_devtype,
7441           {"Peripheral Device Type", "scsi.inquiry.devtype", FT_UINT8, BASE_HEX,
7442            VALS (scsi_devtype_val), SCSI_DEV_BITS, "", HFILL}},
7443         { &hf_scsi_inq_rmb,
7444           {"Removable", "scsi.inquiry.removable", FT_BOOLEAN, 8,
7445            TFS (&scsi_removable_val), 0x80, "", HFILL}},
7446         { & hf_scsi_inq_version,
7447           {"Version", "scsi.inquiry.version", FT_UINT8, BASE_HEX,
7448            VALS (scsi_inquiry_vers_val), 0x0, "", HFILL}},
7449         { &hf_scsi_inq_normaca,
7450           {"NormACA", "scsi.inquiry.normaca", FT_UINT8, BASE_HEX, NULL, 0x20,
7451            "", HFILL}},
7452         { &hf_scsi_rluns_lun,
7453           {"LUN", "scsi.reportluns.lun", FT_UINT8, BASE_DEC, NULL, 0x0, "",
7454            HFILL}},
7455         { &hf_scsi_rluns_multilun,
7456           {"Multi-level LUN", "scsi.reportluns.mlun", FT_BYTES, BASE_HEX, NULL,
7457            0x0, "", HFILL}},
7458         { &hf_scsi_modesns_errrep,
7459           {"MRIE", "scsi.mode.mrie", FT_UINT8, BASE_HEX,
7460            VALS (scsi_modesns_mrie_val), 0x0F, "", HFILL}},
7461         { &hf_scsi_modesns_tst,
7462           {"Task Set Type", "scsi.mode.tst", FT_UINT8, BASE_DEC,
7463            VALS (scsi_modesns_tst_val), 0xE0, "", HFILL}},
7464         { &hf_scsi_modesns_qmod,
7465           {"Queue Algorithm Modifier", "scsi.mode.qmod", FT_UINT8, BASE_HEX,
7466            VALS (scsi_modesns_qmod_val), 0xF0, "", HFILL}},
7467         { &hf_scsi_modesns_qerr,
7468           {"Queue Error Management", "scsi.mode.qerr", FT_BOOLEAN, BASE_HEX,
7469            TFS (&scsi_modesns_qerr_val), 0x2, "", HFILL}},
7470         { &hf_scsi_modesns_tas,
7471           {"Task Aborted Status", "scsi.mode.tac", FT_BOOLEAN, BASE_HEX,
7472            TFS (&scsi_modesns_tas_val), 0x80, "", HFILL}},
7473         { &hf_scsi_modesns_rac,
7474           {"Report a Check", "ssci.mode.rac", FT_BOOLEAN, BASE_HEX,
7475            TFS (&scsi_modesns_rac_val), 0x40, "", HFILL}},
7476         { &hf_scsi_protocol,
7477           {"Protocol", "scsi.proto", FT_UINT8, BASE_DEC, VALS (scsi_proto_val),
7478            0x0F, "", HFILL}},
7479         { &hf_scsi_sns_errtype,
7480           {"SNS Error Type", "scsi.sns.errtype", FT_UINT8, BASE_HEX,
7481            VALS (scsi_sns_errtype_val), 0x7F, "", HFILL}},
7482         { &hf_scsi_snskey,
7483           {"Sense Key", "scsi.sns.key", FT_UINT8, BASE_HEX,
7484            VALS (scsi_sensekey_val), 0x0F, "", HFILL}},
7485         { &hf_scsi_snsinfo,
7486           {"Sense Info", "scsi.sns.info", FT_UINT32, BASE_HEX, NULL, 0x0, "",
7487            HFILL}},
7488         { &hf_scsi_addlsnslen,
7489           {"Additional Sense Length", "scsi.sns.addlen", FT_UINT8, BASE_DEC,
7490            NULL, 0x0, "", HFILL}},
7491         { &hf_scsi_asc,
7492           {"Additional Sense Code", "scsi.sns.asc", FT_UINT8, BASE_HEX, NULL,
7493            0x0, "", HFILL}},
7494         { &hf_scsi_ascq,
7495           {"Additional Sense Code Qualifier", "scsi.sns.ascq", FT_UINT8,
7496            BASE_HEX, NULL, 0x0, "", HFILL}},
7497         { &hf_scsi_ascascq,
7498           {"Additional Sense Code+Qualifier", "scsi.sns.ascascq", FT_UINT16,
7499            BASE_HEX, VALS (scsi_asc_val), 0x0, "", HFILL}},
7500         { &hf_scsi_fru,
7501           {"Field Replaceable Unit Code", "scsi.sns.fru", FT_UINT8, BASE_HEX,
7502            NULL, 0x0, "", HFILL}},
7503         { &hf_scsi_sksv,
7504           {"SKSV", "scsi.sns.sksv", FT_BOOLEAN, BASE_HEX, NULL, 0x80, "",
7505            HFILL}},
7506         { &hf_scsi_persresv_key,
7507           {"Reservation Key", "scsi.spc2.resv.key", FT_BYTES, BASE_HEX, NULL,
7508            0x0, "", HFILL}},
7509         { &hf_scsi_persresv_scopeaddr,
7510           {"Scope Address", "scsi.spc2.resv.scopeaddr", FT_BYTES, BASE_HEX, NULL,
7511            0x0, "", HFILL}},
7512         { &hf_scsi_add_cdblen,
7513           {"Additional CDB Length", "scsi.spc2.addcdblen", FT_UINT8, BASE_DEC,
7514            NULL, 0x0, "", HFILL}},
7515         { &hf_scsi_svcaction,
7516           {"Service Action", "scsi.spc2.svcaction", FT_UINT16, BASE_HEX, NULL,
7517            0x0, "", HFILL}},
7518         { &hf_scsi_ssu_immed,
7519           {"Immediate", "scsi.sbc2.ssu.immediate", FT_BOOLEAN, BASE_DEC, NULL,
7520            0x1, "", HFILL}},
7521         { &hf_scsi_ssu_pwr_cond,
7522           {"Power Conditions", "scsi.sbc2.ssu.pwr", FT_UINT8, BASE_HEX,
7523            VALS (scsi_ssu_pwrcnd_val), 0xF0, "", HFILL}},
7524         { &hf_scsi_ssu_loej,
7525           {"LOEJ", "scsi.sbc2.ssu.loej", FT_BOOLEAN, BASE_HEX, NULL, 0x2, "",
7526            HFILL}},
7527         { &hf_scsi_ssu_start,
7528           {"Start", "scsi.sbc2.ssu.start", FT_BOOLEAN, BASE_HEX, NULL, 0x1,
7529            "", HFILL}},
7530         { &hf_scsi_wb_mode,
7531           {"Mode", "scsi.spc2.wb.mode", FT_UINT8, BASE_HEX,
7532            VALS (scsi_wb_mode_val), 0xF, "", HFILL}},
7533         { &hf_scsi_wb_bufferid,
7534           {"Buffer ID", "scsi.spc2.sb.bufid", FT_UINT8, BASE_DEC, NULL, 0x0,
7535            "", HFILL}},
7536         { &hf_scsi_wb_bufoffset,
7537           {"Buffer Offset", "scsi.spc2.wb.bufoff", FT_UINT24, BASE_HEX, NULL,
7538            0x0, "", HFILL}},
7539         { &hf_scsi_paramlen24,
7540           {"Paremeter List Length", "scsi.cdb.paramlen24", FT_UINT24, BASE_HEX,
7541            NULL, 0x0, "", HFILL}},
7542         { &hf_scsi_senddiag_st_code,
7543           {"Self-Test Code", "scsi.spc2.senddiag.code", FT_UINT8, BASE_HEX,
7544            VALS (scsi_senddiag_st_code_val), 0xE0, "", HFILL}},
7545         { &hf_scsi_select_report,
7546           {"Select Report", "scsi.spc2.select_report", FT_UINT8, BASE_HEX,
7547            VALS (scsi_select_report_val), 0x00, "", HFILL}},
7548         { &hf_scsi_senddiag_pf,
7549           {"PF", "scsi.spc2.senddiag.pf", FT_BOOLEAN, BASE_HEX,
7550            TFS (&scsi_senddiag_pf_val), 0x10, "", HFILL}},
7551         { &hf_scsi_senddiag_st,
7552           {"Self Test", "scsi.spc2.senddiag.st", FT_BOOLEAN, BASE_HEX, NULL,
7553            0x4, "", HFILL}},
7554         { &hf_scsi_senddiag_devoff,
7555           {"Device Offline", "scsi.spc2.senddiag.devoff", FT_BOOLEAN, BASE_HEX,
7556            NULL, 0x2, "", HFILL}},
7557         { &hf_scsi_senddiag_unitoff,
7558           {"Unit Offline", "scsi.spc2.senddiag.unitoff", FT_BOOLEAN, BASE_HEX,
7559            NULL, 0x1, "", HFILL}},
7560         { &hf_scsi_key_class,
7561           {"Key Class", "scsi.mmc4.key_class", FT_UINT8, BASE_HEX,
7562            VALS (scsi_key_class_val), 0x00, "", HFILL}},
7563         { &hf_scsi_agid,
7564           {"AGID", "scsi.mmc4.agid", FT_UINT8, BASE_HEX,
7565            NULL, 0xc0, "", HFILL}},
7566         { &hf_scsi_key_format,
7567           {"Key Format", "scsi.mmc4.key_format", FT_UINT8, BASE_HEX,
7568            VALS (scsi_key_format_val), 0x3f, "", HFILL}},
7569         { &hf_scsi_lba,
7570           {"Logical Block Address", "scsi.lba", FT_UINT32, BASE_DEC,
7571            NULL, 0x0, "", HFILL}},
7572         { &hf_scsi_num_blocks,
7573           {"Number of Blocks", "scsi.num_blocks", FT_UINT32, BASE_DEC,
7574            NULL, 0x0, "", HFILL}},
7575         { &hf_scsi_data_length,
7576           {"Data Length", "scsi.data_length", FT_UINT32, BASE_DEC,
7577            NULL, 0x0, "", HFILL}},
7578         { &hf_scsi_report_key_type_code,
7579           {"Type Code", "scsi.report_key.type_code", FT_UINT8, BASE_HEX,
7580            VALS(scsi_report_key_type_code_val), 0xc0, "", HFILL}},
7581         { &hf_scsi_report_key_vendor_resets,
7582           {"Vendor Resets", "scsi.report_key.vendor_resets", FT_UINT8, BASE_HEX,
7583            NULL, 0x38, "", HFILL}},
7584         { &hf_scsi_report_key_user_changes,
7585           {"User Changes", "scsi.report_key.user_changes", FT_UINT8, BASE_HEX,
7586            NULL, 0x07, "", HFILL}},
7587         { &hf_scsi_report_key_region_mask,
7588           {"Region Mask", "scsi.report_key.region_mask", FT_UINT8, BASE_HEX,
7589            NULL, 0xff, "", HFILL}},
7590         { &hf_scsi_report_key_rpc_scheme,
7591           {"RPC Scheme", "scsi.report_key.rpc_scheme", FT_UINT8, BASE_HEX,
7592            VALS(scsi_report_key_rpc_scheme_val), 0, "", HFILL}},
7593         { &hf_scsi_getconf_rt,
7594           {"RT", "scsi.getconf.rt", FT_UINT8, BASE_HEX,
7595            VALS(scsi_getconf_rt_val), 0x03, "", HFILL}},
7596         { &hf_scsi_getconf_current_profile,
7597           {"Current Profile", "scsi.getconf.current_profile", FT_UINT16, BASE_HEX,
7598            VALS(scsi_getconf_current_profile_val), 0, "", HFILL}},
7599         { &hf_scsi_getconf_starting_feature,
7600           {"Starting Feature", "scsi.getconf.starting_feature", FT_UINT16, BASE_HEX,
7601            VALS(scsi_feature_val), 0, "", HFILL}},
7602         { &hf_scsi_feature,
7603           {"Feature", "scsi.feature", FT_UINT16, BASE_HEX,
7604            VALS(scsi_feature_val), 0, "", HFILL}},
7605         { &hf_scsi_feature_version,
7606           {"Version", "scsi.feature.version", FT_UINT8, BASE_DEC,
7607            NULL, 0x3c, "", HFILL}},
7608         { &hf_scsi_feature_persistent,
7609           {"Persistent", "scsi.feature.persistent", FT_UINT8, BASE_HEX,
7610            NULL, 0x02, "", HFILL}},
7611         { &hf_scsi_feature_current,
7612           {"Current", "scsi.feature.current", FT_UINT8, BASE_HEX,
7613            NULL, 001, "", HFILL}},
7614         { &hf_scsi_feature_additional_length,
7615           {"Additional Length", "scsi.feature.additional_length", FT_UINT8, BASE_DEC,
7616            NULL, 0, "", HFILL}},
7617         { &hf_scsi_feature_lun_sn,
7618           {"LUN Serial Number", "scsi.feature.lun_sn", FT_STRING, BASE_NONE,
7619            NULL, 0, "", HFILL}},
7620         { &hf_scsi_feature_cdread_dap,
7621           {"DAP", "scsi.feature.cdread.dap", FT_BOOLEAN, 8,
7622            NULL, 0x80, "", HFILL}},
7623         { &hf_scsi_feature_cdread_c2flag,
7624           {"C2 Flag", "scsi.feature.cdread.c2flag", FT_BOOLEAN, 8,
7625            NULL, 0x02, "", HFILL}},
7626         { &hf_scsi_feature_cdread_cdtext,
7627           {"CD-Text", "scsi.feature.cdread.cdtext", FT_BOOLEAN, 8,
7628            NULL, 0x01, "", HFILL}},
7629         { &hf_scsi_feature_dvdrw_write,
7630           {"Write", "scsi.feature.dvdrw.write", FT_BOOLEAN, 8,
7631            NULL, 0x01, "", HFILL}},
7632         { &hf_scsi_feature_dvdrw_quickstart,
7633           {"Quick Start", "scsi.feature.dvdrw.quickstart", FT_BOOLEAN, 8,
7634            NULL, 0x02, "", HFILL}},
7635         { &hf_scsi_feature_dvdrw_closeonly,
7636           {"Close Only", "scsi.feature.dvdrw.closeonly", FT_BOOLEAN, 8,
7637            NULL, 0x01, "", HFILL}},
7638         { &hf_scsi_feature_dvdr_write,
7639           {"Write", "scsi.feature.dvdr.write", FT_BOOLEAN, 8,
7640            NULL, 0x01, "", HFILL}},
7641         { &hf_scsi_feature_tao_buf,
7642           {"BUF", "scsi.feature.tao.buf", FT_BOOLEAN, 8,
7643            NULL, 0x40, "", HFILL}},
7644         { &hf_scsi_feature_tao_rwraw,
7645           {"R-W Raw", "scsi.feature.tao.rwraw", FT_BOOLEAN, 8,
7646            NULL, 0x10, "", HFILL}},
7647         { &hf_scsi_feature_tao_rwpack,
7648           {"R-W Pack", "scsi.feature.tao.rwpack", FT_BOOLEAN, 8,
7649            NULL, 0x08, "", HFILL}},
7650         { &hf_scsi_feature_tao_testwrite,
7651           {"Test Write", "scsi.feature.tao.testwrite", FT_BOOLEAN, 8,
7652            NULL, 0x04, "", HFILL}},
7653         { &hf_scsi_feature_tao_cdrw,
7654           {"CD-RW", "scsi.feature.tao.cdrw", FT_BOOLEAN, 8,
7655            NULL, 0x02, "", HFILL}},
7656         { &hf_scsi_feature_tao_rwsubcode,
7657           {"R-W Subcode", "scsi.feature.tao.rwsubcode", FT_BOOLEAN, 8,
7658            NULL, 0x01, "", HFILL}},
7659         { &hf_scsi_feature_dts,
7660           {"Data Type Supported", "scsi.feature.dts", FT_UINT16, BASE_HEX,
7661            NULL, 0xffff, "", HFILL}},
7662         { &hf_scsi_feature_sao_buf,
7663           {"BUF", "scsi.feature.sao.buf", FT_BOOLEAN, 8,
7664            NULL, 0x40, "", HFILL}},
7665         { &hf_scsi_feature_sao_sao,
7666           {"SAO", "scsi.feature.sao.sao", FT_BOOLEAN, 8,
7667            NULL, 0x20, "", HFILL}},
7668         { &hf_scsi_feature_sao_rawms,
7669           {"Raw MS", "scsi.feature.sao.rawms", FT_BOOLEAN, 8,
7670            NULL, 0x10, "", HFILL}},
7671         { &hf_scsi_feature_sao_raw,
7672           {"Raw", "scsi.feature.sao.raw", FT_BOOLEAN, 8,
7673            NULL, 0x08, "", HFILL}},
7674         { &hf_scsi_feature_sao_testwrite,
7675           {"Test Write", "scsi.feature.sao.testwrite", FT_BOOLEAN, 8,
7676            NULL, 0x04, "", HFILL}},
7677         { &hf_scsi_feature_sao_cdrw,
7678           {"CD-RW", "scsi.feature.sao.cdrw", FT_BOOLEAN, 8,
7679            NULL, 0x02, "", HFILL}},
7680         { &hf_scsi_feature_sao_rw,
7681           {"R-W", "scsi.feature.sao.rw", FT_BOOLEAN, 8,
7682            NULL, 0x01, "", HFILL}},
7683         { &hf_scsi_feature_sao_mcsl,
7684           {"Maximum Cue Sheet Length", "scsi.feature.sao.mcsl", FT_UINT24, BASE_DEC,
7685            NULL, 0, "", HFILL}},
7686         { &hf_scsi_feature_dvdr_buf,
7687           {"BUF", "scsi.feature.dvdr.buf", FT_BOOLEAN, 8,
7688            NULL, 0x40, "", HFILL}},
7689         { &hf_scsi_feature_dvdr_testwrite,
7690           {"Test Write", "scsi.feature.dvdr.testwrite", FT_BOOLEAN, 8,
7691            NULL, 0x04, "", HFILL}},
7692         { &hf_scsi_feature_dvdr_dvdrw,
7693           {"DVD-RW", "scsi.feature.dvdr.dvdrw", FT_BOOLEAN, 8,
7694            NULL, 0x02, "", HFILL}},
7695         { &hf_scsi_feature_profile,
7696           {"Profile", "scsi.feature.profile", FT_UINT16, BASE_HEX,
7697            VALS(scsi_getconf_current_profile_val), 0, "", HFILL}},
7698         { &hf_scsi_feature_profile_current,
7699           {"Current", "scsi.feature.profile.current", FT_BOOLEAN, 8,
7700            NULL, 0x01, "", HFILL}},
7701         { &hf_scsi_feature_isw_buf,
7702           {"BUF", "scsi.feature.isw.buf", FT_BOOLEAN, 8,
7703            NULL, 0x01, "", HFILL}},
7704         { &hf_scsi_feature_isw_num_linksize,
7705           {"Number of Link Sizes", "scsi.feature.isw.num_linksize", FT_UINT8, BASE_DEC,
7706            NULL, 0, "", HFILL}},
7707         { &hf_scsi_feature_isw_linksize,
7708           {"Link Size", "scsi.feature.isw.linksize", FT_UINT8, BASE_DEC,
7709            NULL, 0, "", HFILL}},
7710         { &hf_scsi_readtoc_time,
7711           {"Time", "scsi.readtoc.time", FT_BOOLEAN, 8,
7712            NULL, 0x02, "", HFILL}},
7713         { &hf_scsi_readtoc_format,
7714           {"Format", "scsi.readtoc.format", FT_UINT8, BASE_HEX,
7715            NULL, 0x0f, "", HFILL}},
7716         { &hf_scsi_track,
7717           {"Track", "scsi.track", FT_UINT32, BASE_DEC,
7718            NULL, 0, "", HFILL}},
7719         { &hf_scsi_track_size,
7720           {"Track Size", "scsi.track_size", FT_UINT32, BASE_DEC,
7721            NULL, 0, "", HFILL}},
7722         { &hf_scsi_session,
7723           {"Session", "scsi.session", FT_UINT32, BASE_DEC,
7724            NULL, 0, "", HFILL}},
7725         { &hf_scsi_first_track,
7726           {"First Track", "scsi.first_track", FT_UINT8, BASE_DEC,
7727            NULL, 0, "", HFILL}},
7728         { &hf_scsi_readtoc_first_session,
7729           {"First Session", "scsi.readtoc.first_session", FT_UINT8, BASE_DEC,
7730            NULL, 0, "", HFILL}},
7731         { &hf_scsi_readtoc_last_track,
7732           {"Last Track", "scsi.readtoc.last_track", FT_UINT8, BASE_DEC,
7733            NULL, 0, "", HFILL}},
7734         { &hf_scsi_readtoc_last_session,
7735           {"Last Session", "scsi.readtoc.last_session", FT_UINT8, BASE_DEC,
7736            NULL, 0, "", HFILL}},
7737         { &hf_scsi_q_subchannel_adr,
7738           {"Q Subchannel ADR", "scsi.q.subchannel.adr", FT_UINT8, BASE_HEX,
7739            VALS(scsi_q_subchannel_adr_val), 0xf0, "", HFILL}},
7740         { &hf_scsi_q_subchannel_control,
7741           {"Q Subchannel Control", "scsi.q.subchannel.control", FT_UINT8, BASE_HEX,
7742            VALS(scsi_q_subchannel_control_val), 0x0f, "", HFILL}},
7743         { &hf_scsi_track_start_address,
7744           {"Track Start Address", "scsi.track_start_address", FT_UINT32, BASE_DEC,
7745            NULL, 0, "", HFILL}},
7746         { &hf_scsi_next_writable_address,
7747           {"Next Writable Address", "scsi.next_writable_address", FT_UINT32, BASE_DEC,
7748            NULL, 0, "", HFILL}},
7749         { &hf_scsi_track_start_time,
7750           {"Track Start Time", "scsi.track_start_time", FT_UINT32, BASE_DEC,
7751            NULL, 0, "", HFILL}},
7752         { &hf_scsi_synccache_immed,
7753           {"IMMED", "scsi.synccache.immed", FT_BOOLEAN, 8,
7754            NULL, 0x02, "", HFILL}},
7755         { &hf_scsi_synccache_reladr,
7756           {"RelAdr", "scsi.synccache.reladr", FT_BOOLEAN, 8,
7757            NULL, 0x01, "", HFILL}},
7758         { &hf_scsi_rbc_block,
7759           {"BLOCK", "scsi.rbc.block", FT_BOOLEAN, 8,
7760            NULL, 0x01, "", HFILL}},
7761         { &hf_scsi_rbc_lob_blocks,
7762           {"Buffer Len (blocks)", "scsi.rbc.lob_blocks", FT_UINT32, BASE_DEC,
7763            NULL, 0, "", HFILL}},
7764         { &hf_scsi_rbc_alob_blocks,
7765           {"Available Buffer Len (blocks)", "scsi.rbc.alob_blocks", FT_UINT32, BASE_DEC,
7766            NULL, 0, "", HFILL}},
7767         { &hf_scsi_rbc_lob_bytes,
7768           {"Buffer Len (bytes)", "scsi.rbc.lob_bytes", FT_UINT32, BASE_DEC,
7769            NULL, 0, "", HFILL}},
7770         { &hf_scsi_rbc_alob_bytes,
7771           {"Available Buffer Len (bytes)", "scsi.rbc.alob_bytes", FT_UINT32, BASE_DEC,
7772            NULL, 0, "", HFILL}},
7773         { &hf_scsi_setstreaming_type,
7774           {"Type", "scsi.setstreaming.type", FT_UINT8, BASE_DEC,
7775            VALS(scsi_setstreaming_type_val), 0, "", HFILL}},
7776         { &hf_scsi_setstreaming_param_len,
7777           {"Parameter Length", "scsi.setstreaming.param_len", FT_UINT16, BASE_DEC,
7778            NULL, 0, "", HFILL}},
7779         { &hf_scsi_setstreaming_wrc,
7780           {"WRC", "scsi.setstreaming.wrc", FT_UINT8, BASE_HEX,
7781            NULL, 0x18, "", HFILL}},
7782         { &hf_scsi_setstreaming_rdd,
7783           {"RDD", "scsi.setstreaming.rdd", FT_BOOLEAN, 8,
7784            NULL, 0x04, "", HFILL}},
7785         { &hf_scsi_setstreaming_exact,
7786           {"Exact", "scsi.setstreaming.exact", FT_BOOLEAN, 8,
7787            NULL, 0x02, "", HFILL}},
7788         { &hf_scsi_setstreaming_ra,
7789           {"RA", "scsi.setstreaming.ra", FT_BOOLEAN, 8,
7790            NULL, 0x01, "", HFILL}},
7791         { &hf_scsi_setstreaming_start_lba,
7792           {"Start LBA", "scsi.setstreaming.start_lbs", FT_UINT32, BASE_DEC,
7793            NULL, 0, "", HFILL}},
7794         { &hf_scsi_setstreaming_end_lba,
7795           {"End LBA", "scsi.setstreaming.end_lba", FT_UINT32, BASE_DEC,
7796            NULL, 0, "", HFILL}},
7797         { &hf_scsi_setstreaming_read_size,
7798           {"Read Size", "scsi.setstreaming.read_size", FT_UINT32, BASE_DEC,
7799            NULL, 0, "", HFILL}},
7800         { &hf_scsi_setstreaming_read_time,
7801           {"Read Time", "scsi.setstreaming.read_time", FT_UINT32, BASE_DEC,
7802            NULL, 0, "", HFILL}},
7803         { &hf_scsi_setstreaming_write_size,
7804           {"Write Size", "scsi.setstreaming.write_size", FT_UINT32, BASE_DEC,
7805            NULL, 0, "", HFILL}},
7806         { &hf_scsi_setstreaming_write_time,
7807           {"Write Time", "scsi.setstreaming.write_time", FT_UINT32, BASE_DEC,
7808            NULL, 0, "", HFILL}},
7809         { &hf_scsi_reservation_size,
7810           {"Reservation Size", "scsi.reservation_size", FT_UINT32, BASE_DEC,
7811            NULL, 0, "", HFILL}},
7812         { &hf_scsi_rti_address_type,
7813           {"Address Type", "scsi.rti.address_type", FT_UINT8, BASE_HEX,
7814            VALS(scsi_rti_address_type_val), 0x03, "", HFILL}},
7815         { &hf_scsi_rti_damage,
7816           {"Damage", "scsi.rti.damage", FT_BOOLEAN, 8,
7817            NULL, 0x20, "", HFILL}},
7818         { &hf_scsi_rti_copy,
7819           {"Copy", "scsi.rti.copy", FT_BOOLEAN, 8,
7820            NULL, 0x10, "", HFILL}},
7821         { &hf_scsi_rti_track_mode,
7822           {"Track Mode", "scsi.rti.track_mode", FT_UINT8, BASE_HEX,
7823            NULL, 0x0f, "", HFILL}},
7824         { &hf_scsi_rti_rt,
7825           {"RT", "scsi.rti.rt", FT_BOOLEAN, 8,
7826            NULL, 0x80, "", HFILL}},
7827         { &hf_scsi_rti_blank,
7828           {"Blank", "scsi.rti.blank", FT_BOOLEAN, 8,
7829            NULL, 0x40, "", HFILL}},
7830         { &hf_scsi_rti_packet,
7831           {"Packet/Inc", "scsi.rti.packet", FT_BOOLEAN, 8,
7832            NULL, 0x20, "", HFILL}},
7833         { &hf_scsi_rti_fp,
7834           {"FP", "scsi.rti.fp", FT_BOOLEAN, 8,
7835            NULL, 0x10, "", HFILL}},
7836         { &hf_scsi_rti_data_mode,
7837           {"Data Mode", "scsi.rti.data_mode", FT_UINT8, BASE_HEX,
7838            NULL, 0x0f, "", HFILL}},
7839         { &hf_scsi_rti_lra_v,
7840           {"LRA_V", "scsi.rti.lra_v", FT_BOOLEAN, 8,
7841            NULL, 0x02, "", HFILL}},
7842         { &hf_scsi_rti_nwa_v,
7843           {"NWA_V", "scsi.rti.nwa_v", FT_BOOLEAN, 8,
7844            NULL, 0x01, "", HFILL}},
7845         { &hf_scsi_free_blocks,
7846           {"Free Blocks", "scsi.free_blocks", FT_UINT32, BASE_DEC,
7847            NULL, 0, "", HFILL}},
7848         { &hf_scsi_fixed_packet_size,
7849           {"Fixed Packet Size", "scsi.fixed_packet_size", FT_UINT32, BASE_DEC,
7850            NULL, 0, "", HFILL}},
7851         { &hf_scsi_last_recorded_address,
7852           {"Last Recorded Address", "scsi.last_recorded_address", FT_UINT32, BASE_DEC,
7853            NULL, 0, "", HFILL}},
7854         { &hf_scsi_read_compatibility_lba,
7855           {"Read Compatibility LBA", "scsi.read_compatibility_lba", FT_UINT32, BASE_DEC,
7856            NULL, 0, "", HFILL}},
7857         { &hf_scsi_disc_info_erasable,
7858           {"Erasable", "scsi.disc_info.erasable", FT_BOOLEAN, 8,
7859            NULL, 0x10, "", HFILL}},
7860         { &hf_scsi_disc_info_state_of_last_session,
7861           {"State Of Last Session", "scsi.disc_info.state_of_last_session", FT_UINT8, BASE_HEX,
7862            VALS(scsi_disc_info_sols_val), 0x0c, "", HFILL}},
7863         { &hf_scsi_disc_info_disk_status,
7864           {"Disk Status", "scsi.disc_info.disk_status", FT_UINT8, BASE_HEX,
7865            VALS(scsi_disc_info_disc_status_val), 0x03, "", HFILL}},
7866         { &hf_scsi_disc_info_number_of_sessions,
7867           {"Number Of Sessions", "scsi.disc_info.number_of_sessions", FT_UINT16, BASE_DEC,
7868            NULL, 0, "", HFILL}},
7869         { &hf_scsi_disc_info_first_track_in_last_session,
7870           {"First Track In Last Session", "scsi.disc_info.first_track_in_last_session", FT_UINT16, BASE_DEC,
7871            NULL, 0, "", HFILL}},
7872         { &hf_scsi_disc_info_last_track_in_last_session,
7873           {"Last Track In Last Session", "scsi.disc_info.last_track_in_last_session", FT_UINT16, BASE_DEC,
7874            NULL, 0, "", HFILL}},
7875         { &hf_scsi_disc_info_did_v,
7876           {"DID_V", "scsi.disc_info.did_v", FT_BOOLEAN, 8,
7877            NULL, 0x80, "", HFILL}},
7878         { &hf_scsi_disc_info_dbc_v,
7879           {"DBC_V", "scsi.disc_info.dbc_v", FT_BOOLEAN, 8,
7880            NULL, 0x40, "", HFILL}},
7881         { &hf_scsi_disc_info_uru,
7882           {"URU", "scsi.disc_info.uru", FT_BOOLEAN, 8,
7883            NULL, 0x20, "", HFILL}},
7884         { &hf_scsi_disc_info_dac_v,
7885           {"DAC_V", "scsi.disc_info.dac_v", FT_BOOLEAN, 8,
7886            NULL, 0x10, "", HFILL}},
7887         { &hf_scsi_disc_info_dbit,
7888           {"Dbit", "scsi.disc_info.dbit", FT_BOOLEAN, 8,
7889            NULL, 0x04, "", HFILL}},
7890         { &hf_scsi_disc_info_bgfs,
7891           {"BG Format Status", "scsi.disc_info.bgfs", FT_UINT8, BASE_HEX,
7892            VALS(scsi_disc_info_bgfs_val), 0x03, "", HFILL}},
7893         { &hf_scsi_disc_info_disc_type,
7894           {"Disc Type", "scsi.disc_info.disc_type", FT_UINT8, BASE_HEX,
7895            VALS(scsi_disc_info_disc_type_val), 0, "", HFILL}},
7896         { &hf_scsi_disc_info_disc_identification,
7897           {"Disc Identification", "scsi.disc_info.disc_identification", FT_UINT32, BASE_HEX,
7898            NULL, 0, "", HFILL}},
7899         { &hf_scsi_disc_info_last_session_lead_in_start_address,
7900           {"Last Session Lead-In Start Address", "scsi.disc_info.last_session_lead_in_start_address", FT_UINT32, BASE_DEC,
7901            NULL, 0, "", HFILL}},
7902         { &hf_scsi_disc_info_last_possible_lead_out_start_address,
7903           {"Last Possible Lead-Out Start Address", "scsi.disc_info.last_possible_lead_out_start_address", FT_UINT32, BASE_DEC,
7904            NULL, 0, "", HFILL}},
7905         { &hf_scsi_disc_info_disc_bar_code,
7906           {"Disc Bar Code", "scsi.disc_info.disc_bar_code", FT_UINT64, BASE_HEX,
7907            NULL, 0, "", HFILL}},
7908         { &hf_sbc2_verify_lba,
7909           {"LBA", "scsi.sbc2.verify.lba", FT_UINT32, BASE_DEC, NULL, 0x0, "",
7910            HFILL}},
7911         { &hf_sbc2_verify_vlen,
7912           {"Verification Length", "scsi.sbc2.verify.vlen", FT_UINT16,
7913            BASE_DEC, NULL, 0x0, "", HFILL}},
7914         { &hf_sbc2_verify_dpo,
7915           {"DPO", "scsi.sbc2.verify.dpo", FT_BOOLEAN, BASE_HEX, NULL, 0x10, "",
7916            HFILL}},
7917         { &hf_sbc2_verify_blkvfy,
7918           {"BLKVFY", "scsi.sbc2.verify.blkvfy", FT_BOOLEAN, BASE_HEX, NULL, 0x4,
7919            "", HFILL}},
7920         { &hf_sbc2_verify_bytchk,
7921           {"BYTCHK", "scsi.sbc2.verify.bytchk", FT_BOOLEAN, BASE_HEX, NULL, 0x2,
7922            "", HFILL}},
7923         { &hf_sbc2_verify_reladdr,
7924           {"RELADDR", "scsi.sbc2.verify.reladdr", FT_BOOLEAN, BASE_HEX, NULL,
7925            0x1, "", HFILL}},
7926         { &hf_sbc2_verify_vlen32,
7927           {"Verification Length", "scsi.sbc2.verify.vlen32", FT_UINT32,
7928            BASE_DEC, NULL, 0x0, "", HFILL}},
7929         { &hf_sbc2_verify_lba64,
7930           {"LBA", "scsi.sbc2.verify.lba64", FT_UINT64, BASE_DEC, NULL, 0x0, "",
7931            HFILL}},
7932         { &hf_sbc2_wrverify_ebp,
7933           {"EBP", "scsi.sbc2.wrverify.ebp", FT_BOOLEAN, BASE_HEX, NULL, 0x4, "",
7934            HFILL}},
7935         { &hf_sbc2_wrverify_lba,
7936           {"LBA", "scsi.sbc2.wrverify.lba", FT_UINT32, BASE_DEC, NULL, 0x0, "",
7937            HFILL}},
7938         { &hf_sbc2_wrverify_xferlen,
7939           {"Transfer Length", "scsi.sbc2.wrverify.xferlen", FT_UINT16, BASE_DEC,
7940            NULL, 0x0, "", HFILL}},
7941         { &hf_sbc2_wrverify_lba64,
7942           {"LBA", "scsi.sbc2.wrverify.lba64", FT_UINT64, BASE_DEC, NULL, 0x0,
7943            "", HFILL}},
7944         { &hf_sbc2_wrverify_xferlen32,
7945           {"Transfer Length", "scsi.sbc2.wrverify.xferlen32", FT_UINT32,
7946            BASE_DEC, NULL, 0x0, "", HFILL}},
7947         { &hf_ssc3_space6_count,
7948           {"Count", "scsi.space6.count", FT_UINT24, BASE_DEC, NULL, 0x0,
7949            "", HFILL}},
7950         { &hf_ssc3_space16_count,
7951           {"Count", "scsi.space16.count", FT_UINT64, BASE_DEC, NULL, 0x0,
7952            "", HFILL}},
7953         { &hf_ssc3_locate10_loid,
7954           {"Logical Object Identifier", "scsi.locate10.loid", FT_UINT32, BASE_DEC, NULL, 0x0,
7955            "", HFILL}},
7956         { &hf_ssc3_locate16_loid,
7957           {"Logical Identifier", "scsi.locate16.loid", FT_UINT64, BASE_DEC, NULL, 0x0,
7958            "", HFILL}},
7959     };
7960
7961     /* Setup protocol subtree array */
7962     static gint *ett[] = {
7963         &ett_scsi,
7964         &ett_scsi_page,
7965     };
7966     module_t *scsi_module;
7967
7968     /* Register the protocol name and description */
7969     proto_scsi = proto_register_protocol("SCSI", "SCSI", "scsi");
7970
7971     /* Required function calls to register the header fields and subtrees used */
7972     proto_register_field_array(proto_scsi, hf, array_length(hf));
7973     proto_register_subtree_array(ett, array_length(ett));
7974     register_init_routine (&scsi_init_protocol);
7975     data_handle = find_dissector ("data");
7976
7977     /* add preferences to decode SCSI message */
7978     scsi_module = prefs_register_protocol (proto_scsi, NULL);
7979     prefs_register_enum_preference (scsi_module, "decode_scsi_messages_as",
7980                                     "Decode SCSI Messages As",
7981                                     "When Target Cannot Be Identified, Decode SCSI Messages As",
7982                                     &scsi_def_devtype, scsi_devtype_options, TRUE);
7983
7984 }