|
1 // Copyright (c) 2009 Nokia Corporation and/or its subsidiary(-ies). |
|
2 // All rights reserved. |
|
3 // This component and the accompanying materials are made available |
|
4 // under the terms of the License "Eclipse Public License v1.0" |
|
5 // which accompanies this distribution, and is available |
|
6 // at the URL "http://www.eclipse.org/legal/epl-v10.html". |
|
7 // |
|
8 // Initial Contributors: |
|
9 // Nokia Corporation - initial contribution. |
|
10 // |
|
11 // Contributors: |
|
12 // |
|
13 // Description: |
|
14 // |
|
15 |
|
16 |
|
17 #include <e32def.h> |
|
18 #include <e32cmn.h> |
|
19 #include <e32des8.h> |
|
20 #include <e32std.h> |
|
21 |
|
22 #include "mstypes.h" |
|
23 #include "msctypes.h" |
|
24 #include "mscutils.h" |
|
25 #include "scsimsctypes.h" |
|
26 |
|
27 #include "tscsiserverreq.h" |
|
28 #include "tscsiservercmds.h" |
|
29 #include "debug.h" |
|
30 #include "msdebug.h" |
|
31 |
|
32 /** |
|
33 Default constructor for TSenseInfo |
|
34 */ |
|
35 TSrvSenseInfo::TSrvSenseInfo() |
|
36 { |
|
37 __MSFNLOG |
|
38 iSenseCode = ENoSense; |
|
39 iAdditional = 0; |
|
40 iQualifier = 0; |
|
41 } |
|
42 |
|
43 /** |
|
44 Set sense with no additional info. |
|
45 |
|
46 @param aSenseCode sense key |
|
47 */ |
|
48 void TSrvSenseInfo::SetSense(TSenseCode aSenseCode) |
|
49 { |
|
50 __MSFNLOG |
|
51 iSenseCode = static_cast<TUint8>(aSenseCode); |
|
52 iAdditional = 0; |
|
53 iQualifier = 0; |
|
54 } |
|
55 |
|
56 |
|
57 /** |
|
58 Set sense with additional info. |
|
59 |
|
60 @param aSenseCode sense key |
|
61 @param aAdditional additional sense code (ASC) |
|
62 */ |
|
63 void TSrvSenseInfo::SetSense(TSenseCode aSenseCode, |
|
64 TAdditionalCode aAdditional) |
|
65 |
|
66 { |
|
67 __MSFNLOG |
|
68 iSenseCode = static_cast<TUint8>(aSenseCode); |
|
69 iAdditional = static_cast<TUint8>(aAdditional); |
|
70 iQualifier = 0; |
|
71 } |
|
72 |
|
73 |
|
74 /** |
|
75 Set sense with additional info and qualifier. |
|
76 |
|
77 @param aSenseCode sense key |
|
78 @param aAdditional additional sense code (ASC) |
|
79 @param aQualifier additional sense code qualifier (ASCQ) |
|
80 */ |
|
81 void TSrvSenseInfo::SetSense(TSenseCode aSenseCode, |
|
82 TAdditionalCode aAdditional, |
|
83 TUint8 aQualifier) |
|
84 { |
|
85 __MSFNLOG |
|
86 iSenseCode = static_cast<TUint8>(aSenseCode); |
|
87 iAdditional = static_cast<TUint8>(aAdditional); |
|
88 iQualifier = aQualifier; |
|
89 } |
|
90 |
|
91 |
|
92 // **** TEST UNIT READY **** |
|
93 // **** REQUEST SENSE **** |
|
94 void TScsiServerRequestSenseResp::Encode(TDes8& aBuffer) const |
|
95 { |
|
96 __MSFNSLOG |
|
97 aBuffer.FillZ(KCommandLength); |
|
98 __PRINT(_L("->PROTOCOL(SCSI) REQUEST SENSE\n")); |
|
99 //additional sense length |
|
100 aBuffer[07] = static_cast<TUint8>(KCommandLength - 8); |
|
101 |
|
102 aBuffer[0] = iResponseCode; |
|
103 aBuffer[02] = static_cast<TUint8>(iSensePtr->iSenseCode); |
|
104 aBuffer[12] = iSensePtr->iAdditional; |
|
105 aBuffer[13] = iSensePtr->iQualifier; |
|
106 |
|
107 //truncate to Allocation Length of the Request |
|
108 TUint length = iAllocationLength < KCommandLength ? |
|
109 iAllocationLength : KCommandLength; |
|
110 aBuffer.SetLength(length); |
|
111 } |
|
112 |
|
113 // **** INQUIRY **** |
|
114 void TScsiServerInquiryReq::DecodeL(const TDesC8& aPtr) |
|
115 { |
|
116 __MSFNLOG |
|
117 TScsiServerReq::DecodeL(aPtr); |
|
118 iCmdDt = aPtr[1] & 0x2; |
|
119 iEvpd = aPtr[1] & 0x1; |
|
120 iPage = aPtr[2]; |
|
121 iAllocationLength = aPtr[4]; |
|
122 __PRINT(_L("<-PROTOCOL(SCSI) INQUIRY\n")); |
|
123 } |
|
124 |
|
125 |
|
126 void TScsiServerInquiryResp::Encode(TDes8& aBuffer) const |
|
127 { |
|
128 __MSFNSLOG |
|
129 __PRINT(_L("->PROTOCOL(SCSI) INQUIRY\n")); |
|
130 |
|
131 aBuffer.FillZ(KResponseLength); |
|
132 |
|
133 // MSB: RMB : Removable |
|
134 if (iRemovable) |
|
135 { |
|
136 aBuffer[1] |= 0x80; |
|
137 } |
|
138 |
|
139 // AERC, TrmTsk, NormACA, Response Data Format |
|
140 aBuffer[3] |= (iResponseDataFormat & 0x0F); |
|
141 |
|
142 // Additional Length |
|
143 aBuffer[4] = 0x1F; |
|
144 |
|
145 // Vendor ID (Vendor Specific/Logged by T10) |
|
146 TPtr8 vendorId(&aBuffer[8], 8, 8); |
|
147 vendorId.Fill(' ', 8); |
|
148 vendorId.Copy(iConfig.iVendorId); |
|
149 |
|
150 // Product ID (Vendor Specific) |
|
151 TPtr8 productId(&aBuffer[16], 16, 16); |
|
152 productId.Fill(' ', 16); |
|
153 productId.Copy(iConfig.iProductId); |
|
154 |
|
155 // Product Revision Level (Vendor Specific) |
|
156 TPtr8 productRev(&aBuffer[32], 4, 4); |
|
157 productRev.Fill(' ', 4); |
|
158 productRev.Copy(iConfig.iProductRev); |
|
159 |
|
160 // Truncate to Allocation Length of the Request |
|
161 TUint length = iAllocationLength < KResponseLength ? |
|
162 iAllocationLength : KResponseLength; |
|
163 aBuffer.SetLength(length); |
|
164 } |
|
165 |
|
166 |
|
167 // **** MODE SENSE (6) **** |
|
168 void TScsiServerModeSense6Req::DecodeL(const TDesC8& aPtr) |
|
169 { |
|
170 __MSFNLOG |
|
171 TScsiServerReq::DecodeL(aPtr); |
|
172 iPageCode = aPtr[2] & 0x3F; |
|
173 iPageControl = static_cast<TPageControl>(aPtr[2] >> 6); |
|
174 iAllocationLength = aPtr[4]; |
|
175 __PRINT(_L("<-PROTOCOL(SCSI) MODE SENSE (6)\n")); |
|
176 } |
|
177 |
|
178 |
|
179 void TScsiServerModeSense6Resp::Encode(TDes8& aBuffer) const |
|
180 { |
|
181 __MSFNSLOG |
|
182 __PRINT(_L("->PROTOCOL(SCSI) MODE SENSE (6)\n")); |
|
183 // reserve 4 bytes for Length, Media type, Device-specific parameter and |
|
184 // Block descriptor length |
|
185 aBuffer.FillZ(KCommandLength); |
|
186 |
|
187 // Mode Parameter List |
|
188 // SPC-3 7.4.2 |
|
189 // - Mode Parameter Header |
|
190 // - Block Descriptor(s) |
|
191 // - Mode Page(s) |
|
192 |
|
193 // Mode Parameter Header |
|
194 // SPC-3 7.4.3 |
|
195 // [0] Mode Data Length |
|
196 // [1] Medium Type |
|
197 // [2] Device-Specific Paramater |
|
198 // [3] Block Descriptor Length |
|
199 |
|
200 // [0] Mode Date Length |
|
201 // Sending only Mode parameter header |
|
202 aBuffer[0] = 3; |
|
203 |
|
204 // [1] Medium Type |
|
205 // 0x00 for SBC |
|
206 |
|
207 // [2] Device specific parameter |
|
208 // SBC-3 6.3.1 |
|
209 // set SWP bit at the Device Specific parameters |
|
210 if (iWp) |
|
211 { |
|
212 aBuffer[2] |= 0x80; |
|
213 } |
|
214 |
|
215 // [3] Block Descriptor Length |
|
216 // 0x00 for no descriptors |
|
217 |
|
218 // No Block Descriptors |
|
219 |
|
220 // No Mode Pages |
|
221 |
|
222 // Truncate to Allocation Length of the Request |
|
223 TUint length = iAllocationLength < KCommandLength ? |
|
224 iAllocationLength : KCommandLength; |
|
225 aBuffer.SetLength(length); |
|
226 } |
|
227 |
|
228 // **** START STOP UNIT **** |
|
229 void TScsiServerStartStopUnitReq::DecodeL(const TDesC8& aPtr) |
|
230 { |
|
231 __MSFNLOG |
|
232 TScsiServerReq::DecodeL(aPtr); |
|
233 |
|
234 const TUint8 KStartMask = 0x01; |
|
235 const TUint8 KImmedMask = 0x01; |
|
236 const TUint8 KLoejMask = 0x02; |
|
237 |
|
238 iImmed = aPtr[1] & KImmedMask ? ETrue : EFalse; |
|
239 iStart = aPtr[4] & KStartMask ? ETrue : EFalse; |
|
240 iLoej = aPtr[4] & KLoejMask ? ETrue : EFalse; |
|
241 |
|
242 __PRINT2(_L("<-PROTOCOL(SCSI) START STOP UNIT Data %X %X\n"), aPtr[1], aPtr[4]); |
|
243 __PRINT1(_L("IMMED = %d\n"), iImmed); |
|
244 __PRINT1(_L("START = %d\n"), iStart); |
|
245 __PRINT1(_L("LOEJ = %d\n"), iLoej); |
|
246 } |
|
247 |
|
248 |
|
249 // **** PREVENT MEDIA REMOVAL **** |
|
250 void TScsiServerPreventMediaRemovalReq::DecodeL(const TDesC8& aPtr) |
|
251 { |
|
252 __MSFNLOG |
|
253 TScsiServerReq::DecodeL(aPtr); |
|
254 iPrevent = aPtr[4] & 0x01; |
|
255 __PRINT1(_L("<-PROTOCOL(SCSI) PREVENT MEDIA REMOVAL prevent = %d\n"), iPrevent); |
|
256 } |
|
257 |
|
258 |
|
259 // **** READ FORMAT CAPACITIES **** |
|
260 void TScsiServerReadFormatCapacitiesReq::DecodeL(const TDesC8& aPtr) |
|
261 { |
|
262 __MSFNLOG |
|
263 TScsiServerReq::DecodeL(aPtr); |
|
264 const TUint8* ptr = aPtr.Ptr(); |
|
265 iAllocationLength = BigEndian::Get32(ptr+7); |
|
266 __PRINT(_L("<-PROTOCOL(SCSI) READ FORMAT CAPACITIES\n")); |
|
267 } |
|
268 |
|
269 |
|
270 void TScsiServerReadFormatCapacitiesResp::Encode(TDes8& aBuffer) const |
|
271 { |
|
272 __MSFNSLOG |
|
273 __PRINT(_L("->PROTOCOL(SCSI) READ FORMAT CAPACITIES\n")); |
|
274 aBuffer.FillZ(KResponseLength); |
|
275 aBuffer[3] = 0x08; // Capacity List Length |
|
276 |
|
277 aBuffer[4] = static_cast<TUint8>(iNumberBlocks >> 24); // Number of blocks |
|
278 aBuffer[5] = static_cast<TUint8>(iNumberBlocks >> 16); // |
|
279 aBuffer[6] = static_cast<TUint8>(iNumberBlocks >> 8); // |
|
280 aBuffer[7] = static_cast<TUint8>(iNumberBlocks); // |
|
281 |
|
282 aBuffer[8] = 0x02; // Formatted size |
|
283 |
|
284 aBuffer[9] = 0x00; // 512 Byte Blocks |
|
285 aBuffer[10] = 0x02; // |
|
286 aBuffer[11] = 0x00; // |
|
287 |
|
288 // Truncate to Allocation Length of the Request |
|
289 // Truncate to Allocation Length of the Request |
|
290 TUint length = iAllocationLength < KResponseLength ? |
|
291 iAllocationLength : KResponseLength; |
|
292 aBuffer.SetLength(length); |
|
293 } |
|
294 |
|
295 |
|
296 // **** READ CAPACITY (10) **** |
|
297 void TScsiServerReadCapacity10Req::DecodeL(const TDesC8& aPtr) |
|
298 { |
|
299 __MSFNLOG |
|
300 TScsiServerReq::DecodeL(aPtr); |
|
301 iPmi = aPtr[8] & 0x01; |
|
302 const TUint8* ptr = aPtr.Ptr(); |
|
303 iLogicalBlockAddress = BigEndian::Get32(ptr+2); |
|
304 __PRINT(_L("<-PROTOCOL(SCSI) READ CAPACITY (10)\n")); |
|
305 } |
|
306 |
|
307 |
|
308 void TScsiServerReadCapacity10Resp::Encode(TDes8& aBuffer) const |
|
309 { |
|
310 __MSFNSLOG |
|
311 aBuffer.FillZ(KCommandLength); |
|
312 |
|
313 __PRINT3(_L("->PROTOCOL(SCSI) READ CAPACITY (10) Block size=0x%X, NumBlocks=0x%08X%08X\n"), |
|
314 iBlockSize, |
|
315 I64HIGH(iNumberBlocks), |
|
316 I64LOW(iNumberBlocks)); |
|
317 |
|
318 if (I64HIGH(iNumberBlocks) == 0) |
|
319 { |
|
320 TUint32 numBlocks = I64LOW(iNumberBlocks); |
|
321 |
|
322 // Number of blocks |
|
323 aBuffer[0] = static_cast<TUint8>(numBlocks >> 24); |
|
324 aBuffer[1] = static_cast<TUint8>(numBlocks >> 16); |
|
325 aBuffer[2] = static_cast<TUint8>(numBlocks >> 8); |
|
326 aBuffer[3] = static_cast<TUint8>(numBlocks); |
|
327 } |
|
328 else |
|
329 { |
|
330 // indicate that size more then )0xFFFFFFFF |
|
331 aBuffer[0] = aBuffer[1] = aBuffer[2] = aBuffer[3] = 0xFF; |
|
332 } |
|
333 |
|
334 // Block Size |
|
335 aBuffer[4] = static_cast<TUint8>(iBlockSize >> 24); |
|
336 aBuffer[5] = static_cast<TUint8>(iBlockSize >> 16); |
|
337 aBuffer[6] = static_cast<TUint8>(iBlockSize >> 8); |
|
338 aBuffer[7] = static_cast<TUint8>(iBlockSize); |
|
339 } |
|
340 |
|
341 |
|
342 // **** RdWr10 **** |
|
343 void TScsiServerRdWr10Req::DecodeL(const TDesC8& aDes) |
|
344 { |
|
345 __MSFNLOG |
|
346 TScsiServerReq::DecodeL(aDes); |
|
347 |
|
348 // PROTECT |
|
349 iProtect = aDes[1] >> 5; |
|
350 |
|
351 const TUint8* ptr = aDes.Ptr(); |
|
352 // LOGICAL BLOCK ADDRESS |
|
353 iLogicalBlockAddress = BigEndian::Get32(ptr+2); |
|
354 // TRANSFER LENGTH |
|
355 iTransferLength = BigEndian::Get16(ptr+7); |
|
356 |
|
357 __PRINT2(_L("<-PROTOCOL(SCSI) RD/WR (10) : LBA = %x, Length = %x (blocks)\n"), |
|
358 iLogicalBlockAddress, iTransferLength); |
|
359 } |
|
360 |
|
361 |
|
362 // **** READ (10) **** |
|
363 // **** WRITE (10) **** |
|
364 // **** VERIFY (10) **** |
|
365 void TScsiServerVerify10Req::DecodeL(const TDesC8& aPtr) |
|
366 { |
|
367 __MSFNLOG |
|
368 TScsiServerRdWr10Req::DecodeL(aPtr); |
|
369 iBytchk = aPtr[1] & 0x02 ? ETrue : EFalse; |
|
370 } |