1 /*******************************************************************************
2 *Copyright (c) 2014 PMC-Sierra, Inc. All rights reserved.
3 *
4 *Redistribution and use in source and binary forms, with or without modification, are permitted provided
5 *that the following conditions are met:
6 *1. Redistributions of source code must retain the above copyright notice, this list of conditions and the
7 *following disclaimer.
8 *2. Redistributions in binary form must reproduce the above copyright notice,
9 *this list of conditions and the following disclaimer in the documentation and/or other materials provided
10 *with the distribution.
11 *
12 *THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND ANY EXPRESS OR IMPLIED
13 *WARRANTIES,INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
14 *FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
15 *FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
16 *NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
17 *BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
18 *LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
19 *SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE
20
21 ********************************************************************************/
22 #include <sys/cdefs.h>
23 #include <dev/pms/config.h>
24
25 #include <dev/pms/freebsd/driver/common/osenv.h>
26 #include <dev/pms/freebsd/driver/common/ostypes.h>
27 #include <dev/pms/freebsd/driver/common/osdebug.h>
28
29 #include <dev/pms/RefTisa/tisa/api/titypes.h>
30
31 #include <dev/pms/RefTisa/sallsdk/api/sa.h>
32 #include <dev/pms/RefTisa/sallsdk/api/saapi.h>
33 #include <dev/pms/RefTisa/sallsdk/api/saosapi.h>
34
35 #include <dev/pms/RefTisa/sat/api/sm.h>
36 #include <dev/pms/RefTisa/sat/api/smapi.h>
37 #include <dev/pms/RefTisa/sat/api/tdsmapi.h>
38
39 #include <dev/pms/RefTisa/sat/src/smdefs.h>
40 #include <dev/pms/RefTisa/sat/src/smproto.h>
41 #include <dev/pms/RefTisa/sat/src/smtypes.h>
42
43 /* start smapi defined APIs */
44 osGLOBAL bit32
smRegisterDevice(smRoot_t * smRoot,agsaDevHandle_t * agDevHandle,smDeviceHandle_t * smDeviceHandle,agsaDevHandle_t * agExpDevHandle,bit32 phyID,bit32 DeviceType)45 smRegisterDevice(
46 smRoot_t *smRoot,
47 agsaDevHandle_t *agDevHandle,
48 smDeviceHandle_t *smDeviceHandle,
49 agsaDevHandle_t *agExpDevHandle,
50 bit32 phyID,
51 bit32 DeviceType
52 )
53 {
54 smDeviceData_t *oneDeviceData = agNULL;
55
56 SM_DBG2(("smRegisterDevice: start\n"));
57
58 if (smDeviceHandle == agNULL)
59 {
60 SM_DBG1(("smRegisterDevice: smDeviceHandle is NULL!!!\n"));
61 return SM_RC_FAILURE;
62 }
63
64 if (agDevHandle == agNULL)
65 {
66 SM_DBG1(("smRegisterDevice: agDevHandle is NULL!!!\n"));
67 return SM_RC_FAILURE;
68 }
69
70 oneDeviceData = smAddToSharedcontext(smRoot, agDevHandle, smDeviceHandle, agExpDevHandle, phyID);
71 if (oneDeviceData != agNULL)
72 {
73 oneDeviceData->satDeviceType = DeviceType;
74 return SM_RC_SUCCESS;
75 }
76 else
77 {
78 return SM_RC_FAILURE;
79 }
80
81 }
82
83 osGLOBAL bit32
smDeregisterDevice(smRoot_t * smRoot,agsaDevHandle_t * agDevHandle,smDeviceHandle_t * smDeviceHandle)84 smDeregisterDevice(
85 smRoot_t *smRoot,
86 agsaDevHandle_t *agDevHandle,
87 smDeviceHandle_t *smDeviceHandle
88 )
89 {
90 bit32 status = SM_RC_FAILURE;
91
92 SM_DBG2(("smDeregisterDevice: start\n"));
93
94 if (smDeviceHandle == agNULL)
95 {
96 SM_DBG1(("smDeregisterDevice: smDeviceHandle is NULL!!!\n"));
97 return SM_RC_FAILURE;
98 }
99
100 if (agDevHandle == agNULL)
101 {
102 SM_DBG1(("smDeregisterDevice: agDevHandle is NULL!!!\n"));
103 return SM_RC_FAILURE;
104 }
105
106 status = smRemoveFromSharedcontext(smRoot, agDevHandle, smDeviceHandle);
107
108 return status;
109 }
110
111 osGLOBAL bit32
smIOAbort(smRoot_t * smRoot,smIORequest_t * tasktag)112 smIOAbort(
113 smRoot_t *smRoot,
114 smIORequest_t *tasktag
115 )
116
117 {
118 smIntRoot_t *smIntRoot = (smIntRoot_t *)smRoot->smData;
119 smIntContext_t *smAllShared = (smIntContext_t *)&smIntRoot->smAllShared;
120 agsaRoot_t *agRoot;
121 smIORequestBody_t *smIORequestBody = agNULL;
122 smIORequestBody_t *smIONewRequestBody = agNULL;
123 agsaIORequest_t *agIORequest = agNULL; /* IO to be aborted */
124 bit32 status = SM_RC_FAILURE;
125 agsaIORequest_t *agAbortIORequest; /* abort IO itself */
126 smIORequestBody_t *smAbortIORequestBody;
127 #if 1
128 bit32 PhysUpper32;
129 bit32 PhysLower32;
130 bit32 memAllocStatus;
131 void *osMemHandle;
132 #endif
133 smSatIOContext_t *satIOContext;
134 smSatInternalIo_t *satIntIo;
135 smSatIOContext_t *satAbortIOContext;
136
137 SM_DBG1(("smIOAbort: start\n"));
138 SM_DBG2(("smIOAbort: tasktag %p\n", tasktag));
139 /*
140 alloc smIORequestBody for abort itself
141 call saSATAAbort()
142 */
143
144 agRoot = smAllShared->agRoot;
145 smIORequestBody = (smIORequestBody_t *)tasktag->smData;
146
147 if (smIORequestBody == agNULL)
148 {
149 SM_DBG1(("smIOAbort: smIORequestBody is NULL!!!\n"));
150 return SM_RC_FAILURE;
151 }
152
153 /* needs to distinguish internally generated or externally generated */
154 satIOContext = &(smIORequestBody->transport.SATA.satIOContext);
155 satIntIo = satIOContext->satIntIoContext;
156 if (satIntIo == agNULL)
157 {
158 SM_DBG2(("smIOAbort: External, OS generated\n"));
159 agIORequest = &(smIORequestBody->agIORequest);
160 }
161 else
162 {
163 SM_DBG2(("smIOAbort: Internal, SM generated\n"));
164 smIONewRequestBody = (smIORequestBody_t *)satIntIo->satIntRequestBody;
165 agIORequest = &(smIONewRequestBody->agIORequest);
166 }
167
168 /*
169 allocate smAbortIORequestBody for abort request itself
170 */
171
172 #if 1
173 /* allocating agIORequest for abort itself */
174 memAllocStatus = tdsmAllocMemory(
175 smRoot,
176 &osMemHandle,
177 (void **)&smAbortIORequestBody,
178 &PhysUpper32,
179 &PhysLower32,
180 8,
181 sizeof(smIORequestBody_t),
182 agTRUE
183 );
184 if (memAllocStatus != SM_RC_SUCCESS)
185 {
186 /* let os process IO */
187 SM_DBG1(("smIOAbort: tdsmAllocMemory failed...!!!\n"));
188 return SM_RC_FAILURE;
189 }
190
191 if (smAbortIORequestBody == agNULL)
192 {
193 /* let os process IO */
194 SM_DBG1(("smIOAbort: tdsmAllocMemory returned NULL smAbortIORequestBody!!!\n"));
195 return SM_RC_FAILURE;
196 }
197
198 smIOReInit(smRoot, smAbortIORequestBody);
199
200 /* setup task management structure */
201 smAbortIORequestBody->IOType.InitiatorTMIO.osMemHandle = osMemHandle;
202 satAbortIOContext = &(smAbortIORequestBody->transport.SATA.satIOContext);
203 satAbortIOContext->smRequestBody = smAbortIORequestBody;
204
205 smAbortIORequestBody->smDevHandle = smIORequestBody->smDevHandle;
206
207 /* initialize agIORequest */
208 agAbortIORequest = &(smAbortIORequestBody->agIORequest);
209 agAbortIORequest->osData = (void *) smAbortIORequestBody;
210 agAbortIORequest->sdkData = agNULL; /* LL takes care of this */
211
212 /* remember IO to be aborted */
213 smAbortIORequestBody->smIOToBeAbortedRequest = tasktag;
214
215 status = saSATAAbort(agRoot, agAbortIORequest, 0, agNULL, 0, agIORequest, smaSATAAbortCB);
216
217 SM_DBG2(("smIOAbort: return status=0x%x\n", status));
218
219 #endif /* 1 */
220
221
222 if (status == AGSA_RC_SUCCESS)
223 {
224 return SM_RC_SUCCESS;
225 }
226 else
227 {
228 SM_DBG1(("smIOAbort: failed to call saSATAAbort, status=%d!!!\n", status));
229 tdsmFreeMemory(smRoot,
230 smAbortIORequestBody->IOType.InitiatorTMIO.osMemHandle,
231 sizeof(smIORequestBody_t)
232 );
233 return SM_RC_FAILURE;
234 }
235 }
236
237 osGLOBAL bit32
smIOAbortAll(smRoot_t * smRoot,smDeviceHandle_t * smDeviceHandle)238 smIOAbortAll(
239 smRoot_t *smRoot,
240 smDeviceHandle_t *smDeviceHandle
241 )
242 {
243 smIntRoot_t *smIntRoot = (smIntRoot_t *)smRoot->smData;
244 smIntContext_t *smAllShared = (smIntContext_t *)&smIntRoot->smAllShared;
245 agsaRoot_t *agRoot;
246 bit32 status = SM_RC_FAILURE;
247 agsaIORequest_t *agAbortIORequest;
248 smIORequestBody_t *smAbortIORequestBody;
249 smSatIOContext_t *satAbortIOContext;
250 smDeviceData_t *oneDeviceData = agNULL;
251 agsaDevHandle_t *agDevHandle;
252
253 bit32 PhysUpper32;
254 bit32 PhysLower32;
255 bit32 memAllocStatus;
256 void *osMemHandle;
257
258
259 SM_DBG2(("smIOAbortAll: start\n"));
260
261 agRoot = smAllShared->agRoot;
262
263 if (smDeviceHandle == agNULL)
264 {
265 SM_DBG1(("smIOAbortAll: smDeviceHandle is NULL!!!\n"));
266 return SM_RC_FAILURE;
267 }
268
269 oneDeviceData = (smDeviceData_t *)smDeviceHandle->smData;
270 if (oneDeviceData == agNULL)
271 {
272 SM_DBG1(("smIOAbortAll: oneDeviceData is NULL!!!\n"));
273 return SM_RC_FAILURE;
274 }
275 if (oneDeviceData->valid == agFALSE)
276 {
277 SM_DBG1(("smIOAbortAll: oneDeviceData is not valid, did %d !!!\n", oneDeviceData->id));
278 return SM_RC_FAILURE;
279 }
280
281 agDevHandle = oneDeviceData->agDevHandle;
282 if (agDevHandle == agNULL)
283 {
284 SM_DBG1(("smIOAbortAll: agDevHandle is NULL!!!\n"));
285 return SM_RC_FAILURE;
286 }
287 /*
288 smAbortIORequestBody = smDequeueIO(smRoot);
289 if (smAbortIORequestBody == agNULL)
290 {
291 SM_DBG1(("smIOAbortAll: empty freeIOList!!!\n"));
292 return SM_RC_FAILURE;
293 }
294 */
295 /* allocating agIORequest for abort itself */
296 memAllocStatus = tdsmAllocMemory(
297 smRoot,
298 &osMemHandle,
299 (void **)&smAbortIORequestBody,
300 &PhysUpper32,
301 &PhysLower32,
302 8,
303 sizeof(smIORequestBody_t),
304 agTRUE
305 );
306 if (memAllocStatus != SM_RC_SUCCESS)
307 {
308 /* let os process IO */
309 SM_DBG1(("smIOAbortAll: tdsmAllocMemory failed...!!!\n"));
310 return SM_RC_FAILURE;
311 }
312
313 if (smAbortIORequestBody == agNULL)
314 {
315 /* let os process IO */
316 SM_DBG1(("smIOAbortAll: tdsmAllocMemory returned NULL smAbortIORequestBody!!!\n"));
317 return SM_RC_FAILURE;
318 }
319
320 smIOReInit(smRoot, smAbortIORequestBody);
321
322 /* setup task management structure */
323 smAbortIORequestBody->IOType.InitiatorTMIO.osMemHandle = osMemHandle;
324
325 satAbortIOContext = &(smAbortIORequestBody->transport.SATA.satIOContext);
326 satAbortIOContext->smRequestBody = smAbortIORequestBody;
327 smAbortIORequestBody->smDevHandle = smDeviceHandle;
328
329 /* initialize agIORequest */
330 agAbortIORequest = &(smAbortIORequestBody->agIORequest);
331 agAbortIORequest->osData = (void *) smAbortIORequestBody;
332 agAbortIORequest->sdkData = agNULL; /* LL takes care of this */
333
334 oneDeviceData->OSAbortAll = agTRUE;
335 /* abort all */
336 status = saSATAAbort(agRoot, agAbortIORequest, tdsmRotateQnumber(smRoot, smDeviceHandle), agDevHandle, 1, agNULL, smaSATAAbortCB);
337 if (status != AGSA_RC_SUCCESS)
338 {
339 SM_DBG1(("smIOAbortAll: failed to call saSATAAbort, status=%d!!!\n", status));
340 tdsmFreeMemory(smRoot,
341 smAbortIORequestBody->IOType.InitiatorTMIO.osMemHandle,
342 sizeof(smIORequestBody_t)
343 );
344 }
345
346 return status;
347 }
348
349 osGLOBAL bit32
smSuperIOStart(smRoot_t * smRoot,smIORequest_t * smIORequest,smDeviceHandle_t * smDeviceHandle,smSuperScsiInitiatorRequest_t * smSCSIRequest,bit32 AddrHi,bit32 AddrLo,bit32 interruptContext)350 smSuperIOStart(
351 smRoot_t *smRoot,
352 smIORequest_t *smIORequest,
353 smDeviceHandle_t *smDeviceHandle,
354 smSuperScsiInitiatorRequest_t *smSCSIRequest,
355 bit32 AddrHi,
356 bit32 AddrLo,
357 bit32 interruptContext
358 )
359 {
360 smDeviceData_t *oneDeviceData = agNULL;
361 smIORequestBody_t *smIORequestBody = agNULL;
362 smSatIOContext_t *satIOContext = agNULL;
363 bit32 status = SM_RC_FAILURE;
364
365 SM_DBG2(("smSuperIOStart: start\n"));
366
367 oneDeviceData = (smDeviceData_t *)smDeviceHandle->smData;
368 if (oneDeviceData == agNULL)
369 {
370 SM_DBG1(("smSuperIOStart: oneDeviceData is NULL!!!\n"));
371 return SM_RC_FAILURE;
372 }
373 if (oneDeviceData->valid == agFALSE)
374 {
375 SM_DBG1(("smSuperIOStart: oneDeviceData is not valid, did %d !!!\n", oneDeviceData->id));
376 return SM_RC_FAILURE;
377 }
378 smIORequestBody = (smIORequestBody_t*)smIORequest->smData;//smDequeueIO(smRoot);
379
380 if (smIORequestBody == agNULL)
381 {
382 SM_DBG1(("smSuperIOStart: smIORequestBody is NULL!!!\n"));
383 return SM_RC_FAILURE;
384 }
385
386 smIOReInit(smRoot, smIORequestBody);
387
388 SM_DBG3(("smSuperIOStart: io ID %d!!!\n", smIORequestBody->id ));
389
390 oneDeviceData->sasAddressHi = AddrHi;
391 oneDeviceData->sasAddressLo = AddrLo;
392
393 smIORequestBody->smIORequest = smIORequest;
394 smIORequestBody->smDevHandle = smDeviceHandle;
395
396 satIOContext = &(smIORequestBody->transport.SATA.satIOContext);
397
398 /*
399 * Need to initialize all the fields within satIOContext except
400 * reqType and satCompleteCB which will be set later in SM.
401 */
402 smIORequestBody->transport.SATA.smSenseData.senseData = agNULL;
403 smIORequestBody->transport.SATA.smSenseData.senseLen = 0;
404 satIOContext->pSatDevData = oneDeviceData;
405 satIOContext->pFis =
406 &smIORequestBody->transport.SATA.agSATARequestBody.fis.fisRegHostToDev;
407 satIOContext->pScsiCmnd = &smSCSIRequest->scsiCmnd;
408 satIOContext->pSense = &smIORequestBody->transport.SATA.sensePayload;
409 satIOContext->pSmSenseData = &smIORequestBody->transport.SATA.smSenseData;
410 satIOContext->pSmSenseData->senseData = satIOContext->pSense;
411 /* satIOContext->pSense = (scsiRspSense_t *)satIOContext->pSmSenseData->senseData; */
412 satIOContext->smRequestBody = smIORequestBody;
413 satIOContext->interruptContext = interruptContext;
414 satIOContext->psmDeviceHandle = smDeviceHandle;
415 satIOContext->smScsiXchg = smSCSIRequest;
416 satIOContext->superIOFlag = agTRUE;
417 // satIOContext->superIOFlag = agFALSE;
418
419 satIOContext->satIntIoContext = agNULL;
420 satIOContext->satOrgIOContext = agNULL;
421 /* satIOContext->tiIORequest = tiIORequest; */
422
423 /* save context if we need to abort later */
424 /*smIORequest->smData = smIORequestBody;*/
425
426 /* followings are used only for internal IO */
427 satIOContext->currentLBA = 0;
428 satIOContext->OrgTL = 0;
429
430 status = smsatIOStart(smRoot, smIORequest, smDeviceHandle, (smScsiInitiatorRequest_t *)smSCSIRequest, satIOContext);
431
432 return status;
433 }
434
435 /*
436 osGLOBAL bit32
437 tiINIIOStart(
438 tiRoot_t *tiRoot,
439 tiIORequest_t *tiIORequest,
440 tiDeviceHandle_t *tiDeviceHandle,
441 tiScsiInitiatorRequest_t *tiScsiRequest,
442 void *tiRequestBody,
443 bit32 interruptContext
444 )
445
446 GLOBAL bit32 satIOStart(
447 tiRoot_t *tiRoot,
448 tiIORequest_t *tiIORequest,
449 tiDeviceHandle_t *tiDeviceHandle,
450 tiScsiInitiatorRequest_t *tiScsiRequest,
451 smSatIOContext_t *satIOContext
452 )
453 smIOStart(
454 smRoot_t *smRoot,
455 smIORequest_t *smIORequest,
456 smDeviceHandle_t *smDeviceHandle,
457 smScsiInitiatorRequest_t *smSCSIRequest,
458 smIORequestBody_t *smRequestBody,
459 bit32 interruptContext
460 )
461
462
463 */
464 FORCEINLINE bit32
smIOStart(smRoot_t * smRoot,smIORequest_t * smIORequest,smDeviceHandle_t * smDeviceHandle,smScsiInitiatorRequest_t * smSCSIRequest,bit32 interruptContext)465 smIOStart(
466 smRoot_t *smRoot,
467 smIORequest_t *smIORequest,
468 smDeviceHandle_t *smDeviceHandle,
469 smScsiInitiatorRequest_t *smSCSIRequest,
470 bit32 interruptContext
471 )
472 {
473 smDeviceData_t *oneDeviceData = agNULL;
474 smIORequestBody_t *smIORequestBody = agNULL;
475 smSatIOContext_t *satIOContext = agNULL;
476 bit32 status = SM_RC_FAILURE;
477
478 SM_DBG2(("smIOStart: start\n"));
479
480 oneDeviceData = (smDeviceData_t *)smDeviceHandle->smData;
481 if (oneDeviceData == agNULL)
482 {
483 SM_DBG1(("smIOStart: oneDeviceData is NULL!!!\n"));
484 return SM_RC_FAILURE;
485 }
486 if (oneDeviceData->valid == agFALSE)
487 {
488 SM_DBG1(("smIOStart: oneDeviceData is not valid, did %d !!!\n", oneDeviceData->id));
489 return SM_RC_FAILURE;
490 }
491 smIORequestBody = (smIORequestBody_t*)smIORequest->smData;//smDequeueIO(smRoot);
492
493 if (smIORequestBody == agNULL)
494 {
495 SM_DBG1(("smIOStart: smIORequestBody is NULL!!!\n"));
496 return SM_RC_FAILURE;
497 }
498
499 smIOReInit(smRoot, smIORequestBody);
500
501 SM_DBG3(("smIOStart: io ID %d!!!\n", smIORequestBody->id ));
502
503 smIORequestBody->smIORequest = smIORequest;
504 smIORequestBody->smDevHandle = smDeviceHandle;
505
506 satIOContext = &(smIORequestBody->transport.SATA.satIOContext);
507
508 /*
509 * Need to initialize all the fields within satIOContext except
510 * reqType and satCompleteCB which will be set later in SM.
511 */
512 smIORequestBody->transport.SATA.smSenseData.senseData = agNULL;
513 smIORequestBody->transport.SATA.smSenseData.senseLen = 0;
514 satIOContext->pSatDevData = oneDeviceData;
515 satIOContext->pFis =
516 &smIORequestBody->transport.SATA.agSATARequestBody.fis.fisRegHostToDev;
517 satIOContext->pScsiCmnd = &smSCSIRequest->scsiCmnd;
518 satIOContext->pSense = &smIORequestBody->transport.SATA.sensePayload;
519 satIOContext->pSmSenseData = &smIORequestBody->transport.SATA.smSenseData;
520 satIOContext->pSmSenseData->senseData = satIOContext->pSense;
521 /* satIOContext->pSense = (scsiRspSense_t *)satIOContext->pSmSenseData->senseData; */
522 satIOContext->smRequestBody = smIORequestBody;
523 satIOContext->interruptContext = interruptContext;
524 satIOContext->psmDeviceHandle = smDeviceHandle;
525 satIOContext->smScsiXchg = smSCSIRequest;
526 satIOContext->superIOFlag = agFALSE;
527
528 satIOContext->satIntIoContext = agNULL;
529 satIOContext->satOrgIOContext = agNULL;
530 satIOContext->currentLBA = 0;
531 satIOContext->OrgTL = 0;
532
533 status = smsatIOStart(smRoot, smIORequest, smDeviceHandle, smSCSIRequest, satIOContext);
534
535 return status;
536
537 }
538
539
540
541 osGLOBAL bit32
smTaskManagement(smRoot_t * smRoot,smDeviceHandle_t * smDeviceHandle,bit32 task,smLUN_t * lun,smIORequest_t * taskTag,smIORequest_t * currentTaskTag)542 smTaskManagement(
543 smRoot_t *smRoot,
544 smDeviceHandle_t *smDeviceHandle,
545 bit32 task,
546 smLUN_t *lun,
547 smIORequest_t *taskTag, /* io to be aborted */
548 smIORequest_t *currentTaskTag /* task management */
549 )
550 {
551 smIntRoot_t *smIntRoot = (smIntRoot_t *)smRoot->smData;
552 smIntContext_t *smAllShared = (smIntContext_t *)&smIntRoot->smAllShared;
553 agsaRoot_t *agRoot = smAllShared->agRoot;
554 smDeviceData_t *oneDeviceData = agNULL;
555 smIORequestBody_t *smIORequestBody = agNULL;
556 bit32 status;
557 agsaContext_t *agContext = agNULL;
558 smSatIOContext_t *satIOContext;
559
560 SM_DBG1(("smTaskManagement: start\n"));
561 oneDeviceData = (smDeviceData_t *)smDeviceHandle->smData;
562
563 if (task == SM_LOGICAL_UNIT_RESET || task == SM_TARGET_WARM_RESET || task == SM_ABORT_TASK)
564 {
565 if (task == AG_LOGICAL_UNIT_RESET)
566 {
567 if ( (lun->lun[0] | lun->lun[1] | lun->lun[2] | lun->lun[3] |
568 lun->lun[4] | lun->lun[5] | lun->lun[6] | lun->lun[7] ) != 0 )
569 {
570 SM_DBG1(("smTaskManagement: *** REJECT *** LUN not zero, did %d!!!\n",
571 oneDeviceData->id));
572 return SM_RC_FAILURE;
573 }
574 }
575
576 oneDeviceData->satDriveState = SAT_DEV_STATE_IN_RECOVERY;
577 oneDeviceData->satAbortAfterReset = agFALSE;
578
579 saSetDeviceState(agRoot,
580 agNULL,
581 tdsmRotateQnumber(smRoot, smDeviceHandle),
582 oneDeviceData->agDevHandle,
583 SA_DS_IN_RECOVERY
584 );
585
586 if (oneDeviceData->directlyAttached == agFALSE)
587 {
588 /* expander attached */
589 SM_DBG1(("smTaskManagement: LUN reset or device reset expander attached!!!\n"));
590 status = smPhyControlSend(smRoot,
591 oneDeviceData,
592 SMP_PHY_CONTROL_HARD_RESET,
593 currentTaskTag,
594 tdsmRotateQnumber(smRoot, smDeviceHandle)
595 );
596 return status;
597 }
598 else
599 {
600 SM_DBG1(("smTaskManagement: LUN reset or device reset directly attached\n"));
601
602 smIORequestBody = (smIORequestBody_t*)currentTaskTag->smData;//smDequeueIO(smRoot);
603
604 if (smIORequestBody == agNULL)
605 {
606 SM_DBG1(("smTaskManagement: smIORequestBody is NULL!!!\n"));
607 return SM_RC_FAILURE;
608 }
609
610 smIOReInit(smRoot, smIORequestBody);
611
612 satIOContext = &(smIORequestBody->transport.SATA.satIOContext);
613 satIOContext->smRequestBody = smIORequestBody;
614 smIORequestBody->smDevHandle = smDeviceHandle;
615
616 agContext = &(oneDeviceData->agDeviceResetContext);
617 agContext->osData = currentTaskTag;
618
619 status = saLocalPhyControl(agRoot,
620 agContext,
621 tdsmRotateQnumber(smRoot, smDeviceHandle) &0xFFFF,
622 oneDeviceData->phyID,
623 AGSA_PHY_HARD_RESET,
624 smLocalPhyControlCB
625 );
626
627 if ( status == AGSA_RC_SUCCESS)
628 {
629 return SM_RC_SUCCESS;
630 }
631 else if (status == AGSA_RC_BUSY)
632 {
633 return SM_RC_BUSY;
634 }
635 else if (status == AGSA_RC_FAILURE)
636 {
637 return SM_RC_FAILURE;
638 }
639 else
640 {
641 SM_DBG1(("smTaskManagement: unknown status %d\n",status));
642 return SM_RC_FAILURE;
643 }
644 }
645 }
646 else
647 {
648 /* smsatsmTaskManagement() which is satTM() */
649 smIORequestBody = (smIORequestBody_t*)currentTaskTag->smData;//smDequeueIO(smRoot);
650
651 if (smIORequestBody == agNULL)
652 {
653 SM_DBG1(("smTaskManagement: smIORequestBody is NULL!!!\n"));
654 return SM_RC_FAILURE;
655 }
656
657 smIOReInit(smRoot, smIORequestBody);
658 /*currentTaskTag->smData = smIORequestBody;*/
659
660 status = smsatTaskManagement(smRoot,
661 smDeviceHandle,
662 task,
663 lun,
664 taskTag,
665 currentTaskTag,
666 smIORequestBody
667 );
668
669 return status;
670 }
671 return SM_RC_SUCCESS;
672 }
673
674
675
676 /********************************************************* end smapi defined APIS */
677 /* counterpart is
678 smEnqueueIO(smRoot_t *smRoot,
679 smSatIOContext_t *satIOContext)
680 */
681 osGLOBAL smIORequestBody_t *
smDequeueIO(smRoot_t * smRoot)682 smDequeueIO(smRoot_t *smRoot)
683 {
684 smIntRoot_t *smIntRoot = (smIntRoot_t *)smRoot->smData;
685 smIntContext_t *smAllShared = (smIntContext_t *)&smIntRoot->smAllShared;
686 smIORequestBody_t *smIORequestBody = agNULL;
687 smList_t *IOListList;
688
689 SM_DBG2(("smDequeueIO: start\n"));
690
691 tdsmSingleThreadedEnter(smRoot, SM_EXTERNAL_IO_LOCK);
692 if (SMLIST_EMPTY(&(smAllShared->freeIOList)))
693 {
694 SM_DBG1(("smDequeueIO: empty freeIOList!!!\n"));
695 tdsmSingleThreadedLeave(smRoot, SM_EXTERNAL_IO_LOCK);
696 return agNULL;
697 }
698
699 SMLIST_DEQUEUE_FROM_HEAD(&IOListList, &(smAllShared->freeIOList));
700 smIORequestBody = SMLIST_OBJECT_BASE(smIORequestBody_t, satIoBodyLink, IOListList);
701 SMLIST_DEQUEUE_THIS(&(smIORequestBody->satIoBodyLink));
702 SMLIST_ENQUEUE_AT_TAIL(&(smIORequestBody->satIoBodyLink), &(smAllShared->mainIOList));
703 tdsmSingleThreadedLeave(smRoot, SM_EXTERNAL_IO_LOCK);
704
705 if (smIORequestBody->InUse == agTRUE)
706 {
707 SM_DBG1(("smDequeueIO: wrong. already in USE ID %d!!!!\n", smIORequestBody->id));
708 }
709 smIOReInit(smRoot, smIORequestBody);
710
711
712 SM_DBG2(("smDequeueIO: io ID %d!\n", smIORequestBody->id));
713
714 /* debugging */
715 if (smIORequestBody->satIoBodyLink.flink == agNULL)
716 {
717 SM_DBG1(("smDequeueIO: io ID %d, flink is NULL!!!\n", smIORequestBody->id));
718 }
719 if (smIORequestBody->satIoBodyLink.blink == agNULL)
720 {
721 SM_DBG1(("smDequeueIO: io ID %d, blink is NULL!!!\n", smIORequestBody->id));
722 }
723
724 return smIORequestBody;
725 }
726
727 //start here
728 //compare with ossaSATAAbortCB()
729 //qqq1
730 osGLOBAL void
smsatAbort(smRoot_t * smRoot,agsaRoot_t * agRoot,smSatIOContext_t * satIOContext)731 smsatAbort(
732 smRoot_t *smRoot,
733 agsaRoot_t *agRoot,
734 smSatIOContext_t *satIOContext
735 )
736 {
737 smIORequestBody_t *smIORequestBody = agNULL; /* abort itself */
738 smIORequestBody_t *smToBeAbortedIORequestBody; /* io to be aborted */
739 agsaIORequest_t *agToBeAbortedIORequest; /* io to be aborted */
740 agsaIORequest_t *agAbortIORequest; /* abort io itself */
741 smSatIOContext_t *satAbortIOContext;
742 bit32 PhysUpper32;
743 bit32 PhysLower32;
744 bit32 memAllocStatus;
745 void *osMemHandle;
746
747
748 SM_DBG2(("smsatAbort: start\n"));
749
750 if (satIOContext == agNULL)
751 {
752 SM_DBG1(("smsatAbort: satIOContext is NULL, wrong!!!\n"));
753 return;
754 }
755
756 smToBeAbortedIORequestBody = (smIORequestBody_t *)satIOContext->smRequestBody;
757 agToBeAbortedIORequest = (agsaIORequest_t *)&(smToBeAbortedIORequestBody->agIORequest);
758 /*
759 smIORequestBody = smDequeueIO(smRoot);
760
761 if (smIORequestBody == agNULL)
762 {
763 SM_DBG1(("smsatAbort: empty freeIOList!!!\n"));
764 return;
765 }
766 */
767 /* allocating agIORequest for abort itself */
768 memAllocStatus = tdsmAllocMemory(
769 smRoot,
770 &osMemHandle,
771 (void **)&smIORequestBody,
772 &PhysUpper32,
773 &PhysLower32,
774 8,
775 sizeof(smIORequestBody_t),
776 agTRUE
777 );
778 if (memAllocStatus != tiSuccess)
779 {
780 /* let os process IO */
781 SM_DBG1(("smsatAbort: ostiAllocMemory failed...\n"));
782 return;
783 }
784
785 if (smIORequestBody == agNULL)
786 {
787 /* let os process IO */
788 SM_DBG1(("smsatAbort: ostiAllocMemory returned NULL smIORequestBody\n"));
789 return;
790 }
791 smIOReInit(smRoot, smIORequestBody);
792
793 smIORequestBody->IOType.InitiatorTMIO.osMemHandle = osMemHandle;
794 smIORequestBody->smDevHandle = smToBeAbortedIORequestBody->smDevHandle;
795 /* initialize agIORequest */
796 satAbortIOContext = &(smIORequestBody->transport.SATA.satIOContext);
797 satAbortIOContext->smRequestBody = smIORequestBody;
798
799 agAbortIORequest = &(smIORequestBody->agIORequest);
800 agAbortIORequest->osData = (void *) smIORequestBody;
801 agAbortIORequest->sdkData = agNULL; /* LL takes care of this */
802
803 /*
804 * Issue abort
805 */
806 saSATAAbort( agRoot, agAbortIORequest, 0, agNULL, 0, agToBeAbortedIORequest, smaSATAAbortCB);
807
808
809 SM_DBG1(("satAbort: end!!!\n"));
810
811 return;
812 }
813
814 osGLOBAL bit32
smsatStartCheckPowerMode(smRoot_t * smRoot,smIORequest_t * currentTaskTag,smDeviceHandle_t * smDeviceHandle,smScsiInitiatorRequest_t * smScsiRequest,smSatIOContext_t * satIOContext)815 smsatStartCheckPowerMode(
816 smRoot_t *smRoot,
817 smIORequest_t *currentTaskTag,
818 smDeviceHandle_t *smDeviceHandle,
819 smScsiInitiatorRequest_t *smScsiRequest,
820 smSatIOContext_t *satIOContext
821 )
822 {
823 smSatInternalIo_t *satIntIo = agNULL;
824 smDeviceData_t *oneDeviceData = agNULL;
825 smSatIOContext_t *satNewIOContext;
826 bit32 status;
827
828 SM_DBG1(("smsatStartCheckPowerMode: start\n"));
829
830 oneDeviceData = satIOContext->pSatDevData;
831
832 SM_DBG6(("smsatStartCheckPowerMode: before alloc\n"));
833
834 /* allocate any fis for seting SRT bit in device control */
835 satIntIo = smsatAllocIntIoResource( smRoot,
836 currentTaskTag,
837 oneDeviceData,
838 0,
839 satIntIo);
840
841 SM_DBG6(("smsatStartCheckPowerMode: before after\n"));
842
843 if (satIntIo == agNULL)
844 {
845 SM_DBG1(("smsatStartCheckPowerMode: can't alloacate!!!\n"));
846 /*smEnqueueIO(smRoot, satIOContext);*/
847 return SM_RC_FAILURE;
848 }
849
850 satNewIOContext = smsatPrepareNewIO(satIntIo,
851 currentTaskTag,
852 oneDeviceData,
853 agNULL,
854 satIOContext);
855
856 SM_DBG6(("smsatStartCheckPowerMode: TD satIOContext %p \n", satIOContext));
857 SM_DBG6(("smsatStartCheckPowerMode: SM satNewIOContext %p \n", satNewIOContext));
858 SM_DBG6(("smsatStartCheckPowerMode: TD smScsiXchg %p \n", satIOContext->smScsiXchg));
859 SM_DBG6(("smsatStartCheckPowerMode: SM smScsiXchg %p \n", satNewIOContext->smScsiXchg));
860
861
862
863 SM_DBG2(("smsatStartCheckPowerMode: satNewIOContext %p \n", satNewIOContext));
864
865 status = smsatCheckPowerMode(smRoot,
866 &satIntIo->satIntSmIORequest, /* New smIORequest */
867 smDeviceHandle,
868 satNewIOContext->smScsiXchg, /* New tiScsiInitiatorRequest_t *smScsiRequest, */
869 satNewIOContext);
870
871 if (status != SM_RC_SUCCESS)
872 {
873 SM_DBG1(("smsatStartCheckPowerMode: failed in sending!!!\n"));
874
875 smsatFreeIntIoResource( smRoot,
876 oneDeviceData,
877 satIntIo);
878
879 /*smEnqueueIO(smRoot, satIOContext);*/
880
881 return SM_RC_FAILURE;
882 }
883
884
885 SM_DBG6(("smsatStartCheckPowerMode: end\n"));
886
887 return status;
888 }
889
890 osGLOBAL bit32
smsatStartResetDevice(smRoot_t * smRoot,smIORequest_t * currentTaskTag,smDeviceHandle_t * smDeviceHandle,smScsiInitiatorRequest_t * smScsiRequest,smSatIOContext_t * satIOContext)891 smsatStartResetDevice(
892 smRoot_t *smRoot,
893 smIORequest_t *currentTaskTag,
894 smDeviceHandle_t *smDeviceHandle,
895 smScsiInitiatorRequest_t *smScsiRequest,
896 smSatIOContext_t *satIOContext
897 )
898 {
899 smSatInternalIo_t *satIntIo = agNULL;
900 smDeviceData_t *oneDeviceData = agNULL;
901 smSatIOContext_t *satNewIOContext;
902 bit32 status;
903
904 SM_DBG1(("smsatStartResetDevice: start\n"));
905
906 oneDeviceData = satIOContext->pSatDevData;
907
908 SM_DBG6(("smsatStartResetDevice: before alloc\n"));
909
910 /* allocate any fis for seting SRT bit in device control */
911 satIntIo = smsatAllocIntIoResource( smRoot,
912 currentTaskTag,
913 oneDeviceData,
914 0,
915 satIntIo);
916
917 SM_DBG6(("smsatStartResetDevice: before after\n"));
918
919 if (satIntIo == agNULL)
920 {
921 SM_DBG1(("smsatStartResetDevice: can't alloacate!!!\n"));
922 /*smEnqueueIO(smRoot, satIOContext);*/
923 return SM_RC_FAILURE;
924 }
925
926 satNewIOContext = smsatPrepareNewIO(satIntIo,
927 currentTaskTag,
928 oneDeviceData,
929 agNULL,
930 satIOContext);
931
932 SM_DBG6(("smsatStartResetDevice: TD satIOContext %p \n", satIOContext));
933 SM_DBG6(("smsatStartResetDevice: SM satNewIOContext %p \n", satNewIOContext));
934 SM_DBG6(("smsatStartResetDevice: TD smScsiXchg %p \n", satIOContext->smScsiXchg));
935 SM_DBG6(("smsatStartResetDevice: SM smScsiXchg %p \n", satNewIOContext->smScsiXchg));
936
937
938
939 SM_DBG6(("smsatStartResetDevice: satNewIOContext %p \n", satNewIOContext));
940
941 if (oneDeviceData->satDeviceType == SATA_ATAPI_DEVICE)
942 {
943 /*if ATAPI device, send DEVICE RESET command to ATAPI device*/
944 status = smsatDeviceReset(smRoot,
945 &satIntIo->satIntSmIORequest, /* New smIORequest */
946 smDeviceHandle,
947 satNewIOContext->smScsiXchg, /* New smScsiInitiatorRequest_t *smScsiRequest, NULL */
948 satNewIOContext);
949 }
950 else
951 {
952 status = smsatResetDevice(smRoot,
953 &satIntIo->satIntSmIORequest, /* New smIORequest */
954 smDeviceHandle,
955 satNewIOContext->smScsiXchg, /* New smScsiInitiatorRequest_t *smScsiRequest, NULL */
956 satNewIOContext);
957 }
958
959 if (status != SM_RC_SUCCESS)
960 {
961 SM_DBG1(("smsatStartResetDevice: failed in sending!!!\n"));
962
963 smsatFreeIntIoResource( smRoot,
964 oneDeviceData,
965 satIntIo);
966
967 /*smEnqueueIO(smRoot, satIOContext);*/
968
969 return SM_RC_FAILURE;
970 }
971
972
973 SM_DBG6(("smsatStartResetDevice: end\n"));
974
975 return status;
976 }
977
978 osGLOBAL bit32
smsatTmAbortTask(smRoot_t * smRoot,smIORequest_t * currentTaskTag,smDeviceHandle_t * smDeviceHandle,smScsiInitiatorRequest_t * smScsiRequest,smSatIOContext_t * satIOContext,smIORequest_t * taskTag)979 smsatTmAbortTask(
980 smRoot_t *smRoot,
981 smIORequest_t *currentTaskTag, /* task management */
982 smDeviceHandle_t *smDeviceHandle,
983 smScsiInitiatorRequest_t *smScsiRequest, /* NULL */
984 smSatIOContext_t *satIOContext, /* task management */
985 smIORequest_t *taskTag) /* io to be aborted */
986 {
987 smDeviceData_t *oneDeviceData = agNULL;
988 smSatIOContext_t *satTempIOContext = agNULL;
989 smList_t *elementHdr;
990 bit32 found = agFALSE;
991 smIORequestBody_t *smIORequestBody = agNULL;
992 smIORequest_t *smIOReq = agNULL;
993 bit32 status;
994
995 SM_DBG1(("smsatTmAbortTask: start\n"));
996
997 oneDeviceData = (smDeviceData_t *)smDeviceHandle->smData;
998
999 /*
1000 * Check that the only pending I/O matches taskTag. If not return tiError.
1001 */
1002 tdsmSingleThreadedEnter(smRoot, SM_EXTERNAL_IO_LOCK);
1003
1004 elementHdr = oneDeviceData->satIoLinkList.flink;
1005
1006 while (elementHdr != &oneDeviceData->satIoLinkList)
1007 {
1008 satTempIOContext = SMLIST_OBJECT_BASE( smSatIOContext_t,
1009 satIoContextLink,
1010 elementHdr );
1011
1012 if ( satTempIOContext != agNULL)
1013 {
1014 smIORequestBody = (smIORequestBody_t *) satTempIOContext->smRequestBody;
1015 smIOReq = smIORequestBody->smIORequest;
1016 }
1017
1018 elementHdr = elementHdr->flink; /* for the next while loop */
1019
1020 /*
1021 * Check if the tag matches
1022 */
1023 if ( smIOReq == taskTag)
1024 {
1025 found = agTRUE;
1026 satIOContext->satToBeAbortedIOContext = satTempIOContext;
1027 SM_DBG1(("smsatTmAbortTask: found matching tag.\n"));
1028
1029 break;
1030
1031 } /* if matching tag */
1032
1033 } /* while loop */
1034
1035 tdsmSingleThreadedLeave(smRoot, SM_EXTERNAL_IO_LOCK);
1036
1037 if (found == agFALSE )
1038 {
1039 SM_DBG1(("smsatTmAbortTask: *** REJECT *** no match!!!\n"));
1040
1041 /*smEnqueueIO(smRoot, satIOContext);*/
1042 /* clean up TD layer's smIORequestBody */
1043 if (smIORequestBody)
1044 {
1045 if (smIORequestBody->IOType.InitiatorTMIO.osMemHandle != agNULL)
1046 {
1047 tdsmFreeMemory(
1048 smRoot,
1049 smIORequestBody->IOType.InitiatorTMIO.osMemHandle,
1050 sizeof(smIORequestBody_t)
1051 );
1052 }
1053 }
1054 else
1055 {
1056 SM_DBG1(("smsatTmAbortTask: smIORequestBody is NULL!!!\n"));
1057 }
1058
1059 return SM_RC_FAILURE;
1060 }
1061
1062 if (satTempIOContext == agNULL)
1063 {
1064 SM_DBG1(("smsatTmAbortTask: satTempIOContext is NULL!!!\n"));
1065 return SM_RC_FAILURE;
1066 }
1067
1068 /*
1069 * Save smIORequest, will be returned at device reset completion to return
1070 * the TM completion.
1071 */
1072 oneDeviceData->satTmTaskTag = currentTaskTag;
1073
1074 /*
1075 * Set flag to indicate device in recovery mode.
1076 */
1077 oneDeviceData->satDriveState = SAT_DEV_STATE_IN_RECOVERY;
1078
1079
1080 /*
1081 * Issue SATA device reset or check power mode.. Set flag to to automatically abort
1082 * at the completion of SATA device reset.
1083 * SAT r09 p25
1084 */
1085 oneDeviceData->satAbortAfterReset = agTRUE;
1086
1087 if ( (satTempIOContext->reqType == AGSA_SATA_PROTOCOL_FPDMA_WRITE) ||
1088 (satTempIOContext->reqType == AGSA_SATA_PROTOCOL_FPDMA_READ)
1089 )
1090 {
1091 SM_DBG1(("smsatTmAbortTask: calling satStartCheckPowerMode!!!\n"));
1092 /* send check power mode */
1093 status = smsatStartCheckPowerMode(
1094 smRoot,
1095 currentTaskTag, /* currentTaskTag */
1096 smDeviceHandle,
1097 smScsiRequest, /* NULL */
1098 satIOContext
1099 );
1100 }
1101 else
1102 {
1103 SM_DBG1(("smsatTmAbortTask: calling satStartResetDevice!!!\n"));
1104 /* send AGSA_SATA_PROTOCOL_SRST_ASSERT */
1105 status = smsatStartResetDevice(
1106 smRoot,
1107 currentTaskTag, /* currentTaskTag */
1108 smDeviceHandle,
1109 smScsiRequest, /* NULL */
1110 satIOContext
1111 );
1112 }
1113 return status;
1114 }
1115
1116 /* satTM() */
1117 osGLOBAL bit32
smsatTaskManagement(smRoot_t * smRoot,smDeviceHandle_t * smDeviceHandle,bit32 task,smLUN_t * lun,smIORequest_t * taskTag,smIORequest_t * currentTaskTag,smIORequestBody_t * smIORequestBody)1118 smsatTaskManagement(
1119 smRoot_t *smRoot,
1120 smDeviceHandle_t *smDeviceHandle,
1121 bit32 task,
1122 smLUN_t *lun,
1123 smIORequest_t *taskTag, /* io to be aborted */
1124 smIORequest_t *currentTaskTag, /* task management */
1125 smIORequestBody_t *smIORequestBody
1126 )
1127 {
1128 smSatIOContext_t *satIOContext = agNULL;
1129 smDeviceData_t *oneDeviceData = agNULL;
1130 bit32 status;
1131
1132 SM_DBG1(("smsatTaskManagement: start\n"));
1133 oneDeviceData = (smDeviceData_t *)smDeviceHandle->smData;
1134
1135 satIOContext = &(smIORequestBody->transport.SATA.satIOContext);
1136
1137 satIOContext->pSatDevData = oneDeviceData;
1138 satIOContext->pFis =
1139 &(smIORequestBody->transport.SATA.agSATARequestBody.fis.fisRegHostToDev);
1140
1141
1142 satIOContext->smRequestBody = smIORequestBody;
1143 satIOContext->psmDeviceHandle = smDeviceHandle;
1144 satIOContext->satIntIoContext = agNULL;
1145 satIOContext->satOrgIOContext = agNULL;
1146
1147 /* followings are used only for internal IO */
1148 satIOContext->currentLBA = 0;
1149 satIOContext->OrgTL = 0;
1150
1151 /* saving task in satIOContext */
1152 satIOContext->TMF = task;
1153
1154 satIOContext->satToBeAbortedIOContext = agNULL;
1155
1156 if (task == AG_ABORT_TASK)
1157 {
1158 status = smsatTmAbortTask( smRoot,
1159 currentTaskTag,
1160 smDeviceHandle,
1161 agNULL,
1162 satIOContext,
1163 taskTag);
1164
1165 return status;
1166 }
1167 else
1168 {
1169 SM_DBG1(("smsatTaskManagement: UNSUPPORTED TM task=0x%x!!!\n", task ));
1170
1171 /*smEnqueueIO(smRoot, satIOContext);*/
1172
1173 return SM_RC_FAILURE;
1174 }
1175
1176 return SM_RC_SUCCESS;
1177 }
1178
1179
1180 osGLOBAL bit32
smPhyControlSend(smRoot_t * smRoot,smDeviceData_t * oneDeviceData,bit8 phyOp,smIORequest_t * CurrentTaskTag,bit32 queueNumber)1181 smPhyControlSend(
1182 smRoot_t *smRoot,
1183 smDeviceData_t *oneDeviceData, /* sata disk itself */
1184 bit8 phyOp,
1185 smIORequest_t *CurrentTaskTag,
1186 bit32 queueNumber
1187 )
1188 {
1189 smIntRoot_t *smIntRoot = (smIntRoot_t *)smRoot->smData;
1190 smIntContext_t *smAllShared = (smIntContext_t *)&smIntRoot->smAllShared;
1191 agsaRoot_t *agRoot = smAllShared->agRoot;
1192 agsaDevHandle_t *agExpDevHandle;
1193 smpReqPhyControl_t smpPhyControlReq;
1194 void *osMemHandle;
1195 bit32 PhysUpper32;
1196 bit32 PhysLower32;
1197 bit32 memAllocStatus;
1198 bit32 expectedRspLen = 0;
1199 smSMPRequestBody_t *smSMPRequestBody;
1200 agsaSASRequestBody_t *agSASRequestBody;
1201 agsaSMPFrame_t *agSMPFrame;
1202 agsaIORequest_t *agIORequest;
1203 // agsaDevHandle_t *agDevHandle;
1204 smSMPFrameHeader_t smSMPFrameHeader;
1205 bit32 status;
1206 bit8 *pSmpBody; /* smp payload itself w/o first 4 bytes(header) */
1207 bit32 smpBodySize; /* smp payload size w/o first 4 bytes(header) */
1208 bit32 agRequestType;
1209
1210 SM_DBG2(("smPhyControlSend: start\n"));
1211
1212 agExpDevHandle = oneDeviceData->agExpDevHandle;
1213
1214 if (agExpDevHandle == agNULL)
1215 {
1216 SM_DBG1(("smPhyControlSend: agExpDevHandle is NULL!!!\n"));
1217 return SM_RC_FAILURE;
1218 }
1219
1220 SM_DBG5(("smPhyControlSend: phyID %d\n", oneDeviceData->phyID));
1221
1222 sm_memset(&smpPhyControlReq, 0, sizeof(smpReqPhyControl_t));
1223
1224 /* fill in SMP payload */
1225 smpPhyControlReq.phyIdentifier = (bit8)oneDeviceData->phyID;
1226 smpPhyControlReq.phyOperation = phyOp;
1227
1228 /* allocate smp and send it */
1229 memAllocStatus = tdsmAllocMemory(
1230 smRoot,
1231 &osMemHandle,
1232 (void **)&smSMPRequestBody,
1233 &PhysUpper32,
1234 &PhysLower32,
1235 8,
1236 sizeof(smSMPRequestBody_t),
1237 agTRUE
1238 );
1239
1240 if (memAllocStatus != SM_RC_SUCCESS)
1241 {
1242 SM_DBG1(("smPhyControlSend: tdsmAllocMemory failed...!!!\n"));
1243 return SM_RC_FAILURE;
1244 }
1245
1246 if (smSMPRequestBody == agNULL)
1247 {
1248 SM_DBG1(("smPhyControlSend: tdsmAllocMemory returned NULL smSMPRequestBody!!!\n"));
1249 return SM_RC_FAILURE;
1250 }
1251
1252 /* saves mem handle for freeing later */
1253 smSMPRequestBody->osMemHandle = osMemHandle;
1254
1255 /* saves oneDeviceData */
1256 smSMPRequestBody->smDeviceData = oneDeviceData; /* sata disk */
1257
1258 /* saves oneDeviceData */
1259 smSMPRequestBody->smDevHandle = oneDeviceData->smDevHandle;
1260
1261 // agDevHandle = oneDeviceData->agDevHandle;
1262
1263 /* save the callback funtion */
1264 smSMPRequestBody->SMPCompletionFunc = smSMPCompleted; /* in satcb.c */
1265
1266 /* for simulate warm target reset */
1267 smSMPRequestBody->CurrentTaskTag = CurrentTaskTag;
1268
1269 if (CurrentTaskTag != agNULL)
1270 {
1271 CurrentTaskTag->smData = smSMPRequestBody;
1272 }
1273
1274 /* initializes the number of SMP retries */
1275 smSMPRequestBody->retries = 0;
1276
1277 #ifdef TD_INTERNAL_DEBUG /* debugging */
1278 SM_DBG4(("smPhyControlSend: SMPRequestbody %p\n", smSMPRequestBody));
1279 SM_DBG4(("smPhyControlSend: callback fn %p\n", smSMPRequestBody->SMPCompletionFunc));
1280 #endif
1281
1282 agIORequest = &(smSMPRequestBody->agIORequest);
1283 agIORequest->osData = (void *) smSMPRequestBody;
1284 agIORequest->sdkData = agNULL; /* SALL takes care of this */
1285
1286
1287 agSASRequestBody = &(smSMPRequestBody->agSASRequestBody);
1288 agSMPFrame = &(agSASRequestBody->smpFrame);
1289
1290 SM_DBG3(("smPhyControlSend: agIORequest %p\n", agIORequest));
1291 SM_DBG3(("smPhyControlSend: SMPRequestbody %p\n", smSMPRequestBody));
1292
1293 expectedRspLen = 4;
1294
1295 pSmpBody = (bit8 *)&smpPhyControlReq;
1296 smpBodySize = sizeof(smpReqPhyControl_t);
1297 agRequestType = AGSA_SMP_INIT_REQ;
1298
1299 if (SMIsSPC(agRoot))
1300 {
1301 if ( (smpBodySize + 4) <= SMP_DIRECT_PAYLOAD_LIMIT) /* 48 */
1302 {
1303 SM_DBG3(("smPhyControlSend: DIRECT smp payload\n"));
1304 sm_memset(&smSMPFrameHeader, 0, sizeof(smSMPFrameHeader_t));
1305 sm_memset(smSMPRequestBody->smpPayload, 0, SMP_DIRECT_PAYLOAD_LIMIT);
1306
1307 /* SMP header */
1308 smSMPFrameHeader.smpFrameType = SMP_REQUEST; /* SMP request */
1309 smSMPFrameHeader.smpFunction = (bit8)SMP_PHY_CONTROL;
1310 smSMPFrameHeader.smpFunctionResult = 0;
1311 smSMPFrameHeader.smpReserved = 0;
1312
1313 sm_memcpy(smSMPRequestBody->smpPayload, &smSMPFrameHeader, 4);
1314 sm_memcpy((smSMPRequestBody->smpPayload)+4, pSmpBody, smpBodySize);
1315
1316 /* direct SMP payload eg) REPORT_GENERAL, DISCOVER etc */
1317 agSMPFrame->outFrameBuf = smSMPRequestBody->smpPayload;
1318 agSMPFrame->outFrameLen = smpBodySize + 4; /* without last 4 byte crc */
1319 /* to specify DIRECT SMP response */
1320 agSMPFrame->inFrameLen = 0;
1321
1322 /* temporary solution for T2D Combo*/
1323 #if defined (INITIATOR_DRIVER) && defined (TARGET_DRIVER)
1324 /* force smp repsonse to be direct */
1325 agSMPFrame->expectedRespLen = 0;
1326 #else
1327 agSMPFrame->expectedRespLen = expectedRspLen;
1328 #endif
1329 // smhexdump("smPhyControlSend", (bit8*)agSMPFrame->outFrameBuf, agSMPFrame->outFrameLen);
1330 // smhexdump("smPhyControlSend new", (bit8*)smSMPRequestBody->smpPayload, agSMPFrame->outFrameLen);
1331 // smhexdump("smPhyControlSend - smSMPRequestBody", (bit8*)smSMPRequestBody, sizeof(smSMPRequestBody_t));
1332 }
1333 else
1334 {
1335 SM_DBG1(("smPhyControlSend: INDIRECT smp payload, not supported!!!\n"));
1336 tdsmFreeMemory(
1337 smRoot,
1338 osMemHandle,
1339 sizeof(smSMPRequestBody_t)
1340 );
1341
1342 return SM_RC_FAILURE;
1343 }
1344 }
1345 else /* SPCv controller */
1346 {
1347 /* only direct mode for both request and response */
1348 SM_DBG3(("smPhyControlSend: DIRECT smp payload\n"));
1349 agSMPFrame->flag = 0;
1350 sm_memset(&smSMPFrameHeader, 0, sizeof(smSMPFrameHeader_t));
1351 sm_memset(smSMPRequestBody->smpPayload, 0, SMP_DIRECT_PAYLOAD_LIMIT);
1352
1353 /* SMP header */
1354 smSMPFrameHeader.smpFrameType = SMP_REQUEST; /* SMP request */
1355 smSMPFrameHeader.smpFunction = (bit8)SMP_PHY_CONTROL;
1356 smSMPFrameHeader.smpFunctionResult = 0;
1357 smSMPFrameHeader.smpReserved = 0;
1358
1359 sm_memcpy(smSMPRequestBody->smpPayload, &smSMPFrameHeader, 4);
1360 sm_memcpy((smSMPRequestBody->smpPayload)+4, pSmpBody, smpBodySize);
1361
1362 /* direct SMP payload eg) REPORT_GENERAL, DISCOVER etc */
1363 agSMPFrame->outFrameBuf = smSMPRequestBody->smpPayload;
1364 agSMPFrame->outFrameLen = smpBodySize + 4; /* without last 4 byte crc */
1365 /* to specify DIRECT SMP response */
1366 agSMPFrame->inFrameLen = 0;
1367
1368 /* temporary solution for T2D Combo*/
1369 #if defined (INITIATOR_DRIVER) && defined (TARGET_DRIVER)
1370 /* force smp repsonse to be direct */
1371 agSMPFrame->expectedRespLen = 0;
1372 #else
1373 agSMPFrame->expectedRespLen = expectedRspLen;
1374 #endif
1375 // smhexdump("smPhyControlSend", (bit8*)agSMPFrame->outFrameBuf, agSMPFrame->outFrameLen);
1376 // smhexdump("smPhyControlSend new", (bit8*)smSMPRequestBody->smpPayload, agSMPFrame->outFrameLen);
1377 // smhexdump("smPhyControlSend - smSMPRequestBody", (bit8*)smSMPRequestBody, sizeof(smSMPRequestBody_t));
1378 }
1379
1380 status = saSMPStart(
1381 agRoot,
1382 agIORequest,
1383 queueNumber,
1384 agExpDevHandle,
1385 agRequestType,
1386 agSASRequestBody,
1387 &smSMPCompletedCB
1388 );
1389
1390 if (status == AGSA_RC_SUCCESS)
1391 {
1392 return SM_RC_SUCCESS;
1393 }
1394 else if (status == AGSA_RC_BUSY)
1395 {
1396 SM_DBG1(("smPhyControlSend: saSMPStart is busy!!!\n"));
1397 tdsmFreeMemory(
1398 smRoot,
1399 osMemHandle,
1400 sizeof(smSMPRequestBody_t)
1401 );
1402
1403 return SM_RC_BUSY;
1404 }
1405 else /* AGSA_RC_FAILURE */
1406 {
1407 SM_DBG1(("smPhyControlSend: saSMPStart is failed. status %d!!!\n", status));
1408 tdsmFreeMemory(
1409 smRoot,
1410 osMemHandle,
1411 sizeof(smSMPRequestBody_t)
1412 );
1413
1414 return SM_RC_FAILURE;
1415 }
1416 }
1417
1418 /* free IO which are internally completed within SM
1419 counterpart is
1420 osGLOBAL smIORequestBody_t *
1421 smDequeueIO(smRoot_t *smRoot)
1422 */
1423 osGLOBAL void
smEnqueueIO(smRoot_t * smRoot,smSatIOContext_t * satIOContext)1424 smEnqueueIO(
1425 smRoot_t *smRoot,
1426 smSatIOContext_t *satIOContext
1427 )
1428 {
1429 smIntRoot_t *smIntRoot = agNULL;
1430 smIntContext_t *smAllShared = agNULL;
1431 smIORequestBody_t *smIORequestBody;
1432
1433 SM_DBG3(("smEnqueueIO: start\n"));
1434 smIORequestBody = (smIORequestBody_t *)satIOContext->smRequestBody;
1435 smIntRoot = (smIntRoot_t *)smRoot->smData;
1436 smAllShared = (smIntContext_t *)&smIntRoot->smAllShared;
1437
1438 /* enque back to smAllShared->freeIOList */
1439 if (satIOContext->satIntIoContext == agNULL)
1440 {
1441 SM_DBG2(("smEnqueueIO: external command!!!, io ID %d!!!\n", smIORequestBody->id));
1442 /* debugging only */
1443 if (smIORequestBody->satIoBodyLink.flink == agNULL)
1444 {
1445 SM_DBG1(("smEnqueueIO: external command!!!, io ID %d, flink is NULL!!!\n", smIORequestBody->id));
1446 }
1447 if (smIORequestBody->satIoBodyLink.blink == agNULL)
1448 {
1449 SM_DBG1(("smEnqueueIO: external command!!!, io ID %d, blink is NULL!!!\n", smIORequestBody->id));
1450 }
1451 }
1452 else
1453 {
1454 SM_DBG2(("smEnqueueIO: internal command!!!, io ID %d!!!\n", smIORequestBody->id));
1455 /* debugging only */
1456 if (smIORequestBody->satIoBodyLink.flink == agNULL)
1457 {
1458 SM_DBG1(("smEnqueueIO: internal command!!!, io ID %d, flink is NULL!!!\n", smIORequestBody->id));
1459 }
1460 if (smIORequestBody->satIoBodyLink.blink == agNULL)
1461 {
1462 SM_DBG1(("smEnqueueIO: internal command!!!, io ID %d, blink is NULL!!!\n", smIORequestBody->id));
1463 }
1464 }
1465
1466 if (smIORequestBody->smIORequest == agNULL)
1467 {
1468 SM_DBG1(("smEnqueueIO: smIORequest is NULL, io ID %d!!!\n", smIORequestBody->id));
1469 }
1470
1471 if (smIORequestBody->InUse == agTRUE)
1472 {
1473 smIORequestBody->InUse = agFALSE;
1474 tdsmSingleThreadedEnter(smRoot, SM_EXTERNAL_IO_LOCK);
1475 SMLIST_DEQUEUE_THIS(&(smIORequestBody->satIoBodyLink));
1476 SMLIST_ENQUEUE_AT_TAIL(&(smIORequestBody->satIoBodyLink), &(smAllShared->freeIOList));
1477 tdsmSingleThreadedLeave(smRoot, SM_EXTERNAL_IO_LOCK);
1478 }
1479 else
1480 {
1481 SM_DBG2(("smEnqueueIO: check!!!, io ID %d!!!\n", smIORequestBody->id));
1482 }
1483
1484
1485 return;
1486 }
1487
1488 FORCEINLINE void
smsatFreeIntIoResource(smRoot_t * smRoot,smDeviceData_t * satDevData,smSatInternalIo_t * satIntIo)1489 smsatFreeIntIoResource(
1490 smRoot_t *smRoot,
1491 smDeviceData_t *satDevData,
1492 smSatInternalIo_t *satIntIo
1493 )
1494 {
1495 SM_DBG3(("smsatFreeIntIoResource: start\n"));
1496
1497 if (satIntIo == agNULL)
1498 {
1499 SM_DBG2(("smsatFreeIntIoResource: allowed call\n"));
1500 return;
1501 }
1502
1503 /* sets the original smIOrequest to agNULL for internally generated ATA cmnd */
1504 satIntIo->satOrgSmIORequest = agNULL;
1505
1506 /*
1507 * Free DMA memory if previosly alocated
1508 */
1509 if (satIntIo->satIntSmScsiXchg.scsiCmnd.expDataLength != 0)
1510 {
1511 SM_DBG3(("smsatFreeIntIoResource: DMA len %d\n", satIntIo->satIntDmaMem.totalLength));
1512 SM_DBG3(("smsatFreeIntIoResource: pointer %p\n", satIntIo->satIntDmaMem.osHandle));
1513
1514 tdsmFreeMemory( smRoot,
1515 satIntIo->satIntDmaMem.osHandle,
1516 satIntIo->satIntDmaMem.totalLength);
1517 satIntIo->satIntSmScsiXchg.scsiCmnd.expDataLength = 0;
1518 }
1519
1520 if (satIntIo->satIntReqBodyMem.totalLength != 0)
1521 {
1522 SM_DBG3(("smsatFreeIntIoResource: req body len %d\n", satIntIo->satIntReqBodyMem.totalLength));
1523 /*
1524 * Free mem allocated for Req body
1525 */
1526 tdsmFreeMemory( smRoot,
1527 satIntIo->satIntReqBodyMem.osHandle,
1528 satIntIo->satIntReqBodyMem.totalLength);
1529
1530 satIntIo->satIntReqBodyMem.totalLength = 0;
1531 }
1532
1533 SM_DBG3(("smsatFreeIntIoResource: satDevData %p satIntIo id %d\n", satDevData, satIntIo->id));
1534 /*
1535 * Return satIntIo to the free list
1536 */
1537 tdsmSingleThreadedEnter(smRoot, SM_INTERNAL_IO_LOCK);
1538 SMLIST_DEQUEUE_THIS (&(satIntIo->satIntIoLink));
1539 SMLIST_ENQUEUE_AT_TAIL (&(satIntIo->satIntIoLink), &(satDevData->satFreeIntIoLinkList));
1540 tdsmSingleThreadedLeave(smRoot, SM_INTERNAL_IO_LOCK);
1541
1542 return;
1543 }
1544 //start here
1545 osGLOBAL smSatInternalIo_t *
smsatAllocIntIoResource(smRoot_t * smRoot,smIORequest_t * smIORequest,smDeviceData_t * satDevData,bit32 dmaAllocLength,smSatInternalIo_t * satIntIo)1546 smsatAllocIntIoResource(
1547 smRoot_t *smRoot,
1548 smIORequest_t *smIORequest,
1549 smDeviceData_t *satDevData,
1550 bit32 dmaAllocLength,
1551 smSatInternalIo_t *satIntIo)
1552 {
1553 smList_t *smList = agNULL;
1554 bit32 memAllocStatus;
1555
1556 SM_DBG3(("smsatAllocIntIoResource: start\n"));
1557 SM_DBG3(("smsatAllocIntIoResource: satIntIo %p\n", satIntIo));
1558 if (satDevData == agNULL)
1559 {
1560 SM_DBG1(("smsatAllocIntIoResource: ***** ASSERT satDevData is null!!!\n"));
1561 return agNULL;
1562 }
1563
1564 tdsmSingleThreadedEnter(smRoot, SM_INTERNAL_IO_LOCK);
1565 if (!SMLIST_EMPTY(&(satDevData->satFreeIntIoLinkList)))
1566 {
1567 SMLIST_DEQUEUE_FROM_HEAD(&smList, &(satDevData->satFreeIntIoLinkList));
1568 }
1569 else
1570 {
1571 tdsmSingleThreadedLeave(smRoot, SM_INTERNAL_IO_LOCK);
1572 SM_DBG1(("smsatAllocIntIoResource() no more internal free link!!!\n"));
1573 return agNULL;
1574 }
1575
1576 if (smList == agNULL)
1577 {
1578 tdsmSingleThreadedLeave(smRoot, SM_INTERNAL_IO_LOCK);
1579 SM_DBG1(("smsatAllocIntIoResource() FAIL to alloc satIntIo!!!\n"));
1580 return agNULL;
1581 }
1582
1583 satIntIo = SMLIST_OBJECT_BASE( smSatInternalIo_t, satIntIoLink, smList);
1584 SM_DBG3(("smsatAllocIntIoResource: satDevData %p satIntIo id %d\n", satDevData, satIntIo->id));
1585
1586 /* Put in active list */
1587 SMLIST_DEQUEUE_THIS (&(satIntIo->satIntIoLink));
1588 SMLIST_ENQUEUE_AT_TAIL (&(satIntIo->satIntIoLink), &(satDevData->satActiveIntIoLinkList));
1589 tdsmSingleThreadedLeave(smRoot, SM_INTERNAL_IO_LOCK);
1590
1591 #ifdef REMOVED
1592 /* Put in active list */
1593 tdsmSingleThreadedEnter(smRoot, SM_INTERNAL_IO_LOCK);
1594 SMLIST_DEQUEUE_THIS (smList);
1595 SMLIST_ENQUEUE_AT_TAIL (smList, &(satDevData->satActiveIntIoLinkList));
1596 tdsmSingleThreadedLeave(smRoot, SM_INTERNAL_IO_LOCK);
1597
1598 satIntIo = SMLIST_OBJECT_BASE( smSatInternalIo_t, satIntIoLink, smList);
1599 SM_DBG3(("smsatAllocIntIoResource: satDevData %p satIntIo id %d\n", satDevData, satIntIo->id));
1600 #endif
1601
1602 /*
1603 typedef struct
1604 {
1605 tdList_t satIntIoLink;
1606 smIORequest_t satIntSmIORequest;
1607 void *satIntRequestBody;
1608 smScsiInitiatorRequest_t satIntSmScsiXchg;
1609 smMem_t satIntDmaMem;
1610 smMem_t satIntReqBodyMem;
1611 bit32 satIntFlag;
1612 } smSatInternalIo_t;
1613 */
1614
1615 /*
1616 * Allocate mem for Request Body
1617 */
1618 satIntIo->satIntReqBodyMem.totalLength = sizeof(smIORequestBody_t);
1619
1620 memAllocStatus = tdsmAllocMemory( smRoot,
1621 &satIntIo->satIntReqBodyMem.osHandle,
1622 (void **)&satIntIo->satIntRequestBody,
1623 &satIntIo->satIntReqBodyMem.physAddrUpper,
1624 &satIntIo->satIntReqBodyMem.physAddrLower,
1625 8,
1626 satIntIo->satIntReqBodyMem.totalLength,
1627 agTRUE );
1628
1629 if (memAllocStatus != SM_RC_SUCCESS)
1630 {
1631 SM_DBG1(("smsatAllocIntIoResource() FAIL to alloc mem for Req Body!!!\n"));
1632 /*
1633 * Return satIntIo to the free list
1634 */
1635 tdsmSingleThreadedEnter(smRoot, SM_INTERNAL_IO_LOCK);
1636 SMLIST_DEQUEUE_THIS (&satIntIo->satIntIoLink);
1637 SMLIST_ENQUEUE_AT_HEAD(&satIntIo->satIntIoLink, &satDevData->satFreeIntIoLinkList);
1638 tdsmSingleThreadedLeave(smRoot, SM_INTERNAL_IO_LOCK);
1639
1640 return agNULL;
1641 }
1642
1643 /*
1644 * Allocate DMA memory if required
1645 */
1646 if (dmaAllocLength != 0)
1647 {
1648 satIntIo->satIntDmaMem.totalLength = dmaAllocLength;
1649
1650 memAllocStatus = tdsmAllocMemory( smRoot,
1651 &satIntIo->satIntDmaMem.osHandle,
1652 (void **)&satIntIo->satIntDmaMem.virtPtr,
1653 &satIntIo->satIntDmaMem.physAddrUpper,
1654 &satIntIo->satIntDmaMem.physAddrLower,
1655 8,
1656 satIntIo->satIntDmaMem.totalLength,
1657 agFALSE);
1658 SM_DBG3(("smsatAllocIntIoResource: len %d \n", satIntIo->satIntDmaMem.totalLength));
1659 SM_DBG3(("smsatAllocIntIoResource: pointer %p \n", satIntIo->satIntDmaMem.osHandle));
1660
1661 if (memAllocStatus != SM_RC_SUCCESS)
1662 {
1663 SM_DBG1(("smsatAllocIntIoResource() FAIL to alloc mem for DMA mem!!!\n"));
1664 /*
1665 * Return satIntIo to the free list
1666 */
1667 tdsmSingleThreadedEnter(smRoot, SM_INTERNAL_IO_LOCK);
1668 SMLIST_DEQUEUE_THIS (&satIntIo->satIntIoLink);
1669 SMLIST_ENQUEUE_AT_HEAD(&satIntIo->satIntIoLink, &satDevData->satFreeIntIoLinkList);
1670 tdsmSingleThreadedLeave(smRoot, SM_INTERNAL_IO_LOCK);
1671
1672 /*
1673 * Free mem allocated for Req body
1674 */
1675 tdsmFreeMemory( smRoot,
1676 satIntIo->satIntReqBodyMem.osHandle,
1677 satIntIo->satIntReqBodyMem.totalLength);
1678
1679 return agNULL;
1680 }
1681 }
1682
1683 /*
1684 typedef struct
1685 {
1686 smList_t satIntIoLink;
1687 smIORequest_t satIntSmIORequest;
1688 void *satIntRequestBody;
1689 smScsiInitiatorRequest_t satIntSmScsiXchg;
1690 smMem_t satIntDmaMem;
1691 smMem_t satIntReqBodyMem;
1692 bit32 satIntFlag;
1693 } smSatInternalIo_t;
1694 */
1695
1696 /*
1697 * Initialize satIntSmIORequest field
1698 */
1699 satIntIo->satIntSmIORequest.tdData = agNULL; /* Not used for internal SAT I/O */
1700 satIntIo->satIntSmIORequest.smData = satIntIo->satIntRequestBody;
1701
1702 /*
1703 * saves the original smIOrequest
1704 */
1705 satIntIo->satOrgSmIORequest = smIORequest;
1706 /*
1707 typedef struct tiIniScsiCmnd
1708 {
1709 tiLUN_t lun;
1710 bit32 expDataLength;
1711 bit32 taskAttribute;
1712 bit32 crn;
1713 bit8 cdb[16];
1714 } tiIniScsiCmnd_t;
1715
1716 typedef struct tiScsiInitiatorExchange
1717 {
1718 void *sglVirtualAddr;
1719 tiIniScsiCmnd_t scsiCmnd;
1720 tiSgl_t agSgl1;
1721 tiSgl_t agSgl2;
1722 tiDataDirection_t dataDirection;
1723 } tiScsiInitiatorRequest_t;
1724
1725 */
1726
1727 /*
1728 * Initialize satIntSmScsiXchg. Since the internal SAT request is NOT
1729 * originated from SCSI request, only the following fields are initialized:
1730 * - sglVirtualAddr if DMA transfer is involved
1731 * - agSgl1 if DMA transfer is involved
1732 * - expDataLength in scsiCmnd since this field is read by smsataLLIOStart()
1733 */
1734 if (dmaAllocLength != 0)
1735 {
1736 satIntIo->satIntSmScsiXchg.sglVirtualAddr = satIntIo->satIntDmaMem.virtPtr;
1737
1738 OSSA_WRITE_LE_32(agNULL, &satIntIo->satIntSmScsiXchg.smSgl1.len, 0,
1739 satIntIo->satIntDmaMem.totalLength);
1740 satIntIo->satIntSmScsiXchg.smSgl1.lower = satIntIo->satIntDmaMem.physAddrLower;
1741 satIntIo->satIntSmScsiXchg.smSgl1.upper = satIntIo->satIntDmaMem.physAddrUpper;
1742 satIntIo->satIntSmScsiXchg.smSgl1.type = tiSgl;
1743
1744 satIntIo->satIntSmScsiXchg.scsiCmnd.expDataLength = satIntIo->satIntDmaMem.totalLength;
1745 }
1746 else
1747 {
1748 satIntIo->satIntSmScsiXchg.sglVirtualAddr = agNULL;
1749
1750 satIntIo->satIntSmScsiXchg.smSgl1.len = 0;
1751 satIntIo->satIntSmScsiXchg.smSgl1.lower = 0;
1752 satIntIo->satIntSmScsiXchg.smSgl1.upper = 0;
1753 satIntIo->satIntSmScsiXchg.smSgl1.type = tiSgl;
1754
1755 satIntIo->satIntSmScsiXchg.scsiCmnd.expDataLength = 0;
1756 }
1757
1758 SM_DBG5(("smsatAllocIntIoResource: satIntIo->satIntSmScsiXchg.agSgl1.len %d\n", satIntIo->satIntSmScsiXchg.smSgl1.len));
1759
1760 SM_DBG5(("smsatAllocIntIoResource: satIntIo->satIntSmScsiXchg.agSgl1.upper %d\n", satIntIo->satIntSmScsiXchg.smSgl1.upper));
1761
1762 SM_DBG5(("smsatAllocIntIoResource: satIntIo->satIntSmScsiXchg.agSgl1.lower %d\n", satIntIo->satIntSmScsiXchg.smSgl1.lower));
1763
1764 SM_DBG5(("smsatAllocIntIoResource: satIntIo->satIntSmScsiXchg.agSgl1.type %d\n", satIntIo->satIntSmScsiXchg.smSgl1.type));
1765 SM_DBG5(("smsatAllocIntIoResource: return satIntIo %p\n", satIntIo));
1766 return satIntIo;
1767 }
1768
1769 osGLOBAL smDeviceData_t *
smAddToSharedcontext(smRoot_t * smRoot,agsaDevHandle_t * agDevHandle,smDeviceHandle_t * smDeviceHandle,agsaDevHandle_t * agExpDevHandle,bit32 phyID)1770 smAddToSharedcontext(
1771 smRoot_t *smRoot,
1772 agsaDevHandle_t *agDevHandle,
1773 smDeviceHandle_t *smDeviceHandle,
1774 agsaDevHandle_t *agExpDevHandle,
1775 bit32 phyID
1776 )
1777 {
1778 smIntRoot_t *smIntRoot = (smIntRoot_t *)smRoot->smData;
1779 smIntContext_t *smAllShared = (smIntContext_t *)&smIntRoot->smAllShared;
1780 smDeviceData_t *oneDeviceData = agNULL;
1781 smList_t *DeviceListList;
1782 bit32 new_device = agTRUE;
1783
1784 SM_DBG2(("smAddToSharedcontext: start\n"));
1785
1786 /* find a device's existence */
1787 DeviceListList = smAllShared->MainDeviceList.flink;
1788 while (DeviceListList != &(smAllShared->MainDeviceList))
1789 {
1790 oneDeviceData = SMLIST_OBJECT_BASE(smDeviceData_t, MainLink, DeviceListList);
1791 if (oneDeviceData == agNULL)
1792 {
1793 SM_DBG1(("smAddToSharedcontext: oneDeviceData is NULL!!!\n"));
1794 return agNULL;
1795 }
1796 if (oneDeviceData->agDevHandle == agDevHandle)
1797 {
1798 SM_DBG2(("smAddToSharedcontext: did %d\n", oneDeviceData->id));
1799 new_device = agFALSE;
1800 break;
1801 }
1802 DeviceListList = DeviceListList->flink;
1803 }
1804
1805 /* new device */
1806 if (new_device == agTRUE)
1807 {
1808 SM_DBG2(("smAddToSharedcontext: new device\n"));
1809 tdsmSingleThreadedEnter(smRoot, SM_DEVICE_LOCK);
1810 if (SMLIST_EMPTY(&(smAllShared->FreeDeviceList)))
1811 {
1812 tdsmSingleThreadedLeave(smRoot, SM_DEVICE_LOCK);
1813 SM_DBG1(("smAddToSharedcontext: empty DeviceData FreeLink!!!\n"));
1814 smDeviceHandle->smData = agNULL;
1815 return agNULL;
1816 }
1817
1818 SMLIST_DEQUEUE_FROM_HEAD(&DeviceListList, &(smAllShared->FreeDeviceList));
1819 tdsmSingleThreadedLeave(smRoot, SM_DEVICE_LOCK);
1820 oneDeviceData = SMLIST_OBJECT_BASE(smDeviceData_t, FreeLink, DeviceListList);
1821 oneDeviceData->smRoot = smRoot;
1822 oneDeviceData->agDevHandle = agDevHandle;
1823 oneDeviceData->valid = agTRUE;
1824 smDeviceHandle->smData = oneDeviceData;
1825 oneDeviceData->smDevHandle = smDeviceHandle;
1826 if (agExpDevHandle == agNULL)
1827 {
1828 oneDeviceData->directlyAttached = agTRUE;
1829 }
1830 else
1831 {
1832 oneDeviceData->directlyAttached = agFALSE;
1833 }
1834 oneDeviceData->agExpDevHandle = agExpDevHandle;
1835 oneDeviceData->phyID = phyID;
1836 oneDeviceData->satPendingIO = 0;
1837 oneDeviceData->satPendingNCQIO = 0;
1838 oneDeviceData->satPendingNONNCQIO = 0;
1839 /* add the devicedata to the portcontext */
1840 tdsmSingleThreadedEnter(smRoot, SM_DEVICE_LOCK);
1841 SMLIST_ENQUEUE_AT_TAIL(&(oneDeviceData->MainLink), &(smAllShared->MainDeviceList));
1842 tdsmSingleThreadedLeave(smRoot, SM_DEVICE_LOCK);
1843 SM_DBG2(("smAddToSharedcontext: new case did %d\n", oneDeviceData->id));
1844 }
1845 else
1846 {
1847 SM_DBG2(("smAddToSharedcontext: old device\n"));
1848 oneDeviceData->smRoot = smRoot;
1849 oneDeviceData->agDevHandle = agDevHandle;
1850 oneDeviceData->valid = agTRUE;
1851 smDeviceHandle->smData = oneDeviceData;
1852 oneDeviceData->smDevHandle = smDeviceHandle;
1853 if (agExpDevHandle == agNULL)
1854 {
1855 oneDeviceData->directlyAttached = agTRUE;
1856 }
1857 else
1858 {
1859 oneDeviceData->directlyAttached = agFALSE;
1860 }
1861 oneDeviceData->agExpDevHandle = agExpDevHandle;
1862 oneDeviceData->phyID = phyID;
1863 oneDeviceData->satPendingIO = 0;
1864 oneDeviceData->satPendingNCQIO = 0;
1865 oneDeviceData->satPendingNONNCQIO = 0;
1866 SM_DBG2(("smAddToSharedcontext: old case did %d\n", oneDeviceData->id));
1867 }
1868
1869 return oneDeviceData;
1870 }
1871
1872 osGLOBAL bit32
smRemoveFromSharedcontext(smRoot_t * smRoot,agsaDevHandle_t * agDevHandle,smDeviceHandle_t * smDeviceHandle)1873 smRemoveFromSharedcontext(
1874 smRoot_t *smRoot,
1875 agsaDevHandle_t *agDevHandle,
1876 smDeviceHandle_t *smDeviceHandle
1877 )
1878 {
1879 smIntRoot_t *smIntRoot = (smIntRoot_t *)smRoot->smData;
1880 smIntContext_t *smAllShared = (smIntContext_t *)&smIntRoot->smAllShared;
1881 smDeviceData_t *oneDeviceData = agNULL;
1882
1883 SM_DBG2(("smRemoveFromSharedcontext: start\n"));
1884
1885 //due to device all and completion
1886 //smDeviceHandle->smData = agNULL;
1887
1888 /* find oneDeviceData from MainLink */
1889 oneDeviceData = smFindInSharedcontext(smRoot, agDevHandle);
1890
1891 if (oneDeviceData == agNULL)
1892 {
1893 return SM_RC_FAILURE;
1894 }
1895 else
1896 {
1897 if (oneDeviceData->valid == agTRUE)
1898 {
1899 smDeviceDataReInit(smRoot, oneDeviceData);
1900 tdsmSingleThreadedEnter(smRoot, SM_DEVICE_LOCK);
1901 SMLIST_DEQUEUE_THIS(&(oneDeviceData->MainLink));
1902 SMLIST_ENQUEUE_AT_TAIL(&(oneDeviceData->FreeLink), &(smAllShared->FreeDeviceList));
1903 tdsmSingleThreadedLeave(smRoot, SM_DEVICE_LOCK);
1904 return SM_RC_SUCCESS;
1905 }
1906 else
1907 {
1908 SM_DBG1(("smRemoveFromSharedcontext: did %d bad case!!!\n", oneDeviceData->id));
1909 return SM_RC_FAILURE;
1910 }
1911 }
1912
1913 }
1914
1915 osGLOBAL smDeviceData_t *
smFindInSharedcontext(smRoot_t * smRoot,agsaDevHandle_t * agDevHandle)1916 smFindInSharedcontext(
1917 smRoot_t *smRoot,
1918 agsaDevHandle_t *agDevHandle
1919 )
1920 {
1921 smIntRoot_t *smIntRoot = (smIntRoot_t *)smRoot->smData;
1922 smIntContext_t *smAllShared = (smIntContext_t *)&smIntRoot->smAllShared;
1923 smDeviceData_t *oneDeviceData = agNULL;
1924 smList_t *DeviceListList;
1925
1926 SM_DBG2(("smFindInSharedcontext: start\n"));
1927
1928 tdsmSingleThreadedEnter(smRoot, SM_DEVICE_LOCK);
1929 if (SMLIST_EMPTY(&(smAllShared->MainDeviceList)))
1930 {
1931 SM_DBG1(("smFindInSharedcontext: empty MainDeviceList!!!\n"));
1932 tdsmSingleThreadedLeave(smRoot, SM_DEVICE_LOCK);
1933 return agNULL;
1934 }
1935 else
1936 {
1937 tdsmSingleThreadedLeave(smRoot, SM_DEVICE_LOCK);
1938 }
1939
1940 DeviceListList = smAllShared->MainDeviceList.flink;
1941 while (DeviceListList != &(smAllShared->MainDeviceList))
1942 {
1943 oneDeviceData = SMLIST_OBJECT_BASE(smDeviceData_t, MainLink, DeviceListList);
1944 if (oneDeviceData == agNULL)
1945 {
1946 SM_DBG1(("smFindInSharedcontext: oneDeviceData is NULL!!!\n"));
1947 return agNULL;
1948 }
1949 if ((oneDeviceData->agDevHandle == agDevHandle) &&
1950 (oneDeviceData->valid == agTRUE)
1951 )
1952 {
1953 SM_DBG2(("smFindInSharedcontext: found, did %d\n", oneDeviceData->id));
1954 return oneDeviceData;
1955 }
1956 DeviceListList = DeviceListList->flink;
1957 }
1958 SM_DBG2(("smFindInSharedcontext: not found\n"));
1959 return agNULL;
1960 }
1961
1962 osGLOBAL smSatIOContext_t *
smsatPrepareNewIO(smSatInternalIo_t * satNewIntIo,smIORequest_t * smOrgIORequest,smDeviceData_t * satDevData,smIniScsiCmnd_t * scsiCmnd,smSatIOContext_t * satOrgIOContext)1963 smsatPrepareNewIO(
1964 smSatInternalIo_t *satNewIntIo,
1965 smIORequest_t *smOrgIORequest,
1966 smDeviceData_t *satDevData,
1967 smIniScsiCmnd_t *scsiCmnd,
1968 smSatIOContext_t *satOrgIOContext
1969 )
1970 {
1971 smSatIOContext_t *satNewIOContext;
1972 smIORequestBody_t *smNewIORequestBody;
1973
1974 SM_DBG3(("smsatPrepareNewIO: start\n"));
1975
1976 /* the one to be used; good 8/2/07 */
1977 satNewIntIo->satOrgSmIORequest = smOrgIORequest; /* this is already done in
1978 smsatAllocIntIoResource() */
1979
1980 smNewIORequestBody = (smIORequestBody_t *)satNewIntIo->satIntRequestBody;
1981 satNewIOContext = &(smNewIORequestBody->transport.SATA.satIOContext);
1982
1983 satNewIOContext->pSatDevData = satDevData;
1984 satNewIOContext->pFis = &(smNewIORequestBody->transport.SATA.agSATARequestBody.fis.fisRegHostToDev);
1985 satNewIOContext->pScsiCmnd = &(satNewIntIo->satIntSmScsiXchg.scsiCmnd);
1986 if (scsiCmnd != agNULL)
1987 {
1988 /* saves only CBD; not scsi command for LBA and number of blocks */
1989 sm_memcpy(satNewIOContext->pScsiCmnd->cdb, scsiCmnd->cdb, 16);
1990 }
1991 satNewIOContext->pSense = &(smNewIORequestBody->transport.SATA.sensePayload);
1992 satNewIOContext->pSmSenseData = &(smNewIORequestBody->transport.SATA.smSenseData);
1993 satNewIOContext->pSmSenseData->senseData = satNewIOContext->pSense;
1994 satNewIOContext->smRequestBody = satNewIntIo->satIntRequestBody;
1995 satNewIOContext->interruptContext = satNewIOContext->interruptContext;
1996 satNewIOContext->satIntIoContext = satNewIntIo;
1997 satNewIOContext->psmDeviceHandle = satOrgIOContext->psmDeviceHandle;
1998 satNewIOContext->satOrgIOContext = satOrgIOContext;
1999 /* saves tiScsiXchg; only for writesame10() */
2000 satNewIOContext->smScsiXchg = satOrgIOContext->smScsiXchg;
2001
2002 return satNewIOContext;
2003 }
2004
2005
2006 osGLOBAL void
smsatSetDevInfo(smDeviceData_t * oneDeviceData,agsaSATAIdentifyData_t * SATAIdData)2007 smsatSetDevInfo(
2008 smDeviceData_t *oneDeviceData,
2009 agsaSATAIdentifyData_t *SATAIdData
2010 )
2011 {
2012 SM_DBG3(("smsatSetDevInfo: start\n"));
2013
2014 oneDeviceData->satDriveState = SAT_DEV_STATE_NORMAL;
2015 oneDeviceData->satFormatState = agFALSE;
2016 oneDeviceData->satDeviceFaultState = agFALSE;
2017 oneDeviceData->satTmTaskTag = agNULL;
2018 oneDeviceData->satAbortAfterReset = agFALSE;
2019 oneDeviceData->satAbortCalled = agFALSE;
2020 oneDeviceData->satSectorDone = 0;
2021
2022 /* Qeueu depth, Word 75 */
2023 oneDeviceData->satNCQMaxIO = SATAIdData->queueDepth + 1;
2024 SM_DBG3(("smsatSetDevInfo: max queue depth %d\n",oneDeviceData->satNCQMaxIO));
2025
2026 /* Support NCQ, if Word 76 bit 8 is set */
2027 if (SATAIdData->sataCapabilities & 0x100)
2028 {
2029 SM_DBG3(("smsatSetDevInfo: device supports NCQ\n"));
2030 oneDeviceData->satNCQ = agTRUE;
2031 }
2032 else
2033 {
2034 SM_DBG3(("smsatSetDevInfo: no NCQ\n"));
2035 oneDeviceData->satNCQ = agFALSE;
2036 }
2037
2038 /* Support 48 bit addressing, if Word 83 bit 10 and Word 86 bit 10 are set */
2039 if ((SATAIdData->commandSetSupported1 & 0x400) &&
2040 (SATAIdData->commandSetFeatureEnabled1 & 0x400) )
2041 {
2042 SM_DBG3(("smsatSetDevInfo: support 48 bit addressing\n"));
2043 oneDeviceData->sat48BitSupport = agTRUE;
2044 }
2045 else
2046 {
2047 SM_DBG3(("smsatSetDevInfo: NO 48 bit addressing\n"));
2048 oneDeviceData->sat48BitSupport = agFALSE;
2049 }
2050
2051 /* Support SMART Self Test, word84 bit 1 */
2052 if (SATAIdData->commandSetFeatureSupportedExt & 0x02)
2053 {
2054 SM_DBG3(("smsatSetDevInfo: SMART self-test supported \n"));
2055 oneDeviceData->satSMARTSelfTest = agTRUE;
2056 }
2057 else
2058 {
2059 SM_DBG3(("smsatSetDevInfo: no SMART self-test suppored\n"));
2060 oneDeviceData->satSMARTSelfTest = agFALSE;
2061 }
2062
2063 /* Support SMART feature set, word82 bit 0 */
2064 if (SATAIdData->commandSetSupported & 0x01)
2065 {
2066 SM_DBG3(("smsatSetDevInfo: SMART feature set supported \n"));
2067 oneDeviceData->satSMARTFeatureSet = agTRUE;
2068 }
2069 else
2070 {
2071 SM_DBG3(("smsatSetDevInfo: no SMART feature set suppored\n"));
2072 oneDeviceData->satSMARTFeatureSet = agFALSE;
2073 }
2074
2075 /* Support SMART enabled, word85 bit 0 */
2076 if (SATAIdData->commandSetFeatureEnabled & 0x01)
2077 {
2078 SM_DBG3(("smsatSetDevInfo: SMART enabled \n"));
2079 oneDeviceData->satSMARTEnabled = agTRUE;
2080 }
2081 else
2082 {
2083 SM_DBG3(("smsatSetDevInfo: no SMART enabled\n"));
2084 oneDeviceData->satSMARTEnabled = agFALSE;
2085 }
2086
2087 oneDeviceData->satVerifyState = 0;
2088
2089 /* Removable Media feature set support, word82 bit 2 */
2090 if (SATAIdData->commandSetSupported & 0x4)
2091 {
2092 SM_DBG3(("smsatSetDevInfo: Removable Media supported \n"));
2093 oneDeviceData->satRemovableMedia = agTRUE;
2094 }
2095 else
2096 {
2097 SM_DBG3(("smsatSetDevInfo: no Removable Media suppored\n"));
2098 oneDeviceData->satRemovableMedia = agFALSE;
2099 }
2100
2101 /* Removable Media feature set enabled, word 85, bit 2 */
2102 if (SATAIdData->commandSetFeatureEnabled & 0x4)
2103 {
2104 SM_DBG3(("smsatSetDevInfo: Removable Media enabled\n"));
2105 oneDeviceData->satRemovableMediaEnabled = agTRUE;
2106 }
2107 else
2108 {
2109 SM_DBG3(("smsatSetDevInfo: no Removable Media enabled\n"));
2110 oneDeviceData->satRemovableMediaEnabled = agFALSE;
2111 }
2112
2113 /* DMA Support, word49 bit8 */
2114 if (SATAIdData->dma_lba_iod_ios_stimer & 0x100)
2115 {
2116 SM_DBG3(("smsatSetDevInfo: DMA supported \n"));
2117 oneDeviceData->satDMASupport = agTRUE;
2118 }
2119 else
2120 {
2121 SM_DBG3(("smsatSetDevInfo: no DMA suppored\n"));
2122 oneDeviceData->satDMASupport = agFALSE;
2123 }
2124
2125 /* Support DMADIR, if Word 62 bit 8 is set */
2126 if (SATAIdData->word62_74[0] & 0x8000)
2127 {
2128 SM_DBG3(("satSetDevInfo: DMADIR enabled\n"));
2129 oneDeviceData->satDMADIRSupport = agTRUE;
2130 }
2131 else
2132 {
2133 SM_DBG3(("satSetDevInfo: DMADIR disabled\n"));
2134 oneDeviceData->satDMADIRSupport = agFALSE;
2135 }
2136
2137 /* DMA Enabled, word88 bit0-6, bit8-14*/
2138 /* 0x7F7F = 0111 1111 0111 1111*/
2139 if (SATAIdData->ultraDMAModes & 0x7F7F)
2140 {
2141 SM_DBG3(("smsatSetDevInfo: DMA enabled \n"));
2142 oneDeviceData->satDMAEnabled = agTRUE;
2143 if (SATAIdData->ultraDMAModes & 0x40)
2144 {
2145 oneDeviceData->satUltraDMAMode = 6;
2146 }
2147 else if (SATAIdData->ultraDMAModes & 0x20)
2148 {
2149 oneDeviceData->satUltraDMAMode = 5;
2150 }
2151 else if (SATAIdData->ultraDMAModes & 0x10)
2152 {
2153 oneDeviceData->satUltraDMAMode = 4;
2154 }
2155 else if (SATAIdData->ultraDMAModes & 0x08)
2156 {
2157 oneDeviceData->satUltraDMAMode = 3;
2158 }
2159 else if (SATAIdData->ultraDMAModes & 0x04)
2160 {
2161 oneDeviceData->satUltraDMAMode = 2;
2162 }
2163 else if (SATAIdData->ultraDMAModes & 0x01)
2164 {
2165 oneDeviceData->satUltraDMAMode = 1;
2166 }
2167 }
2168 else
2169 {
2170 SM_DBG3(("smsatSetDevInfo: no DMA enabled\n"));
2171 oneDeviceData->satDMAEnabled = agFALSE;
2172 oneDeviceData->satUltraDMAMode = 0;
2173 }
2174
2175 /*
2176 setting MaxUserAddrSectors: max user addressable setctors
2177 word60 - 61, should be 0x 0F FF FF FF
2178 */
2179 oneDeviceData->satMaxUserAddrSectors
2180 = (SATAIdData->numOfUserAddressableSectorsHi << (8*2) )
2181 + SATAIdData->numOfUserAddressableSectorsLo;
2182 SM_DBG3(("smsatSetDevInfo: MaxUserAddrSectors 0x%x decimal %d\n", oneDeviceData->satMaxUserAddrSectors, oneDeviceData->satMaxUserAddrSectors));
2183
2184 /* Read Look-ahead is supported */
2185 if (SATAIdData->commandSetSupported & 0x40)
2186 {
2187 SM_DBG3(("smsatSetDevInfo: Read Look-ahead is supported\n"));
2188 oneDeviceData->satReadLookAheadSupport= agTRUE;
2189 }
2190 else
2191 {
2192 SM_DBG3(("smsatSetDevInfo: Read Look-ahead is not supported\n"));
2193 oneDeviceData->satReadLookAheadSupport= agFALSE;
2194 }
2195
2196 /* Volatile Write Cache is supported */
2197 if (SATAIdData->commandSetSupported & 0x20)
2198 {
2199 SM_DBG3(("smsatSetDevInfo: Volatile Write Cache is supported\n"));
2200 oneDeviceData->satVolatileWriteCacheSupport = agTRUE;
2201 }
2202 else
2203 {
2204 SM_DBG3(("smsatSetDevInfo: Volatile Write Cache is not supported\n"));
2205 oneDeviceData->satVolatileWriteCacheSupport = agFALSE;
2206 }
2207
2208 /* write cache enabled for caching mode page SAT Table 67 p69, word85 bit5 */
2209 if (SATAIdData->commandSetFeatureEnabled & 0x20)
2210 {
2211 SM_DBG3(("smsatSetDevInfo: write cache enabled\n"));
2212 oneDeviceData->satWriteCacheEnabled = agTRUE;
2213 }
2214 else
2215 {
2216 SM_DBG3(("smsatSetDevInfo: no write cache enabled\n"));
2217 oneDeviceData->satWriteCacheEnabled = agFALSE;
2218 }
2219
2220 /* look ahead enabled for caching mode page SAT Table 67 p69, word85 bit6 */
2221 if (SATAIdData->commandSetFeatureEnabled & 0x40)
2222 {
2223 SM_DBG3(("smsatSetDevInfo: look ahead enabled\n"));
2224 oneDeviceData->satLookAheadEnabled = agTRUE;
2225 }
2226 else
2227 {
2228 SM_DBG3(("smsatSetDevInfo: no look ahead enabled\n"));
2229 oneDeviceData->satLookAheadEnabled = agFALSE;
2230 }
2231
2232 /* Support WWN, if Word 87 bit 8 is set */
2233 if (SATAIdData->commandSetFeatureDefault & 0x100)
2234 {
2235 SM_DBG3(("smsatSetDevInfo: device supports WWN\n"));
2236 oneDeviceData->satWWNSupport = agTRUE;
2237 }
2238 else
2239 {
2240 SM_DBG3(("smsatSetDevInfo: no WWN\n"));
2241 oneDeviceData->satWWNSupport = agFALSE;
2242 }
2243
2244 /* Support DMA Setup Auto-Activate, if Word 78 bit 2 is set */
2245 if (SATAIdData->sataFeaturesSupported & 0x4)
2246 {
2247 SM_DBG3(("smsatSetDevInfo: device supports DMA Setup Auto-Activate\n"));
2248 oneDeviceData->satDMASetupAA = agTRUE;
2249 }
2250 else
2251 {
2252 SM_DBG3(("smsatSetDevInfo: no DMA Setup Auto-Activate\n"));
2253 oneDeviceData->satDMASetupAA = agFALSE;
2254 }
2255
2256 /* Support NCQ Queue Management Command, if Word 77 bit 5 is set */
2257 if (SATAIdData->word77 & 0x10)
2258 {
2259 SM_DBG3(("smsatSetDevInfo: device supports NCQ Queue Management Command\n"));
2260 oneDeviceData->satNCQQMgntCmd = agTRUE;
2261 }
2262 else
2263 {
2264 SM_DBG3(("smsatSetDevInfo: no NCQ Queue Management Command\n"));
2265 oneDeviceData->satNCQQMgntCmd = agFALSE;
2266 }
2267 return;
2268 }
2269
2270
2271 osGLOBAL void
smsatInquiryStandard(bit8 * pInquiry,agsaSATAIdentifyData_t * pSATAIdData,smIniScsiCmnd_t * scsiCmnd)2272 smsatInquiryStandard(
2273 bit8 *pInquiry,
2274 agsaSATAIdentifyData_t *pSATAIdData,
2275 smIniScsiCmnd_t *scsiCmnd
2276 )
2277 {
2278 smLUN_t *pLun;
2279 pLun = &scsiCmnd->lun;
2280
2281 /*
2282 Assumption: Basic Task Mangement is supported
2283 -> BQUE 1 and CMDQUE 0, SPC-4, Table96, p147
2284 */
2285 /*
2286 See SPC-4, 6.4.2, p 143
2287 and SAT revision 8, 8.1.2, p 28
2288 */
2289 SM_DBG5(("smsatInquiryStandard: start\n"));
2290
2291 if (pInquiry == agNULL)
2292 {
2293 SM_DBG1(("smsatInquiryStandard: pInquiry is NULL, wrong\n"));
2294 return;
2295 }
2296 else
2297 {
2298 SM_DBG5(("smsatInquiryStandard: pInquiry is NOT NULL\n"));
2299 }
2300 /*
2301 * Reject all other LUN other than LUN 0.
2302 */
2303 if ( ((pLun->lun[0] | pLun->lun[1] | pLun->lun[2] | pLun->lun[3] |
2304 pLun->lun[4] | pLun->lun[5] | pLun->lun[6] | pLun->lun[7] ) != 0) )
2305 {
2306 /* SAT Spec Table 8, p27, footnote 'a' */
2307 pInquiry[0] = 0x7F;
2308
2309 }
2310 else
2311 {
2312 pInquiry[0] = 0x00;
2313 }
2314
2315 if (pSATAIdData->rm_ataDevice & ATA_REMOVABLE_MEDIA_DEVICE_MASK )
2316 {
2317 pInquiry[1] = 0x80;
2318 }
2319 else
2320 {
2321 pInquiry[1] = 0x00;
2322 }
2323 pInquiry[2] = 0x05; /* SPC-3 */
2324 pInquiry[3] = 0x12; /* set HiSup 1; resp data format set to 2 */
2325 pInquiry[4] = 0x1F; /* 35 - 4 = 31; Additional length */
2326 pInquiry[5] = 0x00;
2327 /* The following two are for task management. SAT Rev8, p20 */
2328 if (pSATAIdData->sataCapabilities & 0x100)
2329 {
2330 /* NCQ supported; multiple outstanding SCSI IO are supported */
2331 pInquiry[6] = 0x00; /* BQUE bit is not set */
2332 pInquiry[7] = 0x02; /* CMDQUE bit is set */
2333 }
2334 else
2335 {
2336 pInquiry[6] = 0x80; /* BQUE bit is set */
2337 pInquiry[7] = 0x00; /* CMDQUE bit is not set */
2338 }
2339 /*
2340 * Vendor ID.
2341 */
2342 sm_strncpy((char*)&pInquiry[8], AG_SAT_VENDOR_ID_STRING, 8); /* 8 bytes */
2343
2344 /*
2345 * Product ID
2346 */
2347 /* when flipped by LL */
2348 pInquiry[16] = pSATAIdData->modelNumber[1];
2349 pInquiry[17] = pSATAIdData->modelNumber[0];
2350 pInquiry[18] = pSATAIdData->modelNumber[3];
2351 pInquiry[19] = pSATAIdData->modelNumber[2];
2352 pInquiry[20] = pSATAIdData->modelNumber[5];
2353 pInquiry[21] = pSATAIdData->modelNumber[4];
2354 pInquiry[22] = pSATAIdData->modelNumber[7];
2355 pInquiry[23] = pSATAIdData->modelNumber[6];
2356 pInquiry[24] = pSATAIdData->modelNumber[9];
2357 pInquiry[25] = pSATAIdData->modelNumber[8];
2358 pInquiry[26] = pSATAIdData->modelNumber[11];
2359 pInquiry[27] = pSATAIdData->modelNumber[10];
2360 pInquiry[28] = pSATAIdData->modelNumber[13];
2361 pInquiry[29] = pSATAIdData->modelNumber[12];
2362 pInquiry[30] = pSATAIdData->modelNumber[15];
2363 pInquiry[31] = pSATAIdData->modelNumber[14];
2364
2365 /* when flipped */
2366 /*
2367 * Product Revision level.
2368 */
2369
2370 /*
2371 * If the IDENTIFY DEVICE data received in words 25 and 26 from the ATA
2372 * device are ASCII spaces (20h), do this translation.
2373 */
2374 if ( (pSATAIdData->firmwareVersion[4] == 0x20 ) &&
2375 (pSATAIdData->firmwareVersion[5] == 0x20 ) &&
2376 (pSATAIdData->firmwareVersion[6] == 0x20 ) &&
2377 (pSATAIdData->firmwareVersion[7] == 0x20 )
2378 )
2379 {
2380 pInquiry[32] = pSATAIdData->firmwareVersion[1];
2381 pInquiry[33] = pSATAIdData->firmwareVersion[0];
2382 pInquiry[34] = pSATAIdData->firmwareVersion[3];
2383 pInquiry[35] = pSATAIdData->firmwareVersion[2];
2384 }
2385 else
2386 {
2387 pInquiry[32] = pSATAIdData->firmwareVersion[5];
2388 pInquiry[33] = pSATAIdData->firmwareVersion[4];
2389 pInquiry[34] = pSATAIdData->firmwareVersion[7];
2390 pInquiry[35] = pSATAIdData->firmwareVersion[6];
2391 }
2392
2393
2394 #ifdef REMOVED
2395 /*
2396 * Product ID
2397 */
2398 /* when flipped by LL */
2399 pInquiry[16] = pSATAIdData->modelNumber[0];
2400 pInquiry[17] = pSATAIdData->modelNumber[1];
2401 pInquiry[18] = pSATAIdData->modelNumber[2];
2402 pInquiry[19] = pSATAIdData->modelNumber[3];
2403 pInquiry[20] = pSATAIdData->modelNumber[4];
2404 pInquiry[21] = pSATAIdData->modelNumber[5];
2405 pInquiry[22] = pSATAIdData->modelNumber[6];
2406 pInquiry[23] = pSATAIdData->modelNumber[7];
2407 pInquiry[24] = pSATAIdData->modelNumber[8];
2408 pInquiry[25] = pSATAIdData->modelNumber[9];
2409 pInquiry[26] = pSATAIdData->modelNumber[10];
2410 pInquiry[27] = pSATAIdData->modelNumber[11];
2411 pInquiry[28] = pSATAIdData->modelNumber[12];
2412 pInquiry[29] = pSATAIdData->modelNumber[13];
2413 pInquiry[30] = pSATAIdData->modelNumber[14];
2414 pInquiry[31] = pSATAIdData->modelNumber[15];
2415
2416 /* when flipped */
2417 /*
2418 * Product Revision level.
2419 */
2420
2421 /*
2422 * If the IDENTIFY DEVICE data received in words 25 and 26 from the ATA
2423 * device are ASCII spaces (20h), do this translation.
2424 */
2425 if ( (pSATAIdData->firmwareVersion[4] == 0x20 ) &&
2426 (pSATAIdData->firmwareVersion[5] == 0x20 ) &&
2427 (pSATAIdData->firmwareVersion[6] == 0x20 ) &&
2428 (pSATAIdData->firmwareVersion[7] == 0x20 )
2429 )
2430 {
2431 pInquiry[32] = pSATAIdData->firmwareVersion[0];
2432 pInquiry[33] = pSATAIdData->firmwareVersion[1];
2433 pInquiry[34] = pSATAIdData->firmwareVersion[2];
2434 pInquiry[35] = pSATAIdData->firmwareVersion[3];
2435 }
2436 else
2437 {
2438 pInquiry[32] = pSATAIdData->firmwareVersion[4];
2439 pInquiry[33] = pSATAIdData->firmwareVersion[5];
2440 pInquiry[34] = pSATAIdData->firmwareVersion[6];
2441 pInquiry[35] = pSATAIdData->firmwareVersion[7];
2442 }
2443 #endif
2444
2445 SM_DBG5(("smsatInquiryStandard: end\n"));
2446
2447 return;
2448 }
2449
2450 osGLOBAL void
smsatInquiryPage0(bit8 * pInquiry,agsaSATAIdentifyData_t * pSATAIdData)2451 smsatInquiryPage0(
2452 bit8 *pInquiry,
2453 agsaSATAIdentifyData_t *pSATAIdData
2454 )
2455 {
2456 SM_DBG5(("smsatInquiryPage0: start\n"));
2457
2458 /*
2459 See SPC-4, 7.6.9, p 345
2460 and SAT revision 8, 10.3.2, p 77
2461 */
2462 pInquiry[0] = 0x00;
2463 pInquiry[1] = 0x00; /* page code */
2464 pInquiry[2] = 0x00; /* reserved */
2465 pInquiry[3] = 8 - 3; /* last index(in this case, 6) - 3; page length */
2466
2467 /* supported vpd page list */
2468 pInquiry[4] = 0x00; /* page 0x00 supported */
2469 pInquiry[5] = 0x80; /* page 0x80 supported */
2470 pInquiry[6] = 0x83; /* page 0x83 supported */
2471 pInquiry[7] = 0x89; /* page 0x89 supported */
2472 pInquiry[8] = 0xB1; /* page 0xB1 supported */
2473
2474 return;
2475 }
2476
2477 osGLOBAL void
smsatInquiryPage83(bit8 * pInquiry,agsaSATAIdentifyData_t * pSATAIdData,smDeviceData_t * oneDeviceData)2478 smsatInquiryPage83(
2479 bit8 *pInquiry,
2480 agsaSATAIdentifyData_t *pSATAIdData,
2481 smDeviceData_t *oneDeviceData
2482 )
2483 {
2484 satSimpleSATAIdentifyData_t *pSimpleData;
2485
2486 /*
2487 * When translating the fields, in some cases using the simple form of SATA
2488 * Identify Device Data is easier. So we define it here.
2489 * Both pSimpleData and pSATAIdData points to the same data.
2490 */
2491 pSimpleData = ( satSimpleSATAIdentifyData_t *)pSATAIdData;
2492
2493 SM_DBG5(("smsatInquiryPage83: start\n"));
2494
2495 pInquiry[0] = 0x00;
2496 pInquiry[1] = 0x83; /* page code */
2497 pInquiry[2] = 0; /* Reserved */
2498 /*
2499 * If the ATA device returns word 87 bit 8 set to one in its IDENTIFY DEVICE
2500 * data indicating that it supports the WORLD WIDE NAME field
2501 * (i.e., words 108-111), the SATL shall include an identification descriptor
2502 * containing a logical unit name.
2503 */
2504 if ( oneDeviceData->satWWNSupport)
2505 {
2506 #ifndef PMC_FREEBSD
2507 /* Fill in SAT Rev8 Table85 */
2508 /*
2509 * Logical unit name derived from the world wide name.
2510 */
2511 pInquiry[3] = 12; /* 15-3; page length, no addition ID descriptor assumed*/
2512
2513 /*
2514 * Identifier descriptor
2515 */
2516 pInquiry[4] = 0x01; /* Code set: binary codes */
2517 pInquiry[5] = 0x03; /* Identifier type : NAA */
2518 pInquiry[6] = 0x00; /* Reserved */
2519 pInquiry[7] = 0x08; /* Identifier length */
2520
2521 /* Bit 4-7 NAA field, bit 0-3 MSB of IEEE Company ID */
2522 pInquiry[8] = (bit8)((pSATAIdData->namingAuthority) >> 8);
2523 pInquiry[9] = (bit8)((pSATAIdData->namingAuthority) & 0xFF); /* IEEE Company ID */
2524 pInquiry[10] = (bit8)((pSATAIdData->namingAuthority1) >> 8); /* IEEE Company ID */
2525 /* Bit 4-7 LSB of IEEE Company ID, bit 0-3 MSB of Vendor Specific ID */
2526 pInquiry[11] = (bit8)((pSATAIdData->namingAuthority1) & 0xFF);
2527 pInquiry[12] = (bit8)((pSATAIdData->uniqueID_bit16_31) >> 8); /* Vendor Specific ID */
2528 pInquiry[13] = (bit8)((pSATAIdData->uniqueID_bit16_31) & 0xFF); /* Vendor Specific ID */
2529 pInquiry[14] = (bit8)((pSATAIdData->uniqueID_bit0_15) >> 8); /* Vendor Specific ID */
2530 pInquiry[15] = (bit8)((pSATAIdData->uniqueID_bit0_15) & 0xFF); /* Vendor Specific ID */
2531
2532 #else
2533
2534 /* For FreeBSD */
2535
2536 /* Fill in SAT Rev8 Table85 */
2537 /*
2538 * Logical unit name derived from the world wide name.
2539 */
2540 pInquiry[3] = 24; /* 35-3; page length, no addition ID descriptor assumed*/
2541 /*
2542 * Identifier descriptor
2543 */
2544 pInquiry[4] = 0x01; /* Code set: binary codes; this is proto_codeset in FreeBSD */
2545 pInquiry[5] = 0x03; /* Identifier type : NAA ; this is id_type in FreeBSD*/
2546 pInquiry[6] = 0x00; /* Reserved */
2547 pInquiry[7] = 0x08; /* Identifier length */
2548
2549 /* Bit 4-7 NAA field, bit 0-3 MSB of IEEE Company ID */
2550 pInquiry[8] = (bit8)((pSATAIdData->namingAuthority) >> 8);
2551 pInquiry[9] = (bit8)((pSATAIdData->namingAuthority) & 0xFF); /* IEEE Company ID */
2552 pInquiry[10] = (bit8)((pSATAIdData->namingAuthority1) >> 8); /* IEEE Company ID */
2553 /* Bit 4-7 LSB of IEEE Company ID, bit 0-3 MSB of Vendor Specific ID */
2554 pInquiry[11] = (bit8)((pSATAIdData->namingAuthority1) & 0xFF);
2555 pInquiry[12] = (bit8)((pSATAIdData->uniqueID_bit16_31) >> 8); /* Vendor Specific ID */
2556 pInquiry[13] = (bit8)((pSATAIdData->uniqueID_bit16_31) & 0xFF); /* Vendor Specific ID */
2557 pInquiry[14] = (bit8)((pSATAIdData->uniqueID_bit0_15) >> 8); /* Vendor Specific ID */
2558 pInquiry[15] = (bit8)((pSATAIdData->uniqueID_bit0_15) & 0xFF); /* Vendor Specific ID */
2559
2560 pInquiry[16] = 0x61; /* Code set: binary codes; this is proto_codeset in FreeBSD; SCSI_PROTO_SAS and SVPD_ID_CODESET_BINARY */
2561 pInquiry[17] = 0x93; /* Identifier type : NAA ; this is id_type in FreeBSD; PIV set, ASSOCIATION is 01b and NAA (3h) */
2562 pInquiry[18] = 0x00; /* Reserved */
2563 pInquiry[19] = 0x08; /* Identifier length */
2564
2565 SM_DBG5(("smsatInquiryPage83: sasAddressHi 0x%08x\n", oneDeviceData->sasAddressHi));
2566 SM_DBG5(("smsatInquiryPage83: sasAddressLo 0x%08x\n", oneDeviceData->sasAddressLo));
2567
2568 /* SAS address of SATA */
2569 pInquiry[20] = ((oneDeviceData->sasAddressHi) & 0xFF000000 ) >> 24;
2570 pInquiry[21] = ((oneDeviceData->sasAddressHi) & 0xFF0000 ) >> 16;
2571 pInquiry[22] = ((oneDeviceData->sasAddressHi) & 0xFF00 ) >> 8;
2572 pInquiry[23] = (oneDeviceData->sasAddressHi) & 0xFF;
2573 pInquiry[24] = ((oneDeviceData->sasAddressLo) & 0xFF000000 ) >> 24;
2574 pInquiry[25] = ((oneDeviceData->sasAddressLo) & 0xFF0000 ) >> 16;
2575 pInquiry[26] = ((oneDeviceData->sasAddressLo) & 0xFF00 ) >> 8;
2576 pInquiry[27] = (oneDeviceData->sasAddressLo) & 0xFF;
2577 #endif
2578 }
2579 else
2580 {
2581 #ifndef PMC_FREEBSD
2582 /* Fill in SAT Rev8 Table86 */
2583 /*
2584 * Logical unit name derived from the model number and serial number.
2585 */
2586 pInquiry[3] = 72; /* 75 - 3; page length */
2587
2588 /*
2589 * Identifier descriptor
2590 */
2591 pInquiry[4] = 0x02; /* Code set: ASCII codes */
2592 pInquiry[5] = 0x01; /* Identifier type : T10 vendor ID based */
2593 pInquiry[6] = 0x00; /* Reserved */
2594 pInquiry[7] = 0x44; /* 0x44, 68 Identifier length */
2595
2596 /* Byte 8 to 15 is the vendor id string 'ATA '. */
2597 sm_strncpy((char *)&pInquiry[8], AG_SAT_VENDOR_ID_STRING, 8);
2598
2599
2600 /*
2601 * Byte 16 to 75 is vendor specific id
2602 */
2603 pInquiry[16] = (bit8)((pSimpleData->word[27]) >> 8);
2604 pInquiry[17] = (bit8)((pSimpleData->word[27]) & 0x00ff);
2605 pInquiry[18] = (bit8)((pSimpleData->word[28]) >> 8);
2606 pInquiry[19] = (bit8)((pSimpleData->word[28]) & 0x00ff);
2607 pInquiry[20] = (bit8)((pSimpleData->word[29]) >> 8);
2608 pInquiry[21] = (bit8)((pSimpleData->word[29]) & 0x00ff);
2609 pInquiry[22] = (bit8)((pSimpleData->word[30]) >> 8);
2610 pInquiry[23] = (bit8)((pSimpleData->word[30]) & 0x00ff);
2611 pInquiry[24] = (bit8)((pSimpleData->word[31]) >> 8);
2612 pInquiry[25] = (bit8)((pSimpleData->word[31]) & 0x00ff);
2613 pInquiry[26] = (bit8)((pSimpleData->word[32]) >> 8);
2614 pInquiry[27] = (bit8)((pSimpleData->word[32]) & 0x00ff);
2615 pInquiry[28] = (bit8)((pSimpleData->word[33]) >> 8);
2616 pInquiry[29] = (bit8)((pSimpleData->word[33]) & 0x00ff);
2617 pInquiry[30] = (bit8)((pSimpleData->word[34]) >> 8);
2618 pInquiry[31] = (bit8)((pSimpleData->word[34]) & 0x00ff);
2619 pInquiry[32] = (bit8)((pSimpleData->word[35]) >> 8);
2620 pInquiry[33] = (bit8)((pSimpleData->word[35]) & 0x00ff);
2621 pInquiry[34] = (bit8)((pSimpleData->word[36]) >> 8);
2622 pInquiry[35] = (bit8)((pSimpleData->word[36]) & 0x00ff);
2623 pInquiry[36] = (bit8)((pSimpleData->word[37]) >> 8);
2624 pInquiry[37] = (bit8)((pSimpleData->word[37]) & 0x00ff);
2625 pInquiry[38] = (bit8)((pSimpleData->word[38]) >> 8);
2626 pInquiry[39] = (bit8)((pSimpleData->word[38]) & 0x00ff);
2627 pInquiry[40] = (bit8)((pSimpleData->word[39]) >> 8);
2628 pInquiry[41] = (bit8)((pSimpleData->word[39]) & 0x00ff);
2629 pInquiry[42] = (bit8)((pSimpleData->word[40]) >> 8);
2630 pInquiry[43] = (bit8)((pSimpleData->word[40]) & 0x00ff);
2631 pInquiry[44] = (bit8)((pSimpleData->word[41]) >> 8);
2632 pInquiry[45] = (bit8)((pSimpleData->word[41]) & 0x00ff);
2633 pInquiry[46] = (bit8)((pSimpleData->word[42]) >> 8);
2634 pInquiry[47] = (bit8)((pSimpleData->word[42]) & 0x00ff);
2635 pInquiry[48] = (bit8)((pSimpleData->word[43]) >> 8);
2636 pInquiry[49] = (bit8)((pSimpleData->word[43]) & 0x00ff);
2637 pInquiry[50] = (bit8)((pSimpleData->word[44]) >> 8);
2638 pInquiry[51] = (bit8)((pSimpleData->word[44]) & 0x00ff);
2639 pInquiry[52] = (bit8)((pSimpleData->word[45]) >> 8);
2640 pInquiry[53] = (bit8)((pSimpleData->word[45]) & 0x00ff);
2641 pInquiry[54] = (bit8)((pSimpleData->word[46]) >> 8);
2642 pInquiry[55] = (bit8)((pSimpleData->word[46]) & 0x00ff);
2643
2644 pInquiry[56] = (bit8)((pSimpleData->word[10]) >> 8);
2645 pInquiry[57] = (bit8)((pSimpleData->word[10]) & 0x00ff);
2646 pInquiry[58] = (bit8)((pSimpleData->word[11]) >> 8);
2647 pInquiry[59] = (bit8)((pSimpleData->word[11]) & 0x00ff);
2648 pInquiry[60] = (bit8)((pSimpleData->word[12]) >> 8);
2649 pInquiry[61] = (bit8)((pSimpleData->word[12]) & 0x00ff);
2650 pInquiry[62] = (bit8)((pSimpleData->word[13]) >> 8);
2651 pInquiry[63] = (bit8)((pSimpleData->word[13]) & 0x00ff);
2652 pInquiry[64] = (bit8)((pSimpleData->word[14]) >> 8);
2653 pInquiry[65] = (bit8)((pSimpleData->word[14]) & 0x00ff);
2654 pInquiry[66] = (bit8)((pSimpleData->word[15]) >> 8);
2655 pInquiry[67] = (bit8)((pSimpleData->word[15]) & 0x00ff);
2656 pInquiry[68] = (bit8)((pSimpleData->word[16]) >> 8);
2657 pInquiry[69] = (bit8)((pSimpleData->word[16]) & 0x00ff);
2658 pInquiry[70] = (bit8)((pSimpleData->word[17]) >> 8);
2659 pInquiry[71] = (bit8)((pSimpleData->word[17]) & 0x00ff);
2660 pInquiry[72] = (bit8)((pSimpleData->word[18]) >> 8);
2661 pInquiry[73] = (bit8)((pSimpleData->word[18]) & 0x00ff);
2662 pInquiry[74] = (bit8)((pSimpleData->word[19]) >> 8);
2663 pInquiry[75] = (bit8)((pSimpleData->word[19]) & 0x00ff);
2664 #else
2665 /* for the FreeBSD */
2666 /* Fill in SAT Rev8 Table86 */
2667 /*
2668 * Logical unit name derived from the model number and serial number.
2669 */
2670 pInquiry[3] = 84; /* 87 - 3; page length */
2671
2672 /*
2673 * Identifier descriptor
2674 */
2675 pInquiry[4] = 0x02; /* Code set: ASCII codes */
2676 pInquiry[5] = 0x01; /* Identifier type : T10 vendor ID based */
2677 pInquiry[6] = 0x00; /* Reserved */
2678 pInquiry[7] = 0x44; /* 0x44, 68 Identifier length */
2679
2680 /* Byte 8 to 15 is the vendor id string 'ATA '. */
2681 sm_strncpy((char *)&pInquiry[8], AG_SAT_VENDOR_ID_STRING, 8);
2682
2683
2684 /*
2685 * Byte 16 to 75 is vendor specific id
2686 */
2687 pInquiry[16] = (bit8)((pSimpleData->word[27]) >> 8);
2688 pInquiry[17] = (bit8)((pSimpleData->word[27]) & 0x00ff);
2689 pInquiry[18] = (bit8)((pSimpleData->word[28]) >> 8);
2690 pInquiry[19] = (bit8)((pSimpleData->word[28]) & 0x00ff);
2691 pInquiry[20] = (bit8)((pSimpleData->word[29]) >> 8);
2692 pInquiry[21] = (bit8)((pSimpleData->word[29]) & 0x00ff);
2693 pInquiry[22] = (bit8)((pSimpleData->word[30]) >> 8);
2694 pInquiry[23] = (bit8)((pSimpleData->word[30]) & 0x00ff);
2695 pInquiry[24] = (bit8)((pSimpleData->word[31]) >> 8);
2696 pInquiry[25] = (bit8)((pSimpleData->word[31]) & 0x00ff);
2697 pInquiry[26] = (bit8)((pSimpleData->word[32]) >> 8);
2698 pInquiry[27] = (bit8)((pSimpleData->word[32]) & 0x00ff);
2699 pInquiry[28] = (bit8)((pSimpleData->word[33]) >> 8);
2700 pInquiry[29] = (bit8)((pSimpleData->word[33]) & 0x00ff);
2701 pInquiry[30] = (bit8)((pSimpleData->word[34]) >> 8);
2702 pInquiry[31] = (bit8)((pSimpleData->word[34]) & 0x00ff);
2703 pInquiry[32] = (bit8)((pSimpleData->word[35]) >> 8);
2704 pInquiry[33] = (bit8)((pSimpleData->word[35]) & 0x00ff);
2705 pInquiry[34] = (bit8)((pSimpleData->word[36]) >> 8);
2706 pInquiry[35] = (bit8)((pSimpleData->word[36]) & 0x00ff);
2707 pInquiry[36] = (bit8)((pSimpleData->word[37]) >> 8);
2708 pInquiry[37] = (bit8)((pSimpleData->word[37]) & 0x00ff);
2709 pInquiry[38] = (bit8)((pSimpleData->word[38]) >> 8);
2710 pInquiry[39] = (bit8)((pSimpleData->word[38]) & 0x00ff);
2711 pInquiry[40] = (bit8)((pSimpleData->word[39]) >> 8);
2712 pInquiry[41] = (bit8)((pSimpleData->word[39]) & 0x00ff);
2713 pInquiry[42] = (bit8)((pSimpleData->word[40]) >> 8);
2714 pInquiry[43] = (bit8)((pSimpleData->word[40]) & 0x00ff);
2715 pInquiry[44] = (bit8)((pSimpleData->word[41]) >> 8);
2716 pInquiry[45] = (bit8)((pSimpleData->word[41]) & 0x00ff);
2717 pInquiry[46] = (bit8)((pSimpleData->word[42]) >> 8);
2718 pInquiry[47] = (bit8)((pSimpleData->word[42]) & 0x00ff);
2719 pInquiry[48] = (bit8)((pSimpleData->word[43]) >> 8);
2720 pInquiry[49] = (bit8)((pSimpleData->word[43]) & 0x00ff);
2721 pInquiry[50] = (bit8)((pSimpleData->word[44]) >> 8);
2722 pInquiry[51] = (bit8)((pSimpleData->word[44]) & 0x00ff);
2723 pInquiry[52] = (bit8)((pSimpleData->word[45]) >> 8);
2724 pInquiry[53] = (bit8)((pSimpleData->word[45]) & 0x00ff);
2725 pInquiry[54] = (bit8)((pSimpleData->word[46]) >> 8);
2726 pInquiry[55] = (bit8)((pSimpleData->word[46]) & 0x00ff);
2727
2728 pInquiry[56] = (bit8)((pSimpleData->word[10]) >> 8);
2729 pInquiry[57] = (bit8)((pSimpleData->word[10]) & 0x00ff);
2730 pInquiry[58] = (bit8)((pSimpleData->word[11]) >> 8);
2731 pInquiry[59] = (bit8)((pSimpleData->word[11]) & 0x00ff);
2732 pInquiry[60] = (bit8)((pSimpleData->word[12]) >> 8);
2733 pInquiry[61] = (bit8)((pSimpleData->word[12]) & 0x00ff);
2734 pInquiry[62] = (bit8)((pSimpleData->word[13]) >> 8);
2735 pInquiry[63] = (bit8)((pSimpleData->word[13]) & 0x00ff);
2736 pInquiry[64] = (bit8)((pSimpleData->word[14]) >> 8);
2737 pInquiry[65] = (bit8)((pSimpleData->word[14]) & 0x00ff);
2738 pInquiry[66] = (bit8)((pSimpleData->word[15]) >> 8);
2739 pInquiry[67] = (bit8)((pSimpleData->word[15]) & 0x00ff);
2740 pInquiry[68] = (bit8)((pSimpleData->word[16]) >> 8);
2741 pInquiry[69] = (bit8)((pSimpleData->word[16]) & 0x00ff);
2742 pInquiry[70] = (bit8)((pSimpleData->word[17]) >> 8);
2743 pInquiry[71] = (bit8)((pSimpleData->word[17]) & 0x00ff);
2744 pInquiry[72] = (bit8)((pSimpleData->word[18]) >> 8);
2745 pInquiry[73] = (bit8)((pSimpleData->word[18]) & 0x00ff);
2746 pInquiry[74] = (bit8)((pSimpleData->word[19]) >> 8);
2747 pInquiry[75] = (bit8)((pSimpleData->word[19]) & 0x00ff);
2748
2749 pInquiry[76] = 0x61; /* Code set: binary codes; this is proto_codeset in FreeBSD; SCSI_PROTO_SAS and SVPD_ID_CODESET_BINARY */
2750 pInquiry[77] = 0x93; /* Identifier type : NAA ; this is id_type in FreeBSD; PIV set, ASSOCIATION is 01b and NAA (3h) */
2751 pInquiry[78] = 0x00; /* Reserved */
2752 pInquiry[79] = 0x08; /* Identifier length */
2753
2754 SM_DBG5(("smsatInquiryPage83: NO WWN sasAddressHi 0x%08x\n", oneDeviceData->sasAddressHi));
2755 SM_DBG5(("smsatInquiryPage83: No WWN sasAddressLo 0x%08x\n", oneDeviceData->sasAddressLo));
2756
2757 /* SAS address of SATA */
2758 pInquiry[80] = ((oneDeviceData->sasAddressHi) & 0xFF000000 ) >> 24;
2759 pInquiry[81] = ((oneDeviceData->sasAddressHi) & 0xFF0000 ) >> 16;
2760 pInquiry[82] = ((oneDeviceData->sasAddressHi) & 0xFF00 ) >> 8;
2761 pInquiry[83] = (oneDeviceData->sasAddressHi) & 0xFF;
2762 pInquiry[84] = ((oneDeviceData->sasAddressLo) & 0xFF000000 ) >> 24;
2763 pInquiry[85] = ((oneDeviceData->sasAddressLo) & 0xFF0000 ) >> 16;
2764 pInquiry[86] = ((oneDeviceData->sasAddressLo) & 0xFF00 ) >> 8;
2765 pInquiry[87] = (oneDeviceData->sasAddressLo) & 0xFF;
2766
2767 #endif
2768 }
2769
2770 return;
2771 }
2772
2773 osGLOBAL void
smsatInquiryPage89(bit8 * pInquiry,agsaSATAIdentifyData_t * pSATAIdData,smDeviceData_t * oneDeviceData,bit32 len)2774 smsatInquiryPage89(
2775 bit8 *pInquiry,
2776 agsaSATAIdentifyData_t *pSATAIdData,
2777 smDeviceData_t *oneDeviceData,
2778 bit32 len
2779 )
2780 {
2781 /*
2782 SAT revision 8, 10.3.5, p 83
2783 */
2784 satSimpleSATAIdentifyData_t *pSimpleData;
2785
2786 /*
2787 * When translating the fields, in some cases using the simple form of SATA
2788 * Identify Device Data is easier. So we define it here.
2789 * Both pSimpleData and pSATAIdData points to the same data.
2790 */
2791 pSimpleData = ( satSimpleSATAIdentifyData_t *)pSATAIdData;
2792
2793 SM_DBG5(("smsatInquiryPage89: start\n"));
2794
2795 pInquiry[0] = 0x00; /* Peripheral Qualifier and Peripheral Device Type */
2796 pInquiry[1] = 0x89; /* page code */
2797
2798 /* Page length 0x238 */
2799 pInquiry[2] = 0x02;
2800 pInquiry[3] = 0x38;
2801
2802 pInquiry[4] = 0x0; /* reserved */
2803 pInquiry[5] = 0x0; /* reserved */
2804 pInquiry[6] = 0x0; /* reserved */
2805 pInquiry[7] = 0x0; /* reserved */
2806
2807 /* SAT Vendor Identification */
2808 sm_strncpy((char*)&pInquiry[8], "PMC-SIERRA", 8); /* 8 bytes */
2809
2810 /* SAT Product Idetification */
2811 sm_strncpy((char*)&pInquiry[16], "Tachyon-SPC ", 16); /* 16 bytes */
2812
2813 /* SAT Product Revision Level */
2814 sm_strncpy((char*)&pInquiry[32], "01", 4); /* 4 bytes */
2815
2816 /* Signature, SAT revision8, Table88, p85 */
2817
2818
2819 pInquiry[36] = 0x34; /* FIS type */
2820 if (oneDeviceData->satDeviceType == SATA_ATA_DEVICE)
2821 {
2822 /* interrupt assume to be 0 */
2823 pInquiry[37] = (bit8)((oneDeviceData->satPMField) >> (4 * 7)); /* first four bits of PM field */
2824 }
2825 else
2826 {
2827 /* interrupt assume to be 1 */
2828 pInquiry[37] = (bit8)(0x40 + (bit8)(((oneDeviceData->satPMField) >> (4 * 7)))); /* first four bits of PM field */
2829 }
2830 pInquiry[38] = 0;
2831 pInquiry[39] = 0;
2832
2833 if (oneDeviceData->satDeviceType == SATA_ATA_DEVICE)
2834 {
2835 pInquiry[40] = 0x01; /* LBA Low */
2836 pInquiry[41] = 0x00; /* LBA Mid */
2837 pInquiry[42] = 0x00; /* LBA High */
2838 pInquiry[43] = 0x00; /* Device */
2839 pInquiry[44] = 0x00; /* LBA Low Exp */
2840 pInquiry[45] = 0x00; /* LBA Mid Exp */
2841 pInquiry[46] = 0x00; /* LBA High Exp */
2842 pInquiry[47] = 0x00; /* Reserved */
2843 pInquiry[48] = 0x01; /* Sector Count */
2844 pInquiry[49] = 0x00; /* Sector Count Exp */
2845 }
2846 else
2847 {
2848 pInquiry[40] = 0x01; /* LBA Low */
2849 pInquiry[41] = 0x00; /* LBA Mid */
2850 pInquiry[42] = 0x00; /* LBA High */
2851 pInquiry[43] = 0x00; /* Device */
2852 pInquiry[44] = 0x00; /* LBA Low Exp */
2853 pInquiry[45] = 0x00; /* LBA Mid Exp */
2854 pInquiry[46] = 0x00; /* LBA High Exp */
2855 pInquiry[47] = 0x00; /* Reserved */
2856 pInquiry[48] = 0x01; /* Sector Count */
2857 pInquiry[49] = 0x00; /* Sector Count Exp */
2858 }
2859
2860 /* Reserved */
2861 pInquiry[50] = 0x00;
2862 pInquiry[51] = 0x00;
2863 pInquiry[52] = 0x00;
2864 pInquiry[53] = 0x00;
2865 pInquiry[54] = 0x00;
2866 pInquiry[55] = 0x00;
2867
2868 /* Command Code */
2869 if (oneDeviceData->satDeviceType == SATA_ATA_DEVICE)
2870 {
2871 pInquiry[56] = 0xEC; /* IDENTIFY DEVICE */
2872 }
2873 else
2874 {
2875 pInquiry[56] = 0xA1; /* IDENTIFY PACKET DEVICE */
2876 }
2877 /* Reserved */
2878 pInquiry[57] = 0x0;
2879 pInquiry[58] = 0x0;
2880 pInquiry[59] = 0x0;
2881
2882 /* check the length; len is assumed to be at least 60 */
2883 if (len < SATA_PAGE89_INQUIRY_SIZE)
2884 {
2885 /* Identify Device */
2886 sm_memcpy(&pInquiry[60], pSimpleData, MIN((len - 60), sizeof(satSimpleSATAIdentifyData_t)));
2887 }
2888 else
2889 {
2890 /* Identify Device */
2891 sm_memcpy(&pInquiry[60], pSimpleData, sizeof(satSimpleSATAIdentifyData_t));
2892 }
2893
2894 return;
2895 }
2896
2897 osGLOBAL void
smsatInquiryPage80(bit8 * pInquiry,agsaSATAIdentifyData_t * pSATAIdData)2898 smsatInquiryPage80(
2899 bit8 *pInquiry,
2900 agsaSATAIdentifyData_t *pSATAIdData
2901 )
2902 {
2903 SM_DBG5(("smsatInquiryPage89: start\n"));
2904 /*
2905 See SPC-4, 7.6.9, p 345
2906 and SAT revision 8, 10.3.3, p 77
2907 */
2908 pInquiry[0] = 0x00;
2909 pInquiry[1] = 0x80; /* page code */
2910 pInquiry[2] = 0x00; /* reserved */
2911 pInquiry[3] = 0x14; /* page length */
2912
2913 /* product serial number */
2914 pInquiry[4] = pSATAIdData->serialNumber[1];
2915 pInquiry[5] = pSATAIdData->serialNumber[0];
2916 pInquiry[6] = pSATAIdData->serialNumber[3];
2917 pInquiry[7] = pSATAIdData->serialNumber[2];
2918 pInquiry[8] = pSATAIdData->serialNumber[5];
2919 pInquiry[9] = pSATAIdData->serialNumber[4];
2920 pInquiry[10] = pSATAIdData->serialNumber[7];
2921 pInquiry[11] = pSATAIdData->serialNumber[6];
2922 pInquiry[12] = pSATAIdData->serialNumber[9];
2923 pInquiry[13] = pSATAIdData->serialNumber[8];
2924 pInquiry[14] = pSATAIdData->serialNumber[11];
2925 pInquiry[15] = pSATAIdData->serialNumber[10];
2926 pInquiry[16] = pSATAIdData->serialNumber[13];
2927 pInquiry[17] = pSATAIdData->serialNumber[12];
2928 pInquiry[18] = pSATAIdData->serialNumber[15];
2929 pInquiry[19] = pSATAIdData->serialNumber[14];
2930 pInquiry[20] = pSATAIdData->serialNumber[17];
2931 pInquiry[21] = pSATAIdData->serialNumber[16];
2932 pInquiry[22] = pSATAIdData->serialNumber[19];
2933 pInquiry[23] = pSATAIdData->serialNumber[18];
2934
2935 return;
2936 }
2937
2938 osGLOBAL void
smsatInquiryPageB1(bit8 * pInquiry,agsaSATAIdentifyData_t * pSATAIdData)2939 smsatInquiryPageB1(
2940 bit8 *pInquiry,
2941 agsaSATAIdentifyData_t *pSATAIdData
2942 )
2943 {
2944 bit32 i;
2945 satSimpleSATAIdentifyData_t *pSimpleData;
2946
2947 SM_DBG5(("smsatInquiryPageB1: start\n"));
2948
2949 pSimpleData = ( satSimpleSATAIdentifyData_t *)pSATAIdData;
2950 /*
2951 See SBC-3, revision31, Table193, p273
2952 and SAT-3 revision 3, 10.3.6, p141
2953 */
2954 pInquiry[0] = 0x00; /* Peripheral Qualifier and Peripheral Device Type */
2955 pInquiry[1] = 0xB1; /* page code */
2956
2957 /* page length */
2958 pInquiry[2] = 0x0;
2959 pInquiry[3] = 0x3C;
2960
2961 /* medium rotation rate */
2962 pInquiry[4] = (bit8) ((pSimpleData->word[217]) >> 8);
2963 pInquiry[5] = (bit8) ((pSimpleData->word[217]) & 0xFF);
2964
2965 /* reserved */
2966 pInquiry[6] = 0x0;
2967
2968 /* nominal form factor bits 3:0 */
2969 pInquiry[7] = (bit8) ((pSimpleData->word[168]) & 0xF);
2970
2971
2972 /* reserved */
2973 for (i=8;i<64;i++)
2974 {
2975 pInquiry[i] = 0x0;
2976 }
2977 return;
2978 }
2979
2980 osGLOBAL void
smsatDefaultTranslation(smRoot_t * smRoot,smIORequest_t * smIORequest,smSatIOContext_t * satIOContext,smScsiRspSense_t * pSense,bit8 ataStatus,bit8 ataError,bit32 interruptContext)2981 smsatDefaultTranslation(
2982 smRoot_t *smRoot,
2983 smIORequest_t *smIORequest,
2984 smSatIOContext_t *satIOContext,
2985 smScsiRspSense_t *pSense,
2986 bit8 ataStatus,
2987 bit8 ataError,
2988 bit32 interruptContext
2989 )
2990 {
2991 SM_DBG5(("smsatDefaultTranslation: start\n"));
2992 /*
2993 * Check for device fault case
2994 */
2995 if ( ataStatus & DF_ATA_STATUS_MASK )
2996 {
2997 smsatSetSensePayload( pSense,
2998 SCSI_SNSKEY_HARDWARE_ERROR,
2999 0,
3000 SCSI_SNSCODE_INTERNAL_TARGET_FAILURE,
3001 satIOContext);
3002
3003 tdsmIOCompletedCB( smRoot,
3004 smIORequest,
3005 smIOSuccess,
3006 SCSI_STAT_CHECK_CONDITION,
3007 satIOContext->pSmSenseData,
3008 interruptContext );
3009 return;
3010 }
3011
3012 /*
3013 * If status error bit it set, need to check the error register
3014 */
3015 if ( ataStatus & ERR_ATA_STATUS_MASK )
3016 {
3017 if ( ataError & NM_ATA_ERROR_MASK )
3018 {
3019 SM_DBG1(("smsatDefaultTranslation: NM_ATA_ERROR ataError= 0x%x, smIORequest=%p!!!\n",
3020 ataError, smIORequest));
3021 smsatSetSensePayload( pSense,
3022 SCSI_SNSKEY_NOT_READY,
3023 0,
3024 SCSI_SNSCODE_MEDIUM_NOT_PRESENT,
3025 satIOContext);
3026 }
3027
3028 else if (ataError & UNC_ATA_ERROR_MASK)
3029 {
3030 SM_DBG1(("smsatDefaultTranslation: UNC_ATA_ERROR ataError= 0x%x, smIORequest=%p!!!\n",
3031 ataError, smIORequest));
3032 smsatSetSensePayload( pSense,
3033 SCSI_SNSKEY_MEDIUM_ERROR,
3034 0,
3035 SCSI_SNSCODE_UNRECOVERED_READ_ERROR,
3036 satIOContext);
3037 }
3038
3039 else if (ataError & IDNF_ATA_ERROR_MASK)
3040 {
3041 SM_DBG1(("smsatDefaultTranslation: IDNF_ATA_ERROR ataError= 0x%x, smIORequest=%p!!!\n",
3042 ataError, smIORequest));
3043 smsatSetSensePayload( pSense,
3044 SCSI_SNSKEY_MEDIUM_ERROR,
3045 0,
3046 SCSI_SNSCODE_RECORD_NOT_FOUND,
3047 satIOContext);
3048 }
3049
3050 else if (ataError & MC_ATA_ERROR_MASK)
3051 {
3052 SM_DBG1(("smsatDefaultTranslation: MC_ATA_ERROR ataError= 0x%x, smIORequest=%p!!!\n",
3053 ataError, smIORequest));
3054 smsatSetSensePayload( pSense,
3055 SCSI_SNSKEY_UNIT_ATTENTION,
3056 0,
3057 SCSI_SNSCODE_NOT_READY_TO_READY_CHANGE,
3058 satIOContext);
3059 }
3060
3061 else if (ataError & MCR_ATA_ERROR_MASK)
3062 {
3063 SM_DBG1(("smsatDefaultTranslation: MCR_ATA_ERROR ataError= 0x%x, smIORequest=%p!!!\n",
3064 ataError, smIORequest));
3065 smsatSetSensePayload( pSense,
3066 SCSI_SNSKEY_UNIT_ATTENTION,
3067 0,
3068 SCSI_SNSCODE_OPERATOR_MEDIUM_REMOVAL_REQUEST,
3069 satIOContext);
3070 }
3071
3072 else if (ataError & ICRC_ATA_ERROR_MASK)
3073 {
3074 SM_DBG1(("smsatDefaultTranslation: ICRC_ATA_ERROR ataError= 0x%x, smIORequest=%p!!!\n",
3075 ataError, smIORequest));
3076 smsatSetSensePayload( pSense,
3077 SCSI_SNSKEY_ABORTED_COMMAND,
3078 0,
3079 SCSI_SNSCODE_INFORMATION_UNIT_CRC_ERROR,
3080 satIOContext);
3081 }
3082
3083 else if (ataError & ABRT_ATA_ERROR_MASK)
3084 {
3085 SM_DBG1(("smsatDefaultTranslation: ABRT_ATA_ERROR ataError= 0x%x, smIORequest=%p!!!\n",
3086 ataError, smIORequest));
3087 smsatSetSensePayload( pSense,
3088 SCSI_SNSKEY_ABORTED_COMMAND,
3089 0,
3090 SCSI_SNSCODE_NO_ADDITIONAL_INFO,
3091 satIOContext);
3092 }
3093
3094 else
3095 {
3096 SM_DBG1(("smsatDefaultTranslation: **** UNEXPECTED ATA_ERROR **** ataError= 0x%x, smIORequest=%p!!!\n",
3097 ataError, smIORequest));
3098 smsatSetSensePayload( pSense,
3099 SCSI_SNSKEY_HARDWARE_ERROR,
3100 0,
3101 SCSI_SNSCODE_INTERNAL_TARGET_FAILURE,
3102 satIOContext);
3103 }
3104
3105 /* Send the completion response now */
3106 tdsmIOCompletedCB( smRoot,
3107 smIORequest,
3108 smIOSuccess,
3109 SCSI_STAT_CHECK_CONDITION,
3110 satIOContext->pSmSenseData,
3111 interruptContext );
3112 return;
3113
3114
3115 }
3116
3117 else /* (ataStatus & ERR_ATA_STATUS_MASK ) is false */
3118 {
3119 /* This case should never happen */
3120 SM_DBG1(("smsatDefaultTranslation: *** UNEXPECTED ATA status 0x%x *** smIORequest=%p!!!\n",
3121 ataStatus, smIORequest));
3122 smsatSetSensePayload( pSense,
3123 SCSI_SNSKEY_HARDWARE_ERROR,
3124 0,
3125 SCSI_SNSCODE_INTERNAL_TARGET_FAILURE,
3126 satIOContext);
3127
3128 tdsmIOCompletedCB( smRoot,
3129 smIORequest,
3130 smIOSuccess,
3131 SCSI_STAT_CHECK_CONDITION,
3132 satIOContext->pSmSenseData,
3133 interruptContext );
3134 return;
3135
3136 }
3137
3138 return;
3139 }
3140
3141 osGLOBAL bit32
smIDStart(smRoot_t * smRoot,smIORequest_t * smIORequest,smDeviceHandle_t * smDeviceHandle)3142 smIDStart(
3143 smRoot_t *smRoot,
3144 smIORequest_t *smIORequest,
3145 smDeviceHandle_t *smDeviceHandle
3146 )
3147 {
3148 smDeviceData_t *oneDeviceData = agNULL;
3149 smIORequestBody_t *smIORequestBody = agNULL;
3150 smSatIOContext_t *satIOContext = agNULL;
3151 bit32 status = SM_RC_FAILURE;
3152
3153 SM_DBG2(("smIDStart: start, smIORequest %p\n", smIORequest));
3154
3155 oneDeviceData = (smDeviceData_t *)smDeviceHandle->smData;
3156 if (oneDeviceData == agNULL)
3157 {
3158 SM_DBG1(("smIDStart: oneDeviceData is NULL!!!\n"));
3159 return SM_RC_FAILURE;
3160 }
3161 if (oneDeviceData->valid == agFALSE)
3162 {
3163 SM_DBG1(("smIDStart: oneDeviceData is not valid, did %d !!!\n", oneDeviceData->id));
3164 return SM_RC_FAILURE;
3165 }
3166
3167 smIORequestBody = (smIORequestBody_t*)smIORequest->smData;//smDequeueIO(smRoot);
3168
3169 if (smIORequestBody == agNULL)
3170 {
3171 SM_DBG1(("smIDStart: smIORequestBody is NULL!!!\n"));
3172 return SM_RC_FAILURE;
3173 }
3174
3175 smIOReInit(smRoot, smIORequestBody);
3176
3177 SM_DBG3(("smIDStart: io ID %d!!!\n", smIORequestBody->id ));
3178
3179 smIORequestBody->smIORequest = smIORequest;
3180 smIORequestBody->smDevHandle = smDeviceHandle;
3181 satIOContext = &(smIORequestBody->transport.SATA.satIOContext);
3182
3183 /* setting up satIOContext */
3184 satIOContext->pSatDevData = oneDeviceData;
3185 satIOContext->pFis = &(smIORequestBody->transport.SATA.agSATARequestBody.fis.fisRegHostToDev);
3186 satIOContext->smRequestBody = smIORequestBody;
3187 satIOContext->psmDeviceHandle = smDeviceHandle;
3188 satIOContext->smScsiXchg = agNULL;
3189
3190 /*smIORequest->smData = smIORequestBody;*/
3191 SM_DBG3(("smIDStart: smIORequestBody %p smIORequestBody->smIORequest %p!!!\n", smIORequestBody, smIORequestBody->smIORequest));
3192 SM_DBG1(("smIDStart: did %d\n", oneDeviceData->id));
3193
3194 status = smsatIDSubStart( smRoot,
3195 smIORequest,
3196 smDeviceHandle,
3197 agNULL,
3198 satIOContext);
3199
3200 if (status != SM_RC_SUCCESS)
3201 {
3202 SM_DBG1(("smIDStart: smsatIDSubStart failure %d!!!\n", status));
3203 /*smEnqueueIO(smRoot, satIOContext);*/
3204 }
3205 SM_DBG2(("smIDStart: exit\n"));
3206
3207 return status;
3208 }
3209
3210 /*
3211 SM generated IO, needs to call smsatAllocIntIoResource()
3212 allocating using smsatAllocIntIoResource
3213 */
3214 osGLOBAL bit32
smsatIDSubStart(smRoot_t * smRoot,smIORequest_t * smIORequest,smDeviceHandle_t * smDeviceHandle,smScsiInitiatorRequest_t * smSCSIRequest,smSatIOContext_t * satIOContext)3215 smsatIDSubStart(
3216 smRoot_t *smRoot,
3217 smIORequest_t *smIORequest,
3218 smDeviceHandle_t *smDeviceHandle,
3219 smScsiInitiatorRequest_t *smSCSIRequest, /* agNULL */
3220 smSatIOContext_t *satIOContext
3221 )
3222 {
3223 smSatInternalIo_t *satIntIo = agNULL;
3224 smDeviceData_t *satDevData = agNULL;
3225 smIORequestBody_t *smIORequestBody;
3226 smSatIOContext_t *satNewIOContext;
3227 bit32 status;
3228 SM_DBG2(("smsatIDSubStart: start\n"));
3229
3230 satDevData = satIOContext->pSatDevData;
3231
3232 /* allocate identify device command */
3233 satIntIo = smsatAllocIntIoResource( smRoot,
3234 smIORequest,
3235 satDevData,
3236 sizeof(agsaSATAIdentifyData_t), /* 512; size of identify device data */
3237 satIntIo);
3238
3239 if (satIntIo == agNULL)
3240 {
3241 SM_DBG1(("smsatIDSubStart: can't alloacate!!!\n"));
3242 return SM_RC_FAILURE;
3243 }
3244
3245 satIOContext->satIntIoContext = satIntIo;
3246
3247 /* fill in fields */
3248 /* real ttttttthe one worked and the same; 5/21/07/ */
3249 satIntIo->satOrgSmIORequest = smIORequest; /* changed */
3250 smIORequestBody = satIntIo->satIntRequestBody;
3251 satNewIOContext = &(smIORequestBody->transport.SATA.satIOContext);
3252
3253 satNewIOContext->pSatDevData = satDevData;
3254 satNewIOContext->pFis = &(smIORequestBody->transport.SATA.agSATARequestBody.fis.fisRegHostToDev);
3255 satNewIOContext->pScsiCmnd = &(satIntIo->satIntSmScsiXchg.scsiCmnd);
3256 satNewIOContext->pSense = &(smIORequestBody->transport.SATA.sensePayload);
3257 satNewIOContext->pSmSenseData = &(smIORequestBody->transport.SATA.smSenseData);
3258 satNewIOContext->smRequestBody = satIntIo->satIntRequestBody; /* key fix */
3259 // satNewIOContext->interruptContext = tiInterruptContext;
3260 satNewIOContext->satIntIoContext = satIntIo;
3261
3262 satNewIOContext->psmDeviceHandle = smDeviceHandle;
3263 satNewIOContext->satOrgIOContext = satIOContext; /* changed */
3264
3265 /* this is valid only for TD layer generated (not triggered by OS at all) IO */
3266 satNewIOContext->smScsiXchg = &(satIntIo->satIntSmScsiXchg);
3267
3268
3269 SM_DBG6(("smsatIDSubStart: SM satIOContext %p \n", satIOContext));
3270 SM_DBG6(("smsatIDSubStart: SM satNewIOContext %p \n", satNewIOContext));
3271 SM_DBG6(("smsatIDSubStart: SM tiScsiXchg %p \n", satIOContext->smScsiXchg));
3272 SM_DBG6(("smsatIDSubStart: SM tiScsiXchg %p \n", satNewIOContext->smScsiXchg));
3273
3274
3275
3276 SM_DBG3(("smsatIDSubStart: satNewIOContext %p smIORequestBody %p\n", satNewIOContext, smIORequestBody));
3277
3278 status = smsatIDStart(smRoot,
3279 &satIntIo->satIntSmIORequest, /* New smIORequest */
3280 smDeviceHandle,
3281 satNewIOContext->smScsiXchg, /* New smScsiInitiatorRequest_t *smScsiRequest, */
3282 satNewIOContext);
3283
3284 if (status != SM_RC_SUCCESS)
3285 {
3286 SM_DBG1(("smsatIDSubStart: failed in sending %d!!!\n", status));
3287
3288 smsatFreeIntIoResource( smRoot,
3289 satDevData,
3290 satIntIo);
3291
3292 return SM_RC_FAILURE;
3293 }
3294
3295
3296 SM_DBG2(("smsatIDSubStart: end\n"));
3297
3298 return status;
3299
3300 }
3301
3302
3303 osGLOBAL bit32
smsatIDStart(smRoot_t * smRoot,smIORequest_t * smIORequest,smDeviceHandle_t * smDeviceHandle,smScsiInitiatorRequest_t * smSCSIRequest,smSatIOContext_t * satIOContext)3304 smsatIDStart(
3305 smRoot_t *smRoot,
3306 smIORequest_t *smIORequest,
3307 smDeviceHandle_t *smDeviceHandle,
3308 smScsiInitiatorRequest_t *smSCSIRequest,
3309 smSatIOContext_t *satIOContext
3310 )
3311 {
3312 bit32 status;
3313 bit32 agRequestType;
3314 smDeviceData_t *pSatDevData;
3315 agsaFisRegHostToDevice_t *fis;
3316 #ifdef SM_INTERNAL_DEBUG
3317 smIORequestBody_t *smIORequestBody;
3318 smSatInternalIo_t *satIntIoContext;
3319 #endif
3320
3321 pSatDevData = satIOContext->pSatDevData;
3322 fis = satIOContext->pFis;
3323 SM_DBG2(("smsatIDStart: start\n"));
3324 #ifdef SM_INTERNAL_DEBUG
3325 satIntIoContext = satIOContext->satIntIoContext;
3326 smIORequestBody = satIntIoContext->satIntRequestBody;
3327 #endif
3328 fis->h.fisType = 0x27; /* Reg host to device */
3329 fis->h.c_pmPort = 0x80; /* C Bit is set */
3330 if (pSatDevData->satDeviceType == SATA_ATAPI_DEVICE)
3331 {
3332 SM_DBG2(("smsatIDStart: IDENTIFY_PACKET_DEVICE\n"));
3333 fis->h.command = SAT_IDENTIFY_PACKET_DEVICE; /* 0x40 */
3334 }
3335 else
3336 {
3337 SM_DBG2(("smsatIDStart: IDENTIFY_DEVICE\n"));
3338 fis->h.command = SAT_IDENTIFY_DEVICE; /* 0xEC */
3339 }
3340 fis->h.features = 0; /* FIS reserve */
3341 fis->d.lbaLow = 0; /* FIS LBA (7 :0 ) */
3342 fis->d.lbaMid = 0; /* FIS LBA (15:8 ) */
3343 fis->d.lbaHigh = 0; /* FIS LBA (23:16) */
3344 fis->d.device = 0; /* FIS LBA mode */
3345 fis->d.lbaLowExp = 0;
3346 fis->d.lbaMidExp = 0;
3347 fis->d.lbaHighExp = 0;
3348 fis->d.featuresExp = 0;
3349 fis->d.sectorCount = 0; /* FIS sector count (7:0) */
3350 fis->d.sectorCountExp = 0;
3351 fis->d.reserved4 = 0;
3352 fis->d.control = 0; /* FIS HOB bit clear */
3353 fis->d.reserved5 = 0;
3354
3355 agRequestType = AGSA_SATA_PROTOCOL_PIO_READ;
3356
3357 /* Initialize CB for SATA completion.
3358 */
3359 satIOContext->satCompleteCB = &smsatIDStartCB;
3360
3361 /*
3362 * Prepare SGL and send FIS to LL layer.
3363 */
3364 satIOContext->reqType = agRequestType; /* Save it */
3365
3366 #ifdef SM_INTERNAL_DEBUG
3367 smhexdump("smsatIDStart", (bit8 *)satIOContext->pFis, sizeof(agsaFisRegHostToDevice_t));
3368 smhexdump("smsatIDStart LL", (bit8 *)&(smIORequestBody->transport.SATA.agSATARequestBody.fis.fisRegHostToDev), sizeof(agsaFisRegHostToDevice_t));
3369 #endif
3370 status = smsataLLIOStart( smRoot,
3371 smIORequest,
3372 smDeviceHandle,
3373 smSCSIRequest,
3374 satIOContext);
3375
3376 SM_DBG2(("smsatIDStart: end status %d\n", status));
3377
3378 return status;
3379 }
3380
3381
3382 osGLOBAL FORCEINLINE bit32
smsatIOStart(smRoot_t * smRoot,smIORequest_t * smIORequest,smDeviceHandle_t * smDeviceHandle,smScsiInitiatorRequest_t * smSCSIRequest,smSatIOContext_t * satIOContext)3383 smsatIOStart(
3384 smRoot_t *smRoot,
3385 smIORequest_t *smIORequest,
3386 smDeviceHandle_t *smDeviceHandle,
3387 smScsiInitiatorRequest_t *smSCSIRequest,
3388 smSatIOContext_t *satIOContext
3389 )
3390 {
3391 smDeviceData_t *pSatDevData = satIOContext->pSatDevData;
3392 smScsiRspSense_t *pSense = satIOContext->pSense;
3393 smIniScsiCmnd_t *scsiCmnd = &smSCSIRequest->scsiCmnd;
3394 smLUN_t *pLun = &scsiCmnd->lun;
3395 smSatInternalIo_t *pSatIntIo = agNULL;
3396 bit32 status = SM_RC_FAILURE;
3397
3398 SM_DBG2(("smsatIOStart: start\n"));
3399
3400 /*
3401 * Reject all other LUN other than LUN 0.
3402 */
3403 if ( ((pLun->lun[0] | pLun->lun[1] | pLun->lun[2] | pLun->lun[3] |
3404 pLun->lun[4] | pLun->lun[5] | pLun->lun[6] | pLun->lun[7] ) != 0) &&
3405 (scsiCmnd->cdb[0] != SCSIOPC_INQUIRY)
3406 )
3407 {
3408 SM_DBG1(("smsatIOStart: *** REJECT *** LUN not zero, cdb[0]=0x%x did %d !!!\n",
3409 scsiCmnd->cdb[0], pSatDevData->id));
3410 smsatSetSensePayload( pSense,
3411 SCSI_SNSKEY_ILLEGAL_REQUEST,
3412 0,
3413 SCSI_SNSCODE_LOGICAL_NOT_SUPPORTED,
3414 satIOContext);
3415
3416 /*smEnqueueIO(smRoot, satIOContext);*/
3417
3418 tdsmIOCompletedCB( smRoot,
3419 smIORequest,
3420 smIOSuccess,
3421 SCSI_STAT_CHECK_CONDITION,
3422 satIOContext->pSmSenseData,
3423 satIOContext->interruptContext );
3424
3425 return SM_RC_SUCCESS;
3426 }
3427
3428 SM_DBG2(("smsatIOStart: satPendingIO %d satNCQMaxIO %d\n",pSatDevData->satPendingIO, pSatDevData->satNCQMaxIO ));
3429
3430 /* this may happen after tiCOMReset until OS sends inquiry */
3431 if (pSatDevData->IDDeviceValid == agFALSE && (scsiCmnd->cdb[0] != SCSIOPC_INQUIRY))
3432 {
3433 SM_DBG1(("smsatIOStart: invalid identify device data did %d !!!\n", pSatDevData->id));
3434 SM_DBG1(("smsatIOStart: satPendingIO %d satNCQMaxIO %d\n", pSatDevData->satPendingIO, pSatDevData->satNCQMaxIO ));
3435 SM_DBG1(("smsatIOStart: satPendingNCQIO %d satPendingNONNCQIO %d\n", pSatDevData->satPendingNCQIO, pSatDevData->satPendingNONNCQIO));
3436
3437 /*smEnqueueIO(smRoot, satIOContext);*/
3438
3439 return SM_RC_NODEVICE;
3440 }
3441
3442 /*
3443 * Check if we need to return BUSY, i.e. recovery in progress
3444 */
3445 if (pSatDevData->satDriveState == SAT_DEV_STATE_IN_RECOVERY)
3446 {
3447 SM_DBG1(("smsatIOStart: IN RECOVERY STATE cdb[0]=0x%x did=%d !!!\n",
3448 scsiCmnd->cdb[0], pSatDevData->id));
3449 SM_DBG2(("smsatIOStart: device %p satPendingIO %d satNCQMaxIO %d\n", pSatDevData, pSatDevData->satPendingIO, pSatDevData->satNCQMaxIO ));
3450 SM_DBG2(("smsatIOStart: device %p satPendingNCQIO %d satPendingNONNCQIO %d\n",pSatDevData, pSatDevData->satPendingNCQIO, pSatDevData->satPendingNONNCQIO));
3451
3452 /*smEnqueueIO(smRoot, satIOContext);*/
3453
3454 // return SM_RC_FAILURE;
3455 return SM_RC_DEVICE_BUSY;
3456 }
3457
3458 if (pSatDevData->satDeviceType == SATA_ATAPI_DEVICE)
3459 {
3460 if (scsiCmnd->cdb[0] == SCSIOPC_REPORT_LUN)
3461 {
3462 return smsatReportLun(smRoot, smIORequest, smDeviceHandle, smSCSIRequest, satIOContext);
3463 }
3464 else
3465 {
3466 return smsatPacket(smRoot, smIORequest, smDeviceHandle, smSCSIRequest, satIOContext);
3467 }
3468 }
3469 else
3470 {
3471 /* Parse CDB */
3472 switch(scsiCmnd->cdb[0])
3473 {
3474 case SCSIOPC_READ_10:
3475 status = smsatRead10( smRoot,
3476 smIORequest,
3477 smDeviceHandle,
3478 smSCSIRequest,
3479 satIOContext);
3480 break;
3481
3482 case SCSIOPC_WRITE_10:
3483 status = smsatWrite10( smRoot,
3484 smIORequest,
3485 smDeviceHandle,
3486 smSCSIRequest,
3487 satIOContext);
3488 break;
3489
3490 case SCSIOPC_READ_6:
3491 status = smsatRead6( smRoot,
3492 smIORequest,
3493 smDeviceHandle,
3494 smSCSIRequest,
3495 satIOContext);
3496 break;
3497
3498 case SCSIOPC_READ_12:
3499 SM_DBG5(("smsatIOStart: SCSIOPC_READ_12\n"));
3500 status = smsatRead12( smRoot,
3501 smIORequest,
3502 smDeviceHandle,
3503 smSCSIRequest,
3504 satIOContext);
3505 break;
3506
3507 case SCSIOPC_READ_16:
3508 status = smsatRead16( smRoot,
3509 smIORequest,
3510 smDeviceHandle,
3511 smSCSIRequest,
3512 satIOContext);
3513 break;
3514
3515 case SCSIOPC_WRITE_6:
3516 status = smsatWrite6( smRoot,
3517 smIORequest,
3518 smDeviceHandle,
3519 smSCSIRequest,
3520 satIOContext);
3521 break;
3522
3523 case SCSIOPC_WRITE_12:
3524 SM_DBG5(("smsatIOStart: SCSIOPC_WRITE_12 \n"));
3525 status = smsatWrite12( smRoot,
3526 smIORequest,
3527 smDeviceHandle,
3528 smSCSIRequest,
3529 satIOContext);
3530 break;
3531
3532 case SCSIOPC_WRITE_16:
3533 SM_DBG5(("smsatIOStart: SCSIOPC_WRITE_16 \n"));
3534 status = smsatWrite16( smRoot,
3535 smIORequest,
3536 smDeviceHandle,
3537 smSCSIRequest,
3538 satIOContext);
3539 break;
3540
3541 case SCSIOPC_VERIFY_10:
3542 status = smsatVerify10( smRoot,
3543 smIORequest,
3544 smDeviceHandle,
3545 smSCSIRequest,
3546 satIOContext);
3547 break;
3548
3549 case SCSIOPC_VERIFY_12:
3550 SM_DBG5(("smsatIOStart: SCSIOPC_VERIFY_12\n"));
3551 status = smsatVerify12( smRoot,
3552 smIORequest,
3553 smDeviceHandle,
3554 smSCSIRequest,
3555 satIOContext);
3556 break;
3557
3558 case SCSIOPC_VERIFY_16:
3559 SM_DBG5(("smsatIOStart: SCSIOPC_VERIFY_16\n"));
3560 status = smsatVerify16( smRoot,
3561 smIORequest,
3562 smDeviceHandle,
3563 smSCSIRequest,
3564 satIOContext);
3565 break;
3566
3567 case SCSIOPC_TEST_UNIT_READY:
3568 status = smsatTestUnitReady( smRoot,
3569 smIORequest,
3570 smDeviceHandle,
3571 smSCSIRequest,
3572 satIOContext);
3573 break;
3574
3575 case SCSIOPC_INQUIRY:
3576 status = smsatInquiry( smRoot,
3577 smIORequest,
3578 smDeviceHandle,
3579 smSCSIRequest,
3580 satIOContext);
3581 break;
3582
3583 case SCSIOPC_REQUEST_SENSE:
3584 status = smsatRequestSense( smRoot,
3585 smIORequest,
3586 smDeviceHandle,
3587 smSCSIRequest,
3588 satIOContext);
3589 break;
3590
3591 case SCSIOPC_MODE_SENSE_6:
3592 status = smsatModeSense6( smRoot,
3593 smIORequest,
3594 smDeviceHandle,
3595 smSCSIRequest,
3596 satIOContext);
3597 break;
3598
3599 case SCSIOPC_MODE_SENSE_10:
3600 status = smsatModeSense10( smRoot,
3601 smIORequest,
3602 smDeviceHandle,
3603 smSCSIRequest,
3604 satIOContext);
3605 break;
3606
3607 case SCSIOPC_READ_CAPACITY_10:
3608 status = smsatReadCapacity10( smRoot,
3609 smIORequest,
3610 smDeviceHandle,
3611 smSCSIRequest,
3612 satIOContext);
3613 break;
3614
3615 case SCSIOPC_READ_CAPACITY_16:
3616 status = smsatReadCapacity16( smRoot,
3617 smIORequest,
3618 smDeviceHandle,
3619 smSCSIRequest,
3620 satIOContext);
3621 break;
3622
3623
3624 case SCSIOPC_REPORT_LUN:
3625 status = smsatReportLun( smRoot,
3626 smIORequest,
3627 smDeviceHandle,
3628 smSCSIRequest,
3629 satIOContext);
3630 break;
3631
3632 case SCSIOPC_FORMAT_UNIT:
3633 SM_DBG5(("smsatIOStart: SCSIOPC_FORMAT_UNIT\n"));
3634 status = smsatFormatUnit( smRoot,
3635 smIORequest,
3636 smDeviceHandle,
3637 smSCSIRequest,
3638 satIOContext);
3639 break;
3640
3641 case SCSIOPC_SEND_DIAGNOSTIC:
3642 SM_DBG5(("smsatIOStart: SCSIOPC_SEND_DIAGNOSTIC\n"));
3643 status = smsatSendDiagnostic( smRoot,
3644 smIORequest,
3645 smDeviceHandle,
3646 smSCSIRequest,
3647 satIOContext);
3648 break;
3649
3650 case SCSIOPC_START_STOP_UNIT:
3651 SM_DBG5(("smsatIOStart: SCSIOPC_START_STOP_UNIT\n"));
3652 status = smsatStartStopUnit( smRoot,
3653 smIORequest,
3654 smDeviceHandle,
3655 smSCSIRequest,
3656 satIOContext);
3657 break;
3658
3659 case SCSIOPC_WRITE_SAME_10:
3660 SM_DBG5(("smsatIOStart: SCSIOPC_WRITE_SAME_10\n"));
3661 status = smsatWriteSame10( smRoot,
3662 smIORequest,
3663 smDeviceHandle,
3664 smSCSIRequest,
3665 satIOContext);
3666 break;
3667
3668 case SCSIOPC_WRITE_SAME_16: /* no support due to transfer length(sector count) */
3669 SM_DBG5(("smsatIOStart: SCSIOPC_WRITE_SAME_16\n"));
3670 status = smsatWriteSame16( smRoot,
3671 smIORequest,
3672 smDeviceHandle,
3673 smSCSIRequest,
3674 satIOContext);
3675 break;
3676
3677 case SCSIOPC_LOG_SENSE:
3678 SM_DBG5(("smsatIOStart: SCSIOPC_LOG_SENSE\n"));
3679 status = smsatLogSense( smRoot,
3680 smIORequest,
3681 smDeviceHandle,
3682 smSCSIRequest,
3683 satIOContext);
3684 break;
3685
3686 case SCSIOPC_MODE_SELECT_6:
3687 SM_DBG5(("smsatIOStart: SCSIOPC_MODE_SELECT_6\n"));
3688 status = smsatModeSelect6( smRoot,
3689 smIORequest,
3690 smDeviceHandle,
3691 smSCSIRequest,
3692 satIOContext);
3693 break;
3694
3695 case SCSIOPC_MODE_SELECT_10:
3696 SM_DBG5(("smsatIOStart: SCSIOPC_MODE_SELECT_10\n"));
3697 status = smsatModeSelect10( smRoot,
3698 smIORequest,
3699 smDeviceHandle,
3700 smSCSIRequest,
3701 satIOContext);
3702 break;
3703
3704 case SCSIOPC_SYNCHRONIZE_CACHE_10: /* on error what to return, sharing CB with
3705 satSynchronizeCache16 */
3706 SM_DBG5(("smsatIOStart: SCSIOPC_SYNCHRONIZE_CACHE_10\n"));
3707 status = smsatSynchronizeCache10( smRoot,
3708 smIORequest,
3709 smDeviceHandle,
3710 smSCSIRequest,
3711 satIOContext);
3712 break;
3713
3714 case SCSIOPC_SYNCHRONIZE_CACHE_16:/* on error what to return, sharing CB with
3715 satSynchronizeCache16 */
3716
3717 SM_DBG5(("smsatIOStart: SCSIOPC_SYNCHRONIZE_CACHE_16\n"));
3718 status = smsatSynchronizeCache16( smRoot,
3719 smIORequest,
3720 smDeviceHandle,
3721 smSCSIRequest,
3722 satIOContext);
3723 break;
3724
3725 case SCSIOPC_WRITE_AND_VERIFY_10: /* single write and multiple writes */
3726 SM_DBG5(("smsatIOStart: SCSIOPC_WRITE_AND_VERIFY_10\n"));
3727 status = smsatWriteAndVerify10( smRoot,
3728 smIORequest,
3729 smDeviceHandle,
3730 smSCSIRequest,
3731 satIOContext);
3732 break;
3733
3734 case SCSIOPC_WRITE_AND_VERIFY_12:
3735 SM_DBG5(("smsatIOStart: SCSIOPC_WRITE_AND_VERIFY_12\n"));
3736 status = smsatWriteAndVerify12( smRoot,
3737 smIORequest,
3738 smDeviceHandle,
3739 smSCSIRequest,
3740 satIOContext);
3741 break;
3742
3743 case SCSIOPC_WRITE_AND_VERIFY_16:
3744 SM_DBG5(("smsatIOStart: SCSIOPC_WRITE_AND_VERIFY_16\n"));
3745 status = smsatWriteAndVerify16( smRoot,
3746 smIORequest,
3747 smDeviceHandle,
3748 smSCSIRequest,
3749 satIOContext);
3750
3751 break;
3752
3753 case SCSIOPC_READ_MEDIA_SERIAL_NUMBER:
3754 SM_DBG5(("smsatIOStart: SCSIOPC_READ_MEDIA_SERIAL_NUMBER\n"));
3755 status = smsatReadMediaSerialNumber( smRoot,
3756 smIORequest,
3757 smDeviceHandle,
3758 smSCSIRequest,
3759 satIOContext);
3760
3761 break;
3762
3763 case SCSIOPC_READ_BUFFER:
3764 SM_DBG5(("smsatIOStart: SCSIOPC_READ_BUFFER\n"));
3765 status = smsatReadBuffer( smRoot,
3766 smIORequest,
3767 smDeviceHandle,
3768 smSCSIRequest,
3769 satIOContext);
3770
3771 break;
3772
3773 case SCSIOPC_WRITE_BUFFER:
3774 SM_DBG5(("smsatIOStart: SCSIOPC_WRITE_BUFFER\n"));
3775 status = smsatWriteBuffer( smRoot,
3776 smIORequest,
3777 smDeviceHandle,
3778 smSCSIRequest,
3779 satIOContext);
3780
3781 break;
3782
3783 case SCSIOPC_REASSIGN_BLOCKS:
3784 SM_DBG5(("smsatIOStart: SCSIOPC_REASSIGN_BLOCKS\n"));
3785 status = smsatReassignBlocks( smRoot,
3786 smIORequest,
3787 smDeviceHandle,
3788 smSCSIRequest,
3789 satIOContext);
3790
3791 break;
3792
3793 case SCSIOPC_ATA_PASS_THROUGH12: /* fall through */
3794 case SCSIOPC_ATA_PASS_THROUGH16:
3795 SM_DBG5(("smsatIOStart: SCSIOPC_ATA_PASS_THROUGH\n"));
3796 status = smsatPassthrough( smRoot,
3797 smIORequest,
3798 smDeviceHandle,
3799 smSCSIRequest,
3800 satIOContext);
3801 break;
3802
3803 default:
3804 /* Not implemented SCSI cmd, set up error response */
3805 SM_DBG1(("smsatIOStart: unsupported SCSI cdb[0]=0x%x did=%d !!!\n",
3806 scsiCmnd->cdb[0], pSatDevData->id));
3807
3808 smsatSetSensePayload( pSense,
3809 SCSI_SNSKEY_ILLEGAL_REQUEST,
3810 0,
3811 SCSI_SNSCODE_INVALID_COMMAND,
3812 satIOContext);
3813
3814 /*smEnqueueIO(smRoot, satIOContext);*/
3815
3816 tdsmIOCompletedCB( smRoot,
3817 smIORequest,
3818 smIOSuccess,
3819 SCSI_STAT_CHECK_CONDITION,
3820 satIOContext->pSmSenseData,
3821 satIOContext->interruptContext );
3822 status = SM_RC_SUCCESS;
3823
3824 break;
3825
3826 } /* end switch */
3827 }
3828
3829 if (status == SM_RC_BUSY || status == SM_RC_DEVICE_BUSY)
3830 {
3831 SM_DBG1(("smsatIOStart: BUSY did %d!!!\n", pSatDevData->id));
3832 SM_DBG2(("smsatIOStart: LL is busy or target queue is full\n"));
3833 SM_DBG2(("smsatIOStart: device %p satPendingIO %d satNCQMaxIO %d\n",pSatDevData, pSatDevData->satPendingIO, pSatDevData->satNCQMaxIO ));
3834 SM_DBG2(("smsatIOStart: device %p satPendingNCQIO %d satPendingNONNCQIO %d\n",pSatDevData, pSatDevData->satPendingNCQIO, pSatDevData->satPendingNONNCQIO));
3835 pSatIntIo = satIOContext->satIntIoContext;
3836
3837 /*smEnqueueIO(smRoot, satIOContext);*/
3838
3839 /* interal structure free */
3840 smsatFreeIntIoResource( smRoot,
3841 pSatDevData,
3842 pSatIntIo);
3843 }
3844
3845 return status;
3846 }
3847
3848 osGLOBAL void
smsatSetSensePayload(smScsiRspSense_t * pSense,bit8 SnsKey,bit32 SnsInfo,bit16 SnsCode,smSatIOContext_t * satIOContext)3849 smsatSetSensePayload(
3850 smScsiRspSense_t *pSense,
3851 bit8 SnsKey,
3852 bit32 SnsInfo,
3853 bit16 SnsCode,
3854 smSatIOContext_t *satIOContext)
3855 {
3856 /* for fixed format sense data, SPC-4, p37 */
3857 bit32 i;
3858 bit32 senseLength;
3859 bit8 tmp = 0;
3860
3861 SM_DBG2(("smsatSetSensePayload: start\n"));
3862
3863 senseLength = sizeof(smScsiRspSense_t);
3864
3865 /* zero out the data area */
3866 for (i=0;i< senseLength;i++)
3867 {
3868 ((bit8*)pSense)[i] = 0;
3869 }
3870
3871 /*
3872 * SCSI Sense Data part of response data
3873 */
3874 pSense->snsRespCode = 0x70; /* 0xC0 == vendor specific */
3875 /* 0x70 == standard current error */
3876 pSense->senseKey = SnsKey;
3877 /*
3878 * Put sense info in scsi order format
3879 */
3880 pSense->info[0] = (bit8)((SnsInfo >> 24) & 0xff);
3881 pSense->info[1] = (bit8)((SnsInfo >> 16) & 0xff);
3882 pSense->info[2] = (bit8)((SnsInfo >> 8) & 0xff);
3883 pSense->info[3] = (bit8)((SnsInfo) & 0xff);
3884 pSense->addSenseLen = 11; /* fixed size of sense data = 18 */
3885 pSense->addSenseCode = (bit8)((SnsCode >> 8) & 0xFF);
3886 pSense->senseQual = (bit8)(SnsCode & 0xFF);
3887 /*
3888 * Set pointer in scsi status
3889 */
3890 switch(SnsKey)
3891 {
3892 /*
3893 * set illegal request sense key specific error in cdb, no bit pointer
3894 */
3895 case SCSI_SNSKEY_ILLEGAL_REQUEST:
3896 pSense->skeySpecific[0] = 0xC8;
3897 break;
3898
3899 default:
3900 break;
3901 }
3902 /* setting sense data length */
3903 if (satIOContext != agNULL)
3904 {
3905 satIOContext->pSmSenseData->senseLen = 18;
3906 }
3907 else
3908 {
3909 SM_DBG1(("smsatSetSensePayload: satIOContext is NULL!!!\n"));
3910 }
3911
3912 /* Only for SCSI_SNSCODE_ATA_PASS_THROUGH_INFORMATION_AVAILABLE */
3913 if (SnsCode == SCSI_SNSCODE_ATA_PASS_THROUGH_INFORMATION_AVAILABLE)
3914 {
3915 /* filling in COMMAND-SPECIFIC INFORMATION */
3916 tmp = satIOContext->extend << 7 | satIOContext->Sector_Cnt_Upper_Nonzero << 6 | satIOContext->LBA_Upper_Nonzero << 5;
3917 SM_DBG3(("smsatSetSensePayload: extend 0x%x Sector_Cnt_Upper_Nonzero 0x%x LBA_Upper_Nonzero 0x%x\n",
3918 satIOContext->extend, satIOContext->Sector_Cnt_Upper_Nonzero, satIOContext->LBA_Upper_Nonzero));
3919 SM_DBG3(("smsatSetSensePayload: tmp 0x%x\n", tmp));
3920 pSense->cmdSpecific[0] = tmp;
3921 pSense->cmdSpecific[1] = satIOContext->LBAHigh07;
3922 pSense->cmdSpecific[2] = satIOContext->LBAMid07;
3923 pSense->cmdSpecific[3] = satIOContext->LBALow07;
3924 // smhexdump("smsatSetSensePayload: cmdSpecific",(bit8 *)pSense->cmdSpecific, 4);
3925 // smhexdump("smsatSetSensePayload: info",(bit8 *)pSense->info, 4);
3926
3927 }
3928 return;
3929 }
3930
3931 /*****************************************************************************
3932 *! \brief smsatDecodeSATADeviceType
3933 *
3934 * This routine decodes ATA signature
3935 *
3936 * \param pSignature: ATA signature
3937 *
3938 *
3939 * \return:
3940 * TRUE if ATA signature
3941 * FALSE otherwise
3942 *
3943 *****************************************************************************/
3944 /*
3945 ATA p65
3946 PM p65
3947 SATAII p79, p80
3948 */
3949 GLOBAL bit32
smsatDecodeSATADeviceType(bit8 * pSignature)3950 smsatDecodeSATADeviceType(
3951 bit8 *pSignature
3952 )
3953 {
3954 bit32 deviceType = UNKNOWN_DEVICE;
3955
3956 if ( (pSignature)[0] == 0x01 && (pSignature)[1] == 0x01
3957 && (pSignature)[2] == 0x00 && (pSignature)[3] == 0x00
3958 && (pSignature)[4] == 0xA0 ) /* this is the signature of a Hitachi SATA HDD*/
3959 {
3960 deviceType = SATA_ATA_DEVICE;
3961 }
3962 else if ( (pSignature)[0] == 0x01 && (pSignature)[1] == 0x01
3963 && (pSignature)[2] == 0x00 && (pSignature)[3] == 0x00
3964 && (pSignature)[4] == 0x00 )
3965 {
3966 deviceType = SATA_ATA_DEVICE;
3967 }
3968 else if ( (pSignature)[0] == 0x01 && (pSignature)[1] == 0x01
3969 && (pSignature)[2] == 0x14 && (pSignature)[3] == 0xEB
3970 && ( (pSignature)[4] == 0x00 || (pSignature)[4] == 0x10) )
3971 {
3972 deviceType = SATA_ATAPI_DEVICE;
3973 }
3974 else if ( (pSignature)[0] == 0x01 && (pSignature)[1] == 0x01
3975 && (pSignature)[2] == 0x69 && (pSignature)[3] == 0x96
3976 && (pSignature)[4] == 0x00 )
3977 {
3978 deviceType = SATA_PM_DEVICE;
3979 }
3980 else if ( (pSignature)[0] == 0x01 && (pSignature)[1] == 0x01
3981 && (pSignature)[2] == 0x3C && (pSignature)[3] == 0xC3
3982 && (pSignature)[4] == 0x00 )
3983 {
3984 deviceType = SATA_SEMB_DEVICE;
3985 }
3986 else if ( (pSignature)[0] == 0xFF && (pSignature)[1] == 0xFF
3987 && (pSignature)[2] == 0xFF && (pSignature)[3] == 0xFF
3988 && (pSignature)[4] == 0xFF )
3989 {
3990 deviceType = SATA_SEMB_WO_SEP_DEVICE;
3991 }
3992
3993 return deviceType;
3994 }
3995
3996
3997 /*****************************************************************************/
3998 /*! \brief SAT implementation for ATAPI Packet Command.
3999 *
4000 * SAT implementation for ATAPI Packet and send FIS request to LL layer.
4001 *
4002 * \param tiRoot: Pointer to TISA initiator driver/port instance.
4003 * \param tiIORequest: Pointer to TISA I/O request context for this I/O.
4004 * \param tiDeviceHandle: Pointer to TISA device handle for this I/O.
4005 * \param tiScsiRequest: Pointer to TISA SCSI I/O request and SGL list.
4006 * \param smSatIOContext_t: Pointer to the SAT IO Context
4007 *
4008 * \return If command is started successfully
4009 * - \e smIOSuccess: I/O request successfully initiated.
4010 * - \e smIOBusy: No resources available, try again later.
4011 * - \e smIONoDevice: Invalid device handle.
4012 * - \e smIOError: Other errors.
4013 */
4014 /*****************************************************************************/
4015 osGLOBAL bit32
smsatPacket(smRoot_t * smRoot,smIORequest_t * smIORequest,smDeviceHandle_t * smDeviceHandle,smScsiInitiatorRequest_t * smScsiRequest,smSatIOContext_t * satIOContext)4016 smsatPacket(
4017 smRoot_t *smRoot,
4018 smIORequest_t *smIORequest,
4019 smDeviceHandle_t *smDeviceHandle,
4020 smScsiInitiatorRequest_t *smScsiRequest,
4021 smSatIOContext_t *satIOContext
4022 )
4023 {
4024 bit32 status;
4025 bit32 agRequestType = AGSA_SATA_PROTOCOL_D2H_PKT;
4026 smDeviceData_t *pSatDevData;
4027 smIniScsiCmnd_t *scsiCmnd;
4028 agsaFisRegHostToDevice_t *fis;
4029
4030 pSatDevData = satIOContext->pSatDevData;
4031 scsiCmnd = &smScsiRequest->scsiCmnd;
4032 fis = satIOContext->pFis;
4033
4034 SM_DBG3(("smsatPacket: start, SCSI CDB is 0x%X %X %X %X %X %X %X %X %X %X %X %X\n",
4035 scsiCmnd->cdb[0],scsiCmnd->cdb[1],scsiCmnd->cdb[2],scsiCmnd->cdb[3],
4036 scsiCmnd->cdb[4],scsiCmnd->cdb[5],scsiCmnd->cdb[6],scsiCmnd->cdb[7],
4037 scsiCmnd->cdb[8],scsiCmnd->cdb[9],scsiCmnd->cdb[10],scsiCmnd->cdb[11]));
4038
4039 fis->h.fisType = 0x27; /* Reg host to device */
4040 fis->h.c_pmPort = 0x80; /* C Bit is set 1*/
4041 fis->h.command = SAT_PACKET; /* 0xA0 */
4042 if (pSatDevData->satDMADIRSupport) /* DMADIR enabled*/
4043 {
4044 fis->h.features = (smScsiRequest->dataDirection == smDirectionIn)? 0x04 : 0; /* 1 for D2H, 0 for H2D */
4045 }
4046 else
4047 {
4048 fis->h.features = 0; /* FIS reserve */
4049 }
4050
4051 if (pSatDevData->satDMASupport == agTRUE && pSatDevData->satDMAEnabled == agTRUE)
4052 {
4053 /*DMA transfer mode*/
4054 fis->h.features |= 0x01;
4055 }
4056 else
4057 {
4058 /*PIO transfer mode*/
4059 fis->h.features |= 0x0;
4060 }
4061 /* Byte count low and byte count high */
4062 if ( scsiCmnd->expDataLength > 0xFFFF )
4063 {
4064 fis->d.lbaMid = 0xFF; /* FIS LBA (15:8 ) */
4065 fis->d.lbaHigh = 0xFF; /* FIS LBA (23:16) */
4066 }
4067 else
4068 {
4069 fis->d.lbaMid = (bit8)scsiCmnd->expDataLength; /* FIS LBA (15:8 ) */
4070 fis->d.lbaHigh = (bit8)(scsiCmnd->expDataLength>>8); /* FIS LBA (23:16) */
4071 }
4072
4073 fis->d.lbaLow = 0; /* FIS LBA (7 :0 ) */
4074 fis->d.device = 0; /* FIS LBA (27:24) and FIS LBA mode */
4075 fis->d.lbaLowExp = 0;
4076 fis->d.lbaMidExp = 0;
4077 fis->d.lbaHighExp = 0;
4078 fis->d.featuresExp = 0;
4079 fis->d.sectorCount = 0; /* FIS sector count (7:0) */
4080 fis->d.sectorCountExp = 0;
4081 fis->d.reserved4 = 0;
4082 fis->d.control = 0; /* FIS HOB bit clear */
4083 fis->d.reserved5 = 0;
4084
4085 satIOContext->ATACmd = SAT_PACKET;
4086
4087 if (smScsiRequest->dataDirection == smDirectionIn)
4088 {
4089 agRequestType = AGSA_SATA_PROTOCOL_D2H_PKT;
4090 }
4091 else
4092 {
4093 agRequestType = AGSA_SATA_PROTOCOL_H2D_PKT;
4094 }
4095
4096 satIOContext->satCompleteCB = &smsatPacketCB;
4097
4098 /*
4099 * Prepare SGL and send FIS to LL layer.
4100 */
4101 satIOContext->reqType = agRequestType; /* Save it */
4102
4103 status = smsataLLIOStart(smRoot,
4104 smIORequest,
4105 smDeviceHandle,
4106 smScsiRequest,
4107 satIOContext);
4108
4109 SM_DBG3(("smsatPacket: return\n"));
4110 return (status);
4111 }
4112
4113 /*****************************************************************************/
4114 /*! \brief SAT implementation for smsatSetFeaturePIO.
4115 *
4116 * This function creates Set Features fis and sends the request to LL layer
4117 *
4118 * \param tiRoot: Pointer to TISA initiator driver/port instance.
4119 * \param tiIORequest: Pointer to TISA I/O request context for this I/O.
4120 * \param tiDeviceHandle: Pointer to TISA device handle for this I/O.
4121 * \param tiScsiRequest: Pointer to TISA SCSI I/O request and SGL list.
4122 * \param smSatIOContext_t: Pointer to the SAT IO Context
4123 *
4124 * \return If command is started successfully
4125 * - \e smIOSuccess: I/O request successfully initiated.
4126 * - \e smIOBusy: No resources available, try again later.
4127 * - \e smIONoDevice: Invalid device handle.
4128 * - \e smIOError: Other errors.
4129 */
4130 /*****************************************************************************/
4131 osGLOBAL bit32
smsatSetFeaturesPIO(smRoot_t * smRoot,smIORequest_t * smIORequest,smDeviceHandle_t * smDeviceHandle,smScsiInitiatorRequest_t * smScsiRequest,smSatIOContext_t * satIOContext)4132 smsatSetFeaturesPIO(
4133 smRoot_t *smRoot,
4134 smIORequest_t *smIORequest,
4135 smDeviceHandle_t *smDeviceHandle,
4136 smScsiInitiatorRequest_t *smScsiRequest,
4137 smSatIOContext_t *satIOContext
4138 )
4139 {
4140 bit32 status = SM_RC_FAILURE;
4141 bit32 agRequestType;
4142 agsaFisRegHostToDevice_t *fis;
4143
4144 fis = satIOContext->pFis;
4145 SM_DBG2(("smsatSetFeaturesPIO: start\n"));
4146 /*
4147 * Send the Set Features command.
4148 */
4149 fis->h.fisType = 0x27; /* Reg host to device */
4150 fis->h.c_pmPort = 0x80; /* C Bit is set */
4151 fis->h.command = SAT_SET_FEATURES; /* 0xEF */
4152 fis->h.features = 0x03; /* set transfer mode */
4153 fis->d.lbaLow = 0;
4154 fis->d.lbaMid = 0;
4155 fis->d.lbaHigh = 0;
4156 fis->d.device = 0;
4157 fis->d.lbaLowExp = 0;
4158 fis->d.lbaMidExp = 0;
4159 fis->d.lbaHighExp = 0;
4160 fis->d.featuresExp = 0;
4161 fis->d.sectorCountExp = 0;
4162 fis->d.reserved4 = 0;
4163 fis->d.control = 0; /* FIS HOB bit clear */
4164 fis->d.reserved5 = 0;
4165
4166 agRequestType = AGSA_SATA_PROTOCOL_NON_DATA;
4167
4168 /* Initialize CB for SATA completion.
4169 */
4170 fis->d.sectorCount = 0x0C; /*enable PIO transfer mode */
4171 satIOContext->satCompleteCB = &smsatSetFeaturesPIOCB;
4172
4173 /*
4174 * Prepare SGL and send FIS to LL layer.
4175 */
4176 satIOContext->reqType = agRequestType; /* Save it */
4177
4178 status = smsataLLIOStart( smRoot,
4179 smIORequest,
4180 smDeviceHandle,
4181 smScsiRequest,
4182 satIOContext);
4183
4184 SM_DBG2(("smsatSetFeaturesPIO: return\n"));
4185 /* debugging code */
4186 if (smIORequest->tdData == smIORequest->smData)
4187 {
4188 SM_DBG1(("smsatSetFeaturesPIO: incorrect smIORequest\n"));
4189 }
4190
4191 return status;
4192 }
4193 /*****************************************************************************/
4194 /*! \brief SAT implementation for SCSI REQUEST SENSE to ATAPI device.
4195 *
4196 * SAT implementation for SCSI REQUEST SENSE.
4197 *
4198 * \param tiRoot: Pointer to TISA initiator driver/port instance.
4199 * \param tiIORequest: Pointer to TISA I/O request context for this I/O.
4200 * \param tiDeviceHandle: Pointer to TISA device handle for this I/O.
4201 * \param tiScsiRequest: Pointer to TISA SCSI I/O request and SGL list.
4202 * \param smSatIOContext_t: Pointer to the SAT IO Context
4203 *
4204 * \return If command is started successfully
4205 * - \e smIOSuccess: I/O request successfully initiated.
4206 * - \e smIOBusy: No resources available, try again later.
4207 * - \e smIONoDevice: Invalid device handle.
4208 * - \e smIOError: Other errors.
4209 */
4210 /*****************************************************************************/
4211 osGLOBAL bit32
smsatRequestSenseForATAPI(smRoot_t * smRoot,smIORequest_t * smIORequest,smDeviceHandle_t * smDeviceHandle,smScsiInitiatorRequest_t * smScsiRequest,smSatIOContext_t * satIOContext)4212 smsatRequestSenseForATAPI(
4213 smRoot_t *smRoot,
4214 smIORequest_t *smIORequest,
4215 smDeviceHandle_t *smDeviceHandle,
4216 smScsiInitiatorRequest_t *smScsiRequest,
4217 smSatIOContext_t *satIOContext
4218 )
4219 {
4220 bit32 status;
4221 bit32 agRequestType = AGSA_SATA_PROTOCOL_D2H_PKT;
4222 smDeviceData_t *pSatDevData;
4223 smIniScsiCmnd_t *scsiCmnd;
4224 agsaFisRegHostToDevice_t *fis;
4225
4226 pSatDevData = satIOContext->pSatDevData;
4227 scsiCmnd = &smScsiRequest->scsiCmnd;
4228 fis = satIOContext->pFis;
4229
4230 scsiCmnd->cdb[0] = SCSIOPC_REQUEST_SENSE;
4231 scsiCmnd->cdb[1] = 0;
4232 scsiCmnd->cdb[2] = 0;
4233 scsiCmnd->cdb[3] = 0;
4234 scsiCmnd->cdb[4] = (bit8)scsiCmnd->expDataLength;
4235 scsiCmnd->cdb[5] = 0;
4236 SM_DBG3(("smsatRequestSenseForATAPI: start, SCSI CDB is 0x%X %X %X %X %X %X %X %X %X %X %X %X\n",
4237 scsiCmnd->cdb[0],scsiCmnd->cdb[1],scsiCmnd->cdb[2],scsiCmnd->cdb[3],
4238 scsiCmnd->cdb[4],scsiCmnd->cdb[5],scsiCmnd->cdb[6],scsiCmnd->cdb[7],
4239 scsiCmnd->cdb[8],scsiCmnd->cdb[9],scsiCmnd->cdb[10],scsiCmnd->cdb[11]));
4240
4241 fis->h.fisType = 0x27; /* Reg host to device */
4242 fis->h.c_pmPort = 0x80; /* C Bit is set 1*/
4243 fis->h.command = SAT_PACKET; /* 0xA0 */
4244 if (pSatDevData->satDMADIRSupport) /* DMADIR enabled*/
4245 {
4246 fis->h.features = (smScsiRequest->dataDirection == smDirectionIn)? 0x04 : 0; /* 1 for D2H, 0 for H2D */
4247 }
4248 else
4249 {
4250 fis->h.features = 0; /* FIS reserve */
4251 }
4252
4253 if (pSatDevData->satDMASupport == agTRUE && pSatDevData->satDMAEnabled == agTRUE)
4254 {
4255 fis->h.features |= 0x01;
4256 }
4257 else
4258 {
4259 fis->h.features |= 0x0;
4260 }
4261
4262 fis->d.lbaLow = 0; /* FIS LBA (7 :0 ) */
4263 fis->d.lbaMid = (bit8)scsiCmnd->expDataLength; /* FIS LBA (15:8 ) */
4264 fis->d.lbaHigh = (bit8)(scsiCmnd->expDataLength>>8); /* FIS LBA (23:16) */
4265 fis->d.device = 0; /* FIS LBA (27:24) and FIS LBA mode */
4266 fis->d.lbaLowExp = 0;
4267 fis->d.lbaMidExp = 0;
4268 fis->d.lbaHighExp = 0;
4269 fis->d.featuresExp = 0;
4270 fis->d.sectorCount = 0; /* FIS sector count (7:0) */
4271 fis->d.sectorCountExp = 0;
4272 fis->d.reserved4 = 0;
4273 fis->d.control = 0; /* FIS HOB bit clear */
4274 fis->d.reserved5 = 0;
4275
4276 satIOContext->ATACmd = SAT_PACKET;
4277
4278 agRequestType = AGSA_SATA_PROTOCOL_D2H_PKT;
4279
4280
4281 satIOContext->satCompleteCB = &smsatRequestSenseForATAPICB;
4282
4283 /*
4284 * Prepare SGL and send FIS to LL layer.
4285 */
4286 satIOContext->reqType = agRequestType; /* Save it */
4287
4288 status = smsataLLIOStart( smRoot,
4289 smIORequest,
4290 smDeviceHandle,
4291 smScsiRequest,
4292 satIOContext);
4293
4294 SM_DBG3(("smsatRequestSenseForATAPI: return\n"));
4295 return (status);
4296 }
4297 /*****************************************************************************/
4298 /*! \brief SAT implementation for smsatDeviceReset.
4299 *
4300 * This function creates DEVICE RESET fis and sends the request to LL layer
4301 *
4302 * \param smRoot: Pointer to TISA initiator driver/port instance.
4303 * \param smIORequest: Pointer to TISA I/O request context for this I/O.
4304 * \param smDeviceHandle: Pointer to TISA device handle for this I/O.
4305 * \param smScsiRequest: Pointer to TISA SCSI I/O request and SGL list.
4306 * \param smSatIOContext_t: Pointer to the SAT IO Context
4307 *
4308 * \return If command is started successfully
4309 * - \e smIOSuccess: I/O request successfully initiated.
4310 * - \e smIOBusy: No resources available, try again later.
4311 * - \e smIONoDevice: Invalid device handle.
4312 * - \e smIOError: Other errors.
4313 */
4314 /*****************************************************************************/
4315 osGLOBAL bit32
smsatDeviceReset(smRoot_t * smRoot,smIORequest_t * smIORequest,smDeviceHandle_t * smDeviceHandle,smScsiInitiatorRequest_t * smScsiRequest,smSatIOContext_t * satIOContext)4316 smsatDeviceReset(
4317 smRoot_t *smRoot,
4318 smIORequest_t *smIORequest,
4319 smDeviceHandle_t *smDeviceHandle,
4320 smScsiInitiatorRequest_t *smScsiRequest,
4321 smSatIOContext_t *satIOContext
4322 )
4323 {
4324 bit32 status;
4325 bit32 agRequestType;
4326 agsaFisRegHostToDevice_t *fis;
4327
4328 fis = satIOContext->pFis;
4329 SM_DBG3(("smsatDeviceReset: start\n"));
4330 /*
4331 * Send the Execute Device Diagnostic command.
4332 */
4333 fis->h.fisType = 0x27; /* Reg host to device */
4334 fis->h.c_pmPort = 0x80; /* C Bit is set */
4335 fis->h.command = SAT_DEVICE_RESET; /* 0x08 */
4336 fis->h.features = 0;
4337 fis->d.lbaLow = 0;
4338 fis->d.lbaMid = 0;
4339 fis->d.lbaHigh = 0;
4340 fis->d.device = 0;
4341 fis->d.lbaLowExp = 0;
4342 fis->d.lbaMidExp = 0;
4343 fis->d.lbaHighExp = 0;
4344 fis->d.featuresExp = 0;
4345 fis->d.sectorCount = 0;
4346 fis->d.sectorCountExp = 0;
4347 fis->d.reserved4 = 0;
4348 fis->d.control = 0; /* FIS HOB bit clear */
4349 fis->d.reserved5 = 0;
4350
4351 agRequestType = AGSA_SATA_PROTOCOL_DEV_RESET;
4352
4353 /* Initialize CB for SATA completion.
4354 */
4355 satIOContext->satCompleteCB = &smsatDeviceResetCB;
4356
4357 /*
4358 * Prepare SGL and send FIS to LL layer.
4359 */
4360 satIOContext->reqType = agRequestType; /* Save it */
4361
4362 status = smsataLLIOStart( smRoot,
4363 smIORequest,
4364 smDeviceHandle,
4365 smScsiRequest,
4366 satIOContext);
4367
4368 SM_DBG3(("smsatDeviceReset: return\n"));
4369
4370 return status;
4371 }
4372
4373
4374 /*****************************************************************************/
4375 /*! \brief SAT implementation for smsatExecuteDeviceDiagnostic.
4376 *
4377 * This function creates Execute Device Diagnostic fis and sends the request to LL layer
4378 *
4379 * \param smRoot: Pointer to TISA initiator driver/port instance.
4380 * \param smIORequest: Pointer to TISA I/O request context for this I/O.
4381 * \param smDeviceHandle: Pointer to TISA device handle for this I/O.
4382 * \param smScsiRequest: Pointer to TISA SCSI I/O request and SGL list.
4383 * \param smSatIOContext_t: Pointer to the SAT IO Context
4384 *
4385 * \return If command is started successfully
4386 * - \e smIOSuccess: I/O request successfully initiated.
4387 * - \e smIOBusy: No resources available, try again later.
4388 * - \e smIONoDevice: Invalid device handle.
4389 * - \e smIOError: Other errors.
4390 */
4391 /*****************************************************************************/
4392 osGLOBAL bit32
smsatExecuteDeviceDiagnostic(smRoot_t * smRoot,smIORequest_t * smIORequest,smDeviceHandle_t * smDeviceHandle,smScsiInitiatorRequest_t * smScsiRequest,smSatIOContext_t * satIOContext)4393 smsatExecuteDeviceDiagnostic(
4394 smRoot_t *smRoot,
4395 smIORequest_t *smIORequest,
4396 smDeviceHandle_t *smDeviceHandle,
4397 smScsiInitiatorRequest_t *smScsiRequest,
4398 smSatIOContext_t *satIOContext
4399 )
4400 {
4401 bit32 status;
4402 bit32 agRequestType;
4403 agsaFisRegHostToDevice_t *fis;
4404
4405 fis = satIOContext->pFis;
4406 SM_DBG3(("smsatExecuteDeviceDiagnostic: start\n"));
4407 /*
4408 * Send the Execute Device Diagnostic command.
4409 */
4410 fis->h.fisType = 0x27; /* Reg host to device */
4411 fis->h.c_pmPort = 0x80; /* C Bit is set */
4412 fis->h.command = SAT_EXECUTE_DEVICE_DIAGNOSTIC; /* 0x90 */
4413 fis->h.features = 0;
4414 fis->d.lbaLow = 0;
4415 fis->d.lbaMid = 0;
4416 fis->d.lbaHigh = 0;
4417 fis->d.device = 0;
4418 fis->d.lbaLowExp = 0;
4419 fis->d.lbaMidExp = 0;
4420 fis->d.lbaHighExp = 0;
4421 fis->d.featuresExp = 0;
4422 fis->d.sectorCount = 0;
4423 fis->d.sectorCountExp = 0;
4424 fis->d.reserved4 = 0;
4425 fis->d.control = 0; /* FIS HOB bit clear */
4426 fis->d.reserved5 = 0;
4427
4428 agRequestType = AGSA_SATA_PROTOCOL_NON_DATA;
4429
4430 /* Initialize CB for SATA completion.
4431 */
4432 satIOContext->satCompleteCB = &smsatExecuteDeviceDiagnosticCB;
4433
4434 /*
4435 * Prepare SGL and send FIS to LL layer.
4436 */
4437 satIOContext->reqType = agRequestType; /* Save it */
4438
4439 status = smsataLLIOStart( smRoot,
4440 smIORequest,
4441 smDeviceHandle,
4442 smScsiRequest,
4443 satIOContext);
4444
4445 SM_DBG3(("smsatExecuteDeviceDiagnostic: return\n"));
4446
4447 return status;
4448 }
4449
4450
4451 osGLOBAL void
smsatSetDeferredSensePayload(smScsiRspSense_t * pSense,bit8 SnsKey,bit32 SnsInfo,bit16 SnsCode,smSatIOContext_t * satIOContext)4452 smsatSetDeferredSensePayload(
4453 smScsiRspSense_t *pSense,
4454 bit8 SnsKey,
4455 bit32 SnsInfo,
4456 bit16 SnsCode,
4457 smSatIOContext_t *satIOContext
4458 )
4459 {
4460 SM_DBG2(("smsatSetDeferredSensePayload: start\n"));
4461 return;
4462 }
4463
4464
4465 GLOBAL bit32
smsatRead6(smRoot_t * smRoot,smIORequest_t * smIORequest,smDeviceHandle_t * smDeviceHandle,smScsiInitiatorRequest_t * smScsiRequest,smSatIOContext_t * satIOContext)4466 smsatRead6(
4467 smRoot_t *smRoot,
4468 smIORequest_t *smIORequest,
4469 smDeviceHandle_t *smDeviceHandle,
4470 smScsiInitiatorRequest_t *smScsiRequest,
4471 smSatIOContext_t *satIOContext
4472 )
4473 {
4474 bit32 status;
4475 bit32 agRequestType = AGSA_SATA_PROTOCOL_DMA_READ;
4476 smDeviceData_t *pSatDevData;
4477 smScsiRspSense_t *pSense;
4478 smIniScsiCmnd_t *scsiCmnd;
4479 agsaFisRegHostToDevice_t *fis;
4480 bit32 lba = 0;
4481 bit16 tl = 0;
4482
4483 pSense = satIOContext->pSense;
4484 pSatDevData = satIOContext->pSatDevData;
4485 scsiCmnd = &smScsiRequest->scsiCmnd;
4486 fis = satIOContext->pFis;
4487
4488 SM_DBG2(("smsatRead6: start\n"));
4489
4490 /* no FUA checking since read6 */
4491
4492
4493 /* checking CONTROL */
4494 /* NACA == 1 or LINK == 1*/
4495 if ( (scsiCmnd->cdb[5] & SCSI_NACA_MASK) || (scsiCmnd->cdb[5] & SCSI_LINK_MASK) )
4496 {
4497 smsatSetSensePayload( pSense,
4498 SCSI_SNSKEY_ILLEGAL_REQUEST,
4499 0,
4500 SCSI_SNSCODE_INVALID_FIELD_IN_CDB,
4501 satIOContext);
4502
4503 /*smEnqueueIO(smRoot, satIOContext);*/
4504
4505 tdsmIOCompletedCB( smRoot,
4506 smIORequest,
4507 smIOSuccess,
4508 SCSI_STAT_CHECK_CONDITION,
4509 satIOContext->pSmSenseData,
4510 satIOContext->interruptContext );
4511
4512 SM_DBG1(("smsatRead6: return control!!!\n"));
4513 return SM_RC_SUCCESS;
4514 }
4515
4516 /* cbd6; computing LBA and transfer length */
4517 lba = (((scsiCmnd->cdb[1]) & 0x1f) << (8*2))
4518 + (scsiCmnd->cdb[2] << 8) + scsiCmnd->cdb[3];
4519 tl = scsiCmnd->cdb[4];
4520
4521 /* Table 34, 9.1, p 46 */
4522 /*
4523 note: As of 2/10/2006, no support for DMA QUEUED
4524 */
4525
4526 /*
4527 Table 34, 9.1, p 46, b
4528 When no 48-bit addressing support or NCQ, if LBA is beyond (2^28 - 1),
4529 return check condition
4530 */
4531 if (pSatDevData->satNCQ != agTRUE &&
4532 pSatDevData->sat48BitSupport != agTRUE
4533 )
4534 {
4535 if (lba > SAT_TR_LBA_LIMIT - 1)
4536 {
4537 smsatSetSensePayload( pSense,
4538 SCSI_SNSKEY_ILLEGAL_REQUEST,
4539 0,
4540 SCSI_SNSCODE_LOGICAL_BLOCK_ADDRESS_OUT_OF_RANGE,
4541 satIOContext);
4542
4543 /*smEnqueueIO(smRoot, satIOContext);*/
4544
4545 tdsmIOCompletedCB( smRoot,
4546 smIORequest,
4547 smIOSuccess,
4548 SCSI_STAT_CHECK_CONDITION,
4549 satIOContext->pSmSenseData,
4550 satIOContext->interruptContext );
4551
4552 SM_DBG1(("smsatRead6: return LBA out of range!!!\n"));
4553 return SM_RC_SUCCESS;
4554 }
4555 }
4556
4557 /* case 1 and 2 */
4558 if (lba + tl <= SAT_TR_LBA_LIMIT)
4559 {
4560 if (pSatDevData->satDMASupport == agTRUE && pSatDevData->satDMAEnabled == agTRUE)
4561 {
4562 /* case 2 */
4563 /* READ DMA*/
4564 SM_DBG5(("smsatRead6: case 2\n"));
4565
4566
4567 fis->h.fisType = 0x27; /* Reg host to device */
4568 fis->h.c_pmPort = 0x80; /* C Bit is set */
4569 fis->h.command = SAT_READ_DMA; /* 0xC8 */
4570 fis->h.features = 0; /* FIS reserve */
4571 fis->d.lbaLow = scsiCmnd->cdb[3]; /* FIS LBA (7 :0 ) */
4572 fis->d.lbaMid = scsiCmnd->cdb[2]; /* FIS LBA (15:8 ) */
4573 fis->d.lbaHigh = (bit8)((scsiCmnd->cdb[1]) & 0x1f); /* FIS LBA (23:16) */
4574 fis->d.device = 0x40; /* FIS LBA mode */
4575 fis->d.lbaLowExp = 0;
4576 fis->d.lbaMidExp = 0;
4577 fis->d.lbaHighExp = 0;
4578 fis->d.featuresExp = 0;
4579 if (tl == 0)
4580 {
4581 /* temporary fix */
4582 fis->d.sectorCount = 0xff; /* FIS sector count (7:0) */
4583 }
4584 else
4585 {
4586 fis->d.sectorCount = scsiCmnd->cdb[4]; /* FIS sector count (7:0) */
4587 }
4588 fis->d.sectorCountExp = 0;
4589 fis->d.reserved4 = 0;
4590 fis->d.control = 0; /* FIS HOB bit clear */
4591 fis->d.reserved5 = 0;
4592
4593 agRequestType = AGSA_SATA_PROTOCOL_DMA_READ;
4594 }
4595 else
4596 {
4597 /* case 1 */
4598 /* READ SECTORS for easier implemetation */
4599 SM_DBG5(("smsatRead6: case 1\n"));
4600
4601 fis->h.fisType = 0x27; /* Reg host to device */
4602 fis->h.c_pmPort = 0x80; /* C Bit is set */
4603 fis->h.command = SAT_READ_SECTORS; /* 0x20 */
4604 fis->h.features = 0; /* FIS reserve */
4605 fis->d.lbaLow = scsiCmnd->cdb[3]; /* FIS LBA (7 :0 ) */
4606 fis->d.lbaMid = scsiCmnd->cdb[2]; /* FIS LBA (15:8 ) */
4607 fis->d.lbaHigh = (bit8)((scsiCmnd->cdb[1]) & 0x1f); /* FIS LBA (23:16) */
4608 fis->d.device = 0x40; /* FIS LBA mode */
4609 fis->d.lbaLowExp = 0;
4610 fis->d.lbaMidExp = 0;
4611 fis->d.lbaHighExp = 0;
4612 fis->d.featuresExp = 0;
4613 if (tl == 0)
4614 {
4615 /* temporary fix */
4616 fis->d.sectorCount = 0xff; /* FIS sector count (7:0) */
4617 }
4618 else
4619 {
4620 fis->d.sectorCount = scsiCmnd->cdb[4]; /* FIS sector count (7:0) */
4621 }
4622 fis->d.sectorCountExp = 0;
4623 fis->d.reserved4 = 0;
4624 fis->d.control = 0; /* FIS HOB bit clear */
4625 fis->d.reserved5 = 0;
4626
4627 agRequestType = AGSA_SATA_PROTOCOL_PIO_READ;
4628
4629 }
4630 }
4631
4632 /* case 3 and 4 */
4633 if (pSatDevData->sat48BitSupport == agTRUE)
4634 {
4635 if (pSatDevData->satDMASupport == agTRUE && pSatDevData->satDMAEnabled == agTRUE)
4636 {
4637 /* case 3 */
4638 /* READ DMA EXT only */
4639 SM_DBG5(("smsatRead6: case 3\n"));
4640 fis->h.fisType = 0x27; /* Reg host to device */
4641 fis->h.c_pmPort = 0x80; /* C Bit is set */
4642 fis->h.command = SAT_READ_DMA_EXT; /* 0x25 */
4643 fis->h.features = 0; /* FIS reserve */
4644 fis->d.lbaLow = scsiCmnd->cdb[3]; /* FIS LBA (7 :0 ) */
4645 fis->d.lbaMid = scsiCmnd->cdb[2]; /* FIS LBA (15:8 ) */
4646 fis->d.lbaHigh = (bit8)((scsiCmnd->cdb[1]) & 0x1f); /* FIS LBA (23:16) */
4647 fis->d.device = 0x40; /* FIS LBA mode set */
4648 fis->d.lbaLowExp = 0; /* FIS LBA (31:24) */
4649 fis->d.lbaMidExp = 0; /* FIS LBA (39:32) */
4650 fis->d.lbaHighExp = 0; /* FIS LBA (47:40) */
4651 fis->d.featuresExp = 0; /* FIS reserve */
4652 if (tl == 0)
4653 {
4654 /* sector count is 256, 0x100*/
4655 fis->d.sectorCount = 0; /* FIS sector count (7:0) */
4656 fis->d.sectorCountExp = 0x01; /* FIS sector count (15:8) */
4657 }
4658 else
4659 {
4660 fis->d.sectorCount = scsiCmnd->cdb[4]; /* FIS sector count (7:0) */
4661 fis->d.sectorCountExp = 0; /* FIS sector count (15:8) */
4662 }
4663 fis->d.reserved4 = 0;
4664 fis->d.control = 0; /* FIS HOB bit clear */
4665 fis->d.reserved5 = 0;
4666
4667 agRequestType = AGSA_SATA_PROTOCOL_DMA_READ;
4668 }
4669 else
4670 {
4671 /* case 4 */
4672 /* READ SECTORS EXT for easier implemetation */
4673 SM_DBG5(("smsatRead6: case 4\n"));
4674
4675 fis->h.fisType = 0x27; /* Reg host to device */
4676 fis->h.c_pmPort = 0x80; /* C Bit is set */
4677 fis->h.command = SAT_READ_SECTORS_EXT; /* 0x24 */
4678 fis->h.features = 0; /* FIS reserve */
4679 fis->d.lbaLow = scsiCmnd->cdb[3]; /* FIS LBA (7 :0 ) */
4680 fis->d.lbaMid = scsiCmnd->cdb[2]; /* FIS LBA (15:8 ) */
4681 fis->d.lbaHigh = (bit8)((scsiCmnd->cdb[1]) & 0x1f); /* FIS LBA (23:16) */
4682 fis->d.device = 0x40; /* FIS LBA mode set */
4683 fis->d.lbaLowExp = 0; /* FIS LBA (31:24) */
4684 fis->d.lbaMidExp = 0; /* FIS LBA (39:32) */
4685 fis->d.lbaHighExp = 0; /* FIS LBA (47:40) */
4686 fis->d.featuresExp = 0; /* FIS reserve */
4687 if (tl == 0)
4688 {
4689 /* sector count is 256, 0x100*/
4690 fis->d.sectorCount = 0; /* FIS sector count (7:0) */
4691 fis->d.sectorCountExp = 0x01; /* FIS sector count (15:8) */
4692 }
4693 else
4694 {
4695 fis->d.sectorCount = scsiCmnd->cdb[4]; /* FIS sector count (7:0) */
4696 fis->d.sectorCountExp = 0; /* FIS sector count (15:8) */
4697 }
4698 fis->d.reserved4 = 0;
4699 fis->d.control = 0; /* FIS HOB bit clear */
4700 fis->d.reserved5 = 0;
4701
4702 agRequestType = AGSA_SATA_PROTOCOL_PIO_READ;
4703 }
4704 }
4705
4706 /* case 5 */
4707 if (pSatDevData->satNCQ == agTRUE)
4708 {
4709 /* READ FPDMA QUEUED */
4710 if (pSatDevData->sat48BitSupport != agTRUE)
4711 {
4712 /* sanity check */
4713 SM_DBG1(("smsatRead6: case 5 !!! error NCQ but 28 bit address support!!!\n"));
4714 smsatSetSensePayload( pSense,
4715 SCSI_SNSKEY_ILLEGAL_REQUEST,
4716 0,
4717 SCSI_SNSCODE_INVALID_FIELD_IN_CDB,
4718 satIOContext);
4719
4720 /*smEnqueueIO(smRoot, satIOContext);*/
4721
4722 tdsmIOCompletedCB( smRoot,
4723 smIORequest,
4724 smIOSuccess,
4725 SCSI_STAT_CHECK_CONDITION,
4726 satIOContext->pSmSenseData,
4727 satIOContext->interruptContext );
4728 return SM_RC_SUCCESS;
4729 }
4730 SM_DBG5(("smsatRead6: case 5\n"));
4731
4732 /* Support 48-bit FPDMA addressing, use READ FPDMA QUEUE command */
4733
4734 fis->h.fisType = 0x27; /* Reg host to device */
4735 fis->h.c_pmPort = 0x80; /* C Bit is set */
4736 fis->h.command = SAT_READ_FPDMA_QUEUED; /* 0x60 */
4737 fis->d.lbaLow = scsiCmnd->cdb[3]; /* FIS LBA (7 :0 ) */
4738 fis->d.lbaMid = scsiCmnd->cdb[2]; /* FIS LBA (15:8 ) */
4739 fis->d.lbaHigh = (bit8)((scsiCmnd->cdb[1]) & 0x1f); /* FIS LBA (23:16) */
4740 fis->d.device = 0x40; /* FIS FUA clear */
4741 fis->d.lbaLowExp = 0; /* FIS LBA (31:24) */
4742 fis->d.lbaMidExp = 0; /* FIS LBA (39:32) */
4743 fis->d.lbaHighExp = 0; /* FIS LBA (47:40) */
4744 if (tl == 0)
4745 {
4746 /* sector count is 256, 0x100*/
4747 fis->h.features = 0; /* FIS sector count (7:0) */
4748 fis->d.featuresExp = 0x01; /* FIS sector count (15:8) */
4749 }
4750 else
4751 {
4752 fis->h.features = scsiCmnd->cdb[4]; /* FIS sector count (7:0) */
4753 fis->d.featuresExp = 0; /* FIS sector count (15:8) */
4754 }
4755 fis->d.sectorCount = 0; /* Tag (7:3) set by LL layer */
4756 fis->d.sectorCountExp = 0;
4757 fis->d.reserved4 = 0;
4758 fis->d.control = 0; /* FIS HOB bit clear */
4759 fis->d.reserved5 = 0;
4760
4761 agRequestType = AGSA_SATA_PROTOCOL_FPDMA_READ;
4762 }
4763
4764 /* Initialize CB for SATA completion.
4765 */
4766 satIOContext->satCompleteCB = &smsatNonChainedDataIOCB;
4767
4768 /*
4769 * Prepare SGL and send FIS to LL layer.
4770 */
4771 satIOContext->reqType = agRequestType; /* Save it */
4772
4773 status = smsataLLIOStart( smRoot,
4774 smIORequest,
4775 smDeviceHandle,
4776 smScsiRequest,
4777 satIOContext);
4778 return (status);
4779
4780 }
4781
4782 osGLOBAL FORCEINLINE bit32
smsatRead10(smRoot_t * smRoot,smIORequest_t * smIORequest,smDeviceHandle_t * smDeviceHandle,smScsiInitiatorRequest_t * smScsiRequest,smSatIOContext_t * satIOContext)4783 smsatRead10(
4784 smRoot_t *smRoot,
4785 smIORequest_t *smIORequest,
4786 smDeviceHandle_t *smDeviceHandle,
4787 smScsiInitiatorRequest_t *smScsiRequest,
4788 smSatIOContext_t *satIOContext
4789 )
4790 {
4791 smDeviceData_t *pSatDevData = satIOContext->pSatDevData;
4792 smScsiRspSense_t *pSense = satIOContext->pSense;
4793 smIniScsiCmnd_t *scsiCmnd = &smScsiRequest->scsiCmnd;
4794 agsaFisRegHostToDevice_t *fis = satIOContext->pFis;
4795
4796 bit32 status;
4797 bit32 agRequestType = AGSA_SATA_PROTOCOL_DMA_READ;
4798 bit32 lba = 0;
4799 bit32 tl = 0;
4800 bit32 LoopNum = 1;
4801 bit8 LBA[8];
4802 bit8 TL[8];
4803 bit32 AllChk = agFALSE; /* lba, lba+tl check against ATA limit and Disk capacity */
4804
4805 SM_DBG2(("smsatRead10: start\n"));
4806 SM_DBG2(("smsatRead10: pSatDevData did=%d\n", pSatDevData->id));
4807 // smhexdump("smsatRead10", (bit8 *)scsiCmnd->cdb, 10);
4808
4809 /* checking FUA_NV */
4810 if (scsiCmnd->cdb[1] & SCSI_FUA_NV_MASK)
4811 {
4812 smsatSetSensePayload( pSense,
4813 SCSI_SNSKEY_ILLEGAL_REQUEST,
4814 0,
4815 SCSI_SNSCODE_INVALID_FIELD_IN_CDB,
4816 satIOContext);
4817
4818 /*smEnqueueIO(smRoot, satIOContext);*/
4819
4820 tdsmIOCompletedCB( smRoot,
4821 smIORequest,
4822 smIOSuccess,
4823 SCSI_STAT_CHECK_CONDITION,
4824 satIOContext->pSmSenseData,
4825 satIOContext->interruptContext );
4826
4827 SM_DBG1(("smsatRead10: return FUA_NV!!!\n"));
4828 return SM_RC_SUCCESS;
4829
4830 }
4831
4832 /* checking CONTROL */
4833 /* NACA == 1 or LINK == 1*/
4834 if ( (scsiCmnd->cdb[9] & SCSI_NACA_MASK) || (scsiCmnd->cdb[9] & SCSI_LINK_MASK) )
4835 {
4836 smsatSetSensePayload( pSense,
4837 SCSI_SNSKEY_ILLEGAL_REQUEST,
4838 0,
4839 SCSI_SNSCODE_INVALID_FIELD_IN_CDB,
4840 satIOContext);
4841
4842 /*smEnqueueIO(smRoot, satIOContext);*/
4843
4844 tdsmIOCompletedCB( smRoot,
4845 smIORequest,
4846 smIOSuccess,
4847 SCSI_STAT_CHECK_CONDITION,
4848 satIOContext->pSmSenseData,
4849 satIOContext->interruptContext );
4850
4851 SM_DBG1(("smsatRead10: return control!!!\n"));
4852 return SM_RC_SUCCESS;
4853 }
4854 /*
4855 sm_memset(LBA, 0, sizeof(LBA));
4856 sm_memset(TL, 0, sizeof(TL));
4857 */
4858 /* do not use memcpy due to indexing in LBA and TL */
4859 LBA[0] = 0; /* MSB */
4860 LBA[1] = 0;
4861 LBA[2] = 0;
4862 LBA[3] = 0;
4863 LBA[4] = scsiCmnd->cdb[2];
4864 LBA[5] = scsiCmnd->cdb[3];
4865 LBA[6] = scsiCmnd->cdb[4];
4866 LBA[7] = scsiCmnd->cdb[5]; /* LSB */
4867
4868 TL[0] = 0;
4869 TL[1] = 0;
4870 TL[2] = 0;
4871 TL[3] = 0;
4872 TL[4] = 0;
4873 TL[5] = 0;
4874 TL[6] = scsiCmnd->cdb[7];
4875 TL[7] = scsiCmnd->cdb[8]; /* LSB */
4876
4877
4878 /* cbd10; computing LBA and transfer length */
4879 lba = (scsiCmnd->cdb[2] << 24) + (scsiCmnd->cdb[3] << 16)
4880 + (scsiCmnd->cdb[4] << 8) + scsiCmnd->cdb[5];
4881 tl = (scsiCmnd->cdb[7] << 8) + scsiCmnd->cdb[8];
4882
4883
4884 SM_DBG5(("smsatRead10: lba %d functioned lba %d\n", lba, smsatComputeCDB10LBA(satIOContext)));
4885 SM_DBG5(("smsatRead10: lba 0x%x functioned lba 0x%x\n", lba, smsatComputeCDB10LBA(satIOContext)));
4886 SM_DBG5(("smsatRead10: tl %d functioned tl %d\n", tl, smsatComputeCDB10TL(satIOContext)));
4887
4888 /* Table 34, 9.1, p 46 */
4889 /*
4890 note: As of 2/10/2006, no support for DMA QUEUED
4891 */
4892
4893 /*
4894 Table 34, 9.1, p 46, b
4895 When no 48-bit addressing support or NCQ, if LBA is beyond (2^28 - 1),
4896 return check condition
4897 */
4898
4899 if (pSatDevData->satNCQ != agTRUE &&
4900 pSatDevData->sat48BitSupport != agTRUE
4901 )
4902 {
4903 AllChk = smsatCheckLimit(LBA, TL, agFALSE, pSatDevData);
4904 if (AllChk)
4905 {
4906 SM_DBG1(("smsatRead10: return LBA out of range, not EXT!!!\n"));
4907 smsatSetSensePayload( pSense,
4908 SCSI_SNSKEY_ILLEGAL_REQUEST,
4909 0,
4910 SCSI_SNSCODE_LOGICAL_BLOCK_ADDRESS_OUT_OF_RANGE,
4911 satIOContext);
4912
4913 /*smEnqueueIO(smRoot, satIOContext);*/
4914
4915 tdsmIOCompletedCB( smRoot,
4916 smIORequest,
4917 smIOSuccess,
4918 SCSI_STAT_CHECK_CONDITION,
4919 satIOContext->pSmSenseData,
4920 satIOContext->interruptContext );
4921
4922 return SM_RC_SUCCESS;
4923 }
4924 }
4925 else
4926 {
4927 AllChk = smsatCheckLimit(LBA, TL, agTRUE, pSatDevData);
4928 if (AllChk)
4929 {
4930 SM_DBG1(("smsatRead10: return LBA out of range, EXT!!!\n"));
4931 smsatSetSensePayload( pSense,
4932 SCSI_SNSKEY_ILLEGAL_REQUEST,
4933 0,
4934 SCSI_SNSCODE_LOGICAL_BLOCK_ADDRESS_OUT_OF_RANGE,
4935 satIOContext);
4936
4937 /*smEnqueueIO(smRoot, satIOContext);*/
4938
4939 tdsmIOCompletedCB( smRoot,
4940 smIORequest,
4941 smIOSuccess,
4942 SCSI_STAT_CHECK_CONDITION,
4943 satIOContext->pSmSenseData,
4944 satIOContext->interruptContext );
4945
4946 return SM_RC_SUCCESS;
4947 }
4948 }
4949 /* case 5 */
4950 if (pSatDevData->satNCQ == agTRUE)
4951 {
4952 /* READ FPDMA QUEUED */
4953 if (pSatDevData->sat48BitSupport != agTRUE)
4954 {
4955 SM_DBG1(("smsatRead10: case 5 !!! error NCQ but 28 bit address support!!!\n"));
4956 smsatSetSensePayload( pSense,
4957 SCSI_SNSKEY_ILLEGAL_REQUEST,
4958 0,
4959 SCSI_SNSCODE_INVALID_FIELD_IN_CDB,
4960 satIOContext);
4961
4962 /*smEnqueueIO(smRoot, satIOContext);*/
4963
4964 tdsmIOCompletedCB( smRoot,
4965 smIORequest,
4966 smIOSuccess,
4967 SCSI_STAT_CHECK_CONDITION,
4968 satIOContext->pSmSenseData,
4969 satIOContext->interruptContext );
4970 return SM_RC_SUCCESS;
4971 }
4972
4973 SM_DBG6(("smsatRead10: case 5\n"));
4974
4975 /* Support 48-bit FPDMA addressing, use READ FPDMA QUEUE command */
4976
4977 fis->h.fisType = 0x27; /* Reg host to device */
4978 fis->h.c_pmPort = 0x80; /* C Bit is set */
4979 fis->h.command = SAT_READ_FPDMA_QUEUED; /* 0x60 */
4980 fis->h.features = scsiCmnd->cdb[8]; /* FIS sector count (7:0) */
4981 fis->d.lbaLow = scsiCmnd->cdb[5]; /* FIS LBA (7 :0 ) */
4982 fis->d.lbaMid = scsiCmnd->cdb[4]; /* FIS LBA (15:8 ) */
4983 fis->d.lbaHigh = scsiCmnd->cdb[3]; /* FIS LBA (23:16) */
4984
4985 /* Check FUA bit */
4986 if (scsiCmnd->cdb[1] & SCSI_READ10_FUA_MASK)
4987 fis->d.device = 0xC0; /* FIS FUA set */
4988 else
4989 fis->d.device = 0x40; /* FIS FUA clear */
4990
4991 fis->d.lbaLowExp = scsiCmnd->cdb[2]; /* FIS LBA (31:24) */
4992 fis->d.lbaMidExp = 0; /* FIS LBA (39:32) */
4993 fis->d.lbaHighExp = 0; /* FIS LBA (47:40) */
4994 fis->d.featuresExp = scsiCmnd->cdb[7]; /* FIS sector count (15:8) */
4995 fis->d.sectorCount = 0; /* Tag (7:3) set by LL layer */
4996 fis->d.sectorCountExp = 0;
4997 fis->d.reserved4 = 0;
4998 fis->d.control = 0; /* FIS HOB bit clear */
4999 fis->d.reserved5 = 0;
5000
5001 agRequestType = AGSA_SATA_PROTOCOL_FPDMA_READ;
5002 satIOContext->ATACmd = SAT_READ_FPDMA_QUEUED;
5003 }
5004 else if (pSatDevData->sat48BitSupport == agTRUE) /* case 3 and 4 */
5005 {
5006 if (pSatDevData->satDMASupport == agTRUE && pSatDevData->satDMAEnabled == agTRUE)
5007 {
5008 /* case 3 */
5009 /* READ DMA EXT */
5010 SM_DBG5(("smsatRead10: case 3\n"));
5011 fis->h.fisType = 0x27; /* Reg host to device */
5012
5013 fis->h.c_pmPort = 0x80; /* C Bit is set */
5014 fis->h.command = SAT_READ_DMA_EXT; /* 0x25 */
5015 fis->h.features = 0; /* FIS reserve */
5016 fis->d.lbaLow = scsiCmnd->cdb[5]; /* FIS LBA (7 :0 ) */
5017 fis->d.lbaMid = scsiCmnd->cdb[4]; /* FIS LBA (15:8 ) */
5018 fis->d.lbaHigh = scsiCmnd->cdb[3]; /* FIS LBA (23:16) */
5019 fis->d.device = 0x40; /* FIS LBA mode set */
5020 fis->d.lbaLowExp = scsiCmnd->cdb[2]; /* FIS LBA (31:24) */
5021 fis->d.lbaMidExp = 0; /* FIS LBA (39:32) */
5022 fis->d.lbaHighExp = 0; /* FIS LBA (47:40) */
5023 fis->d.featuresExp = 0; /* FIS reserve */
5024 fis->d.sectorCount = scsiCmnd->cdb[8]; /* FIS sector count (7:0) */
5025 fis->d.sectorCountExp = scsiCmnd->cdb[7]; /* FIS sector count (15:8) */
5026 fis->d.reserved4 = 0;
5027 fis->d.control = 0; /* FIS HOB bit clear */
5028 fis->d.reserved5 = 0;
5029
5030 agRequestType = AGSA_SATA_PROTOCOL_DMA_READ;
5031 satIOContext->ATACmd = SAT_READ_DMA_EXT;
5032
5033 }
5034 else
5035 {
5036 /* case 4 */
5037 /* READ MULTIPLE EXT or READ SECTOR(S) EXT or READ VERIFY SECTOR(S) EXT*/
5038 /* READ SECTORS EXT for easier implemetation */
5039 SM_DBG5(("smsatRead10: case 4\n"));
5040 fis->h.fisType = 0x27; /* Reg host to device */
5041 fis->h.c_pmPort = 0x80; /* C Bit is set */
5042
5043 /* Check FUA bit */
5044 if (scsiCmnd->cdb[1] & SCSI_READ10_FUA_MASK)
5045 {
5046
5047 /* for now, no support for FUA */
5048 smsatSetSensePayload( pSense,
5049 SCSI_SNSKEY_ILLEGAL_REQUEST,
5050 0,
5051 SCSI_SNSCODE_INVALID_FIELD_IN_CDB,
5052 satIOContext);
5053
5054 /*smEnqueueIO(smRoot, satIOContext);*/
5055
5056 tdsmIOCompletedCB( smRoot,
5057 smIORequest,
5058 smIOSuccess,
5059 SCSI_STAT_CHECK_CONDITION,
5060 satIOContext->pSmSenseData,
5061 satIOContext->interruptContext );
5062 return SM_RC_SUCCESS;
5063 }
5064
5065 fis->h.command = SAT_READ_SECTORS_EXT; /* 0x24 */
5066
5067 fis->h.features = 0; /* FIS reserve */
5068 fis->d.lbaLow = scsiCmnd->cdb[5]; /* FIS LBA (7 :0 ) */
5069 fis->d.lbaMid = scsiCmnd->cdb[4]; /* FIS LBA (15:8 ) */
5070 fis->d.lbaHigh = scsiCmnd->cdb[3]; /* FIS LBA (23:16) */
5071 fis->d.device = 0x40; /* FIS LBA mode set */
5072 fis->d.lbaLowExp = scsiCmnd->cdb[2]; /* FIS LBA (31:24) */
5073 fis->d.lbaMidExp = 0; /* FIS LBA (39:32) */
5074 fis->d.lbaHighExp = 0; /* FIS LBA (47:40) */
5075 fis->d.featuresExp = 0; /* FIS reserve */
5076 fis->d.sectorCount = scsiCmnd->cdb[8]; /* FIS sector count (7:0) */
5077 fis->d.sectorCountExp = scsiCmnd->cdb[7]; /* FIS sector count (15:8) */
5078 fis->d.reserved4 = 0;
5079 fis->d.control = 0; /* FIS HOB bit clear */
5080 fis->d.reserved5 = 0;
5081
5082 agRequestType = AGSA_SATA_PROTOCOL_PIO_READ;
5083 satIOContext->ATACmd = SAT_READ_SECTORS_EXT;
5084 }
5085 }
5086 else/* case 1 and 2 */
5087 {
5088 if (pSatDevData->satDMASupport == agTRUE && pSatDevData->satDMAEnabled == agTRUE)
5089 {
5090 /* case 2 */
5091 /* READ DMA*/
5092 /* in case that we can't fit the transfer length, we need to make it fit by sending multiple ATA cmnds */
5093 SM_DBG5(("smsatRead10: case 2\n"));
5094
5095
5096 fis->h.fisType = 0x27; /* Reg host to device */
5097 fis->h.c_pmPort = 0x80; /* C Bit is set */
5098 fis->h.command = SAT_READ_DMA; /* 0xC8 */
5099 fis->h.features = 0; /* FIS reserve */
5100 fis->d.lbaLow = scsiCmnd->cdb[5]; /* FIS LBA (7 :0 ) */
5101 fis->d.lbaMid = scsiCmnd->cdb[4]; /* FIS LBA (15:8 ) */
5102 fis->d.lbaHigh = scsiCmnd->cdb[3]; /* FIS LBA (23:16) */
5103 fis->d.device =
5104 (bit8)((0x4 << 4) | (scsiCmnd->cdb[2] & 0xF)); /* FIS LBA (27:24) and FIS LBA mode */
5105 fis->d.lbaLowExp = 0;
5106 fis->d.lbaMidExp = 0;
5107 fis->d.lbaHighExp = 0;
5108 fis->d.featuresExp = 0;
5109 fis->d.sectorCount = scsiCmnd->cdb[8]; /* FIS sector count (7:0) */
5110 fis->d.sectorCountExp = 0;
5111 fis->d.reserved4 = 0;
5112 fis->d.control = 0; /* FIS HOB bit clear */
5113 fis->d.reserved5 = 0;
5114
5115
5116 agRequestType = AGSA_SATA_PROTOCOL_DMA_READ;
5117 satIOContext->ATACmd = SAT_READ_DMA;
5118 }
5119 else
5120 {
5121 /* case 1 */
5122 /* READ MULTIPLE or READ SECTOR(S) */
5123 /* READ SECTORS for easier implemetation */
5124 /* in case that we can't fit the transfer length, we need to make it fit by sending multiple ATA cmnds */
5125 SM_DBG5(("smsatRead10: case 1\n"));
5126
5127 fis->h.fisType = 0x27; /* Reg host to device */
5128 fis->h.c_pmPort = 0x80; /* C Bit is set */
5129 fis->h.command = SAT_READ_SECTORS; /* 0x20 */
5130 fis->h.features = 0; /* FIS reserve */
5131 fis->d.lbaLow = scsiCmnd->cdb[5]; /* FIS LBA (7 :0 ) */
5132 fis->d.lbaMid = scsiCmnd->cdb[4]; /* FIS LBA (15:8 ) */
5133 fis->d.lbaHigh = scsiCmnd->cdb[3]; /* FIS LBA (23:16) */
5134 fis->d.device =
5135 (bit8)((0x4 << 4) | (scsiCmnd->cdb[2] & 0xF)); /* FIS LBA (27:24) and FIS LBA mode */
5136 fis->d.lbaLowExp = 0;
5137 fis->d.lbaMidExp = 0;
5138 fis->d.lbaHighExp = 0;
5139 fis->d.featuresExp = 0;
5140 fis->d.sectorCount = scsiCmnd->cdb[8]; /* FIS sector count (7:0) */
5141 fis->d.sectorCountExp = 0;
5142 fis->d.reserved4 = 0;
5143 fis->d.control = 0; /* FIS HOB bit clear */
5144 fis->d.reserved5 = 0;
5145
5146
5147 agRequestType = AGSA_SATA_PROTOCOL_PIO_READ;
5148 satIOContext->ATACmd = SAT_READ_SECTORS;
5149 }
5150 }
5151 // smhexdump("satRead10 final fis", (bit8 *)fis, sizeof(agsaFisRegHostToDevice_t));
5152
5153 /* saves the current LBA and orginal TL */
5154 satIOContext->currentLBA = lba;
5155 satIOContext->OrgTL = tl;
5156
5157 /*
5158 computing number of loop and remainder for tl
5159 0xFF in case not ext
5160 0xFFFF in case EXT
5161 */
5162 if (fis->h.command == SAT_READ_SECTORS || fis->h.command == SAT_READ_DMA)
5163 {
5164 LoopNum = smsatComputeLoopNum(tl, 0x100);
5165 }
5166 else
5167 {
5168 /* SAT_READ_FPDMA_QUEUED */
5169 /* SAT_READ_SECTORS_EXT, SAT_READ_DMA_EXT */
5170 LoopNum = smsatComputeLoopNum(tl, 0xFFFF);
5171 }
5172
5173 satIOContext->LoopNum = LoopNum;
5174
5175 /* Initialize CB for SATA completion.
5176 */
5177 if (LoopNum == 1)
5178 {
5179 SM_DBG5(("smsatRead10: NON CHAINED data\n"));
5180 satIOContext->satCompleteCB = &smsatNonChainedDataIOCB;
5181 }
5182 else
5183 {
5184 SM_DBG2(("smsatRead10: CHAINED data!!!\n"));
5185
5186 /* re-setting tl */
5187 if (fis->h.command == SAT_READ_SECTORS || fis->h.command == SAT_READ_DMA)
5188 {
5189 fis->d.sectorCount = 0x0;
5190 smsatSplitSGL(smRoot,
5191 smIORequest,
5192 smDeviceHandle,
5193 smScsiRequest,
5194 satIOContext,
5195 NON_BIT48_ADDRESS_TL_LIMIT*SATA_SECTOR_SIZE, /* 0x100 * 0x200 */
5196 (satIOContext->OrgTL)*SATA_SECTOR_SIZE,
5197 agTRUE);
5198 }
5199 else if (fis->h.command == SAT_READ_SECTORS_EXT || fis->h.command == SAT_READ_DMA_EXT)
5200 {
5201 /* SAT_READ_SECTORS_EXT, SAT_READ_DMA_EXT */
5202 fis->d.sectorCount = 0xFF;
5203 fis->d.sectorCountExp = 0xFF;
5204 smsatSplitSGL(smRoot,
5205 smIORequest,
5206 smDeviceHandle,
5207 smScsiRequest,
5208 satIOContext,
5209 BIT48_ADDRESS_TL_LIMIT*SATA_SECTOR_SIZE, /* 0xFFFF * 0x200 */
5210 (satIOContext->OrgTL)*SATA_SECTOR_SIZE,
5211 agTRUE);
5212 }
5213 else
5214 {
5215 /* SAT_READ_FPDMA_QUEUED */
5216 fis->h.features = 0xFF;
5217 fis->d.featuresExp = 0xFF;
5218 smsatSplitSGL(smRoot,
5219 smIORequest,
5220 smDeviceHandle,
5221 smScsiRequest,
5222 satIOContext,
5223 BIT48_ADDRESS_TL_LIMIT*SATA_SECTOR_SIZE, /* 0xFFFF * 0x200 */
5224 (satIOContext->OrgTL)*SATA_SECTOR_SIZE,
5225 agTRUE);
5226 }
5227
5228 /* chained data */
5229 satIOContext->satCompleteCB = &smsatChainedDataIOCB;
5230
5231 }
5232
5233 /*
5234 * Prepare SGL and send FIS to LL layer.
5235 */
5236 satIOContext->reqType = agRequestType; /* Save it */
5237
5238 status = smsataLLIOStart( smRoot,
5239 smIORequest,
5240 smDeviceHandle,
5241 smScsiRequest,
5242 satIOContext);
5243
5244 SM_DBG5(("smsatRead10: return\n"));
5245 return (status);
5246
5247 }
5248
5249 osGLOBAL bit32
smsatRead12(smRoot_t * smRoot,smIORequest_t * smIORequest,smDeviceHandle_t * smDeviceHandle,smScsiInitiatorRequest_t * smScsiRequest,smSatIOContext_t * satIOContext)5250 smsatRead12(
5251 smRoot_t *smRoot,
5252 smIORequest_t *smIORequest,
5253 smDeviceHandle_t *smDeviceHandle,
5254 smScsiInitiatorRequest_t *smScsiRequest,
5255 smSatIOContext_t *satIOContext
5256 )
5257 {
5258 bit32 status;
5259 bit32 agRequestType = AGSA_SATA_PROTOCOL_DMA_READ;
5260 smDeviceData_t *pSatDevData;
5261 smScsiRspSense_t *pSense;
5262 smIniScsiCmnd_t *scsiCmnd;
5263 agsaFisRegHostToDevice_t *fis;
5264 bit32 lba = 0;
5265 bit32 tl = 0;
5266 bit32 LoopNum = 1;
5267 bit8 LBA[8];
5268 bit8 TL[8];
5269 bit32 AllChk = agFALSE; /* lba, lba+tl check against ATA limit and Disk capacity */
5270
5271 pSense = satIOContext->pSense;
5272 pSatDevData = satIOContext->pSatDevData;
5273 scsiCmnd = &smScsiRequest->scsiCmnd;
5274 fis = satIOContext->pFis;
5275
5276 SM_DBG5(("smsatRead12: start\n"));
5277
5278 /* checking FUA_NV */
5279 if (scsiCmnd->cdb[1] & SCSI_FUA_NV_MASK)
5280 {
5281 smsatSetSensePayload( pSense,
5282 SCSI_SNSKEY_ILLEGAL_REQUEST,
5283 0,
5284 SCSI_SNSCODE_INVALID_FIELD_IN_CDB,
5285 satIOContext);
5286
5287 /*smEnqueueIO(smRoot, satIOContext);*/
5288
5289 tdsmIOCompletedCB( smRoot,
5290 smIORequest,
5291 smIOSuccess,
5292 SCSI_STAT_CHECK_CONDITION,
5293 satIOContext->pSmSenseData,
5294 satIOContext->interruptContext );
5295
5296 SM_DBG1(("smsatRead12: return FUA_NV!!!\n"));
5297 return SM_RC_SUCCESS;
5298
5299 }
5300
5301 /* checking CONTROL */
5302 /* NACA == 1 or LINK == 1*/
5303 if ( (scsiCmnd->cdb[11] & SCSI_NACA_MASK) || (scsiCmnd->cdb[11] & SCSI_LINK_MASK) )
5304 {
5305 smsatSetSensePayload( pSense,
5306 SCSI_SNSKEY_ILLEGAL_REQUEST,
5307 0,
5308 SCSI_SNSCODE_INVALID_FIELD_IN_CDB,
5309 satIOContext);
5310
5311 /*smEnqueueIO(smRoot, satIOContext);*/
5312
5313 tdsmIOCompletedCB( smRoot,
5314 smIORequest,
5315 smIOSuccess,
5316 SCSI_STAT_CHECK_CONDITION,
5317 satIOContext->pSmSenseData,
5318 satIOContext->interruptContext );
5319
5320 SM_DBG1(("smsatRead12: return control!!!\n"));
5321 return SM_RC_SUCCESS;
5322 }
5323
5324 sm_memset(LBA, 0, sizeof(LBA));
5325 sm_memset(TL, 0, sizeof(TL));
5326
5327 /* do not use memcpy due to indexing in LBA and TL */
5328 LBA[0] = 0; /* MSB */
5329 LBA[1] = 0;
5330 LBA[2] = 0;
5331 LBA[3] = 0;
5332 LBA[4] = scsiCmnd->cdb[2];
5333 LBA[5] = scsiCmnd->cdb[3];
5334 LBA[6] = scsiCmnd->cdb[4];
5335 LBA[7] = scsiCmnd->cdb[5]; /* LSB */
5336
5337 TL[0] = 0; /* MSB */
5338 TL[1] = 0;
5339 TL[2] = 0;
5340 TL[3] = 0;
5341 TL[4] = scsiCmnd->cdb[6];
5342 TL[5] = scsiCmnd->cdb[7];
5343 TL[6] = scsiCmnd->cdb[8];
5344 TL[7] = scsiCmnd->cdb[9]; /* LSB */
5345
5346
5347 lba = smsatComputeCDB12LBA(satIOContext);
5348 tl = smsatComputeCDB12TL(satIOContext);
5349
5350 /* Table 34, 9.1, p 46 */
5351 /*
5352 note: As of 2/10/2006, no support for DMA QUEUED
5353 */
5354
5355 /*
5356 Table 34, 9.1, p 46, b
5357 When no 48-bit addressing support or NCQ, if LBA is beyond (2^28 - 1),
5358 return check condition
5359 */
5360 if (pSatDevData->satNCQ != agTRUE &&
5361 pSatDevData->sat48BitSupport != agTRUE
5362 )
5363 {
5364
5365 AllChk = smsatCheckLimit(LBA, TL, agFALSE, pSatDevData);
5366 if (AllChk)
5367 {
5368 SM_DBG1(("smsatRead12: return LBA out of range, not EXT!!!\n"));
5369 smsatSetSensePayload( pSense,
5370 SCSI_SNSKEY_ILLEGAL_REQUEST,
5371 0,
5372 SCSI_SNSCODE_LOGICAL_BLOCK_ADDRESS_OUT_OF_RANGE,
5373 satIOContext);
5374
5375 /*smEnqueueIO(smRoot, satIOContext);*/
5376
5377 tdsmIOCompletedCB( smRoot,
5378 smIORequest,
5379 smIOSuccess,
5380 SCSI_STAT_CHECK_CONDITION,
5381 satIOContext->pSmSenseData,
5382 satIOContext->interruptContext );
5383
5384 return SM_RC_SUCCESS;
5385 }
5386 }
5387 else
5388 {
5389 AllChk = smsatCheckLimit(LBA, TL, agTRUE, pSatDevData);
5390 if (AllChk)
5391 {
5392 SM_DBG1(("smsatRead12: return LBA out of range, EXT!!!\n"));
5393 smsatSetSensePayload( pSense,
5394 SCSI_SNSKEY_ILLEGAL_REQUEST,
5395 0,
5396 SCSI_SNSCODE_LOGICAL_BLOCK_ADDRESS_OUT_OF_RANGE,
5397 satIOContext);
5398
5399 /*smEnqueueIO(smRoot, satIOContext);*/
5400
5401 tdsmIOCompletedCB( smRoot,
5402 smIORequest,
5403 smIOSuccess,
5404 SCSI_STAT_CHECK_CONDITION,
5405 satIOContext->pSmSenseData,
5406 satIOContext->interruptContext );
5407
5408 return SM_RC_SUCCESS;
5409 }
5410 }
5411
5412 /* case 1 and 2 */
5413 if (pSatDevData->satDMASupport == agTRUE && pSatDevData->satDMAEnabled == agTRUE)
5414 {
5415 /* case 2 */
5416 /* READ DMA*/
5417 /* in case that we can't fit the transfer length,
5418 we need to make it fit by sending multiple ATA cmnds */
5419 SM_DBG5(("smsatRead12: case 2\n"));
5420
5421
5422 fis->h.fisType = 0x27; /* Reg host to device */
5423 fis->h.c_pmPort = 0x80; /* C Bit is set */
5424 fis->h.command = SAT_READ_DMA; /* 0xC8 */
5425 fis->h.features = 0; /* FIS reserve */
5426 fis->d.lbaLow = scsiCmnd->cdb[5]; /* FIS LBA (7 :0 ) */
5427 fis->d.lbaMid = scsiCmnd->cdb[4]; /* FIS LBA (15:8 ) */
5428 fis->d.lbaHigh = scsiCmnd->cdb[3]; /* FIS LBA (23:16) */
5429 fis->d.device =
5430 (bit8)((0x4 << 4) | (scsiCmnd->cdb[2] & 0xF)); /* FIS LBA (27:24) and FIS LBA mode */
5431 fis->d.lbaLowExp = 0;
5432 fis->d.lbaMidExp = 0;
5433 fis->d.lbaHighExp = 0;
5434 fis->d.featuresExp = 0;
5435 fis->d.sectorCount = scsiCmnd->cdb[9]; /* FIS sector count (7:0) */
5436 fis->d.sectorCountExp = 0;
5437 fis->d.reserved4 = 0;
5438 fis->d.control = 0; /* FIS HOB bit clear */
5439 fis->d.reserved5 = 0;
5440
5441
5442 agRequestType = AGSA_SATA_PROTOCOL_DMA_READ;
5443 satIOContext->ATACmd = SAT_READ_DMA;
5444 }
5445 else
5446 {
5447 /* case 1 */
5448 /* READ MULTIPLE or READ SECTOR(S) */
5449 /* READ SECTORS for easier implemetation */
5450 /* can't fit the transfer length but need to make it fit by sending multiple*/
5451 SM_DBG5(("smsatRead12: case 1\n"));
5452
5453 fis->h.fisType = 0x27; /* Reg host to device */
5454 fis->h.c_pmPort = 0x80; /* C Bit is set */
5455 fis->h.command = SAT_READ_SECTORS; /* 0x20 */
5456 fis->h.features = 0; /* FIS reserve */
5457 fis->d.lbaLow = scsiCmnd->cdb[5]; /* FIS LBA (7 :0 ) */
5458 fis->d.lbaMid = scsiCmnd->cdb[4]; /* FIS LBA (15:8 ) */
5459 fis->d.lbaHigh = scsiCmnd->cdb[3]; /* FIS LBA (23:16) */
5460 fis->d.device =
5461 (bit8)((0x4 << 4) | (scsiCmnd->cdb[2] & 0xF)); /* FIS LBA (27:24) and FIS LBA mode */
5462 fis->d.lbaLowExp = 0;
5463 fis->d.lbaMidExp = 0;
5464 fis->d.lbaHighExp = 0;
5465 fis->d.featuresExp = 0;
5466 fis->d.sectorCount = scsiCmnd->cdb[9]; /* FIS sector count (7:0) */
5467 fis->d.sectorCountExp = 0;
5468 fis->d.reserved4 = 0;
5469 fis->d.control = 0; /* FIS HOB bit clear */
5470 fis->d.reserved5 = 0;
5471
5472
5473 agRequestType = AGSA_SATA_PROTOCOL_PIO_READ;
5474 satIOContext->ATACmd = SAT_READ_SECTORS;
5475 }
5476
5477 /* case 3 and 4 */
5478 if (pSatDevData->sat48BitSupport == agTRUE)
5479 {
5480 if (pSatDevData->satDMASupport == agTRUE && pSatDevData->satDMAEnabled == agTRUE)
5481 {
5482 /* case 3 */
5483 /* READ DMA EXT */
5484 SM_DBG5(("smsatRead12: case 3\n"));
5485 fis->h.fisType = 0x27; /* Reg host to device */
5486
5487 fis->h.c_pmPort = 0x80; /* C Bit is set */
5488 fis->h.command = SAT_READ_DMA_EXT; /* 0x25 */
5489 fis->h.features = 0; /* FIS reserve */
5490 fis->d.lbaLow = scsiCmnd->cdb[5]; /* FIS LBA (7 :0 ) */
5491 fis->d.lbaMid = scsiCmnd->cdb[4]; /* FIS LBA (15:8 ) */
5492 fis->d.lbaHigh = scsiCmnd->cdb[3]; /* FIS LBA (23:16) */
5493 fis->d.device = 0x40; /* FIS LBA mode set */
5494 fis->d.lbaLowExp = scsiCmnd->cdb[2]; /* FIS LBA (31:24) */
5495 fis->d.lbaMidExp = 0; /* FIS LBA (39:32) */
5496 fis->d.lbaHighExp = 0; /* FIS LBA (47:40) */
5497 fis->d.featuresExp = 0; /* FIS reserve */
5498 fis->d.sectorCount = scsiCmnd->cdb[9]; /* FIS sector count (7:0) */
5499 fis->d.sectorCountExp = scsiCmnd->cdb[8]; /* FIS sector count (15:8) */
5500 fis->d.reserved4 = 0;
5501 fis->d.control = 0; /* FIS HOB bit clear */
5502 fis->d.reserved5 = 0;
5503
5504 agRequestType = AGSA_SATA_PROTOCOL_DMA_READ;
5505 satIOContext->ATACmd = SAT_READ_DMA_EXT;
5506
5507 }
5508 else
5509 {
5510 /* case 4 */
5511 /* READ MULTIPLE EXT or READ SECTOR(S) EXT or READ VERIFY SECTOR(S) EXT*/
5512 /* READ SECTORS EXT for easier implemetation */
5513 SM_DBG5(("smsatRead12: case 4\n"));
5514 fis->h.fisType = 0x27; /* Reg host to device */
5515 fis->h.c_pmPort = 0x80; /* C Bit is set */
5516
5517 /* Check FUA bit */
5518 if (scsiCmnd->cdb[1] & SCSI_READ12_FUA_MASK)
5519 {
5520
5521 /* for now, no support for FUA */
5522 smsatSetSensePayload( pSense,
5523 SCSI_SNSKEY_ILLEGAL_REQUEST,
5524 0,
5525 SCSI_SNSCODE_INVALID_FIELD_IN_CDB,
5526 satIOContext);
5527
5528 /*smEnqueueIO(smRoot, satIOContext);*/
5529
5530 tdsmIOCompletedCB( smRoot,
5531 smIORequest,
5532 smIOSuccess,
5533 SCSI_STAT_CHECK_CONDITION,
5534 satIOContext->pSmSenseData,
5535 satIOContext->interruptContext );
5536 return SM_RC_SUCCESS;
5537 }
5538
5539 fis->h.command = SAT_READ_SECTORS_EXT; /* 0x24 */
5540
5541 fis->h.features = 0; /* FIS reserve */
5542 fis->d.lbaLow = scsiCmnd->cdb[5]; /* FIS LBA (7 :0 ) */
5543 fis->d.lbaMid = scsiCmnd->cdb[4]; /* FIS LBA (15:8 ) */
5544 fis->d.lbaHigh = scsiCmnd->cdb[3]; /* FIS LBA (23:16) */
5545 fis->d.device = 0x40; /* FIS LBA mode set */
5546 fis->d.lbaLowExp = scsiCmnd->cdb[2]; /* FIS LBA (31:24) */
5547 fis->d.lbaMidExp = 0; /* FIS LBA (39:32) */
5548 fis->d.lbaHighExp = 0; /* FIS LBA (47:40) */
5549 fis->d.featuresExp = 0; /* FIS reserve */
5550 fis->d.sectorCount = scsiCmnd->cdb[9]; /* FIS sector count (7:0) */
5551 fis->d.sectorCountExp = scsiCmnd->cdb[8]; /* FIS sector count (15:8) */
5552 fis->d.reserved4 = 0;
5553 fis->d.control = 0; /* FIS HOB bit clear */
5554 fis->d.reserved5 = 0;
5555
5556 agRequestType = AGSA_SATA_PROTOCOL_PIO_READ;
5557 satIOContext->ATACmd = SAT_READ_SECTORS_EXT;
5558 }
5559 }
5560
5561 /* case 5 */
5562 if (pSatDevData->satNCQ == agTRUE)
5563 {
5564 /* READ FPDMA QUEUED */
5565 if (pSatDevData->sat48BitSupport != agTRUE)
5566 {
5567 SM_DBG1(("smsatRead12: case 5 !!! error NCQ but 28 bit address support!!!\n"));
5568 smsatSetSensePayload( pSense,
5569 SCSI_SNSKEY_ILLEGAL_REQUEST,
5570 0,
5571 SCSI_SNSCODE_INVALID_FIELD_IN_CDB,
5572 satIOContext);
5573
5574 /*smEnqueueIO(smRoot, satIOContext);*/
5575
5576 tdsmIOCompletedCB( smRoot,
5577 smIORequest,
5578 smIOSuccess,
5579 SCSI_STAT_CHECK_CONDITION,
5580 satIOContext->pSmSenseData,
5581 satIOContext->interruptContext );
5582 return SM_RC_SUCCESS;
5583 }
5584
5585 SM_DBG6(("smsatRead12: case 5\n"));
5586
5587 /* Support 48-bit FPDMA addressing, use READ FPDMA QUEUE command */
5588
5589 fis->h.fisType = 0x27; /* Reg host to device */
5590 fis->h.c_pmPort = 0x80; /* C Bit is set */
5591 fis->h.command = SAT_READ_FPDMA_QUEUED; /* 0x60 */
5592 fis->h.features = scsiCmnd->cdb[9]; /* FIS sector count (7:0) */
5593 fis->d.lbaLow = scsiCmnd->cdb[5]; /* FIS LBA (7 :0 ) */
5594 fis->d.lbaMid = scsiCmnd->cdb[4]; /* FIS LBA (15:8 ) */
5595 fis->d.lbaHigh = scsiCmnd->cdb[3]; /* FIS LBA (23:16) */
5596
5597 /* Check FUA bit */
5598 if (scsiCmnd->cdb[1] & SCSI_READ12_FUA_MASK)
5599 fis->d.device = 0xC0; /* FIS FUA set */
5600 else
5601 fis->d.device = 0x40; /* FIS FUA clear */
5602
5603 fis->d.lbaLowExp = scsiCmnd->cdb[2]; /* FIS LBA (31:24) */
5604 fis->d.lbaMidExp = 0; /* FIS LBA (39:32) */
5605 fis->d.lbaHighExp = 0; /* FIS LBA (47:40) */
5606 fis->d.featuresExp = scsiCmnd->cdb[8]; /* FIS sector count (15:8) */
5607 fis->d.sectorCount = 0; /* Tag (7:3) set by LL layer */
5608 fis->d.sectorCountExp = 0;
5609 fis->d.reserved4 = 0;
5610 fis->d.control = 0; /* FIS HOB bit clear */
5611 fis->d.reserved5 = 0;
5612
5613 agRequestType = AGSA_SATA_PROTOCOL_FPDMA_READ;
5614 satIOContext->ATACmd = SAT_READ_FPDMA_QUEUED;
5615 }
5616
5617 /* saves the current LBA and orginal TL */
5618 satIOContext->currentLBA = lba;
5619 satIOContext->OrgTL = tl;
5620
5621 /*
5622 computing number of loop and remainder for tl
5623 0xFF in case not ext
5624 0xFFFF in case EXT
5625 */
5626 if (fis->h.command == SAT_READ_SECTORS || fis->h.command == SAT_READ_DMA)
5627 {
5628 LoopNum = smsatComputeLoopNum(tl, 0xFF);
5629 }
5630 else if (fis->h.command == SAT_READ_SECTORS_EXT || fis->h.command == SAT_READ_DMA_EXT)
5631 {
5632 /* SAT_READ_SECTORS_EXT, SAT_READ_DMA_EXT */
5633 LoopNum = smsatComputeLoopNum(tl, 0xFFFF);
5634 }
5635 else
5636 {
5637 /* SAT_READ_FPDMA_QUEUEDK */
5638 LoopNum = smsatComputeLoopNum(tl, 0xFFFF);
5639 }
5640
5641 satIOContext->LoopNum = LoopNum;
5642
5643 if (LoopNum == 1)
5644 {
5645 SM_DBG5(("smsatRead12: NON CHAINED data\n"));
5646 satIOContext->satCompleteCB = &smsatNonChainedDataIOCB;
5647 }
5648 else
5649 {
5650 SM_DBG1(("smsatRead12: CHAINED data\n"));
5651 /* re-setting tl */
5652 if (fis->h.command == SAT_READ_SECTORS || fis->h.command == SAT_READ_DMA)
5653 {
5654 fis->d.sectorCount = 0xFF;
5655 }
5656 else if (fis->h.command == SAT_READ_SECTORS_EXT || fis->h.command == SAT_READ_DMA_EXT)
5657 {
5658 /* SAT_READ_SECTORS_EXT, SAT_READ_DMA_EXT */
5659 fis->d.sectorCount = 0xFF;
5660 fis->d.sectorCountExp = 0xFF;
5661 }
5662 else
5663 {
5664 /* SAT_READ_FPDMA_QUEUED */
5665 fis->h.features = 0xFF;
5666 fis->d.featuresExp = 0xFF;
5667 }
5668
5669 /* chained data */
5670 satIOContext->satCompleteCB = &smsatChainedDataIOCB;
5671 }
5672
5673 /*
5674 * Prepare SGL and send FIS to LL layer.
5675 */
5676 satIOContext->reqType = agRequestType; /* Save it */
5677
5678 status = smsataLLIOStart( smRoot,
5679 smIORequest,
5680 smDeviceHandle,
5681 smScsiRequest,
5682 satIOContext);
5683
5684 SM_DBG5(("smsatRead12: return\n"));
5685 return (status);
5686 }
5687
5688 osGLOBAL bit32
smsatRead16(smRoot_t * smRoot,smIORequest_t * smIORequest,smDeviceHandle_t * smDeviceHandle,smScsiInitiatorRequest_t * smScsiRequest,smSatIOContext_t * satIOContext)5689 smsatRead16(
5690 smRoot_t *smRoot,
5691 smIORequest_t *smIORequest,
5692 smDeviceHandle_t *smDeviceHandle,
5693 smScsiInitiatorRequest_t *smScsiRequest,
5694 smSatIOContext_t *satIOContext
5695 )
5696 {
5697 bit32 status;
5698 bit32 agRequestType = AGSA_SATA_PROTOCOL_DMA_READ;
5699 smDeviceData_t *pSatDevData;
5700 smScsiRspSense_t *pSense;
5701 smIniScsiCmnd_t *scsiCmnd;
5702 agsaFisRegHostToDevice_t *fis;
5703 bit32 lba = 0;
5704 bit32 tl = 0;
5705 bit32 LoopNum = 1;
5706 bit8 LBA[8];
5707 bit8 TL[8];
5708 bit32 AllChk = agFALSE; /* lba, lba+tl check against ATA limit and Disk capacity */
5709 // bit32 limitExtChk = agFALSE; /* lba limit check for bit48 addressing check */
5710
5711 pSense = satIOContext->pSense;
5712 pSatDevData = satIOContext->pSatDevData;
5713 scsiCmnd = &smScsiRequest->scsiCmnd;
5714 fis = satIOContext->pFis;
5715
5716 SM_DBG5(("smsatRead16: start\n"));
5717
5718 /* checking FUA_NV */
5719 if (scsiCmnd->cdb[1] & SCSI_FUA_NV_MASK)
5720 {
5721 smsatSetSensePayload( pSense,
5722 SCSI_SNSKEY_ILLEGAL_REQUEST,
5723 0,
5724 SCSI_SNSCODE_INVALID_FIELD_IN_CDB,
5725 satIOContext);
5726
5727 /*smEnqueueIO(smRoot, satIOContext);*/
5728
5729 tdsmIOCompletedCB( smRoot,
5730 smIORequest,
5731 smIOSuccess,
5732 SCSI_STAT_CHECK_CONDITION,
5733 satIOContext->pSmSenseData,
5734 satIOContext->interruptContext );
5735
5736 SM_DBG1(("smsatRead16: return FUA_NV!!!\n"));
5737 return SM_RC_SUCCESS;
5738
5739 }
5740
5741 /* checking CONTROL */
5742 /* NACA == 1 or LINK == 1*/
5743 if ( (scsiCmnd->cdb[15] & SCSI_NACA_MASK) || (scsiCmnd->cdb[15] & SCSI_LINK_MASK) )
5744 {
5745 smsatSetSensePayload( pSense,
5746 SCSI_SNSKEY_ILLEGAL_REQUEST,
5747 0,
5748 SCSI_SNSCODE_INVALID_FIELD_IN_CDB,
5749 satIOContext);
5750
5751 /*smEnqueueIO(smRoot, satIOContext);*/
5752
5753 tdsmIOCompletedCB( smRoot,
5754 smIORequest,
5755 smIOSuccess,
5756 SCSI_STAT_CHECK_CONDITION,
5757 satIOContext->pSmSenseData,
5758 satIOContext->interruptContext );
5759
5760 SM_DBG1(("smsatRead16: return control!!!\n"));
5761 return SM_RC_SUCCESS;
5762 }
5763
5764
5765 sm_memset(LBA, 0, sizeof(LBA));
5766 sm_memset(TL, 0, sizeof(TL));
5767
5768
5769 /* do not use memcpy due to indexing in LBA and TL */
5770 LBA[0] = scsiCmnd->cdb[2]; /* MSB */
5771 LBA[1] = scsiCmnd->cdb[3];
5772 LBA[2] = scsiCmnd->cdb[4];
5773 LBA[3] = scsiCmnd->cdb[5];
5774 LBA[4] = scsiCmnd->cdb[6];
5775 LBA[5] = scsiCmnd->cdb[7];
5776 LBA[6] = scsiCmnd->cdb[8];
5777 LBA[7] = scsiCmnd->cdb[9]; /* LSB */
5778
5779 TL[0] = 0;
5780 TL[1] = 0;
5781 TL[2] = 0;
5782 TL[3] = 0;
5783 TL[4] = scsiCmnd->cdb[10]; /* MSB */
5784 TL[5] = scsiCmnd->cdb[11];
5785 TL[6] = scsiCmnd->cdb[12];
5786 TL[7] = scsiCmnd->cdb[13]; /* LSB */
5787
5788
5789
5790
5791 lba = smsatComputeCDB16LBA(satIOContext);
5792 tl = smsatComputeCDB16TL(satIOContext);
5793
5794
5795 /* Table 34, 9.1, p 46 */
5796 /*
5797 note: As of 2/10/2006, no support for DMA QUEUED
5798 */
5799
5800 /*
5801 Table 34, 9.1, p 46, b
5802 When no 48-bit addressing support or NCQ, if LBA is beyond (2^28 - 1),
5803 return check condition
5804 */
5805 if (pSatDevData->satNCQ != agTRUE &&
5806 pSatDevData->sat48BitSupport != agTRUE
5807 )
5808 {
5809 AllChk = smsatCheckLimit(LBA, TL, agFALSE, pSatDevData);
5810 if (AllChk)
5811 {
5812 SM_DBG1(("smsatRead16: return LBA out of range, not EXT!!!\n"));
5813
5814 /*smEnqueueIO(smRoot, satIOContext);*/
5815
5816
5817 smsatSetSensePayload( pSense,
5818 SCSI_SNSKEY_ILLEGAL_REQUEST,
5819 0,
5820 SCSI_SNSCODE_LOGICAL_BLOCK_ADDRESS_OUT_OF_RANGE,
5821 satIOContext);
5822
5823 /*smEnqueueIO(smRoot, satIOContext);*/
5824
5825 tdsmIOCompletedCB( smRoot,
5826 smIORequest,
5827 smIOSuccess,
5828 SCSI_STAT_CHECK_CONDITION,
5829 satIOContext->pSmSenseData,
5830 satIOContext->interruptContext );
5831
5832 return SM_RC_SUCCESS;
5833 }
5834 }
5835 else
5836 {
5837 // rangeChk = smsatAddNComparebit64(LBA, TL);
5838
5839 AllChk = smsatCheckLimit(LBA, TL, agTRUE, pSatDevData);
5840
5841
5842 if (AllChk)
5843 {
5844 SM_DBG1(("smsatRead16: return LBA out of range, EXT!!!\n"));
5845 smsatSetSensePayload( pSense,
5846 SCSI_SNSKEY_ILLEGAL_REQUEST,
5847 0,
5848 SCSI_SNSCODE_LOGICAL_BLOCK_ADDRESS_OUT_OF_RANGE,
5849 satIOContext);
5850
5851 /*smEnqueueIO(smRoot, satIOContext);*/
5852
5853 tdsmIOCompletedCB( smRoot,
5854 smIORequest,
5855 smIOSuccess,
5856 SCSI_STAT_CHECK_CONDITION,
5857 satIOContext->pSmSenseData,
5858 satIOContext->interruptContext );
5859
5860 return SM_RC_SUCCESS;
5861 }
5862 }
5863
5864 /* case 1 and 2 */
5865 if (pSatDevData->satDMASupport == agTRUE && pSatDevData->satDMAEnabled == agTRUE)
5866 {
5867 /* case 2 */
5868 /* READ DMA*/
5869 /* in case that we can't fit the transfer length,
5870 we need to make it fit by sending multiple ATA cmnds */
5871 SM_DBG5(("smsatRead16: case 2\n"));
5872
5873
5874 fis->h.fisType = 0x27; /* Reg host to device */
5875 fis->h.c_pmPort = 0x80; /* C Bit is set */
5876 fis->h.command = SAT_READ_DMA; /* 0xC8 */
5877 fis->h.features = 0; /* FIS reserve */
5878 fis->d.lbaLow = scsiCmnd->cdb[9]; /* FIS LBA (7 :0 ) */
5879 fis->d.lbaMid = scsiCmnd->cdb[8]; /* FIS LBA (15:8 ) */
5880 fis->d.lbaHigh = scsiCmnd->cdb[7]; /* FIS LBA (23:16) */
5881 fis->d.device =
5882 (bit8)((0x4 << 4) | (scsiCmnd->cdb[6] & 0xF)); /* FIS LBA (27:24) and FIS LBA mode */
5883 fis->d.lbaLowExp = 0;
5884 fis->d.lbaMidExp = 0;
5885 fis->d.lbaHighExp = 0;
5886 fis->d.featuresExp = 0;
5887 fis->d.sectorCount = scsiCmnd->cdb[13]; /* FIS sector count (7:0) */
5888 fis->d.sectorCountExp = 0;
5889 fis->d.reserved4 = 0;
5890 fis->d.control = 0; /* FIS HOB bit clear */
5891 fis->d.reserved5 = 0;
5892
5893
5894 agRequestType = AGSA_SATA_PROTOCOL_DMA_READ;
5895 satIOContext->ATACmd = SAT_READ_DMA;
5896 }
5897 else
5898 {
5899 /* case 1 */
5900 /* READ MULTIPLE or READ SECTOR(S) */
5901 /* READ SECTORS for easier implemetation */
5902 /* can't fit the transfer length but need to make it fit by sending multiple*/
5903 SM_DBG5(("smsatRead16: case 1\n"));
5904
5905 fis->h.fisType = 0x27; /* Reg host to device */
5906 fis->h.c_pmPort = 0x80; /* C Bit is set */
5907 fis->h.command = SAT_READ_SECTORS; /* 0x20 */
5908 fis->h.features = 0; /* FIS reserve */
5909 fis->d.lbaLow = scsiCmnd->cdb[9]; /* FIS LBA (7 :0 ) */
5910 fis->d.lbaMid = scsiCmnd->cdb[8]; /* FIS LBA (15:8 ) */
5911 fis->d.lbaHigh = scsiCmnd->cdb[7]; /* FIS LBA (23:16) */
5912 fis->d.device =
5913 (bit8)((0x4 << 4) | (scsiCmnd->cdb[6] & 0xF)); /* FIS LBA (27:24) and FIS LBA mode */
5914 fis->d.lbaLowExp = 0;
5915 fis->d.lbaMidExp = 0;
5916 fis->d.lbaHighExp = 0;
5917 fis->d.featuresExp = 0;
5918 fis->d.sectorCount = scsiCmnd->cdb[13]; /* FIS sector count (7:0) */
5919 fis->d.sectorCountExp = 0;
5920 fis->d.reserved4 = 0;
5921 fis->d.control = 0; /* FIS HOB bit clear */
5922 fis->d.reserved5 = 0;
5923
5924
5925 agRequestType = AGSA_SATA_PROTOCOL_PIO_READ;
5926 satIOContext->ATACmd = SAT_READ_SECTORS;
5927 }
5928
5929 /* case 3 and 4 */
5930 if (pSatDevData->sat48BitSupport == agTRUE)
5931 {
5932 if (pSatDevData->satDMASupport == agTRUE && pSatDevData->satDMAEnabled == agTRUE)
5933 {
5934 /* case 3 */
5935 /* READ DMA EXT */
5936 SM_DBG5(("smsatRead16: case 3\n"));
5937 fis->h.fisType = 0x27; /* Reg host to device */
5938
5939 fis->h.c_pmPort = 0x80; /* C Bit is set */
5940 fis->h.command = SAT_READ_DMA_EXT; /* 0x25 */
5941 fis->h.features = 0; /* FIS reserve */
5942 fis->d.lbaLow = scsiCmnd->cdb[9]; /* FIS LBA (7 :0 ) */
5943 fis->d.lbaMid = scsiCmnd->cdb[8]; /* FIS LBA (15:8 ) */
5944 fis->d.lbaHigh = scsiCmnd->cdb[7]; /* FIS LBA (23:16) */
5945 fis->d.device = 0x40; /* FIS LBA mode set */
5946 fis->d.lbaLowExp = scsiCmnd->cdb[6]; /* FIS LBA (31:24) */
5947 fis->d.lbaMidExp = scsiCmnd->cdb[5]; /* FIS LBA (39:32) */
5948 fis->d.lbaHighExp = scsiCmnd->cdb[4]; /* FIS LBA (47:40) */
5949 fis->d.featuresExp = 0; /* FIS reserve */
5950 fis->d.sectorCount = scsiCmnd->cdb[13]; /* FIS sector count (7:0) */
5951 fis->d.sectorCountExp = scsiCmnd->cdb[12]; /* FIS sector count (15:8) */
5952 fis->d.reserved4 = 0;
5953 fis->d.control = 0; /* FIS HOB bit clear */
5954 fis->d.reserved5 = 0;
5955
5956 agRequestType = AGSA_SATA_PROTOCOL_DMA_READ;
5957 satIOContext->ATACmd = SAT_READ_DMA_EXT;
5958
5959 }
5960 else
5961 {
5962 /* case 4 */
5963 /* READ MULTIPLE EXT or READ SECTOR(S) EXT or READ VERIFY SECTOR(S) EXT*/
5964 /* READ SECTORS EXT for easier implemetation */
5965 SM_DBG5(("smsatRead16: case 4\n"));
5966 fis->h.fisType = 0x27; /* Reg host to device */
5967 fis->h.c_pmPort = 0x80; /* C Bit is set */
5968
5969 /* Check FUA bit */
5970 if (scsiCmnd->cdb[1] & SCSI_READ16_FUA_MASK)
5971 {
5972 /* for now, no support for FUA */
5973 smsatSetSensePayload( pSense,
5974 SCSI_SNSKEY_ILLEGAL_REQUEST,
5975 0,
5976 SCSI_SNSCODE_INVALID_FIELD_IN_CDB,
5977 satIOContext);
5978
5979 /*smEnqueueIO(smRoot, satIOContext);*/
5980
5981 tdsmIOCompletedCB( smRoot,
5982 smIORequest,
5983 smIOSuccess,
5984 SCSI_STAT_CHECK_CONDITION,
5985 satIOContext->pSmSenseData,
5986 satIOContext->interruptContext );
5987 return SM_RC_SUCCESS;
5988 }
5989
5990 fis->h.command = SAT_READ_SECTORS_EXT; /* 0x24 */
5991
5992 fis->h.features = 0; /* FIS reserve */
5993 fis->d.lbaLow = scsiCmnd->cdb[9]; /* FIS LBA (7 :0 ) */
5994 fis->d.lbaMid = scsiCmnd->cdb[8]; /* FIS LBA (15:8 ) */
5995 fis->d.lbaHigh = scsiCmnd->cdb[7]; /* FIS LBA (23:16) */
5996 fis->d.device = 0x40; /* FIS LBA mode set */
5997 fis->d.lbaLowExp = scsiCmnd->cdb[6]; /* FIS LBA (31:24) */
5998 fis->d.lbaMidExp = scsiCmnd->cdb[5]; /* FIS LBA (39:32) */
5999 fis->d.lbaHighExp = scsiCmnd->cdb[4]; /* FIS LBA (47:40) */
6000 fis->d.featuresExp = 0; /* FIS reserve */
6001 fis->d.sectorCount = scsiCmnd->cdb[13]; /* FIS sector count (7:0) */
6002 fis->d.sectorCountExp = scsiCmnd->cdb[12]; /* FIS sector count (15:8) */
6003 fis->d.reserved4 = 0;
6004 fis->d.control = 0; /* FIS HOB bit clear */
6005 fis->d.reserved5 = 0;
6006
6007 agRequestType = AGSA_SATA_PROTOCOL_PIO_READ;
6008 satIOContext->ATACmd = SAT_READ_SECTORS_EXT;
6009 }
6010 }
6011
6012
6013 /* case 5 */
6014 if (pSatDevData->satNCQ == agTRUE)
6015 {
6016 /* READ FPDMA QUEUED */
6017 if (pSatDevData->sat48BitSupport != agTRUE)
6018 {
6019 SM_DBG1(("smsatRead16: case 5 !!! error NCQ but 28 bit address support!!!\n"));
6020 smsatSetSensePayload( pSense,
6021 SCSI_SNSKEY_ILLEGAL_REQUEST,
6022 0,
6023 SCSI_SNSCODE_INVALID_FIELD_IN_CDB,
6024 satIOContext);
6025
6026 /*smEnqueueIO(smRoot, satIOContext);*/
6027
6028 tdsmIOCompletedCB( smRoot,
6029 smIORequest,
6030 smIOSuccess,
6031 SCSI_STAT_CHECK_CONDITION,
6032 satIOContext->pSmSenseData,
6033 satIOContext->interruptContext );
6034 return SM_RC_SUCCESS;
6035 }
6036
6037 SM_DBG6(("smsatRead16: case 5\n"));
6038
6039 /* Support 48-bit FPDMA addressing, use READ FPDMA QUEUE command */
6040
6041 fis->h.fisType = 0x27; /* Reg host to device */
6042 fis->h.c_pmPort = 0x80; /* C Bit is set */
6043 fis->h.command = SAT_READ_FPDMA_QUEUED; /* 0x60 */
6044 fis->h.features = scsiCmnd->cdb[13]; /* FIS sector count (7:0) */
6045 fis->d.lbaLow = scsiCmnd->cdb[9]; /* FIS LBA (7 :0 ) */
6046 fis->d.lbaMid = scsiCmnd->cdb[8]; /* FIS LBA (15:8 ) */
6047 fis->d.lbaHigh = scsiCmnd->cdb[7]; /* FIS LBA (23:16) */
6048
6049 /* Check FUA bit */
6050 if (scsiCmnd->cdb[1] & SCSI_READ16_FUA_MASK)
6051 fis->d.device = 0xC0; /* FIS FUA set */
6052 else
6053 fis->d.device = 0x40; /* FIS FUA clear */
6054
6055 fis->d.lbaLowExp = scsiCmnd->cdb[6]; /* FIS LBA (31:24) */
6056 fis->d.lbaMidExp = scsiCmnd->cdb[5]; /* FIS LBA (39:32) */
6057 fis->d.lbaHighExp = scsiCmnd->cdb[4]; /* FIS LBA (47:40) */
6058 fis->d.featuresExp = scsiCmnd->cdb[12]; /* FIS sector count (15:8) */
6059 fis->d.sectorCount = 0; /* Tag (7:3) set by LL layer */
6060 fis->d.sectorCountExp = 0;
6061 fis->d.reserved4 = 0;
6062 fis->d.control = 0; /* FIS HOB bit clear */
6063 fis->d.reserved5 = 0;
6064
6065 agRequestType = AGSA_SATA_PROTOCOL_FPDMA_READ;
6066 satIOContext->ATACmd = SAT_READ_FPDMA_QUEUED;
6067 }
6068
6069 /* saves the current LBA and orginal TL */
6070 satIOContext->currentLBA = lba;
6071 satIOContext->OrgTL = tl;
6072
6073 /*
6074 computing number of loop and remainder for tl
6075 0xFF in case not ext
6076 0xFFFF in case EXT
6077 */
6078 if (fis->h.command == SAT_READ_SECTORS || fis->h.command == SAT_READ_DMA)
6079 {
6080 LoopNum = smsatComputeLoopNum(tl, 0xFF);
6081 }
6082 else if (fis->h.command == SAT_READ_SECTORS_EXT || fis->h.command == SAT_READ_DMA_EXT)
6083 {
6084 /* SAT_READ_SECTORS_EXT, SAT_READ_DMA_EXT */
6085 LoopNum = smsatComputeLoopNum(tl, 0xFFFF);
6086 }
6087 else
6088 {
6089 /* SAT_READ_FPDMA_QUEUEDK */
6090 LoopNum = smsatComputeLoopNum(tl, 0xFFFF);
6091 }
6092 satIOContext->LoopNum = LoopNum;
6093
6094 if (LoopNum == 1)
6095 {
6096 SM_DBG5(("smsatRead16: NON CHAINED data\n"));
6097 satIOContext->satCompleteCB = &smsatNonChainedDataIOCB;
6098 }
6099 else
6100 {
6101 SM_DBG1(("smsatRead16: CHAINED data!!!\n"));
6102 /* re-setting tl */
6103 if (fis->h.command == SAT_READ_SECTORS || fis->h.command == SAT_READ_DMA)
6104 {
6105 fis->d.sectorCount = 0xFF;
6106 }
6107 else if (fis->h.command == SAT_READ_SECTORS_EXT || fis->h.command == SAT_READ_DMA_EXT)
6108 {
6109 /* SAT_READ_SECTORS_EXT, SAT_READ_DMA_EXT */
6110 fis->d.sectorCount = 0xFF;
6111 fis->d.sectorCountExp = 0xFF;
6112 }
6113 else
6114 {
6115 /* SAT_READ_FPDMA_QUEUED */
6116 fis->h.features = 0xFF;
6117 fis->d.featuresExp = 0xFF;
6118 }
6119
6120 /* chained data */
6121 satIOContext->satCompleteCB = &smsatChainedDataIOCB;
6122 }
6123
6124 /*
6125 * Prepare SGL and send FIS to LL layer.
6126 */
6127 satIOContext->reqType = agRequestType; /* Save it */
6128
6129 status = smsataLLIOStart( smRoot,
6130 smIORequest,
6131 smDeviceHandle,
6132 smScsiRequest,
6133 satIOContext);
6134
6135 SM_DBG5(("smsatRead16: return\n"));
6136 return (status);
6137
6138 }
6139
6140 osGLOBAL bit32
smsatWrite6(smRoot_t * smRoot,smIORequest_t * smIORequest,smDeviceHandle_t * smDeviceHandle,smScsiInitiatorRequest_t * smScsiRequest,smSatIOContext_t * satIOContext)6141 smsatWrite6(
6142 smRoot_t *smRoot,
6143 smIORequest_t *smIORequest,
6144 smDeviceHandle_t *smDeviceHandle,
6145 smScsiInitiatorRequest_t *smScsiRequest,
6146 smSatIOContext_t *satIOContext
6147 )
6148 {
6149
6150 bit32 status;
6151 bit32 agRequestType = AGSA_SATA_PROTOCOL_DMA_WRITE;
6152 smDeviceData_t *pSatDevData;
6153 smScsiRspSense_t *pSense;
6154 smIniScsiCmnd_t *scsiCmnd;
6155 agsaFisRegHostToDevice_t *fis;
6156 bit32 lba = 0;
6157 bit16 tl = 0;
6158
6159 pSense = satIOContext->pSense;
6160 pSatDevData = satIOContext->pSatDevData;
6161 scsiCmnd = &smScsiRequest->scsiCmnd;
6162 fis = satIOContext->pFis;
6163
6164 SM_DBG5(("smsatWrite6: start\n"));
6165
6166 /* checking CONTROL */
6167 /* NACA == 1 or LINK == 1*/
6168 if ( (scsiCmnd->cdb[5] & SCSI_NACA_MASK) || (scsiCmnd->cdb[5] & SCSI_LINK_MASK) )
6169 {
6170 smsatSetSensePayload( pSense,
6171 SCSI_SNSKEY_ILLEGAL_REQUEST,
6172 0,
6173 SCSI_SNSCODE_INVALID_FIELD_IN_CDB,
6174 satIOContext);
6175
6176 /*smEnqueueIO(smRoot, satIOContext);*/
6177
6178 tdsmIOCompletedCB( smRoot,
6179 smIORequest,
6180 smIOSuccess,
6181 SCSI_STAT_CHECK_CONDITION,
6182 satIOContext->pSmSenseData,
6183 satIOContext->interruptContext );
6184
6185 SM_DBG1(("smsatWrite6: return control!!!\n"));
6186 return SM_RC_SUCCESS;
6187 }
6188
6189
6190 /* cbd6; computing LBA and transfer length */
6191 lba = (((scsiCmnd->cdb[1]) & 0x1f) << (8*2))
6192 + (scsiCmnd->cdb[2] << 8) + scsiCmnd->cdb[3];
6193 tl = scsiCmnd->cdb[4];
6194
6195
6196 /* Table 34, 9.1, p 46 */
6197 /*
6198 note: As of 2/10/2006, no support for DMA QUEUED
6199 */
6200
6201 /*
6202 Table 34, 9.1, p 46, b
6203 When no 48-bit addressing support or NCQ, if LBA is beyond (2^28 - 1),
6204 return check condition
6205 */
6206 if (pSatDevData->satNCQ != agTRUE &&
6207 pSatDevData->sat48BitSupport != agTRUE
6208 )
6209 {
6210 if (lba > SAT_TR_LBA_LIMIT - 1)
6211 {
6212 smsatSetSensePayload( pSense,
6213 SCSI_SNSKEY_ILLEGAL_REQUEST,
6214 0,
6215 SCSI_SNSCODE_LOGICAL_BLOCK_ADDRESS_OUT_OF_RANGE,
6216 satIOContext);
6217
6218 /*smEnqueueIO(smRoot, satIOContext);*/
6219
6220 tdsmIOCompletedCB( smRoot,
6221 smIORequest,
6222 smIOSuccess,
6223 SCSI_STAT_CHECK_CONDITION,
6224 satIOContext->pSmSenseData,
6225 satIOContext->interruptContext );
6226
6227 SM_DBG1(("smsatWrite6: return LBA out of range!!!\n"));
6228 return SM_RC_SUCCESS;
6229 }
6230 }
6231
6232 /* case 1 and 2 */
6233 if (lba + tl <= SAT_TR_LBA_LIMIT)
6234 {
6235 if (pSatDevData->satDMASupport == agTRUE && pSatDevData->satDMAEnabled == agTRUE)
6236 {
6237 /* case 2 */
6238 /* WRITE DMA*/
6239 SM_DBG5(("smsatWrite6: case 2\n"));
6240
6241
6242 fis->h.fisType = 0x27; /* Reg host to device */
6243 fis->h.c_pmPort = 0x80; /* C Bit is set */
6244 fis->h.command = SAT_WRITE_DMA; /* 0xCA */
6245 fis->h.features = 0; /* FIS reserve */
6246 fis->d.lbaLow = scsiCmnd->cdb[3]; /* FIS LBA (7 :0 ) */
6247 fis->d.lbaMid = scsiCmnd->cdb[2]; /* FIS LBA (15:8 ) */
6248 fis->d.lbaHigh = (bit8)((scsiCmnd->cdb[1]) & 0x1f); /* FIS LBA (23:16) */
6249 fis->d.device = 0x40; /* FIS LBA mode */
6250 fis->d.lbaLowExp = 0;
6251 fis->d.lbaMidExp = 0;
6252 fis->d.lbaHighExp = 0;
6253 fis->d.featuresExp = 0;
6254 if (tl == 0)
6255 {
6256 /* temporary fix */
6257 fis->d.sectorCount = 0xff; /* FIS sector count (7:0) */
6258 }
6259 else
6260 {
6261 fis->d.sectorCount = scsiCmnd->cdb[4]; /* FIS sector count (7:0) */
6262 }
6263 fis->d.sectorCountExp = 0;
6264 fis->d.reserved4 = 0;
6265 fis->d.control = 0; /* FIS HOB bit clear */
6266 fis->d.reserved5 = 0;
6267
6268 agRequestType = AGSA_SATA_PROTOCOL_DMA_WRITE;
6269 }
6270 else
6271 {
6272 /* case 1 */
6273 /* WRITE SECTORS for easier implemetation */
6274 SM_DBG5(("smsatWrite6: case 1\n"));
6275
6276 fis->h.fisType = 0x27; /* Reg host to device */
6277 fis->h.c_pmPort = 0x80; /* C Bit is set */
6278 fis->h.command = SAT_WRITE_SECTORS; /* 0xCA */
6279 fis->h.features = 0; /* FIS reserve */
6280 fis->d.lbaLow = scsiCmnd->cdb[3]; /* FIS LBA (7 :0 ) */
6281 fis->d.lbaMid = scsiCmnd->cdb[2]; /* FIS LBA (15:8 ) */
6282 fis->d.lbaHigh = (bit8)((scsiCmnd->cdb[1]) & 0x1f); /* FIS LBA (23:16) */
6283 fis->d.device = 0x40; /* FIS LBA mode */
6284 fis->d.lbaLowExp = 0;
6285 fis->d.lbaMidExp = 0;
6286 fis->d.lbaHighExp = 0;
6287 fis->d.featuresExp = 0;
6288 if (tl == 0)
6289 {
6290 /* temporary fix */
6291 fis->d.sectorCount = 0xff; /* FIS sector count (7:0) */
6292 }
6293 else
6294 {
6295 fis->d.sectorCount = scsiCmnd->cdb[4]; /* FIS sector count (7:0) */
6296 }
6297 fis->d.sectorCountExp = 0;
6298 fis->d.reserved4 = 0;
6299 fis->d.control = 0; /* FIS HOB bit clear */
6300 fis->d.reserved5 = 0;
6301
6302 agRequestType = AGSA_SATA_PROTOCOL_PIO_WRITE;
6303
6304 }
6305 }
6306
6307 /* case 3 and 4 */
6308 if (pSatDevData->sat48BitSupport == agTRUE)
6309 {
6310 if (pSatDevData->satDMASupport == agTRUE && pSatDevData->satDMAEnabled == agTRUE)
6311 {
6312 /* case 3 */
6313 /* WRITE DMA EXT only */
6314 SM_DBG5(("smsatWrite6: case 3\n"));
6315 fis->h.fisType = 0x27; /* Reg host to device */
6316 fis->h.c_pmPort = 0x80; /* C Bit is set */
6317 fis->h.command = SAT_WRITE_DMA_EXT; /* 0x35 */
6318 fis->h.features = 0; /* FIS reserve */
6319 fis->d.lbaLow = scsiCmnd->cdb[3]; /* FIS LBA (7 :0 ) */
6320 fis->d.lbaMid = scsiCmnd->cdb[2]; /* FIS LBA (15:8 ) */
6321 fis->d.lbaHigh = (bit8)((scsiCmnd->cdb[1]) & 0x1f); /* FIS LBA (23:16) */
6322 fis->d.device = 0x40; /* FIS LBA mode set */
6323 fis->d.lbaLowExp = 0; /* FIS LBA (31:24) */
6324 fis->d.lbaMidExp = 0; /* FIS LBA (39:32) */
6325 fis->d.lbaHighExp = 0; /* FIS LBA (47:40) */
6326 fis->d.featuresExp = 0; /* FIS reserve */
6327 if (tl == 0)
6328 {
6329 /* sector count is 256, 0x100*/
6330 fis->d.sectorCount = 0; /* FIS sector count (7:0) */
6331 fis->d.sectorCountExp = 0x01; /* FIS sector count (15:8) */
6332 }
6333 else
6334 {
6335 fis->d.sectorCount = scsiCmnd->cdb[4]; /* FIS sector count (7:0) */
6336 fis->d.sectorCountExp = 0; /* FIS sector count (15:8) */
6337 }
6338 fis->d.reserved4 = 0;
6339 fis->d.control = 0; /* FIS HOB bit clear */
6340 fis->d.reserved5 = 0;
6341
6342 agRequestType = AGSA_SATA_PROTOCOL_DMA_WRITE;
6343 }
6344 else
6345 {
6346 /* case 4 */
6347 /* WRITE SECTORS EXT for easier implemetation */
6348 SM_DBG5(("smsatWrite6: case 4\n"));
6349
6350 fis->h.fisType = 0x27; /* Reg host to device */
6351 fis->h.c_pmPort = 0x80; /* C Bit is set */
6352 fis->h.command = SAT_WRITE_SECTORS_EXT; /* 0x34 */
6353 fis->h.features = 0; /* FIS reserve */
6354 fis->d.lbaLow = scsiCmnd->cdb[3]; /* FIS LBA (7 :0 ) */
6355 fis->d.lbaMid = scsiCmnd->cdb[2]; /* FIS LBA (15:8 ) */
6356 fis->d.lbaHigh = (bit8)((scsiCmnd->cdb[1]) & 0x1f); /* FIS LBA (23:16) */
6357 fis->d.device = 0x40; /* FIS LBA mode set */
6358 fis->d.lbaLowExp = 0; /* FIS LBA (31:24) */
6359 fis->d.lbaMidExp = 0; /* FIS LBA (39:32) */
6360 fis->d.lbaHighExp = 0; /* FIS LBA (47:40) */
6361 fis->d.featuresExp = 0; /* FIS reserve */
6362 if (tl == 0)
6363 {
6364 /* sector count is 256, 0x100*/
6365 fis->d.sectorCount = 0; /* FIS sector count (7:0) */
6366 fis->d.sectorCountExp = 0x01; /* FIS sector count (15:8) */
6367 }
6368 else
6369 {
6370 fis->d.sectorCount = scsiCmnd->cdb[4]; /* FIS sector count (7:0) */
6371 fis->d.sectorCountExp = 0; /* FIS sector count (15:8) */
6372 }
6373 fis->d.reserved4 = 0;
6374 fis->d.control = 0; /* FIS HOB bit clear */
6375 fis->d.reserved5 = 0;
6376
6377 agRequestType = AGSA_SATA_PROTOCOL_PIO_WRITE;
6378 }
6379 }
6380
6381 /* case 5 */
6382 if (pSatDevData->satNCQ == agTRUE)
6383 {
6384 /* WRITE FPDMA QUEUED */
6385 if (pSatDevData->sat48BitSupport != agTRUE)
6386 {
6387 /* sanity check */
6388 SM_DBG5(("smsatWrite6: case 5 !!! error NCQ but 28 bit address support!!!\n"));
6389 smsatSetSensePayload( pSense,
6390 SCSI_SNSKEY_ILLEGAL_REQUEST,
6391 0,
6392 SCSI_SNSCODE_INVALID_FIELD_IN_CDB,
6393 satIOContext);
6394
6395 /*smEnqueueIO(smRoot, satIOContext);*/
6396
6397 tdsmIOCompletedCB( smRoot,
6398 smIORequest,
6399 smIOSuccess,
6400 SCSI_STAT_CHECK_CONDITION,
6401 satIOContext->pSmSenseData,
6402 satIOContext->interruptContext );
6403 return SM_RC_SUCCESS;
6404 }
6405 SM_DBG5(("smsatWrite6: case 5\n"));
6406
6407 /* Support 48-bit FPDMA addressing, use WRITE FPDMA QUEUE command */
6408
6409 fis->h.fisType = 0x27; /* Reg host to device */
6410 fis->h.c_pmPort = 0x80; /* C Bit is set */
6411 fis->h.command = SAT_WRITE_FPDMA_QUEUED; /* 0x61 */
6412 fis->d.lbaLow = scsiCmnd->cdb[3]; /* FIS LBA (7 :0 ) */
6413 fis->d.lbaMid = scsiCmnd->cdb[2]; /* FIS LBA (15:8 ) */
6414 fis->d.lbaHigh = (bit8)((scsiCmnd->cdb[1]) & 0x1f); /* FIS LBA (23:16) */
6415 fis->d.device = 0x40; /* FIS FUA clear */
6416 fis->d.lbaLowExp = 0; /* FIS LBA (31:24) */
6417 fis->d.lbaMidExp = 0; /* FIS LBA (39:32) */
6418 fis->d.lbaHighExp = 0; /* FIS LBA (47:40) */
6419 if (tl == 0)
6420 {
6421 /* sector count is 256, 0x100*/
6422 fis->h.features = 0; /* FIS sector count (7:0) */
6423 fis->d.featuresExp = 0x01; /* FIS sector count (15:8) */
6424 }
6425 else
6426 {
6427 fis->h.features = scsiCmnd->cdb[4]; /* FIS sector count (7:0) */
6428 fis->d.featuresExp = 0; /* FIS sector count (15:8) */
6429 }
6430 fis->d.sectorCount = 0; /* Tag (7:3) set by LL layer */
6431 fis->d.sectorCountExp = 0;
6432 fis->d.reserved4 = 0;
6433 fis->d.control = 0; /* FIS HOB bit clear */
6434 fis->d.reserved5 = 0;
6435
6436 agRequestType = AGSA_SATA_PROTOCOL_FPDMA_WRITE;
6437 }
6438
6439 /* Initialize CB for SATA completion.
6440 */
6441 satIOContext->satCompleteCB = &smsatNonChainedDataIOCB;
6442
6443 /*
6444 * Prepare SGL and send FIS to LL layer.
6445 */
6446 satIOContext->reqType = agRequestType; /* Save it */
6447
6448 status = smsataLLIOStart( smRoot,
6449 smIORequest,
6450 smDeviceHandle,
6451 smScsiRequest,
6452 satIOContext);
6453 return (status);
6454 }
6455
6456 osGLOBAL FORCEINLINE bit32
smsatWrite10(smRoot_t * smRoot,smIORequest_t * smIORequest,smDeviceHandle_t * smDeviceHandle,smScsiInitiatorRequest_t * smScsiRequest,smSatIOContext_t * satIOContext)6457 smsatWrite10(
6458 smRoot_t *smRoot,
6459 smIORequest_t *smIORequest,
6460 smDeviceHandle_t *smDeviceHandle,
6461 smScsiInitiatorRequest_t *smScsiRequest,
6462 smSatIOContext_t *satIOContext
6463 )
6464 {
6465 smDeviceData_t *pSatDevData = satIOContext->pSatDevData;
6466 smScsiRspSense_t *pSense = satIOContext->pSense;
6467 smIniScsiCmnd_t *scsiCmnd = &smScsiRequest->scsiCmnd;
6468 agsaFisRegHostToDevice_t *fis = satIOContext->pFis;
6469 bit32 status = SM_RC_FAILURE;
6470 bit32 agRequestType = AGSA_SATA_PROTOCOL_DMA_WRITE;
6471 bit32 lba = 0;
6472 bit32 tl = 0;
6473 bit32 LoopNum = 1;
6474 bit32 AllChk = agFALSE; /* lba, lba+tl check against ATA limit and Disk capacity */
6475 bit8 LBA[8];
6476 bit8 TL[8];
6477
6478 SM_DBG2(("smsatWrite10: start\n"));
6479
6480 /* checking FUA_NV */
6481 if (scsiCmnd->cdb[1] & SCSI_FUA_NV_MASK)
6482 {
6483 smsatSetSensePayload( pSense,
6484 SCSI_SNSKEY_ILLEGAL_REQUEST,
6485 0,
6486 SCSI_SNSCODE_INVALID_FIELD_IN_CDB,
6487 satIOContext);
6488
6489 /*smEnqueueIO(smRoot, satIOContext);*/
6490
6491 tdsmIOCompletedCB( smRoot,
6492 smIORequest,
6493 smIOSuccess,
6494 SCSI_STAT_CHECK_CONDITION,
6495 satIOContext->pSmSenseData,
6496 satIOContext->interruptContext );
6497
6498 SM_DBG1(("smsatWrite10: return FUA_NV!!!\n"));
6499 return SM_RC_SUCCESS;
6500
6501 }
6502
6503 /* checking CONTROL */
6504 /* NACA == 1 or LINK == 1*/
6505 if ( (scsiCmnd->cdb[9] & SCSI_NACA_MASK) || (scsiCmnd->cdb[9] & SCSI_LINK_MASK) )
6506 {
6507 smsatSetSensePayload( pSense,
6508 SCSI_SNSKEY_ILLEGAL_REQUEST,
6509 0,
6510 SCSI_SNSCODE_INVALID_FIELD_IN_CDB,
6511 satIOContext);
6512
6513 /*smEnqueueIO(smRoot, satIOContext);*/
6514
6515 tdsmIOCompletedCB( smRoot,
6516 smIORequest,
6517 smIOSuccess,
6518 SCSI_STAT_CHECK_CONDITION,
6519 satIOContext->pSmSenseData,
6520 satIOContext->interruptContext );
6521
6522 SM_DBG1(("smsatWrite10: return control!!!\n"));
6523 return SM_RC_SUCCESS;
6524 }
6525 /*
6526 sm_memset(LBA, 0, sizeof(LBA));
6527 sm_memset(TL, 0, sizeof(TL));
6528 */
6529 /* do not use memcpy due to indexing in LBA and TL */
6530 LBA[0] = 0; /* MSB */
6531 LBA[1] = 0;
6532 LBA[2] = 0;
6533 LBA[3] = 0;
6534 LBA[4] = scsiCmnd->cdb[2];
6535 LBA[5] = scsiCmnd->cdb[3];
6536 LBA[6] = scsiCmnd->cdb[4];
6537 LBA[7] = scsiCmnd->cdb[5]; /* LSB */
6538
6539 TL[0] = 0;
6540 TL[1] = 0;
6541 TL[2] = 0;
6542 TL[3] = 0;
6543 TL[4] = 0;
6544 TL[5] = 0;
6545 TL[6] = scsiCmnd->cdb[7];
6546 TL[7] = scsiCmnd->cdb[8]; /* LSB */
6547
6548
6549
6550 /* cbd10; computing LBA and transfer length */
6551 lba = (scsiCmnd->cdb[2] << (24)) + (scsiCmnd->cdb[3] << (16))
6552 + (scsiCmnd->cdb[4] << 8) + scsiCmnd->cdb[5];
6553 tl = (scsiCmnd->cdb[7] << 8) + scsiCmnd->cdb[8];
6554
6555 SM_DBG5(("smsatWrite10: lba %d functioned lba %d\n", lba, smsatComputeCDB10LBA(satIOContext)));
6556 SM_DBG5(("smsatWrite10: tl %d functioned tl %d\n", tl, smsatComputeCDB10TL(satIOContext)));
6557
6558 /* Table 34, 9.1, p 46 */
6559 /*
6560 note: As of 2/10/2006, no support for DMA QUEUED
6561 */
6562
6563 /*
6564 Table 34, 9.1, p 46, b
6565 When no 48-bit addressing support or NCQ, if LBA is beyond (2^28 - 1),
6566 return check condition
6567 */
6568 if (pSatDevData->satNCQ != agTRUE &&
6569 pSatDevData->sat48BitSupport != agTRUE
6570 )
6571 {
6572 AllChk = smsatCheckLimit(LBA, TL, agFALSE, pSatDevData);
6573 if (AllChk)
6574 {
6575 SM_DBG1(("smsatWrite10: return LBA out of range, not EXT!!!\n"));
6576 SM_DBG1(("smsatWrite10: cdb 0x%x 0x%x 0x%x 0x%x!!!\n",scsiCmnd->cdb[2], scsiCmnd->cdb[3],
6577 scsiCmnd->cdb[4], scsiCmnd->cdb[5]));
6578 SM_DBG1(("smsatWrite10: lba 0x%x SAT_TR_LBA_LIMIT 0x%x!!!\n", lba, SAT_TR_LBA_LIMIT));
6579 smsatSetSensePayload( pSense,
6580 SCSI_SNSKEY_ILLEGAL_REQUEST,
6581 0,
6582 SCSI_SNSCODE_LOGICAL_BLOCK_ADDRESS_OUT_OF_RANGE,
6583 satIOContext);
6584
6585 /*smEnqueueIO(smRoot, satIOContext);*/
6586
6587 tdsmIOCompletedCB( smRoot,
6588 smIORequest,
6589 smIOSuccess,
6590 SCSI_STAT_CHECK_CONDITION,
6591 satIOContext->pSmSenseData,
6592 satIOContext->interruptContext );
6593
6594 return SM_RC_SUCCESS;
6595 }
6596 }
6597 else
6598 {
6599 AllChk = smsatCheckLimit(LBA, TL, agTRUE, pSatDevData);
6600 if (AllChk)
6601 {
6602 SM_DBG1(("smsatWrite10: return LBA out of range, EXT!!!\n"));
6603 smsatSetSensePayload( pSense,
6604 SCSI_SNSKEY_ILLEGAL_REQUEST,
6605 0,
6606 SCSI_SNSCODE_LOGICAL_BLOCK_ADDRESS_OUT_OF_RANGE,
6607 satIOContext);
6608
6609 /*smEnqueueIO(smRoot, satIOContext);*/
6610
6611 tdsmIOCompletedCB( smRoot,
6612 smIORequest,
6613 smIOSuccess,
6614 SCSI_STAT_CHECK_CONDITION,
6615 satIOContext->pSmSenseData,
6616 satIOContext->interruptContext );
6617
6618 return SM_RC_SUCCESS;
6619 }
6620
6621 }
6622
6623 /* case 5 */
6624 if (pSatDevData->satNCQ == agTRUE)
6625 {
6626 /* WRITE FPDMA QUEUED */
6627 if (pSatDevData->sat48BitSupport != agTRUE)
6628 {
6629 SM_DBG1(("smsatWrite10: case 5 !!! error NCQ but 28 bit address support!!!\n"));
6630 smsatSetSensePayload( pSense,
6631 SCSI_SNSKEY_ILLEGAL_REQUEST,
6632 0,
6633 SCSI_SNSCODE_INVALID_FIELD_IN_CDB,
6634 satIOContext);
6635
6636 /*smEnqueueIO(smRoot, satIOContext);*/
6637
6638 tdsmIOCompletedCB( smRoot,
6639 smIORequest,
6640 smIOSuccess,
6641 SCSI_STAT_CHECK_CONDITION,
6642 satIOContext->pSmSenseData,
6643 satIOContext->interruptContext );
6644 return SM_RC_SUCCESS;
6645 }
6646 SM_DBG6(("smsatWrite10: case 5\n"));
6647
6648 /* Support 48-bit FPDMA addressing, use WRITE FPDMA QUEUE command */
6649
6650 fis->h.fisType = 0x27; /* Reg host to device */
6651 fis->h.c_pmPort = 0x80; /* C Bit is set */
6652 fis->h.command = SAT_WRITE_FPDMA_QUEUED; /* 0x61 */
6653 fis->h.features = scsiCmnd->cdb[8]; /* FIS sector count (7:0) */
6654 fis->d.lbaLow = scsiCmnd->cdb[5]; /* FIS LBA (7 :0 ) */
6655 fis->d.lbaMid = scsiCmnd->cdb[4]; /* FIS LBA (15:8 ) */
6656 fis->d.lbaHigh = scsiCmnd->cdb[3]; /* FIS LBA (23:16) */
6657
6658 /* Check FUA bit */
6659 if (scsiCmnd->cdb[1] & SCSI_WRITE10_FUA_MASK)
6660 fis->d.device = 0xC0; /* FIS FUA set */
6661 else
6662 fis->d.device = 0x40; /* FIS FUA clear */
6663
6664 fis->d.lbaLowExp = scsiCmnd->cdb[2]; /* FIS LBA (31:24) */
6665 fis->d.lbaMidExp = 0; /* FIS LBA (39:32) */
6666 fis->d.lbaHighExp = 0; /* FIS LBA (47:40) */
6667 fis->d.featuresExp = scsiCmnd->cdb[7]; /* FIS sector count (15:8) */
6668 fis->d.sectorCount = 0; /* Tag (7:3) set by LL layer */
6669 fis->d.sectorCountExp = 0;
6670 fis->d.reserved4 = 0;
6671 fis->d.control = 0; /* FIS HOB bit clear */
6672 fis->d.reserved5 = 0;
6673
6674 agRequestType = AGSA_SATA_PROTOCOL_FPDMA_WRITE;
6675 satIOContext->ATACmd = SAT_WRITE_FPDMA_QUEUED;
6676 }
6677 /* case 3 and 4 */
6678 else if (pSatDevData->sat48BitSupport == agTRUE)
6679 {
6680 if (pSatDevData->satDMASupport == agTRUE && pSatDevData->satDMAEnabled == agTRUE)
6681 {
6682 /* case 3 */
6683 /* WRITE DMA EXT or WRITE DMA FUA EXT */
6684 SM_DBG5(("smsatWrite10: case 3\n"));
6685 fis->h.fisType = 0x27; /* Reg host to device */
6686 fis->h.c_pmPort = 0x80; /* C Bit is set */
6687
6688 /* SAT_WRITE_DMA_FUA_EXT is optional and we don't support it */
6689 fis->h.command = SAT_WRITE_DMA_EXT; /* 0x35 */
6690 satIOContext->ATACmd = SAT_WRITE_DMA_EXT;
6691
6692 fis->h.features = 0; /* FIS reserve */
6693 fis->d.lbaLow = scsiCmnd->cdb[5]; /* FIS LBA (7 :0 ) */
6694 fis->d.lbaMid = scsiCmnd->cdb[4]; /* FIS LBA (15:8 ) */
6695 fis->d.lbaHigh = scsiCmnd->cdb[3]; /* FIS LBA (23:16) */
6696 fis->d.device = 0x40; /* FIS LBA mode set */
6697 fis->d.lbaLowExp = scsiCmnd->cdb[2]; /* FIS LBA (31:24) */
6698 fis->d.lbaMidExp = 0; /* FIS LBA (39:32) */
6699 fis->d.lbaHighExp = 0; /* FIS LBA (47:40) */
6700 fis->d.featuresExp = 0; /* FIS reserve */
6701 fis->d.sectorCount = scsiCmnd->cdb[8]; /* FIS sector count (7:0) */
6702 fis->d.sectorCountExp = scsiCmnd->cdb[7]; /* FIS sector count (15:8) */
6703 fis->d.reserved4 = 0;
6704 fis->d.control = 0; /* FIS HOB bit clear */
6705 fis->d.reserved5 = 0;
6706
6707 agRequestType = AGSA_SATA_PROTOCOL_DMA_WRITE;
6708 }
6709 else
6710 {
6711 /* case 4 */
6712 /* WRITE MULTIPLE EXT or WRITE MULTIPLE FUA EXT or WRITE SECTOR(S) EXT */
6713 /* WRITE SECTORS EXT for easier implemetation */
6714 SM_DBG5(("smsatWrite10: case 4\n"));
6715 fis->h.fisType = 0x27; /* Reg host to device */
6716 fis->h.c_pmPort = 0x80; /* C Bit is set */
6717 fis->h.command = SAT_WRITE_SECTORS_EXT; /* 0x34 */
6718
6719 fis->h.features = 0; /* FIS reserve */
6720 fis->d.lbaLow = scsiCmnd->cdb[5]; /* FIS LBA (7 :0 ) */
6721 fis->d.lbaMid = scsiCmnd->cdb[4]; /* FIS LBA (15:8 ) */
6722 fis->d.lbaHigh = scsiCmnd->cdb[3]; /* FIS LBA (23:16) */
6723 fis->d.device = 0x40; /* FIS LBA mode set */
6724 fis->d.lbaLowExp = scsiCmnd->cdb[2]; /* FIS LBA (31:24) */
6725 fis->d.lbaMidExp = 0; /* FIS LBA (39:32) */
6726 fis->d.lbaHighExp = 0; /* FIS LBA (47:40) */
6727 fis->d.featuresExp = 0; /* FIS reserve */
6728 fis->d.sectorCount = scsiCmnd->cdb[8]; /* FIS sector count (7:0) */
6729 fis->d.sectorCountExp = scsiCmnd->cdb[7]; /* FIS sector count (15:8) */
6730 fis->d.reserved4 = 0;
6731 fis->d.control = 0; /* FIS HOB bit clear */
6732 fis->d.reserved5 = 0;
6733
6734 agRequestType = AGSA_SATA_PROTOCOL_PIO_WRITE;
6735 satIOContext->ATACmd = SAT_WRITE_SECTORS_EXT;
6736 }
6737 }
6738 else /* case 1 and 2 */
6739 {
6740 if (pSatDevData->satDMASupport == agTRUE && pSatDevData->satDMAEnabled == agTRUE)
6741 {
6742 /* case 2 */
6743 /* WRITE DMA*/
6744 /* can't fit the transfer length */
6745 SM_DBG5(("smsatWrite10: case 2\n"));
6746 fis->h.fisType = 0x27; /* Reg host to device */
6747 fis->h.c_pmPort = 0x80; /* C bit is set */
6748 fis->h.command = SAT_WRITE_DMA; /* 0xCA */
6749 fis->h.features = 0; /* FIS reserve */
6750 fis->d.lbaLow = scsiCmnd->cdb[5]; /* FIS LBA (7 :0 ) */
6751 fis->d.lbaMid = scsiCmnd->cdb[4]; /* FIS LBA (15:8 ) */
6752 fis->d.lbaHigh = scsiCmnd->cdb[3]; /* FIS LBA (23:16) */
6753
6754 /* FIS LBA mode set LBA (27:24) */
6755 fis->d.device = (bit8)((0x4 << 4) | (scsiCmnd->cdb[2] & 0xF));
6756
6757 fis->d.lbaLowExp = 0;
6758 fis->d.lbaMidExp = 0;
6759 fis->d.lbaHighExp = 0;
6760 fis->d.featuresExp = 0;
6761 fis->d.sectorCount = scsiCmnd->cdb[8]; /* FIS sector count (7:0) */
6762 fis->d.sectorCountExp = 0;
6763 fis->d.reserved4 = 0;
6764 fis->d.control = 0; /* FIS HOB bit clear */
6765 fis->d.reserved5 = 0;
6766
6767 agRequestType = AGSA_SATA_PROTOCOL_DMA_WRITE;
6768 satIOContext->ATACmd = SAT_WRITE_DMA;
6769 }
6770 else
6771 {
6772 /* case 1 */
6773 /* WRITE MULTIPLE or WRITE SECTOR(S) */
6774 /* WRITE SECTORS for easier implemetation */
6775 /* can't fit the transfer length */
6776 SM_DBG5(("smsatWrite10: case 1\n"));
6777 fis->h.fisType = 0x27; /* Reg host to device */
6778 fis->h.c_pmPort = 0x80; /* C bit is set */
6779 fis->h.command = SAT_WRITE_SECTORS; /* 0x30 */
6780 fis->h.features = 0; /* FIS reserve */
6781 fis->d.lbaLow = scsiCmnd->cdb[5]; /* FIS LBA (7 :0 ) */
6782 fis->d.lbaMid = scsiCmnd->cdb[4]; /* FIS LBA (15:8 ) */
6783 fis->d.lbaHigh = scsiCmnd->cdb[3]; /* FIS LBA (23:16) */
6784
6785 /* FIS LBA mode set LBA (27:24) */
6786 fis->d.device = (bit8)((0x4 << 4) | (scsiCmnd->cdb[2] & 0xF));
6787
6788 fis->d.lbaLowExp = 0;
6789 fis->d.lbaMidExp = 0;
6790 fis->d.lbaHighExp = 0;
6791 fis->d.featuresExp = 0;
6792 fis->d.sectorCount = scsiCmnd->cdb[8]; /* FIS sector count (7:0) */
6793 fis->d.sectorCountExp = 0;
6794 fis->d.reserved4 = 0;
6795 fis->d.control = 0; /* FIS HOB bit clear */
6796 fis->d.reserved5 = 0;
6797
6798 agRequestType = AGSA_SATA_PROTOCOL_PIO_WRITE;
6799 satIOContext->ATACmd = SAT_WRITE_SECTORS;
6800 }
6801 }
6802
6803 // smhexdump("satWrite10 final fis", (bit8 *)fis, sizeof(agsaFisRegHostToDevice_t));
6804
6805 satIOContext->currentLBA = lba;
6806 satIOContext->OrgTL = tl;
6807
6808 /*
6809 computing number of loop and remainder for tl
6810 0xFF in case not ext
6811 0xFFFF in case EXT
6812 */
6813 if (fis->h.command == SAT_WRITE_SECTORS || fis->h.command == SAT_WRITE_DMA)
6814 {
6815 LoopNum = smsatComputeLoopNum(tl, 0x100);
6816 }
6817 else
6818 {
6819 /* SAT_WRITE_FPDMA_QUEUEDK */
6820 /* SAT_READ_SECTORS_EXT, SAT_READ_DMA_EXT */
6821 LoopNum = smsatComputeLoopNum(tl, 0xFFFF);
6822 }
6823
6824 satIOContext->LoopNum = LoopNum;
6825
6826
6827 if (LoopNum == 1)
6828 {
6829 SM_DBG5(("smsatWrite10: NON CHAINED data\n"));
6830 /* Initialize CB for SATA completion.
6831 */
6832 satIOContext->satCompleteCB = &smsatNonChainedDataIOCB;
6833 }
6834 else
6835 {
6836 SM_DBG2(("smsatWrite10: CHAINED data!!!\n"));
6837 /* re-setting tl */
6838 if (fis->h.command == SAT_WRITE_SECTORS || fis->h.command == SAT_WRITE_DMA)
6839 {
6840 fis->d.sectorCount = 0x0;
6841 smsatSplitSGL(smRoot,
6842 smIORequest,
6843 smDeviceHandle,
6844 smScsiRequest,
6845 satIOContext,
6846 NON_BIT48_ADDRESS_TL_LIMIT*SATA_SECTOR_SIZE, /* 0x100 * 0x200 */
6847 (satIOContext->OrgTL)*SATA_SECTOR_SIZE,
6848 agTRUE);
6849 }
6850 else if (fis->h.command == SAT_WRITE_SECTORS_EXT ||
6851 fis->h.command == SAT_WRITE_DMA_EXT ||
6852 fis->h.command == SAT_WRITE_DMA_FUA_EXT
6853 )
6854 {
6855 fis->d.sectorCount = 0xFF;
6856 fis->d.sectorCountExp = 0xFF;
6857 smsatSplitSGL(smRoot,
6858 smIORequest,
6859 smDeviceHandle,
6860 smScsiRequest,
6861 satIOContext,
6862 BIT48_ADDRESS_TL_LIMIT*SATA_SECTOR_SIZE, /* 0xFFFF * 0x200 */
6863 (satIOContext->OrgTL)*SATA_SECTOR_SIZE,
6864 agTRUE);
6865 }
6866 else
6867 {
6868 /* SAT_WRITE_FPDMA_QUEUED */
6869 fis->h.features = 0xFF;
6870 fis->d.featuresExp = 0xFF;
6871 smsatSplitSGL(smRoot,
6872 smIORequest,
6873 smDeviceHandle,
6874 smScsiRequest,
6875 satIOContext,
6876 BIT48_ADDRESS_TL_LIMIT*SATA_SECTOR_SIZE, /* 0xFFFF * 0x200 */
6877 (satIOContext->OrgTL)*SATA_SECTOR_SIZE,
6878 agTRUE);
6879 }
6880
6881 /* Initialize CB for SATA completion.
6882 */
6883 satIOContext->satCompleteCB = &smsatChainedDataIOCB;
6884 }
6885
6886
6887 /*
6888 * Prepare SGL and send FIS to LL layer.
6889 */
6890 satIOContext->reqType = agRequestType; /* Save it */
6891
6892 status = smsataLLIOStart( smRoot,
6893 smIORequest,
6894 smDeviceHandle,
6895 smScsiRequest,
6896 satIOContext);
6897 return (status);
6898 }
6899
6900 osGLOBAL bit32
smsatWrite12(smRoot_t * smRoot,smIORequest_t * smIORequest,smDeviceHandle_t * smDeviceHandle,smScsiInitiatorRequest_t * smScsiRequest,smSatIOContext_t * satIOContext)6901 smsatWrite12(
6902 smRoot_t *smRoot,
6903 smIORequest_t *smIORequest,
6904 smDeviceHandle_t *smDeviceHandle,
6905 smScsiInitiatorRequest_t *smScsiRequest,
6906 smSatIOContext_t *satIOContext
6907 )
6908 {
6909 bit32 status;
6910 bit32 agRequestType = AGSA_SATA_PROTOCOL_DMA_WRITE;
6911 smDeviceData_t *pSatDevData;
6912 smScsiRspSense_t *pSense;
6913 smIniScsiCmnd_t *scsiCmnd;
6914 agsaFisRegHostToDevice_t *fis;
6915 bit32 lba = 0;
6916 bit32 tl = 0;
6917 bit32 LoopNum = 1;
6918 bit8 LBA[8];
6919 bit8 TL[8];
6920 bit32 AllChk = agFALSE; /* lba, lba+tl check against ATA limit and Disk capacity */
6921
6922 pSense = satIOContext->pSense;
6923 pSatDevData = satIOContext->pSatDevData;
6924 scsiCmnd = &smScsiRequest->scsiCmnd;
6925 fis = satIOContext->pFis;
6926
6927 SM_DBG5(("smsatWrite12: start\n"));
6928
6929 /* checking FUA_NV */
6930 if (scsiCmnd->cdb[1] & SCSI_FUA_NV_MASK)
6931 {
6932 smsatSetSensePayload( pSense,
6933 SCSI_SNSKEY_ILLEGAL_REQUEST,
6934 0,
6935 SCSI_SNSCODE_INVALID_FIELD_IN_CDB,
6936 satIOContext);
6937
6938 /*smEnqueueIO(smRoot, satIOContext);*/
6939
6940 tdsmIOCompletedCB( smRoot,
6941 smIORequest,
6942 smIOSuccess,
6943 SCSI_STAT_CHECK_CONDITION,
6944 satIOContext->pSmSenseData,
6945 satIOContext->interruptContext );
6946
6947 SM_DBG1(("smsatWrite12: return FUA_NV!!!\n"));
6948 return SM_RC_SUCCESS;
6949
6950 }
6951
6952
6953 /* checking CONTROL */
6954 /* NACA == 1 or LINK == 1*/
6955 if ( (scsiCmnd->cdb[11] & SCSI_NACA_MASK) || (scsiCmnd->cdb[11] & SCSI_LINK_MASK) )
6956 {
6957 smsatSetSensePayload( pSense,
6958 SCSI_SNSKEY_ILLEGAL_REQUEST,
6959 0,
6960 SCSI_SNSCODE_INVALID_FIELD_IN_CDB,
6961 satIOContext);
6962
6963 /*smEnqueueIO(smRoot, satIOContext);*/
6964
6965 tdsmIOCompletedCB( smRoot,
6966 smIORequest,
6967 smIOSuccess,
6968 SCSI_STAT_CHECK_CONDITION,
6969 satIOContext->pSmSenseData,
6970 satIOContext->interruptContext );
6971
6972 SM_DBG1(("smsatWrite10: return control!!!\n"));
6973 return SM_RC_SUCCESS;
6974 }
6975
6976
6977 sm_memset(LBA, 0, sizeof(LBA));
6978 sm_memset(TL, 0, sizeof(TL));
6979
6980 /* do not use memcpy due to indexing in LBA and TL */
6981 LBA[0] = 0; /* MSB */
6982 LBA[1] = 0;
6983 LBA[2] = 0;
6984 LBA[3] = 0;
6985 LBA[4] = scsiCmnd->cdb[2];
6986 LBA[5] = scsiCmnd->cdb[3];
6987 LBA[6] = scsiCmnd->cdb[4];
6988 LBA[7] = scsiCmnd->cdb[5]; /* LSB */
6989
6990 TL[0] = 0; /* MSB */
6991 TL[1] = 0;
6992 TL[2] = 0;
6993 TL[3] = 0;
6994 TL[4] = scsiCmnd->cdb[6];
6995 TL[5] = scsiCmnd->cdb[7];
6996 TL[6] = scsiCmnd->cdb[8];
6997 TL[7] = scsiCmnd->cdb[9]; /* LSB */
6998
6999
7000 lba = smsatComputeCDB12LBA(satIOContext);
7001 tl = smsatComputeCDB12TL(satIOContext);
7002
7003
7004 /* Table 34, 9.1, p 46 */
7005 /*
7006 note: As of 2/10/2006, no support for DMA QUEUED
7007 */
7008
7009 /*
7010 Table 34, 9.1, p 46, b
7011 When no 48-bit addressing support or NCQ, if LBA is beyond (2^28 - 1),
7012 return check condition
7013 */
7014 if (pSatDevData->satNCQ != agTRUE &&
7015 pSatDevData->sat48BitSupport != agTRUE
7016 )
7017 {
7018 AllChk = smsatCheckLimit(LBA, TL, agFALSE, pSatDevData);
7019
7020 /*smEnqueueIO(smRoot, satIOContext);*/
7021
7022
7023
7024 if (AllChk)
7025 {
7026 SM_DBG1(("smsatWrite12: return LBA out of range, not EXT!!!\n"));
7027 smsatSetSensePayload( pSense,
7028 SCSI_SNSKEY_ILLEGAL_REQUEST,
7029 0,
7030 SCSI_SNSCODE_LOGICAL_BLOCK_ADDRESS_OUT_OF_RANGE,
7031 satIOContext);
7032
7033 /*smEnqueueIO(smRoot, satIOContext);*/
7034
7035 tdsmIOCompletedCB( smRoot,
7036 smIORequest,
7037 smIOSuccess,
7038 SCSI_STAT_CHECK_CONDITION,
7039 satIOContext->pSmSenseData,
7040 satIOContext->interruptContext );
7041
7042 return SM_RC_SUCCESS;
7043 }
7044 }
7045 else
7046 {
7047 AllChk = smsatCheckLimit(LBA, TL, agTRUE, pSatDevData);
7048 if (AllChk)
7049 {
7050 SM_DBG1(("smsatWrite12: return LBA out of range, EXT!!!\n"));
7051 smsatSetSensePayload( pSense,
7052 SCSI_SNSKEY_ILLEGAL_REQUEST,
7053 0,
7054 SCSI_SNSCODE_LOGICAL_BLOCK_ADDRESS_OUT_OF_RANGE,
7055 satIOContext);
7056 tdsmIOCompletedCB( smRoot,
7057 smIORequest,
7058 smIOSuccess,
7059 SCSI_STAT_CHECK_CONDITION,
7060 satIOContext->pSmSenseData,
7061 satIOContext->interruptContext );
7062 return SM_RC_SUCCESS;
7063 }
7064 }
7065 if (pSatDevData->satDMASupport == agTRUE && pSatDevData->satDMAEnabled == agTRUE)
7066 {
7067 /* case 2 */
7068 /* WRITE DMA*/
7069 /* In case that we can't fit the transfer length, we loop */
7070 SM_DBG5(("smsatWrite10: case 2\n"));
7071 fis->h.fisType = 0x27; /* Reg host to device */
7072 fis->h.c_pmPort = 0x80; /* C bit is set */
7073 fis->h.command = SAT_WRITE_DMA; /* 0xCA */
7074 fis->h.features = 0; /* FIS reserve */
7075 fis->d.lbaLow = scsiCmnd->cdb[5]; /* FIS LBA (7 :0 ) */
7076 fis->d.lbaMid = scsiCmnd->cdb[4]; /* FIS LBA (15:8 ) */
7077 fis->d.lbaHigh = scsiCmnd->cdb[3]; /* FIS LBA (23:16) */
7078
7079 /* FIS LBA mode set LBA (27:24) */
7080 fis->d.device = (bit8)((0x4 << 4) | (scsiCmnd->cdb[2] & 0xF));
7081
7082 fis->d.lbaLowExp = 0;
7083 fis->d.lbaMidExp = 0;
7084 fis->d.lbaHighExp = 0;
7085 fis->d.featuresExp = 0;
7086 fis->d.sectorCount = scsiCmnd->cdb[9]; /* FIS sector count (7:0) */
7087 fis->d.sectorCountExp = 0;
7088 fis->d.reserved4 = 0;
7089 fis->d.control = 0; /* FIS HOB bit clear */
7090 fis->d.reserved5 = 0;
7091
7092 agRequestType = AGSA_SATA_PROTOCOL_DMA_WRITE;
7093 satIOContext->ATACmd = SAT_WRITE_DMA;
7094 }
7095 else
7096 {
7097 /* case 1 */
7098 /* WRITE MULTIPLE or WRITE SECTOR(S) */
7099 /* WRITE SECTORS for easier implemetation */
7100 /* In case that we can't fit the transfer length, we loop */
7101 SM_DBG5(("smsatWrite10: case 1\n"));
7102 fis->h.fisType = 0x27; /* Reg host to device */
7103 fis->h.c_pmPort = 0x80; /* C bit is set */
7104 fis->h.command = SAT_WRITE_SECTORS; /* 0x30 */
7105 fis->h.features = 0; /* FIS reserve */
7106 fis->d.lbaLow = scsiCmnd->cdb[5]; /* FIS LBA (7 :0 ) */
7107 fis->d.lbaMid = scsiCmnd->cdb[4]; /* FIS LBA (15:8 ) */
7108 fis->d.lbaHigh = scsiCmnd->cdb[3]; /* FIS LBA (23:16) */
7109
7110 /* FIS LBA mode set LBA (27:24) */
7111 fis->d.device = (bit8)((0x4 << 4) | (scsiCmnd->cdb[2] & 0xF));
7112
7113 fis->d.lbaLowExp = 0;
7114 fis->d.lbaMidExp = 0;
7115 fis->d.lbaHighExp = 0;
7116 fis->d.featuresExp = 0;
7117 fis->d.sectorCount = scsiCmnd->cdb[9]; /* FIS sector count (7:0) */
7118 fis->d.sectorCountExp = 0;
7119 fis->d.reserved4 = 0;
7120 fis->d.control = 0; /* FIS HOB bit clear */
7121 fis->d.reserved5 = 0;
7122
7123 agRequestType = AGSA_SATA_PROTOCOL_PIO_WRITE;
7124 satIOContext->ATACmd = SAT_WRITE_SECTORS;
7125 }
7126
7127 /* case 3 and 4 */
7128 if (pSatDevData->sat48BitSupport == agTRUE)
7129 {
7130 if (pSatDevData->satDMASupport == agTRUE && pSatDevData->satDMAEnabled == agTRUE)
7131 {
7132 /* case 3 */
7133 /* WRITE DMA EXT or WRITE DMA FUA EXT */
7134 SM_DBG5(("smsatWrite10: case 3\n"));
7135 fis->h.fisType = 0x27; /* Reg host to device */
7136 fis->h.c_pmPort = 0x80; /* C Bit is set */
7137
7138 /* SAT_WRITE_DMA_FUA_EXT is optional and we don't support it */
7139 fis->h.command = SAT_WRITE_DMA_EXT; /* 0x35 */
7140
7141 fis->h.features = 0; /* FIS reserve */
7142 fis->d.lbaLow = scsiCmnd->cdb[5]; /* FIS LBA (7 :0 ) */
7143 fis->d.lbaMid = scsiCmnd->cdb[4]; /* FIS LBA (15:8 ) */
7144 fis->d.lbaHigh = scsiCmnd->cdb[3]; /* FIS LBA (23:16) */
7145 fis->d.device = 0x40; /* FIS LBA mode set */
7146 fis->d.lbaLowExp = scsiCmnd->cdb[2]; /* FIS LBA (31:24) */
7147 fis->d.lbaMidExp = 0; /* FIS LBA (39:32) */
7148 fis->d.lbaHighExp = 0; /* FIS LBA (47:40) */
7149 fis->d.featuresExp = 0; /* FIS reserve */
7150 fis->d.sectorCount = scsiCmnd->cdb[9]; /* FIS sector count (7:0) */
7151 fis->d.sectorCountExp = scsiCmnd->cdb[8]; /* FIS sector count (15:8) */
7152 fis->d.reserved4 = 0;
7153 fis->d.control = 0; /* FIS HOB bit clear */
7154 fis->d.reserved5 = 0;
7155
7156 agRequestType = AGSA_SATA_PROTOCOL_DMA_WRITE;
7157 satIOContext->ATACmd = SAT_WRITE_DMA_EXT;
7158 }
7159 else
7160 {
7161 /* case 4 */
7162 /* WRITE MULTIPLE EXT or WRITE MULTIPLE FUA EXT or WRITE SECTOR(S) EXT */
7163 /* WRITE SECTORS EXT for easier implemetation */
7164 SM_DBG5(("smsatWrite10: case 4\n"));
7165 fis->h.fisType = 0x27; /* Reg host to device */
7166 fis->h.c_pmPort = 0x80; /* C Bit is set */
7167 fis->h.command = SAT_WRITE_SECTORS_EXT; /* 0x34 */
7168
7169 fis->h.features = 0; /* FIS reserve */
7170 fis->d.lbaLow = scsiCmnd->cdb[5]; /* FIS LBA (7 :0 ) */
7171 fis->d.lbaMid = scsiCmnd->cdb[4]; /* FIS LBA (15:8 ) */
7172 fis->d.lbaHigh = scsiCmnd->cdb[3]; /* FIS LBA (23:16) */
7173 fis->d.device = 0x40; /* FIS LBA mode set */
7174 fis->d.lbaLowExp = scsiCmnd->cdb[2]; /* FIS LBA (31:24) */
7175 fis->d.lbaMidExp = 0; /* FIS LBA (39:32) */
7176 fis->d.lbaHighExp = 0; /* FIS LBA (47:40) */
7177 fis->d.featuresExp = 0; /* FIS reserve */
7178 fis->d.sectorCount = scsiCmnd->cdb[9]; /* FIS sector count (7:0) */
7179 fis->d.sectorCountExp = scsiCmnd->cdb[8]; /* FIS sector count (15:8) */
7180 fis->d.reserved4 = 0;
7181 fis->d.control = 0; /* FIS HOB bit clear */
7182 fis->d.reserved5 = 0;
7183
7184 agRequestType = AGSA_SATA_PROTOCOL_PIO_WRITE;
7185 satIOContext->ATACmd = SAT_WRITE_SECTORS_EXT;
7186 }
7187 }
7188
7189 /* case 5 */
7190 if (pSatDevData->satNCQ == agTRUE)
7191 {
7192 /* WRITE FPDMA QUEUED */
7193 if (pSatDevData->sat48BitSupport != agTRUE)
7194 {
7195 SM_DBG5(("smsatWrite10: case 5 !!! error NCQ but 28 bit address support!!!\n"));
7196 smsatSetSensePayload( pSense,
7197 SCSI_SNSKEY_ILLEGAL_REQUEST,
7198 0,
7199 SCSI_SNSCODE_INVALID_FIELD_IN_CDB,
7200 satIOContext);
7201
7202 /*smEnqueueIO(smRoot, satIOContext);*/
7203
7204 tdsmIOCompletedCB( smRoot,
7205 smIORequest,
7206 smIOSuccess,
7207 SCSI_STAT_CHECK_CONDITION,
7208 satIOContext->pSmSenseData,
7209 satIOContext->interruptContext );
7210 return SM_RC_SUCCESS;
7211 }
7212 SM_DBG6(("smsatWrite10: case 5\n"));
7213
7214 /* Support 48-bit FPDMA addressing, use WRITE FPDMA QUEUE command */
7215
7216 fis->h.fisType = 0x27; /* Reg host to device */
7217 fis->h.c_pmPort = 0x80; /* C Bit is set */
7218 fis->h.command = SAT_WRITE_FPDMA_QUEUED; /* 0x61 */
7219 fis->h.features = scsiCmnd->cdb[9]; /* FIS sector count (7:0) */
7220 fis->d.lbaLow = scsiCmnd->cdb[5]; /* FIS LBA (7 :0 ) */
7221 fis->d.lbaMid = scsiCmnd->cdb[4]; /* FIS LBA (15:8 ) */
7222 fis->d.lbaHigh = scsiCmnd->cdb[3]; /* FIS LBA (23:16) */
7223
7224 /* Check FUA bit */
7225 if (scsiCmnd->cdb[1] & SCSI_WRITE12_FUA_MASK)
7226 fis->d.device = 0xC0; /* FIS FUA set */
7227 else
7228 fis->d.device = 0x40; /* FIS FUA clear */
7229
7230 fis->d.lbaLowExp = scsiCmnd->cdb[2]; /* FIS LBA (31:24) */
7231 fis->d.lbaMidExp = 0; /* FIS LBA (39:32) */
7232 fis->d.lbaHighExp = 0; /* FIS LBA (47:40) */
7233 fis->d.featuresExp = scsiCmnd->cdb[8]; /* FIS sector count (15:8) */
7234 fis->d.sectorCount = 0; /* Tag (7:3) set by LL layer */
7235 fis->d.sectorCountExp = 0;
7236 fis->d.reserved4 = 0;
7237 fis->d.control = 0; /* FIS HOB bit clear */
7238 fis->d.reserved5 = 0;
7239
7240 agRequestType = AGSA_SATA_PROTOCOL_FPDMA_WRITE;
7241 satIOContext->ATACmd = SAT_WRITE_FPDMA_QUEUED;
7242 }
7243
7244 satIOContext->currentLBA = lba;
7245 satIOContext->OrgTL = tl;
7246
7247 /*
7248 computing number of loop and remainder for tl
7249 0xFF in case not ext
7250 0xFFFF in case EXT
7251 */
7252 if (fis->h.command == SAT_WRITE_SECTORS || fis->h.command == SAT_WRITE_DMA)
7253 {
7254 LoopNum = smsatComputeLoopNum(tl, 0xFF);
7255 }
7256 else if (fis->h.command == SAT_WRITE_SECTORS_EXT ||
7257 fis->h.command == SAT_WRITE_DMA_EXT ||
7258 fis->h.command == SAT_WRITE_DMA_FUA_EXT
7259 )
7260 {
7261 /* SAT_READ_SECTORS_EXT, SAT_READ_DMA_EXT */
7262 LoopNum = smsatComputeLoopNum(tl, 0xFFFF);
7263 }
7264 else
7265 {
7266 /* SAT_WRITE_FPDMA_QUEUEDK */
7267 LoopNum = smsatComputeLoopNum(tl, 0xFFFF);
7268 }
7269
7270 satIOContext->LoopNum = LoopNum;
7271
7272
7273 if (LoopNum == 1)
7274 {
7275 SM_DBG5(("smsatWrite10: NON CHAINED data\n"));
7276 /* Initialize CB for SATA completion.
7277 */
7278 satIOContext->satCompleteCB = &smsatNonChainedDataIOCB;
7279 }
7280 else
7281 {
7282 SM_DBG1(("smsatWrite10: CHAINED data\n"));
7283 /* re-setting tl */
7284 if (fis->h.command == SAT_WRITE_SECTORS || fis->h.command == SAT_WRITE_DMA)
7285 {
7286 fis->d.sectorCount = 0xFF;
7287 }
7288 else if (fis->h.command == SAT_WRITE_SECTORS_EXT ||
7289 fis->h.command == SAT_WRITE_DMA_EXT ||
7290 fis->h.command == SAT_WRITE_DMA_FUA_EXT
7291 )
7292 {
7293 fis->d.sectorCount = 0xFF;
7294 fis->d.sectorCountExp = 0xFF;
7295 }
7296 else
7297 {
7298 /* SAT_WRITE_FPDMA_QUEUED */
7299 fis->h.features = 0xFF;
7300 fis->d.featuresExp = 0xFF;
7301 }
7302
7303 /* Initialize CB for SATA completion.
7304 */
7305 satIOContext->satCompleteCB = &smsatChainedDataIOCB;
7306 }
7307
7308
7309 /*
7310 * Prepare SGL and send FIS to LL layer.
7311 */
7312 satIOContext->reqType = agRequestType; /* Save it */
7313
7314 status = smsataLLIOStart( smRoot,
7315 smIORequest,
7316 smDeviceHandle,
7317 smScsiRequest,
7318 satIOContext);
7319 return (status);
7320 }
7321
7322 osGLOBAL bit32
smsatWrite16(smRoot_t * smRoot,smIORequest_t * smIORequest,smDeviceHandle_t * smDeviceHandle,smScsiInitiatorRequest_t * smScsiRequest,smSatIOContext_t * satIOContext)7323 smsatWrite16(
7324 smRoot_t *smRoot,
7325 smIORequest_t *smIORequest,
7326 smDeviceHandle_t *smDeviceHandle,
7327 smScsiInitiatorRequest_t *smScsiRequest,
7328 smSatIOContext_t *satIOContext
7329 )
7330 {
7331 bit32 status;
7332 bit32 agRequestType = AGSA_SATA_PROTOCOL_DMA_WRITE;
7333 smDeviceData_t *pSatDevData;
7334 smScsiRspSense_t *pSense;
7335 smIniScsiCmnd_t *scsiCmnd;
7336 agsaFisRegHostToDevice_t *fis;
7337 bit32 lba = 0;
7338 bit32 tl = 0;
7339 bit32 LoopNum = 1;
7340 bit8 LBA[8];
7341 bit8 TL[8];
7342 bit32 AllChk = agFALSE; /* lba, lba+tl check against ATA limit and Disk capacity */
7343
7344 pSense = satIOContext->pSense;
7345 pSatDevData = satIOContext->pSatDevData;
7346 scsiCmnd = &smScsiRequest->scsiCmnd;
7347 fis = satIOContext->pFis;
7348
7349 SM_DBG5(("smsatWrite16: start\n"));
7350
7351 /* checking FUA_NV */
7352 if (scsiCmnd->cdb[1] & SCSI_FUA_NV_MASK)
7353 {
7354 smsatSetSensePayload( pSense,
7355 SCSI_SNSKEY_ILLEGAL_REQUEST,
7356 0,
7357 SCSI_SNSCODE_INVALID_FIELD_IN_CDB,
7358 satIOContext);
7359
7360 /*smEnqueueIO(smRoot, satIOContext);*/
7361
7362 tdsmIOCompletedCB( smRoot,
7363 smIORequest,
7364 smIOSuccess,
7365 SCSI_STAT_CHECK_CONDITION,
7366 satIOContext->pSmSenseData,
7367 satIOContext->interruptContext );
7368
7369 SM_DBG1(("smsatWrite16: return FUA_NV!!!\n"));
7370 return SM_RC_SUCCESS;
7371
7372 }
7373
7374 /* checking CONTROL */
7375 /* NACA == 1 or LINK == 1*/
7376 if ( (scsiCmnd->cdb[15] & SCSI_NACA_MASK) || (scsiCmnd->cdb[15] & SCSI_LINK_MASK) )
7377 {
7378 smsatSetSensePayload( pSense,
7379 SCSI_SNSKEY_ILLEGAL_REQUEST,
7380 0,
7381 SCSI_SNSCODE_INVALID_FIELD_IN_CDB,
7382 satIOContext);
7383
7384 /*smEnqueueIO(smRoot, satIOContext);*/
7385
7386 tdsmIOCompletedCB( smRoot,
7387 smIORequest,
7388 smIOSuccess,
7389 SCSI_STAT_CHECK_CONDITION,
7390 satIOContext->pSmSenseData,
7391 satIOContext->interruptContext );
7392
7393 SM_DBG1(("smsatWrite16: return control!!!\n"));
7394 return SM_RC_SUCCESS;
7395 }
7396
7397
7398 sm_memset(LBA, 0, sizeof(LBA));
7399 sm_memset(TL, 0, sizeof(TL));
7400
7401
7402 /* do not use memcpy due to indexing in LBA and TL */
7403 LBA[0] = scsiCmnd->cdb[2]; /* MSB */
7404 LBA[1] = scsiCmnd->cdb[3];
7405 LBA[2] = scsiCmnd->cdb[4];
7406 LBA[3] = scsiCmnd->cdb[5];
7407 LBA[4] = scsiCmnd->cdb[6];
7408 LBA[5] = scsiCmnd->cdb[7];
7409 LBA[6] = scsiCmnd->cdb[8];
7410 LBA[7] = scsiCmnd->cdb[9]; /* LSB */
7411
7412 TL[0] = 0;
7413 TL[1] = 0;
7414 TL[2] = 0;
7415 TL[3] = 0;
7416 TL[4] = scsiCmnd->cdb[10]; /* MSB */
7417 TL[5] = scsiCmnd->cdb[11];
7418 TL[6] = scsiCmnd->cdb[12];
7419 TL[7] = scsiCmnd->cdb[13]; /* LSB */
7420
7421
7422
7423 lba = smsatComputeCDB16LBA(satIOContext);
7424 tl = smsatComputeCDB16TL(satIOContext);
7425
7426
7427
7428 /* Table 34, 9.1, p 46 */
7429 /*
7430 note: As of 2/10/2006, no support for DMA QUEUED
7431 */
7432
7433 /*
7434 Table 34, 9.1, p 46, b
7435 When no 48-bit addressing support or NCQ, if LBA is beyond (2^28 - 1),
7436 return check condition
7437 */
7438 if (pSatDevData->satNCQ != agTRUE &&
7439 pSatDevData->sat48BitSupport != agTRUE
7440 )
7441 {
7442 AllChk = smsatCheckLimit(LBA, TL, agFALSE, pSatDevData);
7443 if (AllChk)
7444 {
7445 SM_DBG1(("smsatWrite16: return LBA out of range, not EXT!!!\n"));
7446 smsatSetSensePayload( pSense,
7447 SCSI_SNSKEY_ILLEGAL_REQUEST,
7448 0,
7449 SCSI_SNSCODE_LOGICAL_BLOCK_ADDRESS_OUT_OF_RANGE,
7450 satIOContext);
7451
7452 /*smEnqueueIO(smRoot, satIOContext);*/
7453
7454 tdsmIOCompletedCB( smRoot,
7455 smIORequest,
7456 smIOSuccess,
7457 SCSI_STAT_CHECK_CONDITION,
7458 satIOContext->pSmSenseData,
7459 satIOContext->interruptContext );
7460
7461 return SM_RC_SUCCESS;
7462 }
7463 }
7464 else
7465 {
7466 AllChk = smsatCheckLimit(LBA, TL, agTRUE, pSatDevData);
7467 if (AllChk)
7468 {
7469 SM_DBG1(("smsatWrite16: return LBA out of range, EXT!!!\n"));
7470 smsatSetSensePayload( pSense,
7471 SCSI_SNSKEY_ILLEGAL_REQUEST,
7472 0,
7473 SCSI_SNSCODE_LOGICAL_BLOCK_ADDRESS_OUT_OF_RANGE,
7474 satIOContext);
7475
7476 /*smEnqueueIO(smRoot, satIOContext);*/
7477
7478 tdsmIOCompletedCB( smRoot,
7479 smIORequest,
7480 smIOSuccess,
7481 SCSI_STAT_CHECK_CONDITION,
7482 satIOContext->pSmSenseData,
7483 satIOContext->interruptContext );
7484
7485 return SM_RC_SUCCESS;
7486 }
7487 }
7488
7489 /* case 1 and 2 */
7490 if (pSatDevData->satDMASupport == agTRUE && pSatDevData->satDMAEnabled == agTRUE)
7491 {
7492 /* case 2 */
7493 /* WRITE DMA*/
7494 /* In case that we can't fit the transfer length, we loop */
7495 SM_DBG5(("smsatWrite16: case 2\n"));
7496 fis->h.fisType = 0x27; /* Reg host to device */
7497 fis->h.c_pmPort = 0x80; /* C bit is set */
7498 fis->h.command = SAT_WRITE_DMA; /* 0xCA */
7499 fis->h.features = 0; /* FIS reserve */
7500 fis->d.lbaLow = scsiCmnd->cdb[9]; /* FIS LBA (7 :0 ) */
7501 fis->d.lbaMid = scsiCmnd->cdb[8]; /* FIS LBA (15:8 ) */
7502 fis->d.lbaHigh = scsiCmnd->cdb[7]; /* FIS LBA (23:16) */
7503
7504 /* FIS LBA mode set LBA (27:24) */
7505 fis->d.device = (bit8)((0x4 << 4) | (scsiCmnd->cdb[6] & 0xF));
7506
7507 fis->d.lbaLowExp = 0;
7508 fis->d.lbaMidExp = 0;
7509 fis->d.lbaHighExp = 0;
7510 fis->d.featuresExp = 0;
7511 fis->d.sectorCount = scsiCmnd->cdb[13]; /* FIS sector count (7:0) */
7512 fis->d.sectorCountExp = 0;
7513 fis->d.reserved4 = 0;
7514 fis->d.control = 0; /* FIS HOB bit clear */
7515 fis->d.reserved5 = 0;
7516
7517 agRequestType = AGSA_SATA_PROTOCOL_DMA_WRITE;
7518 satIOContext->ATACmd = SAT_WRITE_DMA;
7519 }
7520 else
7521 {
7522 /* case 1 */
7523 /* WRITE MULTIPLE or WRITE SECTOR(S) */
7524 /* WRITE SECTORS for easier implemetation */
7525 /* In case that we can't fit the transfer length, we loop */
7526 SM_DBG5(("smsatWrite16: case 1\n"));
7527 fis->h.fisType = 0x27; /* Reg host to device */
7528 fis->h.c_pmPort = 0x80; /* C bit is set */
7529 fis->h.command = SAT_WRITE_SECTORS; /* 0x30 */
7530 fis->h.features = 0; /* FIS reserve */
7531 fis->d.lbaLow = scsiCmnd->cdb[9]; /* FIS LBA (7 :0 ) */
7532 fis->d.lbaMid = scsiCmnd->cdb[8]; /* FIS LBA (15:8 ) */
7533 fis->d.lbaHigh = scsiCmnd->cdb[7]; /* FIS LBA (23:16) */
7534
7535 /* FIS LBA mode set LBA (27:24) */
7536 fis->d.device = (bit8)((0x4 << 4) | (scsiCmnd->cdb[6] & 0xF));
7537
7538 fis->d.lbaLowExp = 0;
7539 fis->d.lbaMidExp = 0;
7540 fis->d.lbaHighExp = 0;
7541 fis->d.featuresExp = 0;
7542 fis->d.sectorCount = scsiCmnd->cdb[13]; /* FIS sector count (7:0) */
7543 fis->d.sectorCountExp = 0;
7544 fis->d.reserved4 = 0;
7545 fis->d.control = 0; /* FIS HOB bit clear */
7546 fis->d.reserved5 = 0;
7547
7548 agRequestType = AGSA_SATA_PROTOCOL_PIO_WRITE;
7549 satIOContext->ATACmd = SAT_WRITE_SECTORS;
7550 }
7551
7552 /* case 3 and 4 */
7553 if (pSatDevData->sat48BitSupport == agTRUE)
7554 {
7555 if (pSatDevData->satDMASupport == agTRUE && pSatDevData->satDMAEnabled == agTRUE)
7556 {
7557 /* case 3 */
7558 /* WRITE DMA EXT or WRITE DMA FUA EXT */
7559 SM_DBG5(("smsatWrite16: case 3\n"));
7560 fis->h.fisType = 0x27; /* Reg host to device */
7561 fis->h.c_pmPort = 0x80; /* C Bit is set */
7562
7563 /* SAT_WRITE_DMA_FUA_EXT is optional and we don't support it */
7564 fis->h.command = SAT_WRITE_DMA_EXT; /* 0x35 */
7565
7566 fis->h.features = 0; /* FIS reserve */
7567 fis->d.lbaLow = scsiCmnd->cdb[9]; /* FIS LBA (7 :0 ) */
7568 fis->d.lbaMid = scsiCmnd->cdb[8]; /* FIS LBA (15:8 ) */
7569 fis->d.lbaHigh = scsiCmnd->cdb[7]; /* FIS LBA (23:16) */
7570 fis->d.device = 0x40; /* FIS LBA mode set */
7571 fis->d.lbaLowExp = scsiCmnd->cdb[6]; /* FIS LBA (31:24) */
7572 fis->d.lbaMidExp = scsiCmnd->cdb[5]; /* FIS LBA (39:32) */
7573 fis->d.lbaHighExp = scsiCmnd->cdb[4]; /* FIS LBA (47:40) */
7574 fis->d.featuresExp = 0; /* FIS reserve */
7575 fis->d.sectorCount = scsiCmnd->cdb[13]; /* FIS sector count (7:0) */
7576 fis->d.sectorCountExp = scsiCmnd->cdb[12]; /* FIS sector count (15:8) */
7577 fis->d.reserved4 = 0;
7578 fis->d.control = 0; /* FIS HOB bit clear */
7579 fis->d.reserved5 = 0;
7580
7581 agRequestType = AGSA_SATA_PROTOCOL_DMA_WRITE;
7582 satIOContext->ATACmd = SAT_WRITE_DMA_EXT;
7583 }
7584 else
7585 {
7586 /* case 4 */
7587 /* WRITE MULTIPLE EXT or WRITE MULTIPLE FUA EXT or WRITE SECTOR(S) EXT */
7588 /* WRITE SECTORS EXT for easier implemetation */
7589 SM_DBG5(("smsatWrite16: case 4\n"));
7590 fis->h.fisType = 0x27; /* Reg host to device */
7591 fis->h.c_pmPort = 0x80; /* C Bit is set */
7592 fis->h.command = SAT_WRITE_SECTORS_EXT; /* 0x34 */
7593
7594 fis->h.features = 0; /* FIS reserve */
7595 fis->d.lbaLow = scsiCmnd->cdb[9]; /* FIS LBA (7 :0 ) */
7596 fis->d.lbaMid = scsiCmnd->cdb[8]; /* FIS LBA (15:8 ) */
7597 fis->d.lbaHigh = scsiCmnd->cdb[7]; /* FIS LBA (23:16) */
7598 fis->d.device = 0x40; /* FIS LBA mode set */
7599 fis->d.lbaLowExp = scsiCmnd->cdb[6]; /* FIS LBA (31:24) */
7600 fis->d.lbaMidExp = scsiCmnd->cdb[5]; /* FIS LBA (39:32) */
7601 fis->d.lbaHighExp = scsiCmnd->cdb[4]; /* FIS LBA (47:40) */
7602 fis->d.featuresExp = 0; /* FIS reserve */
7603 fis->d.sectorCount = scsiCmnd->cdb[13]; /* FIS sector count (7:0) */
7604 fis->d.sectorCountExp = scsiCmnd->cdb[12]; /* FIS sector count (15:8) */
7605 fis->d.reserved4 = 0;
7606 fis->d.control = 0; /* FIS HOB bit clear */
7607 fis->d.reserved5 = 0;
7608
7609 agRequestType = AGSA_SATA_PROTOCOL_PIO_WRITE;
7610 satIOContext->ATACmd = SAT_WRITE_SECTORS_EXT;
7611 }
7612 }
7613
7614 /* case 5 */
7615 if (pSatDevData->satNCQ == agTRUE)
7616 {
7617 /* WRITE FPDMA QUEUED */
7618 if (pSatDevData->sat48BitSupport != agTRUE)
7619 {
7620 SM_DBG5(("smsatWrite16: case 5 !!! error NCQ but 28 bit address support!!!\n"));
7621 smsatSetSensePayload( pSense,
7622 SCSI_SNSKEY_ILLEGAL_REQUEST,
7623 0,
7624 SCSI_SNSCODE_INVALID_FIELD_IN_CDB,
7625 satIOContext);
7626
7627 /*smEnqueueIO(smRoot, satIOContext);*/
7628
7629 tdsmIOCompletedCB( smRoot,
7630 smIORequest,
7631 smIOSuccess,
7632 SCSI_STAT_CHECK_CONDITION,
7633 satIOContext->pSmSenseData,
7634 satIOContext->interruptContext );
7635 return SM_RC_SUCCESS;
7636 }
7637 SM_DBG6(("smsatWrite16: case 5\n"));
7638
7639 /* Support 48-bit FPDMA addressing, use WRITE FPDMA QUEUE command */
7640
7641 fis->h.fisType = 0x27; /* Reg host to device */
7642 fis->h.c_pmPort = 0x80; /* C Bit is set */
7643 fis->h.command = SAT_WRITE_FPDMA_QUEUED; /* 0x61 */
7644 fis->h.features = scsiCmnd->cdb[13]; /* FIS sector count (7:0) */
7645 fis->d.lbaLow = scsiCmnd->cdb[9]; /* FIS LBA (7 :0 ) */
7646 fis->d.lbaMid = scsiCmnd->cdb[8]; /* FIS LBA (15:8 ) */
7647 fis->d.lbaHigh = scsiCmnd->cdb[7]; /* FIS LBA (23:16) */
7648
7649 /* Check FUA bit */
7650 if (scsiCmnd->cdb[1] & SCSI_WRITE16_FUA_MASK)
7651 fis->d.device = 0xC0; /* FIS FUA set */
7652 else
7653 fis->d.device = 0x40; /* FIS FUA clear */
7654
7655 fis->d.lbaLowExp = scsiCmnd->cdb[6]; /* FIS LBA (31:24) */
7656 fis->d.lbaMidExp = scsiCmnd->cdb[5]; /* FIS LBA (39:32) */
7657 fis->d.lbaHighExp = scsiCmnd->cdb[4]; /* FIS LBA (47:40) */
7658 fis->d.featuresExp = scsiCmnd->cdb[12]; /* FIS sector count (15:8) */
7659 fis->d.sectorCount = 0; /* Tag (7:3) set by LL layer */
7660 fis->d.sectorCountExp = 0;
7661 fis->d.reserved4 = 0;
7662 fis->d.control = 0; /* FIS HOB bit clear */
7663 fis->d.reserved5 = 0;
7664
7665 agRequestType = AGSA_SATA_PROTOCOL_FPDMA_WRITE;
7666 satIOContext->ATACmd = SAT_WRITE_FPDMA_QUEUED;
7667 }
7668
7669 satIOContext->currentLBA = lba;
7670 satIOContext->OrgTL = tl;
7671
7672 /*
7673 computing number of loop and remainder for tl
7674 0xFF in case not ext
7675 0xFFFF in case EXT
7676 */
7677 if (fis->h.command == SAT_WRITE_SECTORS || fis->h.command == SAT_WRITE_DMA)
7678 {
7679 LoopNum = smsatComputeLoopNum(tl, 0xFF);
7680 }
7681 else if (fis->h.command == SAT_WRITE_SECTORS_EXT ||
7682 fis->h.command == SAT_WRITE_DMA_EXT ||
7683 fis->h.command == SAT_WRITE_DMA_FUA_EXT
7684 )
7685 {
7686 /* SAT_READ_SECTORS_EXT, SAT_READ_DMA_EXT */
7687 LoopNum = smsatComputeLoopNum(tl, 0xFFFF);
7688 }
7689 else
7690 {
7691 /* SAT_WRITE_FPDMA_QUEUEDK */
7692 LoopNum = smsatComputeLoopNum(tl, 0xFFFF);
7693 }
7694
7695 satIOContext->LoopNum = LoopNum;
7696
7697
7698 if (LoopNum == 1)
7699 {
7700 SM_DBG5(("smsatWrite16: NON CHAINED data\n"));
7701 /* Initialize CB for SATA completion.
7702 */
7703 satIOContext->satCompleteCB = &smsatNonChainedDataIOCB;
7704 }
7705 else
7706 {
7707 SM_DBG1(("smsatWrite16: CHAINED data!!!\n"));
7708 /* re-setting tl */
7709 if (fis->h.command == SAT_WRITE_SECTORS || fis->h.command == SAT_WRITE_DMA)
7710 {
7711 fis->d.sectorCount = 0xFF;
7712 }
7713 else if (fis->h.command == SAT_WRITE_SECTORS_EXT ||
7714 fis->h.command == SAT_WRITE_DMA_EXT ||
7715 fis->h.command == SAT_WRITE_DMA_FUA_EXT
7716 )
7717 {
7718 fis->d.sectorCount = 0xFF;
7719 fis->d.sectorCountExp = 0xFF;
7720 }
7721 else
7722 {
7723 /* SAT_WRITE_FPDMA_QUEUED */
7724 fis->h.features = 0xFF;
7725 fis->d.featuresExp = 0xFF;
7726 }
7727
7728 /* Initialize CB for SATA completion.
7729 */
7730 satIOContext->satCompleteCB = &smsatChainedDataIOCB;
7731 }
7732
7733
7734 /*
7735 * Prepare SGL and send FIS to LL layer.
7736 */
7737 satIOContext->reqType = agRequestType; /* Save it */
7738
7739 status = smsataLLIOStart( smRoot,
7740 smIORequest,
7741 smDeviceHandle,
7742 smScsiRequest,
7743 satIOContext);
7744 return (status);
7745 }
7746
7747
7748 osGLOBAL bit32
smsatVerify10(smRoot_t * smRoot,smIORequest_t * smIORequest,smDeviceHandle_t * smDeviceHandle,smScsiInitiatorRequest_t * smScsiRequest,smSatIOContext_t * satIOContext)7749 smsatVerify10(
7750 smRoot_t *smRoot,
7751 smIORequest_t *smIORequest,
7752 smDeviceHandle_t *smDeviceHandle,
7753 smScsiInitiatorRequest_t *smScsiRequest,
7754 smSatIOContext_t *satIOContext
7755 )
7756 {
7757 /*
7758 For simple implementation,
7759 no byte comparison supported as of 4/5/06
7760 */
7761 smScsiRspSense_t *pSense;
7762 smIniScsiCmnd_t *scsiCmnd;
7763 smDeviceData_t *pSatDevData;
7764 agsaFisRegHostToDevice_t *fis;
7765 bit32 status;
7766 bit32 agRequestType = AGSA_SATA_PROTOCOL_NON_DATA;
7767 bit32 lba = 0;
7768 bit32 tl = 0;
7769 bit32 LoopNum = 1;
7770 bit8 LBA[8];
7771 bit8 TL[8];
7772 bit32 AllChk = agFALSE; /* lba, lba+tl check against ATA limit and Disk capacity */
7773
7774 pSense = satIOContext->pSense;
7775 scsiCmnd = &smScsiRequest->scsiCmnd;
7776 pSatDevData = satIOContext->pSatDevData;
7777 fis = satIOContext->pFis;
7778 SM_DBG5(("smsatVerify10: start\n"));
7779 /* checking BYTCHK */
7780 if (scsiCmnd->cdb[1] & SCSI_VERIFY_BYTCHK_MASK)
7781 {
7782 /*
7783 should do the byte check
7784 but not supported in this version
7785 */
7786 smsatSetSensePayload( pSense,
7787 SCSI_SNSKEY_ILLEGAL_REQUEST,
7788 0,
7789 SCSI_SNSCODE_INVALID_FIELD_IN_CDB,
7790 satIOContext);
7791 /*smEnqueueIO(smRoot, satIOContext);*/
7792 tdsmIOCompletedCB( smRoot,
7793 smIORequest,
7794 smIOSuccess,
7795 SCSI_STAT_CHECK_CONDITION,
7796 satIOContext->pSmSenseData,
7797 satIOContext->interruptContext );
7798
7799 SM_DBG1(("smsatVerify10: no byte checking!!!\n"));
7800 return SM_RC_SUCCESS;
7801 }
7802
7803 /* checking CONTROL */
7804 /* NACA == 1 or LINK == 1*/
7805 if ( (scsiCmnd->cdb[9] & SCSI_NACA_MASK) || (scsiCmnd->cdb[9] & SCSI_LINK_MASK) )
7806 {
7807 smsatSetSensePayload( pSense,
7808 SCSI_SNSKEY_ILLEGAL_REQUEST,
7809 0,
7810 SCSI_SNSCODE_INVALID_FIELD_IN_CDB,
7811 satIOContext);
7812
7813 /*smEnqueueIO(smRoot, satIOContext);*/
7814
7815 tdsmIOCompletedCB( smRoot,
7816 smIORequest,
7817 smIOSuccess,
7818 SCSI_STAT_CHECK_CONDITION,
7819 satIOContext->pSmSenseData,
7820 satIOContext->interruptContext );
7821
7822 SM_DBG1(("smsatVerify10: return control!!!\n"));
7823 return SM_RC_SUCCESS;
7824 }
7825
7826
7827 sm_memset(LBA, 0, sizeof(LBA));
7828 sm_memset(TL, 0, sizeof(TL));
7829
7830 /* do not use memcpy due to indexing in LBA and TL */
7831 LBA[0] = 0; /* MSB */
7832 LBA[1] = 0;
7833 LBA[2] = 0;
7834 LBA[3] = 0;
7835 LBA[4] = scsiCmnd->cdb[2];
7836 LBA[5] = scsiCmnd->cdb[3];
7837 LBA[6] = scsiCmnd->cdb[4];
7838 LBA[7] = scsiCmnd->cdb[5]; /* LSB */
7839
7840 TL[0] = 0;
7841 TL[1] = 0;
7842 TL[2] = 0;
7843 TL[3] = 0;
7844 TL[4] = 0;
7845 TL[5] = 0;
7846 TL[6] = scsiCmnd->cdb[7];
7847 TL[7] = scsiCmnd->cdb[8]; /* LSB */
7848
7849
7850 /* cbd10; computing LBA and transfer length */
7851 lba = (scsiCmnd->cdb[2] << (8*3)) + (scsiCmnd->cdb[3] << (8*2))
7852 + (scsiCmnd->cdb[4] << 8) + scsiCmnd->cdb[5];
7853 tl = (scsiCmnd->cdb[7] << 8) + scsiCmnd->cdb[8];
7854
7855 if (pSatDevData->satNCQ != agTRUE &&
7856 pSatDevData->sat48BitSupport != agTRUE
7857 )
7858 {
7859 AllChk = smsatCheckLimit(LBA, TL, agFALSE, pSatDevData);
7860 if (AllChk)
7861 {
7862 SM_DBG1(("smsatVerify10: return LBA out of range, not EXT!!!\n"));
7863 SM_DBG1(("smsatVerify10: cdb 0x%x 0x%x 0x%x 0x%x!!!\n",scsiCmnd->cdb[2], scsiCmnd->cdb[3],
7864 scsiCmnd->cdb[4], scsiCmnd->cdb[5]));
7865 SM_DBG1(("smsatVerify10: lba 0x%x SAT_TR_LBA_LIMIT 0x%x!!!\n", lba, SAT_TR_LBA_LIMIT));
7866 smsatSetSensePayload( pSense,
7867 SCSI_SNSKEY_ILLEGAL_REQUEST,
7868 0,
7869 SCSI_SNSCODE_LOGICAL_BLOCK_ADDRESS_OUT_OF_RANGE,
7870 satIOContext);
7871
7872 /*smEnqueueIO(smRoot, satIOContext);*/
7873
7874 tdsmIOCompletedCB( smRoot,
7875 smIORequest,
7876 smIOSuccess,
7877 SCSI_STAT_CHECK_CONDITION,
7878 satIOContext->pSmSenseData,
7879 satIOContext->interruptContext );
7880
7881 return SM_RC_SUCCESS;
7882 }
7883 }
7884 else
7885 {
7886 AllChk = smsatCheckLimit(LBA, TL, agTRUE, pSatDevData);
7887 if (AllChk)
7888 {
7889 SM_DBG1(("smsatVerify10: return LBA out of range, EXT!!!\n"));
7890 smsatSetSensePayload( pSense,
7891 SCSI_SNSKEY_ILLEGAL_REQUEST,
7892 0,
7893 SCSI_SNSCODE_LOGICAL_BLOCK_ADDRESS_OUT_OF_RANGE,
7894 satIOContext);
7895
7896 /*smEnqueueIO(smRoot, satIOContext);*/
7897
7898 tdsmIOCompletedCB( smRoot,
7899 smIORequest,
7900 smIOSuccess,
7901 SCSI_STAT_CHECK_CONDITION,
7902 satIOContext->pSmSenseData,
7903 satIOContext->interruptContext );
7904
7905 return SM_RC_SUCCESS;
7906 }
7907 }
7908
7909 if (pSatDevData->sat48BitSupport == agTRUE)
7910 {
7911 SM_DBG5(("smsatVerify10: SAT_READ_VERIFY_SECTORS_EXT\n"));
7912 fis->h.fisType = 0x27; /* Reg host to device */
7913 fis->h.c_pmPort = 0x80; /* C Bit is set */
7914
7915 fis->h.command = SAT_READ_VERIFY_SECTORS_EXT;/* 0x42 */
7916 fis->h.features = 0; /* FIS reserve */
7917 fis->d.lbaLow = scsiCmnd->cdb[5]; /* FIS LBA (7 :0 ) */
7918 fis->d.lbaMid = scsiCmnd->cdb[4]; /* FIS LBA (15:8 ) */
7919 fis->d.lbaHigh = scsiCmnd->cdb[3]; /* FIS LBA (23:16) */
7920 fis->d.device = 0x40; /* FIS LBA mode set 01000000 */
7921 fis->d.lbaLowExp = scsiCmnd->cdb[2]; /* FIS LBA (31:24) */
7922 fis->d.lbaMidExp = 0; /* FIS LBA (39:32) */
7923 fis->d.lbaHighExp = 0; /* FIS LBA (47:40) */
7924 fis->d.featuresExp = 0; /* FIS reserve */
7925 fis->d.sectorCount = scsiCmnd->cdb[8]; /* FIS sector count (7:0) */
7926 fis->d.sectorCountExp = scsiCmnd->cdb[7]; /* FIS sector count (15:8) */
7927
7928 fis->d.reserved4 = 0;
7929 fis->d.control = 0; /* FIS HOB bit clear */
7930 fis->d.reserved5 = 0;
7931
7932 agRequestType = AGSA_SATA_PROTOCOL_NON_DATA;
7933 satIOContext->ATACmd = SAT_READ_VERIFY_SECTORS_EXT;
7934 }
7935 else
7936 {
7937 SM_DBG5(("smsatVerify10: SAT_READ_VERIFY_SECTORS\n"));
7938 fis->h.fisType = 0x27; /* Reg host to device */
7939 fis->h.c_pmPort = 0x80; /* C bit is set */
7940 fis->h.command = SAT_READ_VERIFY_SECTORS; /* 0x40 */
7941 fis->h.features = 0; /* FIS reserve */
7942 fis->d.lbaLow = scsiCmnd->cdb[5]; /* FIS LBA (7 :0 ) */
7943 fis->d.lbaMid = scsiCmnd->cdb[4]; /* FIS LBA (15:8 ) */
7944 fis->d.lbaHigh = scsiCmnd->cdb[3]; /* FIS LBA (23:16) */
7945 /* FIS LBA mode set LBA (27:24) */
7946 fis->d.device = (bit8)((0x4 << 4) | (scsiCmnd->cdb[2] & 0xF));
7947 fis->d.lbaLowExp = 0;
7948 fis->d.lbaMidExp = 0;
7949 fis->d.lbaHighExp = 0;
7950 fis->d.featuresExp = 0;
7951 fis->d.sectorCount = scsiCmnd->cdb[8]; /* FIS sector count (7:0) */
7952 fis->d.sectorCountExp = 0;
7953 fis->d.reserved4 = 0;
7954 fis->d.control = 0; /* FIS HOB bit clear */
7955 fis->d.reserved5 = 0;
7956
7957 agRequestType = AGSA_SATA_PROTOCOL_NON_DATA;
7958 satIOContext->ATACmd = SAT_READ_VERIFY_SECTORS;
7959
7960 }
7961
7962 satIOContext->currentLBA = lba;
7963 satIOContext->OrgTL = tl;
7964
7965 /*
7966 computing number of loop and remainder for tl
7967 0xFF in case not ext
7968 0xFFFF in case EXT
7969 */
7970 if (fis->h.command == SAT_READ_VERIFY_SECTORS)
7971 {
7972 LoopNum = smsatComputeLoopNum(tl, 0xFF);
7973 }
7974 else if (fis->h.command == SAT_READ_VERIFY_SECTORS_EXT)
7975 {
7976 /* SAT_READ_SECTORS_EXT, SAT_READ_DMA_EXT */
7977 LoopNum = smsatComputeLoopNum(tl, 0xFFFF);
7978 }
7979 else
7980 {
7981 SM_DBG1(("smsatVerify10: error case 1!!!\n"));
7982 LoopNum = 1;
7983 }
7984
7985 satIOContext->LoopNum = LoopNum;
7986
7987 if (LoopNum == 1)
7988 {
7989 SM_DBG5(("smsatVerify10: NON CHAINED data\n"));
7990 /* Initialize CB for SATA completion.
7991 */
7992 satIOContext->satCompleteCB = &smsatNonChainedVerifyCB;
7993 }
7994 else
7995 {
7996 SM_DBG1(("smsatVerify10: CHAINED data!!!\n"));
7997 /* re-setting tl */
7998 if (fis->h.command == SAT_READ_VERIFY_SECTORS)
7999 {
8000 fis->d.sectorCount = 0xFF;
8001 }
8002 else if (fis->h.command == SAT_READ_VERIFY_SECTORS_EXT)
8003 {
8004 fis->d.sectorCount = 0xFF;
8005 fis->d.sectorCountExp = 0xFF;
8006 }
8007 else
8008 {
8009 SM_DBG1(("smsatVerify10: error case 2!!!\n"));
8010 }
8011
8012 /* Initialize CB for SATA completion.
8013 */
8014 satIOContext->satCompleteCB = &smsatChainedVerifyCB;
8015 }
8016
8017
8018 /*
8019 * Prepare SGL and send FIS to LL layer.
8020 */
8021 satIOContext->reqType = agRequestType; /* Save it */
8022
8023 status = smsataLLIOStart( smRoot,
8024 smIORequest,
8025 smDeviceHandle,
8026 smScsiRequest,
8027 satIOContext);
8028 return (status);
8029 }
8030
8031 osGLOBAL bit32
smsatVerify12(smRoot_t * smRoot,smIORequest_t * smIORequest,smDeviceHandle_t * smDeviceHandle,smScsiInitiatorRequest_t * smScsiRequest,smSatIOContext_t * satIOContext)8032 smsatVerify12(
8033 smRoot_t *smRoot,
8034 smIORequest_t *smIORequest,
8035 smDeviceHandle_t *smDeviceHandle,
8036 smScsiInitiatorRequest_t *smScsiRequest,
8037 smSatIOContext_t *satIOContext
8038 )
8039 {
8040 /*
8041 For simple implementation,
8042 no byte comparison supported as of 4/5/06
8043 */
8044 smScsiRspSense_t *pSense;
8045 smIniScsiCmnd_t *scsiCmnd;
8046 smDeviceData_t *pSatDevData;
8047 agsaFisRegHostToDevice_t *fis;
8048 bit32 status;
8049 bit32 agRequestType = AGSA_SATA_PROTOCOL_NON_DATA;
8050 bit32 lba = 0;
8051 bit32 tl = 0;
8052 bit32 LoopNum = 1;
8053 bit8 LBA[8];
8054 bit8 TL[8];
8055 bit32 AllChk = agFALSE; /* lba, lba+tl check against ATA limit and Disk capacity */
8056
8057 pSense = satIOContext->pSense;
8058 scsiCmnd = &smScsiRequest->scsiCmnd;
8059 pSatDevData = satIOContext->pSatDevData;
8060 fis = satIOContext->pFis;
8061 SM_DBG5(("smsatVerify12: start\n"));
8062 /* checking BYTCHK */
8063 if (scsiCmnd->cdb[1] & SCSI_VERIFY_BYTCHK_MASK)
8064 {
8065 /*
8066 should do the byte check
8067 but not supported in this version
8068 */
8069 smsatSetSensePayload( pSense,
8070 SCSI_SNSKEY_ILLEGAL_REQUEST,
8071 0,
8072 SCSI_SNSCODE_INVALID_FIELD_IN_CDB,
8073 satIOContext);
8074
8075 /*smEnqueueIO(smRoot, satIOContext);*/
8076
8077 tdsmIOCompletedCB( smRoot,
8078 smIORequest,
8079 smIOSuccess,
8080 SCSI_STAT_CHECK_CONDITION,
8081 satIOContext->pSmSenseData,
8082 satIOContext->interruptContext );
8083
8084 SM_DBG1(("smsatVerify12: no byte checking!!!\n"));
8085 return SM_RC_SUCCESS;
8086 }
8087
8088 /* checking CONTROL */
8089 /* NACA == 1 or LINK == 1*/
8090 if ( (scsiCmnd->cdb[11] & SCSI_NACA_MASK) || (scsiCmnd->cdb[11] & SCSI_LINK_MASK) )
8091 {
8092 smsatSetSensePayload( pSense,
8093 SCSI_SNSKEY_ILLEGAL_REQUEST,
8094 0,
8095 SCSI_SNSCODE_INVALID_FIELD_IN_CDB,
8096 satIOContext);
8097
8098 /*smEnqueueIO(smRoot, satIOContext);*/
8099
8100 tdsmIOCompletedCB( smRoot,
8101 smIORequest,
8102 smIOSuccess,
8103 SCSI_STAT_CHECK_CONDITION,
8104 satIOContext->pSmSenseData,
8105 satIOContext->interruptContext );
8106
8107 SM_DBG1(("smsatVerify12: return control!!!\n"));
8108 return SM_RC_SUCCESS;
8109 }
8110
8111 sm_memset(LBA, 0, sizeof(LBA));
8112 sm_memset(TL, 0, sizeof(TL));
8113
8114 /* do not use memcpy due to indexing in LBA and TL */
8115 LBA[0] = 0; /* MSB */
8116 LBA[1] = 0;
8117 LBA[2] = 0;
8118 LBA[3] = 0;
8119 LBA[4] = scsiCmnd->cdb[2];
8120 LBA[5] = scsiCmnd->cdb[3];
8121 LBA[6] = scsiCmnd->cdb[4];
8122 LBA[7] = scsiCmnd->cdb[5]; /* LSB */
8123
8124 TL[0] = 0; /* MSB */
8125 TL[1] = 0;
8126 TL[2] = 0;
8127 TL[3] = 0;
8128 TL[4] = scsiCmnd->cdb[6];
8129 TL[5] = scsiCmnd->cdb[7];
8130 TL[6] = scsiCmnd->cdb[8];
8131 TL[7] = scsiCmnd->cdb[9]; /* LSB */
8132
8133
8134 lba = smsatComputeCDB12LBA(satIOContext);
8135 tl = smsatComputeCDB12TL(satIOContext);
8136
8137 if (pSatDevData->satNCQ != agTRUE &&
8138 pSatDevData->sat48BitSupport != agTRUE
8139 )
8140 {
8141 AllChk = smsatCheckLimit(LBA, TL, agFALSE, pSatDevData);
8142 if (AllChk)
8143 {
8144 SM_DBG1(("smsatVerify12: return LBA out of range, not EXT!!!\n"));
8145 SM_DBG1(("smsatVerify12: cdb 0x%x 0x%x 0x%x 0x%x!!!\n",scsiCmnd->cdb[2], scsiCmnd->cdb[3],
8146 scsiCmnd->cdb[4], scsiCmnd->cdb[5]));
8147 SM_DBG1(("smsatVerify12: lba 0x%x SAT_TR_LBA_LIMIT 0x%x!!!\n", lba, SAT_TR_LBA_LIMIT));
8148 smsatSetSensePayload( pSense,
8149 SCSI_SNSKEY_ILLEGAL_REQUEST,
8150 0,
8151 SCSI_SNSCODE_LOGICAL_BLOCK_ADDRESS_OUT_OF_RANGE,
8152 satIOContext);
8153
8154 /*smEnqueueIO(smRoot, satIOContext);*/
8155
8156 tdsmIOCompletedCB( smRoot,
8157 smIORequest,
8158 smIOSuccess,
8159 SCSI_STAT_CHECK_CONDITION,
8160 satIOContext->pSmSenseData,
8161 satIOContext->interruptContext );
8162
8163 return SM_RC_SUCCESS;
8164 }
8165 }
8166 else
8167 {
8168 AllChk = smsatCheckLimit(LBA, TL, agTRUE, pSatDevData);
8169 if (AllChk)
8170 {
8171 SM_DBG1(("smsatVerify12: return LBA out of range, EXT!!!\n"));
8172 smsatSetSensePayload( pSense,
8173 SCSI_SNSKEY_ILLEGAL_REQUEST,
8174 0,
8175 SCSI_SNSCODE_LOGICAL_BLOCK_ADDRESS_OUT_OF_RANGE,
8176 satIOContext);
8177
8178 /*smEnqueueIO(smRoot, satIOContext);*/
8179
8180 tdsmIOCompletedCB( smRoot,
8181 smIORequest,
8182 smIOSuccess,
8183 SCSI_STAT_CHECK_CONDITION,
8184 satIOContext->pSmSenseData,
8185 satIOContext->interruptContext );
8186
8187 return SM_RC_SUCCESS;
8188 }
8189 }
8190
8191 if (pSatDevData->sat48BitSupport == agTRUE)
8192 {
8193 SM_DBG5(("smsatVerify12: SAT_READ_VERIFY_SECTORS_EXT\n"));
8194 fis->h.fisType = 0x27; /* Reg host to device */
8195 fis->h.c_pmPort = 0x80; /* C Bit is set */
8196
8197 fis->h.command = SAT_READ_VERIFY_SECTORS_EXT;/* 0x42 */
8198 fis->h.features = 0; /* FIS reserve */
8199 fis->d.lbaLow = scsiCmnd->cdb[5]; /* FIS LBA (7 :0 ) */
8200 fis->d.lbaMid = scsiCmnd->cdb[4]; /* FIS LBA (15:8 ) */
8201 fis->d.lbaHigh = scsiCmnd->cdb[3]; /* FIS LBA (23:16) */
8202 fis->d.device = 0x40; /* FIS LBA mode set 01000000 */
8203 fis->d.lbaLowExp = scsiCmnd->cdb[2]; /* FIS LBA (31:24) */
8204 fis->d.lbaMidExp = 0; /* FIS LBA (39:32) */
8205 fis->d.lbaHighExp = 0; /* FIS LBA (47:40) */
8206 fis->d.featuresExp = 0; /* FIS reserve */
8207 fis->d.sectorCount = scsiCmnd->cdb[9]; /* FIS sector count (7:0) */
8208 fis->d.sectorCountExp = scsiCmnd->cdb[8]; /* FIS sector count (15:8) */
8209
8210 fis->d.reserved4 = 0;
8211 fis->d.control = 0; /* FIS HOB bit clear */
8212 fis->d.reserved5 = 0;
8213
8214 agRequestType = AGSA_SATA_PROTOCOL_NON_DATA;
8215 satIOContext->ATACmd = SAT_READ_VERIFY_SECTORS_EXT;
8216 }
8217 else
8218 {
8219 SM_DBG5(("smsatVerify12: SAT_READ_VERIFY_SECTORS\n"));
8220 fis->h.fisType = 0x27; /* Reg host to device */
8221 fis->h.c_pmPort = 0x80; /* C bit is set */
8222 fis->h.command = SAT_READ_VERIFY_SECTORS; /* 0x40 */
8223 fis->h.features = 0; /* FIS reserve */
8224 fis->d.lbaLow = scsiCmnd->cdb[5]; /* FIS LBA (7 :0 ) */
8225 fis->d.lbaMid = scsiCmnd->cdb[4]; /* FIS LBA (15:8 ) */
8226 fis->d.lbaHigh = scsiCmnd->cdb[3]; /* FIS LBA (23:16) */
8227 /* FIS LBA mode set LBA (27:24) */
8228 fis->d.device = (bit8)((0x4 << 4) | (scsiCmnd->cdb[2] & 0xF));
8229 fis->d.lbaLowExp = 0;
8230 fis->d.lbaMidExp = 0;
8231 fis->d.lbaHighExp = 0;
8232 fis->d.featuresExp = 0;
8233 fis->d.sectorCount = scsiCmnd->cdb[9]; /* FIS sector count (7:0) */
8234 fis->d.sectorCountExp = 0;
8235 fis->d.reserved4 = 0;
8236 fis->d.control = 0; /* FIS HOB bit clear */
8237 fis->d.reserved5 = 0;
8238
8239 agRequestType = AGSA_SATA_PROTOCOL_NON_DATA;
8240 satIOContext->ATACmd = SAT_READ_VERIFY_SECTORS;
8241
8242 }
8243
8244 satIOContext->currentLBA = lba;
8245 satIOContext->OrgTL = tl;
8246
8247 /*
8248 computing number of loop and remainder for tl
8249 0xFF in case not ext
8250 0xFFFF in case EXT
8251 */
8252 if (fis->h.command == SAT_READ_VERIFY_SECTORS)
8253 {
8254 LoopNum = smsatComputeLoopNum(tl, 0xFF);
8255 }
8256 else if (fis->h.command == SAT_READ_VERIFY_SECTORS_EXT)
8257 {
8258 /* SAT_READ_SECTORS_EXT, SAT_READ_DMA_EXT */
8259 LoopNum = smsatComputeLoopNum(tl, 0xFFFF);
8260 }
8261 else
8262 {
8263 SM_DBG1(("smsatVerify12: error case 1!!!\n"));
8264 LoopNum = 1;
8265 }
8266
8267 satIOContext->LoopNum = LoopNum;
8268
8269 if (LoopNum == 1)
8270 {
8271 SM_DBG5(("smsatVerify12: NON CHAINED data\n"));
8272 /* Initialize CB for SATA completion.
8273 */
8274 satIOContext->satCompleteCB = &smsatNonChainedVerifyCB;
8275 }
8276 else
8277 {
8278 SM_DBG1(("smsatVerify12: CHAINED data!!!\n"));
8279 /* re-setting tl */
8280 if (fis->h.command == SAT_READ_VERIFY_SECTORS)
8281 {
8282 fis->d.sectorCount = 0xFF;
8283 }
8284 else if (fis->h.command == SAT_READ_VERIFY_SECTORS_EXT)
8285 {
8286 fis->d.sectorCount = 0xFF;
8287 fis->d.sectorCountExp = 0xFF;
8288 }
8289 else
8290 {
8291 SM_DBG1(("smsatVerify12: error case 2!!!\n"));
8292 }
8293
8294 /* Initialize CB for SATA completion.
8295 */
8296 satIOContext->satCompleteCB = &smsatChainedVerifyCB;
8297 }
8298
8299
8300 /*
8301 * Prepare SGL and send FIS to LL layer.
8302 */
8303 satIOContext->reqType = agRequestType; /* Save it */
8304
8305 status = smsataLLIOStart( smRoot,
8306 smIORequest,
8307 smDeviceHandle,
8308 smScsiRequest,
8309 satIOContext);
8310 return (status);
8311 }
8312
8313 osGLOBAL bit32
smsatVerify16(smRoot_t * smRoot,smIORequest_t * smIORequest,smDeviceHandle_t * smDeviceHandle,smScsiInitiatorRequest_t * smScsiRequest,smSatIOContext_t * satIOContext)8314 smsatVerify16(
8315 smRoot_t *smRoot,
8316 smIORequest_t *smIORequest,
8317 smDeviceHandle_t *smDeviceHandle,
8318 smScsiInitiatorRequest_t *smScsiRequest,
8319 smSatIOContext_t *satIOContext
8320 )
8321 {
8322 /*
8323 For simple implementation,
8324 no byte comparison supported as of 4/5/06
8325 */
8326 smScsiRspSense_t *pSense;
8327 smIniScsiCmnd_t *scsiCmnd;
8328 smDeviceData_t *pSatDevData;
8329 agsaFisRegHostToDevice_t *fis;
8330 bit32 status;
8331 bit32 agRequestType = AGSA_SATA_PROTOCOL_NON_DATA;
8332 bit32 lba = 0;
8333 bit32 tl = 0;
8334 bit32 LoopNum = 1;
8335 bit8 LBA[8];
8336 bit8 TL[8];
8337 bit32 AllChk = agFALSE; /* lba, lba+tl check against ATA limit and Disk capacity */
8338
8339 pSense = satIOContext->pSense;
8340 scsiCmnd = &smScsiRequest->scsiCmnd;
8341 pSatDevData = satIOContext->pSatDevData;
8342 fis = satIOContext->pFis;
8343 SM_DBG5(("smsatVerify16: start\n"));
8344 /* checking BYTCHK */
8345 if (scsiCmnd->cdb[1] & SCSI_VERIFY_BYTCHK_MASK)
8346 {
8347 /*
8348 should do the byte check
8349 but not supported in this version
8350 */
8351 smsatSetSensePayload( pSense,
8352 SCSI_SNSKEY_ILLEGAL_REQUEST,
8353 0,
8354 SCSI_SNSCODE_INVALID_FIELD_IN_CDB,
8355 satIOContext);
8356 /*smEnqueueIO(smRoot, satIOContext);*/
8357 tdsmIOCompletedCB( smRoot,
8358 smIORequest,
8359 smIOSuccess,
8360 SCSI_STAT_CHECK_CONDITION,
8361 satIOContext->pSmSenseData,
8362 satIOContext->interruptContext );
8363 SM_DBG1(("smsatVerify16: no byte checking!!!\n"));
8364 return SM_RC_SUCCESS;
8365 }
8366 /* checking CONTROL */
8367 /* NACA == 1 or LINK == 1*/
8368 if ( (scsiCmnd->cdb[15] & SCSI_NACA_MASK) || (scsiCmnd->cdb[15] & SCSI_LINK_MASK) )
8369 {
8370 smsatSetSensePayload( pSense,
8371 SCSI_SNSKEY_ILLEGAL_REQUEST,
8372 0,
8373 SCSI_SNSCODE_INVALID_FIELD_IN_CDB,
8374 satIOContext);
8375 /*smEnqueueIO(smRoot, satIOContext);*/
8376 tdsmIOCompletedCB( smRoot,
8377 smIORequest,
8378 smIOSuccess,
8379 SCSI_STAT_CHECK_CONDITION,
8380 satIOContext->pSmSenseData,
8381 satIOContext->interruptContext );
8382 SM_DBG1(("smsatVerify16: return control!!!\n"));
8383 return SM_RC_SUCCESS;
8384 }
8385 sm_memset(LBA, 0, sizeof(LBA));
8386 sm_memset(TL, 0, sizeof(TL));
8387
8388 /* do not use memcpy due to indexing in LBA and TL */
8389 LBA[0] = scsiCmnd->cdb[2]; /* MSB */
8390 LBA[1] = scsiCmnd->cdb[3];
8391 LBA[2] = scsiCmnd->cdb[4];
8392 LBA[3] = scsiCmnd->cdb[5];
8393 LBA[4] = scsiCmnd->cdb[6];
8394 LBA[5] = scsiCmnd->cdb[7];
8395 LBA[6] = scsiCmnd->cdb[8];
8396 LBA[7] = scsiCmnd->cdb[9]; /* LSB */
8397
8398 TL[0] = 0;
8399 TL[1] = 0;
8400 TL[2] = 0;
8401 TL[3] = 0;
8402 TL[4] = scsiCmnd->cdb[10]; /* MSB */
8403 TL[5] = scsiCmnd->cdb[11];
8404 TL[6] = scsiCmnd->cdb[12];
8405 TL[7] = scsiCmnd->cdb[13]; /* LSB */
8406 lba = smsatComputeCDB16LBA(satIOContext);
8407 tl = smsatComputeCDB16TL(satIOContext);
8408
8409 if (pSatDevData->satNCQ != agTRUE &&
8410 pSatDevData->sat48BitSupport != agTRUE
8411 )
8412 {
8413 AllChk = smsatCheckLimit(LBA, TL, agFALSE, pSatDevData);
8414 if (AllChk)
8415 {
8416 SM_DBG1(("smsatVerify16: return LBA out of range, not EXT!!!\n"));
8417 smsatSetSensePayload( pSense,
8418 SCSI_SNSKEY_ILLEGAL_REQUEST,
8419 0,
8420 SCSI_SNSCODE_LOGICAL_BLOCK_ADDRESS_OUT_OF_RANGE,
8421 satIOContext);
8422 /*smEnqueueIO(smRoot, satIOContext);*/
8423 tdsmIOCompletedCB( smRoot,
8424 smIORequest,
8425 smIOSuccess,
8426 SCSI_STAT_CHECK_CONDITION,
8427 satIOContext->pSmSenseData,
8428 satIOContext->interruptContext );
8429 return SM_RC_SUCCESS;
8430 }
8431 }
8432 else
8433 {
8434 AllChk = smsatCheckLimit(LBA, TL, agTRUE, pSatDevData);
8435 if (AllChk)
8436 {
8437 SM_DBG1(("smsatVerify16: return LBA out of range, EXT!!!\n"));
8438 smsatSetSensePayload( pSense,
8439 SCSI_SNSKEY_ILLEGAL_REQUEST,
8440 0,
8441 SCSI_SNSCODE_LOGICAL_BLOCK_ADDRESS_OUT_OF_RANGE,
8442 satIOContext);
8443 /*smEnqueueIO(smRoot, satIOContext);*/
8444 tdsmIOCompletedCB( smRoot,
8445 smIORequest,
8446 smIOSuccess,
8447 SCSI_STAT_CHECK_CONDITION,
8448 satIOContext->pSmSenseData,
8449 satIOContext->interruptContext );
8450 return SM_RC_SUCCESS;
8451 }
8452 }
8453
8454 if (pSatDevData->sat48BitSupport == agTRUE)
8455 {
8456 SM_DBG5(("smsatVerify16: SAT_READ_VERIFY_SECTORS_EXT\n"));
8457 fis->h.fisType = 0x27; /* Reg host to device */
8458 fis->h.c_pmPort = 0x80; /* C Bit is set */
8459 fis->h.command = SAT_READ_VERIFY_SECTORS_EXT;/* 0x42 */
8460 fis->h.features = 0; /* FIS reserve */
8461 fis->d.lbaLow = scsiCmnd->cdb[9]; /* FIS LBA (7 :0 ) */
8462 fis->d.lbaMid = scsiCmnd->cdb[8]; /* FIS LBA (15:8 ) */
8463 fis->d.lbaHigh = scsiCmnd->cdb[7]; /* FIS LBA (23:16) */
8464 fis->d.device = 0x40; /* FIS LBA mode set 01000000 */
8465 fis->d.lbaLowExp = scsiCmnd->cdb[6]; /* FIS LBA (31:24) */
8466 fis->d.lbaMidExp = scsiCmnd->cdb[5]; /* FIS LBA (39:32) */
8467 fis->d.lbaHighExp = scsiCmnd->cdb[4]; /* FIS LBA (47:40) */
8468 fis->d.featuresExp = 0; /* FIS reserve */
8469 fis->d.sectorCount = scsiCmnd->cdb[13]; /* FIS sector count (7:0) */
8470 fis->d.sectorCountExp = scsiCmnd->cdb[12]; /* FIS sector count (15:8) */
8471
8472 fis->d.reserved4 = 0;
8473 fis->d.control = 0; /* FIS HOB bit clear */
8474 fis->d.reserved5 = 0;
8475
8476 agRequestType = AGSA_SATA_PROTOCOL_NON_DATA;
8477 satIOContext->ATACmd = SAT_READ_VERIFY_SECTORS_EXT;
8478 }
8479 else
8480 {
8481 SM_DBG5(("smsatVerify16: SAT_READ_VERIFY_SECTORS\n"));
8482 fis->h.fisType = 0x27; /* Reg host to device */
8483 fis->h.c_pmPort = 0x80; /* C bit is set */
8484 fis->h.command = SAT_READ_VERIFY_SECTORS; /* 0x40 */
8485 fis->h.features = 0; /* FIS reserve */
8486 fis->d.lbaLow = scsiCmnd->cdb[9]; /* FIS LBA (7 :0 ) */
8487 fis->d.lbaMid = scsiCmnd->cdb[8]; /* FIS LBA (15:8 ) */
8488 fis->d.lbaHigh = scsiCmnd->cdb[7]; /* FIS LBA (23:16) */
8489 /* FIS LBA mode set LBA (27:24) */
8490 fis->d.device = (bit8)((0x4 << 4) | (scsiCmnd->cdb[6] & 0xF));
8491 fis->d.lbaLowExp = 0;
8492 fis->d.lbaMidExp = 0;
8493 fis->d.lbaHighExp = 0;
8494 fis->d.featuresExp = 0;
8495 fis->d.sectorCount = scsiCmnd->cdb[13]; /* FIS sector count (7:0) */
8496 fis->d.sectorCountExp = 0;
8497 fis->d.reserved4 = 0;
8498 fis->d.control = 0; /* FIS HOB bit clear */
8499 fis->d.reserved5 = 0;
8500
8501 agRequestType = AGSA_SATA_PROTOCOL_NON_DATA;
8502 satIOContext->ATACmd = SAT_READ_VERIFY_SECTORS;
8503
8504 }
8505
8506 satIOContext->currentLBA = lba;
8507 satIOContext->OrgTL = tl;
8508
8509 /*
8510 computing number of loop and remainder for tl
8511 0xFF in case not ext
8512 0xFFFF in case EXT
8513 */
8514 if (fis->h.command == SAT_READ_VERIFY_SECTORS)
8515 {
8516 LoopNum = smsatComputeLoopNum(tl, 0xFF);
8517 }
8518 else if (fis->h.command == SAT_READ_VERIFY_SECTORS_EXT)
8519 {
8520 /* SAT_READ_SECTORS_EXT, SAT_READ_DMA_EXT */
8521 LoopNum = smsatComputeLoopNum(tl, 0xFFFF);
8522 }
8523 else
8524 {
8525 SM_DBG1(("smsatVerify16: error case 1!!!\n"));
8526 LoopNum = 1;
8527 }
8528
8529 satIOContext->LoopNum = LoopNum;
8530
8531 if (LoopNum == 1)
8532 {
8533 SM_DBG5(("smsatVerify16: NON CHAINED data\n"));
8534 /* Initialize CB for SATA completion.
8535 */
8536 satIOContext->satCompleteCB = &smsatNonChainedVerifyCB;
8537 }
8538 else
8539 {
8540 SM_DBG1(("smsatVerify16: CHAINED data!!!\n"));
8541 /* re-setting tl */
8542 if (fis->h.command == SAT_READ_VERIFY_SECTORS)
8543 {
8544 fis->d.sectorCount = 0xFF;
8545 }
8546 else if (fis->h.command == SAT_READ_VERIFY_SECTORS_EXT)
8547 {
8548 fis->d.sectorCount = 0xFF;
8549 fis->d.sectorCountExp = 0xFF;
8550 }
8551 else
8552 {
8553 SM_DBG1(("smsatVerify16: error case 2!!!\n"));
8554 }
8555
8556 /* Initialize CB for SATA completion.
8557 */
8558 satIOContext->satCompleteCB = &smsatChainedVerifyCB;
8559 }
8560
8561
8562 /*
8563 * Prepare SGL and send FIS to LL layer.
8564 */
8565 satIOContext->reqType = agRequestType; /* Save it */
8566
8567 status = smsataLLIOStart( smRoot,
8568 smIORequest,
8569 smDeviceHandle,
8570 smScsiRequest,
8571 satIOContext);
8572 return (status);
8573 }
8574
8575 osGLOBAL bit32
smsatTestUnitReady(smRoot_t * smRoot,smIORequest_t * smIORequest,smDeviceHandle_t * smDeviceHandle,smScsiInitiatorRequest_t * smScsiRequest,smSatIOContext_t * satIOContext)8576 smsatTestUnitReady(
8577 smRoot_t *smRoot,
8578 smIORequest_t *smIORequest,
8579 smDeviceHandle_t *smDeviceHandle,
8580 smScsiInitiatorRequest_t *smScsiRequest,
8581 smSatIOContext_t *satIOContext
8582 )
8583 {
8584 bit32 status;
8585 bit32 agRequestType;
8586 smDeviceData_t *pSatDevData;
8587 smScsiRspSense_t *pSense;
8588 smIniScsiCmnd_t *scsiCmnd;
8589 agsaFisRegHostToDevice_t *fis;
8590
8591 pSense = satIOContext->pSense;
8592 pSatDevData = satIOContext->pSatDevData;
8593 scsiCmnd = &smScsiRequest->scsiCmnd;
8594 fis = satIOContext->pFis;
8595
8596 SM_DBG5(("smsatTestUnitReady: start\n"));
8597
8598 /* checking CONTROL */
8599 /* NACA == 1 or LINK == 1*/
8600 if ( (scsiCmnd->cdb[5] & SCSI_NACA_MASK) || (scsiCmnd->cdb[5] & SCSI_LINK_MASK) )
8601 {
8602 smsatSetSensePayload( pSense,
8603 SCSI_SNSKEY_ILLEGAL_REQUEST,
8604 0,
8605 SCSI_SNSCODE_INVALID_FIELD_IN_CDB,
8606 satIOContext);
8607
8608 /*smEnqueueIO(smRoot, satIOContext);*/
8609
8610 tdsmIOCompletedCB( smRoot,
8611 smIORequest,
8612 smIOSuccess,
8613 SCSI_STAT_CHECK_CONDITION,
8614 satIOContext->pSmSenseData,
8615 satIOContext->interruptContext );
8616
8617 SM_DBG1(("smsatTestUnitReady: return control!!!\n"));
8618 return SM_RC_SUCCESS;
8619 }
8620
8621 /* SAT revision 8, 8.11.2, p42*/
8622 if (pSatDevData->satStopState == agTRUE)
8623 {
8624 smsatSetSensePayload( pSense,
8625 SCSI_SNSKEY_NOT_READY,
8626 0,
8627 SCSI_SNSCODE_LOGICAL_UNIT_NOT_READY_INITIALIZING_COMMAND_REQUIRED,
8628 satIOContext);
8629
8630 /*smEnqueueIO(smRoot, satIOContext);*/
8631
8632 tdsmIOCompletedCB( smRoot,
8633 smIORequest,
8634 smIOSuccess,
8635 SCSI_STAT_CHECK_CONDITION,
8636 satIOContext->pSmSenseData,
8637 satIOContext->interruptContext );
8638 SM_DBG1(("smsatTestUnitReady: stop state!!!\n"));
8639 return SM_RC_SUCCESS;
8640 }
8641
8642 /*
8643 * Check if format is in progress
8644 */
8645 if (pSatDevData->satDriveState == SAT_DEV_STATE_FORMAT_IN_PROGRESS)
8646 {
8647 SM_DBG1(("smsatTestUnitReady: FORMAT_IN_PROGRESS!!!\n"));
8648
8649 smsatSetSensePayload( pSense,
8650 SCSI_SNSKEY_NOT_READY,
8651 0,
8652 SCSI_SNSCODE_LOGICAL_UNIT_NOT_READY_FORMAT_IN_PROGRESS,
8653 satIOContext);
8654
8655 /*smEnqueueIO(smRoot, satIOContext);*/
8656
8657 tdsmIOCompletedCB( smRoot,
8658 smIORequest,
8659 smIOSuccess,
8660 SCSI_STAT_CHECK_CONDITION,
8661 satIOContext->pSmSenseData,
8662 satIOContext->interruptContext );
8663 SM_DBG1(("smsatTestUnitReady: format in progress!!!\n"));
8664 return SM_RC_SUCCESS;
8665 }
8666
8667 /*
8668 check previously issued ATA command
8669 */
8670 if (pSatDevData->satPendingIO != 0)
8671 {
8672 if (pSatDevData->satDeviceFaultState == agTRUE)
8673 {
8674 smsatSetSensePayload( pSense,
8675 SCSI_SNSKEY_HARDWARE_ERROR,
8676 0,
8677 SCSI_SNSCODE_LOGICAL_UNIT_FAILURE,
8678 satIOContext);
8679
8680 /*smEnqueueIO(smRoot, satIOContext);*/
8681
8682 tdsmIOCompletedCB( smRoot,
8683 smIORequest,
8684 smIOSuccess,
8685 SCSI_STAT_CHECK_CONDITION,
8686 satIOContext->pSmSenseData,
8687 satIOContext->interruptContext );
8688 SM_DBG1(("smsatTestUnitReady: previous command ended in error!!!\n"));
8689 return SM_RC_SUCCESS;
8690 }
8691 }
8692
8693 /*
8694 check removalbe media feature set
8695 */
8696 if(pSatDevData->satRemovableMedia && pSatDevData->satRemovableMediaEnabled)
8697 {
8698 SM_DBG5(("smsatTestUnitReady: sending get media status cmnd\n"));
8699 /* send GET MEDIA STATUS command */
8700 fis->h.fisType = 0x27; /* Reg host to device */
8701 fis->h.c_pmPort = 0x80; /* C Bit is set */
8702 fis->h.command = SAT_GET_MEDIA_STATUS; /* 0xDA */
8703 fis->h.features = 0; /* FIS features NA */
8704 fis->d.lbaLow = 0; /* FIS LBA (7 :0 ) */
8705 fis->d.lbaMid = 0; /* FIS LBA (15:8 ) */
8706 fis->d.lbaHigh = 0; /* FIS LBA (23:16) */
8707 fis->d.device = 0; /* FIS DEV is discared in SATA */
8708 fis->d.lbaLowExp = 0;
8709 fis->d.lbaMidExp = 0;
8710 fis->d.lbaHighExp = 0;
8711 fis->d.featuresExp = 0;
8712 fis->d.sectorCount = 0; /* FIS sector count (7:0) */
8713 fis->d.sectorCountExp = 0;
8714 fis->d.reserved4 = 0;
8715 fis->d.control = 0; /* FIS HOB bit clear */
8716 fis->d.reserved5 = 0;
8717 agRequestType = AGSA_SATA_PROTOCOL_NON_DATA;
8718
8719 /* Initialize CB for SATA completion.
8720 */
8721 satIOContext->satCompleteCB = &smsatTestUnitReadyCB;
8722
8723 /*
8724 * Prepare SGL and send FIS to LL layer.
8725 */
8726 satIOContext->reqType = agRequestType; /* Save it */
8727
8728 status = smsataLLIOStart( smRoot,
8729 smIORequest,
8730 smDeviceHandle,
8731 smScsiRequest,
8732 satIOContext);
8733
8734 return (status);
8735 }
8736 /*
8737 number 6) in SAT p42
8738 send ATA CHECK POWER MODE
8739 */
8740 SM_DBG5(("smsatTestUnitReady: sending check power mode cmnd\n"));
8741 status = smsatTestUnitReady_1( smRoot,
8742 smIORequest,
8743 smDeviceHandle,
8744 smScsiRequest,
8745 satIOContext);
8746 return (status);
8747 }
8748
8749 osGLOBAL bit32
smsatTestUnitReady_1(smRoot_t * smRoot,smIORequest_t * smIORequest,smDeviceHandle_t * smDeviceHandle,smScsiInitiatorRequest_t * smScsiRequest,smSatIOContext_t * satIOContext)8750 smsatTestUnitReady_1(
8751 smRoot_t *smRoot,
8752 smIORequest_t *smIORequest,
8753 smDeviceHandle_t *smDeviceHandle,
8754 smScsiInitiatorRequest_t *smScsiRequest,
8755 smSatIOContext_t *satIOContext
8756 )
8757 {
8758 /*
8759 sends SAT_CHECK_POWER_MODE as a part of TESTUNITREADY
8760 internally generated - no directly corresponding scsi
8761 called in satIOCompleted as a part of satTestUnitReady(), SAT, revision8, 8.11.2, p42
8762 */
8763 bit32 status;
8764 bit32 agRequestType;
8765 agsaFisRegHostToDevice_t *fis;
8766
8767 fis = satIOContext->pFis;
8768 SM_DBG5(("smsatTestUnitReady_1: start\n"));
8769 /*
8770 * Send the ATA CHECK POWER MODE command.
8771 */
8772 fis->h.fisType = 0x27; /* Reg host to device */
8773 fis->h.c_pmPort = 0x80; /* C Bit is set */
8774 fis->h.command = SAT_CHECK_POWER_MODE; /* 0xE5 */
8775 fis->h.features = 0;
8776 fis->d.lbaLow = 0;
8777 fis->d.lbaMid = 0;
8778 fis->d.lbaHigh = 0;
8779 fis->d.device = 0;
8780 fis->d.lbaLowExp = 0;
8781 fis->d.lbaMidExp = 0;
8782 fis->d.lbaHighExp = 0;
8783 fis->d.featuresExp = 0;
8784 fis->d.sectorCount = 0;
8785 fis->d.sectorCountExp = 0;
8786 fis->d.reserved4 = 0;
8787 fis->d.control = 0; /* FIS HOB bit clear */
8788 fis->d.reserved5 = 0;
8789
8790 agRequestType = AGSA_SATA_PROTOCOL_NON_DATA;
8791
8792 /* Initialize CB for SATA completion.
8793 */
8794 satIOContext->satCompleteCB = &smsatTestUnitReadyCB;
8795
8796 /*
8797 * Prepare SGL and send FIS to LL layer.
8798 */
8799 satIOContext->reqType = agRequestType; /* Save it */
8800
8801 status = smsataLLIOStart( smRoot,
8802 smIORequest,
8803 smDeviceHandle,
8804 smScsiRequest,
8805 satIOContext);
8806
8807 SM_DBG5(("smsatTestUnitReady_1: return\n"));
8808
8809 return status;
8810 }
8811
8812 osGLOBAL bit32
smsatInquiry(smRoot_t * smRoot,smIORequest_t * smIORequest,smDeviceHandle_t * smDeviceHandle,smScsiInitiatorRequest_t * smScsiRequest,smSatIOContext_t * satIOContext)8813 smsatInquiry(
8814 smRoot_t *smRoot,
8815 smIORequest_t *smIORequest,
8816 smDeviceHandle_t *smDeviceHandle,
8817 smScsiInitiatorRequest_t *smScsiRequest,
8818 smSatIOContext_t *satIOContext
8819 )
8820 {
8821 /*
8822 CMDDT bit is obsolete in SPC-3 and this is assumed in SAT revision 8
8823 */
8824 smScsiRspSense_t *pSense;
8825 smIniScsiCmnd_t *scsiCmnd;
8826 smDeviceData_t *pSatDevData;
8827 bit32 status;
8828
8829 pSense = satIOContext->pSense;
8830 scsiCmnd = &smScsiRequest->scsiCmnd;
8831 pSatDevData = satIOContext->pSatDevData;
8832 SM_DBG5(("smsatInquiry: start\n"));
8833 SM_DBG5(("smsatInquiry: pSatDevData did %d\n", pSatDevData->id));
8834 //smhexdump("smsatInquiry", (bit8 *)scsiCmnd->cdb, 6);
8835 /* checking CONTROL */
8836 /* NACA == 1 or LINK == 1*/
8837 if ( (scsiCmnd->cdb[5] & SCSI_NACA_MASK) || (scsiCmnd->cdb[5] & SCSI_LINK_MASK) )
8838 {
8839 smsatSetSensePayload( pSense,
8840 SCSI_SNSKEY_ILLEGAL_REQUEST,
8841 0,
8842 SCSI_SNSCODE_INVALID_FIELD_IN_CDB,
8843 satIOContext);
8844 /*smEnqueueIO(smRoot, satIOContext);*/
8845 tdsmIOCompletedCB( smRoot,
8846 smIORequest,
8847 smIOSuccess,
8848 SCSI_STAT_CHECK_CONDITION,
8849 satIOContext->pSmSenseData,
8850 satIOContext->interruptContext );
8851 SM_DBG1(("smsatInquiry: return control!!!\n"));
8852 return SM_RC_SUCCESS;
8853 }
8854
8855 /* checking EVPD and Allocation Length */
8856 /* SPC-4 spec 6.4 p141 */
8857 /* EVPD bit == 0 && PAGE CODE != 0 */
8858 if ( !(scsiCmnd->cdb[1] & SCSI_EVPD_MASK) &&
8859 (scsiCmnd->cdb[2] != 0)
8860 )
8861 {
8862 smsatSetSensePayload( pSense,
8863 SCSI_SNSKEY_ILLEGAL_REQUEST,
8864 0,
8865 SCSI_SNSCODE_INVALID_FIELD_IN_CDB,
8866 satIOContext);
8867 /*smEnqueueIO(smRoot, satIOContext);*/
8868 tdsmIOCompletedCB( smRoot,
8869 smIORequest,
8870 smIOSuccess,
8871 SCSI_STAT_CHECK_CONDITION,
8872 satIOContext->pSmSenseData,
8873 satIOContext->interruptContext );
8874 SM_DBG1(("smsatInquiry: return EVPD and PAGE CODE!!!\n"));
8875 return SM_RC_SUCCESS;
8876 }
8877 SM_DBG6(("smsatInquiry: allocation length 0x%x %d\n", ((scsiCmnd->cdb[3]) << 8) + scsiCmnd->cdb[4], ((scsiCmnd->cdb[3]) << 8) + scsiCmnd->cdb[4]));
8878 /* convert OS IO to TD internal IO */
8879 if ( pSatDevData->IDDeviceValid == agFALSE)
8880 {
8881 status = smsatStartIDDev(
8882 smRoot,
8883 smIORequest,
8884 smDeviceHandle,
8885 smScsiRequest,
8886 satIOContext
8887 );
8888 SM_DBG6(("smsatInquiry: end status %d\n", status));
8889 return status;
8890 }
8891 else
8892 {
8893 SM_DBG6(("smsatInquiry: calling satInquiryIntCB\n"));
8894 smsatInquiryIntCB(
8895 smRoot,
8896 smIORequest,
8897 smDeviceHandle,
8898 smScsiRequest,
8899 satIOContext
8900 );
8901 /*smEnqueueIO(smRoot, satIOContext);*/
8902 return SM_RC_SUCCESS;
8903 }
8904 }
8905
8906
8907 osGLOBAL bit32
smsatStartIDDev(smRoot_t * smRoot,smIORequest_t * smIORequest,smDeviceHandle_t * smDeviceHandle,smScsiInitiatorRequest_t * smScsiRequest,smSatIOContext_t * satIOContext)8908 smsatStartIDDev(
8909 smRoot_t *smRoot,
8910 smIORequest_t *smIORequest,
8911 smDeviceHandle_t *smDeviceHandle,
8912 smScsiInitiatorRequest_t *smScsiRequest,
8913 smSatIOContext_t *satIOContext
8914 )
8915 {
8916 smSatInternalIo_t *satIntIo = agNULL;
8917 smDeviceData_t *satDevData = agNULL;
8918 smIORequestBody_t *smIORequestBody;
8919 smSatIOContext_t *satNewIOContext;
8920 bit32 status;
8921
8922 SM_DBG5(("smsatStartIDDev: start\n"));
8923
8924 satDevData = satIOContext->pSatDevData;
8925
8926 SM_DBG6(("smsatStartIDDev: before alloc\n"));
8927
8928 /* allocate identify device command */
8929 satIntIo = smsatAllocIntIoResource( smRoot,
8930 smIORequest,
8931 satDevData,
8932 sizeof(agsaSATAIdentifyData_t), /* 512; size of identify device data */
8933 satIntIo);
8934
8935 SM_DBG6(("smsatStartIDDev: before after\n"));
8936
8937 if (satIntIo == agNULL)
8938 {
8939 SM_DBG1(("smsatStartIDDev: can't alloacate!!!\n"));
8940
8941 /*smEnqueueIO(smRoot, satIOContext);*/
8942
8943 return SM_RC_FAILURE;
8944 }
8945
8946 satIntIo->satOrgSmIORequest = smIORequest; /* changed */
8947 smIORequestBody = satIntIo->satIntRequestBody;
8948 satNewIOContext = &(smIORequestBody->transport.SATA.satIOContext);
8949
8950 satNewIOContext->pSatDevData = satDevData;
8951 satNewIOContext->pFis = &(smIORequestBody->transport.SATA.agSATARequestBody.fis.fisRegHostToDev);
8952 satNewIOContext->pScsiCmnd = &(satIntIo->satIntSmScsiXchg.scsiCmnd);
8953 satNewIOContext->pSense = &(smIORequestBody->transport.SATA.sensePayload);
8954 satNewIOContext->pSmSenseData = &(smIORequestBody->transport.SATA.smSenseData);
8955 satNewIOContext->smRequestBody = satIntIo->satIntRequestBody; /* key fix */
8956 satNewIOContext->interruptContext = tiInterruptContext;
8957 satNewIOContext->satIntIoContext = satIntIo;
8958
8959 satNewIOContext->psmDeviceHandle = agNULL;
8960 satNewIOContext->satOrgIOContext = satIOContext; /* changed */
8961
8962 /* this is valid only for TD layer generated (not triggered by OS at all) IO */
8963 satNewIOContext->smScsiXchg = &(satIntIo->satIntSmScsiXchg);
8964
8965
8966 SM_DBG6(("smsatStartIDDev: OS satIOContext %p \n", satIOContext));
8967 SM_DBG6(("smsatStartIDDev: TD satNewIOContext %p \n", satNewIOContext));
8968 SM_DBG6(("smsatStartIDDev: OS tiScsiXchg %p \n", satIOContext->smScsiXchg));
8969 SM_DBG6(("smsatStartIDDev: TD tiScsiXchg %p \n", satNewIOContext->smScsiXchg));
8970
8971
8972
8973 SM_DBG1(("smsatStartIDDev: satNewIOContext %p smIORequestBody %p!!!\n", satNewIOContext, smIORequestBody));
8974
8975 status = smsatSendIDDev( smRoot,
8976 &satIntIo->satIntSmIORequest, /* New smIORequest */
8977 smDeviceHandle,
8978 satNewIOContext->smScsiXchg, /* New tiScsiInitiatorRequest_t *tiScsiRequest, */
8979 satNewIOContext);
8980
8981 if (status != SM_RC_SUCCESS)
8982 {
8983 SM_DBG1(("smsatStartIDDev: failed in sending!!!\n"));
8984
8985 smsatFreeIntIoResource( smRoot,
8986 satDevData,
8987 satIntIo);
8988 /*smEnqueueIO(smRoot, satIOContext);*/
8989
8990 return SM_RC_FAILURE;
8991 }
8992
8993
8994 SM_DBG6(("smsatStartIDDev: end\n"));
8995
8996 return status;
8997 }
8998
8999 osGLOBAL bit32
smsatSendIDDev(smRoot_t * smRoot,smIORequest_t * smIORequest,smDeviceHandle_t * smDeviceHandle,smScsiInitiatorRequest_t * smScsiRequest,smSatIOContext_t * satIOContext)9000 smsatSendIDDev(
9001 smRoot_t *smRoot,
9002 smIORequest_t *smIORequest,
9003 smDeviceHandle_t *smDeviceHandle,
9004 smScsiInitiatorRequest_t *smScsiRequest,
9005 smSatIOContext_t *satIOContext
9006 )
9007 {
9008 bit32 status;
9009 bit32 agRequestType;
9010 smDeviceData_t *pSatDevData;
9011 agsaFisRegHostToDevice_t *fis;
9012 #ifdef SM_INTERNAL_DEBUG
9013 smIORequestBody_t *smIORequestBody;
9014 smSatInternalIo_t *satIntIoContext;
9015 #endif
9016
9017 pSatDevData = satIOContext->pSatDevData;
9018 fis = satIOContext->pFis;
9019 SM_DBG6(("smsatSendIDDev: start\n"));
9020 SM_DBG6(("smsatSendIDDev: did %d\n", pSatDevData->id));
9021 #ifdef SM_INTERNAL_DEBUG
9022 satIntIoContext = satIOContext->satIntIoContext;
9023 smIORequestBody = satIntIoContext->satIntRequestBody;
9024 #endif
9025 fis->h.fisType = 0x27; /* Reg host to device */
9026 fis->h.c_pmPort = 0x80; /* C Bit is set */
9027 if (pSatDevData->satDeviceType == SATA_ATAPI_DEVICE)
9028 fis->h.command = SAT_IDENTIFY_PACKET_DEVICE; /* 0x40 */
9029 else
9030 fis->h.command = SAT_IDENTIFY_DEVICE; /* 0xEC */
9031 fis->h.features = 0; /* FIS reserve */
9032 fis->d.lbaLow = 0; /* FIS LBA (7 :0 ) */
9033 fis->d.lbaMid = 0; /* FIS LBA (15:8 ) */
9034 fis->d.lbaHigh = 0; /* FIS LBA (23:16) */
9035 fis->d.device = 0; /* FIS LBA mode */
9036 fis->d.lbaLowExp = 0;
9037 fis->d.lbaMidExp = 0;
9038 fis->d.lbaHighExp = 0;
9039 fis->d.featuresExp = 0;
9040 fis->d.sectorCount = 0; /* FIS sector count (7:0) */
9041 fis->d.sectorCountExp = 0;
9042 fis->d.reserved4 = 0;
9043 fis->d.control = 0; /* FIS HOB bit clear */
9044 fis->d.reserved5 = 0;
9045
9046 agRequestType = AGSA_SATA_PROTOCOL_PIO_READ;
9047
9048 /* Initialize CB for SATA completion.
9049 */
9050 satIOContext->satCompleteCB = &smsatInquiryCB;
9051
9052 /*
9053 * Prepare SGL and send FIS to LL layer.
9054 */
9055 satIOContext->reqType = agRequestType; /* Save it */
9056
9057 #ifdef SM_INTERNAL_DEBUG
9058 smhexdump("smsatSendIDDev", (bit8 *)satIOContext->pFis, sizeof(agsaFisRegHostToDevice_t));
9059 smhexdump("smsatSendIDDev LL", (bit8 *)&(smIORequestBody->transport.SATA.agSATARequestBody.fis.fisRegHostToDev), sizeof(agsaFisRegHostToDevice_t));
9060 #endif
9061 status = smsataLLIOStart( smRoot,
9062 smIORequest,
9063 smDeviceHandle,
9064 smScsiRequest,
9065 satIOContext);
9066
9067 SM_DBG6(("smsatSendIDDev: end status %d\n", status));
9068 return status;
9069 }
9070
9071 osGLOBAL bit32
smsatRequestSense(smRoot_t * smRoot,smIORequest_t * smIORequest,smDeviceHandle_t * smDeviceHandle,smScsiInitiatorRequest_t * smScsiRequest,smSatIOContext_t * satIOContext)9072 smsatRequestSense(
9073 smRoot_t *smRoot,
9074 smIORequest_t *smIORequest,
9075 smDeviceHandle_t *smDeviceHandle,
9076 smScsiInitiatorRequest_t *smScsiRequest,
9077 smSatIOContext_t *satIOContext
9078 )
9079 {
9080 /*
9081 SAT Rev 8 p38, Table25
9082 sending SMART RETURN STATUS
9083 Checking SMART Treshold Exceeded Condition is done in satRequestSenseCB()
9084 Only fixed format sense data is support. In other words, we don't support DESC bit is set
9085 in Request Sense
9086 */
9087 bit32 status;
9088 bit32 agRequestType;
9089 smScsiRspSense_t *pSense;
9090 smDeviceData_t *pSatDevData;
9091 smIniScsiCmnd_t *scsiCmnd;
9092 agsaFisRegHostToDevice_t *fis;
9093 smIORequestBody_t *smIORequestBody;
9094 smSatInternalIo_t *satIntIo = agNULL;
9095 smSatIOContext_t *satIOContext2;
9096 bit8 *pDataBuffer = agNULL;
9097 bit32 allocationLen = 0;
9098
9099 pSense = satIOContext->pSense;
9100 pSatDevData = satIOContext->pSatDevData;
9101 scsiCmnd = &smScsiRequest->scsiCmnd;
9102 fis = satIOContext->pFis;
9103 pDataBuffer = (bit8 *) smScsiRequest->sglVirtualAddr;
9104 allocationLen = scsiCmnd->cdb[4];
9105 allocationLen = MIN(allocationLen, scsiCmnd->expDataLength);
9106 SM_DBG5(("smsatRequestSense: start\n"));
9107
9108 /* checking CONTROL */
9109 /* NACA == 1 or LINK == 1*/
9110 if ( (scsiCmnd->cdb[5] & SCSI_NACA_MASK) || (scsiCmnd->cdb[5] & SCSI_LINK_MASK) )
9111 {
9112 smsatSetSensePayload( pSense,
9113 SCSI_SNSKEY_ILLEGAL_REQUEST,
9114 0,
9115 SCSI_SNSCODE_INVALID_FIELD_IN_CDB,
9116 satIOContext);
9117 sm_memcpy(pDataBuffer, pSense, MIN(SENSE_DATA_LENGTH, allocationLen));
9118
9119 /*smEnqueueIO(smRoot, satIOContext);*/
9120
9121 tdsmIOCompletedCB( smRoot,
9122 smIORequest,
9123 smIOSuccess,
9124 SCSI_STAT_CHECK_CONDITION,
9125 satIOContext->pSmSenseData,
9126 satIOContext->interruptContext );
9127
9128 SM_DBG1(("smsatRequestSense: return control!!!\n"));
9129 return SM_RC_SUCCESS;
9130 }
9131
9132 /*
9133 Only fixed format sense data is support. In other words, we don't support DESC bit is set
9134 in Request Sense
9135 */
9136 if ( scsiCmnd->cdb[1] & ATA_REMOVABLE_MEDIA_DEVICE_MASK )
9137 {
9138 smsatSetSensePayload( pSense,
9139 SCSI_SNSKEY_ILLEGAL_REQUEST,
9140 0,
9141 SCSI_SNSCODE_INVALID_FIELD_IN_CDB,
9142 satIOContext);
9143 sm_memcpy(pDataBuffer, pSense, MIN(SENSE_DATA_LENGTH, allocationLen));
9144
9145 /*smEnqueueIO(smRoot, satIOContext);*/
9146
9147 tdsmIOCompletedCB( smRoot,
9148 smIORequest,
9149 smIOSuccess,
9150 SCSI_STAT_CHECK_CONDITION,
9151 satIOContext->pSmSenseData,
9152 satIOContext->interruptContext );
9153
9154 SM_DBG1(("smsatRequestSense: DESC bit is set, which we don't support!!!\n"));
9155 return SM_RC_SUCCESS;
9156 }
9157
9158
9159 if (pSatDevData->satSMARTEnabled == agTRUE)
9160 {
9161 /* sends SMART RETURN STATUS */
9162 fis->h.fisType = 0x27; /* Reg host to device */
9163 fis->h.c_pmPort = 0x80; /* C Bit is set */
9164
9165 fis->h.command = SAT_SMART; /* 0xB0 */
9166 fis->h.features = SAT_SMART_RETURN_STATUS; /* FIS features */
9167 fis->d.featuresExp = 0; /* FIS reserve */
9168 fis->d.sectorCount = 0; /* FIS sector count (7:0) */
9169 fis->d.sectorCountExp = 0; /* FIS sector count (15:8) */
9170 fis->d.lbaLow = 0; /* FIS LBA (7 :0 ) */
9171 fis->d.lbaLowExp = 0; /* FIS LBA (31:24) */
9172 fis->d.lbaMid = 0x4F; /* FIS LBA (15:8 ) */
9173 fis->d.lbaMidExp = 0; /* FIS LBA (39:32) */
9174 fis->d.lbaHigh = 0xC2; /* FIS LBA (23:16) */
9175 fis->d.lbaHighExp = 0; /* FIS LBA (47:40) */
9176 fis->d.device = 0; /* FIS DEV is discared in SATA */
9177 fis->d.control = 0; /* FIS HOB bit clear */
9178 fis->d.reserved4 = 0;
9179 fis->d.reserved5 = 0;
9180
9181 agRequestType = AGSA_SATA_PROTOCOL_NON_DATA;
9182 /* Initialize CB for SATA completion.
9183 */
9184 satIOContext->satCompleteCB = &smsatRequestSenseCB;
9185
9186 /*
9187 * Prepare SGL and send FIS to LL layer.
9188 */
9189 satIOContext->reqType = agRequestType; /* Save it */
9190
9191 status = smsataLLIOStart( smRoot,
9192 smIORequest,
9193 smDeviceHandle,
9194 smScsiRequest,
9195 satIOContext);
9196
9197 SM_DBG4(("smsatRequestSense: if return, status %d\n", status));
9198 return (status);
9199 }
9200 else
9201 {
9202 /*allocate iocontext for xmitting xmit SAT_CHECK_POWER_MODE
9203 then call satRequestSense2 */
9204
9205 SM_DBG4(("smsatRequestSense: before satIntIo %p\n", satIntIo));
9206 /* allocate iocontext */
9207 satIntIo = smsatAllocIntIoResource( smRoot,
9208 smIORequest, /* original request */
9209 pSatDevData,
9210 smScsiRequest->scsiCmnd.expDataLength,
9211 satIntIo);
9212
9213 SM_DBG4(("smsatRequestSense: after satIntIo %p\n", satIntIo));
9214
9215 if (satIntIo == agNULL)
9216 {
9217 /* failed during sending SMART RETURN STATUS */
9218 smsatSetSensePayload( pSense,
9219 SCSI_SNSKEY_NO_SENSE,
9220 0,
9221 SCSI_SNSCODE_HARDWARE_IMPENDING_FAILURE,
9222 satIOContext);
9223 sm_memcpy(pDataBuffer, pSense, MIN(SENSE_DATA_LENGTH, allocationLen));
9224
9225 /*smEnqueueIO(smRoot, satIOContext);*/
9226
9227 tdsmIOCompletedCB( smRoot,
9228 smIORequest,
9229 smIOSuccess,
9230 SCSI_STAT_GOOD,
9231 agNULL,
9232 satIOContext->interruptContext );
9233
9234 SM_DBG1(("smsatRequestSense: else fail 1!!!\n"));
9235 return SM_RC_SUCCESS;
9236 } /* end of memory allocation failure */
9237
9238
9239 /*
9240 * Need to initialize all the fields within satIOContext except
9241 * reqType and satCompleteCB which will be set depending on cmd.
9242 */
9243
9244 if (satIntIo == agNULL)
9245 {
9246 SM_DBG4(("smsatRequestSense: satIntIo is NULL\n"));
9247 }
9248 else
9249 {
9250 SM_DBG4(("smsatRequestSense: satIntIo is NOT NULL\n"));
9251 }
9252 /* use this --- tttttthe one the same */
9253
9254
9255 satIntIo->satOrgSmIORequest = smIORequest;
9256 smIORequestBody = (smIORequestBody_t *)satIntIo->satIntRequestBody;
9257 satIOContext2 = &(smIORequestBody->transport.SATA.satIOContext);
9258
9259 satIOContext2->pSatDevData = pSatDevData;
9260 satIOContext2->pFis = &(smIORequestBody->transport.SATA.agSATARequestBody.fis.fisRegHostToDev);
9261 satIOContext2->pScsiCmnd = &(satIntIo->satIntSmScsiXchg.scsiCmnd);
9262 satIOContext2->pSense = &(smIORequestBody->transport.SATA.sensePayload);
9263 satIOContext2->pSmSenseData = &(smIORequestBody->transport.SATA.smSenseData);
9264 satIOContext2->pSmSenseData->senseData = satIOContext2->pSense;
9265 satIOContext2->smRequestBody = satIntIo->satIntRequestBody;
9266 satIOContext2->interruptContext = satIOContext->interruptContext;
9267 satIOContext2->satIntIoContext = satIntIo;
9268 satIOContext2->psmDeviceHandle = smDeviceHandle;
9269 satIOContext2->satOrgIOContext = satIOContext;
9270
9271 SM_DBG4(("smsatRequestSense: satIntIo->satIntSmScsiXchg.agSgl1.len %d\n", satIntIo->satIntSmScsiXchg.smSgl1.len));
9272
9273 SM_DBG4(("smsatRequestSense: satIntIo->satIntSmScsiXchg.agSgl1.upper %d\n", satIntIo->satIntSmScsiXchg.smSgl1.upper));
9274
9275 SM_DBG4(("smsatRequestSense: satIntIo->satIntSmScsiXchg.agSgl1.lower %d\n", satIntIo->satIntSmScsiXchg.smSgl1.lower));
9276
9277 SM_DBG4(("smsatRequestSense: satIntIo->satIntSmScsiXchg.agSgl1.type %d\n", satIntIo->satIntSmScsiXchg.smSgl1.type));
9278
9279 status = smsatRequestSense_1( smRoot,
9280 &(satIntIo->satIntSmIORequest),
9281 smDeviceHandle,
9282 &(satIntIo->satIntSmScsiXchg),
9283 satIOContext2);
9284
9285 if (status != SM_RC_SUCCESS)
9286 {
9287 smsatFreeIntIoResource( smRoot,
9288 pSatDevData,
9289 satIntIo);
9290
9291 /* failed during sending SMART RETURN STATUS */
9292 smsatSetSensePayload( pSense,
9293 SCSI_SNSKEY_NO_SENSE,
9294 0,
9295 SCSI_SNSCODE_HARDWARE_IMPENDING_FAILURE,
9296 satIOContext);
9297 sm_memcpy(pDataBuffer, pSense, MIN(SENSE_DATA_LENGTH, allocationLen));
9298
9299 /*smEnqueueIO(smRoot, satIOContext);*/
9300
9301 tdsmIOCompletedCB( smRoot,
9302 smIORequest,
9303 smIOSuccess,
9304 SCSI_STAT_CHECK_CONDITION,
9305 agNULL,
9306 satIOContext->interruptContext );
9307
9308 SM_DBG1(("smsatRequestSense: else fail 2!!!\n"));
9309 return SM_RC_SUCCESS;
9310 }
9311 SM_DBG4(("smsatRequestSense: else return success\n"));
9312 return SM_RC_SUCCESS;
9313 }
9314 }
9315
9316 osGLOBAL bit32
smsatRequestSense_1(smRoot_t * smRoot,smIORequest_t * smIORequest,smDeviceHandle_t * smDeviceHandle,smScsiInitiatorRequest_t * smScsiRequest,smSatIOContext_t * satIOContext)9317 smsatRequestSense_1(
9318 smRoot_t *smRoot,
9319 smIORequest_t *smIORequest,
9320 smDeviceHandle_t *smDeviceHandle,
9321 smScsiInitiatorRequest_t *smScsiRequest,
9322 smSatIOContext_t *satIOContext
9323 )
9324 {
9325 /*
9326 sends SAT_CHECK_POWER_MODE
9327 */
9328 bit32 status;
9329 bit32 agRequestType;
9330 agsaFisRegHostToDevice_t *fis;
9331
9332 fis = satIOContext->pFis;
9333 SM_DBG5(("smsatRequestSense_1: start\n"));
9334 /*
9335 * Send the ATA CHECK POWER MODE command.
9336 */
9337 fis->h.fisType = 0x27; /* Reg host to device */
9338 fis->h.c_pmPort = 0x80; /* C Bit is set */
9339 fis->h.command = SAT_CHECK_POWER_MODE; /* 0xE5 */
9340 fis->h.features = 0;
9341 fis->d.lbaLow = 0;
9342 fis->d.lbaMid = 0;
9343 fis->d.lbaHigh = 0;
9344 fis->d.device = 0;
9345 fis->d.lbaLowExp = 0;
9346 fis->d.lbaMidExp = 0;
9347 fis->d.lbaHighExp = 0;
9348 fis->d.featuresExp = 0;
9349 fis->d.sectorCount = 0;
9350 fis->d.sectorCountExp = 0;
9351 fis->d.reserved4 = 0;
9352 fis->d.control = 0; /* FIS HOB bit clear */
9353 fis->d.reserved5 = 0;
9354
9355 agRequestType = AGSA_SATA_PROTOCOL_NON_DATA;
9356
9357 /* Initialize CB for SATA completion.
9358 */
9359 satIOContext->satCompleteCB = &smsatRequestSenseCB;
9360
9361 /*
9362 * Prepare SGL and send FIS to LL layer.
9363 */
9364 satIOContext->reqType = agRequestType; /* Save it */
9365
9366
9367 SM_DBG4(("smsatRequestSense_1: smSgl1.len %d\n", smScsiRequest->smSgl1.len));
9368
9369 SM_DBG4(("smsatRequestSense_1: smSgl1.upper %d\n", smScsiRequest->smSgl1.upper));
9370
9371 SM_DBG4(("smsatRequestSense_1: smSgl1.lower %d\n", smScsiRequest->smSgl1.lower));
9372
9373 SM_DBG4(("smsatRequestSense_1: smSgl1.type %d\n", smScsiRequest->smSgl1.type));
9374
9375 // smhexdump("smsatRequestSense_1", (bit8 *)fis, sizeof(agsaFisRegHostToDevice_t));
9376
9377 status = smsataLLIOStart( smRoot,
9378 smIORequest,
9379 smDeviceHandle,
9380 smScsiRequest,
9381 satIOContext);
9382
9383
9384
9385 return status;
9386 }
9387
9388 osGLOBAL bit32
smsatModeSense6(smRoot_t * smRoot,smIORequest_t * smIORequest,smDeviceHandle_t * smDeviceHandle,smScsiInitiatorRequest_t * smScsiRequest,smSatIOContext_t * satIOContext)9389 smsatModeSense6(
9390 smRoot_t *smRoot,
9391 smIORequest_t *smIORequest,
9392 smDeviceHandle_t *smDeviceHandle,
9393 smScsiInitiatorRequest_t *smScsiRequest,
9394 smSatIOContext_t *satIOContext
9395 )
9396 {
9397 smScsiRspSense_t *pSense;
9398 bit32 allocationLen;
9399 smIniScsiCmnd_t *scsiCmnd;
9400 bit32 pageSupported;
9401 bit8 page;
9402 bit8 *pModeSense; /* Mode Sense data buffer */
9403 smDeviceData_t *pSatDevData;
9404 bit8 PC;
9405 bit8 AllPages[MODE_SENSE6_RETURN_ALL_PAGES_LEN];
9406 bit8 Control[MODE_SENSE6_CONTROL_PAGE_LEN];
9407 bit8 RWErrorRecovery[MODE_SENSE6_READ_WRITE_ERROR_RECOVERY_PAGE_LEN];
9408 bit8 Caching[MODE_SENSE6_CACHING_LEN];
9409 bit8 InfoExceptionCtrl[MODE_SENSE6_INFORMATION_EXCEPTION_CONTROL_PAGE_LEN];
9410 bit8 lenRead = 0;
9411
9412
9413 pSense = satIOContext->pSense;
9414 scsiCmnd = &smScsiRequest->scsiCmnd;
9415 pModeSense = (bit8 *) smScsiRequest->sglVirtualAddr;
9416 pSatDevData = satIOContext->pSatDevData;
9417
9418 //smhexdump("smsatModeSense6", (bit8 *)scsiCmnd->cdb, 6);
9419 SM_DBG5(("smsatModeSense6: start\n"));
9420 /* checking CONTROL */
9421 /* NACA == 1 or LINK == 1*/
9422 if ( (scsiCmnd->cdb[5] & SCSI_NACA_MASK) || (scsiCmnd->cdb[5] & SCSI_LINK_MASK) )
9423 {
9424 smsatSetSensePayload( pSense,
9425 SCSI_SNSKEY_ILLEGAL_REQUEST,
9426 0,
9427 SCSI_SNSCODE_INVALID_FIELD_IN_CDB,
9428 satIOContext);
9429 /*smEnqueueIO(smRoot, satIOContext);*/
9430 tdsmIOCompletedCB( smRoot,
9431 smIORequest,
9432 smIOSuccess,
9433 SCSI_STAT_CHECK_CONDITION,
9434 satIOContext->pSmSenseData,
9435 satIOContext->interruptContext );
9436 SM_DBG1(("smsatModeSense6: return control!!!\n"));
9437 return SM_RC_SUCCESS;
9438 }
9439 /* checking PC(Page Control)
9440 SAT revion 8, 8.5.3 p33 and 10.1.2, p66
9441 */
9442 PC = (bit8)((scsiCmnd->cdb[2]) & SCSI_MODE_SENSE6_PC_MASK);
9443 if (PC != 0)
9444 {
9445 smsatSetSensePayload( pSense,
9446 SCSI_SNSKEY_ILLEGAL_REQUEST,
9447 0,
9448 SCSI_SNSCODE_INVALID_FIELD_IN_CDB,
9449 satIOContext);
9450 /*smEnqueueIO(smRoot, satIOContext);*/
9451 tdsmIOCompletedCB( smRoot,
9452 smIORequest,
9453 smIOSuccess,
9454 SCSI_STAT_CHECK_CONDITION,
9455 satIOContext->pSmSenseData,
9456 satIOContext->interruptContext );
9457 SM_DBG1(("smsatModeSense6: return due to PC value pc 0x%x!!!\n", PC >> 6));
9458 return SM_RC_SUCCESS;
9459 }
9460 /* reading PAGE CODE */
9461 page = (bit8)((scsiCmnd->cdb[2]) & SCSI_MODE_SENSE6_PAGE_CODE_MASK);
9462
9463
9464 SM_DBG5(("smsatModeSense6: page=0x%x\n", page));
9465
9466 allocationLen = scsiCmnd->cdb[4];
9467 allocationLen = MIN(allocationLen, scsiCmnd->expDataLength);
9468 /*
9469 Based on page code value, returns a corresponding mode page
9470 note: no support for subpage
9471 */
9472 switch(page)
9473 {
9474 case MODESENSE_RETURN_ALL_PAGES:
9475 case MODESENSE_CONTROL_PAGE: /* control */
9476 case MODESENSE_READ_WRITE_ERROR_RECOVERY_PAGE: /* Read-Write Error Recovery */
9477 case MODESENSE_CACHING: /* caching */
9478 case MODESENSE_INFORMATION_EXCEPTION_CONTROL_PAGE: /* informational exceptions control*/
9479 pageSupported = agTRUE;
9480 break;
9481 case MODESENSE_VENDOR_SPECIFIC_PAGE: /* vendor specific */
9482 default:
9483 pageSupported = agFALSE;
9484 break;
9485 }
9486
9487 if (pageSupported == agFALSE)
9488 {
9489
9490 SM_DBG1(("smsatModeSense6 *** ERROR *** not supported page 0x%x did %d!!!\n",
9491 page, pSatDevData->id));
9492
9493 smsatSetSensePayload( pSense,
9494 SCSI_SNSKEY_ILLEGAL_REQUEST,
9495 0,
9496 SCSI_SNSCODE_INVALID_COMMAND,
9497 satIOContext);
9498
9499 /*smEnqueueIO(smRoot, satIOContext);*/
9500
9501 tdsmIOCompletedCB( smRoot,
9502 smIORequest,
9503 smIOSuccess,
9504 SCSI_STAT_CHECK_CONDITION,
9505 satIOContext->pSmSenseData,
9506 satIOContext->interruptContext );
9507 return SM_RC_SUCCESS;
9508 }
9509
9510 switch(page)
9511 {
9512 case MODESENSE_RETURN_ALL_PAGES:
9513 lenRead = (bit8)MIN(allocationLen, MODE_SENSE6_RETURN_ALL_PAGES_LEN);
9514 break;
9515 case MODESENSE_CONTROL_PAGE: /* control */
9516 lenRead = (bit8)MIN(allocationLen, MODE_SENSE6_CONTROL_PAGE_LEN);
9517 break;
9518 case MODESENSE_READ_WRITE_ERROR_RECOVERY_PAGE: /* Read-Write Error Recovery */
9519 lenRead = (bit8)MIN(allocationLen, MODE_SENSE6_READ_WRITE_ERROR_RECOVERY_PAGE_LEN);
9520 break;
9521 case MODESENSE_CACHING: /* caching */
9522 lenRead = (bit8)MIN(allocationLen, MODE_SENSE6_CACHING_LEN);
9523 break;
9524 case MODESENSE_INFORMATION_EXCEPTION_CONTROL_PAGE: /* informational exceptions control*/
9525 lenRead = (bit8)MIN(allocationLen, MODE_SENSE6_INFORMATION_EXCEPTION_CONTROL_PAGE_LEN);
9526 break;
9527 default:
9528 SM_DBG1(("smsatModeSense6: default error page %d!!!\n", page));
9529 break;
9530 }
9531
9532 if (page == MODESENSE_RETURN_ALL_PAGES)
9533 {
9534 SM_DBG5(("smsatModeSense6: MODESENSE_RETURN_ALL_PAGES\n"));
9535 AllPages[0] = (bit8)(lenRead - 1);
9536 AllPages[1] = 0x00; /* default medium type (currently mounted medium type) */
9537 AllPages[2] = 0x00; /* no write-protect, no support for DPO-FUA */
9538 AllPages[3] = 0x08; /* block descriptor length */
9539
9540 /*
9541 * Fill-up direct-access device block-descriptor, SAT, Table 19
9542 */
9543
9544 /* density code */
9545 AllPages[4] = 0x04; /* density-code : reserved for direct-access */
9546 /* number of blocks */
9547 AllPages[5] = 0x00; /* unspecified */
9548 AllPages[6] = 0x00; /* unspecified */
9549 AllPages[7] = 0x00; /* unspecified */
9550 /* reserved */
9551 AllPages[8] = 0x00; /* reserved */
9552 /* Block size */
9553 AllPages[9] = 0x00;
9554 AllPages[10] = 0x02; /* Block size is always 512 bytes */
9555 AllPages[11] = 0x00;
9556
9557 /* MODESENSE_READ_WRITE_ERROR_RECOVERY_PAGE */
9558 AllPages[12] = 0x01; /* page code */
9559 AllPages[13] = 0x0A; /* page length */
9560 AllPages[14] = 0x40; /* ARRE is set */
9561 AllPages[15] = 0x00;
9562 AllPages[16] = 0x00;
9563 AllPages[17] = 0x00;
9564 AllPages[18] = 0x00;
9565 AllPages[19] = 0x00;
9566 AllPages[20] = 0x00;
9567 AllPages[21] = 0x00;
9568 AllPages[22] = 0x00;
9569 AllPages[23] = 0x00;
9570 /* MODESENSE_CACHING */
9571 AllPages[24] = 0x08; /* page code */
9572 AllPages[25] = 0x12; /* page length */
9573 if (pSatDevData->satWriteCacheEnabled == agTRUE)
9574 {
9575 AllPages[26] = 0x04;/* WCE bit is set */
9576 }
9577 else
9578 {
9579 AllPages[26] = 0x00;/* WCE bit is NOT set */
9580 }
9581
9582 AllPages[27] = 0x00;
9583 AllPages[28] = 0x00;
9584 AllPages[29] = 0x00;
9585 AllPages[30] = 0x00;
9586 AllPages[31] = 0x00;
9587 AllPages[32] = 0x00;
9588 AllPages[33] = 0x00;
9589 AllPages[34] = 0x00;
9590 AllPages[35] = 0x00;
9591 if (pSatDevData->satLookAheadEnabled == agTRUE)
9592 {
9593 AllPages[36] = 0x00;/* DRA bit is NOT set */
9594 }
9595 else
9596 {
9597 AllPages[36] = 0x20;/* DRA bit is set */
9598 }
9599 AllPages[37] = 0x00;
9600 AllPages[38] = 0x00;
9601 AllPages[39] = 0x00;
9602 AllPages[40] = 0x00;
9603 AllPages[41] = 0x00;
9604 AllPages[42] = 0x00;
9605 AllPages[43] = 0x00;
9606 /* MODESENSE_CONTROL_PAGE */
9607 AllPages[44] = 0x0A; /* page code */
9608 AllPages[45] = 0x0A; /* page length */
9609 AllPages[46] = 0x02; /* only GLTSD bit is set */
9610 if (pSatDevData->satNCQ == agTRUE)
9611 {
9612 AllPages[47] = 0x12; /* Queue Alogorithm modifier 1b and QErr 01b*/
9613 }
9614 else
9615 {
9616 AllPages[47] = 0x02; /* Queue Alogorithm modifier 0b and QErr 01b */
9617 }
9618 AllPages[48] = 0x00;
9619 AllPages[49] = 0x00;
9620 AllPages[50] = 0x00; /* obsolete */
9621 AllPages[51] = 0x00; /* obsolete */
9622 AllPages[52] = 0xFF; /* Busy Timeout Period */
9623 AllPages[53] = 0xFF; /* Busy Timeout Period */
9624 AllPages[54] = 0x00; /* we don't support non-000b value for the self-test code */
9625 AllPages[55] = 0x00; /* we don't support non-000b value for the self-test code */
9626 /* MODESENSE_INFORMATION_EXCEPTION_CONTROL_PAGE */
9627 AllPages[56] = 0x1C; /* page code */
9628 AllPages[57] = 0x0A; /* page length */
9629 if (pSatDevData->satSMARTEnabled == agTRUE)
9630 {
9631 AllPages[58] = 0x00;/* DEXCPT bit is NOT set */
9632 }
9633 else
9634 {
9635 AllPages[58] = 0x08;/* DEXCPT bit is set */
9636 }
9637 AllPages[59] = 0x00; /* We don't support MRIE */
9638 AllPages[60] = 0x00; /* Interval timer vendor-specific */
9639 AllPages[61] = 0x00;
9640 AllPages[62] = 0x00;
9641 AllPages[63] = 0x00;
9642 AllPages[64] = 0x00; /* REPORT-COUNT */
9643 AllPages[65] = 0x00;
9644 AllPages[66] = 0x00;
9645 AllPages[67] = 0x00;
9646
9647 sm_memcpy(pModeSense, &AllPages, lenRead);
9648 }
9649 else if (page == MODESENSE_CONTROL_PAGE)
9650 {
9651 SM_DBG5(("smsatModeSense6: MODESENSE_CONTROL_PAGE\n"));
9652 Control[0] = MODE_SENSE6_CONTROL_PAGE_LEN - 1;
9653 Control[1] = 0x00; /* default medium type (currently mounted medium type) */
9654 Control[2] = 0x00; /* no write-protect, no support for DPO-FUA */
9655 Control[3] = 0x08; /* block descriptor length */
9656 /*
9657 * Fill-up direct-access device block-descriptor, SAT, Table 19
9658 */
9659
9660 /* density code */
9661 Control[4] = 0x04; /* density-code : reserved for direct-access */
9662 /* number of blocks */
9663 Control[5] = 0x00; /* unspecified */
9664 Control[6] = 0x00; /* unspecified */
9665 Control[7] = 0x00; /* unspecified */
9666 /* reserved */
9667 Control[8] = 0x00; /* reserved */
9668 /* Block size */
9669 Control[9] = 0x00;
9670 Control[10] = 0x02; /* Block size is always 512 bytes */
9671 Control[11] = 0x00;
9672 /*
9673 * Fill-up control mode page, SAT, Table 65
9674 */
9675 Control[12] = 0x0A; /* page code */
9676 Control[13] = 0x0A; /* page length */
9677 Control[14] = 0x02; /* only GLTSD bit is set */
9678 if (pSatDevData->satNCQ == agTRUE)
9679 {
9680 Control[15] = 0x12; /* Queue Alogorithm modifier 1b and QErr 01b*/
9681 }
9682 else
9683 {
9684 Control[15] = 0x02; /* Queue Alogorithm modifier 0b and QErr 01b */
9685 }
9686 Control[16] = 0x00;
9687 Control[17] = 0x00;
9688 Control[18] = 0x00; /* obsolete */
9689 Control[19] = 0x00; /* obsolete */
9690 Control[20] = 0xFF; /* Busy Timeout Period */
9691 Control[21] = 0xFF; /* Busy Timeout Period */
9692 Control[22] = 0x00; /* we don't support non-000b value for the self-test code */
9693 Control[23] = 0x00; /* we don't support non-000b value for the self-test code */
9694
9695 sm_memcpy(pModeSense, &Control, lenRead);
9696
9697 }
9698 else if (page == MODESENSE_READ_WRITE_ERROR_RECOVERY_PAGE)
9699 {
9700 SM_DBG5(("smsatModeSense6: MODESENSE_READ_WRITE_ERROR_RECOVERY_PAGE\n"));
9701 RWErrorRecovery[0] = MODE_SENSE6_READ_WRITE_ERROR_RECOVERY_PAGE_LEN - 1;
9702 RWErrorRecovery[1] = 0x00; /* default medium type (currently mounted medium type) */
9703 RWErrorRecovery[2] = 0x00; /* no write-protect, no support for DPO-FUA */
9704 RWErrorRecovery[3] = 0x08; /* block descriptor length */
9705 /*
9706 * Fill-up direct-access device block-descriptor, SAT, Table 19
9707 */
9708
9709 /* density code */
9710 RWErrorRecovery[4] = 0x04; /* density-code : reserved for direct-access */
9711 /* number of blocks */
9712 RWErrorRecovery[5] = 0x00; /* unspecified */
9713 RWErrorRecovery[6] = 0x00; /* unspecified */
9714 RWErrorRecovery[7] = 0x00; /* unspecified */
9715 /* reserved */
9716 RWErrorRecovery[8] = 0x00; /* reserved */
9717 /* Block size */
9718 RWErrorRecovery[9] = 0x00;
9719 RWErrorRecovery[10] = 0x02; /* Block size is always 512 bytes */
9720 RWErrorRecovery[11] = 0x00;
9721 /*
9722 * Fill-up Read-Write Error Recovery mode page, SAT, Table 66
9723 */
9724 RWErrorRecovery[12] = 0x01; /* page code */
9725 RWErrorRecovery[13] = 0x0A; /* page length */
9726 RWErrorRecovery[14] = 0x40; /* ARRE is set */
9727 RWErrorRecovery[15] = 0x00;
9728 RWErrorRecovery[16] = 0x00;
9729 RWErrorRecovery[17] = 0x00;
9730 RWErrorRecovery[18] = 0x00;
9731 RWErrorRecovery[19] = 0x00;
9732 RWErrorRecovery[20] = 0x00;
9733 RWErrorRecovery[21] = 0x00;
9734 RWErrorRecovery[22] = 0x00;
9735 RWErrorRecovery[23] = 0x00;
9736
9737 sm_memcpy(pModeSense, &RWErrorRecovery, lenRead);
9738
9739 }
9740 else if (page == MODESENSE_CACHING)
9741 {
9742 SM_DBG5(("smsatModeSense6: MODESENSE_CACHING\n"));
9743 /* special case */
9744 if (allocationLen == 4 && page == MODESENSE_CACHING)
9745 {
9746 SM_DBG5(("smsatModeSense6: linux 2.6.8.24 support\n"));
9747
9748 Caching[0] = 0x20 - 1; /* 32 - 1 */
9749 Caching[1] = 0x00; /* default medium type (currently mounted medium type) */
9750 Caching[2] = 0x00; /* no write-protect, no support for DPO-FUA */
9751 Caching[3] = 0x08; /* block descriptor length */
9752
9753 sm_memcpy(pModeSense, &Caching, 4);
9754 /*smEnqueueIO(smRoot, satIOContext);*/
9755
9756 tdsmIOCompletedCB( smRoot,
9757 smIORequest,
9758 smIOSuccess,
9759 SCSI_STAT_GOOD,
9760 agNULL,
9761 satIOContext->interruptContext);
9762 return SM_RC_SUCCESS;
9763 }
9764 Caching[0] = MODE_SENSE6_CACHING_LEN - 1;
9765 Caching[1] = 0x00; /* default medium type (currently mounted medium type) */
9766 Caching[2] = 0x00; /* no write-protect, no support for DPO-FUA */
9767 Caching[3] = 0x08; /* block descriptor length */
9768 /*
9769 * Fill-up direct-access device block-descriptor, SAT, Table 19
9770 */
9771
9772 /* density code */
9773 Caching[4] = 0x04; /* density-code : reserved for direct-access */
9774 /* number of blocks */
9775 Caching[5] = 0x00; /* unspecified */
9776 Caching[6] = 0x00; /* unspecified */
9777 Caching[7] = 0x00; /* unspecified */
9778 /* reserved */
9779 Caching[8] = 0x00; /* reserved */
9780 /* Block size */
9781 Caching[9] = 0x00;
9782 Caching[10] = 0x02; /* Block size is always 512 bytes */
9783 Caching[11] = 0x00;
9784 /*
9785 * Fill-up Caching mode page, SAT, Table 67
9786 */
9787 /* length 20 */
9788 Caching[12] = 0x08; /* page code */
9789 Caching[13] = 0x12; /* page length */
9790 if (pSatDevData->satWriteCacheEnabled == agTRUE)
9791 {
9792 Caching[14] = 0x04;/* WCE bit is set */
9793 }
9794 else
9795 {
9796 Caching[14] = 0x00;/* WCE bit is NOT set */
9797 }
9798
9799 Caching[15] = 0x00;
9800 Caching[16] = 0x00;
9801 Caching[17] = 0x00;
9802 Caching[18] = 0x00;
9803 Caching[19] = 0x00;
9804 Caching[20] = 0x00;
9805 Caching[21] = 0x00;
9806 Caching[22] = 0x00;
9807 Caching[23] = 0x00;
9808 if (pSatDevData->satLookAheadEnabled == agTRUE)
9809 {
9810 Caching[24] = 0x00;/* DRA bit is NOT set */
9811 }
9812 else
9813 {
9814 Caching[24] = 0x20;/* DRA bit is set */
9815 }
9816 Caching[25] = 0x00;
9817 Caching[26] = 0x00;
9818 Caching[27] = 0x00;
9819 Caching[28] = 0x00;
9820 Caching[29] = 0x00;
9821 Caching[30] = 0x00;
9822 Caching[31] = 0x00;
9823
9824 sm_memcpy(pModeSense, &Caching, lenRead);
9825
9826 }
9827 else if (page == MODESENSE_INFORMATION_EXCEPTION_CONTROL_PAGE)
9828 {
9829 SM_DBG5(("smsatModeSense6: MODESENSE_INFORMATION_EXCEPTION_CONTROL_PAGE\n"));
9830 InfoExceptionCtrl[0] = MODE_SENSE6_INFORMATION_EXCEPTION_CONTROL_PAGE_LEN - 1;
9831 InfoExceptionCtrl[1] = 0x00; /* default medium type (currently mounted medium type) */
9832 InfoExceptionCtrl[2] = 0x00; /* no write-protect, no support for DPO-FUA */
9833 InfoExceptionCtrl[3] = 0x08; /* block descriptor length */
9834 /*
9835 * Fill-up direct-access device block-descriptor, SAT, Table 19
9836 */
9837
9838 /* density code */
9839 InfoExceptionCtrl[4] = 0x04; /* density-code : reserved for direct-access */
9840 /* number of blocks */
9841 InfoExceptionCtrl[5] = 0x00; /* unspecified */
9842 InfoExceptionCtrl[6] = 0x00; /* unspecified */
9843 InfoExceptionCtrl[7] = 0x00; /* unspecified */
9844 /* reserved */
9845 InfoExceptionCtrl[8] = 0x00; /* reserved */
9846 /* Block size */
9847 InfoExceptionCtrl[9] = 0x00;
9848 InfoExceptionCtrl[10] = 0x02; /* Block size is always 512 bytes */
9849 InfoExceptionCtrl[11] = 0x00;
9850 /*
9851 * Fill-up informational-exceptions control mode page, SAT, Table 68
9852 */
9853 InfoExceptionCtrl[12] = 0x1C; /* page code */
9854 InfoExceptionCtrl[13] = 0x0A; /* page length */
9855 if (pSatDevData->satSMARTEnabled == agTRUE)
9856 {
9857 InfoExceptionCtrl[14] = 0x00;/* DEXCPT bit is NOT set */
9858 }
9859 else
9860 {
9861 InfoExceptionCtrl[14] = 0x08;/* DEXCPT bit is set */
9862 }
9863 InfoExceptionCtrl[15] = 0x00; /* We don't support MRIE */
9864 InfoExceptionCtrl[16] = 0x00; /* Interval timer vendor-specific */
9865 InfoExceptionCtrl[17] = 0x00;
9866 InfoExceptionCtrl[18] = 0x00;
9867 InfoExceptionCtrl[19] = 0x00;
9868 InfoExceptionCtrl[20] = 0x00; /* REPORT-COUNT */
9869 InfoExceptionCtrl[21] = 0x00;
9870 InfoExceptionCtrl[22] = 0x00;
9871 InfoExceptionCtrl[23] = 0x00;
9872 sm_memcpy(pModeSense, &InfoExceptionCtrl, lenRead);
9873
9874 }
9875 else
9876 {
9877 /* Error */
9878 SM_DBG1(("smsatModeSense6: Error page %d!!!\n", page));
9879 smsatSetSensePayload( pSense,
9880 SCSI_SNSKEY_ILLEGAL_REQUEST,
9881 0,
9882 SCSI_SNSCODE_INVALID_COMMAND,
9883 satIOContext);
9884
9885 /*smEnqueueIO(smRoot, satIOContext);*/
9886
9887 tdsmIOCompletedCB( smRoot,
9888 smIORequest,
9889 smIOSuccess,
9890 SCSI_STAT_CHECK_CONDITION,
9891 satIOContext->pSmSenseData,
9892 satIOContext->interruptContext );
9893 return SM_RC_SUCCESS;
9894 }
9895
9896 /* there can be only underrun not overrun in error case */
9897 if (allocationLen > lenRead)
9898 {
9899 SM_DBG6(("smsatModeSense6 reporting underrun lenRead=0x%x allocationLen=0x%x\n", lenRead, allocationLen));
9900
9901 /*smEnqueueIO(smRoot, satIOContext);*/
9902
9903 tdsmIOCompletedCB( smRoot,
9904 smIORequest,
9905 smIOUnderRun,
9906 allocationLen - lenRead,
9907 agNULL,
9908 satIOContext->interruptContext );
9909
9910
9911 }
9912 else
9913 {
9914 /*smEnqueueIO(smRoot, satIOContext);*/
9915
9916 tdsmIOCompletedCB( smRoot,
9917 smIORequest,
9918 smIOSuccess,
9919 SCSI_STAT_GOOD,
9920 agNULL,
9921 satIOContext->interruptContext);
9922 }
9923
9924 return SM_RC_SUCCESS;
9925
9926 }
9927
9928 osGLOBAL bit32
smsatModeSense10(smRoot_t * smRoot,smIORequest_t * smIORequest,smDeviceHandle_t * smDeviceHandle,smScsiInitiatorRequest_t * smScsiRequest,smSatIOContext_t * satIOContext)9929 smsatModeSense10(
9930 smRoot_t *smRoot,
9931 smIORequest_t *smIORequest,
9932 smDeviceHandle_t *smDeviceHandle,
9933 smScsiInitiatorRequest_t *smScsiRequest,
9934 smSatIOContext_t *satIOContext
9935 )
9936 {
9937 smScsiRspSense_t *pSense;
9938 bit32 allocationLen;
9939 smIniScsiCmnd_t *scsiCmnd;
9940 bit32 pageSupported;
9941 bit8 page;
9942 bit8 *pModeSense; /* Mode Sense data buffer */
9943 smDeviceData_t *pSatDevData;
9944 bit8 PC; /* page control */
9945 bit8 LLBAA; /* Long LBA Accepted */
9946 bit32 index;
9947 bit8 AllPages[MODE_SENSE10_RETURN_ALL_PAGES_LLBAA_LEN];
9948 bit8 Control[MODE_SENSE10_CONTROL_PAGE_LLBAA_LEN];
9949 bit8 RWErrorRecovery[MODE_SENSE10_READ_WRITE_ERROR_RECOVERY_PAGE_LLBAA_LEN];
9950 bit8 Caching[MODE_SENSE10_CACHING_LLBAA_LEN];
9951 bit8 InfoExceptionCtrl[MODE_SENSE10_INFORMATION_EXCEPTION_CONTROL_PAGE_LLBAA_LEN];
9952 bit8 lenRead = 0;
9953
9954 pSense = satIOContext->pSense;
9955 scsiCmnd = &smScsiRequest->scsiCmnd;
9956 pModeSense = (bit8 *) smScsiRequest->sglVirtualAddr;
9957 pSatDevData = satIOContext->pSatDevData;
9958 SM_DBG5(("smsatModeSense10: start\n"));
9959 /* checking CONTROL */
9960 /* NACA == 1 or LINK == 1*/
9961 if ( (scsiCmnd->cdb[9] & SCSI_NACA_MASK) || (scsiCmnd->cdb[9] & SCSI_LINK_MASK) )
9962 {
9963 smsatSetSensePayload( pSense,
9964 SCSI_SNSKEY_ILLEGAL_REQUEST,
9965 0,
9966 SCSI_SNSCODE_INVALID_FIELD_IN_CDB,
9967 satIOContext);
9968
9969 /*smEnqueueIO(smRoot, satIOContext);*/
9970
9971 tdsmIOCompletedCB( smRoot,
9972 smIORequest,
9973 smIOSuccess,
9974 SCSI_STAT_CHECK_CONDITION,
9975 satIOContext->pSmSenseData,
9976 satIOContext->interruptContext );
9977
9978 SM_DBG1(("smsatModeSense10: return control!!!\n"));
9979 return SM_RC_SUCCESS;
9980 }
9981
9982 /* checking PC(Page Control)
9983 SAT revion 8, 8.5.3 p33 and 10.1.2, p66
9984 */
9985 PC = (bit8)((scsiCmnd->cdb[2]) & SCSI_MODE_SENSE10_PC_MASK);
9986 if (PC != 0)
9987 {
9988 smsatSetSensePayload( pSense,
9989 SCSI_SNSKEY_ILLEGAL_REQUEST,
9990 0,
9991 SCSI_SNSCODE_INVALID_FIELD_IN_CDB,
9992 satIOContext);
9993
9994 /*smEnqueueIO(smRoot, satIOContext);*/
9995
9996 tdsmIOCompletedCB( smRoot,
9997 smIORequest,
9998 smIOSuccess,
9999 SCSI_STAT_CHECK_CONDITION,
10000 satIOContext->pSmSenseData,
10001 satIOContext->interruptContext );
10002
10003 SM_DBG1(("smsatModeSense10: return due to PC value pc 0x%x!!!\n", PC));
10004 return SM_RC_SUCCESS;
10005 }
10006
10007 /* finding LLBAA bit */
10008 LLBAA = (bit8)((scsiCmnd->cdb[1]) & SCSI_MODE_SENSE10_LLBAA_MASK);
10009
10010 /* reading PAGE CODE */
10011 page = (bit8)((scsiCmnd->cdb[2]) & SCSI_MODE_SENSE10_PAGE_CODE_MASK);
10012 SM_DBG5(("smsatModeSense10: page=0x%x, did %d\n", page, pSatDevData->id));
10013 allocationLen = (scsiCmnd->cdb[7] << 8) + scsiCmnd->cdb[8];
10014 allocationLen = MIN(allocationLen, scsiCmnd->expDataLength);
10015
10016 /*
10017 Based on page code value, returns a corresponding mode page
10018 note: no support for subpage
10019 */
10020 switch(page)
10021 {
10022 case MODESENSE_RETURN_ALL_PAGES: /* return all pages */
10023 case MODESENSE_CONTROL_PAGE: /* control */
10024 case MODESENSE_READ_WRITE_ERROR_RECOVERY_PAGE: /* Read-Write Error Recovery */
10025 case MODESENSE_CACHING: /* caching */
10026 case MODESENSE_INFORMATION_EXCEPTION_CONTROL_PAGE: /* informational exceptions control*/
10027 pageSupported = agTRUE;
10028 break;
10029 case MODESENSE_VENDOR_SPECIFIC_PAGE: /* vendor specific */
10030 default:
10031 pageSupported = agFALSE;
10032 break;
10033 }
10034 if (pageSupported == agFALSE)
10035 {
10036 SM_DBG1(("smsatModeSense10 *** ERROR *** not supported page 0x%x did %d!!!\n", page, pSatDevData->id));
10037
10038 smsatSetSensePayload( pSense,
10039 SCSI_SNSKEY_ILLEGAL_REQUEST,
10040 0,
10041 SCSI_SNSCODE_INVALID_COMMAND,
10042 satIOContext);
10043 /*smEnqueueIO(smRoot, satIOContext);*/
10044 tdsmIOCompletedCB( smRoot,
10045 smIORequest,
10046 smIOSuccess,
10047 SCSI_STAT_CHECK_CONDITION,
10048 satIOContext->pSmSenseData,
10049 satIOContext->interruptContext );
10050 return SM_RC_SUCCESS;
10051 }
10052 switch(page)
10053 {
10054 case MODESENSE_RETURN_ALL_PAGES:
10055 if (LLBAA)
10056 {
10057 lenRead = (bit8)MIN(allocationLen, MODE_SENSE10_RETURN_ALL_PAGES_LLBAA_LEN);
10058 }
10059 else
10060 {
10061 lenRead = (bit8)MIN(allocationLen, MODE_SENSE10_RETURN_ALL_PAGES_LEN);
10062 }
10063 break;
10064 case MODESENSE_CONTROL_PAGE: /* control */
10065 if (LLBAA)
10066 {
10067 lenRead = (bit8)MIN(allocationLen, MODE_SENSE10_CONTROL_PAGE_LLBAA_LEN);
10068 }
10069 else
10070 {
10071 lenRead = (bit8)MIN(allocationLen, MODE_SENSE10_CONTROL_PAGE_LEN);
10072 }
10073 break;
10074 case MODESENSE_READ_WRITE_ERROR_RECOVERY_PAGE: /* Read-Write Error Recovery */
10075 if (LLBAA)
10076 {
10077 lenRead = (bit8)MIN(allocationLen, MODE_SENSE10_READ_WRITE_ERROR_RECOVERY_PAGE_LLBAA_LEN);
10078 }
10079 else
10080 {
10081 lenRead = (bit8)MIN(allocationLen, MODE_SENSE10_READ_WRITE_ERROR_RECOVERY_PAGE_LEN);
10082 }
10083 break;
10084 case MODESENSE_CACHING: /* caching */
10085 if (LLBAA)
10086 {
10087 lenRead = (bit8)MIN(allocationLen, MODE_SENSE10_CACHING_LLBAA_LEN);
10088 }
10089 else
10090 {
10091 lenRead = (bit8)MIN(allocationLen, MODE_SENSE10_CACHING_LEN);
10092 }
10093 break;
10094 case MODESENSE_INFORMATION_EXCEPTION_CONTROL_PAGE: /* informational exceptions control*/
10095 if (LLBAA)
10096 {
10097 lenRead = (bit8)MIN(allocationLen, MODE_SENSE10_INFORMATION_EXCEPTION_CONTROL_PAGE_LLBAA_LEN);
10098 }
10099 else
10100 {
10101 lenRead = (bit8)MIN(allocationLen, MODE_SENSE10_INFORMATION_EXCEPTION_CONTROL_PAGE_LEN);
10102 }
10103 break;
10104 default:
10105 SM_DBG1(("smsatModeSense10: default error page %d!!!\n", page));
10106 break;
10107 }
10108
10109 if (page == MODESENSE_RETURN_ALL_PAGES)
10110 {
10111 SM_DBG5(("smsatModeSense10: MODESENSE_RETURN_ALL_PAGES\n"));
10112 AllPages[0] = 0;
10113 AllPages[1] = (bit8)(lenRead - 2);
10114 AllPages[2] = 0x00; /* medium type: default medium type (currently mounted medium type) */
10115 AllPages[3] = 0x00; /* device-specific param: no write-protect, no support for DPO-FUA */
10116 if (LLBAA)
10117 {
10118 AllPages[4] = 0x00; /* reserved and LONGLBA */
10119 AllPages[4] = (bit8)(AllPages[4] | 0x1); /* LONGLBA is set */
10120 }
10121 else
10122 {
10123 AllPages[4] = 0x00; /* reserved and LONGLBA: LONGLBA is not set */
10124 }
10125 AllPages[5] = 0x00; /* reserved */
10126 AllPages[6] = 0x00; /* block descriptot length */
10127 if (LLBAA)
10128 {
10129 AllPages[7] = 0x10; /* block descriptor length: LONGLBA is set. So, length is 16 */
10130 }
10131 else
10132 {
10133 AllPages[7] = 0x08; /* block descriptor length: LONGLBA is NOT set. So, length is 8 */
10134 }
10135
10136 /*
10137 * Fill-up direct-access device block-descriptor, SAT, Table 19
10138 */
10139
10140 if (LLBAA)
10141 {
10142 /* density code */
10143 AllPages[8] = 0x04; /* density-code : reserved for direct-access */
10144 /* number of blocks */
10145 AllPages[9] = 0x00; /* unspecified */
10146 AllPages[10] = 0x00; /* unspecified */
10147 AllPages[11] = 0x00; /* unspecified */
10148 AllPages[12] = 0x00; /* unspecified */
10149 AllPages[13] = 0x00; /* unspecified */
10150 AllPages[14] = 0x00; /* unspecified */
10151 AllPages[15] = 0x00; /* unspecified */
10152 /* reserved */
10153 AllPages[16] = 0x00; /* reserved */
10154 AllPages[17] = 0x00; /* reserved */
10155 AllPages[18] = 0x00; /* reserved */
10156 AllPages[19] = 0x00; /* reserved */
10157 /* Block size */
10158 AllPages[20] = 0x00;
10159 AllPages[21] = 0x00;
10160 AllPages[22] = 0x02; /* Block size is always 512 bytes */
10161 AllPages[23] = 0x00;
10162 }
10163 else
10164 {
10165 /* density code */
10166 AllPages[8] = 0x04; /* density-code : reserved for direct-access */
10167 /* number of blocks */
10168 AllPages[9] = 0x00; /* unspecified */
10169 AllPages[10] = 0x00; /* unspecified */
10170 AllPages[11] = 0x00; /* unspecified */
10171 /* reserved */
10172 AllPages[12] = 0x00; /* reserved */
10173 /* Block size */
10174 AllPages[13] = 0x00;
10175 AllPages[14] = 0x02; /* Block size is always 512 bytes */
10176 AllPages[15] = 0x00;
10177 }
10178
10179 if (LLBAA)
10180 {
10181 index = 24;
10182 }
10183 else
10184 {
10185 index = 16;
10186 }
10187 /* MODESENSE_READ_WRITE_ERROR_RECOVERY_PAGE */
10188 AllPages[index+0] = 0x01; /* page code */
10189 AllPages[index+1] = 0x0A; /* page length */
10190 AllPages[index+2] = 0x40; /* ARRE is set */
10191 AllPages[index+3] = 0x00;
10192 AllPages[index+4] = 0x00;
10193 AllPages[index+5] = 0x00;
10194 AllPages[index+6] = 0x00;
10195 AllPages[index+7] = 0x00;
10196 AllPages[index+8] = 0x00;
10197 AllPages[index+9] = 0x00;
10198 AllPages[index+10] = 0x00;
10199 AllPages[index+11] = 0x00;
10200
10201 /* MODESENSE_CACHING */
10202 /*
10203 * Fill-up Caching mode page, SAT, Table 67
10204 */
10205 /* length 20 */
10206 AllPages[index+12] = 0x08; /* page code */
10207 AllPages[index+13] = 0x12; /* page length */
10208 if (pSatDevData->satWriteCacheEnabled == agTRUE)
10209 {
10210 AllPages[index+14] = 0x04;/* WCE bit is set */
10211 }
10212 else
10213 {
10214 AllPages[index+14] = 0x00;/* WCE bit is NOT set */
10215 }
10216
10217 AllPages[index+15] = 0x00;
10218 AllPages[index+16] = 0x00;
10219 AllPages[index+17] = 0x00;
10220 AllPages[index+18] = 0x00;
10221 AllPages[index+19] = 0x00;
10222 AllPages[index+20] = 0x00;
10223 AllPages[index+21] = 0x00;
10224 AllPages[index+22] = 0x00;
10225 AllPages[index+23] = 0x00;
10226 if (pSatDevData->satLookAheadEnabled == agTRUE)
10227 {
10228 AllPages[index+24] = 0x00;/* DRA bit is NOT set */
10229 }
10230 else
10231 {
10232 AllPages[index+24] = 0x20;/* DRA bit is set */
10233 }
10234 AllPages[index+25] = 0x00;
10235 AllPages[index+26] = 0x00;
10236 AllPages[index+27] = 0x00;
10237 AllPages[index+28] = 0x00;
10238 AllPages[index+29] = 0x00;
10239 AllPages[index+30] = 0x00;
10240 AllPages[index+31] = 0x00;
10241
10242 /* MODESENSE_CONTROL_PAGE */
10243 /*
10244 * Fill-up control mode page, SAT, Table 65
10245 */
10246 AllPages[index+32] = 0x0A; /* page code */
10247 AllPages[index+33] = 0x0A; /* page length */
10248 AllPages[index+34] = 0x02; /* only GLTSD bit is set */
10249 if (pSatDevData->satNCQ == agTRUE)
10250 {
10251 AllPages[index+35] = 0x12; /* Queue Alogorithm modifier 1b and QErr 01b*/
10252 }
10253 else
10254 {
10255 AllPages[index+35] = 0x02; /* Queue Alogorithm modifier 0b and QErr 01b */
10256 }
10257 AllPages[index+36] = 0x00;
10258 AllPages[index+37] = 0x00;
10259 AllPages[index+38] = 0x00; /* obsolete */
10260 AllPages[index+39] = 0x00; /* obsolete */
10261 AllPages[index+40] = 0xFF; /* Busy Timeout Period */
10262 AllPages[index+41] = 0xFF; /* Busy Timeout Period */
10263 AllPages[index+42] = 0x00; /* we don't support non-000b value for the self-test code */
10264 AllPages[index+43] = 0x00; /* we don't support non-000b value for the self-test code */
10265
10266 /* MODESENSE_INFORMATION_EXCEPTION_CONTROL_PAGE */
10267 /*
10268 * Fill-up informational-exceptions control mode page, SAT, Table 68
10269 */
10270 AllPages[index+44] = 0x1C; /* page code */
10271 AllPages[index+45] = 0x0A; /* page length */
10272 if (pSatDevData->satSMARTEnabled == agTRUE)
10273 {
10274 AllPages[index+46] = 0x00;/* DEXCPT bit is NOT set */
10275 }
10276 else
10277 {
10278 AllPages[index+46] = 0x08;/* DEXCPT bit is set */
10279 }
10280 AllPages[index+47] = 0x00; /* We don't support MRIE */
10281 AllPages[index+48] = 0x00; /* Interval timer vendor-specific */
10282 AllPages[index+49] = 0x00;
10283 AllPages[index+50] = 0x00;
10284 AllPages[index+51] = 0x00;
10285 AllPages[index+52] = 0x00; /* REPORT-COUNT */
10286 AllPages[index+53] = 0x00;
10287 AllPages[index+54] = 0x00;
10288 AllPages[index+55] = 0x00;
10289
10290 sm_memcpy(pModeSense, &AllPages, lenRead);
10291 }
10292 else if (page == MODESENSE_CONTROL_PAGE)
10293 {
10294 SM_DBG5(("smsatModeSense10: MODESENSE_CONTROL_PAGE\n"));
10295 Control[0] = 0;
10296 Control[1] = (bit8)(lenRead - 2);
10297 Control[2] = 0x00; /* medium type: default medium type (currently mounted medium type) */
10298 Control[3] = 0x00; /* device-specific param: no write-protect, no support for DPO-FUA */
10299 if (LLBAA)
10300 {
10301 Control[4] = 0x00; /* reserved and LONGLBA */
10302 Control[4] = (bit8)(Control[4] | 0x1); /* LONGLBA is set */
10303 }
10304 else
10305 {
10306 Control[4] = 0x00; /* reserved and LONGLBA: LONGLBA is not set */
10307 }
10308 Control[5] = 0x00; /* reserved */
10309 Control[6] = 0x00; /* block descriptot length */
10310 if (LLBAA)
10311 {
10312 Control[7] = 0x10; /* block descriptor length: LONGLBA is set. So, length is 16 */
10313 }
10314 else
10315 {
10316 Control[7] = 0x08; /* block descriptor length: LONGLBA is NOT set. So, length is 8 */
10317 }
10318
10319 /*
10320 * Fill-up direct-access device block-descriptor, SAT, Table 19
10321 */
10322
10323 if (LLBAA)
10324 {
10325 /* density code */
10326 Control[8] = 0x04; /* density-code : reserved for direct-access */
10327 /* number of blocks */
10328 Control[9] = 0x00; /* unspecified */
10329 Control[10] = 0x00; /* unspecified */
10330 Control[11] = 0x00; /* unspecified */
10331 Control[12] = 0x00; /* unspecified */
10332 Control[13] = 0x00; /* unspecified */
10333 Control[14] = 0x00; /* unspecified */
10334 Control[15] = 0x00; /* unspecified */
10335 /* reserved */
10336 Control[16] = 0x00; /* reserved */
10337 Control[17] = 0x00; /* reserved */
10338 Control[18] = 0x00; /* reserved */
10339 Control[19] = 0x00; /* reserved */
10340 /* Block size */
10341 Control[20] = 0x00;
10342 Control[21] = 0x00;
10343 Control[22] = 0x02; /* Block size is always 512 bytes */
10344 Control[23] = 0x00;
10345 }
10346 else
10347 {
10348 /* density code */
10349 Control[8] = 0x04; /* density-code : reserved for direct-access */
10350 /* number of blocks */
10351 Control[9] = 0x00; /* unspecified */
10352 Control[10] = 0x00; /* unspecified */
10353 Control[11] = 0x00; /* unspecified */
10354 /* reserved */
10355 Control[12] = 0x00; /* reserved */
10356 /* Block size */
10357 Control[13] = 0x00;
10358 Control[14] = 0x02; /* Block size is always 512 bytes */
10359 Control[15] = 0x00;
10360 }
10361
10362 if (LLBAA)
10363 {
10364 index = 24;
10365 }
10366 else
10367 {
10368 index = 16;
10369 }
10370 /*
10371 * Fill-up control mode page, SAT, Table 65
10372 */
10373 Control[index+0] = 0x0A; /* page code */
10374 Control[index+1] = 0x0A; /* page length */
10375 Control[index+2] = 0x02; /* only GLTSD bit is set */
10376 if (pSatDevData->satNCQ == agTRUE)
10377 {
10378 Control[index+3] = 0x12; /* Queue Alogorithm modifier 1b and QErr 01b*/
10379 }
10380 else
10381 {
10382 Control[index+3] = 0x02; /* Queue Alogorithm modifier 0b and QErr 01b */
10383 }
10384 Control[index+4] = 0x00;
10385 Control[index+5] = 0x00;
10386 Control[index+6] = 0x00; /* obsolete */
10387 Control[index+7] = 0x00; /* obsolete */
10388 Control[index+8] = 0xFF; /* Busy Timeout Period */
10389 Control[index+9] = 0xFF; /* Busy Timeout Period */
10390 Control[index+10] = 0x00; /* we don't support non-000b value for the self-test code */
10391 Control[index+11] = 0x00; /* we don't support non-000b value for the self-test code */
10392
10393 sm_memcpy(pModeSense, &Control, lenRead);
10394 }
10395 else if (page == MODESENSE_READ_WRITE_ERROR_RECOVERY_PAGE)
10396 {
10397 SM_DBG5(("smsatModeSense10: MODESENSE_READ_WRITE_ERROR_RECOVERY_PAGE\n"));
10398 RWErrorRecovery[0] = 0;
10399 RWErrorRecovery[1] = (bit8)(lenRead - 2);
10400 RWErrorRecovery[2] = 0x00; /* medium type: default medium type (currently mounted medium type) */
10401 RWErrorRecovery[3] = 0x00; /* device-specific param: no write-protect, no support for DPO-FUA */
10402 if (LLBAA)
10403 {
10404 RWErrorRecovery[4] = 0x00; /* reserved and LONGLBA */
10405 RWErrorRecovery[4] = (bit8)(RWErrorRecovery[4] | 0x1); /* LONGLBA is set */
10406 }
10407 else
10408 {
10409 RWErrorRecovery[4] = 0x00; /* reserved and LONGLBA: LONGLBA is not set */
10410 }
10411 RWErrorRecovery[5] = 0x00; /* reserved */
10412 RWErrorRecovery[6] = 0x00; /* block descriptot length */
10413 if (LLBAA)
10414 {
10415 RWErrorRecovery[7] = 0x10; /* block descriptor length: LONGLBA is set. So, length is 16 */
10416 }
10417 else
10418 {
10419 RWErrorRecovery[7] = 0x08; /* block descriptor length: LONGLBA is NOT set. So, length is 8 */
10420 }
10421
10422 /*
10423 * Fill-up direct-access device block-descriptor, SAT, Table 19
10424 */
10425
10426 if (LLBAA)
10427 {
10428 /* density code */
10429 RWErrorRecovery[8] = 0x04; /* density-code : reserved for direct-access */
10430 /* number of blocks */
10431 RWErrorRecovery[9] = 0x00; /* unspecified */
10432 RWErrorRecovery[10] = 0x00; /* unspecified */
10433 RWErrorRecovery[11] = 0x00; /* unspecified */
10434 RWErrorRecovery[12] = 0x00; /* unspecified */
10435 RWErrorRecovery[13] = 0x00; /* unspecified */
10436 RWErrorRecovery[14] = 0x00; /* unspecified */
10437 RWErrorRecovery[15] = 0x00; /* unspecified */
10438 /* reserved */
10439 RWErrorRecovery[16] = 0x00; /* reserved */
10440 RWErrorRecovery[17] = 0x00; /* reserved */
10441 RWErrorRecovery[18] = 0x00; /* reserved */
10442 RWErrorRecovery[19] = 0x00; /* reserved */
10443 /* Block size */
10444 RWErrorRecovery[20] = 0x00;
10445 RWErrorRecovery[21] = 0x00;
10446 RWErrorRecovery[22] = 0x02; /* Block size is always 512 bytes */
10447 RWErrorRecovery[23] = 0x00;
10448 }
10449 else
10450 {
10451 /* density code */
10452 RWErrorRecovery[8] = 0x04; /* density-code : reserved for direct-access */
10453 /* number of blocks */
10454 RWErrorRecovery[9] = 0x00; /* unspecified */
10455 RWErrorRecovery[10] = 0x00; /* unspecified */
10456 RWErrorRecovery[11] = 0x00; /* unspecified */
10457 /* reserved */
10458 RWErrorRecovery[12] = 0x00; /* reserved */
10459 /* Block size */
10460 RWErrorRecovery[13] = 0x00;
10461 RWErrorRecovery[14] = 0x02; /* Block size is always 512 bytes */
10462 RWErrorRecovery[15] = 0x00;
10463 }
10464
10465 if (LLBAA)
10466 {
10467 index = 24;
10468 }
10469 else
10470 {
10471 index = 16;
10472 }
10473 /*
10474 * Fill-up Read-Write Error Recovery mode page, SAT, Table 66
10475 */
10476 RWErrorRecovery[index+0] = 0x01; /* page code */
10477 RWErrorRecovery[index+1] = 0x0A; /* page length */
10478 RWErrorRecovery[index+2] = 0x40; /* ARRE is set */
10479 RWErrorRecovery[index+3] = 0x00;
10480 RWErrorRecovery[index+4] = 0x00;
10481 RWErrorRecovery[index+5] = 0x00;
10482 RWErrorRecovery[index+6] = 0x00;
10483 RWErrorRecovery[index+7] = 0x00;
10484 RWErrorRecovery[index+8] = 0x00;
10485 RWErrorRecovery[index+9] = 0x00;
10486 RWErrorRecovery[index+10] = 0x00;
10487 RWErrorRecovery[index+11] = 0x00;
10488
10489 sm_memcpy(pModeSense, &RWErrorRecovery, lenRead);
10490 }
10491 else if (page == MODESENSE_CACHING)
10492 {
10493 SM_DBG5(("smsatModeSense10: MODESENSE_CACHING\n"));
10494 Caching[0] = 0;
10495 Caching[1] = (bit8)(lenRead - 2);
10496 Caching[2] = 0x00; /* medium type: default medium type (currently mounted medium type) */
10497 Caching[3] = 0x00; /* device-specific param: no write-protect, no support for DPO-FUA */
10498 if (LLBAA)
10499 {
10500 Caching[4] = 0x00; /* reserved and LONGLBA */
10501 Caching[4] = (bit8)(Caching[4] | 0x1); /* LONGLBA is set */
10502 }
10503 else
10504 {
10505 Caching[4] = 0x00; /* reserved and LONGLBA: LONGLBA is not set */
10506 }
10507 Caching[5] = 0x00; /* reserved */
10508 Caching[6] = 0x00; /* block descriptot length */
10509 if (LLBAA)
10510 {
10511 Caching[7] = 0x10; /* block descriptor length: LONGLBA is set. So, length is 16 */
10512 }
10513 else
10514 {
10515 Caching[7] = 0x08; /* block descriptor length: LONGLBA is NOT set. So, length is 8 */
10516 }
10517
10518 /*
10519 * Fill-up direct-access device block-descriptor, SAT, Table 19
10520 */
10521
10522 if (LLBAA)
10523 {
10524 /* density code */
10525 Caching[8] = 0x04; /* density-code : reserved for direct-access */
10526 /* number of blocks */
10527 Caching[9] = 0x00; /* unspecified */
10528 Caching[10] = 0x00; /* unspecified */
10529 Caching[11] = 0x00; /* unspecified */
10530 Caching[12] = 0x00; /* unspecified */
10531 Caching[13] = 0x00; /* unspecified */
10532 Caching[14] = 0x00; /* unspecified */
10533 Caching[15] = 0x00; /* unspecified */
10534 /* reserved */
10535 Caching[16] = 0x00; /* reserved */
10536 Caching[17] = 0x00; /* reserved */
10537 Caching[18] = 0x00; /* reserved */
10538 Caching[19] = 0x00; /* reserved */
10539 /* Block size */
10540 Caching[20] = 0x00;
10541 Caching[21] = 0x00;
10542 Caching[22] = 0x02; /* Block size is always 512 bytes */
10543 Caching[23] = 0x00;
10544 }
10545 else
10546 {
10547 /* density code */
10548 Caching[8] = 0x04; /* density-code : reserved for direct-access */
10549 /* number of blocks */
10550 Caching[9] = 0x00; /* unspecified */
10551 Caching[10] = 0x00; /* unspecified */
10552 Caching[11] = 0x00; /* unspecified */
10553 /* reserved */
10554 Caching[12] = 0x00; /* reserved */
10555 /* Block size */
10556 Caching[13] = 0x00;
10557 Caching[14] = 0x02; /* Block size is always 512 bytes */
10558 Caching[15] = 0x00;
10559 }
10560
10561 if (LLBAA)
10562 {
10563 index = 24;
10564 }
10565 else
10566 {
10567 index = 16;
10568 }
10569 /*
10570 * Fill-up Caching mode page, SAT, Table 67
10571 */
10572 /* length 20 */
10573 Caching[index+0] = 0x08; /* page code */
10574 Caching[index+1] = 0x12; /* page length */
10575 if (pSatDevData->satWriteCacheEnabled == agTRUE)
10576 {
10577 Caching[index+2] = 0x04;/* WCE bit is set */
10578 }
10579 else
10580 {
10581 Caching[index+2] = 0x00;/* WCE bit is NOT set */
10582 }
10583
10584 Caching[index+3] = 0x00;
10585 Caching[index+4] = 0x00;
10586 Caching[index+5] = 0x00;
10587 Caching[index+6] = 0x00;
10588 Caching[index+7] = 0x00;
10589 Caching[index+8] = 0x00;
10590 Caching[index+9] = 0x00;
10591 Caching[index+10] = 0x00;
10592 Caching[index+11] = 0x00;
10593 if (pSatDevData->satLookAheadEnabled == agTRUE)
10594 {
10595 Caching[index+12] = 0x00;/* DRA bit is NOT set */
10596 }
10597 else
10598 {
10599 Caching[index+12] = 0x20;/* DRA bit is set */
10600 }
10601 Caching[index+13] = 0x00;
10602 Caching[index+14] = 0x00;
10603 Caching[index+15] = 0x00;
10604 Caching[index+16] = 0x00;
10605 Caching[index+17] = 0x00;
10606 Caching[index+18] = 0x00;
10607 Caching[index+19] = 0x00;
10608 sm_memcpy(pModeSense, &Caching, lenRead);
10609
10610 }
10611 else if (page == MODESENSE_INFORMATION_EXCEPTION_CONTROL_PAGE)
10612 {
10613 SM_DBG5(("smsatModeSense10: MODESENSE_INFORMATION_EXCEPTION_CONTROL_PAGE\n"));
10614 InfoExceptionCtrl[0] = 0;
10615 InfoExceptionCtrl[1] = (bit8)(lenRead - 2);
10616 InfoExceptionCtrl[2] = 0x00; /* medium type: default medium type (currently mounted medium type) */
10617 InfoExceptionCtrl[3] = 0x00; /* device-specific param: no write-protect, no support for DPO-FUA */
10618 if (LLBAA)
10619 {
10620 InfoExceptionCtrl[4] = 0x00; /* reserved and LONGLBA */
10621 InfoExceptionCtrl[4] = (bit8)(InfoExceptionCtrl[4] | 0x1); /* LONGLBA is set */
10622 }
10623 else
10624 {
10625 InfoExceptionCtrl[4] = 0x00; /* reserved and LONGLBA: LONGLBA is not set */
10626 }
10627 InfoExceptionCtrl[5] = 0x00; /* reserved */
10628 InfoExceptionCtrl[6] = 0x00; /* block descriptot length */
10629 if (LLBAA)
10630 {
10631 InfoExceptionCtrl[7] = 0x10; /* block descriptor length: LONGLBA is set. So, length is 16 */
10632 }
10633 else
10634 {
10635 InfoExceptionCtrl[7] = 0x08; /* block descriptor length: LONGLBA is NOT set. So, length is 8 */
10636 }
10637
10638 /*
10639 * Fill-up direct-access device block-descriptor, SAT, Table 19
10640 */
10641
10642 if (LLBAA)
10643 {
10644 /* density code */
10645 InfoExceptionCtrl[8] = 0x04; /* density-code : reserved for direct-access */
10646 /* number of blocks */
10647 InfoExceptionCtrl[9] = 0x00; /* unspecified */
10648 InfoExceptionCtrl[10] = 0x00; /* unspecified */
10649 InfoExceptionCtrl[11] = 0x00; /* unspecified */
10650 InfoExceptionCtrl[12] = 0x00; /* unspecified */
10651 InfoExceptionCtrl[13] = 0x00; /* unspecified */
10652 InfoExceptionCtrl[14] = 0x00; /* unspecified */
10653 InfoExceptionCtrl[15] = 0x00; /* unspecified */
10654 /* reserved */
10655 InfoExceptionCtrl[16] = 0x00; /* reserved */
10656 InfoExceptionCtrl[17] = 0x00; /* reserved */
10657 InfoExceptionCtrl[18] = 0x00; /* reserved */
10658 InfoExceptionCtrl[19] = 0x00; /* reserved */
10659 /* Block size */
10660 InfoExceptionCtrl[20] = 0x00;
10661 InfoExceptionCtrl[21] = 0x00;
10662 InfoExceptionCtrl[22] = 0x02; /* Block size is always 512 bytes */
10663 InfoExceptionCtrl[23] = 0x00;
10664 }
10665 else
10666 {
10667 /* density code */
10668 InfoExceptionCtrl[8] = 0x04; /* density-code : reserved for direct-access */
10669 /* number of blocks */
10670 InfoExceptionCtrl[9] = 0x00; /* unspecified */
10671 InfoExceptionCtrl[10] = 0x00; /* unspecified */
10672 InfoExceptionCtrl[11] = 0x00; /* unspecified */
10673 /* reserved */
10674 InfoExceptionCtrl[12] = 0x00; /* reserved */
10675 /* Block size */
10676 InfoExceptionCtrl[13] = 0x00;
10677 InfoExceptionCtrl[14] = 0x02; /* Block size is always 512 bytes */
10678 InfoExceptionCtrl[15] = 0x00;
10679 }
10680
10681 if (LLBAA)
10682 {
10683 index = 24;
10684 }
10685 else
10686 {
10687 index = 16;
10688 }
10689 /*
10690 * Fill-up informational-exceptions control mode page, SAT, Table 68
10691 */
10692 InfoExceptionCtrl[index+0] = 0x1C; /* page code */
10693 InfoExceptionCtrl[index+1] = 0x0A; /* page length */
10694 if (pSatDevData->satSMARTEnabled == agTRUE)
10695 {
10696 InfoExceptionCtrl[index+2] = 0x00;/* DEXCPT bit is NOT set */
10697 }
10698 else
10699 {
10700 InfoExceptionCtrl[index+2] = 0x08;/* DEXCPT bit is set */
10701 }
10702 InfoExceptionCtrl[index+3] = 0x00; /* We don't support MRIE */
10703 InfoExceptionCtrl[index+4] = 0x00; /* Interval timer vendor-specific */
10704 InfoExceptionCtrl[index+5] = 0x00;
10705 InfoExceptionCtrl[index+6] = 0x00;
10706 InfoExceptionCtrl[index+7] = 0x00;
10707 InfoExceptionCtrl[index+8] = 0x00; /* REPORT-COUNT */
10708 InfoExceptionCtrl[index+9] = 0x00;
10709 InfoExceptionCtrl[index+10] = 0x00;
10710 InfoExceptionCtrl[index+11] = 0x00;
10711 sm_memcpy(pModeSense, &InfoExceptionCtrl, lenRead);
10712
10713 }
10714 else
10715 {
10716 /* Error */
10717 SM_DBG1(("smsatModeSense10: Error page %d!!!\n", page));
10718 smsatSetSensePayload( pSense,
10719 SCSI_SNSKEY_ILLEGAL_REQUEST,
10720 0,
10721 SCSI_SNSCODE_INVALID_COMMAND,
10722 satIOContext);
10723
10724 /*smEnqueueIO(smRoot, satIOContext);*/
10725
10726 tdsmIOCompletedCB( smRoot,
10727 smIORequest,
10728 smIOSuccess,
10729 SCSI_STAT_CHECK_CONDITION,
10730 satIOContext->pSmSenseData,
10731 satIOContext->interruptContext );
10732 return SM_RC_SUCCESS;
10733 }
10734
10735 if (allocationLen > lenRead)
10736 {
10737 SM_DBG1(("smsatModeSense10: reporting underrun lenRead=0x%x allocationLen=0x%x smIORequest=%p\n", lenRead, allocationLen, smIORequest));
10738
10739 /*smEnqueueIO(smRoot, satIOContext);*/
10740
10741 tdsmIOCompletedCB( smRoot,
10742 smIORequest,
10743 smIOUnderRun,
10744 allocationLen - lenRead,
10745 agNULL,
10746 satIOContext->interruptContext );
10747
10748
10749 }
10750 else
10751 {
10752 /*smEnqueueIO(smRoot, satIOContext);*/
10753
10754 tdsmIOCompletedCB( smRoot,
10755 smIORequest,
10756 smIOSuccess,
10757 SCSI_STAT_GOOD,
10758 agNULL,
10759 satIOContext->interruptContext);
10760 }
10761
10762 return SM_RC_SUCCESS;
10763 }
10764
10765 osGLOBAL bit32
smsatReadCapacity10(smRoot_t * smRoot,smIORequest_t * smIORequest,smDeviceHandle_t * smDeviceHandle,smScsiInitiatorRequest_t * smScsiRequest,smSatIOContext_t * satIOContext)10766 smsatReadCapacity10(
10767 smRoot_t *smRoot,
10768 smIORequest_t *smIORequest,
10769 smDeviceHandle_t *smDeviceHandle,
10770 smScsiInitiatorRequest_t *smScsiRequest,
10771 smSatIOContext_t *satIOContext
10772 )
10773 {
10774 smScsiRspSense_t *pSense;
10775 smIniScsiCmnd_t *scsiCmnd;
10776 bit8 dataBuffer[8] = {0};
10777 bit32 allocationLen;
10778 bit8 *pVirtAddr = agNULL;
10779 smDeviceData_t *pSatDevData;
10780 agsaSATAIdentifyData_t *pSATAIdData;
10781 bit32 lastLba;
10782 bit32 word117_118;
10783 bit32 word117;
10784 bit32 word118;
10785
10786 pSense = satIOContext->pSense;
10787 pVirtAddr = (bit8 *) smScsiRequest->sglVirtualAddr;
10788 scsiCmnd = &smScsiRequest->scsiCmnd;
10789 pSatDevData = satIOContext->pSatDevData;
10790 pSATAIdData = &pSatDevData->satIdentifyData;
10791 allocationLen = scsiCmnd->expDataLength;
10792
10793 SM_DBG5(("smsatReadCapacity10: start\n"));
10794
10795 /* checking CONTROL */
10796 /* NACA == 1 or LINK == 1*/
10797 if ( (scsiCmnd->cdb[9] & SCSI_NACA_MASK) || (scsiCmnd->cdb[9] & SCSI_LINK_MASK) )
10798 {
10799 smsatSetSensePayload( pSense,
10800 SCSI_SNSKEY_ILLEGAL_REQUEST,
10801 0,
10802 SCSI_SNSCODE_INVALID_FIELD_IN_CDB,
10803 satIOContext);
10804
10805 /*smEnqueueIO(smRoot, satIOContext);*/
10806
10807 tdsmIOCompletedCB( smRoot,
10808 smIORequest,
10809 smIOSuccess,
10810 SCSI_STAT_CHECK_CONDITION,
10811 satIOContext->pSmSenseData,
10812 satIOContext->interruptContext );
10813
10814 SM_DBG1(("smsatReadCapacity10: return control!!!\n"));
10815 return SM_RC_SUCCESS;
10816 }
10817
10818
10819 /*
10820 * If Logical block address is not set to zero, return error
10821 */
10822 if ((scsiCmnd->cdb[2] || scsiCmnd->cdb[3] || scsiCmnd->cdb[4] || scsiCmnd->cdb[5]))
10823 {
10824 SM_DBG1(("smsatReadCapacity10: *** ERROR *** logical address non zero, did %d!!!\n",
10825 pSatDevData->id));
10826
10827 smsatSetSensePayload( pSense,
10828 SCSI_SNSKEY_ILLEGAL_REQUEST,
10829 0,
10830 SCSI_SNSCODE_INVALID_FIELD_IN_CDB,
10831 satIOContext);
10832
10833 /*smEnqueueIO(smRoot, satIOContext);*/
10834
10835 tdsmIOCompletedCB( smRoot,
10836 smIORequest,
10837 smIOSuccess,
10838 SCSI_STAT_CHECK_CONDITION,
10839 satIOContext->pSmSenseData,
10840 satIOContext->interruptContext );
10841 return SM_RC_SUCCESS;
10842
10843 }
10844
10845 /*
10846 * If PMI bit is not zero, return error
10847 */
10848 if ( ((scsiCmnd->cdb[8]) & SCSI_READ_CAPACITY10_PMI_MASK) != 0 )
10849 {
10850 SM_DBG1(("smsatReadCapacity10: *** ERROR *** PMI is not zero, did %d\n",
10851 pSatDevData->id));
10852
10853 smsatSetSensePayload( pSense,
10854 SCSI_SNSKEY_ILLEGAL_REQUEST,
10855 0,
10856 SCSI_SNSCODE_INVALID_FIELD_IN_CDB,
10857 satIOContext);
10858
10859 /*smEnqueueIO(smRoot, satIOContext);*/
10860
10861 tdsmIOCompletedCB( smRoot,
10862 smIORequest,
10863 smIOSuccess,
10864 SCSI_STAT_CHECK_CONDITION,
10865 satIOContext->pSmSenseData,
10866 satIOContext->interruptContext );
10867 return SM_RC_SUCCESS;
10868
10869 }
10870
10871 /*
10872 filling in Read Capacity parameter data
10873 saved identify device has been already flipped
10874 See ATA spec p125 and p136 and SBC spec p54
10875 */
10876 /*
10877 * If 48-bit addressing is supported, set capacity information from Identify
10878 * Device Word 100-103.
10879 */
10880 if (pSatDevData->sat48BitSupport == agTRUE)
10881 {
10882 /*
10883 * Setting RETURNED LOGICAL BLOCK ADDRESS in READ CAPACITY(10) response data:
10884 * SBC-2 specifies that if the capacity exceeded the 4-byte RETURNED LOGICAL
10885 * BLOCK ADDRESS in READ CAPACITY(10) parameter data, the RETURNED LOGICAL
10886 * BLOCK ADDRESS should be set to 0xFFFFFFFF so the application client would
10887 * then issue a READ CAPACITY(16) command.
10888 */
10889 /* ATA Identify Device information word 100 - 103 */
10890 if ( (pSATAIdData->maxLBA32_47 != 0 ) || (pSATAIdData->maxLBA48_63 != 0))
10891 {
10892 dataBuffer[0] = 0xFF; /* MSB number of block */
10893 dataBuffer[1] = 0xFF;
10894 dataBuffer[2] = 0xFF;
10895 dataBuffer[3] = 0xFF; /* LSB number of block */
10896 SM_DBG1(("smsatReadCapacity10: returns 0xFFFFFFFF!!!\n"));
10897 }
10898 else /* Fit the Readcapacity10 4-bytes response length */
10899 {
10900 lastLba = (((pSATAIdData->maxLBA16_31) << 16) ) |
10901 (pSATAIdData->maxLBA0_15);
10902 lastLba = lastLba - 1; /* LBA starts from zero */
10903
10904 /*
10905 for testing
10906 lastLba = lastLba - (512*10) - 1;
10907 */
10908
10909
10910 dataBuffer[0] = (bit8)((lastLba >> 24) & 0xFF); /* MSB */
10911 dataBuffer[1] = (bit8)((lastLba >> 16) & 0xFF);
10912 dataBuffer[2] = (bit8)((lastLba >> 8) & 0xFF);
10913 dataBuffer[3] = (bit8)((lastLba ) & 0xFF); /* LSB */
10914
10915 SM_DBG3(("smsatReadCapacity10: lastLba is 0x%x %d\n", lastLba, lastLba));
10916 SM_DBG3(("smsatReadCapacity10: LBA 0 is 0x%x %d\n", dataBuffer[0], dataBuffer[0]));
10917 SM_DBG3(("smsatReadCapacity10: LBA 1 is 0x%x %d\n", dataBuffer[1], dataBuffer[1]));
10918 SM_DBG3(("smsatReadCapacity10: LBA 2 is 0x%x %d\n", dataBuffer[2], dataBuffer[2]));
10919 SM_DBG3(("smsatReadCapacity10: LBA 3 is 0x%x %d\n", dataBuffer[3], dataBuffer[3]));
10920
10921 }
10922 }
10923
10924 /*
10925 * For 28-bit addressing, set capacity information from Identify
10926 * Device Word 60-61.
10927 */
10928 else
10929 {
10930 /* ATA Identify Device information word 60 - 61 */
10931 lastLba = (((pSATAIdData->numOfUserAddressableSectorsHi) << 16) ) |
10932 (pSATAIdData->numOfUserAddressableSectorsLo);
10933 lastLba = lastLba - 1; /* LBA starts from zero */
10934
10935 dataBuffer[0] = (bit8)((lastLba >> 24) & 0xFF); /* MSB */
10936 dataBuffer[1] = (bit8)((lastLba >> 16) & 0xFF);
10937 dataBuffer[2] = (bit8)((lastLba >> 8) & 0xFF);
10938 dataBuffer[3] = (bit8)((lastLba ) & 0xFF); /* LSB */
10939 }
10940 /* SAT Rev 8d */
10941 if (((pSATAIdData->word104_107[2]) & 0x1000) == 0)
10942 {
10943 SM_DBG5(("smsatReadCapacity10: Default Block Length is 512\n"));
10944 /*
10945 * Set the block size, fixed at 512 bytes.
10946 */
10947 dataBuffer[4] = 0x00; /* MSB block size in bytes */
10948 dataBuffer[5] = 0x00;
10949 dataBuffer[6] = 0x02;
10950 dataBuffer[7] = 0x00; /* LSB block size in bytes */
10951 }
10952 else
10953 {
10954 word118 = pSATAIdData->word112_126[6];
10955 word117 = pSATAIdData->word112_126[5];
10956
10957 word117_118 = (word118 << 16) + word117;
10958 word117_118 = word117_118 * 2;
10959 dataBuffer[4] = (bit8)((word117_118 >> 24) & 0xFF); /* MSB block size in bytes */
10960 dataBuffer[5] = (bit8)((word117_118 >> 16) & 0xFF);
10961 dataBuffer[6] = (bit8)((word117_118 >> 8) & 0xFF);
10962 dataBuffer[7] = (bit8)(word117_118 & 0xFF); /* LSB block size in bytes */
10963
10964 SM_DBG1(("smsatReadCapacity10: Nondefault word118 %d 0x%x !!!\n", word118, word118));
10965 SM_DBG1(("smsatReadCapacity10: Nondefault word117 %d 0x%x !!!\n", word117, word117));
10966 SM_DBG1(("smsatReadCapacity10: Nondefault Block Length is %d 0x%x !!!\n",word117_118, word117_118));
10967
10968 }
10969
10970 /* fill in MAX LBA, which is used in satSendDiagnostic_1() */
10971 pSatDevData->satMaxLBA[0] = 0; /* MSB */
10972 pSatDevData->satMaxLBA[1] = 0;
10973 pSatDevData->satMaxLBA[2] = 0;
10974 pSatDevData->satMaxLBA[3] = 0;
10975 pSatDevData->satMaxLBA[4] = dataBuffer[0];
10976 pSatDevData->satMaxLBA[5] = dataBuffer[1];
10977 pSatDevData->satMaxLBA[6] = dataBuffer[2];
10978 pSatDevData->satMaxLBA[7] = dataBuffer[3]; /* LSB */
10979
10980
10981 SM_DBG4(("smsatReadCapacity10: 0x%x 0x%x 0x%x 0x%x 0x%x 0x%x 0x%x 0x%x , did %d\n",
10982 dataBuffer[0], dataBuffer[1], dataBuffer[2], dataBuffer[3],
10983 dataBuffer[4], dataBuffer[5], dataBuffer[6], dataBuffer[7],
10984 pSatDevData->id));
10985
10986 sm_memcpy(pVirtAddr, dataBuffer, MIN(allocationLen, 8));
10987
10988 /*
10989 * Send the completion response now.
10990 */
10991 /*smEnqueueIO(smRoot, satIOContext);*/
10992
10993 tdsmIOCompletedCB( smRoot,
10994 smIORequest,
10995 smIOSuccess,
10996 SCSI_STAT_GOOD,
10997 agNULL,
10998 satIOContext->interruptContext);
10999 return SM_RC_SUCCESS;
11000 }
11001
11002 osGLOBAL bit32
smsatReadCapacity16(smRoot_t * smRoot,smIORequest_t * smIORequest,smDeviceHandle_t * smDeviceHandle,smScsiInitiatorRequest_t * smScsiRequest,smSatIOContext_t * satIOContext)11003 smsatReadCapacity16(
11004 smRoot_t *smRoot,
11005 smIORequest_t *smIORequest,
11006 smDeviceHandle_t *smDeviceHandle,
11007 smScsiInitiatorRequest_t *smScsiRequest,
11008 smSatIOContext_t *satIOContext
11009 )
11010 {
11011 smScsiRspSense_t *pSense;
11012 smIniScsiCmnd_t *scsiCmnd;
11013 bit8 dataBuffer[32] = {0};
11014 bit8 *pVirtAddr = agNULL;
11015 smDeviceData_t *pSatDevData;
11016 agsaSATAIdentifyData_t *pSATAIdData;
11017 bit32 lastLbaLo;
11018 bit32 allocationLen;
11019 bit32 readCapacityLen = 32;
11020 bit32 i = 0;
11021
11022 pSense = satIOContext->pSense;
11023 pVirtAddr = (bit8 *) smScsiRequest->sglVirtualAddr;
11024 scsiCmnd = &smScsiRequest->scsiCmnd;
11025 pSatDevData = satIOContext->pSatDevData;
11026 pSATAIdData = &pSatDevData->satIdentifyData;
11027
11028 SM_DBG5(("smsatReadCapacity16: start\n"));
11029
11030 /* Find the buffer size allocated by Initiator */
11031 allocationLen = (((bit32)scsiCmnd->cdb[10]) << 24) |
11032 (((bit32)scsiCmnd->cdb[11]) << 16) |
11033 (((bit32)scsiCmnd->cdb[12]) << 8 ) |
11034 (((bit32)scsiCmnd->cdb[13]) );
11035 allocationLen = MIN(allocationLen, scsiCmnd->expDataLength);
11036
11037 #ifdef REMOVED
11038 if (allocationLen < readCapacityLen)
11039 {
11040 SM_DBG1(("smsatReadCapacity16: *** ERROR *** insufficient len=0x%x readCapacityLen=0x%x!!!\n", allocationLen, readCapacityLen));
11041
11042 smsatSetSensePayload( pSense,
11043 SCSI_SNSKEY_ILLEGAL_REQUEST,
11044 0,
11045 SCSI_SNSCODE_INVALID_FIELD_IN_CDB,
11046 satIOContext);
11047
11048 /*smEnqueueIO(smRoot, satIOContext);*/
11049
11050 tdsmIOCompletedCB( smRoot,
11051 smIORequest,
11052 smIOSuccess,
11053 SCSI_STAT_CHECK_CONDITION,
11054 satIOContext->pSmSenseData,
11055 satIOContext->interruptContext );
11056 return SM_RC_SUCCESS;
11057
11058 }
11059 #endif
11060
11061 /* checking CONTROL */
11062 /* NACA == 1 or LINK == 1*/
11063 if ( (scsiCmnd->cdb[15] & SCSI_NACA_MASK) || (scsiCmnd->cdb[15] & SCSI_LINK_MASK) )
11064 {
11065 smsatSetSensePayload( pSense,
11066 SCSI_SNSKEY_ILLEGAL_REQUEST,
11067 0,
11068 SCSI_SNSCODE_INVALID_FIELD_IN_CDB,
11069 satIOContext);
11070
11071 /*smEnqueueIO(smRoot, satIOContext);*/
11072
11073 tdsmIOCompletedCB( smRoot,
11074 smIORequest,
11075 smIOSuccess,
11076 SCSI_STAT_CHECK_CONDITION,
11077 satIOContext->pSmSenseData,
11078 satIOContext->interruptContext );
11079
11080 SM_DBG1(("smsatReadCapacity16: return control!!!\n"));
11081 return SM_RC_SUCCESS;
11082 }
11083
11084 /*
11085 * If Logical blcok address is not set to zero, return error
11086 */
11087 if ((scsiCmnd->cdb[2] || scsiCmnd->cdb[3] || scsiCmnd->cdb[4] || scsiCmnd->cdb[5]) ||
11088 (scsiCmnd->cdb[6] || scsiCmnd->cdb[7] || scsiCmnd->cdb[8] || scsiCmnd->cdb[9]) )
11089 {
11090 SM_DBG1(("smsatReadCapacity16: *** ERROR *** logical address non zero, did %d\n",
11091 pSatDevData->id));
11092
11093 smsatSetSensePayload( pSense,
11094 SCSI_SNSKEY_ILLEGAL_REQUEST,
11095 0,
11096 SCSI_SNSCODE_INVALID_FIELD_IN_CDB,
11097 satIOContext);
11098
11099 /*smEnqueueIO(smRoot, satIOContext);*/
11100
11101 tdsmIOCompletedCB( smRoot,
11102 smIORequest,
11103 smIOSuccess,
11104 SCSI_STAT_CHECK_CONDITION,
11105 satIOContext->pSmSenseData,
11106 satIOContext->interruptContext );
11107 return SM_RC_SUCCESS;
11108
11109 }
11110
11111 /*
11112 * If PMI bit is not zero, return error
11113 */
11114 if ( ((scsiCmnd->cdb[14]) & SCSI_READ_CAPACITY16_PMI_MASK) != 0 )
11115 {
11116 SM_DBG1(("smsatReadCapacity16: *** ERROR *** PMI is not zero, did %d\n",
11117 pSatDevData->id));
11118
11119 smsatSetSensePayload( pSense,
11120 SCSI_SNSKEY_ILLEGAL_REQUEST,
11121 0,
11122 SCSI_SNSCODE_INVALID_FIELD_IN_CDB,
11123 satIOContext);
11124
11125 /*smEnqueueIO(smRoot, satIOContext);*/
11126
11127 tdsmIOCompletedCB( smRoot,
11128 smIORequest,
11129 smIOSuccess,
11130 SCSI_STAT_CHECK_CONDITION,
11131 satIOContext->pSmSenseData,
11132 satIOContext->interruptContext );
11133 return SM_RC_SUCCESS;
11134
11135 }
11136
11137 /*
11138 filling in Read Capacity parameter data
11139 */
11140
11141 /*
11142 * If 48-bit addressing is supported, set capacity information from Identify
11143 * Device Word 100-103.
11144 */
11145 if (pSatDevData->sat48BitSupport == agTRUE)
11146 {
11147 dataBuffer[0] = (bit8)(((pSATAIdData->maxLBA48_63) >> 8) & 0xff); /* MSB */
11148 dataBuffer[1] = (bit8)((pSATAIdData->maxLBA48_63) & 0xff);
11149 dataBuffer[2] = (bit8)(((pSATAIdData->maxLBA32_47) >> 8) & 0xff);
11150 dataBuffer[3] = (bit8)((pSATAIdData->maxLBA32_47) & 0xff);
11151
11152 lastLbaLo = (((pSATAIdData->maxLBA16_31) << 16) ) | (pSATAIdData->maxLBA0_15);
11153 lastLbaLo = lastLbaLo - 1; /* LBA starts from zero */
11154
11155 dataBuffer[4] = (bit8)((lastLbaLo >> 24) & 0xFF);
11156 dataBuffer[5] = (bit8)((lastLbaLo >> 16) & 0xFF);
11157 dataBuffer[6] = (bit8)((lastLbaLo >> 8) & 0xFF);
11158 dataBuffer[7] = (bit8)((lastLbaLo ) & 0xFF); /* LSB */
11159
11160 }
11161
11162 /*
11163 * For 28-bit addressing, set capacity information from Identify
11164 * Device Word 60-61.
11165 */
11166 else
11167 {
11168 dataBuffer[0] = 0; /* MSB */
11169 dataBuffer[1] = 0;
11170 dataBuffer[2] = 0;
11171 dataBuffer[3] = 0;
11172
11173 lastLbaLo = (((pSATAIdData->numOfUserAddressableSectorsHi) << 16) ) |
11174 (pSATAIdData->numOfUserAddressableSectorsLo);
11175 lastLbaLo = lastLbaLo - 1; /* LBA starts from zero */
11176
11177 dataBuffer[4] = (bit8)((lastLbaLo >> 24) & 0xFF);
11178 dataBuffer[5] = (bit8)((lastLbaLo >> 16) & 0xFF);
11179 dataBuffer[6] = (bit8)((lastLbaLo >> 8) & 0xFF);
11180 dataBuffer[7] = (bit8)((lastLbaLo ) & 0xFF); /* LSB */
11181
11182 }
11183
11184 /*
11185 * Set the block size, fixed at 512 bytes.
11186 */
11187 dataBuffer[8] = 0x00; /* MSB block size in bytes */
11188 dataBuffer[9] = 0x00;
11189 dataBuffer[10] = 0x02;
11190 dataBuffer[11] = 0x00; /* LSB block size in bytes */
11191
11192
11193 /* fill in MAX LBA, which is used in satSendDiagnostic_1() */
11194 pSatDevData->satMaxLBA[0] = dataBuffer[0]; /* MSB */
11195 pSatDevData->satMaxLBA[1] = dataBuffer[1];
11196 pSatDevData->satMaxLBA[2] = dataBuffer[2];
11197 pSatDevData->satMaxLBA[3] = dataBuffer[3];
11198 pSatDevData->satMaxLBA[4] = dataBuffer[4];
11199 pSatDevData->satMaxLBA[5] = dataBuffer[5];
11200 pSatDevData->satMaxLBA[6] = dataBuffer[6];
11201 pSatDevData->satMaxLBA[7] = dataBuffer[7]; /* LSB */
11202
11203 SM_DBG5(("smsatReadCapacity16: 0x%x 0x%x 0x%x 0x%x 0x%x 0x%x 0x%x 0x%x 0x%x 0x%x 0x%x 0x%x , did %d\n",
11204 dataBuffer[0], dataBuffer[1], dataBuffer[2], dataBuffer[3],
11205 dataBuffer[4], dataBuffer[5], dataBuffer[6], dataBuffer[7],
11206 dataBuffer[8], dataBuffer[9], dataBuffer[10], dataBuffer[11],
11207 pSatDevData->id));
11208
11209 if (allocationLen > 0xC) /* 0xc = 12 */
11210 {
11211 for(i=12;i<=31;i++)
11212 {
11213 dataBuffer[i] = 0x00;
11214 }
11215 }
11216
11217 sm_memcpy(pVirtAddr, dataBuffer, MIN(allocationLen, readCapacityLen));
11218 /*
11219 * Send the completion response now.
11220 */
11221 if (allocationLen > readCapacityLen)
11222 {
11223 /* underrun */
11224 SM_DBG1(("smsatReadCapacity16: reporting underrun readCapacityLen=0x%x allocationLen=0x%x !!!\n", readCapacityLen, allocationLen));
11225
11226 /*smEnqueueIO(smRoot, satIOContext);*/
11227
11228 tdsmIOCompletedCB( smRoot,
11229 smIORequest,
11230 smIOUnderRun,
11231 allocationLen - readCapacityLen,
11232 agNULL,
11233 satIOContext->interruptContext );
11234
11235
11236 }
11237 else
11238 {
11239 /*smEnqueueIO(smRoot, satIOContext);*/
11240
11241 tdsmIOCompletedCB( smRoot,
11242 smIORequest,
11243 smIOSuccess,
11244 SCSI_STAT_GOOD,
11245 agNULL,
11246 satIOContext->interruptContext);
11247 }
11248 return SM_RC_SUCCESS;
11249 }
11250
11251 osGLOBAL bit32
smsatReportLun(smRoot_t * smRoot,smIORequest_t * smIORequest,smDeviceHandle_t * smDeviceHandle,smScsiInitiatorRequest_t * smScsiRequest,smSatIOContext_t * satIOContext)11252 smsatReportLun(
11253 smRoot_t *smRoot,
11254 smIORequest_t *smIORequest,
11255 smDeviceHandle_t *smDeviceHandle,
11256 smScsiInitiatorRequest_t *smScsiRequest,
11257 smSatIOContext_t *satIOContext
11258 )
11259 {
11260 smScsiRspSense_t *pSense;
11261 bit8 dataBuffer[16] = {0};
11262 bit32 allocationLen;
11263 bit32 reportLunLen;
11264 smScsiReportLun_t *pReportLun;
11265 smIniScsiCmnd_t *scsiCmnd;
11266 #ifdef TD_DEBUG_ENABLE
11267 smDeviceData_t *pSatDevData;
11268 #endif
11269
11270 pSense = satIOContext->pSense;
11271 pReportLun = (smScsiReportLun_t *) dataBuffer;
11272 scsiCmnd = &smScsiRequest->scsiCmnd;
11273 #ifdef TD_DEBUG_ENABLE
11274 pSatDevData = satIOContext->pSatDevData;
11275 #endif
11276 SM_DBG5(("smsatReportLun: start\n"));
11277 // smhexdump("smsatReportLun: cdb", (bit8 *)scsiCmnd, 16);
11278 /* Find the buffer size allocated by Initiator */
11279 allocationLen = (((bit32)scsiCmnd->cdb[6]) << 24) |
11280 (((bit32)scsiCmnd->cdb[7]) << 16) |
11281 (((bit32)scsiCmnd->cdb[8]) << 8 ) |
11282 (((bit32)scsiCmnd->cdb[9]) );
11283 allocationLen = MIN(allocationLen, scsiCmnd->expDataLength);
11284 reportLunLen = 16; /* 8 byte header and 8 bytes of LUN0 */
11285 if (allocationLen < reportLunLen)
11286 {
11287 SM_DBG1(("smsatReportLun: *** ERROR *** insufficient len=0x%x did %d\n",
11288 reportLunLen, pSatDevData->id));
11289 smsatSetSensePayload( pSense,
11290 SCSI_SNSKEY_ILLEGAL_REQUEST,
11291 0,
11292 SCSI_SNSCODE_INVALID_FIELD_IN_CDB,
11293 satIOContext);
11294 /*smEnqueueIO(smRoot, satIOContext);*/
11295 tdsmIOCompletedCB( smRoot,
11296 smIORequest,
11297 smIOSuccess,
11298 SCSI_STAT_CHECK_CONDITION,
11299 satIOContext->pSmSenseData,
11300 satIOContext->interruptContext );
11301 return SM_RC_SUCCESS;
11302 }
11303 /* Set length to one entry */
11304 pReportLun->len[0] = 0;
11305 pReportLun->len[1] = 0;
11306 pReportLun->len[2] = 0;
11307 pReportLun->len[3] = sizeof (tiLUN_t);
11308 pReportLun->reserved = 0;
11309 /* Set to LUN 0:
11310 * - address method to 0x00: Peripheral device addressing method,
11311 * - bus identifier to 0
11312 */
11313 pReportLun->lunList[0].lun[0] = 0;
11314 pReportLun->lunList[0].lun[1] = 0;
11315 pReportLun->lunList[0].lun[2] = 0;
11316 pReportLun->lunList[0].lun[3] = 0;
11317 pReportLun->lunList[0].lun[4] = 0;
11318 pReportLun->lunList[0].lun[5] = 0;
11319 pReportLun->lunList[0].lun[6] = 0;
11320 pReportLun->lunList[0].lun[7] = 0;
11321
11322 sm_memcpy(smScsiRequest->sglVirtualAddr, dataBuffer, MIN(allocationLen, reportLunLen));
11323 if (allocationLen > reportLunLen)
11324 {
11325 /* underrun */
11326 SM_DBG1(("smsatReportLun: reporting underrun reportLunLen=0x%x allocationLen=0x%x !!!\n", reportLunLen, allocationLen));
11327
11328 /*smEnqueueIO(smRoot, satIOContext);*/
11329
11330 tdsmIOCompletedCB( smRoot,
11331 smIORequest,
11332 smIOUnderRun,
11333 allocationLen - reportLunLen,
11334 agNULL,
11335 satIOContext->interruptContext );
11336
11337
11338 }
11339 else
11340 {
11341 /*smEnqueueIO(smRoot, satIOContext);*/
11342
11343 tdsmIOCompletedCB( smRoot,
11344 smIORequest,
11345 smIOSuccess,
11346 SCSI_STAT_GOOD,
11347 agNULL,
11348 satIOContext->interruptContext);
11349 }
11350 return SM_RC_SUCCESS;
11351 }
11352
11353 osGLOBAL bit32
smsatFormatUnit(smRoot_t * smRoot,smIORequest_t * smIORequest,smDeviceHandle_t * smDeviceHandle,smScsiInitiatorRequest_t * smScsiRequest,smSatIOContext_t * satIOContext)11354 smsatFormatUnit(
11355 smRoot_t *smRoot,
11356 smIORequest_t *smIORequest,
11357 smDeviceHandle_t *smDeviceHandle,
11358 smScsiInitiatorRequest_t *smScsiRequest,
11359 smSatIOContext_t *satIOContext
11360 )
11361 {
11362 /*
11363 note: we don't support media certification in this version and IP bit
11364 satDevData->satFormatState will be agFalse since SAT does not actually sends
11365 any ATA command
11366 */
11367
11368 smScsiRspSense_t *pSense;
11369 smIniScsiCmnd_t *scsiCmnd;
11370 bit32 index = 0;
11371
11372 pSense = satIOContext->pSense;
11373 scsiCmnd = &smScsiRequest->scsiCmnd;
11374 SM_DBG5(("smsatFormatUnit: start\n"));
11375 /*
11376 checking opcode
11377 1. FMTDATA bit == 0(no defect list header)
11378 2. FMTDATA bit == 1 and DCRT bit == 1(defect list header is provided
11379 with DCRT bit set)
11380 */
11381 if ( ((scsiCmnd->cdb[1] & SCSI_FORMAT_UNIT_FMTDATA_MASK) == 0) ||
11382 ((scsiCmnd->cdb[1] & SCSI_FORMAT_UNIT_FMTDATA_MASK) &&
11383 (scsiCmnd->cdb[7] & SCSI_FORMAT_UNIT_DCRT_MASK))
11384 )
11385 {
11386 /*smEnqueueIO(smRoot, satIOContext);*/
11387
11388 tdsmIOCompletedCB( smRoot,
11389 smIORequest,
11390 smIOSuccess,
11391 SCSI_STAT_GOOD,
11392 agNULL,
11393 satIOContext->interruptContext);
11394
11395 SM_DBG1(("smsatFormatUnit: return opcode!!!\n"));
11396 return SM_RC_SUCCESS;
11397 }
11398
11399 /*
11400 checking DEFECT LIST FORMAT and defect list length
11401 */
11402 if ( (((scsiCmnd->cdb[1] & SCSI_FORMAT_UNIT_DEFECT_LIST_FORMAT_MASK) == 0x00) ||
11403 ((scsiCmnd->cdb[1] & SCSI_FORMAT_UNIT_DEFECT_LIST_FORMAT_MASK) == 0x06)) )
11404 {
11405 /* short parameter header */
11406 if ((scsiCmnd->cdb[2] & SCSI_FORMAT_UNIT_LONGLIST_MASK) == 0x00)
11407 {
11408 index = 8;
11409 }
11410 /* long parameter header */
11411 if ((scsiCmnd->cdb[2] & SCSI_FORMAT_UNIT_LONGLIST_MASK) == 0x01)
11412 {
11413 index = 10;
11414 }
11415 /* defect list length */
11416 if ((scsiCmnd->cdb[index] != 0) || (scsiCmnd->cdb[index+1] != 0))
11417 {
11418 smsatSetSensePayload( pSense,
11419 SCSI_SNSKEY_ILLEGAL_REQUEST,
11420 0,
11421 SCSI_SNSCODE_INVALID_FIELD_IN_CDB,
11422 satIOContext);
11423
11424 /*smEnqueueIO(smRoot, satIOContext);*/
11425
11426 tdsmIOCompletedCB( smRoot,
11427 smIORequest,
11428 smIOSuccess,
11429 SCSI_STAT_CHECK_CONDITION,
11430 satIOContext->pSmSenseData,
11431 satIOContext->interruptContext );
11432
11433 SM_DBG1(("smsatFormatUnit: return defect list format!!!\n"));
11434 return SM_RC_SUCCESS;
11435 }
11436 }
11437
11438 if ( (scsiCmnd->cdb[1] & SCSI_FORMAT_UNIT_FMTDATA_MASK) &&
11439 (scsiCmnd->cdb[1] & SCSI_FORMAT_UNIT_CMPLIST_MASK) )
11440 {
11441 smsatSetSensePayload( pSense,
11442 SCSI_SNSKEY_ILLEGAL_REQUEST,
11443 0,
11444 SCSI_SNSCODE_INVALID_FIELD_IN_CDB,
11445 satIOContext);
11446
11447 /*smEnqueueIO(smRoot, satIOContext);*/
11448
11449 tdsmIOCompletedCB( smRoot,
11450 smIORequest,
11451 smIOSuccess,
11452 SCSI_STAT_CHECK_CONDITION,
11453 satIOContext->pSmSenseData,
11454 satIOContext->interruptContext );
11455
11456 SM_DBG1(("smsatFormatUnit: return cmplist!!!\n"));
11457 return SM_RC_SUCCESS;
11458
11459 }
11460
11461 if ( (scsiCmnd->cdb[5] & SCSI_NACA_MASK) || (scsiCmnd->cdb[5] & SCSI_LINK_MASK) )
11462 {
11463 smsatSetSensePayload( pSense,
11464 SCSI_SNSKEY_ILLEGAL_REQUEST,
11465 0,
11466 SCSI_SNSCODE_INVALID_FIELD_IN_CDB,
11467 satIOContext);
11468
11469 /*smEnqueueIO(smRoot, satIOContext);*/
11470
11471 tdsmIOCompletedCB( smRoot,
11472 smIORequest,
11473 smIOSuccess,
11474 SCSI_STAT_CHECK_CONDITION,
11475 satIOContext->pSmSenseData,
11476 satIOContext->interruptContext );
11477
11478 SM_DBG1(("smsatFormatUnit: return control!!!\n"));
11479 return SM_RC_SUCCESS;
11480 }
11481
11482 /* defect list header filed, if exists, SAT rev8, Table 37, p48 */
11483 if (scsiCmnd->cdb[1] & SCSI_FORMAT_UNIT_FMTDATA_MASK)
11484 {
11485 /* case 1,2,3 */
11486 /* IMMED 1; FOV 0; FOV 1, DCRT 1, IP 0 */
11487 if ( (scsiCmnd->cdb[7] & SCSI_FORMAT_UNIT_IMMED_MASK) ||
11488 ( !(scsiCmnd->cdb[7] & SCSI_FORMAT_UNIT_FOV_MASK)) ||
11489 ( (scsiCmnd->cdb[7] & SCSI_FORMAT_UNIT_FOV_MASK) &&
11490 (scsiCmnd->cdb[7] & SCSI_FORMAT_UNIT_DCRT_MASK) &&
11491 !(scsiCmnd->cdb[7] & SCSI_FORMAT_UNIT_IP_MASK))
11492 )
11493 {
11494 /*smEnqueueIO(smRoot, satIOContext);*/
11495
11496 tdsmIOCompletedCB( smRoot,
11497 smIORequest,
11498 smIOSuccess,
11499 SCSI_STAT_GOOD,
11500 agNULL,
11501 satIOContext->interruptContext);
11502
11503 SM_DBG5(("smsatFormatUnit: return defect list case 1\n"));
11504 return SM_RC_SUCCESS;
11505 }
11506 /* case 4,5,6 */
11507 /*
11508 1. IMMED 0, FOV 1, DCRT 0, IP 0
11509 2. IMMED 0, FOV 1, DCRT 0, IP 1
11510 3. IMMED 0, FOV 1, DCRT 1, IP 1
11511 */
11512
11513 if ( ( !(scsiCmnd->cdb[7] & SCSI_FORMAT_UNIT_IMMED_MASK) &&
11514 (scsiCmnd->cdb[7] & SCSI_FORMAT_UNIT_FOV_MASK) &&
11515 !(scsiCmnd->cdb[7] & SCSI_FORMAT_UNIT_DCRT_MASK) &&
11516 !(scsiCmnd->cdb[7] & SCSI_FORMAT_UNIT_IP_MASK) )
11517 ||
11518 ( !(scsiCmnd->cdb[7] & SCSI_FORMAT_UNIT_IMMED_MASK) &&
11519 (scsiCmnd->cdb[7] & SCSI_FORMAT_UNIT_FOV_MASK) &&
11520 !(scsiCmnd->cdb[7] & SCSI_FORMAT_UNIT_DCRT_MASK) &&
11521 (scsiCmnd->cdb[7] & SCSI_FORMAT_UNIT_IP_MASK) )
11522 ||
11523 ( !(scsiCmnd->cdb[7] & SCSI_FORMAT_UNIT_IMMED_MASK) &&
11524 (scsiCmnd->cdb[7] & SCSI_FORMAT_UNIT_FOV_MASK) &&
11525 (scsiCmnd->cdb[7] & SCSI_FORMAT_UNIT_DCRT_MASK) &&
11526 (scsiCmnd->cdb[7] & SCSI_FORMAT_UNIT_IP_MASK) )
11527 )
11528 {
11529
11530 smsatSetSensePayload( pSense,
11531 SCSI_SNSKEY_ILLEGAL_REQUEST,
11532 0,
11533 SCSI_SNSCODE_INVALID_FIELD_PARAMETER_LIST,
11534 satIOContext);
11535
11536 /*smEnqueueIO(smRoot, satIOContext);*/
11537
11538 tdsmIOCompletedCB( smRoot,
11539 smIORequest,
11540 smIOSuccess,
11541 SCSI_STAT_CHECK_CONDITION,
11542 satIOContext->pSmSenseData,
11543 satIOContext->interruptContext );
11544
11545 SM_DBG5(("smsatFormatUnit: return defect list case 2\n"));
11546 return SM_RC_SUCCESS;
11547
11548 }
11549 }
11550
11551
11552 /*
11553 * Send the completion response now.
11554 */
11555 /*smEnqueueIO(smRoot, satIOContext);*/
11556
11557 tdsmIOCompletedCB( smRoot,
11558 smIORequest,
11559 smIOSuccess,
11560 SCSI_STAT_GOOD,
11561 agNULL,
11562 satIOContext->interruptContext);
11563
11564 SM_DBG5(("smsatFormatUnit: return last\n"));
11565 return SM_RC_SUCCESS;
11566 }
11567
11568 osGLOBAL bit32
smsatSendDiagnostic(smRoot_t * smRoot,smIORequest_t * smIORequest,smDeviceHandle_t * smDeviceHandle,smScsiInitiatorRequest_t * smScsiRequest,smSatIOContext_t * satIOContext)11569 smsatSendDiagnostic(
11570 smRoot_t *smRoot,
11571 smIORequest_t *smIORequest,
11572 smDeviceHandle_t *smDeviceHandle,
11573 smScsiInitiatorRequest_t *smScsiRequest,
11574 smSatIOContext_t *satIOContext
11575 )
11576 {
11577 bit32 status;
11578 bit32 agRequestType;
11579 smDeviceData_t *pSatDevData;
11580 smScsiRspSense_t *pSense;
11581 smIniScsiCmnd_t *scsiCmnd;
11582 agsaFisRegHostToDevice_t *fis;
11583 bit32 parmLen;
11584
11585 pSense = satIOContext->pSense;
11586 pSatDevData = satIOContext->pSatDevData;
11587 scsiCmnd = &smScsiRequest->scsiCmnd;
11588 fis = satIOContext->pFis;
11589
11590 SM_DBG5(("smsatSendDiagnostic: start\n"));
11591
11592 /* reset satVerifyState */
11593 pSatDevData->satVerifyState = 0;
11594 /* no pending diagnostic in background */
11595 pSatDevData->satBGPendingDiag = agFALSE;
11596
11597 /* table 27, 8.10 p39 SAT Rev8 */
11598 /*
11599 1. checking PF == 1
11600 2. checking DEVOFFL == 1
11601 3. checking UNITOFFL == 1
11602 4. checking PARAMETER LIST LENGTH != 0
11603
11604 */
11605 if ( (scsiCmnd->cdb[1] & SCSI_PF_MASK) ||
11606 (scsiCmnd->cdb[1] & SCSI_DEVOFFL_MASK) ||
11607 (scsiCmnd->cdb[1] & SCSI_UNITOFFL_MASK) ||
11608 ( (scsiCmnd->cdb[3] != 0) || (scsiCmnd->cdb[4] != 0) )
11609 )
11610 {
11611 smsatSetSensePayload( pSense,
11612 SCSI_SNSKEY_ILLEGAL_REQUEST,
11613 0,
11614 SCSI_SNSCODE_INVALID_FIELD_IN_CDB,
11615 satIOContext);
11616
11617 /*smEnqueueIO(smRoot, satIOContext);*/
11618
11619 tdsmIOCompletedCB( smRoot,
11620 smIORequest,
11621 smIOSuccess,
11622 SCSI_STAT_CHECK_CONDITION,
11623 satIOContext->pSmSenseData,
11624 satIOContext->interruptContext );
11625
11626 SM_DBG1(("smsatSendDiagnostic: return PF, DEVOFFL, UNITOFFL, PARAM LIST!!!\n"));
11627 return SM_RC_SUCCESS;
11628 }
11629
11630 /* checking CONTROL */
11631 /* NACA == 1 or LINK == 1*/
11632 if ( (scsiCmnd->cdb[5] & SCSI_NACA_MASK) || (scsiCmnd->cdb[5] & SCSI_LINK_MASK) )
11633 {
11634 smsatSetSensePayload( pSense,
11635 SCSI_SNSKEY_ILLEGAL_REQUEST,
11636 0,
11637 SCSI_SNSCODE_INVALID_FIELD_IN_CDB,
11638 satIOContext);
11639
11640 /*smEnqueueIO(smRoot, satIOContext);*/
11641
11642 tdsmIOCompletedCB( smRoot,
11643 smIORequest,
11644 smIOSuccess,
11645 SCSI_STAT_CHECK_CONDITION,
11646 satIOContext->pSmSenseData,
11647 satIOContext->interruptContext );
11648
11649 SM_DBG1(("smsatSendDiagnostic: return control!!!\n"));
11650 return SM_RC_SUCCESS;
11651 }
11652
11653 parmLen = (scsiCmnd->cdb[3] << 8) + scsiCmnd->cdb[4];
11654
11655 /* checking SELFTEST bit*/
11656 /* table 29, 8.10.3, p41 SAT Rev8 */
11657 /* case 1 */
11658 if ( !(scsiCmnd->cdb[1] & SCSI_SEND_DIAGNOSTIC_SELFTEST_MASK) &&
11659 (pSatDevData->satSMARTSelfTest == agFALSE)
11660 )
11661 {
11662 smsatSetSensePayload( pSense,
11663 SCSI_SNSKEY_ILLEGAL_REQUEST,
11664 0,
11665 SCSI_SNSCODE_INVALID_FIELD_IN_CDB,
11666 satIOContext);
11667
11668 /*smEnqueueIO(smRoot, satIOContext);*/
11669
11670 tdsmIOCompletedCB( smRoot,
11671 smIORequest,
11672 smIOSuccess,
11673 SCSI_STAT_CHECK_CONDITION,
11674 satIOContext->pSmSenseData,
11675 satIOContext->interruptContext );
11676
11677 SM_DBG1(("smsatSendDiagnostic: return Table 29 case 1!!!\n"));
11678 return SM_RC_SUCCESS;
11679 }
11680
11681 /* case 2 */
11682 if ( !(scsiCmnd->cdb[1] & SCSI_SEND_DIAGNOSTIC_SELFTEST_MASK) &&
11683 (pSatDevData->satSMARTSelfTest == agTRUE) &&
11684 (pSatDevData->satSMARTEnabled == agFALSE)
11685 )
11686 {
11687 smsatSetSensePayload( pSense,
11688 SCSI_SNSKEY_ABORTED_COMMAND,
11689 0,
11690 SCSI_SNSCODE_ATA_DEVICE_FEATURE_NOT_ENABLED,
11691 satIOContext);
11692
11693 /*smEnqueueIO(smRoot, satIOContext);*/
11694
11695 tdsmIOCompletedCB( smRoot,
11696 smIORequest,
11697 smIOSuccess,
11698 SCSI_STAT_CHECK_CONDITION,
11699 satIOContext->pSmSenseData,
11700 satIOContext->interruptContext );
11701
11702 SM_DBG5(("smsatSendDiagnostic: return Table 29 case 2\n"));
11703 return SM_RC_SUCCESS;
11704 }
11705 /*
11706 case 3
11707 see SELF TEST CODE later
11708 */
11709
11710
11711
11712 /* case 4 */
11713
11714 /*
11715 sends three ATA verify commands
11716
11717 */
11718 if ( ((scsiCmnd->cdb[1] & SCSI_SEND_DIAGNOSTIC_SELFTEST_MASK) &&
11719 (pSatDevData->satSMARTSelfTest == agFALSE))
11720 ||
11721 ((scsiCmnd->cdb[1] & SCSI_SEND_DIAGNOSTIC_SELFTEST_MASK) &&
11722 (pSatDevData->satSMARTSelfTest == agTRUE) &&
11723 (pSatDevData->satSMARTEnabled == agFALSE))
11724 )
11725 {
11726 /*
11727 sector count 1, LBA 0
11728 sector count 1, LBA MAX
11729 sector count 1, LBA random
11730 */
11731 if (pSatDevData->sat48BitSupport == agTRUE)
11732 {
11733 /* sends READ VERIFY SECTOR(S) EXT*/
11734 fis->h.fisType = 0x27; /* Reg host to device */
11735 fis->h.c_pmPort = 0x80; /* C Bit is set */
11736 fis->h.command = SAT_READ_VERIFY_SECTORS_EXT;/* 0x42 */
11737 fis->h.features = 0; /* FIS reserve */
11738 fis->d.lbaLow = 0; /* FIS LBA (7 :0 ) */
11739 fis->d.lbaMid = 0; /* FIS LBA (15:8 ) */
11740 fis->d.lbaHigh = 0; /* FIS LBA (23:16) */
11741 fis->d.lbaLowExp = 0; /* FIS LBA (31:24) */
11742 fis->d.lbaMidExp = 0; /* FIS LBA (39:32) */
11743 fis->d.lbaHighExp = 0; /* FIS LBA (47:40) */
11744 fis->d.featuresExp = 0; /* FIS reserve */
11745 fis->d.sectorCount = 1; /* FIS sector count (7:0) */
11746 fis->d.sectorCountExp = 0; /* FIS sector count (15:8) */
11747 fis->d.reserved4 = 0;
11748 fis->d.device = 0x40; /* 01000000 */
11749 fis->d.control = 0; /* FIS HOB bit clear */
11750 fis->d.reserved5 = 0;
11751
11752 agRequestType = AGSA_SATA_PROTOCOL_NON_DATA;
11753 }
11754 else
11755 {
11756 /* READ VERIFY SECTOR(S)*/
11757 fis->h.fisType = 0x27; /* Reg host to device */
11758 fis->h.c_pmPort = 0x80; /* C Bit is set */
11759 fis->h.command = SAT_READ_VERIFY_SECTORS;/* 0x40 */
11760 fis->h.features = 0; /* FIS features NA */
11761 fis->d.lbaLow = 0; /* FIS LBA (7 :0 ) */
11762 fis->d.lbaMid = 0; /* FIS LBA (15:8 ) */
11763 fis->d.lbaHigh = 0; /* FIS LBA (23:16) */
11764 fis->d.lbaLowExp = 0;
11765 fis->d.lbaMidExp = 0;
11766 fis->d.lbaHighExp = 0;
11767 fis->d.featuresExp = 0;
11768 fis->d.sectorCount = 1; /* FIS sector count (7:0) */
11769 fis->d.sectorCountExp = 0;
11770 fis->d.reserved4 = 0;
11771 fis->d.device = 0x40; /* 01000000 */
11772 fis->d.control = 0; /* FIS HOB bit clear */
11773 fis->d.reserved5 = 0;
11774
11775 agRequestType = AGSA_SATA_PROTOCOL_NON_DATA;
11776 }
11777
11778 /* Initialize CB for SATA completion.
11779 */
11780 satIOContext->satCompleteCB = &smsatSendDiagnosticCB;
11781
11782 /*
11783 * Prepare SGL and send FIS to LL layer.
11784 */
11785 satIOContext->reqType = agRequestType; /* Save it */
11786
11787 status = smsataLLIOStart( smRoot,
11788 smIORequest,
11789 smDeviceHandle,
11790 smScsiRequest,
11791 satIOContext);
11792
11793
11794 SM_DBG5(("smsatSendDiagnostic: return Table 29 case 4\n"));
11795 return (status);
11796 }
11797 /* case 5 */
11798 if ( (scsiCmnd->cdb[1] & SCSI_SEND_DIAGNOSTIC_SELFTEST_MASK) &&
11799 (pSatDevData->satSMARTSelfTest == agTRUE) &&
11800 (pSatDevData->satSMARTEnabled == agTRUE)
11801 )
11802 {
11803 /* sends SMART EXECUTE OFF-LINE IMMEDIATE */
11804 fis->h.fisType = 0x27; /* Reg host to device */
11805 fis->h.c_pmPort = 0x80; /* C Bit is set */
11806 fis->h.command = SAT_SMART; /* 0xB0 */
11807 fis->h.features = SAT_SMART_EXEUTE_OFF_LINE_IMMEDIATE; /* FIS features NA */
11808 fis->d.lbaLow = 0x81; /* FIS LBA (7 :0 ) */
11809 fis->d.lbaMid = 0x4F; /* FIS LBA (15:8 ) */
11810 fis->d.lbaHigh = 0xC2; /* FIS LBA (23:16) */
11811 fis->d.lbaLowExp = 0;
11812 fis->d.lbaMidExp = 0;
11813 fis->d.lbaHighExp = 0;
11814 fis->d.featuresExp = 0;
11815 fis->d.sectorCount = 0; /* FIS sector count (7:0) */
11816 fis->d.sectorCountExp = 0;
11817 fis->d.reserved4 = 0;
11818 fis->d.device = 0; /* FIS DEV is discared in SATA */
11819 fis->d.control = 0; /* FIS HOB bit clear */
11820 fis->d.reserved5 = 0;
11821
11822 agRequestType = AGSA_SATA_PROTOCOL_NON_DATA;
11823
11824 /* Initialize CB for SATA completion.
11825 */
11826 satIOContext->satCompleteCB = &smsatSendDiagnosticCB;
11827
11828 /*
11829 * Prepare SGL and send FIS to LL layer.
11830 */
11831 satIOContext->reqType = agRequestType; /* Save it */
11832
11833 status = smsataLLIOStart( smRoot,
11834 smIORequest,
11835 smDeviceHandle,
11836 smScsiRequest,
11837 satIOContext);
11838
11839
11840 SM_DBG5(("smsatSendDiagnostic: return Table 29 case 5\n"));
11841 return (status);
11842 }
11843
11844
11845
11846
11847 /* SAT rev8 Table29 p41 case 3*/
11848 /* checking SELF TEST CODE*/
11849 if ( !(scsiCmnd->cdb[1] & SCSI_SEND_DIAGNOSTIC_SELFTEST_MASK) &&
11850 (pSatDevData->satSMARTSelfTest == agTRUE) &&
11851 (pSatDevData->satSMARTEnabled == agTRUE)
11852 )
11853 {
11854 /* SAT rev8 Table28 p40 */
11855 /* finding self-test code */
11856 switch ((scsiCmnd->cdb[1] & SCSI_SEND_DIAGNOSTIC_TEST_CODE_MASK) >> 5)
11857 {
11858 case 1:
11859 pSatDevData->satBGPendingDiag = agTRUE;
11860
11861 tdsmIOCompletedCB( smRoot,
11862 smIORequest,
11863 smIOSuccess,
11864 SCSI_STAT_GOOD,
11865 agNULL,
11866 satIOContext->interruptContext );
11867 /* sends SMART EXECUTE OFF-LINE IMMEDIATE */
11868 fis->h.fisType = 0x27; /* Reg host to device */
11869 fis->h.c_pmPort = 0x80; /* C Bit is set */
11870 fis->h.command = SAT_SMART; /* 0x40 */
11871 fis->h.features = SAT_SMART_EXEUTE_OFF_LINE_IMMEDIATE; /* FIS features NA */
11872 fis->d.lbaLow = 0x01; /* FIS LBA (7 :0 ) */
11873 fis->d.lbaMid = 0x4F; /* FIS LBA (15:8 ) */
11874 fis->d.lbaHigh = 0xC2; /* FIS LBA (23:16) */
11875
11876 fis->d.lbaLowExp = 0;
11877 fis->d.lbaMidExp = 0;
11878 fis->d.lbaHighExp = 0;
11879 fis->d.featuresExp = 0;
11880 fis->d.sectorCount = 0; /* FIS sector count (7:0) */
11881 fis->d.sectorCountExp = 0;
11882 fis->d.reserved4 = 0;
11883 fis->d.device = 0; /* FIS DEV is discared in SATA */
11884 fis->d.control = 0; /* FIS HOB bit clear */
11885 fis->d.reserved5 = 0;
11886
11887 agRequestType = AGSA_SATA_PROTOCOL_NON_DATA;
11888
11889 /* Initialize CB for SATA completion.
11890 */
11891 satIOContext->satCompleteCB = &smsatSendDiagnosticCB;
11892
11893 /*
11894 * Prepare SGL and send FIS to LL layer.
11895 */
11896 satIOContext->reqType = agRequestType; /* Save it */
11897
11898 status = smsataLLIOStart( smRoot,
11899 smIORequest,
11900 smDeviceHandle,
11901 smScsiRequest,
11902 satIOContext);
11903
11904
11905 SM_DBG5(("smsatSendDiagnostic: return Table 28 case 1\n"));
11906 return (status);
11907 case 2:
11908 pSatDevData->satBGPendingDiag = agTRUE;
11909
11910 tdsmIOCompletedCB( smRoot,
11911 smIORequest,
11912 smIOSuccess,
11913 SCSI_STAT_GOOD,
11914 agNULL,
11915 satIOContext->interruptContext );
11916
11917
11918 /* issuing SMART EXECUTE OFF-LINE IMMEDIATE */
11919 fis->h.fisType = 0x27; /* Reg host to device */
11920 fis->h.c_pmPort = 0x80; /* C Bit is set */
11921 fis->h.command = SAT_SMART; /* 0x40 */
11922 fis->h.features = SAT_SMART_EXEUTE_OFF_LINE_IMMEDIATE; /* FIS features NA */
11923 fis->d.lbaLow = 0x02; /* FIS LBA (7 :0 ) */
11924 fis->d.lbaMid = 0x4F; /* FIS LBA (15:8 ) */
11925 fis->d.lbaHigh = 0xC2; /* FIS LBA (23:16) */
11926 fis->d.lbaLowExp = 0;
11927 fis->d.lbaMidExp = 0;
11928 fis->d.lbaHighExp = 0;
11929 fis->d.featuresExp = 0;
11930 fis->d.sectorCount = 0; /* FIS sector count (7:0) */
11931 fis->d.sectorCountExp = 0;
11932 fis->d.reserved4 = 0;
11933 fis->d.device = 0; /* FIS DEV is discared in SATA */
11934 fis->d.control = 0; /* FIS HOB bit clear */
11935 fis->d.reserved5 = 0;
11936
11937 agRequestType = AGSA_SATA_PROTOCOL_NON_DATA;
11938
11939 /* Initialize CB for SATA completion.
11940 */
11941 satIOContext->satCompleteCB = &smsatSendDiagnosticCB;
11942
11943 /*
11944 * Prepare SGL and send FIS to LL layer.
11945 */
11946 satIOContext->reqType = agRequestType; /* Save it */
11947
11948 status = smsataLLIOStart( smRoot,
11949 smIORequest,
11950 smDeviceHandle,
11951 smScsiRequest,
11952 satIOContext);
11953
11954
11955 SM_DBG5(("smsatSendDiagnostic: return Table 28 case 2\n"));
11956 return (status);
11957 case 4:
11958
11959 if (parmLen != 0)
11960 {
11961 /* check condition */
11962 smsatSetSensePayload( pSense,
11963 SCSI_SNSKEY_ILLEGAL_REQUEST,
11964 0,
11965 SCSI_SNSCODE_INVALID_FIELD_IN_CDB,
11966 satIOContext);
11967
11968 /*smEnqueueIO(smRoot, satIOContext);*/
11969
11970 tdsmIOCompletedCB( smRoot,
11971 smIORequest,
11972 smIOSuccess,
11973 SCSI_STAT_CHECK_CONDITION,
11974 satIOContext->pSmSenseData,
11975 satIOContext->interruptContext );
11976
11977 SM_DBG1(("smsatSendDiagnostic: case 4, non zero ParmLen %d!!!\n", parmLen));
11978 return SM_RC_SUCCESS;
11979 }
11980 if (pSatDevData->satBGPendingDiag == agTRUE)
11981 {
11982 /* sends SMART EXECUTE OFF-LINE IMMEDIATE abort */
11983 fis->h.fisType = 0x27; /* Reg host to device */
11984 fis->h.c_pmPort = 0x80; /* C Bit is set */
11985 fis->h.command = SAT_SMART; /* 0x40 */
11986 fis->h.features = SAT_SMART_EXEUTE_OFF_LINE_IMMEDIATE; /* FIS features NA */
11987 fis->d.lbaLow = 0x7F; /* FIS LBA (7 :0 ) */
11988 fis->d.lbaMid = 0x4F; /* FIS LBA (15:8 ) */
11989 fis->d.lbaHigh = 0xC2; /* FIS LBA (23:16) */
11990
11991 fis->d.lbaLowExp = 0;
11992 fis->d.lbaMidExp = 0;
11993 fis->d.lbaHighExp = 0;
11994 fis->d.featuresExp = 0;
11995 fis->d.sectorCount = 0; /* FIS sector count (7:0) */
11996 fis->d.sectorCountExp = 0;
11997 fis->d.reserved4 = 0;
11998 fis->d.device = 0; /* FIS DEV is discared in SATA */
11999 fis->d.control = 0; /* FIS HOB bit clear */
12000 fis->d.reserved5 = 0;
12001
12002 agRequestType = AGSA_SATA_PROTOCOL_NON_DATA;
12003
12004 /* Initialize CB for SATA completion.
12005 */
12006 satIOContext->satCompleteCB = &smsatSendDiagnosticCB;
12007
12008 /*
12009 * Prepare SGL and send FIS to LL layer.
12010 */
12011 satIOContext->reqType = agRequestType; /* Save it */
12012
12013 status = smsataLLIOStart( smRoot,
12014 smIORequest,
12015 smDeviceHandle,
12016 smScsiRequest,
12017 satIOContext);
12018
12019
12020 SM_DBG5(("smsatSendDiagnostic: send SAT_SMART_EXEUTE_OFF_LINE_IMMEDIATE case 3\n"));
12021 SM_DBG5(("smsatSendDiagnostic: Table 28 case 4\n"));
12022 return (status);
12023 }
12024 else
12025 {
12026 /* check condition */
12027 smsatSetSensePayload( pSense,
12028 SCSI_SNSKEY_ILLEGAL_REQUEST,
12029 0,
12030 SCSI_SNSCODE_INVALID_FIELD_IN_CDB,
12031 satIOContext);
12032
12033 /*smEnqueueIO(smRoot, satIOContext);*/
12034
12035 tdsmIOCompletedCB( smRoot,
12036 smIORequest,
12037 smIOSuccess,
12038 SCSI_STAT_CHECK_CONDITION,
12039 satIOContext->pSmSenseData,
12040 satIOContext->interruptContext );
12041
12042 SM_DBG1(("smsatSendDiagnostic: case 4, no pending diagnostic in background!!!\n"));
12043 SM_DBG5(("smsatSendDiagnostic: Table 28 case 4\n"));
12044 return SM_RC_SUCCESS;
12045 }
12046 break;
12047 case 5:
12048 /* issuing SMART EXECUTE OFF-LINE IMMEDIATE */
12049 fis->h.fisType = 0x27; /* Reg host to device */
12050 fis->h.c_pmPort = 0x80; /* C Bit is set */
12051 fis->h.command = SAT_SMART; /* 0x40 */
12052 fis->h.features = SAT_SMART_EXEUTE_OFF_LINE_IMMEDIATE; /* FIS features NA */
12053 fis->d.lbaLow = 0x81; /* FIS LBA (7 :0 ) */
12054 fis->d.lbaMid = 0x4F; /* FIS LBA (15:8 ) */
12055 fis->d.lbaHigh = 0xC2; /* FIS LBA (23:16) */
12056 fis->d.lbaLowExp = 0;
12057 fis->d.lbaMidExp = 0;
12058 fis->d.lbaHighExp = 0;
12059 fis->d.featuresExp = 0;
12060 fis->d.sectorCount = 0; /* FIS sector count (7:0) */
12061 fis->d.sectorCountExp = 0;
12062 fis->d.reserved4 = 0;
12063 fis->d.device = 0; /* FIS DEV is discared in SATA */
12064 fis->d.control = 0; /* FIS HOB bit clear */
12065 fis->d.reserved5 = 0;
12066
12067 agRequestType = AGSA_SATA_PROTOCOL_NON_DATA;
12068
12069 /* Initialize CB for SATA completion.
12070 */
12071 satIOContext->satCompleteCB = &smsatSendDiagnosticCB;
12072
12073 /*
12074 * Prepare SGL and send FIS to LL layer.
12075 */
12076 satIOContext->reqType = agRequestType; /* Save it */
12077
12078 status = smsataLLIOStart( smRoot,
12079 smIORequest,
12080 smDeviceHandle,
12081 smScsiRequest,
12082 satIOContext);
12083
12084
12085 SM_DBG5(("smsatSendDiagnostic: return Table 28 case 5\n"));
12086 return (status);
12087 case 6:
12088 /* issuing SMART EXECUTE OFF-LINE IMMEDIATE */
12089 fis->h.fisType = 0x27; /* Reg host to device */
12090 fis->h.c_pmPort = 0x80; /* C Bit is set */
12091 fis->h.command = SAT_SMART; /* 0x40 */
12092 fis->h.features = SAT_SMART_EXEUTE_OFF_LINE_IMMEDIATE; /* FIS features NA */
12093 fis->d.lbaLow = 0x82; /* FIS LBA (7 :0 ) */
12094 fis->d.lbaMid = 0x4F; /* FIS LBA (15:8 ) */
12095 fis->d.lbaHigh = 0xC2; /* FIS LBA (23:16) */
12096 fis->d.lbaLowExp = 0;
12097 fis->d.lbaMidExp = 0;
12098 fis->d.lbaHighExp = 0;
12099 fis->d.featuresExp = 0;
12100 fis->d.sectorCount = 0; /* FIS sector count (7:0) */
12101 fis->d.sectorCountExp = 0;
12102 fis->d.reserved4 = 0;
12103 fis->d.device = 0; /* FIS DEV is discared in SATA */
12104 fis->d.control = 0; /* FIS HOB bit clear */
12105 fis->d.reserved5 = 0;
12106
12107 agRequestType = AGSA_SATA_PROTOCOL_NON_DATA;
12108
12109 /* Initialize CB for SATA completion.
12110 */
12111 satIOContext->satCompleteCB = &smsatSendDiagnosticCB;
12112
12113 /*
12114 * Prepare SGL and send FIS to LL layer.
12115 */
12116 satIOContext->reqType = agRequestType; /* Save it */
12117
12118 status = smsataLLIOStart( smRoot,
12119 smIORequest,
12120 smDeviceHandle,
12121 smScsiRequest,
12122 satIOContext);
12123
12124
12125 SM_DBG5(("smsatSendDiagnostic: return Table 28 case 6\n"));
12126 return (status);
12127 case 0:
12128 case 3: /* fall through */
12129 case 7: /* fall through */
12130 default:
12131 break;
12132 }/* switch */
12133
12134 /* returns the results of default self-testing, which is good */
12135 /*smEnqueueIO(smRoot, satIOContext);*/
12136
12137 tdsmIOCompletedCB( smRoot,
12138 smIORequest,
12139 smIOSuccess,
12140 SCSI_STAT_GOOD,
12141 agNULL,
12142 satIOContext->interruptContext );
12143
12144 SM_DBG5(("smsatSendDiagnostic: return Table 28 case 0,3,7 and default\n"));
12145 return SM_RC_SUCCESS;
12146 }
12147
12148
12149 /*smEnqueueIO(smRoot, satIOContext);*/
12150
12151 tdsmIOCompletedCB( smRoot,
12152 smIORequest,
12153 smIOSuccess,
12154 SCSI_STAT_GOOD,
12155 agNULL,
12156 satIOContext->interruptContext );
12157
12158
12159 SM_DBG5(("smsatSendDiagnostic: return last\n"));
12160 return SM_RC_SUCCESS;
12161
12162 }
12163
12164 osGLOBAL bit32
smsatStartStopUnit(smRoot_t * smRoot,smIORequest_t * smIORequest,smDeviceHandle_t * smDeviceHandle,smScsiInitiatorRequest_t * smScsiRequest,smSatIOContext_t * satIOContext)12165 smsatStartStopUnit(
12166 smRoot_t *smRoot,
12167 smIORequest_t *smIORequest,
12168 smDeviceHandle_t *smDeviceHandle,
12169 smScsiInitiatorRequest_t *smScsiRequest,
12170 smSatIOContext_t *satIOContext
12171 )
12172 {
12173 bit32 status;
12174 bit32 agRequestType;
12175 smDeviceData_t *pSatDevData;
12176 smScsiRspSense_t *pSense;
12177 smIniScsiCmnd_t *scsiCmnd;
12178 agsaFisRegHostToDevice_t *fis;
12179
12180 pSense = satIOContext->pSense;
12181 pSatDevData = satIOContext->pSatDevData;
12182 scsiCmnd = &smScsiRequest->scsiCmnd;
12183 fis = satIOContext->pFis;
12184
12185 SM_DBG5(("smsatStartStopUnit: start\n"));
12186
12187 /* checking CONTROL */
12188 /* NACA == 1 or LINK == 1*/
12189 if ( (scsiCmnd->cdb[5] & SCSI_NACA_MASK) || (scsiCmnd->cdb[5] & SCSI_LINK_MASK) )
12190 {
12191 smsatSetSensePayload( pSense,
12192 SCSI_SNSKEY_ILLEGAL_REQUEST,
12193 0,
12194 SCSI_SNSCODE_INVALID_FIELD_IN_CDB,
12195 satIOContext);
12196
12197 /*smEnqueueIO(smRoot, satIOContext);*/
12198
12199 tdsmIOCompletedCB( smRoot,
12200 smIORequest,
12201 smIOSuccess,
12202 SCSI_STAT_CHECK_CONDITION,
12203 satIOContext->pSmSenseData,
12204 satIOContext->interruptContext );
12205
12206 SM_DBG1(("smsatStartStopUnit: return control!!!\n"));
12207 return SM_RC_SUCCESS;
12208 }
12209
12210 /* Spec p55, Table 48 checking START and LOEJ bit */
12211 /* case 1 */
12212 if ( !(scsiCmnd->cdb[4] & SCSI_START_MASK) && !(scsiCmnd->cdb[4] & SCSI_LOEJ_MASK) )
12213 {
12214 if ( (scsiCmnd->cdb[1] & SCSI_IMMED_MASK) )
12215 {
12216 /* immed bit , SAT rev 8, 9.11.2.1 p 54*/
12217 /*smEnqueueIO(smRoot, satIOContext);*/
12218
12219 tdsmIOCompletedCB( smRoot,
12220 smIORequest,
12221 smIOSuccess,
12222 SCSI_STAT_GOOD,
12223 agNULL,
12224 satIOContext->interruptContext );
12225 SM_DBG5(("smsatStartStopUnit: return table48 case 1-1\n"));
12226 return SM_RC_SUCCESS;
12227 }
12228 /* sends FLUSH CACHE or FLUSH CACHE EXT */
12229 if (pSatDevData->sat48BitSupport == agTRUE)
12230 {
12231 /* FLUSH CACHE EXT */
12232 fis->h.fisType = 0x27; /* Reg host to device */
12233 fis->h.c_pmPort = 0x80; /* C Bit is set */
12234
12235 fis->h.command = SAT_FLUSH_CACHE_EXT; /* 0xEA */
12236 fis->h.features = 0; /* FIS reserve */
12237 fis->d.featuresExp = 0; /* FIS reserve */
12238 fis->d.sectorCount = 0; /* FIS sector count (7:0) */
12239 fis->d.sectorCountExp = 0; /* FIS sector count (15:8) */
12240 fis->d.lbaLow = 0; /* FIS LBA (7 :0 ) */
12241 fis->d.lbaLowExp = 0; /* FIS LBA (31:24) */
12242 fis->d.lbaMid = 0; /* FIS LBA (15:8 ) */
12243 fis->d.lbaMidExp = 0; /* FIS LBA (39:32) */
12244 fis->d.lbaHigh = 0; /* FIS LBA (23:16) */
12245 fis->d.lbaHighExp = 0; /* FIS LBA (47:40) */
12246 fis->d.device = 0; /* FIS DEV is discared in SATA */
12247 fis->d.control = 0; /* FIS HOB bit clear */
12248 fis->d.reserved4 = 0;
12249 fis->d.reserved5 = 0;
12250
12251 agRequestType = AGSA_SATA_PROTOCOL_NON_DATA;
12252 }
12253 else
12254 {
12255 /* FLUSH CACHE */
12256 fis->h.fisType = 0x27; /* Reg host to device */
12257 fis->h.c_pmPort = 0x80; /* C Bit is set */
12258
12259 fis->h.command = SAT_FLUSH_CACHE; /* 0xE7 */
12260 fis->h.features = 0; /* FIS features NA */
12261 fis->d.lbaLow = 0; /* FIS LBA (7 :0 ) */
12262 fis->d.lbaMid = 0; /* FIS LBA (15:8 ) */
12263 fis->d.lbaHigh = 0; /* FIS LBA (23:16) */
12264 fis->d.lbaLowExp = 0;
12265 fis->d.lbaMidExp = 0;
12266 fis->d.lbaHighExp = 0;
12267 fis->d.featuresExp = 0;
12268 fis->d.sectorCount = 0; /* FIS sector count (7:0) */
12269 fis->d.sectorCountExp = 0;
12270 fis->d.device = 0; /* FIS DEV is discared in SATA */
12271 fis->d.control = 0; /* FIS HOB bit clear */
12272 fis->d.reserved4 = 0;
12273 fis->d.reserved5 = 0;
12274
12275 agRequestType = AGSA_SATA_PROTOCOL_NON_DATA;
12276 }
12277
12278 /* Initialize CB for SATA completion.
12279 */
12280 satIOContext->satCompleteCB = &smsatStartStopUnitCB;
12281
12282 /*
12283 * Prepare SGL and send FIS to LL layer.
12284 */
12285 satIOContext->reqType = agRequestType; /* Save it */
12286
12287 status = smsataLLIOStart( smRoot,
12288 smIORequest,
12289 smDeviceHandle,
12290 smScsiRequest,
12291 satIOContext);
12292
12293
12294 SM_DBG5(("smsatStartStopUnit: return table48 case 1\n"));
12295 return (status);
12296 }
12297 /* case 2 */
12298 else if ( (scsiCmnd->cdb[4] & SCSI_START_MASK) && !(scsiCmnd->cdb[4] & SCSI_LOEJ_MASK) )
12299 {
12300 /* immed bit , SAT rev 8, 9.11.2.1 p 54*/
12301 if ( (scsiCmnd->cdb[1] & SCSI_IMMED_MASK) )
12302 {
12303 /*smEnqueueIO(smRoot, satIOContext);*/
12304
12305 tdsmIOCompletedCB( smRoot,
12306 smIORequest,
12307 smIOSuccess,
12308 SCSI_STAT_GOOD,
12309 agNULL,
12310 satIOContext->interruptContext );
12311
12312 SM_DBG5(("smsatStartStopUnit: return table48 case 2 1\n"));
12313 return SM_RC_SUCCESS;
12314 }
12315 /*
12316 sends READ_VERIFY_SECTORS(_EXT)
12317 sector count 1, any LBA between zero to Maximum
12318 */
12319 if (pSatDevData->sat48BitSupport == agTRUE)
12320 {
12321 /* READ VERIFY SECTOR(S) EXT*/
12322 fis->h.fisType = 0x27; /* Reg host to device */
12323 fis->h.c_pmPort = 0x80; /* C Bit is set */
12324
12325 fis->h.command = SAT_READ_VERIFY_SECTORS_EXT;/* 0x42 */
12326 fis->h.features = 0; /* FIS reserve */
12327 fis->d.lbaLow = 0x01; /* FIS LBA (7 :0 ) */
12328 fis->d.lbaMid = 0x00; /* FIS LBA (15:8 ) */
12329 fis->d.lbaHigh = 0x00; /* FIS LBA (23:16) */
12330 fis->d.lbaLowExp = 0x00; /* FIS LBA (31:24) */
12331 fis->d.lbaMidExp = 0x00; /* FIS LBA (39:32) */
12332 fis->d.lbaHighExp = 0x00; /* FIS LBA (47:40) */
12333 fis->d.featuresExp = 0; /* FIS reserve */
12334 fis->d.sectorCount = 1; /* FIS sector count (7:0) */
12335 fis->d.sectorCountExp = 0; /* FIS sector count (15:8) */
12336 fis->d.reserved4 = 0;
12337 fis->d.device = 0x40; /* 01000000 */
12338 fis->d.control = 0; /* FIS HOB bit clear */
12339 fis->d.reserved5 = 0;
12340
12341 }
12342 else
12343 {
12344 /* READ VERIFY SECTOR(S)*/
12345 fis->h.fisType = 0x27; /* Reg host to device */
12346 fis->h.c_pmPort = 0x80; /* C Bit is set */
12347
12348 fis->h.command = SAT_READ_VERIFY_SECTORS;/* 0x40 */
12349 fis->h.features = 0; /* FIS features NA */
12350 fis->d.lbaLow = 0x01; /* FIS LBA (7 :0 ) */
12351 fis->d.lbaMid = 0x00; /* FIS LBA (15:8 ) */
12352 fis->d.lbaHigh = 0x00; /* FIS LBA (23:16) */
12353 fis->d.lbaLowExp = 0;
12354 fis->d.lbaMidExp = 0;
12355 fis->d.lbaHighExp = 0;
12356 fis->d.featuresExp = 0;
12357 fis->d.sectorCount = 1; /* FIS sector count (7:0) */
12358 fis->d.sectorCountExp = 0;
12359 fis->d.reserved4 = 0;
12360 fis->d.device = 0x40; /* 01000000 */
12361 fis->d.control = 0; /* FIS HOB bit clear */
12362 fis->d.reserved5 = 0;
12363
12364 }
12365
12366 agRequestType = AGSA_SATA_PROTOCOL_NON_DATA;
12367
12368 /* Initialize CB for SATA completion.
12369 */
12370 satIOContext->satCompleteCB = &smsatStartStopUnitCB;
12371
12372 /*
12373 * Prepare SGL and send FIS to LL layer.
12374 */
12375 satIOContext->reqType = agRequestType; /* Save it */
12376
12377 status = smsataLLIOStart( smRoot,
12378 smIORequest,
12379 smDeviceHandle,
12380 smScsiRequest,
12381 satIOContext);
12382
12383 SM_DBG5(("smsatStartStopUnit: return table48 case 2 2\n"));
12384 return status;
12385 }
12386 /* case 3 */
12387 else if ( !(scsiCmnd->cdb[4] & SCSI_START_MASK) && (scsiCmnd->cdb[4] & SCSI_LOEJ_MASK) )
12388 {
12389 if(pSatDevData->satRemovableMedia && pSatDevData->satRemovableMediaEnabled)
12390 {
12391 /* support for removal media */
12392 /* immed bit , SAT rev 8, 9.11.2.1 p 54*/
12393 if ( (scsiCmnd->cdb[1] & SCSI_IMMED_MASK) )
12394 {
12395 /*smEnqueueIO(smRoot, satIOContext);*/
12396
12397 tdsmIOCompletedCB( smRoot,
12398 smIORequest,
12399 smIOSuccess,
12400 SCSI_STAT_GOOD,
12401 agNULL,
12402 satIOContext->interruptContext );
12403
12404 SM_DBG5(("smsatStartStopUnit: return table48 case 3 1\n"));
12405 return SM_RC_SUCCESS;
12406 }
12407 /*
12408 sends MEDIA EJECT
12409 */
12410 /* Media Eject fis */
12411 fis->h.fisType = 0x27; /* Reg host to device */
12412 fis->h.c_pmPort = 0x80; /* C Bit is set */
12413
12414 fis->h.command = SAT_MEDIA_EJECT; /* 0xED */
12415 fis->h.features = 0; /* FIS features NA */
12416 fis->d.lbaLow = 0; /* FIS LBA (7 :0 ) */
12417 fis->d.lbaMid = 0; /* FIS LBA (15:8 ) */
12418 fis->d.lbaHigh = 0; /* FIS LBA (23:16) */
12419 fis->d.lbaLowExp = 0;
12420 fis->d.lbaMidExp = 0;
12421 fis->d.lbaHighExp = 0;
12422 fis->d.featuresExp = 0;
12423 /* sector count zero */
12424 fis->d.sectorCount = 0; /* FIS sector count (7:0) */
12425 fis->d.sectorCountExp = 0;
12426 fis->d.device = 0; /* FIS DEV is discared in SATA */
12427 fis->d.control = 0; /* FIS HOB bit clear */
12428 fis->d.reserved4 = 0;
12429 fis->d.reserved5 = 0;
12430
12431 agRequestType = AGSA_SATA_PROTOCOL_NON_DATA;
12432
12433 /* Initialize CB for SATA completion.
12434 */
12435 satIOContext->satCompleteCB = &smsatStartStopUnitCB;
12436
12437 /*
12438 * Prepare SGL and send FIS to LL layer.
12439 */
12440 satIOContext->reqType = agRequestType; /* Save it */
12441
12442 status = smsataLLIOStart( smRoot,
12443 smIORequest,
12444 smDeviceHandle,
12445 smScsiRequest,
12446 satIOContext);
12447
12448 return status;
12449 }
12450 else
12451 {
12452 /* no support for removal media */
12453 smsatSetSensePayload( pSense,
12454 SCSI_SNSKEY_ILLEGAL_REQUEST,
12455 0,
12456 SCSI_SNSCODE_INVALID_FIELD_IN_CDB,
12457 satIOContext);
12458
12459 /*smEnqueueIO(smRoot, satIOContext);*/
12460
12461 tdsmIOCompletedCB( smRoot,
12462 smIORequest,
12463 smIOSuccess,
12464 SCSI_STAT_CHECK_CONDITION,
12465 satIOContext->pSmSenseData,
12466 satIOContext->interruptContext );
12467
12468 SM_DBG5(("smsatStartStopUnit: return Table 29 case 3 2\n"));
12469 return SM_RC_SUCCESS;
12470 }
12471
12472 }
12473 /* case 4 */
12474 else /* ( (scsiCmnd->cdb[4] & SCSI_START_MASK) && (scsiCmnd->cdb[4] & SCSI_LOEJ_MASK) ) */
12475 {
12476 smsatSetSensePayload( pSense,
12477 SCSI_SNSKEY_ILLEGAL_REQUEST,
12478 0,
12479 SCSI_SNSCODE_INVALID_FIELD_IN_CDB,
12480 satIOContext);
12481
12482 /*smEnqueueIO(smRoot, satIOContext);*/
12483
12484 tdsmIOCompletedCB( smRoot,
12485 smIORequest,
12486 smIOSuccess,
12487 SCSI_STAT_CHECK_CONDITION,
12488 satIOContext->pSmSenseData,
12489 satIOContext->interruptContext );
12490
12491 SM_DBG5(("smsatStartStopUnit: return Table 29 case 4\n"));
12492 return SM_RC_SUCCESS;
12493 }
12494 }
12495
12496 osGLOBAL bit32
smsatWriteSame10(smRoot_t * smRoot,smIORequest_t * smIORequest,smDeviceHandle_t * smDeviceHandle,smScsiInitiatorRequest_t * smScsiRequest,smSatIOContext_t * satIOContext)12497 smsatWriteSame10(
12498 smRoot_t *smRoot,
12499 smIORequest_t *smIORequest,
12500 smDeviceHandle_t *smDeviceHandle,
12501 smScsiInitiatorRequest_t *smScsiRequest,
12502 smSatIOContext_t *satIOContext
12503 )
12504 {
12505
12506 bit32 status;
12507 bit32 agRequestType = AGSA_SATA_PROTOCOL_DMA_WRITE;
12508 smDeviceData_t *pSatDevData;
12509 smScsiRspSense_t *pSense;
12510 smIniScsiCmnd_t *scsiCmnd;
12511 agsaFisRegHostToDevice_t *fis;
12512 bit32 lba = 0;
12513 bit32 tl = 0;
12514
12515 pSense = satIOContext->pSense;
12516 pSatDevData = satIOContext->pSatDevData;
12517 scsiCmnd = &smScsiRequest->scsiCmnd;
12518 fis = satIOContext->pFis;
12519
12520 SM_DBG5(("smsatWriteSame10: start\n"));
12521
12522 /* checking CONTROL */
12523 /* NACA == 1 or LINK == 1*/
12524 if ( (scsiCmnd->cdb[9] & SCSI_NACA_MASK) || (scsiCmnd->cdb[9] & SCSI_LINK_MASK) )
12525 {
12526 smsatSetSensePayload( pSense,
12527 SCSI_SNSKEY_ILLEGAL_REQUEST,
12528 0,
12529 SCSI_SNSCODE_INVALID_FIELD_IN_CDB,
12530 satIOContext);
12531
12532 /*smEnqueueIO(smRoot, satIOContext);*/
12533
12534 tdsmIOCompletedCB( smRoot,
12535 smIORequest,
12536 smIOSuccess,
12537 SCSI_STAT_CHECK_CONDITION,
12538 satIOContext->pSmSenseData,
12539 satIOContext->interruptContext );
12540
12541 SM_DBG1(("smsatWriteSame10: return control!!!\n"));
12542 return SM_RC_SUCCESS;
12543 }
12544
12545
12546 /* checking LBDATA and PBDATA */
12547 /* case 1 */
12548 if ( !(scsiCmnd->cdb[1] & SCSI_WRITE_SAME_LBDATA_MASK) &&
12549 !(scsiCmnd->cdb[1] & SCSI_WRITE_SAME_PBDATA_MASK))
12550 {
12551 SM_DBG5(("smsatWriteSame10: case 1\n"));
12552 /* spec 9.26.2, Table 62, p64, case 1*/
12553 /*
12554 normal case
12555 just like write in 9.17.1
12556 */
12557
12558 if ( pSatDevData->sat48BitSupport != agTRUE )
12559 {
12560 /*
12561 writeSame10 but no support for 48 bit addressing
12562 -> problem in transfer length. Therefore, return check condition
12563 */
12564 smsatSetSensePayload( pSense,
12565 SCSI_SNSKEY_ILLEGAL_REQUEST,
12566 0,
12567 SCSI_SNSCODE_INVALID_FIELD_IN_CDB,
12568 satIOContext);
12569
12570 /*smEnqueueIO(smRoot, satIOContext);*/
12571
12572 tdsmIOCompletedCB( smRoot,
12573 smIORequest,
12574 smIOSuccess,
12575 SCSI_STAT_CHECK_CONDITION,
12576 satIOContext->pSmSenseData,
12577 satIOContext->interruptContext );
12578
12579 SM_DBG1(("smsatWriteSame10: return internal checking!!!\n"));
12580 return SM_RC_SUCCESS;
12581 }
12582
12583 /* cdb10; computing LBA and transfer length */
12584 lba = (scsiCmnd->cdb[2] << (8*3)) + (scsiCmnd->cdb[3] << (8*2))
12585 + (scsiCmnd->cdb[4] << 8) + scsiCmnd->cdb[5];
12586 tl = (scsiCmnd->cdb[7] << 8) + scsiCmnd->cdb[8];
12587
12588
12589 /* Table 34, 9.1, p 46 */
12590 /*
12591 note: As of 2/10/2006, no support for DMA QUEUED
12592 */
12593
12594 /*
12595 Table 34, 9.1, p 46, b (footnote)
12596 When no 48-bit addressing support or NCQ, if LBA is beyond (2^28 - 1),
12597 return check condition
12598 */
12599 if (pSatDevData->satNCQ != agTRUE &&
12600 pSatDevData->sat48BitSupport != agTRUE
12601 )
12602 {
12603 if (lba > SAT_TR_LBA_LIMIT - 1) /* SAT_TR_LBA_LIMIT is 2^28, 0x10000000 */
12604 {
12605 smsatSetSensePayload( pSense,
12606 SCSI_SNSKEY_ILLEGAL_REQUEST,
12607 0,
12608 SCSI_SNSCODE_LOGICAL_BLOCK_ADDRESS_OUT_OF_RANGE,
12609 satIOContext);
12610
12611 /*smEnqueueIO(smRoot, satIOContext);*/
12612
12613 tdsmIOCompletedCB( smRoot,
12614 smIORequest,
12615 smIOSuccess,
12616 SCSI_STAT_CHECK_CONDITION,
12617 satIOContext->pSmSenseData,
12618 satIOContext->interruptContext );
12619
12620 SM_DBG1(("smsatWriteSame10: return LBA out of range!!!\n"));
12621 return SM_RC_SUCCESS;
12622 }
12623 }
12624
12625
12626 if (lba + tl <= SAT_TR_LBA_LIMIT)
12627 {
12628 if (pSatDevData->satDMASupport == agTRUE && pSatDevData->satDMAEnabled == agTRUE)
12629 {
12630 /* case 2 */
12631 /* WRITE DMA */
12632 /* can't fit the transfer length since WRITE DMA has 1 byte for sector count */
12633 SM_DBG1(("smsatWriteSame10: case 1-2 !!! error due to writesame10!!!\n"));
12634 smsatSetSensePayload( pSense,
12635 SCSI_SNSKEY_ILLEGAL_REQUEST,
12636 0,
12637 SCSI_SNSCODE_INVALID_FIELD_IN_CDB,
12638 satIOContext);
12639
12640 /*smEnqueueIO(smRoot, satIOContext);*/
12641
12642 tdsmIOCompletedCB( smRoot,
12643 smIORequest,
12644 smIOSuccess,
12645 SCSI_STAT_CHECK_CONDITION,
12646 satIOContext->pSmSenseData,
12647 satIOContext->interruptContext );
12648 return SM_RC_SUCCESS;
12649 }
12650 else
12651 {
12652 /* case 1 */
12653 /* WRITE MULTIPLE or WRITE SECTOR(S) */
12654 /* WRITE SECTORS is chosen for easier implemetation */
12655 /* can't fit the transfer length since WRITE DMA has 1 byte for sector count */
12656 SM_DBG1(("smsatWriteSame10: case 1-1 !!! error due to writesame10!!!\n"));
12657 smsatSetSensePayload( pSense,
12658 SCSI_SNSKEY_ILLEGAL_REQUEST,
12659 0,
12660 SCSI_SNSCODE_INVALID_FIELD_IN_CDB,
12661 satIOContext);
12662
12663 /*smEnqueueIO(smRoot, satIOContext);*/
12664
12665 tdsmIOCompletedCB( smRoot,
12666 smIORequest,
12667 smIOSuccess,
12668 SCSI_STAT_CHECK_CONDITION,
12669 satIOContext->pSmSenseData,
12670 satIOContext->interruptContext );
12671 return SM_RC_SUCCESS;
12672 }
12673 } /* end of case 1 and 2 */
12674
12675 /* case 3 and 4 */
12676 if (pSatDevData->sat48BitSupport == agTRUE)
12677 {
12678 if (pSatDevData->satDMASupport == agTRUE && pSatDevData->satDMAEnabled == agTRUE)
12679 {
12680 /* case 3 */
12681 /* WRITE DMA EXT or WRITE DMA FUA EXT */
12682 /* WRITE DMA EXT is chosen since WRITE SAME does not have FUA bit */
12683 SM_DBG5(("smsatWriteSame10: case 1-3\n"));
12684 fis->h.fisType = 0x27; /* Reg host to device */
12685 fis->h.c_pmPort = 0x80; /* C Bit is set */
12686
12687 fis->h.command = SAT_WRITE_DMA_EXT; /* 0x35 */
12688
12689 fis->h.features = 0; /* FIS reserve */
12690 fis->d.lbaLow = scsiCmnd->cdb[5]; /* FIS LBA (7 :0 ) */
12691 fis->d.lbaMid = scsiCmnd->cdb[4]; /* FIS LBA (15:8 ) */
12692 fis->d.lbaHigh = scsiCmnd->cdb[3]; /* FIS LBA (23:16) */
12693 fis->d.device = 0x40; /* FIS LBA mode set */
12694 fis->d.lbaLowExp = scsiCmnd->cdb[2]; /* FIS LBA (31:24) */
12695 fis->d.lbaMidExp = 0; /* FIS LBA (39:32) */
12696 fis->d.lbaHighExp = 0; /* FIS LBA (47:40) */
12697 fis->d.featuresExp = 0; /* FIS reserve */
12698 if (tl == 0)
12699 {
12700 /* error check
12701 ATA spec, p125, 6.17.29
12702 pSatDevData->satMaxUserAddrSectors should be 0x0FFFFFFF
12703 and allowed value is 0x0FFFFFFF - 1
12704 */
12705 if (pSatDevData->satMaxUserAddrSectors > 0x0FFFFFFF)
12706 {
12707 SM_DBG1(("smsatWriteSame10: case 3 !!! warning can't fit sectors!!!\n"));
12708 smsatSetSensePayload( pSense,
12709 SCSI_SNSKEY_ILLEGAL_REQUEST,
12710 0,
12711 SCSI_SNSCODE_INVALID_FIELD_IN_CDB,
12712 satIOContext);
12713
12714 /*smEnqueueIO(smRoot, satIOContext);*/
12715
12716 tdsmIOCompletedCB( smRoot,
12717 smIORequest,
12718 smIOSuccess,
12719 SCSI_STAT_CHECK_CONDITION,
12720 satIOContext->pSmSenseData,
12721 satIOContext->interruptContext );
12722 return SM_RC_SUCCESS;
12723 }
12724 }
12725 /* one sector at a time */
12726 fis->d.sectorCount = 1; /* FIS sector count (7:0) */
12727 fis->d.sectorCountExp = 0; /* FIS sector count (15:8) */
12728 fis->d.reserved4 = 0;
12729 fis->d.control = 0; /* FIS HOB bit clear */
12730 fis->d.reserved5 = 0;
12731
12732 agRequestType = AGSA_SATA_PROTOCOL_DMA_WRITE;
12733 }
12734 else
12735 {
12736 /* case 4 */
12737 /* WRITE MULTIPLE EXT or WRITE MULTIPLE FUA EXT or WRITE SECTOR(S) EXT */
12738 /* WRITE SECTORS EXT is chosen for easier implemetation */
12739 SM_DBG5(("smsatWriteSame10: case 1-4\n"));
12740 fis->h.fisType = 0x27; /* Reg host to device */
12741 fis->h.c_pmPort = 0x80; /* C Bit is set */
12742
12743 fis->h.command = SAT_WRITE_SECTORS_EXT; /* 0x34 */
12744 fis->h.features = 0; /* FIS reserve */
12745 fis->d.lbaLow = scsiCmnd->cdb[5]; /* FIS LBA (7 :0 ) */
12746 fis->d.lbaMid = scsiCmnd->cdb[4]; /* FIS LBA (15:8 ) */
12747 fis->d.lbaHigh = scsiCmnd->cdb[3]; /* FIS LBA (23:16) */
12748 fis->d.device = 0x40; /* FIS LBA mode set */
12749 fis->d.lbaLowExp = scsiCmnd->cdb[2]; /* FIS LBA (31:24) */
12750 fis->d.lbaMidExp = 0; /* FIS LBA (39:32) */
12751 fis->d.lbaHighExp = 0; /* FIS LBA (47:40) */
12752 fis->d.featuresExp = 0; /* FIS reserve */
12753 if (tl == 0)
12754 {
12755 /* error check
12756 ATA spec, p125, 6.17.29
12757 pSatDevData->satMaxUserAddrSectors should be 0x0FFFFFFF
12758 and allowed value is 0x0FFFFFFF - 1
12759 */
12760 if (pSatDevData->satMaxUserAddrSectors > 0x0FFFFFFF)
12761 {
12762 SM_DBG1(("smsatWriteSame10: case 4 !!! warning can't fit sectors!!!\n"));
12763 smsatSetSensePayload( pSense,
12764 SCSI_SNSKEY_ILLEGAL_REQUEST,
12765 0,
12766 SCSI_SNSCODE_INVALID_FIELD_IN_CDB,
12767 satIOContext);
12768
12769 /*smEnqueueIO(smRoot, satIOContext);*/
12770
12771 tdsmIOCompletedCB( smRoot,
12772 smIORequest,
12773 smIOSuccess,
12774 SCSI_STAT_CHECK_CONDITION,
12775 satIOContext->pSmSenseData,
12776 satIOContext->interruptContext );
12777 return SM_RC_SUCCESS;
12778 }
12779 }
12780 /* one sector at a time */
12781 fis->d.sectorCount = 1; /* FIS sector count (7:0) */
12782 fis->d.sectorCountExp = 0; /* FIS sector count (15:8) */
12783 fis->d.reserved4 = 0;
12784 fis->d.control = 0; /* FIS HOB bit clear */
12785 fis->d.reserved5 = 0;
12786
12787 agRequestType = AGSA_SATA_PROTOCOL_PIO_WRITE;
12788 }
12789 }
12790
12791 /* case 5 */
12792 if (pSatDevData->satNCQ == agTRUE)
12793 {
12794 /* WRITE FPDMA QUEUED */
12795 if (pSatDevData->sat48BitSupport != agTRUE)
12796 {
12797 SM_DBG1(("smsatWriteSame10: case 1-5 !!! error NCQ but 28 bit address support!!!\n"));
12798 smsatSetSensePayload( pSense,
12799 SCSI_SNSKEY_ILLEGAL_REQUEST,
12800 0,
12801 SCSI_SNSCODE_INVALID_FIELD_IN_CDB,
12802 satIOContext);
12803
12804 /*smEnqueueIO(smRoot, satIOContext);*/
12805
12806 tdsmIOCompletedCB( smRoot,
12807 smIORequest,
12808 smIOSuccess,
12809 SCSI_STAT_CHECK_CONDITION,
12810 satIOContext->pSmSenseData,
12811 satIOContext->interruptContext );
12812 return SM_RC_SUCCESS;
12813 }
12814 SM_DBG5(("smsatWriteSame10: case 1-5\n"));
12815
12816 /* Support 48-bit FPDMA addressing, use WRITE FPDMA QUEUE command */
12817
12818 fis->h.fisType = 0x27; /* Reg host to device */
12819 fis->h.c_pmPort = 0x80; /* C Bit is set */
12820 fis->h.command = SAT_WRITE_FPDMA_QUEUED; /* 0x61 */
12821
12822 if (tl == 0)
12823 {
12824 /* error check
12825 ATA spec, p125, 6.17.29
12826 pSatDevData->satMaxUserAddrSectors should be 0x0FFFFFFF
12827 and allowed value is 0x0FFFFFFF - 1
12828 */
12829 if (pSatDevData->satMaxUserAddrSectors > 0x0FFFFFFF)
12830 {
12831 SM_DBG1(("smsatWriteSame10: case 4 !!! warning can't fit sectors!!!\n"));
12832 smsatSetSensePayload( pSense,
12833 SCSI_SNSKEY_ILLEGAL_REQUEST,
12834 0,
12835 SCSI_SNSCODE_INVALID_FIELD_IN_CDB,
12836 satIOContext);
12837
12838 /*smEnqueueIO(smRoot, satIOContext);*/
12839
12840 tdsmIOCompletedCB( smRoot,
12841 smIORequest,
12842 smIOSuccess,
12843 SCSI_STAT_CHECK_CONDITION,
12844 satIOContext->pSmSenseData,
12845 satIOContext->interruptContext );
12846 return SM_RC_SUCCESS;
12847 }
12848 }
12849 /* one sector at a time */
12850 fis->h.features = 1; /* FIS sector count (7:0) */
12851 fis->d.featuresExp = 0; /* FIS sector count (15:8) */
12852
12853
12854 fis->d.lbaLow = scsiCmnd->cdb[5]; /* FIS LBA (7 :0 ) */
12855 fis->d.lbaMid = scsiCmnd->cdb[4]; /* FIS LBA (15:8 ) */
12856 fis->d.lbaHigh = scsiCmnd->cdb[3]; /* FIS LBA (23:16) */
12857
12858 /* NO FUA bit in the WRITE SAME 10 */
12859 fis->d.device = 0x40; /* FIS FUA clear */
12860
12861 fis->d.lbaLowExp = scsiCmnd->cdb[2]; /* FIS LBA (31:24) */
12862 fis->d.lbaMidExp = 0; /* FIS LBA (39:32) */
12863 fis->d.lbaHighExp = 0; /* FIS LBA (47:40) */
12864 fis->d.sectorCount = 0; /* Tag (7:3) set by LL layer */
12865 fis->d.sectorCountExp = 0;
12866 fis->d.reserved4 = 0;
12867 fis->d.control = 0; /* FIS HOB bit clear */
12868 fis->d.reserved5 = 0;
12869
12870 agRequestType = AGSA_SATA_PROTOCOL_FPDMA_WRITE;
12871 }
12872 /* Initialize CB for SATA completion.
12873 */
12874 satIOContext->satCompleteCB = &smsatWriteSame10CB;
12875
12876 /*
12877 * Prepare SGL and send FIS to LL layer.
12878 */
12879 satIOContext->reqType = agRequestType; /* Save it */
12880
12881 status = smsataLLIOStart( smRoot,
12882 smIORequest,
12883 smDeviceHandle,
12884 smScsiRequest,
12885 satIOContext);
12886 return (status);
12887
12888
12889 } /* end of case 1 */
12890 else if ( !(scsiCmnd->cdb[1] & SCSI_WRITE_SAME_LBDATA_MASK) &&
12891 (scsiCmnd->cdb[1] & SCSI_WRITE_SAME_PBDATA_MASK))
12892 {
12893 /* spec 9.26.2, Table 62, p64, case 2*/
12894 smsatSetSensePayload( pSense,
12895 SCSI_SNSKEY_ILLEGAL_REQUEST,
12896 0,
12897 SCSI_SNSCODE_INVALID_FIELD_IN_CDB,
12898 satIOContext);
12899
12900 /*smEnqueueIO(smRoot, satIOContext);*/
12901
12902 tdsmIOCompletedCB( smRoot,
12903 smIORequest,
12904 smIOSuccess,
12905 SCSI_STAT_CHECK_CONDITION,
12906 satIOContext->pSmSenseData,
12907 satIOContext->interruptContext );
12908
12909 SM_DBG5(("smsatWriteSame10: return Table 62 case 2\n"));
12910 return SM_RC_SUCCESS;
12911 }
12912 else if ( (scsiCmnd->cdb[1] & SCSI_WRITE_SAME_LBDATA_MASK) &&
12913 !(scsiCmnd->cdb[1] & SCSI_WRITE_SAME_PBDATA_MASK))
12914 {
12915 SM_DBG5(("smsatWriteSame10: Table 62 case 3\n"));
12916
12917 }
12918 else /* ( (scsiCmnd->cdb[1] & SCSI_WRITE_SAME_LBDATA_MASK) &&
12919 (scsiCmnd->cdb[1] & SCSI_WRITE_SAME_PBDATA_MASK)) */
12920 {
12921
12922 /* spec 9.26.2, Table 62, p64, case 4*/
12923 smsatSetSensePayload( pSense,
12924 SCSI_SNSKEY_ILLEGAL_REQUEST,
12925 0,
12926 SCSI_SNSCODE_INVALID_FIELD_IN_CDB,
12927 satIOContext);
12928
12929 /*smEnqueueIO(smRoot, satIOContext);*/
12930
12931 tdsmIOCompletedCB( smRoot,
12932 smIORequest,
12933 smIOSuccess,
12934 SCSI_STAT_CHECK_CONDITION,
12935 satIOContext->pSmSenseData,
12936 satIOContext->interruptContext );
12937
12938 SM_DBG5(("smsatWriteSame10: return Table 62 case 4\n"));
12939 return SM_RC_SUCCESS;
12940 }
12941
12942
12943 return SM_RC_SUCCESS;
12944 }
12945
12946 osGLOBAL bit32
smsatWriteSame16(smRoot_t * smRoot,smIORequest_t * smIORequest,smDeviceHandle_t * smDeviceHandle,smScsiInitiatorRequest_t * smScsiRequest,smSatIOContext_t * satIOContext)12947 smsatWriteSame16(
12948 smRoot_t *smRoot,
12949 smIORequest_t *smIORequest,
12950 smDeviceHandle_t *smDeviceHandle,
12951 smScsiInitiatorRequest_t *smScsiRequest,
12952 smSatIOContext_t *satIOContext
12953 )
12954 {
12955 smScsiRspSense_t *pSense;
12956
12957 pSense = satIOContext->pSense;
12958
12959 SM_DBG5(("smsatWriteSame16: start\n"));
12960
12961
12962 smsatSetSensePayload( pSense,
12963 SCSI_SNSKEY_NO_SENSE,
12964 0,
12965 SCSI_SNSCODE_NO_ADDITIONAL_INFO,
12966 satIOContext);
12967
12968 /*smEnqueueIO(smRoot, satIOContext);*/
12969
12970 tdsmIOCompletedCB( smRoot,
12971 smIORequest, /* == &satIntIo->satOrgSmIORequest */
12972 smIOSuccess,
12973 SCSI_STAT_CHECK_CONDITION,
12974 satIOContext->pSmSenseData,
12975 satIOContext->interruptContext );
12976 SM_DBG1(("smsatWriteSame16: return internal checking!!!\n"));
12977 return SM_RC_SUCCESS;
12978 }
12979
12980 osGLOBAL bit32
smsatLogSense(smRoot_t * smRoot,smIORequest_t * smIORequest,smDeviceHandle_t * smDeviceHandle,smScsiInitiatorRequest_t * smScsiRequest,smSatIOContext_t * satIOContext)12981 smsatLogSense(
12982 smRoot_t *smRoot,
12983 smIORequest_t *smIORequest,
12984 smDeviceHandle_t *smDeviceHandle,
12985 smScsiInitiatorRequest_t *smScsiRequest,
12986 smSatIOContext_t *satIOContext
12987 )
12988 {
12989 bit32 status;
12990 bit32 agRequestType;
12991 smDeviceData_t *pSatDevData;
12992 smScsiRspSense_t *pSense;
12993 smIniScsiCmnd_t *scsiCmnd;
12994 agsaFisRegHostToDevice_t *fis;
12995 bit8 *pLogPage; /* Log Page data buffer */
12996 bit32 flag = 0;
12997 bit16 AllocLen = 0; /* allocation length */
12998 bit8 AllLogPages[8];
12999 bit16 lenRead = 0;
13000
13001 pSense = satIOContext->pSense;
13002 pSatDevData = satIOContext->pSatDevData;
13003 scsiCmnd = &smScsiRequest->scsiCmnd;
13004 fis = satIOContext->pFis;
13005 pLogPage = (bit8 *) smScsiRequest->sglVirtualAddr;
13006
13007 SM_DBG5(("smsatLogSense: start\n"));
13008
13009 sm_memset(&AllLogPages, 0, 8);
13010 /* checking CONTROL */
13011 /* NACA == 1 or LINK == 1*/
13012 if ( (scsiCmnd->cdb[9] & SCSI_NACA_MASK) || (scsiCmnd->cdb[9] & SCSI_LINK_MASK) )
13013 {
13014 smsatSetSensePayload( pSense,
13015 SCSI_SNSKEY_ILLEGAL_REQUEST,
13016 0,
13017 SCSI_SNSCODE_INVALID_FIELD_IN_CDB,
13018 satIOContext);
13019
13020 /*smEnqueueIO(smRoot, satIOContext);*/
13021
13022 tdsmIOCompletedCB( smRoot,
13023 smIORequest,
13024 smIOSuccess,
13025 SCSI_STAT_CHECK_CONDITION,
13026 satIOContext->pSmSenseData,
13027 satIOContext->interruptContext );
13028
13029 SM_DBG1(("smsatLogSense: return control!!!\n"));
13030 return SM_RC_SUCCESS;
13031 }
13032
13033
13034 AllocLen = ((scsiCmnd->cdb[7] << 8) + scsiCmnd->cdb[8]);
13035 AllocLen = MIN(AllocLen, scsiCmnd->expDataLength);
13036
13037 /* checking PC (Page Control) */
13038 /* nothing */
13039
13040 /* special cases */
13041 if (AllocLen == 4)
13042 {
13043 SM_DBG1(("smsatLogSense: AllocLen is 4!!!\n"));
13044 switch (scsiCmnd->cdb[2] & SCSI_LOG_SENSE_PAGE_CODE_MASK)
13045 {
13046 case LOGSENSE_SUPPORTED_LOG_PAGES:
13047 SM_DBG5(("smsatLogSense: case LOGSENSE_SUPPORTED_LOG_PAGES\n"));
13048
13049 if (pSatDevData->satSMARTFeatureSet == agTRUE)
13050 {
13051 /* add informational exception log */
13052 flag = 1;
13053 if (pSatDevData->satSMARTSelfTest == agTRUE)
13054 {
13055 /* add Self-Test results log page */
13056 flag = 2;
13057 }
13058 }
13059 else
13060 {
13061 /* only supported, no informational exception log, no Self-Test results log page */
13062 flag = 0;
13063 }
13064 lenRead = 4;
13065 AllLogPages[0] = LOGSENSE_SUPPORTED_LOG_PAGES; /* page code */
13066 AllLogPages[1] = 0; /* reserved */
13067 switch (flag)
13068 {
13069 case 0:
13070 /* only supported */
13071 AllLogPages[2] = 0; /* page length */
13072 AllLogPages[3] = 1; /* page length */
13073 break;
13074 case 1:
13075 /* supported and informational exception log */
13076 AllLogPages[2] = 0; /* page length */
13077 AllLogPages[3] = 2; /* page length */
13078 break;
13079 case 2:
13080 /* supported and informational exception log */
13081 AllLogPages[2] = 0; /* page length */
13082 AllLogPages[3] = 3; /* page length */
13083 break;
13084 default:
13085 SM_DBG1(("smsatLogSense: error unallowed flag value %d!!!\n", flag));
13086 break;
13087 }
13088 sm_memcpy(pLogPage, &AllLogPages, lenRead);
13089 break;
13090 case LOGSENSE_SELFTEST_RESULTS_PAGE:
13091 SM_DBG5(("smsatLogSense: case LOGSENSE_SUPPORTED_LOG_PAGES\n"));
13092 lenRead = 4;
13093 AllLogPages[0] = LOGSENSE_SELFTEST_RESULTS_PAGE; /* page code */
13094 AllLogPages[1] = 0; /* reserved */
13095 /* page length = SELFTEST_RESULTS_LOG_PAGE_LENGTH - 1 - 3 = 400 = 0x190 */
13096 AllLogPages[2] = 0x01;
13097 AllLogPages[3] = 0x90; /* page length */
13098 sm_memcpy(pLogPage, &AllLogPages, lenRead);
13099
13100 break;
13101 case LOGSENSE_INFORMATION_EXCEPTIONS_PAGE:
13102 SM_DBG5(("smsatLogSense: case LOGSENSE_SUPPORTED_LOG_PAGES\n"));
13103 lenRead = 4;
13104 AllLogPages[0] = LOGSENSE_INFORMATION_EXCEPTIONS_PAGE; /* page code */
13105 AllLogPages[1] = 0; /* reserved */
13106 AllLogPages[2] = 0; /* page length */
13107 AllLogPages[3] = INFORMATION_EXCEPTIONS_LOG_PAGE_LENGTH - 1 - 3; /* page length */
13108 sm_memcpy(pLogPage, &AllLogPages, lenRead);
13109 break;
13110 default:
13111 SM_DBG1(("smsatLogSense: default Page Code 0x%x!!!\n", scsiCmnd->cdb[2] & SCSI_LOG_SENSE_PAGE_CODE_MASK));
13112 smsatSetSensePayload( pSense,
13113 SCSI_SNSKEY_ILLEGAL_REQUEST,
13114 0,
13115 SCSI_SNSCODE_INVALID_FIELD_IN_CDB,
13116 satIOContext);
13117
13118 /*smEnqueueIO(smRoot, satIOContext);*/
13119
13120 tdsmIOCompletedCB( smRoot,
13121 smIORequest,
13122 smIOSuccess,
13123 SCSI_STAT_CHECK_CONDITION,
13124 satIOContext->pSmSenseData,
13125 satIOContext->interruptContext );
13126 return SM_RC_SUCCESS;
13127 }
13128 /*smEnqueueIO(smRoot, satIOContext);*/
13129
13130 tdsmIOCompletedCB( smRoot,
13131 smIORequest,
13132 smIOSuccess,
13133 SCSI_STAT_GOOD,
13134 agNULL,
13135 satIOContext->interruptContext);
13136 return SM_RC_SUCCESS;
13137
13138 } /* if */
13139
13140 /* SAT rev8 Table 11 p30*/
13141 /* checking Page Code */
13142 switch (scsiCmnd->cdb[2] & SCSI_LOG_SENSE_PAGE_CODE_MASK)
13143 {
13144 case LOGSENSE_SUPPORTED_LOG_PAGES:
13145 SM_DBG5(("smsatLogSense: case 1\n"));
13146
13147 if (pSatDevData->satSMARTFeatureSet == agTRUE)
13148 {
13149 /* add informational exception log */
13150 flag = 1;
13151 if (pSatDevData->satSMARTSelfTest == agTRUE)
13152 {
13153 /* add Self-Test results log page */
13154 flag = 2;
13155 }
13156 }
13157 else
13158 {
13159 /* only supported, no informational exception log, no Self-Test results log page */
13160 flag = 0;
13161 }
13162 AllLogPages[0] = 0; /* page code */
13163 AllLogPages[1] = 0; /* reserved */
13164 switch (flag)
13165 {
13166 case 0:
13167 /* only supported */
13168 AllLogPages[2] = 0; /* page length */
13169 AllLogPages[3] = 1; /* page length */
13170 AllLogPages[4] = 0x00; /* supported page list */
13171 lenRead = (bit8)(MIN(AllocLen, 5));
13172 break;
13173 case 1:
13174 /* supported and informational exception log */
13175 AllLogPages[2] = 0; /* page length */
13176 AllLogPages[3] = 2; /* page length */
13177 AllLogPages[4] = 0x00; /* supported page list */
13178 AllLogPages[5] = 0x10; /* supported page list */
13179 lenRead = (bit8)(MIN(AllocLen, 6));
13180 break;
13181 case 2:
13182 /* supported and informational exception log */
13183 AllLogPages[2] = 0; /* page length */
13184 AllLogPages[3] = 3; /* page length */
13185 AllLogPages[4] = 0x00; /* supported page list */
13186 AllLogPages[5] = 0x10; /* supported page list */
13187 AllLogPages[6] = 0x2F; /* supported page list */
13188 lenRead = (bit8)(MIN(AllocLen, 7));
13189 break;
13190 default:
13191 SM_DBG1(("smsatLogSense: error unallowed flag value %d!!!\n", flag));
13192 break;
13193 }
13194
13195 sm_memcpy(pLogPage, &AllLogPages, lenRead);
13196 /* comparing allocation length to Log Page byte size */
13197 /* SPC-4, 4.3.4.6, p28 */
13198 if (AllocLen > lenRead )
13199 {
13200 SM_DBG1(("smsatLogSense: reporting underrun lenRead=0x%x AllocLen=0x%x!!!\n", lenRead, AllocLen));
13201 /*smEnqueueIO(smRoot, satIOContext);*/
13202
13203 tdsmIOCompletedCB( smRoot,
13204 smIORequest,
13205 smIOUnderRun,
13206 AllocLen - lenRead,
13207 agNULL,
13208 satIOContext->interruptContext );
13209 }
13210 else
13211 {
13212 /*smEnqueueIO(smRoot, satIOContext);*/
13213 tdsmIOCompletedCB( smRoot,
13214 smIORequest,
13215 smIOSuccess,
13216 SCSI_STAT_GOOD,
13217 agNULL,
13218 satIOContext->interruptContext);
13219 }
13220 break;
13221 case LOGSENSE_SELFTEST_RESULTS_PAGE:
13222 SM_DBG5(("smsatLogSense: case 2\n"));
13223 /* checking SMART self-test */
13224 if (pSatDevData->satSMARTSelfTest == agFALSE)
13225 {
13226 SM_DBG5(("smsatLogSense: case 2 no SMART Self Test\n"));
13227 smsatSetSensePayload( pSense,
13228 SCSI_SNSKEY_ILLEGAL_REQUEST,
13229 0,
13230 SCSI_SNSCODE_INVALID_FIELD_IN_CDB,
13231 satIOContext);
13232
13233 /*smEnqueueIO(smRoot, satIOContext);*/
13234
13235 tdsmIOCompletedCB( smRoot,
13236 smIORequest,
13237 smIOSuccess,
13238 SCSI_STAT_CHECK_CONDITION,
13239 satIOContext->pSmSenseData,
13240 satIOContext->interruptContext );
13241 }
13242 else
13243 {
13244 /* if satSMARTEnabled is false, send SMART_ENABLE_OPERATIONS */
13245 if (pSatDevData->satSMARTEnabled == agFALSE)
13246 {
13247 SM_DBG5(("smsatLogSense: case 2 calling satSMARTEnable\n"));
13248 status = smsatLogSenseAllocate(smRoot,
13249 smIORequest,
13250 smDeviceHandle,
13251 smScsiRequest,
13252 satIOContext,
13253 0,
13254 LOG_SENSE_0
13255 );
13256
13257 return status;
13258
13259 }
13260 else
13261 {
13262 /* SAT Rev 8, 10.2.4 p74 */
13263 if ( pSatDevData->sat48BitSupport == agTRUE )
13264 {
13265 SM_DBG5(("smsatLogSense: case 2-1 sends READ LOG EXT\n"));
13266 status = smsatLogSenseAllocate(smRoot,
13267 smIORequest,
13268 smDeviceHandle,
13269 smScsiRequest,
13270 satIOContext,
13271 512,
13272 LOG_SENSE_1
13273 );
13274
13275 return status;
13276 }
13277 else
13278 {
13279 SM_DBG5(("smsatLogSense: case 2-2 sends SMART READ LOG\n"));
13280 status = smsatLogSenseAllocate(smRoot,
13281 smIORequest,
13282 smDeviceHandle,
13283 smScsiRequest,
13284 satIOContext,
13285 512,
13286 LOG_SENSE_2
13287 );
13288
13289 return status;
13290 }
13291 }
13292 }
13293 break;
13294 case LOGSENSE_INFORMATION_EXCEPTIONS_PAGE:
13295 SM_DBG5(("smsatLogSense: case 3\n"));
13296 /* checking SMART feature set */
13297 if (pSatDevData->satSMARTFeatureSet == agFALSE)
13298 {
13299 smsatSetSensePayload( pSense,
13300 SCSI_SNSKEY_ILLEGAL_REQUEST,
13301 0,
13302 SCSI_SNSCODE_INVALID_FIELD_IN_CDB,
13303 satIOContext);
13304
13305 /*smEnqueueIO(smRoot, satIOContext);*/
13306
13307 tdsmIOCompletedCB( smRoot,
13308 smIORequest,
13309 smIOSuccess,
13310 SCSI_STAT_CHECK_CONDITION,
13311 satIOContext->pSmSenseData,
13312 satIOContext->interruptContext );
13313 }
13314 else
13315 {
13316 /* checking SMART feature enabled */
13317 if (pSatDevData->satSMARTEnabled == agFALSE)
13318 {
13319 smsatSetSensePayload( pSense,
13320 SCSI_SNSKEY_ABORTED_COMMAND,
13321 0,
13322 SCSI_SNSCODE_ATA_DEVICE_FEATURE_NOT_ENABLED,
13323 satIOContext);
13324
13325 /*smEnqueueIO(smRoot, satIOContext);*/
13326
13327 tdsmIOCompletedCB( smRoot,
13328 smIORequest,
13329 smIOSuccess,
13330 SCSI_STAT_CHECK_CONDITION,
13331 satIOContext->pSmSenseData,
13332 satIOContext->interruptContext );
13333 }
13334 else
13335 {
13336 /* SAT Rev 8, 10.2.3 p72 */
13337 SM_DBG5(("smsatLogSense: case 3 sends SMART RETURN STATUS\n"));
13338
13339 /* sends SMART RETURN STATUS */
13340 fis->h.fisType = 0x27; /* Reg host to device */
13341 fis->h.c_pmPort = 0x80; /* C Bit is set */
13342
13343 fis->h.command = SAT_SMART; /* 0xB0 */
13344 fis->h.features = SAT_SMART_RETURN_STATUS;/* FIS features */
13345 fis->d.featuresExp = 0; /* FIS reserve */
13346 fis->d.sectorCount = 0; /* FIS sector count (7:0) */
13347 fis->d.sectorCountExp = 0; /* FIS sector count (15:8) */
13348 fis->d.lbaLow = 0; /* FIS LBA (7 :0 ) */
13349 fis->d.lbaLowExp = 0; /* FIS LBA (31:24) */
13350 fis->d.lbaMid = 0x4F; /* FIS LBA (15:8 ) */
13351 fis->d.lbaMidExp = 0; /* FIS LBA (39:32) */
13352 fis->d.lbaHigh = 0xC2; /* FIS LBA (23:16) */
13353 fis->d.lbaHighExp = 0; /* FIS LBA (47:40) */
13354 fis->d.device = 0; /* FIS DEV is discared in SATA */
13355 fis->d.control = 0; /* FIS HOB bit clear */
13356 fis->d.reserved4 = 0;
13357 fis->d.reserved5 = 0;
13358
13359 agRequestType = AGSA_SATA_PROTOCOL_NON_DATA;
13360 /* Initialize CB for SATA completion.
13361 */
13362 satIOContext->satCompleteCB = &smsatLogSenseCB;
13363
13364 /*
13365 * Prepare SGL and send FIS to LL layer.
13366 */
13367 satIOContext->reqType = agRequestType; /* Save it */
13368
13369 status = smsataLLIOStart( smRoot,
13370 smIORequest,
13371 smDeviceHandle,
13372 smScsiRequest,
13373 satIOContext);
13374
13375
13376 return status;
13377 }
13378 }
13379 break;
13380 default:
13381 SM_DBG1(("smsatLogSense: default Page Code 0x%x!!!\n", scsiCmnd->cdb[2] & SCSI_LOG_SENSE_PAGE_CODE_MASK));
13382 smsatSetSensePayload( pSense,
13383 SCSI_SNSKEY_ILLEGAL_REQUEST,
13384 0,
13385 SCSI_SNSCODE_INVALID_FIELD_IN_CDB,
13386 satIOContext);
13387
13388 /*smEnqueueIO(smRoot, satIOContext);*/
13389
13390 tdsmIOCompletedCB( smRoot,
13391 smIORequest,
13392 smIOSuccess,
13393 SCSI_STAT_CHECK_CONDITION,
13394 satIOContext->pSmSenseData,
13395 satIOContext->interruptContext );
13396
13397 break;
13398 } /* end switch */
13399
13400 return SM_RC_SUCCESS;
13401 }
13402
13403 osGLOBAL bit32
smsatLogSenseAllocate(smRoot_t * smRoot,smIORequest_t * smIORequest,smDeviceHandle_t * smDeviceHandle,smScsiInitiatorRequest_t * smSCSIRequest,smSatIOContext_t * satIOContext,bit32 payloadSize,bit32 flag)13404 smsatLogSenseAllocate(
13405 smRoot_t *smRoot,
13406 smIORequest_t *smIORequest,
13407 smDeviceHandle_t *smDeviceHandle,
13408 smScsiInitiatorRequest_t *smSCSIRequest,
13409 smSatIOContext_t *satIOContext,
13410 bit32 payloadSize,
13411 bit32 flag
13412 )
13413 {
13414 smDeviceData_t *pSatDevData;
13415 smIORequestBody_t *smIORequestBody;
13416 smSatInternalIo_t *satIntIo = agNULL;
13417 smSatIOContext_t *satIOContext2;
13418 bit32 status;
13419
13420 SM_DBG5(("smsatLogSenseAllocate: start\n"));
13421
13422 pSatDevData = satIOContext->pSatDevData;
13423
13424 /* create internal satIOContext */
13425 satIntIo = smsatAllocIntIoResource( smRoot,
13426 smIORequest, /* original request */
13427 pSatDevData,
13428 payloadSize,
13429 satIntIo);
13430
13431 if (satIntIo == agNULL)
13432 {
13433 /*smEnqueueIO(smRoot, satIOContext);*/
13434
13435 tdsmIOCompletedCB( smRoot,
13436 smIORequest,
13437 smIOFailed,
13438 smDetailOtherError,
13439 agNULL,
13440 satIOContext->interruptContext );
13441
13442 SM_DBG1(("smsatLogSenseAllocate: fail in allocation!!!\n"));
13443 return SM_RC_SUCCESS;
13444 } /* end of memory allocation failure */
13445
13446 satIntIo->satOrgSmIORequest = smIORequest;
13447 smIORequestBody = (smIORequestBody_t *)satIntIo->satIntRequestBody;
13448 satIOContext2 = &(smIORequestBody->transport.SATA.satIOContext);
13449
13450 satIOContext2->pSatDevData = pSatDevData;
13451 satIOContext2->pFis = &(smIORequestBody->transport.SATA.agSATARequestBody.fis.fisRegHostToDev);
13452 satIOContext2->pScsiCmnd = &(satIntIo->satIntSmScsiXchg.scsiCmnd);
13453 satIOContext2->pSense = &(smIORequestBody->transport.SATA.sensePayload);
13454 satIOContext2->pSmSenseData = &(smIORequestBody->transport.SATA.smSenseData);
13455 satIOContext2->pSmSenseData->senseData = satIOContext2->pSense;
13456 satIOContext2->smRequestBody = satIntIo->satIntRequestBody;
13457 satIOContext2->interruptContext = satIOContext->interruptContext;
13458 satIOContext2->satIntIoContext = satIntIo;
13459 satIOContext2->psmDeviceHandle = smDeviceHandle;
13460 satIOContext2->satOrgIOContext = satIOContext;
13461
13462 if (flag == LOG_SENSE_0)
13463 {
13464 /* SAT_SMART_ENABLE_OPERATIONS */
13465 status = smsatSMARTEnable( smRoot,
13466 &(satIntIo->satIntSmIORequest),
13467 smDeviceHandle,
13468 &(satIntIo->satIntSmScsiXchg),
13469 satIOContext2);
13470 }
13471 else if (flag == LOG_SENSE_1)
13472 {
13473 /* SAT_READ_LOG_EXT */
13474 status = smsatLogSense_2( smRoot,
13475 &(satIntIo->satIntSmIORequest),
13476 smDeviceHandle,
13477 &(satIntIo->satIntSmScsiXchg),
13478 satIOContext2);
13479 }
13480 else
13481 {
13482 /* SAT_SMART_READ_LOG */
13483 /* SAT_READ_LOG_EXT */
13484 status = smsatLogSense_3( smRoot,
13485 &(satIntIo->satIntSmIORequest),
13486 smDeviceHandle,
13487 &(satIntIo->satIntSmScsiXchg),
13488 satIOContext2);
13489
13490 }
13491 if (status != SM_RC_SUCCESS)
13492 {
13493 smsatFreeIntIoResource( smRoot,
13494 pSatDevData,
13495 satIntIo);
13496
13497 /*smEnqueueIO(smRoot, satIOContext);*/
13498
13499 tdsmIOCompletedCB( smRoot,
13500 smIORequest,
13501 smIOFailed,
13502 smDetailOtherError,
13503 agNULL,
13504 satIOContext->interruptContext );
13505 return SM_RC_SUCCESS;
13506 }
13507
13508
13509 return SM_RC_SUCCESS;
13510 }
13511
13512 osGLOBAL bit32
smsatSMARTEnable(smRoot_t * smRoot,smIORequest_t * smIORequest,smDeviceHandle_t * smDeviceHandle,smScsiInitiatorRequest_t * smScsiRequest,smSatIOContext_t * satIOContext)13513 smsatSMARTEnable(
13514 smRoot_t *smRoot,
13515 smIORequest_t *smIORequest,
13516 smDeviceHandle_t *smDeviceHandle,
13517 smScsiInitiatorRequest_t *smScsiRequest,
13518 smSatIOContext_t *satIOContext
13519 )
13520 {
13521 bit32 status;
13522 bit32 agRequestType;
13523 agsaFisRegHostToDevice_t *fis;
13524
13525 fis = satIOContext->pFis;
13526 SM_DBG5(("smsatSMARTEnable: start\n"));
13527 /*
13528 * Send the SAT_SMART_ENABLE_OPERATIONS command.
13529 */
13530 fis->h.fisType = 0x27; /* Reg host to device */
13531 fis->h.c_pmPort = 0x80; /* C Bit is set */
13532 fis->h.command = SAT_SMART; /* 0xB0 */
13533 fis->h.features = SAT_SMART_ENABLE_OPERATIONS;
13534 fis->d.lbaLow = 0;
13535 fis->d.lbaMid = 0x4F;
13536 fis->d.lbaHigh = 0xC2;
13537 fis->d.device = 0;
13538 fis->d.lbaLowExp = 0;
13539 fis->d.lbaMidExp = 0;
13540 fis->d.lbaHighExp = 0;
13541 fis->d.featuresExp = 0;
13542 fis->d.sectorCount = 0;
13543 fis->d.sectorCountExp = 0;
13544 fis->d.reserved4 = 0;
13545 fis->d.control = 0; /* FIS HOB bit clear */
13546 fis->d.reserved5 = 0;
13547
13548 agRequestType = AGSA_SATA_PROTOCOL_NON_DATA;
13549
13550 /* Initialize CB for SATA completion.
13551 */
13552 satIOContext->satCompleteCB = &smsatSMARTEnableCB;
13553
13554 /*
13555 * Prepare SGL and send FIS to LL layer.
13556 */
13557 satIOContext->reqType = agRequestType; /* Save it */
13558
13559 status = smsataLLIOStart( smRoot,
13560 smIORequest,
13561 smDeviceHandle,
13562 smScsiRequest,
13563 satIOContext);
13564
13565
13566 return status;
13567 }
13568
13569 osGLOBAL bit32
smsatLogSense_2(smRoot_t * smRoot,smIORequest_t * smIORequest,smDeviceHandle_t * smDeviceHandle,smScsiInitiatorRequest_t * smScsiRequest,smSatIOContext_t * satIOContext)13570 smsatLogSense_2(
13571 smRoot_t *smRoot,
13572 smIORequest_t *smIORequest,
13573 smDeviceHandle_t *smDeviceHandle,
13574 smScsiInitiatorRequest_t *smScsiRequest,
13575 smSatIOContext_t *satIOContext
13576 )
13577 {
13578 bit32 status;
13579 bit32 agRequestType;
13580 agsaFisRegHostToDevice_t *fis;
13581
13582 fis = satIOContext->pFis;
13583 SM_DBG5(("smsatLogSense_2: start\n"));
13584
13585 /* sends READ LOG EXT */
13586 fis->h.fisType = 0x27; /* Reg host to device */
13587 fis->h.c_pmPort = 0x80; /* C Bit is set */
13588
13589 fis->h.command = SAT_READ_LOG_EXT; /* 0x2F */
13590 fis->h.features = 0; /* FIS reserve */
13591 fis->d.lbaLow = 0x07; /* 0x07 */
13592 fis->d.lbaMid = 0; /* */
13593 fis->d.lbaHigh = 0; /* */
13594 fis->d.device = 0; /* */
13595 fis->d.lbaLowExp = 0; /* */
13596 fis->d.lbaMidExp = 0; /* */
13597 fis->d.lbaHighExp = 0; /* */
13598 fis->d.featuresExp = 0; /* FIS reserve */
13599 fis->d.sectorCount = 0x01; /* 1 sector counts */
13600 fis->d.sectorCountExp = 0x00; /* 1 sector counts */
13601 fis->d.reserved4 = 0;
13602 fis->d.control = 0; /* FIS HOB bit clear */
13603 fis->d.reserved5 = 0;
13604
13605 agRequestType = AGSA_SATA_PROTOCOL_PIO_READ;
13606
13607 /* Initialize CB for SATA completion.
13608 */
13609 satIOContext->satCompleteCB = &smsatLogSenseCB;
13610
13611 /*
13612 * Prepare SGL and send FIS to LL layer.
13613 */
13614 satIOContext->reqType = agRequestType; /* Save it */
13615
13616 status = smsataLLIOStart( smRoot,
13617 smIORequest,
13618 smDeviceHandle,
13619 smScsiRequest,
13620 satIOContext);
13621 return status;
13622 }
13623
13624 osGLOBAL bit32
smsatLogSense_3(smRoot_t * smRoot,smIORequest_t * smIORequest,smDeviceHandle_t * smDeviceHandle,smScsiInitiatorRequest_t * smScsiRequest,smSatIOContext_t * satIOContext)13625 smsatLogSense_3(
13626 smRoot_t *smRoot,
13627 smIORequest_t *smIORequest,
13628 smDeviceHandle_t *smDeviceHandle,
13629 smScsiInitiatorRequest_t *smScsiRequest,
13630 smSatIOContext_t *satIOContext
13631 )
13632 {
13633 bit32 status;
13634 bit32 agRequestType;
13635 agsaFisRegHostToDevice_t *fis;
13636
13637 fis = satIOContext->pFis;
13638 SM_DBG5(("smsatLogSense_3: start\n"));
13639 /* sends READ LOG EXT */
13640 fis->h.fisType = 0x27; /* Reg host to device */
13641 fis->h.c_pmPort = 0x80; /* C Bit is set */
13642 fis->h.command = SAT_SMART; /* 0x2F */
13643 fis->h.features = SAT_SMART_READ_LOG; /* 0xd5 */
13644 fis->d.lbaLow = 0x06; /* 0x06 */
13645 fis->d.lbaMid = 0x4F; /* 0x4f */
13646 fis->d.lbaHigh = 0xC2; /* 0xc2 */
13647 fis->d.device = 0; /* */
13648 fis->d.lbaLowExp = 0; /* */
13649 fis->d.lbaMidExp = 0; /* */
13650 fis->d.lbaHighExp = 0; /* */
13651 fis->d.featuresExp = 0; /* FIS reserve */
13652 fis->d.sectorCount = 0x01; /* 1 sector counts */
13653 fis->d.sectorCountExp = 0x00; /* 1 sector counts */
13654 fis->d.reserved4 = 0;
13655 fis->d.control = 0; /* FIS HOB bit clear */
13656 fis->d.reserved5 = 0;
13657 agRequestType = AGSA_SATA_PROTOCOL_PIO_READ;
13658 /* Initialize CB for SATA completion.
13659 */
13660 satIOContext->satCompleteCB = &smsatLogSenseCB;
13661 /*
13662 * Prepare SGL and send FIS to LL layer.
13663 */
13664 satIOContext->reqType = agRequestType; /* Save it */
13665 status = smsataLLIOStart( smRoot,
13666 smIORequest,
13667 smDeviceHandle,
13668 smScsiRequest,
13669 satIOContext);
13670 return status;
13671 }
13672
13673
13674 osGLOBAL bit32
smsatModeSelect6(smRoot_t * smRoot,smIORequest_t * smIORequest,smDeviceHandle_t * smDeviceHandle,smScsiInitiatorRequest_t * smScsiRequest,smSatIOContext_t * satIOContext)13675 smsatModeSelect6(
13676 smRoot_t *smRoot,
13677 smIORequest_t *smIORequest,
13678 smDeviceHandle_t *smDeviceHandle,
13679 smScsiInitiatorRequest_t *smScsiRequest,
13680 smSatIOContext_t *satIOContext
13681 )
13682 {
13683 bit32 status;
13684 bit32 agRequestType;
13685 smDeviceData_t *pSatDevData;
13686 smScsiRspSense_t *pSense;
13687 smIniScsiCmnd_t *scsiCmnd;
13688 agsaFisRegHostToDevice_t *fis;
13689 bit8 *pLogPage; /* Log Page data buffer */
13690 bit32 StartingIndex = 0;
13691 bit8 PageCode = 0;
13692 bit32 chkCnd = agFALSE;
13693 bit32 parameterListLen = 0;
13694
13695 pSense = satIOContext->pSense;
13696 pSatDevData = satIOContext->pSatDevData;
13697 scsiCmnd = &smScsiRequest->scsiCmnd;
13698 fis = satIOContext->pFis;
13699 pLogPage = (bit8 *) smScsiRequest->sglVirtualAddr;
13700
13701 SM_DBG5(("smsatModeSelect6: start\n"));
13702
13703 /* checking CONTROL */
13704 /* NACA == 1 or LINK == 1*/
13705 if ( (scsiCmnd->cdb[5] & SCSI_NACA_MASK) || (scsiCmnd->cdb[5] & SCSI_LINK_MASK) )
13706 {
13707 smsatSetSensePayload( pSense,
13708 SCSI_SNSKEY_ILLEGAL_REQUEST,
13709 0,
13710 SCSI_SNSCODE_INVALID_FIELD_IN_CDB,
13711 satIOContext);
13712
13713 /*smEnqueueIO(smRoot, satIOContext);*/
13714
13715 tdsmIOCompletedCB( smRoot,
13716 smIORequest,
13717 smIOSuccess,
13718 SCSI_STAT_CHECK_CONDITION,
13719 satIOContext->pSmSenseData,
13720 satIOContext->interruptContext );
13721
13722 SM_DBG1(("smsatModeSelect6: return control!!!\n"));
13723 return SM_RC_SUCCESS;
13724 }
13725
13726 /* checking PF bit */
13727 if ( !(scsiCmnd->cdb[1] & SCSI_MODE_SELECT6_PF_MASK))
13728 {
13729 smsatSetSensePayload( pSense,
13730 SCSI_SNSKEY_ILLEGAL_REQUEST,
13731 0,
13732 SCSI_SNSCODE_INVALID_FIELD_IN_CDB,
13733 satIOContext);
13734
13735 /*smEnqueueIO(smRoot, satIOContext);*/
13736
13737 tdsmIOCompletedCB( smRoot,
13738 smIORequest,
13739 smIOSuccess,
13740 SCSI_STAT_CHECK_CONDITION,
13741 satIOContext->pSmSenseData,
13742 satIOContext->interruptContext );
13743
13744 SM_DBG1(("smsatModeSelect6: PF bit check!!!\n"));
13745 return SM_RC_SUCCESS;
13746 }
13747
13748 parameterListLen = scsiCmnd->cdb[4];
13749 parameterListLen = MIN(parameterListLen, scsiCmnd->expDataLength);
13750 if ((0 == parameterListLen) || (agNULL == pLogPage))
13751 {
13752 tdsmIOCompletedCB( smRoot,
13753 smIORequest,
13754 smIOSuccess,
13755 SCSI_STAT_GOOD,
13756 agNULL,
13757 satIOContext->interruptContext);
13758 return SM_RC_SUCCESS;
13759 }
13760
13761 /* checking Block Descriptor Length on Mode parameter header(6)*/
13762 if (pLogPage[3] == 8)
13763 {
13764 /* mode parameter block descriptor exists */
13765 PageCode = (bit8)(pLogPage[12] & 0x3F); /* page code and index is 4 + 8 */
13766 StartingIndex = 12;
13767 }
13768 else if (pLogPage[3] == 0)
13769 {
13770 /* mode parameter block descriptor does not exist */
13771 PageCode = (bit8)(pLogPage[4] & 0x3F); /* page code and index is 4 + 0 */
13772 StartingIndex = 4;
13773 /*smEnqueueIO(smRoot, satIOContext);*/
13774
13775 tdsmIOCompletedCB( smRoot,
13776 smIORequest,
13777 smIOSuccess,
13778 SCSI_STAT_GOOD,
13779 agNULL,
13780 satIOContext->interruptContext);
13781 return SM_RC_SUCCESS;
13782 }
13783 else
13784 {
13785 SM_DBG1(("smsatModeSelect6: return mode parameter block descriptor 0x%x!!!\n", pLogPage[3]));
13786
13787 smsatSetSensePayload( pSense,
13788 SCSI_SNSKEY_NO_SENSE,
13789 0,
13790 SCSI_SNSCODE_NO_ADDITIONAL_INFO,
13791 satIOContext);
13792
13793 /*smEnqueueIO(smRoot, satIOContext);*/
13794
13795 tdsmIOCompletedCB( smRoot,
13796 smIORequest,
13797 smIOSuccess,
13798 SCSI_STAT_CHECK_CONDITION,
13799 satIOContext->pSmSenseData,
13800 satIOContext->interruptContext );
13801 return SM_RC_SUCCESS;
13802 }
13803
13804
13805
13806 switch (PageCode) /* page code */
13807 {
13808 case MODESELECT_CONTROL_PAGE:
13809 SM_DBG1(("smsatModeSelect6: Control mode page!!!\n"));
13810
13811 if ( pLogPage[StartingIndex+1] != 0x0A ||
13812 pLogPage[StartingIndex+2] != 0x02 ||
13813 (pSatDevData->satNCQ == agTRUE && pLogPage[StartingIndex+3] != 0x12) ||
13814 (pSatDevData->satNCQ == agFALSE && pLogPage[StartingIndex+3] != 0x02) ||
13815 (pLogPage[StartingIndex+4] & BIT3_MASK) != 0x00 || /* SWP bit */
13816 (pLogPage[StartingIndex+4] & BIT4_MASK) != 0x00 || /* UA_INTLCK_CTRL */
13817 (pLogPage[StartingIndex+4] & BIT5_MASK) != 0x00 || /* UA_INTLCK_CTRL */
13818
13819 (pLogPage[StartingIndex+5] & BIT0_MASK) != 0x00 || /* AUTOLOAD MODE */
13820 (pLogPage[StartingIndex+5] & BIT1_MASK) != 0x00 || /* AUTOLOAD MODE */
13821 (pLogPage[StartingIndex+5] & BIT2_MASK) != 0x00 || /* AUTOLOAD MODE */
13822 (pLogPage[StartingIndex+5] & BIT6_MASK) != 0x00 || /* TAS bit */
13823
13824 pLogPage[StartingIndex+8] != 0xFF ||
13825 pLogPage[StartingIndex+9] != 0xFF ||
13826 pLogPage[StartingIndex+10] != 0x00 ||
13827 pLogPage[StartingIndex+11] != 0x00
13828 )
13829 {
13830 chkCnd = agTRUE;
13831 }
13832 if (chkCnd == agTRUE)
13833 {
13834 smsatSetSensePayload( pSense,
13835 SCSI_SNSKEY_ILLEGAL_REQUEST,
13836 0,
13837 SCSI_SNSCODE_INVALID_FIELD_IN_CDB,
13838 satIOContext);
13839
13840 /*smEnqueueIO(smRoot, satIOContext);*/
13841
13842 tdsmIOCompletedCB( smRoot,
13843 smIORequest,
13844 smIOSuccess,
13845 SCSI_STAT_CHECK_CONDITION,
13846 satIOContext->pSmSenseData,
13847 satIOContext->interruptContext );
13848
13849 SM_DBG1(("smsatModeSelect6: unexpected values!!!\n"));
13850 }
13851 else
13852 {
13853 /*smEnqueueIO(smRoot, satIOContext);*/
13854
13855 tdsmIOCompletedCB( smRoot,
13856 smIORequest,
13857 smIOSuccess,
13858 SCSI_STAT_GOOD,
13859 agNULL,
13860 satIOContext->interruptContext);
13861 }
13862 return SM_RC_SUCCESS;
13863 break;
13864 case MODESELECT_READ_WRITE_ERROR_RECOVERY_PAGE:
13865 SM_DBG1(("smsatModeSelect6: Read-Write Error Recovery mode page!!!\n"));
13866
13867 if ( (pLogPage[StartingIndex + 2] & SCSI_MODE_SELECT6_AWRE_MASK) ||
13868 (pLogPage[StartingIndex + 2] & SCSI_MODE_SELECT6_RC_MASK) ||
13869 (pLogPage[StartingIndex + 2] & SCSI_MODE_SELECT6_EER_MASK) ||
13870 (pLogPage[StartingIndex + 2] & SCSI_MODE_SELECT6_PER_MASK) ||
13871 (pLogPage[StartingIndex + 2] & SCSI_MODE_SELECT6_DTE_MASK) ||
13872 (pLogPage[StartingIndex + 2] & SCSI_MODE_SELECT6_DCR_MASK) ||
13873 (pLogPage[StartingIndex + 10]) ||
13874 (pLogPage[StartingIndex + 11])
13875 )
13876 {
13877 SM_DBG5(("smsatModeSelect6: return check condition\n"));
13878
13879 smsatSetSensePayload( pSense,
13880 SCSI_SNSKEY_ILLEGAL_REQUEST,
13881 0,
13882 SCSI_SNSCODE_INVALID_FIELD_PARAMETER_LIST,
13883 satIOContext);
13884
13885 /*smEnqueueIO(smRoot, satIOContext);*/
13886
13887 tdsmIOCompletedCB( smRoot,
13888 smIORequest,
13889 smIOSuccess,
13890 SCSI_STAT_CHECK_CONDITION,
13891 satIOContext->pSmSenseData,
13892 satIOContext->interruptContext );
13893 return SM_RC_SUCCESS;
13894 }
13895 else
13896 {
13897 SM_DBG5(("smsatModeSelect6: return GOOD \n"));
13898 /*smEnqueueIO(smRoot, satIOContext);*/
13899
13900 tdsmIOCompletedCB( smRoot,
13901 smIORequest,
13902 smIOSuccess,
13903 SCSI_STAT_GOOD,
13904 agNULL,
13905 satIOContext->interruptContext);
13906 return SM_RC_SUCCESS;
13907 }
13908
13909 break;
13910 case MODESELECT_CACHING:
13911 /* SAT rev8 Table67, p69*/
13912 SM_DBG5(("smsatModeSelect6: Caching mode page\n"));
13913 if ( (pLogPage[StartingIndex + 2] & 0xFB) || /* 1111 1011 */
13914 (pLogPage[StartingIndex + 3]) ||
13915 (pLogPage[StartingIndex + 4]) ||
13916 (pLogPage[StartingIndex + 5]) ||
13917 (pLogPage[StartingIndex + 6]) ||
13918 (pLogPage[StartingIndex + 7]) ||
13919 (pLogPage[StartingIndex + 8]) ||
13920 (pLogPage[StartingIndex + 9]) ||
13921 (pLogPage[StartingIndex + 10]) ||
13922 (pLogPage[StartingIndex + 11]) ||
13923
13924 (pLogPage[StartingIndex + 12] & 0xC1) || /* 1100 0001 */
13925 (pLogPage[StartingIndex + 13]) ||
13926 (pLogPage[StartingIndex + 14]) ||
13927 (pLogPage[StartingIndex + 15])
13928 )
13929 {
13930 SM_DBG1(("smsatModeSelect6: return check condition!!!\n"));
13931
13932 smsatSetSensePayload( pSense,
13933 SCSI_SNSKEY_ILLEGAL_REQUEST,
13934 0,
13935 SCSI_SNSCODE_INVALID_FIELD_PARAMETER_LIST,
13936 satIOContext);
13937
13938 /*smEnqueueIO(smRoot, satIOContext);*/
13939
13940 tdsmIOCompletedCB( smRoot,
13941 smIORequest,
13942 smIOSuccess,
13943 SCSI_STAT_CHECK_CONDITION,
13944 satIOContext->pSmSenseData,
13945 satIOContext->interruptContext );
13946 return SM_RC_SUCCESS;
13947
13948 }
13949 else
13950 {
13951 /* sends ATA SET FEATURES based on WCE bit */
13952 if ( !(pLogPage[StartingIndex + 2] & SCSI_MODE_SELECT6_WCE_MASK) )
13953 {
13954 SM_DBG5(("smsatModeSelect6: disable write cache\n"));
13955 /* sends SET FEATURES */
13956 fis->h.fisType = 0x27; /* Reg host to device */
13957 fis->h.c_pmPort = 0x80; /* C Bit is set */
13958
13959 fis->h.command = SAT_SET_FEATURES; /* 0xEF */
13960 fis->h.features = 0x82; /* disable write cache */
13961 fis->d.lbaLow = 0; /* */
13962 fis->d.lbaMid = 0; /* */
13963 fis->d.lbaHigh = 0; /* */
13964 fis->d.device = 0; /* */
13965 fis->d.lbaLowExp = 0; /* */
13966 fis->d.lbaMidExp = 0; /* */
13967 fis->d.lbaHighExp = 0; /* */
13968 fis->d.featuresExp = 0; /* */
13969 fis->d.sectorCount = 0; /* */
13970 fis->d.sectorCountExp = 0; /* */
13971 fis->d.reserved4 = 0;
13972 fis->d.control = 0; /* FIS HOB bit clear */
13973 fis->d.reserved5 = 0;
13974
13975 agRequestType = AGSA_SATA_PROTOCOL_NON_DATA;
13976
13977 /* Initialize CB for SATA completion.
13978 */
13979 satIOContext->satCompleteCB = &smsatModeSelect6n10CB;
13980
13981 /*
13982 * Prepare SGL and send FIS to LL layer.
13983 */
13984 satIOContext->reqType = agRequestType; /* Save it */
13985
13986 status = smsataLLIOStart( smRoot,
13987 smIORequest,
13988 smDeviceHandle,
13989 smScsiRequest,
13990 satIOContext);
13991 return status;
13992 }
13993 else
13994 {
13995 SM_DBG5(("smsatModeSelect6: enable write cache\n"));
13996 /* sends SET FEATURES */
13997 fis->h.fisType = 0x27; /* Reg host to device */
13998 fis->h.c_pmPort = 0x80; /* C Bit is set */
13999
14000 fis->h.command = SAT_SET_FEATURES; /* 0xEF */
14001 fis->h.features = 0x02; /* enable write cache */
14002 fis->d.lbaLow = 0; /* */
14003 fis->d.lbaMid = 0; /* */
14004 fis->d.lbaHigh = 0; /* */
14005 fis->d.device = 0; /* */
14006 fis->d.lbaLowExp = 0; /* */
14007 fis->d.lbaMidExp = 0; /* */
14008 fis->d.lbaHighExp = 0; /* */
14009 fis->d.featuresExp = 0; /* */
14010 fis->d.sectorCount = 0; /* */
14011 fis->d.sectorCountExp = 0; /* */
14012 fis->d.reserved4 = 0;
14013 fis->d.control = 0; /* FIS HOB bit clear */
14014 fis->d.reserved5 = 0;
14015
14016 agRequestType = AGSA_SATA_PROTOCOL_NON_DATA;
14017
14018 /* Initialize CB for SATA completion.
14019 */
14020 satIOContext->satCompleteCB = &smsatModeSelect6n10CB;
14021
14022 /*
14023 * Prepare SGL and send FIS to LL layer.
14024 */
14025 satIOContext->reqType = agRequestType; /* Save it */
14026
14027 status = smsataLLIOStart( smRoot,
14028 smIORequest,
14029 smDeviceHandle,
14030 smScsiRequest,
14031 satIOContext);
14032 return status;
14033
14034 }
14035 }
14036 break;
14037 case MODESELECT_INFORMATION_EXCEPTION_CONTROL_PAGE:
14038 SM_DBG5(("smsatModeSelect6: Informational Exception Control mode page\n"));
14039
14040 if ( (pLogPage[StartingIndex + 2] & SCSI_MODE_SELECT6_PERF_MASK) ||
14041 (pLogPage[StartingIndex + 2] & SCSI_MODE_SELECT6_TEST_MASK)
14042 )
14043 {
14044 SM_DBG1(("smsatModeSelect6: return check condition!!! \n"));
14045
14046 smsatSetSensePayload( pSense,
14047 SCSI_SNSKEY_ILLEGAL_REQUEST,
14048 0,
14049 SCSI_SNSCODE_INVALID_FIELD_PARAMETER_LIST,
14050 satIOContext);
14051
14052 /*smEnqueueIO(smRoot, satIOContext);*/
14053
14054 tdsmIOCompletedCB( smRoot,
14055 smIORequest,
14056 smIOSuccess,
14057 SCSI_STAT_CHECK_CONDITION,
14058 satIOContext->pSmSenseData,
14059 satIOContext->interruptContext );
14060 return SM_RC_SUCCESS;
14061 }
14062 else
14063 {
14064 /* sends either ATA SMART ENABLE/DISABLE OPERATIONS based on DEXCPT bit */
14065 if ( !(pLogPage[StartingIndex + 2] & 0x08) )
14066 {
14067 SM_DBG5(("smsatModeSelect6: enable information exceptions reporting\n"));
14068 /* sends SMART ENABLE OPERATIONS */
14069 fis->h.fisType = 0x27; /* Reg host to device */
14070 fis->h.c_pmPort = 0x80; /* C Bit is set */
14071
14072 fis->h.command = SAT_SMART; /* 0xB0 */
14073 fis->h.features = SAT_SMART_ENABLE_OPERATIONS; /* enable */
14074 fis->d.lbaLow = 0; /* */
14075 fis->d.lbaMid = 0x4F; /* 0x4F */
14076 fis->d.lbaHigh = 0xC2; /* 0xC2 */
14077 fis->d.device = 0; /* */
14078 fis->d.lbaLowExp = 0; /* */
14079 fis->d.lbaMidExp = 0; /* */
14080 fis->d.lbaHighExp = 0; /* */
14081 fis->d.featuresExp = 0; /* */
14082 fis->d.sectorCount = 0; /* */
14083 fis->d.sectorCountExp = 0; /* */
14084 fis->d.reserved4 = 0;
14085 fis->d.control = 0; /* FIS HOB bit clear */
14086 fis->d.reserved5 = 0;
14087
14088 agRequestType = AGSA_SATA_PROTOCOL_NON_DATA;
14089
14090 /* Initialize CB for SATA completion.
14091 */
14092 satIOContext->satCompleteCB = &smsatModeSelect6n10CB;
14093
14094 /*
14095 * Prepare SGL and send FIS to LL layer.
14096 */
14097 satIOContext->reqType = agRequestType; /* Save it */
14098
14099 status = smsataLLIOStart( smRoot,
14100 smIORequest,
14101 smDeviceHandle,
14102 smScsiRequest,
14103 satIOContext);
14104 return status;
14105 }
14106 else
14107 {
14108 SM_DBG5(("smsatModeSelect6: disable information exceptions reporting\n"));
14109 /* sends SMART DISABLE OPERATIONS */
14110 fis->h.fisType = 0x27; /* Reg host to device */
14111 fis->h.c_pmPort = 0x80; /* C Bit is set */
14112
14113 fis->h.command = SAT_SMART; /* 0xB0 */
14114 fis->h.features = SAT_SMART_DISABLE_OPERATIONS; /* disable */
14115 fis->d.lbaLow = 0; /* */
14116 fis->d.lbaMid = 0x4F; /* 0x4F */
14117 fis->d.lbaHigh = 0xC2; /* 0xC2 */
14118 fis->d.device = 0; /* */
14119 fis->d.lbaLowExp = 0; /* */
14120 fis->d.lbaMidExp = 0; /* */
14121 fis->d.lbaHighExp = 0; /* */
14122 fis->d.featuresExp = 0; /* */
14123 fis->d.sectorCount = 0; /* */
14124 fis->d.sectorCountExp = 0; /* */
14125 fis->d.reserved4 = 0;
14126 fis->d.control = 0; /* FIS HOB bit clear */
14127 fis->d.reserved5 = 0;
14128
14129 agRequestType = AGSA_SATA_PROTOCOL_NON_DATA;
14130
14131 /* Initialize CB for SATA completion.
14132 */
14133 satIOContext->satCompleteCB = &smsatModeSelect6n10CB;
14134
14135 /*
14136 * Prepare SGL and send FIS to LL layer.
14137 */
14138 satIOContext->reqType = agRequestType; /* Save it */
14139
14140 status = smsataLLIOStart( smRoot,
14141 smIORequest,
14142 smDeviceHandle,
14143 smScsiRequest,
14144 satIOContext);
14145 return status;
14146
14147 }
14148 }
14149 break;
14150 default:
14151 SM_DBG1(("smsatModeSelect6: Error unknown page code 0x%x!!!\n", pLogPage[12]));
14152 smsatSetSensePayload( pSense,
14153 SCSI_SNSKEY_NO_SENSE,
14154 0,
14155 SCSI_SNSCODE_NO_ADDITIONAL_INFO,
14156 satIOContext);
14157
14158 /*smEnqueueIO(smRoot, satIOContext);*/
14159
14160 tdsmIOCompletedCB( smRoot,
14161 smIORequest,
14162 smIOSuccess,
14163 SCSI_STAT_CHECK_CONDITION,
14164 satIOContext->pSmSenseData,
14165 satIOContext->interruptContext );
14166 return SM_RC_SUCCESS;
14167 }
14168 }
14169
14170
14171 osGLOBAL bit32
smsatModeSelect10(smRoot_t * smRoot,smIORequest_t * smIORequest,smDeviceHandle_t * smDeviceHandle,smScsiInitiatorRequest_t * smScsiRequest,smSatIOContext_t * satIOContext)14172 smsatModeSelect10(
14173 smRoot_t *smRoot,
14174 smIORequest_t *smIORequest,
14175 smDeviceHandle_t *smDeviceHandle,
14176 smScsiInitiatorRequest_t *smScsiRequest,
14177 smSatIOContext_t *satIOContext
14178 )
14179 {
14180 bit32 status;
14181 bit32 agRequestType;
14182 smDeviceData_t *pSatDevData;
14183 smScsiRspSense_t *pSense;
14184 smIniScsiCmnd_t *scsiCmnd;
14185 agsaFisRegHostToDevice_t *fis;
14186 bit8 *pLogPage; /* Log Page data buffer */
14187 bit16 BlkDescLen = 0; /* Block Descriptor Length */
14188 bit32 StartingIndex = 0;
14189 bit8 PageCode = 0;
14190 bit32 chkCnd = agFALSE;
14191 bit32 parameterListLen = 0;
14192
14193 pSense = satIOContext->pSense;
14194 pSatDevData = satIOContext->pSatDevData;
14195 scsiCmnd = &smScsiRequest->scsiCmnd;
14196 fis = satIOContext->pFis;
14197 pLogPage = (bit8 *) smScsiRequest->sglVirtualAddr;
14198
14199 SM_DBG5(("smsatModeSelect10: start\n"));
14200
14201 /* checking CONTROL */
14202 /* NACA == 1 or LINK == 1*/
14203 if ( (scsiCmnd->cdb[9] & SCSI_NACA_MASK) || (scsiCmnd->cdb[9] & SCSI_LINK_MASK) )
14204 {
14205 smsatSetSensePayload( pSense,
14206 SCSI_SNSKEY_ILLEGAL_REQUEST,
14207 0,
14208 SCSI_SNSCODE_INVALID_FIELD_IN_CDB,
14209 satIOContext);
14210
14211 /*smEnqueueIO(smRoot, satIOContext);*/
14212
14213 tdsmIOCompletedCB( smRoot,
14214 smIORequest,
14215 smIOSuccess,
14216 SCSI_STAT_CHECK_CONDITION,
14217 satIOContext->pSmSenseData,
14218 satIOContext->interruptContext );
14219
14220 SM_DBG1(("smsatModeSelect10: return control!!!\n"));
14221 return SM_RC_SUCCESS;
14222 }
14223
14224 /* checking PF bit */
14225 if ( !(scsiCmnd->cdb[1] & SCSI_MODE_SELECT10_PF_MASK))
14226 {
14227 smsatSetSensePayload( pSense,
14228 SCSI_SNSKEY_ILLEGAL_REQUEST,
14229 0,
14230 SCSI_SNSCODE_INVALID_FIELD_IN_CDB,
14231 satIOContext);
14232
14233 /*smEnqueueIO(smRoot, satIOContext);*/
14234
14235 tdsmIOCompletedCB( smRoot,
14236 smIORequest,
14237 smIOSuccess,
14238 SCSI_STAT_CHECK_CONDITION,
14239 satIOContext->pSmSenseData,
14240 satIOContext->interruptContext );
14241
14242 SM_DBG1(("smsatModeSelect10: PF bit check!!!\n"));
14243 return SM_RC_SUCCESS;
14244 }
14245
14246 parameterListLen = ((scsiCmnd->cdb[7]) << 8) + scsiCmnd->cdb[8];
14247 parameterListLen = MIN(parameterListLen, scsiCmnd->expDataLength);
14248 if ((0 == parameterListLen) || (agNULL == pLogPage))
14249 {
14250 tdsmIOCompletedCB( smRoot,
14251 smIORequest,
14252 smIOSuccess,
14253 SCSI_STAT_GOOD,
14254 agNULL,
14255 satIOContext->interruptContext);
14256 return SM_RC_SUCCESS;
14257 }
14258
14259 BlkDescLen = (bit8)((pLogPage[6] << 8) + pLogPage[7]);
14260
14261 /* checking Block Descriptor Length on Mode parameter header(10) and LONGLBA bit*/
14262 if ( (BlkDescLen == 8) && !(pLogPage[4] & SCSI_MODE_SELECT10_LONGLBA_MASK) )
14263 {
14264 /* mode parameter block descriptor exists and length is 8 byte */
14265 PageCode = (bit8)(pLogPage[16] & 0x3F); /* page code and index is 8 + 8 */
14266 StartingIndex = 16;
14267 }
14268 else if ( (BlkDescLen == 16) && (pLogPage[4] & SCSI_MODE_SELECT10_LONGLBA_MASK) )
14269 {
14270 /* mode parameter block descriptor exists and length is 16 byte */
14271 PageCode = (bit8)(pLogPage[24] & 0x3F); /* page code and index is 8 + 16 */
14272 StartingIndex = 24;
14273 }
14274 else if (BlkDescLen == 0)
14275 {
14276 PageCode = (bit8)(pLogPage[8] & 0x3F); /* page code and index is 8 + 0 */
14277 StartingIndex = 8;
14278 /*smEnqueueIO(smRoot, satIOContext);*/
14279
14280 tdsmIOCompletedCB( smRoot,
14281 smIORequest,
14282 smIOSuccess,
14283 SCSI_STAT_GOOD,
14284 agNULL,
14285 satIOContext->interruptContext);
14286 return SM_RC_SUCCESS;
14287 }
14288 else
14289 {
14290 SM_DBG1(("smsatModeSelect10: return mode parameter block descriptor 0x%x!!!\n", BlkDescLen));
14291 /* no more than one mode parameter block descriptor shall be supported */
14292 smsatSetSensePayload( pSense,
14293 SCSI_SNSKEY_NO_SENSE,
14294 0,
14295 SCSI_SNSCODE_NO_ADDITIONAL_INFO,
14296 satIOContext);
14297
14298 /*smEnqueueIO(smRoot, satIOContext);*/
14299
14300 tdsmIOCompletedCB( smRoot,
14301 smIORequest,
14302 smIOSuccess,
14303 SCSI_STAT_CHECK_CONDITION,
14304 satIOContext->pSmSenseData,
14305 satIOContext->interruptContext );
14306 return SM_RC_SUCCESS;
14307 }
14308 /*
14309 for debugging only
14310 */
14311 if (StartingIndex == 8)
14312 {
14313 smhexdump("startingindex 8", (bit8 *)pLogPage, 8);
14314 }
14315 else if(StartingIndex == 16)
14316 {
14317 if (PageCode == MODESELECT_CACHING)
14318 {
14319 smhexdump("startingindex 16", (bit8 *)pLogPage, 16+20);
14320 }
14321 else
14322 {
14323 smhexdump("startingindex 16", (bit8 *)pLogPage, 16+12);
14324 }
14325 }
14326 else
14327 {
14328 if (PageCode == MODESELECT_CACHING)
14329 {
14330 smhexdump("startingindex 24", (bit8 *)pLogPage, 24+20);
14331 }
14332 else
14333 {
14334 smhexdump("startingindex 24", (bit8 *)pLogPage, 24+12);
14335 }
14336 }
14337 switch (PageCode) /* page code */
14338 {
14339 case MODESELECT_CONTROL_PAGE:
14340 SM_DBG5(("smsatModeSelect10: Control mode page\n"));
14341 /*
14342 compare pLogPage to expected value (SAT Table 65, p67)
14343 If not match, return check condition
14344 */
14345 if ( pLogPage[StartingIndex+1] != 0x0A ||
14346 pLogPage[StartingIndex+2] != 0x02 ||
14347 (pSatDevData->satNCQ == agTRUE && pLogPage[StartingIndex+3] != 0x12) ||
14348 (pSatDevData->satNCQ == agFALSE && pLogPage[StartingIndex+3] != 0x02) ||
14349 (pLogPage[StartingIndex+4] & BIT3_MASK) != 0x00 || /* SWP bit */
14350 (pLogPage[StartingIndex+4] & BIT4_MASK) != 0x00 || /* UA_INTLCK_CTRL */
14351 (pLogPage[StartingIndex+4] & BIT5_MASK) != 0x00 || /* UA_INTLCK_CTRL */
14352
14353 (pLogPage[StartingIndex+5] & BIT0_MASK) != 0x00 || /* AUTOLOAD MODE */
14354 (pLogPage[StartingIndex+5] & BIT1_MASK) != 0x00 || /* AUTOLOAD MODE */
14355 (pLogPage[StartingIndex+5] & BIT2_MASK) != 0x00 || /* AUTOLOAD MODE */
14356 (pLogPage[StartingIndex+5] & BIT6_MASK) != 0x00 || /* TAS bit */
14357
14358 pLogPage[StartingIndex+8] != 0xFF ||
14359 pLogPage[StartingIndex+9] != 0xFF ||
14360 pLogPage[StartingIndex+10] != 0x00 ||
14361 pLogPage[StartingIndex+11] != 0x00
14362 )
14363 {
14364 chkCnd = agTRUE;
14365 }
14366 if (chkCnd == agTRUE)
14367 {
14368 smsatSetSensePayload( pSense,
14369 SCSI_SNSKEY_ILLEGAL_REQUEST,
14370 0,
14371 SCSI_SNSCODE_INVALID_FIELD_IN_CDB,
14372 satIOContext);
14373
14374 /*smEnqueueIO(smRoot, satIOContext);*/
14375
14376 tdsmIOCompletedCB( smRoot,
14377 smIORequest,
14378 smIOSuccess,
14379 SCSI_STAT_CHECK_CONDITION,
14380 satIOContext->pSmSenseData,
14381 satIOContext->interruptContext );
14382
14383 SM_DBG1(("smsatModeSelect10: unexpected values!!!\n"));
14384 }
14385 else
14386 {
14387 /*smEnqueueIO(smRoot, satIOContext);*/
14388
14389 tdsmIOCompletedCB( smRoot,
14390 smIORequest,
14391 smIOSuccess,
14392 SCSI_STAT_GOOD,
14393 agNULL,
14394 satIOContext->interruptContext);
14395 }
14396 return SM_RC_SUCCESS;
14397 break;
14398 case MODESELECT_READ_WRITE_ERROR_RECOVERY_PAGE:
14399 SM_DBG5(("smsatModeSelect10: Read-Write Error Recovery mode page\n"));
14400
14401 if ( (pLogPage[StartingIndex + 2] & SCSI_MODE_SELECT10_AWRE_MASK) ||
14402 (pLogPage[StartingIndex + 2] & SCSI_MODE_SELECT10_RC_MASK) ||
14403 (pLogPage[StartingIndex + 2] & SCSI_MODE_SELECT10_EER_MASK) ||
14404 (pLogPage[StartingIndex + 2] & SCSI_MODE_SELECT10_PER_MASK) ||
14405 (pLogPage[StartingIndex + 2] & SCSI_MODE_SELECT10_DTE_MASK) ||
14406 (pLogPage[StartingIndex + 2] & SCSI_MODE_SELECT10_DCR_MASK) ||
14407 (pLogPage[StartingIndex + 10]) ||
14408 (pLogPage[StartingIndex + 11])
14409 )
14410 {
14411 SM_DBG1(("smsatModeSelect10: return check condition!!!\n"));
14412
14413 smsatSetSensePayload( pSense,
14414 SCSI_SNSKEY_ILLEGAL_REQUEST,
14415 0,
14416 SCSI_SNSCODE_INVALID_FIELD_PARAMETER_LIST,
14417 satIOContext);
14418
14419 /*smEnqueueIO(smRoot, satIOContext);*/
14420
14421 tdsmIOCompletedCB( smRoot,
14422 smIORequest,
14423 smIOSuccess,
14424 SCSI_STAT_CHECK_CONDITION,
14425 satIOContext->pSmSenseData,
14426 satIOContext->interruptContext );
14427 return SM_RC_SUCCESS;
14428 }
14429 else
14430 {
14431 SM_DBG2(("smsatModeSelect10: return GOOD \n"));
14432 /*smEnqueueIO(smRoot, satIOContext);*/
14433
14434 tdsmIOCompletedCB( smRoot,
14435 smIORequest,
14436 smIOSuccess,
14437 SCSI_STAT_GOOD,
14438 agNULL,
14439 satIOContext->interruptContext);
14440 return SM_RC_SUCCESS;
14441 }
14442
14443 break;
14444 case MODESELECT_CACHING:
14445 /* SAT rev8 Table67, p69*/
14446 SM_DBG5(("smsatModeSelect10: Caching mode page\n"));
14447 if ( (pLogPage[StartingIndex + 2] & 0xFB) || /* 1111 1011 */
14448 (pLogPage[StartingIndex + 3]) ||
14449 (pLogPage[StartingIndex + 4]) ||
14450 (pLogPage[StartingIndex + 5]) ||
14451 (pLogPage[StartingIndex + 6]) ||
14452 (pLogPage[StartingIndex + 7]) ||
14453 (pLogPage[StartingIndex + 8]) ||
14454 (pLogPage[StartingIndex + 9]) ||
14455 (pLogPage[StartingIndex + 10]) ||
14456 (pLogPage[StartingIndex + 11]) ||
14457
14458 (pLogPage[StartingIndex + 12] & 0xC1) || /* 1100 0001 */
14459 (pLogPage[StartingIndex + 13]) ||
14460 (pLogPage[StartingIndex + 14]) ||
14461 (pLogPage[StartingIndex + 15])
14462 )
14463 {
14464 SM_DBG1(("smsatModeSelect10: return check condition!!!\n"));
14465
14466 smsatSetSensePayload( pSense,
14467 SCSI_SNSKEY_ILLEGAL_REQUEST,
14468 0,
14469 SCSI_SNSCODE_INVALID_FIELD_PARAMETER_LIST,
14470 satIOContext);
14471
14472 /*smEnqueueIO(smRoot, satIOContext);*/
14473
14474 tdsmIOCompletedCB( smRoot,
14475 smIORequest,
14476 smIOSuccess,
14477 SCSI_STAT_CHECK_CONDITION,
14478 satIOContext->pSmSenseData,
14479 satIOContext->interruptContext );
14480 return SM_RC_SUCCESS;
14481
14482 }
14483 else
14484 {
14485 /* sends ATA SET FEATURES based on WCE bit */
14486 if ( !(pLogPage[StartingIndex + 2] & SCSI_MODE_SELECT10_WCE_MASK) )
14487 {
14488 SM_DBG5(("smsatModeSelect10: disable write cache\n"));
14489 /* sends SET FEATURES */
14490 fis->h.fisType = 0x27; /* Reg host to device */
14491 fis->h.c_pmPort = 0x80; /* C Bit is set */
14492
14493 fis->h.command = SAT_SET_FEATURES; /* 0xEF */
14494 fis->h.features = 0x82; /* disable write cache */
14495 fis->d.lbaLow = 0; /* */
14496 fis->d.lbaMid = 0; /* */
14497 fis->d.lbaHigh = 0; /* */
14498 fis->d.device = 0; /* */
14499 fis->d.lbaLowExp = 0; /* */
14500 fis->d.lbaMidExp = 0; /* */
14501 fis->d.lbaHighExp = 0; /* */
14502 fis->d.featuresExp = 0; /* */
14503 fis->d.sectorCount = 0; /* */
14504 fis->d.sectorCountExp = 0; /* */
14505 fis->d.reserved4 = 0;
14506 fis->d.control = 0; /* FIS HOB bit clear */
14507 fis->d.reserved5 = 0;
14508
14509 agRequestType = AGSA_SATA_PROTOCOL_NON_DATA;
14510
14511 /* Initialize CB for SATA completion.
14512 */
14513 satIOContext->satCompleteCB = &smsatModeSelect6n10CB;
14514
14515 /*
14516 * Prepare SGL and send FIS to LL layer.
14517 */
14518 satIOContext->reqType = agRequestType; /* Save it */
14519
14520 status = smsataLLIOStart( smRoot,
14521 smIORequest,
14522 smDeviceHandle,
14523 smScsiRequest,
14524 satIOContext);
14525 return status;
14526 }
14527 else
14528 {
14529 SM_DBG5(("smsatModeSelect10: enable write cache\n"));
14530 /* sends SET FEATURES */
14531 fis->h.fisType = 0x27; /* Reg host to device */
14532 fis->h.c_pmPort = 0x80; /* C Bit is set */
14533
14534 fis->h.command = SAT_SET_FEATURES; /* 0xEF */
14535 fis->h.features = 0x02; /* enable write cache */
14536 fis->d.lbaLow = 0; /* */
14537 fis->d.lbaMid = 0; /* */
14538 fis->d.lbaHigh = 0; /* */
14539 fis->d.device = 0; /* */
14540 fis->d.lbaLowExp = 0; /* */
14541 fis->d.lbaMidExp = 0; /* */
14542 fis->d.lbaHighExp = 0; /* */
14543 fis->d.featuresExp = 0; /* */
14544 fis->d.sectorCount = 0; /* */
14545 fis->d.sectorCountExp = 0; /* */
14546 fis->d.reserved4 = 0;
14547 fis->d.control = 0; /* FIS HOB bit clear */
14548 fis->d.reserved5 = 0;
14549
14550 agRequestType = AGSA_SATA_PROTOCOL_NON_DATA;
14551
14552 /* Initialize CB for SATA completion.
14553 */
14554 satIOContext->satCompleteCB = &smsatModeSelect6n10CB;
14555
14556 /*
14557 * Prepare SGL and send FIS to LL layer.
14558 */
14559 satIOContext->reqType = agRequestType; /* Save it */
14560
14561 status = smsataLLIOStart( smRoot,
14562 smIORequest,
14563 smDeviceHandle,
14564 smScsiRequest,
14565 satIOContext);
14566 return status;
14567
14568 }
14569 }
14570 break;
14571 case MODESELECT_INFORMATION_EXCEPTION_CONTROL_PAGE:
14572 SM_DBG5(("smsatModeSelect10: Informational Exception Control mode page\n"));
14573
14574 if ( (pLogPage[StartingIndex + 2] & SCSI_MODE_SELECT10_PERF_MASK) ||
14575 (pLogPage[StartingIndex + 2] & SCSI_MODE_SELECT10_TEST_MASK)
14576 )
14577 {
14578 SM_DBG1(("smsatModeSelect10: return check condition!!!\n"));
14579
14580 smsatSetSensePayload( pSense,
14581 SCSI_SNSKEY_ILLEGAL_REQUEST,
14582 0,
14583 SCSI_SNSCODE_INVALID_FIELD_PARAMETER_LIST,
14584 satIOContext);
14585
14586 /*smEnqueueIO(smRoot, satIOContext);*/
14587
14588 tdsmIOCompletedCB( smRoot,
14589 smIORequest,
14590 smIOSuccess,
14591 SCSI_STAT_CHECK_CONDITION,
14592 satIOContext->pSmSenseData,
14593 satIOContext->interruptContext );
14594 return SM_RC_SUCCESS;
14595 }
14596 else
14597 {
14598 /* sends either ATA SMART ENABLE/DISABLE OPERATIONS based on DEXCPT bit */
14599 if ( !(pLogPage[StartingIndex + 2] & SCSI_MODE_SELECT10_DEXCPT_MASK) )
14600 {
14601 SM_DBG5(("smsatModeSelect10: enable information exceptions reporting\n"));
14602 /* sends SMART ENABLE OPERATIONS */
14603 fis->h.fisType = 0x27; /* Reg host to device */
14604 fis->h.c_pmPort = 0x80; /* C Bit is set */
14605
14606 fis->h.command = SAT_SMART; /* 0xB0 */
14607 fis->h.features = SAT_SMART_ENABLE_OPERATIONS; /* enable */
14608 fis->d.lbaLow = 0; /* */
14609 fis->d.lbaMid = 0x4F; /* 0x4F */
14610 fis->d.lbaHigh = 0xC2; /* 0xC2 */
14611 fis->d.device = 0; /* */
14612 fis->d.lbaLowExp = 0; /* */
14613 fis->d.lbaMidExp = 0; /* */
14614 fis->d.lbaHighExp = 0; /* */
14615 fis->d.featuresExp = 0; /* */
14616 fis->d.sectorCount = 0; /* */
14617 fis->d.sectorCountExp = 0; /* */
14618 fis->d.reserved4 = 0;
14619 fis->d.control = 0; /* FIS HOB bit clear */
14620 fis->d.reserved5 = 0;
14621
14622 agRequestType = AGSA_SATA_PROTOCOL_NON_DATA;
14623
14624 /* Initialize CB for SATA completion.
14625 */
14626 satIOContext->satCompleteCB = &smsatModeSelect6n10CB;
14627
14628 /*
14629 * Prepare SGL and send FIS to LL layer.
14630 */
14631 satIOContext->reqType = agRequestType; /* Save it */
14632
14633 status = smsataLLIOStart( smRoot,
14634 smIORequest,
14635 smDeviceHandle,
14636 smScsiRequest,
14637 satIOContext);
14638 return status;
14639 }
14640 else
14641 {
14642 SM_DBG5(("smsatModeSelect10: disable information exceptions reporting\n"));
14643 /* sends SMART DISABLE OPERATIONS */
14644 fis->h.fisType = 0x27; /* Reg host to device */
14645 fis->h.c_pmPort = 0x80; /* C Bit is set */
14646
14647 fis->h.command = SAT_SMART; /* 0xB0 */
14648 fis->h.features = SAT_SMART_DISABLE_OPERATIONS; /* disable */
14649 fis->d.lbaLow = 0; /* */
14650 fis->d.lbaMid = 0x4F; /* 0x4F */
14651 fis->d.lbaHigh = 0xC2; /* 0xC2 */
14652 fis->d.device = 0; /* */
14653 fis->d.lbaLowExp = 0; /* */
14654 fis->d.lbaMidExp = 0; /* */
14655 fis->d.lbaHighExp = 0; /* */
14656 fis->d.featuresExp = 0; /* */
14657 fis->d.sectorCount = 0; /* */
14658 fis->d.sectorCountExp = 0; /* */
14659 fis->d.reserved4 = 0;
14660 fis->d.control = 0; /* FIS HOB bit clear */
14661 fis->d.reserved5 = 0;
14662
14663 agRequestType = AGSA_SATA_PROTOCOL_NON_DATA;
14664
14665 /* Initialize CB for SATA completion.
14666 */
14667 satIOContext->satCompleteCB = &smsatModeSelect6n10CB;
14668
14669 /*
14670 * Prepare SGL and send FIS to LL layer.
14671 */
14672 satIOContext->reqType = agRequestType; /* Save it */
14673
14674 status = smsataLLIOStart( smRoot,
14675 smIORequest,
14676 smDeviceHandle,
14677 smScsiRequest,
14678 satIOContext);
14679 return status;
14680
14681 }
14682 }
14683 break;
14684 default:
14685 SM_DBG1(("smsatModeSelect10: Error unknown page code 0x%x!!!\n", pLogPage[12]));
14686 smsatSetSensePayload( pSense,
14687 SCSI_SNSKEY_NO_SENSE,
14688 0,
14689 SCSI_SNSCODE_NO_ADDITIONAL_INFO,
14690 satIOContext);
14691
14692 /*smEnqueueIO(smRoot, satIOContext);*/
14693
14694 tdsmIOCompletedCB( smRoot,
14695 smIORequest,
14696 smIOSuccess,
14697 SCSI_STAT_CHECK_CONDITION,
14698 satIOContext->pSmSenseData,
14699 satIOContext->interruptContext );
14700 return SM_RC_SUCCESS;
14701 }
14702 }
14703
14704 osGLOBAL bit32
smsatSynchronizeCache10(smRoot_t * smRoot,smIORequest_t * smIORequest,smDeviceHandle_t * smDeviceHandle,smScsiInitiatorRequest_t * smScsiRequest,smSatIOContext_t * satIOContext)14705 smsatSynchronizeCache10(
14706 smRoot_t *smRoot,
14707 smIORequest_t *smIORequest,
14708 smDeviceHandle_t *smDeviceHandle,
14709 smScsiInitiatorRequest_t *smScsiRequest,
14710 smSatIOContext_t *satIOContext
14711 )
14712 {
14713 bit32 status;
14714 bit32 agRequestType;
14715 smDeviceData_t *pSatDevData;
14716 smScsiRspSense_t *pSense;
14717 smIniScsiCmnd_t *scsiCmnd;
14718 agsaFisRegHostToDevice_t *fis;
14719
14720 pSense = satIOContext->pSense;
14721 pSatDevData = satIOContext->pSatDevData;
14722 scsiCmnd = &smScsiRequest->scsiCmnd;
14723 fis = satIOContext->pFis;
14724
14725 SM_DBG5(("smsatSynchronizeCache10: start\n"));
14726
14727 /* checking CONTROL */
14728 /* NACA == 1 or LINK == 1*/
14729 if ( (scsiCmnd->cdb[9] & SCSI_NACA_MASK) || (scsiCmnd->cdb[9] & SCSI_LINK_MASK) )
14730 {
14731 smsatSetSensePayload( pSense,
14732 SCSI_SNSKEY_ILLEGAL_REQUEST,
14733 0,
14734 SCSI_SNSCODE_INVALID_FIELD_IN_CDB,
14735 satIOContext);
14736
14737 /*smEnqueueIO(smRoot, satIOContext);*/
14738
14739 tdsmIOCompletedCB( smRoot,
14740 smIORequest,
14741 smIOSuccess,
14742 SCSI_STAT_CHECK_CONDITION,
14743 satIOContext->pSmSenseData,
14744 satIOContext->interruptContext );
14745
14746 SM_DBG1(("smsatSynchronizeCache10: return control!!!\n"));
14747 return SM_RC_SUCCESS;
14748 }
14749
14750 /* checking IMMED bit */
14751 if (scsiCmnd->cdb[1] & SCSI_SYNC_CACHE_IMMED_MASK)
14752 {
14753 SM_DBG1(("smsatSynchronizeCache10: GOOD status due to IMMED bit!!!\n"));
14754
14755 /* return GOOD status first here */
14756 tdsmIOCompletedCB( smRoot,
14757 smIORequest,
14758 smIOSuccess,
14759 SCSI_STAT_GOOD,
14760 agNULL,
14761 satIOContext->interruptContext);
14762 }
14763
14764 /* sends FLUSH CACHE or FLUSH CACHE EXT */
14765 if (pSatDevData->sat48BitSupport == agTRUE)
14766 {
14767 SM_DBG5(("smsatSynchronizeCache10: sends FLUSH CACHE EXT\n"));
14768 /* FLUSH CACHE EXT */
14769 fis->h.fisType = 0x27; /* Reg host to device */
14770 fis->h.c_pmPort = 0x80; /* C Bit is set */
14771
14772 fis->h.command = SAT_FLUSH_CACHE_EXT; /* 0xEA */
14773 fis->h.features = 0; /* FIS reserve */
14774 fis->d.featuresExp = 0; /* FIS reserve */
14775 fis->d.sectorCount = 0; /* FIS sector count (7:0) */
14776 fis->d.sectorCountExp = 0; /* FIS sector count (15:8) */
14777 fis->d.lbaLow = 0; /* FIS LBA (7 :0 ) */
14778 fis->d.lbaLowExp = 0; /* FIS LBA (31:24) */
14779 fis->d.lbaMid = 0; /* FIS LBA (15:8 ) */
14780 fis->d.lbaMidExp = 0; /* FIS LBA (39:32) */
14781 fis->d.lbaHigh = 0; /* FIS LBA (23:16) */
14782 fis->d.lbaHighExp = 0; /* FIS LBA (47:40) */
14783 fis->d.device = 0; /* FIS DEV is discared in SATA */
14784 fis->d.control = 0; /* FIS HOB bit clear */
14785 fis->d.reserved4 = 0;
14786 fis->d.reserved5 = 0;
14787
14788 }
14789 else
14790 {
14791 SM_DBG5(("smsatSynchronizeCache10: sends FLUSH CACHE\n"));
14792 /* FLUSH CACHE */
14793 fis->h.fisType = 0x27; /* Reg host to device */
14794 fis->h.c_pmPort = 0x80; /* C Bit is set */
14795
14796 fis->h.command = SAT_FLUSH_CACHE; /* 0xE7 */
14797 fis->h.features = 0; /* FIS features NA */
14798 fis->d.lbaLow = 0; /* FIS LBA (7 :0 ) */
14799 fis->d.lbaMid = 0; /* FIS LBA (15:8 ) */
14800 fis->d.lbaHigh = 0; /* FIS LBA (23:16) */
14801 fis->d.lbaLowExp = 0;
14802 fis->d.lbaMidExp = 0;
14803 fis->d.lbaHighExp = 0;
14804 fis->d.featuresExp = 0;
14805 fis->d.sectorCount = 0; /* FIS sector count (7:0) */
14806 fis->d.sectorCountExp = 0;
14807 fis->d.device = 0; /* FIS DEV is discared in SATA */
14808 fis->d.control = 0; /* FIS HOB bit clear */
14809 fis->d.reserved4 = 0;
14810 fis->d.reserved5 = 0;
14811
14812 }
14813
14814 agRequestType = AGSA_SATA_PROTOCOL_NON_DATA;
14815
14816 /* Initialize CB for SATA completion.
14817 */
14818 satIOContext->satCompleteCB = &smsatSynchronizeCache10n16CB;
14819
14820 /*
14821 * Prepare SGL and send FIS to LL layer.
14822 */
14823 satIOContext->reqType = agRequestType; /* Save it */
14824
14825 status = smsataLLIOStart( smRoot,
14826 smIORequest,
14827 smDeviceHandle,
14828 smScsiRequest,
14829 satIOContext);
14830
14831
14832 return (status);
14833 }
14834
14835 osGLOBAL bit32
smsatSynchronizeCache16(smRoot_t * smRoot,smIORequest_t * smIORequest,smDeviceHandle_t * smDeviceHandle,smScsiInitiatorRequest_t * smScsiRequest,smSatIOContext_t * satIOContext)14836 smsatSynchronizeCache16(
14837 smRoot_t *smRoot,
14838 smIORequest_t *smIORequest,
14839 smDeviceHandle_t *smDeviceHandle,
14840 smScsiInitiatorRequest_t *smScsiRequest,
14841 smSatIOContext_t *satIOContext
14842 )
14843 {
14844 bit32 status;
14845 bit32 agRequestType;
14846 smDeviceData_t *pSatDevData;
14847 smScsiRspSense_t *pSense;
14848 smIniScsiCmnd_t *scsiCmnd;
14849 agsaFisRegHostToDevice_t *fis;
14850
14851 pSense = satIOContext->pSense;
14852 pSatDevData = satIOContext->pSatDevData;
14853 scsiCmnd = &smScsiRequest->scsiCmnd;
14854 fis = satIOContext->pFis;
14855
14856 SM_DBG5(("smsatSynchronizeCache10: start\n"));
14857
14858 /* checking CONTROL */
14859 /* NACA == 1 or LINK == 1*/
14860 if ( (scsiCmnd->cdb[15] & SCSI_NACA_MASK) || (scsiCmnd->cdb[15] & SCSI_LINK_MASK) )
14861 {
14862 smsatSetSensePayload( pSense,
14863 SCSI_SNSKEY_ILLEGAL_REQUEST,
14864 0,
14865 SCSI_SNSCODE_INVALID_FIELD_IN_CDB,
14866 satIOContext);
14867
14868 /*smEnqueueIO(smRoot, satIOContext);*/
14869
14870 tdsmIOCompletedCB( smRoot,
14871 smIORequest,
14872 smIOSuccess,
14873 SCSI_STAT_CHECK_CONDITION,
14874 satIOContext->pSmSenseData,
14875 satIOContext->interruptContext );
14876
14877 SM_DBG1(("smsatSynchronizeCache10: return control!!!\n"));
14878 return SM_RC_SUCCESS;
14879 }
14880
14881
14882 /* checking IMMED bit */
14883 if (scsiCmnd->cdb[1] & SCSI_SYNC_CACHE_IMMED_MASK)
14884 {
14885 SM_DBG1(("smsatSynchronizeCache10: GOOD status due to IMMED bit!!!\n"));
14886
14887 /* return GOOD status first here */
14888 tdsmIOCompletedCB( smRoot,
14889 smIORequest,
14890 smIOSuccess,
14891 SCSI_STAT_GOOD,
14892 agNULL,
14893 satIOContext->interruptContext);
14894 }
14895
14896 /* sends FLUSH CACHE or FLUSH CACHE EXT */
14897 if (pSatDevData->sat48BitSupport == agTRUE)
14898 {
14899 SM_DBG5(("smsatSynchronizeCache10: sends FLUSH CACHE EXT\n"));
14900 /* FLUSH CACHE EXT */
14901 fis->h.fisType = 0x27; /* Reg host to device */
14902 fis->h.c_pmPort = 0x80; /* C Bit is set */
14903
14904 fis->h.command = SAT_FLUSH_CACHE_EXT; /* 0xEA */
14905 fis->h.features = 0; /* FIS reserve */
14906 fis->d.featuresExp = 0; /* FIS reserve */
14907 fis->d.sectorCount = 0; /* FIS sector count (7:0) */
14908 fis->d.sectorCountExp = 0; /* FIS sector count (15:8) */
14909 fis->d.lbaLow = 0; /* FIS LBA (7 :0 ) */
14910 fis->d.lbaLowExp = 0; /* FIS LBA (31:24) */
14911 fis->d.lbaMid = 0; /* FIS LBA (15:8 ) */
14912 fis->d.lbaMidExp = 0; /* FIS LBA (39:32) */
14913 fis->d.lbaHigh = 0; /* FIS LBA (23:16) */
14914 fis->d.lbaHighExp = 0; /* FIS LBA (47:40) */
14915 fis->d.device = 0; /* FIS DEV is discared in SATA */
14916 fis->d.control = 0; /* FIS HOB bit clear */
14917 fis->d.reserved4 = 0;
14918 fis->d.reserved5 = 0;
14919
14920 }
14921 else
14922 {
14923 SM_DBG5(("smsatSynchronizeCache10: sends FLUSH CACHE\n"));
14924 /* FLUSH CACHE */
14925 fis->h.fisType = 0x27; /* Reg host to device */
14926 fis->h.c_pmPort = 0x80; /* C Bit is set */
14927
14928 fis->h.command = SAT_FLUSH_CACHE; /* 0xE7 */
14929 fis->h.features = 0; /* FIS features NA */
14930 fis->d.lbaLow = 0; /* FIS LBA (7 :0 ) */
14931 fis->d.lbaMid = 0; /* FIS LBA (15:8 ) */
14932 fis->d.lbaHigh = 0; /* FIS LBA (23:16) */
14933 fis->d.lbaLowExp = 0;
14934 fis->d.lbaMidExp = 0;
14935 fis->d.lbaHighExp = 0;
14936 fis->d.featuresExp = 0;
14937 fis->d.sectorCount = 0; /* FIS sector count (7:0) */
14938 fis->d.sectorCountExp = 0;
14939 fis->d.device = 0; /* FIS DEV is discared in SATA */
14940 fis->d.control = 0; /* FIS HOB bit clear */
14941 fis->d.reserved4 = 0;
14942 fis->d.reserved5 = 0;
14943
14944 }
14945
14946 agRequestType = AGSA_SATA_PROTOCOL_NON_DATA;
14947
14948 /* Initialize CB for SATA completion.
14949 */
14950 satIOContext->satCompleteCB = &smsatSynchronizeCache10n16CB;
14951
14952 /*
14953 * Prepare SGL and send FIS to LL layer.
14954 */
14955 satIOContext->reqType = agRequestType; /* Save it */
14956
14957 status = smsataLLIOStart( smRoot,
14958 smIORequest,
14959 smDeviceHandle,
14960 smScsiRequest,
14961 satIOContext);
14962
14963
14964 return (status);
14965 }
14966
14967 osGLOBAL bit32
smsatWriteAndVerify10(smRoot_t * smRoot,smIORequest_t * smIORequest,smDeviceHandle_t * smDeviceHandle,smScsiInitiatorRequest_t * smScsiRequest,smSatIOContext_t * satIOContext)14968 smsatWriteAndVerify10(
14969 smRoot_t *smRoot,
14970 smIORequest_t *smIORequest,
14971 smDeviceHandle_t *smDeviceHandle,
14972 smScsiInitiatorRequest_t *smScsiRequest,
14973 smSatIOContext_t *satIOContext
14974 )
14975 {
14976 /*
14977 combination of write10 and verify10
14978 */
14979
14980 bit32 status;
14981 bit32 agRequestType = AGSA_SATA_PROTOCOL_DMA_WRITE;
14982 smDeviceData_t *pSatDevData;
14983 smScsiRspSense_t *pSense;
14984 smIniScsiCmnd_t *scsiCmnd;
14985 agsaFisRegHostToDevice_t *fis;
14986 bit32 lba = 0;
14987 bit32 tl = 0;
14988 bit32 LoopNum = 1;
14989 bit8 LBA[8];
14990 bit8 TL[8];
14991 bit32 AllChk = agFALSE; /* lba, lba+tl check against ATA limit and Disk capacity */
14992
14993 pSense = satIOContext->pSense;
14994 pSatDevData = satIOContext->pSatDevData;
14995 scsiCmnd = &smScsiRequest->scsiCmnd;
14996 fis = satIOContext->pFis;
14997
14998 SM_DBG5(("smsatWriteAndVerify10: start\n"));
14999
15000 /* checking BYTCHK bit */
15001 if (scsiCmnd->cdb[1] & SCSI_WRITE_N_VERIFY_BYTCHK_MASK)
15002 {
15003 smsatSetSensePayload( pSense,
15004 SCSI_SNSKEY_ILLEGAL_REQUEST,
15005 0,
15006 SCSI_SNSCODE_INVALID_FIELD_IN_CDB,
15007 satIOContext);
15008
15009 /*smEnqueueIO(smRoot, satIOContext);*/
15010
15011 tdsmIOCompletedCB( smRoot,
15012 smIORequest,
15013 smIOSuccess,
15014 SCSI_STAT_CHECK_CONDITION,
15015 satIOContext->pSmSenseData,
15016 satIOContext->interruptContext );
15017
15018 SM_DBG1(("smsatWriteAndVerify10: BYTCHK bit checking!!!\n"));
15019 return SM_RC_SUCCESS;
15020 }
15021
15022
15023 /* checking CONTROL */
15024 /* NACA == 1 or LINK == 1*/
15025 if ( (scsiCmnd->cdb[9] & SCSI_NACA_MASK) || (scsiCmnd->cdb[9] & SCSI_LINK_MASK) )
15026 {
15027 smsatSetSensePayload( pSense,
15028 SCSI_SNSKEY_ILLEGAL_REQUEST,
15029 0,
15030 SCSI_SNSCODE_INVALID_FIELD_IN_CDB,
15031 satIOContext);
15032
15033 /*smEnqueueIO(smRoot, satIOContext);*/
15034
15035 tdsmIOCompletedCB( smRoot,
15036 smIORequest,
15037 smIOSuccess,
15038 SCSI_STAT_CHECK_CONDITION,
15039 satIOContext->pSmSenseData,
15040 satIOContext->interruptContext );
15041
15042 SM_DBG1(("smsatWriteAndVerify10: return control!!!\n"));
15043 return SM_RC_SUCCESS;
15044 }
15045
15046 sm_memset(LBA, 0, sizeof(LBA));
15047 sm_memset(TL, 0, sizeof(TL));
15048
15049 /* do not use memcpy due to indexing in LBA and TL */
15050 LBA[0] = 0; /* MSB */
15051 LBA[1] = 0;
15052 LBA[2] = 0;
15053 LBA[3] = 0;
15054 LBA[4] = scsiCmnd->cdb[2];
15055 LBA[5] = scsiCmnd->cdb[3];
15056 LBA[6] = scsiCmnd->cdb[4];
15057 LBA[7] = scsiCmnd->cdb[5]; /* LSB */
15058
15059 TL[0] = 0;
15060 TL[1] = 0;
15061 TL[2] = 0;
15062 TL[3] = 0;
15063 TL[4] = 0;
15064 TL[5] = 0;
15065 TL[6] = scsiCmnd->cdb[7];
15066 TL[7] = scsiCmnd->cdb[8]; /* LSB */
15067
15068
15069 /* cbd10; computing LBA and transfer length */
15070 lba = (scsiCmnd->cdb[2] << (8*3)) + (scsiCmnd->cdb[3] << (8*2))
15071 + (scsiCmnd->cdb[4] << 8) + scsiCmnd->cdb[5];
15072 tl = (scsiCmnd->cdb[7] << 8) + scsiCmnd->cdb[8];
15073
15074
15075 /* Table 34, 9.1, p 46 */
15076 /*
15077 note: As of 2/10/2006, no support for DMA QUEUED
15078 */
15079
15080 /*
15081 Table 34, 9.1, p 46, b
15082 When no 48-bit addressing support or NCQ, if LBA is beyond (2^28 - 1),
15083 return check condition
15084 */
15085 if (pSatDevData->satNCQ != agTRUE &&
15086 pSatDevData->sat48BitSupport != agTRUE
15087 )
15088 {
15089 AllChk = smsatCheckLimit(LBA, TL, agFALSE, pSatDevData);
15090 if (AllChk)
15091 {
15092 SM_DBG1(("smsatWriteAndVerify10: return LBA out of range!!!\n"));
15093 smsatSetSensePayload( pSense,
15094 SCSI_SNSKEY_ILLEGAL_REQUEST,
15095 0,
15096 SCSI_SNSCODE_LOGICAL_BLOCK_ADDRESS_OUT_OF_RANGE,
15097 satIOContext);
15098
15099 /*smEnqueueIO(smRoot, satIOContext);*/
15100
15101 tdsmIOCompletedCB( smRoot,
15102 smIORequest,
15103 smIOSuccess,
15104 SCSI_STAT_CHECK_CONDITION,
15105 satIOContext->pSmSenseData,
15106 satIOContext->interruptContext );
15107
15108 return SM_RC_SUCCESS;
15109 }
15110 }
15111 else
15112 {
15113 AllChk = smsatCheckLimit(LBA, TL, agTRUE, pSatDevData);
15114 if (AllChk)
15115 {
15116 SM_DBG1(("smsatWriteAndVerify10: return LBA out of range, EXT!!!\n"));
15117 smsatSetSensePayload( pSense,
15118 SCSI_SNSKEY_ILLEGAL_REQUEST,
15119 0,
15120 SCSI_SNSCODE_LOGICAL_BLOCK_ADDRESS_OUT_OF_RANGE,
15121 satIOContext);
15122
15123 /*smEnqueueIO(smRoot, satIOContext);*/
15124
15125 tdsmIOCompletedCB( smRoot,
15126 smIORequest,
15127 smIOSuccess,
15128 SCSI_STAT_CHECK_CONDITION,
15129 satIOContext->pSmSenseData,
15130 satIOContext->interruptContext );
15131
15132 return SM_RC_SUCCESS;
15133 }
15134 }
15135
15136
15137 /* case 1 and 2 */
15138 if (pSatDevData->satDMASupport == agTRUE && pSatDevData->satDMAEnabled == agTRUE)
15139 {
15140 /* case 2 */
15141 /* WRITE DMA*/
15142 /* can't fit the transfer length */
15143 SM_DBG5(("smsatWriteAndVerify10: case 2\n"));
15144 fis->h.fisType = 0x27; /* Reg host to device */
15145 fis->h.c_pmPort = 0x80; /* C bit is set */
15146 fis->h.command = SAT_WRITE_DMA; /* 0xCA */
15147 fis->h.features = 0; /* FIS reserve */
15148 fis->d.lbaLow = scsiCmnd->cdb[5]; /* FIS LBA (7 :0 ) */
15149 fis->d.lbaMid = scsiCmnd->cdb[4]; /* FIS LBA (15:8 ) */
15150 fis->d.lbaHigh = scsiCmnd->cdb[3]; /* FIS LBA (23:16) */
15151
15152 /* FIS LBA mode set LBA (27:24) */
15153 fis->d.device = (bit8)((0x4 << 4) | (scsiCmnd->cdb[2] & 0xF));
15154
15155 fis->d.lbaLowExp = 0;
15156 fis->d.lbaMidExp = 0;
15157 fis->d.lbaHighExp = 0;
15158 fis->d.featuresExp = 0;
15159 fis->d.sectorCount = scsiCmnd->cdb[8]; /* FIS sector count (7:0) */
15160 fis->d.sectorCountExp = 0;
15161 fis->d.reserved4 = 0;
15162 fis->d.control = 0; /* FIS HOB bit clear */
15163 fis->d.reserved5 = 0;
15164
15165 agRequestType = AGSA_SATA_PROTOCOL_DMA_WRITE;
15166 satIOContext->ATACmd = SAT_WRITE_DMA;
15167 }
15168 else
15169 {
15170 /* case 1 */
15171 /* WRITE MULTIPLE or WRITE SECTOR(S) */
15172 /* WRITE SECTORS for easier implemetation */
15173 /* can't fit the transfer length */
15174 SM_DBG5(("smsatWriteAndVerify10: case 1\n"));
15175 fis->h.fisType = 0x27; /* Reg host to device */
15176 fis->h.c_pmPort = 0x80; /* C bit is set */
15177 fis->h.command = SAT_WRITE_SECTORS; /* 0x30 */
15178 fis->h.features = 0; /* FIS reserve */
15179 fis->d.lbaLow = scsiCmnd->cdb[5]; /* FIS LBA (7 :0 ) */
15180 fis->d.lbaMid = scsiCmnd->cdb[4]; /* FIS LBA (15:8 ) */
15181 fis->d.lbaHigh = scsiCmnd->cdb[3]; /* FIS LBA (23:16) */
15182
15183 /* FIS LBA mode set LBA (27:24) */
15184 fis->d.device = (bit8)((0x4 << 4) | (scsiCmnd->cdb[2] & 0xF));
15185
15186 fis->d.lbaLowExp = 0;
15187 fis->d.lbaMidExp = 0;
15188 fis->d.lbaHighExp = 0;
15189 fis->d.featuresExp = 0;
15190 fis->d.sectorCount = scsiCmnd->cdb[8]; /* FIS sector count (7:0) */
15191 fis->d.sectorCountExp = 0;
15192 fis->d.reserved4 = 0;
15193 fis->d.control = 0; /* FIS HOB bit clear */
15194 fis->d.reserved5 = 0;
15195
15196 agRequestType = AGSA_SATA_PROTOCOL_PIO_WRITE;
15197 satIOContext->ATACmd = SAT_WRITE_SECTORS;
15198
15199 }
15200
15201 /* case 3 and 4 */
15202 if (pSatDevData->sat48BitSupport == agTRUE)
15203 {
15204 if (pSatDevData->satDMASupport == agTRUE && pSatDevData->satDMAEnabled == agTRUE)
15205 {
15206 /* case 3 */
15207 /* WRITE DMA EXT or WRITE DMA FUA EXT */
15208 SM_DBG5(("smsatWriteAndVerify10: case 3\n"));
15209 fis->h.fisType = 0x27; /* Reg host to device */
15210 fis->h.c_pmPort = 0x80; /* C Bit is set */
15211
15212 /* SAT_WRITE_DMA_FUA_EXT is optional and we don't support it */
15213 fis->h.command = SAT_WRITE_DMA_EXT; /* 0x35 */
15214
15215 fis->h.features = 0; /* FIS reserve */
15216 fis->d.lbaLow = scsiCmnd->cdb[5]; /* FIS LBA (7 :0 ) */
15217 fis->d.lbaMid = scsiCmnd->cdb[4]; /* FIS LBA (15:8 ) */
15218 fis->d.lbaHigh = scsiCmnd->cdb[3]; /* FIS LBA (23:16) */
15219 fis->d.device = 0x40; /* FIS LBA mode set */
15220 fis->d.lbaLowExp = scsiCmnd->cdb[2]; /* FIS LBA (31:24) */
15221 fis->d.lbaMidExp = 0; /* FIS LBA (39:32) */
15222 fis->d.lbaHighExp = 0; /* FIS LBA (47:40) */
15223 fis->d.featuresExp = 0; /* FIS reserve */
15224 fis->d.sectorCount = scsiCmnd->cdb[8]; /* FIS sector count (7:0) */
15225 fis->d.sectorCountExp = scsiCmnd->cdb[7]; /* FIS sector count (15:8) */
15226 fis->d.reserved4 = 0;
15227 fis->d.control = 0; /* FIS HOB bit clear */
15228 fis->d.reserved5 = 0;
15229
15230 agRequestType = AGSA_SATA_PROTOCOL_DMA_WRITE;
15231 satIOContext->ATACmd = SAT_WRITE_DMA_EXT;
15232 }
15233 else
15234 {
15235 /* case 4 */
15236 /* WRITE MULTIPLE EXT or WRITE MULTIPLE FUA EXT or WRITE SECTOR(S) EXT */
15237 /* WRITE SECTORS EXT for easier implemetation */
15238 SM_DBG5(("smsatWriteAndVerify10: case 4\n"));
15239 fis->h.fisType = 0x27; /* Reg host to device */
15240 fis->h.c_pmPort = 0x80; /* C Bit is set */
15241 fis->h.command = SAT_WRITE_SECTORS_EXT; /* 0x34 */
15242
15243 fis->h.features = 0; /* FIS reserve */
15244 fis->d.lbaLow = scsiCmnd->cdb[5]; /* FIS LBA (7 :0 ) */
15245 fis->d.lbaMid = scsiCmnd->cdb[4]; /* FIS LBA (15:8 ) */
15246 fis->d.lbaHigh = scsiCmnd->cdb[3]; /* FIS LBA (23:16) */
15247 fis->d.device = 0x40; /* FIS LBA mode set */
15248 fis->d.lbaLowExp = scsiCmnd->cdb[2]; /* FIS LBA (31:24) */
15249 fis->d.lbaMidExp = 0; /* FIS LBA (39:32) */
15250 fis->d.lbaHighExp = 0; /* FIS LBA (47:40) */
15251 fis->d.featuresExp = 0; /* FIS reserve */
15252 fis->d.sectorCount = scsiCmnd->cdb[8]; /* FIS sector count (7:0) */
15253 fis->d.sectorCountExp = scsiCmnd->cdb[7]; /* FIS sector count (15:8) */
15254 fis->d.reserved4 = 0;
15255 fis->d.control = 0; /* FIS HOB bit clear */
15256 fis->d.reserved5 = 0;
15257
15258 agRequestType = AGSA_SATA_PROTOCOL_PIO_WRITE;
15259 satIOContext->ATACmd = SAT_WRITE_SECTORS_EXT;
15260 }
15261 }
15262 /* case 5 */
15263 if (pSatDevData->satNCQ == agTRUE)
15264 {
15265 /* WRITE FPDMA QUEUED */
15266 if (pSatDevData->sat48BitSupport != agTRUE)
15267 {
15268 SM_DBG1(("smsatWriteAndVerify10: case 5 !!! error NCQ but 28 bit address support!!!\n"));
15269 smsatSetSensePayload( pSense,
15270 SCSI_SNSKEY_ILLEGAL_REQUEST,
15271 0,
15272 SCSI_SNSCODE_INVALID_FIELD_IN_CDB,
15273 satIOContext);
15274
15275 /*smEnqueueIO(smRoot, satIOContext);*/
15276
15277 tdsmIOCompletedCB( smRoot,
15278 smIORequest,
15279 smIOSuccess,
15280 SCSI_STAT_CHECK_CONDITION,
15281 satIOContext->pSmSenseData,
15282 satIOContext->interruptContext );
15283 return SM_RC_SUCCESS;
15284 }
15285 SM_DBG5(("smsatWriteAndVerify10: case 5\n"));
15286
15287 /* Support 48-bit FPDMA addressing, use WRITE FPDMA QUEUE command */
15288
15289 fis->h.fisType = 0x27; /* Reg host to device */
15290 fis->h.c_pmPort = 0x80; /* C Bit is set */
15291 fis->h.command = SAT_WRITE_FPDMA_QUEUED; /* 0x61 */
15292 fis->h.features = scsiCmnd->cdb[8]; /* FIS sector count (7:0) */
15293 fis->d.lbaLow = scsiCmnd->cdb[5]; /* FIS LBA (7 :0 ) */
15294 fis->d.lbaMid = scsiCmnd->cdb[4]; /* FIS LBA (15:8 ) */
15295 fis->d.lbaHigh = scsiCmnd->cdb[3]; /* FIS LBA (23:16) */
15296
15297 /* Check FUA bit */
15298 if (scsiCmnd->cdb[1] & SCSI_WRITE_N_VERIFY10_FUA_MASK)
15299 fis->d.device = 0xC0; /* FIS FUA set */
15300 else
15301 fis->d.device = 0x40; /* FIS FUA clear */
15302
15303 fis->d.lbaLowExp = scsiCmnd->cdb[2]; /* FIS LBA (31:24) */
15304 fis->d.lbaMidExp = 0; /* FIS LBA (39:32) */
15305 fis->d.lbaHighExp = 0; /* FIS LBA (47:40) */
15306 fis->d.featuresExp = scsiCmnd->cdb[7]; /* FIS sector count (15:8) */
15307 fis->d.sectorCount = 0; /* Tag (7:3) set by LL layer */
15308 fis->d.sectorCountExp = 0;
15309 fis->d.reserved4 = 0;
15310 fis->d.control = 0; /* FIS HOB bit clear */
15311 fis->d.reserved5 = 0;
15312
15313 agRequestType = AGSA_SATA_PROTOCOL_FPDMA_WRITE;
15314 satIOContext->ATACmd = SAT_WRITE_FPDMA_QUEUED;
15315 }
15316
15317 satIOContext->currentLBA = lba;
15318 satIOContext->OrgTL = tl;
15319
15320 /*
15321 computing number of loop and remainder for tl
15322 0xFF in case not ext
15323 0xFFFF in case EXT
15324 */
15325 if (fis->h.command == SAT_WRITE_SECTORS || fis->h.command == SAT_WRITE_DMA)
15326 {
15327 LoopNum = smsatComputeLoopNum(tl, 0xFF);
15328 }
15329 else if (fis->h.command == SAT_WRITE_SECTORS_EXT ||
15330 fis->h.command == SAT_WRITE_DMA_EXT ||
15331 fis->h.command == SAT_WRITE_DMA_FUA_EXT
15332 )
15333 {
15334 /* SAT_READ_SECTORS_EXT, SAT_READ_DMA_EXT */
15335 LoopNum = smsatComputeLoopNum(tl, 0xFFFF);
15336 }
15337 else
15338 {
15339 /* SAT_WRITE_FPDMA_QUEUED */
15340 LoopNum = smsatComputeLoopNum(tl, 0xFFFF);
15341 }
15342
15343 satIOContext->LoopNum = LoopNum;
15344
15345
15346 if (LoopNum == 1)
15347 {
15348 SM_DBG5(("smsatWriteAndVerify10: NON CHAINED data\n"));
15349 /* Initialize CB for SATA completion.
15350 */
15351 satIOContext->satCompleteCB = &smsatNonChainedWriteNVerifyCB;
15352 }
15353 else
15354 {
15355 SM_DBG1(("smsatWriteAndVerify10: CHAINED data!!!\n"));
15356 /* re-setting tl */
15357 if (fis->h.command == SAT_WRITE_SECTORS || fis->h.command == SAT_WRITE_DMA)
15358 {
15359 fis->d.sectorCount = 0xFF;
15360 }
15361 else if (fis->h.command == SAT_WRITE_SECTORS_EXT ||
15362 fis->h.command == SAT_WRITE_DMA_EXT ||
15363 fis->h.command == SAT_WRITE_DMA_FUA_EXT
15364 )
15365 {
15366 fis->d.sectorCount = 0xFF;
15367 fis->d.sectorCountExp = 0xFF;
15368 }
15369 else
15370 {
15371 /* SAT_WRITE_FPDMA_QUEUED */
15372 fis->h.features = 0xFF;
15373 fis->d.featuresExp = 0xFF;
15374 }
15375
15376 /* Initialize CB for SATA completion.
15377 */
15378 satIOContext->satCompleteCB = &smsatChainedWriteNVerifyCB;
15379 }
15380
15381
15382 /*
15383 * Prepare SGL and send FIS to LL layer.
15384 */
15385 satIOContext->reqType = agRequestType; /* Save it */
15386
15387 status = smsataLLIOStart( smRoot,
15388 smIORequest,
15389 smDeviceHandle,
15390 smScsiRequest,
15391 satIOContext);
15392 return (status);
15393
15394 }
15395
15396 osGLOBAL bit32
smsatWriteAndVerify12(smRoot_t * smRoot,smIORequest_t * smIORequest,smDeviceHandle_t * smDeviceHandle,smScsiInitiatorRequest_t * smScsiRequest,smSatIOContext_t * satIOContext)15397 smsatWriteAndVerify12(
15398 smRoot_t *smRoot,
15399 smIORequest_t *smIORequest,
15400 smDeviceHandle_t *smDeviceHandle,
15401 smScsiInitiatorRequest_t *smScsiRequest,
15402 smSatIOContext_t *satIOContext
15403 )
15404 {
15405 /*
15406 combination of write12 and verify12
15407 temp: since write12 is not support (due to internal checking), no support
15408 */
15409 bit32 status;
15410 bit32 agRequestType = AGSA_SATA_PROTOCOL_DMA_WRITE;
15411 smDeviceData_t *pSatDevData;
15412 smScsiRspSense_t *pSense;
15413 smIniScsiCmnd_t *scsiCmnd;
15414 agsaFisRegHostToDevice_t *fis;
15415 bit32 lba = 0;
15416 bit32 tl = 0;
15417 bit32 LoopNum = 1;
15418 bit8 LBA[8];
15419 bit8 TL[8];
15420 bit32 AllChk = agFALSE; /* lba, lba+tl check against ATA limit and Disk capacity */
15421
15422 pSense = satIOContext->pSense;
15423 pSatDevData = satIOContext->pSatDevData;
15424 scsiCmnd = &smScsiRequest->scsiCmnd;
15425 fis = satIOContext->pFis;
15426
15427 SM_DBG5(("smsatWriteAndVerify12: start\n"));
15428
15429 /* checking BYTCHK bit */
15430 if (scsiCmnd->cdb[1] & SCSI_WRITE_N_VERIFY_BYTCHK_MASK)
15431 {
15432 smsatSetSensePayload( pSense,
15433 SCSI_SNSKEY_ILLEGAL_REQUEST,
15434 0,
15435 SCSI_SNSCODE_INVALID_FIELD_IN_CDB,
15436 satIOContext);
15437
15438 /*smEnqueueIO(smRoot, satIOContext);*/
15439
15440 tdsmIOCompletedCB( smRoot,
15441 smIORequest,
15442 smIOSuccess,
15443 SCSI_STAT_CHECK_CONDITION,
15444 satIOContext->pSmSenseData,
15445 satIOContext->interruptContext );
15446
15447 SM_DBG1(("smsatWriteAndVerify12: BYTCHK bit checking!!!\n"));
15448 return SM_RC_SUCCESS;
15449 }
15450
15451 /* checking CONTROL */
15452 /* NACA == 1 or LINK == 1*/
15453 if ( (scsiCmnd->cdb[11] & SCSI_NACA_MASK) || (scsiCmnd->cdb[11] & SCSI_LINK_MASK) )
15454 {
15455 smsatSetSensePayload( pSense,
15456 SCSI_SNSKEY_ILLEGAL_REQUEST,
15457 0,
15458 SCSI_SNSCODE_INVALID_FIELD_IN_CDB,
15459 satIOContext);
15460
15461 /*smEnqueueIO(smRoot, satIOContext);*/
15462
15463 tdsmIOCompletedCB( smRoot,
15464 smIORequest,
15465 smIOSuccess,
15466 SCSI_STAT_CHECK_CONDITION,
15467 satIOContext->pSmSenseData,
15468 satIOContext->interruptContext );
15469
15470 SM_DBG1(("smsatWriteAndVerify12: return control!!!\n"));
15471 return SM_RC_SUCCESS;
15472 }
15473
15474 sm_memset(LBA, 0, sizeof(LBA));
15475 sm_memset(TL, 0, sizeof(TL));
15476
15477 /* do not use memcpy due to indexing in LBA and TL */
15478 LBA[0] = 0; /* MSB */
15479 LBA[1] = 0;
15480 LBA[2] = 0;
15481 LBA[3] = 0;
15482 LBA[4] = scsiCmnd->cdb[2];
15483 LBA[5] = scsiCmnd->cdb[3];
15484 LBA[6] = scsiCmnd->cdb[4];
15485 LBA[7] = scsiCmnd->cdb[5]; /* LSB */
15486
15487 TL[0] = 0; /* MSB */
15488 TL[1] = 0;
15489 TL[2] = 0;
15490 TL[3] = 0;
15491 TL[4] = scsiCmnd->cdb[6];
15492 TL[5] = scsiCmnd->cdb[7];
15493 TL[6] = scsiCmnd->cdb[8];
15494 TL[7] = scsiCmnd->cdb[9]; /* LSB */
15495
15496
15497 lba = smsatComputeCDB12LBA(satIOContext);
15498 tl = smsatComputeCDB12TL(satIOContext);
15499
15500
15501 /* Table 34, 9.1, p 46 */
15502 /*
15503 note: As of 2/10/2006, no support for DMA QUEUED
15504 */
15505
15506 /*
15507 Table 34, 9.1, p 46, b
15508 When no 48-bit addressing support or NCQ, if LBA is beyond (2^28 - 1),
15509 return check condition
15510 */
15511 if (pSatDevData->satNCQ != agTRUE &&
15512 pSatDevData->sat48BitSupport != agTRUE
15513 )
15514 {
15515 AllChk = smsatCheckLimit(LBA, TL, agFALSE, pSatDevData);
15516 if (AllChk)
15517 {
15518
15519 /*smEnqueueIO(smRoot, satIOContext);*/
15520
15521
15522 SM_DBG1(("smsatWriteAndVerify12: return LBA out of range, not EXT!!!\n"));
15523
15524 smsatSetSensePayload( pSense,
15525 SCSI_SNSKEY_ILLEGAL_REQUEST,
15526 0,
15527 SCSI_SNSCODE_LOGICAL_BLOCK_ADDRESS_OUT_OF_RANGE,
15528 satIOContext);
15529
15530 /*smEnqueueIO(smRoot, satIOContext);*/
15531
15532 tdsmIOCompletedCB( smRoot,
15533 smIORequest,
15534 smIOSuccess,
15535 SCSI_STAT_CHECK_CONDITION,
15536 satIOContext->pSmSenseData,
15537 satIOContext->interruptContext );
15538
15539 return SM_RC_SUCCESS;
15540 }
15541 }
15542 else
15543 {
15544 AllChk = smsatCheckLimit(LBA, TL, agTRUE, pSatDevData);
15545 if (AllChk)
15546 {
15547 SM_DBG1(("smsatWriteAndVerify12: return LBA out of range, EXT!!!\n"));
15548 smsatSetSensePayload( pSense,
15549 SCSI_SNSKEY_ILLEGAL_REQUEST,
15550 0,
15551 SCSI_SNSCODE_LOGICAL_BLOCK_ADDRESS_OUT_OF_RANGE,
15552 satIOContext);
15553 tdsmIOCompletedCB( smRoot,
15554 smIORequest,
15555 smIOSuccess,
15556 SCSI_STAT_CHECK_CONDITION,
15557 satIOContext->pSmSenseData,
15558 satIOContext->interruptContext );
15559 return SM_RC_SUCCESS;
15560 }
15561 }
15562 if (pSatDevData->satDMASupport == agTRUE && pSatDevData->satDMAEnabled == agTRUE)
15563 {
15564 /* case 2 */
15565 /* WRITE DMA*/
15566 /* In case that we can't fit the transfer length, we loop */
15567 SM_DBG5(("smsatWriteAndVerify12: case 2\n"));
15568 fis->h.fisType = 0x27; /* Reg host to device */
15569 fis->h.c_pmPort = 0x80; /* C bit is set */
15570 fis->h.command = SAT_WRITE_DMA; /* 0xCA */
15571 fis->h.features = 0; /* FIS reserve */
15572 fis->d.lbaLow = scsiCmnd->cdb[5]; /* FIS LBA (7 :0 ) */
15573 fis->d.lbaMid = scsiCmnd->cdb[4]; /* FIS LBA (15:8 ) */
15574 fis->d.lbaHigh = scsiCmnd->cdb[3]; /* FIS LBA (23:16) */
15575
15576 /* FIS LBA mode set LBA (27:24) */
15577 fis->d.device = (bit8)((0x4 << 4) | (scsiCmnd->cdb[2] & 0xF));
15578
15579 fis->d.lbaLowExp = 0;
15580 fis->d.lbaMidExp = 0;
15581 fis->d.lbaHighExp = 0;
15582 fis->d.featuresExp = 0;
15583 fis->d.sectorCount = scsiCmnd->cdb[9]; /* FIS sector count (7:0) */
15584 fis->d.sectorCountExp = 0;
15585 fis->d.reserved4 = 0;
15586 fis->d.control = 0; /* FIS HOB bit clear */
15587 fis->d.reserved5 = 0;
15588
15589 agRequestType = AGSA_SATA_PROTOCOL_DMA_WRITE;
15590 satIOContext->ATACmd = SAT_WRITE_DMA;
15591 }
15592 else
15593 {
15594 /* case 1 */
15595 /* WRITE MULTIPLE or WRITE SECTOR(S) */
15596 /* WRITE SECTORS for easier implemetation */
15597 /* In case that we can't fit the transfer length, we loop */
15598 SM_DBG5(("smsatWriteAndVerify12: case 1\n"));
15599 fis->h.fisType = 0x27; /* Reg host to device */
15600 fis->h.c_pmPort = 0x80; /* C bit is set */
15601 fis->h.command = SAT_WRITE_SECTORS; /* 0x30 */
15602 fis->h.features = 0; /* FIS reserve */
15603 fis->d.lbaLow = scsiCmnd->cdb[5]; /* FIS LBA (7 :0 ) */
15604 fis->d.lbaMid = scsiCmnd->cdb[4]; /* FIS LBA (15:8 ) */
15605 fis->d.lbaHigh = scsiCmnd->cdb[3]; /* FIS LBA (23:16) */
15606
15607 /* FIS LBA mode set LBA (27:24) */
15608 fis->d.device = (bit8)((0x4 << 4) | (scsiCmnd->cdb[2] & 0xF));
15609
15610 fis->d.lbaLowExp = 0;
15611 fis->d.lbaMidExp = 0;
15612 fis->d.lbaHighExp = 0;
15613 fis->d.featuresExp = 0;
15614 fis->d.sectorCount = scsiCmnd->cdb[9]; /* FIS sector count (7:0) */
15615 fis->d.sectorCountExp = 0;
15616 fis->d.reserved4 = 0;
15617 fis->d.control = 0; /* FIS HOB bit clear */
15618 fis->d.reserved5 = 0;
15619
15620 agRequestType = AGSA_SATA_PROTOCOL_PIO_WRITE;
15621 satIOContext->ATACmd = SAT_WRITE_SECTORS;
15622 }
15623
15624 /* case 3 and 4 */
15625 if (pSatDevData->sat48BitSupport == agTRUE)
15626 {
15627 if (pSatDevData->satDMASupport == agTRUE && pSatDevData->satDMAEnabled == agTRUE)
15628 {
15629 /* case 3 */
15630 /* WRITE DMA EXT or WRITE DMA FUA EXT */
15631 SM_DBG5(("smsatWriteAndVerify12: case 3\n"));
15632 fis->h.fisType = 0x27; /* Reg host to device */
15633 fis->h.c_pmPort = 0x80; /* C Bit is set */
15634
15635 /* SAT_WRITE_DMA_FUA_EXT is optional and we don't support it */
15636 fis->h.command = SAT_WRITE_DMA_EXT; /* 0x35 */
15637
15638 fis->h.features = 0; /* FIS reserve */
15639 fis->d.lbaLow = scsiCmnd->cdb[5]; /* FIS LBA (7 :0 ) */
15640 fis->d.lbaMid = scsiCmnd->cdb[4]; /* FIS LBA (15:8 ) */
15641 fis->d.lbaHigh = scsiCmnd->cdb[3]; /* FIS LBA (23:16) */
15642 fis->d.device = 0x40; /* FIS LBA mode set */
15643 fis->d.lbaLowExp = scsiCmnd->cdb[2]; /* FIS LBA (31:24) */
15644 fis->d.lbaMidExp = 0; /* FIS LBA (39:32) */
15645 fis->d.lbaHighExp = 0; /* FIS LBA (47:40) */
15646 fis->d.featuresExp = 0; /* FIS reserve */
15647 fis->d.sectorCount = scsiCmnd->cdb[9]; /* FIS sector count (7:0) */
15648 fis->d.sectorCountExp = scsiCmnd->cdb[8]; /* FIS sector count (15:8) */
15649 fis->d.reserved4 = 0;
15650 fis->d.control = 0; /* FIS HOB bit clear */
15651 fis->d.reserved5 = 0;
15652
15653 agRequestType = AGSA_SATA_PROTOCOL_DMA_WRITE;
15654 satIOContext->ATACmd = SAT_WRITE_DMA_EXT;
15655 }
15656 else
15657 {
15658 /* case 4 */
15659 /* WRITE MULTIPLE EXT or WRITE MULTIPLE FUA EXT or WRITE SECTOR(S) EXT */
15660 /* WRITE SECTORS EXT for easier implemetation */
15661 SM_DBG5(("smsatWriteAndVerify12: case 4\n"));
15662 fis->h.fisType = 0x27; /* Reg host to device */
15663 fis->h.c_pmPort = 0x80; /* C Bit is set */
15664 fis->h.command = SAT_WRITE_SECTORS_EXT; /* 0x34 */
15665
15666 fis->h.features = 0; /* FIS reserve */
15667 fis->d.lbaLow = scsiCmnd->cdb[5]; /* FIS LBA (7 :0 ) */
15668 fis->d.lbaMid = scsiCmnd->cdb[4]; /* FIS LBA (15:8 ) */
15669 fis->d.lbaHigh = scsiCmnd->cdb[3]; /* FIS LBA (23:16) */
15670 fis->d.device = 0x40; /* FIS LBA mode set */
15671 fis->d.lbaLowExp = scsiCmnd->cdb[2]; /* FIS LBA (31:24) */
15672 fis->d.lbaMidExp = 0; /* FIS LBA (39:32) */
15673 fis->d.lbaHighExp = 0; /* FIS LBA (47:40) */
15674 fis->d.featuresExp = 0; /* FIS reserve */
15675 fis->d.sectorCount = scsiCmnd->cdb[9]; /* FIS sector count (7:0) */
15676 fis->d.sectorCountExp = scsiCmnd->cdb[8]; /* FIS sector count (15:8) */
15677 fis->d.reserved4 = 0;
15678 fis->d.control = 0; /* FIS HOB bit clear */
15679 fis->d.reserved5 = 0;
15680
15681 agRequestType = AGSA_SATA_PROTOCOL_PIO_WRITE;
15682 satIOContext->ATACmd = SAT_WRITE_SECTORS_EXT;
15683 }
15684 }
15685
15686 /* case 5 */
15687 if (pSatDevData->satNCQ == agTRUE)
15688 {
15689 /* WRITE FPDMA QUEUED */
15690 if (pSatDevData->sat48BitSupport != agTRUE)
15691 {
15692 SM_DBG1(("smsatWriteAndVerify12: case 5 !!! error NCQ but 28 bit address support!!!\n"));
15693 smsatSetSensePayload( pSense,
15694 SCSI_SNSKEY_ILLEGAL_REQUEST,
15695 0,
15696 SCSI_SNSCODE_INVALID_FIELD_IN_CDB,
15697 satIOContext);
15698
15699 /*smEnqueueIO(smRoot, satIOContext);*/
15700
15701 tdsmIOCompletedCB( smRoot,
15702 smIORequest,
15703 smIOSuccess,
15704 SCSI_STAT_CHECK_CONDITION,
15705 satIOContext->pSmSenseData,
15706 satIOContext->interruptContext );
15707 return SM_RC_SUCCESS;
15708 }
15709 SM_DBG6(("smsatWriteAndVerify12: case 5\n"));
15710
15711 /* Support 48-bit FPDMA addressing, use WRITE FPDMA QUEUE command */
15712
15713 fis->h.fisType = 0x27; /* Reg host to device */
15714 fis->h.c_pmPort = 0x80; /* C Bit is set */
15715 fis->h.command = SAT_WRITE_FPDMA_QUEUED; /* 0x61 */
15716 fis->h.features = scsiCmnd->cdb[9]; /* FIS sector count (7:0) */
15717 fis->d.lbaLow = scsiCmnd->cdb[5]; /* FIS LBA (7 :0 ) */
15718 fis->d.lbaMid = scsiCmnd->cdb[4]; /* FIS LBA (15:8 ) */
15719 fis->d.lbaHigh = scsiCmnd->cdb[3]; /* FIS LBA (23:16) */
15720
15721 /* Check FUA bit */
15722 if (scsiCmnd->cdb[1] & SCSI_WRITE12_FUA_MASK)
15723 fis->d.device = 0xC0; /* FIS FUA set */
15724 else
15725 fis->d.device = 0x40; /* FIS FUA clear */
15726
15727 fis->d.lbaLowExp = scsiCmnd->cdb[2]; /* FIS LBA (31:24) */
15728 fis->d.lbaMidExp = 0; /* FIS LBA (39:32) */
15729 fis->d.lbaHighExp = 0; /* FIS LBA (47:40) */
15730 fis->d.featuresExp = scsiCmnd->cdb[8]; /* FIS sector count (15:8) */
15731 fis->d.sectorCount = 0; /* Tag (7:3) set by LL layer */
15732 fis->d.sectorCountExp = 0;
15733 fis->d.reserved4 = 0;
15734 fis->d.control = 0; /* FIS HOB bit clear */
15735 fis->d.reserved5 = 0;
15736
15737 agRequestType = AGSA_SATA_PROTOCOL_FPDMA_WRITE;
15738 satIOContext->ATACmd = SAT_WRITE_FPDMA_QUEUED;
15739 }
15740
15741 satIOContext->currentLBA = lba;
15742 // satIOContext->OrgLBA = lba;
15743 satIOContext->OrgTL = tl;
15744
15745 /*
15746 computing number of loop and remainder for tl
15747 0xFF in case not ext
15748 0xFFFF in case EXT
15749 */
15750 if (fis->h.command == SAT_WRITE_SECTORS || fis->h.command == SAT_WRITE_DMA)
15751 {
15752 LoopNum = smsatComputeLoopNum(tl, 0xFF);
15753 }
15754 else if (fis->h.command == SAT_WRITE_SECTORS_EXT ||
15755 fis->h.command == SAT_WRITE_DMA_EXT ||
15756 fis->h.command == SAT_WRITE_DMA_FUA_EXT
15757 )
15758 {
15759 /* SAT_READ_SECTORS_EXT, SAT_READ_DMA_EXT */
15760 LoopNum = smsatComputeLoopNum(tl, 0xFFFF);
15761 }
15762 else
15763 {
15764 /* SAT_WRITE_FPDMA_QUEUEDK */
15765 LoopNum = smsatComputeLoopNum(tl, 0xFFFF);
15766 }
15767
15768 satIOContext->LoopNum = LoopNum;
15769 satIOContext->LoopNum2 = LoopNum;
15770
15771
15772 if (LoopNum == 1)
15773 {
15774 SM_DBG5(("smsatWriteAndVerify12: NON CHAINED data\n"));
15775 /* Initialize CB for SATA completion.
15776 */
15777 satIOContext->satCompleteCB = &smsatNonChainedWriteNVerifyCB;
15778 }
15779 else
15780 {
15781 SM_DBG1(("smsatWriteAndVerify12: CHAINED data!!!\n"));
15782 /* re-setting tl */
15783 if (fis->h.command == SAT_WRITE_SECTORS || fis->h.command == SAT_WRITE_DMA)
15784 {
15785 fis->d.sectorCount = 0xFF;
15786 }
15787 else if (fis->h.command == SAT_WRITE_SECTORS_EXT ||
15788 fis->h.command == SAT_WRITE_DMA_EXT ||
15789 fis->h.command == SAT_WRITE_DMA_FUA_EXT
15790 )
15791 {
15792 fis->d.sectorCount = 0xFF;
15793 fis->d.sectorCountExp = 0xFF;
15794 }
15795 else
15796 {
15797 /* SAT_WRITE_FPDMA_QUEUED */
15798 fis->h.features = 0xFF;
15799 fis->d.featuresExp = 0xFF;
15800 }
15801
15802 /* Initialize CB for SATA completion.
15803 */
15804 satIOContext->satCompleteCB = &smsatChainedWriteNVerifyCB;
15805 }
15806
15807
15808 /*
15809 * Prepare SGL and send FIS to LL layer.
15810 */
15811 satIOContext->reqType = agRequestType; /* Save it */
15812
15813 status = smsataLLIOStart( smRoot,
15814 smIORequest,
15815 smDeviceHandle,
15816 smScsiRequest,
15817 satIOContext);
15818 return (status);
15819 }
15820
15821 osGLOBAL bit32
smsatWriteAndVerify16(smRoot_t * smRoot,smIORequest_t * smIORequest,smDeviceHandle_t * smDeviceHandle,smScsiInitiatorRequest_t * smScsiRequest,smSatIOContext_t * satIOContext)15822 smsatWriteAndVerify16(
15823 smRoot_t *smRoot,
15824 smIORequest_t *smIORequest,
15825 smDeviceHandle_t *smDeviceHandle,
15826 smScsiInitiatorRequest_t *smScsiRequest,
15827 smSatIOContext_t *satIOContext
15828 )
15829 {
15830 /*
15831 combination of write16 and verify16
15832 since write16 has 8 bytes LBA -> problem ATA LBA(upto 6 bytes), no support
15833 */
15834 bit32 status;
15835 bit32 agRequestType = AGSA_SATA_PROTOCOL_DMA_WRITE;
15836 smDeviceData_t *pSatDevData;
15837 smScsiRspSense_t *pSense;
15838 smIniScsiCmnd_t *scsiCmnd;
15839 agsaFisRegHostToDevice_t *fis;
15840 bit32 lba = 0;
15841 bit32 tl = 0;
15842 bit32 LoopNum = 1;
15843 bit8 LBA[8];
15844 bit8 TL[8];
15845 bit32 AllChk = agFALSE; /* lba, lba+tl check against ATA limit and Disk capacity */
15846
15847 pSense = satIOContext->pSense;
15848 pSatDevData = satIOContext->pSatDevData;
15849 scsiCmnd = &smScsiRequest->scsiCmnd;
15850 fis = satIOContext->pFis;
15851
15852 SM_DBG5(("smsatWriteAndVerify16: start\n"));
15853
15854 /* checking BYTCHK bit */
15855 if (scsiCmnd->cdb[1] & SCSI_WRITE_N_VERIFY_BYTCHK_MASK)
15856 {
15857 smsatSetSensePayload( pSense,
15858 SCSI_SNSKEY_ILLEGAL_REQUEST,
15859 0,
15860 SCSI_SNSCODE_INVALID_FIELD_IN_CDB,
15861 satIOContext);
15862
15863 /*smEnqueueIO(smRoot, satIOContext);*/
15864
15865 tdsmIOCompletedCB( smRoot,
15866 smIORequest,
15867 smIOSuccess,
15868 SCSI_STAT_CHECK_CONDITION,
15869 satIOContext->pSmSenseData,
15870 satIOContext->interruptContext );
15871
15872 SM_DBG1(("smsatWriteAndVerify16: BYTCHK bit checking!!!\n"));
15873 return SM_RC_SUCCESS;
15874 }
15875
15876
15877 /* checking CONTROL */
15878 /* NACA == 1 or LINK == 1*/
15879 if ( (scsiCmnd->cdb[15] & SCSI_NACA_MASK) || (scsiCmnd->cdb[15] & SCSI_LINK_MASK) )
15880 {
15881 smsatSetSensePayload( pSense,
15882 SCSI_SNSKEY_ILLEGAL_REQUEST,
15883 0,
15884 SCSI_SNSCODE_INVALID_FIELD_IN_CDB,
15885 satIOContext);
15886
15887 /*smEnqueueIO(smRoot, satIOContext);*/
15888
15889 tdsmIOCompletedCB( smRoot,
15890 smIORequest,
15891 smIOSuccess,
15892 SCSI_STAT_CHECK_CONDITION,
15893 satIOContext->pSmSenseData,
15894 satIOContext->interruptContext );
15895
15896 SM_DBG1(("smsatWriteAndVerify16: return control!!!\n"));
15897 return SM_RC_SUCCESS;
15898 }
15899
15900 sm_memset(LBA, 0, sizeof(LBA));
15901 sm_memset(TL, 0, sizeof(TL));
15902
15903
15904 /* do not use memcpy due to indexing in LBA and TL */
15905 LBA[0] = scsiCmnd->cdb[2]; /* MSB */
15906 LBA[1] = scsiCmnd->cdb[3];
15907 LBA[2] = scsiCmnd->cdb[4];
15908 LBA[3] = scsiCmnd->cdb[5];
15909 LBA[4] = scsiCmnd->cdb[6];
15910 LBA[5] = scsiCmnd->cdb[7];
15911 LBA[6] = scsiCmnd->cdb[8];
15912 LBA[7] = scsiCmnd->cdb[9]; /* LSB */
15913
15914 TL[0] = 0;
15915 TL[1] = 0;
15916 TL[2] = 0;
15917 TL[3] = 0;
15918 TL[4] = scsiCmnd->cdb[10]; /* MSB */
15919 TL[5] = scsiCmnd->cdb[11];
15920 TL[6] = scsiCmnd->cdb[12];
15921 TL[7] = scsiCmnd->cdb[13]; /* LSB */
15922
15923
15924
15925 lba = smsatComputeCDB16LBA(satIOContext);
15926 tl = smsatComputeCDB16TL(satIOContext);
15927
15928
15929 /* Table 34, 9.1, p 46 */
15930 /*
15931 note: As of 2/10/2006, no support for DMA QUEUED
15932 */
15933
15934 /*
15935 Table 34, 9.1, p 46, b
15936 When no 48-bit addressing support or NCQ, if LBA is beyond (2^28 - 1),
15937 return check condition
15938 */
15939 if (pSatDevData->satNCQ != agTRUE &&
15940 pSatDevData->sat48BitSupport != agTRUE
15941 )
15942 {
15943 AllChk = smsatCheckLimit(LBA, TL, agFALSE, pSatDevData);
15944 if (AllChk)
15945 {
15946 SM_DBG1(("smsatWriteAndVerify16: return LBA out of range, not EXT!!!\n"));
15947 smsatSetSensePayload( pSense,
15948 SCSI_SNSKEY_ILLEGAL_REQUEST,
15949 0,
15950 SCSI_SNSCODE_LOGICAL_BLOCK_ADDRESS_OUT_OF_RANGE,
15951 satIOContext);
15952
15953 /*smEnqueueIO(smRoot, satIOContext);*/
15954
15955 tdsmIOCompletedCB( smRoot,
15956 smIORequest,
15957 smIOSuccess,
15958 SCSI_STAT_CHECK_CONDITION,
15959 satIOContext->pSmSenseData,
15960 satIOContext->interruptContext );
15961
15962 return SM_RC_SUCCESS;
15963 }
15964 }
15965 else
15966 {
15967 AllChk = smsatCheckLimit(LBA, TL, agTRUE, pSatDevData);
15968 if (AllChk)
15969 {
15970 SM_DBG1(("smsatWriteAndVerify16: return LBA out of range, EXT!!!\n"));
15971 smsatSetSensePayload( pSense,
15972 SCSI_SNSKEY_ILLEGAL_REQUEST,
15973 0,
15974 SCSI_SNSCODE_LOGICAL_BLOCK_ADDRESS_OUT_OF_RANGE,
15975 satIOContext);
15976
15977 /*smEnqueueIO(smRoot, satIOContext);*/
15978
15979 tdsmIOCompletedCB( smRoot,
15980 smIORequest,
15981 smIOSuccess,
15982 SCSI_STAT_CHECK_CONDITION,
15983 satIOContext->pSmSenseData,
15984 satIOContext->interruptContext );
15985
15986 return SM_RC_SUCCESS;
15987 }
15988 }
15989
15990
15991 /* case 1 and 2 */
15992 if (pSatDevData->satDMASupport == agTRUE && pSatDevData->satDMAEnabled == agTRUE)
15993 {
15994 /* case 2 */
15995 /* WRITE DMA*/
15996 /* In case that we can't fit the transfer length, we loop */
15997 SM_DBG5(("smsatWriteAndVerify16: case 2\n"));
15998 fis->h.fisType = 0x27; /* Reg host to device */
15999 fis->h.c_pmPort = 0x80; /* C bit is set */
16000 fis->h.command = SAT_WRITE_DMA; /* 0xCA */
16001 fis->h.features = 0; /* FIS reserve */
16002 fis->d.lbaLow = scsiCmnd->cdb[9]; /* FIS LBA (7 :0 ) */
16003 fis->d.lbaMid = scsiCmnd->cdb[8]; /* FIS LBA (15:8 ) */
16004 fis->d.lbaHigh = scsiCmnd->cdb[7]; /* FIS LBA (23:16) */
16005
16006 /* FIS LBA mode set LBA (27:24) */
16007 fis->d.device = (bit8)((0x4 << 4) | (scsiCmnd->cdb[6] & 0xF));
16008
16009 fis->d.lbaLowExp = 0;
16010 fis->d.lbaMidExp = 0;
16011 fis->d.lbaHighExp = 0;
16012 fis->d.featuresExp = 0;
16013 fis->d.sectorCount = scsiCmnd->cdb[13]; /* FIS sector count (7:0) */
16014 fis->d.sectorCountExp = 0;
16015 fis->d.reserved4 = 0;
16016 fis->d.control = 0; /* FIS HOB bit clear */
16017 fis->d.reserved5 = 0;
16018
16019 agRequestType = AGSA_SATA_PROTOCOL_DMA_WRITE;
16020 satIOContext->ATACmd = SAT_WRITE_DMA;
16021 }
16022 else
16023 {
16024 /* case 1 */
16025 /* WRITE MULTIPLE or WRITE SECTOR(S) */
16026 /* WRITE SECTORS for easier implemetation */
16027 /* In case that we can't fit the transfer length, we loop */
16028 SM_DBG5(("smsatWriteAndVerify16: case 1\n"));
16029 fis->h.fisType = 0x27; /* Reg host to device */
16030 fis->h.c_pmPort = 0x80; /* C bit is set */
16031 fis->h.command = SAT_WRITE_SECTORS; /* 0x30 */
16032 fis->h.features = 0; /* FIS reserve */
16033 fis->d.lbaLow = scsiCmnd->cdb[9]; /* FIS LBA (7 :0 ) */
16034 fis->d.lbaMid = scsiCmnd->cdb[8]; /* FIS LBA (15:8 ) */
16035 fis->d.lbaHigh = scsiCmnd->cdb[7]; /* FIS LBA (23:16) */
16036
16037 /* FIS LBA mode set LBA (27:24) */
16038 fis->d.device = (bit8)((0x4 << 4) | (scsiCmnd->cdb[6] & 0xF));
16039
16040 fis->d.lbaLowExp = 0;
16041 fis->d.lbaMidExp = 0;
16042 fis->d.lbaHighExp = 0;
16043 fis->d.featuresExp = 0;
16044 fis->d.sectorCount = scsiCmnd->cdb[13]; /* FIS sector count (7:0) */
16045 fis->d.sectorCountExp = 0;
16046 fis->d.reserved4 = 0;
16047 fis->d.control = 0; /* FIS HOB bit clear */
16048 fis->d.reserved5 = 0;
16049
16050 agRequestType = AGSA_SATA_PROTOCOL_PIO_WRITE;
16051 satIOContext->ATACmd = SAT_WRITE_SECTORS;
16052 }
16053
16054 /* case 3 and 4 */
16055 if (pSatDevData->sat48BitSupport == agTRUE)
16056 {
16057 if (pSatDevData->satDMASupport == agTRUE && pSatDevData->satDMAEnabled == agTRUE)
16058 {
16059 /* case 3 */
16060 /* WRITE DMA EXT or WRITE DMA FUA EXT */
16061 SM_DBG5(("smsatWriteAndVerify16: case 3\n"));
16062 fis->h.fisType = 0x27; /* Reg host to device */
16063 fis->h.c_pmPort = 0x80; /* C Bit is set */
16064
16065 /* SAT_WRITE_DMA_FUA_EXT is optional and we don't support it */
16066 fis->h.command = SAT_WRITE_DMA_EXT; /* 0x35 */
16067
16068 fis->h.features = 0; /* FIS reserve */
16069 fis->d.lbaLow = scsiCmnd->cdb[9]; /* FIS LBA (7 :0 ) */
16070 fis->d.lbaMid = scsiCmnd->cdb[8]; /* FIS LBA (15:8 ) */
16071 fis->d.lbaHigh = scsiCmnd->cdb[7]; /* FIS LBA (23:16) */
16072 fis->d.device = 0x40; /* FIS LBA mode set */
16073 fis->d.lbaLowExp = scsiCmnd->cdb[6]; /* FIS LBA (31:24) */
16074 fis->d.lbaMidExp = scsiCmnd->cdb[5]; /* FIS LBA (39:32) */
16075 fis->d.lbaHighExp = scsiCmnd->cdb[4]; /* FIS LBA (47:40) */
16076 fis->d.featuresExp = 0; /* FIS reserve */
16077 fis->d.sectorCount = scsiCmnd->cdb[13]; /* FIS sector count (7:0) */
16078 fis->d.sectorCountExp = scsiCmnd->cdb[12]; /* FIS sector count (15:8) */
16079 fis->d.reserved4 = 0;
16080 fis->d.control = 0; /* FIS HOB bit clear */
16081 fis->d.reserved5 = 0;
16082
16083 agRequestType = AGSA_SATA_PROTOCOL_DMA_WRITE;
16084 satIOContext->ATACmd = SAT_WRITE_DMA_EXT;
16085 }
16086 else
16087 {
16088 /* case 4 */
16089 /* WRITE MULTIPLE EXT or WRITE MULTIPLE FUA EXT or WRITE SECTOR(S) EXT */
16090 /* WRITE SECTORS EXT for easier implemetation */
16091 SM_DBG5(("smsatWriteAndVerify16: case 4\n"));
16092 fis->h.fisType = 0x27; /* Reg host to device */
16093 fis->h.c_pmPort = 0x80; /* C Bit is set */
16094 fis->h.command = SAT_WRITE_SECTORS_EXT; /* 0x34 */
16095
16096 fis->h.features = 0; /* FIS reserve */
16097 fis->d.lbaLow = scsiCmnd->cdb[9]; /* FIS LBA (7 :0 ) */
16098 fis->d.lbaMid = scsiCmnd->cdb[8]; /* FIS LBA (15:8 ) */
16099 fis->d.lbaHigh = scsiCmnd->cdb[7]; /* FIS LBA (23:16) */
16100 fis->d.device = 0x40; /* FIS LBA mode set */
16101 fis->d.lbaLowExp = scsiCmnd->cdb[6]; /* FIS LBA (31:24) */
16102 fis->d.lbaMidExp = scsiCmnd->cdb[5]; /* FIS LBA (39:32) */
16103 fis->d.lbaHighExp = scsiCmnd->cdb[4]; /* FIS LBA (47:40) */
16104 fis->d.featuresExp = 0; /* FIS reserve */
16105 fis->d.sectorCount = scsiCmnd->cdb[13]; /* FIS sector count (7:0) */
16106 fis->d.sectorCountExp = scsiCmnd->cdb[12]; /* FIS sector count (15:8) */
16107 fis->d.reserved4 = 0;
16108 fis->d.control = 0; /* FIS HOB bit clear */
16109 fis->d.reserved5 = 0;
16110
16111 agRequestType = AGSA_SATA_PROTOCOL_PIO_WRITE;
16112 satIOContext->ATACmd = SAT_WRITE_SECTORS_EXT;
16113 }
16114 }
16115
16116 /* case 5 */
16117 if (pSatDevData->satNCQ == agTRUE)
16118 {
16119 /* WRITE FPDMA QUEUED */
16120 if (pSatDevData->sat48BitSupport != agTRUE)
16121 {
16122 SM_DBG1(("smsatWriteAndVerify16: case 5 !!! error NCQ but 28 bit address support!!!\n"));
16123 smsatSetSensePayload( pSense,
16124 SCSI_SNSKEY_ILLEGAL_REQUEST,
16125 0,
16126 SCSI_SNSCODE_INVALID_FIELD_IN_CDB,
16127 satIOContext);
16128
16129 /*smEnqueueIO(smRoot, satIOContext);*/
16130
16131 tdsmIOCompletedCB( smRoot,
16132 smIORequest,
16133 smIOSuccess,
16134 SCSI_STAT_CHECK_CONDITION,
16135 satIOContext->pSmSenseData,
16136 satIOContext->interruptContext );
16137 return SM_RC_SUCCESS;
16138 }
16139 SM_DBG6(("smsatWriteAndVerify16: case 5\n"));
16140
16141 /* Support 48-bit FPDMA addressing, use WRITE FPDMA QUEUE command */
16142
16143 fis->h.fisType = 0x27; /* Reg host to device */
16144 fis->h.c_pmPort = 0x80; /* C Bit is set */
16145 fis->h.command = SAT_WRITE_FPDMA_QUEUED; /* 0x61 */
16146 fis->h.features = scsiCmnd->cdb[13]; /* FIS sector count (7:0) */
16147 fis->d.lbaLow = scsiCmnd->cdb[9]; /* FIS LBA (7 :0 ) */
16148 fis->d.lbaMid = scsiCmnd->cdb[8]; /* FIS LBA (15:8 ) */
16149 fis->d.lbaHigh = scsiCmnd->cdb[7]; /* FIS LBA (23:16) */
16150
16151 /* Check FUA bit */
16152 if (scsiCmnd->cdb[1] & SCSI_WRITE16_FUA_MASK)
16153 fis->d.device = 0xC0; /* FIS FUA set */
16154 else
16155 fis->d.device = 0x40; /* FIS FUA clear */
16156
16157 fis->d.lbaLowExp = scsiCmnd->cdb[6]; /* FIS LBA (31:24) */
16158 fis->d.lbaMidExp = scsiCmnd->cdb[5]; /* FIS LBA (39:32) */
16159 fis->d.lbaHighExp = scsiCmnd->cdb[4]; /* FIS LBA (47:40) */
16160 fis->d.featuresExp = scsiCmnd->cdb[12]; /* FIS sector count (15:8) */
16161 fis->d.sectorCount = 0; /* Tag (7:3) set by LL layer */
16162 fis->d.sectorCountExp = 0;
16163 fis->d.reserved4 = 0;
16164 fis->d.control = 0; /* FIS HOB bit clear */
16165 fis->d.reserved5 = 0;
16166
16167 agRequestType = AGSA_SATA_PROTOCOL_FPDMA_WRITE;
16168 satIOContext->ATACmd = SAT_WRITE_FPDMA_QUEUED;
16169 }
16170
16171 satIOContext->currentLBA = lba;
16172 satIOContext->OrgTL = tl;
16173
16174 /*
16175 computing number of loop and remainder for tl
16176 0xFF in case not ext
16177 0xFFFF in case EXT
16178 */
16179 if (fis->h.command == SAT_WRITE_SECTORS || fis->h.command == SAT_WRITE_DMA)
16180 {
16181 LoopNum = smsatComputeLoopNum(tl, 0xFF);
16182 }
16183 else if (fis->h.command == SAT_WRITE_SECTORS_EXT ||
16184 fis->h.command == SAT_WRITE_DMA_EXT ||
16185 fis->h.command == SAT_WRITE_DMA_FUA_EXT
16186 )
16187 {
16188 /* SAT_READ_SECTORS_EXT, SAT_READ_DMA_EXT */
16189 LoopNum = smsatComputeLoopNum(tl, 0xFFFF);
16190 }
16191 else
16192 {
16193 /* SAT_WRITE_FPDMA_QUEUEDK */
16194 LoopNum = smsatComputeLoopNum(tl, 0xFFFF);
16195 }
16196
16197 satIOContext->LoopNum = LoopNum;
16198
16199
16200 if (LoopNum == 1)
16201 {
16202 SM_DBG5(("smsatWriteAndVerify16: NON CHAINED data\n"));
16203 /* Initialize CB for SATA completion.
16204 */
16205 satIOContext->satCompleteCB = &smsatNonChainedWriteNVerifyCB;
16206 }
16207 else
16208 {
16209 SM_DBG1(("smsatWriteAndVerify16: CHAINED data!!!\n"));
16210 /* re-setting tl */
16211 if (fis->h.command == SAT_WRITE_SECTORS || fis->h.command == SAT_WRITE_DMA)
16212 {
16213 fis->d.sectorCount = 0xFF;
16214 }
16215 else if (fis->h.command == SAT_WRITE_SECTORS_EXT ||
16216 fis->h.command == SAT_WRITE_DMA_EXT ||
16217 fis->h.command == SAT_WRITE_DMA_FUA_EXT
16218 )
16219 {
16220 fis->d.sectorCount = 0xFF;
16221 fis->d.sectorCountExp = 0xFF;
16222 }
16223 else
16224 {
16225 /* SAT_WRITE_FPDMA_QUEUED */
16226 fis->h.features = 0xFF;
16227 fis->d.featuresExp = 0xFF;
16228 }
16229
16230 /* Initialize CB for SATA completion.
16231 */
16232 satIOContext->satCompleteCB = &smsatChainedWriteNVerifyCB;
16233 }
16234
16235
16236 /*
16237 * Prepare SGL and send FIS to LL layer.
16238 */
16239 satIOContext->reqType = agRequestType; /* Save it */
16240
16241 status = smsataLLIOStart( smRoot,
16242 smIORequest,
16243 smDeviceHandle,
16244 smScsiRequest,
16245 satIOContext);
16246 return (status);
16247 }
16248
16249 osGLOBAL bit32
smsatReadMediaSerialNumber(smRoot_t * smRoot,smIORequest_t * smIORequest,smDeviceHandle_t * smDeviceHandle,smScsiInitiatorRequest_t * smScsiRequest,smSatIOContext_t * satIOContext)16250 smsatReadMediaSerialNumber(
16251 smRoot_t *smRoot,
16252 smIORequest_t *smIORequest,
16253 smDeviceHandle_t *smDeviceHandle,
16254 smScsiInitiatorRequest_t *smScsiRequest,
16255 smSatIOContext_t *satIOContext
16256 )
16257 {
16258 bit32 status;
16259 bit32 agRequestType = AGSA_SATA_PROTOCOL_PIO_READ;
16260 smDeviceData_t *pSatDevData;
16261 smScsiRspSense_t *pSense;
16262 smIniScsiCmnd_t *scsiCmnd;
16263 agsaFisRegHostToDevice_t *fis;
16264 agsaSATAIdentifyData_t *pSATAIdData;
16265 bit8 *pSerialNumber;
16266 bit8 MediaSerialNumber[64] = {0};
16267 bit32 allocationLen = 0;
16268
16269 pSense = satIOContext->pSense;
16270 pSatDevData = satIOContext->pSatDevData;
16271 scsiCmnd = &smScsiRequest->scsiCmnd;
16272 fis = satIOContext->pFis;
16273 pSATAIdData = &(pSatDevData->satIdentifyData);
16274 pSerialNumber = (bit8 *) smScsiRequest->sglVirtualAddr;
16275
16276 SM_DBG5(("smsatReadMediaSerialNumber: start\n"));
16277
16278 /* checking CONTROL */
16279 /* NACA == 1 or LINK == 1*/
16280 if ( (scsiCmnd->cdb[11] & SCSI_NACA_MASK) || (scsiCmnd->cdb[11] & SCSI_LINK_MASK) )
16281 {
16282 smsatSetSensePayload( pSense,
16283 SCSI_SNSKEY_ILLEGAL_REQUEST,
16284 0,
16285 SCSI_SNSCODE_INVALID_FIELD_IN_CDB,
16286 satIOContext);
16287
16288 /*smEnqueueIO(smRoot, satIOContext);*/
16289
16290 tdsmIOCompletedCB( smRoot,
16291 smIORequest,
16292 smIOSuccess,
16293 SCSI_STAT_CHECK_CONDITION,
16294 satIOContext->pSmSenseData,
16295 satIOContext->interruptContext );
16296
16297 SM_DBG1(("smsatReadMediaSerialNumber: return control!!!\n"));
16298 return SM_RC_SUCCESS;
16299 }
16300
16301 allocationLen = (((bit32)scsiCmnd->cdb[6]) << 24) |
16302 (((bit32)scsiCmnd->cdb[7]) << 16) |
16303 (((bit32)scsiCmnd->cdb[8]) << 8 ) |
16304 (((bit32)scsiCmnd->cdb[9]));
16305 allocationLen = MIN(allocationLen, scsiCmnd->expDataLength);
16306 if (allocationLen == 4)
16307 {
16308 if (pSATAIdData->commandSetFeatureDefault & 0x4)
16309 {
16310 SM_DBG1(("smsatReadMediaSerialNumber: Media serial number returning only length!!!\n"));
16311 /* SPC-3 6.16 p192; filling in length */
16312 MediaSerialNumber[0] = 0;
16313 MediaSerialNumber[1] = 0;
16314 MediaSerialNumber[2] = 0;
16315 MediaSerialNumber[3] = 0x3C;
16316 }
16317 else
16318 {
16319 /* 1 sector - 4 = 512 - 4 to avoid underflow; 0x1fc*/
16320 MediaSerialNumber[0] = 0;
16321 MediaSerialNumber[1] = 0;
16322 MediaSerialNumber[2] = 0x1;
16323 MediaSerialNumber[3] = 0xfc;
16324 }
16325
16326 sm_memcpy(pSerialNumber, MediaSerialNumber, 4);
16327 /*smEnqueueIO(smRoot, satIOContext);*/
16328
16329 tdsmIOCompletedCB( smRoot,
16330 smIORequest,
16331 smIOSuccess,
16332 SCSI_STAT_GOOD,
16333 agNULL,
16334 satIOContext->interruptContext);
16335
16336 return SM_RC_SUCCESS;
16337 }
16338
16339 if ( pSatDevData->IDDeviceValid == agTRUE)
16340 {
16341 if (pSATAIdData->commandSetFeatureDefault & 0x4)
16342 {
16343 /* word87 bit2 Media serial number is valid */
16344 /* read word 176 to 205; length is 2*30 = 60 = 0x3C*/
16345 #ifdef LOG_ENABLE
16346 smhexdump("ID smsatReadMediaSerialNumber", (bit8*)pSATAIdData->currentMediaSerialNumber, 2*30);
16347 #endif
16348 /* SPC-3 6.16 p192; filling in length */
16349 MediaSerialNumber[0] = 0;
16350 MediaSerialNumber[1] = 0;
16351 MediaSerialNumber[2] = 0;
16352 MediaSerialNumber[3] = 0x3C;
16353 sm_memcpy(&MediaSerialNumber[4], (void *)pSATAIdData->currentMediaSerialNumber, 60);
16354 #ifdef LOG_ENABLE
16355 smhexdump("smsatReadMediaSerialNumber", (bit8*)MediaSerialNumber, 2*30 + 4);
16356 #endif
16357 sm_memcpy(pSerialNumber, MediaSerialNumber, MIN(allocationLen, 64));
16358 /*smEnqueueIO(smRoot, satIOContext);*/
16359
16360 tdsmIOCompletedCB( smRoot,
16361 smIORequest,
16362 smIOSuccess,
16363 SCSI_STAT_GOOD,
16364 agNULL,
16365 satIOContext->interruptContext);
16366 return SM_RC_SUCCESS;
16367
16368
16369 }
16370 else
16371 {
16372 /* word87 bit2 Media serial number is NOT valid */
16373 SM_DBG1(("smsatReadMediaSerialNumber: Media serial number is NOT valid!!!\n"));
16374
16375 if (pSatDevData->sat48BitSupport == agTRUE)
16376 {
16377 /* READ VERIFY SECTORS EXT */
16378 fis->h.fisType = 0x27; /* Reg host to device */
16379 fis->h.c_pmPort = 0x80; /* C Bit is set */
16380 fis->h.command = SAT_READ_SECTORS_EXT; /* 0x24 */
16381
16382 fis->h.features = 0; /* FIS reserve */
16383 fis->d.lbaLow = 0; /* FIS LBA (7 :0 ) */
16384 fis->d.lbaMid = 0; /* FIS LBA (15:8 ) */
16385 fis->d.lbaHigh = 0; /* FIS LBA (23:16) */
16386 fis->d.device = 0x40; /* FIS LBA mode set */
16387 fis->d.lbaLowExp = 0; /* FIS LBA (31:24) */
16388 fis->d.lbaMidExp = 0; /* FIS LBA (39:32) */
16389 fis->d.lbaHighExp = 0; /* FIS LBA (47:40) */
16390 fis->d.featuresExp = 0; /* FIS reserve */
16391 fis->d.sectorCount = 1; /* FIS sector count (7:0) */
16392 fis->d.sectorCountExp = 0; /* FIS sector count (15:8) */
16393 fis->d.reserved4 = 0;
16394 fis->d.control = 0; /* FIS HOB bit clear */
16395 fis->d.reserved5 = 0;
16396
16397 agRequestType = AGSA_SATA_PROTOCOL_PIO_READ;
16398 }
16399 else
16400 {
16401 /* READ VERIFY SECTORS */
16402 fis->h.fisType = 0x27; /* Reg host to device */
16403 fis->h.c_pmPort = 0x80; /* C Bit is set */
16404 fis->h.command = SAT_READ_SECTORS; /* 0x20 */
16405 fis->h.features = 0; /* FIS reserve */
16406 fis->d.lbaLow = 0; /* FIS LBA (7 :0 ) */
16407 fis->d.lbaMid = 0; /* FIS LBA (15:8 ) */
16408 fis->d.lbaHigh = 0; /* FIS LBA (23:16) */
16409 fis->d.device = 0x40; /* FIS LBA (27:24) and FIS LBA mode */
16410 fis->d.lbaLowExp = 0;
16411 fis->d.lbaMidExp = 0;
16412 fis->d.lbaHighExp = 0;
16413 fis->d.featuresExp = 0;
16414 fis->d.sectorCount = 1; /* FIS sector count (7:0) */
16415 fis->d.sectorCountExp = 0;
16416 fis->d.reserved4 = 0;
16417 fis->d.control = 0; /* FIS HOB bit clear */
16418 fis->d.reserved5 = 0;
16419
16420
16421 agRequestType = AGSA_SATA_PROTOCOL_PIO_READ;
16422 }
16423 satIOContext->satCompleteCB = &smsatReadMediaSerialNumberCB;
16424 satIOContext->reqType = agRequestType; /* Save it */
16425 status = smsataLLIOStart( smRoot,
16426 smIORequest,
16427 smDeviceHandle,
16428 smScsiRequest,
16429 satIOContext);
16430
16431 return status;
16432 }
16433 }
16434 else
16435 {
16436
16437 tdsmIOCompletedCB( smRoot,
16438 smIORequest,
16439 smIOFailed,
16440 smDetailOtherError,
16441 agNULL,
16442 satIOContext->interruptContext);
16443
16444 return SM_RC_SUCCESS;
16445
16446 }
16447 }
16448
16449 osGLOBAL bit32
smsatReadBuffer(smRoot_t * smRoot,smIORequest_t * smIORequest,smDeviceHandle_t * smDeviceHandle,smScsiInitiatorRequest_t * smScsiRequest,smSatIOContext_t * satIOContext)16450 smsatReadBuffer(
16451 smRoot_t *smRoot,
16452 smIORequest_t *smIORequest,
16453 smDeviceHandle_t *smDeviceHandle,
16454 smScsiInitiatorRequest_t *smScsiRequest,
16455 smSatIOContext_t *satIOContext
16456 )
16457 {
16458 bit32 status = SM_RC_SUCCESS;
16459 bit32 agRequestType = AGSA_SATA_PROTOCOL_PIO_READ;
16460 smScsiRspSense_t *pSense;
16461 smIniScsiCmnd_t *scsiCmnd;
16462 agsaFisRegHostToDevice_t *fis;
16463 bit32 bufferOffset;
16464 bit32 tl;
16465 bit8 mode;
16466 bit8 bufferID;
16467 bit8 *pBuff;
16468
16469 pSense = satIOContext->pSense;
16470 scsiCmnd = &smScsiRequest->scsiCmnd;
16471 fis = satIOContext->pFis;
16472 pBuff = (bit8 *) smScsiRequest->sglVirtualAddr;
16473
16474 SM_DBG5(("smsatReadBuffer: start\n"));
16475
16476 /* checking CONTROL */
16477 /* NACA == 1 or LINK == 1*/
16478 if ( (scsiCmnd->cdb[9] & SCSI_NACA_MASK) || (scsiCmnd->cdb[9] & SCSI_LINK_MASK) )
16479 {
16480 smsatSetSensePayload( pSense,
16481 SCSI_SNSKEY_ILLEGAL_REQUEST,
16482 0,
16483 SCSI_SNSCODE_INVALID_FIELD_IN_CDB,
16484 satIOContext);
16485
16486 /*smEnqueueIO(smRoot, satIOContext);*/
16487
16488 tdsmIOCompletedCB( smRoot,
16489 smIORequest,
16490 smIOSuccess,
16491 SCSI_STAT_CHECK_CONDITION,
16492 satIOContext->pSmSenseData,
16493 satIOContext->interruptContext );
16494
16495 SM_DBG1(("smsatReadBuffer: return control!!!\n"));
16496 return SM_RC_SUCCESS;
16497 }
16498
16499 bufferOffset = (scsiCmnd->cdb[3] << (8*2)) + (scsiCmnd->cdb[4] << 8) + scsiCmnd->cdb[5];
16500 tl = (scsiCmnd->cdb[6] << (8*2)) + (scsiCmnd->cdb[7] << 8) + scsiCmnd->cdb[8];
16501
16502 mode = (bit8)(scsiCmnd->cdb[1] & SCSI_READ_BUFFER_MODE_MASK);
16503 bufferID = scsiCmnd->cdb[2];
16504
16505 if (mode == READ_BUFFER_DATA_MODE) /* 2 */
16506 {
16507 if (bufferID == 0 && bufferOffset == 0 && tl == 512)
16508 {
16509 /* send ATA READ BUFFER */
16510 fis->h.fisType = 0x27; /* Reg host to device */
16511 fis->h.c_pmPort = 0x80; /* C Bit is set */
16512 fis->h.command = SAT_READ_BUFFER; /* 0xE4 */
16513 fis->h.features = 0; /* FIS reserve */
16514 fis->d.lbaLow = 0; /* FIS LBA (7 :0 ) */
16515 fis->d.lbaMid = 0; /* FIS LBA (15:8 ) */
16516 fis->d.lbaHigh = 0; /* FIS LBA (23:16) */
16517 fis->d.device = 0x40; /* FIS LBA (27:24) and FIS LBA mode */
16518 fis->d.lbaLowExp = 0;
16519 fis->d.lbaMidExp = 0;
16520 fis->d.lbaHighExp = 0;
16521 fis->d.featuresExp = 0;
16522 fis->d.sectorCount = 0; /* FIS sector count (7:0) */
16523 fis->d.sectorCountExp = 0;
16524 fis->d.reserved4 = 0;
16525 fis->d.control = 0; /* FIS HOB bit clear */
16526 fis->d.reserved5 = 0;
16527
16528
16529 agRequestType = AGSA_SATA_PROTOCOL_PIO_READ;
16530
16531 satIOContext->satCompleteCB = &smsatReadBufferCB;
16532
16533 satIOContext->reqType = agRequestType; /* Save it */
16534
16535 status = smsataLLIOStart( smRoot,
16536 smIORequest,
16537 smDeviceHandle,
16538 smScsiRequest,
16539 satIOContext);
16540 return status;
16541 }
16542
16543 if (bufferID == 0 && bufferOffset == 0 && tl != 512)
16544 {
16545 smsatSetSensePayload( pSense,
16546 SCSI_SNSKEY_ILLEGAL_REQUEST,
16547 0,
16548 SCSI_SNSCODE_INVALID_FIELD_IN_CDB,
16549 satIOContext);
16550
16551 /*smEnqueueIO(smRoot, satIOContext);*/
16552
16553 tdsmIOCompletedCB( smRoot,
16554 smIORequest,
16555 smIOSuccess,
16556 SCSI_STAT_CHECK_CONDITION,
16557 satIOContext->pSmSenseData,
16558 satIOContext->interruptContext );
16559
16560 SM_DBG1(("smsatReadBuffer: allocation length is not 512; it is %d!!!\n", tl));
16561 return SM_RC_SUCCESS;
16562 }
16563
16564 if (bufferID == 0 && bufferOffset != 0)
16565 {
16566 smsatSetSensePayload( pSense,
16567 SCSI_SNSKEY_ILLEGAL_REQUEST,
16568 0,
16569 SCSI_SNSCODE_INVALID_FIELD_IN_CDB,
16570 satIOContext);
16571
16572 /*smEnqueueIO(smRoot, satIOContext);*/
16573
16574 tdsmIOCompletedCB( smRoot,
16575 smIORequest,
16576 smIOSuccess,
16577 SCSI_STAT_CHECK_CONDITION,
16578 satIOContext->pSmSenseData,
16579 satIOContext->interruptContext );
16580
16581 SM_DBG1(("smsatReadBuffer: buffer offset is not 0; it is %d!!!\n", bufferOffset));
16582 return SM_RC_SUCCESS;
16583 }
16584 /* all other cases unsupported */
16585 SM_DBG1(("smsatReadBuffer: unsupported case 1!!!\n"));
16586 smsatSetSensePayload( pSense,
16587 SCSI_SNSKEY_ILLEGAL_REQUEST,
16588 0,
16589 SCSI_SNSCODE_INVALID_COMMAND,
16590 satIOContext);
16591
16592 /*smEnqueueIO(smRoot, satIOContext);*/
16593
16594 tdsmIOCompletedCB( smRoot,
16595 smIORequest,
16596 smIOSuccess,
16597 SCSI_STAT_CHECK_CONDITION,
16598 satIOContext->pSmSenseData,
16599 satIOContext->interruptContext );
16600
16601 return SM_RC_SUCCESS;
16602
16603 }
16604 else if (mode == READ_BUFFER_DESCRIPTOR_MODE) /* 3 */
16605 {
16606 if (tl < READ_BUFFER_DESCRIPTOR_MODE_DATA_LEN) /* 4 */
16607 {
16608 smsatSetSensePayload( pSense,
16609 SCSI_SNSKEY_ILLEGAL_REQUEST,
16610 0,
16611 SCSI_SNSCODE_INVALID_FIELD_IN_CDB,
16612 satIOContext);
16613
16614 /*smEnqueueIO(smRoot, satIOContext);*/
16615
16616 tdsmIOCompletedCB( smRoot,
16617 smIORequest,
16618 smIOSuccess,
16619 SCSI_STAT_CHECK_CONDITION,
16620 satIOContext->pSmSenseData,
16621 satIOContext->interruptContext );
16622
16623 SM_DBG1(("smsatReadBuffer: tl < 4; tl is %d!!!\n", tl));
16624 return SM_RC_SUCCESS;
16625 }
16626 if (bufferID == 0)
16627 {
16628 /* SPC-4, 6.15.5, p189; SAT-2 Rev00, 8.7.2.3, p41*/
16629 pBuff[0] = 0xFF;
16630 pBuff[1] = 0x00;
16631 pBuff[2] = 0x02;
16632 pBuff[3] = 0x00;
16633 if (READ_BUFFER_DESCRIPTOR_MODE_DATA_LEN < tl)
16634 {
16635 /* underrrun */
16636 SM_DBG1(("smsatReadBuffer: underrun tl %d data %d!!!\n", tl, READ_BUFFER_DESCRIPTOR_MODE_DATA_LEN));
16637 /*smEnqueueIO(smRoot, satIOContext);*/
16638
16639 tdsmIOCompletedCB( smRoot,
16640 smIORequest,
16641 smIOUnderRun,
16642 tl - READ_BUFFER_DESCRIPTOR_MODE_DATA_LEN,
16643 agNULL,
16644 satIOContext->interruptContext );
16645
16646 return SM_RC_SUCCESS;
16647 }
16648 else
16649 {
16650 /*smEnqueueIO(smRoot, satIOContext);*/
16651
16652 tdsmIOCompletedCB( smRoot,
16653 smIORequest,
16654 smIOSuccess,
16655 SCSI_STAT_GOOD,
16656 agNULL,
16657 satIOContext->interruptContext);
16658 return SM_RC_SUCCESS;
16659 }
16660 }
16661 else
16662 {
16663 /* We don't support other than bufferID 0 */
16664 smsatSetSensePayload( pSense,
16665 SCSI_SNSKEY_ILLEGAL_REQUEST,
16666 0,
16667 SCSI_SNSCODE_INVALID_COMMAND,
16668 satIOContext);
16669
16670 /*smEnqueueIO(smRoot, satIOContext);*/
16671
16672 tdsmIOCompletedCB( smRoot,
16673 smIORequest,
16674 smIOSuccess,
16675 SCSI_STAT_CHECK_CONDITION,
16676 satIOContext->pSmSenseData,
16677 satIOContext->interruptContext );
16678
16679 return SM_RC_SUCCESS;
16680 }
16681 }
16682 else
16683 {
16684 /* We don't support any other mode */
16685 SM_DBG1(("smsatReadBuffer: unsupported mode %d!!!\n", mode));
16686 smsatSetSensePayload( pSense,
16687 SCSI_SNSKEY_ILLEGAL_REQUEST,
16688 0,
16689 SCSI_SNSCODE_INVALID_COMMAND,
16690 satIOContext);
16691
16692 /*smEnqueueIO(smRoot, satIOContext);*/
16693
16694 tdsmIOCompletedCB( smRoot,
16695 smIORequest,
16696 smIOSuccess,
16697 SCSI_STAT_CHECK_CONDITION,
16698 satIOContext->pSmSenseData,
16699 satIOContext->interruptContext );
16700
16701 return SM_RC_SUCCESS;
16702 }
16703 }
16704
16705 osGLOBAL bit32
smsatWriteBuffer(smRoot_t * smRoot,smIORequest_t * smIORequest,smDeviceHandle_t * smDeviceHandle,smScsiInitiatorRequest_t * smScsiRequest,smSatIOContext_t * satIOContext)16706 smsatWriteBuffer(
16707 smRoot_t *smRoot,
16708 smIORequest_t *smIORequest,
16709 smDeviceHandle_t *smDeviceHandle,
16710 smScsiInitiatorRequest_t *smScsiRequest,
16711 smSatIOContext_t *satIOContext
16712 )
16713 {
16714 #ifdef NOT_YET
16715 bit32 agRequestType = AGSA_SATA_PROTOCOL_PIO_READ;
16716 #endif
16717 smScsiRspSense_t *pSense;
16718 smIniScsiCmnd_t *scsiCmnd;
16719 #ifdef NOT_YET
16720 agsaFisRegHostToDevice_t *fis;
16721 #endif
16722 bit32 bufferOffset;
16723 bit32 parmLen;
16724 bit8 mode;
16725 bit8 bufferID;
16726 bit8 *pBuff;
16727
16728 pSense = satIOContext->pSense;
16729 scsiCmnd = &smScsiRequest->scsiCmnd;
16730 #ifdef NOT_YET
16731 fis = satIOContext->pFis;
16732 #endif
16733 pBuff = (bit8 *) smScsiRequest->sglVirtualAddr;
16734
16735 SM_DBG5(("smsatWriteBuffer: start\n"));
16736
16737 /* checking CONTROL */
16738 /* NACA == 1 or LINK == 1*/
16739 if ( (scsiCmnd->cdb[9] & SCSI_NACA_MASK) || (scsiCmnd->cdb[9] & SCSI_LINK_MASK) )
16740 {
16741 smsatSetSensePayload( pSense,
16742 SCSI_SNSKEY_ILLEGAL_REQUEST,
16743 0,
16744 SCSI_SNSCODE_INVALID_FIELD_IN_CDB,
16745 satIOContext);
16746
16747 /*smEnqueueIO(smRoot, satIOContext);*/
16748
16749 tdsmIOCompletedCB( smRoot,
16750 smIORequest,
16751 smIOSuccess,
16752 SCSI_STAT_CHECK_CONDITION,
16753 satIOContext->pSmSenseData,
16754 satIOContext->interruptContext );
16755
16756 SM_DBG1(("smsatWriteBuffer: return control!!!\n"));
16757 return SM_RC_SUCCESS;
16758 }
16759
16760 bufferOffset = (scsiCmnd->cdb[3] << (8*2)) + (scsiCmnd->cdb[4] << 8) + scsiCmnd->cdb[5];
16761 parmLen = (scsiCmnd->cdb[6] << (8*2)) + (scsiCmnd->cdb[7] << 8) + scsiCmnd->cdb[8];
16762
16763 mode = (bit8)(scsiCmnd->cdb[1] & SCSI_READ_BUFFER_MODE_MASK);
16764 bufferID = scsiCmnd->cdb[2];
16765
16766 /* for debugging only */
16767 smhexdump("smsatWriteBuffer pBuff", (bit8 *)pBuff, 24);
16768
16769 if (mode == WRITE_BUFFER_DATA_MODE) /* 2 */
16770 {
16771 if (bufferID == 0 && bufferOffset == 0 && parmLen == 512)
16772 {
16773 SM_DBG1(("smsatWriteBuffer: sending ATA WRITE BUFFER!!!\n"));
16774 /* send ATA WRITE BUFFER */
16775 #ifdef NOT_YET
16776 fis->h.fisType = 0x27; /* Reg host to device */
16777 fis->h.c_pmPort = 0x80; /* C Bit is set */
16778 fis->h.command = SAT_WRITE_BUFFER; /* 0xE8 */
16779 fis->h.features = 0; /* FIS reserve */
16780 fis->d.lbaLow = 0; /* FIS LBA (7 :0 ) */
16781 fis->d.lbaMid = 0; /* FIS LBA (15:8 ) */
16782 fis->d.lbaHigh = 0; /* FIS LBA (23:16) */
16783 fis->d.device = 0x40; /* FIS LBA (27:24) and FIS LBA mode */
16784 fis->d.lbaLowExp = 0;
16785 fis->d.lbaMidExp = 0;
16786 fis->d.lbaHighExp = 0;
16787 fis->d.featuresExp = 0;
16788 fis->d.sectorCount = 0; /* FIS sector count (7:0) */
16789 fis->d.sectorCountExp = 0;
16790 fis->d.reserved4 = 0;
16791 fis->d.control = 0; /* FIS HOB bit clear */
16792 fis->d.reserved5 = 0;
16793
16794
16795 agRequestType = AGSA_SATA_PROTOCOL_PIO_WRITE;
16796
16797 satIOContext->satCompleteCB = &smsatWriteBufferCB;
16798
16799 satIOContext->reqType = agRequestType; /* Save it */
16800
16801 status = smsataLLIOStart( smRoot,
16802 smIORequest,
16803 smDeviceHandle,
16804 smScsiRequest,
16805 satIOContext);
16806 return status;
16807 #endif
16808 /* temp */
16809 /*smEnqueueIO(smRoot, satIOContext);*/
16810
16811 tdsmIOCompletedCB( smRoot,
16812 smIORequest,
16813 smIOSuccess,
16814 SCSI_STAT_GOOD,
16815 agNULL,
16816 satIOContext->interruptContext);
16817 return SM_RC_SUCCESS;
16818 }
16819 if ( (bufferID == 0 && bufferOffset != 0) ||
16820 (bufferID == 0 && parmLen != 512)
16821 )
16822 {
16823 smsatSetSensePayload( pSense,
16824 SCSI_SNSKEY_ILLEGAL_REQUEST,
16825 0,
16826 SCSI_SNSCODE_INVALID_FIELD_IN_CDB,
16827 satIOContext);
16828
16829 /*smEnqueueIO(smRoot, satIOContext);*/
16830
16831 tdsmIOCompletedCB( smRoot,
16832 smIORequest,
16833 smIOSuccess,
16834 SCSI_STAT_CHECK_CONDITION,
16835 satIOContext->pSmSenseData,
16836 satIOContext->interruptContext );
16837
16838 SM_DBG1(("smsatWriteBuffer: wrong buffer offset %d or parameter length parmLen %d!!!\n", bufferOffset, parmLen));
16839 return SM_RC_SUCCESS;
16840 }
16841
16842 /* all other cases unsupported */
16843 SM_DBG1(("smsatWriteBuffer: unsupported case 1!!!\n"));
16844 smsatSetSensePayload( pSense,
16845 SCSI_SNSKEY_ILLEGAL_REQUEST,
16846 0,
16847 SCSI_SNSCODE_INVALID_COMMAND,
16848 satIOContext);
16849
16850 /*smEnqueueIO(smRoot, satIOContext);*/
16851
16852 tdsmIOCompletedCB( smRoot,
16853 smIORequest,
16854 smIOSuccess,
16855 SCSI_STAT_CHECK_CONDITION,
16856 satIOContext->pSmSenseData,
16857 satIOContext->interruptContext );
16858
16859 return SM_RC_SUCCESS;
16860
16861 }
16862 else if (mode == WRITE_BUFFER_DL_MICROCODE_SAVE_MODE) /* 5 */
16863 {
16864 /* temporary */
16865 SM_DBG1(("smsatWriteBuffer: not yet supported mode %d!!!\n", mode));
16866 smsatSetSensePayload( pSense,
16867 SCSI_SNSKEY_ILLEGAL_REQUEST,
16868 0,
16869 SCSI_SNSCODE_INVALID_COMMAND,
16870 satIOContext);
16871
16872
16873 tdsmIOCompletedCB( smRoot,
16874 smIORequest,
16875 smIOSuccess,
16876 SCSI_STAT_CHECK_CONDITION,
16877 satIOContext->pSmSenseData,
16878 satIOContext->interruptContext );
16879
16880 return SM_RC_SUCCESS;
16881 }
16882 else
16883 {
16884 /* We don't support any other mode */
16885 SM_DBG1(("smsatWriteBuffer: unsupported mode %d!!!\n", mode));
16886 smsatSetSensePayload( pSense,
16887 SCSI_SNSKEY_ILLEGAL_REQUEST,
16888 0,
16889 SCSI_SNSCODE_INVALID_COMMAND,
16890 satIOContext);
16891
16892 /*smEnqueueIO(smRoot, satIOContext);*/
16893
16894 tdsmIOCompletedCB( smRoot,
16895 smIORequest,
16896 smIOSuccess,
16897 SCSI_STAT_CHECK_CONDITION,
16898 satIOContext->pSmSenseData,
16899 satIOContext->interruptContext );
16900
16901 return SM_RC_SUCCESS;
16902 }
16903
16904 }
16905
16906 osGLOBAL bit32
smsatReassignBlocks(smRoot_t * smRoot,smIORequest_t * smIORequest,smDeviceHandle_t * smDeviceHandle,smScsiInitiatorRequest_t * smScsiRequest,smSatIOContext_t * satIOContext)16907 smsatReassignBlocks(
16908 smRoot_t *smRoot,
16909 smIORequest_t *smIORequest,
16910 smDeviceHandle_t *smDeviceHandle,
16911 smScsiInitiatorRequest_t *smScsiRequest,
16912 smSatIOContext_t *satIOContext
16913 )
16914 {
16915 /*
16916 assumes all LBA fits in ATA command; no boundary condition is checked here yet
16917 */
16918 bit32 status;
16919 bit32 agRequestType;
16920 smDeviceData_t *pSatDevData;
16921 smScsiRspSense_t *pSense;
16922 smIniScsiCmnd_t *scsiCmnd;
16923 agsaFisRegHostToDevice_t *fis;
16924 bit8 *pParmList; /* Log Page data buffer */
16925 bit8 LongLBA;
16926 bit8 LongList;
16927 bit32 defectListLen;
16928 bit8 LBA[8];
16929 bit32 startingIndex;
16930
16931 pSense = satIOContext->pSense;
16932 pSatDevData = satIOContext->pSatDevData;
16933 scsiCmnd = &smScsiRequest->scsiCmnd;
16934 fis = satIOContext->pFis;
16935 pParmList = (bit8 *) smScsiRequest->sglVirtualAddr;
16936
16937 SM_DBG5(("smsatReassignBlocks: start\n"));
16938
16939 /* checking CONTROL */
16940 /* NACA == 1 or LINK == 1*/
16941 if ( (scsiCmnd->cdb[5] & SCSI_NACA_MASK) || (scsiCmnd->cdb[5] & SCSI_LINK_MASK) )
16942 {
16943 smsatSetSensePayload( pSense,
16944 SCSI_SNSKEY_ILLEGAL_REQUEST,
16945 0,
16946 SCSI_SNSCODE_INVALID_FIELD_IN_CDB,
16947 satIOContext);
16948
16949 /*smEnqueueIO(smRoot, satIOContext);*/
16950
16951 tdsmIOCompletedCB( smRoot,
16952 smIORequest,
16953 smIOSuccess,
16954 SCSI_STAT_CHECK_CONDITION,
16955 satIOContext->pSmSenseData,
16956 satIOContext->interruptContext );
16957
16958 SM_DBG1(("smsatReassignBlocks: return control!!!\n"));
16959 return SM_RC_SUCCESS;
16960 }
16961
16962 sm_memset(satIOContext->LBA, 0, 8);
16963 satIOContext->ParmIndex = 0;
16964 satIOContext->ParmLen = 0;
16965
16966 LongList = (bit8)(scsiCmnd->cdb[1] & SCSI_REASSIGN_BLOCKS_LONGLIST_MASK);
16967 LongLBA = (bit8)(scsiCmnd->cdb[1] & SCSI_REASSIGN_BLOCKS_LONGLBA_MASK);
16968 sm_memset(LBA, 0, sizeof(LBA));
16969
16970 if (LongList == 0)
16971 {
16972 defectListLen = (pParmList[2] << 8) + pParmList[3];
16973 }
16974 else
16975 {
16976 defectListLen = (pParmList[0] << (8*3)) + (pParmList[1] << (8*2))
16977 + (pParmList[2] << 8) + pParmList[3];
16978 }
16979 /* SBC 5.16.2, p61*/
16980 satIOContext->ParmLen = defectListLen + 4 /* header size */;
16981
16982 startingIndex = 4;
16983
16984 if (LongLBA == 0)
16985 {
16986 LBA[4] = pParmList[startingIndex]; /* MSB */
16987 LBA[5] = pParmList[startingIndex+1];
16988 LBA[6] = pParmList[startingIndex+2];
16989 LBA[7] = pParmList[startingIndex+3]; /* LSB */
16990 startingIndex = startingIndex + 4;
16991 }
16992 else
16993 {
16994 LBA[0] = pParmList[startingIndex]; /* MSB */
16995 LBA[1] = pParmList[startingIndex+1];
16996 LBA[2] = pParmList[startingIndex+2];
16997 LBA[3] = pParmList[startingIndex+3];
16998 LBA[4] = pParmList[startingIndex+4];
16999 LBA[5] = pParmList[startingIndex+5];
17000 LBA[6] = pParmList[startingIndex+6];
17001 LBA[7] = pParmList[startingIndex+7]; /* LSB */
17002 startingIndex = startingIndex + 8;
17003 }
17004
17005 smhexdump("smsatReassignBlocks Parameter list", (bit8 *)pParmList, 4 + defectListLen);
17006
17007 if (pSatDevData->sat48BitSupport == agTRUE)
17008 {
17009 /* sends READ VERIFY SECTOR(S) EXT*/
17010 fis->h.fisType = 0x27; /* Reg host to device */
17011 fis->h.c_pmPort = 0x80; /* C Bit is set */
17012 fis->h.command = SAT_READ_VERIFY_SECTORS_EXT;/* 0x42 */
17013 fis->h.features = 0; /* FIS reserve */
17014 fis->d.lbaLow = LBA[7]; /* FIS LBA (7 :0 ) */
17015 fis->d.lbaMid = LBA[6]; /* FIS LBA (15:8 ) */
17016 fis->d.lbaHigh = LBA[5]; /* FIS LBA (23:16) */
17017 fis->d.lbaLowExp = LBA[4]; /* FIS LBA (31:24) */
17018 fis->d.lbaMidExp = LBA[3]; /* FIS LBA (39:32) */
17019 fis->d.lbaHighExp = LBA[2]; /* FIS LBA (47:40) */
17020 fis->d.featuresExp = 0; /* FIS reserve */
17021 fis->d.sectorCount = 1; /* FIS sector count (7:0) */
17022 fis->d.sectorCountExp = 0; /* FIS sector count (15:8) */
17023 fis->d.reserved4 = 0;
17024 fis->d.device = 0x40; /* 01000000 */
17025 fis->d.control = 0; /* FIS HOB bit clear */
17026 fis->d.reserved5 = 0;
17027 }
17028 else
17029 {
17030 /* READ VERIFY SECTOR(S)*/
17031 fis->h.fisType = 0x27; /* Reg host to device */
17032 fis->h.c_pmPort = 0x80; /* C Bit is set */
17033 fis->h.command = SAT_READ_VERIFY_SECTORS;/* 0x40 */
17034 fis->h.features = 0; /* FIS features NA */
17035 fis->d.lbaLow = LBA[7]; /* FIS LBA (7 :0 ) */
17036 fis->d.lbaMid = LBA[6]; /* FIS LBA (15:8 ) */
17037 fis->d.lbaHigh = LBA[5]; /* FIS LBA (23:16) */
17038 fis->d.lbaLowExp = 0;
17039 fis->d.lbaMidExp = 0;
17040 fis->d.lbaHighExp = 0;
17041 fis->d.featuresExp = 0;
17042 fis->d.sectorCount = 1; /* FIS sector count (7:0) */
17043 fis->d.sectorCountExp = 0;
17044 fis->d.reserved4 = 0;
17045 fis->d.device = (bit8)((0x4 << 4) | (LBA[4] & 0xF));
17046 /* DEV and LBA 27:24 */
17047 fis->d.control = 0; /* FIS HOB bit clear */
17048 fis->d.reserved5 = 0;
17049 }
17050
17051 sm_memcpy(satIOContext->LBA, LBA, 8);
17052 satIOContext->ParmIndex = startingIndex;
17053
17054 agRequestType = AGSA_SATA_PROTOCOL_NON_DATA;
17055
17056 /* Initialize CB for SATA completion.
17057 */
17058 satIOContext->satCompleteCB = &smsatReassignBlocksCB;
17059
17060 /*
17061 * Prepare SGL and send FIS to LL layer.
17062 */
17063 satIOContext->reqType = agRequestType; /* Save it */
17064
17065 status = smsataLLIOStart( smRoot,
17066 smIORequest,
17067 smDeviceHandle,
17068 smScsiRequest,
17069 satIOContext);
17070
17071 return status;
17072 }
17073
17074 osGLOBAL bit32
smsatRead_1(smRoot_t * smRoot,smIORequest_t * smIORequest,smDeviceHandle_t * smDeviceHandle,smScsiInitiatorRequest_t * smScsiRequest,smSatIOContext_t * satIOContext)17075 smsatRead_1(
17076 smRoot_t *smRoot,
17077 smIORequest_t *smIORequest,
17078 smDeviceHandle_t *smDeviceHandle,
17079 smScsiInitiatorRequest_t *smScsiRequest,
17080 smSatIOContext_t *satIOContext
17081 )
17082 {
17083 /*
17084 Assumption: error check on lba and tl has been done in satRead*()
17085 lba = lba + tl;
17086 */
17087 bit32 status;
17088 smSatIOContext_t *satOrgIOContext = agNULL;
17089 smIniScsiCmnd_t *scsiCmnd;
17090 agsaFisRegHostToDevice_t *fis;
17091 bit32 agRequestType = AGSA_SATA_PROTOCOL_DMA_READ;
17092 bit32 lba = 0;
17093 bit32 DenomTL = 0xFF;
17094 bit32 Remainder = 0;
17095 bit8 LBA[4]; /* 0 MSB, 3 LSB */
17096
17097 SM_DBG2(("smsatRead_1: start\n"));
17098
17099 fis = satIOContext->pFis;
17100 satOrgIOContext = satIOContext->satOrgIOContext;
17101 scsiCmnd = satOrgIOContext->pScsiCmnd;
17102
17103 sm_memset(LBA,0, sizeof(LBA));
17104
17105 switch (satOrgIOContext->ATACmd)
17106 {
17107 case SAT_READ_DMA:
17108 DenomTL = 0x100;
17109 break;
17110 case SAT_READ_SECTORS:
17111 DenomTL = 0x100;
17112 break;
17113 case SAT_READ_DMA_EXT:
17114 DenomTL = 0xFFFF;
17115 break;
17116 case SAT_READ_SECTORS_EXT:
17117 DenomTL = 0xFFFF;
17118 break;
17119 case SAT_READ_FPDMA_QUEUED:
17120 DenomTL = 0xFFFF;
17121 break;
17122 default:
17123 SM_DBG1(("smsatRead_1: error incorrect ata command 0x%x!!!\n", satIOContext->ATACmd));
17124 return SM_RC_FAILURE;
17125 break;
17126 }
17127
17128 Remainder = satOrgIOContext->OrgTL % DenomTL;
17129 satOrgIOContext->currentLBA = satOrgIOContext->currentLBA + DenomTL;
17130 lba = satOrgIOContext->currentLBA;
17131
17132 LBA[0] = (bit8)((lba & 0xFF000000) >> (8 * 3));
17133 LBA[1] = (bit8)((lba & 0xFF0000) >> (8 * 2));
17134 LBA[2] = (bit8)((lba & 0xFF00) >> 8);
17135 LBA[3] = (bit8)(lba & 0xFF);
17136
17137 switch (satOrgIOContext->ATACmd)
17138 {
17139 case SAT_READ_DMA:
17140 fis->h.fisType = 0x27; /* Reg host to device */
17141 fis->h.c_pmPort = 0x80; /* C Bit is set */
17142 fis->h.command = SAT_READ_DMA; /* 0xC8 */
17143 fis->h.features = 0; /* FIS reserve */
17144 fis->d.lbaLow = LBA[3]; /* FIS LBA (7 :0 ) */
17145 fis->d.lbaMid = LBA[2]; /* FIS LBA (15:8 ) */
17146 fis->d.lbaHigh = LBA[1]; /* FIS LBA (23:16) */
17147 fis->d.device =
17148 (bit8)((0x4 << 4) | (LBA[0] & 0xF)); /* FIS LBA (27:24) and FIS LBA mode */
17149 fis->d.lbaLowExp = 0;
17150 fis->d.lbaMidExp = 0;
17151 fis->d.lbaHighExp = 0;
17152 fis->d.featuresExp = 0;
17153
17154 if (satOrgIOContext->LoopNum == 1)
17155 {
17156 /* last loop */
17157 fis->d.sectorCount = (bit8)Remainder; /* FIS sector count (7:0) */
17158 }
17159 else
17160 {
17161 fis->d.sectorCount = 0x0; /* FIS sector count (7:0) */
17162 }
17163
17164 fis->d.sectorCountExp = 0;
17165 fis->d.reserved4 = 0;
17166 fis->d.control = 0; /* FIS HOB bit clear */
17167 fis->d.reserved5 = 0;
17168
17169 agRequestType = AGSA_SATA_PROTOCOL_DMA_READ;
17170
17171 break;
17172 case SAT_READ_SECTORS:
17173 fis->h.fisType = 0x27; /* Reg host to device */
17174 fis->h.c_pmPort = 0x80; /* C Bit is set */
17175 fis->h.command = SAT_READ_SECTORS; /* 0x20 */
17176 fis->h.features = 0; /* FIS reserve */
17177 fis->d.lbaLow = LBA[3]; /* FIS LBA (7 :0 ) */
17178 fis->d.lbaMid = LBA[2]; /* FIS LBA (15:8 ) */
17179 fis->d.lbaHigh = LBA[1]; /* FIS LBA (23:16) */
17180 fis->d.device =
17181 (bit8)((0x4 << 4) | (LBA[0] & 0xF)); /* FIS LBA (27:24) and FIS LBA mode */
17182 fis->d.lbaLowExp = 0;
17183 fis->d.lbaMidExp = 0;
17184 fis->d.lbaHighExp = 0;
17185 fis->d.featuresExp = 0;
17186 if (satOrgIOContext->LoopNum == 1)
17187 {
17188 /* last loop */
17189 fis->d.sectorCount = (bit8)Remainder; /* FIS sector count (7:0) */
17190 }
17191 else
17192 {
17193 fis->d.sectorCount = 0x0; /* FIS sector count (7:0) */
17194 }
17195 fis->d.sectorCountExp = 0;
17196 fis->d.reserved4 = 0;
17197 fis->d.control = 0; /* FIS HOB bit clear */
17198 fis->d.reserved5 = 0;
17199
17200 agRequestType = AGSA_SATA_PROTOCOL_PIO_READ;
17201
17202 break;
17203 case SAT_READ_DMA_EXT:
17204 fis->h.fisType = 0x27; /* Reg host to device */
17205 fis->h.c_pmPort = 0x80; /* C Bit is set */
17206 fis->h.command = SAT_READ_DMA_EXT; /* 0x25 */
17207 fis->h.features = 0; /* FIS reserve */
17208 fis->d.lbaLow = LBA[3]; /* FIS LBA (7 :0 ) */
17209 fis->d.lbaMid = LBA[2]; /* FIS LBA (15:8 ) */
17210 fis->d.lbaHigh = LBA[1]; /* FIS LBA (23:16) */
17211 fis->d.device = 0x40; /* FIS LBA mode set */
17212 fis->d.lbaLowExp = LBA[0]; /* FIS LBA (31:24) */
17213 fis->d.lbaMidExp = 0; /* FIS LBA (39:32) */
17214 fis->d.lbaHighExp = 0; /* FIS LBA (47:40) */
17215 fis->d.featuresExp = 0; /* FIS reserve */
17216 if (satOrgIOContext->LoopNum == 1)
17217 {
17218 /* last loop */
17219 fis->d.sectorCount = (bit8)(Remainder & 0xFF); /* FIS sector count (7:0) */
17220 fis->d.sectorCountExp = (bit8)((Remainder & 0xFF00) >> 8); /* FIS sector count (15:8) */
17221
17222 }
17223 else
17224 {
17225 fis->d.sectorCount = 0xFF; /* FIS sector count (7:0) */
17226 fis->d.sectorCountExp = 0xFF; /* FIS sector count (15:8) */
17227 }
17228 fis->d.reserved4 = 0;
17229 fis->d.control = 0; /* FIS HOB bit clear */
17230 fis->d.reserved5 = 0;
17231
17232 agRequestType = AGSA_SATA_PROTOCOL_DMA_READ;
17233
17234 break;
17235 case SAT_READ_SECTORS_EXT:
17236 fis->h.fisType = 0x27; /* Reg host to device */
17237 fis->h.c_pmPort = 0x80; /* C Bit is set */
17238 fis->h.command = SAT_READ_SECTORS_EXT; /* 0x24 */
17239 fis->h.features = 0; /* FIS reserve */
17240 fis->d.lbaLow = LBA[3]; /* FIS LBA (7 :0 ) */
17241 fis->d.lbaMid = LBA[2]; /* FIS LBA (15:8 ) */
17242 fis->d.lbaHigh = LBA[1]; /* FIS LBA (23:16) */
17243 fis->d.device = 0x40; /* FIS LBA mode set */
17244 fis->d.lbaLowExp = LBA[0]; /* FIS LBA (31:24) */
17245 fis->d.lbaMidExp = 0; /* FIS LBA (39:32) */
17246 fis->d.lbaHighExp = 0; /* FIS LBA (47:40) */
17247 fis->d.featuresExp = 0; /* FIS reserve */
17248 if (satOrgIOContext->LoopNum == 1)
17249 {
17250 /* last loop */
17251 fis->d.sectorCount = (bit8)(Remainder & 0xFF); /* FIS sector count (7:0) */
17252 fis->d.sectorCountExp = (bit8)((Remainder & 0xFF00) >> 8); /* FIS sector count (15:8) */
17253 }
17254 else
17255 {
17256 fis->d.sectorCount = 0xFF; /* FIS sector count (7:0) */
17257 fis->d.sectorCountExp = 0xFF; /* FIS sector count (15:8) */
17258 }
17259 fis->d.reserved4 = 0;
17260 fis->d.control = 0; /* FIS HOB bit clear */
17261 fis->d.reserved5 = 0;
17262
17263 agRequestType = AGSA_SATA_PROTOCOL_PIO_READ;
17264 break;
17265 case SAT_READ_FPDMA_QUEUED:
17266 fis->h.fisType = 0x27; /* Reg host to device */
17267 fis->h.c_pmPort = 0x80; /* C Bit is set */
17268 fis->h.command = SAT_READ_FPDMA_QUEUED; /* 0x60 */
17269 fis->d.lbaLow = LBA[3]; /* FIS LBA (7 :0 ) */
17270 fis->d.lbaMid = LBA[2]; /* FIS LBA (15:8 ) */
17271 fis->d.lbaHigh = LBA[1]; /* FIS LBA (23:16) */
17272
17273 /* Check FUA bit */
17274 if (scsiCmnd->cdb[1] & SCSI_READ10_FUA_MASK)
17275 fis->d.device = 0xC0; /* FIS FUA set */
17276 else
17277 fis->d.device = 0x40; /* FIS FUA clear */
17278
17279 fis->d.lbaLowExp = LBA[0]; /* FIS LBA (31:24) */
17280 fis->d.lbaMidExp = 0; /* FIS LBA (39:32) */
17281 fis->d.lbaHighExp = 0; /* FIS LBA (47:40) */
17282 if (satOrgIOContext->LoopNum == 1)
17283 {
17284 /* last loop */
17285 fis->h.features = (bit8)(Remainder & 0xFF); /* FIS sector count (7:0) */
17286 fis->d.featuresExp = (bit8)((Remainder & 0xFF00) >> 8); /* FIS sector count (15:8) */
17287 }
17288 else
17289 {
17290 fis->h.features = 0xFF; /* FIS sector count (7:0) */
17291 fis->d.featuresExp = 0xFF; /* FIS sector count (15:8) */
17292 }
17293 fis->d.sectorCount = 0; /* Tag (7:3) set by LL layer */
17294 fis->d.sectorCountExp = 0;
17295 fis->d.reserved4 = 0;
17296 fis->d.control = 0; /* FIS HOB bit clear */
17297 fis->d.reserved5 = 0;
17298
17299 agRequestType = AGSA_SATA_PROTOCOL_FPDMA_READ;
17300 break;
17301 default:
17302 SM_DBG1(("smsatRead_1: error incorrect ata command 0x%x!!!\n", satIOContext->ATACmd));
17303 return SM_RC_FAILURE;
17304 break;
17305 }
17306
17307 /* Initialize CB for SATA completion.
17308 */
17309 /* chained data */
17310 satIOContext->satCompleteCB = &smsatChainedDataIOCB;
17311
17312 if (satOrgIOContext->ATACmd == SAT_READ_DMA || satOrgIOContext->ATACmd == SAT_READ_SECTORS)
17313 {
17314 smsatSplitSGL(smRoot,
17315 smIORequest,
17316 smDeviceHandle,
17317 (smScsiInitiatorRequest_t *)satOrgIOContext->smScsiXchg,
17318 satOrgIOContext,
17319 NON_BIT48_ADDRESS_TL_LIMIT * SATA_SECTOR_SIZE, /* 0x100 * 0x200*/
17320 (satOrgIOContext->OrgTL) * SATA_SECTOR_SIZE,
17321 agFALSE);
17322 }
17323 else
17324 {
17325 smsatSplitSGL(smRoot,
17326 smIORequest,
17327 smDeviceHandle,
17328 (smScsiInitiatorRequest_t *)satOrgIOContext->smScsiXchg,
17329 satOrgIOContext,
17330 BIT48_ADDRESS_TL_LIMIT * SATA_SECTOR_SIZE, /* 0xFFFF * 0x200*/
17331 (satOrgIOContext->OrgTL) * SATA_SECTOR_SIZE,
17332 agFALSE);
17333 }
17334
17335 /*
17336 * Prepare SGL and send FIS to LL layer.
17337 */
17338 satIOContext->reqType = agRequestType; /* Save it */
17339
17340 status = smsataLLIOStart( smRoot,
17341 smIORequest,
17342 smDeviceHandle,
17343 (smScsiInitiatorRequest_t *)satOrgIOContext->smScsiXchg, //smScsiRequest,
17344 satIOContext);
17345
17346 SM_DBG5(("smsatRead_1: return\n"));
17347 return (status);
17348 }
17349
17350 osGLOBAL bit32
smsatWrite_1(smRoot_t * smRoot,smIORequest_t * smIORequest,smDeviceHandle_t * smDeviceHandle,smScsiInitiatorRequest_t * smScsiRequest,smSatIOContext_t * satIOContext)17351 smsatWrite_1(
17352 smRoot_t *smRoot,
17353 smIORequest_t *smIORequest,
17354 smDeviceHandle_t *smDeviceHandle,
17355 smScsiInitiatorRequest_t *smScsiRequest,
17356 smSatIOContext_t *satIOContext
17357 )
17358 {
17359 /*
17360 Assumption: error check on lba and tl has been done in satWrite*()
17361 lba = lba + tl;
17362 */
17363 bit32 status;
17364 smSatIOContext_t *satOrgIOContext = agNULL;
17365 smIniScsiCmnd_t *scsiCmnd;
17366 agsaFisRegHostToDevice_t *fis;
17367 bit32 agRequestType = AGSA_SATA_PROTOCOL_DMA_WRITE;
17368 bit32 lba = 0;
17369 bit32 DenomTL = 0xFF;
17370 bit32 Remainder = 0;
17371 bit8 LBA[4]; /* 0 MSB, 3 LSB */
17372
17373 SM_DBG2(("smsatWrite_1: start\n"));
17374
17375 fis = satIOContext->pFis;
17376 satOrgIOContext = satIOContext->satOrgIOContext;
17377 scsiCmnd = satOrgIOContext->pScsiCmnd;
17378
17379 sm_memset(LBA,0, sizeof(LBA));
17380
17381 switch (satOrgIOContext->ATACmd)
17382 {
17383 case SAT_WRITE_DMA:
17384 DenomTL = 0x100;
17385 break;
17386 case SAT_WRITE_SECTORS:
17387 DenomTL = 0x100;
17388 break;
17389 case SAT_WRITE_DMA_EXT:
17390 DenomTL = 0xFFFF;
17391 break;
17392 case SAT_WRITE_DMA_FUA_EXT:
17393 DenomTL = 0xFFFF;
17394 break;
17395 case SAT_WRITE_SECTORS_EXT:
17396 DenomTL = 0xFFFF;
17397 break;
17398 case SAT_WRITE_FPDMA_QUEUED:
17399 DenomTL = 0xFFFF;
17400 break;
17401 default:
17402 SM_DBG1(("smsatWrite_1: error incorrect ata command 0x%x!!!\n", satIOContext->ATACmd));
17403 return SM_RC_FAILURE;
17404 break;
17405 }
17406
17407 Remainder = satOrgIOContext->OrgTL % DenomTL;
17408 satOrgIOContext->currentLBA = satOrgIOContext->currentLBA + DenomTL;
17409 lba = satOrgIOContext->currentLBA;
17410
17411
17412 LBA[0] = (bit8)((lba & 0xFF000000) >> (8 * 3));
17413 LBA[1] = (bit8)((lba & 0xFF0000) >> (8 * 2));
17414 LBA[2] = (bit8)((lba & 0xFF00) >> 8);
17415 LBA[3] = (bit8)(lba & 0xFF);
17416
17417 switch (satOrgIOContext->ATACmd)
17418 {
17419 case SAT_WRITE_DMA:
17420 fis->h.fisType = 0x27; /* Reg host to device */
17421 fis->h.c_pmPort = 0x80; /* C bit is set */
17422 fis->h.command = SAT_WRITE_DMA; /* 0xCA */
17423 fis->h.features = 0; /* FIS reserve */
17424 fis->d.lbaLow = LBA[3]; /* FIS LBA (7 :0 ) */
17425 fis->d.lbaMid = LBA[2]; /* FIS LBA (15:8 ) */
17426 fis->d.lbaHigh = LBA[1]; /* FIS LBA (23:16) */
17427
17428 /* FIS LBA mode set LBA (27:24) */
17429 fis->d.device = (bit8)((0x4 << 4) | (LBA[0] & 0xF));
17430
17431 fis->d.lbaLowExp = 0;
17432 fis->d.lbaMidExp = 0;
17433 fis->d.lbaHighExp = 0;
17434 fis->d.featuresExp = 0;
17435 if (satOrgIOContext->LoopNum == 1)
17436 {
17437 /* last loop */
17438 fis->d.sectorCount = (bit8)Remainder; /* FIS sector count (7:0) */
17439 }
17440 else
17441 {
17442 fis->d.sectorCount = 0x0; /* FIS sector count (7:0) */
17443 }
17444 fis->d.sectorCountExp = 0;
17445 fis->d.reserved4 = 0;
17446 fis->d.control = 0; /* FIS HOB bit clear */
17447 fis->d.reserved5 = 0;
17448
17449 agRequestType = AGSA_SATA_PROTOCOL_DMA_WRITE;
17450
17451 break;
17452 case SAT_WRITE_SECTORS:
17453 fis->h.fisType = 0x27; /* Reg host to device */
17454 fis->h.c_pmPort = 0x80; /* C bit is set */
17455 fis->h.command = SAT_WRITE_SECTORS; /* 0x30 */
17456 fis->h.features = 0; /* FIS reserve */
17457 fis->d.lbaLow = LBA[3]; /* FIS LBA (7 :0 ) */
17458 fis->d.lbaMid = LBA[2]; /* FIS LBA (15:8 ) */
17459 fis->d.lbaHigh = LBA[1]; /* FIS LBA (23:16) */
17460
17461 /* FIS LBA mode set LBA (27:24) */
17462 fis->d.device = (bit8)((0x4 << 4) | (LBA[0] & 0xF));
17463
17464 fis->d.lbaLowExp = 0;
17465 fis->d.lbaMidExp = 0;
17466 fis->d.lbaHighExp = 0;
17467 fis->d.featuresExp = 0;
17468 if (satOrgIOContext->LoopNum == 1)
17469 {
17470 /* last loop */
17471 fis->d.sectorCount = (bit8)Remainder; /* FIS sector count (7:0) */
17472 }
17473 else
17474 {
17475 fis->d.sectorCount = 0x0; /* FIS sector count (7:0) */
17476 }
17477 fis->d.sectorCountExp = 0;
17478 fis->d.reserved4 = 0;
17479 fis->d.control = 0; /* FIS HOB bit clear */
17480 fis->d.reserved5 = 0;
17481
17482 agRequestType = AGSA_SATA_PROTOCOL_PIO_WRITE;
17483
17484 break;
17485 case SAT_WRITE_DMA_EXT:
17486 fis->h.fisType = 0x27; /* Reg host to device */
17487 fis->h.c_pmPort = 0x80; /* C Bit is set */
17488 fis->h.command = SAT_WRITE_DMA_EXT; /* 0x3D */
17489 fis->h.features = 0; /* FIS reserve */
17490 fis->d.lbaLow = LBA[3]; /* FIS LBA (7 :0 ) */
17491 fis->d.lbaMid = LBA[2]; /* FIS LBA (15:8 ) */
17492 fis->d.lbaHigh = LBA[1]; /* FIS LBA (23:16) */
17493 fis->d.device = 0x40; /* FIS LBA mode set */
17494 fis->d.lbaLowExp = LBA[0]; /* FIS LBA (31:24) */
17495 fis->d.lbaMidExp = 0; /* FIS LBA (39:32) */
17496 fis->d.lbaHighExp = 0; /* FIS LBA (47:40) */
17497 fis->d.featuresExp = 0; /* FIS reserve */
17498 if (satOrgIOContext->LoopNum == 1)
17499 {
17500 /* last loop */
17501 fis->d.sectorCount = (bit8)(Remainder & 0xFF); /* FIS sector count (7:0) */
17502 fis->d.sectorCountExp = (bit8)((Remainder & 0xFF00) >> 8); /* FIS sector count (15:8) */
17503 }
17504 else
17505 {
17506 fis->d.sectorCount = 0xFF; /* FIS sector count (7:0) */
17507 fis->d.sectorCountExp = 0xFF; /* FIS sector count (15:8) */
17508 }
17509 fis->d.reserved4 = 0;
17510 fis->d.control = 0; /* FIS HOB bit clear */
17511 fis->d.reserved5 = 0;
17512
17513 agRequestType = AGSA_SATA_PROTOCOL_DMA_WRITE;
17514
17515 break;
17516 case SAT_WRITE_SECTORS_EXT:
17517 fis->h.fisType = 0x27; /* Reg host to device */
17518 fis->h.c_pmPort = 0x80; /* C Bit is set */
17519 fis->h.command = SAT_WRITE_SECTORS_EXT; /* 0x34 */
17520
17521 fis->h.features = 0; /* FIS reserve */
17522 fis->d.lbaLow = LBA[3]; /* FIS LBA (7 :0 ) */
17523 fis->d.lbaMid = LBA[2]; /* FIS LBA (15:8 ) */
17524 fis->d.lbaHigh = LBA[1]; /* FIS LBA (23:16) */
17525 fis->d.device = 0x40; /* FIS LBA mode set */
17526 fis->d.lbaLowExp = LBA[0]; /* FIS LBA (31:24) */
17527 fis->d.lbaMidExp = 0; /* FIS LBA (39:32) */
17528 fis->d.lbaHighExp = 0; /* FIS LBA (47:40) */
17529 fis->d.featuresExp = 0; /* FIS reserve */
17530 if (satOrgIOContext->LoopNum == 1)
17531 {
17532 /* last loop */
17533 fis->d.sectorCount = (bit8)(Remainder & 0xFF); /* FIS sector count (7:0) */
17534 fis->d.sectorCountExp = (bit8)((Remainder & 0xFF00) >> 8); /* FIS sector count (15:8) */
17535 }
17536 else
17537 {
17538 fis->d.sectorCount = 0xFF; /* FIS sector count (7:0) */
17539 fis->d.sectorCountExp = 0xFF; /* FIS sector count (15:8) */
17540 }
17541 fis->d.reserved4 = 0;
17542 fis->d.control = 0; /* FIS HOB bit clear */
17543 fis->d.reserved5 = 0;
17544
17545 agRequestType = AGSA_SATA_PROTOCOL_PIO_WRITE;
17546
17547 break;
17548 case SAT_WRITE_FPDMA_QUEUED:
17549 fis->h.fisType = 0x27; /* Reg host to device */
17550 fis->h.c_pmPort = 0x80; /* C Bit is set */
17551 fis->h.command = SAT_WRITE_FPDMA_QUEUED; /* 0x61 */
17552 fis->d.lbaLow = LBA[3]; /* FIS LBA (7 :0 ) */
17553 fis->d.lbaMid = LBA[2]; /* FIS LBA (15:8 ) */
17554 fis->d.lbaHigh = LBA[1]; /* FIS LBA (23:16) */
17555
17556 /* Check FUA bit */
17557 if (scsiCmnd->cdb[1] & SCSI_WRITE10_FUA_MASK)
17558 fis->d.device = 0xC0; /* FIS FUA set */
17559 else
17560 fis->d.device = 0x40; /* FIS FUA clear */
17561
17562 fis->d.lbaLowExp = LBA[0];; /* FIS LBA (31:24) */
17563 fis->d.lbaMidExp = 0; /* FIS LBA (39:32) */
17564 fis->d.lbaHighExp = 0; /* FIS LBA (47:40) */
17565 if (satOrgIOContext->LoopNum == 1)
17566 {
17567 /* last loop */
17568 fis->h.features = (bit8)(Remainder & 0xFF); /* FIS sector count (7:0) */
17569 fis->d.featuresExp = (bit8)((Remainder & 0xFF00) >> 8); /* FIS sector count (15:8) */
17570 }
17571 else
17572 {
17573 fis->h.features = 0xFF; /* FIS sector count (7:0) */
17574 fis->d.featuresExp = 0xFF; /* FIS sector count (15:8) */
17575 }
17576 fis->d.sectorCount = 0; /* Tag (7:3) set by LL layer */
17577 fis->d.sectorCountExp = 0;
17578 fis->d.reserved4 = 0;
17579 fis->d.control = 0; /* FIS HOB bit clear */
17580 fis->d.reserved5 = 0;
17581
17582 agRequestType = AGSA_SATA_PROTOCOL_FPDMA_WRITE;
17583 break;
17584
17585 default:
17586 SM_DBG1(("smsatWrite_1: error incorrect ata command 0x%x!!!\n", satIOContext->ATACmd));
17587 return SM_RC_FAILURE;
17588 break;
17589 }
17590
17591 /* Initialize CB for SATA completion.
17592 */
17593 /* chained data */
17594 satIOContext->satCompleteCB = &smsatChainedDataIOCB;
17595
17596 if (satOrgIOContext->ATACmd == SAT_WRITE_DMA || satOrgIOContext->ATACmd == SAT_WRITE_SECTORS)
17597 {
17598 smsatSplitSGL(smRoot,
17599 smIORequest,
17600 smDeviceHandle,
17601 (smScsiInitiatorRequest_t *)satOrgIOContext->smScsiXchg,
17602 satOrgIOContext,
17603 NON_BIT48_ADDRESS_TL_LIMIT * SATA_SECTOR_SIZE, /* 0x100 * 0x200*/
17604 (satOrgIOContext->OrgTL) * SATA_SECTOR_SIZE,
17605 agFALSE);
17606 }
17607 else
17608 {
17609 smsatSplitSGL(smRoot,
17610 smIORequest,
17611 smDeviceHandle,
17612 (smScsiInitiatorRequest_t *)satOrgIOContext->smScsiXchg,
17613 satOrgIOContext,
17614 BIT48_ADDRESS_TL_LIMIT * SATA_SECTOR_SIZE, /* 0xFFFF * 0x200*/
17615 (satOrgIOContext->OrgTL) * SATA_SECTOR_SIZE,
17616 agFALSE);
17617 }
17618
17619 /*
17620 * Prepare SGL and send FIS to LL layer.
17621 */
17622 satIOContext->reqType = agRequestType; /* Save it */
17623
17624 status = smsataLLIOStart( smRoot,
17625 smIORequest,
17626 smDeviceHandle,
17627 (smScsiInitiatorRequest_t *)satOrgIOContext->smScsiXchg, //smScsiRequest,
17628 satIOContext);
17629
17630 SM_DBG5(("smsatWrite_1: return\n"));
17631 return (status);
17632 }
17633
17634 osGLOBAL bit32
smsatPassthrough(smRoot_t * smRoot,smIORequest_t * smIORequest,smDeviceHandle_t * smDeviceHandle,smScsiInitiatorRequest_t * smScsiRequest,smSatIOContext_t * satIOContext)17635 smsatPassthrough(
17636 smRoot_t *smRoot,
17637 smIORequest_t *smIORequest,
17638 smDeviceHandle_t *smDeviceHandle,
17639 smScsiInitiatorRequest_t *smScsiRequest,
17640 smSatIOContext_t *satIOContext
17641 )
17642 {
17643 smScsiRspSense_t *pSense;
17644 smIniScsiCmnd_t *scsiCmnd;
17645 smDeviceData_t *pSatDevData;
17646 agsaFisRegHostToDevice_t *fis;
17647 bit32 status;
17648 bit32 agRequestType;
17649 smAtaPassThroughHdr_t ataPassThroughHdr;
17650
17651
17652 pSense = satIOContext->pSense;
17653 scsiCmnd = &smScsiRequest->scsiCmnd;
17654 pSatDevData = satIOContext->pSatDevData;
17655 fis = satIOContext->pFis;
17656
17657 SM_DBG1(("smsatPassthrough: START!!!\n"));
17658
17659 osti_memset(&ataPassThroughHdr, 0 , sizeof(smAtaPassThroughHdr_t));
17660
17661 ataPassThroughHdr.opc = scsiCmnd->cdb[0];
17662 ataPassThroughHdr.mulCount = scsiCmnd->cdb[1] >> 5;
17663 ataPassThroughHdr.proto = (scsiCmnd->cdb[1] >> 1) & 0x0F;
17664 ataPassThroughHdr.extend = scsiCmnd->cdb[1] & 1;
17665 ataPassThroughHdr.offline = scsiCmnd->cdb[2] >> 6;
17666 ataPassThroughHdr.ckCond = (scsiCmnd->cdb[2] >> 5) & 1;
17667 ataPassThroughHdr.tType = (scsiCmnd->cdb[2] >> 4) & 1;
17668 ataPassThroughHdr.tDir = (scsiCmnd->cdb[2] >> 3) & 1;
17669 ataPassThroughHdr.byteBlock = (scsiCmnd->cdb[2] >> 2) & 1;
17670 ataPassThroughHdr.tlength = scsiCmnd->cdb[2] & 0x3;
17671
17672 switch(ataPassThroughHdr.proto)
17673 {
17674 case 0:
17675 case 9:
17676 agRequestType = AGSA_SATA_PROTOCOL_DEV_RESET; //Device Reset
17677 break;
17678 case 1:
17679 agRequestType = AGSA_SATA_PROTOCOL_SRST_ASSERT; //Software reset
17680 break;
17681 case 3:
17682 agRequestType = AGSA_SATA_PROTOCOL_NON_DATA; //Non Data mode
17683 break;
17684 case 4:
17685 agRequestType = AGSA_SATA_PROTOCOL_PIO_READ; //IO_Data_In mode
17686 break;
17687 case 5:
17688 agRequestType = AGSA_SATA_PROTOCOL_PIO_WRITE; //PIO_Data_out
17689 break;
17690 case 6:
17691 agRequestType = AGSA_SATA_PROTOCOL_DMA_WRITE; //DMA READ and WRITE
17692 break;
17693 case 8:
17694 agRequestType = AGSA_SATA_ATAP_EXECDEVDIAG; //device diagnostic
17695 break;
17696 case 12:
17697 agRequestType = AGSA_SATA_PROTOCOL_FPDMA_WRITE; //FPDMA Read and Write
17698 break;
17699 default:
17700 agRequestType = AGSA_SATA_PROTOCOL_NON_DATA; //Default Non Data Mode
17701 break;
17702 }
17703
17704
17705 if((ataPassThroughHdr.tlength == 0) && (agRequestType != AGSA_SATA_PROTOCOL_NON_DATA))
17706 {
17707 SM_DBG1(("smsatPassthrough SCSI_SNSCODE_INVALID_FIELD_IN_CDB\n"));
17708
17709 smsatSetSensePayload( pSense,
17710 SCSI_SNSKEY_ILLEGAL_REQUEST,
17711 0,
17712 SCSI_SNSCODE_INVALID_FIELD_IN_CDB,
17713 satIOContext);
17714
17715 tdsmIOCompletedCB( smRoot,
17716 smIORequest,
17717 smIOSuccess,
17718 SCSI_STAT_CHECK_CONDITION,
17719 satIOContext->pSmSenseData,
17720 satIOContext->interruptContext );
17721
17722 return SM_RC_SUCCESS;
17723 }
17724
17725 if(scsiCmnd->cdb[0] == 0xA1)
17726 {
17727 SM_DBG1(("smsatPassthrough A1h: COMMAND: %x FEATURE: %x \n",scsiCmnd->cdb[9],scsiCmnd->cdb[3]));
17728
17729 fis->h.fisType = 0x27; /* Reg host to device */
17730 fis->h.c_pmPort = 0x80; /* C Bit is set */
17731 fis->h.features = scsiCmnd->cdb[3];
17732 fis->d.sectorCount = scsiCmnd->cdb[4]; /* 0x01 FIS sector count (7:0) */
17733 fis->d.lbaLow = scsiCmnd->cdb[5]; /* Reading LBA FIS LBA (7 :0 ) */
17734 fis->d.lbaMid = scsiCmnd->cdb[6];
17735 fis->d.lbaHigh = scsiCmnd->cdb[7];
17736 fis->d.device = scsiCmnd->cdb[8];
17737 fis->h.command = scsiCmnd->cdb[9];
17738 fis->d.featuresExp = 0;
17739 fis->d.sectorCountExp = 0;
17740 fis->d.lbaLowExp = 0;
17741 fis->d.lbaMidExp = 0;
17742 fis->d.lbaHighExp = 0;
17743 fis->d.reserved4 = 0;
17744 fis->d.control = 0; /* FIS HOB bit clear */
17745 fis->d.reserved5 = 0;
17746
17747 /* Initialize CB for SATA completion*/
17748 satIOContext->satCompleteCB = &smsatPassthroughCB;
17749
17750 /*
17751 * Prepare SGL and send FIS to LL layer.
17752 */
17753
17754 satIOContext->reqType = agRequestType;
17755 status = smsataLLIOStart( smRoot,
17756 smIORequest,
17757 smDeviceHandle,
17758 smScsiRequest,
17759 satIOContext);
17760 return status;
17761
17762 }
17763 else if(scsiCmnd->cdb[0] == 0x85)
17764 {
17765 SM_DBG1(("smsatPassthrough 85h: COMMAND: %x FEATURE: %x \n",scsiCmnd->cdb[14],scsiCmnd->cdb[4]));
17766
17767 fis->h.fisType = 0x27; /* Reg host to device */
17768 fis->h.c_pmPort = 0x80; /* C Bit is set */
17769
17770 if(1 == ataPassThroughHdr.extend)
17771 {
17772 fis->d.featuresExp = scsiCmnd->cdb[3];
17773 fis->d.sectorCountExp = scsiCmnd->cdb[5];
17774 fis->d.lbaMidExp = scsiCmnd->cdb[9];
17775 fis->d.lbaHighExp = scsiCmnd->cdb[11];
17776 fis->d.lbaLowExp = scsiCmnd->cdb[7];
17777 }
17778 fis->h.features = scsiCmnd->cdb[4];
17779 fis->d.sectorCount = scsiCmnd->cdb[6];
17780 fis->d.lbaLow = scsiCmnd->cdb[8];
17781 fis->d.lbaMid = scsiCmnd->cdb[10];
17782 fis->d.lbaHigh = scsiCmnd->cdb[12];
17783 fis->d.device = scsiCmnd->cdb[13];
17784 fis->h.command = scsiCmnd->cdb[14];
17785 fis->d.reserved4 = 0;
17786 fis->d.control = 0;
17787 fis->d.reserved5 = 0;
17788
17789
17790 /* Initialize CB for SATA completion.
17791 */
17792
17793 satIOContext->satCompleteCB = &smsatPassthroughCB;
17794
17795 /*
17796 * Prepare SGL and send FIS to LL layer.
17797 */
17798 satIOContext->reqType = agRequestType;
17799 status = smsataLLIOStart( smRoot,
17800 smIORequest,
17801 smDeviceHandle,
17802 smScsiRequest,
17803 satIOContext);
17804 return status;
17805
17806 }
17807 else
17808 {
17809 SM_DBG1(("smsatPassthrough : INVALD PASSTHROUGH!!!\n"));
17810 smsatSetSensePayload( pSense,
17811 SCSI_SNSKEY_ILLEGAL_REQUEST,
17812 0,
17813 SCSI_SNSCODE_INVALID_FIELD_IN_CDB,
17814 satIOContext);
17815 tdsmIOCompletedCB( smRoot,
17816 smIORequest,
17817 smIOSuccess,
17818 SCSI_STAT_CHECK_CONDITION,
17819 satIOContext->pSmSenseData,
17820 satIOContext->interruptContext );
17821
17822 SM_DBG1(("smsatPassthrough : return control!!!\n"));
17823
17824 return SM_RC_SUCCESS;
17825 }
17826 }
17827
17828 osGLOBAL bit32
smsatNonChainedWriteNVerify_Verify(smRoot_t * smRoot,smIORequest_t * smIORequest,smDeviceHandle_t * smDeviceHandle,smScsiInitiatorRequest_t * smScsiRequest,smSatIOContext_t * satIOContext)17829 smsatNonChainedWriteNVerify_Verify(
17830 smRoot_t *smRoot,
17831 smIORequest_t *smIORequest,
17832 smDeviceHandle_t *smDeviceHandle,
17833 smScsiInitiatorRequest_t *smScsiRequest,
17834 smSatIOContext_t *satIOContext
17835 )
17836 {
17837 bit32 status;
17838 bit32 agRequestType = AGSA_SATA_PROTOCOL_DMA_WRITE;
17839 smDeviceData_t *pSatDevData;
17840 smIniScsiCmnd_t *scsiCmnd;
17841 agsaFisRegHostToDevice_t *fis;
17842
17843 pSatDevData = satIOContext->pSatDevData;
17844 scsiCmnd = &smScsiRequest->scsiCmnd;
17845 fis = satIOContext->pFis;
17846 SM_DBG5(("smsatNonChainedWriteNVerify_Verify: start\n"));
17847 if (pSatDevData->sat48BitSupport == agTRUE)
17848 {
17849 fis->h.fisType = 0x27; /* Reg host to device */
17850 fis->h.c_pmPort = 0x80; /* C Bit is set */
17851
17852 fis->h.command = SAT_READ_VERIFY_SECTORS_EXT;/* 0x42 */
17853 fis->h.features = 0; /* FIS reserve */
17854 fis->d.lbaLow = scsiCmnd->cdb[5]; /* FIS LBA (7 :0 ) */
17855 fis->d.lbaMid = scsiCmnd->cdb[4]; /* FIS LBA (15:8 ) */
17856 fis->d.lbaHigh = scsiCmnd->cdb[3]; /* FIS LBA (23:16) */
17857 fis->d.device = 0x40; /* FIS LBA mode set 01000000 */
17858 fis->d.lbaLowExp = scsiCmnd->cdb[2]; /* FIS LBA (31:24) */
17859 fis->d.lbaMidExp = 0; /* FIS LBA (39:32) */
17860 fis->d.lbaHighExp = 0; /* FIS LBA (47:40) */
17861 fis->d.featuresExp = 0; /* FIS reserve */
17862 fis->d.sectorCount = scsiCmnd->cdb[8]; /* FIS sector count (7:0) */
17863 fis->d.sectorCountExp = scsiCmnd->cdb[7]; /* FIS sector count (15:8) */
17864
17865 fis->d.reserved4 = 0;
17866 fis->d.control = 0; /* FIS HOB bit clear */
17867 fis->d.reserved5 = 0;
17868
17869 agRequestType = AGSA_SATA_PROTOCOL_NON_DATA;
17870
17871 /* Initialize CB for SATA completion.
17872 */
17873 satIOContext->satCompleteCB = &smsatNonChainedWriteNVerifyCB;
17874
17875 /*
17876 * Prepare SGL and send FIS to LL layer.
17877 */
17878 satIOContext->reqType = agRequestType; /* Save it */
17879
17880 status = smsataLLIOStart( smRoot,
17881 smIORequest,
17882 smDeviceHandle,
17883 smScsiRequest,
17884 satIOContext);
17885
17886
17887 SM_DBG1(("smsatNonChainedWriteNVerify_Verify: return status %d!!!\n", status));
17888 return (status);
17889 }
17890 else
17891 {
17892 /* can't fit in SAT_READ_VERIFY_SECTORS becasue of Sector Count and LBA */
17893 SM_DBG1(("smsatNonChainedWriteNVerify_Verify: can't fit in SAT_READ_VERIFY_SECTORS!!!\n"));
17894 return SM_RC_FAILURE;
17895 }
17896 }
17897
17898 osGLOBAL bit32
smsatChainedWriteNVerify_Start_Verify(smRoot_t * smRoot,smIORequest_t * smIORequest,smDeviceHandle_t * smDeviceHandle,smScsiInitiatorRequest_t * smScsiRequest,smSatIOContext_t * satIOContext)17899 smsatChainedWriteNVerify_Start_Verify(
17900 smRoot_t *smRoot,
17901 smIORequest_t *smIORequest,
17902 smDeviceHandle_t *smDeviceHandle,
17903 smScsiInitiatorRequest_t *smScsiRequest,
17904 smSatIOContext_t *satIOContext
17905 )
17906 {
17907 /*
17908 deal with transfer length; others have been handled previously at this point;
17909 no LBA check; no range check;
17910 */
17911 bit32 status;
17912 bit32 agRequestType = AGSA_SATA_PROTOCOL_NON_DATA;
17913 smDeviceData_t *pSatDevData;
17914 smIniScsiCmnd_t *scsiCmnd;
17915 agsaFisRegHostToDevice_t *fis;
17916 bit32 lba = 0;
17917 bit32 tl = 0;
17918 bit32 LoopNum = 1;
17919 bit8 LBA[4];
17920 bit8 TL[4];
17921
17922 pSatDevData = satIOContext->pSatDevData;
17923 scsiCmnd = &smScsiRequest->scsiCmnd;
17924 fis = satIOContext->pFis;
17925
17926 SM_DBG5(("smsatChainedWriteNVerify_Start_Verify: start\n"));
17927 sm_memset(LBA, 0, sizeof(LBA));
17928 sm_memset(TL, 0, sizeof(TL));
17929 /* do not use memcpy due to indexing in LBA and TL */
17930 LBA[0] = scsiCmnd->cdb[2]; /* MSB */
17931 LBA[1] = scsiCmnd->cdb[3];
17932 LBA[2] = scsiCmnd->cdb[4];
17933 LBA[3] = scsiCmnd->cdb[5]; /* LSB */
17934 TL[0] = scsiCmnd->cdb[6]; /* MSB */
17935 TL[1] = scsiCmnd->cdb[7];
17936 TL[2] = scsiCmnd->cdb[7];
17937 TL[3] = scsiCmnd->cdb[8]; /* LSB */
17938 lba = smsatComputeCDB12LBA(satIOContext);
17939 tl = smsatComputeCDB12TL(satIOContext);
17940 if (pSatDevData->sat48BitSupport == agTRUE)
17941 {
17942 SM_DBG5(("smsatChainedWriteNVerify_Start_Verify: SAT_READ_VERIFY_SECTORS_EXT\n"));
17943 fis->h.fisType = 0x27; /* Reg host to device */
17944 fis->h.c_pmPort = 0x80; /* C Bit is set */
17945
17946 fis->h.command = SAT_READ_VERIFY_SECTORS_EXT;/* 0x42 */
17947 fis->h.features = 0; /* FIS reserve */
17948 fis->d.lbaLow = scsiCmnd->cdb[5]; /* FIS LBA (7 :0 ) */
17949 fis->d.lbaMid = scsiCmnd->cdb[4]; /* FIS LBA (15:8 ) */
17950 fis->d.lbaHigh = scsiCmnd->cdb[3]; /* FIS LBA (23:16) */
17951 fis->d.device = 0x40; /* FIS LBA mode set 01000000 */
17952 fis->d.lbaLowExp = scsiCmnd->cdb[2]; /* FIS LBA (31:24) */
17953 fis->d.lbaMidExp = 0; /* FIS LBA (39:32) */
17954 fis->d.lbaHighExp = 0; /* FIS LBA (47:40) */
17955 fis->d.featuresExp = 0; /* FIS reserve */
17956 fis->d.sectorCount = scsiCmnd->cdb[8]; /* FIS sector count (7:0) */
17957 fis->d.sectorCountExp = scsiCmnd->cdb[7]; /* FIS sector count (15:8) */
17958
17959 fis->d.reserved4 = 0;
17960 fis->d.control = 0; /* FIS HOB bit clear */
17961 fis->d.reserved5 = 0;
17962
17963 agRequestType = AGSA_SATA_PROTOCOL_NON_DATA;
17964 satIOContext->ATACmd = SAT_READ_VERIFY_SECTORS_EXT;
17965 }
17966 else
17967 {
17968 SM_DBG5(("smsatChainedWriteNVerify_Start_Verify: SAT_READ_VERIFY_SECTORS\n"));
17969 fis->h.fisType = 0x27; /* Reg host to device */
17970 fis->h.c_pmPort = 0x80; /* C bit is set */
17971 fis->h.command = SAT_READ_VERIFY_SECTORS; /* 0x40 */
17972 fis->h.features = 0; /* FIS reserve */
17973 fis->d.lbaLow = scsiCmnd->cdb[5]; /* FIS LBA (7 :0 ) */
17974 fis->d.lbaMid = scsiCmnd->cdb[4]; /* FIS LBA (15:8 ) */
17975 fis->d.lbaHigh = scsiCmnd->cdb[3]; /* FIS LBA (23:16) */
17976 /* FIS LBA mode set LBA (27:24) */
17977 fis->d.device = (bit8)((0x4 << 4) | (scsiCmnd->cdb[2] & 0xF));
17978 fis->d.lbaLowExp = 0;
17979 fis->d.lbaMidExp = 0;
17980 fis->d.lbaHighExp = 0;
17981 fis->d.featuresExp = 0;
17982 fis->d.sectorCount = scsiCmnd->cdb[8]; /* FIS sector count (7:0) */
17983 fis->d.sectorCountExp = 0;
17984 fis->d.reserved4 = 0;
17985 fis->d.control = 0; /* FIS HOB bit clear */
17986 fis->d.reserved5 = 0;
17987
17988 agRequestType = AGSA_SATA_PROTOCOL_NON_DATA;
17989 satIOContext->ATACmd = SAT_READ_VERIFY_SECTORS;
17990
17991 }
17992
17993 satIOContext->currentLBA = lba;
17994 satIOContext->OrgTL = tl;
17995
17996 /*
17997 computing number of loop and remainder for tl
17998 0xFF in case not ext
17999 0xFFFF in case EXT
18000 */
18001 if (fis->h.command == SAT_READ_VERIFY_SECTORS)
18002 {
18003 LoopNum = smsatComputeLoopNum(tl, 0xFF);
18004 }
18005 else if (fis->h.command == SAT_READ_VERIFY_SECTORS_EXT)
18006 {
18007 /* SAT_READ_SECTORS_EXT, SAT_READ_DMA_EXT */
18008 LoopNum = smsatComputeLoopNum(tl, 0xFFFF);
18009 }
18010 else
18011 {
18012 SM_DBG1(("smsatChainedWriteNVerify_Start_Verify: error case 1!!!\n"));
18013 LoopNum = 1;
18014 }
18015
18016 satIOContext->LoopNum = LoopNum;
18017
18018 if (LoopNum == 1)
18019 {
18020 SM_DBG5(("smsatChainedWriteNVerify_Start_Verify: NON CHAINED data\n"));
18021 /* Initialize CB for SATA completion.
18022 */
18023 satIOContext->satCompleteCB = &smsatNonChainedWriteNVerifyCB;
18024 }
18025 else
18026 {
18027 SM_DBG1(("smsatChainedWriteNVerify_Start_Verify: CHAINED data!!!\n"));
18028 /* re-setting tl */
18029 if (fis->h.command == SAT_READ_VERIFY_SECTORS)
18030 {
18031 fis->d.sectorCount = 0xFF;
18032 }
18033 else if (fis->h.command == SAT_READ_VERIFY_SECTORS_EXT)
18034 {
18035 fis->d.sectorCount = 0xFF;
18036 fis->d.sectorCountExp = 0xFF;
18037 }
18038 else
18039 {
18040 SM_DBG1(("smsatChainedWriteNVerify_Start_Verify: error case 2!!!\n"));
18041 }
18042
18043 /* Initialize CB for SATA completion.
18044 */
18045 satIOContext->satCompleteCB = &smsatChainedWriteNVerifyCB;
18046 }
18047
18048
18049 /*
18050 * Prepare SGL and send FIS to LL layer.
18051 */
18052 satIOContext->reqType = agRequestType; /* Save it */
18053
18054 status = smsataLLIOStart( smRoot,
18055 smIORequest,
18056 smDeviceHandle,
18057 smScsiRequest,
18058 satIOContext);
18059 return (status);
18060
18061
18062 }
18063
18064 osGLOBAL bit32
smsatChainedWriteNVerify_Write(smRoot_t * smRoot,smIORequest_t * smIORequest,smDeviceHandle_t * smDeviceHandle,smScsiInitiatorRequest_t * smScsiRequest,smSatIOContext_t * satIOContext)18065 smsatChainedWriteNVerify_Write(
18066 smRoot_t *smRoot,
18067 smIORequest_t *smIORequest,
18068 smDeviceHandle_t *smDeviceHandle,
18069 smScsiInitiatorRequest_t *smScsiRequest,
18070 smSatIOContext_t *satIOContext
18071 )
18072 {
18073 /*
18074 Assumption: error check on lba and tl has been done in satWrite*()
18075 lba = lba + tl;
18076 */
18077 bit32 status;
18078 smSatIOContext_t *satOrgIOContext = agNULL;
18079 smIniScsiCmnd_t *scsiCmnd;
18080 agsaFisRegHostToDevice_t *fis;
18081 bit32 agRequestType = AGSA_SATA_PROTOCOL_DMA_WRITE;
18082 bit32 lba = 0;
18083 bit32 DenomTL = 0xFF;
18084 bit32 Remainder = 0;
18085 bit8 LBA[4]; /* 0 MSB, 3 LSB */
18086
18087 SM_DBG1(("smsatChainedWriteNVerify_Write: start\n"));
18088
18089 fis = satIOContext->pFis;
18090 satOrgIOContext = satIOContext->satOrgIOContext;
18091 scsiCmnd = satOrgIOContext->pScsiCmnd;
18092
18093
18094 sm_memset(LBA,0, sizeof(LBA));
18095
18096 switch (satOrgIOContext->ATACmd)
18097 {
18098 case SAT_WRITE_DMA:
18099 DenomTL = 0xFF;
18100 break;
18101 case SAT_WRITE_SECTORS:
18102 DenomTL = 0xFF;
18103 break;
18104 case SAT_WRITE_DMA_EXT:
18105 DenomTL = 0xFFFF;
18106 break;
18107 case SAT_WRITE_DMA_FUA_EXT:
18108 DenomTL = 0xFFFF;
18109 break;
18110 case SAT_WRITE_SECTORS_EXT:
18111 DenomTL = 0xFFFF;
18112 break;
18113 case SAT_WRITE_FPDMA_QUEUED:
18114 DenomTL = 0xFFFF;
18115 break;
18116 default:
18117 SM_DBG1(("satChainedWriteNVerify_Write: error incorrect ata command 0x%x!!!\n", satIOContext->ATACmd));
18118 return SM_RC_FAILURE;
18119 break;
18120 }
18121
18122 Remainder = satOrgIOContext->OrgTL % DenomTL;
18123 satOrgIOContext->currentLBA = satOrgIOContext->currentLBA + DenomTL;
18124 lba = satOrgIOContext->currentLBA;
18125
18126 LBA[0] = (bit8)((lba & 0xF000) >> (8 * 3)); /* MSB */
18127 LBA[1] = (bit8)((lba & 0xF00) >> (8 * 2));
18128 LBA[2] = (bit8)((lba & 0xF0) >> 8);
18129 LBA[3] = (bit8)(lba & 0xF); /* LSB */
18130
18131 switch (satOrgIOContext->ATACmd)
18132 {
18133 case SAT_WRITE_DMA:
18134 fis->h.fisType = 0x27; /* Reg host to device */
18135 fis->h.c_pmPort = 0x80; /* C bit is set */
18136 fis->h.command = SAT_WRITE_DMA; /* 0xCA */
18137 fis->h.features = 0; /* FIS reserve */
18138 fis->d.lbaLow = LBA[3]; /* FIS LBA (7 :0 ) */
18139 fis->d.lbaMid = LBA[2]; /* FIS LBA (15:8 ) */
18140 fis->d.lbaHigh = LBA[1]; /* FIS LBA (23:16) */
18141
18142 /* FIS LBA mode set LBA (27:24) */
18143 fis->d.device = (bit8)((0x4 << 4) | (LBA[0] & 0xF));
18144
18145 fis->d.lbaLowExp = 0;
18146 fis->d.lbaMidExp = 0;
18147 fis->d.lbaHighExp = 0;
18148 fis->d.featuresExp = 0;
18149 if (satOrgIOContext->LoopNum == 1)
18150 {
18151 /* last loop */
18152 fis->d.sectorCount = (bit8)Remainder; /* FIS sector count (7:0) */
18153 }
18154 else
18155 {
18156 fis->d.sectorCount = 0xFF; /* FIS sector count (7:0) */
18157 }
18158 fis->d.sectorCountExp = 0;
18159 fis->d.reserved4 = 0;
18160 fis->d.control = 0; /* FIS HOB bit clear */
18161 fis->d.reserved5 = 0;
18162
18163 agRequestType = AGSA_SATA_PROTOCOL_DMA_WRITE;
18164
18165 break;
18166 case SAT_WRITE_SECTORS:
18167 fis->h.fisType = 0x27; /* Reg host to device */
18168 fis->h.c_pmPort = 0x80; /* C bit is set */
18169 fis->h.command = SAT_WRITE_SECTORS; /* 0x30 */
18170 fis->h.features = 0; /* FIS reserve */
18171 fis->d.lbaLow = LBA[3]; /* FIS LBA (7 :0 ) */
18172 fis->d.lbaMid = LBA[2]; /* FIS LBA (15:8 ) */
18173 fis->d.lbaHigh = LBA[1]; /* FIS LBA (23:16) */
18174
18175 /* FIS LBA mode set LBA (27:24) */
18176 fis->d.device = (bit8)((0x4 << 4) | (LBA[0] & 0xF));
18177
18178 fis->d.lbaLowExp = 0;
18179 fis->d.lbaMidExp = 0;
18180 fis->d.lbaHighExp = 0;
18181 fis->d.featuresExp = 0;
18182 if (satOrgIOContext->LoopNum == 1)
18183 {
18184 /* last loop */
18185 fis->d.sectorCount = (bit8)Remainder; /* FIS sector count (7:0) */
18186 }
18187 else
18188 {
18189 fis->d.sectorCount = 0xFF; /* FIS sector count (7:0) */
18190 }
18191 fis->d.sectorCountExp = 0;
18192 fis->d.reserved4 = 0;
18193 fis->d.control = 0; /* FIS HOB bit clear */
18194 fis->d.reserved5 = 0;
18195
18196 agRequestType = AGSA_SATA_PROTOCOL_PIO_WRITE;
18197
18198 break;
18199 case SAT_WRITE_DMA_EXT:
18200 fis->h.fisType = 0x27; /* Reg host to device */
18201 fis->h.c_pmPort = 0x80; /* C Bit is set */
18202 fis->h.command = SAT_WRITE_DMA_EXT; /* 0x3D */
18203 fis->h.features = 0; /* FIS reserve */
18204 fis->d.lbaLow = LBA[3]; /* FIS LBA (7 :0 ) */
18205 fis->d.lbaMid = LBA[2]; /* FIS LBA (15:8 ) */
18206 fis->d.lbaHigh = LBA[1]; /* FIS LBA (23:16) */
18207 fis->d.device = 0x40; /* FIS LBA mode set */
18208 fis->d.lbaLowExp = LBA[0]; /* FIS LBA (31:24) */
18209 fis->d.lbaMidExp = 0; /* FIS LBA (39:32) */
18210 fis->d.lbaHighExp = 0; /* FIS LBA (47:40) */
18211 fis->d.featuresExp = 0; /* FIS reserve */
18212 if (satOrgIOContext->LoopNum == 1)
18213 {
18214 /* last loop */
18215 fis->d.sectorCount = (bit8)(Remainder & 0xFF); /* FIS sector count (7:0) */
18216 fis->d.sectorCountExp = (bit8)((Remainder & 0xFF00) >> 8); /* FIS sector count (15:8) */
18217 }
18218 else
18219 {
18220 fis->d.sectorCount = 0xFF; /* FIS sector count (7:0) */
18221 fis->d.sectorCountExp = 0xFF; /* FIS sector count (15:8) */
18222 }
18223 fis->d.reserved4 = 0;
18224 fis->d.control = 0; /* FIS HOB bit clear */
18225 fis->d.reserved5 = 0;
18226
18227 agRequestType = AGSA_SATA_PROTOCOL_DMA_WRITE;
18228
18229 break;
18230 case SAT_WRITE_SECTORS_EXT:
18231 fis->h.fisType = 0x27; /* Reg host to device */
18232 fis->h.c_pmPort = 0x80; /* C Bit is set */
18233 fis->h.command = SAT_WRITE_SECTORS_EXT; /* 0x34 */
18234
18235 fis->h.features = 0; /* FIS reserve */
18236 fis->d.lbaLow = LBA[3]; /* FIS LBA (7 :0 ) */
18237 fis->d.lbaMid = LBA[2]; /* FIS LBA (15:8 ) */
18238 fis->d.lbaHigh = LBA[1]; /* FIS LBA (23:16) */
18239 fis->d.device = 0x40; /* FIS LBA mode set */
18240 fis->d.lbaLowExp = LBA[0]; /* FIS LBA (31:24) */
18241 fis->d.lbaMidExp = 0; /* FIS LBA (39:32) */
18242 fis->d.lbaHighExp = 0; /* FIS LBA (47:40) */
18243 fis->d.featuresExp = 0; /* FIS reserve */
18244 if (satOrgIOContext->LoopNum == 1)
18245 {
18246 /* last loop */
18247 fis->d.sectorCount = (bit8)(Remainder & 0xFF); /* FIS sector count (7:0) */
18248 fis->d.sectorCountExp = (bit8)((Remainder & 0xFF00) >> 8); /* FIS sector count (15:8) */
18249 }
18250 else
18251 {
18252 fis->d.sectorCount = 0xFF; /* FIS sector count (7:0) */
18253 fis->d.sectorCountExp = 0xFF; /* FIS sector count (15:8) */
18254 }
18255 fis->d.reserved4 = 0;
18256 fis->d.control = 0; /* FIS HOB bit clear */
18257 fis->d.reserved5 = 0;
18258
18259 agRequestType = AGSA_SATA_PROTOCOL_PIO_WRITE;
18260
18261 break;
18262 case SAT_WRITE_FPDMA_QUEUED:
18263 fis->h.fisType = 0x27; /* Reg host to device */
18264 fis->h.c_pmPort = 0x80; /* C Bit is set */
18265 fis->h.command = SAT_WRITE_FPDMA_QUEUED; /* 0x61 */
18266 fis->d.lbaLow = LBA[3]; /* FIS LBA (7 :0 ) */
18267 fis->d.lbaMid = LBA[2]; /* FIS LBA (15:8 ) */
18268 fis->d.lbaHigh = LBA[1]; /* FIS LBA (23:16) */
18269
18270 /* Check FUA bit */
18271 if (scsiCmnd->cdb[1] & SCSI_WRITE10_FUA_MASK)
18272 fis->d.device = 0xC0; /* FIS FUA set */
18273 else
18274 fis->d.device = 0x40; /* FIS FUA clear */
18275
18276 fis->d.lbaLowExp = LBA[0];; /* FIS LBA (31:24) */
18277 fis->d.lbaMidExp = 0; /* FIS LBA (39:32) */
18278 fis->d.lbaHighExp = 0; /* FIS LBA (47:40) */
18279 if (satOrgIOContext->LoopNum == 1)
18280 {
18281 /* last loop */
18282 fis->h.features = (bit8)(Remainder & 0xFF); /* FIS sector count (7:0) */
18283 fis->d.featuresExp = (bit8)((Remainder & 0xFF00) >> 8); /* FIS sector count (15:8) */
18284 }
18285 else
18286 {
18287 fis->h.features = 0xFF; /* FIS sector count (7:0) */
18288 fis->d.featuresExp = 0xFF; /* FIS sector count (15:8) */
18289 }
18290 fis->d.sectorCount = 0; /* Tag (7:3) set by LL layer */
18291 fis->d.sectorCountExp = 0;
18292 fis->d.reserved4 = 0;
18293 fis->d.control = 0; /* FIS HOB bit clear */
18294 fis->d.reserved5 = 0;
18295
18296 agRequestType = AGSA_SATA_PROTOCOL_FPDMA_WRITE;
18297 break;
18298
18299 default:
18300 SM_DBG1(("satChainedWriteNVerify_Write: error incorrect ata command 0x%x!!!\n", satIOContext->ATACmd));
18301 return SM_RC_FAILURE;
18302 break;
18303 }
18304
18305 /* Initialize CB for SATA completion.
18306 */
18307 /* chained data */
18308 satIOContext->satCompleteCB = &smsatChainedWriteNVerifyCB;
18309
18310
18311 /*
18312 * Prepare SGL and send FIS to LL layer.
18313 */
18314 satIOContext->reqType = agRequestType; /* Save it */
18315
18316 status = smsataLLIOStart( smRoot,
18317 smIORequest,
18318 smDeviceHandle,
18319 smScsiRequest,
18320 satIOContext);
18321
18322 SM_DBG5(("satChainedWriteNVerify_Write: return\n"));
18323 return (status);
18324 }
18325
18326 osGLOBAL bit32
smsatChainedWriteNVerify_Verify(smRoot_t * smRoot,smIORequest_t * smIORequest,smDeviceHandle_t * smDeviceHandle,smScsiInitiatorRequest_t * smScsiRequest,smSatIOContext_t * satIOContext)18327 smsatChainedWriteNVerify_Verify(
18328 smRoot_t *smRoot,
18329 smIORequest_t *smIORequest,
18330 smDeviceHandle_t *smDeviceHandle,
18331 smScsiInitiatorRequest_t *smScsiRequest,
18332 smSatIOContext_t *satIOContext
18333 )
18334 {
18335 bit32 status;
18336 smSatIOContext_t *satOrgIOContext = agNULL;
18337 agsaFisRegHostToDevice_t *fis;
18338 bit32 agRequestType = AGSA_SATA_PROTOCOL_NON_DATA;
18339 bit32 lba = 0;
18340 bit32 DenomTL = 0xFF;
18341 bit32 Remainder = 0;
18342 bit8 LBA[4]; /* 0 MSB, 3 LSB */
18343
18344 SM_DBG2(("smsatChainedWriteNVerify_Verify: start\n"));
18345 fis = satIOContext->pFis;
18346 satOrgIOContext = satIOContext->satOrgIOContext;
18347 sm_memset(LBA,0, sizeof(LBA));
18348 switch (satOrgIOContext->ATACmd)
18349 {
18350 case SAT_READ_VERIFY_SECTORS:
18351 DenomTL = 0xFF;
18352 break;
18353 case SAT_READ_VERIFY_SECTORS_EXT:
18354 DenomTL = 0xFFFF;
18355 break;
18356 default:
18357 SM_DBG1(("smsatChainedWriteNVerify_Verify: error incorrect ata command 0x%x!!!\n", satIOContext->ATACmd));
18358 return SM_RC_FAILURE;
18359 break;
18360 }
18361
18362 Remainder = satOrgIOContext->OrgTL % DenomTL;
18363 satOrgIOContext->currentLBA = satOrgIOContext->currentLBA + DenomTL;
18364 lba = satOrgIOContext->currentLBA;
18365
18366 LBA[0] = (bit8)((lba & 0xF000) >> (8 * 3)); /* MSB */
18367 LBA[1] = (bit8)((lba & 0xF00) >> (8 * 2));
18368 LBA[2] = (bit8)((lba & 0xF0) >> 8);
18369 LBA[3] = (bit8)(lba & 0xF); /* LSB */
18370
18371 switch (satOrgIOContext->ATACmd)
18372 {
18373 case SAT_READ_VERIFY_SECTORS:
18374 fis->h.fisType = 0x27; /* Reg host to device */
18375 fis->h.c_pmPort = 0x80; /* C bit is set */
18376 fis->h.command = SAT_READ_VERIFY_SECTORS; /* 0x40 */
18377 fis->h.features = 0; /* FIS reserve */
18378 fis->d.lbaLow = LBA[3]; /* FIS LBA (7 :0 ) */
18379 fis->d.lbaMid = LBA[2]; /* FIS LBA (15:8 ) */
18380 fis->d.lbaHigh = LBA[1]; /* FIS LBA (23:16) */
18381
18382 /* FIS LBA mode set LBA (27:24) */
18383 fis->d.device = (bit8)((0x4 << 4) | (LBA[0] & 0xF));
18384
18385 fis->d.lbaLowExp = 0;
18386 fis->d.lbaMidExp = 0;
18387 fis->d.lbaHighExp = 0;
18388 fis->d.featuresExp = 0;
18389 if (satOrgIOContext->LoopNum == 1)
18390 {
18391 /* last loop */
18392 fis->d.sectorCount = (bit8)Remainder; /* FIS sector count (7:0) */
18393 }
18394 else
18395 {
18396 fis->d.sectorCount = 0xFF; /* FIS sector count (7:0) */
18397 }
18398 fis->d.sectorCountExp = 0;
18399 fis->d.reserved4 = 0;
18400 fis->d.control = 0; /* FIS HOB bit clear */
18401 fis->d.reserved5 = 0;
18402
18403 agRequestType = AGSA_SATA_PROTOCOL_NON_DATA;
18404
18405 break;
18406 case SAT_READ_VERIFY_SECTORS_EXT:
18407 fis->h.fisType = 0x27; /* Reg host to device */
18408 fis->h.c_pmPort = 0x80; /* C Bit is set */
18409 fis->h.command = SAT_READ_VERIFY_SECTORS_EXT; /* 0x42 */
18410 fis->h.features = 0; /* FIS reserve */
18411 fis->d.lbaLow = LBA[3]; /* FIS LBA (7 :0 ) */
18412 fis->d.lbaMid = LBA[2]; /* FIS LBA (15:8 ) */
18413 fis->d.lbaHigh = LBA[1]; /* FIS LBA (23:16) */
18414 fis->d.device = 0x40; /* FIS LBA mode set */
18415 fis->d.lbaLowExp = LBA[0]; /* FIS LBA (31:24) */
18416 fis->d.lbaMidExp = 0; /* FIS LBA (39:32) */
18417 fis->d.lbaHighExp = 0; /* FIS LBA (47:40) */
18418 fis->d.featuresExp = 0; /* FIS reserve */
18419 if (satOrgIOContext->LoopNum == 1)
18420 {
18421 /* last loop */
18422 fis->d.sectorCount = (bit8)(Remainder & 0xFF); /* FIS sector count (7:0) */
18423 fis->d.sectorCountExp = (bit8)((Remainder & 0xFF00) >> 8); /* FIS sector count (15:8) */
18424 }
18425 else
18426 {
18427 fis->d.sectorCount = 0xFF; /* FIS sector count (7:0) */
18428 fis->d.sectorCountExp = 0xFF; /* FIS sector count (15:8) */
18429 }
18430 fis->d.reserved4 = 0;
18431 fis->d.control = 0; /* FIS HOB bit clear */
18432 fis->d.reserved5 = 0;
18433
18434 agRequestType = AGSA_SATA_PROTOCOL_NON_DATA;
18435
18436 break;
18437
18438 default:
18439 SM_DBG1(("smsatChainedWriteNVerify_Verify: error incorrect ata command 0x%x!!!\n", satIOContext->ATACmd));
18440 return SM_RC_FAILURE;
18441 break;
18442 }
18443
18444 /* Initialize CB for SATA completion.
18445 */
18446 /* chained data */
18447 satIOContext->satCompleteCB = &smsatChainedWriteNVerifyCB;
18448
18449
18450 /*
18451 * Prepare SGL and send FIS to LL layer.
18452 */
18453 satIOContext->reqType = agRequestType; /* Save it */
18454
18455 status = smsataLLIOStart( smRoot,
18456 smIORequest,
18457 smDeviceHandle,
18458 smScsiRequest,
18459 satIOContext);
18460
18461 SM_DBG5(("smsatChainedWriteNVerify_Verify: return\n"));
18462 return (status);
18463 }
18464
18465 osGLOBAL bit32
smsatChainedVerify(smRoot_t * smRoot,smIORequest_t * smIORequest,smDeviceHandle_t * smDeviceHandle,smScsiInitiatorRequest_t * smScsiRequest,smSatIOContext_t * satIOContext)18466 smsatChainedVerify(
18467 smRoot_t *smRoot,
18468 smIORequest_t *smIORequest,
18469 smDeviceHandle_t *smDeviceHandle,
18470 smScsiInitiatorRequest_t *smScsiRequest,
18471 smSatIOContext_t *satIOContext
18472 )
18473 {
18474 bit32 status;
18475 smSatIOContext_t *satOrgIOContext = agNULL;
18476 agsaFisRegHostToDevice_t *fis;
18477 bit32 agRequestType = AGSA_SATA_PROTOCOL_NON_DATA;
18478 bit32 lba = 0;
18479 bit32 DenomTL = 0xFF;
18480 bit32 Remainder = 0;
18481 bit8 LBA[4]; /* 0 MSB, 3 LSB */
18482
18483 SM_DBG2(("smsatChainedVerify: start\n"));
18484 fis = satIOContext->pFis;
18485 satOrgIOContext = satIOContext->satOrgIOContext;
18486 sm_memset(LBA,0, sizeof(LBA));
18487 switch (satOrgIOContext->ATACmd)
18488 {
18489 case SAT_READ_VERIFY_SECTORS:
18490 DenomTL = 0xFF;
18491 break;
18492 case SAT_READ_VERIFY_SECTORS_EXT:
18493 DenomTL = 0xFFFF;
18494 break;
18495 default:
18496 SM_DBG1(("satChainedVerify: error incorrect ata command 0x%x!!!\n", satIOContext->ATACmd));
18497 return tiError;
18498 break;
18499 }
18500
18501 Remainder = satOrgIOContext->OrgTL % DenomTL;
18502 satOrgIOContext->currentLBA = satOrgIOContext->currentLBA + DenomTL;
18503 lba = satOrgIOContext->currentLBA;
18504
18505 LBA[0] = (bit8)((lba & 0xF000) >> (8 * 3)); /* MSB */
18506 LBA[1] = (bit8)((lba & 0xF00) >> (8 * 2));
18507 LBA[2] = (bit8)((lba & 0xF0) >> 8);
18508 LBA[3] = (bit8)(lba & 0xF); /* LSB */
18509
18510 switch (satOrgIOContext->ATACmd)
18511 {
18512 case SAT_READ_VERIFY_SECTORS:
18513 fis->h.fisType = 0x27; /* Reg host to device */
18514 fis->h.c_pmPort = 0x80; /* C bit is set */
18515 fis->h.command = SAT_READ_VERIFY_SECTORS; /* 0x40 */
18516 fis->h.features = 0; /* FIS reserve */
18517 fis->d.lbaLow = LBA[3]; /* FIS LBA (7 :0 ) */
18518 fis->d.lbaMid = LBA[2]; /* FIS LBA (15:8 ) */
18519 fis->d.lbaHigh = LBA[1]; /* FIS LBA (23:16) */
18520
18521 /* FIS LBA mode set LBA (27:24) */
18522 fis->d.device = (bit8)((0x4 << 4) | (LBA[0] & 0xF));
18523
18524 fis->d.lbaLowExp = 0;
18525 fis->d.lbaMidExp = 0;
18526 fis->d.lbaHighExp = 0;
18527 fis->d.featuresExp = 0;
18528 if (satOrgIOContext->LoopNum == 1)
18529 {
18530 /* last loop */
18531 fis->d.sectorCount = (bit8)Remainder; /* FIS sector count (7:0) */
18532 }
18533 else
18534 {
18535 fis->d.sectorCount = 0xFF; /* FIS sector count (7:0) */
18536 }
18537 fis->d.sectorCountExp = 0;
18538 fis->d.reserved4 = 0;
18539 fis->d.control = 0; /* FIS HOB bit clear */
18540 fis->d.reserved5 = 0;
18541
18542 agRequestType = AGSA_SATA_PROTOCOL_NON_DATA;
18543
18544 break;
18545 case SAT_READ_VERIFY_SECTORS_EXT:
18546 fis->h.fisType = 0x27; /* Reg host to device */
18547 fis->h.c_pmPort = 0x80; /* C Bit is set */
18548 fis->h.command = SAT_READ_VERIFY_SECTORS_EXT; /* 0x42 */
18549 fis->h.features = 0; /* FIS reserve */
18550 fis->d.lbaLow = LBA[3]; /* FIS LBA (7 :0 ) */
18551 fis->d.lbaMid = LBA[2]; /* FIS LBA (15:8 ) */
18552 fis->d.lbaHigh = LBA[1]; /* FIS LBA (23:16) */
18553 fis->d.device = 0x40; /* FIS LBA mode set */
18554 fis->d.lbaLowExp = LBA[0]; /* FIS LBA (31:24) */
18555 fis->d.lbaMidExp = 0; /* FIS LBA (39:32) */
18556 fis->d.lbaHighExp = 0; /* FIS LBA (47:40) */
18557 fis->d.featuresExp = 0; /* FIS reserve */
18558 if (satOrgIOContext->LoopNum == 1)
18559 {
18560 /* last loop */
18561 fis->d.sectorCount = (bit8)(Remainder & 0xFF); /* FIS sector count (7:0) */
18562 fis->d.sectorCountExp = (bit8)((Remainder & 0xFF00) >> 8); /* FIS sector count (15:8) */
18563 }
18564 else
18565 {
18566 fis->d.sectorCount = 0xFF; /* FIS sector count (7:0) */
18567 fis->d.sectorCountExp = 0xFF; /* FIS sector count (15:8) */
18568 }
18569 fis->d.reserved4 = 0;
18570 fis->d.control = 0; /* FIS HOB bit clear */
18571 fis->d.reserved5 = 0;
18572
18573 agRequestType = AGSA_SATA_PROTOCOL_NON_DATA;
18574
18575 break;
18576
18577 default:
18578 SM_DBG1(("satChainedVerify: error incorrect ata command 0x%x!!!\n", satIOContext->ATACmd));
18579 return tiError;
18580 break;
18581 }
18582
18583 /* Initialize CB for SATA completion.
18584 */
18585 /* chained data */
18586 satIOContext->satCompleteCB = &smsatChainedVerifyCB;
18587
18588
18589 /*
18590 * Prepare SGL and send FIS to LL layer.
18591 */
18592 satIOContext->reqType = agRequestType; /* Save it */
18593
18594 status = smsataLLIOStart( smRoot,
18595 smIORequest,
18596 smDeviceHandle,
18597 smScsiRequest,
18598 satIOContext);
18599
18600 SM_DBG5(("satChainedVerify: return\n"));
18601 return (status);
18602 }
18603
18604 osGLOBAL bit32
smsatWriteSame10_1(smRoot_t * smRoot,smIORequest_t * smIORequest,smDeviceHandle_t * smDeviceHandle,smScsiInitiatorRequest_t * smScsiRequest,smSatIOContext_t * satIOContext,bit32 lba)18605 smsatWriteSame10_1(
18606 smRoot_t *smRoot,
18607 smIORequest_t *smIORequest,
18608 smDeviceHandle_t *smDeviceHandle,
18609 smScsiInitiatorRequest_t *smScsiRequest,
18610 smSatIOContext_t *satIOContext,
18611 bit32 lba
18612 )
18613 {
18614 /*
18615 sends SAT_WRITE_DMA_EXT
18616 */
18617
18618 bit32 status;
18619 bit32 agRequestType;
18620 agsaFisRegHostToDevice_t *fis;
18621 bit8 lba1, lba2 ,lba3, lba4;
18622
18623 SM_DBG5(("smsatWriteSame10_1: start\n"));
18624 fis = satIOContext->pFis;
18625 /* MSB */
18626 lba1 = (bit8)((lba & 0xFF000000) >> (8*3));
18627 lba2 = (bit8)((lba & 0x00FF0000) >> (8*2));
18628 lba3 = (bit8)((lba & 0x0000FF00) >> (8*1));
18629 /* LSB */
18630 lba4 = (bit8)(lba & 0x000000FF);
18631 /* SAT_WRITE_DMA_EXT */
18632 fis->h.fisType = 0x27; /* Reg host to device */
18633 fis->h.c_pmPort = 0x80; /* C Bit is set */
18634 fis->h.command = SAT_WRITE_DMA_EXT; /* 0x35 */
18635 fis->h.features = 0; /* FIS reserve */
18636 fis->d.lbaLow = lba4; /* FIS LBA (7 :0 ) */
18637 fis->d.lbaMid = lba3; /* FIS LBA (15:8 ) */
18638 fis->d.lbaHigh = lba2; /* FIS LBA (23:16) */
18639 fis->d.device = 0x40; /* FIS LBA mode set */
18640 fis->d.lbaLowExp = lba1; /* FIS LBA (31:24) */
18641 fis->d.lbaMidExp = 0; /* FIS LBA (39:32) */
18642 fis->d.lbaHighExp = 0; /* FIS LBA (47:40) */
18643 fis->d.featuresExp = 0; /* FIS reserve */
18644 /* one sector at a time */
18645 fis->d.sectorCount = 1; /* FIS sector count (7:0) */
18646 fis->d.sectorCountExp = 0; /* FIS sector count (15:8) */
18647 fis->d.reserved4 = 0;
18648 fis->d.control = 0; /* FIS HOB bit clear */
18649 fis->d.reserved5 = 0;
18650 agRequestType = AGSA_SATA_PROTOCOL_DMA_WRITE;
18651 /* Initialize CB for SATA completion.
18652 */
18653 satIOContext->satCompleteCB = &smsatWriteSame10CB;
18654 /*
18655 * Prepare SGL and send FIS to LL layer.
18656 */
18657 satIOContext->reqType = agRequestType; /* Save it */
18658 status = smsataLLIOStart( smRoot,
18659 smIORequest,
18660 smDeviceHandle,
18661 smScsiRequest,
18662 satIOContext);
18663 SM_DBG5(("smsatWriteSame10_1 return status %d\n", status));
18664 return status;
18665 }
18666
18667
18668 osGLOBAL bit32
smsatWriteSame10_2(smRoot_t * smRoot,smIORequest_t * smIORequest,smDeviceHandle_t * smDeviceHandle,smScsiInitiatorRequest_t * smScsiRequest,smSatIOContext_t * satIOContext,bit32 lba)18669 smsatWriteSame10_2(
18670 smRoot_t *smRoot,
18671 smIORequest_t *smIORequest,
18672 smDeviceHandle_t *smDeviceHandle,
18673 smScsiInitiatorRequest_t *smScsiRequest,
18674 smSatIOContext_t *satIOContext,
18675 bit32 lba
18676 )
18677 {
18678 /*
18679 sends SAT_WRITE_SECTORS_EXT
18680 */
18681
18682 bit32 status;
18683 bit32 agRequestType;
18684 agsaFisRegHostToDevice_t *fis;
18685 bit8 lba1, lba2 ,lba3, lba4;
18686
18687 SM_DBG5(("smsatWriteSame10_2: start\n"));
18688 fis = satIOContext->pFis;
18689 /* MSB */
18690 lba1 = (bit8)((lba & 0xFF000000) >> (8*3));
18691 lba2 = (bit8)((lba & 0x00FF0000) >> (8*2));
18692 lba3 = (bit8)((lba & 0x0000FF00) >> (8*1));
18693 /* LSB */
18694 lba4 = (bit8)(lba & 0x000000FF);
18695 /* SAT_WRITE_SECTORS_EXT */
18696 fis->h.fisType = 0x27; /* Reg host to device */
18697 fis->h.c_pmPort = 0x80; /* C Bit is set */
18698 fis->h.command = SAT_WRITE_SECTORS_EXT; /* 0x34 */
18699 fis->h.features = 0; /* FIS reserve */
18700 fis->d.lbaLow = lba4; /* FIS LBA (7 :0 ) */
18701 fis->d.lbaMid = lba3; /* FIS LBA (15:8 ) */
18702 fis->d.lbaHigh = lba2; /* FIS LBA (23:16) */
18703 fis->d.device = 0x40; /* FIS LBA mode set */
18704 fis->d.lbaLowExp = lba1; /* FIS LBA (31:24) */
18705 fis->d.lbaMidExp = 0; /* FIS LBA (39:32) */
18706 fis->d.lbaHighExp = 0; /* FIS LBA (47:40) */
18707 fis->d.featuresExp = 0; /* FIS reserve */
18708 /* one sector at a time */
18709 fis->d.sectorCount = 1; /* FIS sector count (7:0) */
18710 fis->d.sectorCountExp = 0; /* FIS sector count (15:8) */
18711 fis->d.reserved4 = 0;
18712 fis->d.control = 0; /* FIS HOB bit clear */
18713 fis->d.reserved5 = 0;
18714 agRequestType = AGSA_SATA_PROTOCOL_PIO_WRITE;
18715 /* Initialize CB for SATA completion.
18716 */
18717 satIOContext->satCompleteCB = &smsatWriteSame10CB;
18718 /*
18719 * Prepare SGL and send FIS to LL layer.
18720 */
18721 satIOContext->reqType = agRequestType; /* Save it */
18722 status = smsataLLIOStart( smRoot,
18723 smIORequest,
18724 smDeviceHandle,
18725 smScsiRequest,
18726 satIOContext);
18727 SM_DBG5(("smsatWriteSame10_2 return status %d\n", status));
18728 return status;
18729 }
18730
18731
18732 osGLOBAL bit32
smsatWriteSame10_3(smRoot_t * smRoot,smIORequest_t * smIORequest,smDeviceHandle_t * smDeviceHandle,smScsiInitiatorRequest_t * smScsiRequest,smSatIOContext_t * satIOContext,bit32 lba)18733 smsatWriteSame10_3(
18734 smRoot_t *smRoot,
18735 smIORequest_t *smIORequest,
18736 smDeviceHandle_t *smDeviceHandle,
18737 smScsiInitiatorRequest_t *smScsiRequest,
18738 smSatIOContext_t *satIOContext,
18739 bit32 lba
18740 )
18741 {
18742 /*
18743 sends SAT_WRITE_FPDMA_QUEUED
18744 */
18745
18746 bit32 status;
18747 bit32 agRequestType;
18748 agsaFisRegHostToDevice_t *fis;
18749 bit8 lba1, lba2 ,lba3, lba4;
18750
18751 SM_DBG5(("smsatWriteSame10_3: start\n"));
18752 fis = satIOContext->pFis;
18753 /* MSB */
18754 lba1 = (bit8)((lba & 0xFF000000) >> (8*3));
18755 lba2 = (bit8)((lba & 0x00FF0000) >> (8*2));
18756 lba3 = (bit8)((lba & 0x0000FF00) >> (8*1));
18757 /* LSB */
18758 lba4 = (bit8)(lba & 0x000000FF);
18759
18760 /* SAT_WRITE_FPDMA_QUEUED */
18761 fis->h.fisType = 0x27; /* Reg host to device */
18762 fis->h.c_pmPort = 0x80; /* C Bit is set */
18763 fis->h.command = SAT_WRITE_FPDMA_QUEUED; /* 0x61 */
18764
18765
18766 /* one sector at a time */
18767 fis->h.features = 1; /* FIS sector count (7:0) */
18768 fis->d.featuresExp = 0; /* FIS sector count (15:8) */
18769
18770 fis->d.lbaLow = lba4; /* FIS LBA (7 :0 ) */
18771 fis->d.lbaMid = lba3; /* FIS LBA (15:8 ) */
18772 fis->d.lbaHigh = lba2; /* FIS LBA (23:16) */
18773 /* NO FUA bit in the WRITE SAME 10 */
18774 fis->d.device = 0x40; /* FIS FUA clear */
18775 fis->d.lbaLowExp = lba1; /* FIS LBA (31:24) */
18776 fis->d.lbaMidExp = 0; /* FIS LBA (39:32) */
18777 fis->d.lbaHighExp = 0; /* FIS LBA (47:40) */
18778 fis->d.sectorCount = 0; /* Tag (7:3) set by LL layer */
18779 fis->d.sectorCountExp = 0;
18780 fis->d.reserved4 = 0;
18781 fis->d.control = 0; /* FIS HOB bit clear */
18782 fis->d.reserved5 = 0;
18783 agRequestType = AGSA_SATA_PROTOCOL_FPDMA_WRITE;
18784
18785 /* Initialize CB for SATA completion.
18786 */
18787 satIOContext->satCompleteCB = &smsatWriteSame10CB;
18788 /*
18789 * Prepare SGL and send FIS to LL layer.
18790 */
18791 satIOContext->reqType = agRequestType; /* Save it */
18792 status = smsataLLIOStart( smRoot,
18793 smIORequest,
18794 smDeviceHandle,
18795 smScsiRequest,
18796 satIOContext);
18797
18798 SM_DBG5(("smsatWriteSame10_3 return status %d\n", status));
18799 return status;
18800 }
18801
18802 osGLOBAL bit32
smsatStartStopUnit_1(smRoot_t * smRoot,smIORequest_t * smIORequest,smDeviceHandle_t * smDeviceHandle,smScsiInitiatorRequest_t * smScsiRequest,smSatIOContext_t * satIOContext)18803 smsatStartStopUnit_1(
18804 smRoot_t *smRoot,
18805 smIORequest_t *smIORequest,
18806 smDeviceHandle_t *smDeviceHandle,
18807 smScsiInitiatorRequest_t *smScsiRequest,
18808 smSatIOContext_t *satIOContext
18809 )
18810 {
18811 /*
18812 SAT Rev 8, Table 48, 9.11.3 p55
18813 sends STANDBY
18814 */
18815 bit32 status;
18816 bit32 agRequestType;
18817 agsaFisRegHostToDevice_t *fis;
18818
18819 SM_DBG5(("smsatStartStopUnit_1: start\n"));
18820 fis = satIOContext->pFis;
18821 /* STANDBY */
18822 fis->h.fisType = 0x27; /* Reg host to device */
18823 fis->h.c_pmPort = 0x80; /* C Bit is set */
18824 fis->h.command = SAT_STANDBY; /* 0xE2 */
18825 fis->h.features = 0; /* FIS features NA */
18826 fis->d.lbaLow = 0; /* FIS LBA (7 :0 ) */
18827 fis->d.lbaMid = 0; /* FIS LBA (15:8 ) */
18828 fis->d.lbaHigh = 0; /* FIS LBA (23:16) */
18829 fis->d.lbaLowExp = 0;
18830 fis->d.lbaMidExp = 0;
18831 fis->d.lbaHighExp = 0;
18832 fis->d.featuresExp = 0;
18833 fis->d.sectorCount = 0; /* FIS sector count (7:0) */
18834 fis->d.sectorCountExp = 0;
18835 fis->d.reserved4 = 0;
18836 fis->d.device = 0; /* 0 */
18837 fis->d.control = 0; /* FIS HOB bit clear */
18838 fis->d.reserved5 = 0;
18839
18840 agRequestType = AGSA_SATA_PROTOCOL_NON_DATA;
18841
18842 /* Initialize CB for SATA completion.
18843 */
18844 satIOContext->satCompleteCB = &smsatStartStopUnitCB;
18845
18846 /*
18847 * Prepare SGL and send FIS to LL layer.
18848 */
18849 satIOContext->reqType = agRequestType; /* Save it */
18850
18851 status = smsataLLIOStart( smRoot,
18852 smIORequest,
18853 smDeviceHandle,
18854 smScsiRequest,
18855 satIOContext);
18856
18857 SM_DBG5(("smsatStartStopUnit_1 return status %d\n", status));
18858 return status;
18859 }
18860
18861 osGLOBAL bit32
smsatSendDiagnostic_1(smRoot_t * smRoot,smIORequest_t * smIORequest,smDeviceHandle_t * smDeviceHandle,smScsiInitiatorRequest_t * smScsiRequest,smSatIOContext_t * satIOContext)18862 smsatSendDiagnostic_1(
18863 smRoot_t *smRoot,
18864 smIORequest_t *smIORequest,
18865 smDeviceHandle_t *smDeviceHandle,
18866 smScsiInitiatorRequest_t *smScsiRequest,
18867 smSatIOContext_t *satIOContext
18868 )
18869 {
18870 /*
18871 SAT Rev9, Table29, p41
18872 send 2nd SAT_READ_VERIFY_SECTORS(_EXT)
18873 */
18874 bit32 status;
18875 bit32 agRequestType;
18876 smDeviceData_t *pSatDevData;
18877 agsaFisRegHostToDevice_t *fis;
18878
18879 SM_DBG5(("smsatSendDiagnostic_1: start\n"));
18880 pSatDevData = satIOContext->pSatDevData;
18881 fis = satIOContext->pFis;
18882 /*
18883 sector count 1, LBA MAX
18884 */
18885 if (pSatDevData->sat48BitSupport == agTRUE)
18886 {
18887 /* sends READ VERIFY SECTOR(S) EXT*/
18888 fis->h.fisType = 0x27; /* Reg host to device */
18889 fis->h.c_pmPort = 0x80; /* C Bit is set */
18890 fis->h.command = SAT_READ_VERIFY_SECTORS_EXT;/* 0x42 */
18891 fis->h.features = 0; /* FIS reserve */
18892 fis->d.lbaLow = pSatDevData->satMaxLBA[7]; /* FIS LBA (7 :0 ) */
18893 fis->d.lbaMid = pSatDevData->satMaxLBA[6]; /* FIS LBA (15:8 ) */
18894 fis->d.lbaHigh = pSatDevData->satMaxLBA[5]; /* FIS LBA (23:16) */
18895 fis->d.lbaLowExp = pSatDevData->satMaxLBA[4]; /* FIS LBA (31:24) */
18896 fis->d.lbaMidExp = pSatDevData->satMaxLBA[3]; /* FIS LBA (39:32) */
18897 fis->d.lbaHighExp = pSatDevData->satMaxLBA[2]; /* FIS LBA (47:40) */
18898 fis->d.featuresExp = 0; /* FIS reserve */
18899 fis->d.sectorCount = 1; /* FIS sector count (7:0) */
18900 fis->d.sectorCountExp = 0; /* FIS sector count (15:8) */
18901 fis->d.reserved4 = 0;
18902 fis->d.device = 0x40; /* 01000000 */
18903 fis->d.control = 0; /* FIS HOB bit clear */
18904 fis->d.reserved5 = 0;
18905
18906 }
18907 else
18908 {
18909 /* READ VERIFY SECTOR(S)*/
18910 fis->h.fisType = 0x27; /* Reg host to device */
18911 fis->h.c_pmPort = 0x80; /* C Bit is set */
18912 fis->h.command = SAT_READ_VERIFY_SECTORS;/* 0x40 */
18913 fis->h.features = 0; /* FIS features NA */
18914 fis->d.lbaLow = pSatDevData->satMaxLBA[7]; /* FIS LBA (7 :0 ) */
18915 fis->d.lbaMid = pSatDevData->satMaxLBA[6]; /* FIS LBA (15:8 ) */
18916 fis->d.lbaHigh = pSatDevData->satMaxLBA[5]; /* FIS LBA (23:16) */
18917 fis->d.lbaLowExp = 0;
18918 fis->d.lbaMidExp = 0;
18919 fis->d.lbaHighExp = 0;
18920 fis->d.featuresExp = 0;
18921 fis->d.sectorCount = 1; /* FIS sector count (7:0) */
18922 fis->d.sectorCountExp = 0;
18923 fis->d.reserved4 = 0;
18924 fis->d.device = (bit8)((0x4 << 4) | (pSatDevData->satMaxLBA[4] & 0xF));
18925 /* DEV and LBA 27:24 */
18926 fis->d.control = 0; /* FIS HOB bit clear */
18927 fis->d.reserved5 = 0;
18928
18929 }
18930
18931 agRequestType = AGSA_SATA_PROTOCOL_NON_DATA;
18932
18933 /* Initialize CB for SATA completion.
18934 */
18935 satIOContext->satCompleteCB = &smsatSendDiagnosticCB;
18936
18937 /*
18938 * Prepare SGL and send FIS to LL layer.
18939 */
18940 satIOContext->reqType = agRequestType; /* Save it */
18941
18942 status = smsataLLIOStart( smRoot,
18943 smIORequest,
18944 smDeviceHandle,
18945 smScsiRequest,
18946 satIOContext);
18947
18948
18949 return status;
18950 }
18951
18952 osGLOBAL bit32
smsatSendDiagnostic_2(smRoot_t * smRoot,smIORequest_t * smIORequest,smDeviceHandle_t * smDeviceHandle,smScsiInitiatorRequest_t * smScsiRequest,smSatIOContext_t * satIOContext)18953 smsatSendDiagnostic_2(
18954 smRoot_t *smRoot,
18955 smIORequest_t *smIORequest,
18956 smDeviceHandle_t *smDeviceHandle,
18957 smScsiInitiatorRequest_t *smScsiRequest,
18958 smSatIOContext_t *satIOContext
18959 )
18960 {
18961 /*
18962 SAT Rev9, Table29, p41
18963 send 3rd SAT_READ_VERIFY_SECTORS(_EXT)
18964 */
18965 bit32 status;
18966 bit32 agRequestType;
18967 smDeviceData_t *pSatDevData;
18968 agsaFisRegHostToDevice_t *fis;
18969
18970 SM_DBG5(("smsatSendDiagnostic_2: start\n"));
18971
18972 pSatDevData = satIOContext->pSatDevData;
18973 fis = satIOContext->pFis;
18974 /*
18975 sector count 1, LBA Random
18976 */
18977 if (pSatDevData->sat48BitSupport == agTRUE)
18978 {
18979 /* sends READ VERIFY SECTOR(S) EXT*/
18980 fis->h.fisType = 0x27; /* Reg host to device */
18981 fis->h.c_pmPort = 0x80; /* C Bit is set */
18982 fis->h.command = SAT_READ_VERIFY_SECTORS_EXT;/* 0x42 */
18983 fis->h.features = 0; /* FIS reserve */
18984 fis->d.lbaLow = 0x7F; /* FIS LBA (7 :0 ) */
18985 fis->d.lbaMid = 0; /* FIS LBA (15:8 ) */
18986 fis->d.lbaHigh = 0; /* FIS LBA (23:16) */
18987 fis->d.lbaLowExp = 0; /* FIS LBA (31:24) */
18988 fis->d.lbaMidExp = 0; /* FIS LBA (39:32) */
18989 fis->d.lbaHighExp = 0; /* FIS LBA (47:40) */
18990 fis->d.featuresExp = 0; /* FIS reserve */
18991 fis->d.sectorCount = 1; /* FIS sector count (7:0) */
18992 fis->d.sectorCountExp = 0; /* FIS sector count (15:8) */
18993 fis->d.reserved4 = 0;
18994 fis->d.device = 0x40; /* 01000000 */
18995 fis->d.control = 0; /* FIS HOB bit clear */
18996 fis->d.reserved5 = 0;
18997
18998 }
18999 else
19000 {
19001 /* READ VERIFY SECTOR(S)*/
19002 fis->h.fisType = 0x27; /* Reg host to device */
19003 fis->h.c_pmPort = 0x80; /* C Bit is set */
19004 fis->h.command = SAT_READ_VERIFY_SECTORS;/* 0x40 */
19005 fis->h.features = 0; /* FIS features NA */
19006 fis->d.lbaLow = 0x7F; /* FIS LBA (7 :0 ) */
19007 fis->d.lbaMid = 0; /* FIS LBA (15:8 ) */
19008 fis->d.lbaHigh = 0; /* FIS LBA (23:16) */
19009 fis->d.lbaLowExp = 0;
19010 fis->d.lbaMidExp = 0;
19011 fis->d.lbaHighExp = 0;
19012 fis->d.featuresExp = 0;
19013 fis->d.sectorCount = 1; /* FIS sector count (7:0) */
19014 fis->d.sectorCountExp = 0;
19015 fis->d.reserved4 = 0;
19016 fis->d.device = 0x40; /* FIS LBA mode set 01000000 */
19017 fis->d.control = 0; /* FIS HOB bit clear */
19018 fis->d.reserved5 = 0;
19019
19020 }
19021
19022 agRequestType = AGSA_SATA_PROTOCOL_NON_DATA;
19023
19024 /* Initialize CB for SATA completion.
19025 */
19026 satIOContext->satCompleteCB = &smsatSendDiagnosticCB;
19027
19028 /*
19029 * Prepare SGL and send FIS to LL layer.
19030 */
19031 satIOContext->reqType = agRequestType; /* Save it */
19032
19033 status = smsataLLIOStart( smRoot,
19034 smIORequest,
19035 smDeviceHandle,
19036 smScsiRequest,
19037 satIOContext);
19038
19039
19040 return status;
19041 }
19042
19043 osGLOBAL bit32
smsatModeSelect6n10_1(smRoot_t * smRoot,smIORequest_t * smIORequest,smDeviceHandle_t * smDeviceHandle,smScsiInitiatorRequest_t * smScsiRequest,smSatIOContext_t * satIOContext)19044 smsatModeSelect6n10_1(
19045 smRoot_t *smRoot,
19046 smIORequest_t *smIORequest,
19047 smDeviceHandle_t *smDeviceHandle,
19048 smScsiInitiatorRequest_t *smScsiRequest,
19049 smSatIOContext_t *satIOContext
19050 )
19051 {
19052 /* sends either ATA SET FEATURES based on DRA bit */
19053 bit32 status;
19054 bit32 agRequestType;
19055 agsaFisRegHostToDevice_t *fis;
19056 bit8 *pLogPage; /* Log Page data buffer */
19057 bit32 StartingIndex = 0;
19058
19059 fis = satIOContext->pFis;
19060 pLogPage = (bit8 *) smScsiRequest->sglVirtualAddr;
19061 SM_DBG5(("smsatModeSelect6n10_1: start\n"));
19062
19063 if (pLogPage[3] == 8)
19064 {
19065 /* mode parameter block descriptor exists */
19066 StartingIndex = 12;
19067 }
19068 else
19069 {
19070 /* mode parameter block descriptor does not exist */
19071 StartingIndex = 4;
19072 }
19073
19074 /* sends ATA SET FEATURES based on DRA bit */
19075 if ( !(pLogPage[StartingIndex + 12] & SCSI_MODE_SELECT6_DRA_MASK) )
19076 {
19077 SM_DBG5(("smsatModeSelect6n10_1: enable read look-ahead feature\n"));
19078 /* sends SET FEATURES */
19079 fis->h.fisType = 0x27; /* Reg host to device */
19080 fis->h.c_pmPort = 0x80; /* C Bit is set */
19081
19082 fis->h.command = SAT_SET_FEATURES; /* 0xEF */
19083 fis->h.features = 0xAA; /* enable read look-ahead */
19084 fis->d.lbaLow = 0; /* */
19085 fis->d.lbaMid = 0; /* */
19086 fis->d.lbaHigh = 0; /* */
19087 fis->d.device = 0; /* */
19088 fis->d.lbaLowExp = 0; /* */
19089 fis->d.lbaMidExp = 0; /* */
19090 fis->d.lbaHighExp = 0; /* */
19091 fis->d.featuresExp = 0; /* */
19092 fis->d.sectorCount = 0; /* */
19093 fis->d.sectorCountExp = 0; /* */
19094 fis->d.reserved4 = 0;
19095 fis->d.control = 0; /* FIS HOB bit clear */
19096 fis->d.reserved5 = 0;
19097
19098 agRequestType = AGSA_SATA_PROTOCOL_NON_DATA;
19099
19100 /* Initialize CB for SATA completion.
19101 */
19102 satIOContext->satCompleteCB = &smsatModeSelect6n10CB;
19103
19104 /*
19105 * Prepare SGL and send FIS to LL layer.
19106 */
19107 satIOContext->reqType = agRequestType; /* Save it */
19108
19109 status = smsataLLIOStart( smRoot,
19110 smIORequest,
19111 smDeviceHandle,
19112 smScsiRequest,
19113 satIOContext);
19114 return status;
19115 }
19116 else
19117 {
19118 SM_DBG5(("smsatModeSelect6n10_1: disable read look-ahead feature\n"));
19119 /* sends SET FEATURES */
19120 fis->h.fisType = 0x27; /* Reg host to device */
19121 fis->h.c_pmPort = 0x80; /* C Bit is set */
19122
19123 fis->h.command = SAT_SET_FEATURES; /* 0xEF */
19124 fis->h.features = 0x55; /* disable read look-ahead */
19125 fis->d.lbaLow = 0; /* */
19126 fis->d.lbaMid = 0; /* */
19127 fis->d.lbaHigh = 0; /* */
19128 fis->d.device = 0; /* */
19129 fis->d.lbaLowExp = 0; /* */
19130 fis->d.lbaMidExp = 0; /* */
19131 fis->d.lbaHighExp = 0; /* */
19132 fis->d.featuresExp = 0; /* */
19133 fis->d.sectorCount = 0; /* */
19134 fis->d.sectorCountExp = 0; /* */
19135 fis->d.reserved4 = 0;
19136 fis->d.control = 0; /* FIS HOB bit clear */
19137 fis->d.reserved5 = 0;
19138
19139 agRequestType = AGSA_SATA_PROTOCOL_NON_DATA;
19140
19141 /* Initialize CB for SATA completion.
19142 */
19143 satIOContext->satCompleteCB = &smsatModeSelect6n10CB;
19144
19145 /*
19146 * Prepare SGL and send FIS to LL layer.
19147 */
19148 satIOContext->reqType = agRequestType; /* Save it */
19149
19150 status = smsataLLIOStart( smRoot,
19151 smIORequest,
19152 smDeviceHandle,
19153 smScsiRequest,
19154 satIOContext);
19155 return status;
19156 }
19157 }
19158
19159
19160 osGLOBAL bit32
smsatLogSense_1(smRoot_t * smRoot,smIORequest_t * smIORequest,smDeviceHandle_t * smDeviceHandle,smScsiInitiatorRequest_t * smScsiRequest,smSatIOContext_t * satIOContext)19161 smsatLogSense_1(
19162 smRoot_t *smRoot,
19163 smIORequest_t *smIORequest,
19164 smDeviceHandle_t *smDeviceHandle,
19165 smScsiInitiatorRequest_t *smScsiRequest,
19166 smSatIOContext_t *satIOContext
19167 )
19168 {
19169 bit32 status;
19170 bit32 agRequestType;
19171 smDeviceData_t *pSatDevData;
19172 agsaFisRegHostToDevice_t *fis;
19173
19174 pSatDevData = satIOContext->pSatDevData;
19175 fis = satIOContext->pFis;
19176
19177 SM_DBG5(("smsatLogSense_1: start\n"));
19178
19179 /* SAT Rev 8, 10.2.4 p74 */
19180 if ( pSatDevData->sat48BitSupport == agTRUE )
19181 {
19182 SM_DBG5(("smsatLogSense_1: case 2-1 sends READ LOG EXT\n"));
19183 /* sends READ LOG EXT */
19184 fis->h.fisType = 0x27; /* Reg host to device */
19185 fis->h.c_pmPort = 0x80; /* C Bit is set */
19186
19187 fis->h.command = SAT_READ_LOG_EXT; /* 0x2F */
19188 fis->h.features = 0; /* FIS reserve */
19189 fis->d.lbaLow = 0x07; /* 0x07 */
19190 fis->d.lbaMid = 0; /* */
19191 fis->d.lbaHigh = 0; /* */
19192 fis->d.device = 0; /* */
19193 fis->d.lbaLowExp = 0; /* */
19194 fis->d.lbaMidExp = 0; /* */
19195 fis->d.lbaHighExp = 0; /* */
19196 fis->d.featuresExp = 0; /* FIS reserve */
19197 fis->d.sectorCount = 0x01; /* 1 sector counts */
19198 fis->d.sectorCountExp = 0x00; /* 1 sector counts */
19199 fis->d.reserved4 = 0;
19200 fis->d.control = 0; /* FIS HOB bit clear */
19201 fis->d.reserved5 = 0;
19202
19203 agRequestType = AGSA_SATA_PROTOCOL_PIO_READ;
19204
19205 /* Initialize CB for SATA completion.
19206 */
19207 satIOContext->satCompleteCB = &smsatLogSenseCB;
19208
19209 /*
19210 * Prepare SGL and send FIS to LL layer.
19211 */
19212 satIOContext->reqType = agRequestType; /* Save it */
19213
19214 status = smsataLLIOStart( smRoot,
19215 smIORequest,
19216 smDeviceHandle,
19217 smScsiRequest,
19218 satIOContext);
19219 return status;
19220
19221 }
19222 else
19223 {
19224 SM_DBG5(("smsatLogSense_1: case 2-2 sends SMART READ LOG\n"));
19225 /* sends SMART READ LOG */
19226 fis->h.fisType = 0x27; /* Reg host to device */
19227 fis->h.c_pmPort = 0x80; /* C Bit is set */
19228
19229 fis->h.command = SAT_SMART; /* 0x2F */
19230 fis->h.features = SAT_SMART_READ_LOG; /* 0xd5 */
19231 fis->d.lbaLow = 0x06; /* 0x06 */
19232 fis->d.lbaMid = 0x00; /* 0x4f */
19233 fis->d.lbaHigh = 0x00; /* 0xc2 */
19234 fis->d.device = 0; /* */
19235 fis->d.lbaLowExp = 0; /* */
19236 fis->d.lbaMidExp = 0; /* */
19237 fis->d.lbaHighExp = 0; /* */
19238 fis->d.featuresExp = 0; /* FIS reserve */
19239 fis->d.sectorCount = 0x01; /* */
19240 fis->d.sectorCountExp = 0x00; /* */
19241 fis->d.reserved4 = 0;
19242 fis->d.control = 0; /* FIS HOB bit clear */
19243 fis->d.reserved5 = 0;
19244
19245 agRequestType = AGSA_SATA_PROTOCOL_PIO_READ;
19246
19247 /* Initialize CB for SATA completion.
19248 */
19249 satIOContext->satCompleteCB = &smsatLogSenseCB;
19250
19251 /*
19252 * Prepare SGL and send FIS to LL layer.
19253 */
19254 satIOContext->reqType = agRequestType; /* Save it */
19255
19256 status = smsataLLIOStart( smRoot,
19257 smIORequest,
19258 smDeviceHandle,
19259 smScsiRequest,
19260 satIOContext);
19261 return status;
19262
19263 }
19264 }
19265
19266 osGLOBAL bit32
smsatReassignBlocks_2(smRoot_t * smRoot,smIORequest_t * smIORequest,smDeviceHandle_t * smDeviceHandle,smScsiInitiatorRequest_t * smScsiRequest,smSatIOContext_t * satIOContext,bit8 * LBA)19267 smsatReassignBlocks_2(
19268 smRoot_t *smRoot,
19269 smIORequest_t *smIORequest,
19270 smDeviceHandle_t *smDeviceHandle,
19271 smScsiInitiatorRequest_t *smScsiRequest,
19272 smSatIOContext_t *satIOContext,
19273 bit8 *LBA
19274 )
19275 {
19276 /*
19277 assumes all LBA fits in ATA command; no boundary condition is checked here yet
19278 tiScsiRequest is TD generated for writing
19279 */
19280 bit32 status;
19281 bit32 agRequestType;
19282 smDeviceData_t *pSatDevData;
19283 smScsiRspSense_t *pSense;
19284 agsaFisRegHostToDevice_t *fis;
19285
19286 pSense = satIOContext->pSense;
19287 pSatDevData = satIOContext->pSatDevData;
19288 fis = satIOContext->pFis;
19289 SM_DBG5(("smsatReassignBlocks_2: start\n"));
19290
19291 if (pSatDevData->satDMASupport == agTRUE && pSatDevData->satDMAEnabled == agTRUE)
19292 {
19293 /* case 2 */
19294 /* WRITE DMA*/
19295 /* can't fit the transfer length */
19296 SM_DBG5(("smsatReassignBlocks_2: case 2\n"));
19297 fis->h.fisType = 0x27; /* Reg host to device */
19298 fis->h.c_pmPort = 0x80; /* C bit is set */
19299 fis->h.command = SAT_WRITE_DMA; /* 0xCA */
19300 fis->h.features = 0; /* FIS reserve */
19301 fis->d.lbaLow = LBA[7]; /* FIS LBA (7 :0 ) */
19302 fis->d.lbaMid = LBA[6]; /* FIS LBA (15:8 ) */
19303 fis->d.lbaHigh = LBA[5]; /* FIS LBA (23:16) */
19304
19305 /* FIS LBA mode set LBA (27:24) */
19306 fis->d.device = (bit8)((0x4 << 4) | (LBA[4] & 0xF));
19307
19308 fis->d.lbaLowExp = 0;
19309 fis->d.lbaMidExp = 0;
19310 fis->d.lbaHighExp = 0;
19311 fis->d.featuresExp = 0;
19312 fis->d.sectorCount = 1; /* FIS sector count (7:0) */
19313 fis->d.sectorCountExp = 0;
19314 fis->d.reserved4 = 0;
19315 fis->d.control = 0; /* FIS HOB bit clear */
19316 fis->d.reserved5 = 0;
19317
19318 agRequestType = AGSA_SATA_PROTOCOL_DMA_WRITE;
19319 satIOContext->ATACmd = SAT_WRITE_DMA;
19320 }
19321 else
19322 {
19323 /* case 1 */
19324 /* WRITE MULTIPLE or WRITE SECTOR(S) */
19325 /* WRITE SECTORS for easier implemetation */
19326 /* can't fit the transfer length */
19327 SM_DBG5(("smsatReassignBlocks_2: case 1\n"));
19328 fis->h.fisType = 0x27; /* Reg host to device */
19329 fis->h.c_pmPort = 0x80; /* C bit is set */
19330 fis->h.command = SAT_WRITE_SECTORS; /* 0x30 */
19331 fis->h.features = 0; /* FIS reserve */
19332 fis->d.lbaLow = LBA[7]; /* FIS LBA (7 :0 ) */
19333 fis->d.lbaMid = LBA[6]; /* FIS LBA (15:8 ) */
19334 fis->d.lbaHigh = LBA[7]; /* FIS LBA (23:16) */
19335
19336 /* FIS LBA mode set LBA (27:24) */
19337 fis->d.device = (bit8)((0x4 << 4) | (LBA[4] & 0xF));
19338
19339 fis->d.lbaLowExp = 0;
19340 fis->d.lbaMidExp = 0;
19341 fis->d.lbaHighExp = 0;
19342 fis->d.featuresExp = 0;
19343 fis->d.sectorCount = 1; /* FIS sector count (7:0) */
19344 fis->d.sectorCountExp = 0;
19345 fis->d.reserved4 = 0;
19346 fis->d.control = 0; /* FIS HOB bit clear */
19347 fis->d.reserved5 = 0;
19348
19349 agRequestType = AGSA_SATA_PROTOCOL_PIO_WRITE;
19350 satIOContext->ATACmd = SAT_WRITE_SECTORS;
19351 }
19352
19353 /* case 3 and 4 */
19354 if (pSatDevData->sat48BitSupport == agTRUE)
19355 {
19356 if (pSatDevData->satDMASupport == agTRUE && pSatDevData->satDMAEnabled == agTRUE)
19357 {
19358 /* case 3 */
19359 /* WRITE DMA EXT or WRITE DMA FUA EXT */
19360 SM_DBG5(("smsatReassignBlocks_2: case 3\n"));
19361 fis->h.fisType = 0x27; /* Reg host to device */
19362 fis->h.c_pmPort = 0x80; /* C Bit is set */
19363
19364 /* SAT_WRITE_DMA_FUA_EXT is optional and we don't support it */
19365 fis->h.command = SAT_WRITE_DMA_EXT; /* 0x35 */
19366 satIOContext->ATACmd = SAT_WRITE_DMA_EXT;
19367
19368 fis->h.features = 0; /* FIS reserve */
19369 fis->d.lbaLow = LBA[7]; /* FIS LBA (7 :0 ) */
19370 fis->d.lbaMid = LBA[6]; /* FIS LBA (15:8 ) */
19371 fis->d.lbaHigh = LBA[5]; /* FIS LBA (23:16) */
19372 fis->d.device = 0x40; /* FIS LBA mode set */
19373 fis->d.lbaLowExp = LBA[4]; /* FIS LBA (31:24) */
19374 fis->d.lbaMidExp = LBA[3]; /* FIS LBA (39:32) */
19375 fis->d.lbaHighExp = LBA[2]; /* FIS LBA (47:40) */
19376 fis->d.featuresExp = 0; /* FIS reserve */
19377 fis->d.sectorCount = 1; /* FIS sector count (7:0) */
19378 fis->d.sectorCountExp = 0; /* FIS sector count (15:8) */
19379 fis->d.reserved4 = 0;
19380 fis->d.control = 0; /* FIS HOB bit clear */
19381 fis->d.reserved5 = 0;
19382
19383 agRequestType = AGSA_SATA_PROTOCOL_DMA_WRITE;
19384 }
19385 else
19386 {
19387 /* case 4 */
19388 /* WRITE MULTIPLE EXT or WRITE MULTIPLE FUA EXT or WRITE SECTOR(S) EXT */
19389 /* WRITE SECTORS EXT for easier implemetation */
19390 SM_DBG5(("smsatReassignBlocks_2: case 4\n"));
19391 fis->h.fisType = 0x27; /* Reg host to device */
19392 fis->h.c_pmPort = 0x80; /* C Bit is set */
19393 fis->h.command = SAT_WRITE_SECTORS_EXT; /* 0x34 */
19394
19395 fis->h.features = 0; /* FIS reserve */
19396 fis->d.lbaLow = LBA[7]; /* FIS LBA (7 :0 ) */
19397 fis->d.lbaMid = LBA[6]; /* FIS LBA (15:8 ) */
19398 fis->d.lbaHigh = LBA[5]; /* FIS LBA (23:16) */
19399 fis->d.device = 0x40; /* FIS LBA mode set */
19400 fis->d.lbaLowExp = LBA[4]; /* FIS LBA (31:24) */
19401 fis->d.lbaMidExp = LBA[3]; /* FIS LBA (39:32) */
19402 fis->d.lbaHighExp = LBA[2]; /* FIS LBA (47:40) */
19403 fis->d.featuresExp = 0; /* FIS reserve */
19404 fis->d.sectorCount = 1; /* FIS sector count (7:0) */
19405 fis->d.sectorCountExp = 0; /* FIS sector count (15:8) */
19406 fis->d.reserved4 = 0;
19407 fis->d.control = 0; /* FIS HOB bit clear */
19408 fis->d.reserved5 = 0;
19409
19410 agRequestType = AGSA_SATA_PROTOCOL_PIO_WRITE;
19411 satIOContext->ATACmd = SAT_WRITE_SECTORS_EXT;
19412 }
19413 }
19414 /* case 5 */
19415 if (pSatDevData->satNCQ == agTRUE)
19416 {
19417 /* WRITE FPDMA QUEUED */
19418 if (pSatDevData->sat48BitSupport != agTRUE)
19419 {
19420 SM_DBG5(("smsatReassignBlocks_2: case 5 !!! error NCQ but 28 bit address support \n"));
19421 smsatSetSensePayload( pSense,
19422 SCSI_SNSKEY_HARDWARE_ERROR,
19423 0,
19424 SCSI_SNSCODE_WRITE_ERROR_AUTO_REALLOCATION_FAILED,
19425 satIOContext);
19426
19427 /*smEnqueueIO(smRoot, satIOContext);*/
19428
19429 tdsmIOCompletedCB( smRoot,
19430 smIORequest,
19431 smIOSuccess,
19432 SCSI_STAT_CHECK_CONDITION,
19433 satIOContext->pSmSenseData,
19434 satIOContext->interruptContext );
19435 return SM_RC_SUCCESS;
19436 }
19437 SM_DBG6(("satWrite10: case 5\n"));
19438
19439 /* Support 48-bit FPDMA addressing, use WRITE FPDMA QUEUE command */
19440
19441 fis->h.fisType = 0x27; /* Reg host to device */
19442 fis->h.c_pmPort = 0x80; /* C Bit is set */
19443 fis->h.command = SAT_WRITE_FPDMA_QUEUED; /* 0x61 */
19444 fis->h.features = 1; /* FIS sector count (7:0) */
19445 fis->d.lbaLow = LBA[7]; /* FIS LBA (7 :0 ) */
19446 fis->d.lbaMid = LBA[6]; /* FIS LBA (15:8 ) */
19447 fis->d.lbaHigh = LBA[5]; /* FIS LBA (23:16) */
19448
19449 /* Check FUA bit */
19450 fis->d.device = 0x40; /* FIS FUA clear */
19451
19452 fis->d.lbaLowExp = LBA[4]; /* FIS LBA (31:24) */
19453 fis->d.lbaMidExp = LBA[3]; /* FIS LBA (39:32) */
19454 fis->d.lbaHighExp = LBA[2]; /* FIS LBA (47:40) */
19455 fis->d.featuresExp = 0; /* FIS sector count (15:8) */
19456 fis->d.sectorCount = 0; /* Tag (7:3) set by LL layer */
19457 fis->d.sectorCountExp = 0;
19458 fis->d.reserved4 = 0;
19459 fis->d.control = 0; /* FIS HOB bit clear */
19460 fis->d.reserved5 = 0;
19461
19462 agRequestType = AGSA_SATA_PROTOCOL_FPDMA_WRITE;
19463 satIOContext->ATACmd = SAT_WRITE_FPDMA_QUEUED;
19464 }
19465
19466 satIOContext->satCompleteCB = &smsatReassignBlocksCB;
19467
19468 /*
19469 * Prepare SGL and send FIS to LL layer.
19470 */
19471 satIOContext->reqType = agRequestType; /* Save it */
19472
19473 status = smsataLLIOStart( smRoot,
19474 smIORequest,
19475 smDeviceHandle,
19476 /* not the original, should be the TD generated one */
19477 smScsiRequest,
19478 satIOContext);
19479 return (status);
19480 }
19481
19482 osGLOBAL bit32
smsatReassignBlocks_1(smRoot_t * smRoot,smIORequest_t * smIORequest,smDeviceHandle_t * smDeviceHandle,smScsiInitiatorRequest_t * smScsiRequest,smSatIOContext_t * satIOContext,smSatIOContext_t * satOrgIOContext)19483 smsatReassignBlocks_1(
19484 smRoot_t *smRoot,
19485 smIORequest_t *smIORequest,
19486 smDeviceHandle_t *smDeviceHandle,
19487 smScsiInitiatorRequest_t *smScsiRequest,
19488 smSatIOContext_t *satIOContext,
19489 smSatIOContext_t *satOrgIOContext
19490 )
19491 {
19492 /*
19493 assumes all LBA fits in ATA command; no boundary condition is checked here yet
19494 tiScsiRequest is OS generated; needs for accessing parameter list
19495 */
19496 bit32 agRequestType;
19497 smDeviceData_t *pSatDevData;
19498 smIniScsiCmnd_t *scsiCmnd;
19499 agsaFisRegHostToDevice_t *fis;
19500 bit8 *pParmList; /* Log Page data buffer */
19501 bit8 LongLBA;
19502 bit8 LBA[8];
19503 bit32 startingIndex;
19504
19505 pSatDevData = satIOContext->pSatDevData;
19506 scsiCmnd = &smScsiRequest->scsiCmnd;
19507 fis = satIOContext->pFis;
19508 pParmList = (bit8 *) smScsiRequest->sglVirtualAddr;
19509 SM_DBG5(("smsatReassignBlocks_1: start\n"));
19510 LongLBA = (bit8)(scsiCmnd->cdb[1] & SCSI_REASSIGN_BLOCKS_LONGLBA_MASK);
19511 sm_memset(LBA, 0, sizeof(LBA));
19512 startingIndex = satOrgIOContext->ParmIndex;
19513 if (LongLBA == 0)
19514 {
19515 LBA[4] = pParmList[startingIndex];
19516 LBA[5] = pParmList[startingIndex+1];
19517 LBA[6] = pParmList[startingIndex+2];
19518 LBA[7] = pParmList[startingIndex+3];
19519 startingIndex = startingIndex + 4;
19520 }
19521 else
19522 {
19523 LBA[0] = pParmList[startingIndex];
19524 LBA[1] = pParmList[startingIndex+1];
19525 LBA[2] = pParmList[startingIndex+2];
19526 LBA[3] = pParmList[startingIndex+3];
19527 LBA[4] = pParmList[startingIndex+4];
19528 LBA[5] = pParmList[startingIndex+5];
19529 LBA[6] = pParmList[startingIndex+6];
19530 LBA[7] = pParmList[startingIndex+7];
19531 startingIndex = startingIndex + 8;
19532 }
19533
19534 if (pSatDevData->sat48BitSupport == agTRUE)
19535 {
19536 /* sends READ VERIFY SECTOR(S) EXT*/
19537 fis->h.fisType = 0x27; /* Reg host to device */
19538 fis->h.c_pmPort = 0x80; /* C Bit is set */
19539 fis->h.command = SAT_READ_VERIFY_SECTORS_EXT;/* 0x42 */
19540 fis->h.features = 0; /* FIS reserve */
19541 fis->d.lbaLow = LBA[7]; /* FIS LBA (7 :0 ) */
19542 fis->d.lbaMid = LBA[6]; /* FIS LBA (15:8 ) */
19543 fis->d.lbaHigh = LBA[5]; /* FIS LBA (23:16) */
19544 fis->d.lbaLowExp = LBA[4]; /* FIS LBA (31:24) */
19545 fis->d.lbaMidExp = LBA[3]; /* FIS LBA (39:32) */
19546 fis->d.lbaHighExp = LBA[2]; /* FIS LBA (47:40) */
19547 fis->d.featuresExp = 0; /* FIS reserve */
19548 fis->d.sectorCount = 1; /* FIS sector count (7:0) */
19549 fis->d.sectorCountExp = 0; /* FIS sector count (15:8) */
19550 fis->d.reserved4 = 0;
19551 fis->d.device = 0x40; /* 01000000 */
19552 fis->d.control = 0; /* FIS HOB bit clear */
19553 fis->d.reserved5 = 0;
19554 }
19555 else
19556 {
19557 /* READ VERIFY SECTOR(S)*/
19558 fis->h.fisType = 0x27; /* Reg host to device */
19559 fis->h.c_pmPort = 0x80; /* C Bit is set */
19560 fis->h.command = SAT_READ_VERIFY_SECTORS;/* 0x40 */
19561 fis->h.features = 0; /* FIS features NA */
19562 fis->d.lbaLow = LBA[7]; /* FIS LBA (7 :0 ) */
19563 fis->d.lbaMid = LBA[6]; /* FIS LBA (15:8 ) */
19564 fis->d.lbaHigh = LBA[5]; /* FIS LBA (23:16) */
19565 fis->d.lbaLowExp = 0;
19566 fis->d.lbaMidExp = 0;
19567 fis->d.lbaHighExp = 0;
19568 fis->d.featuresExp = 0;
19569 fis->d.sectorCount = 1; /* FIS sector count (7:0) */
19570 fis->d.sectorCountExp = 0;
19571 fis->d.reserved4 = 0;
19572 fis->d.device = (bit8)((0x4 << 4) | (LBA[4] & 0xF));
19573 /* DEV and LBA 27:24 */
19574 fis->d.control = 0; /* FIS HOB bit clear */
19575 fis->d.reserved5 = 0;
19576 }
19577
19578 sm_memcpy(satOrgIOContext->LBA, LBA, 8);
19579 satOrgIOContext->ParmIndex = startingIndex;
19580
19581 agRequestType = AGSA_SATA_PROTOCOL_NON_DATA;
19582
19583 /* Initialize CB for SATA completion.
19584 */
19585 satIOContext->satCompleteCB = &smsatReassignBlocksCB;
19586
19587 /*
19588 * Prepare SGL and send FIS to LL layer.
19589 */
19590 satIOContext->reqType = agRequestType; /* Save it */
19591
19592 smsataLLIOStart( smRoot,
19593 smIORequest,
19594 smDeviceHandle,
19595 smScsiRequest,
19596 satIOContext);
19597
19598 return SM_RC_SUCCESS;
19599 }
19600
19601 osGLOBAL bit32
smsatSendReadLogExt(smRoot_t * smRoot,smIORequest_t * smIORequest,smDeviceHandle_t * smDeviceHandle,smScsiInitiatorRequest_t * smScsiRequest,smSatIOContext_t * satIOContext)19602 smsatSendReadLogExt(
19603 smRoot_t *smRoot,
19604 smIORequest_t *smIORequest,
19605 smDeviceHandle_t *smDeviceHandle,
19606 smScsiInitiatorRequest_t *smScsiRequest,
19607 smSatIOContext_t *satIOContext
19608 )
19609 {
19610 bit32 status;
19611 bit32 agRequestType;
19612 agsaFisRegHostToDevice_t *fis;
19613
19614 fis = satIOContext->pFis;
19615 SM_DBG1(("smsatSendReadLogExt: start\n"));
19616 fis->h.fisType = 0x27; /* Reg host to device */
19617 fis->h.c_pmPort = 0x80; /* C Bit is set */
19618 fis->h.command = SAT_READ_LOG_EXT; /* 0x2F */
19619 fis->h.features = 0; /* FIS reserve */
19620 fis->d.lbaLow = 0x10; /* Page number */
19621 fis->d.lbaMid = 0; /* */
19622 fis->d.lbaHigh = 0; /* */
19623 fis->d.device = 0; /* DEV is ignored in SATA */
19624 fis->d.lbaLowExp = 0; /* */
19625 fis->d.lbaMidExp = 0; /* */
19626 fis->d.lbaHighExp = 0; /* */
19627 fis->d.featuresExp = 0; /* FIS reserve */
19628 fis->d.sectorCount = 0x01; /* 1 sector counts*/
19629 fis->d.sectorCountExp = 0x00; /* 1 sector counts */
19630 fis->d.reserved4 = 0;
19631 fis->d.control = 0; /* FIS HOB bit clear */
19632 fis->d.reserved5 = 0;
19633
19634 agRequestType = AGSA_SATA_PROTOCOL_PIO_READ;
19635
19636 /* Initialize CB for SATA completion.
19637 */
19638 satIOContext->satCompleteCB = &smsatReadLogExtCB;
19639
19640 /*
19641 * Prepare SGL and send FIS to LL layer.
19642 */
19643 satIOContext->reqType = agRequestType; /* Save it */
19644
19645 status = smsataLLIOStart( smRoot,
19646 smIORequest,
19647 smDeviceHandle,
19648 smScsiRequest,
19649 satIOContext);
19650
19651 SM_DBG1(("smsatSendReadLogExt: end status %d!!!\n", status));
19652
19653 return (status);
19654 }
19655
19656 osGLOBAL bit32
smsatCheckPowerMode(smRoot_t * smRoot,smIORequest_t * smIORequest,smDeviceHandle_t * smDeviceHandle,smScsiInitiatorRequest_t * smScsiRequest,smSatIOContext_t * satIOContext)19657 smsatCheckPowerMode(
19658 smRoot_t *smRoot,
19659 smIORequest_t *smIORequest,
19660 smDeviceHandle_t *smDeviceHandle,
19661 smScsiInitiatorRequest_t *smScsiRequest,
19662 smSatIOContext_t *satIOContext
19663 )
19664 {
19665 /*
19666 sends SAT_CHECK_POWER_MODE as a part of ABORT TASKMANGEMENT for NCQ commands
19667 internally generated - no directly corresponding scsi
19668 */
19669 bit32 status;
19670 bit32 agRequestType;
19671 agsaFisRegHostToDevice_t *fis;
19672
19673 fis = satIOContext->pFis;
19674 SM_DBG1(("smsatCheckPowerMode: start\n"));
19675 /*
19676 * Send the ATA CHECK POWER MODE command.
19677 */
19678 fis->h.fisType = 0x27; /* Reg host to device */
19679 fis->h.c_pmPort = 0x80; /* C Bit is set */
19680 fis->h.command = SAT_CHECK_POWER_MODE; /* 0xE5 */
19681 fis->h.features = 0;
19682 fis->d.lbaLow = 0;
19683 fis->d.lbaMid = 0;
19684 fis->d.lbaHigh = 0;
19685 fis->d.device = 0;
19686 fis->d.lbaLowExp = 0;
19687 fis->d.lbaMidExp = 0;
19688 fis->d.lbaHighExp = 0;
19689 fis->d.featuresExp = 0;
19690 fis->d.sectorCount = 0;
19691 fis->d.sectorCountExp = 0;
19692 fis->d.reserved4 = 0;
19693 fis->d.control = 0; /* FIS HOB bit clear */
19694 fis->d.reserved5 = 0;
19695
19696 agRequestType = AGSA_SATA_PROTOCOL_NON_DATA;
19697
19698 /* Initialize CB for SATA completion.
19699 */
19700 satIOContext->satCompleteCB = &smsatCheckPowerModeCB;
19701
19702 /*
19703 * Prepare SGL and send FIS to LL layer.
19704 */
19705 satIOContext->reqType = agRequestType; /* Save it */
19706
19707 status = smsataLLIOStart( smRoot,
19708 smIORequest,
19709 smDeviceHandle,
19710 smScsiRequest,
19711 satIOContext);
19712
19713 SM_DBG5(("smsatCheckPowerMode: return\n"));
19714
19715 return status;
19716 }
19717
19718 osGLOBAL bit32
smsatResetDevice(smRoot_t * smRoot,smIORequest_t * smIORequest,smDeviceHandle_t * smDeviceHandle,smScsiInitiatorRequest_t * smScsiRequest,smSatIOContext_t * satIOContext)19719 smsatResetDevice(
19720 smRoot_t *smRoot,
19721 smIORequest_t *smIORequest,
19722 smDeviceHandle_t *smDeviceHandle,
19723 smScsiInitiatorRequest_t *smScsiRequest, /* NULL */
19724 smSatIOContext_t *satIOContext
19725 )
19726 {
19727 bit32 status;
19728 bit32 agRequestType;
19729 agsaFisRegHostToDevice_t *fis;
19730 #ifdef TD_DEBUG_ENABLE
19731 smIORequestBody_t *smIORequestBody;
19732 smSatInternalIo_t *satIntIoContext;
19733 #endif
19734
19735 fis = satIOContext->pFis;
19736 SM_DBG1(("smsatResetDevice: start\n"));
19737 #ifdef TD_DEBUG_ENABLE
19738 satIntIoContext = satIOContext->satIntIoContext;
19739 smIORequestBody = satIntIoContext->satIntRequestBody;
19740 #endif
19741 SM_DBG5(("smsatResetDevice: satIOContext %p smIORequestBody %p\n", satIOContext, smIORequestBody));
19742 /* any fis should work */
19743 fis->h.fisType = 0x27; /* Reg host to device */
19744 fis->h.c_pmPort = 0; /* C Bit is not set */
19745 fis->h.command = 0; /* any command */
19746 fis->h.features = 0; /* FIS reserve */
19747 fis->d.lbaLow = 0; /* FIS LBA (7 :0 ) */
19748 fis->d.lbaMid = 0; /* FIS LBA (15:8 ) */
19749 fis->d.lbaHigh = 0; /* FIS LBA (23:16) */
19750 fis->d.device = 0; /* FIS LBA mode */
19751 fis->d.lbaLowExp = 0;
19752 fis->d.lbaMidExp = 0;
19753 fis->d.lbaHighExp = 0;
19754 fis->d.featuresExp = 0;
19755 fis->d.sectorCount = 0; /* FIS sector count (7:0) */
19756 fis->d.sectorCountExp = 0;
19757 fis->d.reserved4 = 0;
19758 fis->d.control = 0x4; /* SRST bit is set */
19759 fis->d.reserved5 = 0;
19760
19761 agRequestType = AGSA_SATA_PROTOCOL_SRST_ASSERT;
19762
19763 /* Initialize CB for SATA completion.
19764 */
19765 satIOContext->satCompleteCB = &smsatResetDeviceCB;
19766
19767 /*
19768 * Prepare SGL and send FIS to LL layer.
19769 */
19770 satIOContext->reqType = agRequestType; /* Save it */
19771
19772 #ifdef SM_INTERNAL_DEBUG
19773 smhexdump("smsatResetDevice", (bit8 *)satIOContext->pFis, sizeof(agsaFisRegHostToDevice_t));
19774 #ifdef TD_DEBUG_ENABLE
19775 smhexdump("smsatResetDevice LL", (bit8 *)&(smIORequestBody->transport.SATA.agSATARequestBody.fis.fisRegHostToDev), sizeof(agsaFisRegHostToDevice_t));
19776 #endif
19777 #endif
19778
19779 status = smsataLLIOStart( smRoot,
19780 smIORequest,
19781 smDeviceHandle,
19782 smScsiRequest,
19783 satIOContext);
19784
19785 SM_DBG6(("smsatResetDevice: end status %d\n", status));
19786 return status;
19787 }
19788
19789 osGLOBAL bit32
smsatDeResetDevice(smRoot_t * smRoot,smIORequest_t * smIORequest,smDeviceHandle_t * smDeviceHandle,smScsiInitiatorRequest_t * smScsiRequest,smSatIOContext_t * satIOContext)19790 smsatDeResetDevice(
19791 smRoot_t *smRoot,
19792 smIORequest_t *smIORequest,
19793 smDeviceHandle_t *smDeviceHandle,
19794 smScsiInitiatorRequest_t *smScsiRequest,
19795 smSatIOContext_t *satIOContext
19796 )
19797 {
19798 bit32 status;
19799 bit32 agRequestType;
19800 agsaFisRegHostToDevice_t *fis;
19801 #ifdef TD_DEBUG_ENABLE
19802 smIORequestBody_t *smIORequestBody;
19803 smSatInternalIo_t *satIntIoContext;
19804 #endif
19805
19806 fis = satIOContext->pFis;
19807 SM_DBG1(("smsatDeResetDevice: start\n"));
19808 #ifdef TD_DEBUG_ENABLE
19809 satIntIoContext = satIOContext->satIntIoContext;
19810 smIORequestBody = satIntIoContext->satIntRequestBody;
19811 #endif
19812 SM_DBG5(("smsatDeResetDevice: satIOContext %p smIORequestBody %p\n", satIOContext, smIORequestBody));
19813 /* any fis should work */
19814 fis->h.fisType = 0x27; /* Reg host to device */
19815 fis->h.c_pmPort = 0; /* C Bit is not set */
19816 fis->h.command = 0; /* any command */
19817 fis->h.features = 0; /* FIS reserve */
19818 fis->d.lbaLow = 0; /* FIS LBA (7 :0 ) */
19819 fis->d.lbaMid = 0; /* FIS LBA (15:8 ) */
19820 fis->d.lbaHigh = 0; /* FIS LBA (23:16) */
19821 fis->d.device = 0; /* FIS LBA mode */
19822 fis->d.lbaLowExp = 0;
19823 fis->d.lbaMidExp = 0;
19824 fis->d.lbaHighExp = 0;
19825 fis->d.featuresExp = 0;
19826 fis->d.sectorCount = 0; /* FIS sector count (7:0) */
19827 fis->d.sectorCountExp = 0;
19828 fis->d.reserved4 = 0;
19829 fis->d.control = 0; /* SRST bit is not set */
19830 fis->d.reserved5 = 0;
19831
19832 agRequestType = AGSA_SATA_PROTOCOL_SRST_DEASSERT;
19833
19834 /* Initialize CB for SATA completion.
19835 */
19836 satIOContext->satCompleteCB = &smsatDeResetDeviceCB;
19837
19838 /*
19839 * Prepare SGL and send FIS to LL layer.
19840 */
19841 satIOContext->reqType = agRequestType; /* Save it */
19842
19843 #ifdef SM_INTERNAL_DEBUG
19844 smhexdump("smsatDeResetDevice", (bit8 *)satIOContext->pFis, sizeof(agsaFisRegHostToDevice_t));
19845 #ifdef TD_DEBUG_ENABLE
19846 smhexdump("smsatDeResetDevice LL", (bit8 *)&(smIORequestBody->transport.SATA.agSATARequestBody.fis.fisRegHostToDev), sizeof(agsaFisRegHostToDevice_t));
19847 #endif
19848 #endif
19849
19850 status = smsataLLIOStart( smRoot,
19851 smIORequest,
19852 smDeviceHandle,
19853 smScsiRequest,
19854 satIOContext);
19855
19856 SM_DBG6(("smsatDeResetDevice: end status %d\n", status));
19857 return status;
19858 }
19859
19860 /* set feature for auto activate */
19861 osGLOBAL bit32
smsatSetFeaturesAA(smRoot_t * smRoot,smIORequest_t * smIORequest,smDeviceHandle_t * smDeviceHandle,smScsiInitiatorRequest_t * smScsiRequest,smSatIOContext_t * satIOContext)19862 smsatSetFeaturesAA(
19863 smRoot_t *smRoot,
19864 smIORequest_t *smIORequest,
19865 smDeviceHandle_t *smDeviceHandle,
19866 smScsiInitiatorRequest_t *smScsiRequest,
19867 smSatIOContext_t *satIOContext
19868 )
19869 {
19870 bit32 status = SM_RC_FAILURE;
19871 bit32 agRequestType;
19872 agsaFisRegHostToDevice_t *fis;
19873
19874 fis = satIOContext->pFis;
19875 SM_DBG2(("smsatSetFeaturesAA: start\n"));
19876 /*
19877 * Send the Set Features command.
19878 * See SATA II 1.0a spec
19879 */
19880 fis->h.fisType = 0x27; /* Reg host to device */
19881 fis->h.c_pmPort = 0x80; /* C Bit is set */
19882 fis->h.command = SAT_SET_FEATURES; /* 0xEF */
19883 fis->h.features = 0x10; /* enable SATA feature */
19884 fis->d.lbaLow = 0;
19885 fis->d.lbaMid = 0;
19886 fis->d.lbaHigh = 0;
19887 fis->d.device = 0;
19888 fis->d.lbaLowExp = 0;
19889 fis->d.lbaMidExp = 0;
19890 fis->d.lbaHighExp = 0;
19891 fis->d.featuresExp = 0;
19892 fis->d.sectorCount = 0x02; /* DMA Setup FIS Auto-Activate */
19893 fis->d.sectorCountExp = 0;
19894 fis->d.reserved4 = 0;
19895 fis->d.control = 0; /* FIS HOB bit clear */
19896 fis->d.reserved5 = 0;
19897
19898 agRequestType = AGSA_SATA_PROTOCOL_NON_DATA;
19899
19900 /* Initialize CB for SATA completion.
19901 */
19902 satIOContext->satCompleteCB = &smsatSetFeaturesAACB;
19903
19904 /*
19905 * Prepare SGL and send FIS to LL layer.
19906 */
19907 satIOContext->reqType = agRequestType; /* Save it */
19908
19909 status = smsataLLIOStart( smRoot,
19910 smIORequest,
19911 smDeviceHandle,
19912 smScsiRequest,
19913 satIOContext);
19914
19915 /* debugging code */
19916 if (smIORequest->tdData == smIORequest->smData)
19917 {
19918 SM_DBG1(("smsatSetFeaturesAA: incorrect smIORequest\n"));
19919 }
19920 SM_DBG2(("smsatSetFeatures: return\n"));
19921 return status;
19922 }
19923
19924
19925 /* set feature for DMA transfer mode*/
19926 osGLOBAL bit32
smsatSetFeaturesDMA(smRoot_t * smRoot,smIORequest_t * smIORequest,smDeviceHandle_t * smDeviceHandle,smScsiInitiatorRequest_t * smScsiRequest,smSatIOContext_t * satIOContext)19927 smsatSetFeaturesDMA(
19928 smRoot_t *smRoot,
19929 smIORequest_t *smIORequest,
19930 smDeviceHandle_t *smDeviceHandle,
19931 smScsiInitiatorRequest_t *smScsiRequest,
19932 smSatIOContext_t *satIOContext
19933 )
19934 {
19935 bit32 status = SM_RC_FAILURE;
19936 bit32 agRequestType;
19937 smDeviceData_t *pSatDevData;
19938 agsaFisRegHostToDevice_t *fis;
19939
19940 pSatDevData = satIOContext->pSatDevData;
19941 fis = satIOContext->pFis;
19942 SM_DBG2(("smsatSetFeaturesDMA: start\n"));
19943 /*
19944 * Send the Set Features command.
19945 * See SATA II 1.0a spec
19946 */
19947 fis->h.fisType = 0x27; /* Reg host to device */
19948 fis->h.c_pmPort = 0x80; /* C Bit is set */
19949 fis->h.command = SAT_SET_FEATURES; /* 0xEF */
19950 fis->h.features = 0x03; /* enable ATA transfer mode */
19951 fis->d.lbaLow = 0;
19952 fis->d.lbaMid = 0;
19953 fis->d.lbaHigh = 0;
19954 fis->d.device = 0;
19955 fis->d.lbaLowExp = 0;
19956 fis->d.lbaMidExp = 0;
19957 fis->d.lbaHighExp = 0;
19958 fis->d.featuresExp = 0;
19959 fis->d.sectorCount = 0x40 |(bit8)pSatDevData->satUltraDMAMode; /* enable Ultra DMA mode */
19960 fis->d.sectorCountExp = 0;
19961 fis->d.reserved4 = 0;
19962 fis->d.control = 0; /* FIS HOB bit clear */
19963 fis->d.reserved5 = 0;
19964
19965 agRequestType = AGSA_SATA_PROTOCOL_NON_DATA;
19966
19967 /* Initialize CB for SATA completion.
19968 */
19969 satIOContext->satCompleteCB = &smsatSetFeaturesDMACB;
19970
19971 /*
19972 * Prepare SGL and send FIS to LL layer.
19973 */
19974 satIOContext->reqType = agRequestType; /* Save it */
19975
19976 status = smsataLLIOStart( smRoot,
19977 smIORequest,
19978 smDeviceHandle,
19979 smScsiRequest,
19980 satIOContext);
19981
19982 /* debugging code */
19983 if (smIORequest->tdData == smIORequest->smData)
19984 {
19985 SM_DBG1(("smsatSetFeaturesDMA: incorrect smIORequest\n"));
19986 }
19987
19988 SM_DBG2(("smsatSetFeaturesDMA: return\n"));
19989
19990 return status;
19991 }
19992
19993 /* set feature for Read Look Ahead*/
19994 osGLOBAL bit32
smsatSetFeaturesReadLookAhead(smRoot_t * smRoot,smIORequest_t * smIORequest,smDeviceHandle_t * smDeviceHandle,smScsiInitiatorRequest_t * smScsiRequest,smSatIOContext_t * satIOContext)19995 smsatSetFeaturesReadLookAhead(
19996 smRoot_t *smRoot,
19997 smIORequest_t *smIORequest,
19998 smDeviceHandle_t *smDeviceHandle,
19999 smScsiInitiatorRequest_t *smScsiRequest,
20000 smSatIOContext_t *satIOContext
20001 )
20002 {
20003 bit32 status = SM_RC_FAILURE;
20004 bit32 agRequestType;
20005 agsaFisRegHostToDevice_t *fis;
20006
20007 fis = satIOContext->pFis;
20008 SM_DBG2(("smsatSetFeaturesReadLookAhead: start\n"));
20009 /*
20010 * Send the Set Features command.
20011 * See SATA II 1.0a spec
20012 */
20013 fis->h.fisType = 0x27; /* Reg host to device */
20014 fis->h.c_pmPort = 0x80; /* C Bit is set */
20015 fis->h.command = SAT_SET_FEATURES; /* 0xEF */
20016 fis->h.features = 0xAA; /* Enable read look-ahead feature */
20017 fis->d.lbaLow = 0;
20018 fis->d.lbaMid = 0;
20019 fis->d.lbaHigh = 0;
20020 fis->d.device = 0;
20021 fis->d.lbaLowExp = 0;
20022 fis->d.lbaMidExp = 0;
20023 fis->d.lbaHighExp = 0;
20024 fis->d.featuresExp = 0;
20025 fis->d.sectorCount = 0;
20026 fis->d.sectorCountExp = 0;
20027 fis->d.reserved4 = 0;
20028 fis->d.control = 0; /* FIS HOB bit clear */
20029 fis->d.reserved5 = 0;
20030
20031 agRequestType = AGSA_SATA_PROTOCOL_NON_DATA;
20032
20033 /* Initialize CB for SATA completion.
20034 */
20035 satIOContext->satCompleteCB = &smsatSetFeaturesReadLookAheadCB;
20036
20037 /*
20038 * Prepare SGL and send FIS to LL layer.
20039 */
20040 satIOContext->reqType = agRequestType; /* Save it */
20041
20042 status = smsataLLIOStart( smRoot,
20043 smIORequest,
20044 smDeviceHandle,
20045 smScsiRequest,
20046 satIOContext);
20047
20048 /* debugging code */
20049 if (smIORequest->tdData == smIORequest->smData)
20050 {
20051 SM_DBG1(("smsatSetFeaturesReadLookAhead: incorrect smIORequest\n"));
20052 }
20053
20054 SM_DBG2(("smsatSetFeaturesReadLookAhead: return\n"));
20055
20056 return status;
20057 }
20058
20059 /* set feature for Volatile Write Cache*/
20060 osGLOBAL bit32
smsatSetFeaturesVolatileWriteCache(smRoot_t * smRoot,smIORequest_t * smIORequest,smDeviceHandle_t * smDeviceHandle,smScsiInitiatorRequest_t * smScsiRequest,smSatIOContext_t * satIOContext)20061 smsatSetFeaturesVolatileWriteCache(
20062 smRoot_t *smRoot,
20063 smIORequest_t *smIORequest,
20064 smDeviceHandle_t *smDeviceHandle,
20065 smScsiInitiatorRequest_t *smScsiRequest,
20066 smSatIOContext_t *satIOContext
20067 )
20068 {
20069 bit32 status = SM_RC_FAILURE;
20070 bit32 agRequestType;
20071 agsaFisRegHostToDevice_t *fis;
20072
20073 fis = satIOContext->pFis;
20074 SM_DBG2(("smsatSetFeaturesVolatileWriteCache: start\n"));
20075 /*
20076 * Send the Set Features command.
20077 * See SATA II 1.0a spec
20078 */
20079 fis->h.fisType = 0x27; /* Reg host to device */
20080 fis->h.c_pmPort = 0x80; /* C Bit is set */
20081 fis->h.command = SAT_SET_FEATURES; /* 0xEF */
20082 fis->h.features = 0x02; /* Enable Volatile Write Cache feature */
20083 fis->d.lbaLow = 0;
20084 fis->d.lbaMid = 0;
20085 fis->d.lbaHigh = 0;
20086 fis->d.device = 0;
20087 fis->d.lbaLowExp = 0;
20088 fis->d.lbaMidExp = 0;
20089 fis->d.lbaHighExp = 0;
20090 fis->d.featuresExp = 0;
20091 fis->d.sectorCount = 0;
20092 fis->d.sectorCountExp = 0;
20093 fis->d.reserved4 = 0;
20094 fis->d.control = 0; /* FIS HOB bit clear */
20095 fis->d.reserved5 = 0;
20096
20097 agRequestType = AGSA_SATA_PROTOCOL_NON_DATA;
20098
20099 /* Initialize CB for SATA completion.
20100 */
20101 satIOContext->satCompleteCB = &smsatSetFeaturesVolatileWriteCacheCB;
20102 /*
20103 * Prepare SGL and send FIS to LL layer.
20104 */
20105 satIOContext->reqType = agRequestType; /* Save it */
20106
20107 status = smsataLLIOStart( smRoot,
20108 smIORequest,
20109 smDeviceHandle,
20110 smScsiRequest,
20111 satIOContext);
20112 /* debugging code */
20113 if (smIORequest->tdData == smIORequest->smData)
20114 {
20115 SM_DBG1(("smsatSetFeaturesVolatileWriteCache: incorrect smIORequest\n"));
20116 }
20117 SM_DBG2(("smsatSetFeaturesVolatileWriteCache: return\n"));
20118
20119 return status;
20120 }
20121
20122
20123
20124 /******************************** start of utils ***********************************************************/
20125 osGLOBAL FORCEINLINE void
smsatBitSet(smRoot_t * smRoot,bit8 * data,bit32 index)20126 smsatBitSet(smRoot_t *smRoot, bit8 *data, bit32 index)
20127 {
20128 data[index>>3] |= (1 << (index&7));
20129 }
20130
20131 osGLOBAL FORCEINLINE void
smsatBitClear(smRoot_t * smRoot,bit8 * data,bit32 index)20132 smsatBitClear(smRoot_t *smRoot, bit8 *data, bit32 index)
20133 {
20134 data[index>>3] &= ~(1 << (index&7));
20135 }
20136
20137 osGLOBAL FORCEINLINE BOOLEAN
smsatBitTest(smRoot_t * smRoot,bit8 * data,bit32 index)20138 smsatBitTest(smRoot_t *smRoot, bit8 *data, bit32 index)
20139 {
20140 return ( (BOOLEAN)((data[index>>3] & (1 << (index&7)) ) ? 1: 0));
20141 }
20142
20143
20144 FORCEINLINE bit32
smsatTagAlloc(smRoot_t * smRoot,smDeviceData_t * pSatDevData,bit8 * pTag)20145 smsatTagAlloc(
20146 smRoot_t *smRoot,
20147 smDeviceData_t *pSatDevData,
20148 bit8 *pTag
20149 )
20150 {
20151 bit32 retCode = agFALSE;
20152 bit32 i;
20153
20154 tdsmSingleThreadedEnter(smRoot, SM_NCQ_TAG_LOCK);
20155
20156 #ifdef CCFLAG_OPTIMIZE_SAT_LOCK
20157
20158 if (tdsmBitScanForward(smRoot, &i, ~(pSatDevData->freeSATAFDMATagBitmap)))
20159 {
20160 smsatBitSet(smRoot, (bit8*)&pSatDevData->freeSATAFDMATagBitmap, i);
20161 *pTag = (bit8)i;
20162 retCode = agTRUE;
20163 }
20164
20165 #else
20166
20167 for ( i = 0; i < pSatDevData->satNCQMaxIO; i ++ )
20168 {
20169 if ( 0 == smsatBitTest(smRoot, (bit8 *)&pSatDevData->freeSATAFDMATagBitmap, i) )
20170 {
20171 smsatBitSet(smRoot, (bit8*)&pSatDevData->freeSATAFDMATagBitmap, i);
20172 *pTag = (bit8) i;
20173 retCode = agTRUE;
20174 break;
20175 }
20176 }
20177
20178 #endif
20179
20180 tdsmSingleThreadedLeave(smRoot, SM_NCQ_TAG_LOCK);
20181
20182 return retCode;
20183 }
20184
20185 FORCEINLINE bit32
smsatTagRelease(smRoot_t * smRoot,smDeviceData_t * pSatDevData,bit8 tag)20186 smsatTagRelease(
20187 smRoot_t *smRoot,
20188 smDeviceData_t *pSatDevData,
20189 bit8 tag
20190 )
20191 {
20192 bit32 retCode = agFALSE;
20193
20194 if ( tag < pSatDevData->satNCQMaxIO )
20195 {
20196 tdsmSingleThreadedEnter(smRoot, SM_NCQ_TAG_LOCK);
20197 smsatBitClear(smRoot, (bit8 *)&pSatDevData->freeSATAFDMATagBitmap, (bit32)tag);
20198 tdsmSingleThreadedLeave(smRoot, SM_NCQ_TAG_LOCK);
20199 /*tdsmInterlockedAnd(smRoot, (volatile LONG *)(&pSatDevData->freeSATAFDMATagBitmap), ~(1 << (tag&31)));*/
20200 retCode = agTRUE;
20201 }
20202 else
20203 {
20204 SM_DBG1(("smsatTagRelease: tag %d >= satNCQMaxIO %d!!!!\n", tag, pSatDevData->satNCQMaxIO));
20205 }
20206 return retCode;
20207 }
20208
20209
20210
20211 osGLOBAL bit32
smsatComputeCDB10LBA(smSatIOContext_t * satIOContext)20212 smsatComputeCDB10LBA(smSatIOContext_t *satIOContext)
20213 {
20214 smIniScsiCmnd_t *scsiCmnd;
20215 smScsiInitiatorRequest_t *smScsiRequest;
20216 bit32 lba = 0;
20217
20218 SM_DBG5(("smsatComputeCDB10LBA: start\n"));
20219 smScsiRequest = satIOContext->smScsiXchg;
20220 scsiCmnd = &(smScsiRequest->scsiCmnd);
20221
20222 lba = (scsiCmnd->cdb[2] << (8*3)) + (scsiCmnd->cdb[3] << (8*2))
20223 + (scsiCmnd->cdb[4] << 8) + scsiCmnd->cdb[5];
20224
20225 return lba;
20226 }
20227
20228 osGLOBAL bit32
smsatComputeCDB10TL(smSatIOContext_t * satIOContext)20229 smsatComputeCDB10TL(smSatIOContext_t *satIOContext)
20230 {
20231
20232 smIniScsiCmnd_t *scsiCmnd;
20233 smScsiInitiatorRequest_t *smScsiRequest;
20234 bit32 tl = 0;
20235
20236 SM_DBG5(("smsatComputeCDB10TL: start\n"));
20237 smScsiRequest = satIOContext->smScsiXchg;
20238 scsiCmnd = &(smScsiRequest->scsiCmnd);
20239
20240 tl = (scsiCmnd->cdb[7] << 8) + scsiCmnd->cdb[8];
20241 return tl;
20242 }
20243
20244 osGLOBAL bit32
smsatComputeCDB12LBA(smSatIOContext_t * satIOContext)20245 smsatComputeCDB12LBA(smSatIOContext_t *satIOContext)
20246 {
20247 smIniScsiCmnd_t *scsiCmnd;
20248 smScsiInitiatorRequest_t *smScsiRequest;
20249 bit32 lba = 0;
20250
20251 SM_DBG5(("smsatComputeCDB12LBA: start\n"));
20252 smScsiRequest = satIOContext->smScsiXchg;
20253 scsiCmnd = &(smScsiRequest->scsiCmnd);
20254
20255 lba = (scsiCmnd->cdb[2] << (8*3)) + (scsiCmnd->cdb[3] << (8*2))
20256 + (scsiCmnd->cdb[4] << 8) + scsiCmnd->cdb[5];
20257
20258 return lba;
20259 }
20260
20261 osGLOBAL bit32
smsatComputeCDB12TL(smSatIOContext_t * satIOContext)20262 smsatComputeCDB12TL(smSatIOContext_t *satIOContext)
20263 {
20264
20265 smIniScsiCmnd_t *scsiCmnd;
20266 smScsiInitiatorRequest_t *smScsiRequest;
20267 bit32 tl = 0;
20268
20269 SM_DBG5(("smsatComputeCDB12TL: start\n"));
20270 smScsiRequest = satIOContext->smScsiXchg;
20271 scsiCmnd = &(smScsiRequest->scsiCmnd);
20272
20273 tl = (scsiCmnd->cdb[6] << (8*3)) + (scsiCmnd->cdb[7] << (8*2))
20274 + (scsiCmnd->cdb[8] << 8) + scsiCmnd->cdb[9];
20275 return tl;
20276 }
20277
20278 /*
20279 CBD16 has bit64 LBA
20280 But it has to be less than (2^28 - 1)
20281 Therefore, use last four bytes to compute LBA is OK
20282 */
20283 osGLOBAL bit32
smsatComputeCDB16LBA(smSatIOContext_t * satIOContext)20284 smsatComputeCDB16LBA(smSatIOContext_t *satIOContext)
20285 {
20286 smIniScsiCmnd_t *scsiCmnd;
20287 smScsiInitiatorRequest_t *smScsiRequest;
20288 bit32 lba = 0;
20289
20290 SM_DBG5(("smsatComputeCDB16LBA: start\n"));
20291 smScsiRequest = satIOContext->smScsiXchg;
20292 scsiCmnd = &(smScsiRequest->scsiCmnd);
20293
20294 lba = (scsiCmnd->cdb[6] << (8*3)) + (scsiCmnd->cdb[7] << (8*2))
20295 + (scsiCmnd->cdb[8] << 8) + scsiCmnd->cdb[9];
20296
20297 return lba;
20298 }
20299
20300 osGLOBAL bit32
smsatComputeCDB16TL(smSatIOContext_t * satIOContext)20301 smsatComputeCDB16TL(smSatIOContext_t *satIOContext)
20302 {
20303
20304 smIniScsiCmnd_t *scsiCmnd;
20305 smScsiInitiatorRequest_t *smScsiRequest;
20306 bit32 tl = 0;
20307
20308 SM_DBG5(("smsatComputeCDB16TL: start\n"));
20309 smScsiRequest = satIOContext->smScsiXchg;
20310 scsiCmnd = &(smScsiRequest->scsiCmnd);
20311
20312 tl = (scsiCmnd->cdb[10] << (8*3)) + (scsiCmnd->cdb[11] << (8*2))
20313 + (scsiCmnd->cdb[12] << 8) + scsiCmnd->cdb[13];
20314 return tl;
20315 }
20316
20317 /*
20318 (tl, denom)
20319 tl can be upto bit32 because CDB16 has bit32 tl
20320 Therefore, fine
20321 either (tl, 0xFF) or (tl, 0xFFFF)
20322 */
20323 osGLOBAL FORCEINLINE bit32
smsatComputeLoopNum(bit32 a,bit32 b)20324 smsatComputeLoopNum(bit32 a, bit32 b)
20325 {
20326 bit32 LoopNum = 0;
20327
20328 SM_DBG5(("smsatComputeLoopNum: start\n"));
20329
20330 if (a < b || a == 0)
20331 {
20332 LoopNum = 1;
20333 }
20334 else
20335 {
20336 if (a == b || a == 0)
20337 {
20338 LoopNum = a/b;
20339 }
20340 else
20341 {
20342 LoopNum = a/b + 1;
20343 }
20344 }
20345
20346 return LoopNum;
20347 }
20348
20349 /*
20350 Generic new function for checking
20351 LBA itself, LBA+TL < SAT_TR_LBA_LIMIT or SAT_EXT_TR_LBA_LIMIT
20352 and LBA+TL < Read Capacity Limit
20353 flag: false - not 48BitSupport; true - 48BitSupport
20354 returns TRUE when over the limit
20355
20356 */
20357 osGLOBAL FORCEINLINE bit32
smsatCheckLimit(bit8 * lba,bit8 * tl,int flag,smDeviceData_t * pSatDevData)20358 smsatCheckLimit(bit8 *lba, bit8 *tl, int flag, smDeviceData_t *pSatDevData)
20359 {
20360 bit32 lbaCheck = agFALSE;
20361 int i;
20362 bit8 limit[8];
20363 bit32 rangeCheck = agFALSE;
20364 bit16 ans[8]; // 0 MSB, 8 LSB
20365 bit8 final_ans[9]; // 0 MSB, 9 LSB
20366 bit8 Bit28max[8];
20367 bit8 Bit48max[8];
20368 bit32 ReadCapCheck = agFALSE;
20369 bit32 ret;
20370
20371 bit8 final_satMaxLBA[9];
20372 bit8 oneTL[8];
20373 bit8 temp_satMaxLBA[8]; // 0 MSB, 8 LSB
20374 /*
20375 check LBA
20376 */
20377 if (flag == agFALSE)
20378 {
20379 /* limit is 0xF FF FF = 2^28 - 1 */
20380 limit[0] = 0x0; /* MSB */
20381 limit[1] = 0x0;
20382 limit[2] = 0x0;
20383 limit[3] = 0x0;
20384 limit[4] = 0xF;
20385 limit[5] = 0xFF;
20386 limit[6] = 0xFF;
20387 limit[7] = 0xFF; /* LSB */
20388 }
20389 else
20390 {
20391 /* limit is 0xF FF FF = 2^48 - 1 */
20392 limit[0] = 0x0; /* MSB */
20393 limit[1] = 0x0;
20394 limit[2] = 0xFF;
20395 limit[3] = 0xFF;
20396 limit[4] = 0xFF;
20397 limit[5] = 0xFF;
20398 limit[6] = 0xFF;
20399 limit[7] = 0xFF; /* LSB */
20400 }
20401 //compare lba to limit
20402 for(i=0;i<8;i++)
20403 {
20404 if (lba[i] > limit[i])
20405 {
20406 SM_DBG1(("smsatCheckLimit: LBA check True at %d\n", i));
20407 lbaCheck = agTRUE;
20408 break;
20409 }
20410 else if (lba[i] < limit[i])
20411 {
20412 SM_DBG5(("smsatCheckLimit: LBA check False at %d\n", i));
20413 lbaCheck = agFALSE;
20414 break;
20415 }
20416 else
20417 {
20418 continue;
20419 }
20420 }
20421
20422 if (lbaCheck == agTRUE)
20423 {
20424 SM_DBG1(("smsatCheckLimit: return LBA check True\n"));
20425 return agTRUE;
20426 }
20427
20428 /*
20429 check LBA+TL < SAT_TR_LBA_LIMIT or SAT_EXT_TR_LBA_LIMIT
20430 */
20431 sm_memset(ans, 0, sizeof(ans));
20432 sm_memset(final_ans, 0, sizeof(final_ans));
20433
20434 // adding from LSB to MSB
20435 for(i=7;i>=0;i--)
20436 {
20437 ans[i] = (bit16)(lba[i] + tl[i]);
20438 if (i != 7)
20439 {
20440 ans[i] = (bit16)(ans[i] + ((ans[i+1] & 0xFF00) >> 8));
20441 }
20442 }
20443
20444 /*
20445 filling in the final answer
20446 */
20447 final_ans[0] = (bit8)(((ans[0] & 0xFF00) >> 8));
20448
20449 for(i=1;i<=8;i++)
20450 {
20451 final_ans[i] = (bit8)(ans[i-1] & 0xFF);
20452 }
20453
20454
20455 if (flag == agFALSE)
20456 {
20457 sm_memset(Bit28max, 0, sizeof(Bit28max));
20458 Bit28max[4] = 0x10; // max =0x1000 0000
20459
20460 //compare final_ans to max
20461 if (final_ans[0] != 0 || final_ans[1] != 0 || final_ans[2] != 0
20462 || final_ans[3] != 0 || final_ans[4] != 0)
20463 {
20464 SM_DBG1(("smsatCheckLimit: before 28Bit addressing TRUE\n"));
20465 rangeCheck = agTRUE;
20466 }
20467 else
20468 {
20469 for(i=5;i<=8;i++)
20470 {
20471 if (final_ans[i] > Bit28max[i-1])
20472 {
20473 SM_DBG1(("smsatCheckLimit: 28Bit addressing TRUE at %d\n", i));
20474 rangeCheck = agTRUE;
20475 break;
20476 }
20477 else if (final_ans[i] < Bit28max[i-1])
20478 {
20479 SM_DBG5(("smsatCheckLimit: 28Bit addressing FALSE at %d\n", i));
20480 rangeCheck = agFALSE;
20481 break;
20482 }
20483 else
20484 {
20485 continue;
20486 }
20487 }
20488 }
20489 }
20490 else
20491 {
20492 sm_memset(Bit48max, 0, sizeof(Bit48max));
20493 Bit48max[1] = 0x1; //max = 0x1 0000 0000 0000
20494
20495 //compare final_ans to max
20496 if (final_ans[0] != 0 || final_ans[1] != 0)
20497 {
20498 SM_DBG1(("smsatCheckLimit: before 48Bit addressing TRUE\n"));
20499 rangeCheck = agTRUE;
20500 }
20501 else
20502 {
20503 for(i=2;i<=8;i++)
20504 {
20505 if (final_ans[i] > Bit48max[i-1])
20506 {
20507 SM_DBG1(("smsatCheckLimit: 48Bit addressing TRUE at %d\n", i));
20508 rangeCheck = agTRUE;
20509 break;
20510 }
20511 else if (final_ans[i] < Bit48max[i-1])
20512 {
20513 SM_DBG5(("smsatCheckLimit: 48Bit addressing FALSE at %d\n", i));
20514 rangeCheck = agFALSE;
20515 break;
20516 }
20517 else
20518 {
20519 continue;
20520 }
20521 }
20522 }
20523 }
20524 if (rangeCheck == agTRUE)
20525 {
20526 SM_DBG1(("smsatCheckLimit: return rangeCheck True\n"));
20527 return agTRUE;
20528 }
20529
20530 /*
20531 LBA+TL < Read Capacity Limit
20532 */
20533 sm_memset(temp_satMaxLBA, 0, sizeof(temp_satMaxLBA));
20534 sm_memset(oneTL, 0, sizeof(oneTL));
20535 sm_memset(final_satMaxLBA, 0, sizeof(final_satMaxLBA));
20536 sm_memset(ans, 0, sizeof(ans));
20537
20538 sm_memcpy(&temp_satMaxLBA, &pSatDevData->satMaxLBA, sizeof(temp_satMaxLBA));
20539 oneTL[7] = 1;
20540
20541 // adding temp_satMaxLBA to oneTL
20542 for(i=7;i>=0;i--)
20543 {
20544 ans[i] = (bit16)(temp_satMaxLBA[i] + oneTL[i]);
20545 if (i != 7)
20546 {
20547 ans[i] = (bit16)(ans[i] + ((ans[i+1] & 0xFF00) >> 8));
20548 }
20549 }
20550
20551 /*
20552 filling in the final answer
20553 */
20554 final_satMaxLBA[0] = (bit8)(((ans[0] & 0xFF00) >> 8));
20555
20556 for(i=1;i<=8;i++)
20557 {
20558 final_satMaxLBA[i] = (bit8)(ans[i-1] & 0xFF);
20559 }
20560 if ( pSatDevData->ReadCapacity == 10)
20561 {
20562 for (i=0;i<=8;i++)
20563 {
20564 if (final_ans[i] > final_satMaxLBA[i])
20565 {
20566 SM_DBG1(("smsatCheckLimit: Read Capacity 10 TRUE at %d\n", i));
20567 ReadCapCheck = agTRUE;
20568 break;
20569 }
20570 else if (final_ans[i] < final_satMaxLBA[i])
20571 {
20572 SM_DBG5(("smsatCheckLimit: Read Capacity 10 FALSE at %d\n", i));
20573 ReadCapCheck = agFALSE;
20574 break;
20575 }
20576 else
20577 {
20578 continue;
20579 }
20580 }
20581 if ( ReadCapCheck)
20582 {
20583 SM_DBG1(("smsatCheckLimit: after Read Capacity 10 TRUE\n"));
20584 }
20585 else
20586 {
20587 SM_DBG5(("smsatCheckLimit: after Read Capacity 10 FALSE\n"));
20588 }
20589 }
20590 else if ( pSatDevData->ReadCapacity == 16)
20591 {
20592 for (i=0;i<=8;i++)
20593 {
20594 if (final_ans[i] > final_satMaxLBA[i])
20595 {
20596 SM_DBG1(("smsatCheckLimit: Read Capacity 16 TRUE at %d\n", i));
20597 ReadCapCheck = agTRUE;
20598 break;
20599 }
20600 else if (final_ans[i] < final_satMaxLBA[i])
20601 {
20602 SM_DBG5(("smsatCheckLimit: Read Capacity 16 FALSE at %d\n", i));
20603 ReadCapCheck = agFALSE;
20604 break;
20605 }
20606 else
20607 {
20608 continue;
20609 }
20610 }
20611 if ( ReadCapCheck)
20612 {
20613 SM_DBG1(("smsatCheckLimit: after Read Capacity 16 TRUE\n"));
20614 }
20615 else
20616 {
20617 SM_DBG5(("smsatCheckLimit: after Read Capacity 16 FALSE\n"));
20618 }
20619 }
20620 else
20621 {
20622 SM_DBG5(("smsatCheckLimit: unknown pSatDevData->ReadCapacity %d\n", pSatDevData->ReadCapacity));
20623 }
20624
20625 if (ReadCapCheck == agTRUE)
20626 {
20627 SM_DBG1(("smsatCheckLimit: return ReadCapCheck True\n"));
20628 return agTRUE;
20629 }
20630
20631
20632 ret = (lbaCheck | rangeCheck | ReadCapCheck);
20633 if (ret == agTRUE)
20634 {
20635 SM_DBG1(("smsatCheckLimit: final check TRUE\n"));
20636 }
20637 else
20638 {
20639 SM_DBG5(("smsatCheckLimit: final check FALSE\n"));
20640 }
20641 return ret;
20642 }
20643
20644
20645
20646 osGLOBAL void
smsatPrintSgl(smRoot_t * smRoot,agsaEsgl_t * agEsgl,bit32 idx)20647 smsatPrintSgl(
20648 smRoot_t *smRoot,
20649 agsaEsgl_t *agEsgl,
20650 bit32 idx
20651 )
20652 {
20653 bit32 i=0;
20654 #ifdef TD_DEBUG_ENABLE
20655 agsaSgl_t *agSgl;
20656 #endif
20657
20658 for (i=0;i<idx;i++)
20659 {
20660 #ifdef TD_DEBUG_ENABLE
20661 agSgl = &(agEsgl->descriptor[i]);
20662 #endif
20663 SM_DBG3(("smsatPrintSgl: agSgl %d upperAddr 0x%08x lowerAddr 0x%08x len 0x%08x ext 0x%08x\n",
20664 i, agSgl->sgUpper, agSgl->sgLower, agSgl->len, agSgl->extReserved));
20665 }
20666
20667 return;
20668 }
20669
20670
20671 osGLOBAL void
smsatSplitSGL(smRoot_t * smRoot,smIORequest_t * smIORequest,smDeviceHandle_t * smDeviceHandle,smScsiInitiatorRequest_t * smScsiRequest,smSatIOContext_t * satIOContext,bit32 split,bit32 tl,bit32 flag)20672 smsatSplitSGL(
20673 smRoot_t *smRoot,
20674 smIORequest_t *smIORequest,
20675 smDeviceHandle_t *smDeviceHandle,
20676 smScsiInitiatorRequest_t *smScsiRequest,
20677 smSatIOContext_t *satIOContext,
20678 bit32 split, /*in sector number, depeding on IO value */
20679 bit32 tl, /* in sector number */
20680 bit32 flag
20681 )
20682 {
20683 agsaSgl_t *agSgl;
20684 agsaEsgl_t *agEsgl;
20685 bit32 i=0;
20686 smIniScsiCmnd_t *scsiCmnd;
20687 bit32 totalLen=0; /* in bytes */
20688 bit32 splitLen=0; /* in bytes */
20689 bit32 splitDiffByte = 0; /* in bytes */
20690 bit32 splitDiffExtra = 0; /* in bytes */
20691 bit32 splitIdx = 0;
20692 bit32 UpperAddr, LowerAddr;
20693 bit32 tmpLowerAddr;
20694 void *sglVirtualAddr;
20695 void *sglSplitVirtualAddr;
20696
20697 scsiCmnd = &smScsiRequest->scsiCmnd;
20698 SM_DBG3(("smsatSplitSGL: start\n"));
20699
20700 if (smScsiRequest->smSgl1.type == 0x80000000) /* esgl */
20701 {
20702 if (flag == agFALSE)
20703 {
20704 SM_DBG3(("smsatSplitSGL: Not first time\n"));
20705 SM_DBG3(("smsatSplitSGL: UpperAddr 0x%08x LowerAddr 0x%08x\n", satIOContext->UpperAddr, satIOContext->LowerAddr));
20706 SM_DBG3(("smsatSplitSGL: SplitIdx %d AdjustBytes 0x%08x\n", satIOContext->SplitIdx, satIOContext->AdjustBytes));
20707
20708 sglVirtualAddr = smScsiRequest->sglVirtualAddr;
20709
20710 agEsgl = (agsaEsgl_t *)smScsiRequest->sglVirtualAddr;
20711
20712 sglSplitVirtualAddr = &(agEsgl->descriptor[satIOContext->SplitIdx]);
20713
20714 agEsgl = (agsaEsgl_t *)sglSplitVirtualAddr;
20715
20716 if (agEsgl == agNULL)
20717 {
20718 SM_DBG1(("smsatSplitSGL: error!\n"));
20719 return;
20720 }
20721 /* first sgl ajustment */
20722 agSgl = &(agEsgl->descriptor[0]);
20723 agSgl->sgUpper = satIOContext->UpperAddr;
20724 agSgl->sgLower = satIOContext->LowerAddr;
20725 agSgl->len = satIOContext->AdjustBytes;
20726 sm_memcpy(sglVirtualAddr, sglSplitVirtualAddr, (satIOContext->EsglLen) * sizeof(agsaSgl_t));
20727 agEsgl = (agsaEsgl_t *)smScsiRequest->sglVirtualAddr;
20728 smsatPrintSgl(smRoot, (agsaEsgl_t *)sglVirtualAddr, satIOContext->EsglLen);
20729 }
20730 else
20731 {
20732 /* first time */
20733 SM_DBG3(("smsatSplitSGL: first time\n"));
20734 satIOContext->EsglLen = smScsiRequest->smSgl1.len;
20735 agEsgl = (agsaEsgl_t *)smScsiRequest->sglVirtualAddr;
20736 if (agEsgl == agNULL)
20737 {
20738 return;
20739 }
20740 smsatPrintSgl(smRoot, agEsgl, satIOContext->EsglLen);
20741 }
20742
20743 if (tl > split)
20744 {
20745 /* split */
20746 SM_DBG3(("smsatSplitSGL: split case\n"));
20747 i = 0;
20748 while (1)
20749 {
20750 agSgl = &(agEsgl->descriptor[i]);
20751 splitLen = splitLen + agSgl->len;
20752 if (splitLen >= split)
20753 {
20754 splitDiffExtra = splitLen - split;
20755 splitDiffByte = agSgl->len - splitDiffExtra;
20756 splitIdx = i;
20757 break;
20758 }
20759 i++;
20760 }
20761 SM_DBG3(("smsatSplitSGL: splitIdx %d\n", splitIdx));
20762 SM_DBG3(("smsatSplitSGL: splitDiffByte 0x%8x\n", splitDiffByte));
20763 SM_DBG3(("smsatSplitSGL: splitDiffExtra 0x%8x \n", splitDiffExtra));
20764
20765
20766 agSgl = &(agEsgl->descriptor[splitIdx]);
20767 UpperAddr = agSgl->sgUpper;
20768 LowerAddr = agSgl->sgLower;
20769 tmpLowerAddr = LowerAddr + splitDiffByte;
20770 if (tmpLowerAddr < LowerAddr)
20771 {
20772 UpperAddr = UpperAddr + 1;
20773 }
20774 SM_DBG3(("smsatSplitSGL: UpperAddr 0x%08x tmpLowerAddr 0x%08x\n", UpperAddr, tmpLowerAddr));
20775 agSgl->len = splitDiffByte;
20776 /* Esgl len adjustment */
20777 smScsiRequest->smSgl1.len = splitIdx;
20778 /* expected data lent adjustment */
20779 scsiCmnd->expDataLength = 0x20000;
20780 /* remeber for the next round */
20781 satIOContext->UpperAddr = UpperAddr;
20782 satIOContext->LowerAddr = tmpLowerAddr;
20783 satIOContext->SplitIdx = splitIdx;
20784 satIOContext->AdjustBytes = splitDiffExtra;
20785 satIOContext->EsglLen = satIOContext->EsglLen - smScsiRequest->smSgl1.len;
20786 satIOContext->OrgTL = satIOContext->OrgTL - 0x100;
20787 // smsatPrintSgl(smRoot, agEsgl, satIOContext->EsglLen);
20788
20789 }
20790 else
20791 {
20792 /* no split */
20793 SM_DBG3(("smsatSplitSGL: no split case\n"));
20794 /* Esgl len adjustment */
20795 smScsiRequest->smSgl1.len = satIOContext->EsglLen;
20796 for (i=0;i< smScsiRequest->smSgl1.len;i++)
20797 {
20798 agSgl = &(agEsgl->descriptor[i]);
20799 totalLen = totalLen + (agSgl->len);
20800 }
20801 /* expected data lent adjustment */
20802 scsiCmnd->expDataLength = totalLen;
20803 // smsatPrintSgl(smRoot, agEsgl, satIOContext->EsglLen);
20804 }
20805 }
20806 else
20807 {
20808 SM_DBG1(("not exntened esgl\n"));
20809
20810 }
20811
20812 return;
20813 }
20814
20815
20816 /******************************** end of utils ***********************************************************/
20817
20818
20819
20820