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 /*****************************************************************************/
23 /** \file
24 *
25 * The file implementing SCSI/ATA Translation (SAT).
26 * The routines in this file are independent from HW LL API.
27 *
28 */
29 /*****************************************************************************/
30 #include <sys/cdefs.h>
31 __FBSDID("$FreeBSD$");
32 #include <dev/pms/config.h>
33
34 #include <dev/pms/freebsd/driver/common/osenv.h>
35 #include <dev/pms/freebsd/driver/common/ostypes.h>
36 #include <dev/pms/freebsd/driver/common/osdebug.h>
37
38 #ifdef SATA_ENABLE
39
40 #include <dev/pms/RefTisa/sallsdk/api/sa.h>
41 #include <dev/pms/RefTisa/sallsdk/api/saapi.h>
42 #include <dev/pms/RefTisa/sallsdk/api/saosapi.h>
43
44 #include <dev/pms/RefTisa/tisa/api/titypes.h>
45 #include <dev/pms/RefTisa/tisa/api/ostiapi.h>
46 #include <dev/pms/RefTisa/tisa/api/tiapi.h>
47 #include <dev/pms/RefTisa/tisa/api/tiglobal.h>
48
49 #ifdef FDS_SM
50 #include <dev/pms/RefTisa/sat/api/sm.h>
51 #include <dev/pms/RefTisa/sat/api/smapi.h>
52 #include <dev/pms/RefTisa/sat/api/tdsmapi.h>
53 #endif
54
55 #ifdef FDS_DM
56 #include <dev/pms/RefTisa/discovery/api/dm.h>
57 #include <dev/pms/RefTisa/discovery/api/dmapi.h>
58 #include <dev/pms/RefTisa/discovery/api/tddmapi.h>
59 #endif
60
61 #include <dev/pms/RefTisa/tisa/sassata/sas/common/tdtypes.h>
62 #include <dev/pms/freebsd/driver/common/osstring.h>
63 #include <dev/pms/RefTisa/tisa/sassata/common/tdutil.h>
64
65 #ifdef INITIATOR_DRIVER
66 #include <dev/pms/RefTisa/tisa/sassata/sas/ini/itdtypes.h>
67 #include <dev/pms/RefTisa/tisa/sassata/sas/ini/itddefs.h>
68 #include <dev/pms/RefTisa/tisa/sassata/sas/ini/itdglobl.h>
69 #endif
70
71 #ifdef TARGET_DRIVER
72 #include <dev/pms/RefTisa/tisa/sassata/sas/tgt/ttdglobl.h>
73 #include <dev/pms/RefTisa/tisa/sassata/sas/tgt/ttdxchg.h>
74 #include <dev/pms/RefTisa/tisa/sassata/sas/tgt/ttdtypes.h>
75 #endif
76
77 #include <dev/pms/RefTisa/tisa/sassata/common/tdsatypes.h>
78 #include <dev/pms/RefTisa/tisa/sassata/common/tdproto.h>
79
80 #include <dev/pms/RefTisa/tisa/sassata/sata/host/sat.h>
81 #include <dev/pms/RefTisa/tisa/sassata/sata/host/satproto.h>
82
83 /*****************************************************************************
84 *! \brief satIOStart
85 *
86 * This routine is called to initiate a new SCSI request to SATL.
87 *
88 * \param tiRoot: Pointer to TISA initiator driver/port instance.
89 * \param tiIORequest: Pointer to TISA I/O request context for this I/O.
90 * \param tiDeviceHandle: Pointer to TISA device handle for this I/O.
91 * \param tiScsiRequest: Pointer to TISA SCSI I/O request and SGL list.
92 * \param satIOContext_t: Pointer to the SAT IO Context
93 *
94 * \return:
95 *
96 * \e tiSuccess: I/O request successfully initiated.
97 * \e tiBusy: No resources available, try again later.
98 * \e tiIONoDevice: Invalid device handle.
99 * \e tiError: Other errors that prevent the I/O request to be started.
100 *
101 *
102 *****************************************************************************/
103 GLOBAL bit32 satIOStart(
104 tiRoot_t *tiRoot,
105 tiIORequest_t *tiIORequest,
106 tiDeviceHandle_t *tiDeviceHandle,
107 tiScsiInitiatorRequest_t *tiScsiRequest,
108 satIOContext_t *satIOContext
109 )
110 {
111
112 bit32 retVal = tiSuccess;
113 satDeviceData_t *pSatDevData;
114 scsiRspSense_t *pSense;
115 tiIniScsiCmnd_t *scsiCmnd;
116 tiLUN_t *pLun;
117 satInternalIo_t *pSatIntIo;
118 #ifdef TD_DEBUG_ENABLE
119 tdsaDeviceData_t *oneDeviceData;
120 #endif
121
122 pSense = satIOContext->pSense;
123 pSatDevData = satIOContext->pSatDevData;
124 scsiCmnd = &tiScsiRequest->scsiCmnd;
125 pLun = &scsiCmnd->lun;
126
127 /*
128 * Reject all other LUN other than LUN 0.
129 */
130 if ( ((pLun->lun[0] | pLun->lun[1] | pLun->lun[2] | pLun->lun[3] |
131 pLun->lun[4] | pLun->lun[5] | pLun->lun[6] | pLun->lun[7] ) != 0) &&
132 (scsiCmnd->cdb[0] != SCSIOPC_INQUIRY)
133 )
134 {
135 TI_DBG1(("satIOStart: *** REJECT *** LUN not zero, cdb[0]=0x%x tiIORequest=%p tiDeviceHandle=%p\n",
136 scsiCmnd->cdb[0], tiIORequest, tiDeviceHandle));
137 satSetSensePayload( pSense,
138 SCSI_SNSKEY_ILLEGAL_REQUEST,
139 0,
140 SCSI_SNSCODE_LOGICAL_NOT_SUPPORTED,
141 satIOContext);
142
143 ostiInitiatorIOCompleted( tiRoot,
144 tiIORequest,
145 tiIOSuccess,
146 SCSI_STAT_CHECK_CONDITION,
147 satIOContext->pTiSenseData,
148 satIOContext->interruptContext );
149 retVal = tiSuccess;
150 goto ext;
151 }
152
153 TI_DBG6(("satIOStart: satPendingIO %d satNCQMaxIO %d\n",pSatDevData->satPendingIO, pSatDevData->satNCQMaxIO ));
154
155 /* this may happen after tiCOMReset until OS sends inquiry */
156 if (pSatDevData->IDDeviceValid == agFALSE && (scsiCmnd->cdb[0] != SCSIOPC_INQUIRY))
157 {
158 #ifdef TD_DEBUG_ENABLE
159 oneDeviceData = (tdsaDeviceData_t *)tiDeviceHandle->tdData;
160 #endif
161 TI_DBG1(("satIOStart: invalid identify device data did %d\n", oneDeviceData->id));
162 retVal = tiIONoDevice;
163 goto ext;
164 }
165 /*
166 * Check if we need to return BUSY, i.e. recovery in progress
167 */
168 if (pSatDevData->satDriveState == SAT_DEV_STATE_IN_RECOVERY)
169 {
170 #ifdef TD_DEBUG_ENABLE
171 oneDeviceData = (tdsaDeviceData_t *)tiDeviceHandle->tdData;
172 #endif
173 TI_DBG1(("satIOStart: IN RECOVERY STATE cdb[0]=0x%x tiIORequest=%p tiDeviceHandle=%p\n",
174 scsiCmnd->cdb[0], tiIORequest, tiDeviceHandle));
175 TI_DBG1(("satIOStart: IN RECOVERY STATE did %d\n", oneDeviceData->id));
176
177 TI_DBG1(("satIOStart: device %p satPendingIO %d satNCQMaxIO %d\n",pSatDevData, pSatDevData->satPendingIO, pSatDevData->satNCQMaxIO ));
178 TI_DBG1(("satIOStart: device %p satPendingNCQIO %d satPendingNONNCQIO %d\n",pSatDevData, pSatDevData->satPendingNCQIO, pSatDevData->satPendingNONNCQIO));
179 retVal = tiError;
180 goto ext;
181 // return tiBusy;
182 }
183
184 if (pSatDevData->satDeviceType == SATA_ATAPI_DEVICE)
185 {
186 if (scsiCmnd->cdb[0] == SCSIOPC_REPORT_LUN)
187 {
188 return satReportLun(tiRoot, tiIORequest, tiDeviceHandle, tiScsiRequest, satIOContext);
189 }
190 else
191 {
192 return satPacket(tiRoot, tiIORequest, tiDeviceHandle, tiScsiRequest, satIOContext);
193 }
194 }
195 else /* pSatDevData->satDeviceType != SATA_ATAPI_DEVICE */
196 {
197 /* Parse CDB */
198 switch(scsiCmnd->cdb[0])
199 {
200 case SCSIOPC_READ_6:
201 retVal = satRead6( tiRoot,
202 tiIORequest,
203 tiDeviceHandle,
204 tiScsiRequest,
205 satIOContext);
206 break;
207
208 case SCSIOPC_READ_10:
209 retVal = satRead10( tiRoot,
210 tiIORequest,
211 tiDeviceHandle,
212 tiScsiRequest,
213 satIOContext);
214 break;
215
216 case SCSIOPC_READ_12:
217 TI_DBG5(("satIOStart: SCSIOPC_READ_12\n"));
218 retVal = satRead12( tiRoot,
219 tiIORequest,
220 tiDeviceHandle,
221 tiScsiRequest,
222 satIOContext);
223 break;
224
225 case SCSIOPC_READ_16:
226 retVal = satRead16( tiRoot,
227 tiIORequest,
228 tiDeviceHandle,
229 tiScsiRequest,
230 satIOContext);
231 break;
232
233 case SCSIOPC_WRITE_6:
234 retVal = satWrite6( tiRoot,
235 tiIORequest,
236 tiDeviceHandle,
237 tiScsiRequest,
238 satIOContext);
239 break;
240
241 case SCSIOPC_WRITE_10:
242 retVal = satWrite10( tiRoot,
243 tiIORequest,
244 tiDeviceHandle,
245 tiScsiRequest,
246 satIOContext);
247 break;
248
249 case SCSIOPC_WRITE_12:
250 TI_DBG5(("satIOStart: SCSIOPC_WRITE_12 \n"));
251 retVal = satWrite12( tiRoot,
252 tiIORequest,
253 tiDeviceHandle,
254 tiScsiRequest,
255 satIOContext);
256
257 break;
258
259 case SCSIOPC_WRITE_16:
260 TI_DBG5(("satIOStart: SCSIOPC_WRITE_16\n"));
261 retVal = satWrite16( tiRoot,
262 tiIORequest,
263 tiDeviceHandle,
264 tiScsiRequest,
265 satIOContext);
266
267 break;
268
269 case SCSIOPC_VERIFY_10:
270 retVal = satVerify10( tiRoot,
271 tiIORequest,
272 tiDeviceHandle,
273 tiScsiRequest,
274 satIOContext);
275 break;
276
277 case SCSIOPC_VERIFY_12:
278 TI_DBG5(("satIOStart: SCSIOPC_VERIFY_12\n"));
279 retVal = satVerify12( tiRoot,
280 tiIORequest,
281 tiDeviceHandle,
282 tiScsiRequest,
283 satIOContext);
284 break;
285
286 case SCSIOPC_VERIFY_16:
287 TI_DBG5(("satIOStart: SCSIOPC_VERIFY_16\n"));
288 retVal = satVerify16( tiRoot,
289 tiIORequest,
290 tiDeviceHandle,
291 tiScsiRequest,
292 satIOContext);
293 break;
294
295 case SCSIOPC_TEST_UNIT_READY:
296 retVal = satTestUnitReady( tiRoot,
297 tiIORequest,
298 tiDeviceHandle,
299 tiScsiRequest,
300 satIOContext);
301 break;
302
303 case SCSIOPC_INQUIRY:
304 retVal = satInquiry( tiRoot,
305 tiIORequest,
306 tiDeviceHandle,
307 tiScsiRequest,
308 satIOContext);
309 break;
310
311 case SCSIOPC_REQUEST_SENSE:
312 retVal = satRequestSense( tiRoot,
313 tiIORequest,
314 tiDeviceHandle,
315 tiScsiRequest,
316 satIOContext);
317 break;
318
319 case SCSIOPC_MODE_SENSE_6:
320 retVal = satModeSense6( tiRoot,
321 tiIORequest,
322 tiDeviceHandle,
323 tiScsiRequest,
324 satIOContext);
325 break;
326
327 case SCSIOPC_MODE_SENSE_10:
328 retVal = satModeSense10( tiRoot,
329 tiIORequest,
330 tiDeviceHandle,
331 tiScsiRequest,
332 satIOContext);
333 break;
334
335
336 case SCSIOPC_READ_CAPACITY_10:
337 retVal = satReadCapacity10( tiRoot,
338 tiIORequest,
339 tiDeviceHandle,
340 tiScsiRequest,
341 satIOContext);
342 break;
343
344 case SCSIOPC_READ_CAPACITY_16:
345 retVal = satReadCapacity16( tiRoot,
346 tiIORequest,
347 tiDeviceHandle,
348 tiScsiRequest,
349 satIOContext);
350 break;
351
352 case SCSIOPC_REPORT_LUN:
353 retVal = satReportLun( tiRoot,
354 tiIORequest,
355 tiDeviceHandle,
356 tiScsiRequest,
357 satIOContext);
358 break;
359
360 case SCSIOPC_FORMAT_UNIT:
361 TI_DBG5(("satIOStart: SCSIOPC_FORMAT_UNIT\n"));
362 retVal = satFormatUnit( tiRoot,
363 tiIORequest,
364 tiDeviceHandle,
365 tiScsiRequest,
366 satIOContext);
367 break;
368 case SCSIOPC_SEND_DIAGNOSTIC: /* Table 28, p40 */
369 TI_DBG5(("satIOStart: SCSIOPC_SEND_DIAGNOSTIC\n"));
370 retVal = satSendDiagnostic( tiRoot,
371 tiIORequest,
372 tiDeviceHandle,
373 tiScsiRequest,
374 satIOContext);
375 break;
376
377 case SCSIOPC_START_STOP_UNIT:
378 TI_DBG5(("satIOStart: SCSIOPC_START_STOP_UNIT\n"));
379 retVal = satStartStopUnit( tiRoot,
380 tiIORequest,
381 tiDeviceHandle,
382 tiScsiRequest,
383 satIOContext);
384 break;
385
386 case SCSIOPC_WRITE_SAME_10: /* sector and LBA; SAT p64 case 3 accessing payload and very
387 inefficient now */
388 TI_DBG5(("satIOStart: SCSIOPC_WRITE_SAME_10\n"));
389 retVal = satWriteSame10( tiRoot,
390 tiIORequest,
391 tiDeviceHandle,
392 tiScsiRequest,
393 satIOContext);
394 break;
395
396 case SCSIOPC_WRITE_SAME_16: /* no support due to transfer length(sector count) */
397 TI_DBG5(("satIOStart: SCSIOPC_WRITE_SAME_16\n"));
398 retVal = satWriteSame16( tiRoot,
399 tiIORequest,
400 tiDeviceHandle,
401 tiScsiRequest,
402 satIOContext);
403 break;
404
405 case SCSIOPC_LOG_SENSE: /* SCT and log parameter(informational exceptions) */
406 TI_DBG5(("satIOStart: SCSIOPC_LOG_SENSE\n"));
407 retVal = satLogSense( tiRoot,
408 tiIORequest,
409 tiDeviceHandle,
410 tiScsiRequest,
411 satIOContext);
412 break;
413
414 case SCSIOPC_MODE_SELECT_6: /*mode layout and AlloLen check */
415 TI_DBG5(("satIOStart: SCSIOPC_MODE_SELECT_6\n"));
416 retVal = satModeSelect6( tiRoot,
417 tiIORequest,
418 tiDeviceHandle,
419 tiScsiRequest,
420 satIOContext);
421 break;
422
423 case SCSIOPC_MODE_SELECT_10: /* mode layout and AlloLen check and sharing CB with satModeSelect6*/
424 TI_DBG5(("satIOStart: SCSIOPC_MODE_SELECT_10\n"));
425 retVal = satModeSelect10( tiRoot,
426 tiIORequest,
427 tiDeviceHandle,
428 tiScsiRequest,
429 satIOContext);
430 break;
431
432 case SCSIOPC_SYNCHRONIZE_CACHE_10: /* on error what to return, sharing CB with
433 satSynchronizeCache16 */
434 TI_DBG5(("satIOStart: SCSIOPC_SYNCHRONIZE_CACHE_10\n"));
435 retVal = satSynchronizeCache10( tiRoot,
436 tiIORequest,
437 tiDeviceHandle,
438 tiScsiRequest,
439 satIOContext);
440 break;
441
442 case SCSIOPC_SYNCHRONIZE_CACHE_16:/* on error what to return, sharing CB with
443 satSynchronizeCache16 */
444
445 TI_DBG5(("satIOStart: SCSIOPC_SYNCHRONIZE_CACHE_16\n"));
446 retVal = satSynchronizeCache16( tiRoot,
447 tiIORequest,
448 tiDeviceHandle,
449 tiScsiRequest,
450 satIOContext);
451 break;
452
453 case SCSIOPC_WRITE_AND_VERIFY_10: /* single write and multiple writes */
454 TI_DBG5(("satIOStart: SCSIOPC_WRITE_AND_VERIFY_10\n"));
455 retVal = satWriteAndVerify10( tiRoot,
456 tiIORequest,
457 tiDeviceHandle,
458 tiScsiRequest,
459 satIOContext);
460 break;
461
462 case SCSIOPC_WRITE_AND_VERIFY_12:
463 TI_DBG5(("satIOStart: SCSIOPC_WRITE_AND_VERIFY_12\n"));
464 retVal = satWriteAndVerify12( tiRoot,
465 tiIORequest,
466 tiDeviceHandle,
467 tiScsiRequest,
468 satIOContext);
469 break;
470
471 case SCSIOPC_WRITE_AND_VERIFY_16:
472 TI_DBG5(("satIOStart: SCSIOPC_WRITE_AND_VERIFY_16\n"));
473 retVal = satWriteAndVerify16( tiRoot,
474 tiIORequest,
475 tiDeviceHandle,
476 tiScsiRequest,
477 satIOContext);
478
479 break;
480
481 case SCSIOPC_READ_MEDIA_SERIAL_NUMBER:
482 TI_DBG5(("satIOStart: SCSIOPC_READ_MEDIA_SERIAL_NUMBER\n"));
483 retVal = satReadMediaSerialNumber( tiRoot,
484 tiIORequest,
485 tiDeviceHandle,
486 tiScsiRequest,
487 satIOContext);
488
489 break;
490
491 case SCSIOPC_READ_BUFFER:
492 TI_DBG5(("satIOStart: SCSIOPC_READ_BUFFER\n"));
493 retVal = satReadBuffer( tiRoot,
494 tiIORequest,
495 tiDeviceHandle,
496 tiScsiRequest,
497 satIOContext);
498
499 break;
500
501 case SCSIOPC_WRITE_BUFFER:
502 TI_DBG5(("satIOStart: SCSIOPC_WRITE_BUFFER\n"));
503 retVal = satWriteBuffer( tiRoot,
504 tiIORequest,
505 tiDeviceHandle,
506 tiScsiRequest,
507 satIOContext);
508
509 break;
510
511 case SCSIOPC_REASSIGN_BLOCKS:
512 TI_DBG5(("satIOStart: SCSIOPC_REASSIGN_BLOCKS\n"));
513 retVal = satReassignBlocks( tiRoot,
514 tiIORequest,
515 tiDeviceHandle,
516 tiScsiRequest,
517 satIOContext);
518
519 break;
520
521 default:
522 /* Not implemented SCSI cmd, set up error response */
523 TI_DBG1(("satIOStart: unsupported SCSI cdb[0]=0x%x tiIORequest=%p tiDeviceHandle=%p\n",
524 scsiCmnd->cdb[0], tiIORequest, tiDeviceHandle));
525
526 satSetSensePayload( pSense,
527 SCSI_SNSKEY_ILLEGAL_REQUEST,
528 0,
529 SCSI_SNSCODE_INVALID_COMMAND,
530 satIOContext);
531
532 ostiInitiatorIOCompleted( tiRoot,
533 tiIORequest,
534 tiIOSuccess,
535 SCSI_STAT_CHECK_CONDITION,
536 satIOContext->pTiSenseData,
537 satIOContext->interruptContext );
538 retVal = tiSuccess;
539
540 break;
541
542 } /* end switch */
543 }
544 if (retVal == tiBusy)
545 {
546 #ifdef TD_DEBUG_ENABLE
547 oneDeviceData = (tdsaDeviceData_t *)tiDeviceHandle->tdData;
548 #endif
549 TI_DBG1(("satIOStart: BUSY did %d\n", oneDeviceData->id));
550 TI_DBG3(("satIOStart: LL is busy or target queue is full\n"));
551 TI_DBG3(("satIOStart: device %p satPendingIO %d satNCQMaxIO %d\n",pSatDevData, pSatDevData->satPendingIO, pSatDevData->satNCQMaxIO ));
552 TI_DBG3(("satIOStart: device %p satPendingNCQIO %d satPendingNONNCQIO %d\n",pSatDevData, pSatDevData->satPendingNCQIO, pSatDevData->satPendingNONNCQIO));
553 pSatIntIo = satIOContext->satIntIoContext;
554
555 /* interal structure free */
556 satFreeIntIoResource( tiRoot,
557 pSatDevData,
558 pSatIntIo);
559 }
560
561 ext:
562 return retVal;
563 }
564
565
566 /*****************************************************************************/
567 /*! \brief Setup up the SCSI Sense response.
568 *
569 * This function is used to setup up the Sense Data payload for
570 * CHECK CONDITION status.
571 *
572 * \param pSense: Pointer to the scsiRspSense_t sense data structure.
573 * \param SnsKey: SCSI Sense Key.
574 * \param SnsInfo: SCSI Sense Info.
575 * \param SnsCode: SCSI Sense Code.
576 *
577 * \return: None
578 */
579 /*****************************************************************************/
580 void satSetSensePayload( scsiRspSense_t *pSense,
581 bit8 SnsKey,
582 bit32 SnsInfo,
583 bit16 SnsCode,
584 satIOContext_t *satIOContext
585 )
586 {
587 /* for fixed format sense data, SPC-4, p37 */
588 bit32 i;
589 bit32 senseLength;
590
591 TI_DBG5(("satSetSensePayload: start\n"));
592
593 senseLength = sizeof(scsiRspSense_t);
594
595 /* zero out the data area */
596 for (i=0;i< senseLength;i++)
597 {
598 ((bit8*)pSense)[i] = 0;
599 }
600
601 /*
602 * SCSI Sense Data part of response data
603 */
604 pSense->snsRespCode = 0x70; /* 0xC0 == vendor specific */
605 /* 0x70 == standard current error */
606 pSense->senseKey = SnsKey;
607 /*
608 * Put sense info in scsi order format
609 */
610 pSense->info[0] = (bit8)((SnsInfo >> 24) & 0xff);
611 pSense->info[1] = (bit8)((SnsInfo >> 16) & 0xff);
612 pSense->info[2] = (bit8)((SnsInfo >> 8) & 0xff);
613 pSense->info[3] = (bit8)((SnsInfo) & 0xff);
614 pSense->addSenseLen = 11; /* fixed size of sense data = 18 */
615 pSense->addSenseCode = (bit8)((SnsCode >> 8) & 0xFF);
616 pSense->senseQual = (bit8)(SnsCode & 0xFF);
617 /*
618 * Set pointer in scsi status
619 */
620 switch(SnsKey)
621 {
622 /*
623 * set illegal request sense key specific error in cdb, no bit pointer
624 */
625 case SCSI_SNSKEY_ILLEGAL_REQUEST:
626 pSense->skeySpecific[0] = 0xC8;
627 break;
628
629 default:
630 break;
631 }
632 /* setting sense data length */
633 if (satIOContext != agNULL)
634 {
635 satIOContext->pTiSenseData->senseLen = 18;
636 }
637 else
638 {
639 TI_DBG1(("satSetSensePayload: satIOContext is NULL\n"));
640 }
641 }
642
643 /*****************************************************************************/
644 /*! \brief Setup up the SCSI Sense response.
645 *
646 * This function is used to setup up the Sense Data payload for
647 * CHECK CONDITION status.
648 *
649 * \param pSense: Pointer to the scsiRspSense_t sense data structure.
650 * \param SnsKey: SCSI Sense Key.
651 * \param SnsInfo: SCSI Sense Info.
652 * \param SnsCode: SCSI Sense Code.
653 *
654 * \return: None
655 */
656 /*****************************************************************************/
657
658 void satSetDeferredSensePayload( scsiRspSense_t *pSense,
659 bit8 SnsKey,
660 bit32 SnsInfo,
661 bit16 SnsCode,
662 satIOContext_t *satIOContext
663 )
664 {
665 /* for fixed format sense data, SPC-4, p37 */
666 bit32 i;
667 bit32 senseLength;
668
669 senseLength = sizeof(scsiRspSense_t);
670
671 /* zero out the data area */
672 for (i=0;i< senseLength;i++)
673 {
674 ((bit8*)pSense)[i] = 0;
675 }
676
677 /*
678 * SCSI Sense Data part of response data
679 */
680 pSense->snsRespCode = 0x71; /* 0xC0 == vendor specific */
681 /* 0x70 == standard current error */
682 pSense->senseKey = SnsKey;
683 /*
684 * Put sense info in scsi order format
685 */
686 pSense->info[0] = (bit8)((SnsInfo >> 24) & 0xff);
687 pSense->info[1] = (bit8)((SnsInfo >> 16) & 0xff);
688 pSense->info[2] = (bit8)((SnsInfo >> 8) & 0xff);
689 pSense->info[3] = (bit8)((SnsInfo) & 0xff);
690 pSense->addSenseLen = 11; /* fixed size of sense data = 18 */
691 pSense->addSenseCode = (bit8)((SnsCode >> 8) & 0xFF);
692 pSense->senseQual = (bit8)(SnsCode & 0xFF);
693 /*
694 * Set pointer in scsi status
695 */
696 switch(SnsKey)
697 {
698 /*
699 * set illegal request sense key specific error in cdb, no bit pointer
700 */
701 case SCSI_SNSKEY_ILLEGAL_REQUEST:
702 pSense->skeySpecific[0] = 0xC8;
703 break;
704
705 default:
706 break;
707 }
708
709 /* setting sense data length */
710 if (satIOContext != agNULL)
711 {
712 satIOContext->pTiSenseData->senseLen = 18;
713 }
714 else
715 {
716 TI_DBG1(("satSetDeferredSensePayload: satIOContext is NULL\n"));
717 }
718
719 }
720 /*****************************************************************************/
721 /*! \brief SAT implementation for ATAPI Packet Command.
722 *
723 * SAT implementation for ATAPI Packet and send FIS request to LL layer.
724 *
725 * \param tiRoot: Pointer to TISA initiator driver/port instance.
726 * \param tiIORequest: Pointer to TISA I/O request context for this I/O.
727 * \param tiDeviceHandle: Pointer to TISA device handle for this I/O.
728 * \param tiScsiRequest: Pointer to TISA SCSI I/O request and SGL list.
729 * \param satIOContext_t: Pointer to the SAT IO Context
730 *
731 * \return If command is started successfully
732 * - \e tiSuccess: I/O request successfully initiated.
733 * - \e tiBusy: No resources available, try again later.
734 * - \e tiIONoDevice: Invalid device handle.
735 * - \e tiError: Other errors.
736 */
737 /*****************************************************************************/
738 GLOBAL bit32 satPacket(
739 tiRoot_t *tiRoot,
740 tiIORequest_t *tiIORequest,
741 tiDeviceHandle_t *tiDeviceHandle,
742 tiScsiInitiatorRequest_t *tiScsiRequest,
743 satIOContext_t *satIOContext)
744 {
745 bit32 status;
746 bit32 agRequestType = AGSA_SATA_PROTOCOL_D2H_PKT;
747 satDeviceData_t *pSatDevData;
748 tiIniScsiCmnd_t *scsiCmnd;
749 agsaFisRegHostToDevice_t *fis;
750
751 pSatDevData = satIOContext->pSatDevData;
752 scsiCmnd = &tiScsiRequest->scsiCmnd;
753 fis = satIOContext->pFis;
754
755 TI_DBG3(("satPacket: start, SCSI CDB is 0x%X %X %X %X %X %X %X %X %X %X %X %X\n",
756 scsiCmnd->cdb[0],scsiCmnd->cdb[1],scsiCmnd->cdb[2],scsiCmnd->cdb[3],
757 scsiCmnd->cdb[4],scsiCmnd->cdb[5],scsiCmnd->cdb[6],scsiCmnd->cdb[7],
758 scsiCmnd->cdb[8],scsiCmnd->cdb[9],scsiCmnd->cdb[10],scsiCmnd->cdb[11]));
759
760 fis->h.fisType = 0x27; /* Reg host to device */
761 fis->h.c_pmPort = 0x80; /* C Bit is set 1*/
762 fis->h.command = SAT_PACKET; /* 0xA0 */
763 if (pSatDevData->satDMADIRSupport) /* DMADIR enabled*/
764 {
765 fis->h.features = (tiScsiRequest->dataDirection == tiDirectionIn)? 0x04 : 0; /* 1 for D2H, 0 for H2D */
766 }
767 else
768 {
769 fis->h.features = 0; /* FIS reserve */
770 }
771 /* Byte count low and byte count high */
772 if ( scsiCmnd->expDataLength > 0xFFFF )
773 {
774 fis->d.lbaMid = 0xFF; /* FIS LBA (7 :0 ) */
775 fis->d.lbaHigh = 0xFF; /* FIS LBA (15:8 ) */
776 }
777 else
778 {
779 fis->d.lbaMid = (bit8)scsiCmnd->expDataLength; /* FIS LBA (7 :0 ) */
780 fis->d.lbaHigh = (bit8)(scsiCmnd->expDataLength>>8); /* FIS LBA (15:8 ) */
781 }
782
783 fis->d.lbaLow = 0; /* FIS LBA (7 :0 ) */
784 fis->d.device = 0; /* FIS LBA (27:24) and FIS LBA mode */
785 fis->d.lbaLowExp = 0;
786 fis->d.lbaMidExp = 0;
787 fis->d.lbaHighExp = 0;
788 fis->d.featuresExp = 0;
789 fis->d.sectorCount = 0; /* FIS sector count (7:0) */
790 fis->d.sectorCountExp = 0;
791 fis->d.reserved4 = 0;
792 fis->d.control = 0; /* FIS HOB bit clear */
793 fis->d.reserved5 = 0;
794
795 satIOContext->ATACmd = SAT_PACKET;
796
797 if (tiScsiRequest->dataDirection == tiDirectionIn)
798 {
799 agRequestType = AGSA_SATA_PROTOCOL_D2H_PKT;
800 }
801 else
802 {
803 agRequestType = AGSA_SATA_PROTOCOL_H2D_PKT;
804 }
805
806 if (pSatDevData->satDMASupport == agTRUE && pSatDevData->satDMAEnabled == agTRUE)
807 {
808 /*DMA transfer mode*/
809 fis->h.features |= 0x01;
810 }
811 else
812 {
813 /*PIO transfer mode*/
814 fis->h.features |= 0x0;
815 }
816
817 satIOContext->satCompleteCB = &satPacketCB;
818
819 /*
820 * Prepare SGL and send FIS to LL layer.
821 */
822 satIOContext->reqType = agRequestType; /* Save it */
823
824 status = sataLLIOStart( tiRoot,
825 tiIORequest,
826 tiDeviceHandle,
827 tiScsiRequest,
828 satIOContext);
829
830 TI_DBG5(("satPacket: return\n"));
831 return (status);
832 }
833
834 /*****************************************************************************/
835 /*! \brief SAT implementation for satSetFeatures.
836 *
837 * This function creates SetFeatures fis and sends the request to LL layer
838 *
839 * \param tiRoot: Pointer to TISA initiator driver/port instance.
840 * \param tiIORequest: Pointer to TISA I/O request context for this I/O.
841 * \param tiDeviceHandle: Pointer to TISA device handle for this I/O.
842 * \param tiScsiRequest: Pointer to TISA SCSI I/O request and SGL list.
843 * \param satIOContext_t: Pointer to the SAT IO Context
844 *
845 * \return If command is started successfully
846 * - \e tiSuccess: I/O request successfully initiated.
847 * - \e tiBusy: No resources available, try again later.
848 * - \e tiIONoDevice: Invalid device handle.
849 * - \e tiError: Other errors.
850 */
851 /*****************************************************************************/
852 GLOBAL bit32 satSetFeatures(
853 tiRoot_t *tiRoot,
854 tiIORequest_t *tiIORequest,
855 tiDeviceHandle_t *tiDeviceHandle,
856 tiScsiInitiatorRequest_t *tiScsiRequest,
857 satIOContext_t *satIOContext,
858 bit8 bIsDMAMode
859 )
860 {
861 bit32 status;
862 bit32 agRequestType;
863 agsaFisRegHostToDevice_t *fis;
864
865 fis = satIOContext->pFis;
866 TI_DBG3(("satSetFeatures: start\n"));
867
868 /*
869 * Send the Set Features command.
870 */
871 fis->h.fisType = 0x27; /* Reg host to device */
872 fis->h.c_pmPort = 0x80; /* C Bit is set */
873 fis->h.command = SAT_SET_FEATURES; /* 0xEF */
874 fis->h.features = 0x03; /* set transfer mode */
875 fis->d.lbaLow = 0;
876 fis->d.lbaMid = 0;
877 fis->d.lbaHigh = 0;
878 fis->d.device = 0;
879 fis->d.lbaLowExp = 0;
880 fis->d.lbaMidExp = 0;
881 fis->d.lbaHighExp = 0;
882 fis->d.featuresExp = 0;
883 fis->d.sectorCountExp = 0;
884 fis->d.reserved4 = 0;
885 fis->d.control = 0; /* FIS HOB bit clear */
886 fis->d.reserved5 = 0;
887
888 agRequestType = AGSA_SATA_PROTOCOL_NON_DATA;
889
890 /* Initialize CB for SATA completion.
891 */
892 if (bIsDMAMode)
893 {
894 fis->d.sectorCount = 0x45;
895 /*satIOContext->satCompleteCB = &satSetFeaturesDMACB;*/
896 }
897 else
898 {
899 fis->d.sectorCount = 0x0C;
900 /*satIOContext->satCompleteCB = &satSetFeaturesPIOCB;*/
901 }
902 satIOContext->satCompleteCB = &satSetFeaturesCB;
903
904 /*
905 * Prepare SGL and send FIS to LL layer.
906 */
907 satIOContext->reqType = agRequestType; /* Save it */
908
909 status = sataLLIOStart( tiRoot,
910 tiIORequest,
911 tiDeviceHandle,
912 tiScsiRequest,
913 satIOContext);
914
915 TI_DBG5(("satSetFeatures: return\n"));
916
917 return status;
918 }
919 /*****************************************************************************/
920 /*! \brief SAT implementation for SCSI REQUEST SENSE to ATAPI device.
921 *
922 * SAT implementation for SCSI REQUEST SENSE.
923 *
924 * \param tiRoot: Pointer to TISA initiator driver/port instance.
925 * \param tiIORequest: Pointer to TISA I/O request context for this I/O.
926 * \param tiDeviceHandle: Pointer to TISA device handle for this I/O.
927 * \param tiScsiRequest: Pointer to TISA SCSI I/O request and SGL list.
928 * \param satIOContext_t: Pointer to the SAT IO Context
929 *
930 * \return If command is started successfully
931 * - \e tiSuccess: I/O request successfully initiated.
932 * - \e tiBusy: No resources available, try again later.
933 * - \e tiIONoDevice: Invalid device handle.
934 * - \e tiError: Other errors.
935 */
936 /*****************************************************************************/
937 GLOBAL bit32 satRequestSenseForATAPI(
938 tiRoot_t *tiRoot,
939 tiIORequest_t *tiIORequest,
940 tiDeviceHandle_t *tiDeviceHandle,
941 tiScsiInitiatorRequest_t *tiScsiRequest,
942 satIOContext_t *satIOContext)
943 {
944 bit32 status;
945 bit32 agRequestType = AGSA_SATA_PROTOCOL_D2H_PKT;
946 satDeviceData_t *pSatDevData;
947 tiIniScsiCmnd_t *scsiCmnd;
948 agsaFisRegHostToDevice_t *fis;
949
950 pSatDevData = satIOContext->pSatDevData;
951 scsiCmnd = &tiScsiRequest->scsiCmnd;
952 fis = satIOContext->pFis;
953
954 scsiCmnd->cdb[0] = SCSIOPC_REQUEST_SENSE;
955 scsiCmnd->cdb[1] = 0;
956 scsiCmnd->cdb[2] = 0;
957 scsiCmnd->cdb[3] = 0;
958 scsiCmnd->cdb[4] = SENSE_DATA_LENGTH;
959 scsiCmnd->cdb[5] = 0;
960 TI_DBG3(("satRequestSenseForATAPI: start, SCSI CDB is 0x%X %X %X %X %X %X %X %X %X %X %X %X\n",
961 scsiCmnd->cdb[0],scsiCmnd->cdb[1],scsiCmnd->cdb[2],scsiCmnd->cdb[3],
962 scsiCmnd->cdb[4],scsiCmnd->cdb[5],scsiCmnd->cdb[6],scsiCmnd->cdb[7],
963 scsiCmnd->cdb[8],scsiCmnd->cdb[9],scsiCmnd->cdb[10],scsiCmnd->cdb[11]));
964
965 fis->h.fisType = 0x27; /* Reg host to device */
966 fis->h.c_pmPort = 0x80; /* C Bit is set 1*/
967 fis->h.command = SAT_PACKET; /* 0xA0 */
968 if (pSatDevData->satDMADIRSupport) /* DMADIR enabled*/
969 {
970 fis->h.features = (tiScsiRequest->dataDirection == tiDirectionIn)? 0x04 : 0; /* 1 for D2H, 0 for H2D */
971 }
972 else
973 {
974 fis->h.features = 0; /* FIS reserve */
975 }
976
977 fis->d.lbaLow = 0; /* FIS LBA (7 :0 ) */
978 fis->d.lbaMid = 0; /* FIS LBA (15:8 ) */
979 fis->d.lbaHigh = 0x20; /* FIS LBA (23:16) */
980 fis->d.device = 0; /* FIS LBA (27:24) and FIS LBA mode */
981 fis->d.lbaLowExp = 0;
982 fis->d.lbaMidExp = 0;
983 fis->d.lbaHighExp = 0;
984 fis->d.featuresExp = 0;
985 fis->d.sectorCount = 0; /* FIS sector count (7:0) */
986 fis->d.sectorCountExp = 0;
987 fis->d.reserved4 = 0;
988 fis->d.control = 0; /* FIS HOB bit clear */
989 fis->d.reserved5 = (bit32)(scsiCmnd->cdb[0]|(scsiCmnd->cdb[1]<<8)|(scsiCmnd->cdb[2]<<16)|(scsiCmnd->cdb[3]<<24));
990
991 satIOContext->ATACmd = SAT_PACKET;
992
993 agRequestType = AGSA_SATA_PROTOCOL_D2H_PKT;
994
995 //if (pSatDevData->sat48BitSupport == agTRUE)
996 {
997 if (pSatDevData->satDMASupport == agTRUE && pSatDevData->satDMAEnabled == agTRUE)
998 {
999 fis->h.features |= 0x01;
1000 }
1001 else
1002 {
1003 fis->h.features |= 0x0;
1004 }
1005 }
1006
1007 satIOContext->satCompleteCB = &satRequestSenseForATAPICB;
1008
1009 /*
1010 * Prepare SGL and send FIS to LL layer.
1011 */
1012 satIOContext->reqType = agRequestType; /* Save it */
1013
1014 status = sataLLIOStart( tiRoot,
1015 tiIORequest,
1016 tiDeviceHandle,
1017 tiScsiRequest,
1018 satIOContext);
1019
1020 TI_DBG5(("satRequestSenseForATAPI: return\n"));
1021 return (status);
1022 }
1023 /*****************************************************************************/
1024 /*! \brief SAT implementation for satDeviceReset.
1025 *
1026 * This function creates DEVICE RESET fis and sends the request to LL layer
1027 *
1028 * \param tiRoot: Pointer to TISA initiator driver/port instance.
1029 * \param tiIORequest: Pointer to TISA I/O request context for this I/O.
1030 * \param tiDeviceHandle: Pointer to TISA device handle for this I/O.
1031 * \param tiScsiRequest: Pointer to TISA SCSI I/O request and SGL list.
1032 * \param satIOContext_t: Pointer to the SAT IO Context
1033 *
1034 * \return If command is started successfully
1035 * - \e tiSuccess: I/O request successfully initiated.
1036 * - \e tiBusy: No resources available, try again later.
1037 * - \e tiIONoDevice: Invalid device handle.
1038 * - \e tiError: Other errors.
1039 */
1040 /*****************************************************************************/
1041 GLOBAL bit32 satDeviceReset(
1042 tiRoot_t *tiRoot,
1043 tiIORequest_t *tiIORequest,
1044 tiDeviceHandle_t *tiDeviceHandle,
1045 tiScsiInitiatorRequest_t *tiScsiRequest,
1046 satIOContext_t *satIOContext
1047 )
1048 {
1049 bit32 status;
1050 bit32 agRequestType;
1051 agsaFisRegHostToDevice_t *fis;
1052
1053 fis = satIOContext->pFis;
1054
1055 TI_DBG3(("satDeviceReset: start\n"));
1056
1057 /*
1058 * Send the Execute Device Diagnostic command.
1059 */
1060 fis->h.fisType = 0x27; /* Reg host to device */
1061 fis->h.c_pmPort = 0x80; /* C Bit is set */
1062 fis->h.command = SAT_DEVICE_RESET; /* 0x90 */
1063 fis->h.features = 0;
1064 fis->d.lbaLow = 0;
1065 fis->d.lbaMid = 0;
1066 fis->d.lbaHigh = 0;
1067 fis->d.device = 0;
1068 fis->d.lbaLowExp = 0;
1069 fis->d.lbaMidExp = 0;
1070 fis->d.lbaHighExp = 0;
1071 fis->d.featuresExp = 0;
1072 fis->d.sectorCount = 0;
1073 fis->d.sectorCountExp = 0;
1074 fis->d.reserved4 = 0;
1075 fis->d.control = 0; /* FIS HOB bit clear */
1076 fis->d.reserved5 = 0;
1077
1078 agRequestType = AGSA_SATA_PROTOCOL_DEV_RESET;
1079
1080 /* Initialize CB for SATA completion.
1081 */
1082 satIOContext->satCompleteCB = &satDeviceResetCB;
1083
1084 /*
1085 * Prepare SGL and send FIS to LL layer.
1086 */
1087 satIOContext->reqType = agRequestType; /* Save it */
1088
1089 status = sataLLIOStart( tiRoot,
1090 tiIORequest,
1091 tiDeviceHandle,
1092 tiScsiRequest,
1093 satIOContext);
1094
1095 TI_DBG3(("satDeviceReset: return\n"));
1096
1097 return status;
1098 }
1099
1100 /*****************************************************************************/
1101 /*! \brief SAT implementation for saExecuteDeviceDiagnostic.
1102 *
1103 * This function creates Execute Device Diagnostic fis and sends the request to LL layer
1104 *
1105 * \param tiRoot: Pointer to TISA initiator driver/port instance.
1106 * \param tiIORequest: Pointer to TISA I/O request context for this I/O.
1107 * \param tiDeviceHandle: Pointer to TISA device handle for this I/O.
1108 * \param tiScsiRequest: Pointer to TISA SCSI I/O request and SGL list.
1109 * \param satIOContext_t: Pointer to the SAT IO Context
1110 *
1111 * \return If command is started successfully
1112 * - \e tiSuccess: I/O request successfully initiated.
1113 * - \e tiBusy: No resources available, try again later.
1114 * - \e tiIONoDevice: Invalid device handle.
1115 * - \e tiError: Other errors.
1116 */
1117 /*****************************************************************************/
1118 GLOBAL bit32 satExecuteDeviceDiagnostic(
1119 tiRoot_t *tiRoot,
1120 tiIORequest_t *tiIORequest,
1121 tiDeviceHandle_t *tiDeviceHandle,
1122 tiScsiInitiatorRequest_t *tiScsiRequest,
1123 satIOContext_t *satIOContext
1124 )
1125 {
1126 bit32 status;
1127 bit32 agRequestType;
1128 agsaFisRegHostToDevice_t *fis;
1129
1130 fis = satIOContext->pFis;
1131
1132 TI_DBG3(("satExecuteDeviceDiagnostic: start\n"));
1133
1134 /*
1135 * Send the Execute Device Diagnostic command.
1136 */
1137 fis->h.fisType = 0x27; /* Reg host to device */
1138 fis->h.c_pmPort = 0x80; /* C Bit is set */
1139 fis->h.command = SAT_EXECUTE_DEVICE_DIAGNOSTIC; /* 0x90 */
1140 fis->h.features = 0;
1141 fis->d.lbaLow = 0;
1142 fis->d.lbaMid = 0;
1143 fis->d.lbaHigh = 0;
1144 fis->d.device = 0;
1145 fis->d.lbaLowExp = 0;
1146 fis->d.lbaMidExp = 0;
1147 fis->d.lbaHighExp = 0;
1148 fis->d.featuresExp = 0;
1149 fis->d.sectorCount = 0;
1150 fis->d.sectorCountExp = 0;
1151 fis->d.reserved4 = 0;
1152 fis->d.control = 0; /* FIS HOB bit clear */
1153 fis->d.reserved5 = 0;
1154
1155 agRequestType = AGSA_SATA_PROTOCOL_NON_DATA;
1156
1157 /* Initialize CB for SATA completion.
1158 */
1159 satIOContext->satCompleteCB = &satExecuteDeviceDiagnosticCB;
1160
1161 /*
1162 * Prepare SGL and send FIS to LL layer.
1163 */
1164 satIOContext->reqType = agRequestType; /* Save it */
1165
1166 status = sataLLIOStart( tiRoot,
1167 tiIORequest,
1168 tiDeviceHandle,
1169 tiScsiRequest,
1170 satIOContext);
1171
1172 TI_DBG5(("satExecuteDeviceDiagnostic: return\n"));
1173
1174 return status;
1175 }
1176
1177
1178 /*****************************************************************************/
1179 /*! \brief SAT implementation for SCSI READ10.
1180 *
1181 * SAT implementation for SCSI READ10 and send FIS request to LL layer.
1182 *
1183 * \param tiRoot: Pointer to TISA initiator driver/port instance.
1184 * \param tiIORequest: Pointer to TISA I/O request context for this I/O.
1185 * \param tiDeviceHandle: Pointer to TISA device handle for this I/O.
1186 * \param tiScsiRequest: Pointer to TISA SCSI I/O request and SGL list.
1187 * \param satIOContext_t: Pointer to the SAT IO Context
1188 *
1189 * \return If command is started successfully
1190 * - \e tiSuccess: I/O request successfully initiated.
1191 * - \e tiBusy: No resources available, try again later.
1192 * - \e tiIONoDevice: Invalid device handle.
1193 * - \e tiError: Other errors.
1194 */
1195 /*****************************************************************************/
1196 GLOBAL bit32 satRead10(
1197 tiRoot_t *tiRoot,
1198 tiIORequest_t *tiIORequest,
1199 tiDeviceHandle_t *tiDeviceHandle,
1200 tiScsiInitiatorRequest_t *tiScsiRequest,
1201 satIOContext_t *satIOContext)
1202 {
1203
1204 bit32 status;
1205 bit32 agRequestType = AGSA_SATA_PROTOCOL_DMA_READ;
1206 satDeviceData_t *pSatDevData;
1207 scsiRspSense_t *pSense;
1208 tiIniScsiCmnd_t *scsiCmnd;
1209 agsaFisRegHostToDevice_t *fis;
1210 bit32 lba = 0;
1211 bit32 tl = 0;
1212 bit32 LoopNum = 1;
1213 bit8 LBA[4];
1214 bit8 TL[4];
1215 bit32 rangeChk = agFALSE; /* lba and tl range check */
1216
1217 pSense = satIOContext->pSense;
1218 pSatDevData = satIOContext->pSatDevData;
1219 scsiCmnd = &tiScsiRequest->scsiCmnd;
1220 fis = satIOContext->pFis;
1221
1222 TI_DBG5(("satRead10: start\n"));
1223 TI_DBG5(("satRead10: pSatDevData=%p\n", pSatDevData));
1224 // tdhexdump("satRead10", (bit8 *)scsiCmnd->cdb, 10);
1225
1226 /* checking FUA_NV */
1227 if (scsiCmnd->cdb[1] & SCSI_FUA_NV_MASK)
1228 {
1229 satSetSensePayload( pSense,
1230 SCSI_SNSKEY_ILLEGAL_REQUEST,
1231 0,
1232 SCSI_SNSCODE_INVALID_FIELD_IN_CDB,
1233 satIOContext);
1234
1235 ostiInitiatorIOCompleted( tiRoot,
1236 tiIORequest,
1237 tiIOSuccess,
1238 SCSI_STAT_CHECK_CONDITION,
1239 satIOContext->pTiSenseData,
1240 satIOContext->interruptContext );
1241
1242 TI_DBG1(("satRead10: return FUA_NV\n"));
1243 return tiSuccess;
1244
1245 }
1246
1247 /* checking CONTROL */
1248 /* NACA == 1 or LINK == 1*/
1249 if ( (scsiCmnd->cdb[9] & SCSI_NACA_MASK) || (scsiCmnd->cdb[9] & SCSI_LINK_MASK) )
1250 {
1251 satSetSensePayload( pSense,
1252 SCSI_SNSKEY_ILLEGAL_REQUEST,
1253 0,
1254 SCSI_SNSCODE_INVALID_FIELD_IN_CDB,
1255 satIOContext);
1256
1257 ostiInitiatorIOCompleted( tiRoot,
1258 tiIORequest,
1259 tiIOSuccess,
1260 SCSI_STAT_CHECK_CONDITION,
1261 satIOContext->pTiSenseData,
1262 satIOContext->interruptContext );
1263
1264 TI_DBG1(("satRead10: return control\n"));
1265 return tiSuccess;
1266 }
1267
1268 osti_memset(LBA, 0, sizeof(LBA));
1269 osti_memset(TL, 0, sizeof(TL));
1270
1271 /* do not use memcpy due to indexing in LBA and TL */
1272 LBA[0] = scsiCmnd->cdb[2]; /* MSB */
1273 LBA[1] = scsiCmnd->cdb[3];
1274 LBA[2] = scsiCmnd->cdb[4];
1275 LBA[3] = scsiCmnd->cdb[5]; /* LSB */
1276
1277 TL[0] = 0;
1278 TL[1] = 0;
1279 TL[2] = scsiCmnd->cdb[7]; /* MSB */
1280 TL[3] = scsiCmnd->cdb[8]; /* LSB */
1281
1282 rangeChk = satAddNComparebit32(LBA, TL);
1283
1284 /* cbd10; computing LBA and transfer length */
1285 lba = (scsiCmnd->cdb[2] << (8*3)) + (scsiCmnd->cdb[3] << (8*2))
1286 + (scsiCmnd->cdb[4] << 8) + scsiCmnd->cdb[5];
1287 tl = (scsiCmnd->cdb[7] << 8) + scsiCmnd->cdb[8];
1288
1289
1290 TI_DBG5(("satRead10: lba %d functioned lba %d\n", lba, satComputeCDB10LBA(satIOContext)));
1291 TI_DBG5(("satRead10: lba 0x%x functioned lba 0x%x\n", lba, satComputeCDB10LBA(satIOContext)));
1292 TI_DBG5(("satRead10: tl %d functioned tl %d\n", tl, satComputeCDB10TL(satIOContext)));
1293
1294 /* Table 34, 9.1, p 46 */
1295 /*
1296 note: As of 2/10/2006, no support for DMA QUEUED
1297 */
1298
1299 /*
1300 Table 34, 9.1, p 46, b
1301 When no 48-bit addressing support or NCQ, if LBA is beyond (2^28 - 1),
1302 return check condition
1303 */
1304
1305 if (pSatDevData->satNCQ != agTRUE &&
1306 pSatDevData->sat48BitSupport != agTRUE
1307 )
1308 {
1309 if (lba > SAT_TR_LBA_LIMIT - 1)
1310 {
1311 TI_DBG1(("satRead10: return LBA out of range, not EXT\n"));
1312 satSetSensePayload( pSense,
1313 SCSI_SNSKEY_ILLEGAL_REQUEST,
1314 0,
1315 SCSI_SNSCODE_LOGICAL_BLOCK_ADDRESS_OUT_OF_RANGE,
1316 satIOContext);
1317
1318 ostiInitiatorIOCompleted( tiRoot,
1319 tiIORequest,
1320 tiIOSuccess,
1321 SCSI_STAT_CHECK_CONDITION,
1322 satIOContext->pTiSenseData,
1323 satIOContext->interruptContext );
1324
1325 return tiSuccess;
1326 }
1327
1328
1329 if (rangeChk) // if (lba + tl > SAT_TR_LBA_LIMIT)
1330 {
1331 TI_DBG1(("satRead10: return LBA+TL out of range, not EXT\n"));
1332 satSetSensePayload( pSense,
1333 SCSI_SNSKEY_ILLEGAL_REQUEST,
1334 0,
1335 SCSI_SNSCODE_LOGICAL_BLOCK_ADDRESS_OUT_OF_RANGE,
1336 satIOContext);
1337
1338 ostiInitiatorIOCompleted( tiRoot,
1339 tiIORequest,
1340 tiIOSuccess,
1341 SCSI_STAT_CHECK_CONDITION,
1342 satIOContext->pTiSenseData,
1343 satIOContext->interruptContext );
1344
1345 return tiSuccess;
1346 }
1347 }
1348
1349 /* case 1 and 2 */
1350 if (!rangeChk) // if (lba + tl <= SAT_TR_LBA_LIMIT)
1351 {
1352 if (pSatDevData->satDMASupport == agTRUE && pSatDevData->satDMAEnabled == agTRUE)
1353 {
1354 /* case 2 */
1355 /* READ DMA*/
1356 /* in case that we can't fit the transfer length,
1357 we need to make it fit by sending multiple ATA cmnds */
1358 TI_DBG5(("satRead10: case 2\n"));
1359
1360
1361 fis->h.fisType = 0x27; /* Reg host to device */
1362 fis->h.c_pmPort = 0x80; /* C Bit is set */
1363 fis->h.command = SAT_READ_DMA; /* 0xC8 */
1364 fis->h.features = 0; /* FIS reserve */
1365 fis->d.lbaLow = scsiCmnd->cdb[5]; /* FIS LBA (7 :0 ) */
1366 fis->d.lbaMid = scsiCmnd->cdb[4]; /* FIS LBA (15:8 ) */
1367 fis->d.lbaHigh = scsiCmnd->cdb[3]; /* FIS LBA (23:16) */
1368 fis->d.device =
1369 (bit8)((0x4 << 4) | (scsiCmnd->cdb[2] & 0xF)); /* FIS LBA (27:24) and FIS LBA mode */
1370 fis->d.lbaLowExp = 0;
1371 fis->d.lbaMidExp = 0;
1372 fis->d.lbaHighExp = 0;
1373 fis->d.featuresExp = 0;
1374 fis->d.sectorCount = scsiCmnd->cdb[8]; /* FIS sector count (7:0) */
1375 fis->d.sectorCountExp = 0;
1376 fis->d.reserved4 = 0;
1377 fis->d.control = 0; /* FIS HOB bit clear */
1378 fis->d.reserved5 = 0;
1379
1380
1381 agRequestType = AGSA_SATA_PROTOCOL_DMA_READ;
1382 satIOContext->ATACmd = SAT_READ_DMA;
1383 }
1384 else
1385 {
1386 /* case 1 */
1387 /* READ MULTIPLE or READ SECTOR(S) */
1388 /* READ SECTORS for easier implemetation */
1389 /* in case that we can't fit the transfer length,
1390 we need to make it fit by sending multiple ATA cmnds */
1391 TI_DBG5(("satRead10: case 1\n"));
1392
1393 fis->h.fisType = 0x27; /* Reg host to device */
1394 fis->h.c_pmPort = 0x80; /* C Bit is set */
1395 fis->h.command = SAT_READ_SECTORS; /* 0x20 */
1396 fis->h.features = 0; /* FIS reserve */
1397 fis->d.lbaLow = scsiCmnd->cdb[5]; /* FIS LBA (7 :0 ) */
1398 fis->d.lbaMid = scsiCmnd->cdb[4]; /* FIS LBA (15:8 ) */
1399 fis->d.lbaHigh = scsiCmnd->cdb[3]; /* FIS LBA (23:16) */
1400 fis->d.device =
1401 (bit8)((0x4 << 4) | (scsiCmnd->cdb[2] & 0xF)); /* FIS LBA (27:24) and FIS LBA mode */
1402 fis->d.lbaLowExp = 0;
1403 fis->d.lbaMidExp = 0;
1404 fis->d.lbaHighExp = 0;
1405 fis->d.featuresExp = 0;
1406 fis->d.sectorCount = scsiCmnd->cdb[8]; /* FIS sector count (7:0) */
1407 fis->d.sectorCountExp = 0;
1408 fis->d.reserved4 = 0;
1409 fis->d.control = 0; /* FIS HOB bit clear */
1410 fis->d.reserved5 = 0;
1411
1412
1413 agRequestType = AGSA_SATA_PROTOCOL_PIO_READ;
1414 satIOContext->ATACmd = SAT_READ_SECTORS;
1415 }
1416 }
1417
1418 /* case 3 and 4 */
1419 if (pSatDevData->sat48BitSupport == agTRUE)
1420 {
1421 if (pSatDevData->satDMASupport == agTRUE && pSatDevData->satDMAEnabled == agTRUE)
1422 {
1423 /* case 3 */
1424 /* READ DMA EXT */
1425 TI_DBG5(("satRead10: case 3\n"));
1426 fis->h.fisType = 0x27; /* Reg host to device */
1427
1428 fis->h.c_pmPort = 0x80; /* C Bit is set */
1429 fis->h.command = SAT_READ_DMA_EXT; /* 0x25 */
1430 fis->h.features = 0; /* FIS reserve */
1431 fis->d.lbaLow = scsiCmnd->cdb[5]; /* FIS LBA (7 :0 ) */
1432 fis->d.lbaMid = scsiCmnd->cdb[4]; /* FIS LBA (15:8 ) */
1433 fis->d.lbaHigh = scsiCmnd->cdb[3]; /* FIS LBA (23:16) */
1434 fis->d.device = 0x40; /* FIS LBA mode set */
1435 fis->d.lbaLowExp = scsiCmnd->cdb[2]; /* FIS LBA (31:24) */
1436 fis->d.lbaMidExp = 0; /* FIS LBA (39:32) */
1437 fis->d.lbaHighExp = 0; /* FIS LBA (47:40) */
1438 fis->d.featuresExp = 0; /* FIS reserve */
1439 fis->d.sectorCount = scsiCmnd->cdb[8]; /* FIS sector count (7:0) */
1440 fis->d.sectorCountExp = scsiCmnd->cdb[7]; /* FIS sector count (15:8) */
1441 fis->d.reserved4 = 0;
1442 fis->d.control = 0; /* FIS HOB bit clear */
1443 fis->d.reserved5 = 0;
1444
1445 agRequestType = AGSA_SATA_PROTOCOL_DMA_READ;
1446 satIOContext->ATACmd = SAT_READ_DMA_EXT;
1447
1448 }
1449 else
1450 {
1451 /* case 4 */
1452 /* READ MULTIPLE EXT or READ SECTOR(S) EXT or READ VERIFY SECTOR(S) EXT*/
1453 /* READ SECTORS EXT for easier implemetation */
1454 TI_DBG5(("satRead10: case 4\n"));
1455 fis->h.fisType = 0x27; /* Reg host to device */
1456 fis->h.c_pmPort = 0x80; /* C Bit is set */
1457
1458 /* Check FUA bit */
1459 if (scsiCmnd->cdb[1] & SCSI_READ10_FUA_MASK)
1460 {
1461
1462 /* for now, no support for FUA */
1463 satSetSensePayload( pSense,
1464 SCSI_SNSKEY_ILLEGAL_REQUEST,
1465 0,
1466 SCSI_SNSCODE_INVALID_FIELD_IN_CDB,
1467 satIOContext);
1468
1469 ostiInitiatorIOCompleted( tiRoot,
1470 tiIORequest,
1471 tiIOSuccess,
1472 SCSI_STAT_CHECK_CONDITION,
1473 satIOContext->pTiSenseData,
1474 satIOContext->interruptContext );
1475 return tiSuccess;
1476 }
1477
1478 fis->h.command = SAT_READ_SECTORS_EXT; /* 0x24 */
1479
1480 fis->h.features = 0; /* FIS reserve */
1481 fis->d.lbaLow = scsiCmnd->cdb[5]; /* FIS LBA (7 :0 ) */
1482 fis->d.lbaMid = scsiCmnd->cdb[4]; /* FIS LBA (15:8 ) */
1483 fis->d.lbaHigh = scsiCmnd->cdb[3]; /* FIS LBA (23:16) */
1484 fis->d.device = 0x40; /* FIS LBA mode set */
1485 fis->d.lbaLowExp = scsiCmnd->cdb[2]; /* FIS LBA (31:24) */
1486 fis->d.lbaMidExp = 0; /* FIS LBA (39:32) */
1487 fis->d.lbaHighExp = 0; /* FIS LBA (47:40) */
1488 fis->d.featuresExp = 0; /* FIS reserve */
1489 fis->d.sectorCount = scsiCmnd->cdb[8]; /* FIS sector count (7:0) */
1490 fis->d.sectorCountExp = scsiCmnd->cdb[7]; /* FIS sector count (15:8) */
1491 fis->d.reserved4 = 0;
1492 fis->d.control = 0; /* FIS HOB bit clear */
1493 fis->d.reserved5 = 0;
1494
1495 agRequestType = AGSA_SATA_PROTOCOL_PIO_READ;
1496 satIOContext->ATACmd = SAT_READ_SECTORS_EXT;
1497 }
1498 }
1499
1500 /* case 5 */
1501 if (pSatDevData->satNCQ == agTRUE)
1502 {
1503 /* READ FPDMA QUEUED */
1504 if (pSatDevData->sat48BitSupport != agTRUE)
1505 {
1506 TI_DBG5(("satRead10: case 5 !!! error NCQ but 28 bit address support \n"));
1507 satSetSensePayload( pSense,
1508 SCSI_SNSKEY_ILLEGAL_REQUEST,
1509 0,
1510 SCSI_SNSCODE_INVALID_FIELD_IN_CDB,
1511 satIOContext);
1512
1513 ostiInitiatorIOCompleted( tiRoot,
1514 tiIORequest,
1515 tiIOSuccess,
1516 SCSI_STAT_CHECK_CONDITION,
1517 satIOContext->pTiSenseData,
1518 satIOContext->interruptContext );
1519 return tiSuccess;
1520 }
1521
1522 TI_DBG6(("satRead10: case 5\n"));
1523
1524 /* Support 48-bit FPDMA addressing, use READ FPDMA QUEUE command */
1525
1526 fis->h.fisType = 0x27; /* Reg host to device */
1527 fis->h.c_pmPort = 0x80; /* C Bit is set */
1528 fis->h.command = SAT_READ_FPDMA_QUEUED; /* 0x60 */
1529 fis->h.features = scsiCmnd->cdb[8]; /* FIS sector count (7:0) */
1530 fis->d.lbaLow = scsiCmnd->cdb[5]; /* FIS LBA (7 :0 ) */
1531 fis->d.lbaMid = scsiCmnd->cdb[4]; /* FIS LBA (15:8 ) */
1532 fis->d.lbaHigh = scsiCmnd->cdb[3]; /* FIS LBA (23:16) */
1533
1534 /* Check FUA bit */
1535 if (scsiCmnd->cdb[1] & SCSI_READ10_FUA_MASK)
1536 fis->d.device = 0xC0; /* FIS FUA set */
1537 else
1538 fis->d.device = 0x40; /* FIS FUA clear */
1539
1540 fis->d.lbaLowExp = scsiCmnd->cdb[2]; /* FIS LBA (31:24) */
1541 fis->d.lbaMidExp = 0; /* FIS LBA (39:32) */
1542 fis->d.lbaHighExp = 0; /* FIS LBA (47:40) */
1543 fis->d.featuresExp = scsiCmnd->cdb[7]; /* FIS sector count (15:8) */
1544 fis->d.sectorCount = 0; /* Tag (7:3) set by LL layer */
1545 fis->d.sectorCountExp = 0;
1546 fis->d.reserved4 = 0;
1547 fis->d.control = 0; /* FIS HOB bit clear */
1548 fis->d.reserved5 = 0;
1549
1550 agRequestType = AGSA_SATA_PROTOCOL_FPDMA_READ;
1551 satIOContext->ATACmd = SAT_READ_FPDMA_QUEUED;
1552 }
1553
1554
1555 // tdhexdump("satRead10 final fis", (bit8 *)fis, sizeof(agsaFisRegHostToDevice_t));
1556
1557 /* saves the current LBA and orginal TL */
1558 satIOContext->currentLBA = lba;
1559 satIOContext->OrgTL = tl;
1560
1561 /*
1562 computing number of loop and remainder for tl
1563 0xFF in case not ext
1564 0xFFFF in case EXT
1565 */
1566 if (fis->h.command == SAT_READ_SECTORS || fis->h.command == SAT_READ_DMA)
1567 {
1568 LoopNum = satComputeLoopNum(tl, 0xFF);
1569 }
1570 else if (fis->h.command == SAT_READ_SECTORS_EXT || fis->h.command == SAT_READ_DMA_EXT)
1571 {
1572 /* SAT_READ_SECTORS_EXT, SAT_READ_DMA_EXT */
1573 LoopNum = satComputeLoopNum(tl, 0xFFFF);
1574 }
1575 else
1576 {
1577 /* SAT_READ_FPDMA_QUEUED */
1578 LoopNum = satComputeLoopNum(tl, 0xFFFF);
1579 }
1580
1581 satIOContext->LoopNum = LoopNum;
1582
1583 /* Initialize CB for SATA completion.
1584 */
1585 if (LoopNum == 1)
1586 {
1587 TI_DBG5(("satRead10: NON CHAINED data\n"));
1588 satIOContext->satCompleteCB = &satNonChainedDataIOCB;
1589 }
1590 else
1591 {
1592 TI_DBG1(("satRead10: CHAINED data\n"));
1593 /* re-setting tl */
1594 if (fis->h.command == SAT_READ_SECTORS || fis->h.command == SAT_READ_DMA)
1595 {
1596 fis->d.sectorCount = 0xFF;
1597 }
1598 else if (fis->h.command == SAT_READ_SECTORS_EXT || fis->h.command == SAT_READ_DMA_EXT)
1599 {
1600 /* SAT_READ_SECTORS_EXT, SAT_READ_DMA_EXT */
1601 fis->d.sectorCount = 0xFF;
1602 fis->d.sectorCountExp = 0xFF;
1603 }
1604 else
1605 {
1606 /* SAT_READ_FPDMA_QUEUED */
1607 fis->h.features = 0xFF;
1608 fis->d.featuresExp = 0xFF;
1609 }
1610
1611 /* chained data */
1612 satIOContext->satCompleteCB = &satChainedDataIOCB;
1613
1614 }
1615
1616 /*
1617 * Prepare SGL and send FIS to LL layer.
1618 */
1619 satIOContext->reqType = agRequestType; /* Save it */
1620
1621 status = sataLLIOStart( tiRoot,
1622 tiIORequest,
1623 tiDeviceHandle,
1624 tiScsiRequest,
1625 satIOContext);
1626
1627 TI_DBG5(("satRead10: return\n"));
1628 return (status);
1629
1630 }
1631
1632
1633 /*****************************************************************************/
1634 /*! \brief SAT implementation for SCSI satRead_1.
1635 *
1636 * SAT implementation for SCSI satRead_1
1637 * Sub function of satRead10
1638 *
1639 * \param tiRoot: Pointer to TISA initiator driver/port instance.
1640 * \param tiIORequest: Pointer to TISA I/O request context for this I/O.
1641 * \param tiDeviceHandle: Pointer to TISA device handle for this I/O.
1642 * \param tiScsiRequest: Pointer to TISA SCSI I/O request and SGL list.
1643 * \param satIOContext_t: Pointer to the SAT IO Context
1644 *
1645 * \return If command is started successfully
1646 * - \e tiSuccess: I/O request successfully initiated.
1647 * - \e tiBusy: No resources available, try again later.
1648 * - \e tiIONoDevice: Invalid device handle.
1649 * - \e tiError: Other errors.
1650 */
1651 /*****************************************************************************/
1652 /*
1653 * as a part of loop for read10
1654 */
1655 GLOBAL bit32 satRead_1(
1656 tiRoot_t *tiRoot,
1657 tiIORequest_t *tiIORequest,
1658 tiDeviceHandle_t *tiDeviceHandle,
1659 tiScsiInitiatorRequest_t *tiScsiRequest,
1660 satIOContext_t *satIOContext)
1661 {
1662 /*
1663 Assumption: error check on lba and tl has been done in satRead*()
1664 lba = lba + tl;
1665 */
1666 bit32 status;
1667 satIOContext_t *satOrgIOContext = agNULL;
1668 tiIniScsiCmnd_t *scsiCmnd;
1669 agsaFisRegHostToDevice_t *fis;
1670 bit32 agRequestType = AGSA_SATA_PROTOCOL_DMA_READ;
1671 bit32 lba = 0;
1672 bit32 DenomTL = 0xFF;
1673 bit32 Remainder = 0;
1674 bit8 LBA[4]; /* 0 MSB, 3 LSB */
1675
1676 TI_DBG2(("satRead_1: start\n"));
1677
1678 fis = satIOContext->pFis;
1679 satOrgIOContext = satIOContext->satOrgIOContext;
1680 scsiCmnd = satOrgIOContext->pScsiCmnd;
1681
1682 osti_memset(LBA,0, sizeof(LBA));
1683
1684 switch (satOrgIOContext->ATACmd)
1685 {
1686 case SAT_READ_DMA:
1687 DenomTL = 0xFF;
1688 break;
1689 case SAT_READ_SECTORS:
1690 DenomTL = 0xFF;
1691 break;
1692 case SAT_READ_DMA_EXT:
1693 DenomTL = 0xFFFF;
1694 break;
1695 case SAT_READ_SECTORS_EXT:
1696 DenomTL = 0xFFFF;
1697 break;
1698 case SAT_READ_FPDMA_QUEUED:
1699 DenomTL = 0xFFFF;
1700 break;
1701 default:
1702 TI_DBG1(("satRead_1: error incorrect ata command 0x%x\n", satIOContext->ATACmd));
1703 return tiError;
1704 break;
1705 }
1706
1707 Remainder = satOrgIOContext->OrgTL % DenomTL;
1708 satOrgIOContext->currentLBA = satOrgIOContext->currentLBA + DenomTL;
1709 lba = satOrgIOContext->currentLBA;
1710
1711 LBA[0] = (bit8)((lba & 0xF000) >> (8 * 3));
1712 LBA[1] = (bit8)((lba & 0xF00) >> (8 * 2));
1713 LBA[2] = (bit8)((lba & 0xF0) >> 8);
1714 LBA[3] = (bit8)(lba & 0xF);
1715
1716
1717 switch (satOrgIOContext->ATACmd)
1718 {
1719 case SAT_READ_DMA:
1720 fis->h.fisType = 0x27; /* Reg host to device */
1721 fis->h.c_pmPort = 0x80; /* C Bit is set */
1722 fis->h.command = SAT_READ_DMA; /* 0xC8 */
1723 fis->h.features = 0; /* FIS reserve */
1724 fis->d.lbaLow = LBA[3]; /* FIS LBA (7 :0 ) */
1725 fis->d.lbaMid = LBA[2]; /* FIS LBA (15:8 ) */
1726 fis->d.lbaHigh = LBA[1]; /* FIS LBA (23:16) */
1727 fis->d.device =
1728 (bit8)((0x4 << 4) | (LBA[0] & 0xF)); /* FIS LBA (27:24) and FIS LBA mode */
1729 fis->d.lbaLowExp = 0;
1730 fis->d.lbaMidExp = 0;
1731 fis->d.lbaHighExp = 0;
1732 fis->d.featuresExp = 0;
1733
1734 if (satOrgIOContext->LoopNum == 1)
1735 {
1736 /* last loop */
1737 fis->d.sectorCount = (bit8)Remainder; /* FIS sector count (7:0) */
1738 }
1739 else
1740 {
1741 fis->d.sectorCount = 0xFF; /* FIS sector count (7:0) */
1742 }
1743
1744 fis->d.sectorCountExp = 0;
1745 fis->d.reserved4 = 0;
1746 fis->d.control = 0; /* FIS HOB bit clear */
1747 fis->d.reserved5 = 0;
1748
1749 agRequestType = AGSA_SATA_PROTOCOL_DMA_READ;
1750
1751 break;
1752 case SAT_READ_SECTORS:
1753 fis->h.fisType = 0x27; /* Reg host to device */
1754 fis->h.c_pmPort = 0x80; /* C Bit is set */
1755 fis->h.command = SAT_READ_SECTORS; /* 0x20 */
1756 fis->h.features = 0; /* FIS reserve */
1757 fis->d.lbaLow = LBA[3]; /* FIS LBA (7 :0 ) */
1758 fis->d.lbaMid = LBA[2]; /* FIS LBA (15:8 ) */
1759 fis->d.lbaHigh = LBA[1]; /* FIS LBA (23:16) */
1760 fis->d.device =
1761 (bit8)((0x4 << 4) | (LBA[0] & 0xF)); /* FIS LBA (27:24) and FIS LBA mode */
1762 fis->d.lbaLowExp = 0;
1763 fis->d.lbaMidExp = 0;
1764 fis->d.lbaHighExp = 0;
1765 fis->d.featuresExp = 0;
1766 if (satOrgIOContext->LoopNum == 1)
1767 {
1768 /* last loop */
1769 fis->d.sectorCount = (bit8)Remainder; /* FIS sector count (7:0) */
1770 }
1771 else
1772 {
1773 fis->d.sectorCount = 0xFF; /* FIS sector count (7:0) */
1774 }
1775 fis->d.sectorCountExp = 0;
1776 fis->d.reserved4 = 0;
1777 fis->d.control = 0; /* FIS HOB bit clear */
1778 fis->d.reserved5 = 0;
1779
1780 agRequestType = AGSA_SATA_PROTOCOL_PIO_READ;
1781
1782 break;
1783 case SAT_READ_DMA_EXT:
1784 fis->h.fisType = 0x27; /* Reg host to device */
1785 fis->h.c_pmPort = 0x80; /* C Bit is set */
1786 fis->h.command = SAT_READ_DMA_EXT; /* 0x25 */
1787 fis->h.features = 0; /* FIS reserve */
1788 fis->d.lbaLow = LBA[3]; /* FIS LBA (7 :0 ) */
1789 fis->d.lbaMid = LBA[2]; /* FIS LBA (15:8 ) */
1790 fis->d.lbaHigh = LBA[1]; /* FIS LBA (23:16) */
1791 fis->d.device = 0x40; /* FIS LBA mode set */
1792 fis->d.lbaLowExp = LBA[0]; /* FIS LBA (31:24) */
1793 fis->d.lbaMidExp = 0; /* FIS LBA (39:32) */
1794 fis->d.lbaHighExp = 0; /* FIS LBA (47:40) */
1795 fis->d.featuresExp = 0; /* FIS reserve */
1796 if (satOrgIOContext->LoopNum == 1)
1797 {
1798 /* last loop */
1799 fis->d.sectorCount = (bit8)(Remainder & 0xFF); /* FIS sector count (7:0) */
1800 fis->d.sectorCountExp = (bit8)((Remainder & 0xFF00) >> 8); /* FIS sector count (15:8) */
1801
1802 }
1803 else
1804 {
1805 fis->d.sectorCount = 0xFF; /* FIS sector count (7:0) */
1806 fis->d.sectorCountExp = 0xFF; /* FIS sector count (15:8) */
1807 }
1808 fis->d.reserved4 = 0;
1809 fis->d.control = 0; /* FIS HOB bit clear */
1810 fis->d.reserved5 = 0;
1811
1812 agRequestType = AGSA_SATA_PROTOCOL_DMA_READ;
1813
1814 break;
1815 case SAT_READ_SECTORS_EXT:
1816 fis->h.fisType = 0x27; /* Reg host to device */
1817 fis->h.c_pmPort = 0x80; /* C Bit is set */
1818 fis->h.command = SAT_READ_SECTORS_EXT; /* 0x24 */
1819 fis->h.features = 0; /* FIS reserve */
1820 fis->d.lbaLow = LBA[3]; /* FIS LBA (7 :0 ) */
1821 fis->d.lbaMid = LBA[2]; /* FIS LBA (15:8 ) */
1822 fis->d.lbaHigh = LBA[1]; /* FIS LBA (23:16) */
1823 fis->d.device = 0x40; /* FIS LBA mode set */
1824 fis->d.lbaLowExp = LBA[0]; /* FIS LBA (31:24) */
1825 fis->d.lbaMidExp = 0; /* FIS LBA (39:32) */
1826 fis->d.lbaHighExp = 0; /* FIS LBA (47:40) */
1827 fis->d.featuresExp = 0; /* FIS reserve */
1828 if (satOrgIOContext->LoopNum == 1)
1829 {
1830 /* last loop */
1831 fis->d.sectorCount = (bit8)(Remainder & 0xFF); /* FIS sector count (7:0) */
1832 fis->d.sectorCountExp = (bit8)((Remainder & 0xFF00) >> 8); /* FIS sector count (15:8) */
1833 }
1834 else
1835 {
1836 fis->d.sectorCount = 0xFF; /* FIS sector count (7:0) */
1837 fis->d.sectorCountExp = 0xFF; /* FIS sector count (15:8) */
1838 }
1839 fis->d.reserved4 = 0;
1840 fis->d.control = 0; /* FIS HOB bit clear */
1841 fis->d.reserved5 = 0;
1842
1843 agRequestType = AGSA_SATA_PROTOCOL_PIO_READ;
1844 break;
1845 case SAT_READ_FPDMA_QUEUED:
1846 fis->h.fisType = 0x27; /* Reg host to device */
1847 fis->h.c_pmPort = 0x80; /* C Bit is set */
1848 fis->h.command = SAT_READ_FPDMA_QUEUED; /* 0x60 */
1849 fis->d.lbaLow = LBA[3]; /* FIS LBA (7 :0 ) */
1850 fis->d.lbaMid = LBA[2]; /* FIS LBA (15:8 ) */
1851 fis->d.lbaHigh = LBA[1]; /* FIS LBA (23:16) */
1852
1853 /* Check FUA bit */
1854 if (scsiCmnd->cdb[1] & SCSI_READ10_FUA_MASK)
1855 fis->d.device = 0xC0; /* FIS FUA set */
1856 else
1857 fis->d.device = 0x40; /* FIS FUA clear */
1858
1859 fis->d.lbaLowExp = LBA[0]; /* FIS LBA (31:24) */
1860 fis->d.lbaMidExp = 0; /* FIS LBA (39:32) */
1861 fis->d.lbaHighExp = 0; /* FIS LBA (47:40) */
1862 if (satOrgIOContext->LoopNum == 1)
1863 {
1864 /* last loop */
1865 fis->h.features = (bit8)(Remainder & 0xFF); /* FIS sector count (7:0) */
1866 fis->d.featuresExp = (bit8)((Remainder & 0xFF00) >> 8); /* FIS sector count (15:8) */
1867 }
1868 else
1869 {
1870 fis->h.features = 0xFF; /* FIS sector count (7:0) */
1871 fis->d.featuresExp = 0xFF; /* FIS sector count (15:8) */
1872 }
1873 fis->d.sectorCount = 0; /* Tag (7:3) set by LL layer */
1874 fis->d.sectorCountExp = 0;
1875 fis->d.reserved4 = 0;
1876 fis->d.control = 0; /* FIS HOB bit clear */
1877 fis->d.reserved5 = 0;
1878
1879 agRequestType = AGSA_SATA_PROTOCOL_FPDMA_READ;
1880 break;
1881 default:
1882 TI_DBG1(("satRead_1: error incorrect ata command 0x%x\n", satIOContext->ATACmd));
1883 return tiError;
1884 break;
1885 }
1886
1887 /* Initialize CB for SATA completion.
1888 */
1889 /* chained data */
1890 satIOContext->satCompleteCB = &satChainedDataIOCB;
1891
1892
1893 /*
1894 * Prepare SGL and send FIS to LL layer.
1895 */
1896 satIOContext->reqType = agRequestType; /* Save it */
1897
1898 status = sataLLIOStart( tiRoot,
1899 tiIORequest,
1900 tiDeviceHandle,
1901 tiScsiRequest,
1902 satIOContext);
1903
1904 TI_DBG5(("satRead_1: return\n"));
1905 return (status);
1906 }
1907 /*****************************************************************************/
1908 /*! \brief SAT implementation for SCSI READ12.
1909 *
1910 * SAT implementation for SCSI READ12 and send FIS request to LL layer.
1911 *
1912 * \param tiRoot: Pointer to TISA initiator driver/port instance.
1913 * \param tiIORequest: Pointer to TISA I/O request context for this I/O.
1914 * \param tiDeviceHandle: Pointer to TISA device handle for this I/O.
1915 * \param tiScsiRequest: Pointer to TISA SCSI I/O request and SGL list.
1916 * \param satIOContext_t: Pointer to the SAT IO Context
1917 *
1918 * \return If command is started successfully
1919 * - \e tiSuccess: I/O request successfully initiated.
1920 * - \e tiBusy: No resources available, try again later.
1921 * - \e tiIONoDevice: Invalid device handle.
1922 * - \e tiError: Other errors.
1923 */
1924 /*****************************************************************************/
1925 GLOBAL bit32 satRead12(
1926 tiRoot_t *tiRoot,
1927 tiIORequest_t *tiIORequest,
1928 tiDeviceHandle_t *tiDeviceHandle,
1929 tiScsiInitiatorRequest_t *tiScsiRequest,
1930 satIOContext_t *satIOContext)
1931 {
1932 bit32 status;
1933 bit32 agRequestType = AGSA_SATA_PROTOCOL_DMA_READ;
1934 satDeviceData_t *pSatDevData;
1935 scsiRspSense_t *pSense;
1936 tiIniScsiCmnd_t *scsiCmnd;
1937 agsaFisRegHostToDevice_t *fis;
1938 bit32 lba = 0;
1939 bit32 tl = 0;
1940 bit32 LoopNum = 1;
1941 bit8 LBA[4];
1942 bit8 TL[4];
1943 bit32 rangeChk = agFALSE; /* lba and tl range check */
1944
1945 pSense = satIOContext->pSense;
1946 pSatDevData = satIOContext->pSatDevData;
1947 scsiCmnd = &tiScsiRequest->scsiCmnd;
1948 fis = satIOContext->pFis;
1949
1950 TI_DBG5(("satRead12: start\n"));
1951
1952 /* checking FUA_NV */
1953 if (scsiCmnd->cdb[1] & SCSI_FUA_NV_MASK)
1954 {
1955 satSetSensePayload( pSense,
1956 SCSI_SNSKEY_ILLEGAL_REQUEST,
1957 0,
1958 SCSI_SNSCODE_INVALID_FIELD_IN_CDB,
1959 satIOContext);
1960
1961 ostiInitiatorIOCompleted( tiRoot,
1962 tiIORequest,
1963 tiIOSuccess,
1964 SCSI_STAT_CHECK_CONDITION,
1965 satIOContext->pTiSenseData,
1966 satIOContext->interruptContext );
1967
1968 TI_DBG1(("satRead12: return FUA_NV\n"));
1969 return tiSuccess;
1970
1971 }
1972
1973 /* checking CONTROL */
1974 /* NACA == 1 or LINK == 1*/
1975 if ( (scsiCmnd->cdb[11] & SCSI_NACA_MASK) || (scsiCmnd->cdb[11] & SCSI_LINK_MASK) )
1976 {
1977 satSetSensePayload( pSense,
1978 SCSI_SNSKEY_ILLEGAL_REQUEST,
1979 0,
1980 SCSI_SNSCODE_INVALID_FIELD_IN_CDB,
1981 satIOContext);
1982
1983 ostiInitiatorIOCompleted( tiRoot,
1984 tiIORequest,
1985 tiIOSuccess,
1986 SCSI_STAT_CHECK_CONDITION,
1987 satIOContext->pTiSenseData,
1988 satIOContext->interruptContext );
1989
1990 TI_DBG2(("satRead12: return control\n"));
1991 return tiSuccess;
1992 }
1993
1994 osti_memset(LBA, 0, sizeof(LBA));
1995 osti_memset(TL, 0, sizeof(TL));
1996
1997 /* do not use memcpy due to indexing in LBA and TL */
1998 LBA[0] = scsiCmnd->cdb[2]; /* MSB */
1999 LBA[1] = scsiCmnd->cdb[3];
2000 LBA[2] = scsiCmnd->cdb[4];
2001 LBA[3] = scsiCmnd->cdb[5]; /* LSB */
2002
2003 TL[0] = scsiCmnd->cdb[6]; /* MSB */
2004 TL[1] = scsiCmnd->cdb[7];
2005 TL[2] = scsiCmnd->cdb[8];
2006 TL[3] = scsiCmnd->cdb[9]; /* LSB */
2007
2008 rangeChk = satAddNComparebit32(LBA, TL);
2009
2010 lba = satComputeCDB12LBA(satIOContext);
2011 tl = satComputeCDB12TL(satIOContext);
2012
2013 /* Table 34, 9.1, p 46 */
2014 /*
2015 note: As of 2/10/2006, no support for DMA QUEUED
2016 */
2017
2018 /*
2019 Table 34, 9.1, p 46, b
2020 When no 48-bit addressing support or NCQ, if LBA is beyond (2^28 - 1),
2021 return check condition
2022 */
2023 if (pSatDevData->satNCQ != agTRUE &&
2024 pSatDevData->sat48BitSupport != agTRUE
2025 )
2026 {
2027 if (lba > SAT_TR_LBA_LIMIT - 1)
2028 {
2029 TI_DBG1(("satRead12: return LBA out of range, not EXT\n"));
2030 satSetSensePayload( pSense,
2031 SCSI_SNSKEY_ILLEGAL_REQUEST,
2032 0,
2033 SCSI_SNSCODE_LOGICAL_BLOCK_ADDRESS_OUT_OF_RANGE,
2034 satIOContext);
2035
2036 ostiInitiatorIOCompleted( tiRoot,
2037 tiIORequest,
2038 tiIOSuccess,
2039 SCSI_STAT_CHECK_CONDITION,
2040 satIOContext->pTiSenseData,
2041 satIOContext->interruptContext );
2042
2043 return tiSuccess;
2044 }
2045 if (rangeChk) // if (lba + tl > SAT_TR_LBA_LIMIT)
2046 {
2047 TI_DBG1(("satRead12: return LBA+TL out of range, not EXT\n"));
2048 satSetSensePayload( pSense,
2049 SCSI_SNSKEY_ILLEGAL_REQUEST,
2050 0,
2051 SCSI_SNSCODE_LOGICAL_BLOCK_ADDRESS_OUT_OF_RANGE,
2052 satIOContext);
2053
2054 ostiInitiatorIOCompleted( tiRoot,
2055 tiIORequest,
2056 tiIOSuccess,
2057 SCSI_STAT_CHECK_CONDITION,
2058 satIOContext->pTiSenseData,
2059 satIOContext->interruptContext );
2060
2061 return tiSuccess;
2062 }
2063 }
2064
2065 /* case 1 and 2 */
2066 if (!rangeChk) // if (lba + tl <= SAT_TR_LBA_LIMIT)
2067 {
2068 if (pSatDevData->satDMASupport == agTRUE && pSatDevData->satDMAEnabled == agTRUE)
2069 {
2070 /* case 2 */
2071 /* READ DMA*/
2072 /* in case that we can't fit the transfer length,
2073 we need to make it fit by sending multiple ATA cmnds */
2074 TI_DBG5(("satRead12: case 2\n"));
2075
2076
2077 fis->h.fisType = 0x27; /* Reg host to device */
2078 fis->h.c_pmPort = 0x80; /* C Bit is set */
2079 fis->h.command = SAT_READ_DMA; /* 0xC8 */
2080 fis->h.features = 0; /* FIS reserve */
2081 fis->d.lbaLow = scsiCmnd->cdb[5]; /* FIS LBA (7 :0 ) */
2082 fis->d.lbaMid = scsiCmnd->cdb[4]; /* FIS LBA (15:8 ) */
2083 fis->d.lbaHigh = scsiCmnd->cdb[3]; /* FIS LBA (23:16) */
2084 fis->d.device =
2085 (bit8)((0x4 << 4) | (scsiCmnd->cdb[2] & 0xF)); /* FIS LBA (27:24) and FIS LBA mode */
2086 fis->d.lbaLowExp = 0;
2087 fis->d.lbaMidExp = 0;
2088 fis->d.lbaHighExp = 0;
2089 fis->d.featuresExp = 0;
2090 fis->d.sectorCount = scsiCmnd->cdb[9]; /* FIS sector count (7:0) */
2091 fis->d.sectorCountExp = 0;
2092 fis->d.reserved4 = 0;
2093 fis->d.control = 0; /* FIS HOB bit clear */
2094 fis->d.reserved5 = 0;
2095
2096
2097 agRequestType = AGSA_SATA_PROTOCOL_DMA_READ;
2098 satIOContext->ATACmd = SAT_READ_DMA;
2099 }
2100 else
2101 {
2102 /* case 1 */
2103 /* READ MULTIPLE or READ SECTOR(S) */
2104 /* READ SECTORS for easier implemetation */
2105 /* can't fit the transfer length but need to make it fit by sending multiple*/
2106 TI_DBG5(("satRead12: case 1\n"));
2107
2108 fis->h.fisType = 0x27; /* Reg host to device */
2109 fis->h.c_pmPort = 0x80; /* C Bit is set */
2110 fis->h.command = SAT_READ_SECTORS; /* 0x20 */
2111 fis->h.features = 0; /* FIS reserve */
2112 fis->d.lbaLow = scsiCmnd->cdb[5]; /* FIS LBA (7 :0 ) */
2113 fis->d.lbaMid = scsiCmnd->cdb[4]; /* FIS LBA (15:8 ) */
2114 fis->d.lbaHigh = scsiCmnd->cdb[3]; /* FIS LBA (23:16) */
2115 fis->d.device =
2116 (bit8)((0x4 << 4) | (scsiCmnd->cdb[2] & 0xF)); /* FIS LBA (27:24) and FIS LBA mode */
2117 fis->d.lbaLowExp = 0;
2118 fis->d.lbaMidExp = 0;
2119 fis->d.lbaHighExp = 0;
2120 fis->d.featuresExp = 0;
2121 fis->d.sectorCount = scsiCmnd->cdb[9]; /* FIS sector count (7:0) */
2122 fis->d.sectorCountExp = 0;
2123 fis->d.reserved4 = 0;
2124 fis->d.control = 0; /* FIS HOB bit clear */
2125 fis->d.reserved5 = 0;
2126
2127
2128 agRequestType = AGSA_SATA_PROTOCOL_PIO_READ;
2129 satIOContext->ATACmd = SAT_READ_SECTORS;
2130 }
2131 }
2132
2133 /* case 3 and 4 */
2134 if (pSatDevData->sat48BitSupport == agTRUE)
2135 {
2136 if (pSatDevData->satDMASupport == agTRUE && pSatDevData->satDMAEnabled == agTRUE)
2137 {
2138 /* case 3 */
2139 /* READ DMA EXT */
2140 TI_DBG5(("satRead12: case 3\n"));
2141 fis->h.fisType = 0x27; /* Reg host to device */
2142
2143 fis->h.c_pmPort = 0x80; /* C Bit is set */
2144 fis->h.command = SAT_READ_DMA_EXT; /* 0x25 */
2145 fis->h.features = 0; /* FIS reserve */
2146 fis->d.lbaLow = scsiCmnd->cdb[5]; /* FIS LBA (7 :0 ) */
2147 fis->d.lbaMid = scsiCmnd->cdb[4]; /* FIS LBA (15:8 ) */
2148 fis->d.lbaHigh = scsiCmnd->cdb[3]; /* FIS LBA (23:16) */
2149 fis->d.device = 0x40; /* FIS LBA mode set */
2150 fis->d.lbaLowExp = scsiCmnd->cdb[2]; /* FIS LBA (31:24) */
2151 fis->d.lbaMidExp = 0; /* FIS LBA (39:32) */
2152 fis->d.lbaHighExp = 0; /* FIS LBA (47:40) */
2153 fis->d.featuresExp = 0; /* FIS reserve */
2154 fis->d.sectorCount = scsiCmnd->cdb[9]; /* FIS sector count (7:0) */
2155 fis->d.sectorCountExp = scsiCmnd->cdb[8]; /* FIS sector count (15:8) */
2156 fis->d.reserved4 = 0;
2157 fis->d.control = 0; /* FIS HOB bit clear */
2158 fis->d.reserved5 = 0;
2159
2160 agRequestType = AGSA_SATA_PROTOCOL_DMA_READ;
2161 satIOContext->ATACmd = SAT_READ_DMA_EXT;
2162
2163 }
2164 else
2165 {
2166 /* case 4 */
2167 /* READ MULTIPLE EXT or READ SECTOR(S) EXT or READ VERIFY SECTOR(S) EXT*/
2168 /* READ SECTORS EXT for easier implemetation */
2169 TI_DBG5(("satRead12: case 4\n"));
2170 fis->h.fisType = 0x27; /* Reg host to device */
2171 fis->h.c_pmPort = 0x80; /* C Bit is set */
2172
2173 /* Check FUA bit */
2174 if (scsiCmnd->cdb[1] & SCSI_READ12_FUA_MASK)
2175 {
2176 /* for now, no support for FUA */
2177 satSetSensePayload( pSense,
2178 SCSI_SNSKEY_ILLEGAL_REQUEST,
2179 0,
2180 SCSI_SNSCODE_INVALID_FIELD_IN_CDB,
2181 satIOContext);
2182
2183 ostiInitiatorIOCompleted( tiRoot,
2184 tiIORequest,
2185 tiIOSuccess,
2186 SCSI_STAT_CHECK_CONDITION,
2187 satIOContext->pTiSenseData,
2188 satIOContext->interruptContext );
2189 return tiSuccess;
2190 }
2191
2192 fis->h.command = SAT_READ_SECTORS_EXT; /* 0x24 */
2193
2194 fis->h.features = 0; /* FIS reserve */
2195 fis->d.lbaLow = scsiCmnd->cdb[5]; /* FIS LBA (7 :0 ) */
2196 fis->d.lbaMid = scsiCmnd->cdb[4]; /* FIS LBA (15:8 ) */
2197 fis->d.lbaHigh = scsiCmnd->cdb[3]; /* FIS LBA (23:16) */
2198 fis->d.device = 0x40; /* FIS LBA mode set */
2199 fis->d.lbaLowExp = scsiCmnd->cdb[2]; /* FIS LBA (31:24) */
2200 fis->d.lbaMidExp = 0; /* FIS LBA (39:32) */
2201 fis->d.lbaHighExp = 0; /* FIS LBA (47:40) */
2202 fis->d.featuresExp = 0; /* FIS reserve */
2203 fis->d.sectorCount = scsiCmnd->cdb[9]; /* FIS sector count (7:0) */
2204 fis->d.sectorCountExp = scsiCmnd->cdb[8]; /* FIS sector count (15:8) */
2205 fis->d.reserved4 = 0;
2206 fis->d.control = 0; /* FIS HOB bit clear */
2207 fis->d.reserved5 = 0;
2208
2209 agRequestType = AGSA_SATA_PROTOCOL_PIO_READ;
2210 satIOContext->ATACmd = SAT_READ_SECTORS_EXT;
2211 }
2212 }
2213
2214 /* case 5 */
2215 if (pSatDevData->satNCQ == agTRUE)
2216 {
2217 /* READ FPDMA QUEUED */
2218 if (pSatDevData->sat48BitSupport != agTRUE)
2219 {
2220 TI_DBG5(("satRead12: case 5 !!! error NCQ but 28 bit address support \n"));
2221 satSetSensePayload( pSense,
2222 SCSI_SNSKEY_ILLEGAL_REQUEST,
2223 0,
2224 SCSI_SNSCODE_INVALID_FIELD_IN_CDB,
2225 satIOContext);
2226
2227 ostiInitiatorIOCompleted( tiRoot,
2228 tiIORequest,
2229 tiIOSuccess,
2230 SCSI_STAT_CHECK_CONDITION,
2231 satIOContext->pTiSenseData,
2232 satIOContext->interruptContext );
2233 return tiSuccess;
2234 }
2235
2236 TI_DBG6(("satRead12: case 5\n"));
2237
2238 /* Support 48-bit FPDMA addressing, use READ FPDMA QUEUE command */
2239
2240 fis->h.fisType = 0x27; /* Reg host to device */
2241 fis->h.c_pmPort = 0x80; /* C Bit is set */
2242 fis->h.command = SAT_READ_FPDMA_QUEUED; /* 0x60 */
2243 fis->h.features = scsiCmnd->cdb[9]; /* FIS sector count (7:0) */
2244 fis->d.lbaLow = scsiCmnd->cdb[5]; /* FIS LBA (7 :0 ) */
2245 fis->d.lbaMid = scsiCmnd->cdb[4]; /* FIS LBA (15:8 ) */
2246 fis->d.lbaHigh = scsiCmnd->cdb[3]; /* FIS LBA (23:16) */
2247
2248 /* Check FUA bit */
2249 if (scsiCmnd->cdb[1] & SCSI_READ12_FUA_MASK)
2250 fis->d.device = 0xC0; /* FIS FUA set */
2251 else
2252 fis->d.device = 0x40; /* FIS FUA clear */
2253
2254 fis->d.lbaLowExp = scsiCmnd->cdb[2]; /* FIS LBA (31:24) */
2255 fis->d.lbaMidExp = 0; /* FIS LBA (39:32) */
2256 fis->d.lbaHighExp = 0; /* FIS LBA (47:40) */
2257 fis->d.featuresExp = scsiCmnd->cdb[8]; /* FIS sector count (15:8) */
2258 fis->d.sectorCount = 0; /* Tag (7:3) set by LL layer */
2259 fis->d.sectorCountExp = 0;
2260 fis->d.reserved4 = 0;
2261 fis->d.control = 0; /* FIS HOB bit clear */
2262 fis->d.reserved5 = 0;
2263
2264 agRequestType = AGSA_SATA_PROTOCOL_FPDMA_READ;
2265 satIOContext->ATACmd = SAT_READ_FPDMA_QUEUED;
2266 }
2267
2268 /* saves the current LBA and orginal TL */
2269 satIOContext->currentLBA = lba;
2270 satIOContext->OrgTL = tl;
2271
2272 /*
2273 computing number of loop and remainder for tl
2274 0xFF in case not ext
2275 0xFFFF in case EXT
2276 */
2277 if (fis->h.command == SAT_READ_SECTORS || fis->h.command == SAT_READ_DMA)
2278 {
2279 LoopNum = satComputeLoopNum(tl, 0xFF);
2280 }
2281 else if (fis->h.command == SAT_READ_SECTORS_EXT || fis->h.command == SAT_READ_DMA_EXT)
2282 {
2283 /* SAT_READ_SECTORS_EXT, SAT_READ_DMA_EXT */
2284 LoopNum = satComputeLoopNum(tl, 0xFFFF);
2285 }
2286 else
2287 {
2288 /* SAT_READ_FPDMA_QUEUEDK */
2289 LoopNum = satComputeLoopNum(tl, 0xFFFF);
2290 }
2291
2292 satIOContext->LoopNum = LoopNum;
2293
2294 if (LoopNum == 1)
2295 {
2296 TI_DBG5(("satRead12: NON CHAINED data\n"));
2297 satIOContext->satCompleteCB = &satNonChainedDataIOCB;
2298 }
2299 else
2300 {
2301 TI_DBG1(("satRead12: CHAINED data\n"));
2302 /* re-setting tl */
2303 if (fis->h.command == SAT_READ_SECTORS || fis->h.command == SAT_READ_DMA)
2304 {
2305 fis->d.sectorCount = 0xFF;
2306 }
2307 else if (fis->h.command == SAT_READ_SECTORS_EXT || fis->h.command == SAT_READ_DMA_EXT)
2308 {
2309 /* SAT_READ_SECTORS_EXT, SAT_READ_DMA_EXT */
2310 fis->d.sectorCount = 0xFF;
2311 fis->d.sectorCountExp = 0xFF;
2312 }
2313 else
2314 {
2315 /* SAT_READ_FPDMA_QUEUED */
2316 fis->h.features = 0xFF;
2317 fis->d.featuresExp = 0xFF;
2318 }
2319
2320 /* chained data */
2321 satIOContext->satCompleteCB = &satChainedDataIOCB;
2322 }
2323
2324 /*
2325 * Prepare SGL and send FIS to LL layer.
2326 */
2327 satIOContext->reqType = agRequestType; /* Save it */
2328
2329 status = sataLLIOStart( tiRoot,
2330 tiIORequest,
2331 tiDeviceHandle,
2332 tiScsiRequest,
2333 satIOContext);
2334
2335 TI_DBG5(("satRead12: return\n"));
2336 return (status);
2337 }
2338 /*****************************************************************************/
2339 /*! \brief SAT implementation for SCSI READ16.
2340 *
2341 * SAT implementation for SCSI READ16 and send FIS request to LL layer.
2342 *
2343 * \param tiRoot: Pointer to TISA initiator driver/port instance.
2344 * \param tiIORequest: Pointer to TISA I/O request context for this I/O.
2345 * \param tiDeviceHandle: Pointer to TISA device handle for this I/O.
2346 * \param tiScsiRequest: Pointer to TISA SCSI I/O request and SGL list.
2347 * \param satIOContext_t: Pointer to the SAT IO Context
2348 *
2349 * \return If command is started successfully
2350 * - \e tiSuccess: I/O request successfully initiated.
2351 * - \e tiBusy: No resources available, try again later.
2352 * - \e tiIONoDevice: Invalid device handle.
2353 * - \e tiError: Other errors.
2354 */
2355 /*****************************************************************************/
2356 GLOBAL bit32 satRead16(
2357 tiRoot_t *tiRoot,
2358 tiIORequest_t *tiIORequest,
2359 tiDeviceHandle_t *tiDeviceHandle,
2360 tiScsiInitiatorRequest_t *tiScsiRequest,
2361 satIOContext_t *satIOContext)
2362 {
2363 bit32 status;
2364 bit32 agRequestType = AGSA_SATA_PROTOCOL_DMA_READ;
2365 satDeviceData_t *pSatDevData;
2366 scsiRspSense_t *pSense;
2367 tiIniScsiCmnd_t *scsiCmnd;
2368 agsaFisRegHostToDevice_t *fis;
2369 bit32 lba = 0;
2370 bit32 tl = 0;
2371 bit32 LoopNum = 1;
2372 bit8 LBA[8];
2373 bit8 TL[8];
2374 bit32 rangeChk = agFALSE; /* lba and tl range check */
2375 bit32 limitChk = agFALSE; /* lba and tl range check */
2376
2377 pSense = satIOContext->pSense;
2378 pSatDevData = satIOContext->pSatDevData;
2379 scsiCmnd = &tiScsiRequest->scsiCmnd;
2380 fis = satIOContext->pFis;
2381
2382 TI_DBG5(("satRead16: start\n"));
2383
2384 /* checking FUA_NV */
2385 if (scsiCmnd->cdb[1] & SCSI_FUA_NV_MASK)
2386 {
2387 satSetSensePayload( pSense,
2388 SCSI_SNSKEY_ILLEGAL_REQUEST,
2389 0,
2390 SCSI_SNSCODE_INVALID_FIELD_IN_CDB,
2391 satIOContext);
2392
2393 ostiInitiatorIOCompleted( tiRoot,
2394 tiIORequest,
2395 tiIOSuccess,
2396 SCSI_STAT_CHECK_CONDITION,
2397 satIOContext->pTiSenseData,
2398 satIOContext->interruptContext );
2399
2400 TI_DBG1(("satRead16: return FUA_NV\n"));
2401 return tiSuccess;
2402
2403 }
2404
2405 /* checking CONTROL */
2406 /* NACA == 1 or LINK == 1*/
2407 if ( (scsiCmnd->cdb[15] & SCSI_NACA_MASK) || (scsiCmnd->cdb[15] & SCSI_LINK_MASK) )
2408 {
2409 satSetSensePayload( pSense,
2410 SCSI_SNSKEY_ILLEGAL_REQUEST,
2411 0,
2412 SCSI_SNSCODE_INVALID_FIELD_IN_CDB,
2413 satIOContext);
2414
2415 ostiInitiatorIOCompleted( tiRoot,
2416 tiIORequest,
2417 tiIOSuccess,
2418 SCSI_STAT_CHECK_CONDITION,
2419 satIOContext->pTiSenseData,
2420 satIOContext->interruptContext );
2421
2422 TI_DBG1(("satRead16: return control\n"));
2423 return tiSuccess;
2424 }
2425
2426
2427 osti_memset(LBA, 0, sizeof(LBA));
2428 osti_memset(TL, 0, sizeof(TL));
2429
2430
2431 /* do not use memcpy due to indexing in LBA and TL */
2432 LBA[0] = scsiCmnd->cdb[2]; /* MSB */
2433 LBA[1] = scsiCmnd->cdb[3];
2434 LBA[2] = scsiCmnd->cdb[4];
2435 LBA[3] = scsiCmnd->cdb[5];
2436 LBA[4] = scsiCmnd->cdb[6];
2437 LBA[5] = scsiCmnd->cdb[7];
2438 LBA[6] = scsiCmnd->cdb[8];
2439 LBA[7] = scsiCmnd->cdb[9]; /* LSB */
2440
2441 TL[0] = 0;
2442 TL[1] = 0;
2443 TL[2] = 0;
2444 TL[3] = 0;
2445 TL[4] = scsiCmnd->cdb[10]; /* MSB */
2446 TL[5] = scsiCmnd->cdb[11];
2447 TL[6] = scsiCmnd->cdb[12];
2448 TL[7] = scsiCmnd->cdb[13]; /* LSB */
2449
2450 rangeChk = satAddNComparebit64(LBA, TL);
2451
2452 limitChk = satCompareLBALimitbit(LBA);
2453
2454 lba = satComputeCDB16LBA(satIOContext);
2455 tl = satComputeCDB16TL(satIOContext);
2456
2457
2458 /* Table 34, 9.1, p 46 */
2459 /*
2460 note: As of 2/10/2006, no support for DMA QUEUED
2461 */
2462
2463 /*
2464 Table 34, 9.1, p 46, b
2465 When no 48-bit addressing support or NCQ, if LBA is beyond (2^28 - 1),
2466 return check condition
2467 */
2468 if (pSatDevData->satNCQ != agTRUE &&
2469 pSatDevData->sat48BitSupport != agTRUE
2470 )
2471 {
2472 if (limitChk)
2473 {
2474 TI_DBG1(("satRead16: return LBA out of range, not EXT\n"));
2475 satSetSensePayload( pSense,
2476 SCSI_SNSKEY_ILLEGAL_REQUEST,
2477 0,
2478 SCSI_SNSCODE_LOGICAL_BLOCK_ADDRESS_OUT_OF_RANGE,
2479 satIOContext);
2480
2481 ostiInitiatorIOCompleted( tiRoot,
2482 tiIORequest,
2483 tiIOSuccess,
2484 SCSI_STAT_CHECK_CONDITION,
2485 satIOContext->pTiSenseData,
2486 satIOContext->interruptContext );
2487
2488 return tiSuccess;
2489 }
2490 if (rangeChk) // if (lba + tl > SAT_TR_LBA_LIMIT)
2491 {
2492 TI_DBG1(("satRead16: return LBA+TL out of range, not EXT\n"));
2493 satSetSensePayload( pSense,
2494 SCSI_SNSKEY_ILLEGAL_REQUEST,
2495 0,
2496 SCSI_SNSCODE_LOGICAL_BLOCK_ADDRESS_OUT_OF_RANGE,
2497 satIOContext);
2498
2499 ostiInitiatorIOCompleted( tiRoot,
2500 tiIORequest,
2501 tiIOSuccess,
2502 SCSI_STAT_CHECK_CONDITION,
2503 satIOContext->pTiSenseData,
2504 satIOContext->interruptContext );
2505
2506 return tiSuccess;
2507 }
2508 }
2509
2510 /* case 1 and 2 */
2511 if (!rangeChk) // if (lba + tl <= SAT_TR_LBA_LIMIT)
2512 {
2513 if (pSatDevData->satDMASupport == agTRUE && pSatDevData->satDMAEnabled == agTRUE)
2514 {
2515 /* case 2 */
2516 /* READ DMA*/
2517 /* in case that we can't fit the transfer length,
2518 we need to make it fit by sending multiple ATA cmnds */
2519 TI_DBG5(("satRead16: case 2\n"));
2520
2521
2522 fis->h.fisType = 0x27; /* Reg host to device */
2523 fis->h.c_pmPort = 0x80; /* C Bit is set */
2524 fis->h.command = SAT_READ_DMA; /* 0xC8 */
2525 fis->h.features = 0; /* FIS reserve */
2526 fis->d.lbaLow = scsiCmnd->cdb[9]; /* FIS LBA (7 :0 ) */
2527 fis->d.lbaMid = scsiCmnd->cdb[8]; /* FIS LBA (15:8 ) */
2528 fis->d.lbaHigh = scsiCmnd->cdb[7]; /* FIS LBA (23:16) */
2529 fis->d.device =
2530 (bit8)((0x4 << 4) | (scsiCmnd->cdb[6] & 0xF)); /* FIS LBA (27:24) and FIS LBA mode */
2531 fis->d.lbaLowExp = 0;
2532 fis->d.lbaMidExp = 0;
2533 fis->d.lbaHighExp = 0;
2534 fis->d.featuresExp = 0;
2535 fis->d.sectorCount = scsiCmnd->cdb[13]; /* FIS sector count (7:0) */
2536 fis->d.sectorCountExp = 0;
2537 fis->d.reserved4 = 0;
2538 fis->d.control = 0; /* FIS HOB bit clear */
2539 fis->d.reserved5 = 0;
2540
2541
2542 agRequestType = AGSA_SATA_PROTOCOL_DMA_READ;
2543 satIOContext->ATACmd = SAT_READ_DMA;
2544 }
2545 else
2546 {
2547 /* case 1 */
2548 /* READ MULTIPLE or READ SECTOR(S) */
2549 /* READ SECTORS for easier implemetation */
2550 /* can't fit the transfer length but need to make it fit by sending multiple*/
2551 TI_DBG5(("satRead16: case 1\n"));
2552
2553 fis->h.fisType = 0x27; /* Reg host to device */
2554 fis->h.c_pmPort = 0x80; /* C Bit is set */
2555 fis->h.command = SAT_READ_SECTORS; /* 0x20 */
2556 fis->h.features = 0; /* FIS reserve */
2557 fis->d.lbaLow = scsiCmnd->cdb[9]; /* FIS LBA (7 :0 ) */
2558 fis->d.lbaMid = scsiCmnd->cdb[8]; /* FIS LBA (15:8 ) */
2559 fis->d.lbaHigh = scsiCmnd->cdb[7]; /* FIS LBA (23:16) */
2560 fis->d.device =
2561 (bit8)((0x4 << 4) | (scsiCmnd->cdb[6] & 0xF)); /* FIS LBA (27:24) and FIS LBA mode */
2562 fis->d.lbaLowExp = 0;
2563 fis->d.lbaMidExp = 0;
2564 fis->d.lbaHighExp = 0;
2565 fis->d.featuresExp = 0;
2566 fis->d.sectorCount = scsiCmnd->cdb[13]; /* FIS sector count (7:0) */
2567 fis->d.sectorCountExp = 0;
2568 fis->d.reserved4 = 0;
2569 fis->d.control = 0; /* FIS HOB bit clear */
2570 fis->d.reserved5 = 0;
2571
2572
2573 agRequestType = AGSA_SATA_PROTOCOL_PIO_READ;
2574 satIOContext->ATACmd = SAT_READ_SECTORS;
2575 }
2576 }
2577
2578 /* case 3 and 4 */
2579 if (pSatDevData->sat48BitSupport == agTRUE)
2580 {
2581 if (pSatDevData->satDMASupport == agTRUE && pSatDevData->satDMAEnabled == agTRUE)
2582 {
2583 /* case 3 */
2584 /* READ DMA EXT */
2585 TI_DBG5(("satRead16: case 3\n"));
2586 fis->h.fisType = 0x27; /* Reg host to device */
2587
2588 fis->h.c_pmPort = 0x80; /* C Bit is set */
2589 fis->h.command = SAT_READ_DMA_EXT; /* 0x25 */
2590 fis->h.features = 0; /* FIS reserve */
2591 fis->d.lbaLow = scsiCmnd->cdb[9]; /* FIS LBA (7 :0 ) */
2592 fis->d.lbaMid = scsiCmnd->cdb[8]; /* FIS LBA (15:8 ) */
2593 fis->d.lbaHigh = scsiCmnd->cdb[7]; /* FIS LBA (23:16) */
2594 fis->d.device = 0x40; /* FIS LBA mode set */
2595 fis->d.lbaLowExp = scsiCmnd->cdb[6]; /* FIS LBA (31:24) */
2596 fis->d.lbaMidExp = scsiCmnd->cdb[5]; /* FIS LBA (39:32) */
2597 fis->d.lbaHighExp = scsiCmnd->cdb[4]; /* FIS LBA (47:40) */
2598 fis->d.featuresExp = 0; /* FIS reserve */
2599 fis->d.sectorCount = scsiCmnd->cdb[13]; /* FIS sector count (7:0) */
2600 fis->d.sectorCountExp = scsiCmnd->cdb[12]; /* FIS sector count (15:8) */
2601 fis->d.reserved4 = 0;
2602 fis->d.control = 0; /* FIS HOB bit clear */
2603 fis->d.reserved5 = 0;
2604
2605 agRequestType = AGSA_SATA_PROTOCOL_DMA_READ;
2606 satIOContext->ATACmd = SAT_READ_DMA_EXT;
2607
2608 }
2609 else
2610 {
2611 /* case 4 */
2612 /* READ MULTIPLE EXT or READ SECTOR(S) EXT or READ VERIFY SECTOR(S) EXT*/
2613 /* READ SECTORS EXT for easier implemetation */
2614 TI_DBG5(("satRead16: case 4\n"));
2615 fis->h.fisType = 0x27; /* Reg host to device */
2616 fis->h.c_pmPort = 0x80; /* C Bit is set */
2617
2618 /* Check FUA bit */
2619 if (scsiCmnd->cdb[1] & SCSI_READ16_FUA_MASK)
2620 {
2621
2622 /* for now, no support for FUA */
2623 satSetSensePayload( pSense,
2624 SCSI_SNSKEY_ILLEGAL_REQUEST,
2625 0,
2626 SCSI_SNSCODE_INVALID_FIELD_IN_CDB,
2627 satIOContext);
2628
2629 ostiInitiatorIOCompleted( tiRoot,
2630 tiIORequest,
2631 tiIOSuccess,
2632 SCSI_STAT_CHECK_CONDITION,
2633 satIOContext->pTiSenseData,
2634 satIOContext->interruptContext );
2635 return tiSuccess;
2636 }
2637
2638 fis->h.command = SAT_READ_SECTORS_EXT; /* 0x24 */
2639
2640 fis->h.features = 0; /* FIS reserve */
2641 fis->d.lbaLow = scsiCmnd->cdb[9]; /* FIS LBA (7 :0 ) */
2642 fis->d.lbaMid = scsiCmnd->cdb[8]; /* FIS LBA (15:8 ) */
2643 fis->d.lbaHigh = scsiCmnd->cdb[7]; /* FIS LBA (23:16) */
2644 fis->d.device = 0x40; /* FIS LBA mode set */
2645 fis->d.lbaLowExp = scsiCmnd->cdb[6]; /* FIS LBA (31:24) */
2646 fis->d.lbaMidExp = scsiCmnd->cdb[5]; /* FIS LBA (39:32) */
2647 fis->d.lbaHighExp = scsiCmnd->cdb[4]; /* FIS LBA (47:40) */
2648 fis->d.featuresExp = 0; /* FIS reserve */
2649 fis->d.sectorCount = scsiCmnd->cdb[13]; /* FIS sector count (7:0) */
2650 fis->d.sectorCountExp = scsiCmnd->cdb[12]; /* FIS sector count (15:8) */
2651 fis->d.reserved4 = 0;
2652 fis->d.control = 0; /* FIS HOB bit clear */
2653 fis->d.reserved5 = 0;
2654
2655 agRequestType = AGSA_SATA_PROTOCOL_PIO_READ;
2656 satIOContext->ATACmd = SAT_READ_SECTORS_EXT;
2657 }
2658 }
2659
2660
2661 /* case 5 */
2662 if (pSatDevData->satNCQ == agTRUE)
2663 {
2664 /* READ FPDMA QUEUED */
2665 if (pSatDevData->sat48BitSupport != agTRUE)
2666 {
2667 TI_DBG5(("satRead16: case 5 !!! error NCQ but 28 bit address support \n"));
2668 satSetSensePayload( pSense,
2669 SCSI_SNSKEY_ILLEGAL_REQUEST,
2670 0,
2671 SCSI_SNSCODE_INVALID_FIELD_IN_CDB,
2672 satIOContext);
2673
2674 ostiInitiatorIOCompleted( tiRoot,
2675 tiIORequest,
2676 tiIOSuccess,
2677 SCSI_STAT_CHECK_CONDITION,
2678 satIOContext->pTiSenseData,
2679 satIOContext->interruptContext );
2680 return tiSuccess;
2681 }
2682
2683 TI_DBG6(("satRead16: case 5\n"));
2684
2685 /* Support 48-bit FPDMA addressing, use READ FPDMA QUEUE command */
2686
2687 fis->h.fisType = 0x27; /* Reg host to device */
2688 fis->h.c_pmPort = 0x80; /* C Bit is set */
2689 fis->h.command = SAT_READ_FPDMA_QUEUED; /* 0x60 */
2690 fis->h.features = scsiCmnd->cdb[13]; /* FIS sector count (7:0) */
2691 fis->d.lbaLow = scsiCmnd->cdb[9]; /* FIS LBA (7 :0 ) */
2692 fis->d.lbaMid = scsiCmnd->cdb[8]; /* FIS LBA (15:8 ) */
2693 fis->d.lbaHigh = scsiCmnd->cdb[7]; /* FIS LBA (23:16) */
2694
2695 /* Check FUA bit */
2696 if (scsiCmnd->cdb[1] & SCSI_READ16_FUA_MASK)
2697 fis->d.device = 0xC0; /* FIS FUA set */
2698 else
2699 fis->d.device = 0x40; /* FIS FUA clear */
2700
2701 fis->d.lbaLowExp = scsiCmnd->cdb[6]; /* FIS LBA (31:24) */
2702 fis->d.lbaMidExp = scsiCmnd->cdb[5]; /* FIS LBA (39:32) */
2703 fis->d.lbaHighExp = scsiCmnd->cdb[4]; /* FIS LBA (47:40) */
2704 fis->d.featuresExp = scsiCmnd->cdb[12]; /* FIS sector count (15:8) */
2705 fis->d.sectorCount = 0; /* Tag (7:3) set by LL layer */
2706 fis->d.sectorCountExp = 0;
2707 fis->d.reserved4 = 0;
2708 fis->d.control = 0; /* FIS HOB bit clear */
2709 fis->d.reserved5 = 0;
2710
2711 agRequestType = AGSA_SATA_PROTOCOL_FPDMA_READ;
2712 satIOContext->ATACmd = SAT_READ_FPDMA_QUEUED;
2713 }
2714
2715 /* saves the current LBA and orginal TL */
2716 satIOContext->currentLBA = lba;
2717 satIOContext->OrgTL = tl;
2718
2719 /*
2720 computing number of loop and remainder for tl
2721 0xFF in case not ext
2722 0xFFFF in case EXT
2723 */
2724 if (fis->h.command == SAT_READ_SECTORS || fis->h.command == SAT_READ_DMA)
2725 {
2726 LoopNum = satComputeLoopNum(tl, 0xFF);
2727 }
2728 else if (fis->h.command == SAT_READ_SECTORS_EXT || fis->h.command == SAT_READ_DMA_EXT)
2729 {
2730 /* SAT_READ_SECTORS_EXT, SAT_READ_DMA_EXT */
2731 LoopNum = satComputeLoopNum(tl, 0xFFFF);
2732 }
2733 else
2734 {
2735 /* SAT_READ_FPDMA_QUEUEDK */
2736 LoopNum = satComputeLoopNum(tl, 0xFFFF);
2737 }
2738 satIOContext->LoopNum = LoopNum;
2739
2740 if (LoopNum == 1)
2741 {
2742 TI_DBG5(("satRead16: NON CHAINED data\n"));
2743 satIOContext->satCompleteCB = &satNonChainedDataIOCB;
2744 }
2745 else
2746 {
2747 TI_DBG1(("satRead16: CHAINED data\n"));
2748 /* re-setting tl */
2749 if (fis->h.command == SAT_READ_SECTORS || fis->h.command == SAT_READ_DMA)
2750 {
2751 fis->d.sectorCount = 0xFF;
2752 }
2753 else if (fis->h.command == SAT_READ_SECTORS_EXT || fis->h.command == SAT_READ_DMA_EXT)
2754 {
2755 /* SAT_READ_SECTORS_EXT, SAT_READ_DMA_EXT */
2756 fis->d.sectorCount = 0xFF;
2757 fis->d.sectorCountExp = 0xFF;
2758 }
2759 else
2760 {
2761 /* SAT_READ_FPDMA_QUEUED */
2762 fis->h.features = 0xFF;
2763 fis->d.featuresExp = 0xFF;
2764 }
2765
2766 /* chained data */
2767 satIOContext->satCompleteCB = &satChainedDataIOCB;
2768 }
2769
2770 /*
2771 * Prepare SGL and send FIS to LL layer.
2772 */
2773 satIOContext->reqType = agRequestType; /* Save it */
2774
2775 status = sataLLIOStart( tiRoot,
2776 tiIORequest,
2777 tiDeviceHandle,
2778 tiScsiRequest,
2779 satIOContext);
2780
2781 TI_DBG5(("satRead16: return\n"));
2782 return (status);
2783
2784 }
2785
2786 /*****************************************************************************/
2787 /*! \brief SAT implementation for SCSI READ6.
2788 *
2789 * SAT implementation for SCSI READ6 and send FIS request to LL layer.
2790 *
2791 * \param tiRoot: Pointer to TISA initiator driver/port instance.
2792 * \param tiIORequest: Pointer to TISA I/O request context for this I/O.
2793 * \param tiDeviceHandle: Pointer to TISA device handle for this I/O.
2794 * \param tiScsiRequest: Pointer to TISA SCSI I/O request and SGL list.
2795 * \param satIOContext_t: Pointer to the SAT IO Context
2796 *
2797 * \return If command is started successfully
2798 * - \e tiSuccess: I/O request successfully initiated.
2799 * - \e tiBusy: No resources available, try again later.
2800 * - \e tiIONoDevice: Invalid device handle.
2801 * - \e tiError: Other errors.
2802 */
2803 /*****************************************************************************/
2804 GLOBAL bit32 satRead6(
2805 tiRoot_t *tiRoot,
2806 tiIORequest_t *tiIORequest,
2807 tiDeviceHandle_t *tiDeviceHandle,
2808 tiScsiInitiatorRequest_t *tiScsiRequest,
2809 satIOContext_t *satIOContext)
2810 {
2811
2812 bit32 status;
2813 bit32 agRequestType = AGSA_SATA_PROTOCOL_DMA_READ;
2814 satDeviceData_t *pSatDevData;
2815 scsiRspSense_t *pSense;
2816 tiIniScsiCmnd_t *scsiCmnd;
2817 agsaFisRegHostToDevice_t *fis;
2818 bit32 lba = 0;
2819 bit16 tl = 0;
2820
2821 pSense = satIOContext->pSense;
2822 pSatDevData = satIOContext->pSatDevData;
2823 scsiCmnd = &tiScsiRequest->scsiCmnd;
2824 fis = satIOContext->pFis;
2825
2826
2827 TI_DBG5(("satRead6: start\n"));
2828
2829 /* no FUA checking since read6 */
2830
2831
2832 /* checking CONTROL */
2833 /* NACA == 1 or LINK == 1*/
2834 if ( (scsiCmnd->cdb[5] & SCSI_NACA_MASK) || (scsiCmnd->cdb[5] & SCSI_LINK_MASK) )
2835 {
2836 satSetSensePayload( pSense,
2837 SCSI_SNSKEY_ILLEGAL_REQUEST,
2838 0,
2839 SCSI_SNSCODE_INVALID_FIELD_IN_CDB,
2840 satIOContext);
2841
2842 ostiInitiatorIOCompleted( tiRoot,
2843 tiIORequest,
2844 tiIOSuccess,
2845 SCSI_STAT_CHECK_CONDITION,
2846 satIOContext->pTiSenseData,
2847 satIOContext->interruptContext );
2848
2849 TI_DBG2(("satRead6: return control\n"));
2850 return tiSuccess;
2851 }
2852
2853 /* cbd6; computing LBA and transfer length */
2854 lba = (((scsiCmnd->cdb[1]) & 0x1f) << (8*2))
2855 + (scsiCmnd->cdb[2] << 8) + scsiCmnd->cdb[3];
2856 tl = scsiCmnd->cdb[4];
2857
2858
2859 /* Table 34, 9.1, p 46 */
2860 /*
2861 note: As of 2/10/2006, no support for DMA QUEUED
2862 */
2863
2864 /*
2865 Table 34, 9.1, p 46, b
2866 When no 48-bit addressing support or NCQ, if LBA is beyond (2^28 - 1),
2867 return check condition
2868 */
2869 if (pSatDevData->satNCQ != agTRUE &&
2870 pSatDevData->sat48BitSupport != agTRUE
2871 )
2872 {
2873 if (lba > SAT_TR_LBA_LIMIT - 1)
2874 {
2875 satSetSensePayload( pSense,
2876 SCSI_SNSKEY_ILLEGAL_REQUEST,
2877 0,
2878 SCSI_SNSCODE_LOGICAL_BLOCK_ADDRESS_OUT_OF_RANGE,
2879 satIOContext);
2880
2881 ostiInitiatorIOCompleted( tiRoot,
2882 tiIORequest,
2883 tiIOSuccess,
2884 SCSI_STAT_CHECK_CONDITION,
2885 satIOContext->pTiSenseData,
2886 satIOContext->interruptContext );
2887
2888 TI_DBG1(("satRead6: return LBA out of range\n"));
2889 return tiSuccess;
2890 }
2891 }
2892
2893 /* case 1 and 2 */
2894 if (lba + tl <= SAT_TR_LBA_LIMIT)
2895 {
2896 if (pSatDevData->satDMASupport == agTRUE && pSatDevData->satDMAEnabled == agTRUE)
2897 {
2898 /* case 2 */
2899 /* READ DMA*/
2900 TI_DBG5(("satRead6: case 2\n"));
2901
2902
2903 fis->h.fisType = 0x27; /* Reg host to device */
2904 fis->h.c_pmPort = 0x80; /* C Bit is set */
2905 fis->h.command = SAT_READ_DMA; /* 0xC8 */
2906 fis->h.features = 0; /* FIS reserve */
2907 fis->d.lbaLow = scsiCmnd->cdb[3]; /* FIS LBA (7 :0 ) */
2908 fis->d.lbaMid = scsiCmnd->cdb[2]; /* FIS LBA (15:8 ) */
2909 fis->d.lbaHigh = (bit8)((scsiCmnd->cdb[1]) & 0x1f); /* FIS LBA (23:16) */
2910 fis->d.device = 0x40; /* FIS LBA mode */
2911 fis->d.lbaLowExp = 0;
2912 fis->d.lbaMidExp = 0;
2913 fis->d.lbaHighExp = 0;
2914 fis->d.featuresExp = 0;
2915 if (tl == 0)
2916 {
2917 /* temporary fix */
2918 fis->d.sectorCount = 0xff; /* FIS sector count (7:0) */
2919 }
2920 else
2921 {
2922 fis->d.sectorCount = scsiCmnd->cdb[4]; /* FIS sector count (7:0) */
2923 }
2924 fis->d.sectorCountExp = 0;
2925 fis->d.reserved4 = 0;
2926 fis->d.control = 0; /* FIS HOB bit clear */
2927 fis->d.reserved5 = 0;
2928
2929 agRequestType = AGSA_SATA_PROTOCOL_DMA_READ;
2930 }
2931 else
2932 {
2933 /* case 1 */
2934 /* READ SECTORS for easier implemetation */
2935 TI_DBG5(("satRead6: case 1\n"));
2936
2937 fis->h.fisType = 0x27; /* Reg host to device */
2938 fis->h.c_pmPort = 0x80; /* C Bit is set */
2939 fis->h.command = SAT_READ_SECTORS; /* 0x20 */
2940 fis->h.features = 0; /* FIS reserve */
2941 fis->d.lbaLow = scsiCmnd->cdb[3]; /* FIS LBA (7 :0 ) */
2942 fis->d.lbaMid = scsiCmnd->cdb[2]; /* FIS LBA (15:8 ) */
2943 fis->d.lbaHigh = (bit8)((scsiCmnd->cdb[1]) & 0x1f); /* FIS LBA (23:16) */
2944 fis->d.device = 0x40; /* FIS LBA mode */
2945 fis->d.lbaLowExp = 0;
2946 fis->d.lbaMidExp = 0;
2947 fis->d.lbaHighExp = 0;
2948 fis->d.featuresExp = 0;
2949 if (tl == 0)
2950 {
2951 /* temporary fix */
2952 fis->d.sectorCount = 0xff; /* FIS sector count (7:0) */
2953 }
2954 else
2955 {
2956 fis->d.sectorCount = scsiCmnd->cdb[4]; /* FIS sector count (7:0) */
2957 }
2958 fis->d.sectorCountExp = 0;
2959 fis->d.reserved4 = 0;
2960 fis->d.control = 0; /* FIS HOB bit clear */
2961 fis->d.reserved5 = 0;
2962
2963 agRequestType = AGSA_SATA_PROTOCOL_PIO_READ;
2964
2965 }
2966 }
2967
2968 /* case 3 and 4 */
2969 if (pSatDevData->sat48BitSupport == agTRUE)
2970 {
2971 if (pSatDevData->satDMASupport == agTRUE && pSatDevData->satDMAEnabled == agTRUE)
2972 {
2973 /* case 3 */
2974 /* READ DMA EXT only */
2975 TI_DBG5(("satRead6: case 3\n"));
2976 fis->h.fisType = 0x27; /* Reg host to device */
2977 fis->h.c_pmPort = 0x80; /* C Bit is set */
2978 fis->h.command = SAT_READ_DMA_EXT; /* 0x25 */
2979 fis->h.features = 0; /* FIS reserve */
2980 fis->d.lbaLow = scsiCmnd->cdb[3]; /* FIS LBA (7 :0 ) */
2981 fis->d.lbaMid = scsiCmnd->cdb[2]; /* FIS LBA (15:8 ) */
2982 fis->d.lbaHigh = (bit8)((scsiCmnd->cdb[1]) & 0x1f); /* FIS LBA (23:16) */
2983 fis->d.device = 0x40; /* FIS LBA mode set */
2984 fis->d.lbaLowExp = 0; /* FIS LBA (31:24) */
2985 fis->d.lbaMidExp = 0; /* FIS LBA (39:32) */
2986 fis->d.lbaHighExp = 0; /* FIS LBA (47:40) */
2987 fis->d.featuresExp = 0; /* FIS reserve */
2988 if (tl == 0)
2989 {
2990 /* sector count is 256, 0x100*/
2991 fis->d.sectorCount = 0; /* FIS sector count (7:0) */
2992 fis->d.sectorCountExp = 0x01; /* FIS sector count (15:8) */
2993 }
2994 else
2995 {
2996 fis->d.sectorCount = scsiCmnd->cdb[4]; /* FIS sector count (7:0) */
2997 fis->d.sectorCountExp = 0; /* FIS sector count (15:8) */
2998 }
2999 fis->d.reserved4 = 0;
3000 fis->d.control = 0; /* FIS HOB bit clear */
3001 fis->d.reserved5 = 0;
3002
3003 agRequestType = AGSA_SATA_PROTOCOL_DMA_READ;
3004 }
3005 else
3006 {
3007 /* case 4 */
3008 /* READ SECTORS EXT for easier implemetation */
3009 TI_DBG5(("satRead6: case 4\n"));
3010
3011 fis->h.fisType = 0x27; /* Reg host to device */
3012 fis->h.c_pmPort = 0x80; /* C Bit is set */
3013 fis->h.command = SAT_READ_SECTORS_EXT; /* 0x24 */
3014 fis->h.features = 0; /* FIS reserve */
3015 fis->d.lbaLow = scsiCmnd->cdb[3]; /* FIS LBA (7 :0 ) */
3016 fis->d.lbaMid = scsiCmnd->cdb[2]; /* FIS LBA (15:8 ) */
3017 fis->d.lbaHigh = (bit8)((scsiCmnd->cdb[1]) & 0x1f); /* FIS LBA (23:16) */
3018 fis->d.device = 0x40; /* FIS LBA mode set */
3019 fis->d.lbaLowExp = 0; /* FIS LBA (31:24) */
3020 fis->d.lbaMidExp = 0; /* FIS LBA (39:32) */
3021 fis->d.lbaHighExp = 0; /* FIS LBA (47:40) */
3022 fis->d.featuresExp = 0; /* FIS reserve */
3023 if (tl == 0)
3024 {
3025 /* sector count is 256, 0x100*/
3026 fis->d.sectorCount = 0; /* FIS sector count (7:0) */
3027 fis->d.sectorCountExp = 0x01; /* FIS sector count (15:8) */
3028 }
3029 else
3030 {
3031 fis->d.sectorCount = scsiCmnd->cdb[4]; /* FIS sector count (7:0) */
3032 fis->d.sectorCountExp = 0; /* FIS sector count (15:8) */
3033 }
3034 fis->d.reserved4 = 0;
3035 fis->d.control = 0; /* FIS HOB bit clear */
3036 fis->d.reserved5 = 0;
3037
3038 agRequestType = AGSA_SATA_PROTOCOL_PIO_READ;
3039 }
3040 }
3041
3042 /* case 5 */
3043 if (pSatDevData->satNCQ == agTRUE)
3044 {
3045 /* READ FPDMA QUEUED */
3046 if (pSatDevData->sat48BitSupport != agTRUE)
3047 {
3048 /* sanity check */
3049 TI_DBG5(("satRead6: case 5 !!! error NCQ but 28 bit address support \n"));
3050 satSetSensePayload( pSense,
3051 SCSI_SNSKEY_ILLEGAL_REQUEST,
3052 0,
3053 SCSI_SNSCODE_INVALID_FIELD_IN_CDB,
3054 satIOContext);
3055
3056 ostiInitiatorIOCompleted( tiRoot,
3057 tiIORequest,
3058 tiIOSuccess,
3059 SCSI_STAT_CHECK_CONDITION,
3060 satIOContext->pTiSenseData,
3061 satIOContext->interruptContext );
3062 return tiSuccess;
3063 }
3064 TI_DBG5(("satRead6: case 5\n"));
3065
3066 /* Support 48-bit FPDMA addressing, use READ FPDMA QUEUE command */
3067
3068 fis->h.fisType = 0x27; /* Reg host to device */
3069 fis->h.c_pmPort = 0x80; /* C Bit is set */
3070 fis->h.command = SAT_READ_FPDMA_QUEUED; /* 0x60 */
3071 fis->d.lbaLow = scsiCmnd->cdb[3]; /* FIS LBA (7 :0 ) */
3072 fis->d.lbaMid = scsiCmnd->cdb[2]; /* FIS LBA (15:8 ) */
3073 fis->d.lbaHigh = (bit8)((scsiCmnd->cdb[1]) & 0x1f); /* FIS LBA (23:16) */
3074 fis->d.device = 0x40; /* FIS FUA clear */
3075 fis->d.lbaLowExp = 0; /* FIS LBA (31:24) */
3076 fis->d.lbaMidExp = 0; /* FIS LBA (39:32) */
3077 fis->d.lbaHighExp = 0; /* FIS LBA (47:40) */
3078 if (tl == 0)
3079 {
3080 /* sector count is 256, 0x100*/
3081 fis->h.features = 0; /* FIS sector count (7:0) */
3082 fis->d.featuresExp = 0x01; /* FIS sector count (15:8) */
3083 }
3084 else
3085 {
3086 fis->h.features = scsiCmnd->cdb[4]; /* FIS sector count (7:0) */
3087 fis->d.featuresExp = 0; /* FIS sector count (15:8) */
3088 }
3089 fis->d.sectorCount = 0; /* Tag (7:3) set by LL layer */
3090 fis->d.sectorCountExp = 0;
3091 fis->d.reserved4 = 0;
3092 fis->d.control = 0; /* FIS HOB bit clear */
3093 fis->d.reserved5 = 0;
3094
3095 agRequestType = AGSA_SATA_PROTOCOL_FPDMA_READ;
3096 }
3097
3098 /* Initialize CB for SATA completion.
3099 */
3100 satIOContext->satCompleteCB = &satNonChainedDataIOCB;
3101
3102 /*
3103 * Prepare SGL and send FIS to LL layer.
3104 */
3105 satIOContext->reqType = agRequestType; /* Save it */
3106
3107 status = sataLLIOStart( tiRoot,
3108 tiIORequest,
3109 tiDeviceHandle,
3110 tiScsiRequest,
3111 satIOContext);
3112 return (status);
3113
3114 }
3115
3116 /*****************************************************************************/
3117 /*! \brief SAT implementation for SCSI WRITE16.
3118 *
3119 * SAT implementation for SCSI WRITE16 and send FIS request to LL layer.
3120 *
3121 * \param tiRoot: Pointer to TISA initiator driver/port instance.
3122 * \param tiIORequest: Pointer to TISA I/O request context for this I/O.
3123 * \param tiDeviceHandle: Pointer to TISA device handle for this I/O.
3124 * \param tiScsiRequest: Pointer to TISA SCSI I/O request and SGL list.
3125 * \param satIOContext_t: Pointer to the SAT IO Context
3126 *
3127 * \return If command is started successfully
3128 * - \e tiSuccess: I/O request successfully initiated.
3129 * - \e tiBusy: No resources available, try again later.
3130 * - \e tiIONoDevice: Invalid device handle.
3131 * - \e tiError: Other errors.
3132 */
3133 /*****************************************************************************/
3134 GLOBAL bit32 satWrite16(
3135 tiRoot_t *tiRoot,
3136 tiIORequest_t *tiIORequest,
3137 tiDeviceHandle_t *tiDeviceHandle,
3138 tiScsiInitiatorRequest_t *tiScsiRequest,
3139 satIOContext_t *satIOContext)
3140 {
3141 bit32 status;
3142 bit32 agRequestType = AGSA_SATA_PROTOCOL_DMA_WRITE;
3143 satDeviceData_t *pSatDevData;
3144 scsiRspSense_t *pSense;
3145 tiIniScsiCmnd_t *scsiCmnd;
3146 agsaFisRegHostToDevice_t *fis;
3147 bit32 lba = 0;
3148 bit32 tl = 0;
3149 bit32 LoopNum = 1;
3150 bit8 LBA[8];
3151 bit8 TL[8];
3152 bit32 rangeChk = agFALSE; /* lba and tl range check */
3153 bit32 limitChk = agFALSE; /* lba and tl range check */
3154
3155 pSense = satIOContext->pSense;
3156 pSatDevData = satIOContext->pSatDevData;
3157 scsiCmnd = &tiScsiRequest->scsiCmnd;
3158 fis = satIOContext->pFis;
3159
3160 TI_DBG5(("satWrite16: start\n"));
3161
3162 /* checking FUA_NV */
3163 if (scsiCmnd->cdb[1] & SCSI_FUA_NV_MASK)
3164 {
3165 satSetSensePayload( pSense,
3166 SCSI_SNSKEY_ILLEGAL_REQUEST,
3167 0,
3168 SCSI_SNSCODE_INVALID_FIELD_IN_CDB,
3169 satIOContext);
3170
3171 ostiInitiatorIOCompleted( tiRoot,
3172 tiIORequest,
3173 tiIOSuccess,
3174 SCSI_STAT_CHECK_CONDITION,
3175 satIOContext->pTiSenseData,
3176 satIOContext->interruptContext );
3177
3178 TI_DBG1(("satWrite16: return FUA_NV\n"));
3179 return tiSuccess;
3180
3181 }
3182
3183 /* checking CONTROL */
3184 /* NACA == 1 or LINK == 1*/
3185 if ( (scsiCmnd->cdb[15] & SCSI_NACA_MASK) || (scsiCmnd->cdb[15] & SCSI_LINK_MASK) )
3186 {
3187 satSetSensePayload( pSense,
3188 SCSI_SNSKEY_ILLEGAL_REQUEST,
3189 0,
3190 SCSI_SNSCODE_INVALID_FIELD_IN_CDB,
3191 satIOContext);
3192
3193 ostiInitiatorIOCompleted( tiRoot,
3194 tiIORequest,
3195 tiIOSuccess,
3196 SCSI_STAT_CHECK_CONDITION,
3197 satIOContext->pTiSenseData,
3198 satIOContext->interruptContext );
3199
3200 TI_DBG1(("satWrite16: return control\n"));
3201 return tiSuccess;
3202 }
3203
3204
3205 osti_memset(LBA, 0, sizeof(LBA));
3206 osti_memset(TL, 0, sizeof(TL));
3207
3208
3209 /* do not use memcpy due to indexing in LBA and TL */
3210 LBA[0] = scsiCmnd->cdb[2]; /* MSB */
3211 LBA[1] = scsiCmnd->cdb[3];
3212 LBA[2] = scsiCmnd->cdb[4];
3213 LBA[3] = scsiCmnd->cdb[5];
3214 LBA[4] = scsiCmnd->cdb[6];
3215 LBA[5] = scsiCmnd->cdb[7];
3216 LBA[6] = scsiCmnd->cdb[8];
3217 LBA[7] = scsiCmnd->cdb[9]; /* LSB */
3218
3219 TL[0] = 0;
3220 TL[1] = 0;
3221 TL[2] = 0;
3222 TL[3] = 0;
3223 TL[4] = scsiCmnd->cdb[10]; /* MSB */
3224 TL[5] = scsiCmnd->cdb[11];
3225 TL[6] = scsiCmnd->cdb[12];
3226 TL[7] = scsiCmnd->cdb[13]; /* LSB */
3227
3228 rangeChk = satAddNComparebit64(LBA, TL);
3229
3230 limitChk = satCompareLBALimitbit(LBA);
3231
3232 lba = satComputeCDB16LBA(satIOContext);
3233 tl = satComputeCDB16TL(satIOContext);
3234
3235
3236
3237 /* Table 34, 9.1, p 46 */
3238 /*
3239 note: As of 2/10/2006, no support for DMA QUEUED
3240 */
3241
3242 /*
3243 Table 34, 9.1, p 46, b
3244 When no 48-bit addressing support or NCQ, if LBA is beyond (2^28 - 1),
3245 return check condition
3246 */
3247 if (pSatDevData->satNCQ != agTRUE &&
3248 pSatDevData->sat48BitSupport != agTRUE
3249 )
3250 {
3251 if (limitChk)
3252 {
3253 TI_DBG1(("satWrite16: return LBA out of range, not EXT\n"));
3254 satSetSensePayload( pSense,
3255 SCSI_SNSKEY_ILLEGAL_REQUEST,
3256 0,
3257 SCSI_SNSCODE_LOGICAL_BLOCK_ADDRESS_OUT_OF_RANGE,
3258 satIOContext);
3259
3260 ostiInitiatorIOCompleted( tiRoot,
3261 tiIORequest,
3262 tiIOSuccess,
3263 SCSI_STAT_CHECK_CONDITION,
3264 satIOContext->pTiSenseData,
3265 satIOContext->interruptContext );
3266
3267 return tiSuccess;
3268 }
3269 if (rangeChk) // if (lba + tl > SAT_TR_LBA_LIMIT)
3270 {
3271 TI_DBG1(("satWrite16: return LBA+TL out of range, not EXT\n"));
3272 satSetSensePayload( pSense,
3273 SCSI_SNSKEY_ILLEGAL_REQUEST,
3274 0,
3275 SCSI_SNSCODE_LOGICAL_BLOCK_ADDRESS_OUT_OF_RANGE,
3276 satIOContext);
3277
3278 ostiInitiatorIOCompleted( tiRoot,
3279 tiIORequest,
3280 tiIOSuccess,
3281 SCSI_STAT_CHECK_CONDITION,
3282 satIOContext->pTiSenseData,
3283 satIOContext->interruptContext );
3284
3285 return tiSuccess;
3286 }
3287 }
3288
3289 /* case 1 and 2 */
3290 if (!rangeChk) // if (lba + tl <= SAT_TR_LBA_LIMIT)
3291 {
3292 if (pSatDevData->satDMASupport == agTRUE && pSatDevData->satDMAEnabled == agTRUE)
3293 {
3294 /* case 2 */
3295 /* WRITE DMA*/
3296 /* In case that we can't fit the transfer length, we loop */
3297 TI_DBG5(("satWrite16: case 2\n"));
3298 fis->h.fisType = 0x27; /* Reg host to device */
3299 fis->h.c_pmPort = 0x80; /* C bit is set */
3300 fis->h.command = SAT_WRITE_DMA; /* 0xCA */
3301 fis->h.features = 0; /* FIS reserve */
3302 fis->d.lbaLow = scsiCmnd->cdb[9]; /* FIS LBA (7 :0 ) */
3303 fis->d.lbaMid = scsiCmnd->cdb[8]; /* FIS LBA (15:8 ) */
3304 fis->d.lbaHigh = scsiCmnd->cdb[7]; /* FIS LBA (23:16) */
3305
3306 /* FIS LBA mode set LBA (27:24) */
3307 fis->d.device = (bit8)((0x4 << 4) | (scsiCmnd->cdb[6] & 0xF));
3308
3309 fis->d.lbaLowExp = 0;
3310 fis->d.lbaMidExp = 0;
3311 fis->d.lbaHighExp = 0;
3312 fis->d.featuresExp = 0;
3313 fis->d.sectorCount = scsiCmnd->cdb[13]; /* FIS sector count (7:0) */
3314 fis->d.sectorCountExp = 0;
3315 fis->d.reserved4 = 0;
3316 fis->d.control = 0; /* FIS HOB bit clear */
3317 fis->d.reserved5 = 0;
3318
3319 agRequestType = AGSA_SATA_PROTOCOL_DMA_WRITE;
3320 satIOContext->ATACmd = SAT_WRITE_DMA;
3321 }
3322 else
3323 {
3324 /* case 1 */
3325 /* WRITE MULTIPLE or WRITE SECTOR(S) */
3326 /* WRITE SECTORS for easier implemetation */
3327 /* In case that we can't fit the transfer length, we loop */
3328 TI_DBG5(("satWrite16: case 1\n"));
3329 fis->h.fisType = 0x27; /* Reg host to device */
3330 fis->h.c_pmPort = 0x80; /* C bit is set */
3331 fis->h.command = SAT_WRITE_SECTORS; /* 0x30 */
3332 fis->h.features = 0; /* FIS reserve */
3333 fis->d.lbaLow = scsiCmnd->cdb[9]; /* FIS LBA (7 :0 ) */
3334 fis->d.lbaMid = scsiCmnd->cdb[8]; /* FIS LBA (15:8 ) */
3335 fis->d.lbaHigh = scsiCmnd->cdb[7]; /* FIS LBA (23:16) */
3336
3337 /* FIS LBA mode set LBA (27:24) */
3338 fis->d.device = (bit8)((0x4 << 4) | (scsiCmnd->cdb[6] & 0xF));
3339
3340 fis->d.lbaLowExp = 0;
3341 fis->d.lbaMidExp = 0;
3342 fis->d.lbaHighExp = 0;
3343 fis->d.featuresExp = 0;
3344 fis->d.sectorCount = scsiCmnd->cdb[13]; /* FIS sector count (7:0) */
3345 fis->d.sectorCountExp = 0;
3346 fis->d.reserved4 = 0;
3347 fis->d.control = 0; /* FIS HOB bit clear */
3348 fis->d.reserved5 = 0;
3349
3350 agRequestType = AGSA_SATA_PROTOCOL_PIO_WRITE;
3351 satIOContext->ATACmd = SAT_WRITE_SECTORS;
3352 }
3353 }
3354
3355 /* case 3 and 4 */
3356 if (pSatDevData->sat48BitSupport == agTRUE)
3357 {
3358 if (pSatDevData->satDMASupport == agTRUE && pSatDevData->satDMAEnabled == agTRUE)
3359 {
3360 /* case 3 */
3361 /* WRITE DMA EXT or WRITE DMA FUA EXT */
3362 TI_DBG5(("satWrite16: case 3\n"));
3363 fis->h.fisType = 0x27; /* Reg host to device */
3364 fis->h.c_pmPort = 0x80; /* C Bit is set */
3365
3366 /* SAT_WRITE_DMA_FUA_EXT is optional and we don't support it */
3367 fis->h.command = SAT_WRITE_DMA_EXT; /* 0x35 */
3368
3369 fis->h.features = 0; /* FIS reserve */
3370 fis->d.lbaLow = scsiCmnd->cdb[9]; /* FIS LBA (7 :0 ) */
3371 fis->d.lbaMid = scsiCmnd->cdb[8]; /* FIS LBA (15:8 ) */
3372 fis->d.lbaHigh = scsiCmnd->cdb[7]; /* FIS LBA (23:16) */
3373 fis->d.device = 0x40; /* FIS LBA mode set */
3374 fis->d.lbaLowExp = scsiCmnd->cdb[6]; /* FIS LBA (31:24) */
3375 fis->d.lbaMidExp = scsiCmnd->cdb[5]; /* FIS LBA (39:32) */
3376 fis->d.lbaHighExp = scsiCmnd->cdb[4]; /* FIS LBA (47:40) */
3377 fis->d.featuresExp = 0; /* FIS reserve */
3378 fis->d.sectorCount = scsiCmnd->cdb[13]; /* FIS sector count (7:0) */
3379 fis->d.sectorCountExp = scsiCmnd->cdb[12]; /* FIS sector count (15:8) */
3380 fis->d.reserved4 = 0;
3381 fis->d.control = 0; /* FIS HOB bit clear */
3382 fis->d.reserved5 = 0;
3383
3384 agRequestType = AGSA_SATA_PROTOCOL_DMA_WRITE;
3385 satIOContext->ATACmd = SAT_WRITE_DMA_EXT;
3386 }
3387 else
3388 {
3389 /* case 4 */
3390 /* WRITE MULTIPLE EXT or WRITE MULTIPLE FUA EXT or WRITE SECTOR(S) EXT */
3391 /* WRITE SECTORS EXT for easier implemetation */
3392 TI_DBG5(("satWrite16: case 4\n"));
3393 fis->h.fisType = 0x27; /* Reg host to device */
3394 fis->h.c_pmPort = 0x80; /* C Bit is set */
3395 fis->h.command = SAT_WRITE_SECTORS_EXT; /* 0x34 */
3396
3397 fis->h.features = 0; /* FIS reserve */
3398 fis->d.lbaLow = scsiCmnd->cdb[9]; /* FIS LBA (7 :0 ) */
3399 fis->d.lbaMid = scsiCmnd->cdb[8]; /* FIS LBA (15:8 ) */
3400 fis->d.lbaHigh = scsiCmnd->cdb[7]; /* FIS LBA (23:16) */
3401 fis->d.device = 0x40; /* FIS LBA mode set */
3402 fis->d.lbaLowExp = scsiCmnd->cdb[6]; /* FIS LBA (31:24) */
3403 fis->d.lbaMidExp = scsiCmnd->cdb[5]; /* FIS LBA (39:32) */
3404 fis->d.lbaHighExp = scsiCmnd->cdb[4]; /* FIS LBA (47:40) */
3405 fis->d.featuresExp = 0; /* FIS reserve */
3406 fis->d.sectorCount = scsiCmnd->cdb[13]; /* FIS sector count (7:0) */
3407 fis->d.sectorCountExp = scsiCmnd->cdb[12]; /* FIS sector count (15:8) */
3408 fis->d.reserved4 = 0;
3409 fis->d.control = 0; /* FIS HOB bit clear */
3410 fis->d.reserved5 = 0;
3411
3412 agRequestType = AGSA_SATA_PROTOCOL_PIO_WRITE;
3413 satIOContext->ATACmd = SAT_WRITE_SECTORS_EXT;
3414 }
3415 }
3416
3417 /* case 5 */
3418 if (pSatDevData->satNCQ == agTRUE)
3419 {
3420 /* WRITE FPDMA QUEUED */
3421 if (pSatDevData->sat48BitSupport != agTRUE)
3422 {
3423 TI_DBG5(("satWrite16: case 5 !!! error NCQ but 28 bit address support \n"));
3424 satSetSensePayload( pSense,
3425 SCSI_SNSKEY_ILLEGAL_REQUEST,
3426 0,
3427 SCSI_SNSCODE_INVALID_FIELD_IN_CDB,
3428 satIOContext);
3429
3430 ostiInitiatorIOCompleted( tiRoot,
3431 tiIORequest,
3432 tiIOSuccess,
3433 SCSI_STAT_CHECK_CONDITION,
3434 satIOContext->pTiSenseData,
3435 satIOContext->interruptContext );
3436 return tiSuccess;
3437 }
3438 TI_DBG6(("satWrite16: case 5\n"));
3439
3440 /* Support 48-bit FPDMA addressing, use WRITE FPDMA QUEUE command */
3441
3442 fis->h.fisType = 0x27; /* Reg host to device */
3443 fis->h.c_pmPort = 0x80; /* C Bit is set */
3444 fis->h.command = SAT_WRITE_FPDMA_QUEUED; /* 0x61 */
3445 fis->h.features = scsiCmnd->cdb[13]; /* FIS sector count (7:0) */
3446 fis->d.lbaLow = scsiCmnd->cdb[9]; /* FIS LBA (7 :0 ) */
3447 fis->d.lbaMid = scsiCmnd->cdb[8]; /* FIS LBA (15:8 ) */
3448 fis->d.lbaHigh = scsiCmnd->cdb[7]; /* FIS LBA (23:16) */
3449
3450 /* Check FUA bit */
3451 if (scsiCmnd->cdb[1] & SCSI_WRITE16_FUA_MASK)
3452 fis->d.device = 0xC0; /* FIS FUA set */
3453 else
3454 fis->d.device = 0x40; /* FIS FUA clear */
3455
3456 fis->d.lbaLowExp = scsiCmnd->cdb[6]; /* FIS LBA (31:24) */
3457 fis->d.lbaMidExp = scsiCmnd->cdb[5]; /* FIS LBA (39:32) */
3458 fis->d.lbaHighExp = scsiCmnd->cdb[4]; /* FIS LBA (47:40) */
3459 fis->d.featuresExp = scsiCmnd->cdb[12]; /* FIS sector count (15:8) */
3460 fis->d.sectorCount = 0; /* Tag (7:3) set by LL layer */
3461 fis->d.sectorCountExp = 0;
3462 fis->d.reserved4 = 0;
3463 fis->d.control = 0; /* FIS HOB bit clear */
3464 fis->d.reserved5 = 0;
3465
3466 agRequestType = AGSA_SATA_PROTOCOL_FPDMA_WRITE;
3467 satIOContext->ATACmd = SAT_WRITE_FPDMA_QUEUED;
3468 }
3469
3470 satIOContext->currentLBA = lba;
3471 satIOContext->OrgTL = tl;
3472
3473 /*
3474 computing number of loop and remainder for tl
3475 0xFF in case not ext
3476 0xFFFF in case EXT
3477 */
3478 if (fis->h.command == SAT_WRITE_SECTORS || fis->h.command == SAT_WRITE_DMA)
3479 {
3480 LoopNum = satComputeLoopNum(tl, 0xFF);
3481 }
3482 else if (fis->h.command == SAT_WRITE_SECTORS_EXT ||
3483 fis->h.command == SAT_WRITE_DMA_EXT ||
3484 fis->h.command == SAT_WRITE_DMA_FUA_EXT
3485 )
3486 {
3487 /* SAT_READ_SECTORS_EXT, SAT_READ_DMA_EXT */
3488 LoopNum = satComputeLoopNum(tl, 0xFFFF);
3489 }
3490 else
3491 {
3492 /* SAT_WRITE_FPDMA_QUEUEDK */
3493 LoopNum = satComputeLoopNum(tl, 0xFFFF);
3494 }
3495
3496 satIOContext->LoopNum = LoopNum;
3497
3498
3499 if (LoopNum == 1)
3500 {
3501 TI_DBG5(("satWrite16: NON CHAINED data\n"));
3502 /* Initialize CB for SATA completion.
3503 */
3504 satIOContext->satCompleteCB = &satNonChainedDataIOCB;
3505 }
3506 else
3507 {
3508 TI_DBG1(("satWrite16: CHAINED data\n"));
3509 /* re-setting tl */
3510 if (fis->h.command == SAT_WRITE_SECTORS || fis->h.command == SAT_WRITE_DMA)
3511 {
3512 fis->d.sectorCount = 0xFF;
3513 }
3514 else if (fis->h.command == SAT_WRITE_SECTORS_EXT ||
3515 fis->h.command == SAT_WRITE_DMA_EXT ||
3516 fis->h.command == SAT_WRITE_DMA_FUA_EXT
3517 )
3518 {
3519 fis->d.sectorCount = 0xFF;
3520 fis->d.sectorCountExp = 0xFF;
3521 }
3522 else
3523 {
3524 /* SAT_WRITE_FPDMA_QUEUED */
3525 fis->h.features = 0xFF;
3526 fis->d.featuresExp = 0xFF;
3527 }
3528
3529 /* Initialize CB for SATA completion.
3530 */
3531 satIOContext->satCompleteCB = &satChainedDataIOCB;
3532 }
3533
3534
3535 /*
3536 * Prepare SGL and send FIS to LL layer.
3537 */
3538 satIOContext->reqType = agRequestType; /* Save it */
3539
3540 status = sataLLIOStart( tiRoot,
3541 tiIORequest,
3542 tiDeviceHandle,
3543 tiScsiRequest,
3544 satIOContext);
3545 return (status);
3546 }
3547
3548 /*****************************************************************************/
3549 /*! \brief SAT implementation for SCSI WRITE12.
3550 *
3551 * SAT implementation for SCSI WRITE12 and send FIS request to LL layer.
3552 *
3553 * \param tiRoot: Pointer to TISA initiator driver/port instance.
3554 * \param tiIORequest: Pointer to TISA I/O request context for this I/O.
3555 * \param tiDeviceHandle: Pointer to TISA device handle for this I/O.
3556 * \param tiScsiRequest: Pointer to TISA SCSI I/O request and SGL list.
3557 * \param satIOContext_t: Pointer to the SAT IO Context
3558 *
3559 * \return If command is started successfully
3560 * - \e tiSuccess: I/O request successfully initiated.
3561 * - \e tiBusy: No resources available, try again later.
3562 * - \e tiIONoDevice: Invalid device handle.
3563 * - \e tiError: Other errors.
3564 */
3565 /*****************************************************************************/
3566 GLOBAL bit32 satWrite12(
3567 tiRoot_t *tiRoot,
3568 tiIORequest_t *tiIORequest,
3569 tiDeviceHandle_t *tiDeviceHandle,
3570 tiScsiInitiatorRequest_t *tiScsiRequest,
3571 satIOContext_t *satIOContext)
3572 {
3573 bit32 status;
3574 bit32 agRequestType = AGSA_SATA_PROTOCOL_DMA_WRITE;
3575 satDeviceData_t *pSatDevData;
3576 scsiRspSense_t *pSense;
3577 tiIniScsiCmnd_t *scsiCmnd;
3578 agsaFisRegHostToDevice_t *fis;
3579 bit32 lba = 0;
3580 bit32 tl = 0;
3581 bit32 LoopNum = 1;
3582 bit8 LBA[4];
3583 bit8 TL[4];
3584 bit32 rangeChk = agFALSE; /* lba and tl range check */
3585
3586 pSense = satIOContext->pSense;
3587 pSatDevData = satIOContext->pSatDevData;
3588 scsiCmnd = &tiScsiRequest->scsiCmnd;
3589 fis = satIOContext->pFis;
3590
3591 TI_DBG5(("satWrite12: start\n"));
3592
3593 /* checking FUA_NV */
3594 if (scsiCmnd->cdb[1] & SCSI_FUA_NV_MASK)
3595 {
3596 satSetSensePayload( pSense,
3597 SCSI_SNSKEY_ILLEGAL_REQUEST,
3598 0,
3599 SCSI_SNSCODE_INVALID_FIELD_IN_CDB,
3600 satIOContext);
3601
3602 ostiInitiatorIOCompleted( tiRoot,
3603 tiIORequest,
3604 tiIOSuccess,
3605 SCSI_STAT_CHECK_CONDITION,
3606 satIOContext->pTiSenseData,
3607 satIOContext->interruptContext );
3608
3609 TI_DBG1(("satWrite12: return FUA_NV\n"));
3610 return tiSuccess;
3611
3612 }
3613
3614
3615 /* checking CONTROL */
3616 /* NACA == 1 or LINK == 1*/
3617 if ( (scsiCmnd->cdb[11] & SCSI_NACA_MASK) || (scsiCmnd->cdb[11] & SCSI_LINK_MASK) )
3618 {
3619 satSetSensePayload( pSense,
3620 SCSI_SNSKEY_ILLEGAL_REQUEST,
3621 0,
3622 SCSI_SNSCODE_INVALID_FIELD_IN_CDB,
3623 satIOContext);
3624
3625 ostiInitiatorIOCompleted( tiRoot,
3626 tiIORequest,
3627 tiIOSuccess,
3628 SCSI_STAT_CHECK_CONDITION,
3629 satIOContext->pTiSenseData,
3630 satIOContext->interruptContext );
3631
3632 TI_DBG1(("satWrite12: return control\n"));
3633 return tiSuccess;
3634 }
3635
3636
3637 osti_memset(LBA, 0, sizeof(LBA));
3638 osti_memset(TL, 0, sizeof(TL));
3639
3640 /* do not use memcpy due to indexing in LBA and TL */
3641 LBA[0] = scsiCmnd->cdb[2]; /* MSB */
3642 LBA[1] = scsiCmnd->cdb[3];
3643 LBA[2] = scsiCmnd->cdb[4];
3644 LBA[3] = scsiCmnd->cdb[5]; /* LSB */
3645
3646 TL[0] = scsiCmnd->cdb[6]; /* MSB */
3647 TL[1] = scsiCmnd->cdb[7];
3648 TL[2] = scsiCmnd->cdb[8];
3649 TL[3] = scsiCmnd->cdb[9]; /* LSB */
3650
3651 rangeChk = satAddNComparebit32(LBA, TL);
3652
3653 lba = satComputeCDB12LBA(satIOContext);
3654 tl = satComputeCDB12TL(satIOContext);
3655
3656
3657 /* Table 34, 9.1, p 46 */
3658 /*
3659 note: As of 2/10/2006, no support for DMA QUEUED
3660 */
3661
3662 /*
3663 Table 34, 9.1, p 46, b
3664 When no 48-bit addressing support or NCQ, if LBA is beyond (2^28 - 1),
3665 return check condition
3666 */
3667 if (pSatDevData->satNCQ != agTRUE &&
3668 pSatDevData->sat48BitSupport != agTRUE
3669 )
3670 {
3671 if (lba > SAT_TR_LBA_LIMIT - 1)
3672 {
3673 satSetSensePayload( pSense,
3674 SCSI_SNSKEY_ILLEGAL_REQUEST,
3675 0,
3676 SCSI_SNSCODE_LOGICAL_BLOCK_ADDRESS_OUT_OF_RANGE,
3677 satIOContext);
3678
3679 ostiInitiatorIOCompleted( tiRoot,
3680 tiIORequest,
3681 tiIOSuccess,
3682 SCSI_STAT_CHECK_CONDITION,
3683 satIOContext->pTiSenseData,
3684 satIOContext->interruptContext );
3685
3686 TI_DBG1(("satWrite12: return LBA out of range, not EXT\n"));
3687 return tiSuccess;
3688 }
3689
3690 if (rangeChk) // if (lba + tl > SAT_TR_LBA_LIMIT)
3691 {
3692 TI_DBG1(("satWrite12: return LBA+TL out of range, not EXT\n"));
3693 satSetSensePayload( pSense,
3694 SCSI_SNSKEY_ILLEGAL_REQUEST,
3695 0,
3696 SCSI_SNSCODE_LOGICAL_BLOCK_ADDRESS_OUT_OF_RANGE,
3697 satIOContext);
3698
3699 ostiInitiatorIOCompleted( tiRoot,
3700 tiIORequest,
3701 tiIOSuccess,
3702 SCSI_STAT_CHECK_CONDITION,
3703 satIOContext->pTiSenseData,
3704 satIOContext->interruptContext );
3705
3706 return tiSuccess;
3707 }
3708 }
3709
3710
3711 /* case 1 and 2 */
3712 if (!rangeChk) // if (lba + tl <= SAT_TR_LBA_LIMIT)
3713 {
3714 if (pSatDevData->satDMASupport == agTRUE && pSatDevData->satDMAEnabled == agTRUE)
3715 {
3716 /* case 2 */
3717 /* WRITE DMA*/
3718 /* In case that we can't fit the transfer length, we loop */
3719 TI_DBG5(("satWrite12: case 2\n"));
3720 fis->h.fisType = 0x27; /* Reg host to device */
3721 fis->h.c_pmPort = 0x80; /* C bit is set */
3722 fis->h.command = SAT_WRITE_DMA; /* 0xCA */
3723 fis->h.features = 0; /* FIS reserve */
3724 fis->d.lbaLow = scsiCmnd->cdb[5]; /* FIS LBA (7 :0 ) */
3725 fis->d.lbaMid = scsiCmnd->cdb[4]; /* FIS LBA (15:8 ) */
3726 fis->d.lbaHigh = scsiCmnd->cdb[3]; /* FIS LBA (23:16) */
3727
3728 /* FIS LBA mode set LBA (27:24) */
3729 fis->d.device = (bit8)((0x4 << 4) | (scsiCmnd->cdb[2] & 0xF));
3730
3731 fis->d.lbaLowExp = 0;
3732 fis->d.lbaMidExp = 0;
3733 fis->d.lbaHighExp = 0;
3734 fis->d.featuresExp = 0;
3735 fis->d.sectorCount = scsiCmnd->cdb[9]; /* FIS sector count (7:0) */
3736 fis->d.sectorCountExp = 0;
3737 fis->d.reserved4 = 0;
3738 fis->d.control = 0; /* FIS HOB bit clear */
3739 fis->d.reserved5 = 0;
3740
3741 agRequestType = AGSA_SATA_PROTOCOL_DMA_WRITE;
3742 satIOContext->ATACmd = SAT_WRITE_DMA;
3743 }
3744 else
3745 {
3746 /* case 1 */
3747 /* WRITE MULTIPLE or WRITE SECTOR(S) */
3748 /* WRITE SECTORS for easier implemetation */
3749 /* In case that we can't fit the transfer length, we loop */
3750 TI_DBG5(("satWrite12: case 1\n"));
3751 fis->h.fisType = 0x27; /* Reg host to device */
3752 fis->h.c_pmPort = 0x80; /* C bit is set */
3753 fis->h.command = SAT_WRITE_SECTORS; /* 0x30 */
3754 fis->h.features = 0; /* FIS reserve */
3755 fis->d.lbaLow = scsiCmnd->cdb[5]; /* FIS LBA (7 :0 ) */
3756 fis->d.lbaMid = scsiCmnd->cdb[4]; /* FIS LBA (15:8 ) */
3757 fis->d.lbaHigh = scsiCmnd->cdb[3]; /* FIS LBA (23:16) */
3758
3759 /* FIS LBA mode set LBA (27:24) */
3760 fis->d.device = (bit8)((0x4 << 4) | (scsiCmnd->cdb[2] & 0xF));
3761
3762 fis->d.lbaLowExp = 0;
3763 fis->d.lbaMidExp = 0;
3764 fis->d.lbaHighExp = 0;
3765 fis->d.featuresExp = 0;
3766 fis->d.sectorCount = scsiCmnd->cdb[9]; /* FIS sector count (7:0) */
3767 fis->d.sectorCountExp = 0;
3768 fis->d.reserved4 = 0;
3769 fis->d.control = 0; /* FIS HOB bit clear */
3770 fis->d.reserved5 = 0;
3771
3772 agRequestType = AGSA_SATA_PROTOCOL_PIO_WRITE;
3773 satIOContext->ATACmd = SAT_WRITE_SECTORS;
3774 }
3775 }
3776
3777 /* case 3 and 4 */
3778 if (pSatDevData->sat48BitSupport == agTRUE)
3779 {
3780 if (pSatDevData->satDMASupport == agTRUE && pSatDevData->satDMAEnabled == agTRUE)
3781 {
3782 /* case 3 */
3783 /* WRITE DMA EXT or WRITE DMA FUA EXT */
3784 TI_DBG5(("satWrite12: case 3\n"));
3785 fis->h.fisType = 0x27; /* Reg host to device */
3786 fis->h.c_pmPort = 0x80; /* C Bit is set */
3787
3788 /* SAT_WRITE_DMA_FUA_EXT is optional and we don't support it */
3789 fis->h.command = SAT_WRITE_DMA_EXT; /* 0x35 */
3790
3791 fis->h.features = 0; /* FIS reserve */
3792 fis->d.lbaLow = scsiCmnd->cdb[5]; /* FIS LBA (7 :0 ) */
3793 fis->d.lbaMid = scsiCmnd->cdb[4]; /* FIS LBA (15:8 ) */
3794 fis->d.lbaHigh = scsiCmnd->cdb[3]; /* FIS LBA (23:16) */
3795 fis->d.device = 0x40; /* FIS LBA mode set */
3796 fis->d.lbaLowExp = scsiCmnd->cdb[2]; /* FIS LBA (31:24) */
3797 fis->d.lbaMidExp = 0; /* FIS LBA (39:32) */
3798 fis->d.lbaHighExp = 0; /* FIS LBA (47:40) */
3799 fis->d.featuresExp = 0; /* FIS reserve */
3800 fis->d.sectorCount = scsiCmnd->cdb[9]; /* FIS sector count (7:0) */
3801 fis->d.sectorCountExp = scsiCmnd->cdb[8]; /* FIS sector count (15:8) */
3802 fis->d.reserved4 = 0;
3803 fis->d.control = 0; /* FIS HOB bit clear */
3804 fis->d.reserved5 = 0;
3805
3806 agRequestType = AGSA_SATA_PROTOCOL_DMA_WRITE;
3807 satIOContext->ATACmd = SAT_WRITE_DMA_EXT;
3808 }
3809 else
3810 {
3811 /* case 4 */
3812 /* WRITE MULTIPLE EXT or WRITE MULTIPLE FUA EXT or WRITE SECTOR(S) EXT */
3813 /* WRITE SECTORS EXT for easier implemetation */
3814 TI_DBG5(("satWrite12: case 4\n"));
3815 fis->h.fisType = 0x27; /* Reg host to device */
3816 fis->h.c_pmPort = 0x80; /* C Bit is set */
3817 fis->h.command = SAT_WRITE_SECTORS_EXT; /* 0x34 */
3818
3819 fis->h.features = 0; /* FIS reserve */
3820 fis->d.lbaLow = scsiCmnd->cdb[5]; /* FIS LBA (7 :0 ) */
3821 fis->d.lbaMid = scsiCmnd->cdb[4]; /* FIS LBA (15:8 ) */
3822 fis->d.lbaHigh = scsiCmnd->cdb[3]; /* FIS LBA (23:16) */
3823 fis->d.device = 0x40; /* FIS LBA mode set */
3824 fis->d.lbaLowExp = scsiCmnd->cdb[2]; /* FIS LBA (31:24) */
3825 fis->d.lbaMidExp = 0; /* FIS LBA (39:32) */
3826 fis->d.lbaHighExp = 0; /* FIS LBA (47:40) */
3827 fis->d.featuresExp = 0; /* FIS reserve */
3828 fis->d.sectorCount = scsiCmnd->cdb[9]; /* FIS sector count (7:0) */
3829 fis->d.sectorCountExp = scsiCmnd->cdb[8]; /* FIS sector count (15:8) */
3830 fis->d.reserved4 = 0;
3831 fis->d.control = 0; /* FIS HOB bit clear */
3832 fis->d.reserved5 = 0;
3833
3834 agRequestType = AGSA_SATA_PROTOCOL_PIO_WRITE;
3835 satIOContext->ATACmd = SAT_WRITE_SECTORS_EXT;
3836 }
3837 }
3838
3839 /* case 5 */
3840 if (pSatDevData->satNCQ == agTRUE)
3841 {
3842 /* WRITE FPDMA QUEUED */
3843 if (pSatDevData->sat48BitSupport != agTRUE)
3844 {
3845 TI_DBG5(("satWrite12: case 5 !!! error NCQ but 28 bit address support \n"));
3846 satSetSensePayload( pSense,
3847 SCSI_SNSKEY_ILLEGAL_REQUEST,
3848 0,
3849 SCSI_SNSCODE_INVALID_FIELD_IN_CDB,
3850 satIOContext);
3851
3852 ostiInitiatorIOCompleted( tiRoot,
3853 tiIORequest,
3854 tiIOSuccess,
3855 SCSI_STAT_CHECK_CONDITION,
3856 satIOContext->pTiSenseData,
3857 satIOContext->interruptContext );
3858 return tiSuccess;
3859 }
3860 TI_DBG6(("satWrite12: case 5\n"));
3861
3862 /* Support 48-bit FPDMA addressing, use WRITE FPDMA QUEUE command */
3863
3864 fis->h.fisType = 0x27; /* Reg host to device */
3865 fis->h.c_pmPort = 0x80; /* C Bit is set */
3866 fis->h.command = SAT_WRITE_FPDMA_QUEUED; /* 0x61 */
3867 fis->h.features = scsiCmnd->cdb[9]; /* FIS sector count (7:0) */
3868 fis->d.lbaLow = scsiCmnd->cdb[5]; /* FIS LBA (7 :0 ) */
3869 fis->d.lbaMid = scsiCmnd->cdb[4]; /* FIS LBA (15:8 ) */
3870 fis->d.lbaHigh = scsiCmnd->cdb[3]; /* FIS LBA (23:16) */
3871
3872 /* Check FUA bit */
3873 if (scsiCmnd->cdb[1] & SCSI_WRITE12_FUA_MASK)
3874 fis->d.device = 0xC0; /* FIS FUA set */
3875 else
3876 fis->d.device = 0x40; /* FIS FUA clear */
3877
3878 fis->d.lbaLowExp = scsiCmnd->cdb[2]; /* FIS LBA (31:24) */
3879 fis->d.lbaMidExp = 0; /* FIS LBA (39:32) */
3880 fis->d.lbaHighExp = 0; /* FIS LBA (47:40) */
3881 fis->d.featuresExp = scsiCmnd->cdb[8]; /* FIS sector count (15:8) */
3882 fis->d.sectorCount = 0; /* Tag (7:3) set by LL layer */
3883 fis->d.sectorCountExp = 0;
3884 fis->d.reserved4 = 0;
3885 fis->d.control = 0; /* FIS HOB bit clear */
3886 fis->d.reserved5 = 0;
3887
3888 agRequestType = AGSA_SATA_PROTOCOL_FPDMA_WRITE;
3889 satIOContext->ATACmd = SAT_WRITE_FPDMA_QUEUED;
3890 }
3891
3892 satIOContext->currentLBA = lba;
3893 satIOContext->OrgTL = tl;
3894
3895 /*
3896 computing number of loop and remainder for tl
3897 0xFF in case not ext
3898 0xFFFF in case EXT
3899 */
3900 if (fis->h.command == SAT_WRITE_SECTORS || fis->h.command == SAT_WRITE_DMA)
3901 {
3902 LoopNum = satComputeLoopNum(tl, 0xFF);
3903 }
3904 else if (fis->h.command == SAT_WRITE_SECTORS_EXT ||
3905 fis->h.command == SAT_WRITE_DMA_EXT ||
3906 fis->h.command == SAT_WRITE_DMA_FUA_EXT
3907 )
3908 {
3909 /* SAT_READ_SECTORS_EXT, SAT_READ_DMA_EXT */
3910 LoopNum = satComputeLoopNum(tl, 0xFFFF);
3911 }
3912 else
3913 {
3914 /* SAT_WRITE_FPDMA_QUEUEDK */
3915 LoopNum = satComputeLoopNum(tl, 0xFFFF);
3916 }
3917
3918 satIOContext->LoopNum = LoopNum;
3919
3920
3921 if (LoopNum == 1)
3922 {
3923 TI_DBG5(("satWrite12: NON CHAINED data\n"));
3924 /* Initialize CB for SATA completion.
3925 */
3926 satIOContext->satCompleteCB = &satNonChainedDataIOCB;
3927 }
3928 else
3929 {
3930 TI_DBG1(("satWrite12: CHAINED data\n"));
3931 /* re-setting tl */
3932 if (fis->h.command == SAT_WRITE_SECTORS || fis->h.command == SAT_WRITE_DMA)
3933 {
3934 fis->d.sectorCount = 0xFF;
3935 }
3936 else if (fis->h.command == SAT_WRITE_SECTORS_EXT ||
3937 fis->h.command == SAT_WRITE_DMA_EXT ||
3938 fis->h.command == SAT_WRITE_DMA_FUA_EXT
3939 )
3940 {
3941 fis->d.sectorCount = 0xFF;
3942 fis->d.sectorCountExp = 0xFF;
3943 }
3944 else
3945 {
3946 /* SAT_WRITE_FPDMA_QUEUED */
3947 fis->h.features = 0xFF;
3948 fis->d.featuresExp = 0xFF;
3949 }
3950
3951 /* Initialize CB for SATA completion.
3952 */
3953 satIOContext->satCompleteCB = &satChainedDataIOCB;
3954 }
3955
3956
3957 /*
3958 * Prepare SGL and send FIS to LL layer.
3959 */
3960 satIOContext->reqType = agRequestType; /* Save it */
3961
3962 status = sataLLIOStart( tiRoot,
3963 tiIORequest,
3964 tiDeviceHandle,
3965 tiScsiRequest,
3966 satIOContext);
3967 return (status);
3968 }
3969
3970 /*****************************************************************************/
3971 /*! \brief SAT implementation for SCSI WRITE10.
3972 *
3973 * SAT implementation for SCSI WRITE10 and send FIS request to LL layer.
3974 *
3975 * \param tiRoot: Pointer to TISA initiator driver/port instance.
3976 * \param tiIORequest: Pointer to TISA I/O request context for this I/O.
3977 * \param tiDeviceHandle: Pointer to TISA device handle for this I/O.
3978 * \param tiScsiRequest: Pointer to TISA SCSI I/O request and SGL list.
3979 * \param satIOContext_t: Pointer to the SAT IO Context
3980 *
3981 * \return If command is started successfully
3982 * - \e tiSuccess: I/O request successfully initiated.
3983 * - \e tiBusy: No resources available, try again later.
3984 * - \e tiIONoDevice: Invalid device handle.
3985 * - \e tiError: Other errors.
3986 */
3987 /*****************************************************************************/
3988 GLOBAL bit32 satWrite10(
3989 tiRoot_t *tiRoot,
3990 tiIORequest_t *tiIORequest,
3991 tiDeviceHandle_t *tiDeviceHandle,
3992 tiScsiInitiatorRequest_t *tiScsiRequest,
3993 satIOContext_t *satIOContext)
3994 {
3995
3996 bit32 status;
3997 bit32 agRequestType = AGSA_SATA_PROTOCOL_DMA_WRITE;
3998 satDeviceData_t *pSatDevData;
3999 scsiRspSense_t *pSense;
4000 tiIniScsiCmnd_t *scsiCmnd;
4001 agsaFisRegHostToDevice_t *fis;
4002 bit32 lba = 0;
4003 bit32 tl = 0;
4004 bit32 LoopNum = 1;
4005 bit8 LBA[4];
4006 bit8 TL[4];
4007 bit32 rangeChk = agFALSE; /* lba and tl range check */
4008
4009 pSense = satIOContext->pSense;
4010 pSatDevData = satIOContext->pSatDevData;
4011 scsiCmnd = &tiScsiRequest->scsiCmnd;
4012 fis = satIOContext->pFis;
4013
4014 TI_DBG5(("satWrite10: start\n"));
4015
4016 /* checking FUA_NV */
4017 if (scsiCmnd->cdb[1] & SCSI_FUA_NV_MASK)
4018 {
4019 satSetSensePayload( pSense,
4020 SCSI_SNSKEY_ILLEGAL_REQUEST,
4021 0,
4022 SCSI_SNSCODE_INVALID_FIELD_IN_CDB,
4023 satIOContext);
4024
4025 ostiInitiatorIOCompleted( tiRoot,
4026 tiIORequest,
4027 tiIOSuccess,
4028 SCSI_STAT_CHECK_CONDITION,
4029 satIOContext->pTiSenseData,
4030 satIOContext->interruptContext );
4031
4032 TI_DBG1(("satWrite10: return FUA_NV\n"));
4033 return tiSuccess;
4034
4035 }
4036
4037 /* checking CONTROL */
4038 /* NACA == 1 or LINK == 1*/
4039 if ( (scsiCmnd->cdb[9] & SCSI_NACA_MASK) || (scsiCmnd->cdb[9] & SCSI_LINK_MASK) )
4040 {
4041 satSetSensePayload( pSense,
4042 SCSI_SNSKEY_ILLEGAL_REQUEST,
4043 0,
4044 SCSI_SNSCODE_INVALID_FIELD_IN_CDB,
4045 satIOContext);
4046
4047 ostiInitiatorIOCompleted( tiRoot,
4048 tiIORequest,
4049 tiIOSuccess,
4050 SCSI_STAT_CHECK_CONDITION,
4051 satIOContext->pTiSenseData,
4052 satIOContext->interruptContext );
4053
4054 TI_DBG1(("satWrite10: return control\n"));
4055 return tiSuccess;
4056 }
4057
4058 osti_memset(LBA, 0, sizeof(LBA));
4059 osti_memset(TL, 0, sizeof(TL));
4060
4061 /* do not use memcpy due to indexing in LBA and TL */
4062 LBA[0] = scsiCmnd->cdb[2]; /* MSB */
4063 LBA[1] = scsiCmnd->cdb[3];
4064 LBA[2] = scsiCmnd->cdb[4];
4065 LBA[3] = scsiCmnd->cdb[5]; /* LSB */
4066
4067 TL[0] = 0;
4068 TL[1] = 0;
4069 TL[2] = scsiCmnd->cdb[7]; /* MSB */
4070 TL[3] = scsiCmnd->cdb[8]; /* LSB */
4071
4072 rangeChk = satAddNComparebit32(LBA, TL);
4073
4074
4075 /* cbd10; computing LBA and transfer length */
4076 lba = (scsiCmnd->cdb[2] << (8*3)) + (scsiCmnd->cdb[3] << (8*2))
4077 + (scsiCmnd->cdb[4] << 8) + scsiCmnd->cdb[5];
4078 tl = (scsiCmnd->cdb[7] << 8) + scsiCmnd->cdb[8];
4079
4080 TI_DBG5(("satWrite10: lba %d functioned lba %d\n", lba, satComputeCDB10LBA(satIOContext)));
4081 TI_DBG5(("satWrite10: tl %d functioned tl %d\n", tl, satComputeCDB10TL(satIOContext)));
4082
4083 /* Table 34, 9.1, p 46 */
4084 /*
4085 note: As of 2/10/2006, no support for DMA QUEUED
4086 */
4087
4088 /*
4089 Table 34, 9.1, p 46, b
4090 When no 48-bit addressing support or NCQ, if LBA is beyond (2^28 - 1),
4091 return check condition
4092 */
4093 if (pSatDevData->satNCQ != agTRUE &&
4094 pSatDevData->sat48BitSupport != agTRUE
4095 )
4096 {
4097 if (lba > SAT_TR_LBA_LIMIT - 1)
4098 {
4099 satSetSensePayload( pSense,
4100 SCSI_SNSKEY_ILLEGAL_REQUEST,
4101 0,
4102 SCSI_SNSCODE_LOGICAL_BLOCK_ADDRESS_OUT_OF_RANGE,
4103 satIOContext);
4104
4105 ostiInitiatorIOCompleted( tiRoot,
4106 tiIORequest,
4107 tiIOSuccess,
4108 SCSI_STAT_CHECK_CONDITION,
4109 satIOContext->pTiSenseData,
4110 satIOContext->interruptContext );
4111
4112 TI_DBG1(("satWrite10: return LBA out of range, not EXT\n"));
4113 TI_DBG1(("satWrite10: cdb 0x%x 0x%x 0x%x 0x%x\n",scsiCmnd->cdb[2], scsiCmnd->cdb[3],
4114 scsiCmnd->cdb[4], scsiCmnd->cdb[5]));
4115 TI_DBG1(("satWrite10: lba 0x%x SAT_TR_LBA_LIMIT 0x%x\n", lba, SAT_TR_LBA_LIMIT));
4116 return tiSuccess;
4117 }
4118
4119 if (rangeChk) // if (lba + tl > SAT_TR_LBA_LIMIT)
4120 {
4121 TI_DBG1(("satWrite10: return LBA+TL out of range, not EXT\n"));
4122 satSetSensePayload( pSense,
4123 SCSI_SNSKEY_ILLEGAL_REQUEST,
4124 0,
4125 SCSI_SNSCODE_LOGICAL_BLOCK_ADDRESS_OUT_OF_RANGE,
4126 satIOContext);
4127
4128 ostiInitiatorIOCompleted( tiRoot,
4129 tiIORequest,
4130 tiIOSuccess,
4131 SCSI_STAT_CHECK_CONDITION,
4132 satIOContext->pTiSenseData,
4133 satIOContext->interruptContext );
4134
4135 return tiSuccess;
4136 }
4137
4138 }
4139
4140
4141 /* case 1 and 2 */
4142 if (!rangeChk) // if (lba + tl <= SAT_TR_LBA_LIMIT)
4143 {
4144 if (pSatDevData->satDMASupport == agTRUE && pSatDevData->satDMAEnabled == agTRUE)
4145 {
4146 /* case 2 */
4147 /* WRITE DMA*/
4148 /* can't fit the transfer length */
4149 TI_DBG5(("satWrite10: case 2\n"));
4150 fis->h.fisType = 0x27; /* Reg host to device */
4151 fis->h.c_pmPort = 0x80; /* C bit is set */
4152 fis->h.command = SAT_WRITE_DMA; /* 0xCA */
4153 fis->h.features = 0; /* FIS reserve */
4154 fis->d.lbaLow = scsiCmnd->cdb[5]; /* FIS LBA (7 :0 ) */
4155 fis->d.lbaMid = scsiCmnd->cdb[4]; /* FIS LBA (15:8 ) */
4156 fis->d.lbaHigh = scsiCmnd->cdb[3]; /* FIS LBA (23:16) */
4157
4158 /* FIS LBA mode set LBA (27:24) */
4159 fis->d.device = (bit8)((0x4 << 4) | (scsiCmnd->cdb[2] & 0xF));
4160
4161 fis->d.lbaLowExp = 0;
4162 fis->d.lbaMidExp = 0;
4163 fis->d.lbaHighExp = 0;
4164 fis->d.featuresExp = 0;
4165 fis->d.sectorCount = scsiCmnd->cdb[8]; /* FIS sector count (7:0) */
4166 fis->d.sectorCountExp = 0;
4167 fis->d.reserved4 = 0;
4168 fis->d.control = 0; /* FIS HOB bit clear */
4169 fis->d.reserved5 = 0;
4170
4171 agRequestType = AGSA_SATA_PROTOCOL_DMA_WRITE;
4172 satIOContext->ATACmd = SAT_WRITE_DMA;
4173 }
4174 else
4175 {
4176 /* case 1 */
4177 /* WRITE MULTIPLE or WRITE SECTOR(S) */
4178 /* WRITE SECTORS for easier implemetation */
4179 /* can't fit the transfer length */
4180 TI_DBG5(("satWrite10: case 1\n"));
4181 fis->h.fisType = 0x27; /* Reg host to device */
4182 fis->h.c_pmPort = 0x80; /* C bit is set */
4183 fis->h.command = SAT_WRITE_SECTORS; /* 0x30 */
4184 fis->h.features = 0; /* FIS reserve */
4185 fis->d.lbaLow = scsiCmnd->cdb[5]; /* FIS LBA (7 :0 ) */
4186 fis->d.lbaMid = scsiCmnd->cdb[4]; /* FIS LBA (15:8 ) */
4187 fis->d.lbaHigh = scsiCmnd->cdb[3]; /* FIS LBA (23:16) */
4188
4189 /* FIS LBA mode set LBA (27:24) */
4190 fis->d.device = (bit8)((0x4 << 4) | (scsiCmnd->cdb[2] & 0xF));
4191
4192 fis->d.lbaLowExp = 0;
4193 fis->d.lbaMidExp = 0;
4194 fis->d.lbaHighExp = 0;
4195 fis->d.featuresExp = 0;
4196 fis->d.sectorCount = scsiCmnd->cdb[8]; /* FIS sector count (7:0) */
4197 fis->d.sectorCountExp = 0;
4198 fis->d.reserved4 = 0;
4199 fis->d.control = 0; /* FIS HOB bit clear */
4200 fis->d.reserved5 = 0;
4201
4202 agRequestType = AGSA_SATA_PROTOCOL_PIO_WRITE;
4203 satIOContext->ATACmd = SAT_WRITE_SECTORS;
4204 }
4205 }
4206 /* case 3 and 4 */
4207 if (pSatDevData->sat48BitSupport == agTRUE)
4208 {
4209 if (pSatDevData->satDMASupport == agTRUE && pSatDevData->satDMAEnabled == agTRUE)
4210 {
4211 /* case 3 */
4212 /* WRITE DMA EXT or WRITE DMA FUA EXT */
4213 TI_DBG5(("satWrite10: case 3\n"));
4214 fis->h.fisType = 0x27; /* Reg host to device */
4215 fis->h.c_pmPort = 0x80; /* C Bit is set */
4216
4217 /* SAT_WRITE_DMA_FUA_EXT is optional and we don't support it */
4218 fis->h.command = SAT_WRITE_DMA_EXT; /* 0x35 */
4219 satIOContext->ATACmd = SAT_WRITE_DMA_EXT;
4220
4221 fis->h.features = 0; /* FIS reserve */
4222 fis->d.lbaLow = scsiCmnd->cdb[5]; /* FIS LBA (7 :0 ) */
4223 fis->d.lbaMid = scsiCmnd->cdb[4]; /* FIS LBA (15:8 ) */
4224 fis->d.lbaHigh = scsiCmnd->cdb[3]; /* FIS LBA (23:16) */
4225 fis->d.device = 0x40; /* FIS LBA mode set */
4226 fis->d.lbaLowExp = scsiCmnd->cdb[2]; /* FIS LBA (31:24) */
4227 fis->d.lbaMidExp = 0; /* FIS LBA (39:32) */
4228 fis->d.lbaHighExp = 0; /* FIS LBA (47:40) */
4229 fis->d.featuresExp = 0; /* FIS reserve */
4230 fis->d.sectorCount = scsiCmnd->cdb[8]; /* FIS sector count (7:0) */
4231 fis->d.sectorCountExp = scsiCmnd->cdb[7]; /* FIS sector count (15:8) */
4232 fis->d.reserved4 = 0;
4233 fis->d.control = 0; /* FIS HOB bit clear */
4234 fis->d.reserved5 = 0;
4235
4236 agRequestType = AGSA_SATA_PROTOCOL_DMA_WRITE;
4237 }
4238 else
4239 {
4240 /* case 4 */
4241 /* WRITE MULTIPLE EXT or WRITE MULTIPLE FUA EXT or WRITE SECTOR(S) EXT */
4242 /* WRITE SECTORS EXT for easier implemetation */
4243 TI_DBG5(("satWrite10: case 4\n"));
4244 fis->h.fisType = 0x27; /* Reg host to device */
4245 fis->h.c_pmPort = 0x80; /* C Bit is set */
4246 fis->h.command = SAT_WRITE_SECTORS_EXT; /* 0x34 */
4247
4248 fis->h.features = 0; /* FIS reserve */
4249 fis->d.lbaLow = scsiCmnd->cdb[5]; /* FIS LBA (7 :0 ) */
4250 fis->d.lbaMid = scsiCmnd->cdb[4]; /* FIS LBA (15:8 ) */
4251 fis->d.lbaHigh = scsiCmnd->cdb[3]; /* FIS LBA (23:16) */
4252 fis->d.device = 0x40; /* FIS LBA mode set */
4253 fis->d.lbaLowExp = scsiCmnd->cdb[2]; /* FIS LBA (31:24) */
4254 fis->d.lbaMidExp = 0; /* FIS LBA (39:32) */
4255 fis->d.lbaHighExp = 0; /* FIS LBA (47:40) */
4256 fis->d.featuresExp = 0; /* FIS reserve */
4257 fis->d.sectorCount = scsiCmnd->cdb[8]; /* FIS sector count (7:0) */
4258 fis->d.sectorCountExp = scsiCmnd->cdb[7]; /* FIS sector count (15:8) */
4259 fis->d.reserved4 = 0;
4260 fis->d.control = 0; /* FIS HOB bit clear */
4261 fis->d.reserved5 = 0;
4262
4263 agRequestType = AGSA_SATA_PROTOCOL_PIO_WRITE;
4264 satIOContext->ATACmd = SAT_WRITE_SECTORS_EXT;
4265 }
4266 }
4267 /* case 5 */
4268 if (pSatDevData->satNCQ == agTRUE)
4269 {
4270 /* WRITE FPDMA QUEUED */
4271 if (pSatDevData->sat48BitSupport != agTRUE)
4272 {
4273 TI_DBG5(("satWrite10: case 5 !!! error NCQ but 28 bit address support \n"));
4274 satSetSensePayload( pSense,
4275 SCSI_SNSKEY_ILLEGAL_REQUEST,
4276 0,
4277 SCSI_SNSCODE_INVALID_FIELD_IN_CDB,
4278 satIOContext);
4279
4280 ostiInitiatorIOCompleted( tiRoot,
4281 tiIORequest,
4282 tiIOSuccess,
4283 SCSI_STAT_CHECK_CONDITION,
4284 satIOContext->pTiSenseData,
4285 satIOContext->interruptContext );
4286 return tiSuccess;
4287 }
4288 TI_DBG6(("satWrite10: case 5\n"));
4289
4290 /* Support 48-bit FPDMA addressing, use WRITE FPDMA QUEUE command */
4291
4292 fis->h.fisType = 0x27; /* Reg host to device */
4293 fis->h.c_pmPort = 0x80; /* C Bit is set */
4294 fis->h.command = SAT_WRITE_FPDMA_QUEUED; /* 0x61 */
4295 fis->h.features = scsiCmnd->cdb[8]; /* FIS sector count (7:0) */
4296 fis->d.lbaLow = scsiCmnd->cdb[5]; /* FIS LBA (7 :0 ) */
4297 fis->d.lbaMid = scsiCmnd->cdb[4]; /* FIS LBA (15:8 ) */
4298 fis->d.lbaHigh = scsiCmnd->cdb[3]; /* FIS LBA (23:16) */
4299
4300 /* Check FUA bit */
4301 if (scsiCmnd->cdb[1] & SCSI_WRITE10_FUA_MASK)
4302 fis->d.device = 0xC0; /* FIS FUA set */
4303 else
4304 fis->d.device = 0x40; /* FIS FUA clear */
4305
4306 fis->d.lbaLowExp = scsiCmnd->cdb[2]; /* FIS LBA (31:24) */
4307 fis->d.lbaMidExp = 0; /* FIS LBA (39:32) */
4308 fis->d.lbaHighExp = 0; /* FIS LBA (47:40) */
4309 fis->d.featuresExp = scsiCmnd->cdb[7]; /* FIS sector count (15:8) */
4310 fis->d.sectorCount = 0; /* Tag (7:3) set by LL layer */
4311 fis->d.sectorCountExp = 0;
4312 fis->d.reserved4 = 0;
4313 fis->d.control = 0; /* FIS HOB bit clear */
4314 fis->d.reserved5 = 0;
4315
4316 agRequestType = AGSA_SATA_PROTOCOL_FPDMA_WRITE;
4317 satIOContext->ATACmd = SAT_WRITE_FPDMA_QUEUED;
4318 }
4319
4320 // tdhexdump("satWrite10 final fis", (bit8 *)fis, sizeof(agsaFisRegHostToDevice_t));
4321
4322 satIOContext->currentLBA = lba;
4323 satIOContext->OrgTL = tl;
4324
4325 /*
4326 computing number of loop and remainder for tl
4327 0xFF in case not ext
4328 0xFFFF in case EXT
4329 */
4330 if (fis->h.command == SAT_WRITE_SECTORS || fis->h.command == SAT_WRITE_DMA)
4331 {
4332 LoopNum = satComputeLoopNum(tl, 0xFF);
4333 }
4334 else if (fis->h.command == SAT_WRITE_SECTORS_EXT ||
4335 fis->h.command == SAT_WRITE_DMA_EXT ||
4336 fis->h.command == SAT_WRITE_DMA_FUA_EXT
4337 )
4338 {
4339 /* SAT_READ_SECTORS_EXT, SAT_READ_DMA_EXT */
4340 LoopNum = satComputeLoopNum(tl, 0xFFFF);
4341 }
4342 else
4343 {
4344 /* SAT_WRITE_FPDMA_QUEUEDK */
4345 LoopNum = satComputeLoopNum(tl, 0xFFFF);
4346 }
4347
4348 satIOContext->LoopNum = LoopNum;
4349
4350
4351 if (LoopNum == 1)
4352 {
4353 TI_DBG5(("satWrite10: NON CHAINED data\n"));
4354 /* Initialize CB for SATA completion.
4355 */
4356 satIOContext->satCompleteCB = &satNonChainedDataIOCB;
4357 }
4358 else
4359 {
4360 TI_DBG1(("satWrite10: CHAINED data\n"));
4361 /* re-setting tl */
4362 if (fis->h.command == SAT_WRITE_SECTORS || fis->h.command == SAT_WRITE_DMA)
4363 {
4364 fis->d.sectorCount = 0xFF;
4365 }
4366 else if (fis->h.command == SAT_WRITE_SECTORS_EXT ||
4367 fis->h.command == SAT_WRITE_DMA_EXT ||
4368 fis->h.command == SAT_WRITE_DMA_FUA_EXT
4369 )
4370 {
4371 fis->d.sectorCount = 0xFF;
4372 fis->d.sectorCountExp = 0xFF;
4373 }
4374 else
4375 {
4376 /* SAT_WRITE_FPDMA_QUEUED */
4377 fis->h.features = 0xFF;
4378 fis->d.featuresExp = 0xFF;
4379 }
4380
4381 /* Initialize CB for SATA completion.
4382 */
4383 satIOContext->satCompleteCB = &satChainedDataIOCB;
4384 }
4385
4386
4387 /*
4388 * Prepare SGL and send FIS to LL layer.
4389 */
4390 satIOContext->reqType = agRequestType; /* Save it */
4391
4392 status = sataLLIOStart( tiRoot,
4393 tiIORequest,
4394 tiDeviceHandle,
4395 tiScsiRequest,
4396 satIOContext);
4397 return (status);
4398 }
4399
4400 /*****************************************************************************/
4401 /*! \brief SAT implementation for SCSI satWrite_1.
4402 *
4403 * SAT implementation for SCSI WRITE10 and send FIS request to LL layer.
4404 * This is used when WRITE10 is divided into multiple ATA commands
4405 *
4406 * \param tiRoot: Pointer to TISA initiator driver/port instance.
4407 * \param tiIORequest: Pointer to TISA I/O request context for this I/O.
4408 * \param tiDeviceHandle: Pointer to TISA device handle for this I/O.
4409 * \param tiScsiRequest: Pointer to TISA SCSI I/O request and SGL list.
4410 * \param satIOContext_t: Pointer to the SAT IO Context
4411 *
4412 * \return If command is started successfully
4413 * - \e tiSuccess: I/O request successfully initiated.
4414 * - \e tiBusy: No resources available, try again later.
4415 * - \e tiIONoDevice: Invalid device handle.
4416 * - \e tiError: Other errors.
4417 */
4418 /*****************************************************************************/
4419 GLOBAL bit32 satWrite_1(
4420 tiRoot_t *tiRoot,
4421 tiIORequest_t *tiIORequest,
4422 tiDeviceHandle_t *tiDeviceHandle,
4423 tiScsiInitiatorRequest_t *tiScsiRequest,
4424 satIOContext_t *satIOContext)
4425 {
4426 /*
4427 Assumption: error check on lba and tl has been done in satWrite*()
4428 lba = lba + tl;
4429 */
4430 bit32 status;
4431 satIOContext_t *satOrgIOContext = agNULL;
4432 tiIniScsiCmnd_t *scsiCmnd;
4433 agsaFisRegHostToDevice_t *fis;
4434 bit32 agRequestType = AGSA_SATA_PROTOCOL_DMA_WRITE;
4435 bit32 lba = 0;
4436 bit32 DenomTL = 0xFF;
4437 bit32 Remainder = 0;
4438 bit8 LBA[4]; /* 0 MSB, 3 LSB */
4439
4440 TI_DBG2(("satWrite_1: start\n"));
4441
4442 fis = satIOContext->pFis;
4443 satOrgIOContext = satIOContext->satOrgIOContext;
4444 scsiCmnd = satOrgIOContext->pScsiCmnd;
4445
4446 osti_memset(LBA,0, sizeof(LBA));
4447
4448 switch (satOrgIOContext->ATACmd)
4449 {
4450 case SAT_WRITE_DMA:
4451 DenomTL = 0xFF;
4452 break;
4453 case SAT_WRITE_SECTORS:
4454 DenomTL = 0xFF;
4455 break;
4456 case SAT_WRITE_DMA_EXT:
4457 DenomTL = 0xFFFF;
4458 break;
4459 case SAT_WRITE_DMA_FUA_EXT:
4460 DenomTL = 0xFFFF;
4461 break;
4462 case SAT_WRITE_SECTORS_EXT:
4463 DenomTL = 0xFFFF;
4464 break;
4465 case SAT_WRITE_FPDMA_QUEUED:
4466 DenomTL = 0xFFFF;
4467 break;
4468 default:
4469 TI_DBG1(("satWrite_1: error incorrect ata command 0x%x\n", satIOContext->ATACmd));
4470 return tiError;
4471 break;
4472 }
4473
4474 Remainder = satOrgIOContext->OrgTL % DenomTL;
4475 satOrgIOContext->currentLBA = satOrgIOContext->currentLBA + DenomTL;
4476 lba = satOrgIOContext->currentLBA;
4477
4478 LBA[0] = (bit8)((lba & 0xF000) >> (8 * 3)); /* MSB */
4479 LBA[1] = (bit8)((lba & 0xF00) >> (8 * 2));
4480 LBA[2] = (bit8)((lba & 0xF0) >> 8);
4481 LBA[3] = (bit8)(lba & 0xF); /* LSB */
4482
4483 switch (satOrgIOContext->ATACmd)
4484 {
4485 case SAT_WRITE_DMA:
4486 fis->h.fisType = 0x27; /* Reg host to device */
4487 fis->h.c_pmPort = 0x80; /* C bit is set */
4488 fis->h.command = SAT_WRITE_DMA; /* 0xCA */
4489 fis->h.features = 0; /* FIS reserve */
4490 fis->d.lbaLow = LBA[3]; /* FIS LBA (7 :0 ) */
4491 fis->d.lbaMid = LBA[2]; /* FIS LBA (15:8 ) */
4492 fis->d.lbaHigh = LBA[1]; /* FIS LBA (23:16) */
4493
4494 /* FIS LBA mode set LBA (27:24) */
4495 fis->d.device = (bit8)((0x4 << 4) | (LBA[0] & 0xF));
4496
4497 fis->d.lbaLowExp = 0;
4498 fis->d.lbaMidExp = 0;
4499 fis->d.lbaHighExp = 0;
4500 fis->d.featuresExp = 0;
4501 if (satOrgIOContext->LoopNum == 1)
4502 {
4503 /* last loop */
4504 fis->d.sectorCount = (bit8)Remainder; /* FIS sector count (7:0) */
4505 }
4506 else
4507 {
4508 fis->d.sectorCount = 0xFF; /* FIS sector count (7:0) */
4509 }
4510 fis->d.sectorCountExp = 0;
4511 fis->d.reserved4 = 0;
4512 fis->d.control = 0; /* FIS HOB bit clear */
4513 fis->d.reserved5 = 0;
4514
4515 agRequestType = AGSA_SATA_PROTOCOL_DMA_WRITE;
4516
4517 break;
4518 case SAT_WRITE_SECTORS:
4519 fis->h.fisType = 0x27; /* Reg host to device */
4520 fis->h.c_pmPort = 0x80; /* C bit is set */
4521 fis->h.command = SAT_WRITE_SECTORS; /* 0x30 */
4522 fis->h.features = 0; /* FIS reserve */
4523 fis->d.lbaLow = LBA[3]; /* FIS LBA (7 :0 ) */
4524 fis->d.lbaMid = LBA[2]; /* FIS LBA (15:8 ) */
4525 fis->d.lbaHigh = LBA[1]; /* FIS LBA (23:16) */
4526
4527 /* FIS LBA mode set LBA (27:24) */
4528 fis->d.device = (bit8)((0x4 << 4) | (LBA[0] & 0xF));
4529
4530 fis->d.lbaLowExp = 0;
4531 fis->d.lbaMidExp = 0;
4532 fis->d.lbaHighExp = 0;
4533 fis->d.featuresExp = 0;
4534 if (satOrgIOContext->LoopNum == 1)
4535 {
4536 /* last loop */
4537 fis->d.sectorCount = (bit8)Remainder; /* FIS sector count (7:0) */
4538 }
4539 else
4540 {
4541 fis->d.sectorCount = 0xFF; /* FIS sector count (7:0) */
4542 }
4543 fis->d.sectorCountExp = 0;
4544 fis->d.reserved4 = 0;
4545 fis->d.control = 0; /* FIS HOB bit clear */
4546 fis->d.reserved5 = 0;
4547
4548 agRequestType = AGSA_SATA_PROTOCOL_PIO_WRITE;
4549
4550 break;
4551 case SAT_WRITE_DMA_EXT:
4552 fis->h.fisType = 0x27; /* Reg host to device */
4553 fis->h.c_pmPort = 0x80; /* C Bit is set */
4554 fis->h.command = SAT_WRITE_DMA_EXT; /* 0x3D */
4555 fis->h.features = 0; /* FIS reserve */
4556 fis->d.lbaLow = LBA[3]; /* FIS LBA (7 :0 ) */
4557 fis->d.lbaMid = LBA[2]; /* FIS LBA (15:8 ) */
4558 fis->d.lbaHigh = LBA[1]; /* FIS LBA (23:16) */
4559 fis->d.device = 0x40; /* FIS LBA mode set */
4560 fis->d.lbaLowExp = LBA[0]; /* FIS LBA (31:24) */
4561 fis->d.lbaMidExp = 0; /* FIS LBA (39:32) */
4562 fis->d.lbaHighExp = 0; /* FIS LBA (47:40) */
4563 fis->d.featuresExp = 0; /* FIS reserve */
4564 if (satOrgIOContext->LoopNum == 1)
4565 {
4566 /* last loop */
4567 fis->d.sectorCount = (bit8)(Remainder & 0xFF); /* FIS sector count (7:0) */
4568 fis->d.sectorCountExp = (bit8)((Remainder & 0xFF00) >> 8); /* FIS sector count (15:8) */
4569 }
4570 else
4571 {
4572 fis->d.sectorCount = 0xFF; /* FIS sector count (7:0) */
4573 fis->d.sectorCountExp = 0xFF; /* FIS sector count (15:8) */
4574 }
4575 fis->d.reserved4 = 0;
4576 fis->d.control = 0; /* FIS HOB bit clear */
4577 fis->d.reserved5 = 0;
4578
4579 agRequestType = AGSA_SATA_PROTOCOL_DMA_WRITE;
4580
4581 break;
4582 case SAT_WRITE_SECTORS_EXT:
4583 fis->h.fisType = 0x27; /* Reg host to device */
4584 fis->h.c_pmPort = 0x80; /* C Bit is set */
4585 fis->h.command = SAT_WRITE_SECTORS_EXT; /* 0x34 */
4586
4587 fis->h.features = 0; /* FIS reserve */
4588 fis->d.lbaLow = LBA[3]; /* FIS LBA (7 :0 ) */
4589 fis->d.lbaMid = LBA[2]; /* FIS LBA (15:8 ) */
4590 fis->d.lbaHigh = LBA[1]; /* FIS LBA (23:16) */
4591 fis->d.device = 0x40; /* FIS LBA mode set */
4592 fis->d.lbaLowExp = LBA[0]; /* FIS LBA (31:24) */
4593 fis->d.lbaMidExp = 0; /* FIS LBA (39:32) */
4594 fis->d.lbaHighExp = 0; /* FIS LBA (47:40) */
4595 fis->d.featuresExp = 0; /* FIS reserve */
4596 if (satOrgIOContext->LoopNum == 1)
4597 {
4598 /* last loop */
4599 fis->d.sectorCount = (bit8)(Remainder & 0xFF); /* FIS sector count (7:0) */
4600 fis->d.sectorCountExp = (bit8)((Remainder & 0xFF00) >> 8); /* FIS sector count (15:8) */
4601 }
4602 else
4603 {
4604 fis->d.sectorCount = 0xFF; /* FIS sector count (7:0) */
4605 fis->d.sectorCountExp = 0xFF; /* FIS sector count (15:8) */
4606 }
4607 fis->d.reserved4 = 0;
4608 fis->d.control = 0; /* FIS HOB bit clear */
4609 fis->d.reserved5 = 0;
4610
4611 agRequestType = AGSA_SATA_PROTOCOL_PIO_WRITE;
4612
4613 break;
4614 case SAT_WRITE_FPDMA_QUEUED:
4615 fis->h.fisType = 0x27; /* Reg host to device */
4616 fis->h.c_pmPort = 0x80; /* C Bit is set */
4617 fis->h.command = SAT_WRITE_FPDMA_QUEUED; /* 0x61 */
4618 fis->d.lbaLow = LBA[3]; /* FIS LBA (7 :0 ) */
4619 fis->d.lbaMid = LBA[2]; /* FIS LBA (15:8 ) */
4620 fis->d.lbaHigh = LBA[1]; /* FIS LBA (23:16) */
4621
4622 /* Check FUA bit */
4623 if (scsiCmnd->cdb[1] & SCSI_WRITE10_FUA_MASK)
4624 fis->d.device = 0xC0; /* FIS FUA set */
4625 else
4626 fis->d.device = 0x40; /* FIS FUA clear */
4627
4628 fis->d.lbaLowExp = LBA[0];; /* FIS LBA (31:24) */
4629 fis->d.lbaMidExp = 0; /* FIS LBA (39:32) */
4630 fis->d.lbaHighExp = 0; /* FIS LBA (47:40) */
4631 if (satOrgIOContext->LoopNum == 1)
4632 {
4633 /* last loop */
4634 fis->h.features = (bit8)(Remainder & 0xFF); /* FIS sector count (7:0) */
4635 fis->d.featuresExp = (bit8)((Remainder & 0xFF00) >> 8); /* FIS sector count (15:8) */
4636 }
4637 else
4638 {
4639 fis->h.features = 0xFF; /* FIS sector count (7:0) */
4640 fis->d.featuresExp = 0xFF; /* FIS sector count (15:8) */
4641 }
4642 fis->d.sectorCount = 0; /* Tag (7:3) set by LL layer */
4643 fis->d.sectorCountExp = 0;
4644 fis->d.reserved4 = 0;
4645 fis->d.control = 0; /* FIS HOB bit clear */
4646 fis->d.reserved5 = 0;
4647
4648 agRequestType = AGSA_SATA_PROTOCOL_FPDMA_WRITE;
4649 break;
4650
4651 default:
4652 TI_DBG1(("satWrite_1: error incorrect ata command 0x%x\n", satIOContext->ATACmd));
4653 return tiError;
4654 break;
4655 }
4656
4657 /* Initialize CB for SATA completion.
4658 */
4659 /* chained data */
4660 satIOContext->satCompleteCB = &satChainedDataIOCB;
4661
4662
4663 /*
4664 * Prepare SGL and send FIS to LL layer.
4665 */
4666 satIOContext->reqType = agRequestType; /* Save it */
4667
4668 status = sataLLIOStart( tiRoot,
4669 tiIORequest,
4670 tiDeviceHandle,
4671 tiScsiRequest,
4672 satIOContext);
4673
4674 TI_DBG5(("satWrite_1: return\n"));
4675 return (status);
4676 }
4677
4678 /*****************************************************************************/
4679 /*! \brief SAT implementation for SCSI WRITE6.
4680 *
4681 * SAT implementation for SCSI WRITE6 and send FIS request to LL layer.
4682 *
4683 * \param tiRoot: Pointer to TISA initiator driver/port instance.
4684 * \param tiIORequest: Pointer to TISA I/O request context for this I/O.
4685 * \param tiDeviceHandle: Pointer to TISA device handle for this I/O.
4686 * \param tiScsiRequest: Pointer to TISA SCSI I/O request and SGL list.
4687 * \param satIOContext_t: Pointer to the SAT IO Context
4688 *
4689 * \return If command is started successfully
4690 * - \e tiSuccess: I/O request successfully initiated.
4691 * - \e tiBusy: No resources available, try again later.
4692 * - \e tiIONoDevice: Invalid device handle.
4693 * - \e tiError: Other errors.
4694 */
4695 /*****************************************************************************/
4696 GLOBAL bit32 satWrite6(
4697 tiRoot_t *tiRoot,
4698 tiIORequest_t *tiIORequest,
4699 tiDeviceHandle_t *tiDeviceHandle,
4700 tiScsiInitiatorRequest_t *tiScsiRequest,
4701 satIOContext_t *satIOContext)
4702 {
4703
4704 bit32 status;
4705 bit32 agRequestType = AGSA_SATA_PROTOCOL_DMA_WRITE;
4706 satDeviceData_t *pSatDevData;
4707 scsiRspSense_t *pSense;
4708 tiIniScsiCmnd_t *scsiCmnd;
4709 agsaFisRegHostToDevice_t *fis;
4710 bit32 lba = 0;
4711 bit16 tl = 0;
4712
4713 pSense = satIOContext->pSense;
4714 pSatDevData = satIOContext->pSatDevData;
4715 scsiCmnd = &tiScsiRequest->scsiCmnd;
4716 fis = satIOContext->pFis;
4717
4718 TI_DBG5(("satWrite6: start\n"));
4719
4720 /* checking CONTROL */
4721 /* NACA == 1 or LINK == 1*/
4722 if ( (scsiCmnd->cdb[5] & SCSI_NACA_MASK) || (scsiCmnd->cdb[5] & SCSI_LINK_MASK) )
4723 {
4724 satSetSensePayload( pSense,
4725 SCSI_SNSKEY_ILLEGAL_REQUEST,
4726 0,
4727 SCSI_SNSCODE_INVALID_FIELD_IN_CDB,
4728 satIOContext);
4729
4730 ostiInitiatorIOCompleted( tiRoot,
4731 tiIORequest,
4732 tiIOSuccess,
4733 SCSI_STAT_CHECK_CONDITION,
4734 satIOContext->pTiSenseData,
4735 satIOContext->interruptContext );
4736
4737 TI_DBG1(("satWrite6: return control\n"));
4738 return tiSuccess;
4739 }
4740
4741
4742 /* cbd6; computing LBA and transfer length */
4743 lba = (((scsiCmnd->cdb[1]) & 0x1f) << (8*2))
4744 + (scsiCmnd->cdb[2] << 8) + scsiCmnd->cdb[3];
4745 tl = scsiCmnd->cdb[4];
4746
4747
4748 /* Table 34, 9.1, p 46 */
4749 /*
4750 note: As of 2/10/2006, no support for DMA QUEUED
4751 */
4752
4753 /*
4754 Table 34, 9.1, p 46, b
4755 When no 48-bit addressing support or NCQ, if LBA is beyond (2^28 - 1),
4756 return check condition
4757 */
4758 if (pSatDevData->satNCQ != agTRUE &&
4759 pSatDevData->sat48BitSupport != agTRUE
4760 )
4761 {
4762 if (lba > SAT_TR_LBA_LIMIT - 1)
4763 {
4764 satSetSensePayload( pSense,
4765 SCSI_SNSKEY_ILLEGAL_REQUEST,
4766 0,
4767 SCSI_SNSCODE_LOGICAL_BLOCK_ADDRESS_OUT_OF_RANGE,
4768 satIOContext);
4769
4770 ostiInitiatorIOCompleted( tiRoot,
4771 tiIORequest,
4772 tiIOSuccess,
4773 SCSI_STAT_CHECK_CONDITION,
4774 satIOContext->pTiSenseData,
4775 satIOContext->interruptContext );
4776
4777 TI_DBG1(("satWrite6: return LBA out of range\n"));
4778 return tiSuccess;
4779 }
4780 }
4781
4782 /* case 1 and 2 */
4783 if (lba + tl <= SAT_TR_LBA_LIMIT)
4784 {
4785 if (pSatDevData->satDMASupport == agTRUE && pSatDevData->satDMAEnabled == agTRUE)
4786 {
4787 /* case 2 */
4788 /* WRITE DMA*/
4789 TI_DBG5(("satWrite6: case 2\n"));
4790
4791
4792 fis->h.fisType = 0x27; /* Reg host to device */
4793 fis->h.c_pmPort = 0x80; /* C Bit is set */
4794 fis->h.command = SAT_WRITE_DMA; /* 0xCA */
4795 fis->h.features = 0; /* FIS reserve */
4796 fis->d.lbaLow = scsiCmnd->cdb[3]; /* FIS LBA (7 :0 ) */
4797 fis->d.lbaMid = scsiCmnd->cdb[2]; /* FIS LBA (15:8 ) */
4798 fis->d.lbaHigh = (bit8)((scsiCmnd->cdb[1]) & 0x1f); /* FIS LBA (23:16) */
4799 fis->d.device = 0x40; /* FIS LBA mode */
4800 fis->d.lbaLowExp = 0;
4801 fis->d.lbaMidExp = 0;
4802 fis->d.lbaHighExp = 0;
4803 fis->d.featuresExp = 0;
4804 if (tl == 0)
4805 {
4806 /* temporary fix */
4807 fis->d.sectorCount = 0xff; /* FIS sector count (7:0) */
4808 }
4809 else
4810 {
4811 fis->d.sectorCount = scsiCmnd->cdb[4]; /* FIS sector count (7:0) */
4812 }
4813 fis->d.sectorCountExp = 0;
4814 fis->d.reserved4 = 0;
4815 fis->d.control = 0; /* FIS HOB bit clear */
4816 fis->d.reserved5 = 0;
4817
4818 agRequestType = AGSA_SATA_PROTOCOL_DMA_WRITE;
4819 }
4820 else
4821 {
4822 /* case 1 */
4823 /* WRITE SECTORS for easier implemetation */
4824 TI_DBG5(("satWrite6: case 1\n"));
4825
4826 fis->h.fisType = 0x27; /* Reg host to device */
4827 fis->h.c_pmPort = 0x80; /* C Bit is set */
4828 fis->h.command = SAT_WRITE_SECTORS; /* 0xCA */
4829 fis->h.features = 0; /* FIS reserve */
4830 fis->d.lbaLow = scsiCmnd->cdb[3]; /* FIS LBA (7 :0 ) */
4831 fis->d.lbaMid = scsiCmnd->cdb[2]; /* FIS LBA (15:8 ) */
4832 fis->d.lbaHigh = (bit8)((scsiCmnd->cdb[1]) & 0x1f); /* FIS LBA (23:16) */
4833 fis->d.device = 0x40; /* FIS LBA mode */
4834 fis->d.lbaLowExp = 0;
4835 fis->d.lbaMidExp = 0;
4836 fis->d.lbaHighExp = 0;
4837 fis->d.featuresExp = 0;
4838 if (tl == 0)
4839 {
4840 /* temporary fix */
4841 fis->d.sectorCount = 0xff; /* FIS sector count (7:0) */
4842 }
4843 else
4844 {
4845 fis->d.sectorCount = scsiCmnd->cdb[4]; /* FIS sector count (7:0) */
4846 }
4847 fis->d.sectorCountExp = 0;
4848 fis->d.reserved4 = 0;
4849 fis->d.control = 0; /* FIS HOB bit clear */
4850 fis->d.reserved5 = 0;
4851
4852 agRequestType = AGSA_SATA_PROTOCOL_PIO_WRITE;
4853
4854 }
4855 }
4856
4857 /* case 3 and 4 */
4858 if (pSatDevData->sat48BitSupport == agTRUE)
4859 {
4860 if (pSatDevData->satDMASupport == agTRUE && pSatDevData->satDMAEnabled == agTRUE)
4861 {
4862 /* case 3 */
4863 /* WRITE DMA EXT only */
4864 TI_DBG5(("satWrite6: case 3\n"));
4865 fis->h.fisType = 0x27; /* Reg host to device */
4866 fis->h.c_pmPort = 0x80; /* C Bit is set */
4867 fis->h.command = SAT_WRITE_DMA_EXT; /* 0x35 */
4868 fis->h.features = 0; /* FIS reserve */
4869 fis->d.lbaLow = scsiCmnd->cdb[3]; /* FIS LBA (7 :0 ) */
4870 fis->d.lbaMid = scsiCmnd->cdb[2]; /* FIS LBA (15:8 ) */
4871 fis->d.lbaHigh = (bit8)((scsiCmnd->cdb[1]) & 0x1f); /* FIS LBA (23:16) */
4872 fis->d.device = 0x40; /* FIS LBA mode set */
4873 fis->d.lbaLowExp = 0; /* FIS LBA (31:24) */
4874 fis->d.lbaMidExp = 0; /* FIS LBA (39:32) */
4875 fis->d.lbaHighExp = 0; /* FIS LBA (47:40) */
4876 fis->d.featuresExp = 0; /* FIS reserve */
4877 if (tl == 0)
4878 {
4879 /* sector count is 256, 0x100*/
4880 fis->d.sectorCount = 0; /* FIS sector count (7:0) */
4881 fis->d.sectorCountExp = 0x01; /* FIS sector count (15:8) */
4882 }
4883 else
4884 {
4885 fis->d.sectorCount = scsiCmnd->cdb[4]; /* FIS sector count (7:0) */
4886 fis->d.sectorCountExp = 0; /* FIS sector count (15:8) */
4887 }
4888 fis->d.reserved4 = 0;
4889 fis->d.control = 0; /* FIS HOB bit clear */
4890 fis->d.reserved5 = 0;
4891
4892 agRequestType = AGSA_SATA_PROTOCOL_DMA_WRITE;
4893 }
4894 else
4895 {
4896 /* case 4 */
4897 /* WRITE SECTORS EXT for easier implemetation */
4898 TI_DBG5(("satWrite6: case 4\n"));
4899
4900 fis->h.fisType = 0x27; /* Reg host to device */
4901 fis->h.c_pmPort = 0x80; /* C Bit is set */
4902 fis->h.command = SAT_WRITE_SECTORS_EXT; /* 0x34 */
4903 fis->h.features = 0; /* FIS reserve */
4904 fis->d.lbaLow = scsiCmnd->cdb[3]; /* FIS LBA (7 :0 ) */
4905 fis->d.lbaMid = scsiCmnd->cdb[2]; /* FIS LBA (15:8 ) */
4906 fis->d.lbaHigh = (bit8)((scsiCmnd->cdb[1]) & 0x1f); /* FIS LBA (23:16) */
4907 fis->d.device = 0x40; /* FIS LBA mode set */
4908 fis->d.lbaLowExp = 0; /* FIS LBA (31:24) */
4909 fis->d.lbaMidExp = 0; /* FIS LBA (39:32) */
4910 fis->d.lbaHighExp = 0; /* FIS LBA (47:40) */
4911 fis->d.featuresExp = 0; /* FIS reserve */
4912 if (tl == 0)
4913 {
4914 /* sector count is 256, 0x100*/
4915 fis->d.sectorCount = 0; /* FIS sector count (7:0) */
4916 fis->d.sectorCountExp = 0x01; /* FIS sector count (15:8) */
4917 }
4918 else
4919 {
4920 fis->d.sectorCount = scsiCmnd->cdb[4]; /* FIS sector count (7:0) */
4921 fis->d.sectorCountExp = 0; /* FIS sector count (15:8) */
4922 }
4923 fis->d.reserved4 = 0;
4924 fis->d.control = 0; /* FIS HOB bit clear */
4925 fis->d.reserved5 = 0;
4926
4927 agRequestType = AGSA_SATA_PROTOCOL_PIO_WRITE;
4928 }
4929 }
4930
4931 /* case 5 */
4932 if (pSatDevData->satNCQ == agTRUE)
4933 {
4934 /* WRITE FPDMA QUEUED */
4935 if (pSatDevData->sat48BitSupport != agTRUE)
4936 {
4937 /* sanity check */
4938 TI_DBG5(("satWrite6: case 5 !!! error NCQ but 28 bit address support \n"));
4939 satSetSensePayload( pSense,
4940 SCSI_SNSKEY_ILLEGAL_REQUEST,
4941 0,
4942 SCSI_SNSCODE_INVALID_FIELD_IN_CDB,
4943 satIOContext);
4944
4945 ostiInitiatorIOCompleted( tiRoot,
4946 tiIORequest,
4947 tiIOSuccess,
4948 SCSI_STAT_CHECK_CONDITION,
4949 satIOContext->pTiSenseData,
4950 satIOContext->interruptContext );
4951 return tiSuccess;
4952 }
4953 TI_DBG5(("satWrite6: case 5\n"));
4954
4955 /* Support 48-bit FPDMA addressing, use WRITE FPDMA QUEUE command */
4956
4957 fis->h.fisType = 0x27; /* Reg host to device */
4958 fis->h.c_pmPort = 0x80; /* C Bit is set */
4959 fis->h.command = SAT_WRITE_FPDMA_QUEUED; /* 0x61 */
4960 fis->d.lbaLow = scsiCmnd->cdb[3]; /* FIS LBA (7 :0 ) */
4961 fis->d.lbaMid = scsiCmnd->cdb[2]; /* FIS LBA (15:8 ) */
4962 fis->d.lbaHigh = (bit8)((scsiCmnd->cdb[1]) & 0x1f); /* FIS LBA (23:16) */
4963 fis->d.device = 0x40; /* FIS FUA clear */
4964 fis->d.lbaLowExp = 0; /* FIS LBA (31:24) */
4965 fis->d.lbaMidExp = 0; /* FIS LBA (39:32) */
4966 fis->d.lbaHighExp = 0; /* FIS LBA (47:40) */
4967 if (tl == 0)
4968 {
4969 /* sector count is 256, 0x100*/
4970 fis->h.features = 0; /* FIS sector count (7:0) */
4971 fis->d.featuresExp = 0x01; /* FIS sector count (15:8) */
4972 }
4973 else
4974 {
4975 fis->h.features = scsiCmnd->cdb[4]; /* FIS sector count (7:0) */
4976 fis->d.featuresExp = 0; /* FIS sector count (15:8) */
4977 }
4978 fis->d.sectorCount = 0; /* Tag (7:3) set by LL layer */
4979 fis->d.sectorCountExp = 0;
4980 fis->d.reserved4 = 0;
4981 fis->d.control = 0; /* FIS HOB bit clear */
4982 fis->d.reserved5 = 0;
4983
4984 agRequestType = AGSA_SATA_PROTOCOL_FPDMA_WRITE;
4985 }
4986
4987 /* Initialize CB for SATA completion.
4988 */
4989 satIOContext->satCompleteCB = &satNonChainedDataIOCB;
4990
4991 /*
4992 * Prepare SGL and send FIS to LL layer.
4993 */
4994 satIOContext->reqType = agRequestType; /* Save it */
4995
4996 status = sataLLIOStart( tiRoot,
4997 tiIORequest,
4998 tiDeviceHandle,
4999 tiScsiRequest,
5000 satIOContext);
5001 return (status);
5002 }
5003
5004
5005 /*****************************************************************************/
5006 /*! \brief SAT implementation for SCSI TEST UNIT READY.
5007 *
5008 * SAT implementation for SCSI TUR and send FIS request to LL layer.
5009 *
5010 * \param tiRoot: Pointer to TISA initiator driver/port instance.
5011 * \param tiIORequest: Pointer to TISA I/O request context for this I/O.
5012 * \param tiDeviceHandle: Pointer to TISA device handle for this I/O.
5013 * \param tiScsiRequest: Pointer to TISA SCSI I/O request and SGL list.
5014 * \param satIOContext_t: Pointer to the SAT IO Context
5015 *
5016 * \return If command is started successfully
5017 * - \e tiSuccess: I/O request successfully initiated.
5018 * - \e tiBusy: No resources available, try again later.
5019 * - \e tiIONoDevice: Invalid device handle.
5020 * - \e tiError: Other errors.
5021 */
5022 /*****************************************************************************/
5023 GLOBAL bit32 satTestUnitReady(
5024 tiRoot_t *tiRoot,
5025 tiIORequest_t *tiIORequest,
5026 tiDeviceHandle_t *tiDeviceHandle,
5027 tiScsiInitiatorRequest_t *tiScsiRequest,
5028 satIOContext_t *satIOContext)
5029 {
5030
5031 bit32 status;
5032 bit32 agRequestType;
5033 satDeviceData_t *pSatDevData;
5034 scsiRspSense_t *pSense;
5035 tiIniScsiCmnd_t *scsiCmnd;
5036 agsaFisRegHostToDevice_t *fis;
5037
5038 pSense = satIOContext->pSense;
5039 pSatDevData = satIOContext->pSatDevData;
5040 scsiCmnd = &tiScsiRequest->scsiCmnd;
5041 fis = satIOContext->pFis;
5042
5043 TI_DBG6(("satTestUnitReady: entry tiDeviceHandle=%p tiIORequest=%p\n",
5044 tiDeviceHandle, tiIORequest));
5045
5046 /* checking CONTROL */
5047 /* NACA == 1 or LINK == 1*/
5048 if ( (scsiCmnd->cdb[5] & SCSI_NACA_MASK) || (scsiCmnd->cdb[5] & SCSI_LINK_MASK) )
5049 {
5050 satSetSensePayload( pSense,
5051 SCSI_SNSKEY_ILLEGAL_REQUEST,
5052 0,
5053 SCSI_SNSCODE_INVALID_FIELD_IN_CDB,
5054 satIOContext);
5055
5056 ostiInitiatorIOCompleted( tiRoot,
5057 tiIORequest,
5058 tiIOSuccess,
5059 SCSI_STAT_CHECK_CONDITION,
5060 satIOContext->pTiSenseData,
5061 satIOContext->interruptContext );
5062
5063 TI_DBG1(("satTestUnitReady: return control\n"));
5064 return tiSuccess;
5065 }
5066
5067 /* SAT revision 8, 8.11.2, p42*/
5068 if (pSatDevData->satStopState == agTRUE)
5069 {
5070 satSetSensePayload( pSense,
5071 SCSI_SNSKEY_NOT_READY,
5072 0,
5073 SCSI_SNSCODE_LOGICAL_UNIT_NOT_READY_INITIALIZING_COMMAND_REQUIRED,
5074 satIOContext);
5075
5076 ostiInitiatorIOCompleted( tiRoot,
5077 tiIORequest,
5078 tiIOSuccess,
5079 SCSI_STAT_CHECK_CONDITION,
5080 satIOContext->pTiSenseData,
5081 satIOContext->interruptContext );
5082 TI_DBG1(("satTestUnitReady: stop state\n"));
5083 return tiSuccess;
5084 }
5085
5086 /*
5087 * Check if format is in progress
5088 */
5089
5090 if (pSatDevData->satDriveState == SAT_DEV_STATE_FORMAT_IN_PROGRESS)
5091 {
5092 TI_DBG1(("satTestUnitReady() FORMAT_IN_PROGRESS tiDeviceHandle=%p tiIORequest=%p\n",
5093 tiDeviceHandle, tiIORequest));
5094
5095 satSetSensePayload( pSense,
5096 SCSI_SNSKEY_NOT_READY,
5097 0,
5098 SCSI_SNSCODE_LOGICAL_UNIT_NOT_READY_FORMAT_IN_PROGRESS,
5099 satIOContext);
5100
5101 ostiInitiatorIOCompleted( tiRoot,
5102 tiIORequest,
5103 tiIOSuccess,
5104 SCSI_STAT_CHECK_CONDITION,
5105 satIOContext->pTiSenseData,
5106 satIOContext->interruptContext );
5107 TI_DBG1(("satTestUnitReady: format in progress\n"));
5108 return tiSuccess;
5109 }
5110
5111 /*
5112 check previously issued ATA command
5113 */
5114 if (pSatDevData->satPendingIO != 0)
5115 {
5116 if (pSatDevData->satDeviceFaultState == agTRUE)
5117 {
5118 satSetSensePayload( pSense,
5119 SCSI_SNSKEY_HARDWARE_ERROR,
5120 0,
5121 SCSI_SNSCODE_LOGICAL_UNIT_FAILURE,
5122 satIOContext);
5123
5124 ostiInitiatorIOCompleted( tiRoot,
5125 tiIORequest,
5126 tiIOSuccess,
5127 SCSI_STAT_CHECK_CONDITION,
5128 satIOContext->pTiSenseData,
5129 satIOContext->interruptContext );
5130 TI_DBG1(("satTestUnitReady: previous command ended in error\n"));
5131 return tiSuccess;
5132 }
5133 }
5134 /*
5135 check removalbe media feature set
5136 */
5137 if(pSatDevData->satRemovableMedia && pSatDevData->satRemovableMediaEnabled)
5138 {
5139 TI_DBG5(("satTestUnitReady: sending get media status cmnd\n"));
5140 /* send GET MEDIA STATUS command */
5141 fis->h.fisType = 0x27; /* Reg host to device */
5142 fis->h.c_pmPort = 0x80; /* C Bit is set */
5143 fis->h.command = SAT_GET_MEDIA_STATUS; /* 0xDA */
5144 fis->h.features = 0; /* FIS features NA */
5145 fis->d.lbaLow = 0; /* FIS LBA (7 :0 ) */
5146 fis->d.lbaMid = 0; /* FIS LBA (15:8 ) */
5147 fis->d.lbaHigh = 0; /* FIS LBA (23:16) */
5148 fis->d.device = 0; /* FIS DEV is discared in SATA */
5149 fis->d.lbaLowExp = 0;
5150 fis->d.lbaMidExp = 0;
5151 fis->d.lbaHighExp = 0;
5152 fis->d.featuresExp = 0;
5153 fis->d.sectorCount = 0; /* FIS sector count (7:0) */
5154 fis->d.sectorCountExp = 0;
5155 fis->d.reserved4 = 0;
5156 fis->d.control = 0; /* FIS HOB bit clear */
5157 fis->d.reserved5 = 0;
5158 agRequestType = AGSA_SATA_PROTOCOL_NON_DATA;
5159
5160 /* Initialize CB for SATA completion.
5161 */
5162 satIOContext->satCompleteCB = &satTestUnitReadyCB;
5163
5164 /*
5165 * Prepare SGL and send FIS to LL layer.
5166 */
5167 satIOContext->reqType = agRequestType; /* Save it */
5168
5169 status = sataLLIOStart( tiRoot,
5170 tiIORequest,
5171 tiDeviceHandle,
5172 tiScsiRequest,
5173 satIOContext);
5174
5175 return (status);
5176 }
5177 /*
5178 number 6) in SAT p42
5179 send ATA CHECK POWER MODE
5180 */
5181 TI_DBG5(("satTestUnitReady: sending check power mode cmnd\n"));
5182 status = satTestUnitReady_1( tiRoot,
5183 tiIORequest,
5184 tiDeviceHandle,
5185 tiScsiRequest,
5186 satIOContext);
5187 return (status);
5188 }
5189
5190
5191 /*****************************************************************************/
5192 /*! \brief SAT implementation for SCSI satTestUnitReady_1.
5193 *
5194 * SAT implementation for SCSI satTestUnitReady_1.
5195 *
5196 * \param tiRoot: Pointer to TISA initiator driver/port instance.
5197 * \param tiIORequest: Pointer to TISA I/O request context for this I/O.
5198 * \param tiDeviceHandle: Pointer to TISA device handle for this I/O.
5199 * \param tiScsiRequest: Pointer to TISA SCSI I/O request and SGL list.
5200 * \param satIOContext_t: Pointer to the SAT IO Context
5201 *
5202 * \return If command is started successfully
5203 * - \e tiSuccess: I/O request successfully initiated.
5204 * - \e tiBusy: No resources available, try again later.
5205 * - \e tiIONoDevice: Invalid device handle.
5206 * - \e tiError: Other errors.
5207 */
5208 /*****************************************************************************/
5209 GLOBAL bit32 satTestUnitReady_1(
5210 tiRoot_t *tiRoot,
5211 tiIORequest_t *tiIORequest,
5212 tiDeviceHandle_t *tiDeviceHandle,
5213 tiScsiInitiatorRequest_t *tiScsiRequest,
5214 satIOContext_t *satIOContext)
5215 {
5216 /*
5217 sends SAT_CHECK_POWER_MODE as a part of TESTUNITREADY
5218 internally generated - no directly corresponding scsi
5219 called in satIOCompleted as a part of satTestUnitReady(), SAT, revision8, 8.11.2, p42
5220 */
5221 bit32 status;
5222 bit32 agRequestType;
5223 agsaFisRegHostToDevice_t *fis;
5224
5225 fis = satIOContext->pFis;
5226
5227 TI_DBG5(("satTestUnitReady_1: start\n"));
5228
5229 /*
5230 * Send the ATA CHECK POWER MODE command.
5231 */
5232 fis->h.fisType = 0x27; /* Reg host to device */
5233 fis->h.c_pmPort = 0x80; /* C Bit is set */
5234 fis->h.command = SAT_CHECK_POWER_MODE; /* 0xE5 */
5235 fis->h.features = 0;
5236 fis->d.lbaLow = 0;
5237 fis->d.lbaMid = 0;
5238 fis->d.lbaHigh = 0;
5239 fis->d.device = 0;
5240 fis->d.lbaLowExp = 0;
5241 fis->d.lbaMidExp = 0;
5242 fis->d.lbaHighExp = 0;
5243 fis->d.featuresExp = 0;
5244 fis->d.sectorCount = 0;
5245 fis->d.sectorCountExp = 0;
5246 fis->d.reserved4 = 0;
5247 fis->d.control = 0; /* FIS HOB bit clear */
5248 fis->d.reserved5 = 0;
5249
5250 agRequestType = AGSA_SATA_PROTOCOL_NON_DATA;
5251
5252 /* Initialize CB for SATA completion.
5253 */
5254 satIOContext->satCompleteCB = &satTestUnitReadyCB;
5255
5256 /*
5257 * Prepare SGL and send FIS to LL layer.
5258 */
5259 satIOContext->reqType = agRequestType; /* Save it */
5260
5261 status = sataLLIOStart( tiRoot,
5262 tiIORequest,
5263 tiDeviceHandle,
5264 tiScsiRequest,
5265 satIOContext);
5266
5267 TI_DBG5(("satTestUnitReady_1: return\n"));
5268
5269 return status;
5270 }
5271
5272
5273 /*****************************************************************************/
5274 /*! \brief SAT implementation for SCSI satReportLun.
5275 *
5276 * SAT implementation for SCSI satReportLun. Only LUN0 is reported.
5277 *
5278 * \param tiRoot: Pointer to TISA initiator driver/port instance.
5279 * \param tiIORequest: Pointer to TISA I/O request context for this I/O.
5280 * \param tiDeviceHandle: Pointer to TISA device handle for this I/O.
5281 * \param tiScsiRequest: Pointer to TISA SCSI I/O request and SGL list.
5282 * \param satIOContext_t: Pointer to the SAT IO Context
5283 *
5284 * \return If command is started successfully
5285 * - \e tiSuccess: I/O request successfully initiated.
5286 * - \e tiBusy: No resources available, try again later.
5287 * - \e tiIONoDevice: Invalid device handle.
5288 * - \e tiError: Other errors.
5289 */
5290 /*****************************************************************************/
5291 GLOBAL bit32 satReportLun(
5292 tiRoot_t *tiRoot,
5293 tiIORequest_t *tiIORequest,
5294 tiDeviceHandle_t *tiDeviceHandle,
5295 tiScsiInitiatorRequest_t *tiScsiRequest,
5296 satIOContext_t *satIOContext)
5297 {
5298 scsiRspSense_t *pSense;
5299 bit32 allocationLen;
5300 bit32 reportLunLen;
5301 scsiReportLun_t *pReportLun;
5302 tiIniScsiCmnd_t *scsiCmnd;
5303
5304 TI_DBG5(("satReportLun entry: tiDeviceHandle=%p tiIORequest=%p\n",
5305 tiDeviceHandle, tiIORequest));
5306
5307 pSense = satIOContext->pSense;
5308 pReportLun = (scsiReportLun_t *) tiScsiRequest->sglVirtualAddr;
5309 scsiCmnd = &tiScsiRequest->scsiCmnd;
5310
5311 // tdhexdump("satReportLun cdb", (bit8 *)scsiCmnd, 16);
5312
5313 /* Find the buffer size allocated by Initiator */
5314 allocationLen = (((bit32)scsiCmnd->cdb[6]) << 24) |
5315 (((bit32)scsiCmnd->cdb[7]) << 16) |
5316 (((bit32)scsiCmnd->cdb[8]) << 8 ) |
5317 (((bit32)scsiCmnd->cdb[9]) );
5318
5319 reportLunLen = 16; /* 8 byte header and 8 bytes of LUN0 */
5320
5321 if (allocationLen < reportLunLen)
5322 {
5323 TI_DBG1(("satReportLun *** ERROR *** insufficient len=0x%x tiDeviceHandle=%p tiIORequest=%p\n",
5324 reportLunLen, tiDeviceHandle, tiIORequest));
5325
5326 satSetSensePayload( pSense,
5327 SCSI_SNSKEY_ILLEGAL_REQUEST,
5328 0,
5329 SCSI_SNSCODE_INVALID_FIELD_IN_CDB,
5330 satIOContext);
5331
5332 ostiInitiatorIOCompleted( tiRoot,
5333 tiIORequest,
5334 tiIOSuccess,
5335 SCSI_STAT_CHECK_CONDITION,
5336 satIOContext->pTiSenseData,
5337 satIOContext->interruptContext );
5338 return tiSuccess;
5339
5340 }
5341
5342 /* Set length to one entry */
5343 pReportLun->len[0] = 0;
5344 pReportLun->len[1] = 0;
5345 pReportLun->len[2] = 0;
5346 pReportLun->len[3] = sizeof (tiLUN_t);
5347
5348 pReportLun->reserved = 0;
5349
5350 /* Set to LUN 0:
5351 * - address method to 0x00: Peripheral device addressing method,
5352 * - bus identifier to 0
5353 */
5354 pReportLun->lunList[0].lun[0] = 0;
5355 pReportLun->lunList[0].lun[1] = 0;
5356 pReportLun->lunList[0].lun[2] = 0;
5357 pReportLun->lunList[0].lun[3] = 0;
5358 pReportLun->lunList[0].lun[4] = 0;
5359 pReportLun->lunList[0].lun[5] = 0;
5360 pReportLun->lunList[0].lun[6] = 0;
5361 pReportLun->lunList[0].lun[7] = 0;
5362
5363 if (allocationLen > reportLunLen)
5364 {
5365 /* underrun */
5366 TI_DBG1(("satReportLun reporting underrun reportLunLen=0x%x allocationLen=0x%x \n", reportLunLen, allocationLen));
5367
5368 ostiInitiatorIOCompleted( tiRoot,
5369 tiIORequest,
5370 tiIOUnderRun,
5371 allocationLen - reportLunLen,
5372 agNULL,
5373 satIOContext->interruptContext );
5374
5375
5376 }
5377 else
5378 {
5379 ostiInitiatorIOCompleted( tiRoot,
5380 tiIORequest,
5381 tiIOSuccess,
5382 SCSI_STAT_GOOD,
5383 agNULL,
5384 satIOContext->interruptContext);
5385 }
5386 return tiSuccess;
5387 }
5388
5389
5390 /*****************************************************************************/
5391 /*! \brief SAT implementation for SCSI REQUEST SENSE.
5392 *
5393 * SAT implementation for SCSI REQUEST SENSE.
5394 *
5395 * \param tiRoot: Pointer to TISA initiator driver/port instance.
5396 * \param tiIORequest: Pointer to TISA I/O request context for this I/O.
5397 * \param tiDeviceHandle: Pointer to TISA device handle for this I/O.
5398 * \param tiScsiRequest: Pointer to TISA SCSI I/O request and SGL list.
5399 * \param satIOContext_t: Pointer to the SAT IO Context
5400 *
5401 * \return If command is started successfully
5402 * - \e tiSuccess: I/O request successfully initiated.
5403 * - \e tiBusy: No resources available, try again later.
5404 * - \e tiIONoDevice: Invalid device handle.
5405 * - \e tiError: Other errors.
5406 */
5407 /*****************************************************************************/
5408 GLOBAL bit32 satRequestSense(
5409 tiRoot_t *tiRoot,
5410 tiIORequest_t *tiIORequest,
5411 tiDeviceHandle_t *tiDeviceHandle,
5412 tiScsiInitiatorRequest_t *tiScsiRequest,
5413 satIOContext_t *satIOContext)
5414 {
5415 /*
5416 SAT Rev 8 p38, Table25
5417 sending SMART RETURN STATUS
5418 Checking SMART Treshold Exceeded Condition is done in satRequestSenseCB()
5419 Only fixed format sense data is support. In other words, we don't support DESC bit is set
5420 in Request Sense
5421 */
5422 bit32 status;
5423 bit32 agRequestType;
5424 scsiRspSense_t *pSense;
5425 satDeviceData_t *pSatDevData;
5426 tiIniScsiCmnd_t *scsiCmnd;
5427 agsaFisRegHostToDevice_t *fis;
5428 tdIORequestBody_t *tdIORequestBody;
5429 satInternalIo_t *satIntIo = agNULL;
5430 satIOContext_t *satIOContext2;
5431
5432 TI_DBG4(("satRequestSense entry: tiDeviceHandle=%p tiIORequest=%p\n",
5433 tiDeviceHandle, tiIORequest));
5434
5435 pSense = (scsiRspSense_t *) tiScsiRequest->sglVirtualAddr;
5436 pSatDevData = satIOContext->pSatDevData;
5437 scsiCmnd = &tiScsiRequest->scsiCmnd;
5438 fis = satIOContext->pFis;
5439
5440 TI_DBG4(("satRequestSense: pSatDevData=%p\n", pSatDevData));
5441
5442 /* checking CONTROL */
5443 /* NACA == 1 or LINK == 1*/
5444 if ( (scsiCmnd->cdb[5] & SCSI_NACA_MASK) || (scsiCmnd->cdb[5] & SCSI_LINK_MASK) )
5445 {
5446 satSetSensePayload( pSense,
5447 SCSI_SNSKEY_ILLEGAL_REQUEST,
5448 0,
5449 SCSI_SNSCODE_INVALID_FIELD_IN_CDB,
5450 satIOContext);
5451
5452 ostiInitiatorIOCompleted( tiRoot,
5453 tiIORequest,
5454 tiIOSuccess,
5455 SCSI_STAT_CHECK_CONDITION,
5456 satIOContext->pTiSenseData,
5457 satIOContext->interruptContext );
5458
5459 TI_DBG1(("satRequestSense: return control\n"));
5460 return tiSuccess;
5461 }
5462
5463 /*
5464 Only fixed format sense data is support. In other words, we don't support DESC bit is set
5465 in Request Sense
5466 */
5467 if ( scsiCmnd->cdb[1] & ATA_REMOVABLE_MEDIA_DEVICE_MASK )
5468 {
5469 satSetSensePayload( pSense,
5470 SCSI_SNSKEY_ILLEGAL_REQUEST,
5471 0,
5472 SCSI_SNSCODE_INVALID_FIELD_IN_CDB,
5473 satIOContext);
5474
5475 ostiInitiatorIOCompleted( tiRoot,
5476 tiIORequest,
5477 tiIOSuccess,
5478 SCSI_STAT_CHECK_CONDITION,
5479 satIOContext->pTiSenseData,
5480 satIOContext->interruptContext );
5481
5482 TI_DBG1(("satRequestSense: DESC bit is set, which we don't support\n"));
5483 return tiSuccess;
5484 }
5485
5486
5487 if (pSatDevData->satSMARTEnabled == agTRUE)
5488 {
5489 /* sends SMART RETURN STATUS */
5490 fis->h.fisType = 0x27; /* Reg host to device */
5491 fis->h.c_pmPort = 0x80; /* C Bit is set */
5492
5493 fis->h.command = SAT_SMART_RETURN_STATUS; /* 0xB0 */
5494 fis->h.features = 0xDA; /* FIS features */
5495 fis->d.featuresExp = 0; /* FIS reserve */
5496 fis->d.sectorCount = 0; /* FIS sector count (7:0) */
5497 fis->d.sectorCountExp = 0; /* FIS sector count (15:8) */
5498 fis->d.lbaLow = 0; /* FIS LBA (7 :0 ) */
5499 fis->d.lbaLowExp = 0; /* FIS LBA (31:24) */
5500 fis->d.lbaMid = 0x4F; /* FIS LBA (15:8 ) */
5501 fis->d.lbaMidExp = 0; /* FIS LBA (39:32) */
5502 fis->d.lbaHigh = 0xC2; /* FIS LBA (23:16) */
5503 fis->d.lbaHighExp = 0; /* FIS LBA (47:40) */
5504 fis->d.device = 0; /* FIS DEV is discared in SATA */
5505 fis->d.control = 0; /* FIS HOB bit clear */
5506 fis->d.reserved4 = 0;
5507 fis->d.reserved5 = 0;
5508
5509 agRequestType = AGSA_SATA_PROTOCOL_NON_DATA;
5510 /* Initialize CB for SATA completion.
5511 */
5512 satIOContext->satCompleteCB = &satRequestSenseCB;
5513
5514 /*
5515 * Prepare SGL and send FIS to LL layer.
5516 */
5517 satIOContext->reqType = agRequestType; /* Save it */
5518
5519 status = sataLLIOStart( tiRoot,
5520 tiIORequest,
5521 tiDeviceHandle,
5522 tiScsiRequest,
5523 satIOContext);
5524
5525 TI_DBG4(("satRequestSense: if return, status %d\n", status));
5526 return (status);
5527 }
5528 else
5529 {
5530 /*allocate iocontext for xmitting xmit SAT_CHECK_POWER_MODE
5531 then call satRequestSense2 */
5532
5533 TI_DBG4(("satRequestSense: before satIntIo %p\n", satIntIo));
5534 /* allocate iocontext */
5535 satIntIo = satAllocIntIoResource( tiRoot,
5536 tiIORequest, /* original request */
5537 pSatDevData,
5538 tiScsiRequest->scsiCmnd.expDataLength,
5539 satIntIo);
5540
5541 TI_DBG4(("satRequestSense: after satIntIo %p\n", satIntIo));
5542
5543 if (satIntIo == agNULL)
5544 {
5545 /* memory allocation failure */
5546 satFreeIntIoResource( tiRoot,
5547 pSatDevData,
5548 satIntIo);
5549
5550 /* failed during sending SMART RETURN STATUS */
5551 satSetSensePayload( pSense,
5552 SCSI_SNSKEY_NO_SENSE,
5553 0,
5554 SCSI_SNSCODE_HARDWARE_IMPENDING_FAILURE,
5555 satIOContext);
5556
5557 ostiInitiatorIOCompleted( tiRoot,
5558 tiIORequest,
5559 tiIOSuccess,
5560 SCSI_STAT_GOOD,
5561 agNULL,
5562 satIOContext->interruptContext );
5563
5564 TI_DBG4(("satRequestSense: else fail 1\n"));
5565 return tiSuccess;
5566 } /* end of memory allocation failure */
5567
5568
5569 /*
5570 * Need to initialize all the fields within satIOContext except
5571 * reqType and satCompleteCB which will be set depending on cmd.
5572 */
5573
5574 if (satIntIo == agNULL)
5575 {
5576 TI_DBG4(("satRequestSense: satIntIo is NULL\n"));
5577 }
5578 else
5579 {
5580 TI_DBG4(("satRequestSense: satIntIo is NOT NULL\n"));
5581 }
5582 /* use this --- tttttthe one the same */
5583
5584
5585 satIntIo->satOrgTiIORequest = tiIORequest;
5586 tdIORequestBody = (tdIORequestBody_t *)satIntIo->satIntRequestBody;
5587 satIOContext2 = &(tdIORequestBody->transport.SATA.satIOContext);
5588
5589 satIOContext2->pSatDevData = pSatDevData;
5590 satIOContext2->pFis = &(tdIORequestBody->transport.SATA.agSATARequestBody.fis.fisRegHostToDev);
5591 satIOContext2->pScsiCmnd = &(satIntIo->satIntTiScsiXchg.scsiCmnd);
5592 satIOContext2->pSense = &(tdIORequestBody->transport.SATA.sensePayload);
5593 satIOContext2->pTiSenseData = &(tdIORequestBody->transport.SATA.tiSenseData);
5594 satIOContext2->pTiSenseData->senseData = satIOContext2->pSense;
5595 satIOContext2->tiRequestBody = satIntIo->satIntRequestBody;
5596 satIOContext2->interruptContext = satIOContext->interruptContext;
5597 satIOContext2->satIntIoContext = satIntIo;
5598 satIOContext2->ptiDeviceHandle = tiDeviceHandle;
5599 satIOContext2->satOrgIOContext = satIOContext;
5600
5601 TI_DBG4(("satRequestSense: satIntIo->satIntTiScsiXchg.agSgl1.len %d\n", satIntIo->satIntTiScsiXchg.agSgl1.len));
5602
5603 TI_DBG4(("satRequestSense: satIntIo->satIntTiScsiXchg.agSgl1.upper %d\n", satIntIo->satIntTiScsiXchg.agSgl1.upper));
5604
5605 TI_DBG4(("satRequestSense: satIntIo->satIntTiScsiXchg.agSgl1.lower %d\n", satIntIo->satIntTiScsiXchg.agSgl1.lower));
5606
5607 TI_DBG4(("satRequestSense: satIntIo->satIntTiScsiXchg.agSgl1.type %d\n", satIntIo->satIntTiScsiXchg.agSgl1.type));
5608
5609 status = satRequestSense_1( tiRoot,
5610 &(satIntIo->satIntTiIORequest),
5611 tiDeviceHandle,
5612 &(satIntIo->satIntTiScsiXchg),
5613 satIOContext2);
5614
5615 if (status != tiSuccess)
5616 {
5617 satFreeIntIoResource( tiRoot,
5618 pSatDevData,
5619 satIntIo);
5620
5621 /* failed during sending SMART RETURN STATUS */
5622 satSetSensePayload( pSense,
5623 SCSI_SNSKEY_NO_SENSE,
5624 0,
5625 SCSI_SNSCODE_HARDWARE_IMPENDING_FAILURE,
5626 satIOContext);
5627
5628 ostiInitiatorIOCompleted( tiRoot,
5629 tiIORequest,
5630 tiIOSuccess,
5631 SCSI_STAT_CHECK_CONDITION,
5632 agNULL,
5633 satIOContext->interruptContext );
5634
5635 TI_DBG1(("satRequestSense: else fail 2\n"));
5636 return tiSuccess;
5637 }
5638 TI_DBG4(("satRequestSense: else return success\n"));
5639 return tiSuccess;
5640 }
5641 }
5642
5643
5644 /*****************************************************************************/
5645 /*! \brief SAT implementation for SCSI REQUEST SENSE.
5646 *
5647 * SAT implementation for SCSI REQUEST SENSE.
5648 * Sub function of satRequestSense
5649 *
5650 * \param tiRoot: Pointer to TISA initiator driver/port instance.
5651 * \param tiIORequest: Pointer to TISA I/O request context for this I/O.
5652 * \param tiDeviceHandle: Pointer to TISA device handle for this I/O.
5653 * \param tiScsiRequest: Pointer to TISA SCSI I/O request and SGL list.
5654 * \param satIOContext_t: Pointer to the SAT IO Context
5655 *
5656 * \return If command is started successfully
5657 * - \e tiSuccess: I/O request successfully initiated.
5658 * - \e tiBusy: No resources available, try again later.
5659 * - \e tiIONoDevice: Invalid device handle.
5660 * - \e tiError: Other errors.
5661 */
5662 /*****************************************************************************/
5663 GLOBAL bit32 satRequestSense_1(
5664 tiRoot_t *tiRoot,
5665 tiIORequest_t *tiIORequest,
5666 tiDeviceHandle_t *tiDeviceHandle,
5667 tiScsiInitiatorRequest_t *tiScsiRequest,
5668 satIOContext_t *satIOContext)
5669 {
5670 /*
5671 sends SAT_CHECK_POWER_MODE
5672 */
5673 bit32 status;
5674 bit32 agRequestType;
5675 agsaFisRegHostToDevice_t *fis;
5676
5677 TI_DBG4(("satRequestSense_1 entry: tiDeviceHandle=%p tiIORequest=%p\n",
5678 tiDeviceHandle, tiIORequest));
5679
5680 fis = satIOContext->pFis;
5681 /*
5682 * Send the ATA CHECK POWER MODE command.
5683 */
5684 fis->h.fisType = 0x27; /* Reg host to device */
5685 fis->h.c_pmPort = 0x80; /* C Bit is set */
5686
5687 fis->h.command = SAT_CHECK_POWER_MODE; /* 0xE5 */
5688 fis->h.features = 0;
5689 fis->d.lbaLow = 0;
5690 fis->d.lbaMid = 0;
5691 fis->d.lbaHigh = 0;
5692 fis->d.device = 0;
5693 fis->d.lbaLowExp = 0;
5694 fis->d.lbaMidExp = 0;
5695 fis->d.lbaHighExp = 0;
5696 fis->d.featuresExp = 0;
5697 fis->d.sectorCount = 0;
5698 fis->d.sectorCountExp = 0;
5699 fis->d.reserved4 = 0;
5700 fis->d.control = 0; /* FIS HOB bit clear */
5701 fis->d.reserved5 = 0;
5702
5703 agRequestType = AGSA_SATA_PROTOCOL_NON_DATA;
5704
5705 /* Initialize CB for SATA completion.
5706 */
5707 satIOContext->satCompleteCB = &satRequestSenseCB;
5708
5709 /*
5710 * Prepare SGL and send FIS to LL layer.
5711 */
5712 satIOContext->reqType = agRequestType; /* Save it */
5713
5714
5715 TI_DBG4(("satRequestSense_1: agSgl1.len %d\n", tiScsiRequest->agSgl1.len));
5716
5717 TI_DBG4(("satRequestSense_1: agSgl1.upper %d\n", tiScsiRequest->agSgl1.upper));
5718
5719 TI_DBG4(("satRequestSense_1: agSgl1.lower %d\n", tiScsiRequest->agSgl1.lower));
5720
5721 TI_DBG4(("satRequestSense_1: agSgl1.type %d\n", tiScsiRequest->agSgl1.type));
5722
5723 // tdhexdump("satRequestSense_1", (bit8 *)fis, sizeof(agsaFisRegHostToDevice_t));
5724
5725 status = sataLLIOStart( tiRoot,
5726 tiIORequest,
5727 tiDeviceHandle,
5728 tiScsiRequest,
5729 satIOContext);
5730
5731
5732
5733 return status;
5734 }
5735
5736
5737 /*****************************************************************************/
5738 /*! \brief SAT implementation for SCSI INQUIRY.
5739 *
5740 * SAT implementation for SCSI INQUIRY.
5741 *
5742 * \param tiRoot: Pointer to TISA initiator driver/port instance.
5743 * \param tiIORequest: Pointer to TISA I/O request context for this I/O.
5744 * \param tiDeviceHandle: Pointer to TISA device handle for this I/O.
5745 * \param tiScsiRequest: Pointer to TISA SCSI I/O request and SGL list.
5746 * \param satIOContext_t: Pointer to the SAT IO Context
5747 *
5748 * \return If command is started successfully
5749 * - \e tiSuccess: I/O request successfully initiated.
5750 * - \e tiBusy: No resources available, try again later.
5751 * - \e tiIONoDevice: Invalid device handle.
5752 * - \e tiError: Other errors.
5753 */
5754 /*****************************************************************************/
5755 GLOBAL bit32 satInquiry(
5756 tiRoot_t *tiRoot,
5757 tiIORequest_t *tiIORequest,
5758 tiDeviceHandle_t *tiDeviceHandle,
5759 tiScsiInitiatorRequest_t *tiScsiRequest,
5760 satIOContext_t *satIOContext)
5761 {
5762 /*
5763 CMDDT bit is obsolete in SPC-3 and this is assumed in SAT revision 8
5764 */
5765 scsiRspSense_t *pSense;
5766 tiIniScsiCmnd_t *scsiCmnd;
5767 satDeviceData_t *pSatDevData;
5768 bit32 status;
5769
5770 TI_DBG5(("satInquiry: start\n"));
5771 TI_DBG5(("satInquiry entry: tiDeviceHandle=%p tiIORequest=%p\n",
5772 tiDeviceHandle, tiIORequest));
5773 pSense = satIOContext->pSense;
5774 scsiCmnd = &tiScsiRequest->scsiCmnd;
5775 pSatDevData = satIOContext->pSatDevData;
5776 TI_DBG5(("satInquiry: pSatDevData=%p\n", pSatDevData));
5777 //tdhexdump("satInquiry", (bit8 *)scsiCmnd->cdb, 6);
5778 /* checking CONTROL */
5779 /* NACA == 1 or LINK == 1*/
5780 if ( (scsiCmnd->cdb[5] & SCSI_NACA_MASK) || (scsiCmnd->cdb[5] & SCSI_LINK_MASK) )
5781 {
5782 satSetSensePayload( pSense,
5783 SCSI_SNSKEY_ILLEGAL_REQUEST,
5784 0,
5785 SCSI_SNSCODE_INVALID_FIELD_IN_CDB,
5786 satIOContext);
5787 ostiInitiatorIOCompleted( tiRoot,
5788 tiIORequest,
5789 tiIOSuccess,
5790 SCSI_STAT_CHECK_CONDITION,
5791 satIOContext->pTiSenseData,
5792 satIOContext->interruptContext );
5793 TI_DBG2(("satInquiry: return control\n"));
5794 return tiSuccess;
5795 }
5796
5797 /* checking EVPD and Allocation Length */
5798 /* SPC-4 spec 6.4 p141 */
5799 /* EVPD bit == 0 && PAGE CODE != 0 */
5800 if ( !(scsiCmnd->cdb[1] & SCSI_EVPD_MASK) &&
5801 (scsiCmnd->cdb[2] != 0)
5802 )
5803 {
5804 satSetSensePayload( pSense,
5805 SCSI_SNSKEY_ILLEGAL_REQUEST,
5806 0,
5807 SCSI_SNSCODE_INVALID_FIELD_IN_CDB,
5808 satIOContext);
5809 ostiInitiatorIOCompleted( tiRoot,
5810 tiIORequest,
5811 tiIOSuccess,
5812 SCSI_STAT_CHECK_CONDITION,
5813 satIOContext->pTiSenseData,
5814 satIOContext->interruptContext );
5815 TI_DBG1(("satInquiry: return EVPD and PAGE CODE\n"));
5816 return tiSuccess;
5817 }
5818 TI_DBG6(("satInquiry: allocation length 0x%x %d\n", ((scsiCmnd->cdb[3]) << 8) + scsiCmnd->cdb[4], ((scsiCmnd->cdb[3]) << 8) + scsiCmnd->cdb[4]));
5819
5820 /* convert OS IO to TD internal IO */
5821 if ( pSatDevData->IDDeviceValid == agFALSE)
5822 {
5823 status = satStartIDDev(
5824 tiRoot,
5825 tiIORequest,
5826 tiDeviceHandle,
5827 tiScsiRequest,
5828 satIOContext
5829 );
5830 TI_DBG6(("satInquiry: end status %d\n", status));
5831 return status;
5832 }
5833 else
5834 {
5835 TI_DBG6(("satInquiry: calling satInquiryIntCB\n"));
5836 satInquiryIntCB(
5837 tiRoot,
5838 tiIORequest,
5839 tiDeviceHandle,
5840 tiScsiRequest,
5841 satIOContext
5842 );
5843
5844 return tiSuccess;
5845 }
5846
5847 }
5848
5849
5850 /*****************************************************************************/
5851 /*! \brief SAT implementation for SCSI satReadCapacity10.
5852 *
5853 * SAT implementation for SCSI satReadCapacity10.
5854 *
5855 * \param tiRoot: Pointer to TISA initiator driver/port instance.
5856 * \param tiIORequest: Pointer to TISA I/O request context for this I/O.
5857 * \param tiDeviceHandle: Pointer to TISA device handle for this I/O.
5858 * \param tiScsiRequest: Pointer to TISA SCSI I/O request and SGL list.
5859 * \param satIOContext_t: Pointer to the SAT IO Context
5860 *
5861 * \return If command is started successfully
5862 * - \e tiSuccess: I/O request successfully initiated.
5863 * - \e tiBusy: No resources available, try again later.
5864 * - \e tiIONoDevice: Invalid device handle.
5865 * - \e tiError: Other errors.
5866 */
5867 /*****************************************************************************/
5868 GLOBAL bit32 satReadCapacity10(
5869 tiRoot_t *tiRoot,
5870 tiIORequest_t *tiIORequest,
5871 tiDeviceHandle_t *tiDeviceHandle,
5872 tiScsiInitiatorRequest_t *tiScsiRequest,
5873 satIOContext_t *satIOContext)
5874 {
5875 scsiRspSense_t *pSense;
5876 tiIniScsiCmnd_t *scsiCmnd;
5877 bit8 *pVirtAddr;
5878 satDeviceData_t *pSatDevData;
5879 agsaSATAIdentifyData_t *pSATAIdData;
5880 bit32 lastLba;
5881 bit32 word117_118;
5882 bit32 word117;
5883 bit32 word118;
5884 TI_DBG5(("satReadCapacity10: start: tiDeviceHandle=%p tiIORequest=%p\n",
5885 tiDeviceHandle, tiIORequest));
5886
5887 pSense = satIOContext->pSense;
5888 pVirtAddr = (bit8 *) tiScsiRequest->sglVirtualAddr;
5889 scsiCmnd = &tiScsiRequest->scsiCmnd;
5890 pSatDevData = satIOContext->pSatDevData;
5891 pSATAIdData = &pSatDevData->satIdentifyData;
5892
5893
5894 /* checking CONTROL */
5895 /* NACA == 1 or LINK == 1*/
5896 if ( (scsiCmnd->cdb[9] & SCSI_NACA_MASK) || (scsiCmnd->cdb[9] & SCSI_LINK_MASK) )
5897 {
5898 satSetSensePayload( pSense,
5899 SCSI_SNSKEY_ILLEGAL_REQUEST,
5900 0,
5901 SCSI_SNSCODE_INVALID_FIELD_IN_CDB,
5902 satIOContext);
5903
5904 ostiInitiatorIOCompleted( tiRoot,
5905 tiIORequest,
5906 tiIOSuccess,
5907 SCSI_STAT_CHECK_CONDITION,
5908 satIOContext->pTiSenseData,
5909 satIOContext->interruptContext );
5910
5911 TI_DBG1(("satReadCapacity10: return control\n"));
5912 return tiSuccess;
5913 }
5914
5915
5916 /*
5917 * If Logical block address is not set to zero, return error
5918 */
5919 if ((scsiCmnd->cdb[2] || scsiCmnd->cdb[3] || scsiCmnd->cdb[4] || scsiCmnd->cdb[5]))
5920 {
5921 TI_DBG1(("satReadCapacity10 *** ERROR *** logical address non zero, tiDeviceHandle=%p tiIORequest=%p\n",
5922 tiDeviceHandle, tiIORequest));
5923
5924 satSetSensePayload( pSense,
5925 SCSI_SNSKEY_ILLEGAL_REQUEST,
5926 0,
5927 SCSI_SNSCODE_INVALID_FIELD_IN_CDB,
5928 satIOContext);
5929
5930 ostiInitiatorIOCompleted( tiRoot,
5931 tiIORequest,
5932 tiIOSuccess,
5933 SCSI_STAT_CHECK_CONDITION,
5934 satIOContext->pTiSenseData,
5935 satIOContext->interruptContext );
5936 return tiSuccess;
5937
5938 }
5939
5940 /*
5941 * If PMI bit is not zero, return error
5942 */
5943 if ( ((scsiCmnd->cdb[8]) & SCSI_READ_CAPACITY10_PMI_MASK) != 0 )
5944 {
5945 TI_DBG1(("satReadCapacity10 *** ERROR *** PMI is not zero, tiDeviceHandle=%p tiIORequest=%p\n",
5946 tiDeviceHandle, tiIORequest));
5947
5948 satSetSensePayload( pSense,
5949 SCSI_SNSKEY_ILLEGAL_REQUEST,
5950 0,
5951 SCSI_SNSCODE_INVALID_FIELD_IN_CDB,
5952 satIOContext);
5953
5954 ostiInitiatorIOCompleted( tiRoot,
5955 tiIORequest,
5956 tiIOSuccess,
5957 SCSI_STAT_CHECK_CONDITION,
5958 satIOContext->pTiSenseData,
5959 satIOContext->interruptContext );
5960 return tiSuccess;
5961
5962 }
5963
5964 /*
5965 filling in Read Capacity parameter data
5966 saved identify device has been already flipped
5967 See ATA spec p125 and p136 and SBC spec p54
5968 */
5969 /*
5970 * If 48-bit addressing is supported, set capacity information from Identify
5971 * Device Word 100-103.
5972 */
5973 if (pSatDevData->sat48BitSupport == agTRUE)
5974 {
5975 /*
5976 * Setting RETURNED LOGICAL BLOCK ADDRESS in READ CAPACITY(10) response data:
5977 * SBC-2 specifies that if the capacity exceeded the 4-byte RETURNED LOGICAL
5978 * BLOCK ADDRESS in READ CAPACITY(10) parameter data, the RETURNED LOGICAL
5979 * BLOCK ADDRESS should be set to 0xFFFFFFFF so the application client would
5980 * then issue a READ CAPACITY(16) command.
5981 */
5982 /* ATA Identify Device information word 100 - 103 */
5983 if ( (pSATAIdData->maxLBA32_47 != 0 ) || (pSATAIdData->maxLBA48_63 != 0))
5984 {
5985 pVirtAddr[0] = 0xFF; /* MSB number of block */
5986 pVirtAddr[1] = 0xFF;
5987 pVirtAddr[2] = 0xFF;
5988 pVirtAddr[3] = 0xFF; /* LSB number of block */
5989 TI_DBG1(("satReadCapacity10: returns 0xFFFFFFFF\n"));
5990 }
5991 else /* Fit the Readcapacity10 4-bytes response length */
5992 {
5993 lastLba = (((pSATAIdData->maxLBA16_31) << 16) ) |
5994 (pSATAIdData->maxLBA0_15);
5995 lastLba = lastLba - 1; /* LBA starts from zero */
5996
5997 /*
5998 for testing
5999 lastLba = lastLba - (512*10) - 1;
6000 */
6001
6002
6003 pVirtAddr[0] = (bit8)((lastLba >> 24) & 0xFF); /* MSB */
6004 pVirtAddr[1] = (bit8)((lastLba >> 16) & 0xFF);
6005 pVirtAddr[2] = (bit8)((lastLba >> 8) & 0xFF);
6006 pVirtAddr[3] = (bit8)((lastLba ) & 0xFF); /* LSB */
6007
6008 TI_DBG3(("satReadCapacity10: lastLba is 0x%x %d\n", lastLba, lastLba));
6009 TI_DBG3(("satReadCapacity10: LBA 0 is 0x%x %d\n", pVirtAddr[0], pVirtAddr[0]));
6010 TI_DBG3(("satReadCapacity10: LBA 1 is 0x%x %d\n", pVirtAddr[1], pVirtAddr[1]));
6011 TI_DBG3(("satReadCapacity10: LBA 2 is 0x%x %d\n", pVirtAddr[2], pVirtAddr[2]));
6012 TI_DBG3(("satReadCapacity10: LBA 3 is 0x%x %d\n", pVirtAddr[3], pVirtAddr[3]));
6013
6014 }
6015 }
6016
6017 /*
6018 * For 28-bit addressing, set capacity information from Identify
6019 * Device Word 60-61.
6020 */
6021 else
6022 {
6023 /* ATA Identify Device information word 60 - 61 */
6024 lastLba = (((pSATAIdData->numOfUserAddressableSectorsHi) << 16) ) |
6025 (pSATAIdData->numOfUserAddressableSectorsLo);
6026 lastLba = lastLba - 1; /* LBA starts from zero */
6027
6028 pVirtAddr[0] = (bit8)((lastLba >> 24) & 0xFF); /* MSB */
6029 pVirtAddr[1] = (bit8)((lastLba >> 16) & 0xFF);
6030 pVirtAddr[2] = (bit8)((lastLba >> 8) & 0xFF);
6031 pVirtAddr[3] = (bit8)((lastLba ) & 0xFF); /* LSB */
6032 }
6033 /* SAT Rev 8d */
6034 if (((pSATAIdData->word104_107[2]) & 0x1000) == 0)
6035 {
6036 TI_DBG5(("satReadCapacity10: Default Block Length is 512\n"));
6037 /*
6038 * Set the block size, fixed at 512 bytes.
6039 */
6040 pVirtAddr[4] = 0x00; /* MSB block size in bytes */
6041 pVirtAddr[5] = 0x00;
6042 pVirtAddr[6] = 0x02;
6043 pVirtAddr[7] = 0x00; /* LSB block size in bytes */
6044 }
6045 else
6046 {
6047 word118 = pSATAIdData->word112_126[6];
6048 word117 = pSATAIdData->word112_126[5];
6049
6050 word117_118 = (word118 << 16) + word117;
6051 word117_118 = word117_118 * 2;
6052 pVirtAddr[4] = (bit8)((word117_118 >> 24) & 0xFF); /* MSB block size in bytes */
6053 pVirtAddr[5] = (bit8)((word117_118 >> 16) & 0xFF);
6054 pVirtAddr[6] = (bit8)((word117_118 >> 8) & 0xFF);
6055 pVirtAddr[7] = (bit8)(word117_118 & 0xFF); /* LSB block size in bytes */
6056
6057 TI_DBG1(("satReadCapacity10: Nondefault word118 %d 0x%x \n", word118, word118));
6058 TI_DBG1(("satReadCapacity10: Nondefault word117 %d 0x%x \n", word117, word117));
6059 TI_DBG1(("satReadCapacity10: Nondefault Block Length is %d 0x%x \n",word117_118, word117_118));
6060
6061 }
6062
6063 /* fill in MAX LBA, which is used in satSendDiagnostic_1() */
6064 pSatDevData->satMaxLBA[0] = 0; /* MSB */
6065 pSatDevData->satMaxLBA[1] = 0;
6066 pSatDevData->satMaxLBA[2] = 0;
6067 pSatDevData->satMaxLBA[3] = 0;
6068 pSatDevData->satMaxLBA[4] = pVirtAddr[0];
6069 pSatDevData->satMaxLBA[5] = pVirtAddr[1];
6070 pSatDevData->satMaxLBA[6] = pVirtAddr[2];
6071 pSatDevData->satMaxLBA[7] = pVirtAddr[3]; /* LSB */
6072
6073
6074 TI_DBG4(("satReadCapacity10 0x%x 0x%x 0x%x 0x%x 0x%x 0x%x 0x%x 0x%x , tiDeviceHandle=%p tiIORequest=%p\n",
6075 pVirtAddr[0], pVirtAddr[1], pVirtAddr[2], pVirtAddr[3],
6076 pVirtAddr[4], pVirtAddr[5], pVirtAddr[6], pVirtAddr[7],
6077 tiDeviceHandle, tiIORequest));
6078
6079
6080 /*
6081 * Send the completion response now.
6082 */
6083 ostiInitiatorIOCompleted( tiRoot,
6084 tiIORequest,
6085 tiIOSuccess,
6086 SCSI_STAT_GOOD,
6087 agNULL,
6088 satIOContext->interruptContext);
6089 return tiSuccess;
6090 }
6091
6092
6093 /*****************************************************************************/
6094 /*! \brief SAT implementation for SCSI satReadCapacity16.
6095 *
6096 * SAT implementation for SCSI satReadCapacity16.
6097 *
6098 * \param tiRoot: Pointer to TISA initiator driver/port instance.
6099 * \param tiIORequest: Pointer to TISA I/O request context for this I/O.
6100 * \param tiDeviceHandle: Pointer to TISA device handle for this I/O.
6101 * \param tiScsiRequest: Pointer to TISA SCSI I/O request and SGL list.
6102 * \param satIOContext_t: Pointer to the SAT IO Context
6103 *
6104 * \return If command is started successfully
6105 * - \e tiSuccess: I/O request successfully initiated.
6106 * - \e tiBusy: No resources available, try again later.
6107 * - \e tiIONoDevice: Invalid device handle.
6108 * - \e tiError: Other errors.
6109 */
6110 /*****************************************************************************/
6111 GLOBAL bit32 satReadCapacity16(
6112 tiRoot_t *tiRoot,
6113 tiIORequest_t *tiIORequest,
6114 tiDeviceHandle_t *tiDeviceHandle,
6115 tiScsiInitiatorRequest_t *tiScsiRequest,
6116 satIOContext_t *satIOContext)
6117 {
6118
6119 scsiRspSense_t *pSense;
6120 tiIniScsiCmnd_t *scsiCmnd;
6121 bit8 *pVirtAddr;
6122 satDeviceData_t *pSatDevData;
6123 agsaSATAIdentifyData_t *pSATAIdData;
6124 bit32 lastLbaLo;
6125 bit32 allocationLen;
6126 bit32 readCapacityLen = 32;
6127 bit32 i = 0;
6128 TI_DBG5(("satReadCapacity16 start: tiDeviceHandle=%p tiIORequest=%p\n",
6129 tiDeviceHandle, tiIORequest));
6130
6131 pSense = satIOContext->pSense;
6132 pVirtAddr = (bit8 *) tiScsiRequest->sglVirtualAddr;
6133 scsiCmnd = &tiScsiRequest->scsiCmnd;
6134 pSatDevData = satIOContext->pSatDevData;
6135 pSATAIdData = &pSatDevData->satIdentifyData;
6136
6137 /* Find the buffer size allocated by Initiator */
6138 allocationLen = (((bit32)scsiCmnd->cdb[10]) << 24) |
6139 (((bit32)scsiCmnd->cdb[11]) << 16) |
6140 (((bit32)scsiCmnd->cdb[12]) << 8 ) |
6141 (((bit32)scsiCmnd->cdb[13]) );
6142
6143
6144 if (allocationLen < readCapacityLen)
6145 {
6146 TI_DBG1(("satReadCapacity16 *** ERROR *** insufficient len=0x%x readCapacityLen=0x%x\n", allocationLen, readCapacityLen));
6147
6148 satSetSensePayload( pSense,
6149 SCSI_SNSKEY_ILLEGAL_REQUEST,
6150 0,
6151 SCSI_SNSCODE_INVALID_FIELD_IN_CDB,
6152 satIOContext);
6153
6154 ostiInitiatorIOCompleted( tiRoot,
6155 tiIORequest,
6156 tiIOSuccess,
6157 SCSI_STAT_CHECK_CONDITION,
6158 satIOContext->pTiSenseData,
6159 satIOContext->interruptContext );
6160 return tiSuccess;
6161
6162 }
6163
6164 /* checking CONTROL */
6165 /* NACA == 1 or LINK == 1*/
6166 if ( (scsiCmnd->cdb[15] & SCSI_NACA_MASK) || (scsiCmnd->cdb[15] & SCSI_LINK_MASK) )
6167 {
6168 satSetSensePayload( pSense,
6169 SCSI_SNSKEY_ILLEGAL_REQUEST,
6170 0,
6171 SCSI_SNSCODE_INVALID_FIELD_IN_CDB,
6172 satIOContext);
6173
6174 ostiInitiatorIOCompleted( tiRoot,
6175 tiIORequest,
6176 tiIOSuccess,
6177 SCSI_STAT_CHECK_CONDITION,
6178 satIOContext->pTiSenseData,
6179 satIOContext->interruptContext );
6180
6181 TI_DBG1(("satReadCapacity16: return control\n"));
6182 return tiSuccess;
6183 }
6184
6185 /*
6186 * If Logical blcok address is not set to zero, return error
6187 */
6188 if ((scsiCmnd->cdb[2] || scsiCmnd->cdb[3] || scsiCmnd->cdb[4] || scsiCmnd->cdb[5]) ||
6189 (scsiCmnd->cdb[6] || scsiCmnd->cdb[7] || scsiCmnd->cdb[8] || scsiCmnd->cdb[9]) )
6190 {
6191 TI_DBG1(("satReadCapacity16 *** ERROR *** logical address non zero, tiDeviceHandle=%p tiIORequest=%p\n",
6192 tiDeviceHandle, tiIORequest));
6193
6194 satSetSensePayload( pSense,
6195 SCSI_SNSKEY_ILLEGAL_REQUEST,
6196 0,
6197 SCSI_SNSCODE_INVALID_FIELD_IN_CDB,
6198 satIOContext);
6199
6200 ostiInitiatorIOCompleted( tiRoot,
6201 tiIORequest,
6202 tiIOSuccess,
6203 SCSI_STAT_CHECK_CONDITION,
6204 satIOContext->pTiSenseData,
6205 satIOContext->interruptContext );
6206 return tiSuccess;
6207
6208 }
6209
6210 /*
6211 * If PMI bit is not zero, return error
6212 */
6213 if ( ((scsiCmnd->cdb[14]) & SCSI_READ_CAPACITY16_PMI_MASK) != 0 )
6214 {
6215 TI_DBG1(("satReadCapacity16 *** ERROR *** PMI is not zero, tiDeviceHandle=%p tiIORequest=%p\n",
6216 tiDeviceHandle, tiIORequest));
6217
6218 satSetSensePayload( pSense,
6219 SCSI_SNSKEY_ILLEGAL_REQUEST,
6220 0,
6221 SCSI_SNSCODE_INVALID_FIELD_IN_CDB,
6222 satIOContext);
6223
6224 ostiInitiatorIOCompleted( tiRoot,
6225 tiIORequest,
6226 tiIOSuccess,
6227 SCSI_STAT_CHECK_CONDITION,
6228 satIOContext->pTiSenseData,
6229 satIOContext->interruptContext );
6230 return tiSuccess;
6231
6232 }
6233
6234 /*
6235 filling in Read Capacity parameter data
6236 */
6237
6238 /*
6239 * If 48-bit addressing is supported, set capacity information from Identify
6240 * Device Word 100-103.
6241 */
6242 if (pSatDevData->sat48BitSupport == agTRUE)
6243 {
6244 pVirtAddr[0] = (bit8)(((pSATAIdData->maxLBA48_63) >> 8) & 0xff); /* MSB */
6245 pVirtAddr[1] = (bit8)((pSATAIdData->maxLBA48_63) & 0xff);
6246 pVirtAddr[2] = (bit8)(((pSATAIdData->maxLBA32_47) >> 8) & 0xff);
6247 pVirtAddr[3] = (bit8)((pSATAIdData->maxLBA32_47) & 0xff);
6248
6249 lastLbaLo = (((pSATAIdData->maxLBA16_31) << 16) ) | (pSATAIdData->maxLBA0_15);
6250 lastLbaLo = lastLbaLo - 1; /* LBA starts from zero */
6251
6252 pVirtAddr[4] = (bit8)((lastLbaLo >> 24) & 0xFF);
6253 pVirtAddr[5] = (bit8)((lastLbaLo >> 16) & 0xFF);
6254 pVirtAddr[6] = (bit8)((lastLbaLo >> 8) & 0xFF);
6255 pVirtAddr[7] = (bit8)((lastLbaLo ) & 0xFF); /* LSB */
6256
6257 }
6258
6259 /*
6260 * For 28-bit addressing, set capacity information from Identify
6261 * Device Word 60-61.
6262 */
6263 else
6264 {
6265 pVirtAddr[0] = 0; /* MSB */
6266 pVirtAddr[1] = 0;
6267 pVirtAddr[2] = 0;
6268 pVirtAddr[3] = 0;
6269
6270 lastLbaLo = (((pSATAIdData->numOfUserAddressableSectorsHi) << 16) ) |
6271 (pSATAIdData->numOfUserAddressableSectorsLo);
6272 lastLbaLo = lastLbaLo - 1; /* LBA starts from zero */
6273
6274 pVirtAddr[4] = (bit8)((lastLbaLo >> 24) & 0xFF);
6275 pVirtAddr[5] = (bit8)((lastLbaLo >> 16) & 0xFF);
6276 pVirtAddr[6] = (bit8)((lastLbaLo >> 8) & 0xFF);
6277 pVirtAddr[7] = (bit8)((lastLbaLo ) & 0xFF); /* LSB */
6278
6279 }
6280
6281 /*
6282 * Set the block size, fixed at 512 bytes.
6283 */
6284 pVirtAddr[8] = 0x00; /* MSB block size in bytes */
6285 pVirtAddr[9] = 0x00;
6286 pVirtAddr[10] = 0x02;
6287 pVirtAddr[11] = 0x00; /* LSB block size in bytes */
6288
6289
6290 /* fill in MAX LBA, which is used in satSendDiagnostic_1() */
6291 pSatDevData->satMaxLBA[0] = pVirtAddr[0]; /* MSB */
6292 pSatDevData->satMaxLBA[1] = pVirtAddr[1];
6293 pSatDevData->satMaxLBA[2] = pVirtAddr[2];
6294 pSatDevData->satMaxLBA[3] = pVirtAddr[3];
6295 pSatDevData->satMaxLBA[4] = pVirtAddr[4];
6296 pSatDevData->satMaxLBA[5] = pVirtAddr[5];
6297 pSatDevData->satMaxLBA[6] = pVirtAddr[6];
6298 pSatDevData->satMaxLBA[7] = pVirtAddr[7]; /* LSB */
6299
6300 TI_DBG5(("satReadCapacity16 0x%x 0x%x 0x%x 0x%x 0x%x 0x%x 0x%x 0x%x 0x%x 0x%x 0x%x 0x%x , tiDeviceHandle=%p tiIORequest=%p\n",
6301 pVirtAddr[0], pVirtAddr[1], pVirtAddr[2], pVirtAddr[3],
6302 pVirtAddr[4], pVirtAddr[5], pVirtAddr[6], pVirtAddr[7],
6303 pVirtAddr[8], pVirtAddr[9], pVirtAddr[10], pVirtAddr[11],
6304 tiDeviceHandle, tiIORequest));
6305
6306 for(i=12;i<=31;i++)
6307 {
6308 pVirtAddr[i] = 0x00;
6309 }
6310
6311 /*
6312 * Send the completion response now.
6313 */
6314 if (allocationLen > readCapacityLen)
6315 {
6316 /* underrun */
6317 TI_DBG1(("satReadCapacity16 reporting underrun readCapacityLen=0x%x allocationLen=0x%x \n", readCapacityLen, allocationLen));
6318
6319 ostiInitiatorIOCompleted( tiRoot,
6320 tiIORequest,
6321 tiIOUnderRun,
6322 allocationLen - readCapacityLen,
6323 agNULL,
6324 satIOContext->interruptContext );
6325
6326
6327 }
6328 else
6329 {
6330 ostiInitiatorIOCompleted( tiRoot,
6331 tiIORequest,
6332 tiIOSuccess,
6333 SCSI_STAT_GOOD,
6334 agNULL,
6335 satIOContext->interruptContext);
6336 }
6337 return tiSuccess;
6338
6339 }
6340
6341
6342 /*****************************************************************************/
6343 /*! \brief SAT implementation for SCSI MODE SENSE (6).
6344 *
6345 * SAT implementation for SCSI MODE SENSE (6).
6346 *
6347 * \param tiRoot: Pointer to TISA initiator driver/port instance.
6348 * \param tiIORequest: Pointer to TISA I/O request context for this I/O.
6349 * \param tiDeviceHandle: Pointer to TISA device handle for this I/O.
6350 * \param tiScsiRequest: Pointer to TISA SCSI I/O request and SGL list.
6351 * \param satIOContext_t: Pointer to the SAT IO Context
6352 *
6353 * \return If command is started successfully
6354 * - \e tiSuccess: I/O request successfully initiated.
6355 * - \e tiBusy: No resources available, try again later.
6356 * - \e tiIONoDevice: Invalid device handle.
6357 * - \e tiError: Other errors.
6358 */
6359 /*****************************************************************************/
6360 GLOBAL bit32 satModeSense6(
6361 tiRoot_t *tiRoot,
6362 tiIORequest_t *tiIORequest,
6363 tiDeviceHandle_t *tiDeviceHandle,
6364 tiScsiInitiatorRequest_t *tiScsiRequest,
6365 satIOContext_t *satIOContext)
6366 {
6367
6368 scsiRspSense_t *pSense;
6369 bit32 requestLen;
6370 tiIniScsiCmnd_t *scsiCmnd;
6371 bit32 pageSupported;
6372 bit8 page;
6373 bit8 *pModeSense; /* Mode Sense data buffer */
6374 satDeviceData_t *pSatDevData;
6375 bit8 PC;
6376 bit8 AllPages[MODE_SENSE6_RETURN_ALL_PAGES_LEN];
6377 bit8 Control[MODE_SENSE6_CONTROL_PAGE_LEN];
6378 bit8 RWErrorRecovery[MODE_SENSE6_READ_WRITE_ERROR_RECOVERY_PAGE_LEN];
6379 bit8 Caching[MODE_SENSE6_CACHING_LEN];
6380 bit8 InfoExceptionCtrl[MODE_SENSE6_INFORMATION_EXCEPTION_CONTROL_PAGE_LEN];
6381 bit8 lenRead = 0;
6382
6383
6384 TI_DBG5(("satModeSense6 entry: tiDeviceHandle=%p tiIORequest=%p\n",
6385 tiDeviceHandle, tiIORequest));
6386
6387 pSense = satIOContext->pSense;
6388 scsiCmnd = &tiScsiRequest->scsiCmnd;
6389 pModeSense = (bit8 *) tiScsiRequest->sglVirtualAddr;
6390 pSatDevData = satIOContext->pSatDevData;
6391
6392 //tdhexdump("satModeSense6", (bit8 *)scsiCmnd->cdb, 6);
6393 /* checking CONTROL */
6394 /* NACA == 1 or LINK == 1*/
6395 if ( (scsiCmnd->cdb[5] & SCSI_NACA_MASK) || (scsiCmnd->cdb[5] & SCSI_LINK_MASK) )
6396 {
6397 satSetSensePayload( pSense,
6398 SCSI_SNSKEY_ILLEGAL_REQUEST,
6399 0,
6400 SCSI_SNSCODE_INVALID_FIELD_IN_CDB,
6401 satIOContext);
6402
6403 ostiInitiatorIOCompleted( tiRoot,
6404 tiIORequest,
6405 tiIOSuccess,
6406 SCSI_STAT_CHECK_CONDITION,
6407 satIOContext->pTiSenseData,
6408 satIOContext->interruptContext );
6409
6410 TI_DBG2(("satModeSense6: return control\n"));
6411 return tiSuccess;
6412 }
6413
6414 /* checking PC(Page Control)
6415 SAT revion 8, 8.5.3 p33 and 10.1.2, p66
6416 */
6417 PC = (bit8)((scsiCmnd->cdb[2]) & SCSI_MODE_SENSE6_PC_MASK);
6418 if (PC != 0)
6419 {
6420 satSetSensePayload( pSense,
6421 SCSI_SNSKEY_ILLEGAL_REQUEST,
6422 0,
6423 SCSI_SNSCODE_INVALID_FIELD_IN_CDB,
6424 satIOContext);
6425
6426 ostiInitiatorIOCompleted( tiRoot,
6427 tiIORequest,
6428 tiIOSuccess,
6429 SCSI_STAT_CHECK_CONDITION,
6430 satIOContext->pTiSenseData,
6431 satIOContext->interruptContext );
6432
6433 TI_DBG1(("satModeSense6: return due to PC value pc 0x%x\n", PC >> 6));
6434 return tiSuccess;
6435 }
6436
6437 /* reading PAGE CODE */
6438 page = (bit8)((scsiCmnd->cdb[2]) & SCSI_MODE_SENSE6_PAGE_CODE_MASK);
6439
6440
6441 TI_DBG5(("satModeSense6: page=0x%x, tiDeviceHandle=%p tiIORequest=%p\n",
6442 page, tiDeviceHandle, tiIORequest));
6443
6444 requestLen = scsiCmnd->cdb[4];
6445
6446 /*
6447 Based on page code value, returns a corresponding mode page
6448 note: no support for subpage
6449 */
6450
6451 switch(page)
6452 {
6453 case MODESENSE_RETURN_ALL_PAGES:
6454 case MODESENSE_CONTROL_PAGE: /* control */
6455 case MODESENSE_READ_WRITE_ERROR_RECOVERY_PAGE: /* Read-Write Error Recovery */
6456 case MODESENSE_CACHING: /* caching */
6457 case MODESENSE_INFORMATION_EXCEPTION_CONTROL_PAGE: /* informational exceptions control*/
6458 pageSupported = agTRUE;
6459 break;
6460 case MODESENSE_VENDOR_SPECIFIC_PAGE: /* vendor specific */
6461 default:
6462 pageSupported = agFALSE;
6463 break;
6464 }
6465
6466 if (pageSupported == agFALSE)
6467 {
6468
6469 TI_DBG1(("satModeSense6 *** ERROR *** not supported page 0x%x tiDeviceHandle=%p tiIORequest=%p\n",
6470 page, tiDeviceHandle, tiIORequest));
6471
6472 satSetSensePayload( pSense,
6473 SCSI_SNSKEY_ILLEGAL_REQUEST,
6474 0,
6475 SCSI_SNSCODE_INVALID_COMMAND,
6476 satIOContext);
6477
6478 ostiInitiatorIOCompleted( tiRoot,
6479 tiIORequest,
6480 tiIOSuccess,
6481 SCSI_STAT_CHECK_CONDITION,
6482 satIOContext->pTiSenseData,
6483 satIOContext->interruptContext );
6484 return tiSuccess;
6485 }
6486
6487 switch(page)
6488 {
6489 case MODESENSE_RETURN_ALL_PAGES:
6490 lenRead = (bit8)MIN(requestLen, MODE_SENSE6_RETURN_ALL_PAGES_LEN);
6491 break;
6492 case MODESENSE_CONTROL_PAGE: /* control */
6493 lenRead = (bit8)MIN(requestLen, MODE_SENSE6_CONTROL_PAGE_LEN);
6494 break;
6495 case MODESENSE_READ_WRITE_ERROR_RECOVERY_PAGE: /* Read-Write Error Recovery */
6496 lenRead = (bit8)MIN(requestLen, MODE_SENSE6_READ_WRITE_ERROR_RECOVERY_PAGE_LEN);
6497 break;
6498 case MODESENSE_CACHING: /* caching */
6499 lenRead = (bit8)MIN(requestLen, MODE_SENSE6_CACHING_LEN);
6500 break;
6501 case MODESENSE_INFORMATION_EXCEPTION_CONTROL_PAGE: /* informational exceptions control*/
6502 lenRead = (bit8)MIN(requestLen, MODE_SENSE6_INFORMATION_EXCEPTION_CONTROL_PAGE_LEN);
6503 break;
6504 default:
6505 TI_DBG1(("satModeSense6: default error page %d\n", page));
6506 break;
6507 }
6508
6509 if (page == MODESENSE_RETURN_ALL_PAGES)
6510 {
6511 TI_DBG5(("satModeSense6: MODESENSE_RETURN_ALL_PAGES\n"));
6512 AllPages[0] = (bit8)(lenRead - 1);
6513 AllPages[1] = 0x00; /* default medium type (currently mounted medium type) */
6514 AllPages[2] = 0x00; /* no write-protect, no support for DPO-FUA */
6515 AllPages[3] = 0x08; /* block descriptor length */
6516
6517 /*
6518 * Fill-up direct-access device block-descriptor, SAT, Table 19
6519 */
6520
6521 /* density code */
6522 AllPages[4] = 0x04; /* density-code : reserved for direct-access */
6523 /* number of blocks */
6524 AllPages[5] = 0x00; /* unspecified */
6525 AllPages[6] = 0x00; /* unspecified */
6526 AllPages[7] = 0x00; /* unspecified */
6527 /* reserved */
6528 AllPages[8] = 0x00; /* reserved */
6529 /* Block size */
6530 AllPages[9] = 0x00;
6531 AllPages[10] = 0x02; /* Block size is always 512 bytes */
6532 AllPages[11] = 0x00;
6533
6534 /* MODESENSE_READ_WRITE_ERROR_RECOVERY_PAGE */
6535 AllPages[12] = 0x01; /* page code */
6536 AllPages[13] = 0x0A; /* page length */
6537 AllPages[14] = 0x40; /* ARRE is set */
6538 AllPages[15] = 0x00;
6539 AllPages[16] = 0x00;
6540 AllPages[17] = 0x00;
6541 AllPages[18] = 0x00;
6542 AllPages[19] = 0x00;
6543 AllPages[20] = 0x00;
6544 AllPages[21] = 0x00;
6545 AllPages[22] = 0x00;
6546 AllPages[23] = 0x00;
6547 /* MODESENSE_CACHING */
6548 AllPages[24] = 0x08; /* page code */
6549 AllPages[25] = 0x12; /* page length */
6550 #ifdef NOT_YET
6551 if (pSatDevData->satWriteCacheEnabled == agTRUE)
6552 {
6553 AllPages[26] = 0x04;/* WCE bit is set */
6554 }
6555 else
6556 {
6557 AllPages[26] = 0x00;/* WCE bit is NOT set */
6558 }
6559 #endif
6560 AllPages[26] = 0x00;/* WCE bit is NOT set */
6561
6562 AllPages[27] = 0x00;
6563 AllPages[28] = 0x00;
6564 AllPages[29] = 0x00;
6565 AllPages[30] = 0x00;
6566 AllPages[31] = 0x00;
6567 AllPages[32] = 0x00;
6568 AllPages[33] = 0x00;
6569 AllPages[34] = 0x00;
6570 AllPages[35] = 0x00;
6571 if (pSatDevData->satLookAheadEnabled == agTRUE)
6572 {
6573 AllPages[36] = 0x00;/* DRA bit is NOT set */
6574 }
6575 else
6576 {
6577 AllPages[36] = 0x20;/* DRA bit is set */
6578 }
6579 AllPages[37] = 0x00;
6580 AllPages[38] = 0x00;
6581 AllPages[39] = 0x00;
6582 AllPages[40] = 0x00;
6583 AllPages[41] = 0x00;
6584 AllPages[42] = 0x00;
6585 AllPages[43] = 0x00;
6586 /* MODESENSE_CONTROL_PAGE */
6587 AllPages[44] = 0x0A; /* page code */
6588 AllPages[45] = 0x0A; /* page length */
6589 AllPages[46] = 0x02; /* only GLTSD bit is set */
6590 if (pSatDevData->satNCQ == agTRUE)
6591 {
6592 AllPages[47] = 0x12; /* Queue Alogorithm modifier 1b and QErr 01b*/
6593 }
6594 else
6595 {
6596 AllPages[47] = 0x02; /* Queue Alogorithm modifier 0b and QErr 01b */
6597 }
6598 AllPages[48] = 0x00;
6599 AllPages[49] = 0x00;
6600 AllPages[50] = 0x00; /* obsolete */
6601 AllPages[51] = 0x00; /* obsolete */
6602 AllPages[52] = 0xFF; /* Busy Timeout Period */
6603 AllPages[53] = 0xFF; /* Busy Timeout Period */
6604 AllPages[54] = 0x00; /* we don't support non-000b value for the self-test code */
6605 AllPages[55] = 0x00; /* we don't support non-000b value for the self-test code */
6606 /* MODESENSE_INFORMATION_EXCEPTION_CONTROL_PAGE */
6607 AllPages[56] = 0x1C; /* page code */
6608 AllPages[57] = 0x0A; /* page length */
6609 if (pSatDevData->satSMARTEnabled == agTRUE)
6610 {
6611 AllPages[58] = 0x00;/* DEXCPT bit is NOT set */
6612 }
6613 else
6614 {
6615 AllPages[58] = 0x08;/* DEXCPT bit is set */
6616 }
6617 AllPages[59] = 0x00; /* We don't support MRIE */
6618 AllPages[60] = 0x00; /* Interval timer vendor-specific */
6619 AllPages[61] = 0x00;
6620 AllPages[62] = 0x00;
6621 AllPages[63] = 0x00;
6622 AllPages[64] = 0x00; /* REPORT-COUNT */
6623 AllPages[65] = 0x00;
6624 AllPages[66] = 0x00;
6625 AllPages[67] = 0x00;
6626
6627 osti_memcpy(pModeSense, &AllPages, lenRead);
6628 }
6629 else if (page == MODESENSE_CONTROL_PAGE)
6630 {
6631 TI_DBG5(("satModeSense6: MODESENSE_CONTROL_PAGE\n"));
6632 Control[0] = MODE_SENSE6_CONTROL_PAGE_LEN - 1;
6633 Control[1] = 0x00; /* default medium type (currently mounted medium type) */
6634 Control[2] = 0x00; /* no write-protect, no support for DPO-FUA */
6635 Control[3] = 0x08; /* block descriptor length */
6636 /*
6637 * Fill-up direct-access device block-descriptor, SAT, Table 19
6638 */
6639
6640 /* density code */
6641 Control[4] = 0x04; /* density-code : reserved for direct-access */
6642 /* number of blocks */
6643 Control[5] = 0x00; /* unspecified */
6644 Control[6] = 0x00; /* unspecified */
6645 Control[7] = 0x00; /* unspecified */
6646 /* reserved */
6647 Control[8] = 0x00; /* reserved */
6648 /* Block size */
6649 Control[9] = 0x00;
6650 Control[10] = 0x02; /* Block size is always 512 bytes */
6651 Control[11] = 0x00;
6652 /*
6653 * Fill-up control mode page, SAT, Table 65
6654 */
6655 Control[12] = 0x0A; /* page code */
6656 Control[13] = 0x0A; /* page length */
6657 Control[14] = 0x02; /* only GLTSD bit is set */
6658 if (pSatDevData->satNCQ == agTRUE)
6659 {
6660 Control[15] = 0x12; /* Queue Alogorithm modifier 1b and QErr 01b*/
6661 }
6662 else
6663 {
6664 Control[15] = 0x02; /* Queue Alogorithm modifier 0b and QErr 01b */
6665 }
6666 Control[16] = 0x00;
6667 Control[17] = 0x00;
6668 Control[18] = 0x00; /* obsolete */
6669 Control[19] = 0x00; /* obsolete */
6670 Control[20] = 0xFF; /* Busy Timeout Period */
6671 Control[21] = 0xFF; /* Busy Timeout Period */
6672 Control[22] = 0x00; /* we don't support non-000b value for the self-test code */
6673 Control[23] = 0x00; /* we don't support non-000b value for the self-test code */
6674
6675 osti_memcpy(pModeSense, &Control, lenRead);
6676
6677 }
6678 else if (page == MODESENSE_READ_WRITE_ERROR_RECOVERY_PAGE)
6679 {
6680 TI_DBG5(("satModeSense6: MODESENSE_READ_WRITE_ERROR_RECOVERY_PAGE\n"));
6681 RWErrorRecovery[0] = MODE_SENSE6_READ_WRITE_ERROR_RECOVERY_PAGE_LEN - 1;
6682 RWErrorRecovery[1] = 0x00; /* default medium type (currently mounted medium type) */
6683 RWErrorRecovery[2] = 0x00; /* no write-protect, no support for DPO-FUA */
6684 RWErrorRecovery[3] = 0x08; /* block descriptor length */
6685 /*
6686 * Fill-up direct-access device block-descriptor, SAT, Table 19
6687 */
6688
6689 /* density code */
6690 RWErrorRecovery[4] = 0x04; /* density-code : reserved for direct-access */
6691 /* number of blocks */
6692 RWErrorRecovery[5] = 0x00; /* unspecified */
6693 RWErrorRecovery[6] = 0x00; /* unspecified */
6694 RWErrorRecovery[7] = 0x00; /* unspecified */
6695 /* reserved */
6696 RWErrorRecovery[8] = 0x00; /* reserved */
6697 /* Block size */
6698 RWErrorRecovery[9] = 0x00;
6699 RWErrorRecovery[10] = 0x02; /* Block size is always 512 bytes */
6700 RWErrorRecovery[11] = 0x00;
6701 /*
6702 * Fill-up Read-Write Error Recovery mode page, SAT, Table 66
6703 */
6704 RWErrorRecovery[12] = 0x01; /* page code */
6705 RWErrorRecovery[13] = 0x0A; /* page length */
6706 RWErrorRecovery[14] = 0x40; /* ARRE is set */
6707 RWErrorRecovery[15] = 0x00;
6708 RWErrorRecovery[16] = 0x00;
6709 RWErrorRecovery[17] = 0x00;
6710 RWErrorRecovery[18] = 0x00;
6711 RWErrorRecovery[19] = 0x00;
6712 RWErrorRecovery[20] = 0x00;
6713 RWErrorRecovery[21] = 0x00;
6714 RWErrorRecovery[22] = 0x00;
6715 RWErrorRecovery[23] = 0x00;
6716
6717 osti_memcpy(pModeSense, &RWErrorRecovery, lenRead);
6718
6719 }
6720 else if (page == MODESENSE_CACHING)
6721 {
6722 TI_DBG5(("satModeSense6: MODESENSE_CACHING\n"));
6723 /* special case */
6724 if (requestLen == 4 && page == MODESENSE_CACHING)
6725 {
6726 TI_DBG5(("satModeSense6: linux 2.6.8.24 support\n"));
6727
6728 pModeSense[0] = 0x20 - 1; /* 32 - 1 */
6729 pModeSense[1] = 0x00; /* default medium type (currently mounted medium type) */
6730 pModeSense[2] = 0x00; /* no write-protect, no support for DPO-FUA */
6731 pModeSense[3] = 0x08; /* block descriptor length */
6732 ostiInitiatorIOCompleted( tiRoot,
6733 tiIORequest,
6734 tiIOSuccess,
6735 SCSI_STAT_GOOD,
6736 agNULL,
6737 satIOContext->interruptContext);
6738 return tiSuccess;
6739 }
6740 Caching[0] = MODE_SENSE6_CACHING_LEN - 1;
6741 Caching[1] = 0x00; /* default medium type (currently mounted medium type) */
6742 Caching[2] = 0x00; /* no write-protect, no support for DPO-FUA */
6743 Caching[3] = 0x08; /* block descriptor length */
6744 /*
6745 * Fill-up direct-access device block-descriptor, SAT, Table 19
6746 */
6747
6748 /* density code */
6749 Caching[4] = 0x04; /* density-code : reserved for direct-access */
6750 /* number of blocks */
6751 Caching[5] = 0x00; /* unspecified */
6752 Caching[6] = 0x00; /* unspecified */
6753 Caching[7] = 0x00; /* unspecified */
6754 /* reserved */
6755 Caching[8] = 0x00; /* reserved */
6756 /* Block size */
6757 Caching[9] = 0x00;
6758 Caching[10] = 0x02; /* Block size is always 512 bytes */
6759 Caching[11] = 0x00;
6760 /*
6761 * Fill-up Caching mode page, SAT, Table 67
6762 */
6763 /* length 20 */
6764 Caching[12] = 0x08; /* page code */
6765 Caching[13] = 0x12; /* page length */
6766 #ifdef NOT_YET
6767 if (pSatDevData->satWriteCacheEnabled == agTRUE)
6768 {
6769 Caching[14] = 0x04;/* WCE bit is set */
6770 }
6771 else
6772 {
6773 Caching[14] = 0x00;/* WCE bit is NOT set */
6774 }
6775 #endif
6776 Caching[14] = 0x00;/* WCE bit is NOT set */
6777
6778 Caching[15] = 0x00;
6779 Caching[16] = 0x00;
6780 Caching[17] = 0x00;
6781 Caching[18] = 0x00;
6782 Caching[19] = 0x00;
6783 Caching[20] = 0x00;
6784 Caching[21] = 0x00;
6785 Caching[22] = 0x00;
6786 Caching[23] = 0x00;
6787 if (pSatDevData->satLookAheadEnabled == agTRUE)
6788 {
6789 Caching[24] = 0x00;/* DRA bit is NOT set */
6790 }
6791 else
6792 {
6793 Caching[24] = 0x20;/* DRA bit is set */
6794 }
6795 Caching[25] = 0x00;
6796 Caching[26] = 0x00;
6797 Caching[27] = 0x00;
6798 Caching[28] = 0x00;
6799 Caching[29] = 0x00;
6800 Caching[30] = 0x00;
6801 Caching[31] = 0x00;
6802
6803 osti_memcpy(pModeSense, &Caching, lenRead);
6804
6805 }
6806 else if (page == MODESENSE_INFORMATION_EXCEPTION_CONTROL_PAGE)
6807 {
6808 TI_DBG5(("satModeSense6: MODESENSE_INFORMATION_EXCEPTION_CONTROL_PAGE\n"));
6809 InfoExceptionCtrl[0] = MODE_SENSE6_INFORMATION_EXCEPTION_CONTROL_PAGE_LEN - 1;
6810 InfoExceptionCtrl[1] = 0x00; /* default medium type (currently mounted medium type) */
6811 InfoExceptionCtrl[2] = 0x00; /* no write-protect, no support for DPO-FUA */
6812 InfoExceptionCtrl[3] = 0x08; /* block descriptor length */
6813 /*
6814 * Fill-up direct-access device block-descriptor, SAT, Table 19
6815 */
6816
6817 /* density code */
6818 InfoExceptionCtrl[4] = 0x04; /* density-code : reserved for direct-access */
6819 /* number of blocks */
6820 InfoExceptionCtrl[5] = 0x00; /* unspecified */
6821 InfoExceptionCtrl[6] = 0x00; /* unspecified */
6822 InfoExceptionCtrl[7] = 0x00; /* unspecified */
6823 /* reserved */
6824 InfoExceptionCtrl[8] = 0x00; /* reserved */
6825 /* Block size */
6826 InfoExceptionCtrl[9] = 0x00;
6827 InfoExceptionCtrl[10] = 0x02; /* Block size is always 512 bytes */
6828 InfoExceptionCtrl[11] = 0x00;
6829 /*
6830 * Fill-up informational-exceptions control mode page, SAT, Table 68
6831 */
6832 InfoExceptionCtrl[12] = 0x1C; /* page code */
6833 InfoExceptionCtrl[13] = 0x0A; /* page length */
6834 if (pSatDevData->satSMARTEnabled == agTRUE)
6835 {
6836 InfoExceptionCtrl[14] = 0x00;/* DEXCPT bit is NOT set */
6837 }
6838 else
6839 {
6840 InfoExceptionCtrl[14] = 0x08;/* DEXCPT bit is set */
6841 }
6842 InfoExceptionCtrl[15] = 0x00; /* We don't support MRIE */
6843 InfoExceptionCtrl[16] = 0x00; /* Interval timer vendor-specific */
6844 InfoExceptionCtrl[17] = 0x00;
6845 InfoExceptionCtrl[18] = 0x00;
6846 InfoExceptionCtrl[19] = 0x00;
6847 InfoExceptionCtrl[20] = 0x00; /* REPORT-COUNT */
6848 InfoExceptionCtrl[21] = 0x00;
6849 InfoExceptionCtrl[22] = 0x00;
6850 InfoExceptionCtrl[23] = 0x00;
6851 osti_memcpy(pModeSense, &InfoExceptionCtrl, lenRead);
6852
6853 }
6854 else
6855 {
6856 /* Error */
6857 TI_DBG1(("satModeSense6: Error page %d\n", page));
6858 satSetSensePayload( pSense,
6859 SCSI_SNSKEY_ILLEGAL_REQUEST,
6860 0,
6861 SCSI_SNSCODE_INVALID_COMMAND,
6862 satIOContext);
6863
6864 ostiInitiatorIOCompleted( tiRoot,
6865 tiIORequest,
6866 tiIOSuccess,
6867 SCSI_STAT_CHECK_CONDITION,
6868 satIOContext->pTiSenseData,
6869 satIOContext->interruptContext );
6870 return tiSuccess;
6871 }
6872
6873 /* there can be only underrun not overrun in error case */
6874 if (requestLen > lenRead)
6875 {
6876 TI_DBG6(("satModeSense6 reporting underrun lenRead=0x%x requestLen=0x%x tiIORequest=%p\n", lenRead, requestLen, tiIORequest));
6877
6878 ostiInitiatorIOCompleted( tiRoot,
6879 tiIORequest,
6880 tiIOUnderRun,
6881 requestLen - lenRead,
6882 agNULL,
6883 satIOContext->interruptContext );
6884
6885
6886 }
6887 else
6888 {
6889 ostiInitiatorIOCompleted( tiRoot,
6890 tiIORequest,
6891 tiIOSuccess,
6892 SCSI_STAT_GOOD,
6893 agNULL,
6894 satIOContext->interruptContext);
6895 }
6896
6897 return tiSuccess;
6898
6899 }
6900
6901 /*****************************************************************************/
6902 /*! \brief SAT implementation for SCSI MODE SENSE (10).
6903 *
6904 * SAT implementation for SCSI MODE SENSE (10).
6905 *
6906 * \param tiRoot: Pointer to TISA initiator driver/port instance.
6907 * \param tiIORequest: Pointer to TISA I/O request context for this I/O.
6908 * \param tiDeviceHandle: Pointer to TISA device handle for this I/O.
6909 * \param tiScsiRequest: Pointer to TISA SCSI I/O request and SGL list.
6910 * \param satIOContext_t: Pointer to the SAT IO Context
6911 *
6912 * \return If command is started successfully
6913 * - \e tiSuccess: I/O request successfully initiated.
6914 * - \e tiBusy: No resources available, try again later.
6915 * - \e tiIONoDevice: Invalid device handle.
6916 * - \e tiError: Other errors.
6917 */
6918 /*****************************************************************************/
6919 GLOBAL bit32 satModeSense10(
6920 tiRoot_t *tiRoot,
6921 tiIORequest_t *tiIORequest,
6922 tiDeviceHandle_t *tiDeviceHandle,
6923 tiScsiInitiatorRequest_t *tiScsiRequest,
6924 satIOContext_t *satIOContext)
6925 {
6926
6927 scsiRspSense_t *pSense;
6928 bit32 requestLen;
6929 tiIniScsiCmnd_t *scsiCmnd;
6930 bit32 pageSupported;
6931 bit8 page;
6932 bit8 *pModeSense; /* Mode Sense data buffer */
6933 satDeviceData_t *pSatDevData;
6934 bit8 PC; /* page control */
6935 bit8 LLBAA; /* Long LBA Accepted */
6936 bit32 index;
6937 bit8 AllPages[MODE_SENSE10_RETURN_ALL_PAGES_LLBAA_LEN];
6938 bit8 Control[MODE_SENSE10_CONTROL_PAGE_LLBAA_LEN];
6939 bit8 RWErrorRecovery[MODE_SENSE10_READ_WRITE_ERROR_RECOVERY_PAGE_LLBAA_LEN];
6940 bit8 Caching[MODE_SENSE10_CACHING_LLBAA_LEN];
6941 bit8 InfoExceptionCtrl[MODE_SENSE10_INFORMATION_EXCEPTION_CONTROL_PAGE_LLBAA_LEN];
6942 bit8 lenRead = 0;
6943
6944 TI_DBG5(("satModeSense10 entry: tiDeviceHandle=%p tiIORequest=%p\n",
6945 tiDeviceHandle, tiIORequest));
6946
6947 pSense = satIOContext->pSense;
6948 scsiCmnd = &tiScsiRequest->scsiCmnd;
6949 pModeSense = (bit8 *) tiScsiRequest->sglVirtualAddr;
6950 pSatDevData = satIOContext->pSatDevData;
6951
6952 /* checking CONTROL */
6953 /* NACA == 1 or LINK == 1*/
6954 if ( (scsiCmnd->cdb[9] & SCSI_NACA_MASK) || (scsiCmnd->cdb[9] & SCSI_LINK_MASK) )
6955 {
6956 satSetSensePayload( pSense,
6957 SCSI_SNSKEY_ILLEGAL_REQUEST,
6958 0,
6959 SCSI_SNSCODE_INVALID_FIELD_IN_CDB,
6960 satIOContext);
6961
6962 ostiInitiatorIOCompleted( tiRoot,
6963 tiIORequest,
6964 tiIOSuccess,
6965 SCSI_STAT_CHECK_CONDITION,
6966 satIOContext->pTiSenseData,
6967 satIOContext->interruptContext );
6968
6969 TI_DBG2(("satModeSense10: return control\n"));
6970 return tiSuccess;
6971 }
6972
6973 /* checking PC(Page Control)
6974 SAT revion 8, 8.5.3 p33 and 10.1.2, p66
6975 */
6976 PC = (bit8)((scsiCmnd->cdb[2]) & SCSI_MODE_SENSE10_PC_MASK);
6977 if (PC != 0)
6978 {
6979 satSetSensePayload( pSense,
6980 SCSI_SNSKEY_ILLEGAL_REQUEST,
6981 0,
6982 SCSI_SNSCODE_INVALID_FIELD_IN_CDB,
6983 satIOContext);
6984
6985 ostiInitiatorIOCompleted( tiRoot,
6986 tiIORequest,
6987 tiIOSuccess,
6988 SCSI_STAT_CHECK_CONDITION,
6989 satIOContext->pTiSenseData,
6990 satIOContext->interruptContext );
6991
6992 TI_DBG1(("satModeSense10: return due to PC value pc 0x%x\n", PC));
6993 return tiSuccess;
6994 }
6995 /* finding LLBAA bit */
6996 LLBAA = (bit8)((scsiCmnd->cdb[1]) & SCSI_MODE_SENSE10_LLBAA_MASK);
6997 /* reading PAGE CODE */
6998 page = (bit8)((scsiCmnd->cdb[2]) & SCSI_MODE_SENSE10_PAGE_CODE_MASK);
6999
7000 TI_DBG5(("satModeSense10: page=0x%x, tiDeviceHandle=%p tiIORequest=%p\n",
7001 page, tiDeviceHandle, tiIORequest));
7002 requestLen = (scsiCmnd->cdb[7] << 8) + scsiCmnd->cdb[8];
7003
7004 /*
7005 Based on page code value, returns a corresponding mode page
7006 note: no support for subpage
7007 */
7008 switch(page)
7009 {
7010 case MODESENSE_RETURN_ALL_PAGES: /* return all pages */
7011 case MODESENSE_CONTROL_PAGE: /* control */
7012 case MODESENSE_READ_WRITE_ERROR_RECOVERY_PAGE: /* Read-Write Error Recovery */
7013 case MODESENSE_CACHING: /* caching */
7014 case MODESENSE_INFORMATION_EXCEPTION_CONTROL_PAGE: /* informational exceptions control*/
7015 pageSupported = agTRUE;
7016 break;
7017 case MODESENSE_VENDOR_SPECIFIC_PAGE: /* vendor specific */
7018 default:
7019 pageSupported = agFALSE;
7020 break;
7021 }
7022
7023 if (pageSupported == agFALSE)
7024 {
7025
7026 TI_DBG1(("satModeSense10 *** ERROR *** not supported page 0x%x tiDeviceHandle=%p tiIORequest=%p\n",
7027 page, tiDeviceHandle, tiIORequest));
7028
7029 satSetSensePayload( pSense,
7030 SCSI_SNSKEY_ILLEGAL_REQUEST,
7031 0,
7032 SCSI_SNSCODE_INVALID_COMMAND,
7033 satIOContext);
7034
7035 ostiInitiatorIOCompleted( tiRoot,
7036 tiIORequest,
7037 tiIOSuccess,
7038 SCSI_STAT_CHECK_CONDITION,
7039 satIOContext->pTiSenseData,
7040 satIOContext->interruptContext );
7041 return tiSuccess;
7042 }
7043
7044 switch(page)
7045 {
7046 case MODESENSE_RETURN_ALL_PAGES:
7047 if (LLBAA)
7048 {
7049 lenRead = (bit8)MIN(requestLen, MODE_SENSE10_RETURN_ALL_PAGES_LLBAA_LEN);
7050 }
7051 else
7052 {
7053 lenRead = (bit8)MIN(requestLen, MODE_SENSE10_RETURN_ALL_PAGES_LEN);
7054 }
7055 break;
7056 case MODESENSE_CONTROL_PAGE: /* control */
7057 if (LLBAA)
7058 {
7059 lenRead = (bit8)MIN(requestLen, MODE_SENSE10_CONTROL_PAGE_LLBAA_LEN);
7060 }
7061 else
7062 {
7063 lenRead = (bit8)MIN(requestLen, MODE_SENSE10_CONTROL_PAGE_LEN);
7064 }
7065 break;
7066 case MODESENSE_READ_WRITE_ERROR_RECOVERY_PAGE: /* Read-Write Error Recovery */
7067 if (LLBAA)
7068 {
7069 lenRead = (bit8)MIN(requestLen, MODE_SENSE10_READ_WRITE_ERROR_RECOVERY_PAGE_LLBAA_LEN);
7070 }
7071 else
7072 {
7073 lenRead = (bit8)MIN(requestLen, MODE_SENSE10_READ_WRITE_ERROR_RECOVERY_PAGE_LEN);
7074 }
7075 break;
7076 case MODESENSE_CACHING: /* caching */
7077 if (LLBAA)
7078 {
7079 lenRead = (bit8)MIN(requestLen, MODE_SENSE10_CACHING_LLBAA_LEN);
7080 }
7081 else
7082 {
7083 lenRead = (bit8)MIN(requestLen, MODE_SENSE10_CACHING_LEN);
7084 }
7085 break;
7086 case MODESENSE_INFORMATION_EXCEPTION_CONTROL_PAGE: /* informational exceptions control*/
7087 if (LLBAA)
7088 {
7089 lenRead = (bit8)MIN(requestLen, MODE_SENSE10_INFORMATION_EXCEPTION_CONTROL_PAGE_LLBAA_LEN);
7090 }
7091 else
7092 {
7093 lenRead = (bit8)MIN(requestLen, MODE_SENSE10_INFORMATION_EXCEPTION_CONTROL_PAGE_LEN);
7094 }
7095 break;
7096 default:
7097 TI_DBG1(("satModeSense10: default error page %d\n", page));
7098 break;
7099 }
7100
7101 if (page == MODESENSE_RETURN_ALL_PAGES)
7102 {
7103 TI_DBG5(("satModeSense10: MODESENSE_RETURN_ALL_PAGES\n"));
7104 AllPages[0] = 0;
7105 AllPages[1] = (bit8)(lenRead - 2);
7106 AllPages[2] = 0x00; /* medium type: default medium type (currently mounted medium type) */
7107 AllPages[3] = 0x00; /* device-specific param: no write-protect, no support for DPO-FUA */
7108 if (LLBAA)
7109 {
7110 AllPages[4] = 0x00; /* reserved and LONGLBA */
7111 AllPages[4] = (bit8)(AllPages[4] | 0x1); /* LONGLBA is set */
7112 }
7113 else
7114 {
7115 AllPages[4] = 0x00; /* reserved and LONGLBA: LONGLBA is not set */
7116 }
7117 AllPages[5] = 0x00; /* reserved */
7118 AllPages[6] = 0x00; /* block descriptot length */
7119 if (LLBAA)
7120 {
7121 AllPages[7] = 0x10; /* block descriptor length: LONGLBA is set. So, length is 16 */
7122 }
7123 else
7124 {
7125 AllPages[7] = 0x08; /* block descriptor length: LONGLBA is NOT set. So, length is 8 */
7126 }
7127
7128 /*
7129 * Fill-up direct-access device block-descriptor, SAT, Table 19
7130 */
7131
7132 if (LLBAA)
7133 {
7134 /* density code */
7135 AllPages[8] = 0x04; /* density-code : reserved for direct-access */
7136 /* number of blocks */
7137 AllPages[9] = 0x00; /* unspecified */
7138 AllPages[10] = 0x00; /* unspecified */
7139 AllPages[11] = 0x00; /* unspecified */
7140 AllPages[12] = 0x00; /* unspecified */
7141 AllPages[13] = 0x00; /* unspecified */
7142 AllPages[14] = 0x00; /* unspecified */
7143 AllPages[15] = 0x00; /* unspecified */
7144 /* reserved */
7145 AllPages[16] = 0x00; /* reserved */
7146 AllPages[17] = 0x00; /* reserved */
7147 AllPages[18] = 0x00; /* reserved */
7148 AllPages[19] = 0x00; /* reserved */
7149 /* Block size */
7150 AllPages[20] = 0x00;
7151 AllPages[21] = 0x00;
7152 AllPages[22] = 0x02; /* Block size is always 512 bytes */
7153 AllPages[23] = 0x00;
7154 }
7155 else
7156 {
7157 /* density code */
7158 AllPages[8] = 0x04; /* density-code : reserved for direct-access */
7159 /* number of blocks */
7160 AllPages[9] = 0x00; /* unspecified */
7161 AllPages[10] = 0x00; /* unspecified */
7162 AllPages[11] = 0x00; /* unspecified */
7163 /* reserved */
7164 AllPages[12] = 0x00; /* reserved */
7165 /* Block size */
7166 AllPages[13] = 0x00;
7167 AllPages[14] = 0x02; /* Block size is always 512 bytes */
7168 AllPages[15] = 0x00;
7169 }
7170
7171 if (LLBAA)
7172 {
7173 index = 24;
7174 }
7175 else
7176 {
7177 index = 16;
7178 }
7179 /* MODESENSE_READ_WRITE_ERROR_RECOVERY_PAGE */
7180 AllPages[index+0] = 0x01; /* page code */
7181 AllPages[index+1] = 0x0A; /* page length */
7182 AllPages[index+2] = 0x40; /* ARRE is set */
7183 AllPages[index+3] = 0x00;
7184 AllPages[index+4] = 0x00;
7185 AllPages[index+5] = 0x00;
7186 AllPages[index+6] = 0x00;
7187 AllPages[index+7] = 0x00;
7188 AllPages[index+8] = 0x00;
7189 AllPages[index+9] = 0x00;
7190 AllPages[index+10] = 0x00;
7191 AllPages[index+11] = 0x00;
7192
7193 /* MODESENSE_CACHING */
7194 /*
7195 * Fill-up Caching mode page, SAT, Table 67
7196 */
7197 /* length 20 */
7198 AllPages[index+12] = 0x08; /* page code */
7199 AllPages[index+13] = 0x12; /* page length */
7200 #ifdef NOT_YET
7201 if (pSatDevData->satWriteCacheEnabled == agTRUE)
7202 {
7203 AllPages[index+14] = 0x04;/* WCE bit is set */
7204 }
7205 else
7206 {
7207 AllPages[index+14] = 0x00;/* WCE bit is NOT set */
7208 }
7209 #endif
7210 AllPages[index+14] = 0x00;/* WCE bit is NOT set */
7211 AllPages[index+15] = 0x00;
7212 AllPages[index+16] = 0x00;
7213 AllPages[index+17] = 0x00;
7214 AllPages[index+18] = 0x00;
7215 AllPages[index+19] = 0x00;
7216 AllPages[index+20] = 0x00;
7217 AllPages[index+21] = 0x00;
7218 AllPages[index+22] = 0x00;
7219 AllPages[index+23] = 0x00;
7220 if (pSatDevData->satLookAheadEnabled == agTRUE)
7221 {
7222 AllPages[index+24] = 0x00;/* DRA bit is NOT set */
7223 }
7224 else
7225 {
7226 AllPages[index+24] = 0x20;/* DRA bit is set */
7227 }
7228 AllPages[index+25] = 0x00;
7229 AllPages[index+26] = 0x00;
7230 AllPages[index+27] = 0x00;
7231 AllPages[index+28] = 0x00;
7232 AllPages[index+29] = 0x00;
7233 AllPages[index+30] = 0x00;
7234 AllPages[index+31] = 0x00;
7235
7236 /* MODESENSE_CONTROL_PAGE */
7237 /*
7238 * Fill-up control mode page, SAT, Table 65
7239 */
7240 AllPages[index+32] = 0x0A; /* page code */
7241 AllPages[index+33] = 0x0A; /* page length */
7242 AllPages[index+34] = 0x02; /* only GLTSD bit is set */
7243 if (pSatDevData->satNCQ == agTRUE)
7244 {
7245 AllPages[index+35] = 0x12; /* Queue Alogorithm modifier 1b and QErr 01b*/
7246 }
7247 else
7248 {
7249 AllPages[index+35] = 0x02; /* Queue Alogorithm modifier 0b and QErr 01b */
7250 }
7251 AllPages[index+36] = 0x00;
7252 AllPages[index+37] = 0x00;
7253 AllPages[index+38] = 0x00; /* obsolete */
7254 AllPages[index+39] = 0x00; /* obsolete */
7255 AllPages[index+40] = 0xFF; /* Busy Timeout Period */
7256 AllPages[index+41] = 0xFF; /* Busy Timeout Period */
7257 AllPages[index+42] = 0x00; /* we don't support non-000b value for the self-test code */
7258 AllPages[index+43] = 0x00; /* we don't support non-000b value for the self-test code */
7259
7260 /* MODESENSE_INFORMATION_EXCEPTION_CONTROL_PAGE */
7261 /*
7262 * Fill-up informational-exceptions control mode page, SAT, Table 68
7263 */
7264 AllPages[index+44] = 0x1C; /* page code */
7265 AllPages[index+45] = 0x0A; /* page length */
7266 if (pSatDevData->satSMARTEnabled == agTRUE)
7267 {
7268 AllPages[index+46] = 0x00;/* DEXCPT bit is NOT set */
7269 }
7270 else
7271 {
7272 AllPages[index+46] = 0x08;/* DEXCPT bit is set */
7273 }
7274 AllPages[index+47] = 0x00; /* We don't support MRIE */
7275 AllPages[index+48] = 0x00; /* Interval timer vendor-specific */
7276 AllPages[index+49] = 0x00;
7277 AllPages[index+50] = 0x00;
7278 AllPages[index+51] = 0x00;
7279 AllPages[index+52] = 0x00; /* REPORT-COUNT */
7280 AllPages[index+53] = 0x00;
7281 AllPages[index+54] = 0x00;
7282 AllPages[index+55] = 0x00;
7283
7284 osti_memcpy(pModeSense, &AllPages, lenRead);
7285 }
7286 else if (page == MODESENSE_CONTROL_PAGE)
7287 {
7288 TI_DBG5(("satModeSense10: MODESENSE_CONTROL_PAGE\n"));
7289 Control[0] = 0;
7290 Control[1] = (bit8)(lenRead - 2);
7291 Control[2] = 0x00; /* medium type: default medium type (currently mounted medium type) */
7292 Control[3] = 0x00; /* device-specific param: no write-protect, no support for DPO-FUA */
7293 if (LLBAA)
7294 {
7295 Control[4] = 0x00; /* reserved and LONGLBA */
7296 Control[4] = (bit8)(Control[4] | 0x1); /* LONGLBA is set */
7297 }
7298 else
7299 {
7300 Control[4] = 0x00; /* reserved and LONGLBA: LONGLBA is not set */
7301 }
7302 Control[5] = 0x00; /* reserved */
7303 Control[6] = 0x00; /* block descriptot length */
7304 if (LLBAA)
7305 {
7306 Control[7] = 0x10; /* block descriptor length: LONGLBA is set. So, length is 16 */
7307 }
7308 else
7309 {
7310 Control[7] = 0x08; /* block descriptor length: LONGLBA is NOT set. So, length is 8 */
7311 }
7312
7313 /*
7314 * Fill-up direct-access device block-descriptor, SAT, Table 19
7315 */
7316
7317 if (LLBAA)
7318 {
7319 /* density code */
7320 Control[8] = 0x04; /* density-code : reserved for direct-access */
7321 /* number of blocks */
7322 Control[9] = 0x00; /* unspecified */
7323 Control[10] = 0x00; /* unspecified */
7324 Control[11] = 0x00; /* unspecified */
7325 Control[12] = 0x00; /* unspecified */
7326 Control[13] = 0x00; /* unspecified */
7327 Control[14] = 0x00; /* unspecified */
7328 Control[15] = 0x00; /* unspecified */
7329 /* reserved */
7330 Control[16] = 0x00; /* reserved */
7331 Control[17] = 0x00; /* reserved */
7332 Control[18] = 0x00; /* reserved */
7333 Control[19] = 0x00; /* reserved */
7334 /* Block size */
7335 Control[20] = 0x00;
7336 Control[21] = 0x00;
7337 Control[22] = 0x02; /* Block size is always 512 bytes */
7338 Control[23] = 0x00;
7339 }
7340 else
7341 {
7342 /* density code */
7343 Control[8] = 0x04; /* density-code : reserved for direct-access */
7344 /* number of blocks */
7345 Control[9] = 0x00; /* unspecified */
7346 Control[10] = 0x00; /* unspecified */
7347 Control[11] = 0x00; /* unspecified */
7348 /* reserved */
7349 Control[12] = 0x00; /* reserved */
7350 /* Block size */
7351 Control[13] = 0x00;
7352 Control[14] = 0x02; /* Block size is always 512 bytes */
7353 Control[15] = 0x00;
7354 }
7355
7356 if (LLBAA)
7357 {
7358 index = 24;
7359 }
7360 else
7361 {
7362 index = 16;
7363 }
7364 /*
7365 * Fill-up control mode page, SAT, Table 65
7366 */
7367 Control[index+0] = 0x0A; /* page code */
7368 Control[index+1] = 0x0A; /* page length */
7369 Control[index+2] = 0x02; /* only GLTSD bit is set */
7370 if (pSatDevData->satNCQ == agTRUE)
7371 {
7372 Control[index+3] = 0x12; /* Queue Alogorithm modifier 1b and QErr 01b*/
7373 }
7374 else
7375 {
7376 Control[index+3] = 0x02; /* Queue Alogorithm modifier 0b and QErr 01b */
7377 }
7378 Control[index+4] = 0x00;
7379 Control[index+5] = 0x00;
7380 Control[index+6] = 0x00; /* obsolete */
7381 Control[index+7] = 0x00; /* obsolete */
7382 Control[index+8] = 0xFF; /* Busy Timeout Period */
7383 Control[index+9] = 0xFF; /* Busy Timeout Period */
7384 Control[index+10] = 0x00; /* we don't support non-000b value for the self-test code */
7385 Control[index+11] = 0x00; /* we don't support non-000b value for the self-test code */
7386
7387 osti_memcpy(pModeSense, &Control, lenRead);
7388 }
7389 else if (page == MODESENSE_READ_WRITE_ERROR_RECOVERY_PAGE)
7390 {
7391 TI_DBG5(("satModeSense10: MODESENSE_READ_WRITE_ERROR_RECOVERY_PAGE\n"));
7392 RWErrorRecovery[0] = 0;
7393 RWErrorRecovery[1] = (bit8)(lenRead - 2);
7394 RWErrorRecovery[2] = 0x00; /* medium type: default medium type (currently mounted medium type) */
7395 RWErrorRecovery[3] = 0x00; /* device-specific param: no write-protect, no support for DPO-FUA */
7396 if (LLBAA)
7397 {
7398 RWErrorRecovery[4] = 0x00; /* reserved and LONGLBA */
7399 RWErrorRecovery[4] = (bit8)(RWErrorRecovery[4] | 0x1); /* LONGLBA is set */
7400 }
7401 else
7402 {
7403 RWErrorRecovery[4] = 0x00; /* reserved and LONGLBA: LONGLBA is not set */
7404 }
7405 RWErrorRecovery[5] = 0x00; /* reserved */
7406 RWErrorRecovery[6] = 0x00; /* block descriptot length */
7407 if (LLBAA)
7408 {
7409 RWErrorRecovery[7] = 0x10; /* block descriptor length: LONGLBA is set. So, length is 16 */
7410 }
7411 else
7412 {
7413 RWErrorRecovery[7] = 0x08; /* block descriptor length: LONGLBA is NOT set. So, length is 8 */
7414 }
7415
7416 /*
7417 * Fill-up direct-access device block-descriptor, SAT, Table 19
7418 */
7419
7420 if (LLBAA)
7421 {
7422 /* density code */
7423 RWErrorRecovery[8] = 0x04; /* density-code : reserved for direct-access */
7424 /* number of blocks */
7425 RWErrorRecovery[9] = 0x00; /* unspecified */
7426 RWErrorRecovery[10] = 0x00; /* unspecified */
7427 RWErrorRecovery[11] = 0x00; /* unspecified */
7428 RWErrorRecovery[12] = 0x00; /* unspecified */
7429 RWErrorRecovery[13] = 0x00; /* unspecified */
7430 RWErrorRecovery[14] = 0x00; /* unspecified */
7431 RWErrorRecovery[15] = 0x00; /* unspecified */
7432 /* reserved */
7433 RWErrorRecovery[16] = 0x00; /* reserved */
7434 RWErrorRecovery[17] = 0x00; /* reserved */
7435 RWErrorRecovery[18] = 0x00; /* reserved */
7436 RWErrorRecovery[19] = 0x00; /* reserved */
7437 /* Block size */
7438 RWErrorRecovery[20] = 0x00;
7439 RWErrorRecovery[21] = 0x00;
7440 RWErrorRecovery[22] = 0x02; /* Block size is always 512 bytes */
7441 RWErrorRecovery[23] = 0x00;
7442 }
7443 else
7444 {
7445 /* density code */
7446 RWErrorRecovery[8] = 0x04; /* density-code : reserved for direct-access */
7447 /* number of blocks */
7448 RWErrorRecovery[9] = 0x00; /* unspecified */
7449 RWErrorRecovery[10] = 0x00; /* unspecified */
7450 RWErrorRecovery[11] = 0x00; /* unspecified */
7451 /* reserved */
7452 RWErrorRecovery[12] = 0x00; /* reserved */
7453 /* Block size */
7454 RWErrorRecovery[13] = 0x00;
7455 RWErrorRecovery[14] = 0x02; /* Block size is always 512 bytes */
7456 RWErrorRecovery[15] = 0x00;
7457 }
7458
7459 if (LLBAA)
7460 {
7461 index = 24;
7462 }
7463 else
7464 {
7465 index = 16;
7466 }
7467 /*
7468 * Fill-up Read-Write Error Recovery mode page, SAT, Table 66
7469 */
7470 RWErrorRecovery[index+0] = 0x01; /* page code */
7471 RWErrorRecovery[index+1] = 0x0A; /* page length */
7472 RWErrorRecovery[index+2] = 0x40; /* ARRE is set */
7473 RWErrorRecovery[index+3] = 0x00;
7474 RWErrorRecovery[index+4] = 0x00;
7475 RWErrorRecovery[index+5] = 0x00;
7476 RWErrorRecovery[index+6] = 0x00;
7477 RWErrorRecovery[index+7] = 0x00;
7478 RWErrorRecovery[index+8] = 0x00;
7479 RWErrorRecovery[index+9] = 0x00;
7480 RWErrorRecovery[index+10] = 0x00;
7481 RWErrorRecovery[index+11] = 0x00;
7482
7483 osti_memcpy(pModeSense, &RWErrorRecovery, lenRead);
7484 }
7485 else if (page == MODESENSE_CACHING)
7486 {
7487 TI_DBG5(("satModeSense10: MODESENSE_CACHING\n"));
7488 Caching[0] = 0;
7489 Caching[1] = (bit8)(lenRead - 2);
7490 Caching[2] = 0x00; /* medium type: default medium type (currently mounted medium type) */
7491 Caching[3] = 0x00; /* device-specific param: no write-protect, no support for DPO-FUA */
7492 if (LLBAA)
7493 {
7494 Caching[4] = 0x00; /* reserved and LONGLBA */
7495 Caching[4] = (bit8)(Caching[4] | 0x1); /* LONGLBA is set */
7496 }
7497 else
7498 {
7499 Caching[4] = 0x00; /* reserved and LONGLBA: LONGLBA is not set */
7500 }
7501 Caching[5] = 0x00; /* reserved */
7502 Caching[6] = 0x00; /* block descriptot length */
7503 if (LLBAA)
7504 {
7505 Caching[7] = 0x10; /* block descriptor length: LONGLBA is set. So, length is 16 */
7506 }
7507 else
7508 {
7509 Caching[7] = 0x08; /* block descriptor length: LONGLBA is NOT set. So, length is 8 */
7510 }
7511
7512 /*
7513 * Fill-up direct-access device block-descriptor, SAT, Table 19
7514 */
7515
7516 if (LLBAA)
7517 {
7518 /* density code */
7519 Caching[8] = 0x04; /* density-code : reserved for direct-access */
7520 /* number of blocks */
7521 Caching[9] = 0x00; /* unspecified */
7522 Caching[10] = 0x00; /* unspecified */
7523 Caching[11] = 0x00; /* unspecified */
7524 Caching[12] = 0x00; /* unspecified */
7525 Caching[13] = 0x00; /* unspecified */
7526 Caching[14] = 0x00; /* unspecified */
7527 Caching[15] = 0x00; /* unspecified */
7528 /* reserved */
7529 Caching[16] = 0x00; /* reserved */
7530 Caching[17] = 0x00; /* reserved */
7531 Caching[18] = 0x00; /* reserved */
7532 Caching[19] = 0x00; /* reserved */
7533 /* Block size */
7534 Caching[20] = 0x00;
7535 Caching[21] = 0x00;
7536 Caching[22] = 0x02; /* Block size is always 512 bytes */
7537 Caching[23] = 0x00;
7538 }
7539 else
7540 {
7541 /* density code */
7542 Caching[8] = 0x04; /* density-code : reserved for direct-access */
7543 /* number of blocks */
7544 Caching[9] = 0x00; /* unspecified */
7545 Caching[10] = 0x00; /* unspecified */
7546 Caching[11] = 0x00; /* unspecified */
7547 /* reserved */
7548 Caching[12] = 0x00; /* reserved */
7549 /* Block size */
7550 Caching[13] = 0x00;
7551 Caching[14] = 0x02; /* Block size is always 512 bytes */
7552 Caching[15] = 0x00;
7553 }
7554
7555 if (LLBAA)
7556 {
7557 index = 24;
7558 }
7559 else
7560 {
7561 index = 16;
7562 }
7563 /*
7564 * Fill-up Caching mode page, SAT, Table 67
7565 */
7566 /* length 20 */
7567 Caching[index+0] = 0x08; /* page code */
7568 Caching[index+1] = 0x12; /* page length */
7569 #ifdef NOT_YET
7570 if (pSatDevData->satWriteCacheEnabled == agTRUE)
7571 {
7572 Caching[index+2] = 0x04;/* WCE bit is set */
7573 }
7574 else
7575 {
7576 Caching[index+2] = 0x00;/* WCE bit is NOT set */
7577 }
7578 #endif
7579 Caching[index+2] = 0x00;/* WCE bit is NOT set */
7580 Caching[index+3] = 0x00;
7581 Caching[index+4] = 0x00;
7582 Caching[index+5] = 0x00;
7583 Caching[index+6] = 0x00;
7584 Caching[index+7] = 0x00;
7585 Caching[index+8] = 0x00;
7586 Caching[index+9] = 0x00;
7587 Caching[index+10] = 0x00;
7588 Caching[index+11] = 0x00;
7589 if (pSatDevData->satLookAheadEnabled == agTRUE)
7590 {
7591 Caching[index+12] = 0x00;/* DRA bit is NOT set */
7592 }
7593 else
7594 {
7595 Caching[index+12] = 0x20;/* DRA bit is set */
7596 }
7597 Caching[index+13] = 0x00;
7598 Caching[index+14] = 0x00;
7599 Caching[index+15] = 0x00;
7600 Caching[index+16] = 0x00;
7601 Caching[index+17] = 0x00;
7602 Caching[index+18] = 0x00;
7603 Caching[index+19] = 0x00;
7604 osti_memcpy(pModeSense, &Caching, lenRead);
7605
7606 }
7607 else if (page == MODESENSE_INFORMATION_EXCEPTION_CONTROL_PAGE)
7608 {
7609 TI_DBG5(("satModeSense10: MODESENSE_INFORMATION_EXCEPTION_CONTROL_PAGE\n"));
7610 InfoExceptionCtrl[0] = 0;
7611 InfoExceptionCtrl[1] = (bit8)(lenRead - 2);
7612 InfoExceptionCtrl[2] = 0x00; /* medium type: default medium type (currently mounted medium type) */
7613 InfoExceptionCtrl[3] = 0x00; /* device-specific param: no write-protect, no support for DPO-FUA */
7614 if (LLBAA)
7615 {
7616 InfoExceptionCtrl[4] = 0x00; /* reserved and LONGLBA */
7617 InfoExceptionCtrl[4] = (bit8)(InfoExceptionCtrl[4] | 0x1); /* LONGLBA is set */
7618 }
7619 else
7620 {
7621 InfoExceptionCtrl[4] = 0x00; /* reserved and LONGLBA: LONGLBA is not set */
7622 }
7623 InfoExceptionCtrl[5] = 0x00; /* reserved */
7624 InfoExceptionCtrl[6] = 0x00; /* block descriptot length */
7625 if (LLBAA)
7626 {
7627 InfoExceptionCtrl[7] = 0x10; /* block descriptor length: LONGLBA is set. So, length is 16 */
7628 }
7629 else
7630 {
7631 InfoExceptionCtrl[7] = 0x08; /* block descriptor length: LONGLBA is NOT set. So, length is 8 */
7632 }
7633
7634 /*
7635 * Fill-up direct-access device block-descriptor, SAT, Table 19
7636 */
7637
7638 if (LLBAA)
7639 {
7640 /* density code */
7641 InfoExceptionCtrl[8] = 0x04; /* density-code : reserved for direct-access */
7642 /* number of blocks */
7643 InfoExceptionCtrl[9] = 0x00; /* unspecified */
7644 InfoExceptionCtrl[10] = 0x00; /* unspecified */
7645 InfoExceptionCtrl[11] = 0x00; /* unspecified */
7646 InfoExceptionCtrl[12] = 0x00; /* unspecified */
7647 InfoExceptionCtrl[13] = 0x00; /* unspecified */
7648 InfoExceptionCtrl[14] = 0x00; /* unspecified */
7649 InfoExceptionCtrl[15] = 0x00; /* unspecified */
7650 /* reserved */
7651 InfoExceptionCtrl[16] = 0x00; /* reserved */
7652 InfoExceptionCtrl[17] = 0x00; /* reserved */
7653 InfoExceptionCtrl[18] = 0x00; /* reserved */
7654 InfoExceptionCtrl[19] = 0x00; /* reserved */
7655 /* Block size */
7656 InfoExceptionCtrl[20] = 0x00;
7657 InfoExceptionCtrl[21] = 0x00;
7658 InfoExceptionCtrl[22] = 0x02; /* Block size is always 512 bytes */
7659 InfoExceptionCtrl[23] = 0x00;
7660 }
7661 else
7662 {
7663 /* density code */
7664 InfoExceptionCtrl[8] = 0x04; /* density-code : reserved for direct-access */
7665 /* number of blocks */
7666 InfoExceptionCtrl[9] = 0x00; /* unspecified */
7667 InfoExceptionCtrl[10] = 0x00; /* unspecified */
7668 InfoExceptionCtrl[11] = 0x00; /* unspecified */
7669 /* reserved */
7670 InfoExceptionCtrl[12] = 0x00; /* reserved */
7671 /* Block size */
7672 InfoExceptionCtrl[13] = 0x00;
7673 InfoExceptionCtrl[14] = 0x02; /* Block size is always 512 bytes */
7674 InfoExceptionCtrl[15] = 0x00;
7675 }
7676
7677 if (LLBAA)
7678 {
7679 index = 24;
7680 }
7681 else
7682 {
7683 index = 16;
7684 }
7685 /*
7686 * Fill-up informational-exceptions control mode page, SAT, Table 68
7687 */
7688 InfoExceptionCtrl[index+0] = 0x1C; /* page code */
7689 InfoExceptionCtrl[index+1] = 0x0A; /* page length */
7690 if (pSatDevData->satSMARTEnabled == agTRUE)
7691 {
7692 InfoExceptionCtrl[index+2] = 0x00;/* DEXCPT bit is NOT set */
7693 }
7694 else
7695 {
7696 InfoExceptionCtrl[index+2] = 0x08;/* DEXCPT bit is set */
7697 }
7698 InfoExceptionCtrl[index+3] = 0x00; /* We don't support MRIE */
7699 InfoExceptionCtrl[index+4] = 0x00; /* Interval timer vendor-specific */
7700 InfoExceptionCtrl[index+5] = 0x00;
7701 InfoExceptionCtrl[index+6] = 0x00;
7702 InfoExceptionCtrl[index+7] = 0x00;
7703 InfoExceptionCtrl[index+8] = 0x00; /* REPORT-COUNT */
7704 InfoExceptionCtrl[index+9] = 0x00;
7705 InfoExceptionCtrl[index+10] = 0x00;
7706 InfoExceptionCtrl[index+11] = 0x00;
7707 osti_memcpy(pModeSense, &InfoExceptionCtrl, lenRead);
7708
7709 }
7710 else
7711 {
7712 /* Error */
7713 TI_DBG1(("satModeSense10: Error page %d\n", page));
7714 satSetSensePayload( pSense,
7715 SCSI_SNSKEY_ILLEGAL_REQUEST,
7716 0,
7717 SCSI_SNSCODE_INVALID_COMMAND,
7718 satIOContext);
7719
7720 ostiInitiatorIOCompleted( tiRoot,
7721 tiIORequest,
7722 tiIOSuccess,
7723 SCSI_STAT_CHECK_CONDITION,
7724 satIOContext->pTiSenseData,
7725 satIOContext->interruptContext );
7726 return tiSuccess;
7727 }
7728
7729 if (requestLen > lenRead)
7730 {
7731 TI_DBG1(("satModeSense10 reporting underrun lenRead=0x%x requestLen=0x%x tiIORequest=%p\n", lenRead, requestLen, tiIORequest));
7732
7733 ostiInitiatorIOCompleted( tiRoot,
7734 tiIORequest,
7735 tiIOUnderRun,
7736 requestLen - lenRead,
7737 agNULL,
7738 satIOContext->interruptContext );
7739
7740
7741 }
7742 else
7743 {
7744 ostiInitiatorIOCompleted( tiRoot,
7745 tiIORequest,
7746 tiIOSuccess,
7747 SCSI_STAT_GOOD,
7748 agNULL,
7749 satIOContext->interruptContext);
7750 }
7751
7752 return tiSuccess;
7753 }
7754
7755
7756 /*****************************************************************************/
7757 /*! \brief SAT implementation for SCSI VERIFY (10).
7758 *
7759 * SAT implementation for SCSI VERIFY (10).
7760 *
7761 * \param tiRoot: Pointer to TISA initiator driver/port instance.
7762 * \param tiIORequest: Pointer to TISA I/O request context for this I/O.
7763 * \param tiDeviceHandle: Pointer to TISA device handle for this I/O.
7764 * \param tiScsiRequest: Pointer to TISA SCSI I/O request and SGL list.
7765 * \param satIOContext_t: Pointer to the SAT IO Context
7766 *
7767 * \return If command is started successfully
7768 * - \e tiSuccess: I/O request successfully initiated.
7769 * - \e tiBusy: No resources available, try again later.
7770 * - \e tiIONoDevice: Invalid device handle.
7771 * - \e tiError: Other errors.
7772 */
7773 /*****************************************************************************/
7774 GLOBAL bit32 satVerify10(
7775 tiRoot_t *tiRoot,
7776 tiIORequest_t *tiIORequest,
7777 tiDeviceHandle_t *tiDeviceHandle,
7778 tiScsiInitiatorRequest_t *tiScsiRequest,
7779 satIOContext_t *satIOContext)
7780 {
7781 /*
7782 For simple implementation,
7783 no byte comparison supported as of 4/5/06
7784 */
7785 scsiRspSense_t *pSense;
7786 tiIniScsiCmnd_t *scsiCmnd;
7787 satDeviceData_t *pSatDevData;
7788 agsaFisRegHostToDevice_t *fis;
7789 bit32 status;
7790 bit32 agRequestType = AGSA_SATA_PROTOCOL_NON_DATA;
7791 bit32 lba = 0;
7792 bit32 tl = 0;
7793 bit32 LoopNum = 1;
7794 bit8 LBA[4];
7795 bit8 TL[4];
7796 bit32 rangeChk = agFALSE; /* lba and tl range check */
7797
7798
7799 TI_DBG5(("satVerify10 entry: tiDeviceHandle=%p tiIORequest=%p\n",
7800 tiDeviceHandle, tiIORequest));
7801
7802 pSense = satIOContext->pSense;
7803 scsiCmnd = &tiScsiRequest->scsiCmnd;
7804 pSatDevData = satIOContext->pSatDevData;
7805 fis = satIOContext->pFis;
7806
7807 /* checking BYTCHK */
7808 if (scsiCmnd->cdb[1] & SCSI_VERIFY_BYTCHK_MASK)
7809 {
7810 /*
7811 should do the byte check
7812 but not supported in this version
7813 */
7814 satSetSensePayload( pSense,
7815 SCSI_SNSKEY_ILLEGAL_REQUEST,
7816 0,
7817 SCSI_SNSCODE_INVALID_FIELD_IN_CDB,
7818 satIOContext);
7819
7820 ostiInitiatorIOCompleted( tiRoot,
7821 tiIORequest,
7822 tiIOSuccess,
7823 SCSI_STAT_CHECK_CONDITION,
7824 satIOContext->pTiSenseData,
7825 satIOContext->interruptContext );
7826
7827 TI_DBG1(("satVerify10: no byte checking \n"));
7828 return tiSuccess;
7829 }
7830
7831 /* checking CONTROL */
7832 /* NACA == 1 or LINK == 1*/
7833 if ( (scsiCmnd->cdb[9] & SCSI_NACA_MASK) || (scsiCmnd->cdb[9] & SCSI_LINK_MASK) )
7834 {
7835 satSetSensePayload( pSense,
7836 SCSI_SNSKEY_ILLEGAL_REQUEST,
7837 0,
7838 SCSI_SNSCODE_INVALID_FIELD_IN_CDB,
7839 satIOContext);
7840
7841 ostiInitiatorIOCompleted( tiRoot,
7842 tiIORequest,
7843 tiIOSuccess,
7844 SCSI_STAT_CHECK_CONDITION,
7845 satIOContext->pTiSenseData,
7846 satIOContext->interruptContext );
7847
7848 TI_DBG2(("satVerify10: return control\n"));
7849 return tiSuccess;
7850 }
7851
7852 osti_memset(LBA, 0, sizeof(LBA));
7853 osti_memset(TL, 0, sizeof(TL));
7854
7855 /* do not use memcpy due to indexing in LBA and TL */
7856 LBA[0] = scsiCmnd->cdb[2]; /* MSB */
7857 LBA[1] = scsiCmnd->cdb[3];
7858 LBA[2] = scsiCmnd->cdb[4];
7859 LBA[3] = scsiCmnd->cdb[5]; /* LSB */
7860
7861 TL[0] = 0;
7862 TL[1] = 0;
7863 TL[2] = scsiCmnd->cdb[7]; /* MSB */
7864 TL[3] = scsiCmnd->cdb[8]; /* LSB */
7865
7866 rangeChk = satAddNComparebit32(LBA, TL);
7867
7868 /* cbd10; computing LBA and transfer length */
7869 lba = (scsiCmnd->cdb[2] << (8*3)) + (scsiCmnd->cdb[3] << (8*2))
7870 + (scsiCmnd->cdb[4] << 8) + scsiCmnd->cdb[5];
7871 tl = (scsiCmnd->cdb[7] << 8) + scsiCmnd->cdb[8];
7872
7873 if (pSatDevData->satNCQ != agTRUE &&
7874 pSatDevData->sat48BitSupport != agTRUE
7875 )
7876 {
7877 if (lba > SAT_TR_LBA_LIMIT - 1)
7878 {
7879 satSetSensePayload( pSense,
7880 SCSI_SNSKEY_ILLEGAL_REQUEST,
7881 0,
7882 SCSI_SNSCODE_LOGICAL_BLOCK_ADDRESS_OUT_OF_RANGE,
7883 satIOContext);
7884
7885 ostiInitiatorIOCompleted( tiRoot,
7886 tiIORequest,
7887 tiIOSuccess,
7888 SCSI_STAT_CHECK_CONDITION,
7889 satIOContext->pTiSenseData,
7890 satIOContext->interruptContext );
7891
7892 TI_DBG1(("satVerify10: return LBA out of range, not EXT\n"));
7893 TI_DBG1(("satVerify10: cdb 0x%x 0x%x 0x%x 0x%x\n",scsiCmnd->cdb[2], scsiCmnd->cdb[3],
7894 scsiCmnd->cdb[4], scsiCmnd->cdb[5]));
7895 TI_DBG1(("satVerify10: lba 0x%x SAT_TR_LBA_LIMIT 0x%x\n", lba, SAT_TR_LBA_LIMIT));
7896 return tiSuccess;
7897 }
7898
7899 if (rangeChk) // if (lba + tl > SAT_TR_LBA_LIMIT)
7900 {
7901 TI_DBG1(("satVerify10: return LBA+TL out of range, not EXT\n"));
7902 satSetSensePayload( pSense,
7903 SCSI_SNSKEY_ILLEGAL_REQUEST,
7904 0,
7905 SCSI_SNSCODE_LOGICAL_BLOCK_ADDRESS_OUT_OF_RANGE,
7906 satIOContext);
7907
7908 ostiInitiatorIOCompleted( tiRoot,
7909 tiIORequest,
7910 tiIOSuccess,
7911 SCSI_STAT_CHECK_CONDITION,
7912 satIOContext->pTiSenseData,
7913 satIOContext->interruptContext );
7914
7915 return tiSuccess;
7916 }
7917 }
7918
7919 if (pSatDevData->sat48BitSupport == agTRUE)
7920 {
7921 TI_DBG5(("satVerify10: SAT_READ_VERIFY_SECTORS_EXT\n"));
7922 fis->h.fisType = 0x27; /* Reg host to device */
7923 fis->h.c_pmPort = 0x80; /* C Bit is set */
7924
7925 fis->h.command = SAT_READ_VERIFY_SECTORS_EXT;/* 0x42 */
7926 fis->h.features = 0; /* FIS reserve */
7927 fis->d.lbaLow = scsiCmnd->cdb[5]; /* FIS LBA (7 :0 ) */
7928 fis->d.lbaMid = scsiCmnd->cdb[4]; /* FIS LBA (15:8 ) */
7929 fis->d.lbaHigh = scsiCmnd->cdb[3]; /* FIS LBA (23:16) */
7930 fis->d.device = 0x40; /* FIS LBA mode set 01000000 */
7931 fis->d.lbaLowExp = scsiCmnd->cdb[2]; /* FIS LBA (31:24) */
7932 fis->d.lbaMidExp = 0; /* FIS LBA (39:32) */
7933 fis->d.lbaHighExp = 0; /* FIS LBA (47:40) */
7934 fis->d.featuresExp = 0; /* FIS reserve */
7935 fis->d.sectorCount = scsiCmnd->cdb[8]; /* FIS sector count (7:0) */
7936 fis->d.sectorCountExp = scsiCmnd->cdb[7]; /* FIS sector count (15:8) */
7937
7938 fis->d.reserved4 = 0;
7939 fis->d.control = 0; /* FIS HOB bit clear */
7940 fis->d.reserved5 = 0;
7941
7942 agRequestType = AGSA_SATA_PROTOCOL_NON_DATA;
7943 satIOContext->ATACmd = SAT_READ_VERIFY_SECTORS_EXT;
7944 }
7945 else
7946 {
7947 TI_DBG5(("satVerify10: SAT_READ_VERIFY_SECTORS\n"));
7948 fis->h.fisType = 0x27; /* Reg host to device */
7949 fis->h.c_pmPort = 0x80; /* C bit is set */
7950 fis->h.command = SAT_READ_VERIFY_SECTORS; /* 0x40 */
7951 fis->h.features = 0; /* FIS reserve */
7952 fis->d.lbaLow = scsiCmnd->cdb[5]; /* FIS LBA (7 :0 ) */
7953 fis->d.lbaMid = scsiCmnd->cdb[4]; /* FIS LBA (15:8 ) */
7954 fis->d.lbaHigh = scsiCmnd->cdb[3]; /* FIS LBA (23:16) */
7955 /* FIS LBA mode set LBA (27:24) */
7956 fis->d.device = (bit8)((0x4 << 4) | (scsiCmnd->cdb[2] & 0xF));
7957 fis->d.lbaLowExp = 0;
7958 fis->d.lbaMidExp = 0;
7959 fis->d.lbaHighExp = 0;
7960 fis->d.featuresExp = 0;
7961 fis->d.sectorCount = scsiCmnd->cdb[8]; /* FIS sector count (7:0) */
7962 fis->d.sectorCountExp = 0;
7963 fis->d.reserved4 = 0;
7964 fis->d.control = 0; /* FIS HOB bit clear */
7965 fis->d.reserved5 = 0;
7966
7967 agRequestType = AGSA_SATA_PROTOCOL_NON_DATA;
7968 satIOContext->ATACmd = SAT_READ_VERIFY_SECTORS;
7969
7970 }
7971
7972 satIOContext->currentLBA = lba;
7973 satIOContext->OrgTL = tl;
7974
7975 /*
7976 computing number of loop and remainder for tl
7977 0xFF in case not ext
7978 0xFFFF in case EXT
7979 */
7980 if (fis->h.command == SAT_READ_VERIFY_SECTORS)
7981 {
7982 LoopNum = satComputeLoopNum(tl, 0xFF);
7983 }
7984 else if (fis->h.command == SAT_READ_VERIFY_SECTORS_EXT)
7985 {
7986 /* SAT_READ_SECTORS_EXT, SAT_READ_DMA_EXT */
7987 LoopNum = satComputeLoopNum(tl, 0xFFFF);
7988 }
7989 else
7990 {
7991 TI_DBG1(("satVerify10: error case 1!!!\n"));
7992 LoopNum = 1;
7993 }
7994
7995 satIOContext->LoopNum = LoopNum;
7996
7997 if (LoopNum == 1)
7998 {
7999 TI_DBG5(("satVerify10: NON CHAINED data\n"));
8000 /* Initialize CB for SATA completion.
8001 */
8002 satIOContext->satCompleteCB = &satNonChainedVerifyCB;
8003 }
8004 else
8005 {
8006 TI_DBG1(("satVerify10: CHAINED data\n"));
8007 /* re-setting tl */
8008 if (fis->h.command == SAT_READ_VERIFY_SECTORS)
8009 {
8010 fis->d.sectorCount = 0xFF;
8011 }
8012 else if (fis->h.command == SAT_READ_VERIFY_SECTORS_EXT)
8013 {
8014 fis->d.sectorCount = 0xFF;
8015 fis->d.sectorCountExp = 0xFF;
8016 }
8017 else
8018 {
8019 TI_DBG1(("satVerify10: error case 2!!!\n"));
8020 }
8021
8022 /* Initialize CB for SATA completion.
8023 */
8024 satIOContext->satCompleteCB = &satChainedVerifyCB;
8025 }
8026
8027
8028 /*
8029 * Prepare SGL and send FIS to LL layer.
8030 */
8031 satIOContext->reqType = agRequestType; /* Save it */
8032
8033 status = sataLLIOStart( tiRoot,
8034 tiIORequest,
8035 tiDeviceHandle,
8036 tiScsiRequest,
8037 satIOContext);
8038 return (status);
8039 }
8040
8041 GLOBAL bit32 satChainedVerify(
8042 tiRoot_t *tiRoot,
8043 tiIORequest_t *tiIORequest,
8044 tiDeviceHandle_t *tiDeviceHandle,
8045 tiScsiInitiatorRequest_t *tiScsiRequest,
8046 satIOContext_t *satIOContext)
8047 {
8048 bit32 status;
8049 satIOContext_t *satOrgIOContext = agNULL;
8050 agsaFisRegHostToDevice_t *fis;
8051 bit32 agRequestType = AGSA_SATA_PROTOCOL_NON_DATA;
8052 bit32 lba = 0;
8053 bit32 DenomTL = 0xFF;
8054 bit32 Remainder = 0;
8055 bit8 LBA[4]; /* 0 MSB, 3 LSB */
8056
8057 TI_DBG2(("satChainedVerify: start\n"));
8058
8059 fis = satIOContext->pFis;
8060 satOrgIOContext = satIOContext->satOrgIOContext;
8061 osti_memset(LBA,0, sizeof(LBA));
8062
8063 switch (satOrgIOContext->ATACmd)
8064 {
8065 case SAT_READ_VERIFY_SECTORS:
8066 DenomTL = 0xFF;
8067 break;
8068 case SAT_READ_VERIFY_SECTORS_EXT:
8069 DenomTL = 0xFFFF;
8070 break;
8071 default:
8072 TI_DBG1(("satChainedVerify: error incorrect ata command 0x%x\n", satIOContext->ATACmd));
8073 return tiError;
8074 break;
8075 }
8076
8077 Remainder = satOrgIOContext->OrgTL % DenomTL;
8078 satOrgIOContext->currentLBA = satOrgIOContext->currentLBA + DenomTL;
8079 lba = satOrgIOContext->currentLBA;
8080
8081 LBA[0] = (bit8)((lba & 0xF000) >> (8 * 3)); /* MSB */
8082 LBA[1] = (bit8)((lba & 0xF00) >> (8 * 2));
8083 LBA[2] = (bit8)((lba & 0xF0) >> 8);
8084 LBA[3] = (bit8)(lba & 0xF); /* LSB */
8085
8086 switch (satOrgIOContext->ATACmd)
8087 {
8088 case SAT_READ_VERIFY_SECTORS:
8089 fis->h.fisType = 0x27; /* Reg host to device */
8090 fis->h.c_pmPort = 0x80; /* C bit is set */
8091 fis->h.command = SAT_READ_VERIFY_SECTORS; /* 0x40 */
8092 fis->h.features = 0; /* FIS reserve */
8093 fis->d.lbaLow = LBA[3]; /* FIS LBA (7 :0 ) */
8094 fis->d.lbaMid = LBA[2]; /* FIS LBA (15:8 ) */
8095 fis->d.lbaHigh = LBA[1]; /* FIS LBA (23:16) */
8096
8097 /* FIS LBA mode set LBA (27:24) */
8098 fis->d.device = (bit8)((0x4 << 4) | (LBA[0] & 0xF));
8099
8100 fis->d.lbaLowExp = 0;
8101 fis->d.lbaMidExp = 0;
8102 fis->d.lbaHighExp = 0;
8103 fis->d.featuresExp = 0;
8104 if (satOrgIOContext->LoopNum == 1)
8105 {
8106 /* last loop */
8107 fis->d.sectorCount = (bit8)Remainder; /* FIS sector count (7:0) */
8108 }
8109 else
8110 {
8111 fis->d.sectorCount = 0xFF; /* FIS sector count (7:0) */
8112 }
8113 fis->d.sectorCountExp = 0;
8114 fis->d.reserved4 = 0;
8115 fis->d.control = 0; /* FIS HOB bit clear */
8116 fis->d.reserved5 = 0;
8117
8118 agRequestType = AGSA_SATA_PROTOCOL_NON_DATA;
8119
8120 break;
8121 case SAT_READ_VERIFY_SECTORS_EXT:
8122 fis->h.fisType = 0x27; /* Reg host to device */
8123 fis->h.c_pmPort = 0x80; /* C Bit is set */
8124 fis->h.command = SAT_READ_VERIFY_SECTORS_EXT; /* 0x42 */
8125 fis->h.features = 0; /* FIS reserve */
8126 fis->d.lbaLow = LBA[3]; /* FIS LBA (7 :0 ) */
8127 fis->d.lbaMid = LBA[2]; /* FIS LBA (15:8 ) */
8128 fis->d.lbaHigh = LBA[1]; /* FIS LBA (23:16) */
8129 fis->d.device = 0x40; /* FIS LBA mode set */
8130 fis->d.lbaLowExp = LBA[0]; /* FIS LBA (31:24) */
8131 fis->d.lbaMidExp = 0; /* FIS LBA (39:32) */
8132 fis->d.lbaHighExp = 0; /* FIS LBA (47:40) */
8133 fis->d.featuresExp = 0; /* FIS reserve */
8134 if (satOrgIOContext->LoopNum == 1)
8135 {
8136 /* last loop */
8137 fis->d.sectorCount = (bit8)(Remainder & 0xFF); /* FIS sector count (7:0) */
8138 fis->d.sectorCountExp = (bit8)((Remainder & 0xFF00) >> 8); /* FIS sector count (15:8) */
8139 }
8140 else
8141 {
8142 fis->d.sectorCount = 0xFF; /* FIS sector count (7:0) */
8143 fis->d.sectorCountExp = 0xFF; /* FIS sector count (15:8) */
8144 }
8145 fis->d.reserved4 = 0;
8146 fis->d.control = 0; /* FIS HOB bit clear */
8147 fis->d.reserved5 = 0;
8148
8149 agRequestType = AGSA_SATA_PROTOCOL_NON_DATA;
8150
8151 break;
8152
8153 default:
8154 TI_DBG1(("satChainedVerify: error incorrect ata command 0x%x\n", satIOContext->ATACmd));
8155 return tiError;
8156 break;
8157 }
8158
8159 /* Initialize CB for SATA completion.
8160 */
8161 /* chained data */
8162 satIOContext->satCompleteCB = &satChainedVerifyCB;
8163
8164
8165 /*
8166 * Prepare SGL and send FIS to LL layer.
8167 */
8168 satIOContext->reqType = agRequestType; /* Save it */
8169
8170 status = sataLLIOStart( tiRoot,
8171 tiIORequest,
8172 tiDeviceHandle,
8173 tiScsiRequest,
8174 satIOContext);
8175
8176 TI_DBG5(("satChainedVerify: return\n"));
8177 return (status);
8178
8179 }
8180
8181
8182 /*****************************************************************************/
8183 /*! \brief SAT implementation for SCSI VERIFY (12).
8184 *
8185 * SAT implementation for SCSI VERIFY (12).
8186 *
8187 * \param tiRoot: Pointer to TISA initiator driver/port instance.
8188 * \param tiIORequest: Pointer to TISA I/O request context for this I/O.
8189 * \param tiDeviceHandle: Pointer to TISA device handle for this I/O.
8190 * \param tiScsiRequest: Pointer to TISA SCSI I/O request and SGL list.
8191 * \param satIOContext_t: Pointer to the SAT IO Context
8192 *
8193 * \return If command is started successfully
8194 * - \e tiSuccess: I/O request successfully initiated.
8195 * - \e tiBusy: No resources available, try again later.
8196 * - \e tiIONoDevice: Invalid device handle.
8197 * - \e tiError: Other errors.
8198 */
8199 /*****************************************************************************/
8200 GLOBAL bit32 satVerify12(
8201 tiRoot_t *tiRoot,
8202 tiIORequest_t *tiIORequest,
8203 tiDeviceHandle_t *tiDeviceHandle,
8204 tiScsiInitiatorRequest_t *tiScsiRequest,
8205 satIOContext_t *satIOContext)
8206 {
8207 /*
8208 For simple implementation,
8209 no byte comparison supported as of 4/5/06
8210 */
8211 scsiRspSense_t *pSense;
8212 tiIniScsiCmnd_t *scsiCmnd;
8213 satDeviceData_t *pSatDevData;
8214 agsaFisRegHostToDevice_t *fis;
8215 bit32 status;
8216 bit32 agRequestType = AGSA_SATA_PROTOCOL_NON_DATA;
8217 bit32 lba = 0;
8218 bit32 tl = 0;
8219 bit32 LoopNum = 1;
8220 bit8 LBA[4];
8221 bit8 TL[4];
8222 bit32 rangeChk = agFALSE; /* lba and tl range check */
8223
8224 TI_DBG5(("satVerify12 entry: tiDeviceHandle=%p tiIORequest=%p\n",
8225 tiDeviceHandle, tiIORequest));
8226
8227 pSense = satIOContext->pSense;
8228 scsiCmnd = &tiScsiRequest->scsiCmnd;
8229 pSatDevData = satIOContext->pSatDevData;
8230 fis = satIOContext->pFis;
8231
8232
8233 /* checking BYTCHK */
8234 if (scsiCmnd->cdb[1] & SCSI_VERIFY_BYTCHK_MASK)
8235 {
8236 /*
8237 should do the byte check
8238 but not supported in this version
8239 */
8240 satSetSensePayload( pSense,
8241 SCSI_SNSKEY_ILLEGAL_REQUEST,
8242 0,
8243 SCSI_SNSCODE_INVALID_FIELD_IN_CDB,
8244 satIOContext);
8245
8246 ostiInitiatorIOCompleted( tiRoot,
8247 tiIORequest,
8248 tiIOSuccess,
8249 SCSI_STAT_CHECK_CONDITION,
8250 satIOContext->pTiSenseData,
8251 satIOContext->interruptContext );
8252
8253 TI_DBG1(("satVerify12: no byte checking \n"));
8254 return tiSuccess;
8255 }
8256
8257 /* checking CONTROL */
8258 /* NACA == 1 or LINK == 1*/
8259 if ( (scsiCmnd->cdb[11] & SCSI_NACA_MASK) || (scsiCmnd->cdb[11] & SCSI_LINK_MASK) )
8260 {
8261 satSetSensePayload( pSense,
8262 SCSI_SNSKEY_ILLEGAL_REQUEST,
8263 0,
8264 SCSI_SNSCODE_INVALID_FIELD_IN_CDB,
8265 satIOContext);
8266
8267 ostiInitiatorIOCompleted( tiRoot,
8268 tiIORequest,
8269 tiIOSuccess,
8270 SCSI_STAT_CHECK_CONDITION,
8271 satIOContext->pTiSenseData,
8272 satIOContext->interruptContext );
8273
8274 TI_DBG1(("satVerify12: return control\n"));
8275 return tiSuccess;
8276 }
8277
8278 osti_memset(LBA, 0, sizeof(LBA));
8279 osti_memset(TL, 0, sizeof(TL));
8280
8281 /* do not use memcpy due to indexing in LBA and TL */
8282 LBA[0] = scsiCmnd->cdb[2]; /* MSB */
8283 LBA[1] = scsiCmnd->cdb[3];
8284 LBA[2] = scsiCmnd->cdb[4];
8285 LBA[3] = scsiCmnd->cdb[5]; /* LSB */
8286
8287 TL[0] = scsiCmnd->cdb[6]; /* MSB */
8288 TL[1] = scsiCmnd->cdb[7];
8289 TL[2] = scsiCmnd->cdb[7];
8290 TL[3] = scsiCmnd->cdb[8]; /* LSB */
8291
8292 rangeChk = satAddNComparebit32(LBA, TL);
8293
8294 lba = satComputeCDB12LBA(satIOContext);
8295 tl = satComputeCDB12TL(satIOContext);
8296
8297 if (pSatDevData->satNCQ != agTRUE &&
8298 pSatDevData->sat48BitSupport != agTRUE
8299 )
8300 {
8301 if (lba > SAT_TR_LBA_LIMIT - 1)
8302 {
8303 satSetSensePayload( pSense,
8304 SCSI_SNSKEY_ILLEGAL_REQUEST,
8305 0,
8306 SCSI_SNSCODE_LOGICAL_BLOCK_ADDRESS_OUT_OF_RANGE,
8307 satIOContext);
8308
8309 ostiInitiatorIOCompleted( tiRoot,
8310 tiIORequest,
8311 tiIOSuccess,
8312 SCSI_STAT_CHECK_CONDITION,
8313 satIOContext->pTiSenseData,
8314 satIOContext->interruptContext );
8315
8316 TI_DBG1(("satVerify12: return LBA out of range, not EXT\n"));
8317 TI_DBG1(("satVerify12: cdb 0x%x 0x%x 0x%x 0x%x\n",scsiCmnd->cdb[2], scsiCmnd->cdb[3],
8318 scsiCmnd->cdb[4], scsiCmnd->cdb[5]));
8319 TI_DBG1(("satVerify12: lba 0x%x SAT_TR_LBA_LIMIT 0x%x\n", lba, SAT_TR_LBA_LIMIT));
8320 return tiSuccess;
8321 }
8322
8323 if (rangeChk) // if (lba + tl > SAT_TR_LBA_LIMIT)
8324 {
8325 TI_DBG1(("satVerify12: return LBA+TL out of range, not EXT\n"));
8326 satSetSensePayload( pSense,
8327 SCSI_SNSKEY_ILLEGAL_REQUEST,
8328 0,
8329 SCSI_SNSCODE_LOGICAL_BLOCK_ADDRESS_OUT_OF_RANGE,
8330 satIOContext);
8331
8332 ostiInitiatorIOCompleted( tiRoot,
8333 tiIORequest,
8334 tiIOSuccess,
8335 SCSI_STAT_CHECK_CONDITION,
8336 satIOContext->pTiSenseData,
8337 satIOContext->interruptContext );
8338
8339 return tiSuccess;
8340 }
8341 }
8342
8343 if (pSatDevData->sat48BitSupport == agTRUE)
8344 {
8345 TI_DBG5(("satVerify12: SAT_READ_VERIFY_SECTORS_EXT\n"));
8346 fis->h.fisType = 0x27; /* Reg host to device */
8347 fis->h.c_pmPort = 0x80; /* C Bit is set */
8348
8349 fis->h.command = SAT_READ_VERIFY_SECTORS_EXT;/* 0x42 */
8350 fis->h.features = 0; /* FIS reserve */
8351 fis->d.lbaLow = scsiCmnd->cdb[5]; /* FIS LBA (7 :0 ) */
8352 fis->d.lbaMid = scsiCmnd->cdb[4]; /* FIS LBA (15:8 ) */
8353 fis->d.lbaHigh = scsiCmnd->cdb[3]; /* FIS LBA (23:16) */
8354 fis->d.device = 0x40; /* FIS LBA mode set 01000000 */
8355 fis->d.lbaLowExp = scsiCmnd->cdb[2]; /* FIS LBA (31:24) */
8356 fis->d.lbaMidExp = 0; /* FIS LBA (39:32) */
8357 fis->d.lbaHighExp = 0; /* FIS LBA (47:40) */
8358 fis->d.featuresExp = 0; /* FIS reserve */
8359 fis->d.sectorCount = scsiCmnd->cdb[9]; /* FIS sector count (7:0) */
8360 fis->d.sectorCountExp = scsiCmnd->cdb[8]; /* FIS sector count (15:8) */
8361
8362 fis->d.reserved4 = 0;
8363 fis->d.control = 0; /* FIS HOB bit clear */
8364 fis->d.reserved5 = 0;
8365
8366 agRequestType = AGSA_SATA_PROTOCOL_NON_DATA;
8367 satIOContext->ATACmd = SAT_READ_VERIFY_SECTORS_EXT;
8368 }
8369 else
8370 {
8371 TI_DBG5(("satVerify12: SAT_READ_VERIFY_SECTORS\n"));
8372 fis->h.fisType = 0x27; /* Reg host to device */
8373 fis->h.c_pmPort = 0x80; /* C bit is set */
8374 fis->h.command = SAT_READ_VERIFY_SECTORS; /* 0x40 */
8375 fis->h.features = 0; /* FIS reserve */
8376 fis->d.lbaLow = scsiCmnd->cdb[5]; /* FIS LBA (7 :0 ) */
8377 fis->d.lbaMid = scsiCmnd->cdb[4]; /* FIS LBA (15:8 ) */
8378 fis->d.lbaHigh = scsiCmnd->cdb[3]; /* FIS LBA (23:16) */
8379 /* FIS LBA mode set LBA (27:24) */
8380 fis->d.device = (bit8)((0x4 << 4) | (scsiCmnd->cdb[2] & 0xF));
8381 fis->d.lbaLowExp = 0;
8382 fis->d.lbaMidExp = 0;
8383 fis->d.lbaHighExp = 0;
8384 fis->d.featuresExp = 0;
8385 fis->d.sectorCount = scsiCmnd->cdb[9]; /* FIS sector count (7:0) */
8386 fis->d.sectorCountExp = 0;
8387 fis->d.reserved4 = 0;
8388 fis->d.control = 0; /* FIS HOB bit clear */
8389 fis->d.reserved5 = 0;
8390
8391 agRequestType = AGSA_SATA_PROTOCOL_NON_DATA;
8392 satIOContext->ATACmd = SAT_READ_VERIFY_SECTORS;
8393
8394 }
8395
8396 satIOContext->currentLBA = lba;
8397 satIOContext->OrgTL = tl;
8398
8399 /*
8400 computing number of loop and remainder for tl
8401 0xFF in case not ext
8402 0xFFFF in case EXT
8403 */
8404 if (fis->h.command == SAT_READ_VERIFY_SECTORS)
8405 {
8406 LoopNum = satComputeLoopNum(tl, 0xFF);
8407 }
8408 else if (fis->h.command == SAT_READ_VERIFY_SECTORS_EXT)
8409 {
8410 /* SAT_READ_SECTORS_EXT, SAT_READ_DMA_EXT */
8411 LoopNum = satComputeLoopNum(tl, 0xFFFF);
8412 }
8413 else
8414 {
8415 TI_DBG1(("satVerify12: error case 1!!!\n"));
8416 LoopNum = 1;
8417 }
8418
8419 satIOContext->LoopNum = LoopNum;
8420
8421 if (LoopNum == 1)
8422 {
8423 TI_DBG5(("satVerify12: NON CHAINED data\n"));
8424 /* Initialize CB for SATA completion.
8425 */
8426 satIOContext->satCompleteCB = &satNonChainedVerifyCB;
8427 }
8428 else
8429 {
8430 TI_DBG1(("satVerify12: CHAINED data\n"));
8431 /* re-setting tl */
8432 if (fis->h.command == SAT_READ_VERIFY_SECTORS)
8433 {
8434 fis->d.sectorCount = 0xFF;
8435 }
8436 else if (fis->h.command == SAT_READ_VERIFY_SECTORS_EXT)
8437 {
8438 fis->d.sectorCount = 0xFF;
8439 fis->d.sectorCountExp = 0xFF;
8440 }
8441 else
8442 {
8443 TI_DBG1(("satVerify10: error case 2!!!\n"));
8444 }
8445
8446 /* Initialize CB for SATA completion.
8447 */
8448 satIOContext->satCompleteCB = &satChainedVerifyCB;
8449 }
8450
8451
8452 /*
8453 * Prepare SGL and send FIS to LL layer.
8454 */
8455 satIOContext->reqType = agRequestType; /* Save it */
8456
8457 status = sataLLIOStart( tiRoot,
8458 tiIORequest,
8459 tiDeviceHandle,
8460 tiScsiRequest,
8461 satIOContext);
8462 return (status);
8463 }
8464 /*****************************************************************************/
8465 /*! \brief SAT implementation for SCSI VERIFY (16).
8466 *
8467 * SAT implementation for SCSI VERIFY (16).
8468 *
8469 * \param tiRoot: Pointer to TISA initiator driver/port instance.
8470 * \param tiIORequest: Pointer to TISA I/O request context for this I/O.
8471 * \param tiDeviceHandle: Pointer to TISA device handle for this I/O.
8472 * \param tiScsiRequest: Pointer to TISA SCSI I/O request and SGL list.
8473 * \param satIOContext_t: Pointer to the SAT IO Context
8474 *
8475 * \return If command is started successfully
8476 * - \e tiSuccess: I/O request successfully initiated.
8477 * - \e tiBusy: No resources available, try again later.
8478 * - \e tiIONoDevice: Invalid device handle.
8479 * - \e tiError: Other errors.
8480 */
8481 /*****************************************************************************/
8482 GLOBAL bit32 satVerify16(
8483 tiRoot_t *tiRoot,
8484 tiIORequest_t *tiIORequest,
8485 tiDeviceHandle_t *tiDeviceHandle,
8486 tiScsiInitiatorRequest_t *tiScsiRequest,
8487 satIOContext_t *satIOContext)
8488 {
8489 /*
8490 For simple implementation,
8491 no byte comparison supported as of 4/5/06
8492 */
8493 scsiRspSense_t *pSense;
8494 tiIniScsiCmnd_t *scsiCmnd;
8495 satDeviceData_t *pSatDevData;
8496 agsaFisRegHostToDevice_t *fis;
8497 bit32 status;
8498 bit32 agRequestType = AGSA_SATA_PROTOCOL_NON_DATA;
8499 bit32 lba = 0;
8500 bit32 tl = 0;
8501 bit32 LoopNum = 1;
8502 bit8 LBA[8];
8503 bit8 TL[8];
8504 bit32 rangeChk = agFALSE; /* lba and tl range check */
8505 bit32 limitChk = agFALSE; /* lba and tl range check */
8506
8507 TI_DBG5(("satVerify16 entry: tiDeviceHandle=%p tiIORequest=%p\n",
8508 tiDeviceHandle, tiIORequest));
8509
8510 pSense = satIOContext->pSense;
8511 scsiCmnd = &tiScsiRequest->scsiCmnd;
8512 pSatDevData = satIOContext->pSatDevData;
8513 fis = satIOContext->pFis;
8514
8515 /* checking BYTCHK */
8516 if (scsiCmnd->cdb[1] & SCSI_VERIFY_BYTCHK_MASK)
8517 {
8518 /*
8519 should do the byte check
8520 but not supported in this version
8521 */
8522 satSetSensePayload( pSense,
8523 SCSI_SNSKEY_ILLEGAL_REQUEST,
8524 0,
8525 SCSI_SNSCODE_INVALID_FIELD_IN_CDB,
8526 satIOContext);
8527
8528 ostiInitiatorIOCompleted( tiRoot,
8529 tiIORequest,
8530 tiIOSuccess,
8531 SCSI_STAT_CHECK_CONDITION,
8532 satIOContext->pTiSenseData,
8533 satIOContext->interruptContext );
8534
8535 TI_DBG1(("satVerify16: no byte checking \n"));
8536 return tiSuccess;
8537 }
8538
8539 /* checking CONTROL */
8540 /* NACA == 1 or LINK == 1*/
8541 if ( (scsiCmnd->cdb[15] & SCSI_NACA_MASK) || (scsiCmnd->cdb[15] & SCSI_LINK_MASK) )
8542 {
8543 satSetSensePayload( pSense,
8544 SCSI_SNSKEY_ILLEGAL_REQUEST,
8545 0,
8546 SCSI_SNSCODE_INVALID_FIELD_IN_CDB,
8547 satIOContext);
8548
8549 ostiInitiatorIOCompleted( tiRoot,
8550 tiIORequest,
8551 tiIOSuccess,
8552 SCSI_STAT_CHECK_CONDITION,
8553 satIOContext->pTiSenseData,
8554 satIOContext->interruptContext );
8555
8556 TI_DBG2(("satVerify16: return control\n"));
8557 return tiSuccess;
8558 }
8559
8560 osti_memset(LBA, 0, sizeof(LBA));
8561 osti_memset(TL, 0, sizeof(TL));
8562
8563
8564 /* do not use memcpy due to indexing in LBA and TL */
8565 LBA[0] = scsiCmnd->cdb[2]; /* MSB */
8566 LBA[1] = scsiCmnd->cdb[3];
8567 LBA[2] = scsiCmnd->cdb[4];
8568 LBA[3] = scsiCmnd->cdb[5];
8569 LBA[4] = scsiCmnd->cdb[6];
8570 LBA[5] = scsiCmnd->cdb[7];
8571 LBA[6] = scsiCmnd->cdb[8];
8572 LBA[7] = scsiCmnd->cdb[9]; /* LSB */
8573
8574 TL[0] = 0;
8575 TL[1] = 0;
8576 TL[2] = 0;
8577 TL[3] = 0;
8578 TL[4] = scsiCmnd->cdb[10]; /* MSB */
8579 TL[5] = scsiCmnd->cdb[11];
8580 TL[6] = scsiCmnd->cdb[12];
8581 TL[7] = scsiCmnd->cdb[13]; /* LSB */
8582
8583 rangeChk = satAddNComparebit64(LBA, TL);
8584
8585 limitChk = satCompareLBALimitbit(LBA);
8586
8587 lba = satComputeCDB16LBA(satIOContext);
8588 tl = satComputeCDB16TL(satIOContext);
8589
8590 if (pSatDevData->satNCQ != agTRUE &&
8591 pSatDevData->sat48BitSupport != agTRUE
8592 )
8593 {
8594 if (limitChk)
8595 {
8596 TI_DBG1(("satVerify16: return LBA out of range, not EXT\n"));
8597 satSetSensePayload( pSense,
8598 SCSI_SNSKEY_ILLEGAL_REQUEST,
8599 0,
8600 SCSI_SNSCODE_LOGICAL_BLOCK_ADDRESS_OUT_OF_RANGE,
8601 satIOContext);
8602
8603 ostiInitiatorIOCompleted( tiRoot,
8604 tiIORequest,
8605 tiIOSuccess,
8606 SCSI_STAT_CHECK_CONDITION,
8607 satIOContext->pTiSenseData,
8608 satIOContext->interruptContext );
8609
8610 return tiSuccess;
8611 }
8612 if (rangeChk) // if (lba + tl > SAT_TR_LBA_LIMIT)
8613 {
8614 TI_DBG1(("satVerify16: return LBA+TL out of range, not EXT\n"));
8615 satSetSensePayload( pSense,
8616 SCSI_SNSKEY_ILLEGAL_REQUEST,
8617 0,
8618 SCSI_SNSCODE_LOGICAL_BLOCK_ADDRESS_OUT_OF_RANGE,
8619 satIOContext);
8620
8621 ostiInitiatorIOCompleted( tiRoot,
8622 tiIORequest,
8623 tiIOSuccess,
8624 SCSI_STAT_CHECK_CONDITION,
8625 satIOContext->pTiSenseData,
8626 satIOContext->interruptContext );
8627
8628 return tiSuccess;
8629 }
8630 }
8631
8632 if (pSatDevData->sat48BitSupport == agTRUE)
8633 {
8634 TI_DBG5(("satVerify16: SAT_READ_VERIFY_SECTORS_EXT\n"));
8635 fis->h.fisType = 0x27; /* Reg host to device */
8636 fis->h.c_pmPort = 0x80; /* C Bit is set */
8637
8638 fis->h.command = SAT_READ_VERIFY_SECTORS_EXT;/* 0x42 */
8639 fis->h.features = 0; /* FIS reserve */
8640 fis->d.lbaLow = scsiCmnd->cdb[9]; /* FIS LBA (7 :0 ) */
8641 fis->d.lbaMid = scsiCmnd->cdb[8]; /* FIS LBA (15:8 ) */
8642 fis->d.lbaHigh = scsiCmnd->cdb[7]; /* FIS LBA (23:16) */
8643 fis->d.device = 0x40; /* FIS LBA mode set 01000000 */
8644 fis->d.lbaLowExp = scsiCmnd->cdb[6]; /* FIS LBA (31:24) */
8645 fis->d.lbaMidExp = scsiCmnd->cdb[5]; /* FIS LBA (39:32) */
8646 fis->d.lbaHighExp = scsiCmnd->cdb[4]; /* FIS LBA (47:40) */
8647 fis->d.featuresExp = 0; /* FIS reserve */
8648 fis->d.sectorCount = scsiCmnd->cdb[13]; /* FIS sector count (7:0) */
8649 fis->d.sectorCountExp = scsiCmnd->cdb[12]; /* FIS sector count (15:8) */
8650
8651 fis->d.reserved4 = 0;
8652 fis->d.control = 0; /* FIS HOB bit clear */
8653 fis->d.reserved5 = 0;
8654
8655 agRequestType = AGSA_SATA_PROTOCOL_NON_DATA;
8656 satIOContext->ATACmd = SAT_READ_VERIFY_SECTORS_EXT;
8657 }
8658 else
8659 {
8660 TI_DBG5(("satVerify12: SAT_READ_VERIFY_SECTORS\n"));
8661 fis->h.fisType = 0x27; /* Reg host to device */
8662 fis->h.c_pmPort = 0x80; /* C bit is set */
8663 fis->h.command = SAT_READ_VERIFY_SECTORS; /* 0x40 */
8664 fis->h.features = 0; /* FIS reserve */
8665 fis->d.lbaLow = scsiCmnd->cdb[9]; /* FIS LBA (7 :0 ) */
8666 fis->d.lbaMid = scsiCmnd->cdb[8]; /* FIS LBA (15:8 ) */
8667 fis->d.lbaHigh = scsiCmnd->cdb[7]; /* FIS LBA (23:16) */
8668 /* FIS LBA mode set LBA (27:24) */
8669 fis->d.device = (bit8)((0x4 << 4) | (scsiCmnd->cdb[6] & 0xF));
8670 fis->d.lbaLowExp = 0;
8671 fis->d.lbaMidExp = 0;
8672 fis->d.lbaHighExp = 0;
8673 fis->d.featuresExp = 0;
8674 fis->d.sectorCount = scsiCmnd->cdb[13]; /* FIS sector count (7:0) */
8675 fis->d.sectorCountExp = 0;
8676 fis->d.reserved4 = 0;
8677 fis->d.control = 0; /* FIS HOB bit clear */
8678 fis->d.reserved5 = 0;
8679
8680 agRequestType = AGSA_SATA_PROTOCOL_NON_DATA;
8681 satIOContext->ATACmd = SAT_READ_VERIFY_SECTORS;
8682
8683 }
8684
8685 satIOContext->currentLBA = lba;
8686 satIOContext->OrgTL = tl;
8687
8688 /*
8689 computing number of loop and remainder for tl
8690 0xFF in case not ext
8691 0xFFFF in case EXT
8692 */
8693 if (fis->h.command == SAT_READ_VERIFY_SECTORS)
8694 {
8695 LoopNum = satComputeLoopNum(tl, 0xFF);
8696 }
8697 else if (fis->h.command == SAT_READ_VERIFY_SECTORS_EXT)
8698 {
8699 /* SAT_READ_SECTORS_EXT, SAT_READ_DMA_EXT */
8700 LoopNum = satComputeLoopNum(tl, 0xFFFF);
8701 }
8702 else
8703 {
8704 TI_DBG1(("satVerify12: error case 1!!!\n"));
8705 LoopNum = 1;
8706 }
8707
8708 satIOContext->LoopNum = LoopNum;
8709
8710 if (LoopNum == 1)
8711 {
8712 TI_DBG5(("satVerify12: NON CHAINED data\n"));
8713 /* Initialize CB for SATA completion.
8714 */
8715 satIOContext->satCompleteCB = &satNonChainedVerifyCB;
8716 }
8717 else
8718 {
8719 TI_DBG1(("satVerify12: CHAINED data\n"));
8720 /* re-setting tl */
8721 if (fis->h.command == SAT_READ_VERIFY_SECTORS)
8722 {
8723 fis->d.sectorCount = 0xFF;
8724 }
8725 else if (fis->h.command == SAT_READ_VERIFY_SECTORS_EXT)
8726 {
8727 fis->d.sectorCount = 0xFF;
8728 fis->d.sectorCountExp = 0xFF;
8729 }
8730 else
8731 {
8732 TI_DBG1(("satVerify10: error case 2!!!\n"));
8733 }
8734
8735 /* Initialize CB for SATA completion.
8736 */
8737 satIOContext->satCompleteCB = &satChainedVerifyCB;
8738 }
8739
8740
8741 /*
8742 * Prepare SGL and send FIS to LL layer.
8743 */
8744 satIOContext->reqType = agRequestType; /* Save it */
8745
8746 status = sataLLIOStart( tiRoot,
8747 tiIORequest,
8748 tiDeviceHandle,
8749 tiScsiRequest,
8750 satIOContext);
8751 return (status);
8752 }
8753 /*****************************************************************************/
8754 /*! \brief SAT implementation for SCSI satFormatUnit.
8755 *
8756 * SAT implementation for SCSI satFormatUnit.
8757 *
8758 * \param tiRoot: Pointer to TISA initiator driver/port instance.
8759 * \param tiIORequest: Pointer to TISA I/O request context for this I/O.
8760 * \param tiDeviceHandle: Pointer to TISA device handle for this I/O.
8761 * \param tiScsiRequest: Pointer to TISA SCSI I/O request and SGL list.
8762 * \param satIOContext_t: Pointer to the SAT IO Context
8763 *
8764 * \return If command is started successfully
8765 * - \e tiSuccess: I/O request successfully initiated.
8766 * - \e tiBusy: No resources available, try again later.
8767 * - \e tiIONoDevice: Invalid device handle.
8768 * - \e tiError: Other errors.
8769 */
8770 /*****************************************************************************/
8771 GLOBAL bit32 satFormatUnit(
8772 tiRoot_t *tiRoot,
8773 tiIORequest_t *tiIORequest,
8774 tiDeviceHandle_t *tiDeviceHandle,
8775 tiScsiInitiatorRequest_t *tiScsiRequest,
8776 satIOContext_t *satIOContext)
8777 {
8778 /*
8779 note: we don't support media certification in this version and IP bit
8780 satDevData->satFormatState will be agFalse since SAT does not actually sends
8781 any ATA command
8782 */
8783
8784 scsiRspSense_t *pSense;
8785 tiIniScsiCmnd_t *scsiCmnd;
8786 bit32 index = 0;
8787
8788 pSense = satIOContext->pSense;
8789 scsiCmnd = &tiScsiRequest->scsiCmnd;
8790
8791 TI_DBG5(("satFormatUnit:start\n"));
8792
8793 /*
8794 checking opcode
8795 1. FMTDATA bit == 0(no defect list header)
8796 2. FMTDATA bit == 1 and DCRT bit == 1(defect list header is provided
8797 with DCRT bit set)
8798 */
8799 if ( ((scsiCmnd->cdb[1] & SCSI_FORMAT_UNIT_FMTDATA_MASK) == 0) ||
8800 ((scsiCmnd->cdb[1] & SCSI_FORMAT_UNIT_FMTDATA_MASK) &&
8801 (scsiCmnd->cdb[7] & SCSI_FORMAT_UNIT_DCRT_MASK))
8802 )
8803 {
8804 ostiInitiatorIOCompleted( tiRoot,
8805 tiIORequest,
8806 tiIOSuccess,
8807 SCSI_STAT_GOOD,
8808 agNULL,
8809 satIOContext->interruptContext);
8810
8811 TI_DBG2(("satFormatUnit: return opcode\n"));
8812 return tiSuccess;
8813 }
8814
8815 /*
8816 checking DEFECT LIST FORMAT and defect list length
8817 */
8818 if ( (((scsiCmnd->cdb[1] & SCSI_FORMAT_UNIT_DEFECT_LIST_FORMAT_MASK) == 0x00) ||
8819 ((scsiCmnd->cdb[1] & SCSI_FORMAT_UNIT_DEFECT_LIST_FORMAT_MASK) == 0x06)) )
8820 {
8821 /* short parameter header */
8822 if ((scsiCmnd->cdb[2] & SCSI_FORMAT_UNIT_LONGLIST_MASK) == 0x00)
8823 {
8824 index = 8;
8825 }
8826 /* long parameter header */
8827 if ((scsiCmnd->cdb[2] & SCSI_FORMAT_UNIT_LONGLIST_MASK) == 0x01)
8828 {
8829 index = 10;
8830 }
8831 /* defect list length */
8832 if ((scsiCmnd->cdb[index] != 0) || (scsiCmnd->cdb[index+1] != 0))
8833 {
8834 satSetSensePayload( pSense,
8835 SCSI_SNSKEY_ILLEGAL_REQUEST,
8836 0,
8837 SCSI_SNSCODE_INVALID_FIELD_IN_CDB,
8838 satIOContext);
8839
8840 ostiInitiatorIOCompleted( tiRoot,
8841 tiIORequest,
8842 tiIOSuccess,
8843 SCSI_STAT_CHECK_CONDITION,
8844 satIOContext->pTiSenseData,
8845 satIOContext->interruptContext );
8846
8847 TI_DBG1(("satFormatUnit: return defect list format\n"));
8848 return tiSuccess;
8849 }
8850 }
8851
8852 /* FMTDATA == 1 && CMPLIST == 1*/
8853 if ( (scsiCmnd->cdb[1] & SCSI_FORMAT_UNIT_FMTDATA_MASK) &&
8854 (scsiCmnd->cdb[1] & SCSI_FORMAT_UNIT_CMPLIST_MASK) )
8855 {
8856 satSetSensePayload( pSense,
8857 SCSI_SNSKEY_ILLEGAL_REQUEST,
8858 0,
8859 SCSI_SNSCODE_INVALID_FIELD_IN_CDB,
8860 satIOContext);
8861
8862 ostiInitiatorIOCompleted( tiRoot,
8863 tiIORequest,
8864 tiIOSuccess,
8865 SCSI_STAT_CHECK_CONDITION,
8866 satIOContext->pTiSenseData,
8867 satIOContext->interruptContext );
8868
8869 TI_DBG1(("satFormatUnit: return cmplist\n"));
8870 return tiSuccess;
8871
8872 }
8873
8874 if ( (scsiCmnd->cdb[5] & SCSI_NACA_MASK) || (scsiCmnd->cdb[5] & SCSI_LINK_MASK) )
8875 {
8876 satSetSensePayload( pSense,
8877 SCSI_SNSKEY_ILLEGAL_REQUEST,
8878 0,
8879 SCSI_SNSCODE_INVALID_FIELD_IN_CDB,
8880 satIOContext);
8881
8882 ostiInitiatorIOCompleted( tiRoot,
8883 tiIORequest,
8884 tiIOSuccess,
8885 SCSI_STAT_CHECK_CONDITION,
8886 satIOContext->pTiSenseData,
8887 satIOContext->interruptContext );
8888
8889 TI_DBG1(("satFormatUnit: return control\n"));
8890 return tiSuccess;
8891 }
8892
8893 /* defect list header filed, if exists, SAT rev8, Table 37, p48 */
8894 if (scsiCmnd->cdb[1] & SCSI_FORMAT_UNIT_FMTDATA_MASK)
8895 {
8896 /* case 1,2,3 */
8897 /* IMMED 1; FOV 0; FOV 1, DCRT 1, IP 0 */
8898 if ( (scsiCmnd->cdb[7] & SCSI_FORMAT_UNIT_IMMED_MASK) ||
8899 ( !(scsiCmnd->cdb[7] & SCSI_FORMAT_UNIT_FOV_MASK)) ||
8900 ( (scsiCmnd->cdb[7] & SCSI_FORMAT_UNIT_FOV_MASK) &&
8901 (scsiCmnd->cdb[7] & SCSI_FORMAT_UNIT_DCRT_MASK) &&
8902 !(scsiCmnd->cdb[7] & SCSI_FORMAT_UNIT_IP_MASK))
8903 )
8904 {
8905 ostiInitiatorIOCompleted( tiRoot,
8906 tiIORequest,
8907 tiIOSuccess,
8908 SCSI_STAT_GOOD,
8909 agNULL,
8910 satIOContext->interruptContext);
8911
8912 TI_DBG5(("satFormatUnit: return defect list case 1\n"));
8913 return tiSuccess;
8914 }
8915 /* case 4,5,6 */
8916 /*
8917 1. IMMED 0, FOV 1, DCRT 0, IP 0
8918 2. IMMED 0, FOV 1, DCRT 0, IP 1
8919 3. IMMED 0, FOV 1, DCRT 1, IP 1
8920 */
8921
8922 if ( ( !(scsiCmnd->cdb[7] & SCSI_FORMAT_UNIT_IMMED_MASK) &&
8923 (scsiCmnd->cdb[7] & SCSI_FORMAT_UNIT_FOV_MASK) &&
8924 !(scsiCmnd->cdb[7] & SCSI_FORMAT_UNIT_DCRT_MASK) &&
8925 !(scsiCmnd->cdb[7] & SCSI_FORMAT_UNIT_IP_MASK) )
8926 ||
8927 ( !(scsiCmnd->cdb[7] & SCSI_FORMAT_UNIT_IMMED_MASK) &&
8928 (scsiCmnd->cdb[7] & SCSI_FORMAT_UNIT_FOV_MASK) &&
8929 !(scsiCmnd->cdb[7] & SCSI_FORMAT_UNIT_DCRT_MASK) &&
8930 (scsiCmnd->cdb[7] & SCSI_FORMAT_UNIT_IP_MASK) )
8931 ||
8932 ( !(scsiCmnd->cdb[7] & SCSI_FORMAT_UNIT_IMMED_MASK) &&
8933 (scsiCmnd->cdb[7] & SCSI_FORMAT_UNIT_FOV_MASK) &&
8934 (scsiCmnd->cdb[7] & SCSI_FORMAT_UNIT_DCRT_MASK) &&
8935 (scsiCmnd->cdb[7] & SCSI_FORMAT_UNIT_IP_MASK) )
8936 )
8937 {
8938
8939 satSetSensePayload( pSense,
8940 SCSI_SNSKEY_ILLEGAL_REQUEST,
8941 0,
8942 SCSI_SNSCODE_INVALID_FIELD_PARAMETER_LIST,
8943 satIOContext);
8944
8945 ostiInitiatorIOCompleted( tiRoot,
8946 tiIORequest,
8947 tiIOSuccess,
8948 SCSI_STAT_CHECK_CONDITION,
8949 satIOContext->pTiSenseData,
8950 satIOContext->interruptContext );
8951
8952 TI_DBG5(("satFormatUnit: return defect list case 2\n"));
8953 return tiSuccess;
8954
8955 }
8956 }
8957
8958
8959 /*
8960 * Send the completion response now.
8961 */
8962 ostiInitiatorIOCompleted( tiRoot,
8963 tiIORequest,
8964 tiIOSuccess,
8965 SCSI_STAT_GOOD,
8966 agNULL,
8967 satIOContext->interruptContext);
8968
8969 TI_DBG5(("satFormatUnit: return last\n"));
8970 return tiSuccess;
8971 }
8972
8973
8974 /*****************************************************************************/
8975 /*! \brief SAT implementation for SCSI satSendDiagnostic.
8976 *
8977 * SAT implementation for SCSI satSendDiagnostic.
8978 *
8979 * \param tiRoot: Pointer to TISA initiator driver/port instance.
8980 * \param tiIORequest: Pointer to TISA I/O request context for this I/O.
8981 * \param tiDeviceHandle: Pointer to TISA device handle for this I/O.
8982 * \param tiScsiRequest: Pointer to TISA SCSI I/O request and SGL list.
8983 * \param satIOContext_t: Pointer to the SAT IO Context
8984 *
8985 * \return If command is started successfully
8986 * - \e tiSuccess: I/O request successfully initiated.
8987 * - \e tiBusy: No resources available, try again later.
8988 * - \e tiIONoDevice: Invalid device handle.
8989 * - \e tiError: Other errors.
8990 */
8991 /*****************************************************************************/
8992 GLOBAL bit32 satSendDiagnostic(
8993 tiRoot_t *tiRoot,
8994 tiIORequest_t *tiIORequest,
8995 tiDeviceHandle_t *tiDeviceHandle,
8996 tiScsiInitiatorRequest_t *tiScsiRequest,
8997 satIOContext_t *satIOContext)
8998 {
8999 bit32 status;
9000 bit32 agRequestType;
9001 satDeviceData_t *pSatDevData;
9002 scsiRspSense_t *pSense;
9003 tiIniScsiCmnd_t *scsiCmnd;
9004 agsaFisRegHostToDevice_t *fis;
9005 bit32 parmLen;
9006
9007 pSense = satIOContext->pSense;
9008 pSatDevData = satIOContext->pSatDevData;
9009 scsiCmnd = &tiScsiRequest->scsiCmnd;
9010 fis = satIOContext->pFis;
9011
9012 TI_DBG5(("satSendDiagnostic:start\n"));
9013
9014 /* reset satVerifyState */
9015 pSatDevData->satVerifyState = 0;
9016 /* no pending diagnostic in background */
9017 pSatDevData->satBGPendingDiag = agFALSE;
9018
9019 /* table 27, 8.10 p39 SAT Rev8 */
9020 /*
9021 1. checking PF == 1
9022 2. checking DEVOFFL == 1
9023 3. checking UNITOFFL == 1
9024 4. checking PARAMETER LIST LENGTH != 0
9025
9026 */
9027 if ( (scsiCmnd->cdb[1] & SCSI_PF_MASK) ||
9028 (scsiCmnd->cdb[1] & SCSI_DEVOFFL_MASK) ||
9029 (scsiCmnd->cdb[1] & SCSI_UNITOFFL_MASK) ||
9030 ( (scsiCmnd->cdb[3] != 0) || (scsiCmnd->cdb[4] != 0) )
9031 )
9032 {
9033 satSetSensePayload( pSense,
9034 SCSI_SNSKEY_ILLEGAL_REQUEST,
9035 0,
9036 SCSI_SNSCODE_INVALID_FIELD_IN_CDB,
9037 satIOContext);
9038
9039 ostiInitiatorIOCompleted( tiRoot,
9040 tiIORequest,
9041 tiIOSuccess,
9042 SCSI_STAT_CHECK_CONDITION,
9043 satIOContext->pTiSenseData,
9044 satIOContext->interruptContext );
9045
9046 TI_DBG1(("satSendDiagnostic: return PF, DEVOFFL, UNITOFFL, PARAM LIST\n"));
9047 return tiSuccess;
9048 }
9049
9050 /* checking CONTROL */
9051 /* NACA == 1 or LINK == 1*/
9052 if ( (scsiCmnd->cdb[5] & SCSI_NACA_MASK) || (scsiCmnd->cdb[5] & SCSI_LINK_MASK) )
9053 {
9054 satSetSensePayload( pSense,
9055 SCSI_SNSKEY_ILLEGAL_REQUEST,
9056 0,
9057 SCSI_SNSCODE_INVALID_FIELD_IN_CDB,
9058 satIOContext);
9059
9060 ostiInitiatorIOCompleted( tiRoot,
9061 tiIORequest,
9062 tiIOSuccess,
9063 SCSI_STAT_CHECK_CONDITION,
9064 satIOContext->pTiSenseData,
9065 satIOContext->interruptContext );
9066
9067 TI_DBG2(("satSendDiagnostic: return control\n"));
9068 return tiSuccess;
9069 }
9070
9071 parmLen = (scsiCmnd->cdb[3] << 8) + scsiCmnd->cdb[4];
9072
9073 /* checking SELFTEST bit*/
9074 /* table 29, 8.10.3, p41 SAT Rev8 */
9075 /* case 1 */
9076 if ( !(scsiCmnd->cdb[1] & SCSI_SEND_DIAGNOSTIC_SELFTEST_MASK) &&
9077 (pSatDevData->satSMARTSelfTest == agFALSE)
9078 )
9079 {
9080 satSetSensePayload( pSense,
9081 SCSI_SNSKEY_ILLEGAL_REQUEST,
9082 0,
9083 SCSI_SNSCODE_INVALID_FIELD_IN_CDB,
9084 satIOContext);
9085
9086 ostiInitiatorIOCompleted( tiRoot,
9087 tiIORequest,
9088 tiIOSuccess,
9089 SCSI_STAT_CHECK_CONDITION,
9090 satIOContext->pTiSenseData,
9091 satIOContext->interruptContext );
9092
9093 TI_DBG1(("satSendDiagnostic: return Table 29 case 1\n"));
9094 return tiSuccess;
9095 }
9096
9097 /* case 2 */
9098 if ( !(scsiCmnd->cdb[1] & SCSI_SEND_DIAGNOSTIC_SELFTEST_MASK) &&
9099 (pSatDevData->satSMARTSelfTest == agTRUE) &&
9100 (pSatDevData->satSMARTEnabled == agFALSE)
9101 )
9102 {
9103 satSetSensePayload( pSense,
9104 SCSI_SNSKEY_ABORTED_COMMAND,
9105 0,
9106 SCSI_SNSCODE_ATA_DEVICE_FEATURE_NOT_ENABLED,
9107 satIOContext);
9108
9109 ostiInitiatorIOCompleted( tiRoot,
9110 tiIORequest,
9111 tiIOSuccess,
9112 SCSI_STAT_CHECK_CONDITION,
9113 satIOContext->pTiSenseData,
9114 satIOContext->interruptContext );
9115
9116 TI_DBG5(("satSendDiagnostic: return Table 29 case 2\n"));
9117 return tiSuccess;
9118 }
9119 /*
9120 case 3
9121 see SELF TEST CODE later
9122 */
9123
9124
9125
9126 /* case 4 */
9127
9128 /*
9129 sends three ATA verify commands
9130
9131 */
9132 if ( ((scsiCmnd->cdb[1] & SCSI_SEND_DIAGNOSTIC_SELFTEST_MASK) &&
9133 (pSatDevData->satSMARTSelfTest == agFALSE))
9134 ||
9135 ((scsiCmnd->cdb[1] & SCSI_SEND_DIAGNOSTIC_SELFTEST_MASK) &&
9136 (pSatDevData->satSMARTSelfTest == agTRUE) &&
9137 (pSatDevData->satSMARTEnabled == agFALSE))
9138 )
9139 {
9140 /*
9141 sector count 1, LBA 0
9142 sector count 1, LBA MAX
9143 sector count 1, LBA random
9144 */
9145 if (pSatDevData->sat48BitSupport == agTRUE)
9146 {
9147 /* sends READ VERIFY SECTOR(S) EXT*/
9148 fis->h.fisType = 0x27; /* Reg host to device */
9149 fis->h.c_pmPort = 0x80; /* C Bit is set */
9150 fis->h.command = SAT_READ_VERIFY_SECTORS_EXT;/* 0x42 */
9151 fis->h.features = 0; /* FIS reserve */
9152 fis->d.lbaLow = 0; /* FIS LBA (7 :0 ) */
9153 fis->d.lbaMid = 0; /* FIS LBA (15:8 ) */
9154 fis->d.lbaHigh = 0; /* FIS LBA (23:16) */
9155 fis->d.lbaLowExp = 0; /* FIS LBA (31:24) */
9156 fis->d.lbaMidExp = 0; /* FIS LBA (39:32) */
9157 fis->d.lbaHighExp = 0; /* FIS LBA (47:40) */
9158 fis->d.featuresExp = 0; /* FIS reserve */
9159 fis->d.sectorCount = 1; /* FIS sector count (7:0) */
9160 fis->d.sectorCountExp = 0; /* FIS sector count (15:8) */
9161 fis->d.reserved4 = 0;
9162 fis->d.device = 0x40; /* 01000000 */
9163 fis->d.control = 0; /* FIS HOB bit clear */
9164 fis->d.reserved5 = 0;
9165
9166 agRequestType = AGSA_SATA_PROTOCOL_NON_DATA;
9167 }
9168 else
9169 {
9170 /* READ VERIFY SECTOR(S)*/
9171 fis->h.fisType = 0x27; /* Reg host to device */
9172 fis->h.c_pmPort = 0x80; /* C Bit is set */
9173 fis->h.command = SAT_READ_VERIFY_SECTORS;/* 0x40 */
9174 fis->h.features = 0; /* FIS features NA */
9175 fis->d.lbaLow = 0; /* FIS LBA (7 :0 ) */
9176 fis->d.lbaMid = 0; /* FIS LBA (15:8 ) */
9177 fis->d.lbaHigh = 0; /* FIS LBA (23:16) */
9178 fis->d.lbaLowExp = 0;
9179 fis->d.lbaMidExp = 0;
9180 fis->d.lbaHighExp = 0;
9181 fis->d.featuresExp = 0;
9182 fis->d.sectorCount = 1; /* FIS sector count (7:0) */
9183 fis->d.sectorCountExp = 0;
9184 fis->d.reserved4 = 0;
9185 fis->d.device = 0x40; /* 01000000 */
9186 fis->d.control = 0; /* FIS HOB bit clear */
9187 fis->d.reserved5 = 0;
9188
9189 agRequestType = AGSA_SATA_PROTOCOL_NON_DATA;
9190 }
9191
9192 /* Initialize CB for SATA completion.
9193 */
9194 satIOContext->satCompleteCB = &satSendDiagnosticCB;
9195
9196 /*
9197 * Prepare SGL and send FIS to LL layer.
9198 */
9199 satIOContext->reqType = agRequestType; /* Save it */
9200
9201 status = sataLLIOStart( tiRoot,
9202 tiIORequest,
9203 tiDeviceHandle,
9204 tiScsiRequest,
9205 satIOContext);
9206
9207
9208 TI_DBG5(("satSendDiagnostic: return Table 29 case 4\n"));
9209 return (status);
9210 }
9211 /* case 5 */
9212 if ( (scsiCmnd->cdb[1] & SCSI_SEND_DIAGNOSTIC_SELFTEST_MASK) &&
9213 (pSatDevData->satSMARTSelfTest == agTRUE) &&
9214 (pSatDevData->satSMARTEnabled == agTRUE)
9215 )
9216 {
9217 /* sends SMART EXECUTE OFF-LINE IMMEDIATE */
9218 fis->h.fisType = 0x27; /* Reg host to device */
9219 fis->h.c_pmPort = 0x80; /* C Bit is set */
9220 fis->h.command = SAT_SMART_EXEUTE_OFF_LINE_IMMEDIATE;/* 0xB0 */
9221 fis->h.features = 0xD4; /* FIS features NA */
9222 fis->d.lbaLow = 0x81; /* FIS LBA (7 :0 ) */
9223 fis->d.lbaMid = 0x4F; /* FIS LBA (15:8 ) */
9224 fis->d.lbaHigh = 0xC2; /* FIS LBA (23:16) */
9225 fis->d.lbaLowExp = 0;
9226 fis->d.lbaMidExp = 0;
9227 fis->d.lbaHighExp = 0;
9228 fis->d.featuresExp = 0;
9229 fis->d.sectorCount = 0; /* FIS sector count (7:0) */
9230 fis->d.sectorCountExp = 0;
9231 fis->d.reserved4 = 0;
9232 fis->d.device = 0; /* FIS DEV is discared in SATA */
9233 fis->d.control = 0; /* FIS HOB bit clear */
9234 fis->d.reserved5 = 0;
9235
9236 agRequestType = AGSA_SATA_PROTOCOL_NON_DATA;
9237
9238 /* Initialize CB for SATA completion.
9239 */
9240 satIOContext->satCompleteCB = &satSendDiagnosticCB;
9241
9242 /*
9243 * Prepare SGL and send FIS to LL layer.
9244 */
9245 satIOContext->reqType = agRequestType; /* Save it */
9246
9247 status = sataLLIOStart( tiRoot,
9248 tiIORequest,
9249 tiDeviceHandle,
9250 tiScsiRequest,
9251 satIOContext);
9252
9253
9254 TI_DBG5(("satSendDiagnostic: return Table 29 case 5\n"));
9255 return (status);
9256 }
9257
9258
9259
9260
9261 /* SAT rev8 Table29 p41 case 3*/
9262 /* checking SELF TEST CODE*/
9263 if ( !(scsiCmnd->cdb[1] & SCSI_SEND_DIAGNOSTIC_SELFTEST_MASK) &&
9264 (pSatDevData->satSMARTSelfTest == agTRUE) &&
9265 (pSatDevData->satSMARTEnabled == agTRUE)
9266 )
9267 {
9268 /* SAT rev8 Table28 p40 */
9269 /* finding self-test code */
9270 switch ((scsiCmnd->cdb[1] & SCSI_SEND_DIAGNOSTIC_TEST_CODE_MASK) >> 5)
9271 {
9272 case 1:
9273 pSatDevData->satBGPendingDiag = agTRUE;
9274
9275 ostiInitiatorIOCompleted( tiRoot,
9276 tiIORequest,
9277 tiIOSuccess,
9278 SCSI_STAT_GOOD,
9279 agNULL,
9280 satIOContext->interruptContext );
9281 /* sends SMART EXECUTE OFF-LINE IMMEDIATE */
9282 fis->h.fisType = 0x27; /* Reg host to device */
9283 fis->h.c_pmPort = 0x80; /* C Bit is set */
9284 fis->h.command = SAT_SMART_EXEUTE_OFF_LINE_IMMEDIATE;/* 0x40 */
9285 fis->h.features = 0xD4; /* FIS features NA */
9286 fis->d.lbaLow = 0x01; /* FIS LBA (7 :0 ) */
9287 fis->d.lbaMid = 0x4F; /* FIS LBA (15:8 ) */
9288 fis->d.lbaHigh = 0xC2; /* FIS LBA (23:16) */
9289
9290 fis->d.lbaLowExp = 0;
9291 fis->d.lbaMidExp = 0;
9292 fis->d.lbaHighExp = 0;
9293 fis->d.featuresExp = 0;
9294 fis->d.sectorCount = 0; /* FIS sector count (7:0) */
9295 fis->d.sectorCountExp = 0;
9296 fis->d.reserved4 = 0;
9297 fis->d.device = 0; /* FIS DEV is discared in SATA */
9298 fis->d.control = 0; /* FIS HOB bit clear */
9299 fis->d.reserved5 = 0;
9300
9301 agRequestType = AGSA_SATA_PROTOCOL_NON_DATA;
9302
9303 /* Initialize CB for SATA completion.
9304 */
9305 satIOContext->satCompleteCB = &satSendDiagnosticCB;
9306
9307 /*
9308 * Prepare SGL and send FIS to LL layer.
9309 */
9310 satIOContext->reqType = agRequestType; /* Save it */
9311
9312 status = sataLLIOStart( tiRoot,
9313 tiIORequest,
9314 tiDeviceHandle,
9315 tiScsiRequest,
9316 satIOContext);
9317
9318
9319 TI_DBG5(("satSendDiagnostic: return Table 28 case 1\n"));
9320 return (status);
9321 case 2:
9322 pSatDevData->satBGPendingDiag = agTRUE;
9323
9324 ostiInitiatorIOCompleted( tiRoot,
9325 tiIORequest,
9326 tiIOSuccess,
9327 SCSI_STAT_GOOD,
9328 agNULL,
9329 satIOContext->interruptContext );
9330
9331
9332 /* issuing SMART EXECUTE OFF-LINE IMMEDIATE */
9333 fis->h.fisType = 0x27; /* Reg host to device */
9334 fis->h.c_pmPort = 0x80; /* C Bit is set */
9335 fis->h.command = SAT_SMART_EXEUTE_OFF_LINE_IMMEDIATE;/* 0x40 */
9336 fis->h.features = 0xD4; /* FIS features NA */
9337 fis->d.lbaLow = 0x02; /* FIS LBA (7 :0 ) */
9338 fis->d.lbaMid = 0x4F; /* FIS LBA (15:8 ) */
9339 fis->d.lbaHigh = 0xC2; /* FIS LBA (23:16) */
9340 fis->d.lbaLowExp = 0;
9341 fis->d.lbaMidExp = 0;
9342 fis->d.lbaHighExp = 0;
9343 fis->d.featuresExp = 0;
9344 fis->d.sectorCount = 0; /* FIS sector count (7:0) */
9345 fis->d.sectorCountExp = 0;
9346 fis->d.reserved4 = 0;
9347 fis->d.device = 0; /* FIS DEV is discared in SATA */
9348 fis->d.control = 0; /* FIS HOB bit clear */
9349 fis->d.reserved5 = 0;
9350
9351 agRequestType = AGSA_SATA_PROTOCOL_NON_DATA;
9352
9353 /* Initialize CB for SATA completion.
9354 */
9355 satIOContext->satCompleteCB = &satSendDiagnosticCB;
9356
9357 /*
9358 * Prepare SGL and send FIS to LL layer.
9359 */
9360 satIOContext->reqType = agRequestType; /* Save it */
9361
9362 status = sataLLIOStart( tiRoot,
9363 tiIORequest,
9364 tiDeviceHandle,
9365 tiScsiRequest,
9366 satIOContext);
9367
9368
9369 TI_DBG5(("satSendDiagnostic: return Table 28 case 2\n"));
9370 return (status);
9371 case 4:
9372 /* For simplicity, no abort is supported
9373 Returns good status
9374 need a flag in device data for previously sent background Send Diagnostic
9375 */
9376 if (parmLen != 0)
9377 {
9378 /* check condition */
9379 satSetSensePayload( pSense,
9380 SCSI_SNSKEY_ILLEGAL_REQUEST,
9381 0,
9382 SCSI_SNSCODE_INVALID_FIELD_IN_CDB,
9383 satIOContext);
9384
9385 ostiInitiatorIOCompleted( tiRoot,
9386 tiIORequest,
9387 tiIOSuccess,
9388 SCSI_STAT_CHECK_CONDITION,
9389 satIOContext->pTiSenseData,
9390 satIOContext->interruptContext );
9391
9392 TI_DBG1(("satSendDiagnostic: case 4, non zero ParmLen %d\n", parmLen));
9393 return tiSuccess;
9394 }
9395 if (pSatDevData->satBGPendingDiag == agTRUE)
9396 {
9397 /* sends SMART EXECUTE OFF-LINE IMMEDIATE abort */
9398 fis->h.fisType = 0x27; /* Reg host to device */
9399 fis->h.c_pmPort = 0x80; /* C Bit is set */
9400 fis->h.command = SAT_SMART_EXEUTE_OFF_LINE_IMMEDIATE;/* 0x40 */
9401 fis->h.features = 0xD4; /* FIS features NA */
9402 fis->d.lbaLow = 0x7F; /* FIS LBA (7 :0 ) */
9403 fis->d.lbaMid = 0x4F; /* FIS LBA (15:8 ) */
9404 fis->d.lbaHigh = 0xC2; /* FIS LBA (23:16) */
9405
9406 fis->d.lbaLowExp = 0;
9407 fis->d.lbaMidExp = 0;
9408 fis->d.lbaHighExp = 0;
9409 fis->d.featuresExp = 0;
9410 fis->d.sectorCount = 0; /* FIS sector count (7:0) */
9411 fis->d.sectorCountExp = 0;
9412 fis->d.reserved4 = 0;
9413 fis->d.device = 0; /* FIS DEV is discared in SATA */
9414 fis->d.control = 0; /* FIS HOB bit clear */
9415 fis->d.reserved5 = 0;
9416
9417 agRequestType = AGSA_SATA_PROTOCOL_NON_DATA;
9418
9419 /* Initialize CB for SATA completion.
9420 */
9421 satIOContext->satCompleteCB = &satSendDiagnosticCB;
9422
9423 /*
9424 * Prepare SGL and send FIS to LL layer.
9425 */
9426 satIOContext->reqType = agRequestType; /* Save it */
9427
9428 status = sataLLIOStart( tiRoot,
9429 tiIORequest,
9430 tiDeviceHandle,
9431 tiScsiRequest,
9432 satIOContext);
9433
9434
9435 TI_DBG5(("satSendDiagnostic: send SAT_SMART_EXEUTE_OFF_LINE_IMMEDIATE case 3\n"));
9436 TI_DBG5(("satSendDiagnostic: Table 28 case 4\n"));
9437 return (status);
9438 }
9439 else
9440 {
9441 /* check condition */
9442 satSetSensePayload( pSense,
9443 SCSI_SNSKEY_ILLEGAL_REQUEST,
9444 0,
9445 SCSI_SNSCODE_INVALID_FIELD_IN_CDB,
9446 satIOContext);
9447
9448 ostiInitiatorIOCompleted( tiRoot,
9449 tiIORequest,
9450 tiIOSuccess,
9451 SCSI_STAT_CHECK_CONDITION,
9452 satIOContext->pTiSenseData,
9453 satIOContext->interruptContext );
9454
9455 TI_DBG1(("satSendDiagnostic: case 4, no pending diagnostic in background\n"));
9456 TI_DBG5(("satSendDiagnostic: Table 28 case 4\n"));
9457 return tiSuccess;
9458 }
9459 break;
9460 case 5:
9461 /* issuing SMART EXECUTE OFF-LINE IMMEDIATE */
9462 fis->h.fisType = 0x27; /* Reg host to device */
9463 fis->h.c_pmPort = 0x80; /* C Bit is set */
9464 fis->h.command = SAT_SMART_EXEUTE_OFF_LINE_IMMEDIATE;/* 0x40 */
9465 fis->h.features = 0xD4; /* FIS features NA */
9466 fis->d.lbaLow = 0x81; /* FIS LBA (7 :0 ) */
9467 fis->d.lbaMid = 0x4F; /* FIS LBA (15:8 ) */
9468 fis->d.lbaHigh = 0xC2; /* FIS LBA (23:16) */
9469 fis->d.lbaLowExp = 0;
9470 fis->d.lbaMidExp = 0;
9471 fis->d.lbaHighExp = 0;
9472 fis->d.featuresExp = 0;
9473 fis->d.sectorCount = 0; /* FIS sector count (7:0) */
9474 fis->d.sectorCountExp = 0;
9475 fis->d.reserved4 = 0;
9476 fis->d.device = 0; /* FIS DEV is discared in SATA */
9477 fis->d.control = 0; /* FIS HOB bit clear */
9478 fis->d.reserved5 = 0;
9479
9480 agRequestType = AGSA_SATA_PROTOCOL_NON_DATA;
9481
9482 /* Initialize CB for SATA completion.
9483 */
9484 satIOContext->satCompleteCB = &satSendDiagnosticCB;
9485
9486 /*
9487 * Prepare SGL and send FIS to LL layer.
9488 */
9489 satIOContext->reqType = agRequestType; /* Save it */
9490
9491 status = sataLLIOStart( tiRoot,
9492 tiIORequest,
9493 tiDeviceHandle,
9494 tiScsiRequest,
9495 satIOContext);
9496
9497
9498 TI_DBG5(("satSendDiagnostic: return Table 28 case 5\n"));
9499 return (status);
9500 case 6:
9501 /* issuing SMART EXECUTE OFF-LINE IMMEDIATE */
9502 fis->h.fisType = 0x27; /* Reg host to device */
9503 fis->h.c_pmPort = 0x80; /* C Bit is set */
9504 fis->h.command = SAT_SMART_EXEUTE_OFF_LINE_IMMEDIATE;/* 0x40 */
9505 fis->h.features = 0xD4; /* FIS features NA */
9506 fis->d.lbaLow = 0x82; /* FIS LBA (7 :0 ) */
9507 fis->d.lbaMid = 0x4F; /* FIS LBA (15:8 ) */
9508 fis->d.lbaHigh = 0xC2; /* FIS LBA (23:16) */
9509 fis->d.lbaLowExp = 0;
9510 fis->d.lbaMidExp = 0;
9511 fis->d.lbaHighExp = 0;
9512 fis->d.featuresExp = 0;
9513 fis->d.sectorCount = 0; /* FIS sector count (7:0) */
9514 fis->d.sectorCountExp = 0;
9515 fis->d.reserved4 = 0;
9516 fis->d.device = 0; /* FIS DEV is discared in SATA */
9517 fis->d.control = 0; /* FIS HOB bit clear */
9518 fis->d.reserved5 = 0;
9519
9520 agRequestType = AGSA_SATA_PROTOCOL_NON_DATA;
9521
9522 /* Initialize CB for SATA completion.
9523 */
9524 satIOContext->satCompleteCB = &satSendDiagnosticCB;
9525
9526 /*
9527 * Prepare SGL and send FIS to LL layer.
9528 */
9529 satIOContext->reqType = agRequestType; /* Save it */
9530
9531 status = sataLLIOStart( tiRoot,
9532 tiIORequest,
9533 tiDeviceHandle,
9534 tiScsiRequest,
9535 satIOContext);
9536
9537
9538 TI_DBG5(("satSendDiagnostic: return Table 28 case 6\n"));
9539 return (status);
9540 case 0:
9541 case 3: /* fall through */
9542 case 7: /* fall through */
9543 default:
9544 break;
9545 }/* switch */
9546
9547 /* returns the results of default self-testing, which is good */
9548 ostiInitiatorIOCompleted( tiRoot,
9549 tiIORequest,
9550 tiIOSuccess,
9551 SCSI_STAT_GOOD,
9552 agNULL,
9553 satIOContext->interruptContext );
9554
9555 TI_DBG5(("satSendDiagnostic: return Table 28 case 0,3,7 and default\n"));
9556 return tiSuccess;
9557 }
9558
9559
9560 ostiInitiatorIOCompleted( tiRoot,
9561 tiIORequest,
9562 tiIOSuccess,
9563 SCSI_STAT_GOOD,
9564 agNULL,
9565 satIOContext->interruptContext );
9566
9567
9568 TI_DBG5(("satSendDiagnostic: return last\n"));
9569 return tiSuccess;
9570 }
9571
9572 /*****************************************************************************/
9573 /*! \brief SAT implementation for SCSI satSendDiagnostic_1.
9574 *
9575 * SAT implementation for SCSI satSendDiagnostic_1.
9576 * Sub function of satSendDiagnostic.
9577 *
9578 * \param tiRoot: Pointer to TISA initiator driver/port instance.
9579 * \param tiIORequest: Pointer to TISA I/O request context for this I/O.
9580 * \param tiDeviceHandle: Pointer to TISA device handle for this I/O.
9581 * \param tiScsiRequest: Pointer to TISA SCSI I/O request and SGL list.
9582 * \param satIOContext_t: Pointer to the SAT IO Context
9583 *
9584 * \return If command is started successfully
9585 * - \e tiSuccess: I/O request successfully initiated.
9586 * - \e tiBusy: No resources available, try again later.
9587 * - \e tiIONoDevice: Invalid device handle.
9588 * - \e tiError: Other errors.
9589 */
9590 /*****************************************************************************/
9591 GLOBAL bit32 satSendDiagnostic_1(
9592 tiRoot_t *tiRoot,
9593 tiIORequest_t *tiIORequest,
9594 tiDeviceHandle_t *tiDeviceHandle,
9595 tiScsiInitiatorRequest_t *tiScsiRequest,
9596 satIOContext_t *satIOContext)
9597 {
9598 /*
9599 SAT Rev9, Table29, p41
9600 send 2nd SAT_READ_VERIFY_SECTORS(_EXT)
9601 */
9602 bit32 status;
9603 bit32 agRequestType;
9604 satDeviceData_t *pSatDevData;
9605 agsaFisRegHostToDevice_t *fis;
9606
9607 TI_DBG5(("satSendDiagnostic_1 entry: tiDeviceHandle=%p tiIORequest=%p\n",
9608 tiDeviceHandle, tiIORequest));
9609
9610 pSatDevData = satIOContext->pSatDevData;
9611 fis = satIOContext->pFis;
9612
9613 /*
9614 sector count 1, LBA MAX
9615 */
9616 if (pSatDevData->sat48BitSupport == agTRUE)
9617 {
9618 /* sends READ VERIFY SECTOR(S) EXT*/
9619 fis->h.fisType = 0x27; /* Reg host to device */
9620 fis->h.c_pmPort = 0x80; /* C Bit is set */
9621 fis->h.command = SAT_READ_VERIFY_SECTORS_EXT;/* 0x42 */
9622 fis->h.features = 0; /* FIS reserve */
9623 fis->d.lbaLow = pSatDevData->satMaxLBA[7]; /* FIS LBA (7 :0 ) */
9624 fis->d.lbaMid = pSatDevData->satMaxLBA[6]; /* FIS LBA (15:8 ) */
9625 fis->d.lbaHigh = pSatDevData->satMaxLBA[5]; /* FIS LBA (23:16) */
9626 fis->d.lbaLowExp = pSatDevData->satMaxLBA[4]; /* FIS LBA (31:24) */
9627 fis->d.lbaMidExp = pSatDevData->satMaxLBA[3]; /* FIS LBA (39:32) */
9628 fis->d.lbaHighExp = pSatDevData->satMaxLBA[2]; /* FIS LBA (47:40) */
9629 fis->d.featuresExp = 0; /* FIS reserve */
9630 fis->d.sectorCount = 1; /* FIS sector count (7:0) */
9631 fis->d.sectorCountExp = 0; /* FIS sector count (15:8) */
9632 fis->d.reserved4 = 0;
9633 fis->d.device = 0x40; /* 01000000 */
9634 fis->d.control = 0; /* FIS HOB bit clear */
9635 fis->d.reserved5 = 0;
9636
9637 }
9638 else
9639 {
9640 /* READ VERIFY SECTOR(S)*/
9641 fis->h.fisType = 0x27; /* Reg host to device */
9642 fis->h.c_pmPort = 0x80; /* C Bit is set */
9643 fis->h.command = SAT_READ_VERIFY_SECTORS;/* 0x40 */
9644 fis->h.features = 0; /* FIS features NA */
9645 fis->d.lbaLow = pSatDevData->satMaxLBA[7]; /* FIS LBA (7 :0 ) */
9646 fis->d.lbaMid = pSatDevData->satMaxLBA[6]; /* FIS LBA (15:8 ) */
9647 fis->d.lbaHigh = pSatDevData->satMaxLBA[5]; /* FIS LBA (23:16) */
9648 fis->d.lbaLowExp = 0;
9649 fis->d.lbaMidExp = 0;
9650 fis->d.lbaHighExp = 0;
9651 fis->d.featuresExp = 0;
9652 fis->d.sectorCount = 1; /* FIS sector count (7:0) */
9653 fis->d.sectorCountExp = 0;
9654 fis->d.reserved4 = 0;
9655 fis->d.device = (bit8)((0x4 << 4) | (pSatDevData->satMaxLBA[4] & 0xF));
9656 /* DEV and LBA 27:24 */
9657 fis->d.control = 0; /* FIS HOB bit clear */
9658 fis->d.reserved5 = 0;
9659
9660 }
9661
9662 agRequestType = AGSA_SATA_PROTOCOL_NON_DATA;
9663
9664 /* Initialize CB for SATA completion.
9665 */
9666 satIOContext->satCompleteCB = &satSendDiagnosticCB;
9667
9668 /*
9669 * Prepare SGL and send FIS to LL layer.
9670 */
9671 satIOContext->reqType = agRequestType; /* Save it */
9672
9673 status = sataLLIOStart( tiRoot,
9674 tiIORequest,
9675 tiDeviceHandle,
9676 tiScsiRequest,
9677 satIOContext);
9678
9679
9680 return status;
9681 }
9682
9683 /*****************************************************************************/
9684 /*! \brief SAT implementation for SCSI satSendDiagnostic_2.
9685 *
9686 * SAT implementation for SCSI satSendDiagnostic_2.
9687 * Sub function of satSendDiagnostic.
9688 *
9689 * \param tiRoot: Pointer to TISA initiator driver/port instance.
9690 * \param tiIORequest: Pointer to TISA I/O request context for this I/O.
9691 * \param tiDeviceHandle: Pointer to TISA device handle for this I/O.
9692 * \param tiScsiRequest: Pointer to TISA SCSI I/O request and SGL list.
9693 * \param satIOContext_t: Pointer to the SAT IO Context
9694 *
9695 * \return If command is started successfully
9696 * - \e tiSuccess: I/O request successfully initiated.
9697 * - \e tiBusy: No resources available, try again later.
9698 * - \e tiIONoDevice: Invalid device handle.
9699 * - \e tiError: Other errors.
9700 */
9701 /*****************************************************************************/
9702 GLOBAL bit32 satSendDiagnostic_2(
9703 tiRoot_t *tiRoot,
9704 tiIORequest_t *tiIORequest,
9705 tiDeviceHandle_t *tiDeviceHandle,
9706 tiScsiInitiatorRequest_t *tiScsiRequest,
9707 satIOContext_t *satIOContext)
9708 {
9709 /*
9710 SAT Rev9, Table29, p41
9711 send 3rd SAT_READ_VERIFY_SECTORS(_EXT)
9712 */
9713 bit32 status;
9714 bit32 agRequestType;
9715 satDeviceData_t *pSatDevData;
9716 agsaFisRegHostToDevice_t *fis;
9717
9718 TI_DBG5(("satSendDiagnostic_2 entry: tiDeviceHandle=%p tiIORequest=%p\n",
9719 tiDeviceHandle, tiIORequest));
9720
9721 pSatDevData = satIOContext->pSatDevData;
9722 fis = satIOContext->pFis;
9723
9724 /*
9725 sector count 1, LBA Random
9726 */
9727 if (pSatDevData->sat48BitSupport == agTRUE)
9728 {
9729 /* sends READ VERIFY SECTOR(S) EXT*/
9730 fis->h.fisType = 0x27; /* Reg host to device */
9731 fis->h.c_pmPort = 0x80; /* C Bit is set */
9732 fis->h.command = SAT_READ_VERIFY_SECTORS_EXT;/* 0x42 */
9733 fis->h.features = 0; /* FIS reserve */
9734 fis->d.lbaLow = 0x7F; /* FIS LBA (7 :0 ) */
9735 fis->d.lbaMid = 0; /* FIS LBA (15:8 ) */
9736 fis->d.lbaHigh = 0; /* FIS LBA (23:16) */
9737 fis->d.lbaLowExp = 0; /* FIS LBA (31:24) */
9738 fis->d.lbaMidExp = 0; /* FIS LBA (39:32) */
9739 fis->d.lbaHighExp = 0; /* FIS LBA (47:40) */
9740 fis->d.featuresExp = 0; /* FIS reserve */
9741 fis->d.sectorCount = 1; /* FIS sector count (7:0) */
9742 fis->d.sectorCountExp = 0; /* FIS sector count (15:8) */
9743 fis->d.reserved4 = 0;
9744 fis->d.device = 0x40; /* 01000000 */
9745 fis->d.control = 0; /* FIS HOB bit clear */
9746 fis->d.reserved5 = 0;
9747
9748 }
9749 else
9750 {
9751 /* READ VERIFY SECTOR(S)*/
9752 fis->h.fisType = 0x27; /* Reg host to device */
9753 fis->h.c_pmPort = 0x80; /* C Bit is set */
9754 fis->h.command = SAT_READ_VERIFY_SECTORS;/* 0x40 */
9755 fis->h.features = 0; /* FIS features NA */
9756 fis->d.lbaLow = 0x7F; /* FIS LBA (7 :0 ) */
9757 fis->d.lbaMid = 0; /* FIS LBA (15:8 ) */
9758 fis->d.lbaHigh = 0; /* FIS LBA (23:16) */
9759 fis->d.lbaLowExp = 0;
9760 fis->d.lbaMidExp = 0;
9761 fis->d.lbaHighExp = 0;
9762 fis->d.featuresExp = 0;
9763 fis->d.sectorCount = 1; /* FIS sector count (7:0) */
9764 fis->d.sectorCountExp = 0;
9765 fis->d.reserved4 = 0;
9766 fis->d.device = 0x40; /* FIS LBA mode set 01000000 */
9767 fis->d.control = 0; /* FIS HOB bit clear */
9768 fis->d.reserved5 = 0;
9769
9770 }
9771
9772 agRequestType = AGSA_SATA_PROTOCOL_NON_DATA;
9773
9774 /* Initialize CB for SATA completion.
9775 */
9776 satIOContext->satCompleteCB = &satSendDiagnosticCB;
9777
9778 /*
9779 * Prepare SGL and send FIS to LL layer.
9780 */
9781 satIOContext->reqType = agRequestType; /* Save it */
9782
9783 status = sataLLIOStart( tiRoot,
9784 tiIORequest,
9785 tiDeviceHandle,
9786 tiScsiRequest,
9787 satIOContext);
9788
9789
9790 return status;
9791 }
9792 /*****************************************************************************/
9793 /*! \brief SAT implementation for SCSI satStartStopUnit.
9794 *
9795 * SAT implementation for SCSI satStartStopUnit.
9796 *
9797 * \param tiRoot: Pointer to TISA initiator driver/port instance.
9798 * \param tiIORequest: Pointer to TISA I/O request context for this I/O.
9799 * \param tiDeviceHandle: Pointer to TISA device handle for this I/O.
9800 * \param tiScsiRequest: Pointer to TISA SCSI I/O request and SGL list.
9801 * \param satIOContext_t: Pointer to the SAT IO Context
9802 *
9803 * \return If command is started successfully
9804 * - \e tiSuccess: I/O request successfully initiated.
9805 * - \e tiBusy: No resources available, try again later.
9806 * - \e tiIONoDevice: Invalid device handle.
9807 * - \e tiError: Other errors.
9808 */
9809 /*****************************************************************************/
9810 GLOBAL bit32 satStartStopUnit(
9811 tiRoot_t *tiRoot,
9812 tiIORequest_t *tiIORequest,
9813 tiDeviceHandle_t *tiDeviceHandle,
9814 tiScsiInitiatorRequest_t *tiScsiRequest,
9815 satIOContext_t *satIOContext)
9816 {
9817 bit32 status;
9818 bit32 agRequestType;
9819 satDeviceData_t *pSatDevData;
9820 scsiRspSense_t *pSense;
9821 tiIniScsiCmnd_t *scsiCmnd;
9822 agsaFisRegHostToDevice_t *fis;
9823
9824 pSense = satIOContext->pSense;
9825 pSatDevData = satIOContext->pSatDevData;
9826 scsiCmnd = &tiScsiRequest->scsiCmnd;
9827 fis = satIOContext->pFis;
9828
9829 TI_DBG5(("satStartStopUnit:start\n"));
9830
9831 /* checking CONTROL */
9832 /* NACA == 1 or LINK == 1*/
9833 if ( (scsiCmnd->cdb[5] & SCSI_NACA_MASK) || (scsiCmnd->cdb[5] & SCSI_LINK_MASK) )
9834 {
9835 satSetSensePayload( pSense,
9836 SCSI_SNSKEY_ILLEGAL_REQUEST,
9837 0,
9838 SCSI_SNSCODE_INVALID_FIELD_IN_CDB,
9839 satIOContext);
9840
9841 ostiInitiatorIOCompleted( tiRoot,
9842 tiIORequest,
9843 tiIOSuccess,
9844 SCSI_STAT_CHECK_CONDITION,
9845 satIOContext->pTiSenseData,
9846 satIOContext->interruptContext );
9847
9848 TI_DBG1(("satStartStopUnit: return control\n"));
9849 return tiSuccess;
9850 }
9851
9852 /* Spec p55, Table 48 checking START and LOEJ bit */
9853 /* case 1 */
9854 if ( !(scsiCmnd->cdb[4] & SCSI_START_MASK) && !(scsiCmnd->cdb[4] & SCSI_LOEJ_MASK) )
9855 {
9856 if ( (scsiCmnd->cdb[1] & SCSI_IMMED_MASK) )
9857 {
9858 /* immed bit , SAT rev 8, 9.11.2.1 p 54*/
9859 ostiInitiatorIOCompleted( tiRoot,
9860 tiIORequest,
9861 tiIOSuccess,
9862 SCSI_STAT_GOOD,
9863 agNULL,
9864 satIOContext->interruptContext );
9865 TI_DBG5(("satStartStopUnit: return table48 case 1-1\n"));
9866 return tiSuccess;
9867 }
9868 /* sends FLUSH CACHE or FLUSH CACHE EXT */
9869 if (pSatDevData->sat48BitSupport == agTRUE)
9870 {
9871 /* FLUSH CACHE EXT */
9872 fis->h.fisType = 0x27; /* Reg host to device */
9873 fis->h.c_pmPort = 0x80; /* C Bit is set */
9874
9875 fis->h.command = SAT_FLUSH_CACHE_EXT; /* 0xEA */
9876 fis->h.features = 0; /* FIS reserve */
9877 fis->d.featuresExp = 0; /* FIS reserve */
9878 fis->d.sectorCount = 0; /* FIS sector count (7:0) */
9879 fis->d.sectorCountExp = 0; /* FIS sector count (15:8) */
9880 fis->d.lbaLow = 0; /* FIS LBA (7 :0 ) */
9881 fis->d.lbaLowExp = 0; /* FIS LBA (31:24) */
9882 fis->d.lbaMid = 0; /* FIS LBA (15:8 ) */
9883 fis->d.lbaMidExp = 0; /* FIS LBA (39:32) */
9884 fis->d.lbaHigh = 0; /* FIS LBA (23:16) */
9885 fis->d.lbaHighExp = 0; /* FIS LBA (47:40) */
9886 fis->d.device = 0; /* FIS DEV is discared in SATA */
9887 fis->d.control = 0; /* FIS HOB bit clear */
9888 fis->d.reserved4 = 0;
9889 fis->d.reserved5 = 0;
9890
9891 agRequestType = AGSA_SATA_PROTOCOL_NON_DATA;
9892 }
9893 else
9894 {
9895 /* FLUSH CACHE */
9896 fis->h.fisType = 0x27; /* Reg host to device */
9897 fis->h.c_pmPort = 0x80; /* C Bit is set */
9898
9899 fis->h.command = SAT_FLUSH_CACHE; /* 0xE7 */
9900 fis->h.features = 0; /* FIS features NA */
9901 fis->d.lbaLow = 0; /* FIS LBA (7 :0 ) */
9902 fis->d.lbaMid = 0; /* FIS LBA (15:8 ) */
9903 fis->d.lbaHigh = 0; /* FIS LBA (23:16) */
9904 fis->d.lbaLowExp = 0;
9905 fis->d.lbaMidExp = 0;
9906 fis->d.lbaHighExp = 0;
9907 fis->d.featuresExp = 0;
9908 fis->d.sectorCount = 0; /* FIS sector count (7:0) */
9909 fis->d.sectorCountExp = 0;
9910 fis->d.device = 0; /* FIS DEV is discared in SATA */
9911 fis->d.control = 0; /* FIS HOB bit clear */
9912 fis->d.reserved4 = 0;
9913 fis->d.reserved5 = 0;
9914
9915 agRequestType = AGSA_SATA_PROTOCOL_NON_DATA;
9916 }
9917
9918 /* Initialize CB for SATA completion.
9919 */
9920 satIOContext->satCompleteCB = &satStartStopUnitCB;
9921
9922 /*
9923 * Prepare SGL and send FIS to LL layer.
9924 */
9925 satIOContext->reqType = agRequestType; /* Save it */
9926
9927 status = sataLLIOStart( tiRoot,
9928 tiIORequest,
9929 tiDeviceHandle,
9930 tiScsiRequest,
9931 satIOContext);
9932
9933
9934 TI_DBG5(("satStartStopUnit: return table48 case 1\n"));
9935 return (status);
9936 }
9937 /* case 2 */
9938 else if ( (scsiCmnd->cdb[4] & SCSI_START_MASK) && !(scsiCmnd->cdb[4] & SCSI_LOEJ_MASK) )
9939 {
9940 /* immed bit , SAT rev 8, 9.11.2.1 p 54*/
9941 if ( (scsiCmnd->cdb[1] & SCSI_IMMED_MASK) )
9942 {
9943 ostiInitiatorIOCompleted( tiRoot,
9944 tiIORequest,
9945 tiIOSuccess,
9946 SCSI_STAT_GOOD,
9947 agNULL,
9948 satIOContext->interruptContext );
9949
9950 TI_DBG5(("satStartStopUnit: return table48 case 2 1\n"));
9951 return tiSuccess;
9952 }
9953 /*
9954 sends READ_VERIFY_SECTORS(_EXT)
9955 sector count 1, any LBA between zero to Maximum
9956 */
9957 if (pSatDevData->sat48BitSupport == agTRUE)
9958 {
9959 /* READ VERIFY SECTOR(S) EXT*/
9960 fis->h.fisType = 0x27; /* Reg host to device */
9961 fis->h.c_pmPort = 0x80; /* C Bit is set */
9962
9963 fis->h.command = SAT_READ_VERIFY_SECTORS_EXT;/* 0x42 */
9964 fis->h.features = 0; /* FIS reserve */
9965 fis->d.lbaLow = 0x01; /* FIS LBA (7 :0 ) */
9966 fis->d.lbaMid = 0x00; /* FIS LBA (15:8 ) */
9967 fis->d.lbaHigh = 0x00; /* FIS LBA (23:16) */
9968 fis->d.lbaLowExp = 0x00; /* FIS LBA (31:24) */
9969 fis->d.lbaMidExp = 0x00; /* FIS LBA (39:32) */
9970 fis->d.lbaHighExp = 0x00; /* FIS LBA (47:40) */
9971 fis->d.featuresExp = 0; /* FIS reserve */
9972 fis->d.sectorCount = 1; /* FIS sector count (7:0) */
9973 fis->d.sectorCountExp = 0; /* FIS sector count (15:8) */
9974 fis->d.reserved4 = 0;
9975 fis->d.device = 0x40; /* 01000000 */
9976 fis->d.control = 0; /* FIS HOB bit clear */
9977 fis->d.reserved5 = 0;
9978
9979 }
9980 else
9981 {
9982 /* READ VERIFY SECTOR(S)*/
9983 fis->h.fisType = 0x27; /* Reg host to device */
9984 fis->h.c_pmPort = 0x80; /* C Bit is set */
9985
9986 fis->h.command = SAT_READ_VERIFY_SECTORS;/* 0x40 */
9987 fis->h.features = 0; /* FIS features NA */
9988 fis->d.lbaLow = 0x01; /* FIS LBA (7 :0 ) */
9989 fis->d.lbaMid = 0x00; /* FIS LBA (15:8 ) */
9990 fis->d.lbaHigh = 0x00; /* FIS LBA (23:16) */
9991 fis->d.lbaLowExp = 0;
9992 fis->d.lbaMidExp = 0;
9993 fis->d.lbaHighExp = 0;
9994 fis->d.featuresExp = 0;
9995 fis->d.sectorCount = 1; /* FIS sector count (7:0) */
9996 fis->d.sectorCountExp = 0;
9997 fis->d.reserved4 = 0;
9998 fis->d.device = 0x40; /* 01000000 */
9999 fis->d.control = 0; /* FIS HOB bit clear */
10000 fis->d.reserved5 = 0;
10001
10002 }
10003
10004 agRequestType = AGSA_SATA_PROTOCOL_NON_DATA;
10005
10006 /* Initialize CB for SATA completion.
10007 */
10008 satIOContext->satCompleteCB = &satStartStopUnitCB;
10009
10010 /*
10011 * Prepare SGL and send FIS to LL layer.
10012 */
10013 satIOContext->reqType = agRequestType; /* Save it */
10014
10015 status = sataLLIOStart( tiRoot,
10016 tiIORequest,
10017 tiDeviceHandle,
10018 tiScsiRequest,
10019 satIOContext);
10020
10021 TI_DBG5(("satStartStopUnit: return table48 case 2 2\n"));
10022 return status;
10023 }
10024 /* case 3 */
10025 else if ( !(scsiCmnd->cdb[4] & SCSI_START_MASK) && (scsiCmnd->cdb[4] & SCSI_LOEJ_MASK) )
10026 {
10027 if(pSatDevData->satRemovableMedia && pSatDevData->satRemovableMediaEnabled)
10028 {
10029 /* support for removal media */
10030 /* immed bit , SAT rev 8, 9.11.2.1 p 54*/
10031 if ( (scsiCmnd->cdb[1] & SCSI_IMMED_MASK) )
10032 {
10033 ostiInitiatorIOCompleted( tiRoot,
10034 tiIORequest,
10035 tiIOSuccess,
10036 SCSI_STAT_GOOD,
10037 agNULL,
10038 satIOContext->interruptContext );
10039
10040 TI_DBG5(("satStartStopUnit: return table48 case 3 1\n"));
10041 return tiSuccess;
10042 }
10043 /*
10044 sends MEDIA EJECT
10045 */
10046 /* Media Eject fis */
10047 fis->h.fisType = 0x27; /* Reg host to device */
10048 fis->h.c_pmPort = 0x80; /* C Bit is set */
10049
10050 fis->h.command = SAT_MEDIA_EJECT; /* 0xED */
10051 fis->h.features = 0; /* FIS features NA */
10052 fis->d.lbaLow = 0; /* FIS LBA (7 :0 ) */
10053 fis->d.lbaMid = 0; /* FIS LBA (15:8 ) */
10054 fis->d.lbaHigh = 0; /* FIS LBA (23:16) */
10055 fis->d.lbaLowExp = 0;
10056 fis->d.lbaMidExp = 0;
10057 fis->d.lbaHighExp = 0;
10058 fis->d.featuresExp = 0;
10059 /* sector count zero */
10060 fis->d.sectorCount = 0; /* FIS sector count (7:0) */
10061 fis->d.sectorCountExp = 0;
10062 fis->d.device = 0; /* FIS DEV is discared in SATA */
10063 fis->d.control = 0; /* FIS HOB bit clear */
10064 fis->d.reserved4 = 0;
10065 fis->d.reserved5 = 0;
10066
10067 agRequestType = AGSA_SATA_PROTOCOL_NON_DATA;
10068
10069 /* Initialize CB for SATA completion.
10070 */
10071 satIOContext->satCompleteCB = &satStartStopUnitCB;
10072
10073 /*
10074 * Prepare SGL and send FIS to LL layer.
10075 */
10076 satIOContext->reqType = agRequestType; /* Save it */
10077
10078 status = sataLLIOStart( tiRoot,
10079 tiIORequest,
10080 tiDeviceHandle,
10081 tiScsiRequest,
10082 satIOContext);
10083
10084 return status;
10085 }
10086 else
10087 {
10088 /* no support for removal media */
10089 satSetSensePayload( pSense,
10090 SCSI_SNSKEY_ILLEGAL_REQUEST,
10091 0,
10092 SCSI_SNSCODE_INVALID_FIELD_IN_CDB,
10093 satIOContext);
10094
10095 ostiInitiatorIOCompleted( tiRoot,
10096 tiIORequest,
10097 tiIOSuccess,
10098 SCSI_STAT_CHECK_CONDITION,
10099 satIOContext->pTiSenseData,
10100 satIOContext->interruptContext );
10101
10102 TI_DBG5(("satStartStopUnit: return Table 29 case 3 2\n"));
10103 return tiSuccess;
10104 }
10105
10106 }
10107 /* case 4 */
10108 else /* ( (scsiCmnd->cdb[4] & SCSI_START_MASK) && (scsiCmnd->cdb[4] & SCSI_LOEJ_MASK) ) */
10109 {
10110 satSetSensePayload( pSense,
10111 SCSI_SNSKEY_ILLEGAL_REQUEST,
10112 0,
10113 SCSI_SNSCODE_INVALID_FIELD_IN_CDB,
10114 satIOContext);
10115
10116 ostiInitiatorIOCompleted( tiRoot,
10117 tiIORequest,
10118 tiIOSuccess,
10119 SCSI_STAT_CHECK_CONDITION,
10120 satIOContext->pTiSenseData,
10121 satIOContext->interruptContext );
10122
10123 TI_DBG5(("satStartStopUnit: return Table 29 case 4\n"));
10124 return tiSuccess;
10125 }
10126
10127
10128 }
10129
10130
10131 /*****************************************************************************/
10132 /*! \brief SAT implementation for SCSI satStartStopUnit_1.
10133 *
10134 * SAT implementation for SCSI satStartStopUnit_1.
10135 * Sub function of satStartStopUnit
10136 *
10137 * \param tiRoot: Pointer to TISA initiator driver/port instance.
10138 * \param tiIORequest: Pointer to TISA I/O request context for this I/O.
10139 * \param tiDeviceHandle: Pointer to TISA device handle for this I/O.
10140 * \param tiScsiRequest: Pointer to TISA SCSI I/O request and SGL list.
10141 * \param satIOContext_t: Pointer to the SAT IO Context
10142 *
10143 * \return If command is started successfully
10144 * - \e tiSuccess: I/O request successfully initiated.
10145 * - \e tiBusy: No resources available, try again later.
10146 * - \e tiIONoDevice: Invalid device handle.
10147 * - \e tiError: Other errors.
10148 */
10149 /*****************************************************************************/
10150 GLOBAL bit32 satStartStopUnit_1(
10151 tiRoot_t *tiRoot,
10152 tiIORequest_t *tiIORequest,
10153 tiDeviceHandle_t *tiDeviceHandle,
10154 tiScsiInitiatorRequest_t *tiScsiRequest,
10155 satIOContext_t *satIOContext)
10156 {
10157 /*
10158 SAT Rev 8, Table 48, 9.11.3 p55
10159 sends STANDBY
10160 */
10161 bit32 status;
10162 bit32 agRequestType;
10163 agsaFisRegHostToDevice_t *fis;
10164
10165 TI_DBG5(("satStartStopUnit_1 entry: tiDeviceHandle=%p tiIORequest=%p\n",
10166 tiDeviceHandle, tiIORequest));
10167
10168 fis = satIOContext->pFis;
10169
10170 /* STANDBY */
10171 fis->h.fisType = 0x27; /* Reg host to device */
10172 fis->h.c_pmPort = 0x80; /* C Bit is set */
10173
10174 fis->h.command = SAT_STANDBY; /* 0xE2 */
10175 fis->h.features = 0; /* FIS features NA */
10176 fis->d.lbaLow = 0; /* FIS LBA (7 :0 ) */
10177 fis->d.lbaMid = 0; /* FIS LBA (15:8 ) */
10178 fis->d.lbaHigh = 0; /* FIS LBA (23:16) */
10179 fis->d.lbaLowExp = 0;
10180 fis->d.lbaMidExp = 0;
10181 fis->d.lbaHighExp = 0;
10182 fis->d.featuresExp = 0;
10183 fis->d.sectorCount = 0; /* FIS sector count (7:0) */
10184 fis->d.sectorCountExp = 0;
10185 fis->d.reserved4 = 0;
10186 fis->d.device = 0; /* 0 */
10187 fis->d.control = 0; /* FIS HOB bit clear */
10188 fis->d.reserved5 = 0;
10189
10190 agRequestType = AGSA_SATA_PROTOCOL_NON_DATA;
10191
10192 /* Initialize CB for SATA completion.
10193 */
10194 satIOContext->satCompleteCB = &satStartStopUnitCB;
10195
10196 /*
10197 * Prepare SGL and send FIS to LL layer.
10198 */
10199 satIOContext->reqType = agRequestType; /* Save it */
10200
10201 status = sataLLIOStart( tiRoot,
10202 tiIORequest,
10203 tiDeviceHandle,
10204 tiScsiRequest,
10205 satIOContext);
10206
10207 TI_DBG5(("satStartStopUnit_1 return status %d\n", status));
10208 return status;
10209 }
10210
10211 /*****************************************************************************/
10212 /*! \brief SAT implementation for SCSI satRead10_2.
10213 *
10214 * SAT implementation for SCSI satRead10_2
10215 * Sub function of satRead10
10216 *
10217 * \param tiRoot: Pointer to TISA initiator driver/port instance.
10218 * \param tiIORequest: Pointer to TISA I/O request context for this I/O.
10219 * \param tiDeviceHandle: Pointer to TISA device handle for this I/O.
10220 * \param tiScsiRequest: Pointer to TISA SCSI I/O request and SGL list.
10221 * \param satIOContext_t: Pointer to the SAT IO Context
10222 *
10223 * \return If command is started successfully
10224 * - \e tiSuccess: I/O request successfully initiated.
10225 * - \e tiBusy: No resources available, try again later.
10226 * - \e tiIONoDevice: Invalid device handle.
10227 * - \e tiError: Other errors.
10228 */
10229 /*****************************************************************************/
10230 GLOBAL bit32 satRead10_2(
10231 tiRoot_t *tiRoot,
10232 tiIORequest_t *tiIORequest,
10233 tiDeviceHandle_t *tiDeviceHandle,
10234 tiScsiInitiatorRequest_t *tiScsiRequest,
10235 satIOContext_t *satIOContext)
10236 {
10237 /*
10238 externally generated ATA cmd, there is corresponding scsi cmnd
10239 called by satStartStopUnit() or maybe satRead10()
10240 */
10241
10242 bit32 status;
10243 bit32 agRequestType;
10244 satDeviceData_t *pSatDevData;
10245 agsaFisRegHostToDevice_t *fis;
10246
10247 pSatDevData = satIOContext->pSatDevData;
10248 fis = satIOContext->pFis;
10249
10250 TI_DBG5(("satReadVerifySectorsNoChain: start\n"));
10251
10252 /* specifying ReadVerifySectors has no chain */
10253 pSatDevData->satVerifyState = 0xFFFFFFFF;
10254
10255 if (pSatDevData->sat48BitSupport == agTRUE)
10256 {
10257 /* READ VERIFY SECTOR(S) EXT*/
10258 fis->h.fisType = 0x27; /* Reg host to device */
10259 fis->h.c_pmPort = 0x80; /* C Bit is set */
10260 fis->h.command = SAT_READ_VERIFY_SECTORS_EXT;/* 0x42 */
10261 fis->h.features = 0; /* FIS reserve */
10262 fis->d.lbaLow = 0x7F; /* FIS LBA (7 :0 ) */
10263 fis->d.lbaMid = 0x4F; /* FIS LBA (15:8 ) */
10264 fis->d.lbaHigh = 0x00; /* FIS LBA (23:16) */
10265 fis->d.lbaLowExp = 0xF1; /* FIS LBA (31:24) */
10266 fis->d.lbaMidExp = 0x5F; /* FIS LBA (39:32) */
10267 fis->d.lbaHighExp = 0xFF; /* FIS LBA (47:40) */
10268 fis->d.featuresExp = 0; /* FIS reserve */
10269 fis->d.sectorCount = 1; /* FIS sector count (7:0) */
10270 fis->d.sectorCountExp = 0; /* FIS sector count (15:8) */
10271 fis->d.reserved4 = 0;
10272 fis->d.device = 0x4E; /* 01001110 */
10273 fis->d.control = 0; /* FIS HOB bit clear */
10274 fis->d.reserved5 = 0;
10275
10276 agRequestType = AGSA_SATA_PROTOCOL_NON_DATA;
10277 }
10278 else
10279 {
10280 /* READ VERIFY SECTOR(S)*/
10281 fis->h.fisType = 0x27; /* Reg host to device */
10282 fis->h.c_pmPort = 0x80; /* C Bit is set */
10283 fis->h.command = SAT_READ_VERIFY_SECTORS;/* 0x40 */
10284 fis->h.features = 0; /* FIS features NA */
10285 fis->d.lbaLow = 0x7F; /* FIS LBA (7 :0 ) */
10286 fis->d.lbaMid = 0x4F; /* FIS LBA (15:8 ) */
10287 fis->d.lbaHigh = 0x00; /* FIS LBA (23:16) */
10288 fis->d.lbaLowExp = 0;
10289 fis->d.lbaMidExp = 0;
10290 fis->d.lbaHighExp = 0;
10291 fis->d.featuresExp = 0;
10292 fis->d.sectorCount = 1; /* FIS sector count (7:0) */
10293 fis->d.sectorCountExp = 0;
10294 fis->d.reserved4 = 0;
10295 fis->d.device = 0x4E; /* 01001110 */
10296 fis->d.control = 0; /* FIS HOB bit clear */
10297 fis->d.reserved5 = 0;
10298
10299 agRequestType = AGSA_SATA_PROTOCOL_NON_DATA;
10300 }
10301
10302 /* Initialize CB for SATA completion.
10303 */
10304 satIOContext->satCompleteCB = &satNonDataIOCB;
10305
10306 /*
10307 * Prepare SGL and send FIS to LL layer.
10308 */
10309 satIOContext->reqType = agRequestType; /* Save it */
10310
10311 status = sataLLIOStart( tiRoot,
10312 tiIORequest,
10313 tiDeviceHandle,
10314 tiScsiRequest,
10315 satIOContext);
10316
10317 TI_DBG5(("satReadVerifySectorsNoChain: return last\n"));
10318
10319 return status;
10320 }
10321
10322
10323 /*****************************************************************************/
10324 /*! \brief SAT implementation for SCSI satWriteSame10.
10325 *
10326 * SAT implementation for SCSI satWriteSame10.
10327 *
10328 * \param tiRoot: Pointer to TISA initiator driver/port instance.
10329 * \param tiIORequest: Pointer to TISA I/O request context for this I/O.
10330 * \param tiDeviceHandle: Pointer to TISA device handle for this I/O.
10331 * \param tiScsiRequest: Pointer to TISA SCSI I/O request and SGL list.
10332 * \param satIOContext_t: Pointer to the SAT IO Context
10333 *
10334 * \return If command is started successfully
10335 * - \e tiSuccess: I/O request successfully initiated.
10336 * - \e tiBusy: No resources available, try again later.
10337 * - \e tiIONoDevice: Invalid device handle.
10338 * - \e tiError: Other errors.
10339 */
10340 /*****************************************************************************/
10341 GLOBAL bit32 satWriteSame10(
10342 tiRoot_t *tiRoot,
10343 tiIORequest_t *tiIORequest,
10344 tiDeviceHandle_t *tiDeviceHandle,
10345 tiScsiInitiatorRequest_t *tiScsiRequest,
10346 satIOContext_t *satIOContext)
10347 {
10348 bit32 status;
10349 bit32 agRequestType = AGSA_SATA_PROTOCOL_DMA_WRITE;
10350 satDeviceData_t *pSatDevData;
10351 scsiRspSense_t *pSense;
10352 tiIniScsiCmnd_t *scsiCmnd;
10353 agsaFisRegHostToDevice_t *fis;
10354 bit32 lba = 0;
10355 bit32 tl = 0;
10356
10357 pSense = satIOContext->pSense;
10358 pSatDevData = satIOContext->pSatDevData;
10359 scsiCmnd = &tiScsiRequest->scsiCmnd;
10360 fis = satIOContext->pFis;
10361
10362 TI_DBG5(("satWriteSame10: start\n"));
10363
10364 /* checking CONTROL */
10365 /* NACA == 1 or LINK == 1*/
10366 if ( (scsiCmnd->cdb[9] & SCSI_NACA_MASK) || (scsiCmnd->cdb[9] & SCSI_LINK_MASK) )
10367 {
10368 satSetSensePayload( pSense,
10369 SCSI_SNSKEY_ILLEGAL_REQUEST,
10370 0,
10371 SCSI_SNSCODE_INVALID_FIELD_IN_CDB,
10372 satIOContext);
10373
10374 ostiInitiatorIOCompleted( tiRoot,
10375 tiIORequest,
10376 tiIOSuccess,
10377 SCSI_STAT_CHECK_CONDITION,
10378 satIOContext->pTiSenseData,
10379 satIOContext->interruptContext );
10380
10381 TI_DBG1(("satWriteSame10: return control\n"));
10382 return tiSuccess;
10383 }
10384
10385
10386 /* checking LBDATA and PBDATA */
10387 /* case 1 */
10388 if ( !(scsiCmnd->cdb[1] & SCSI_WRITE_SAME_LBDATA_MASK) &&
10389 !(scsiCmnd->cdb[1] & SCSI_WRITE_SAME_PBDATA_MASK))
10390 {
10391 TI_DBG5(("satWriteSame10: case 1\n"));
10392 /* spec 9.26.2, Table 62, p64, case 1*/
10393 /*
10394 normal case
10395 just like write in 9.17.1
10396 */
10397
10398 if ( pSatDevData->sat48BitSupport != agTRUE )
10399 {
10400 /*
10401 writeSame10 but no support for 48 bit addressing
10402 -> problem in transfer length. Therefore, return check condition
10403 */
10404 satSetSensePayload( pSense,
10405 SCSI_SNSKEY_ILLEGAL_REQUEST,
10406 0,
10407 SCSI_SNSCODE_INVALID_FIELD_IN_CDB,
10408 satIOContext);
10409
10410 ostiInitiatorIOCompleted( tiRoot,
10411 tiIORequest,
10412 tiIOSuccess,
10413 SCSI_STAT_CHECK_CONDITION,
10414 satIOContext->pTiSenseData,
10415 satIOContext->interruptContext );
10416
10417 TI_DBG1(("satWriteSame10: return internal checking\n"));
10418 return tiSuccess;
10419 }
10420
10421 /* cdb10; computing LBA and transfer length */
10422 lba = (scsiCmnd->cdb[2] << (8*3)) + (scsiCmnd->cdb[3] << (8*2))
10423 + (scsiCmnd->cdb[4] << 8) + scsiCmnd->cdb[5];
10424 tl = (scsiCmnd->cdb[7] << 8) + scsiCmnd->cdb[8];
10425
10426
10427 /* Table 34, 9.1, p 46 */
10428 /*
10429 note: As of 2/10/2006, no support for DMA QUEUED
10430 */
10431
10432 /*
10433 Table 34, 9.1, p 46, b (footnote)
10434 When no 48-bit addressing support or NCQ, if LBA is beyond (2^28 - 1),
10435 return check condition
10436 */
10437 if (pSatDevData->satNCQ != agTRUE &&
10438 pSatDevData->sat48BitSupport != agTRUE
10439 )
10440 {
10441 if (lba > SAT_TR_LBA_LIMIT - 1) /* SAT_TR_LBA_LIMIT is 2^28, 0x10000000 */
10442 {
10443 satSetSensePayload( pSense,
10444 SCSI_SNSKEY_ILLEGAL_REQUEST,
10445 0,
10446 SCSI_SNSCODE_LOGICAL_BLOCK_ADDRESS_OUT_OF_RANGE,
10447 satIOContext);
10448
10449 ostiInitiatorIOCompleted( tiRoot,
10450 tiIORequest,
10451 tiIOSuccess,
10452 SCSI_STAT_CHECK_CONDITION,
10453 satIOContext->pTiSenseData,
10454 satIOContext->interruptContext );
10455
10456 TI_DBG1(("satWriteSame10: return LBA out of range\n"));
10457 return tiSuccess;
10458 }
10459 }
10460
10461 if (lba + tl <= SAT_TR_LBA_LIMIT)
10462 {
10463 if (pSatDevData->satDMASupport == agTRUE && pSatDevData->satDMAEnabled == agTRUE)
10464 {
10465 /* case 2 */
10466 /* WRITE DMA */
10467 /* can't fit the transfer length since WRITE DMA has 1 byte for sector count */
10468 TI_DBG5(("satWriteSame10: case 1-2 !!! error due to writeSame10\n"));
10469 satSetSensePayload( pSense,
10470 SCSI_SNSKEY_ILLEGAL_REQUEST,
10471 0,
10472 SCSI_SNSCODE_INVALID_FIELD_IN_CDB,
10473 satIOContext);
10474
10475 ostiInitiatorIOCompleted( tiRoot,
10476 tiIORequest,
10477 tiIOSuccess,
10478 SCSI_STAT_CHECK_CONDITION,
10479 satIOContext->pTiSenseData,
10480 satIOContext->interruptContext );
10481 return tiSuccess;
10482 }
10483 else
10484 {
10485 /* case 1 */
10486 /* WRITE MULTIPLE or WRITE SECTOR(S) */
10487 /* WRITE SECTORS is chosen for easier implemetation */
10488 /* can't fit the transfer length since WRITE DMA has 1 byte for sector count */
10489 TI_DBG5(("satWriteSame10: case 1-1 !!! error due to writesame10\n"));
10490 satSetSensePayload( pSense,
10491 SCSI_SNSKEY_ILLEGAL_REQUEST,
10492 0,
10493 SCSI_SNSCODE_INVALID_FIELD_IN_CDB,
10494 satIOContext);
10495
10496 ostiInitiatorIOCompleted( tiRoot,
10497 tiIORequest,
10498 tiIOSuccess,
10499 SCSI_STAT_CHECK_CONDITION,
10500 satIOContext->pTiSenseData,
10501 satIOContext->interruptContext );
10502 return tiSuccess;
10503 }
10504 } /* end of case 1 and 2 */
10505
10506 /* case 3 and 4 */
10507 if (pSatDevData->sat48BitSupport == agTRUE)
10508 {
10509 if (pSatDevData->satDMASupport == agTRUE && pSatDevData->satDMAEnabled == agTRUE)
10510 {
10511 /* case 3 */
10512 /* WRITE DMA EXT or WRITE DMA FUA EXT */
10513 /* WRITE DMA EXT is chosen since WRITE SAME does not have FUA bit */
10514 TI_DBG5(("satWriteSame10: case 1-3\n"));
10515 fis->h.fisType = 0x27; /* Reg host to device */
10516 fis->h.c_pmPort = 0x80; /* C Bit is set */
10517
10518 fis->h.command = SAT_WRITE_DMA_EXT; /* 0x35 */
10519
10520 fis->h.features = 0; /* FIS reserve */
10521 fis->d.lbaLow = scsiCmnd->cdb[5]; /* FIS LBA (7 :0 ) */
10522 fis->d.lbaMid = scsiCmnd->cdb[4]; /* FIS LBA (15:8 ) */
10523 fis->d.lbaHigh = scsiCmnd->cdb[3]; /* FIS LBA (23:16) */
10524 fis->d.device = 0x40; /* FIS LBA mode set */
10525 fis->d.lbaLowExp = scsiCmnd->cdb[2]; /* FIS LBA (31:24) */
10526 fis->d.lbaMidExp = 0; /* FIS LBA (39:32) */
10527 fis->d.lbaHighExp = 0; /* FIS LBA (47:40) */
10528 fis->d.featuresExp = 0; /* FIS reserve */
10529 if (tl == 0)
10530 {
10531 /* error check
10532 ATA spec, p125, 6.17.29
10533 pSatDevData->satMaxUserAddrSectors should be 0x0FFFFFFF
10534 and allowed value is 0x0FFFFFFF - 1
10535 */
10536 if (pSatDevData->satMaxUserAddrSectors > 0x0FFFFFFF)
10537 {
10538 TI_DBG5(("satWriteSame10: case 3 !!! warning can't fit sectors\n"));
10539 satSetSensePayload( pSense,
10540 SCSI_SNSKEY_ILLEGAL_REQUEST,
10541 0,
10542 SCSI_SNSCODE_INVALID_FIELD_IN_CDB,
10543 satIOContext);
10544
10545 ostiInitiatorIOCompleted( tiRoot,
10546 tiIORequest,
10547 tiIOSuccess,
10548 SCSI_STAT_CHECK_CONDITION,
10549 satIOContext->pTiSenseData,
10550 satIOContext->interruptContext );
10551 return tiSuccess;
10552 }
10553 }
10554 /* one sector at a time */
10555 fis->d.sectorCount = 1; /* FIS sector count (7:0) */
10556 fis->d.sectorCountExp = 0; /* FIS sector count (15:8) */
10557 fis->d.reserved4 = 0;
10558 fis->d.control = 0; /* FIS HOB bit clear */
10559 fis->d.reserved5 = 0;
10560
10561 agRequestType = AGSA_SATA_PROTOCOL_DMA_WRITE;
10562 }
10563 else
10564 {
10565 /* case 4 */
10566 /* WRITE MULTIPLE EXT or WRITE MULTIPLE FUA EXT or WRITE SECTOR(S) EXT */
10567 /* WRITE SECTORS EXT is chosen for easier implemetation */
10568 TI_DBG5(("satWriteSame10: case 1-4\n"));
10569 fis->h.fisType = 0x27; /* Reg host to device */
10570 fis->h.c_pmPort = 0x80; /* C Bit is set */
10571
10572 fis->h.command = SAT_WRITE_SECTORS_EXT; /* 0x34 */
10573 fis->h.features = 0; /* FIS reserve */
10574 fis->d.lbaLow = scsiCmnd->cdb[5]; /* FIS LBA (7 :0 ) */
10575 fis->d.lbaMid = scsiCmnd->cdb[4]; /* FIS LBA (15:8 ) */
10576 fis->d.lbaHigh = scsiCmnd->cdb[3]; /* FIS LBA (23:16) */
10577 fis->d.device = 0x40; /* FIS LBA mode set */
10578 fis->d.lbaLowExp = scsiCmnd->cdb[2]; /* FIS LBA (31:24) */
10579 fis->d.lbaMidExp = 0; /* FIS LBA (39:32) */
10580 fis->d.lbaHighExp = 0; /* FIS LBA (47:40) */
10581 fis->d.featuresExp = 0; /* FIS reserve */
10582 if (tl == 0)
10583 {
10584 /* error check
10585 ATA spec, p125, 6.17.29
10586 pSatDevData->satMaxUserAddrSectors should be 0x0FFFFFFF
10587 and allowed value is 0x0FFFFFFF - 1
10588 */
10589 if (pSatDevData->satMaxUserAddrSectors > 0x0FFFFFFF)
10590 {
10591 TI_DBG5(("satWriteSame10: case 4 !!! warning can't fit sectors\n"));
10592 satSetSensePayload( pSense,
10593 SCSI_SNSKEY_ILLEGAL_REQUEST,
10594 0,
10595 SCSI_SNSCODE_INVALID_FIELD_IN_CDB,
10596 satIOContext);
10597
10598 ostiInitiatorIOCompleted( tiRoot,
10599 tiIORequest,
10600 tiIOSuccess,
10601 SCSI_STAT_CHECK_CONDITION,
10602 satIOContext->pTiSenseData,
10603 satIOContext->interruptContext );
10604 return tiSuccess;
10605 }
10606 }
10607 /* one sector at a time */
10608 fis->d.sectorCount = 1; /* FIS sector count (7:0) */
10609 fis->d.sectorCountExp = 0; /* FIS sector count (15:8) */
10610 fis->d.reserved4 = 0;
10611 fis->d.control = 0; /* FIS HOB bit clear */
10612 fis->d.reserved5 = 0;
10613
10614 agRequestType = AGSA_SATA_PROTOCOL_PIO_WRITE;
10615 }
10616 }
10617
10618 /* case 5 */
10619 if (pSatDevData->satNCQ == agTRUE)
10620 {
10621 /* WRITE FPDMA QUEUED */
10622 if (pSatDevData->sat48BitSupport != agTRUE)
10623 {
10624 TI_DBG5(("satWriteSame10: case 1-5 !!! error NCQ but 28 bit address support \n"));
10625 satSetSensePayload( pSense,
10626 SCSI_SNSKEY_ILLEGAL_REQUEST,
10627 0,
10628 SCSI_SNSCODE_INVALID_FIELD_IN_CDB,
10629 satIOContext);
10630
10631 ostiInitiatorIOCompleted( tiRoot,
10632 tiIORequest,
10633 tiIOSuccess,
10634 SCSI_STAT_CHECK_CONDITION,
10635 satIOContext->pTiSenseData,
10636 satIOContext->interruptContext );
10637 return tiSuccess;
10638 }
10639 TI_DBG5(("satWriteSame10: case 1-5\n"));
10640
10641 /* Support 48-bit FPDMA addressing, use WRITE FPDMA QUEUE command */
10642
10643 fis->h.fisType = 0x27; /* Reg host to device */
10644 fis->h.c_pmPort = 0x80; /* C Bit is set */
10645 fis->h.command = SAT_WRITE_FPDMA_QUEUED; /* 0x61 */
10646
10647 if (tl == 0)
10648 {
10649 /* error check
10650 ATA spec, p125, 6.17.29
10651 pSatDevData->satMaxUserAddrSectors should be 0x0FFFFFFF
10652 and allowed value is 0x0FFFFFFF - 1
10653 */
10654 if (pSatDevData->satMaxUserAddrSectors > 0x0FFFFFFF)
10655 {
10656 TI_DBG5(("satWriteSame10: case 4 !!! warning can't fit sectors\n"));
10657 satSetSensePayload( pSense,
10658 SCSI_SNSKEY_ILLEGAL_REQUEST,
10659 0,
10660 SCSI_SNSCODE_INVALID_FIELD_IN_CDB,
10661 satIOContext);
10662
10663 ostiInitiatorIOCompleted( tiRoot,
10664 tiIORequest,
10665 tiIOSuccess,
10666 SCSI_STAT_CHECK_CONDITION,
10667 satIOContext->pTiSenseData,
10668 satIOContext->interruptContext );
10669 return tiSuccess;
10670 }
10671 }
10672 /* one sector at a time */
10673 fis->h.features = 1; /* FIS sector count (7:0) */
10674 fis->d.featuresExp = 0; /* FIS sector count (15:8) */
10675
10676
10677 fis->d.lbaLow = scsiCmnd->cdb[5]; /* FIS LBA (7 :0 ) */
10678 fis->d.lbaMid = scsiCmnd->cdb[4]; /* FIS LBA (15:8 ) */
10679 fis->d.lbaHigh = scsiCmnd->cdb[3]; /* FIS LBA (23:16) */
10680
10681 /* NO FUA bit in the WRITE SAME 10 */
10682 fis->d.device = 0x40; /* FIS FUA clear */
10683
10684 fis->d.lbaLowExp = scsiCmnd->cdb[2]; /* FIS LBA (31:24) */
10685 fis->d.lbaMidExp = 0; /* FIS LBA (39:32) */
10686 fis->d.lbaHighExp = 0; /* FIS LBA (47:40) */
10687 fis->d.sectorCount = 0; /* Tag (7:3) set by LL layer */
10688 fis->d.sectorCountExp = 0;
10689 fis->d.reserved4 = 0;
10690 fis->d.control = 0; /* FIS HOB bit clear */
10691 fis->d.reserved5 = 0;
10692
10693 agRequestType = AGSA_SATA_PROTOCOL_FPDMA_WRITE;
10694 }
10695 /* Initialize CB for SATA completion.
10696 */
10697 satIOContext->satCompleteCB = &satWriteSame10CB;
10698
10699 /*
10700 * Prepare SGL and send FIS to LL layer.
10701 */
10702 satIOContext->reqType = agRequestType; /* Save it */
10703
10704 status = sataLLIOStart( tiRoot,
10705 tiIORequest,
10706 tiDeviceHandle,
10707 tiScsiRequest,
10708 satIOContext);
10709 return (status);
10710
10711
10712 } /* end of case 1 */
10713 else if ( !(scsiCmnd->cdb[1] & SCSI_WRITE_SAME_LBDATA_MASK) &&
10714 (scsiCmnd->cdb[1] & SCSI_WRITE_SAME_PBDATA_MASK))
10715 {
10716 /* spec 9.26.2, Table 62, p64, case 2*/
10717 satSetSensePayload( pSense,
10718 SCSI_SNSKEY_ILLEGAL_REQUEST,
10719 0,
10720 SCSI_SNSCODE_INVALID_FIELD_IN_CDB,
10721 satIOContext);
10722
10723 ostiInitiatorIOCompleted( tiRoot,
10724 tiIORequest,
10725 tiIOSuccess,
10726 SCSI_STAT_CHECK_CONDITION,
10727 satIOContext->pTiSenseData,
10728 satIOContext->interruptContext );
10729
10730 TI_DBG5(("satWriteSame10: return Table 62 case 2\n"));
10731 return tiSuccess;
10732 }
10733 else if ( (scsiCmnd->cdb[1] & SCSI_WRITE_SAME_LBDATA_MASK) &&
10734 !(scsiCmnd->cdb[1] & SCSI_WRITE_SAME_PBDATA_MASK))
10735 {
10736 TI_DBG5(("satWriteSame10: Table 62 case 3\n"));
10737
10738 }
10739 else /* ( (scsiCmnd->cdb[1] & SCSI_WRITE_SAME_LBDATA_MASK) &&
10740 (scsiCmnd->cdb[1] & SCSI_WRITE_SAME_PBDATA_MASK)) */
10741 {
10742
10743 /* spec 9.26.2, Table 62, p64, case 4*/
10744 satSetSensePayload( pSense,
10745 SCSI_SNSKEY_ILLEGAL_REQUEST,
10746 0,
10747 SCSI_SNSCODE_INVALID_FIELD_IN_CDB,
10748 satIOContext);
10749
10750 ostiInitiatorIOCompleted( tiRoot,
10751 tiIORequest,
10752 tiIOSuccess,
10753 SCSI_STAT_CHECK_CONDITION,
10754 satIOContext->pTiSenseData,
10755 satIOContext->interruptContext );
10756
10757 TI_DBG5(("satWriteSame10: return Table 62 case 4\n"));
10758 return tiSuccess;
10759 }
10760
10761
10762 return tiSuccess;
10763 }
10764
10765 /*****************************************************************************/
10766 /*! \brief SAT implementation for SCSI satWriteSame10_1.
10767 *
10768 * SAT implementation for SCSI WRITESANE10 and send FIS request to LL layer.
10769 * This is used when WRITESAME10 is divided into multiple ATA commands
10770 *
10771 * \param tiRoot: Pointer to TISA initiator driver/port instance.
10772 * \param tiIORequest: Pointer to TISA I/O request context for this I/O.
10773 * \param tiDeviceHandle: Pointer to TISA device handle for this I/O.
10774 * \param tiScsiRequest: Pointer to TISA SCSI I/O request and SGL list.
10775 * \param satIOContext_t: Pointer to the SAT IO Context
10776 * \param lba: LBA
10777 *
10778 * \return If command is started successfully
10779 * - \e tiSuccess: I/O request successfully initiated.
10780 * - \e tiBusy: No resources available, try again later.
10781 * - \e tiIONoDevice: Invalid device handle.
10782 * - \e tiError: Other errors.
10783 */
10784 /*****************************************************************************/
10785 GLOBAL bit32 satWriteSame10_1(
10786 tiRoot_t *tiRoot,
10787 tiIORequest_t *tiIORequest,
10788 tiDeviceHandle_t *tiDeviceHandle,
10789 tiScsiInitiatorRequest_t *tiScsiRequest,
10790 satIOContext_t *satIOContext,
10791 bit32 lba
10792 )
10793 {
10794 /*
10795 sends SAT_WRITE_DMA_EXT
10796 */
10797
10798 bit32 status;
10799 bit32 agRequestType;
10800 agsaFisRegHostToDevice_t *fis;
10801 bit8 lba1, lba2 ,lba3, lba4;
10802
10803 TI_DBG5(("satWriteSame10_1 entry: tiDeviceHandle=%p tiIORequest=%p\n",
10804 tiDeviceHandle, tiIORequest));
10805
10806 fis = satIOContext->pFis;
10807
10808 /* MSB */
10809 lba1 = (bit8)((lba & 0xFF000000) >> (8*3));
10810 lba2 = (bit8)((lba & 0x00FF0000) >> (8*2));
10811 lba3 = (bit8)((lba & 0x0000FF00) >> (8*1));
10812 /* LSB */
10813 lba4 = (bit8)(lba & 0x000000FF);
10814
10815 /* SAT_WRITE_DMA_EXT */
10816 fis->h.fisType = 0x27; /* Reg host to device */
10817 fis->h.c_pmPort = 0x80; /* C Bit is set */
10818
10819 fis->h.command = SAT_WRITE_DMA_EXT; /* 0x35 */
10820
10821 fis->h.features = 0; /* FIS reserve */
10822 fis->d.lbaLow = lba4; /* FIS LBA (7 :0 ) */
10823 fis->d.lbaMid = lba3; /* FIS LBA (15:8 ) */
10824 fis->d.lbaHigh = lba2; /* FIS LBA (23:16) */
10825 fis->d.device = 0x40; /* FIS LBA mode set */
10826 fis->d.lbaLowExp = lba1; /* FIS LBA (31:24) */
10827 fis->d.lbaMidExp = 0; /* FIS LBA (39:32) */
10828 fis->d.lbaHighExp = 0; /* FIS LBA (47:40) */
10829 fis->d.featuresExp = 0; /* FIS reserve */
10830 /* one sector at a time */
10831 fis->d.sectorCount = 1; /* FIS sector count (7:0) */
10832 fis->d.sectorCountExp = 0; /* FIS sector count (15:8) */
10833
10834 fis->d.reserved4 = 0;
10835 fis->d.control = 0; /* FIS HOB bit clear */
10836 fis->d.reserved5 = 0;
10837
10838
10839 agRequestType = AGSA_SATA_PROTOCOL_DMA_WRITE;
10840
10841 /* Initialize CB for SATA completion.
10842 */
10843 satIOContext->satCompleteCB = &satWriteSame10CB;
10844
10845 /*
10846 * Prepare SGL and send FIS to LL layer.
10847 */
10848 satIOContext->reqType = agRequestType; /* Save it */
10849
10850 status = sataLLIOStart( tiRoot,
10851 tiIORequest,
10852 tiDeviceHandle,
10853 tiScsiRequest,
10854 satIOContext);
10855
10856 TI_DBG5(("satWriteSame10_1 return status %d\n", status));
10857 return status;
10858 }
10859
10860 /*****************************************************************************/
10861 /*! \brief SAT implementation for SCSI satWriteSame10_2.
10862 *
10863 * SAT implementation for SCSI WRITESANE10 and send FIS request to LL layer.
10864 * This is used when WRITESAME10 is divided into multiple ATA commands
10865 *
10866 * \param tiRoot: Pointer to TISA initiator driver/port instance.
10867 * \param tiIORequest: Pointer to TISA I/O request context for this I/O.
10868 * \param tiDeviceHandle: Pointer to TISA device handle for this I/O.
10869 * \param tiScsiRequest: Pointer to TISA SCSI I/O request and SGL list.
10870 * \param satIOContext_t: Pointer to the SAT IO Context
10871 * \param lba: LBA
10872 *
10873 * \return If command is started successfully
10874 * - \e tiSuccess: I/O request successfully initiated.
10875 * - \e tiBusy: No resources available, try again later.
10876 * - \e tiIONoDevice: Invalid device handle.
10877 * - \e tiError: Other errors.
10878 */
10879 /*****************************************************************************/
10880 GLOBAL bit32 satWriteSame10_2(
10881 tiRoot_t *tiRoot,
10882 tiIORequest_t *tiIORequest,
10883 tiDeviceHandle_t *tiDeviceHandle,
10884 tiScsiInitiatorRequest_t *tiScsiRequest,
10885 satIOContext_t *satIOContext,
10886 bit32 lba
10887 )
10888 {
10889 /*
10890 sends SAT_WRITE_SECTORS_EXT
10891 */
10892
10893 bit32 status;
10894 bit32 agRequestType;
10895 agsaFisRegHostToDevice_t *fis;
10896 bit8 lba1, lba2 ,lba3, lba4;
10897
10898 TI_DBG5(("satWriteSame10_2 entry: tiDeviceHandle=%p tiIORequest=%p\n",
10899 tiDeviceHandle, tiIORequest));
10900
10901 fis = satIOContext->pFis;
10902
10903 /* MSB */
10904 lba1 = (bit8)((lba & 0xFF000000) >> (8*3));
10905 lba2 = (bit8)((lba & 0x00FF0000) >> (8*2));
10906 lba3 = (bit8)((lba & 0x0000FF00) >> (8*1));
10907 /* LSB */
10908 lba4 = (bit8)(lba & 0x000000FF);
10909
10910
10911 /* SAT_WRITE_SECTORS_EXT */
10912 fis->h.fisType = 0x27; /* Reg host to device */
10913 fis->h.c_pmPort = 0x80; /* C Bit is set */
10914
10915 fis->h.command = SAT_WRITE_SECTORS_EXT; /* 0x34 */
10916 fis->h.features = 0; /* FIS reserve */
10917 fis->d.lbaLow = lba4; /* FIS LBA (7 :0 ) */
10918 fis->d.lbaMid = lba3; /* FIS LBA (15:8 ) */
10919 fis->d.lbaHigh = lba2; /* FIS LBA (23:16) */
10920 fis->d.device = 0x40; /* FIS LBA mode set */
10921 fis->d.lbaLowExp = lba1; /* FIS LBA (31:24) */
10922 fis->d.lbaMidExp = 0; /* FIS LBA (39:32) */
10923 fis->d.lbaHighExp = 0; /* FIS LBA (47:40) */
10924 fis->d.featuresExp = 0; /* FIS reserve */
10925 /* one sector at a time */
10926 fis->d.sectorCount = 1; /* FIS sector count (7:0) */
10927 fis->d.sectorCountExp = 0; /* FIS sector count (15:8) */
10928
10929 fis->d.reserved4 = 0;
10930 fis->d.control = 0; /* FIS HOB bit clear */
10931 fis->d.reserved5 = 0;
10932
10933
10934 agRequestType = AGSA_SATA_PROTOCOL_PIO_WRITE;
10935
10936 /* Initialize CB for SATA completion.
10937 */
10938 satIOContext->satCompleteCB = &satWriteSame10CB;
10939
10940 /*
10941 * Prepare SGL and send FIS to LL layer.
10942 */
10943 satIOContext->reqType = agRequestType; /* Save it */
10944
10945 status = sataLLIOStart( tiRoot,
10946 tiIORequest,
10947 tiDeviceHandle,
10948 tiScsiRequest,
10949 satIOContext);
10950
10951 TI_DBG5(("satWriteSame10_2 return status %d\n", status));
10952 return status;
10953 }
10954
10955 /*****************************************************************************/
10956 /*! \brief SAT implementation for SCSI satWriteSame10_3.
10957 *
10958 * SAT implementation for SCSI WRITESANE10 and send FIS request to LL layer.
10959 * This is used when WRITESAME10 is divided into multiple ATA commands
10960 *
10961 * \param tiRoot: Pointer to TISA initiator driver/port instance.
10962 * \param tiIORequest: Pointer to TISA I/O request context for this I/O.
10963 * \param tiDeviceHandle: Pointer to TISA device handle for this I/O.
10964 * \param tiScsiRequest: Pointer to TISA SCSI I/O request and SGL list.
10965 * \param satIOContext_t: Pointer to the SAT IO Context
10966 * \param lba: LBA
10967 *
10968 * \return If command is started successfully
10969 * - \e tiSuccess: I/O request successfully initiated.
10970 * - \e tiBusy: No resources available, try again later.
10971 * - \e tiIONoDevice: Invalid device handle.
10972 * - \e tiError: Other errors.
10973 */
10974 /*****************************************************************************/
10975 GLOBAL bit32 satWriteSame10_3(
10976 tiRoot_t *tiRoot,
10977 tiIORequest_t *tiIORequest,
10978 tiDeviceHandle_t *tiDeviceHandle,
10979 tiScsiInitiatorRequest_t *tiScsiRequest,
10980 satIOContext_t *satIOContext,
10981 bit32 lba
10982 )
10983 {
10984 /*
10985 sends SAT_WRITE_FPDMA_QUEUED
10986 */
10987
10988 bit32 status;
10989 bit32 agRequestType;
10990 agsaFisRegHostToDevice_t *fis;
10991 bit8 lba1, lba2 ,lba3, lba4;
10992
10993 TI_DBG5(("satWriteSame10_3 entry: tiDeviceHandle=%p tiIORequest=%p\n",
10994 tiDeviceHandle, tiIORequest));
10995
10996 fis = satIOContext->pFis;
10997
10998 /* MSB */
10999 lba1 = (bit8)((lba & 0xFF000000) >> (8*3));
11000 lba2 = (bit8)((lba & 0x00FF0000) >> (8*2));
11001 lba3 = (bit8)((lba & 0x0000FF00) >> (8*1));
11002 /* LSB */
11003 lba4 = (bit8)(lba & 0x000000FF);
11004
11005 /* SAT_WRITE_FPDMA_QUEUED */
11006 fis->h.fisType = 0x27; /* Reg host to device */
11007 fis->h.c_pmPort = 0x80; /* C Bit is set */
11008 fis->h.command = SAT_WRITE_FPDMA_QUEUED; /* 0x61 */
11009
11010
11011 /* one sector at a time */
11012 fis->h.features = 1; /* FIS sector count (7:0) */
11013 fis->d.featuresExp = 0; /* FIS sector count (15:8) */
11014
11015
11016 fis->d.lbaLow = lba4; /* FIS LBA (7 :0 ) */
11017 fis->d.lbaMid = lba3; /* FIS LBA (15:8 ) */
11018 fis->d.lbaHigh = lba2; /* FIS LBA (23:16) */
11019
11020 /* NO FUA bit in the WRITE SAME 10 */
11021 fis->d.device = 0x40; /* FIS FUA clear */
11022
11023 fis->d.lbaLowExp = lba1; /* FIS LBA (31:24) */
11024 fis->d.lbaMidExp = 0; /* FIS LBA (39:32) */
11025 fis->d.lbaHighExp = 0; /* FIS LBA (47:40) */
11026 fis->d.sectorCount = 0; /* Tag (7:3) set by LL layer */
11027 fis->d.sectorCountExp = 0;
11028 fis->d.reserved4 = 0;
11029 fis->d.control = 0; /* FIS HOB bit clear */
11030 fis->d.reserved5 = 0;
11031
11032 agRequestType = AGSA_SATA_PROTOCOL_FPDMA_WRITE;
11033
11034 /* Initialize CB for SATA completion.
11035 */
11036 satIOContext->satCompleteCB = &satWriteSame10CB;
11037
11038 /*
11039 * Prepare SGL and send FIS to LL layer.
11040 */
11041 satIOContext->reqType = agRequestType; /* Save it */
11042
11043 status = sataLLIOStart( tiRoot,
11044 tiIORequest,
11045 tiDeviceHandle,
11046 tiScsiRequest,
11047 satIOContext);
11048
11049 TI_DBG5(("satWriteSame10_2 return status %d\n", status));
11050 return status;
11051 }
11052 /*****************************************************************************/
11053 /*! \brief SAT implementation for SCSI satWriteSame16.
11054 *
11055 * SAT implementation for SCSI satWriteSame16.
11056 *
11057 * \param tiRoot: Pointer to TISA initiator driver/port instance.
11058 * \param tiIORequest: Pointer to TISA I/O request context for this I/O.
11059 * \param tiDeviceHandle: Pointer to TISA device handle for this I/O.
11060 * \param tiScsiRequest: Pointer to TISA SCSI I/O request and SGL list.
11061 * \param satIOContext_t: Pointer to the SAT IO Context
11062 *
11063 * \return If command is started successfully
11064 * - \e tiSuccess: I/O request successfully initiated.
11065 * - \e tiBusy: No resources available, try again later.
11066 * - \e tiIONoDevice: Invalid device handle.
11067 * - \e tiError: Other errors.
11068 */
11069 /*****************************************************************************/
11070 GLOBAL bit32 satWriteSame16(
11071 tiRoot_t *tiRoot,
11072 tiIORequest_t *tiIORequest,
11073 tiDeviceHandle_t *tiDeviceHandle,
11074 tiScsiInitiatorRequest_t *tiScsiRequest,
11075 satIOContext_t *satIOContext)
11076 {
11077 scsiRspSense_t *pSense;
11078
11079 pSense = satIOContext->pSense;
11080
11081 TI_DBG5(("satWriteSame16:start\n"));
11082
11083
11084 satSetSensePayload( pSense,
11085 SCSI_SNSKEY_NO_SENSE,
11086 0,
11087 SCSI_SNSCODE_NO_ADDITIONAL_INFO,
11088 satIOContext);
11089
11090 ostiInitiatorIOCompleted( tiRoot,
11091 tiIORequest, /* == &satIntIo->satOrgTiIORequest */
11092 tiIOSuccess,
11093 SCSI_STAT_CHECK_CONDITION,
11094 satIOContext->pTiSenseData,
11095 satIOContext->interruptContext );
11096 TI_DBG5(("satWriteSame16: return internal checking\n"));
11097 return tiSuccess;
11098 }
11099
11100 /*****************************************************************************/
11101 /*! \brief SAT implementation for SCSI satLogSense_1.
11102 *
11103 * Part of SAT implementation for SCSI satLogSense.
11104 *
11105 * \param tiRoot: Pointer to TISA initiator driver/port instance.
11106 * \param tiIORequest: Pointer to TISA I/O request context for this I/O.
11107 * \param tiDeviceHandle: Pointer to TISA device handle for this I/O.
11108 * \param tiScsiRequest: Pointer to TISA SCSI I/O request and SGL list.
11109 * \param satIOContext_t: Pointer to the SAT IO Context
11110 *
11111 * \return If command is started successfully
11112 * - \e tiSuccess: I/O request successfully initiated.
11113 * - \e tiBusy: No resources available, try again later.
11114 * - \e tiIONoDevice: Invalid device handle.
11115 * - \e tiError: Other errors.
11116 */
11117 /*****************************************************************************/
11118 GLOBAL bit32 satLogSense_1(
11119 tiRoot_t *tiRoot,
11120 tiIORequest_t *tiIORequest,
11121 tiDeviceHandle_t *tiDeviceHandle,
11122 tiScsiInitiatorRequest_t *tiScsiRequest,
11123 satIOContext_t *satIOContext)
11124 {
11125 bit32 status;
11126 bit32 agRequestType;
11127 satDeviceData_t *pSatDevData;
11128 agsaFisRegHostToDevice_t *fis;
11129
11130 pSatDevData = satIOContext->pSatDevData;
11131 fis = satIOContext->pFis;
11132
11133 TI_DBG5(("satLogSense_1: start\n"));
11134
11135
11136 /* SAT Rev 8, 10.2.4 p74 */
11137 if ( pSatDevData->sat48BitSupport == agTRUE )
11138 {
11139 TI_DBG5(("satLogSense_1: case 2-1 sends READ LOG EXT\n"));
11140 /* sends READ LOG EXT */
11141 fis->h.fisType = 0x27; /* Reg host to device */
11142 fis->h.c_pmPort = 0x80; /* C Bit is set */
11143
11144 fis->h.command = SAT_READ_LOG_EXT; /* 0x2F */
11145 fis->h.features = 0; /* FIS reserve */
11146 fis->d.lbaLow = 0x07; /* 0x07 */
11147 fis->d.lbaMid = 0; /* */
11148 fis->d.lbaHigh = 0; /* */
11149 fis->d.device = 0; /* */
11150 fis->d.lbaLowExp = 0; /* */
11151 fis->d.lbaMidExp = 0; /* */
11152 fis->d.lbaHighExp = 0; /* */
11153 fis->d.featuresExp = 0; /* FIS reserve */
11154 fis->d.sectorCount = 0x01; /* 1 sector counts */
11155 fis->d.sectorCountExp = 0x00; /* 1 sector counts */
11156 fis->d.reserved4 = 0;
11157 fis->d.control = 0; /* FIS HOB bit clear */
11158 fis->d.reserved5 = 0;
11159
11160 agRequestType = AGSA_SATA_PROTOCOL_PIO_READ;
11161
11162 /* Initialize CB for SATA completion.
11163 */
11164 satIOContext->satCompleteCB = &satLogSenseCB;
11165
11166 /*
11167 * Prepare SGL and send FIS to LL layer.
11168 */
11169 satIOContext->reqType = agRequestType; /* Save it */
11170
11171 status = sataLLIOStart( tiRoot,
11172 tiIORequest,
11173 tiDeviceHandle,
11174 tiScsiRequest,
11175 satIOContext);
11176 return status;
11177
11178 }
11179 else
11180 {
11181 TI_DBG5(("satLogSense_1: case 2-2 sends SMART READ LOG\n"));
11182 /* sends SMART READ LOG */
11183 fis->h.fisType = 0x27; /* Reg host to device */
11184 fis->h.c_pmPort = 0x80; /* C Bit is set */
11185
11186 fis->h.command = SAT_SMART_READ_LOG; /* 0x2F */
11187 fis->h.features = 0x00; /* 0xd5 */
11188 fis->d.lbaLow = 0x06; /* 0x06 */
11189 fis->d.lbaMid = 0x00; /* 0x4f */
11190 fis->d.lbaHigh = 0x00; /* 0xc2 */
11191 fis->d.device = 0; /* */
11192 fis->d.lbaLowExp = 0; /* */
11193 fis->d.lbaMidExp = 0; /* */
11194 fis->d.lbaHighExp = 0; /* */
11195 fis->d.featuresExp = 0; /* FIS reserve */
11196 fis->d.sectorCount = 0x01; /* */
11197 fis->d.sectorCountExp = 0x00; /* */
11198 fis->d.reserved4 = 0;
11199 fis->d.control = 0; /* FIS HOB bit clear */
11200 fis->d.reserved5 = 0;
11201
11202 agRequestType = AGSA_SATA_PROTOCOL_PIO_READ;
11203
11204 /* Initialize CB for SATA completion.
11205 */
11206 satIOContext->satCompleteCB = &satLogSenseCB;
11207
11208 /*
11209 * Prepare SGL and send FIS to LL layer.
11210 */
11211 satIOContext->reqType = agRequestType; /* Save it */
11212
11213 status = sataLLIOStart( tiRoot,
11214 tiIORequest,
11215 tiDeviceHandle,
11216 tiScsiRequest,
11217 satIOContext);
11218 return status;
11219
11220 }
11221 }
11222
11223 /*****************************************************************************/
11224 /*! \brief SAT implementation for SCSI satSMARTEnable.
11225 *
11226 * Part of SAT implementation for SCSI satLogSense.
11227 *
11228 * \param tiRoot: Pointer to TISA initiator driver/port instance.
11229 * \param tiIORequest: Pointer to TISA I/O request context for this I/O.
11230 * \param tiDeviceHandle: Pointer to TISA device handle for this I/O.
11231 * \param tiScsiRequest: Pointer to TISA SCSI I/O request and SGL list.
11232 * \param satIOContext_t: Pointer to the SAT IO Context
11233 *
11234 * \return If command is started successfully
11235 * - \e tiSuccess: I/O request successfully initiated.
11236 * - \e tiBusy: No resources available, try again later.
11237 * - \e tiIONoDevice: Invalid device handle.
11238 * - \e tiError: Other errors.
11239 */
11240 /*****************************************************************************/
11241 GLOBAL bit32 satSMARTEnable(
11242 tiRoot_t *tiRoot,
11243 tiIORequest_t *tiIORequest,
11244 tiDeviceHandle_t *tiDeviceHandle,
11245 tiScsiInitiatorRequest_t *tiScsiRequest,
11246 satIOContext_t *satIOContext)
11247 {
11248 bit32 status;
11249 bit32 agRequestType;
11250 agsaFisRegHostToDevice_t *fis;
11251
11252 TI_DBG4(("satSMARTEnable entry: tiDeviceHandle=%p tiIORequest=%p\n",
11253 tiDeviceHandle, tiIORequest));
11254
11255 fis = satIOContext->pFis;
11256
11257 /*
11258 * Send the SAT_SMART_ENABLE_OPERATIONS command.
11259 */
11260 fis->h.fisType = 0x27; /* Reg host to device */
11261 fis->h.c_pmPort = 0x80; /* C Bit is set */
11262
11263 fis->h.command = SAT_SMART_ENABLE_OPERATIONS; /* 0xB0 */
11264 fis->h.features = 0xD8;
11265 fis->d.lbaLow = 0;
11266 fis->d.lbaMid = 0x4F;
11267 fis->d.lbaHigh = 0xC2;
11268 fis->d.device = 0;
11269 fis->d.lbaLowExp = 0;
11270 fis->d.lbaMidExp = 0;
11271 fis->d.lbaHighExp = 0;
11272 fis->d.featuresExp = 0;
11273 fis->d.sectorCount = 0;
11274 fis->d.sectorCountExp = 0;
11275 fis->d.reserved4 = 0;
11276 fis->d.control = 0; /* FIS HOB bit clear */
11277 fis->d.reserved5 = 0;
11278
11279 agRequestType = AGSA_SATA_PROTOCOL_NON_DATA;
11280
11281 /* Initialize CB for SATA completion.
11282 */
11283 satIOContext->satCompleteCB = &satSMARTEnableCB;
11284
11285 /*
11286 * Prepare SGL and send FIS to LL layer.
11287 */
11288 satIOContext->reqType = agRequestType; /* Save it */
11289
11290 status = sataLLIOStart( tiRoot,
11291 tiIORequest,
11292 tiDeviceHandle,
11293 tiScsiRequest,
11294 satIOContext);
11295
11296
11297 return status;
11298 }
11299
11300 /*****************************************************************************/
11301 /*! \brief SAT implementation for SCSI satLogSense_3.
11302 *
11303 * Part of SAT implementation for SCSI satLogSense.
11304 *
11305 * \param tiRoot: Pointer to TISA initiator driver/port instance.
11306 * \param tiIORequest: Pointer to TISA I/O request context for this I/O.
11307 * \param tiDeviceHandle: Pointer to TISA device handle for this I/O.
11308 * \param tiScsiRequest: Pointer to TISA SCSI I/O request and SGL list.
11309 * \param satIOContext_t: Pointer to the SAT IO Context
11310 *
11311 * \return If command is started successfully
11312 * - \e tiSuccess: I/O request successfully initiated.
11313 * - \e tiBusy: No resources available, try again later.
11314 * - \e tiIONoDevice: Invalid device handle.
11315 * - \e tiError: Other errors.
11316 */
11317 /*****************************************************************************/
11318 GLOBAL bit32 satLogSense_3(
11319 tiRoot_t *tiRoot,
11320 tiIORequest_t *tiIORequest,
11321 tiDeviceHandle_t *tiDeviceHandle,
11322 tiScsiInitiatorRequest_t *tiScsiRequest,
11323 satIOContext_t *satIOContext)
11324 {
11325 bit32 status;
11326 bit32 agRequestType;
11327 agsaFisRegHostToDevice_t *fis;
11328
11329 TI_DBG4(("satLogSense_3 entry: tiDeviceHandle=%p tiIORequest=%p\n",
11330 tiDeviceHandle, tiIORequest));
11331
11332 fis = satIOContext->pFis;
11333 /* sends READ LOG EXT */
11334 fis->h.fisType = 0x27; /* Reg host to device */
11335 fis->h.c_pmPort = 0x80; /* C Bit is set */
11336
11337 fis->h.command = SAT_SMART_READ_LOG; /* 0x2F */
11338 fis->h.features = 0xD5; /* 0xd5 */
11339 fis->d.lbaLow = 0x06; /* 0x06 */
11340 fis->d.lbaMid = 0x4F; /* 0x4f */
11341 fis->d.lbaHigh = 0xC2; /* 0xc2 */
11342 fis->d.device = 0; /* */
11343 fis->d.lbaLowExp = 0; /* */
11344 fis->d.lbaMidExp = 0; /* */
11345 fis->d.lbaHighExp = 0; /* */
11346 fis->d.featuresExp = 0; /* FIS reserve */
11347 fis->d.sectorCount = 0x01; /* 1 sector counts */
11348 fis->d.sectorCountExp = 0x00; /* 1 sector counts */
11349 fis->d.reserved4 = 0;
11350 fis->d.control = 0; /* FIS HOB bit clear */
11351 fis->d.reserved5 = 0;
11352
11353 agRequestType = AGSA_SATA_PROTOCOL_PIO_READ;
11354
11355 /* Initialize CB for SATA completion.
11356 */
11357 satIOContext->satCompleteCB = &satLogSenseCB;
11358
11359 /*
11360 * Prepare SGL and send FIS to LL layer.
11361 */
11362 satIOContext->reqType = agRequestType; /* Save it */
11363
11364 status = sataLLIOStart( tiRoot,
11365 tiIORequest,
11366 tiDeviceHandle,
11367 tiScsiRequest,
11368 satIOContext);
11369 return status;
11370 }
11371
11372 /*****************************************************************************/
11373 /*! \brief SAT implementation for SCSI satLogSense_2.
11374 *
11375 * Part of SAT implementation for SCSI satLogSense.
11376 *
11377 * \param tiRoot: Pointer to TISA initiator driver/port instance.
11378 * \param tiIORequest: Pointer to TISA I/O request context for this I/O.
11379 * \param tiDeviceHandle: Pointer to TISA device handle for this I/O.
11380 * \param tiScsiRequest: Pointer to TISA SCSI I/O request and SGL list.
11381 * \param satIOContext_t: Pointer to the SAT IO Context
11382 *
11383 * \return If command is started successfully
11384 * - \e tiSuccess: I/O request successfully initiated.
11385 * - \e tiBusy: No resources available, try again later.
11386 * - \e tiIONoDevice: Invalid device handle.
11387 * - \e tiError: Other errors.
11388 */
11389 /*****************************************************************************/
11390 GLOBAL bit32 satLogSense_2(
11391 tiRoot_t *tiRoot,
11392 tiIORequest_t *tiIORequest,
11393 tiDeviceHandle_t *tiDeviceHandle,
11394 tiScsiInitiatorRequest_t *tiScsiRequest,
11395 satIOContext_t *satIOContext)
11396 {
11397 bit32 status;
11398 bit32 agRequestType;
11399 agsaFisRegHostToDevice_t *fis;
11400
11401 TI_DBG4(("satLogSense_2 entry: tiDeviceHandle=%p tiIORequest=%p\n",
11402 tiDeviceHandle, tiIORequest));
11403
11404 fis = satIOContext->pFis;
11405 /* sends READ LOG EXT */
11406 fis->h.fisType = 0x27; /* Reg host to device */
11407 fis->h.c_pmPort = 0x80; /* C Bit is set */
11408
11409 fis->h.command = SAT_READ_LOG_EXT; /* 0x2F */
11410 fis->h.features = 0; /* FIS reserve */
11411 fis->d.lbaLow = 0x07; /* 0x07 */
11412 fis->d.lbaMid = 0; /* */
11413 fis->d.lbaHigh = 0; /* */
11414 fis->d.device = 0; /* */
11415 fis->d.lbaLowExp = 0; /* */
11416 fis->d.lbaMidExp = 0; /* */
11417 fis->d.lbaHighExp = 0; /* */
11418 fis->d.featuresExp = 0; /* FIS reserve */
11419 fis->d.sectorCount = 0x01; /* 1 sector counts */
11420 fis->d.sectorCountExp = 0x00; /* 1 sector counts */
11421 fis->d.reserved4 = 0;
11422 fis->d.control = 0; /* FIS HOB bit clear */
11423 fis->d.reserved5 = 0;
11424
11425 agRequestType = AGSA_SATA_PROTOCOL_PIO_READ;
11426
11427 /* Initialize CB for SATA completion.
11428 */
11429 satIOContext->satCompleteCB = &satLogSenseCB;
11430
11431 /*
11432 * Prepare SGL and send FIS to LL layer.
11433 */
11434 satIOContext->reqType = agRequestType; /* Save it */
11435
11436 status = sataLLIOStart( tiRoot,
11437 tiIORequest,
11438 tiDeviceHandle,
11439 tiScsiRequest,
11440 satIOContext);
11441 return status;
11442 }
11443
11444 /*****************************************************************************/
11445 /*! \brief SAT implementation for SCSI satLogSenseAllocate.
11446 *
11447 * Part of SAT implementation for SCSI satLogSense.
11448 *
11449 * \param tiRoot: Pointer to TISA initiator driver/port instance.
11450 * \param tiIORequest: Pointer to TISA I/O request context for this I/O.
11451 * \param tiDeviceHandle: Pointer to TISA device handle for this I/O.
11452 * \param tiScsiRequest: Pointer to TISA SCSI I/O request and SGL list.
11453 * \param satIOContext_t: Pointer to the SAT IO Context
11454 * \param payloadSize: size of payload to be allocated.
11455 * \param flag: flag value
11456 *
11457 * \return If command is started successfully
11458 * - \e tiSuccess: I/O request successfully initiated.
11459 * - \e tiBusy: No resources available, try again later.
11460 * - \e tiIONoDevice: Invalid device handle.
11461 * - \e tiError: Other errors.
11462 * \note
11463 * - flag values: LOG_SENSE_0, LOG_SENSE_1, LOG_SENSE_2
11464 */
11465 /*****************************************************************************/
11466 GLOBAL bit32 satLogSenseAllocate(
11467 tiRoot_t *tiRoot,
11468 tiIORequest_t *tiIORequest,
11469 tiDeviceHandle_t *tiDeviceHandle,
11470 tiScsiInitiatorRequest_t *tiScsiRequest,
11471 satIOContext_t *satIOContext,
11472 bit32 payloadSize,
11473 bit32 flag
11474 )
11475 {
11476 satDeviceData_t *pSatDevData;
11477 tdIORequestBody_t *tdIORequestBody;
11478 satInternalIo_t *satIntIo = agNULL;
11479 satIOContext_t *satIOContext2;
11480 bit32 status;
11481
11482 TI_DBG4(("satLogSense_2 entry: tiDeviceHandle=%p tiIORequest=%p\n",
11483 tiDeviceHandle, tiIORequest));
11484
11485 pSatDevData = satIOContext->pSatDevData;
11486
11487 /* create internal satIOContext */
11488 satIntIo = satAllocIntIoResource( tiRoot,
11489 tiIORequest, /* original request */
11490 pSatDevData,
11491 payloadSize,
11492 satIntIo);
11493
11494 if (satIntIo == agNULL)
11495 {
11496 /* memory allocation failure */
11497 satFreeIntIoResource( tiRoot,
11498 pSatDevData,
11499 satIntIo);
11500
11501 ostiInitiatorIOCompleted( tiRoot,
11502 tiIORequest,
11503 tiIOFailed,
11504 tiDetailOtherError,
11505 agNULL,
11506 satIOContext->interruptContext );
11507
11508 TI_DBG4(("satLogSense_2: fail in allocation\n"));
11509 return tiSuccess;
11510 } /* end of memory allocation failure */
11511
11512 satIntIo->satOrgTiIORequest = tiIORequest;
11513 tdIORequestBody = (tdIORequestBody_t *)satIntIo->satIntRequestBody;
11514 satIOContext2 = &(tdIORequestBody->transport.SATA.satIOContext);
11515
11516 satIOContext2->pSatDevData = pSatDevData;
11517 satIOContext2->pFis = &(tdIORequestBody->transport.SATA.agSATARequestBody.fis.fisRegHostToDev);
11518 satIOContext2->pScsiCmnd = &(satIntIo->satIntTiScsiXchg.scsiCmnd);
11519 satIOContext2->pSense = &(tdIORequestBody->transport.SATA.sensePayload);
11520 satIOContext2->pTiSenseData = &(tdIORequestBody->transport.SATA.tiSenseData);
11521 satIOContext2->pTiSenseData->senseData = satIOContext2->pSense;
11522 satIOContext2->tiRequestBody = satIntIo->satIntRequestBody;
11523 satIOContext2->interruptContext = satIOContext->interruptContext;
11524 satIOContext2->satIntIoContext = satIntIo;
11525 satIOContext2->ptiDeviceHandle = tiDeviceHandle;
11526 satIOContext2->satOrgIOContext = satIOContext;
11527
11528 if (flag == LOG_SENSE_0)
11529 {
11530 /* SAT_SMART_ENABLE_OPERATIONS */
11531 status = satSMARTEnable( tiRoot,
11532 &(satIntIo->satIntTiIORequest),
11533 tiDeviceHandle,
11534 &(satIntIo->satIntTiScsiXchg),
11535 satIOContext2);
11536 }
11537 else if (flag == LOG_SENSE_1)
11538 {
11539 /* SAT_READ_LOG_EXT */
11540 status = satLogSense_2( tiRoot,
11541 &(satIntIo->satIntTiIORequest),
11542 tiDeviceHandle,
11543 &(satIntIo->satIntTiScsiXchg),
11544 satIOContext2);
11545 }
11546 else
11547 {
11548 /* SAT_SMART_READ_LOG */
11549 /* SAT_READ_LOG_EXT */
11550 status = satLogSense_3( tiRoot,
11551 &(satIntIo->satIntTiIORequest),
11552 tiDeviceHandle,
11553 &(satIntIo->satIntTiScsiXchg),
11554 satIOContext2);
11555
11556 }
11557 if (status != tiSuccess)
11558 {
11559 satFreeIntIoResource( tiRoot,
11560 pSatDevData,
11561 satIntIo);
11562
11563 ostiInitiatorIOCompleted( tiRoot,
11564 tiIORequest,
11565 tiIOFailed,
11566 tiDetailOtherError,
11567 agNULL,
11568 satIOContext->interruptContext );
11569 return tiSuccess;
11570 }
11571
11572
11573 return tiSuccess;
11574 }
11575
11576
11577 /*****************************************************************************/
11578 /*! \brief SAT implementation for SCSI satLogSense.
11579 *
11580 * SAT implementation for SCSI satLogSense.
11581 *
11582 * \param tiRoot: Pointer to TISA initiator driver/port instance.
11583 * \param tiIORequest: Pointer to TISA I/O request context for this I/O.
11584 * \param tiDeviceHandle: Pointer to TISA device handle for this I/O.
11585 * \param tiScsiRequest: Pointer to TISA SCSI I/O request and SGL list.
11586 * \param satIOContext_t: Pointer to the SAT IO Context
11587 *
11588 * \return If command is started successfully
11589 * - \e tiSuccess: I/O request successfully initiated.
11590 * - \e tiBusy: No resources available, try again later.
11591 * - \e tiIONoDevice: Invalid device handle.
11592 * - \e tiError: Other errors.
11593 */
11594 /*****************************************************************************/
11595 GLOBAL bit32 satLogSense(
11596 tiRoot_t *tiRoot,
11597 tiIORequest_t *tiIORequest,
11598 tiDeviceHandle_t *tiDeviceHandle,
11599 tiScsiInitiatorRequest_t *tiScsiRequest,
11600 satIOContext_t *satIOContext)
11601 {
11602 bit32 status;
11603 bit32 agRequestType;
11604 satDeviceData_t *pSatDevData;
11605 scsiRspSense_t *pSense;
11606 tiIniScsiCmnd_t *scsiCmnd;
11607 agsaFisRegHostToDevice_t *fis;
11608 bit8 *pLogPage; /* Log Page data buffer */
11609 bit32 flag = 0;
11610 bit16 AllocLen = 0; /* allocation length */
11611 bit8 AllLogPages[8];
11612 bit16 lenRead = 0;
11613
11614 pSense = satIOContext->pSense;
11615 pSatDevData = satIOContext->pSatDevData;
11616 scsiCmnd = &tiScsiRequest->scsiCmnd;
11617 fis = satIOContext->pFis;
11618 pLogPage = (bit8 *) tiScsiRequest->sglVirtualAddr;
11619
11620 TI_DBG5(("satLogSense: start\n"));
11621
11622 osti_memset(&AllLogPages, 0, 8);
11623 /* checking CONTROL */
11624 /* NACA == 1 or LINK == 1*/
11625 if ( (scsiCmnd->cdb[9] & SCSI_NACA_MASK) || (scsiCmnd->cdb[9] & SCSI_LINK_MASK) )
11626 {
11627 satSetSensePayload( pSense,
11628 SCSI_SNSKEY_ILLEGAL_REQUEST,
11629 0,
11630 SCSI_SNSCODE_INVALID_FIELD_IN_CDB,
11631 satIOContext);
11632
11633 ostiInitiatorIOCompleted( tiRoot,
11634 tiIORequest,
11635 tiIOSuccess,
11636 SCSI_STAT_CHECK_CONDITION,
11637 satIOContext->pTiSenseData,
11638 satIOContext->interruptContext );
11639
11640 TI_DBG2(("satLogSense: return control\n"));
11641 return tiSuccess;
11642 }
11643
11644
11645 AllocLen = (bit8)((scsiCmnd->cdb[7] << 8) + scsiCmnd->cdb[8]);
11646
11647 /* checking PC (Page Control) */
11648 /* nothing */
11649
11650 /* special cases */
11651 if (AllocLen == 4)
11652 {
11653 TI_DBG1(("satLogSense: AllocLen is 4\n"));
11654 switch (scsiCmnd->cdb[2] & SCSI_LOG_SENSE_PAGE_CODE_MASK)
11655 {
11656 case LOGSENSE_SUPPORTED_LOG_PAGES:
11657 TI_DBG5(("satLogSense: case LOGSENSE_SUPPORTED_LOG_PAGES\n"));
11658
11659 /* SAT Rev 8, 10.2.5 p76 */
11660 if (pSatDevData->satSMARTFeatureSet == agTRUE)
11661 {
11662 /* add informational exception log */
11663 flag = 1;
11664 if (pSatDevData->satSMARTSelfTest == agTRUE)
11665 {
11666 /* add Self-Test results log page */
11667 flag = 2;
11668 }
11669 }
11670 else
11671 {
11672 /* only supported, no informational exception log, no Self-Test results log page */
11673 flag = 0;
11674 }
11675 lenRead = 4;
11676 AllLogPages[0] = LOGSENSE_SUPPORTED_LOG_PAGES; /* page code */
11677 AllLogPages[1] = 0; /* reserved */
11678 switch (flag)
11679 {
11680 case 0:
11681 /* only supported */
11682 AllLogPages[2] = 0; /* page length */
11683 AllLogPages[3] = 1; /* page length */
11684 break;
11685 case 1:
11686 /* supported and informational exception log */
11687 AllLogPages[2] = 0; /* page length */
11688 AllLogPages[3] = 2; /* page length */
11689 break;
11690 case 2:
11691 /* supported and informational exception log */
11692 AllLogPages[2] = 0; /* page length */
11693 AllLogPages[3] = 3; /* page length */
11694 break;
11695 default:
11696 TI_DBG1(("satLogSense: error unallowed flag value %d\n", flag));
11697 break;
11698 }
11699 osti_memcpy(pLogPage, &AllLogPages, lenRead);
11700 break;
11701 case LOGSENSE_SELFTEST_RESULTS_PAGE:
11702 TI_DBG5(("satLogSense: case LOGSENSE_SUPPORTED_LOG_PAGES\n"));
11703 lenRead = 4;
11704 AllLogPages[0] = LOGSENSE_SELFTEST_RESULTS_PAGE; /* page code */
11705 AllLogPages[1] = 0; /* reserved */
11706 /* page length = SELFTEST_RESULTS_LOG_PAGE_LENGTH - 1 - 3 = 400 = 0x190 */
11707 AllLogPages[2] = 0x01;
11708 AllLogPages[3] = 0x90; /* page length */
11709 osti_memcpy(pLogPage, &AllLogPages, lenRead);
11710
11711 break;
11712 case LOGSENSE_INFORMATION_EXCEPTIONS_PAGE:
11713 TI_DBG5(("satLogSense: case LOGSENSE_SUPPORTED_LOG_PAGES\n"));
11714 lenRead = 4;
11715 AllLogPages[0] = LOGSENSE_INFORMATION_EXCEPTIONS_PAGE; /* page code */
11716 AllLogPages[1] = 0; /* reserved */
11717 AllLogPages[2] = 0; /* page length */
11718 AllLogPages[3] = INFORMATION_EXCEPTIONS_LOG_PAGE_LENGTH - 1 - 3; /* page length */
11719 osti_memcpy(pLogPage, &AllLogPages, lenRead);
11720 break;
11721 default:
11722 TI_DBG1(("satLogSense: default Page Code 0x%x\n", scsiCmnd->cdb[2] & SCSI_LOG_SENSE_PAGE_CODE_MASK));
11723 satSetSensePayload( pSense,
11724 SCSI_SNSKEY_ILLEGAL_REQUEST,
11725 0,
11726 SCSI_SNSCODE_INVALID_FIELD_IN_CDB,
11727 satIOContext);
11728
11729 ostiInitiatorIOCompleted( tiRoot,
11730 tiIORequest,
11731 tiIOSuccess,
11732 SCSI_STAT_CHECK_CONDITION,
11733 satIOContext->pTiSenseData,
11734 satIOContext->interruptContext );
11735 return tiSuccess;
11736 }
11737 ostiInitiatorIOCompleted( tiRoot,
11738 tiIORequest,
11739 tiIOSuccess,
11740 SCSI_STAT_GOOD,
11741 agNULL,
11742 satIOContext->interruptContext);
11743 return tiSuccess;
11744
11745 } /* if */
11746
11747 /* SAT rev8 Table 11 p30*/
11748 /* checking Page Code */
11749 switch (scsiCmnd->cdb[2] & SCSI_LOG_SENSE_PAGE_CODE_MASK)
11750 {
11751 case LOGSENSE_SUPPORTED_LOG_PAGES:
11752 TI_DBG5(("satLogSense: case 1\n"));
11753
11754 /* SAT Rev 8, 10.2.5 p76 */
11755
11756 if (pSatDevData->satSMARTFeatureSet == agTRUE)
11757 {
11758 /* add informational exception log */
11759 flag = 1;
11760 if (pSatDevData->satSMARTSelfTest == agTRUE)
11761 {
11762 /* add Self-Test results log page */
11763 flag = 2;
11764 }
11765 }
11766 else
11767 {
11768 /* only supported, no informational exception log, no Self-Test results log page */
11769 flag = 0;
11770 }
11771 AllLogPages[0] = 0; /* page code */
11772 AllLogPages[1] = 0; /* reserved */
11773 switch (flag)
11774 {
11775 case 0:
11776 /* only supported */
11777 AllLogPages[2] = 0; /* page length */
11778 AllLogPages[3] = 1; /* page length */
11779 AllLogPages[4] = 0x00; /* supported page list */
11780 lenRead = (bit8)(MIN(AllocLen, 5));
11781 break;
11782 case 1:
11783 /* supported and informational exception log */
11784 AllLogPages[2] = 0; /* page length */
11785 AllLogPages[3] = 2; /* page length */
11786 AllLogPages[4] = 0x00; /* supported page list */
11787 AllLogPages[5] = 0x10; /* supported page list */
11788 lenRead = (bit8)(MIN(AllocLen, 6));
11789 break;
11790 case 2:
11791 /* supported and informational exception log */
11792 AllLogPages[2] = 0; /* page length */
11793 AllLogPages[3] = 3; /* page length */
11794 AllLogPages[4] = 0x00; /* supported page list */
11795 AllLogPages[5] = 0x10; /* supported page list */
11796 AllLogPages[6] = 0x2F; /* supported page list */
11797 lenRead = (bit8)(MIN(AllocLen, 7));
11798 break;
11799 default:
11800 TI_DBG1(("satLogSense: error unallowed flag value %d\n", flag));
11801 break;
11802 }
11803
11804 osti_memcpy(pLogPage, &AllLogPages, lenRead);
11805 /* comparing allocation length to Log Page byte size */
11806 /* SPC-4, 4.3.4.6, p28 */
11807 if (AllocLen > lenRead )
11808 {
11809 TI_DBG1(("satLogSense reporting underrun lenRead=0x%x AllocLen=0x%x tiIORequest=%p\n", lenRead, AllocLen, tiIORequest));
11810 ostiInitiatorIOCompleted( tiRoot,
11811 tiIORequest,
11812 tiIOUnderRun,
11813 AllocLen - lenRead,
11814 agNULL,
11815 satIOContext->interruptContext );
11816 }
11817 else
11818 {
11819 ostiInitiatorIOCompleted( tiRoot,
11820 tiIORequest,
11821 tiIOSuccess,
11822 SCSI_STAT_GOOD,
11823 agNULL,
11824 satIOContext->interruptContext);
11825 }
11826 break;
11827 case LOGSENSE_SELFTEST_RESULTS_PAGE:
11828 TI_DBG5(("satLogSense: case 2\n"));
11829 /* checking SMART self-test */
11830 if (pSatDevData->satSMARTSelfTest == agFALSE)
11831 {
11832 TI_DBG5(("satLogSense: case 2 no SMART Self Test\n"));
11833 satSetSensePayload( pSense,
11834 SCSI_SNSKEY_ILLEGAL_REQUEST,
11835 0,
11836 SCSI_SNSCODE_INVALID_FIELD_IN_CDB,
11837 satIOContext);
11838
11839 ostiInitiatorIOCompleted( tiRoot,
11840 tiIORequest,
11841 tiIOSuccess,
11842 SCSI_STAT_CHECK_CONDITION,
11843 satIOContext->pTiSenseData,
11844 satIOContext->interruptContext );
11845 }
11846 else
11847 {
11848 /* if satSMARTEnabled is false, send SMART_ENABLE_OPERATIONS */
11849 if (pSatDevData->satSMARTEnabled == agFALSE)
11850 {
11851 TI_DBG5(("satLogSense: case 2 calling satSMARTEnable\n"));
11852 status = satLogSenseAllocate(tiRoot,
11853 tiIORequest,
11854 tiDeviceHandle,
11855 tiScsiRequest,
11856 satIOContext,
11857 0,
11858 LOG_SENSE_0
11859 );
11860
11861 return status;
11862
11863 }
11864 else
11865 {
11866 /* SAT Rev 8, 10.2.4 p74 */
11867 if ( pSatDevData->sat48BitSupport == agTRUE )
11868 {
11869 TI_DBG5(("satLogSense: case 2-1 sends READ LOG EXT\n"));
11870 status = satLogSenseAllocate(tiRoot,
11871 tiIORequest,
11872 tiDeviceHandle,
11873 tiScsiRequest,
11874 satIOContext,
11875 512,
11876 LOG_SENSE_1
11877 );
11878
11879 return status;
11880 }
11881 else
11882 {
11883 TI_DBG5(("satLogSense: case 2-2 sends SMART READ LOG\n"));
11884 status = satLogSenseAllocate(tiRoot,
11885 tiIORequest,
11886 tiDeviceHandle,
11887 tiScsiRequest,
11888 satIOContext,
11889 512,
11890 LOG_SENSE_2
11891 );
11892
11893 return status;
11894 }
11895 }
11896 }
11897 break;
11898 case LOGSENSE_INFORMATION_EXCEPTIONS_PAGE:
11899 TI_DBG5(("satLogSense: case 3\n"));
11900 /* checking SMART feature set */
11901 if (pSatDevData->satSMARTFeatureSet == agFALSE)
11902 {
11903 satSetSensePayload( pSense,
11904 SCSI_SNSKEY_ILLEGAL_REQUEST,
11905 0,
11906 SCSI_SNSCODE_INVALID_FIELD_IN_CDB,
11907 satIOContext);
11908
11909 ostiInitiatorIOCompleted( tiRoot,
11910 tiIORequest,
11911 tiIOSuccess,
11912 SCSI_STAT_CHECK_CONDITION,
11913 satIOContext->pTiSenseData,
11914 satIOContext->interruptContext );
11915 }
11916 else
11917 {
11918 /* checking SMART feature enabled */
11919 if (pSatDevData->satSMARTEnabled == agFALSE)
11920 {
11921 satSetSensePayload( pSense,
11922 SCSI_SNSKEY_ABORTED_COMMAND,
11923 0,
11924 SCSI_SNSCODE_ATA_DEVICE_FEATURE_NOT_ENABLED,
11925 satIOContext);
11926
11927 ostiInitiatorIOCompleted( tiRoot,
11928 tiIORequest,
11929 tiIOSuccess,
11930 SCSI_STAT_CHECK_CONDITION,
11931 satIOContext->pTiSenseData,
11932 satIOContext->interruptContext );
11933 }
11934 else
11935 {
11936 /* SAT Rev 8, 10.2.3 p72 */
11937 TI_DBG5(("satLogSense: case 3 sends SMART RETURN STATUS\n"));
11938
11939 /* sends SMART RETURN STATUS */
11940 fis->h.fisType = 0x27; /* Reg host to device */
11941 fis->h.c_pmPort = 0x80; /* C Bit is set */
11942
11943 fis->h.command = SAT_SMART_RETURN_STATUS;/* 0xB0 */
11944 fis->h.features = 0xDA; /* FIS features */
11945 fis->d.featuresExp = 0; /* FIS reserve */
11946 fis->d.sectorCount = 0; /* FIS sector count (7:0) */
11947 fis->d.sectorCountExp = 0; /* FIS sector count (15:8) */
11948 fis->d.lbaLow = 0; /* FIS LBA (7 :0 ) */
11949 fis->d.lbaLowExp = 0; /* FIS LBA (31:24) */
11950 fis->d.lbaMid = 0x4F; /* FIS LBA (15:8 ) */
11951 fis->d.lbaMidExp = 0; /* FIS LBA (39:32) */
11952 fis->d.lbaHigh = 0xC2; /* FIS LBA (23:16) */
11953 fis->d.lbaHighExp = 0; /* FIS LBA (47:40) */
11954 fis->d.device = 0; /* FIS DEV is discared in SATA */
11955 fis->d.control = 0; /* FIS HOB bit clear */
11956 fis->d.reserved4 = 0;
11957 fis->d.reserved5 = 0;
11958
11959 agRequestType = AGSA_SATA_PROTOCOL_NON_DATA;
11960 /* Initialize CB for SATA completion.
11961 */
11962 satIOContext->satCompleteCB = &satLogSenseCB;
11963
11964 /*
11965 * Prepare SGL and send FIS to LL layer.
11966 */
11967 satIOContext->reqType = agRequestType; /* Save it */
11968
11969 status = sataLLIOStart( tiRoot,
11970 tiIORequest,
11971 tiDeviceHandle,
11972 tiScsiRequest,
11973 satIOContext);
11974
11975
11976 return status;
11977 }
11978 }
11979 break;
11980 default:
11981 TI_DBG1(("satLogSense: default Page Code 0x%x\n", scsiCmnd->cdb[2] & SCSI_LOG_SENSE_PAGE_CODE_MASK));
11982 satSetSensePayload( pSense,
11983 SCSI_SNSKEY_ILLEGAL_REQUEST,
11984 0,
11985 SCSI_SNSCODE_INVALID_FIELD_IN_CDB,
11986 satIOContext);
11987
11988 ostiInitiatorIOCompleted( tiRoot,
11989 tiIORequest,
11990 tiIOSuccess,
11991 SCSI_STAT_CHECK_CONDITION,
11992 satIOContext->pTiSenseData,
11993 satIOContext->interruptContext );
11994
11995 break;
11996 } /* end switch */
11997
11998 return tiSuccess;
11999
12000
12001 }
12002
12003 /*****************************************************************************/
12004 /*! \brief SAT implementation for SCSI satModeSelect6.
12005 *
12006 * SAT implementation for SCSI satModeSelect6.
12007 *
12008 * \param tiRoot: Pointer to TISA initiator driver/port instance.
12009 * \param tiIORequest: Pointer to TISA I/O request context for this I/O.
12010 * \param tiDeviceHandle: Pointer to TISA device handle for this I/O.
12011 * \param tiScsiRequest: Pointer to TISA SCSI I/O request and SGL list.
12012 * \param satIOContext_t: Pointer to the SAT IO Context
12013 *
12014 * \return If command is started successfully
12015 * - \e tiSuccess: I/O request successfully initiated.
12016 * - \e tiBusy: No resources available, try again later.
12017 * - \e tiIONoDevice: Invalid device handle.
12018 * - \e tiError: Other errors.
12019 */
12020 /*****************************************************************************/
12021 GLOBAL bit32 satModeSelect6(
12022 tiRoot_t *tiRoot,
12023 tiIORequest_t *tiIORequest,
12024 tiDeviceHandle_t *tiDeviceHandle,
12025 tiScsiInitiatorRequest_t *tiScsiRequest,
12026 satIOContext_t *satIOContext)
12027 {
12028 bit32 status;
12029 bit32 agRequestType;
12030 satDeviceData_t *pSatDevData;
12031 scsiRspSense_t *pSense;
12032 tiIniScsiCmnd_t *scsiCmnd;
12033 agsaFisRegHostToDevice_t *fis;
12034 bit8 *pLogPage; /* Log Page data buffer */
12035 bit32 StartingIndex = 0;
12036 bit8 PageCode = 0;
12037 bit32 chkCnd = agFALSE;
12038
12039 pSense = satIOContext->pSense;
12040 pSatDevData = satIOContext->pSatDevData;
12041 scsiCmnd = &tiScsiRequest->scsiCmnd;
12042 fis = satIOContext->pFis;
12043 pLogPage = (bit8 *) tiScsiRequest->sglVirtualAddr;
12044
12045 TI_DBG5(("satModeSelect6: start\n"));
12046
12047 /* checking CONTROL */
12048 /* NACA == 1 or LINK == 1*/
12049 if ( (scsiCmnd->cdb[5] & SCSI_NACA_MASK) || (scsiCmnd->cdb[5] & SCSI_LINK_MASK) )
12050 {
12051 satSetSensePayload( pSense,
12052 SCSI_SNSKEY_ILLEGAL_REQUEST,
12053 0,
12054 SCSI_SNSCODE_INVALID_FIELD_IN_CDB,
12055 satIOContext);
12056
12057 ostiInitiatorIOCompleted( tiRoot,
12058 tiIORequest,
12059 tiIOSuccess,
12060 SCSI_STAT_CHECK_CONDITION,
12061 satIOContext->pTiSenseData,
12062 satIOContext->interruptContext );
12063
12064 TI_DBG2(("satModeSelect6: return control\n"));
12065 return tiSuccess;
12066 }
12067
12068 /* checking PF bit */
12069 if ( !(scsiCmnd->cdb[1] & SCSI_MODE_SELECT6_PF_MASK))
12070 {
12071 satSetSensePayload( pSense,
12072 SCSI_SNSKEY_ILLEGAL_REQUEST,
12073 0,
12074 SCSI_SNSCODE_INVALID_FIELD_IN_CDB,
12075 satIOContext);
12076
12077 ostiInitiatorIOCompleted( tiRoot,
12078 tiIORequest,
12079 tiIOSuccess,
12080 SCSI_STAT_CHECK_CONDITION,
12081 satIOContext->pTiSenseData,
12082 satIOContext->interruptContext );
12083
12084 TI_DBG1(("satModeSelect6: PF bit check \n"));
12085 return tiSuccess;
12086
12087 }
12088
12089 /* checking Block Descriptor Length on Mode parameter header(6)*/
12090 if (pLogPage[3] == 8)
12091 {
12092 /* mode parameter block descriptor exists */
12093 PageCode = (bit8)(pLogPage[12] & 0x3F); /* page code and index is 4 + 8 */
12094 StartingIndex = 12;
12095 }
12096 else if (pLogPage[3] == 0)
12097 {
12098 /* mode parameter block descriptor does not exist */
12099 PageCode = (bit8)(pLogPage[4] & 0x3F); /* page code and index is 4 + 0 */
12100 StartingIndex = 4;
12101 ostiInitiatorIOCompleted( tiRoot,
12102 tiIORequest,
12103 tiIOSuccess,
12104 SCSI_STAT_GOOD,
12105 agNULL,
12106 satIOContext->interruptContext);
12107 return tiSuccess;
12108 }
12109 else
12110 {
12111 TI_DBG1(("satModeSelect6: return mode parameter block descriptor 0x%x\n", pLogPage[3]));
12112 /* no more than one mode parameter block descriptor shall be supported */
12113 satSetSensePayload( pSense,
12114 SCSI_SNSKEY_NO_SENSE,
12115 0,
12116 SCSI_SNSCODE_NO_ADDITIONAL_INFO,
12117 satIOContext);
12118
12119 ostiInitiatorIOCompleted( tiRoot,
12120 tiIORequest,
12121 tiIOSuccess,
12122 SCSI_STAT_CHECK_CONDITION,
12123 satIOContext->pTiSenseData,
12124 satIOContext->interruptContext );
12125 return tiSuccess;
12126 }
12127
12128
12129
12130 switch (PageCode) /* page code */
12131 {
12132 case MODESELECT_CONTROL_PAGE:
12133 TI_DBG1(("satModeSelect6: Control mode page\n"));
12134 /*
12135 compare pLogPage to expected value (SAT Table 65, p67)
12136 If not match, return check condition
12137 */
12138 if ( pLogPage[StartingIndex+1] != 0x0A ||
12139 pLogPage[StartingIndex+2] != 0x02 ||
12140 (pSatDevData->satNCQ == agTRUE && pLogPage[StartingIndex+3] != 0x12) ||
12141 (pSatDevData->satNCQ == agFALSE && pLogPage[StartingIndex+3] != 0x02) ||
12142 (pLogPage[StartingIndex+4] & BIT3_MASK) != 0x00 || /* SWP bit */
12143 (pLogPage[StartingIndex+4] & BIT4_MASK) != 0x00 || /* UA_INTLCK_CTRL */
12144 (pLogPage[StartingIndex+4] & BIT5_MASK) != 0x00 || /* UA_INTLCK_CTRL */
12145
12146 (pLogPage[StartingIndex+5] & BIT0_MASK) != 0x00 || /* AUTOLOAD MODE */
12147 (pLogPage[StartingIndex+5] & BIT1_MASK) != 0x00 || /* AUTOLOAD MODE */
12148 (pLogPage[StartingIndex+5] & BIT2_MASK) != 0x00 || /* AUTOLOAD MODE */
12149 (pLogPage[StartingIndex+5] & BIT6_MASK) != 0x00 || /* TAS bit */
12150
12151 pLogPage[StartingIndex+8] != 0xFF ||
12152 pLogPage[StartingIndex+9] != 0xFF ||
12153 pLogPage[StartingIndex+10] != 0x00 ||
12154 pLogPage[StartingIndex+11] != 0x00
12155 )
12156 {
12157 chkCnd = agTRUE;
12158 }
12159 if (chkCnd == agTRUE)
12160 {
12161 satSetSensePayload( pSense,
12162 SCSI_SNSKEY_ILLEGAL_REQUEST,
12163 0,
12164 SCSI_SNSCODE_INVALID_FIELD_IN_CDB,
12165 satIOContext);
12166
12167 ostiInitiatorIOCompleted( tiRoot,
12168 tiIORequest,
12169 tiIOSuccess,
12170 SCSI_STAT_CHECK_CONDITION,
12171 satIOContext->pTiSenseData,
12172 satIOContext->interruptContext );
12173
12174 TI_DBG1(("satModeSelect10: unexpected values\n"));
12175 }
12176 else
12177 {
12178 ostiInitiatorIOCompleted( tiRoot,
12179 tiIORequest,
12180 tiIOSuccess,
12181 SCSI_STAT_GOOD,
12182 agNULL,
12183 satIOContext->interruptContext);
12184 }
12185 return tiSuccess;
12186 break;
12187 case MODESELECT_READ_WRITE_ERROR_RECOVERY_PAGE:
12188 TI_DBG1(("satModeSelect6: Read-Write Error Recovery mode page\n"));
12189
12190 if ( (pLogPage[StartingIndex + 2] & SCSI_MODE_SELECT6_AWRE_MASK) ||
12191 (pLogPage[StartingIndex + 2] & SCSI_MODE_SELECT6_RC_MASK) ||
12192 (pLogPage[StartingIndex + 2] & SCSI_MODE_SELECT6_EER_MASK) ||
12193 (pLogPage[StartingIndex + 2] & SCSI_MODE_SELECT6_PER_MASK) ||
12194 (pLogPage[StartingIndex + 2] & SCSI_MODE_SELECT6_DTE_MASK) ||
12195 (pLogPage[StartingIndex + 2] & SCSI_MODE_SELECT6_DCR_MASK) ||
12196 (pLogPage[StartingIndex + 10]) ||
12197 (pLogPage[StartingIndex + 11])
12198 )
12199 {
12200 TI_DBG5(("satModeSelect6: return check condition \n"));
12201
12202 satSetSensePayload( pSense,
12203 SCSI_SNSKEY_ILLEGAL_REQUEST,
12204 0,
12205 SCSI_SNSCODE_INVALID_FIELD_PARAMETER_LIST,
12206 satIOContext);
12207
12208 ostiInitiatorIOCompleted( tiRoot,
12209 tiIORequest,
12210 tiIOSuccess,
12211 SCSI_STAT_CHECK_CONDITION,
12212 satIOContext->pTiSenseData,
12213 satIOContext->interruptContext );
12214 return tiSuccess;
12215 }
12216 else
12217 {
12218 TI_DBG5(("satModeSelect6: return GOOD \n"));
12219 ostiInitiatorIOCompleted( tiRoot,
12220 tiIORequest,
12221 tiIOSuccess,
12222 SCSI_STAT_GOOD,
12223 agNULL,
12224 satIOContext->interruptContext);
12225 return tiSuccess;
12226 }
12227
12228 break;
12229 case MODESELECT_CACHING:
12230 /* SAT rev8 Table67, p69*/
12231 TI_DBG5(("satModeSelect6: Caching mode page\n"));
12232 if ( (pLogPage[StartingIndex + 2] & 0xFB) || /* 1111 1011 */
12233 (pLogPage[StartingIndex + 3]) ||
12234 (pLogPage[StartingIndex + 4]) ||
12235 (pLogPage[StartingIndex + 5]) ||
12236 (pLogPage[StartingIndex + 6]) ||
12237 (pLogPage[StartingIndex + 7]) ||
12238 (pLogPage[StartingIndex + 8]) ||
12239 (pLogPage[StartingIndex + 9]) ||
12240 (pLogPage[StartingIndex + 10]) ||
12241 (pLogPage[StartingIndex + 11]) ||
12242
12243 (pLogPage[StartingIndex + 12] & 0xC1) || /* 1100 0001 */
12244 (pLogPage[StartingIndex + 13]) ||
12245 (pLogPage[StartingIndex + 14]) ||
12246 (pLogPage[StartingIndex + 15])
12247 )
12248 {
12249 TI_DBG1(("satModeSelect6: return check condition \n"));
12250
12251 satSetSensePayload( pSense,
12252 SCSI_SNSKEY_ILLEGAL_REQUEST,
12253 0,
12254 SCSI_SNSCODE_INVALID_FIELD_PARAMETER_LIST,
12255 satIOContext);
12256
12257 ostiInitiatorIOCompleted( tiRoot,
12258 tiIORequest,
12259 tiIOSuccess,
12260 SCSI_STAT_CHECK_CONDITION,
12261 satIOContext->pTiSenseData,
12262 satIOContext->interruptContext );
12263 return tiSuccess;
12264
12265 }
12266 else
12267 {
12268 /* sends ATA SET FEATURES based on WCE bit */
12269 if ( !(pLogPage[StartingIndex + 2] & SCSI_MODE_SELECT6_WCE_MASK) )
12270 {
12271 TI_DBG5(("satModeSelect6: disable write cache\n"));
12272 /* sends SET FEATURES */
12273 fis->h.fisType = 0x27; /* Reg host to device */
12274 fis->h.c_pmPort = 0x80; /* C Bit is set */
12275
12276 fis->h.command = SAT_SET_FEATURES; /* 0xEF */
12277 fis->h.features = 0x82; /* disable write cache */
12278 fis->d.lbaLow = 0; /* */
12279 fis->d.lbaMid = 0; /* */
12280 fis->d.lbaHigh = 0; /* */
12281 fis->d.device = 0; /* */
12282 fis->d.lbaLowExp = 0; /* */
12283 fis->d.lbaMidExp = 0; /* */
12284 fis->d.lbaHighExp = 0; /* */
12285 fis->d.featuresExp = 0; /* */
12286 fis->d.sectorCount = 0; /* */
12287 fis->d.sectorCountExp = 0; /* */
12288 fis->d.reserved4 = 0;
12289 fis->d.control = 0; /* FIS HOB bit clear */
12290 fis->d.reserved5 = 0;
12291
12292 agRequestType = AGSA_SATA_PROTOCOL_NON_DATA;
12293
12294 /* Initialize CB for SATA completion.
12295 */
12296 satIOContext->satCompleteCB = &satModeSelect6n10CB;
12297
12298 /*
12299 * Prepare SGL and send FIS to LL layer.
12300 */
12301 satIOContext->reqType = agRequestType; /* Save it */
12302
12303 status = sataLLIOStart( tiRoot,
12304 tiIORequest,
12305 tiDeviceHandle,
12306 tiScsiRequest,
12307 satIOContext);
12308 return status;
12309 }
12310 else
12311 {
12312 TI_DBG5(("satModeSelect6: enable write cache\n"));
12313 /* sends SET FEATURES */
12314 fis->h.fisType = 0x27; /* Reg host to device */
12315 fis->h.c_pmPort = 0x80; /* C Bit is set */
12316
12317 fis->h.command = SAT_SET_FEATURES; /* 0xEF */
12318 fis->h.features = 0x02; /* enable write cache */
12319 fis->d.lbaLow = 0; /* */
12320 fis->d.lbaMid = 0; /* */
12321 fis->d.lbaHigh = 0; /* */
12322 fis->d.device = 0; /* */
12323 fis->d.lbaLowExp = 0; /* */
12324 fis->d.lbaMidExp = 0; /* */
12325 fis->d.lbaHighExp = 0; /* */
12326 fis->d.featuresExp = 0; /* */
12327 fis->d.sectorCount = 0; /* */
12328 fis->d.sectorCountExp = 0; /* */
12329 fis->d.reserved4 = 0;
12330 fis->d.control = 0; /* FIS HOB bit clear */
12331 fis->d.reserved5 = 0;
12332
12333 agRequestType = AGSA_SATA_PROTOCOL_NON_DATA;
12334
12335 /* Initialize CB for SATA completion.
12336 */
12337 satIOContext->satCompleteCB = &satModeSelect6n10CB;
12338
12339 /*
12340 * Prepare SGL and send FIS to LL layer.
12341 */
12342 satIOContext->reqType = agRequestType; /* Save it */
12343
12344 status = sataLLIOStart( tiRoot,
12345 tiIORequest,
12346 tiDeviceHandle,
12347 tiScsiRequest,
12348 satIOContext);
12349 return status;
12350
12351 }
12352 }
12353 break;
12354 case MODESELECT_INFORMATION_EXCEPTION_CONTROL_PAGE:
12355 TI_DBG5(("satModeSelect6: Informational Exception Control mode page\n"));
12356 if ( (pLogPage[StartingIndex + 2] & SCSI_MODE_SELECT6_PERF_MASK) ||
12357 (pLogPage[StartingIndex + 2] & SCSI_MODE_SELECT6_TEST_MASK)
12358 )
12359 {
12360 TI_DBG1(("satModeSelect6: return check condition \n"));
12361
12362 satSetSensePayload( pSense,
12363 SCSI_SNSKEY_ILLEGAL_REQUEST,
12364 0,
12365 SCSI_SNSCODE_INVALID_FIELD_PARAMETER_LIST,
12366 satIOContext);
12367
12368 ostiInitiatorIOCompleted( tiRoot,
12369 tiIORequest,
12370 tiIOSuccess,
12371 SCSI_STAT_CHECK_CONDITION,
12372 satIOContext->pTiSenseData,
12373 satIOContext->interruptContext );
12374 return tiSuccess;
12375 }
12376 else
12377 {
12378 /* sends either ATA SMART ENABLE/DISABLE OPERATIONS based on DEXCPT bit */
12379 if ( !(pLogPage[StartingIndex + 2] & 0x08) )
12380 {
12381 TI_DBG5(("satModeSelect6: enable information exceptions reporting\n"));
12382 /* sends SMART ENABLE OPERATIONS */
12383 fis->h.fisType = 0x27; /* Reg host to device */
12384 fis->h.c_pmPort = 0x80; /* C Bit is set */
12385
12386 fis->h.command = SAT_SMART_ENABLE_OPERATIONS; /* 0xB0 */
12387 fis->h.features = 0xD8; /* enable */
12388 fis->d.lbaLow = 0; /* */
12389 fis->d.lbaMid = 0x4F; /* 0x4F */
12390 fis->d.lbaHigh = 0xC2; /* 0xC2 */
12391 fis->d.device = 0; /* */
12392 fis->d.lbaLowExp = 0; /* */
12393 fis->d.lbaMidExp = 0; /* */
12394 fis->d.lbaHighExp = 0; /* */
12395 fis->d.featuresExp = 0; /* */
12396 fis->d.sectorCount = 0; /* */
12397 fis->d.sectorCountExp = 0; /* */
12398 fis->d.reserved4 = 0;
12399 fis->d.control = 0; /* FIS HOB bit clear */
12400 fis->d.reserved5 = 0;
12401
12402 agRequestType = AGSA_SATA_PROTOCOL_NON_DATA;
12403
12404 /* Initialize CB for SATA completion.
12405 */
12406 satIOContext->satCompleteCB = &satModeSelect6n10CB;
12407
12408 /*
12409 * Prepare SGL and send FIS to LL layer.
12410 */
12411 satIOContext->reqType = agRequestType; /* Save it */
12412
12413 status = sataLLIOStart( tiRoot,
12414 tiIORequest,
12415 tiDeviceHandle,
12416 tiScsiRequest,
12417 satIOContext);
12418 return status;
12419 }
12420 else
12421 {
12422 TI_DBG5(("satModeSelect6: disable information exceptions reporting\n"));
12423 /* sends SMART DISABLE OPERATIONS */
12424 fis->h.fisType = 0x27; /* Reg host to device */
12425 fis->h.c_pmPort = 0x80; /* C Bit is set */
12426
12427 fis->h.command = SAT_SMART_DISABLE_OPERATIONS; /* 0xB0 */
12428 fis->h.features = 0xD9; /* disable */
12429 fis->d.lbaLow = 0; /* */
12430 fis->d.lbaMid = 0x4F; /* 0x4F */
12431 fis->d.lbaHigh = 0xC2; /* 0xC2 */
12432 fis->d.device = 0; /* */
12433 fis->d.lbaLowExp = 0; /* */
12434 fis->d.lbaMidExp = 0; /* */
12435 fis->d.lbaHighExp = 0; /* */
12436 fis->d.featuresExp = 0; /* */
12437 fis->d.sectorCount = 0; /* */
12438 fis->d.sectorCountExp = 0; /* */
12439 fis->d.reserved4 = 0;
12440 fis->d.control = 0; /* FIS HOB bit clear */
12441 fis->d.reserved5 = 0;
12442
12443 agRequestType = AGSA_SATA_PROTOCOL_NON_DATA;
12444
12445 /* Initialize CB for SATA completion.
12446 */
12447 satIOContext->satCompleteCB = &satModeSelect6n10CB;
12448
12449 /*
12450 * Prepare SGL and send FIS to LL layer.
12451 */
12452 satIOContext->reqType = agRequestType; /* Save it */
12453
12454 status = sataLLIOStart( tiRoot,
12455 tiIORequest,
12456 tiDeviceHandle,
12457 tiScsiRequest,
12458 satIOContext);
12459 return status;
12460
12461 }
12462 }
12463 break;
12464 default:
12465 TI_DBG1(("satModeSelect6: Error unknown page code 0x%x\n", pLogPage[12]));
12466 satSetSensePayload( pSense,
12467 SCSI_SNSKEY_NO_SENSE,
12468 0,
12469 SCSI_SNSCODE_NO_ADDITIONAL_INFO,
12470 satIOContext);
12471
12472 ostiInitiatorIOCompleted( tiRoot,
12473 tiIORequest,
12474 tiIOSuccess,
12475 SCSI_STAT_CHECK_CONDITION,
12476 satIOContext->pTiSenseData,
12477 satIOContext->interruptContext );
12478 return tiSuccess;
12479 }
12480
12481 }
12482
12483 /*****************************************************************************/
12484 /*! \brief SAT implementation for SCSI satModeSelect6n10_1.
12485 *
12486 * This function is part of implementation of ModeSelect6 and ModeSelect10.
12487 * When ModeSelect6 or ModeSelect10 is coverted into multiple ATA commands,
12488 * this function is used.
12489 *
12490 * \param tiRoot: Pointer to TISA initiator driver/port instance.
12491 * \param tiIORequest: Pointer to TISA I/O request context for this I/O.
12492 * \param tiDeviceHandle: Pointer to TISA device handle for this I/O.
12493 * \param tiScsiRequest: Pointer to TISA SCSI I/O request and SGL list.
12494 * \param satIOContext_t: Pointer to the SAT IO Context
12495 *
12496 * \return If command is started successfully
12497 * - \e tiSuccess: I/O request successfully initiated.
12498 * - \e tiBusy: No resources available, try again later.
12499 * - \e tiIONoDevice: Invalid device handle.
12500 * - \e tiError: Other errors.
12501 */
12502 /*****************************************************************************/
12503 GLOBAL bit32 satModeSelect6n10_1(
12504 tiRoot_t *tiRoot,
12505 tiIORequest_t *tiIORequest,
12506 tiDeviceHandle_t *tiDeviceHandle,
12507 tiScsiInitiatorRequest_t *tiScsiRequest,
12508 satIOContext_t *satIOContext)
12509 {
12510 /* sends either ATA SET FEATURES based on DRA bit */
12511 bit32 status;
12512 bit32 agRequestType;
12513 agsaFisRegHostToDevice_t *fis;
12514 bit8 *pLogPage; /* Log Page data buffer */
12515 bit32 StartingIndex = 0;
12516
12517 fis = satIOContext->pFis;
12518 pLogPage = (bit8 *) tiScsiRequest->sglVirtualAddr;
12519 TI_DBG5(("satModeSelect6_1: start\n"));
12520 /* checking Block Descriptor Length on Mode parameter header(6)*/
12521 if (pLogPage[3] == 8)
12522 {
12523 /* mode parameter block descriptor exists */
12524 StartingIndex = 12;
12525 }
12526 else
12527 {
12528 /* mode parameter block descriptor does not exist */
12529 StartingIndex = 4;
12530 }
12531
12532 /* sends ATA SET FEATURES based on DRA bit */
12533 if ( !(pLogPage[StartingIndex + 12] & SCSI_MODE_SELECT6_DRA_MASK) )
12534 {
12535 TI_DBG5(("satModeSelect6_1: enable read look-ahead feature\n"));
12536 /* sends SET FEATURES */
12537 fis->h.fisType = 0x27; /* Reg host to device */
12538 fis->h.c_pmPort = 0x80; /* C Bit is set */
12539
12540 fis->h.command = SAT_SET_FEATURES; /* 0xEF */
12541 fis->h.features = 0xAA; /* enable read look-ahead */
12542 fis->d.lbaLow = 0; /* */
12543 fis->d.lbaMid = 0; /* */
12544 fis->d.lbaHigh = 0; /* */
12545 fis->d.device = 0; /* */
12546 fis->d.lbaLowExp = 0; /* */
12547 fis->d.lbaMidExp = 0; /* */
12548 fis->d.lbaHighExp = 0; /* */
12549 fis->d.featuresExp = 0; /* */
12550 fis->d.sectorCount = 0; /* */
12551 fis->d.sectorCountExp = 0; /* */
12552 fis->d.reserved4 = 0;
12553 fis->d.control = 0; /* FIS HOB bit clear */
12554 fis->d.reserved5 = 0;
12555
12556 agRequestType = AGSA_SATA_PROTOCOL_NON_DATA;
12557
12558 /* Initialize CB for SATA completion.
12559 */
12560 satIOContext->satCompleteCB = &satModeSelect6n10CB;
12561
12562 /*
12563 * Prepare SGL and send FIS to LL layer.
12564 */
12565 satIOContext->reqType = agRequestType; /* Save it */
12566
12567 status = sataLLIOStart( tiRoot,
12568 tiIORequest,
12569 tiDeviceHandle,
12570 tiScsiRequest,
12571 satIOContext);
12572 return status;
12573 }
12574 else
12575 {
12576 TI_DBG5(("satModeSelect6_1: disable read look-ahead feature\n"));
12577 /* sends SET FEATURES */
12578 fis->h.fisType = 0x27; /* Reg host to device */
12579 fis->h.c_pmPort = 0x80; /* C Bit is set */
12580
12581 fis->h.command = SAT_SET_FEATURES; /* 0xEF */
12582 fis->h.features = 0x55; /* disable read look-ahead */
12583 fis->d.lbaLow = 0; /* */
12584 fis->d.lbaMid = 0; /* */
12585 fis->d.lbaHigh = 0; /* */
12586 fis->d.device = 0; /* */
12587 fis->d.lbaLowExp = 0; /* */
12588 fis->d.lbaMidExp = 0; /* */
12589 fis->d.lbaHighExp = 0; /* */
12590 fis->d.featuresExp = 0; /* */
12591 fis->d.sectorCount = 0; /* */
12592 fis->d.sectorCountExp = 0; /* */
12593 fis->d.reserved4 = 0;
12594 fis->d.control = 0; /* FIS HOB bit clear */
12595 fis->d.reserved5 = 0;
12596
12597 agRequestType = AGSA_SATA_PROTOCOL_NON_DATA;
12598
12599 /* Initialize CB for SATA completion.
12600 */
12601 satIOContext->satCompleteCB = &satModeSelect6n10CB;
12602
12603 /*
12604 * Prepare SGL and send FIS to LL layer.
12605 */
12606 satIOContext->reqType = agRequestType; /* Save it */
12607
12608 status = sataLLIOStart( tiRoot,
12609 tiIORequest,
12610 tiDeviceHandle,
12611 tiScsiRequest,
12612 satIOContext);
12613 return status;
12614 }
12615
12616 }
12617
12618
12619 /*****************************************************************************/
12620 /*! \brief SAT implementation for SCSI satModeSelect10.
12621 *
12622 * SAT implementation for SCSI satModeSelect10.
12623 *
12624 * \param tiRoot: Pointer to TISA initiator driver/port instance.
12625 * \param tiIORequest: Pointer to TISA I/O request context for this I/O.
12626 * \param tiDeviceHandle: Pointer to TISA device handle for this I/O.
12627 * \param tiScsiRequest: Pointer to TISA SCSI I/O request and SGL list.
12628 * \param satIOContext_t: Pointer to the SAT IO Context
12629 *
12630 * \return If command is started successfully
12631 * - \e tiSuccess: I/O request successfully initiated.
12632 * - \e tiBusy: No resources available, try again later.
12633 * - \e tiIONoDevice: Invalid device handle.
12634 * - \e tiError: Other errors.
12635 */
12636 /*****************************************************************************/
12637 GLOBAL bit32 satModeSelect10(
12638 tiRoot_t *tiRoot,
12639 tiIORequest_t *tiIORequest,
12640 tiDeviceHandle_t *tiDeviceHandle,
12641 tiScsiInitiatorRequest_t *tiScsiRequest,
12642 satIOContext_t *satIOContext)
12643 {
12644 bit32 status;
12645 bit32 agRequestType;
12646 satDeviceData_t *pSatDevData;
12647 scsiRspSense_t *pSense;
12648 tiIniScsiCmnd_t *scsiCmnd;
12649 agsaFisRegHostToDevice_t *fis;
12650 bit8 *pLogPage; /* Log Page data buffer */
12651 bit16 BlkDescLen = 0; /* Block Descriptor Length */
12652 bit32 StartingIndex = 0;
12653 bit8 PageCode = 0;
12654 bit32 chkCnd = agFALSE;
12655
12656 pSense = satIOContext->pSense;
12657 pSatDevData = satIOContext->pSatDevData;
12658 scsiCmnd = &tiScsiRequest->scsiCmnd;
12659 fis = satIOContext->pFis;
12660 pLogPage = (bit8 *) tiScsiRequest->sglVirtualAddr;
12661
12662 TI_DBG5(("satModeSelect10: start\n"));
12663
12664 /* checking CONTROL */
12665 /* NACA == 1 or LINK == 1*/
12666 if ( (scsiCmnd->cdb[9] & SCSI_NACA_MASK) || (scsiCmnd->cdb[9] & SCSI_LINK_MASK) )
12667 {
12668 satSetSensePayload( pSense,
12669 SCSI_SNSKEY_ILLEGAL_REQUEST,
12670 0,
12671 SCSI_SNSCODE_INVALID_FIELD_IN_CDB,
12672 satIOContext);
12673
12674 ostiInitiatorIOCompleted( tiRoot,
12675 tiIORequest,
12676 tiIOSuccess,
12677 SCSI_STAT_CHECK_CONDITION,
12678 satIOContext->pTiSenseData,
12679 satIOContext->interruptContext );
12680
12681 TI_DBG2(("satModeSelect10: return control\n"));
12682 return tiSuccess;
12683 }
12684
12685 /* checking PF bit */
12686 if ( !(scsiCmnd->cdb[1] & SCSI_MODE_SELECT10_PF_MASK))
12687 {
12688 satSetSensePayload( pSense,
12689 SCSI_SNSKEY_ILLEGAL_REQUEST,
12690 0,
12691 SCSI_SNSCODE_INVALID_FIELD_IN_CDB,
12692 satIOContext);
12693
12694 ostiInitiatorIOCompleted( tiRoot,
12695 tiIORequest,
12696 tiIOSuccess,
12697 SCSI_STAT_CHECK_CONDITION,
12698 satIOContext->pTiSenseData,
12699 satIOContext->interruptContext );
12700
12701 TI_DBG1(("satModeSelect10: PF bit check \n"));
12702 return tiSuccess;
12703
12704 }
12705
12706 BlkDescLen = (bit8)((pLogPage[6] << 8) + pLogPage[7]);
12707
12708 /* checking Block Descriptor Length on Mode parameter header(10) and LONGLBA bit*/
12709 if ( (BlkDescLen == 8) && !(pLogPage[4] & SCSI_MODE_SELECT10_LONGLBA_MASK) )
12710 {
12711 /* mode parameter block descriptor exists and length is 8 byte */
12712 PageCode = (bit8)(pLogPage[16] & 0x3F); /* page code and index is 8 + 8 */
12713 StartingIndex = 16;
12714 }
12715 else if ( (BlkDescLen == 16) && (pLogPage[4] & SCSI_MODE_SELECT10_LONGLBA_MASK) )
12716 {
12717 /* mode parameter block descriptor exists and length is 16 byte */
12718 PageCode = (bit8)(pLogPage[24] & 0x3F); /* page code and index is 8 + 16 */
12719 StartingIndex = 24;
12720 }
12721 else if (BlkDescLen == 0)
12722 {
12723 /*
12724 mode parameter block descriptor does not exist
12725 */
12726 PageCode = (bit8)(pLogPage[8] & 0x3F); /* page code and index is 8 + 0 */
12727 StartingIndex = 8;
12728 ostiInitiatorIOCompleted( tiRoot,
12729 tiIORequest,
12730 tiIOSuccess,
12731 SCSI_STAT_GOOD,
12732 agNULL,
12733 satIOContext->interruptContext);
12734 return tiSuccess;
12735 }
12736 else
12737 {
12738 TI_DBG1(("satModeSelect10: return mode parameter block descriptor 0x%x\n", BlkDescLen));
12739 /* no more than one mode parameter block descriptor shall be supported */
12740 satSetSensePayload( pSense,
12741 SCSI_SNSKEY_NO_SENSE,
12742 0,
12743 SCSI_SNSCODE_NO_ADDITIONAL_INFO,
12744 satIOContext);
12745
12746 ostiInitiatorIOCompleted( tiRoot,
12747 tiIORequest,
12748 tiIOSuccess,
12749 SCSI_STAT_CHECK_CONDITION,
12750 satIOContext->pTiSenseData,
12751 satIOContext->interruptContext );
12752 return tiSuccess;
12753 }
12754 /*
12755 for debugging only
12756 */
12757 if (StartingIndex == 8)
12758 {
12759 tdhexdump("startingindex 8", (bit8 *)pLogPage, 8);
12760 }
12761 else if(StartingIndex == 16)
12762 {
12763 if (PageCode == MODESELECT_CACHING)
12764 {
12765 tdhexdump("startingindex 16", (bit8 *)pLogPage, 16+20);
12766 }
12767 else
12768 {
12769 tdhexdump("startingindex 16", (bit8 *)pLogPage, 16+12);
12770 }
12771 }
12772 else
12773 {
12774 if (PageCode == MODESELECT_CACHING)
12775 {
12776 tdhexdump("startingindex 24", (bit8 *)pLogPage, 24+20);
12777 }
12778 else
12779 {
12780 tdhexdump("startingindex 24", (bit8 *)pLogPage, 24+12);
12781 }
12782 }
12783 switch (PageCode) /* page code */
12784 {
12785 case MODESELECT_CONTROL_PAGE:
12786 TI_DBG5(("satModeSelect10: Control mode page\n"));
12787 /*
12788 compare pLogPage to expected value (SAT Table 65, p67)
12789 If not match, return check condition
12790 */
12791 if ( pLogPage[StartingIndex+1] != 0x0A ||
12792 pLogPage[StartingIndex+2] != 0x02 ||
12793 (pSatDevData->satNCQ == agTRUE && pLogPage[StartingIndex+3] != 0x12) ||
12794 (pSatDevData->satNCQ == agFALSE && pLogPage[StartingIndex+3] != 0x02) ||
12795 (pLogPage[StartingIndex+4] & BIT3_MASK) != 0x00 || /* SWP bit */
12796 (pLogPage[StartingIndex+4] & BIT4_MASK) != 0x00 || /* UA_INTLCK_CTRL */
12797 (pLogPage[StartingIndex+4] & BIT5_MASK) != 0x00 || /* UA_INTLCK_CTRL */
12798
12799 (pLogPage[StartingIndex+5] & BIT0_MASK) != 0x00 || /* AUTOLOAD MODE */
12800 (pLogPage[StartingIndex+5] & BIT1_MASK) != 0x00 || /* AUTOLOAD MODE */
12801 (pLogPage[StartingIndex+5] & BIT2_MASK) != 0x00 || /* AUTOLOAD MODE */
12802 (pLogPage[StartingIndex+5] & BIT6_MASK) != 0x00 || /* TAS bit */
12803
12804 pLogPage[StartingIndex+8] != 0xFF ||
12805 pLogPage[StartingIndex+9] != 0xFF ||
12806 pLogPage[StartingIndex+10] != 0x00 ||
12807 pLogPage[StartingIndex+11] != 0x00
12808 )
12809 {
12810 chkCnd = agTRUE;
12811 }
12812 if (chkCnd == agTRUE)
12813 {
12814 satSetSensePayload( pSense,
12815 SCSI_SNSKEY_ILLEGAL_REQUEST,
12816 0,
12817 SCSI_SNSCODE_INVALID_FIELD_IN_CDB,
12818 satIOContext);
12819
12820 ostiInitiatorIOCompleted( tiRoot,
12821 tiIORequest,
12822 tiIOSuccess,
12823 SCSI_STAT_CHECK_CONDITION,
12824 satIOContext->pTiSenseData,
12825 satIOContext->interruptContext );
12826
12827 TI_DBG1(("satModeSelect10: unexpected values\n"));
12828 }
12829 else
12830 {
12831 ostiInitiatorIOCompleted( tiRoot,
12832 tiIORequest,
12833 tiIOSuccess,
12834 SCSI_STAT_GOOD,
12835 agNULL,
12836 satIOContext->interruptContext);
12837 }
12838 return tiSuccess;
12839 break;
12840 case MODESELECT_READ_WRITE_ERROR_RECOVERY_PAGE:
12841 TI_DBG5(("satModeSelect10: Read-Write Error Recovery mode page\n"));
12842 if ( (pLogPage[StartingIndex + 2] & SCSI_MODE_SELECT10_AWRE_MASK) ||
12843 (pLogPage[StartingIndex + 2] & SCSI_MODE_SELECT10_RC_MASK) ||
12844 (pLogPage[StartingIndex + 2] & SCSI_MODE_SELECT10_EER_MASK) ||
12845 (pLogPage[StartingIndex + 2] & SCSI_MODE_SELECT10_PER_MASK) ||
12846 (pLogPage[StartingIndex + 2] & SCSI_MODE_SELECT10_DTE_MASK) ||
12847 (pLogPage[StartingIndex + 2] & SCSI_MODE_SELECT10_DCR_MASK) ||
12848 (pLogPage[StartingIndex + 10]) ||
12849 (pLogPage[StartingIndex + 11])
12850 )
12851 {
12852 TI_DBG1(("satModeSelect10: return check condition \n"));
12853
12854 satSetSensePayload( pSense,
12855 SCSI_SNSKEY_ILLEGAL_REQUEST,
12856 0,
12857 SCSI_SNSCODE_INVALID_FIELD_PARAMETER_LIST,
12858 satIOContext);
12859
12860 ostiInitiatorIOCompleted( tiRoot,
12861 tiIORequest,
12862 tiIOSuccess,
12863 SCSI_STAT_CHECK_CONDITION,
12864 satIOContext->pTiSenseData,
12865 satIOContext->interruptContext );
12866 return tiSuccess;
12867 }
12868 else
12869 {
12870 TI_DBG2(("satModeSelect10: return GOOD \n"));
12871 ostiInitiatorIOCompleted( tiRoot,
12872 tiIORequest,
12873 tiIOSuccess,
12874 SCSI_STAT_GOOD,
12875 agNULL,
12876 satIOContext->interruptContext);
12877 return tiSuccess;
12878 }
12879
12880 break;
12881 case MODESELECT_CACHING:
12882 /* SAT rev8 Table67, p69*/
12883 TI_DBG5(("satModeSelect10: Caching mode page\n"));
12884 if ( (pLogPage[StartingIndex + 2] & 0xFB) || /* 1111 1011 */
12885 (pLogPage[StartingIndex + 3]) ||
12886 (pLogPage[StartingIndex + 4]) ||
12887 (pLogPage[StartingIndex + 5]) ||
12888 (pLogPage[StartingIndex + 6]) ||
12889 (pLogPage[StartingIndex + 7]) ||
12890 (pLogPage[StartingIndex + 8]) ||
12891 (pLogPage[StartingIndex + 9]) ||
12892 (pLogPage[StartingIndex + 10]) ||
12893 (pLogPage[StartingIndex + 11]) ||
12894
12895 (pLogPage[StartingIndex + 12] & 0xC1) || /* 1100 0001 */
12896 (pLogPage[StartingIndex + 13]) ||
12897 (pLogPage[StartingIndex + 14]) ||
12898 (pLogPage[StartingIndex + 15])
12899 )
12900 {
12901 TI_DBG1(("satModeSelect10: return check condition \n"));
12902
12903 satSetSensePayload( pSense,
12904 SCSI_SNSKEY_ILLEGAL_REQUEST,
12905 0,
12906 SCSI_SNSCODE_INVALID_FIELD_PARAMETER_LIST,
12907 satIOContext);
12908
12909 ostiInitiatorIOCompleted( tiRoot,
12910 tiIORequest,
12911 tiIOSuccess,
12912 SCSI_STAT_CHECK_CONDITION,
12913 satIOContext->pTiSenseData,
12914 satIOContext->interruptContext );
12915 return tiSuccess;
12916
12917 }
12918 else
12919 {
12920 /* sends ATA SET FEATURES based on WCE bit */
12921 if ( !(pLogPage[StartingIndex + 2] & SCSI_MODE_SELECT10_WCE_MASK) )
12922 {
12923 TI_DBG5(("satModeSelect10: disable write cache\n"));
12924 /* sends SET FEATURES */
12925 fis->h.fisType = 0x27; /* Reg host to device */
12926 fis->h.c_pmPort = 0x80; /* C Bit is set */
12927
12928 fis->h.command = SAT_SET_FEATURES; /* 0xEF */
12929 fis->h.features = 0x82; /* disable write cache */
12930 fis->d.lbaLow = 0; /* */
12931 fis->d.lbaMid = 0; /* */
12932 fis->d.lbaHigh = 0; /* */
12933 fis->d.device = 0; /* */
12934 fis->d.lbaLowExp = 0; /* */
12935 fis->d.lbaMidExp = 0; /* */
12936 fis->d.lbaHighExp = 0; /* */
12937 fis->d.featuresExp = 0; /* */
12938 fis->d.sectorCount = 0; /* */
12939 fis->d.sectorCountExp = 0; /* */
12940 fis->d.reserved4 = 0;
12941 fis->d.control = 0; /* FIS HOB bit clear */
12942 fis->d.reserved5 = 0;
12943
12944 agRequestType = AGSA_SATA_PROTOCOL_NON_DATA;
12945
12946 /* Initialize CB for SATA completion.
12947 */
12948 satIOContext->satCompleteCB = &satModeSelect6n10CB;
12949
12950 /*
12951 * Prepare SGL and send FIS to LL layer.
12952 */
12953 satIOContext->reqType = agRequestType; /* Save it */
12954
12955 status = sataLLIOStart( tiRoot,
12956 tiIORequest,
12957 tiDeviceHandle,
12958 tiScsiRequest,
12959 satIOContext);
12960 return status;
12961 }
12962 else
12963 {
12964 TI_DBG5(("satModeSelect10: enable write cache\n"));
12965 /* sends SET FEATURES */
12966 fis->h.fisType = 0x27; /* Reg host to device */
12967 fis->h.c_pmPort = 0x80; /* C Bit is set */
12968
12969 fis->h.command = SAT_SET_FEATURES; /* 0xEF */
12970 fis->h.features = 0x02; /* enable write cache */
12971 fis->d.lbaLow = 0; /* */
12972 fis->d.lbaMid = 0; /* */
12973 fis->d.lbaHigh = 0; /* */
12974 fis->d.device = 0; /* */
12975 fis->d.lbaLowExp = 0; /* */
12976 fis->d.lbaMidExp = 0; /* */
12977 fis->d.lbaHighExp = 0; /* */
12978 fis->d.featuresExp = 0; /* */
12979 fis->d.sectorCount = 0; /* */
12980 fis->d.sectorCountExp = 0; /* */
12981 fis->d.reserved4 = 0;
12982 fis->d.control = 0; /* FIS HOB bit clear */
12983 fis->d.reserved5 = 0;
12984
12985 agRequestType = AGSA_SATA_PROTOCOL_NON_DATA;
12986
12987 /* Initialize CB for SATA completion.
12988 */
12989 satIOContext->satCompleteCB = &satModeSelect6n10CB;
12990
12991 /*
12992 * Prepare SGL and send FIS to LL layer.
12993 */
12994 satIOContext->reqType = agRequestType; /* Save it */
12995
12996 status = sataLLIOStart( tiRoot,
12997 tiIORequest,
12998 tiDeviceHandle,
12999 tiScsiRequest,
13000 satIOContext);
13001 return status;
13002
13003 }
13004 }
13005 break;
13006 case MODESELECT_INFORMATION_EXCEPTION_CONTROL_PAGE:
13007 TI_DBG5(("satModeSelect10: Informational Exception Control mode page\n"));
13008
13009 if ( (pLogPage[StartingIndex + 2] & SCSI_MODE_SELECT10_PERF_MASK) ||
13010 (pLogPage[StartingIndex + 2] & SCSI_MODE_SELECT10_TEST_MASK)
13011 )
13012 {
13013 TI_DBG1(("satModeSelect10: return check condition \n"));
13014
13015 satSetSensePayload( pSense,
13016 SCSI_SNSKEY_ILLEGAL_REQUEST,
13017 0,
13018 SCSI_SNSCODE_INVALID_FIELD_PARAMETER_LIST,
13019 satIOContext);
13020
13021 ostiInitiatorIOCompleted( tiRoot,
13022 tiIORequest,
13023 tiIOSuccess,
13024 SCSI_STAT_CHECK_CONDITION,
13025 satIOContext->pTiSenseData,
13026 satIOContext->interruptContext );
13027 return tiSuccess;
13028 }
13029 else
13030 {
13031 /* sends either ATA SMART ENABLE/DISABLE OPERATIONS based on DEXCPT bit */
13032 if ( !(pLogPage[StartingIndex + 2] & SCSI_MODE_SELECT10_DEXCPT_MASK) )
13033 {
13034 TI_DBG5(("satModeSelect10: enable information exceptions reporting\n"));
13035 /* sends SMART ENABLE OPERATIONS */
13036 fis->h.fisType = 0x27; /* Reg host to device */
13037 fis->h.c_pmPort = 0x80; /* C Bit is set */
13038
13039 fis->h.command = SAT_SMART_ENABLE_OPERATIONS; /* 0xB0 */
13040 fis->h.features = 0xD8; /* enable */
13041 fis->d.lbaLow = 0; /* */
13042 fis->d.lbaMid = 0x4F; /* 0x4F */
13043 fis->d.lbaHigh = 0xC2; /* 0xC2 */
13044 fis->d.device = 0; /* */
13045 fis->d.lbaLowExp = 0; /* */
13046 fis->d.lbaMidExp = 0; /* */
13047 fis->d.lbaHighExp = 0; /* */
13048 fis->d.featuresExp = 0; /* */
13049 fis->d.sectorCount = 0; /* */
13050 fis->d.sectorCountExp = 0; /* */
13051 fis->d.reserved4 = 0;
13052 fis->d.control = 0; /* FIS HOB bit clear */
13053 fis->d.reserved5 = 0;
13054
13055 agRequestType = AGSA_SATA_PROTOCOL_NON_DATA;
13056
13057 /* Initialize CB for SATA completion.
13058 */
13059 satIOContext->satCompleteCB = &satModeSelect6n10CB;
13060
13061 /*
13062 * Prepare SGL and send FIS to LL layer.
13063 */
13064 satIOContext->reqType = agRequestType; /* Save it */
13065
13066 status = sataLLIOStart( tiRoot,
13067 tiIORequest,
13068 tiDeviceHandle,
13069 tiScsiRequest,
13070 satIOContext);
13071 return status;
13072 }
13073 else
13074 {
13075 TI_DBG5(("satModeSelect10: disable information exceptions reporting\n"));
13076 /* sends SMART DISABLE OPERATIONS */
13077 fis->h.fisType = 0x27; /* Reg host to device */
13078 fis->h.c_pmPort = 0x80; /* C Bit is set */
13079
13080 fis->h.command = SAT_SMART_DISABLE_OPERATIONS; /* 0xB0 */
13081 fis->h.features = 0xD9; /* disable */
13082 fis->d.lbaLow = 0; /* */
13083 fis->d.lbaMid = 0x4F; /* 0x4F */
13084 fis->d.lbaHigh = 0xC2; /* 0xC2 */
13085 fis->d.device = 0; /* */
13086 fis->d.lbaLowExp = 0; /* */
13087 fis->d.lbaMidExp = 0; /* */
13088 fis->d.lbaHighExp = 0; /* */
13089 fis->d.featuresExp = 0; /* */
13090 fis->d.sectorCount = 0; /* */
13091 fis->d.sectorCountExp = 0; /* */
13092 fis->d.reserved4 = 0;
13093 fis->d.control = 0; /* FIS HOB bit clear */
13094 fis->d.reserved5 = 0;
13095
13096 agRequestType = AGSA_SATA_PROTOCOL_NON_DATA;
13097
13098 /* Initialize CB for SATA completion.
13099 */
13100 satIOContext->satCompleteCB = &satModeSelect6n10CB;
13101
13102 /*
13103 * Prepare SGL and send FIS to LL layer.
13104 */
13105 satIOContext->reqType = agRequestType; /* Save it */
13106
13107 status = sataLLIOStart( tiRoot,
13108 tiIORequest,
13109 tiDeviceHandle,
13110 tiScsiRequest,
13111 satIOContext);
13112 return status;
13113
13114 }
13115 }
13116 break;
13117 default:
13118 TI_DBG1(("satModeSelect10: Error unknown page code 0x%x\n", pLogPage[12]));
13119 satSetSensePayload( pSense,
13120 SCSI_SNSKEY_NO_SENSE,
13121 0,
13122 SCSI_SNSCODE_NO_ADDITIONAL_INFO,
13123 satIOContext);
13124
13125 ostiInitiatorIOCompleted( tiRoot,
13126 tiIORequest,
13127 tiIOSuccess,
13128 SCSI_STAT_CHECK_CONDITION,
13129 satIOContext->pTiSenseData,
13130 satIOContext->interruptContext );
13131 return tiSuccess;
13132 }
13133
13134 }
13135
13136
13137 /*****************************************************************************/
13138 /*! \brief SAT implementation for SCSI satSynchronizeCache10.
13139 *
13140 * SAT implementation for SCSI satSynchronizeCache10.
13141 *
13142 * \param tiRoot: Pointer to TISA initiator driver/port instance.
13143 * \param tiIORequest: Pointer to TISA I/O request context for this I/O.
13144 * \param tiDeviceHandle: Pointer to TISA device handle for this I/O.
13145 * \param tiScsiRequest: Pointer to TISA SCSI I/O request and SGL list.
13146 * \param satIOContext_t: Pointer to the SAT IO Context
13147 *
13148 * \return If command is started successfully
13149 * - \e tiSuccess: I/O request successfully initiated.
13150 * - \e tiBusy: No resources available, try again later.
13151 * - \e tiIONoDevice: Invalid device handle.
13152 * - \e tiError: Other errors.
13153 */
13154 /*****************************************************************************/
13155 GLOBAL bit32 satSynchronizeCache10(
13156 tiRoot_t *tiRoot,
13157 tiIORequest_t *tiIORequest,
13158 tiDeviceHandle_t *tiDeviceHandle,
13159 tiScsiInitiatorRequest_t *tiScsiRequest,
13160 satIOContext_t *satIOContext)
13161 {
13162 bit32 status;
13163 bit32 agRequestType;
13164 satDeviceData_t *pSatDevData;
13165 scsiRspSense_t *pSense;
13166 tiIniScsiCmnd_t *scsiCmnd;
13167 agsaFisRegHostToDevice_t *fis;
13168
13169 pSense = satIOContext->pSense;
13170 pSatDevData = satIOContext->pSatDevData;
13171 scsiCmnd = &tiScsiRequest->scsiCmnd;
13172 fis = satIOContext->pFis;
13173
13174 TI_DBG5(("satSynchronizeCache10: start\n"));
13175
13176 /* checking CONTROL */
13177 /* NACA == 1 or LINK == 1*/
13178 if ( (scsiCmnd->cdb[9] & SCSI_NACA_MASK) || (scsiCmnd->cdb[9] & SCSI_LINK_MASK) )
13179 {
13180 satSetSensePayload( pSense,
13181 SCSI_SNSKEY_ILLEGAL_REQUEST,
13182 0,
13183 SCSI_SNSCODE_INVALID_FIELD_IN_CDB,
13184 satIOContext);
13185
13186 ostiInitiatorIOCompleted( tiRoot,
13187 tiIORequest,
13188 tiIOSuccess,
13189 SCSI_STAT_CHECK_CONDITION,
13190 satIOContext->pTiSenseData,
13191 satIOContext->interruptContext );
13192
13193 TI_DBG2(("satSynchronizeCache10: return control\n"));
13194 return tiSuccess;
13195 }
13196
13197 /* checking IMMED bit */
13198 if (scsiCmnd->cdb[1] & SCSI_SYNC_CACHE_IMMED_MASK)
13199 {
13200 TI_DBG1(("satSynchronizeCache10: GOOD status due to IMMED bit\n"));
13201
13202 /* return GOOD status first here */
13203 ostiInitiatorIOCompleted( tiRoot,
13204 tiIORequest,
13205 tiIOSuccess,
13206 SCSI_STAT_GOOD,
13207 agNULL,
13208 satIOContext->interruptContext);
13209 }
13210
13211 /* sends FLUSH CACHE or FLUSH CACHE EXT */
13212 if (pSatDevData->sat48BitSupport == agTRUE)
13213 {
13214 TI_DBG5(("satSynchronizeCache10: sends FLUSH CACHE EXT\n"));
13215 /* FLUSH CACHE EXT */
13216 fis->h.fisType = 0x27; /* Reg host to device */
13217 fis->h.c_pmPort = 0x80; /* C Bit is set */
13218
13219 fis->h.command = SAT_FLUSH_CACHE_EXT; /* 0xEA */
13220 fis->h.features = 0; /* FIS reserve */
13221 fis->d.featuresExp = 0; /* FIS reserve */
13222 fis->d.sectorCount = 0; /* FIS sector count (7:0) */
13223 fis->d.sectorCountExp = 0; /* FIS sector count (15:8) */
13224 fis->d.lbaLow = 0; /* FIS LBA (7 :0 ) */
13225 fis->d.lbaLowExp = 0; /* FIS LBA (31:24) */
13226 fis->d.lbaMid = 0; /* FIS LBA (15:8 ) */
13227 fis->d.lbaMidExp = 0; /* FIS LBA (39:32) */
13228 fis->d.lbaHigh = 0; /* FIS LBA (23:16) */
13229 fis->d.lbaHighExp = 0; /* FIS LBA (47:40) */
13230 fis->d.device = 0; /* FIS DEV is discared in SATA */
13231 fis->d.control = 0; /* FIS HOB bit clear */
13232 fis->d.reserved4 = 0;
13233 fis->d.reserved5 = 0;
13234
13235 }
13236 else
13237 {
13238 TI_DBG5(("satSynchronizeCache10: sends FLUSH CACHE\n"));
13239 /* FLUSH CACHE */
13240 fis->h.fisType = 0x27; /* Reg host to device */
13241 fis->h.c_pmPort = 0x80; /* C Bit is set */
13242
13243 fis->h.command = SAT_FLUSH_CACHE; /* 0xE7 */
13244 fis->h.features = 0; /* FIS features NA */
13245 fis->d.lbaLow = 0; /* FIS LBA (7 :0 ) */
13246 fis->d.lbaMid = 0; /* FIS LBA (15:8 ) */
13247 fis->d.lbaHigh = 0; /* FIS LBA (23:16) */
13248 fis->d.lbaLowExp = 0;
13249 fis->d.lbaMidExp = 0;
13250 fis->d.lbaHighExp = 0;
13251 fis->d.featuresExp = 0;
13252 fis->d.sectorCount = 0; /* FIS sector count (7:0) */
13253 fis->d.sectorCountExp = 0;
13254 fis->d.device = 0; /* FIS DEV is discared in SATA */
13255 fis->d.control = 0; /* FIS HOB bit clear */
13256 fis->d.reserved4 = 0;
13257 fis->d.reserved5 = 0;
13258
13259 }
13260
13261 agRequestType = AGSA_SATA_PROTOCOL_NON_DATA;
13262
13263 /* Initialize CB for SATA completion.
13264 */
13265 satIOContext->satCompleteCB = &satSynchronizeCache10n16CB;
13266
13267 /*
13268 * Prepare SGL and send FIS to LL layer.
13269 */
13270 satIOContext->reqType = agRequestType; /* Save it */
13271
13272 status = sataLLIOStart( tiRoot,
13273 tiIORequest,
13274 tiDeviceHandle,
13275 tiScsiRequest,
13276 satIOContext);
13277
13278
13279 return (status);
13280 }
13281
13282 /*****************************************************************************/
13283 /*! \brief SAT implementation for SCSI satSynchronizeCache16.
13284 *
13285 * SAT implementation for SCSI satSynchronizeCache16.
13286 *
13287 * \param tiRoot: Pointer to TISA initiator driver/port instance.
13288 * \param tiIORequest: Pointer to TISA I/O request context for this I/O.
13289 * \param tiDeviceHandle: Pointer to TISA device handle for this I/O.
13290 * \param tiScsiRequest: Pointer to TISA SCSI I/O request and SGL list.
13291 * \param satIOContext_t: Pointer to the SAT IO Context
13292 *
13293 * \return If command is started successfully
13294 * - \e tiSuccess: I/O request successfully initiated.
13295 * - \e tiBusy: No resources available, try again later.
13296 * - \e tiIONoDevice: Invalid device handle.
13297 * - \e tiError: Other errors.
13298 */
13299 /*****************************************************************************/
13300 GLOBAL bit32 satSynchronizeCache16(
13301 tiRoot_t *tiRoot,
13302 tiIORequest_t *tiIORequest,
13303 tiDeviceHandle_t *tiDeviceHandle,
13304 tiScsiInitiatorRequest_t *tiScsiRequest,
13305 satIOContext_t *satIOContext)
13306 {
13307 bit32 status;
13308 bit32 agRequestType;
13309 satDeviceData_t *pSatDevData;
13310 scsiRspSense_t *pSense;
13311 tiIniScsiCmnd_t *scsiCmnd;
13312 agsaFisRegHostToDevice_t *fis;
13313
13314 pSense = satIOContext->pSense;
13315 pSatDevData = satIOContext->pSatDevData;
13316 scsiCmnd = &tiScsiRequest->scsiCmnd;
13317 fis = satIOContext->pFis;
13318
13319 TI_DBG5(("satSynchronizeCache16: start\n"));
13320
13321 /* checking CONTROL */
13322 /* NACA == 1 or LINK == 1*/
13323 if ( (scsiCmnd->cdb[15] & SCSI_NACA_MASK) || (scsiCmnd->cdb[15] & SCSI_LINK_MASK) )
13324 {
13325 satSetSensePayload( pSense,
13326 SCSI_SNSKEY_ILLEGAL_REQUEST,
13327 0,
13328 SCSI_SNSCODE_INVALID_FIELD_IN_CDB,
13329 satIOContext);
13330
13331 ostiInitiatorIOCompleted( tiRoot,
13332 tiIORequest,
13333 tiIOSuccess,
13334 SCSI_STAT_CHECK_CONDITION,
13335 satIOContext->pTiSenseData,
13336 satIOContext->interruptContext );
13337
13338 TI_DBG1(("satSynchronizeCache16: return control\n"));
13339 return tiSuccess;
13340 }
13341
13342
13343 /* checking IMMED bit */
13344 if (scsiCmnd->cdb[1] & SCSI_SYNC_CACHE_IMMED_MASK)
13345 {
13346 TI_DBG1(("satSynchronizeCache16: GOOD status due to IMMED bit\n"));
13347
13348 /* return GOOD status first here */
13349 ostiInitiatorIOCompleted( tiRoot,
13350 tiIORequest,
13351 tiIOSuccess,
13352 SCSI_STAT_GOOD,
13353 agNULL,
13354 satIOContext->interruptContext);
13355 }
13356
13357 /* sends FLUSH CACHE or FLUSH CACHE EXT */
13358 if (pSatDevData->sat48BitSupport == agTRUE)
13359 {
13360 TI_DBG5(("satSynchronizeCache16: sends FLUSH CACHE EXT\n"));
13361 /* FLUSH CACHE EXT */
13362 fis->h.fisType = 0x27; /* Reg host to device */
13363 fis->h.c_pmPort = 0x80; /* C Bit is set */
13364
13365 fis->h.command = SAT_FLUSH_CACHE_EXT; /* 0xEA */
13366 fis->h.features = 0; /* FIS reserve */
13367 fis->d.featuresExp = 0; /* FIS reserve */
13368 fis->d.sectorCount = 0; /* FIS sector count (7:0) */
13369 fis->d.sectorCountExp = 0; /* FIS sector count (15:8) */
13370 fis->d.lbaLow = 0; /* FIS LBA (7 :0 ) */
13371 fis->d.lbaLowExp = 0; /* FIS LBA (31:24) */
13372 fis->d.lbaMid = 0; /* FIS LBA (15:8 ) */
13373 fis->d.lbaMidExp = 0; /* FIS LBA (39:32) */
13374 fis->d.lbaHigh = 0; /* FIS LBA (23:16) */
13375 fis->d.lbaHighExp = 0; /* FIS LBA (47:40) */
13376 fis->d.device = 0; /* FIS DEV is discared in SATA */
13377 fis->d.control = 0; /* FIS HOB bit clear */
13378 fis->d.reserved4 = 0;
13379 fis->d.reserved5 = 0;
13380
13381 }
13382 else
13383 {
13384 TI_DBG5(("satSynchronizeCache16: sends FLUSH CACHE\n"));
13385 /* FLUSH CACHE */
13386 fis->h.fisType = 0x27; /* Reg host to device */
13387 fis->h.c_pmPort = 0x80; /* C Bit is set */
13388
13389 fis->h.command = SAT_FLUSH_CACHE; /* 0xE7 */
13390 fis->h.features = 0; /* FIS features NA */
13391 fis->d.lbaLow = 0; /* FIS LBA (7 :0 ) */
13392 fis->d.lbaMid = 0; /* FIS LBA (15:8 ) */
13393 fis->d.lbaHigh = 0; /* FIS LBA (23:16) */
13394 fis->d.lbaLowExp = 0;
13395 fis->d.lbaMidExp = 0;
13396 fis->d.lbaHighExp = 0;
13397 fis->d.featuresExp = 0;
13398 fis->d.sectorCount = 0; /* FIS sector count (7:0) */
13399 fis->d.sectorCountExp = 0;
13400 fis->d.device = 0; /* FIS DEV is discared in SATA */
13401 fis->d.control = 0; /* FIS HOB bit clear */
13402 fis->d.reserved4 = 0;
13403 fis->d.reserved5 = 0;
13404
13405 }
13406
13407 agRequestType = AGSA_SATA_PROTOCOL_NON_DATA;
13408
13409 /* Initialize CB for SATA completion.
13410 */
13411 satIOContext->satCompleteCB = &satSynchronizeCache10n16CB;
13412
13413 /*
13414 * Prepare SGL and send FIS to LL layer.
13415 */
13416 satIOContext->reqType = agRequestType; /* Save it */
13417
13418 status = sataLLIOStart( tiRoot,
13419 tiIORequest,
13420 tiDeviceHandle,
13421 tiScsiRequest,
13422 satIOContext);
13423
13424
13425 return (status);
13426 }
13427
13428
13429 /*****************************************************************************/
13430 /*! \brief SAT implementation for SCSI satWriteAndVerify10.
13431 *
13432 * SAT implementation for SCSI satWriteAndVerify10.
13433 *
13434 * \param tiRoot: Pointer to TISA initiator driver/port instance.
13435 * \param tiIORequest: Pointer to TISA I/O request context for this I/O.
13436 * \param tiDeviceHandle: Pointer to TISA device handle for this I/O.
13437 * \param tiScsiRequest: Pointer to TISA SCSI I/O request and SGL list.
13438 * \param satIOContext_t: Pointer to the SAT IO Context
13439 *
13440 * \return If command is started successfully
13441 * - \e tiSuccess: I/O request successfully initiated.
13442 * - \e tiBusy: No resources available, try again later.
13443 * - \e tiIONoDevice: Invalid device handle.
13444 * - \e tiError: Other errors.
13445 */
13446 /*****************************************************************************/
13447 GLOBAL bit32 satWriteAndVerify10(
13448 tiRoot_t *tiRoot,
13449 tiIORequest_t *tiIORequest,
13450 tiDeviceHandle_t *tiDeviceHandle,
13451 tiScsiInitiatorRequest_t *tiScsiRequest,
13452 satIOContext_t *satIOContext)
13453 {
13454 /*
13455 combination of write10 and verify10
13456 */
13457
13458 bit32 status;
13459 bit32 agRequestType = AGSA_SATA_PROTOCOL_DMA_WRITE;
13460 satDeviceData_t *pSatDevData;
13461 scsiRspSense_t *pSense;
13462 tiIniScsiCmnd_t *scsiCmnd;
13463 agsaFisRegHostToDevice_t *fis;
13464 bit32 lba = 0;
13465 bit32 tl = 0;
13466 bit32 LoopNum = 1;
13467 bit8 LBA[4];
13468 bit8 TL[4];
13469 bit32 rangeChk = agFALSE; /* lba and tl range check */
13470
13471 pSense = satIOContext->pSense;
13472 pSatDevData = satIOContext->pSatDevData;
13473 scsiCmnd = &tiScsiRequest->scsiCmnd;
13474 fis = satIOContext->pFis;
13475
13476 TI_DBG5(("satWriteAndVerify10: start\n"));
13477
13478
13479 /* checking BYTCHK bit */
13480 if (scsiCmnd->cdb[1] & SCSI_WRITE_N_VERIFY_BYTCHK_MASK)
13481 {
13482 satSetSensePayload( pSense,
13483 SCSI_SNSKEY_ILLEGAL_REQUEST,
13484 0,
13485 SCSI_SNSCODE_INVALID_FIELD_IN_CDB,
13486 satIOContext);
13487
13488 ostiInitiatorIOCompleted( tiRoot,
13489 tiIORequest,
13490 tiIOSuccess,
13491 SCSI_STAT_CHECK_CONDITION,
13492 satIOContext->pTiSenseData,
13493 satIOContext->interruptContext );
13494
13495 TI_DBG1(("satWriteAndVerify10: BYTCHK bit checking \n"));
13496 return tiSuccess;
13497 }
13498
13499
13500 /* checking CONTROL */
13501 /* NACA == 1 or LINK == 1*/
13502 if ( (scsiCmnd->cdb[9] & SCSI_NACA_MASK) || (scsiCmnd->cdb[9] & SCSI_LINK_MASK) )
13503 {
13504 satSetSensePayload( pSense,
13505 SCSI_SNSKEY_ILLEGAL_REQUEST,
13506 0,
13507 SCSI_SNSCODE_INVALID_FIELD_IN_CDB,
13508 satIOContext);
13509
13510 ostiInitiatorIOCompleted( tiRoot,
13511 tiIORequest,
13512 tiIOSuccess,
13513 SCSI_STAT_CHECK_CONDITION,
13514 satIOContext->pTiSenseData,
13515 satIOContext->interruptContext );
13516
13517 TI_DBG1(("satWriteAndVerify10: return control\n"));
13518 return tiSuccess;
13519 }
13520
13521 osti_memset(LBA, 0, sizeof(LBA));
13522 osti_memset(TL, 0, sizeof(TL));
13523
13524 /* do not use memcpy due to indexing in LBA and TL */
13525 LBA[0] = scsiCmnd->cdb[2]; /* MSB */
13526 LBA[1] = scsiCmnd->cdb[3];
13527 LBA[2] = scsiCmnd->cdb[4];
13528 LBA[3] = scsiCmnd->cdb[5]; /* LSB */
13529
13530 TL[0] = 0;
13531 TL[1] = 0;
13532 TL[2] = scsiCmnd->cdb[7]; /* MSB */
13533 TL[3] = scsiCmnd->cdb[8]; /* LSB */
13534
13535 rangeChk = satAddNComparebit32(LBA, TL);
13536
13537 /* cbd10; computing LBA and transfer length */
13538 lba = (scsiCmnd->cdb[2] << (8*3)) + (scsiCmnd->cdb[3] << (8*2))
13539 + (scsiCmnd->cdb[4] << 8) + scsiCmnd->cdb[5];
13540 tl = (scsiCmnd->cdb[7] << 8) + scsiCmnd->cdb[8];
13541
13542
13543 /* Table 34, 9.1, p 46 */
13544 /*
13545 note: As of 2/10/2006, no support for DMA QUEUED
13546 */
13547
13548 /*
13549 Table 34, 9.1, p 46, b
13550 When no 48-bit addressing support or NCQ, if LBA is beyond (2^28 - 1),
13551 return check condition
13552 */
13553 if (pSatDevData->satNCQ != agTRUE &&
13554 pSatDevData->sat48BitSupport != agTRUE
13555 )
13556 {
13557 if (lba > SAT_TR_LBA_LIMIT - 1)
13558 {
13559 satSetSensePayload( pSense,
13560 SCSI_SNSKEY_ILLEGAL_REQUEST,
13561 0,
13562 SCSI_SNSCODE_LOGICAL_BLOCK_ADDRESS_OUT_OF_RANGE,
13563 satIOContext);
13564
13565 ostiInitiatorIOCompleted( tiRoot,
13566 tiIORequest,
13567 tiIOSuccess,
13568 SCSI_STAT_CHECK_CONDITION,
13569 satIOContext->pTiSenseData,
13570 satIOContext->interruptContext );
13571
13572 TI_DBG1(("satWriteAndVerify10: return LBA out of range\n"));
13573 return tiSuccess;
13574 }
13575
13576 if (rangeChk) // if (lba + tl > SAT_TR_LBA_LIMIT)
13577 {
13578 TI_DBG1(("satWrite10: return LBA+TL out of range, not EXT\n"));
13579 satSetSensePayload( pSense,
13580 SCSI_SNSKEY_ILLEGAL_REQUEST,
13581 0,
13582 SCSI_SNSCODE_LOGICAL_BLOCK_ADDRESS_OUT_OF_RANGE,
13583 satIOContext);
13584
13585 ostiInitiatorIOCompleted( tiRoot,
13586 tiIORequest,
13587 tiIOSuccess,
13588 SCSI_STAT_CHECK_CONDITION,
13589 satIOContext->pTiSenseData,
13590 satIOContext->interruptContext );
13591
13592 return tiSuccess;
13593 }
13594 }
13595
13596
13597 /* case 1 and 2 */
13598 if (!rangeChk) // if (lba + tl <= SAT_TR_LBA_LIMIT)
13599 {
13600 if (pSatDevData->satDMASupport == agTRUE && pSatDevData->satDMAEnabled == agTRUE)
13601 {
13602 /* case 2 */
13603 /* WRITE DMA*/
13604 /* can't fit the transfer length */
13605 TI_DBG5(("satWriteAndVerify10: case 2 !!!\n"));
13606 fis->h.fisType = 0x27; /* Reg host to device */
13607 fis->h.c_pmPort = 0x80; /* C bit is set */
13608 fis->h.command = SAT_WRITE_DMA; /* 0xCA */
13609 fis->h.features = 0; /* FIS reserve */
13610 fis->d.lbaLow = scsiCmnd->cdb[5]; /* FIS LBA (7 :0 ) */
13611 fis->d.lbaMid = scsiCmnd->cdb[4]; /* FIS LBA (15:8 ) */
13612 fis->d.lbaHigh = scsiCmnd->cdb[3]; /* FIS LBA (23:16) */
13613
13614 /* FIS LBA mode set LBA (27:24) */
13615 fis->d.device = (bit8)((0x4 << 4) | (scsiCmnd->cdb[2] & 0xF));
13616
13617 fis->d.lbaLowExp = 0;
13618 fis->d.lbaMidExp = 0;
13619 fis->d.lbaHighExp = 0;
13620 fis->d.featuresExp = 0;
13621 fis->d.sectorCount = scsiCmnd->cdb[8]; /* FIS sector count (7:0) */
13622 fis->d.sectorCountExp = 0;
13623 fis->d.reserved4 = 0;
13624 fis->d.control = 0; /* FIS HOB bit clear */
13625 fis->d.reserved5 = 0;
13626
13627 agRequestType = AGSA_SATA_PROTOCOL_DMA_WRITE;
13628 satIOContext->ATACmd = SAT_WRITE_DMA;
13629 }
13630 else
13631 {
13632 /* case 1 */
13633 /* WRITE MULTIPLE or WRITE SECTOR(S) */
13634 /* WRITE SECTORS for easier implemetation */
13635 /* can't fit the transfer length */
13636 TI_DBG5(("satWriteAndVerify10: case 1 !!!\n"));
13637 fis->h.fisType = 0x27; /* Reg host to device */
13638 fis->h.c_pmPort = 0x80; /* C bit is set */
13639 fis->h.command = SAT_WRITE_SECTORS; /* 0x30 */
13640 fis->h.features = 0; /* FIS reserve */
13641 fis->d.lbaLow = scsiCmnd->cdb[5]; /* FIS LBA (7 :0 ) */
13642 fis->d.lbaMid = scsiCmnd->cdb[4]; /* FIS LBA (15:8 ) */
13643 fis->d.lbaHigh = scsiCmnd->cdb[3]; /* FIS LBA (23:16) */
13644
13645 /* FIS LBA mode set LBA (27:24) */
13646 fis->d.device = (bit8)((0x4 << 4) | (scsiCmnd->cdb[2] & 0xF));
13647
13648 fis->d.lbaLowExp = 0;
13649 fis->d.lbaMidExp = 0;
13650 fis->d.lbaHighExp = 0;
13651 fis->d.featuresExp = 0;
13652 fis->d.sectorCount = scsiCmnd->cdb[8]; /* FIS sector count (7:0) */
13653 fis->d.sectorCountExp = 0;
13654 fis->d.reserved4 = 0;
13655 fis->d.control = 0; /* FIS HOB bit clear */
13656 fis->d.reserved5 = 0;
13657
13658 agRequestType = AGSA_SATA_PROTOCOL_PIO_WRITE;
13659 satIOContext->ATACmd = SAT_WRITE_SECTORS;
13660
13661 }
13662 }
13663
13664 /* case 3 and 4 */
13665 if (pSatDevData->sat48BitSupport == agTRUE)
13666 {
13667 if (pSatDevData->satDMASupport == agTRUE && pSatDevData->satDMAEnabled == agTRUE)
13668 {
13669 /* case 3 */
13670 /* WRITE DMA EXT or WRITE DMA FUA EXT */
13671 TI_DBG5(("satWriteAndVerify10: case 3\n"));
13672 fis->h.fisType = 0x27; /* Reg host to device */
13673 fis->h.c_pmPort = 0x80; /* C Bit is set */
13674
13675 /* SAT_WRITE_DMA_FUA_EXT is optional and we don't support it */
13676 fis->h.command = SAT_WRITE_DMA_EXT; /* 0x35 */
13677
13678 fis->h.features = 0; /* FIS reserve */
13679 fis->d.lbaLow = scsiCmnd->cdb[5]; /* FIS LBA (7 :0 ) */
13680 fis->d.lbaMid = scsiCmnd->cdb[4]; /* FIS LBA (15:8 ) */
13681 fis->d.lbaHigh = scsiCmnd->cdb[3]; /* FIS LBA (23:16) */
13682 fis->d.device = 0x40; /* FIS LBA mode set */
13683 fis->d.lbaLowExp = scsiCmnd->cdb[2]; /* FIS LBA (31:24) */
13684 fis->d.lbaMidExp = 0; /* FIS LBA (39:32) */
13685 fis->d.lbaHighExp = 0; /* FIS LBA (47:40) */
13686 fis->d.featuresExp = 0; /* FIS reserve */
13687 fis->d.sectorCount = scsiCmnd->cdb[8]; /* FIS sector count (7:0) */
13688 fis->d.sectorCountExp = scsiCmnd->cdb[7]; /* FIS sector count (15:8) */
13689 fis->d.reserved4 = 0;
13690 fis->d.control = 0; /* FIS HOB bit clear */
13691 fis->d.reserved5 = 0;
13692
13693 agRequestType = AGSA_SATA_PROTOCOL_DMA_WRITE;
13694 satIOContext->ATACmd = SAT_WRITE_DMA_EXT;
13695 }
13696 else
13697 {
13698 /* case 4 */
13699 /* WRITE MULTIPLE EXT or WRITE MULTIPLE FUA EXT or WRITE SECTOR(S) EXT */
13700 /* WRITE SECTORS EXT for easier implemetation */
13701 TI_DBG5(("satWriteAndVerify10: case 4\n"));
13702 fis->h.fisType = 0x27; /* Reg host to device */
13703 fis->h.c_pmPort = 0x80; /* C Bit is set */
13704 fis->h.command = SAT_WRITE_SECTORS_EXT; /* 0x34 */
13705
13706 fis->h.features = 0; /* FIS reserve */
13707 fis->d.lbaLow = scsiCmnd->cdb[5]; /* FIS LBA (7 :0 ) */
13708 fis->d.lbaMid = scsiCmnd->cdb[4]; /* FIS LBA (15:8 ) */
13709 fis->d.lbaHigh = scsiCmnd->cdb[3]; /* FIS LBA (23:16) */
13710 fis->d.device = 0x40; /* FIS LBA mode set */
13711 fis->d.lbaLowExp = scsiCmnd->cdb[2]; /* FIS LBA (31:24) */
13712 fis->d.lbaMidExp = 0; /* FIS LBA (39:32) */
13713 fis->d.lbaHighExp = 0; /* FIS LBA (47:40) */
13714 fis->d.featuresExp = 0; /* FIS reserve */
13715 fis->d.sectorCount = scsiCmnd->cdb[8]; /* FIS sector count (7:0) */
13716 fis->d.sectorCountExp = scsiCmnd->cdb[7]; /* FIS sector count (15:8) */
13717 fis->d.reserved4 = 0;
13718 fis->d.control = 0; /* FIS HOB bit clear */
13719 fis->d.reserved5 = 0;
13720
13721 agRequestType = AGSA_SATA_PROTOCOL_PIO_WRITE;
13722 satIOContext->ATACmd = SAT_WRITE_SECTORS_EXT;
13723 }
13724 }
13725 /* case 5 */
13726 if (pSatDevData->satNCQ == agTRUE)
13727 {
13728 /* WRITE FPDMA QUEUED */
13729 if (pSatDevData->sat48BitSupport != agTRUE)
13730 {
13731 TI_DBG5(("satWriteAndVerify10: case 5 !!! error NCQ but 28 bit address support \n"));
13732 satSetSensePayload( pSense,
13733 SCSI_SNSKEY_ILLEGAL_REQUEST,
13734 0,
13735 SCSI_SNSCODE_INVALID_FIELD_IN_CDB,
13736 satIOContext);
13737
13738 ostiInitiatorIOCompleted( tiRoot,
13739 tiIORequest,
13740 tiIOSuccess,
13741 SCSI_STAT_CHECK_CONDITION,
13742 satIOContext->pTiSenseData,
13743 satIOContext->interruptContext );
13744 return tiSuccess;
13745 }
13746 TI_DBG5(("satWriteAndVerify10: case 5\n"));
13747
13748 /* Support 48-bit FPDMA addressing, use WRITE FPDMA QUEUE command */
13749
13750 fis->h.fisType = 0x27; /* Reg host to device */
13751 fis->h.c_pmPort = 0x80; /* C Bit is set */
13752 fis->h.command = SAT_WRITE_FPDMA_QUEUED; /* 0x61 */
13753 fis->h.features = scsiCmnd->cdb[8]; /* FIS sector count (7:0) */
13754 fis->d.lbaLow = scsiCmnd->cdb[5]; /* FIS LBA (7 :0 ) */
13755 fis->d.lbaMid = scsiCmnd->cdb[4]; /* FIS LBA (15:8 ) */
13756 fis->d.lbaHigh = scsiCmnd->cdb[3]; /* FIS LBA (23:16) */
13757
13758 /* Check FUA bit */
13759 if (scsiCmnd->cdb[1] & SCSI_WRITE_N_VERIFY10_FUA_MASK)
13760 fis->d.device = 0xC0; /* FIS FUA set */
13761 else
13762 fis->d.device = 0x40; /* FIS FUA clear */
13763
13764 fis->d.lbaLowExp = scsiCmnd->cdb[2]; /* FIS LBA (31:24) */
13765 fis->d.lbaMidExp = 0; /* FIS LBA (39:32) */
13766 fis->d.lbaHighExp = 0; /* FIS LBA (47:40) */
13767 fis->d.featuresExp = scsiCmnd->cdb[7]; /* FIS sector count (15:8) */
13768 fis->d.sectorCount = 0; /* Tag (7:3) set by LL layer */
13769 fis->d.sectorCountExp = 0;
13770 fis->d.reserved4 = 0;
13771 fis->d.control = 0; /* FIS HOB bit clear */
13772 fis->d.reserved5 = 0;
13773
13774 agRequestType = AGSA_SATA_PROTOCOL_FPDMA_WRITE;
13775 satIOContext->ATACmd = SAT_WRITE_FPDMA_QUEUED;
13776 }
13777
13778 satIOContext->currentLBA = lba;
13779 satIOContext->OrgTL = tl;
13780
13781 /*
13782 computing number of loop and remainder for tl
13783 0xFF in case not ext
13784 0xFFFF in case EXT
13785 */
13786 if (fis->h.command == SAT_WRITE_SECTORS || fis->h.command == SAT_WRITE_DMA)
13787 {
13788 LoopNum = satComputeLoopNum(tl, 0xFF);
13789 }
13790 else if (fis->h.command == SAT_WRITE_SECTORS_EXT ||
13791 fis->h.command == SAT_WRITE_DMA_EXT ||
13792 fis->h.command == SAT_WRITE_DMA_FUA_EXT
13793 )
13794 {
13795 /* SAT_READ_SECTORS_EXT, SAT_READ_DMA_EXT */
13796 LoopNum = satComputeLoopNum(tl, 0xFFFF);
13797 }
13798 else
13799 {
13800 /* SAT_WRITE_FPDMA_QUEUED */
13801 LoopNum = satComputeLoopNum(tl, 0xFFFF);
13802 }
13803
13804 satIOContext->LoopNum = LoopNum;
13805
13806
13807 if (LoopNum == 1)
13808 {
13809 TI_DBG5(("satWriteAndVerify10: NON CHAINED data\n"));
13810 /* Initialize CB for SATA completion.
13811 */
13812 satIOContext->satCompleteCB = &satNonChainedWriteNVerifyCB;
13813 }
13814 else
13815 {
13816 TI_DBG1(("satWriteAndVerify10: CHAINED data\n"));
13817 /* re-setting tl */
13818 if (fis->h.command == SAT_WRITE_SECTORS || fis->h.command == SAT_WRITE_DMA)
13819 {
13820 fis->d.sectorCount = 0xFF;
13821 }
13822 else if (fis->h.command == SAT_WRITE_SECTORS_EXT ||
13823 fis->h.command == SAT_WRITE_DMA_EXT ||
13824 fis->h.command == SAT_WRITE_DMA_FUA_EXT
13825 )
13826 {
13827 fis->d.sectorCount = 0xFF;
13828 fis->d.sectorCountExp = 0xFF;
13829 }
13830 else
13831 {
13832 /* SAT_WRITE_FPDMA_QUEUED */
13833 fis->h.features = 0xFF;
13834 fis->d.featuresExp = 0xFF;
13835 }
13836
13837 /* Initialize CB for SATA completion.
13838 */
13839 satIOContext->satCompleteCB = &satChainedWriteNVerifyCB;
13840 }
13841
13842
13843 /*
13844 * Prepare SGL and send FIS to LL layer.
13845 */
13846 satIOContext->reqType = agRequestType; /* Save it */
13847
13848 status = sataLLIOStart( tiRoot,
13849 tiIORequest,
13850 tiDeviceHandle,
13851 tiScsiRequest,
13852 satIOContext);
13853 return (status);
13854
13855 }
13856
13857
13858
13859
13860
13861
13862 #ifdef REMOVED
13863 GLOBAL bit32 satWriteAndVerify10(
13864 tiRoot_t *tiRoot,
13865 tiIORequest_t *tiIORequest,
13866 tiDeviceHandle_t *tiDeviceHandle,
13867 tiScsiInitiatorRequest_t *tiScsiRequest,
13868 satIOContext_t *satIOContext)
13869 {
13870 /*
13871 combination of write10 and verify10
13872 */
13873
13874 bit32 status;
13875 bit32 agRequestType = AGSA_SATA_PROTOCOL_DMA_WRITE;
13876 satDeviceData_t *pSatDevData;
13877 scsiRspSense_t *pSense;
13878 tiIniScsiCmnd_t *scsiCmnd;
13879 agsaFisRegHostToDevice_t *fis;
13880 bit32 lba = 0;
13881 bit32 tl = 0;
13882
13883 pSense = satIOContext->pSense;
13884 pSatDevData = satIOContext->pSatDevData;
13885 scsiCmnd = &tiScsiRequest->scsiCmnd;
13886 fis = satIOContext->pFis;
13887
13888 TI_DBG5(("satWriteAndVerify10: start\n"));
13889
13890
13891 /* checking BYTCHK bit */
13892 if (scsiCmnd->cdb[1] & SCSI_WRITE_N_VERIFY_BYTCHK_MASK)
13893 {
13894 satSetSensePayload( pSense,
13895 SCSI_SNSKEY_ILLEGAL_REQUEST,
13896 0,
13897 SCSI_SNSCODE_INVALID_FIELD_IN_CDB,
13898 satIOContext);
13899
13900 ostiInitiatorIOCompleted( tiRoot,
13901 tiIORequest,
13902 tiIOSuccess,
13903 SCSI_STAT_CHECK_CONDITION,
13904 satIOContext->pTiSenseData,
13905 satIOContext->interruptContext );
13906
13907 TI_DBG1(("satWriteAndVerify10: BYTCHK bit checking \n"));
13908 return tiSuccess;
13909 }
13910
13911
13912 /* checking CONTROL */
13913 /* NACA == 1 or LINK == 1*/
13914 if ( (scsiCmnd->cdb[9] & SCSI_NACA_MASK) || (scsiCmnd->cdb[9] & SCSI_LINK_MASK) )
13915 {
13916 satSetSensePayload( pSense,
13917 SCSI_SNSKEY_ILLEGAL_REQUEST,
13918 0,
13919 SCSI_SNSCODE_INVALID_FIELD_IN_CDB,
13920 satIOContext);
13921
13922 ostiInitiatorIOCompleted( tiRoot,
13923 tiIORequest,
13924 tiIOSuccess,
13925 SCSI_STAT_CHECK_CONDITION,
13926 satIOContext->pTiSenseData,
13927 satIOContext->interruptContext );
13928
13929 TI_DBG2(("satWriteAndVerify10: return control\n"));
13930 return tiSuccess;
13931 }
13932
13933 /* let's do write10 */
13934 if ( pSatDevData->sat48BitSupport != agTRUE )
13935 {
13936 /*
13937 writeandverify10 but no support for 48 bit addressing -> problem in transfer
13938 length(sector count)
13939 */
13940 satSetSensePayload( pSense,
13941 SCSI_SNSKEY_ILLEGAL_REQUEST,
13942 0,
13943 SCSI_SNSCODE_INVALID_FIELD_IN_CDB,
13944 satIOContext);
13945
13946 ostiInitiatorIOCompleted( tiRoot,
13947 tiIORequest,
13948 tiIOSuccess,
13949 SCSI_STAT_CHECK_CONDITION,
13950 satIOContext->pTiSenseData,
13951 satIOContext->interruptContext );
13952
13953 TI_DBG1(("satWriteAndVerify10: return internal checking\n"));
13954 return tiSuccess;
13955 }
13956
13957 /* cbd10; computing LBA and transfer length */
13958 lba = (scsiCmnd->cdb[2] << (8*3)) + (scsiCmnd->cdb[3] << (8*2))
13959 + (scsiCmnd->cdb[4] << 8) + scsiCmnd->cdb[5];
13960 tl = (scsiCmnd->cdb[7] << 8) + scsiCmnd->cdb[8];
13961
13962
13963 /* Table 34, 9.1, p 46 */
13964 /*
13965 note: As of 2/10/2006, no support for DMA QUEUED
13966 */
13967
13968 /*
13969 Table 34, 9.1, p 46, b
13970 When no 48-bit addressing support or NCQ, if LBA is beyond (2^28 - 1),
13971 return check condition
13972 */
13973 if (pSatDevData->satNCQ != agTRUE &&
13974 pSatDevData->sat48BitSupport != agTRUE
13975 )
13976 {
13977 if (lba > SAT_TR_LBA_LIMIT - 1)
13978 {
13979 satSetSensePayload( pSense,
13980 SCSI_SNSKEY_ILLEGAL_REQUEST,
13981 0,
13982 SCSI_SNSCODE_LOGICAL_BLOCK_ADDRESS_OUT_OF_RANGE,
13983 satIOContext);
13984
13985 ostiInitiatorIOCompleted( tiRoot,
13986 tiIORequest,
13987 tiIOSuccess,
13988 SCSI_STAT_CHECK_CONDITION,
13989 satIOContext->pTiSenseData,
13990 satIOContext->interruptContext );
13991
13992 TI_DBG1(("satWriteAndVerify10: return LBA out of range\n"));
13993 return tiSuccess;
13994 }
13995 }
13996
13997
13998 /* case 1 and 2 */
13999 if (lba + tl <= SAT_TR_LBA_LIMIT)
14000 {
14001 if (pSatDevData->satDMASupport == agTRUE && pSatDevData->satDMAEnabled == agTRUE)
14002 {
14003 /* case 2 */
14004 /* WRITE DMA*/
14005 /* can't fit the transfer length */
14006 TI_DBG5(("satWriteAndVerify10: case 2 !!!\n"));
14007 fis->h.fisType = 0x27; /* Reg host to device */
14008 fis->h.c_pmPort = 0x80; /* C bit is set */
14009 fis->h.command = SAT_WRITE_DMA; /* 0xCA */
14010 fis->h.features = 0; /* FIS reserve */
14011 fis->d.lbaLow = scsiCmnd->cdb[5]; /* FIS LBA (7 :0 ) */
14012 fis->d.lbaMid = scsiCmnd->cdb[4]; /* FIS LBA (15:8 ) */
14013 fis->d.lbaHigh = scsiCmnd->cdb[3]; /* FIS LBA (23:16) */
14014
14015 /* FIS LBA mode set LBA (27:24) */
14016 fis->d.device = (0x4 << 4) | (scsiCmnd->cdb[2] & 0xF);
14017
14018 fis->d.lbaLowExp = 0;
14019 fis->d.lbaMidExp = 0;
14020 fis->d.lbaHighExp = 0;
14021 fis->d.featuresExp = 0;
14022 fis->d.sectorCount = scsiCmnd->cdb[8]; /* FIS sector count (7:0) */
14023 fis->d.sectorCountExp = 0;
14024 fis->d.reserved4 = 0;
14025 fis->d.control = 0; /* FIS HOB bit clear */
14026 fis->d.reserved5 = 0;
14027
14028 agRequestType = AGSA_SATA_PROTOCOL_DMA_WRITE;
14029 satIOContext->ATACmd = SAT_WRITE_DMA;
14030 }
14031 else
14032 {
14033 /* case 1 */
14034 /* WRITE MULTIPLE or WRITE SECTOR(S) */
14035 /* WRITE SECTORS for easier implemetation */
14036 /* can't fit the transfer length */
14037 TI_DBG5(("satWriteAndVerify10: case 1 !!!\n"));
14038 fis->h.fisType = 0x27; /* Reg host to device */
14039 fis->h.c_pmPort = 0x80; /* C bit is set */
14040 fis->h.command = SAT_WRITE_SECTORS; /* 0x30 */
14041 fis->h.features = 0; /* FIS reserve */
14042 fis->d.lbaLow = scsiCmnd->cdb[5]; /* FIS LBA (7 :0 ) */
14043 fis->d.lbaMid = scsiCmnd->cdb[4]; /* FIS LBA (15:8 ) */
14044 fis->d.lbaHigh = scsiCmnd->cdb[3]; /* FIS LBA (23:16) */
14045
14046 /* FIS LBA mode set LBA (27:24) */
14047 fis->d.device = (0x4 << 4) | (scsiCmnd->cdb[2] & 0xF);
14048
14049 fis->d.lbaLowExp = 0;
14050 fis->d.lbaMidExp = 0;
14051 fis->d.lbaHighExp = 0;
14052 fis->d.featuresExp = 0;
14053 fis->d.sectorCount = scsiCmnd->cdb[8]; /* FIS sector count (7:0) */
14054 fis->d.sectorCountExp = 0;
14055 fis->d.reserved4 = 0;
14056 fis->d.control = 0; /* FIS HOB bit clear */
14057 fis->d.reserved5 = 0;
14058
14059 agRequestType = AGSA_SATA_PROTOCOL_PIO_WRITE;
14060 satIOContext->ATACmd = SAT_WRITE_SECTORS;
14061
14062 }
14063 }
14064
14065 /* case 3 and 4 */
14066 if (pSatDevData->sat48BitSupport == agTRUE)
14067 {
14068 if (pSatDevData->satDMASupport == agTRUE && pSatDevData->satDMAEnabled == agTRUE)
14069 {
14070 /* case 3 */
14071 /* WRITE DMA EXT or WRITE DMA FUA EXT */
14072 TI_DBG5(("satWriteAndVerify10: case 3\n"));
14073 fis->h.fisType = 0x27; /* Reg host to device */
14074 fis->h.c_pmPort = 0x80; /* C Bit is set */
14075
14076 /* SAT_WRITE_DMA_FUA_EXT is optional and we don't support it */
14077 fis->h.command = SAT_WRITE_DMA_EXT; /* 0x35 */
14078
14079 fis->h.features = 0; /* FIS reserve */
14080 fis->d.lbaLow = scsiCmnd->cdb[5]; /* FIS LBA (7 :0 ) */
14081 fis->d.lbaMid = scsiCmnd->cdb[4]; /* FIS LBA (15:8 ) */
14082 fis->d.lbaHigh = scsiCmnd->cdb[3]; /* FIS LBA (23:16) */
14083 fis->d.device = 0x40; /* FIS LBA mode set */
14084 fis->d.lbaLowExp = scsiCmnd->cdb[2]; /* FIS LBA (31:24) */
14085 fis->d.lbaMidExp = 0; /* FIS LBA (39:32) */
14086 fis->d.lbaHighExp = 0; /* FIS LBA (47:40) */
14087 fis->d.featuresExp = 0; /* FIS reserve */
14088 fis->d.sectorCount = scsiCmnd->cdb[8]; /* FIS sector count (7:0) */
14089 fis->d.sectorCountExp = scsiCmnd->cdb[7]; /* FIS sector count (15:8) */
14090 fis->d.reserved4 = 0;
14091 fis->d.control = 0; /* FIS HOB bit clear */
14092 fis->d.reserved5 = 0;
14093
14094 agRequestType = AGSA_SATA_PROTOCOL_DMA_WRITE;
14095 }
14096 else
14097 {
14098 /* case 4 */
14099 /* WRITE MULTIPLE EXT or WRITE MULTIPLE FUA EXT or WRITE SECTOR(S) EXT */
14100 /* WRITE SECTORS EXT for easier implemetation */
14101 TI_DBG5(("satWriteAndVerify10: case 4\n"));
14102 fis->h.fisType = 0x27; /* Reg host to device */
14103 fis->h.c_pmPort = 0x80; /* C Bit is set */
14104 fis->h.command = SAT_WRITE_SECTORS_EXT; /* 0x34 */
14105
14106 fis->h.features = 0; /* FIS reserve */
14107 fis->d.lbaLow = scsiCmnd->cdb[5]; /* FIS LBA (7 :0 ) */
14108 fis->d.lbaMid = scsiCmnd->cdb[4]; /* FIS LBA (15:8 ) */
14109 fis->d.lbaHigh = scsiCmnd->cdb[3]; /* FIS LBA (23:16) */
14110 fis->d.device = 0x40; /* FIS LBA mode set */
14111 fis->d.lbaLowExp = scsiCmnd->cdb[2]; /* FIS LBA (31:24) */
14112 fis->d.lbaMidExp = 0; /* FIS LBA (39:32) */
14113 fis->d.lbaHighExp = 0; /* FIS LBA (47:40) */
14114 fis->d.featuresExp = 0; /* FIS reserve */
14115 fis->d.sectorCount = scsiCmnd->cdb[8]; /* FIS sector count (7:0) */
14116 fis->d.sectorCountExp = scsiCmnd->cdb[7]; /* FIS sector count (15:8) */
14117 fis->d.reserved4 = 0;
14118 fis->d.control = 0; /* FIS HOB bit clear */
14119 fis->d.reserved5 = 0;
14120
14121 agRequestType = AGSA_SATA_PROTOCOL_PIO_WRITE;
14122 }
14123 }
14124 /* case 5 */
14125 if (pSatDevData->satNCQ == agTRUE)
14126 {
14127 /* WRITE FPDMA QUEUED */
14128 if (pSatDevData->sat48BitSupport != agTRUE)
14129 {
14130 TI_DBG5(("satWriteAndVerify10: case 5 !!! error NCQ but 28 bit address support \n"));
14131 satSetSensePayload( pSense,
14132 SCSI_SNSKEY_ILLEGAL_REQUEST,
14133 0,
14134 SCSI_SNSCODE_INVALID_FIELD_IN_CDB,
14135 satIOContext);
14136
14137 ostiInitiatorIOCompleted( tiRoot,
14138 tiIORequest,
14139 tiIOSuccess,
14140 SCSI_STAT_CHECK_CONDITION,
14141 satIOContext->pTiSenseData,
14142 satIOContext->interruptContext );
14143 return tiSuccess;
14144 }
14145 TI_DBG5(("satWriteAndVerify10: case 5\n"));
14146
14147 /* Support 48-bit FPDMA addressing, use WRITE FPDMA QUEUE command */
14148
14149 fis->h.fisType = 0x27; /* Reg host to device */
14150 fis->h.c_pmPort = 0x80; /* C Bit is set */
14151 fis->h.command = SAT_WRITE_FPDMA_QUEUED; /* 0x61 */
14152 fis->h.features = scsiCmnd->cdb[8]; /* FIS sector count (7:0) */
14153 fis->d.lbaLow = scsiCmnd->cdb[5]; /* FIS LBA (7 :0 ) */
14154 fis->d.lbaMid = scsiCmnd->cdb[4]; /* FIS LBA (15:8 ) */
14155 fis->d.lbaHigh = scsiCmnd->cdb[3]; /* FIS LBA (23:16) */
14156
14157 /* Check FUA bit */
14158 if (scsiCmnd->cdb[1] & SCSI_WRITE_N_VERIFY10_FUA_MASK)
14159 fis->d.device = 0xC0; /* FIS FUA set */
14160 else
14161 fis->d.device = 0x40; /* FIS FUA clear */
14162
14163 fis->d.lbaLowExp = scsiCmnd->cdb[2]; /* FIS LBA (31:24) */
14164 fis->d.lbaMidExp = 0; /* FIS LBA (39:32) */
14165 fis->d.lbaHighExp = 0; /* FIS LBA (47:40) */
14166 fis->d.featuresExp = scsiCmnd->cdb[7]; /* FIS sector count (15:8) */
14167 fis->d.sectorCount = 0; /* Tag (7:3) set by LL layer */
14168 fis->d.sectorCountExp = 0;
14169 fis->d.reserved4 = 0;
14170 fis->d.control = 0; /* FIS HOB bit clear */
14171 fis->d.reserved5 = 0;
14172
14173 agRequestType = AGSA_SATA_PROTOCOL_FPDMA_WRITE;
14174 }
14175
14176 /* Initialize CB for SATA completion.
14177 */
14178 satIOContext->satCompleteCB = &satWriteAndVerify10CB;
14179
14180 /*
14181 * Prepare SGL and send FIS to LL layer.
14182 */
14183 satIOContext->reqType = agRequestType; /* Save it */
14184
14185 status = sataLLIOStart( tiRoot,
14186 tiIORequest,
14187 tiDeviceHandle,
14188 tiScsiRequest,
14189 satIOContext);
14190 return (status);
14191
14192 }
14193 #endif /* REMOVED */
14194
14195 #ifdef REMOVED
14196 /*****************************************************************************/
14197 /*! \brief SAT implementation for SCSI satWriteAndVerify10_1.
14198 *
14199 * SAT implementation for SCSI satWriteAndVerify10_1.
14200 * Sub function of satWriteAndVerify10
14201 *
14202 * \param tiRoot: Pointer to TISA initiator driver/port instance.
14203 * \param tiIORequest: Pointer to TISA I/O request context for this I/O.
14204 * \param tiDeviceHandle: Pointer to TISA device handle for this I/O.
14205 * \param tiScsiRequest: Pointer to TISA SCSI I/O request and SGL list.
14206 * \param satIOContext_t: Pointer to the SAT IO Context
14207 *
14208 * \return If command is started successfully
14209 * - \e tiSuccess: I/O request successfully initiated.
14210 * - \e tiBusy: No resources available, try again later.
14211 * - \e tiIONoDevice: Invalid device handle.
14212 * - \e tiError: Other errors.
14213 */
14214 /*****************************************************************************/
14215 GLOBAL bit32 satWriteAndVerify10_1(
14216 tiRoot_t *tiRoot,
14217 tiIORequest_t *tiIORequest,
14218 tiDeviceHandle_t *tiDeviceHandle,
14219 tiScsiInitiatorRequest_t *tiScsiRequest,
14220 satIOContext_t *satIOContext)
14221 {
14222 bit32 status;
14223 bit32 agRequestType = AGSA_SATA_PROTOCOL_DMA_WRITE;
14224 satDeviceData_t *pSatDevData;
14225 scsiRspSense_t *pSense;
14226 tiIniScsiCmnd_t *scsiCmnd;
14227 agsaFisRegHostToDevice_t *fis;
14228
14229 pSense = satIOContext->pSense;
14230 pSatDevData = satIOContext->pSatDevData;
14231 scsiCmnd = &tiScsiRequest->scsiCmnd;
14232 fis = satIOContext->pFis;
14233
14234 TI_DBG5(("satWriteAndVerify10_1: start\n"));
14235
14236 if (pSatDevData->sat48BitSupport == agTRUE)
14237 {
14238 fis->h.fisType = 0x27; /* Reg host to device */
14239 fis->h.c_pmPort = 0x80; /* C Bit is set */
14240
14241 fis->h.command = SAT_READ_VERIFY_SECTORS_EXT;/* 0x42 */
14242 fis->h.features = 0; /* FIS reserve */
14243 fis->d.lbaLow = scsiCmnd->cdb[5]; /* FIS LBA (7 :0 ) */
14244 fis->d.lbaMid = scsiCmnd->cdb[4]; /* FIS LBA (15:8 ) */
14245 fis->d.lbaHigh = scsiCmnd->cdb[3]; /* FIS LBA (23:16) */
14246 fis->d.device = 0x40; /* FIS LBA mode set 01000000 */
14247 fis->d.lbaLowExp = scsiCmnd->cdb[2]; /* FIS LBA (31:24) */
14248 fis->d.lbaMidExp = 0; /* FIS LBA (39:32) */
14249 fis->d.lbaHighExp = 0; /* FIS LBA (47:40) */
14250 fis->d.featuresExp = 0; /* FIS reserve */
14251 fis->d.sectorCount = scsiCmnd->cdb[8]; /* FIS sector count (7:0) */
14252 fis->d.sectorCountExp = scsiCmnd->cdb[7]; /* FIS sector count (15:8) */
14253
14254 fis->d.reserved4 = 0;
14255 fis->d.control = 0; /* FIS HOB bit clear */
14256 fis->d.reserved5 = 0;
14257
14258 agRequestType = AGSA_SATA_PROTOCOL_NON_DATA;
14259
14260 /* Initialize CB for SATA completion.
14261 */
14262 satIOContext->satCompleteCB = &satWriteAndVerify10CB;
14263
14264 /*
14265 * Prepare SGL and send FIS to LL layer.
14266 */
14267 satIOContext->reqType = agRequestType; /* Save it */
14268
14269 status = sataLLIOStart( tiRoot,
14270 tiIORequest,
14271 tiDeviceHandle,
14272 tiScsiRequest,
14273 satIOContext);
14274
14275
14276 TI_DBG1(("satWriteAndVerify10_1: return status %d\n", status));
14277 return (status);
14278 }
14279 else
14280 {
14281 /* can't fit in SAT_READ_VERIFY_SECTORS becasue of Sector Count and LBA */
14282 TI_DBG1(("satWriteAndVerify10_1: can't fit in SAT_READ_VERIFY_SECTORS\n"));
14283 return tiError;
14284 }
14285
14286
14287 return tiSuccess;
14288 }
14289 #endif /* REMOVED */
14290
14291 /*****************************************************************************/
14292 /*! \brief SAT implementation for SCSI satWriteAndVerify12.
14293 *
14294 * SAT implementation for SCSI satWriteAndVerify12.
14295 *
14296 * \param tiRoot: Pointer to TISA initiator driver/port instance.
14297 * \param tiIORequest: Pointer to TISA I/O request context for this I/O.
14298 * \param tiDeviceHandle: Pointer to TISA device handle for this I/O.
14299 * \param tiScsiRequest: Pointer to TISA SCSI I/O request and SGL list.
14300 * \param satIOContext_t: Pointer to the SAT IO Context
14301 *
14302 * \return If command is started successfully
14303 * - \e tiSuccess: I/O request successfully initiated.
14304 * - \e tiBusy: No resources available, try again later.
14305 * - \e tiIONoDevice: Invalid device handle.
14306 * - \e tiError: Other errors.
14307 */
14308 /*****************************************************************************/
14309 GLOBAL bit32 satWriteAndVerify12(
14310 tiRoot_t *tiRoot,
14311 tiIORequest_t *tiIORequest,
14312 tiDeviceHandle_t *tiDeviceHandle,
14313 tiScsiInitiatorRequest_t *tiScsiRequest,
14314 satIOContext_t *satIOContext)
14315 {
14316 /*
14317 combination of write12 and verify12
14318 temp: since write12 is not support (due to internal checking), no support
14319 */
14320 bit32 status;
14321 bit32 agRequestType = AGSA_SATA_PROTOCOL_DMA_WRITE;
14322 satDeviceData_t *pSatDevData;
14323 scsiRspSense_t *pSense;
14324 tiIniScsiCmnd_t *scsiCmnd;
14325 agsaFisRegHostToDevice_t *fis;
14326 bit32 lba = 0;
14327 bit32 tl = 0;
14328 bit32 LoopNum = 1;
14329 bit8 LBA[4];
14330 bit8 TL[4];
14331 bit32 rangeChk = agFALSE; /* lba and tl range check */
14332
14333 pSense = satIOContext->pSense;
14334 pSatDevData = satIOContext->pSatDevData;
14335 scsiCmnd = &tiScsiRequest->scsiCmnd;
14336 fis = satIOContext->pFis;
14337
14338 TI_DBG5(("satWriteAndVerify12: start\n"));
14339
14340 /* checking BYTCHK bit */
14341 if (scsiCmnd->cdb[1] & SCSI_WRITE_N_VERIFY_BYTCHK_MASK)
14342 {
14343 satSetSensePayload( pSense,
14344 SCSI_SNSKEY_ILLEGAL_REQUEST,
14345 0,
14346 SCSI_SNSCODE_INVALID_FIELD_IN_CDB,
14347 satIOContext);
14348
14349 ostiInitiatorIOCompleted( tiRoot,
14350 tiIORequest,
14351 tiIOSuccess,
14352 SCSI_STAT_CHECK_CONDITION,
14353 satIOContext->pTiSenseData,
14354 satIOContext->interruptContext );
14355
14356 TI_DBG1(("satWriteAndVerify12: BYTCHK bit checking \n"));
14357 return tiSuccess;
14358 }
14359
14360 /* checking CONTROL */
14361 /* NACA == 1 or LINK == 1*/
14362 if ( (scsiCmnd->cdb[11] & SCSI_NACA_MASK) || (scsiCmnd->cdb[11] & SCSI_LINK_MASK) )
14363 {
14364 satSetSensePayload( pSense,
14365 SCSI_SNSKEY_ILLEGAL_REQUEST,
14366 0,
14367 SCSI_SNSCODE_INVALID_FIELD_IN_CDB,
14368 satIOContext);
14369
14370 ostiInitiatorIOCompleted( tiRoot,
14371 tiIORequest,
14372 tiIOSuccess,
14373 SCSI_STAT_CHECK_CONDITION,
14374 satIOContext->pTiSenseData,
14375 satIOContext->interruptContext );
14376
14377 TI_DBG2(("satWriteAndVerify12: return control\n"));
14378 return tiSuccess;
14379 }
14380
14381 osti_memset(LBA, 0, sizeof(LBA));
14382 osti_memset(TL, 0, sizeof(TL));
14383
14384 /* do not use memcpy due to indexing in LBA and TL */
14385 LBA[0] = scsiCmnd->cdb[2]; /* MSB */
14386 LBA[1] = scsiCmnd->cdb[3];
14387 LBA[2] = scsiCmnd->cdb[4];
14388 LBA[3] = scsiCmnd->cdb[5]; /* LSB */
14389
14390 TL[0] = scsiCmnd->cdb[6]; /* MSB */
14391 TL[1] = scsiCmnd->cdb[7];
14392 TL[2] = scsiCmnd->cdb[7];
14393 TL[3] = scsiCmnd->cdb[8]; /* LSB */
14394
14395 rangeChk = satAddNComparebit32(LBA, TL);
14396
14397 lba = satComputeCDB12LBA(satIOContext);
14398 tl = satComputeCDB12TL(satIOContext);
14399
14400
14401 /* Table 34, 9.1, p 46 */
14402 /*
14403 note: As of 2/10/2006, no support for DMA QUEUED
14404 */
14405
14406 /*
14407 Table 34, 9.1, p 46, b
14408 When no 48-bit addressing support or NCQ, if LBA is beyond (2^28 - 1),
14409 return check condition
14410 */
14411 if (pSatDevData->satNCQ != agTRUE &&
14412 pSatDevData->sat48BitSupport != agTRUE
14413 )
14414 {
14415 if (lba > SAT_TR_LBA_LIMIT - 1)
14416 {
14417 satSetSensePayload( pSense,
14418 SCSI_SNSKEY_ILLEGAL_REQUEST,
14419 0,
14420 SCSI_SNSCODE_LOGICAL_BLOCK_ADDRESS_OUT_OF_RANGE,
14421 satIOContext);
14422
14423 ostiInitiatorIOCompleted( tiRoot,
14424 tiIORequest,
14425 tiIOSuccess,
14426 SCSI_STAT_CHECK_CONDITION,
14427 satIOContext->pTiSenseData,
14428 satIOContext->interruptContext );
14429
14430 TI_DBG1(("satWriteAndVerify12: return LBA out of range, not EXT\n"));
14431 return tiSuccess;
14432 }
14433
14434 if (rangeChk) // if (lba + tl > SAT_TR_LBA_LIMIT)
14435 {
14436 TI_DBG1(("satWriteAndVerify12: return LBA+TL out of range, not EXT\n"));
14437 satSetSensePayload( pSense,
14438 SCSI_SNSKEY_ILLEGAL_REQUEST,
14439 0,
14440 SCSI_SNSCODE_LOGICAL_BLOCK_ADDRESS_OUT_OF_RANGE,
14441 satIOContext);
14442
14443 ostiInitiatorIOCompleted( tiRoot,
14444 tiIORequest,
14445 tiIOSuccess,
14446 SCSI_STAT_CHECK_CONDITION,
14447 satIOContext->pTiSenseData,
14448 satIOContext->interruptContext );
14449
14450 return tiSuccess;
14451 }
14452 }
14453
14454 /* case 1 and 2 */
14455 if (!rangeChk) // if (lba + tl <= SAT_TR_LBA_LIMIT)
14456 {
14457 if (pSatDevData->satDMASupport == agTRUE && pSatDevData->satDMAEnabled == agTRUE)
14458 {
14459 /* case 2 */
14460 /* WRITE DMA*/
14461 /* In case that we can't fit the transfer length, we loop */
14462 TI_DBG5(("satWriteAndVerify12: case 2\n"));
14463 fis->h.fisType = 0x27; /* Reg host to device */
14464 fis->h.c_pmPort = 0x80; /* C bit is set */
14465 fis->h.command = SAT_WRITE_DMA; /* 0xCA */
14466 fis->h.features = 0; /* FIS reserve */
14467 fis->d.lbaLow = scsiCmnd->cdb[5]; /* FIS LBA (7 :0 ) */
14468 fis->d.lbaMid = scsiCmnd->cdb[4]; /* FIS LBA (15:8 ) */
14469 fis->d.lbaHigh = scsiCmnd->cdb[3]; /* FIS LBA (23:16) */
14470
14471 /* FIS LBA mode set LBA (27:24) */
14472 fis->d.device = (bit8)((0x4 << 4) | (scsiCmnd->cdb[2] & 0xF));
14473
14474 fis->d.lbaLowExp = 0;
14475 fis->d.lbaMidExp = 0;
14476 fis->d.lbaHighExp = 0;
14477 fis->d.featuresExp = 0;
14478 fis->d.sectorCount = scsiCmnd->cdb[9]; /* FIS sector count (7:0) */
14479 fis->d.sectorCountExp = 0;
14480 fis->d.reserved4 = 0;
14481 fis->d.control = 0; /* FIS HOB bit clear */
14482 fis->d.reserved5 = 0;
14483
14484 agRequestType = AGSA_SATA_PROTOCOL_DMA_WRITE;
14485 satIOContext->ATACmd = SAT_WRITE_DMA;
14486 }
14487 else
14488 {
14489 /* case 1 */
14490 /* WRITE MULTIPLE or WRITE SECTOR(S) */
14491 /* WRITE SECTORS for easier implemetation */
14492 /* In case that we can't fit the transfer length, we loop */
14493 TI_DBG5(("satWriteAndVerify12: case 1\n"));
14494 fis->h.fisType = 0x27; /* Reg host to device */
14495 fis->h.c_pmPort = 0x80; /* C bit is set */
14496 fis->h.command = SAT_WRITE_SECTORS; /* 0x30 */
14497 fis->h.features = 0; /* FIS reserve */
14498 fis->d.lbaLow = scsiCmnd->cdb[5]; /* FIS LBA (7 :0 ) */
14499 fis->d.lbaMid = scsiCmnd->cdb[4]; /* FIS LBA (15:8 ) */
14500 fis->d.lbaHigh = scsiCmnd->cdb[3]; /* FIS LBA (23:16) */
14501
14502 /* FIS LBA mode set LBA (27:24) */
14503 fis->d.device = (bit8)((0x4 << 4) | (scsiCmnd->cdb[2] & 0xF));
14504
14505 fis->d.lbaLowExp = 0;
14506 fis->d.lbaMidExp = 0;
14507 fis->d.lbaHighExp = 0;
14508 fis->d.featuresExp = 0;
14509 fis->d.sectorCount = scsiCmnd->cdb[9]; /* FIS sector count (7:0) */
14510 fis->d.sectorCountExp = 0;
14511 fis->d.reserved4 = 0;
14512 fis->d.control = 0; /* FIS HOB bit clear */
14513 fis->d.reserved5 = 0;
14514
14515 agRequestType = AGSA_SATA_PROTOCOL_PIO_WRITE;
14516 satIOContext->ATACmd = SAT_WRITE_SECTORS;
14517 }
14518 }
14519
14520 /* case 3 and 4 */
14521 if (pSatDevData->sat48BitSupport == agTRUE)
14522 {
14523 if (pSatDevData->satDMASupport == agTRUE && pSatDevData->satDMAEnabled == agTRUE)
14524 {
14525 /* case 3 */
14526 /* WRITE DMA EXT or WRITE DMA FUA EXT */
14527 TI_DBG5(("satWriteAndVerify12: case 3\n"));
14528 fis->h.fisType = 0x27; /* Reg host to device */
14529 fis->h.c_pmPort = 0x80; /* C Bit is set */
14530
14531 /* SAT_WRITE_DMA_FUA_EXT is optional and we don't support it */
14532 fis->h.command = SAT_WRITE_DMA_EXT; /* 0x35 */
14533
14534 fis->h.features = 0; /* FIS reserve */
14535 fis->d.lbaLow = scsiCmnd->cdb[5]; /* FIS LBA (7 :0 ) */
14536 fis->d.lbaMid = scsiCmnd->cdb[4]; /* FIS LBA (15:8 ) */
14537 fis->d.lbaHigh = scsiCmnd->cdb[3]; /* FIS LBA (23:16) */
14538 fis->d.device = 0x40; /* FIS LBA mode set */
14539 fis->d.lbaLowExp = scsiCmnd->cdb[2]; /* FIS LBA (31:24) */
14540 fis->d.lbaMidExp = 0; /* FIS LBA (39:32) */
14541 fis->d.lbaHighExp = 0; /* FIS LBA (47:40) */
14542 fis->d.featuresExp = 0; /* FIS reserve */
14543 fis->d.sectorCount = scsiCmnd->cdb[9]; /* FIS sector count (7:0) */
14544 fis->d.sectorCountExp = scsiCmnd->cdb[8]; /* FIS sector count (15:8) */
14545 fis->d.reserved4 = 0;
14546 fis->d.control = 0; /* FIS HOB bit clear */
14547 fis->d.reserved5 = 0;
14548
14549 agRequestType = AGSA_SATA_PROTOCOL_DMA_WRITE;
14550 satIOContext->ATACmd = SAT_WRITE_DMA_EXT;
14551 }
14552 else
14553 {
14554 /* case 4 */
14555 /* WRITE MULTIPLE EXT or WRITE MULTIPLE FUA EXT or WRITE SECTOR(S) EXT */
14556 /* WRITE SECTORS EXT for easier implemetation */
14557 TI_DBG5(("satWriteAndVerify12: case 4\n"));
14558 fis->h.fisType = 0x27; /* Reg host to device */
14559 fis->h.c_pmPort = 0x80; /* C Bit is set */
14560 fis->h.command = SAT_WRITE_SECTORS_EXT; /* 0x34 */
14561
14562 fis->h.features = 0; /* FIS reserve */
14563 fis->d.lbaLow = scsiCmnd->cdb[5]; /* FIS LBA (7 :0 ) */
14564 fis->d.lbaMid = scsiCmnd->cdb[4]; /* FIS LBA (15:8 ) */
14565 fis->d.lbaHigh = scsiCmnd->cdb[3]; /* FIS LBA (23:16) */
14566 fis->d.device = 0x40; /* FIS LBA mode set */
14567 fis->d.lbaLowExp = scsiCmnd->cdb[2]; /* FIS LBA (31:24) */
14568 fis->d.lbaMidExp = 0; /* FIS LBA (39:32) */
14569 fis->d.lbaHighExp = 0; /* FIS LBA (47:40) */
14570 fis->d.featuresExp = 0; /* FIS reserve */
14571 fis->d.sectorCount = scsiCmnd->cdb[9]; /* FIS sector count (7:0) */
14572 fis->d.sectorCountExp = scsiCmnd->cdb[8]; /* FIS sector count (15:8) */
14573 fis->d.reserved4 = 0;
14574 fis->d.control = 0; /* FIS HOB bit clear */
14575 fis->d.reserved5 = 0;
14576
14577 agRequestType = AGSA_SATA_PROTOCOL_PIO_WRITE;
14578 satIOContext->ATACmd = SAT_WRITE_SECTORS_EXT;
14579 }
14580 }
14581
14582 /* case 5 */
14583 if (pSatDevData->satNCQ == agTRUE)
14584 {
14585 /* WRITE FPDMA QUEUED */
14586 if (pSatDevData->sat48BitSupport != agTRUE)
14587 {
14588 TI_DBG5(("satWriteAndVerify12: case 5 !!! error NCQ but 28 bit address support \n"));
14589 satSetSensePayload( pSense,
14590 SCSI_SNSKEY_ILLEGAL_REQUEST,
14591 0,
14592 SCSI_SNSCODE_INVALID_FIELD_IN_CDB,
14593 satIOContext);
14594
14595 ostiInitiatorIOCompleted( tiRoot,
14596 tiIORequest,
14597 tiIOSuccess,
14598 SCSI_STAT_CHECK_CONDITION,
14599 satIOContext->pTiSenseData,
14600 satIOContext->interruptContext );
14601 return tiSuccess;
14602 }
14603 TI_DBG6(("satWriteAndVerify12: case 5\n"));
14604
14605 /* Support 48-bit FPDMA addressing, use WRITE FPDMA QUEUE command */
14606
14607 fis->h.fisType = 0x27; /* Reg host to device */
14608 fis->h.c_pmPort = 0x80; /* C Bit is set */
14609 fis->h.command = SAT_WRITE_FPDMA_QUEUED; /* 0x61 */
14610 fis->h.features = scsiCmnd->cdb[9]; /* FIS sector count (7:0) */
14611 fis->d.lbaLow = scsiCmnd->cdb[5]; /* FIS LBA (7 :0 ) */
14612 fis->d.lbaMid = scsiCmnd->cdb[4]; /* FIS LBA (15:8 ) */
14613 fis->d.lbaHigh = scsiCmnd->cdb[3]; /* FIS LBA (23:16) */
14614
14615 /* Check FUA bit */
14616 if (scsiCmnd->cdb[1] & SCSI_WRITE12_FUA_MASK)
14617 fis->d.device = 0xC0; /* FIS FUA set */
14618 else
14619 fis->d.device = 0x40; /* FIS FUA clear */
14620
14621 fis->d.lbaLowExp = scsiCmnd->cdb[2]; /* FIS LBA (31:24) */
14622 fis->d.lbaMidExp = 0; /* FIS LBA (39:32) */
14623 fis->d.lbaHighExp = 0; /* FIS LBA (47:40) */
14624 fis->d.featuresExp = scsiCmnd->cdb[8]; /* FIS sector count (15:8) */
14625 fis->d.sectorCount = 0; /* Tag (7:3) set by LL layer */
14626 fis->d.sectorCountExp = 0;
14627 fis->d.reserved4 = 0;
14628 fis->d.control = 0; /* FIS HOB bit clear */
14629 fis->d.reserved5 = 0;
14630
14631 agRequestType = AGSA_SATA_PROTOCOL_FPDMA_WRITE;
14632 satIOContext->ATACmd = SAT_WRITE_FPDMA_QUEUED;
14633 }
14634
14635 satIOContext->currentLBA = lba;
14636 // satIOContext->OrgLBA = lba;
14637 satIOContext->OrgTL = tl;
14638
14639 /*
14640 computing number of loop and remainder for tl
14641 0xFF in case not ext
14642 0xFFFF in case EXT
14643 */
14644 if (fis->h.command == SAT_WRITE_SECTORS || fis->h.command == SAT_WRITE_DMA)
14645 {
14646 LoopNum = satComputeLoopNum(tl, 0xFF);
14647 }
14648 else if (fis->h.command == SAT_WRITE_SECTORS_EXT ||
14649 fis->h.command == SAT_WRITE_DMA_EXT ||
14650 fis->h.command == SAT_WRITE_DMA_FUA_EXT
14651 )
14652 {
14653 /* SAT_READ_SECTORS_EXT, SAT_READ_DMA_EXT */
14654 LoopNum = satComputeLoopNum(tl, 0xFFFF);
14655 }
14656 else
14657 {
14658 /* SAT_WRITE_FPDMA_QUEUEDK */
14659 LoopNum = satComputeLoopNum(tl, 0xFFFF);
14660 }
14661
14662 satIOContext->LoopNum = LoopNum;
14663 satIOContext->LoopNum2 = LoopNum;
14664
14665
14666 if (LoopNum == 1)
14667 {
14668 TI_DBG5(("satWriteAndVerify12: NON CHAINED data\n"));
14669 /* Initialize CB for SATA completion.
14670 */
14671 satIOContext->satCompleteCB = &satNonChainedWriteNVerifyCB;
14672 }
14673 else
14674 {
14675 TI_DBG1(("satWriteAndVerify12: CHAINED data\n"));
14676 /* re-setting tl */
14677 if (fis->h.command == SAT_WRITE_SECTORS || fis->h.command == SAT_WRITE_DMA)
14678 {
14679 fis->d.sectorCount = 0xFF;
14680 }
14681 else if (fis->h.command == SAT_WRITE_SECTORS_EXT ||
14682 fis->h.command == SAT_WRITE_DMA_EXT ||
14683 fis->h.command == SAT_WRITE_DMA_FUA_EXT
14684 )
14685 {
14686 fis->d.sectorCount = 0xFF;
14687 fis->d.sectorCountExp = 0xFF;
14688 }
14689 else
14690 {
14691 /* SAT_WRITE_FPDMA_QUEUED */
14692 fis->h.features = 0xFF;
14693 fis->d.featuresExp = 0xFF;
14694 }
14695
14696 /* Initialize CB for SATA completion.
14697 */
14698 satIOContext->satCompleteCB = &satChainedWriteNVerifyCB;
14699 }
14700
14701
14702 /*
14703 * Prepare SGL and send FIS to LL layer.
14704 */
14705 satIOContext->reqType = agRequestType; /* Save it */
14706
14707 status = sataLLIOStart( tiRoot,
14708 tiIORequest,
14709 tiDeviceHandle,
14710 tiScsiRequest,
14711 satIOContext);
14712 return (status);
14713 }
14714
14715 GLOBAL bit32 satNonChainedWriteNVerify_Verify(
14716 tiRoot_t *tiRoot,
14717 tiIORequest_t *tiIORequest,
14718 tiDeviceHandle_t *tiDeviceHandle,
14719 tiScsiInitiatorRequest_t *tiScsiRequest,
14720 satIOContext_t *satIOContext)
14721 {
14722 bit32 status;
14723 bit32 agRequestType = AGSA_SATA_PROTOCOL_DMA_WRITE;
14724 satDeviceData_t *pSatDevData;
14725 tiIniScsiCmnd_t *scsiCmnd;
14726 agsaFisRegHostToDevice_t *fis;
14727
14728 pSatDevData = satIOContext->pSatDevData;
14729 scsiCmnd = &tiScsiRequest->scsiCmnd;
14730 fis = satIOContext->pFis;
14731
14732 TI_DBG5(("satNonChainedWriteNVerify_Verify: start\n"));
14733
14734 if (pSatDevData->sat48BitSupport == agTRUE)
14735 {
14736 fis->h.fisType = 0x27; /* Reg host to device */
14737 fis->h.c_pmPort = 0x80; /* C Bit is set */
14738
14739 fis->h.command = SAT_READ_VERIFY_SECTORS_EXT;/* 0x42 */
14740 fis->h.features = 0; /* FIS reserve */
14741 fis->d.lbaLow = scsiCmnd->cdb[5]; /* FIS LBA (7 :0 ) */
14742 fis->d.lbaMid = scsiCmnd->cdb[4]; /* FIS LBA (15:8 ) */
14743 fis->d.lbaHigh = scsiCmnd->cdb[3]; /* FIS LBA (23:16) */
14744 fis->d.device = 0x40; /* FIS LBA mode set 01000000 */
14745 fis->d.lbaLowExp = scsiCmnd->cdb[2]; /* FIS LBA (31:24) */
14746 fis->d.lbaMidExp = 0; /* FIS LBA (39:32) */
14747 fis->d.lbaHighExp = 0; /* FIS LBA (47:40) */
14748 fis->d.featuresExp = 0; /* FIS reserve */
14749 fis->d.sectorCount = scsiCmnd->cdb[8]; /* FIS sector count (7:0) */
14750 fis->d.sectorCountExp = scsiCmnd->cdb[7]; /* FIS sector count (15:8) */
14751
14752 fis->d.reserved4 = 0;
14753 fis->d.control = 0; /* FIS HOB bit clear */
14754 fis->d.reserved5 = 0;
14755
14756 agRequestType = AGSA_SATA_PROTOCOL_NON_DATA;
14757
14758 /* Initialize CB for SATA completion.
14759 */
14760 satIOContext->satCompleteCB = &satNonChainedWriteNVerifyCB;
14761
14762 /*
14763 * Prepare SGL and send FIS to LL layer.
14764 */
14765 satIOContext->reqType = agRequestType; /* Save it */
14766
14767 status = sataLLIOStart( tiRoot,
14768 tiIORequest,
14769 tiDeviceHandle,
14770 tiScsiRequest,
14771 satIOContext);
14772
14773
14774 TI_DBG1(("satNonChainedWriteNVerify_Verify: return status %d\n", status));
14775 return (status);
14776 }
14777 else
14778 {
14779 /* can't fit in SAT_READ_VERIFY_SECTORS becasue of Sector Count and LBA */
14780 TI_DBG1(("satNonChainedWriteNVerify_Verify: can't fit in SAT_READ_VERIFY_SECTORS\n"));
14781 return tiError;
14782 }
14783
14784 }
14785
14786 GLOBAL bit32 satChainedWriteNVerify_Write(
14787 tiRoot_t *tiRoot,
14788 tiIORequest_t *tiIORequest,
14789 tiDeviceHandle_t *tiDeviceHandle,
14790 tiScsiInitiatorRequest_t *tiScsiRequest,
14791 satIOContext_t *satIOContext)
14792 {
14793 /*
14794 Assumption: error check on lba and tl has been done in satWrite*()
14795 lba = lba + tl;
14796 */
14797 bit32 status;
14798 satIOContext_t *satOrgIOContext = agNULL;
14799 tiIniScsiCmnd_t *scsiCmnd;
14800 agsaFisRegHostToDevice_t *fis;
14801 bit32 agRequestType = AGSA_SATA_PROTOCOL_DMA_WRITE;
14802 bit32 lba = 0;
14803 bit32 DenomTL = 0xFF;
14804 bit32 Remainder = 0;
14805 bit8 LBA[4]; /* 0 MSB, 3 LSB */
14806
14807 TI_DBG1(("satChainedWriteNVerify_Write: start\n"));
14808
14809 fis = satIOContext->pFis;
14810 satOrgIOContext = satIOContext->satOrgIOContext;
14811 scsiCmnd = satOrgIOContext->pScsiCmnd;
14812
14813 osti_memset(LBA,0, sizeof(LBA));
14814
14815 switch (satOrgIOContext->ATACmd)
14816 {
14817 case SAT_WRITE_DMA:
14818 DenomTL = 0xFF;
14819 break;
14820 case SAT_WRITE_SECTORS:
14821 DenomTL = 0xFF;
14822 break;
14823 case SAT_WRITE_DMA_EXT:
14824 DenomTL = 0xFFFF;
14825 break;
14826 case SAT_WRITE_DMA_FUA_EXT:
14827 DenomTL = 0xFFFF;
14828 break;
14829 case SAT_WRITE_SECTORS_EXT:
14830 DenomTL = 0xFFFF;
14831 break;
14832 case SAT_WRITE_FPDMA_QUEUED:
14833 DenomTL = 0xFFFF;
14834 break;
14835 default:
14836 TI_DBG1(("satChainedWriteNVerify_Write: error incorrect ata command 0x%x\n", satIOContext->ATACmd));
14837 return tiError;
14838 break;
14839 }
14840
14841 Remainder = satOrgIOContext->OrgTL % DenomTL;
14842 satOrgIOContext->currentLBA = satOrgIOContext->currentLBA + DenomTL;
14843 lba = satOrgIOContext->currentLBA;
14844
14845 LBA[0] = (bit8)((lba & 0xF000) >> (8 * 3)); /* MSB */
14846 LBA[1] = (bit8)((lba & 0xF00) >> (8 * 2));
14847 LBA[2] = (bit8)((lba & 0xF0) >> 8);
14848 LBA[3] = (bit8)(lba & 0xF); /* LSB */
14849
14850 switch (satOrgIOContext->ATACmd)
14851 {
14852 case SAT_WRITE_DMA:
14853 fis->h.fisType = 0x27; /* Reg host to device */
14854 fis->h.c_pmPort = 0x80; /* C bit is set */
14855 fis->h.command = SAT_WRITE_DMA; /* 0xCA */
14856 fis->h.features = 0; /* FIS reserve */
14857 fis->d.lbaLow = LBA[3]; /* FIS LBA (7 :0 ) */
14858 fis->d.lbaMid = LBA[2]; /* FIS LBA (15:8 ) */
14859 fis->d.lbaHigh = LBA[1]; /* FIS LBA (23:16) */
14860
14861 /* FIS LBA mode set LBA (27:24) */
14862 fis->d.device = (bit8)((0x4 << 4) | (LBA[0] & 0xF));
14863
14864 fis->d.lbaLowExp = 0;
14865 fis->d.lbaMidExp = 0;
14866 fis->d.lbaHighExp = 0;
14867 fis->d.featuresExp = 0;
14868 if (satOrgIOContext->LoopNum == 1)
14869 {
14870 /* last loop */
14871 fis->d.sectorCount = (bit8)Remainder; /* FIS sector count (7:0) */
14872 }
14873 else
14874 {
14875 fis->d.sectorCount = 0xFF; /* FIS sector count (7:0) */
14876 }
14877 fis->d.sectorCountExp = 0;
14878 fis->d.reserved4 = 0;
14879 fis->d.control = 0; /* FIS HOB bit clear */
14880 fis->d.reserved5 = 0;
14881
14882 agRequestType = AGSA_SATA_PROTOCOL_DMA_WRITE;
14883
14884 break;
14885 case SAT_WRITE_SECTORS:
14886 fis->h.fisType = 0x27; /* Reg host to device */
14887 fis->h.c_pmPort = 0x80; /* C bit is set */
14888 fis->h.command = SAT_WRITE_SECTORS; /* 0x30 */
14889 fis->h.features = 0; /* FIS reserve */
14890 fis->d.lbaLow = LBA[3]; /* FIS LBA (7 :0 ) */
14891 fis->d.lbaMid = LBA[2]; /* FIS LBA (15:8 ) */
14892 fis->d.lbaHigh = LBA[1]; /* FIS LBA (23:16) */
14893
14894 /* FIS LBA mode set LBA (27:24) */
14895 fis->d.device = (bit8)((0x4 << 4) | (LBA[0] & 0xF));
14896
14897 fis->d.lbaLowExp = 0;
14898 fis->d.lbaMidExp = 0;
14899 fis->d.lbaHighExp = 0;
14900 fis->d.featuresExp = 0;
14901 if (satOrgIOContext->LoopNum == 1)
14902 {
14903 /* last loop */
14904 fis->d.sectorCount = (bit8)Remainder; /* FIS sector count (7:0) */
14905 }
14906 else
14907 {
14908 fis->d.sectorCount = 0xFF; /* FIS sector count (7:0) */
14909 }
14910 fis->d.sectorCountExp = 0;
14911 fis->d.reserved4 = 0;
14912 fis->d.control = 0; /* FIS HOB bit clear */
14913 fis->d.reserved5 = 0;
14914
14915 agRequestType = AGSA_SATA_PROTOCOL_PIO_WRITE;
14916
14917 break;
14918 case SAT_WRITE_DMA_EXT:
14919 fis->h.fisType = 0x27; /* Reg host to device */
14920 fis->h.c_pmPort = 0x80; /* C Bit is set */
14921 fis->h.command = SAT_WRITE_DMA_EXT; /* 0x3D */
14922 fis->h.features = 0; /* FIS reserve */
14923 fis->d.lbaLow = LBA[3]; /* FIS LBA (7 :0 ) */
14924 fis->d.lbaMid = LBA[2]; /* FIS LBA (15:8 ) */
14925 fis->d.lbaHigh = LBA[1]; /* FIS LBA (23:16) */
14926 fis->d.device = 0x40; /* FIS LBA mode set */
14927 fis->d.lbaLowExp = LBA[0]; /* FIS LBA (31:24) */
14928 fis->d.lbaMidExp = 0; /* FIS LBA (39:32) */
14929 fis->d.lbaHighExp = 0; /* FIS LBA (47:40) */
14930 fis->d.featuresExp = 0; /* FIS reserve */
14931 if (satOrgIOContext->LoopNum == 1)
14932 {
14933 /* last loop */
14934 fis->d.sectorCount = (bit8)(Remainder & 0xFF); /* FIS sector count (7:0) */
14935 fis->d.sectorCountExp = (bit8)((Remainder & 0xFF00) >> 8); /* FIS sector count (15:8) */
14936 }
14937 else
14938 {
14939 fis->d.sectorCount = 0xFF; /* FIS sector count (7:0) */
14940 fis->d.sectorCountExp = 0xFF; /* FIS sector count (15:8) */
14941 }
14942 fis->d.reserved4 = 0;
14943 fis->d.control = 0; /* FIS HOB bit clear */
14944 fis->d.reserved5 = 0;
14945
14946 agRequestType = AGSA_SATA_PROTOCOL_DMA_WRITE;
14947
14948 break;
14949 case SAT_WRITE_SECTORS_EXT:
14950 fis->h.fisType = 0x27; /* Reg host to device */
14951 fis->h.c_pmPort = 0x80; /* C Bit is set */
14952 fis->h.command = SAT_WRITE_SECTORS_EXT; /* 0x34 */
14953
14954 fis->h.features = 0; /* FIS reserve */
14955 fis->d.lbaLow = LBA[3]; /* FIS LBA (7 :0 ) */
14956 fis->d.lbaMid = LBA[2]; /* FIS LBA (15:8 ) */
14957 fis->d.lbaHigh = LBA[1]; /* FIS LBA (23:16) */
14958 fis->d.device = 0x40; /* FIS LBA mode set */
14959 fis->d.lbaLowExp = LBA[0]; /* FIS LBA (31:24) */
14960 fis->d.lbaMidExp = 0; /* FIS LBA (39:32) */
14961 fis->d.lbaHighExp = 0; /* FIS LBA (47:40) */
14962 fis->d.featuresExp = 0; /* FIS reserve */
14963 if (satOrgIOContext->LoopNum == 1)
14964 {
14965 /* last loop */
14966 fis->d.sectorCount = (bit8)(Remainder & 0xFF); /* FIS sector count (7:0) */
14967 fis->d.sectorCountExp = (bit8)((Remainder & 0xFF00) >> 8); /* FIS sector count (15:8) */
14968 }
14969 else
14970 {
14971 fis->d.sectorCount = 0xFF; /* FIS sector count (7:0) */
14972 fis->d.sectorCountExp = 0xFF; /* FIS sector count (15:8) */
14973 }
14974 fis->d.reserved4 = 0;
14975 fis->d.control = 0; /* FIS HOB bit clear */
14976 fis->d.reserved5 = 0;
14977
14978 agRequestType = AGSA_SATA_PROTOCOL_PIO_WRITE;
14979
14980 break;
14981 case SAT_WRITE_FPDMA_QUEUED:
14982 fis->h.fisType = 0x27; /* Reg host to device */
14983 fis->h.c_pmPort = 0x80; /* C Bit is set */
14984 fis->h.command = SAT_WRITE_FPDMA_QUEUED; /* 0x61 */
14985 fis->d.lbaLow = LBA[3]; /* FIS LBA (7 :0 ) */
14986 fis->d.lbaMid = LBA[2]; /* FIS LBA (15:8 ) */
14987 fis->d.lbaHigh = LBA[1]; /* FIS LBA (23:16) */
14988
14989 /* Check FUA bit */
14990 if (scsiCmnd->cdb[1] & SCSI_WRITE10_FUA_MASK)
14991 fis->d.device = 0xC0; /* FIS FUA set */
14992 else
14993 fis->d.device = 0x40; /* FIS FUA clear */
14994
14995 fis->d.lbaLowExp = LBA[0];; /* FIS LBA (31:24) */
14996 fis->d.lbaMidExp = 0; /* FIS LBA (39:32) */
14997 fis->d.lbaHighExp = 0; /* FIS LBA (47:40) */
14998 if (satOrgIOContext->LoopNum == 1)
14999 {
15000 /* last loop */
15001 fis->h.features = (bit8)(Remainder & 0xFF); /* FIS sector count (7:0) */
15002 fis->d.featuresExp = (bit8)((Remainder & 0xFF00) >> 8); /* FIS sector count (15:8) */
15003 }
15004 else
15005 {
15006 fis->h.features = 0xFF; /* FIS sector count (7:0) */
15007 fis->d.featuresExp = 0xFF; /* FIS sector count (15:8) */
15008 }
15009 fis->d.sectorCount = 0; /* Tag (7:3) set by LL layer */
15010 fis->d.sectorCountExp = 0;
15011 fis->d.reserved4 = 0;
15012 fis->d.control = 0; /* FIS HOB bit clear */
15013 fis->d.reserved5 = 0;
15014
15015 agRequestType = AGSA_SATA_PROTOCOL_FPDMA_WRITE;
15016 break;
15017
15018 default:
15019 TI_DBG1(("satChainedWriteNVerify_Write: error incorrect ata command 0x%x\n", satIOContext->ATACmd));
15020 return tiError;
15021 break;
15022 }
15023
15024 /* Initialize CB for SATA completion.
15025 */
15026 /* chained data */
15027 satIOContext->satCompleteCB = &satChainedWriteNVerifyCB;
15028
15029
15030 /*
15031 * Prepare SGL and send FIS to LL layer.
15032 */
15033 satIOContext->reqType = agRequestType; /* Save it */
15034
15035 status = sataLLIOStart( tiRoot,
15036 tiIORequest,
15037 tiDeviceHandle,
15038 tiScsiRequest,
15039 satIOContext);
15040
15041 TI_DBG5(("satChainedWriteNVerify_Write: return\n"));
15042 return (status);
15043
15044 }
15045
15046 /*
15047 similar to write12 and verify10;
15048 this will be similar to verify12
15049 */
15050 GLOBAL bit32 satChainedWriteNVerify_Start_Verify(
15051 tiRoot_t *tiRoot,
15052 tiIORequest_t *tiIORequest,
15053 tiDeviceHandle_t *tiDeviceHandle,
15054 tiScsiInitiatorRequest_t *tiScsiRequest,
15055 satIOContext_t *satIOContext)
15056 {
15057 /*
15058 deal with transfer length; others have been handled previously at this point;
15059 no LBA check; no range check;
15060 */
15061 bit32 status;
15062 bit32 agRequestType = AGSA_SATA_PROTOCOL_NON_DATA;
15063 satDeviceData_t *pSatDevData;
15064 tiIniScsiCmnd_t *scsiCmnd;
15065 agsaFisRegHostToDevice_t *fis;
15066 bit32 lba = 0;
15067 bit32 tl = 0;
15068 bit32 LoopNum = 1;
15069 bit8 LBA[4];
15070 bit8 TL[4];
15071
15072 pSatDevData = satIOContext->pSatDevData;
15073 scsiCmnd = &tiScsiRequest->scsiCmnd;
15074 fis = satIOContext->pFis;
15075
15076 TI_DBG5(("satChainedWriteNVerify_Start_Verify: start\n"));
15077
15078 osti_memset(LBA, 0, sizeof(LBA));
15079 osti_memset(TL, 0, sizeof(TL));
15080
15081 /* do not use memcpy due to indexing in LBA and TL */
15082 LBA[0] = scsiCmnd->cdb[2]; /* MSB */
15083 LBA[1] = scsiCmnd->cdb[3];
15084 LBA[2] = scsiCmnd->cdb[4];
15085 LBA[3] = scsiCmnd->cdb[5]; /* LSB */
15086
15087 TL[0] = scsiCmnd->cdb[6]; /* MSB */
15088 TL[1] = scsiCmnd->cdb[7];
15089 TL[2] = scsiCmnd->cdb[7];
15090 TL[3] = scsiCmnd->cdb[8]; /* LSB */
15091
15092 lba = satComputeCDB12LBA(satIOContext);
15093 tl = satComputeCDB12TL(satIOContext);
15094
15095 if (pSatDevData->sat48BitSupport == agTRUE)
15096 {
15097 TI_DBG5(("satChainedWriteNVerify_Start_Verify: SAT_READ_VERIFY_SECTORS_EXT\n"));
15098 fis->h.fisType = 0x27; /* Reg host to device */
15099 fis->h.c_pmPort = 0x80; /* C Bit is set */
15100
15101 fis->h.command = SAT_READ_VERIFY_SECTORS_EXT;/* 0x42 */
15102 fis->h.features = 0; /* FIS reserve */
15103 fis->d.lbaLow = scsiCmnd->cdb[5]; /* FIS LBA (7 :0 ) */
15104 fis->d.lbaMid = scsiCmnd->cdb[4]; /* FIS LBA (15:8 ) */
15105 fis->d.lbaHigh = scsiCmnd->cdb[3]; /* FIS LBA (23:16) */
15106 fis->d.device = 0x40; /* FIS LBA mode set 01000000 */
15107 fis->d.lbaLowExp = scsiCmnd->cdb[2]; /* FIS LBA (31:24) */
15108 fis->d.lbaMidExp = 0; /* FIS LBA (39:32) */
15109 fis->d.lbaHighExp = 0; /* FIS LBA (47:40) */
15110 fis->d.featuresExp = 0; /* FIS reserve */
15111 fis->d.sectorCount = scsiCmnd->cdb[8]; /* FIS sector count (7:0) */
15112 fis->d.sectorCountExp = scsiCmnd->cdb[7]; /* FIS sector count (15:8) */
15113
15114 fis->d.reserved4 = 0;
15115 fis->d.control = 0; /* FIS HOB bit clear */
15116 fis->d.reserved5 = 0;
15117
15118 agRequestType = AGSA_SATA_PROTOCOL_NON_DATA;
15119 satIOContext->ATACmd = SAT_READ_VERIFY_SECTORS_EXT;
15120 }
15121 else
15122 {
15123 TI_DBG5(("satChainedWriteNVerify_Start_Verify: SAT_READ_VERIFY_SECTORS\n"));
15124 fis->h.fisType = 0x27; /* Reg host to device */
15125 fis->h.c_pmPort = 0x80; /* C bit is set */
15126 fis->h.command = SAT_READ_VERIFY_SECTORS; /* 0x40 */
15127 fis->h.features = 0; /* FIS reserve */
15128 fis->d.lbaLow = scsiCmnd->cdb[5]; /* FIS LBA (7 :0 ) */
15129 fis->d.lbaMid = scsiCmnd->cdb[4]; /* FIS LBA (15:8 ) */
15130 fis->d.lbaHigh = scsiCmnd->cdb[3]; /* FIS LBA (23:16) */
15131 /* FIS LBA mode set LBA (27:24) */
15132 fis->d.device = (bit8)((0x4 << 4) | (scsiCmnd->cdb[2] & 0xF));
15133 fis->d.lbaLowExp = 0;
15134 fis->d.lbaMidExp = 0;
15135 fis->d.lbaHighExp = 0;
15136 fis->d.featuresExp = 0;
15137 fis->d.sectorCount = scsiCmnd->cdb[8]; /* FIS sector count (7:0) */
15138 fis->d.sectorCountExp = 0;
15139 fis->d.reserved4 = 0;
15140 fis->d.control = 0; /* FIS HOB bit clear */
15141 fis->d.reserved5 = 0;
15142
15143 agRequestType = AGSA_SATA_PROTOCOL_NON_DATA;
15144 satIOContext->ATACmd = SAT_READ_VERIFY_SECTORS;
15145
15146 }
15147
15148 satIOContext->currentLBA = lba;
15149 satIOContext->OrgTL = tl;
15150
15151 /*
15152 computing number of loop and remainder for tl
15153 0xFF in case not ext
15154 0xFFFF in case EXT
15155 */
15156 if (fis->h.command == SAT_READ_VERIFY_SECTORS)
15157 {
15158 LoopNum = satComputeLoopNum(tl, 0xFF);
15159 }
15160 else if (fis->h.command == SAT_READ_VERIFY_SECTORS_EXT)
15161 {
15162 /* SAT_READ_SECTORS_EXT, SAT_READ_DMA_EXT */
15163 LoopNum = satComputeLoopNum(tl, 0xFFFF);
15164 }
15165 else
15166 {
15167 TI_DBG1(("satChainedWriteNVerify_Start_Verify: error case 1!!!\n"));
15168 LoopNum = 1;
15169 }
15170
15171 satIOContext->LoopNum = LoopNum;
15172
15173 if (LoopNum == 1)
15174 {
15175 TI_DBG5(("satChainedWriteNVerify_Start_Verify: NON CHAINED data\n"));
15176 /* Initialize CB for SATA completion.
15177 */
15178 satIOContext->satCompleteCB = &satNonChainedWriteNVerifyCB;
15179 }
15180 else
15181 {
15182 TI_DBG1(("satChainedWriteNVerify_Start_Verify: CHAINED data\n"));
15183 /* re-setting tl */
15184 if (fis->h.command == SAT_READ_VERIFY_SECTORS)
15185 {
15186 fis->d.sectorCount = 0xFF;
15187 }
15188 else if (fis->h.command == SAT_READ_VERIFY_SECTORS_EXT)
15189 {
15190 fis->d.sectorCount = 0xFF;
15191 fis->d.sectorCountExp = 0xFF;
15192 }
15193 else
15194 {
15195 TI_DBG1(("satChainedWriteNVerify_Start_Verify: error case 2!!!\n"));
15196 }
15197
15198 /* Initialize CB for SATA completion.
15199 */
15200 satIOContext->satCompleteCB = &satChainedWriteNVerifyCB;
15201 }
15202
15203
15204 /*
15205 * Prepare SGL and send FIS to LL layer.
15206 */
15207 satIOContext->reqType = agRequestType; /* Save it */
15208
15209 status = sataLLIOStart( tiRoot,
15210 tiIORequest,
15211 tiDeviceHandle,
15212 tiScsiRequest,
15213 satIOContext);
15214 return (status);
15215 }
15216
15217 GLOBAL bit32 satChainedWriteNVerify_Verify(
15218 tiRoot_t *tiRoot,
15219 tiIORequest_t *tiIORequest,
15220 tiDeviceHandle_t *tiDeviceHandle,
15221 tiScsiInitiatorRequest_t *tiScsiRequest,
15222 satIOContext_t *satIOContext)
15223 {
15224 bit32 status;
15225 satIOContext_t *satOrgIOContext = agNULL;
15226 agsaFisRegHostToDevice_t *fis;
15227 bit32 agRequestType = AGSA_SATA_PROTOCOL_NON_DATA;
15228 bit32 lba = 0;
15229 bit32 DenomTL = 0xFF;
15230 bit32 Remainder = 0;
15231 bit8 LBA[4]; /* 0 MSB, 3 LSB */
15232
15233 TI_DBG2(("satChainedWriteNVerify_Verify: start\n"));
15234
15235 fis = satIOContext->pFis;
15236 satOrgIOContext = satIOContext->satOrgIOContext;
15237
15238 osti_memset(LBA,0, sizeof(LBA));
15239
15240 switch (satOrgIOContext->ATACmd)
15241 {
15242 case SAT_READ_VERIFY_SECTORS:
15243 DenomTL = 0xFF;
15244 break;
15245 case SAT_READ_VERIFY_SECTORS_EXT:
15246 DenomTL = 0xFFFF;
15247 break;
15248 default:
15249 TI_DBG1(("satChainedWriteNVerify_Verify: error incorrect ata command 0x%x\n", satIOContext->ATACmd));
15250 return tiError;
15251 break;
15252 }
15253
15254 Remainder = satOrgIOContext->OrgTL % DenomTL;
15255 satOrgIOContext->currentLBA = satOrgIOContext->currentLBA + DenomTL;
15256 lba = satOrgIOContext->currentLBA;
15257
15258 LBA[0] = (bit8)((lba & 0xF000) >> (8 * 3)); /* MSB */
15259 LBA[1] = (bit8)((lba & 0xF00) >> (8 * 2));
15260 LBA[2] = (bit8)((lba & 0xF0) >> 8);
15261 LBA[3] = (bit8)(lba & 0xF); /* LSB */
15262
15263 switch (satOrgIOContext->ATACmd)
15264 {
15265 case SAT_READ_VERIFY_SECTORS:
15266 fis->h.fisType = 0x27; /* Reg host to device */
15267 fis->h.c_pmPort = 0x80; /* C bit is set */
15268 fis->h.command = SAT_READ_VERIFY_SECTORS; /* 0x40 */
15269 fis->h.features = 0; /* FIS reserve */
15270 fis->d.lbaLow = LBA[3]; /* FIS LBA (7 :0 ) */
15271 fis->d.lbaMid = LBA[2]; /* FIS LBA (15:8 ) */
15272 fis->d.lbaHigh = LBA[1]; /* FIS LBA (23:16) */
15273
15274 /* FIS LBA mode set LBA (27:24) */
15275 fis->d.device = (bit8)((0x4 << 4) | (LBA[0] & 0xF));
15276
15277 fis->d.lbaLowExp = 0;
15278 fis->d.lbaMidExp = 0;
15279 fis->d.lbaHighExp = 0;
15280 fis->d.featuresExp = 0;
15281 if (satOrgIOContext->LoopNum == 1)
15282 {
15283 /* last loop */
15284 fis->d.sectorCount = (bit8)Remainder; /* FIS sector count (7:0) */
15285 }
15286 else
15287 {
15288 fis->d.sectorCount = 0xFF; /* FIS sector count (7:0) */
15289 }
15290 fis->d.sectorCountExp = 0;
15291 fis->d.reserved4 = 0;
15292 fis->d.control = 0; /* FIS HOB bit clear */
15293 fis->d.reserved5 = 0;
15294
15295 agRequestType = AGSA_SATA_PROTOCOL_NON_DATA;
15296
15297 break;
15298 case SAT_READ_VERIFY_SECTORS_EXT:
15299 fis->h.fisType = 0x27; /* Reg host to device */
15300 fis->h.c_pmPort = 0x80; /* C Bit is set */
15301 fis->h.command = SAT_READ_VERIFY_SECTORS_EXT; /* 0x42 */
15302 fis->h.features = 0; /* FIS reserve */
15303 fis->d.lbaLow = LBA[3]; /* FIS LBA (7 :0 ) */
15304 fis->d.lbaMid = LBA[2]; /* FIS LBA (15:8 ) */
15305 fis->d.lbaHigh = LBA[1]; /* FIS LBA (23:16) */
15306 fis->d.device = 0x40; /* FIS LBA mode set */
15307 fis->d.lbaLowExp = LBA[0]; /* FIS LBA (31:24) */
15308 fis->d.lbaMidExp = 0; /* FIS LBA (39:32) */
15309 fis->d.lbaHighExp = 0; /* FIS LBA (47:40) */
15310 fis->d.featuresExp = 0; /* FIS reserve */
15311 if (satOrgIOContext->LoopNum == 1)
15312 {
15313 /* last loop */
15314 fis->d.sectorCount = (bit8)(Remainder & 0xFF); /* FIS sector count (7:0) */
15315 fis->d.sectorCountExp = (bit8)((Remainder & 0xFF00) >> 8); /* FIS sector count (15:8) */
15316 }
15317 else
15318 {
15319 fis->d.sectorCount = 0xFF; /* FIS sector count (7:0) */
15320 fis->d.sectorCountExp = 0xFF; /* FIS sector count (15:8) */
15321 }
15322 fis->d.reserved4 = 0;
15323 fis->d.control = 0; /* FIS HOB bit clear */
15324 fis->d.reserved5 = 0;
15325
15326 agRequestType = AGSA_SATA_PROTOCOL_NON_DATA;
15327
15328 break;
15329
15330 default:
15331 TI_DBG1(("satChainedWriteNVerify_Verify: error incorrect ata command 0x%x\n", satIOContext->ATACmd));
15332 return tiError;
15333 break;
15334 }
15335
15336 /* Initialize CB for SATA completion.
15337 */
15338 /* chained data */
15339 satIOContext->satCompleteCB = &satChainedWriteNVerifyCB;
15340
15341
15342 /*
15343 * Prepare SGL and send FIS to LL layer.
15344 */
15345 satIOContext->reqType = agRequestType; /* Save it */
15346
15347 status = sataLLIOStart( tiRoot,
15348 tiIORequest,
15349 tiDeviceHandle,
15350 tiScsiRequest,
15351 satIOContext);
15352
15353 TI_DBG5(("satChainedWriteNVerify_Verify: return\n"));
15354 return (status);
15355
15356 }
15357
15358
15359 /*****************************************************************************/
15360 /*! \brief SAT implementation for SCSI satWriteAndVerify16.
15361 *
15362 * SAT implementation for SCSI satWriteAndVerify16.
15363 *
15364 * \param tiRoot: Pointer to TISA initiator driver/port instance.
15365 * \param tiIORequest: Pointer to TISA I/O request context for this I/O.
15366 * \param tiDeviceHandle: Pointer to TISA device handle for this I/O.
15367 * \param tiScsiRequest: Pointer to TISA SCSI I/O request and SGL list.
15368 * \param satIOContext_t: Pointer to the SAT IO Context
15369 *
15370 * \return If command is started successfully
15371 * - \e tiSuccess: I/O request successfully initiated.
15372 * - \e tiBusy: No resources available, try again later.
15373 * - \e tiIONoDevice: Invalid device handle.
15374 * - \e tiError: Other errors.
15375 */
15376 /*****************************************************************************/
15377 GLOBAL bit32 satWriteAndVerify16(
15378 tiRoot_t *tiRoot,
15379 tiIORequest_t *tiIORequest,
15380 tiDeviceHandle_t *tiDeviceHandle,
15381 tiScsiInitiatorRequest_t *tiScsiRequest,
15382 satIOContext_t *satIOContext)
15383 {
15384 /*
15385 combination of write16 and verify16
15386 since write16 has 8 bytes LBA -> problem ATA LBA(upto 6 bytes), no support
15387 */
15388 bit32 status;
15389 bit32 agRequestType = AGSA_SATA_PROTOCOL_DMA_WRITE;
15390 satDeviceData_t *pSatDevData;
15391 scsiRspSense_t *pSense;
15392 tiIniScsiCmnd_t *scsiCmnd;
15393 agsaFisRegHostToDevice_t *fis;
15394 bit32 lba = 0;
15395 bit32 tl = 0;
15396 bit32 LoopNum = 1;
15397 bit8 LBA[8];
15398 bit8 TL[8];
15399 bit32 rangeChk = agFALSE; /* lba and tl range check */
15400 bit32 limitChk = agFALSE; /* lba and tl range check */
15401
15402 pSense = satIOContext->pSense;
15403 pSatDevData = satIOContext->pSatDevData;
15404 scsiCmnd = &tiScsiRequest->scsiCmnd;
15405 fis = satIOContext->pFis;
15406 TI_DBG5(("satWriteAndVerify16:start\n"));
15407
15408 /* checking BYTCHK bit */
15409 if (scsiCmnd->cdb[1] & SCSI_WRITE_N_VERIFY_BYTCHK_MASK)
15410 {
15411 satSetSensePayload( pSense,
15412 SCSI_SNSKEY_ILLEGAL_REQUEST,
15413 0,
15414 SCSI_SNSCODE_INVALID_FIELD_IN_CDB,
15415 satIOContext);
15416
15417 ostiInitiatorIOCompleted( tiRoot,
15418 tiIORequest,
15419 tiIOSuccess,
15420 SCSI_STAT_CHECK_CONDITION,
15421 satIOContext->pTiSenseData,
15422 satIOContext->interruptContext );
15423
15424 TI_DBG1(("satWriteAndVerify16: BYTCHK bit checking \n"));
15425 return tiSuccess;
15426 }
15427
15428
15429 /* checking CONTROL */
15430 /* NACA == 1 or LINK == 1*/
15431 if ( (scsiCmnd->cdb[15] & SCSI_NACA_MASK) || (scsiCmnd->cdb[15] & SCSI_LINK_MASK) )
15432 {
15433 satSetSensePayload( pSense,
15434 SCSI_SNSKEY_ILLEGAL_REQUEST,
15435 0,
15436 SCSI_SNSCODE_INVALID_FIELD_IN_CDB,
15437 satIOContext);
15438
15439 ostiInitiatorIOCompleted( tiRoot,
15440 tiIORequest,
15441 tiIOSuccess,
15442 SCSI_STAT_CHECK_CONDITION,
15443 satIOContext->pTiSenseData,
15444 satIOContext->interruptContext );
15445
15446 TI_DBG2(("satWriteAndVerify16: return control\n"));
15447 return tiSuccess;
15448 }
15449
15450 osti_memset(LBA, 0, sizeof(LBA));
15451 osti_memset(TL, 0, sizeof(TL));
15452
15453
15454 /* do not use memcpy due to indexing in LBA and TL */
15455 LBA[0] = scsiCmnd->cdb[2]; /* MSB */
15456 LBA[1] = scsiCmnd->cdb[3];
15457 LBA[2] = scsiCmnd->cdb[4];
15458 LBA[3] = scsiCmnd->cdb[5];
15459 LBA[4] = scsiCmnd->cdb[6];
15460 LBA[5] = scsiCmnd->cdb[7];
15461 LBA[6] = scsiCmnd->cdb[8];
15462 LBA[7] = scsiCmnd->cdb[9]; /* LSB */
15463
15464 TL[0] = 0;
15465 TL[1] = 0;
15466 TL[2] = 0;
15467 TL[3] = 0;
15468 TL[4] = scsiCmnd->cdb[10]; /* MSB */
15469 TL[5] = scsiCmnd->cdb[11];
15470 TL[6] = scsiCmnd->cdb[12];
15471 TL[7] = scsiCmnd->cdb[13]; /* LSB */
15472
15473 rangeChk = satAddNComparebit64(LBA, TL);
15474
15475 limitChk = satCompareLBALimitbit(LBA);
15476
15477 lba = satComputeCDB16LBA(satIOContext);
15478 tl = satComputeCDB16TL(satIOContext);
15479
15480
15481 /* Table 34, 9.1, p 46 */
15482 /*
15483 note: As of 2/10/2006, no support for DMA QUEUED
15484 */
15485
15486 /*
15487 Table 34, 9.1, p 46, b
15488 When no 48-bit addressing support or NCQ, if LBA is beyond (2^28 - 1),
15489 return check condition
15490 */
15491 if (pSatDevData->satNCQ != agTRUE &&
15492 pSatDevData->sat48BitSupport != agTRUE
15493 )
15494 {
15495 if (limitChk)
15496 {
15497 TI_DBG1(("satWriteAndVerify16: return LBA out of range, not EXT\n"));
15498 satSetSensePayload( pSense,
15499 SCSI_SNSKEY_ILLEGAL_REQUEST,
15500 0,
15501 SCSI_SNSCODE_LOGICAL_BLOCK_ADDRESS_OUT_OF_RANGE,
15502 satIOContext);
15503
15504 ostiInitiatorIOCompleted( tiRoot,
15505 tiIORequest,
15506 tiIOSuccess,
15507 SCSI_STAT_CHECK_CONDITION,
15508 satIOContext->pTiSenseData,
15509 satIOContext->interruptContext );
15510
15511 return tiSuccess;
15512 }
15513 if (rangeChk) // if (lba + tl > SAT_TR_LBA_LIMIT)
15514 {
15515 TI_DBG1(("satWriteAndVerify16: return LBA+TL out of range, not EXT\n"));
15516 satSetSensePayload( pSense,
15517 SCSI_SNSKEY_ILLEGAL_REQUEST,
15518 0,
15519 SCSI_SNSCODE_LOGICAL_BLOCK_ADDRESS_OUT_OF_RANGE,
15520 satIOContext);
15521
15522 ostiInitiatorIOCompleted( tiRoot,
15523 tiIORequest,
15524 tiIOSuccess,
15525 SCSI_STAT_CHECK_CONDITION,
15526 satIOContext->pTiSenseData,
15527 satIOContext->interruptContext );
15528
15529 return tiSuccess;
15530 }
15531 }
15532
15533
15534 /* case 1 and 2 */
15535 if (!rangeChk) // if (lba + tl <= SAT_TR_LBA_LIMIT)
15536 {
15537 if (pSatDevData->satDMASupport == agTRUE && pSatDevData->satDMAEnabled == agTRUE)
15538 {
15539 /* case 2 */
15540 /* WRITE DMA*/
15541 /* In case that we can't fit the transfer length, we loop */
15542 TI_DBG5(("satWriteAndVerify16: case 2\n"));
15543 fis->h.fisType = 0x27; /* Reg host to device */
15544 fis->h.c_pmPort = 0x80; /* C bit is set */
15545 fis->h.command = SAT_WRITE_DMA; /* 0xCA */
15546 fis->h.features = 0; /* FIS reserve */
15547 fis->d.lbaLow = scsiCmnd->cdb[9]; /* FIS LBA (7 :0 ) */
15548 fis->d.lbaMid = scsiCmnd->cdb[8]; /* FIS LBA (15:8 ) */
15549 fis->d.lbaHigh = scsiCmnd->cdb[7]; /* FIS LBA (23:16) */
15550
15551 /* FIS LBA mode set LBA (27:24) */
15552 fis->d.device = (bit8)((0x4 << 4) | (scsiCmnd->cdb[6] & 0xF));
15553
15554 fis->d.lbaLowExp = 0;
15555 fis->d.lbaMidExp = 0;
15556 fis->d.lbaHighExp = 0;
15557 fis->d.featuresExp = 0;
15558 fis->d.sectorCount = scsiCmnd->cdb[13]; /* FIS sector count (7:0) */
15559 fis->d.sectorCountExp = 0;
15560 fis->d.reserved4 = 0;
15561 fis->d.control = 0; /* FIS HOB bit clear */
15562 fis->d.reserved5 = 0;
15563
15564 agRequestType = AGSA_SATA_PROTOCOL_DMA_WRITE;
15565 satIOContext->ATACmd = SAT_WRITE_DMA;
15566 }
15567 else
15568 {
15569 /* case 1 */
15570 /* WRITE MULTIPLE or WRITE SECTOR(S) */
15571 /* WRITE SECTORS for easier implemetation */
15572 /* In case that we can't fit the transfer length, we loop */
15573 TI_DBG5(("satWriteAndVerify16: case 1\n"));
15574 fis->h.fisType = 0x27; /* Reg host to device */
15575 fis->h.c_pmPort = 0x80; /* C bit is set */
15576 fis->h.command = SAT_WRITE_SECTORS; /* 0x30 */
15577 fis->h.features = 0; /* FIS reserve */
15578 fis->d.lbaLow = scsiCmnd->cdb[9]; /* FIS LBA (7 :0 ) */
15579 fis->d.lbaMid = scsiCmnd->cdb[8]; /* FIS LBA (15:8 ) */
15580 fis->d.lbaHigh = scsiCmnd->cdb[7]; /* FIS LBA (23:16) */
15581
15582 /* FIS LBA mode set LBA (27:24) */
15583 fis->d.device = (bit8)((0x4 << 4) | (scsiCmnd->cdb[6] & 0xF));
15584
15585 fis->d.lbaLowExp = 0;
15586 fis->d.lbaMidExp = 0;
15587 fis->d.lbaHighExp = 0;
15588 fis->d.featuresExp = 0;
15589 fis->d.sectorCount = scsiCmnd->cdb[13]; /* FIS sector count (7:0) */
15590 fis->d.sectorCountExp = 0;
15591 fis->d.reserved4 = 0;
15592 fis->d.control = 0; /* FIS HOB bit clear */
15593 fis->d.reserved5 = 0;
15594
15595 agRequestType = AGSA_SATA_PROTOCOL_PIO_WRITE;
15596 satIOContext->ATACmd = SAT_WRITE_SECTORS;
15597 }
15598 }
15599
15600 /* case 3 and 4 */
15601 if (pSatDevData->sat48BitSupport == agTRUE)
15602 {
15603 if (pSatDevData->satDMASupport == agTRUE && pSatDevData->satDMAEnabled == agTRUE)
15604 {
15605 /* case 3 */
15606 /* WRITE DMA EXT or WRITE DMA FUA EXT */
15607 TI_DBG5(("satWriteAndVerify16: case 3\n"));
15608 fis->h.fisType = 0x27; /* Reg host to device */
15609 fis->h.c_pmPort = 0x80; /* C Bit is set */
15610
15611 /* SAT_WRITE_DMA_FUA_EXT is optional and we don't support it */
15612 fis->h.command = SAT_WRITE_DMA_EXT; /* 0x35 */
15613
15614 fis->h.features = 0; /* FIS reserve */
15615 fis->d.lbaLow = scsiCmnd->cdb[9]; /* FIS LBA (7 :0 ) */
15616 fis->d.lbaMid = scsiCmnd->cdb[8]; /* FIS LBA (15:8 ) */
15617 fis->d.lbaHigh = scsiCmnd->cdb[7]; /* FIS LBA (23:16) */
15618 fis->d.device = 0x40; /* FIS LBA mode set */
15619 fis->d.lbaLowExp = scsiCmnd->cdb[6]; /* FIS LBA (31:24) */
15620 fis->d.lbaMidExp = scsiCmnd->cdb[5]; /* FIS LBA (39:32) */
15621 fis->d.lbaHighExp = scsiCmnd->cdb[4]; /* FIS LBA (47:40) */
15622 fis->d.featuresExp = 0; /* FIS reserve */
15623 fis->d.sectorCount = scsiCmnd->cdb[13]; /* FIS sector count (7:0) */
15624 fis->d.sectorCountExp = scsiCmnd->cdb[12]; /* FIS sector count (15:8) */
15625 fis->d.reserved4 = 0;
15626 fis->d.control = 0; /* FIS HOB bit clear */
15627 fis->d.reserved5 = 0;
15628
15629 agRequestType = AGSA_SATA_PROTOCOL_DMA_WRITE;
15630 satIOContext->ATACmd = SAT_WRITE_DMA_EXT;
15631 }
15632 else
15633 {
15634 /* case 4 */
15635 /* WRITE MULTIPLE EXT or WRITE MULTIPLE FUA EXT or WRITE SECTOR(S) EXT */
15636 /* WRITE SECTORS EXT for easier implemetation */
15637 TI_DBG5(("satWriteAndVerify16: case 4\n"));
15638 fis->h.fisType = 0x27; /* Reg host to device */
15639 fis->h.c_pmPort = 0x80; /* C Bit is set */
15640 fis->h.command = SAT_WRITE_SECTORS_EXT; /* 0x34 */
15641
15642 fis->h.features = 0; /* FIS reserve */
15643 fis->d.lbaLow = scsiCmnd->cdb[9]; /* FIS LBA (7 :0 ) */
15644 fis->d.lbaMid = scsiCmnd->cdb[8]; /* FIS LBA (15:8 ) */
15645 fis->d.lbaHigh = scsiCmnd->cdb[7]; /* FIS LBA (23:16) */
15646 fis->d.device = 0x40; /* FIS LBA mode set */
15647 fis->d.lbaLowExp = scsiCmnd->cdb[6]; /* FIS LBA (31:24) */
15648 fis->d.lbaMidExp = scsiCmnd->cdb[5]; /* FIS LBA (39:32) */
15649 fis->d.lbaHighExp = scsiCmnd->cdb[4]; /* FIS LBA (47:40) */
15650 fis->d.featuresExp = 0; /* FIS reserve */
15651 fis->d.sectorCount = scsiCmnd->cdb[13]; /* FIS sector count (7:0) */
15652 fis->d.sectorCountExp = scsiCmnd->cdb[12]; /* FIS sector count (15:8) */
15653 fis->d.reserved4 = 0;
15654 fis->d.control = 0; /* FIS HOB bit clear */
15655 fis->d.reserved5 = 0;
15656
15657 agRequestType = AGSA_SATA_PROTOCOL_PIO_WRITE;
15658 satIOContext->ATACmd = SAT_WRITE_SECTORS_EXT;
15659 }
15660 }
15661
15662 /* case 5 */
15663 if (pSatDevData->satNCQ == agTRUE)
15664 {
15665 /* WRITE FPDMA QUEUED */
15666 if (pSatDevData->sat48BitSupport != agTRUE)
15667 {
15668 TI_DBG5(("satWriteAndVerify16: case 5 !!! error NCQ but 28 bit address support \n"));
15669 satSetSensePayload( pSense,
15670 SCSI_SNSKEY_ILLEGAL_REQUEST,
15671 0,
15672 SCSI_SNSCODE_INVALID_FIELD_IN_CDB,
15673 satIOContext);
15674
15675 ostiInitiatorIOCompleted( tiRoot,
15676 tiIORequest,
15677 tiIOSuccess,
15678 SCSI_STAT_CHECK_CONDITION,
15679 satIOContext->pTiSenseData,
15680 satIOContext->interruptContext );
15681 return tiSuccess;
15682 }
15683 TI_DBG6(("satWriteAndVerify16: case 5\n"));
15684
15685 /* Support 48-bit FPDMA addressing, use WRITE FPDMA QUEUE command */
15686
15687 fis->h.fisType = 0x27; /* Reg host to device */
15688 fis->h.c_pmPort = 0x80; /* C Bit is set */
15689 fis->h.command = SAT_WRITE_FPDMA_QUEUED; /* 0x61 */
15690 fis->h.features = scsiCmnd->cdb[13]; /* FIS sector count (7:0) */
15691 fis->d.lbaLow = scsiCmnd->cdb[9]; /* FIS LBA (7 :0 ) */
15692 fis->d.lbaMid = scsiCmnd->cdb[8]; /* FIS LBA (15:8 ) */
15693 fis->d.lbaHigh = scsiCmnd->cdb[7]; /* FIS LBA (23:16) */
15694
15695 /* Check FUA bit */
15696 if (scsiCmnd->cdb[1] & SCSI_WRITE16_FUA_MASK)
15697 fis->d.device = 0xC0; /* FIS FUA set */
15698 else
15699 fis->d.device = 0x40; /* FIS FUA clear */
15700
15701 fis->d.lbaLowExp = scsiCmnd->cdb[6]; /* FIS LBA (31:24) */
15702 fis->d.lbaMidExp = scsiCmnd->cdb[5]; /* FIS LBA (39:32) */
15703 fis->d.lbaHighExp = scsiCmnd->cdb[4]; /* FIS LBA (47:40) */
15704 fis->d.featuresExp = scsiCmnd->cdb[12]; /* FIS sector count (15:8) */
15705 fis->d.sectorCount = 0; /* Tag (7:3) set by LL layer */
15706 fis->d.sectorCountExp = 0;
15707 fis->d.reserved4 = 0;
15708 fis->d.control = 0; /* FIS HOB bit clear */
15709 fis->d.reserved5 = 0;
15710
15711 agRequestType = AGSA_SATA_PROTOCOL_FPDMA_WRITE;
15712 satIOContext->ATACmd = SAT_WRITE_FPDMA_QUEUED;
15713 }
15714
15715 satIOContext->currentLBA = lba;
15716 satIOContext->OrgTL = tl;
15717
15718 /*
15719 computing number of loop and remainder for tl
15720 0xFF in case not ext
15721 0xFFFF in case EXT
15722 */
15723 if (fis->h.command == SAT_WRITE_SECTORS || fis->h.command == SAT_WRITE_DMA)
15724 {
15725 LoopNum = satComputeLoopNum(tl, 0xFF);
15726 }
15727 else if (fis->h.command == SAT_WRITE_SECTORS_EXT ||
15728 fis->h.command == SAT_WRITE_DMA_EXT ||
15729 fis->h.command == SAT_WRITE_DMA_FUA_EXT
15730 )
15731 {
15732 /* SAT_READ_SECTORS_EXT, SAT_READ_DMA_EXT */
15733 LoopNum = satComputeLoopNum(tl, 0xFFFF);
15734 }
15735 else
15736 {
15737 /* SAT_WRITE_FPDMA_QUEUEDK */
15738 LoopNum = satComputeLoopNum(tl, 0xFFFF);
15739 }
15740
15741 satIOContext->LoopNum = LoopNum;
15742
15743
15744 if (LoopNum == 1)
15745 {
15746 TI_DBG5(("satWriteAndVerify16: NON CHAINED data\n"));
15747 /* Initialize CB for SATA completion.
15748 */
15749 satIOContext->satCompleteCB = &satNonChainedWriteNVerifyCB;
15750 }
15751 else
15752 {
15753 TI_DBG1(("satWriteAndVerify16: CHAINED data\n"));
15754 /* re-setting tl */
15755 if (fis->h.command == SAT_WRITE_SECTORS || fis->h.command == SAT_WRITE_DMA)
15756 {
15757 fis->d.sectorCount = 0xFF;
15758 }
15759 else if (fis->h.command == SAT_WRITE_SECTORS_EXT ||
15760 fis->h.command == SAT_WRITE_DMA_EXT ||
15761 fis->h.command == SAT_WRITE_DMA_FUA_EXT
15762 )
15763 {
15764 fis->d.sectorCount = 0xFF;
15765 fis->d.sectorCountExp = 0xFF;
15766 }
15767 else
15768 {
15769 /* SAT_WRITE_FPDMA_QUEUED */
15770 fis->h.features = 0xFF;
15771 fis->d.featuresExp = 0xFF;
15772 }
15773
15774 /* Initialize CB for SATA completion.
15775 */
15776 satIOContext->satCompleteCB = &satChainedWriteNVerifyCB;
15777 }
15778
15779
15780 /*
15781 * Prepare SGL and send FIS to LL layer.
15782 */
15783 satIOContext->reqType = agRequestType; /* Save it */
15784
15785 status = sataLLIOStart( tiRoot,
15786 tiIORequest,
15787 tiDeviceHandle,
15788 tiScsiRequest,
15789 satIOContext);
15790 return (status);
15791 }
15792
15793 /*****************************************************************************/
15794 /*! \brief SAT implementation for SCSI satReadMediaSerialNumber.
15795 *
15796 * SAT implementation for SCSI Read Media Serial Number.
15797 *
15798 * \param tiRoot: Pointer to TISA initiator driver/port instance.
15799 * \param tiIORequest: Pointer to TISA I/O request context for this I/O.
15800 * \param tiDeviceHandle: Pointer to TISA device handle for this I/O.
15801 * \param tiScsiRequest: Pointer to TISA SCSI I/O request and SGL list.
15802 * \param satIOContext_t: Pointer to the SAT IO Context
15803 *
15804 * \return If command is started successfully
15805 * - \e tiSuccess: I/O request successfully initiated.
15806 * - \e tiBusy: No resources available, try again later.
15807 * - \e tiIONoDevice: Invalid device handle.
15808 * - \e tiError: Other errors.
15809 */
15810 /*****************************************************************************/
15811 GLOBAL bit32 satReadMediaSerialNumber(
15812 tiRoot_t *tiRoot,
15813 tiIORequest_t *tiIORequest,
15814 tiDeviceHandle_t *tiDeviceHandle,
15815 tiScsiInitiatorRequest_t *tiScsiRequest,
15816 satIOContext_t *satIOContext)
15817 {
15818 bit32 status;
15819 bit32 agRequestType = AGSA_SATA_PROTOCOL_PIO_READ;
15820 satDeviceData_t *pSatDevData;
15821 scsiRspSense_t *pSense;
15822 tiIniScsiCmnd_t *scsiCmnd;
15823 agsaFisRegHostToDevice_t *fis;
15824 agsaSATAIdentifyData_t *pSATAIdData;
15825 bit8 *pSerialNumber;
15826
15827 pSense = satIOContext->pSense;
15828 pSatDevData = satIOContext->pSatDevData;
15829 scsiCmnd = &tiScsiRequest->scsiCmnd;
15830 fis = satIOContext->pFis;
15831 pSATAIdData = &(pSatDevData->satIdentifyData);
15832 pSerialNumber = (bit8 *) tiScsiRequest->sglVirtualAddr;
15833
15834
15835 TI_DBG1(("satReadMediaSerialNumber: start\n"));
15836
15837 /* checking CONTROL */
15838 /* NACA == 1 or LINK == 1*/
15839 if ( (scsiCmnd->cdb[11] & SCSI_NACA_MASK) || (scsiCmnd->cdb[11] & SCSI_LINK_MASK) )
15840 {
15841 satSetSensePayload( pSense,
15842 SCSI_SNSKEY_ILLEGAL_REQUEST,
15843 0,
15844 SCSI_SNSCODE_INVALID_FIELD_IN_CDB,
15845 satIOContext);
15846
15847 ostiInitiatorIOCompleted( tiRoot,
15848 tiIORequest,
15849 tiIOSuccess,
15850 SCSI_STAT_CHECK_CONDITION,
15851 satIOContext->pTiSenseData,
15852 satIOContext->interruptContext );
15853
15854 TI_DBG1(("satReadMediaSerialNumber: return control\n"));
15855 return tiSuccess;
15856 }
15857
15858 if (tiScsiRequest->scsiCmnd.expDataLength == 4)
15859 {
15860 if (pSATAIdData->commandSetFeatureDefault & 0x4)
15861 {
15862 TI_DBG1(("satReadMediaSerialNumber: Media serial number returning only length\n"));
15863 /* SPC-3 6.16 p192; filling in length */
15864 pSerialNumber[0] = 0;
15865 pSerialNumber[1] = 0;
15866 pSerialNumber[2] = 0;
15867 pSerialNumber[3] = 0x3C;
15868 }
15869 else
15870 {
15871 /* 1 sector - 4 = 512 - 4 to avoid underflow; 0x1fc*/
15872 pSerialNumber[0] = 0;
15873 pSerialNumber[1] = 0;
15874 pSerialNumber[2] = 0x1;
15875 pSerialNumber[3] = 0xfc;
15876 }
15877
15878 ostiInitiatorIOCompleted( tiRoot,
15879 tiIORequest,
15880 tiIOSuccess,
15881 SCSI_STAT_GOOD,
15882 agNULL,
15883 satIOContext->interruptContext);
15884
15885 return tiSuccess;
15886 }
15887
15888 if ( pSatDevData->IDDeviceValid == agTRUE)
15889 {
15890 if (pSATAIdData->commandSetFeatureDefault & 0x4)
15891 {
15892 /* word87 bit2 Media serial number is valid */
15893 /* read word 176 to 205; length is 2*30 = 60 = 0x3C*/
15894 tdhexdump("ID satReadMediaSerialNumber", (bit8*)pSATAIdData->currentMediaSerialNumber, 2*30);
15895 /* SPC-3 6.16 p192; filling in length */
15896 pSerialNumber[0] = 0;
15897 pSerialNumber[1] = 0;
15898 pSerialNumber[2] = 0;
15899 pSerialNumber[3] = 0x3C;
15900 osti_memcpy(&pSerialNumber[4], (void *)pSATAIdData->currentMediaSerialNumber, 60);
15901 tdhexdump("satReadMediaSerialNumber", (bit8*)pSerialNumber, 2*30 + 4);
15902
15903 ostiInitiatorIOCompleted( tiRoot,
15904 tiIORequest,
15905 tiIOSuccess,
15906 SCSI_STAT_GOOD,
15907 agNULL,
15908 satIOContext->interruptContext);
15909 return tiSuccess;
15910
15911
15912 }
15913 else
15914 {
15915 /* word87 bit2 Media serial number is NOT valid */
15916 TI_DBG1(("satReadMediaSerialNumber: Media serial number is NOT valid \n"));
15917
15918 if (pSatDevData->sat48BitSupport == agTRUE)
15919 {
15920 /* READ VERIFY SECTORS EXT */
15921 fis->h.fisType = 0x27; /* Reg host to device */
15922 fis->h.c_pmPort = 0x80; /* C Bit is set */
15923 fis->h.command = SAT_READ_SECTORS_EXT; /* 0x24 */
15924
15925 fis->h.features = 0; /* FIS reserve */
15926 fis->d.lbaLow = 0; /* FIS LBA (7 :0 ) */
15927 fis->d.lbaMid = 0; /* FIS LBA (15:8 ) */
15928 fis->d.lbaHigh = 0; /* FIS LBA (23:16) */
15929 fis->d.device = 0x40; /* FIS LBA mode set */
15930 fis->d.lbaLowExp = 0; /* FIS LBA (31:24) */
15931 fis->d.lbaMidExp = 0; /* FIS LBA (39:32) */
15932 fis->d.lbaHighExp = 0; /* FIS LBA (47:40) */
15933 fis->d.featuresExp = 0; /* FIS reserve */
15934 fis->d.sectorCount = 1; /* FIS sector count (7:0) */
15935 fis->d.sectorCountExp = 0; /* FIS sector count (15:8) */
15936 fis->d.reserved4 = 0;
15937 fis->d.control = 0; /* FIS HOB bit clear */
15938 fis->d.reserved5 = 0;
15939
15940 agRequestType = AGSA_SATA_PROTOCOL_PIO_READ;
15941 }
15942 else
15943 {
15944 /* READ VERIFY SECTORS */
15945 fis->h.fisType = 0x27; /* Reg host to device */
15946 fis->h.c_pmPort = 0x80; /* C Bit is set */
15947 fis->h.command = SAT_READ_SECTORS; /* 0x20 */
15948 fis->h.features = 0; /* FIS reserve */
15949 fis->d.lbaLow = 0; /* FIS LBA (7 :0 ) */
15950 fis->d.lbaMid = 0; /* FIS LBA (15:8 ) */
15951 fis->d.lbaHigh = 0; /* FIS LBA (23:16) */
15952 fis->d.device = 0x40; /* FIS LBA (27:24) and FIS LBA mode */
15953 fis->d.lbaLowExp = 0;
15954 fis->d.lbaMidExp = 0;
15955 fis->d.lbaHighExp = 0;
15956 fis->d.featuresExp = 0;
15957 fis->d.sectorCount = 1; /* FIS sector count (7:0) */
15958 fis->d.sectorCountExp = 0;
15959 fis->d.reserved4 = 0;
15960 fis->d.control = 0; /* FIS HOB bit clear */
15961 fis->d.reserved5 = 0;
15962
15963
15964 agRequestType = AGSA_SATA_PROTOCOL_PIO_READ;
15965 }
15966 satIOContext->satCompleteCB = &satReadMediaSerialNumberCB;
15967 satIOContext->reqType = agRequestType; /* Save it */
15968 status = sataLLIOStart( tiRoot,
15969 tiIORequest,
15970 tiDeviceHandle,
15971 tiScsiRequest,
15972 satIOContext);
15973
15974 return status;
15975 }
15976 }
15977 else
15978 {
15979 /* temporary failure */
15980 ostiInitiatorIOCompleted( tiRoot,
15981 tiIORequest,
15982 tiIOFailed,
15983 tiDetailOtherError,
15984 agNULL,
15985 satIOContext->interruptContext);
15986
15987 return tiSuccess;
15988
15989 }
15990
15991 }
15992
15993 /*****************************************************************************/
15994 /*! \brief SAT implementation for SCSI satReadBuffer.
15995 *
15996 * SAT implementation for SCSI Read Buffer.
15997 *
15998 * \param tiRoot: Pointer to TISA initiator driver/port instance.
15999 * \param tiIORequest: Pointer to TISA I/O request context for this I/O.
16000 * \param tiDeviceHandle: Pointer to TISA device handle for this I/O.
16001 * \param tiScsiRequest: Pointer to TISA SCSI I/O request and SGL list.
16002 * \param satIOContext_t: Pointer to the SAT IO Context
16003 *
16004 * \return If command is started successfully
16005 * - \e tiSuccess: I/O request successfully initiated.
16006 * - \e tiBusy: No resources available, try again later.
16007 * - \e tiIONoDevice: Invalid device handle.
16008 * - \e tiError: Other errors.
16009 */
16010 /*****************************************************************************/
16011 /* SAT-2, Revision 00*/
16012 GLOBAL bit32 satReadBuffer(
16013 tiRoot_t *tiRoot,
16014 tiIORequest_t *tiIORequest,
16015 tiDeviceHandle_t *tiDeviceHandle,
16016 tiScsiInitiatorRequest_t *tiScsiRequest,
16017 satIOContext_t *satIOContext)
16018 {
16019 bit32 status = tiSuccess;
16020 bit32 agRequestType = AGSA_SATA_PROTOCOL_PIO_READ;
16021 scsiRspSense_t *pSense;
16022 tiIniScsiCmnd_t *scsiCmnd;
16023 agsaFisRegHostToDevice_t *fis;
16024 bit32 bufferOffset;
16025 bit32 tl;
16026 bit8 mode;
16027 bit8 bufferID;
16028 bit8 *pBuff;
16029
16030 pSense = satIOContext->pSense;
16031 scsiCmnd = &tiScsiRequest->scsiCmnd;
16032 fis = satIOContext->pFis;
16033 pBuff = (bit8 *) tiScsiRequest->sglVirtualAddr;
16034
16035 TI_DBG2(("satReadBuffer: start\n"));
16036 /* checking CONTROL */
16037 /* NACA == 1 or LINK == 1*/
16038 if ( (scsiCmnd->cdb[9] & SCSI_NACA_MASK) || (scsiCmnd->cdb[9] & SCSI_LINK_MASK) )
16039 {
16040 satSetSensePayload( pSense,
16041 SCSI_SNSKEY_ILLEGAL_REQUEST,
16042 0,
16043 SCSI_SNSCODE_INVALID_FIELD_IN_CDB,
16044 satIOContext);
16045 ostiInitiatorIOCompleted( tiRoot,
16046 tiIORequest,
16047 tiIOSuccess,
16048 SCSI_STAT_CHECK_CONDITION,
16049 satIOContext->pTiSenseData,
16050 satIOContext->interruptContext );
16051 TI_DBG1(("satReadBuffer: return control\n"));
16052 return tiSuccess;
16053 }
16054
16055 bufferOffset = (scsiCmnd->cdb[3] << (8*2)) + (scsiCmnd->cdb[4] << 8) + scsiCmnd->cdb[5];
16056 tl = (scsiCmnd->cdb[6] << (8*2)) + (scsiCmnd->cdb[7] << 8) + scsiCmnd->cdb[8];
16057
16058 mode = (bit8)(scsiCmnd->cdb[1] & SCSI_READ_BUFFER_MODE_MASK);
16059 bufferID = scsiCmnd->cdb[2];
16060
16061 if (mode == READ_BUFFER_DATA_MODE) /* 2 */
16062 {
16063 if (bufferID == 0 && bufferOffset == 0 && tl == 512)
16064 {
16065 /* send ATA READ BUFFER */
16066 fis->h.fisType = 0x27; /* Reg host to device */
16067 fis->h.c_pmPort = 0x80; /* C Bit is set */
16068 fis->h.command = SAT_READ_BUFFER; /* 0xE4 */
16069 fis->h.features = 0; /* FIS reserve */
16070 fis->d.lbaLow = 0; /* FIS LBA (7 :0 ) */
16071 fis->d.lbaMid = 0; /* FIS LBA (15:8 ) */
16072 fis->d.lbaHigh = 0; /* FIS LBA (23:16) */
16073 fis->d.device = 0x40; /* FIS LBA (27:24) and FIS LBA mode */
16074 fis->d.lbaLowExp = 0;
16075 fis->d.lbaMidExp = 0;
16076 fis->d.lbaHighExp = 0;
16077 fis->d.featuresExp = 0;
16078 fis->d.sectorCount = 0; /* FIS sector count (7:0) */
16079 fis->d.sectorCountExp = 0;
16080 fis->d.reserved4 = 0;
16081 fis->d.control = 0; /* FIS HOB bit clear */
16082 fis->d.reserved5 = 0;
16083
16084 agRequestType = AGSA_SATA_PROTOCOL_PIO_READ;
16085 satIOContext->satCompleteCB = &satReadBufferCB;
16086 satIOContext->reqType = agRequestType; /* Save it */
16087
16088 status = sataLLIOStart( tiRoot,
16089 tiIORequest,
16090 tiDeviceHandle,
16091 tiScsiRequest,
16092 satIOContext);
16093 return status;
16094 }
16095 if (bufferID == 0 && bufferOffset == 0 && tl != 512)
16096 {
16097 satSetSensePayload( pSense,
16098 SCSI_SNSKEY_ILLEGAL_REQUEST,
16099 0,
16100 SCSI_SNSCODE_INVALID_FIELD_IN_CDB,
16101 satIOContext);
16102 ostiInitiatorIOCompleted( tiRoot,
16103 tiIORequest,
16104 tiIOSuccess,
16105 SCSI_STAT_CHECK_CONDITION,
16106 satIOContext->pTiSenseData,
16107 satIOContext->interruptContext );
16108 TI_DBG1(("satReadBuffer: allocation length is not 512; it is %d\n", tl));
16109 return tiSuccess;
16110 }
16111 if (bufferID == 0 && bufferOffset != 0)
16112 {
16113 satSetSensePayload( pSense,
16114 SCSI_SNSKEY_ILLEGAL_REQUEST,
16115 0,
16116 SCSI_SNSCODE_INVALID_FIELD_IN_CDB,
16117 satIOContext);
16118 ostiInitiatorIOCompleted( tiRoot,
16119 tiIORequest,
16120 tiIOSuccess,
16121 SCSI_STAT_CHECK_CONDITION,
16122 satIOContext->pTiSenseData,
16123 satIOContext->interruptContext );
16124 TI_DBG1(("satReadBuffer: buffer offset is not 0; it is %d\n", bufferOffset));
16125 return tiSuccess;
16126 }
16127 /* all other cases unsupported */
16128 TI_DBG1(("satReadBuffer: unsupported case 1\n"));
16129 satSetSensePayload( pSense,
16130 SCSI_SNSKEY_ILLEGAL_REQUEST,
16131 0,
16132 SCSI_SNSCODE_INVALID_COMMAND,
16133 satIOContext);
16134
16135 ostiInitiatorIOCompleted( tiRoot,
16136 tiIORequest,
16137 tiIOSuccess,
16138 SCSI_STAT_CHECK_CONDITION,
16139 satIOContext->pTiSenseData,
16140 satIOContext->interruptContext );
16141 return tiSuccess;
16142 }
16143 else if (mode == READ_BUFFER_DESCRIPTOR_MODE) /* 3 */
16144 {
16145 if (tl < READ_BUFFER_DESCRIPTOR_MODE_DATA_LEN) /* 4 */
16146 {
16147 satSetSensePayload( pSense,
16148 SCSI_SNSKEY_ILLEGAL_REQUEST,
16149 0,
16150 SCSI_SNSCODE_INVALID_FIELD_IN_CDB,
16151 satIOContext);
16152 ostiInitiatorIOCompleted( tiRoot,
16153 tiIORequest,
16154 tiIOSuccess,
16155 SCSI_STAT_CHECK_CONDITION,
16156 satIOContext->pTiSenseData,
16157 satIOContext->interruptContext );
16158 TI_DBG1(("satReadBuffer: tl < 4; tl is %d\n", tl));
16159 return tiSuccess;
16160 }
16161 if (bufferID == 0)
16162 {
16163 /* SPC-4, 6.15.5, p189; SAT-2 Rev00, 8.7.2.3, p41*/
16164 pBuff[0] = 0xFF;
16165 pBuff[1] = 0x00;
16166 pBuff[2] = 0x02;
16167 pBuff[3] = 0x00;
16168 if (READ_BUFFER_DESCRIPTOR_MODE_DATA_LEN < tl)
16169 {
16170 /* underrrun */
16171 TI_DBG1(("satReadBuffer: underrun tl %d data %d\n", tl, READ_BUFFER_DESCRIPTOR_MODE_DATA_LEN));
16172 ostiInitiatorIOCompleted( tiRoot,
16173 tiIORequest,
16174 tiIOUnderRun,
16175 tl - READ_BUFFER_DESCRIPTOR_MODE_DATA_LEN,
16176 agNULL,
16177 satIOContext->interruptContext );
16178 return tiSuccess;
16179 }
16180 else
16181 {
16182 ostiInitiatorIOCompleted( tiRoot,
16183 tiIORequest,
16184 tiIOSuccess,
16185 SCSI_STAT_GOOD,
16186 agNULL,
16187 satIOContext->interruptContext);
16188 return tiSuccess;
16189 }
16190 }
16191 else
16192 {
16193 /* We don't support other than bufferID 0 */
16194 satSetSensePayload( pSense,
16195 SCSI_SNSKEY_ILLEGAL_REQUEST,
16196 0,
16197 SCSI_SNSCODE_INVALID_COMMAND,
16198 satIOContext);
16199
16200 ostiInitiatorIOCompleted( tiRoot,
16201 tiIORequest,
16202 tiIOSuccess,
16203 SCSI_STAT_CHECK_CONDITION,
16204 satIOContext->pTiSenseData,
16205 satIOContext->interruptContext );
16206 return tiSuccess;
16207 }
16208 }
16209 else
16210 {
16211 /* We don't support any other mode */
16212 TI_DBG1(("satReadBuffer: unsupported mode %d\n", mode));
16213 satSetSensePayload( pSense,
16214 SCSI_SNSKEY_ILLEGAL_REQUEST,
16215 0,
16216 SCSI_SNSCODE_INVALID_COMMAND,
16217 satIOContext);
16218
16219 ostiInitiatorIOCompleted( tiRoot,
16220 tiIORequest,
16221 tiIOSuccess,
16222 SCSI_STAT_CHECK_CONDITION,
16223 satIOContext->pTiSenseData,
16224 satIOContext->interruptContext );
16225 return tiSuccess;
16226 }
16227 }
16228
16229 /*****************************************************************************/
16230 /*! \brief SAT implementation for SCSI satWriteBuffer.
16231 *
16232 * SAT implementation for SCSI Write Buffer.
16233 *
16234 * \param tiRoot: Pointer to TISA initiator driver/port instance.
16235 * \param tiIORequest: Pointer to TISA I/O request context for this I/O.
16236 * \param tiDeviceHandle: Pointer to TISA device handle for this I/O.
16237 * \param tiScsiRequest: Pointer to TISA SCSI I/O request and SGL list.
16238 * \param satIOContext_t: Pointer to the SAT IO Context
16239 *
16240 * \return If command is started successfully
16241 * - \e tiSuccess: I/O request successfully initiated.
16242 * - \e tiBusy: No resources available, try again later.
16243 * - \e tiIONoDevice: Invalid device handle.
16244 * - \e tiError: Other errors.
16245 */
16246 /*****************************************************************************/
16247 /* SAT-2, Revision 00*/
16248 GLOBAL bit32 satWriteBuffer(
16249 tiRoot_t *tiRoot,
16250 tiIORequest_t *tiIORequest,
16251 tiDeviceHandle_t *tiDeviceHandle,
16252 tiScsiInitiatorRequest_t *tiScsiRequest,
16253 satIOContext_t *satIOContext)
16254 {
16255 #ifdef NOT_YET
16256 bit32 agRequestType = AGSA_SATA_PROTOCOL_PIO_READ;
16257 #endif
16258 scsiRspSense_t *pSense;
16259 tiIniScsiCmnd_t *scsiCmnd;
16260 bit32 bufferOffset;
16261 bit32 parmLen;
16262 bit8 mode;
16263 bit8 bufferID;
16264 bit8 *pBuff;
16265
16266 pSense = satIOContext->pSense;
16267 scsiCmnd = &tiScsiRequest->scsiCmnd;
16268 pBuff = (bit8 *) tiScsiRequest->sglVirtualAddr;
16269
16270 TI_DBG2(("satWriteBuffer: start\n"));
16271
16272 /* checking CONTROL */
16273 /* NACA == 1 or LINK == 1*/
16274 if ( (scsiCmnd->cdb[9] & SCSI_NACA_MASK) || (scsiCmnd->cdb[9] & SCSI_LINK_MASK) )
16275 {
16276 satSetSensePayload( pSense,
16277 SCSI_SNSKEY_ILLEGAL_REQUEST,
16278 0,
16279 SCSI_SNSCODE_INVALID_FIELD_IN_CDB,
16280 satIOContext);
16281
16282 ostiInitiatorIOCompleted( tiRoot,
16283 tiIORequest,
16284 tiIOSuccess,
16285 SCSI_STAT_CHECK_CONDITION,
16286 satIOContext->pTiSenseData,
16287 satIOContext->interruptContext );
16288
16289 TI_DBG1(("satWriteBuffer: return control\n"));
16290 return tiSuccess;
16291 }
16292
16293 bufferOffset = (scsiCmnd->cdb[3] << (8*2)) + (scsiCmnd->cdb[4] << 8) + scsiCmnd->cdb[5];
16294 parmLen = (scsiCmnd->cdb[6] << (8*2)) + (scsiCmnd->cdb[7] << 8) + scsiCmnd->cdb[8];
16295
16296 mode = (bit8)(scsiCmnd->cdb[1] & SCSI_READ_BUFFER_MODE_MASK);
16297 bufferID = scsiCmnd->cdb[2];
16298
16299 /* for debugging only */
16300 tdhexdump("satWriteBuffer pBuff", (bit8 *)pBuff, 24);
16301
16302 if (mode == WRITE_BUFFER_DATA_MODE) /* 2 */
16303 {
16304 if (bufferID == 0 && bufferOffset == 0 && parmLen == 512)
16305 {
16306 TI_DBG1(("satWriteBuffer: sending ATA WRITE BUFFER\n"));
16307 /* send ATA WRITE BUFFER */
16308 #ifdef NOT_YET
16309 fis->h.fisType = 0x27; /* Reg host to device */
16310 fis->h.c_pmPort = 0x80; /* C Bit is set */
16311 fis->h.command = SAT_WRITE_BUFFER; /* 0xE8 */
16312 fis->h.features = 0; /* FIS reserve */
16313 fis->d.lbaLow = 0; /* FIS LBA (7 :0 ) */
16314 fis->d.lbaMid = 0; /* FIS LBA (15:8 ) */
16315 fis->d.lbaHigh = 0; /* FIS LBA (23:16) */
16316 fis->d.device = 0x40; /* FIS LBA (27:24) and FIS LBA mode */
16317 fis->d.lbaLowExp = 0;
16318 fis->d.lbaMidExp = 0;
16319 fis->d.lbaHighExp = 0;
16320 fis->d.featuresExp = 0;
16321 fis->d.sectorCount = 0; /* FIS sector count (7:0) */
16322 fis->d.sectorCountExp = 0;
16323 fis->d.reserved4 = 0;
16324 fis->d.control = 0; /* FIS HOB bit clear */
16325 fis->d.reserved5 = 0;
16326
16327
16328 agRequestType = AGSA_SATA_PROTOCOL_PIO_WRITE;
16329
16330 satIOContext->satCompleteCB = &satWriteBufferCB;
16331
16332 satIOContext->reqType = agRequestType; /* Save it */
16333
16334 status = sataLLIOStart( tiRoot,
16335 tiIORequest,
16336 tiDeviceHandle,
16337 tiScsiRequest,
16338 satIOContext);
16339 return status;
16340 #endif
16341 /* temp */
16342 ostiInitiatorIOCompleted( tiRoot,
16343 tiIORequest,
16344 tiIOSuccess,
16345 SCSI_STAT_GOOD,
16346 agNULL,
16347 satIOContext->interruptContext);
16348 return tiSuccess;
16349 }
16350 if ( (bufferID == 0 && bufferOffset != 0) ||
16351 (bufferID == 0 && parmLen != 512)
16352 )
16353 {
16354 satSetSensePayload( pSense,
16355 SCSI_SNSKEY_ILLEGAL_REQUEST,
16356 0,
16357 SCSI_SNSCODE_INVALID_FIELD_IN_CDB,
16358 satIOContext);
16359
16360 ostiInitiatorIOCompleted( tiRoot,
16361 tiIORequest,
16362 tiIOSuccess,
16363 SCSI_STAT_CHECK_CONDITION,
16364 satIOContext->pTiSenseData,
16365 satIOContext->interruptContext );
16366
16367 TI_DBG1(("satWriteBuffer: wrong buffer offset %d or parameter length parmLen %d\n", bufferOffset, parmLen));
16368 return tiSuccess;
16369 }
16370
16371 /* all other cases unsupported */
16372 TI_DBG1(("satWriteBuffer: unsupported case 1\n"));
16373 satSetSensePayload( pSense,
16374 SCSI_SNSKEY_ILLEGAL_REQUEST,
16375 0,
16376 SCSI_SNSCODE_INVALID_COMMAND,
16377 satIOContext);
16378
16379 ostiInitiatorIOCompleted( tiRoot,
16380 tiIORequest,
16381 tiIOSuccess,
16382 SCSI_STAT_CHECK_CONDITION,
16383 satIOContext->pTiSenseData,
16384 satIOContext->interruptContext );
16385
16386 return tiSuccess;
16387
16388 }
16389 else if (mode == WRITE_BUFFER_DL_MICROCODE_SAVE_MODE) /* 5 */
16390 {
16391 TI_DBG1(("satWriteBuffer: not yet supported mode %d\n", mode));
16392 satSetSensePayload( pSense,
16393 SCSI_SNSKEY_ILLEGAL_REQUEST,
16394 0,
16395 SCSI_SNSCODE_INVALID_COMMAND,
16396 satIOContext);
16397
16398 ostiInitiatorIOCompleted( tiRoot,
16399 tiIORequest,
16400 tiIOSuccess,
16401 SCSI_STAT_CHECK_CONDITION,
16402 satIOContext->pTiSenseData,
16403 satIOContext->interruptContext );
16404
16405 return tiSuccess;
16406 }
16407 else
16408 {
16409 /* We don't support any other mode */
16410 TI_DBG1(("satWriteBuffer: unsupported mode %d\n", mode));
16411 satSetSensePayload( pSense,
16412 SCSI_SNSKEY_ILLEGAL_REQUEST,
16413 0,
16414 SCSI_SNSCODE_INVALID_COMMAND,
16415 satIOContext);
16416
16417 ostiInitiatorIOCompleted( tiRoot,
16418 tiIORequest,
16419 tiIOSuccess,
16420 SCSI_STAT_CHECK_CONDITION,
16421 satIOContext->pTiSenseData,
16422 satIOContext->interruptContext );
16423
16424 return tiSuccess;
16425 }
16426
16427 }
16428
16429 /*****************************************************************************/
16430 /*! \brief SAT implementation for SCSI satReassignBlocks.
16431 *
16432 * SAT implementation for SCSI Reassign Blocks.
16433 *
16434 * \param tiRoot: Pointer to TISA initiator driver/port instance.
16435 * \param tiIORequest: Pointer to TISA I/O request context for this I/O.
16436 * \param tiDeviceHandle: Pointer to TISA device handle for this I/O.
16437 * \param tiScsiRequest: Pointer to TISA SCSI I/O request and SGL list.
16438 * \param satIOContext_t: Pointer to the SAT IO Context
16439 *
16440 * \return If command is started successfully
16441 * - \e tiSuccess: I/O request successfully initiated.
16442 * - \e tiBusy: No resources available, try again later.
16443 * - \e tiIONoDevice: Invalid device handle.
16444 * - \e tiError: Other errors.
16445 */
16446 /*****************************************************************************/
16447 GLOBAL bit32 satReassignBlocks(
16448 tiRoot_t *tiRoot,
16449 tiIORequest_t *tiIORequest,
16450 tiDeviceHandle_t *tiDeviceHandle,
16451 tiScsiInitiatorRequest_t *tiScsiRequest,
16452 satIOContext_t *satIOContext)
16453 {
16454 /*
16455 assumes all LBA fits in ATA command; no boundary condition is checked here yet
16456 */
16457 bit32 status;
16458 bit32 agRequestType;
16459 satDeviceData_t *pSatDevData;
16460 scsiRspSense_t *pSense;
16461 tiIniScsiCmnd_t *scsiCmnd;
16462 agsaFisRegHostToDevice_t *fis;
16463 bit8 *pParmList; /* Log Page data buffer */
16464 bit8 LongLBA;
16465 bit8 LongList;
16466 bit32 defectListLen;
16467 bit8 LBA[8];
16468 bit32 startingIndex;
16469
16470 pSense = satIOContext->pSense;
16471 pSatDevData = satIOContext->pSatDevData;
16472 scsiCmnd = &tiScsiRequest->scsiCmnd;
16473 fis = satIOContext->pFis;
16474 pParmList = (bit8 *) tiScsiRequest->sglVirtualAddr;
16475
16476 TI_DBG5(("satReassignBlocks: start\n"));
16477
16478 /* checking CONTROL */
16479 /* NACA == 1 or LINK == 1*/
16480 if ( (scsiCmnd->cdb[5] & SCSI_NACA_MASK) || (scsiCmnd->cdb[5] & SCSI_LINK_MASK) )
16481 {
16482 satSetSensePayload( pSense,
16483 SCSI_SNSKEY_ILLEGAL_REQUEST,
16484 0,
16485 SCSI_SNSCODE_INVALID_FIELD_IN_CDB,
16486 satIOContext);
16487
16488 ostiInitiatorIOCompleted( tiRoot,
16489 tiIORequest,
16490 tiIOSuccess,
16491 SCSI_STAT_CHECK_CONDITION,
16492 satIOContext->pTiSenseData,
16493 satIOContext->interruptContext );
16494
16495 TI_DBG1(("satReassignBlocks: return control\n"));
16496 return tiSuccess;
16497 }
16498
16499 osti_memset(satIOContext->LBA, 0, 8);
16500 satIOContext->ParmIndex = 0;
16501 satIOContext->ParmLen = 0;
16502
16503 LongList = (bit8)(scsiCmnd->cdb[1] & SCSI_REASSIGN_BLOCKS_LONGLIST_MASK);
16504 LongLBA = (bit8)(scsiCmnd->cdb[1] & SCSI_REASSIGN_BLOCKS_LONGLBA_MASK);
16505 osti_memset(LBA, 0, sizeof(LBA));
16506
16507 if (LongList == 0)
16508 {
16509 defectListLen = (pParmList[2] << 8) + pParmList[3];
16510 }
16511 else
16512 {
16513 defectListLen = (pParmList[0] << (8*3)) + (pParmList[1] << (8*2))
16514 + (pParmList[2] << 8) + pParmList[3];
16515 }
16516 /* SBC 5.16.2, p61*/
16517 satIOContext->ParmLen = defectListLen + 4 /* header size */;
16518
16519 startingIndex = 4;
16520
16521 if (LongLBA == 0)
16522 {
16523 LBA[4] = pParmList[startingIndex]; /* MSB */
16524 LBA[5] = pParmList[startingIndex+1];
16525 LBA[6] = pParmList[startingIndex+2];
16526 LBA[7] = pParmList[startingIndex+3]; /* LSB */
16527 startingIndex = startingIndex + 4;
16528 }
16529 else
16530 {
16531 LBA[0] = pParmList[startingIndex]; /* MSB */
16532 LBA[1] = pParmList[startingIndex+1];
16533 LBA[2] = pParmList[startingIndex+2];
16534 LBA[3] = pParmList[startingIndex+3];
16535 LBA[4] = pParmList[startingIndex+4];
16536 LBA[5] = pParmList[startingIndex+5];
16537 LBA[6] = pParmList[startingIndex+6];
16538 LBA[7] = pParmList[startingIndex+7]; /* LSB */
16539 startingIndex = startingIndex + 8;
16540 }
16541
16542 tdhexdump("satReassignBlocks Parameter list", (bit8 *)pParmList, 4 + defectListLen);
16543
16544 if (pSatDevData->sat48BitSupport == agTRUE)
16545 {
16546 /* sends READ VERIFY SECTOR(S) EXT*/
16547 fis->h.fisType = 0x27; /* Reg host to device */
16548 fis->h.c_pmPort = 0x80; /* C Bit is set */
16549 fis->h.command = SAT_READ_VERIFY_SECTORS_EXT;/* 0x42 */
16550 fis->h.features = 0; /* FIS reserve */
16551 fis->d.lbaLow = LBA[7]; /* FIS LBA (7 :0 ) */
16552 fis->d.lbaMid = LBA[6]; /* FIS LBA (15:8 ) */
16553 fis->d.lbaHigh = LBA[5]; /* FIS LBA (23:16) */
16554 fis->d.lbaLowExp = LBA[4]; /* FIS LBA (31:24) */
16555 fis->d.lbaMidExp = LBA[3]; /* FIS LBA (39:32) */
16556 fis->d.lbaHighExp = LBA[2]; /* FIS LBA (47:40) */
16557 fis->d.featuresExp = 0; /* FIS reserve */
16558 fis->d.sectorCount = 1; /* FIS sector count (7:0) */
16559 fis->d.sectorCountExp = 0; /* FIS sector count (15:8) */
16560 fis->d.reserved4 = 0;
16561 fis->d.device = 0x40; /* 01000000 */
16562 fis->d.control = 0; /* FIS HOB bit clear */
16563 fis->d.reserved5 = 0;
16564 }
16565 else
16566 {
16567 /* READ VERIFY SECTOR(S)*/
16568 fis->h.fisType = 0x27; /* Reg host to device */
16569 fis->h.c_pmPort = 0x80; /* C Bit is set */
16570 fis->h.command = SAT_READ_VERIFY_SECTORS;/* 0x40 */
16571 fis->h.features = 0; /* FIS features NA */
16572 fis->d.lbaLow = LBA[7]; /* FIS LBA (7 :0 ) */
16573 fis->d.lbaMid = LBA[6]; /* FIS LBA (15:8 ) */
16574 fis->d.lbaHigh = LBA[5]; /* FIS LBA (23:16) */
16575 fis->d.lbaLowExp = 0;
16576 fis->d.lbaMidExp = 0;
16577 fis->d.lbaHighExp = 0;
16578 fis->d.featuresExp = 0;
16579 fis->d.sectorCount = 1; /* FIS sector count (7:0) */
16580 fis->d.sectorCountExp = 0;
16581 fis->d.reserved4 = 0;
16582 fis->d.device = (bit8)((0x4 << 4) | (LBA[4] & 0xF));
16583 /* DEV and LBA 27:24 */
16584 fis->d.control = 0; /* FIS HOB bit clear */
16585 fis->d.reserved5 = 0;
16586 }
16587
16588 osti_memcpy(satIOContext->LBA, LBA, 8);
16589 satIOContext->ParmIndex = startingIndex;
16590
16591 agRequestType = AGSA_SATA_PROTOCOL_NON_DATA;
16592
16593 /* Initialize CB for SATA completion.
16594 */
16595 satIOContext->satCompleteCB = &satReassignBlocksCB;
16596
16597 /*
16598 * Prepare SGL and send FIS to LL layer.
16599 */
16600 satIOContext->reqType = agRequestType; /* Save it */
16601
16602 status = sataLLIOStart( tiRoot,
16603 tiIORequest,
16604 tiDeviceHandle,
16605 tiScsiRequest,
16606 satIOContext);
16607
16608 return status;
16609 }
16610
16611 /*****************************************************************************/
16612 /*! \brief SAT implementation for SCSI satReassignBlocks_1.
16613 *
16614 * SAT implementation for SCSI Reassign Blocks. This is helper function for
16615 * satReassignBlocks and satReassignBlocksCB. This sends ATA verify command.
16616 *
16617 * \param tiRoot: Pointer to TISA initiator driver/port instance.
16618 * \param tiIORequest: Pointer to TISA I/O request context for this I/O.
16619 * \param tiDeviceHandle: Pointer to TISA device handle for this I/O.
16620 * \param tiScsiRequest: Pointer to TISA SCSI I/O request and SGL list.
16621 * \param satIOContext_t: Pointer to the SAT IO Context
16622 *
16623 * \return If command is started successfully
16624 * - \e tiSuccess: I/O request successfully initiated.
16625 * - \e tiBusy: No resources available, try again later.
16626 * - \e tiIONoDevice: Invalid device handle.
16627 * - \e tiError: Other errors.
16628 */
16629 /*****************************************************************************/
16630 /* next LBA; sends READ VERIFY SECTOR; update LBA and ParmIdx */
16631 GLOBAL bit32 satReassignBlocks_1(
16632 tiRoot_t *tiRoot,
16633 tiIORequest_t *tiIORequest,
16634 tiDeviceHandle_t *tiDeviceHandle,
16635 tiScsiInitiatorRequest_t *tiScsiRequest,
16636 satIOContext_t *satIOContext,
16637 satIOContext_t *satOrgIOContext
16638 )
16639 {
16640 /*
16641 assumes all LBA fits in ATA command; no boundary condition is checked here yet
16642 tiScsiRequest is OS generated; needs for accessing parameter list
16643 */
16644 bit32 agRequestType;
16645 satDeviceData_t *pSatDevData;
16646 tiIniScsiCmnd_t *scsiCmnd;
16647 agsaFisRegHostToDevice_t *fis;
16648 bit8 *pParmList; /* Log Page data buffer */
16649 bit8 LongLBA;
16650 bit8 LBA[8];
16651 bit32 startingIndex;
16652
16653 pSatDevData = satIOContext->pSatDevData;
16654 scsiCmnd = &tiScsiRequest->scsiCmnd;
16655 fis = satIOContext->pFis;
16656 pParmList = (bit8 *) tiScsiRequest->sglVirtualAddr;
16657
16658 TI_DBG5(("satReassignBlocks_1: start\n"));
16659
16660 LongLBA = (bit8)(scsiCmnd->cdb[1] & SCSI_REASSIGN_BLOCKS_LONGLBA_MASK);
16661 osti_memset(LBA, 0, sizeof(LBA));
16662
16663 startingIndex = satOrgIOContext->ParmIndex;
16664
16665 if (LongLBA == 0)
16666 {
16667 LBA[4] = pParmList[startingIndex];
16668 LBA[5] = pParmList[startingIndex+1];
16669 LBA[6] = pParmList[startingIndex+2];
16670 LBA[7] = pParmList[startingIndex+3];
16671 startingIndex = startingIndex + 4;
16672 }
16673 else
16674 {
16675 LBA[0] = pParmList[startingIndex];
16676 LBA[1] = pParmList[startingIndex+1];
16677 LBA[2] = pParmList[startingIndex+2];
16678 LBA[3] = pParmList[startingIndex+3];
16679 LBA[4] = pParmList[startingIndex+4];
16680 LBA[5] = pParmList[startingIndex+5];
16681 LBA[6] = pParmList[startingIndex+6];
16682 LBA[7] = pParmList[startingIndex+7];
16683 startingIndex = startingIndex + 8;
16684 }
16685
16686 if (pSatDevData->sat48BitSupport == agTRUE)
16687 {
16688 /* sends READ VERIFY SECTOR(S) EXT*/
16689 fis->h.fisType = 0x27; /* Reg host to device */
16690 fis->h.c_pmPort = 0x80; /* C Bit is set */
16691 fis->h.command = SAT_READ_VERIFY_SECTORS_EXT;/* 0x42 */
16692 fis->h.features = 0; /* FIS reserve */
16693 fis->d.lbaLow = LBA[7]; /* FIS LBA (7 :0 ) */
16694 fis->d.lbaMid = LBA[6]; /* FIS LBA (15:8 ) */
16695 fis->d.lbaHigh = LBA[5]; /* FIS LBA (23:16) */
16696 fis->d.lbaLowExp = LBA[4]; /* FIS LBA (31:24) */
16697 fis->d.lbaMidExp = LBA[3]; /* FIS LBA (39:32) */
16698 fis->d.lbaHighExp = LBA[2]; /* FIS LBA (47:40) */
16699 fis->d.featuresExp = 0; /* FIS reserve */
16700 fis->d.sectorCount = 1; /* FIS sector count (7:0) */
16701 fis->d.sectorCountExp = 0; /* FIS sector count (15:8) */
16702 fis->d.reserved4 = 0;
16703 fis->d.device = 0x40; /* 01000000 */
16704 fis->d.control = 0; /* FIS HOB bit clear */
16705 fis->d.reserved5 = 0;
16706 }
16707 else
16708 {
16709 /* READ VERIFY SECTOR(S)*/
16710 fis->h.fisType = 0x27; /* Reg host to device */
16711 fis->h.c_pmPort = 0x80; /* C Bit is set */
16712 fis->h.command = SAT_READ_VERIFY_SECTORS;/* 0x40 */
16713 fis->h.features = 0; /* FIS features NA */
16714 fis->d.lbaLow = LBA[7]; /* FIS LBA (7 :0 ) */
16715 fis->d.lbaMid = LBA[6]; /* FIS LBA (15:8 ) */
16716 fis->d.lbaHigh = LBA[5]; /* FIS LBA (23:16) */
16717 fis->d.lbaLowExp = 0;
16718 fis->d.lbaMidExp = 0;
16719 fis->d.lbaHighExp = 0;
16720 fis->d.featuresExp = 0;
16721 fis->d.sectorCount = 1; /* FIS sector count (7:0) */
16722 fis->d.sectorCountExp = 0;
16723 fis->d.reserved4 = 0;
16724 fis->d.device = (bit8)((0x4 << 4) | (LBA[4] & 0xF));
16725 /* DEV and LBA 27:24 */
16726 fis->d.control = 0; /* FIS HOB bit clear */
16727 fis->d.reserved5 = 0;
16728 }
16729 osti_memcpy(satOrgIOContext->LBA, LBA, 8);
16730 satOrgIOContext->ParmIndex = startingIndex;
16731 agRequestType = AGSA_SATA_PROTOCOL_NON_DATA;
16732 /* Initialize CB for SATA completion.
16733 */
16734 satIOContext->satCompleteCB = &satReassignBlocksCB;
16735 /*
16736 * Prepare SGL and send FIS to LL layer.
16737 */
16738 satIOContext->reqType = agRequestType; /* Save it */
16739
16740 sataLLIOStart( tiRoot,
16741 tiIORequest,
16742 tiDeviceHandle,
16743 tiScsiRequest,
16744 satIOContext );
16745 return tiSuccess;
16746 }
16747
16748 /*****************************************************************************/
16749 /*! \brief SAT implementation for SCSI satReassignBlocks_2.
16750 *
16751 * SAT implementation for SCSI Reassign Blocks. This is helper function for
16752 * satReassignBlocks and satReassignBlocksCB. This sends ATA write command.
16753 *
16754 * \param tiRoot: Pointer to TISA initiator driver/port instance.
16755 * \param tiIORequest: Pointer to TISA I/O request context for this I/O.
16756 * \param tiDeviceHandle: Pointer to TISA device handle for this I/O.
16757 * \param tiScsiRequest: Pointer to TISA SCSI I/O request and SGL list.
16758 * \param satIOContext_t: Pointer to the SAT IO Context
16759 * \param LBA: Pointer to the LBA to be processed
16760 *
16761 * \return If command is started successfully
16762 * - \e tiSuccess: I/O request successfully initiated.
16763 * - \e tiBusy: No resources available, try again later.
16764 * - \e tiIONoDevice: Invalid device handle.
16765 * - \e tiError: Other errors.
16766 */
16767 /*****************************************************************************/
16768 /* current LBA; sends WRITE */
16769 GLOBAL bit32 satReassignBlocks_2(
16770 tiRoot_t *tiRoot,
16771 tiIORequest_t *tiIORequest,
16772 tiDeviceHandle_t *tiDeviceHandle,
16773 tiScsiInitiatorRequest_t *tiScsiRequest,
16774 satIOContext_t *satIOContext,
16775 bit8 *LBA
16776 )
16777 {
16778 /*
16779 assumes all LBA fits in ATA command; no boundary condition is checked here yet
16780 tiScsiRequest is TD generated for writing
16781 */
16782 bit32 status;
16783 bit32 agRequestType;
16784 satDeviceData_t *pSatDevData;
16785 scsiRspSense_t *pSense;
16786 agsaFisRegHostToDevice_t *fis;
16787
16788 pSense = satIOContext->pSense;
16789 pSatDevData = satIOContext->pSatDevData;
16790 fis = satIOContext->pFis;
16791
16792 if (pSatDevData->satDMASupport == agTRUE && pSatDevData->satDMAEnabled == agTRUE)
16793 {
16794 /* case 2 */
16795 /* WRITE DMA*/
16796 /* can't fit the transfer length */
16797 TI_DBG5(("satReassignBlocks_2: case 2\n"));
16798 fis->h.fisType = 0x27; /* Reg host to device */
16799 fis->h.c_pmPort = 0x80; /* C bit is set */
16800 fis->h.command = SAT_WRITE_DMA; /* 0xCA */
16801 fis->h.features = 0; /* FIS reserve */
16802 fis->d.lbaLow = LBA[7]; /* FIS LBA (7 :0 ) */
16803 fis->d.lbaMid = LBA[6]; /* FIS LBA (15:8 ) */
16804 fis->d.lbaHigh = LBA[5]; /* FIS LBA (23:16) */
16805
16806 /* FIS LBA mode set LBA (27:24) */
16807 fis->d.device = (bit8)((0x4 << 4) | (LBA[4] & 0xF));
16808
16809 fis->d.lbaLowExp = 0;
16810 fis->d.lbaMidExp = 0;
16811 fis->d.lbaHighExp = 0;
16812 fis->d.featuresExp = 0;
16813 fis->d.sectorCount = 1; /* FIS sector count (7:0) */
16814 fis->d.sectorCountExp = 0;
16815 fis->d.reserved4 = 0;
16816 fis->d.control = 0; /* FIS HOB bit clear */
16817 fis->d.reserved5 = 0;
16818
16819 agRequestType = AGSA_SATA_PROTOCOL_DMA_WRITE;
16820 satIOContext->ATACmd = SAT_WRITE_DMA;
16821 }
16822 else
16823 {
16824 /* case 1 */
16825 /* WRITE MULTIPLE or WRITE SECTOR(S) */
16826 /* WRITE SECTORS for easier implemetation */
16827 /* can't fit the transfer length */
16828 TI_DBG5(("satReassignBlocks_2: case 1\n"));
16829 fis->h.fisType = 0x27; /* Reg host to device */
16830 fis->h.c_pmPort = 0x80; /* C bit is set */
16831 fis->h.command = SAT_WRITE_SECTORS; /* 0x30 */
16832 fis->h.features = 0; /* FIS reserve */
16833 fis->d.lbaLow = LBA[7]; /* FIS LBA (7 :0 ) */
16834 fis->d.lbaMid = LBA[6]; /* FIS LBA (15:8 ) */
16835 fis->d.lbaHigh = LBA[7]; /* FIS LBA (23:16) */
16836
16837 /* FIS LBA mode set LBA (27:24) */
16838 fis->d.device = (bit8)((0x4 << 4) | (LBA[4] & 0xF));
16839
16840 fis->d.lbaLowExp = 0;
16841 fis->d.lbaMidExp = 0;
16842 fis->d.lbaHighExp = 0;
16843 fis->d.featuresExp = 0;
16844 fis->d.sectorCount = 1; /* FIS sector count (7:0) */
16845 fis->d.sectorCountExp = 0;
16846 fis->d.reserved4 = 0;
16847 fis->d.control = 0; /* FIS HOB bit clear */
16848 fis->d.reserved5 = 0;
16849
16850 agRequestType = AGSA_SATA_PROTOCOL_PIO_WRITE;
16851 satIOContext->ATACmd = SAT_WRITE_SECTORS;
16852 }
16853
16854 /* case 3 and 4 */
16855 if (pSatDevData->sat48BitSupport == agTRUE)
16856 {
16857 if (pSatDevData->satDMASupport == agTRUE && pSatDevData->satDMAEnabled == agTRUE)
16858 {
16859 /* case 3 */
16860 /* WRITE DMA EXT or WRITE DMA FUA EXT */
16861 TI_DBG5(("satReassignBlocks_2: case 3\n"));
16862 fis->h.fisType = 0x27; /* Reg host to device */
16863 fis->h.c_pmPort = 0x80; /* C Bit is set */
16864
16865 /* SAT_WRITE_DMA_FUA_EXT is optional and we don't support it */
16866 fis->h.command = SAT_WRITE_DMA_EXT; /* 0x35 */
16867 satIOContext->ATACmd = SAT_WRITE_DMA_EXT;
16868
16869 fis->h.features = 0; /* FIS reserve */
16870 fis->d.lbaLow = LBA[7]; /* FIS LBA (7 :0 ) */
16871 fis->d.lbaMid = LBA[6]; /* FIS LBA (15:8 ) */
16872 fis->d.lbaHigh = LBA[5]; /* FIS LBA (23:16) */
16873 fis->d.device = 0x40; /* FIS LBA mode set */
16874 fis->d.lbaLowExp = LBA[4]; /* FIS LBA (31:24) */
16875 fis->d.lbaMidExp = LBA[3]; /* FIS LBA (39:32) */
16876 fis->d.lbaHighExp = LBA[2]; /* FIS LBA (47:40) */
16877 fis->d.featuresExp = 0; /* FIS reserve */
16878 fis->d.sectorCount = 1; /* FIS sector count (7:0) */
16879 fis->d.sectorCountExp = 0; /* FIS sector count (15:8) */
16880 fis->d.reserved4 = 0;
16881 fis->d.control = 0; /* FIS HOB bit clear */
16882 fis->d.reserved5 = 0;
16883
16884 agRequestType = AGSA_SATA_PROTOCOL_DMA_WRITE;
16885 }
16886 else
16887 {
16888 /* case 4 */
16889 /* WRITE MULTIPLE EXT or WRITE MULTIPLE FUA EXT or WRITE SECTOR(S) EXT */
16890 /* WRITE SECTORS EXT for easier implemetation */
16891 TI_DBG5(("satReassignBlocks_2: case 4\n"));
16892 fis->h.fisType = 0x27; /* Reg host to device */
16893 fis->h.c_pmPort = 0x80; /* C Bit is set */
16894 fis->h.command = SAT_WRITE_SECTORS_EXT; /* 0x34 */
16895
16896 fis->h.features = 0; /* FIS reserve */
16897 fis->d.lbaLow = LBA[7]; /* FIS LBA (7 :0 ) */
16898 fis->d.lbaMid = LBA[6]; /* FIS LBA (15:8 ) */
16899 fis->d.lbaHigh = LBA[5]; /* FIS LBA (23:16) */
16900 fis->d.device = 0x40; /* FIS LBA mode set */
16901 fis->d.lbaLowExp = LBA[4]; /* FIS LBA (31:24) */
16902 fis->d.lbaMidExp = LBA[3]; /* FIS LBA (39:32) */
16903 fis->d.lbaHighExp = LBA[2]; /* FIS LBA (47:40) */
16904 fis->d.featuresExp = 0; /* FIS reserve */
16905 fis->d.sectorCount = 1; /* FIS sector count (7:0) */
16906 fis->d.sectorCountExp = 0; /* FIS sector count (15:8) */
16907 fis->d.reserved4 = 0;
16908 fis->d.control = 0; /* FIS HOB bit clear */
16909 fis->d.reserved5 = 0;
16910
16911 agRequestType = AGSA_SATA_PROTOCOL_PIO_WRITE;
16912 satIOContext->ATACmd = SAT_WRITE_SECTORS_EXT;
16913 }
16914 }
16915 /* case 5 */
16916 if (pSatDevData->satNCQ == agTRUE)
16917 {
16918 /* WRITE FPDMA QUEUED */
16919 if (pSatDevData->sat48BitSupport != agTRUE)
16920 {
16921 TI_DBG5(("satReassignBlocks_2: case 5 !!! error NCQ but 28 bit address support \n"));
16922 satSetSensePayload( pSense,
16923 SCSI_SNSKEY_HARDWARE_ERROR,
16924 0,
16925 SCSI_SNSCODE_WRITE_ERROR_AUTO_REALLOCATION_FAILED,
16926 satIOContext);
16927
16928 ostiInitiatorIOCompleted( tiRoot,
16929 tiIORequest,
16930 tiIOSuccess,
16931 SCSI_STAT_CHECK_CONDITION,
16932 satIOContext->pTiSenseData,
16933 satIOContext->interruptContext );
16934 return tiSuccess;
16935 }
16936 TI_DBG6(("satWrite10: case 5\n"));
16937
16938 /* Support 48-bit FPDMA addressing, use WRITE FPDMA QUEUE command */
16939
16940 fis->h.fisType = 0x27; /* Reg host to device */
16941 fis->h.c_pmPort = 0x80; /* C Bit is set */
16942 fis->h.command = SAT_WRITE_FPDMA_QUEUED; /* 0x61 */
16943 fis->h.features = 1; /* FIS sector count (7:0) */
16944 fis->d.lbaLow = LBA[7]; /* FIS LBA (7 :0 ) */
16945 fis->d.lbaMid = LBA[6]; /* FIS LBA (15:8 ) */
16946 fis->d.lbaHigh = LBA[5]; /* FIS LBA (23:16) */
16947
16948 /* Check FUA bit */
16949 fis->d.device = 0x40; /* FIS FUA clear */
16950
16951 fis->d.lbaLowExp = LBA[4]; /* FIS LBA (31:24) */
16952 fis->d.lbaMidExp = LBA[3]; /* FIS LBA (39:32) */
16953 fis->d.lbaHighExp = LBA[2]; /* FIS LBA (47:40) */
16954 fis->d.featuresExp = 0; /* FIS sector count (15:8) */
16955 fis->d.sectorCount = 0; /* Tag (7:3) set by LL layer */
16956 fis->d.sectorCountExp = 0;
16957 fis->d.reserved4 = 0;
16958 fis->d.control = 0; /* FIS HOB bit clear */
16959 fis->d.reserved5 = 0;
16960
16961 agRequestType = AGSA_SATA_PROTOCOL_FPDMA_WRITE;
16962 satIOContext->ATACmd = SAT_WRITE_FPDMA_QUEUED;
16963 }
16964
16965 satIOContext->satCompleteCB = &satReassignBlocksCB;
16966
16967 /*
16968 * Prepare SGL and send FIS to LL layer.
16969 */
16970 satIOContext->reqType = agRequestType; /* Save it */
16971
16972 status = sataLLIOStart( tiRoot,
16973 tiIORequest,
16974 tiDeviceHandle,
16975 /* not the original, should be the TD generated one */
16976 tiScsiRequest,
16977 satIOContext);
16978 return (status);
16979 }
16980
16981
16982 /*****************************************************************************/
16983 /*! \brief SAT implementation for SCSI satPrepareNewIO.
16984 *
16985 * This function fills in the fields of internal IO generated by TD layer.
16986 * This is mostly used in the callback functions.
16987 *
16988 * \param satNewIntIo: Pointer to the internal IO structure.
16989 * \param tiOrgIORequest: Pointer to the original tiIOrequest sent by OS layer
16990 * \param satDevData: Pointer to the device data.
16991 * \param scsiCmnd: Pointer to SCSI command.
16992 * \param satOrgIOContext: Pointer to the original SAT IO Context
16993 *
16994 * \return
16995 * - \e Pointer to the new SAT IO Context
16996 */
16997 /*****************************************************************************/
16998 GLOBAL satIOContext_t *satPrepareNewIO(
16999 satInternalIo_t *satNewIntIo,
17000 tiIORequest_t *tiOrgIORequest,
17001 satDeviceData_t *satDevData,
17002 tiIniScsiCmnd_t *scsiCmnd,
17003 satIOContext_t *satOrgIOContext
17004 )
17005 {
17006 satIOContext_t *satNewIOContext;
17007 tdIORequestBody_t *tdNewIORequestBody;
17008
17009 TI_DBG2(("satPrepareNewIO: start\n"));
17010
17011 /* the one to be used; good 8/2/07 */
17012 satNewIntIo->satOrgTiIORequest = tiOrgIORequest; /* this is already done in
17013 satAllocIntIoResource() */
17014
17015 tdNewIORequestBody = (tdIORequestBody_t *)satNewIntIo->satIntRequestBody;
17016 satNewIOContext = &(tdNewIORequestBody->transport.SATA.satIOContext);
17017
17018 satNewIOContext->pSatDevData = satDevData;
17019 satNewIOContext->pFis = &(tdNewIORequestBody->transport.SATA.agSATARequestBody.fis.fisRegHostToDev);
17020 satNewIOContext->pScsiCmnd = &(satNewIntIo->satIntTiScsiXchg.scsiCmnd);
17021 if (scsiCmnd != agNULL)
17022 {
17023 /* saves only CBD; not scsi command for LBA and number of blocks */
17024 osti_memcpy(satNewIOContext->pScsiCmnd->cdb, scsiCmnd->cdb, 16);
17025 }
17026 satNewIOContext->pSense = &(tdNewIORequestBody->transport.SATA.sensePayload);
17027 satNewIOContext->pTiSenseData = &(tdNewIORequestBody->transport.SATA.tiSenseData);
17028 satNewIOContext->pTiSenseData->senseData = satNewIOContext->pSense;
17029 satNewIOContext->tiRequestBody = satNewIntIo->satIntRequestBody;
17030 satNewIOContext->interruptContext = satNewIOContext->interruptContext;
17031 satNewIOContext->satIntIoContext = satNewIntIo;
17032 satNewIOContext->ptiDeviceHandle = satOrgIOContext->ptiDeviceHandle;
17033 satNewIOContext->satOrgIOContext = satOrgIOContext;
17034 /* saves tiScsiXchg; only for writesame10() */
17035 satNewIOContext->tiScsiXchg = satOrgIOContext->tiScsiXchg;
17036
17037 return satNewIOContext;
17038 }
17039 /*****************************************************************************
17040 *! \brief satIOAbort
17041 *
17042 * This routine is called to initiate a I/O abort to SATL.
17043 * This routine is independent of HW/LL API.
17044 *
17045 * \param tiRoot: Pointer to TISA initiator driver/port instance.
17046 * \param taskTag: Pointer to TISA I/O request context/tag to be aborted.
17047 *
17048 * \return:
17049 *
17050 * \e tiSuccess: I/O request successfully initiated.
17051 * \e tiBusy: No resources available, try again later.
17052 * \e tiError: Other errors that prevent the I/O request to be started.
17053 *
17054 *
17055 *****************************************************************************/
17056 GLOBAL bit32 satIOAbort(
17057 tiRoot_t *tiRoot,
17058 tiIORequest_t *taskTag )
17059 {
17060
17061 tdsaRoot_t *tdsaRoot = (tdsaRoot_t *) tiRoot->tdData;
17062 tdsaContext_t *tdsaAllShared = (tdsaContext_t *)&tdsaRoot->tdsaAllShared;
17063 agsaRoot_t *agRoot;
17064 tdIORequestBody_t *tdIORequestBody;
17065 tdIORequestBody_t *tdIONewRequestBody;
17066 agsaIORequest_t *agIORequest;
17067 bit32 status;
17068 agsaIORequest_t *agAbortIORequest;
17069 tdIORequestBody_t *tdAbortIORequestBody;
17070 bit32 PhysUpper32;
17071 bit32 PhysLower32;
17072 bit32 memAllocStatus;
17073 void *osMemHandle;
17074 satIOContext_t *satIOContext;
17075 satInternalIo_t *satIntIo;
17076
17077 TI_DBG2(("satIOAbort: start\n"));
17078
17079 agRoot = &(tdsaAllShared->agRootNonInt);
17080 tdIORequestBody = (tdIORequestBody_t *)taskTag->tdData;
17081
17082 /* needs to distinguish internally generated or externally generated */
17083 satIOContext = &(tdIORequestBody->transport.SATA.satIOContext);
17084 satIntIo = satIOContext->satIntIoContext;
17085 if (satIntIo == agNULL)
17086 {
17087 TI_DBG1(("satIOAbort: External, OS generated\n"));
17088 agIORequest = &(tdIORequestBody->agIORequest);
17089 }
17090 else
17091 {
17092 TI_DBG1(("satIOAbort: Internal, TD generated\n"));
17093 tdIONewRequestBody = (tdIORequestBody_t *)satIntIo->satIntRequestBody;
17094 agIORequest = &(tdIONewRequestBody->agIORequest);
17095 }
17096
17097 /* allocating agIORequest for abort itself */
17098 memAllocStatus = ostiAllocMemory(
17099 tiRoot,
17100 &osMemHandle,
17101 (void **)&tdAbortIORequestBody,
17102 &PhysUpper32,
17103 &PhysLower32,
17104 8,
17105 sizeof(tdIORequestBody_t),
17106 agTRUE
17107 );
17108 if (memAllocStatus != tiSuccess)
17109 {
17110 /* let os process IO */
17111 TI_DBG1(("satIOAbort: ostiAllocMemory failed...\n"));
17112 return tiError;
17113 }
17114
17115 if (tdAbortIORequestBody == agNULL)
17116 {
17117 /* let os process IO */
17118 TI_DBG1(("satIOAbort: ostiAllocMemory returned NULL tdAbortIORequestBody\n"));
17119 return tiError;
17120 }
17121
17122 /* setup task management structure */
17123 tdAbortIORequestBody->IOType.InitiatorTMIO.osMemHandle = osMemHandle;
17124 tdAbortIORequestBody->tiDevHandle = tdIORequestBody->tiDevHandle;
17125
17126 /* initialize agIORequest */
17127 agAbortIORequest = &(tdAbortIORequestBody->agIORequest);
17128 agAbortIORequest->osData = (void *) tdAbortIORequestBody;
17129 agAbortIORequest->sdkData = agNULL; /* LL takes care of this */
17130
17131 /* remember IO to be aborted */
17132 tdAbortIORequestBody->tiIOToBeAbortedRequest = taskTag;
17133
17134 status = saSATAAbort( agRoot, agAbortIORequest, 0, agNULL, 0, agIORequest, agNULL );
17135
17136 TI_DBG5(("satIOAbort: return status=0x%x\n", status));
17137
17138 if (status == AGSA_RC_SUCCESS)
17139 return tiSuccess;
17140 else
17141 return tiError;
17142
17143 }
17144
17145
17146 /*****************************************************************************
17147 *! \brief satTM
17148 *
17149 * This routine is called to initiate a TM request to SATL.
17150 * This routine is independent of HW/LL API.
17151 *
17152 * \param tiRoot: Pointer to TISA initiator driver/port instance.
17153 * \param tiDeviceHandle: Pointer to TISA device handle for this I/O.
17154 * \param task: SAM-3 task management request.
17155 * \param lun: Pointer to LUN.
17156 * \param taskTag: Pointer to the associated task where the TM
17157 * command is to be applied.
17158 * \param currentTaskTag: Pointer to tag/context for this TM request.
17159 *
17160 * \return:
17161 *
17162 * \e tiSuccess: I/O request successfully initiated.
17163 * \e tiBusy: No resources available, try again later.
17164 * \e tiIONoDevice: Invalid device handle.
17165 * \e tiError: Other errors that prevent the I/O request to be started.
17166 *
17167 *
17168 *****************************************************************************/
17169 /* save task in satIOContext */
17170 osGLOBAL bit32 satTM(
17171 tiRoot_t *tiRoot,
17172 tiDeviceHandle_t *tiDeviceHandle,
17173 bit32 task,
17174 tiLUN_t *lun,
17175 tiIORequest_t *taskTag,
17176 tiIORequest_t *currentTaskTag,
17177 tdIORequestBody_t *tiRequestBody,
17178 bit32 NotifyOS
17179 )
17180 {
17181 tdIORequestBody_t *tdIORequestBody = agNULL;
17182 satIOContext_t *satIOContext = agNULL;
17183 tdsaDeviceData_t *oneDeviceData = agNULL;
17184 bit32 status;
17185
17186 TI_DBG3(("satTM: tiDeviceHandle=%p task=0x%x\n", tiDeviceHandle, task ));
17187
17188 /* set satIOContext fields and etc */
17189 oneDeviceData = (tdsaDeviceData_t *)tiDeviceHandle->tdData;
17190
17191
17192 tdIORequestBody = (tdIORequestBody_t *)tiRequestBody;
17193 satIOContext = &(tdIORequestBody->transport.SATA.satIOContext);
17194
17195 satIOContext->pSatDevData = &oneDeviceData->satDevData;
17196 satIOContext->pFis =
17197 &tdIORequestBody->transport.SATA.agSATARequestBody.fis.fisRegHostToDev;
17198
17199
17200 satIOContext->tiRequestBody = tiRequestBody;
17201 satIOContext->ptiDeviceHandle = tiDeviceHandle;
17202 satIOContext->satIntIoContext = agNULL;
17203 satIOContext->satOrgIOContext = agNULL;
17204
17205 /* followings are used only for internal IO */
17206 satIOContext->currentLBA = 0;
17207 satIOContext->OrgTL = 0;
17208
17209 /* saving task in satIOContext */
17210 satIOContext->TMF = task;
17211
17212 satIOContext->satToBeAbortedIOContext = agNULL;
17213
17214 if (NotifyOS == agTRUE)
17215 {
17216 satIOContext->NotifyOS = agTRUE;
17217 }
17218 else
17219 {
17220 satIOContext->NotifyOS = agFALSE;
17221 }
17222 /*
17223 * Our SAT supports RESET LUN and partially support ABORT TASK (only if there
17224 * is no more than one I/O pending on the drive.
17225 */
17226
17227 if (task == AG_LOGICAL_UNIT_RESET)
17228 {
17229 status = satTmResetLUN( tiRoot,
17230 currentTaskTag,
17231 tiDeviceHandle,
17232 agNULL,
17233 satIOContext,
17234 lun);
17235 return status;
17236 }
17237 #ifdef TO_BE_REMOVED
17238 else if (task == AG_TARGET_WARM_RESET)
17239 {
17240 status = satTmWarmReset( tiRoot,
17241 currentTaskTag,
17242 tiDeviceHandle,
17243 agNULL,
17244 satIOContext);
17245
17246 return status;
17247 }
17248 #endif
17249 else if (task == AG_ABORT_TASK)
17250 {
17251 status = satTmAbortTask( tiRoot,
17252 currentTaskTag,
17253 tiDeviceHandle,
17254 agNULL,
17255 satIOContext,
17256 taskTag);
17257
17258 return status;
17259 }
17260 else if (task == TD_INTERNAL_TM_RESET)
17261 {
17262 status = satTDInternalTmReset( tiRoot,
17263 currentTaskTag,
17264 tiDeviceHandle,
17265 agNULL,
17266 satIOContext);
17267 return status;
17268 }
17269 else
17270 {
17271 TI_DBG1(("satTM: tiDeviceHandle=%p UNSUPPORTED TM task=0x%x\n",
17272 tiDeviceHandle, task ));
17273
17274 /* clean up TD layer's IORequestBody */
17275 ostiFreeMemory(
17276 tiRoot,
17277 tiRequestBody->IOType.InitiatorTMIO.osMemHandle,
17278 sizeof(tdIORequestBody_t)
17279 );
17280 return tiError;
17281 }
17282
17283 }
17284
17285
17286 /*****************************************************************************
17287 *! \brief satTmResetLUN
17288 *
17289 * This routine is called to initiate a TM RESET LUN request to SATL.
17290 * This routine is independent of HW/LL API.
17291 *
17292 * \param tiRoot: Pointer to TISA initiator driver/port instance.
17293 * \param tiDeviceHandle: Pointer to TISA device handle for this I/O.
17294 * \param lun: Pointer to LUN.
17295 * \param currentTaskTag: Pointer to tag/context for this TM request.
17296 *
17297 * \return:
17298 *
17299 * \e tiSuccess: I/O request successfully initiated.
17300 * \e tiBusy: No resources available, try again later.
17301 * \e tiIONoDevice: Invalid device handle.
17302 * \e tiError: Other errors that prevent the I/O request to be started.
17303 *
17304 *
17305 *****************************************************************************/
17306 osGLOBAL bit32 satTmResetLUN(
17307 tiRoot_t *tiRoot,
17308 tiIORequest_t *tiIORequest, /* current task tag */
17309 tiDeviceHandle_t *tiDeviceHandle,
17310 tiScsiInitiatorRequest_t *tiScsiRequest,
17311 satIOContext_t *satIOContext,
17312 tiLUN_t *lun)
17313 {
17314
17315 tdsaDeviceData_t *tdsaDeviceData;
17316 satDeviceData_t *satDevData;
17317
17318 tdsaDeviceData = (tdsaDeviceData_t *)tiDeviceHandle->tdData;
17319 satDevData = &tdsaDeviceData->satDevData;
17320
17321 TI_DBG1(("satTmResetLUN: tiDeviceHandle=%p.\n", tiDeviceHandle ));
17322
17323 /*
17324 * Only support LUN 0
17325 */
17326 if ( (lun->lun[0] | lun->lun[1] | lun->lun[2] | lun->lun[3] |
17327 lun->lun[4] | lun->lun[5] | lun->lun[6] | lun->lun[7] ) != 0 )
17328 {
17329 TI_DBG1(("satTmResetLUN: *** REJECT *** LUN not zero, tiDeviceHandle=%p\n",
17330 tiDeviceHandle));
17331 return tiError;
17332 }
17333
17334 /*
17335 * Check if there is other TM request pending
17336 */
17337 if (satDevData->satTmTaskTag != agNULL)
17338 {
17339 TI_DBG1(("satTmResetLUN: *** REJECT *** other TM pending, tiDeviceHandle=%p\n",
17340 tiDeviceHandle));
17341 return tiError;
17342 }
17343
17344 /*
17345 * Save tiIORequest, will be returned at device reset completion to return
17346 * the TM completion.
17347 */
17348 satDevData->satTmTaskTag = tiIORequest;
17349
17350 /*
17351 * Set flag to indicate device in recovery mode.
17352 */
17353 satDevData->satDriveState = SAT_DEV_STATE_IN_RECOVERY;
17354
17355 /*
17356 * Issue SATA device reset. Set flag to indicate NOT to automatically abort
17357 * at the completion of SATA device reset.
17358 */
17359 satDevData->satAbortAfterReset = agFALSE;
17360
17361 /* SAT rev8 6.3.6 p22 */
17362 satStartResetDevice(
17363 tiRoot,
17364 tiIORequest, /* currentTaskTag */
17365 tiDeviceHandle,
17366 tiScsiRequest,
17367 satIOContext
17368 );
17369
17370
17371 return tiSuccess;
17372
17373 }
17374
17375 /*****************************************************************************
17376 *! \brief satTmWarmReset
17377 *
17378 * This routine is called to initiate a TM warm RESET request to SATL.
17379 * This routine is independent of HW/LL API.
17380 *
17381 * \param tiRoot: Pointer to TISA initiator driver/port instance.
17382 * \param tiDeviceHandle: Pointer to TISA device handle for this I/O.
17383 * \param currentTaskTag: Pointer to tag/context for this TM request.
17384 *
17385 * \return:
17386 *
17387 * \e tiSuccess: I/O request successfully initiated.
17388 * \e tiBusy: No resources available, try again later.
17389 * \e tiIONoDevice: Invalid device handle.
17390 * \e tiError: Other errors that prevent the I/O request to be started.
17391 *
17392 *
17393 *****************************************************************************/
17394 osGLOBAL bit32 satTmWarmReset(
17395 tiRoot_t *tiRoot,
17396 tiIORequest_t *tiIORequest, /* current task tag */
17397 tiDeviceHandle_t *tiDeviceHandle,
17398 tiScsiInitiatorRequest_t *tiScsiRequest,
17399 satIOContext_t *satIOContext)
17400 {
17401
17402 tdsaDeviceData_t *tdsaDeviceData;
17403 satDeviceData_t *satDevData;
17404
17405 tdsaDeviceData = (tdsaDeviceData_t *)tiDeviceHandle->tdData;
17406 satDevData = &tdsaDeviceData->satDevData;
17407
17408 TI_DBG1(("satTmWarmReset: tiDeviceHandle=%p.\n", tiDeviceHandle ));
17409
17410 /*
17411 * Check if there is other TM request pending
17412 */
17413 if (satDevData->satTmTaskTag != agNULL)
17414 {
17415 TI_DBG1(("satTmWarmReset: *** REJECT *** other TM pending, tiDeviceHandle=%p\n",
17416 tiDeviceHandle));
17417 return tiError;
17418 }
17419
17420 /*
17421 * Save tiIORequest, will be returned at device reset completion to return
17422 * the TM completion.
17423 */
17424 satDevData->satTmTaskTag = tiIORequest;
17425
17426 /*
17427 * Set flag to indicate device in recovery mode.
17428 */
17429 satDevData->satDriveState = SAT_DEV_STATE_IN_RECOVERY;
17430
17431 /*
17432 * Issue SATA device reset. Set flag to indicate NOT to automatically abort
17433 * at the completion of SATA device reset.
17434 */
17435 satDevData->satAbortAfterReset = agFALSE;
17436
17437 /* SAT rev8 6.3.6 p22 */
17438 satStartResetDevice(
17439 tiRoot,
17440 tiIORequest, /* currentTaskTag */
17441 tiDeviceHandle,
17442 tiScsiRequest,
17443 satIOContext
17444 );
17445
17446 return tiSuccess;
17447
17448 }
17449
17450 osGLOBAL bit32 satTDInternalTmReset(
17451 tiRoot_t *tiRoot,
17452 tiIORequest_t *tiIORequest, /* current task tag */
17453 tiDeviceHandle_t *tiDeviceHandle,
17454 tiScsiInitiatorRequest_t *tiScsiRequest,
17455 satIOContext_t *satIOContext)
17456 {
17457
17458 tdsaDeviceData_t *tdsaDeviceData;
17459 satDeviceData_t *satDevData;
17460
17461 tdsaDeviceData = (tdsaDeviceData_t *)tiDeviceHandle->tdData;
17462 satDevData = &tdsaDeviceData->satDevData;
17463
17464 TI_DBG1(("satTmWarmReset: tiDeviceHandle=%p.\n", tiDeviceHandle ));
17465
17466 /*
17467 * Check if there is other TM request pending
17468 */
17469 if (satDevData->satTmTaskTag != agNULL)
17470 {
17471 TI_DBG1(("satTmWarmReset: *** REJECT *** other TM pending, tiDeviceHandle=%p\n",
17472 tiDeviceHandle));
17473 return tiError;
17474 }
17475
17476 /*
17477 * Save tiIORequest, will be returned at device reset completion to return
17478 * the TM completion.
17479 */
17480 satDevData->satTmTaskTag = tiIORequest;
17481
17482 /*
17483 * Set flag to indicate device in recovery mode.
17484 */
17485 satDevData->satDriveState = SAT_DEV_STATE_IN_RECOVERY;
17486
17487 /*
17488 * Issue SATA device reset. Set flag to indicate NOT to automatically abort
17489 * at the completion of SATA device reset.
17490 */
17491 satDevData->satAbortAfterReset = agFALSE;
17492
17493 /* SAT rev8 6.3.6 p22 */
17494 satStartResetDevice(
17495 tiRoot,
17496 tiIORequest, /* currentTaskTag */
17497 tiDeviceHandle,
17498 tiScsiRequest,
17499 satIOContext
17500 );
17501
17502 return tiSuccess;
17503
17504 }
17505
17506 /*****************************************************************************
17507 *! \brief satTmAbortTask
17508 *
17509 * This routine is called to initiate a TM ABORT TASK request to SATL.
17510 * This routine is independent of HW/LL API.
17511 *
17512 * \param tiRoot: Pointer to TISA initiator driver/port instance.
17513 * \param tiDeviceHandle: Pointer to TISA device handle for this I/O.
17514 * \param taskTag: Pointer to the associated task where the TM
17515 * command is to be applied.
17516 * \param currentTaskTag: Pointer to tag/context for this TM request.
17517 *
17518 * \return:
17519 *
17520 * \e tiSuccess: I/O request successfully initiated.
17521 * \e tiBusy: No resources available, try again later.
17522 * \e tiIONoDevice: Invalid device handle.
17523 * \e tiError: Other errors that prevent the I/O request to be started.
17524 *
17525 *
17526 *****************************************************************************/
17527 osGLOBAL bit32 satTmAbortTask(
17528 tiRoot_t *tiRoot,
17529 tiIORequest_t *tiIORequest, /* current task tag */
17530 tiDeviceHandle_t *tiDeviceHandle,
17531 tiScsiInitiatorRequest_t *tiScsiRequest, /* NULL */
17532 satIOContext_t *satIOContext,
17533 tiIORequest_t *taskTag)
17534 {
17535
17536 tdsaDeviceData_t *tdsaDeviceData;
17537 satDeviceData_t *satDevData;
17538 satIOContext_t *satTempIOContext = agNULL;
17539 tdIORequestBody_t *tdIORequestBody;
17540 tdIORequestBody_t *TMtdIORequestBody;
17541 tdList_t *elementHdr;
17542 bit32 found = agFALSE;
17543 tiIORequest_t *tiIOReq;
17544
17545 tdsaDeviceData = (tdsaDeviceData_t *)tiDeviceHandle->tdData;
17546 satDevData = &tdsaDeviceData->satDevData;
17547 TMtdIORequestBody = (tdIORequestBody_t *)tiIORequest->tdData;
17548
17549 TI_DBG1(("satTmAbortTask: tiDeviceHandle=%p taskTag=%p.\n", tiDeviceHandle, taskTag ));
17550 /*
17551 * Check if there is other TM request pending
17552 */
17553 if (satDevData->satTmTaskTag != agNULL)
17554 {
17555 TI_DBG1(("satTmAbortTask: REJECT other TM pending, tiDeviceHandle=%p\n",
17556 tiDeviceHandle));
17557 /* clean up TD layer's IORequestBody */
17558 ostiFreeMemory(
17559 tiRoot,
17560 TMtdIORequestBody->IOType.InitiatorTMIO.osMemHandle,
17561 sizeof(tdIORequestBody_t)
17562 );
17563 return tiError;
17564 }
17565
17566 #ifdef REMOVED
17567 /*
17568 * Check if there is only one I/O pending.
17569 */
17570 if (satDevData->satPendingIO > 0)
17571 {
17572 TI_DBG1(("satTmAbortTask: REJECT num pending I/O, tiDeviceHandle=%p, satPendingIO=0x%x\n",
17573 tiDeviceHandle, satDevData->satPendingIO));
17574 /* clean up TD layer's IORequestBody */
17575 ostiFreeMemory(
17576 tiRoot,
17577 TMtdIORequestBody->IOType.InitiatorTMIO.osMemHandle,
17578 sizeof(tdIORequestBody_t)
17579 );
17580
17581 return tiError;
17582 }
17583 #endif
17584
17585 /*
17586 * Check that the only pending I/O matches taskTag. If not return tiError.
17587 */
17588 elementHdr = satDevData->satIoLinkList.flink;
17589
17590 while (elementHdr != &satDevData->satIoLinkList)
17591 {
17592 satTempIOContext = TDLIST_OBJECT_BASE( satIOContext_t,
17593 satIoContextLink,
17594 elementHdr );
17595
17596 tdIORequestBody = (tdIORequestBody_t *) satTempIOContext->tiRequestBody;
17597 tiIOReq = tdIORequestBody->tiIORequest;
17598
17599 elementHdr = elementHdr->flink; /* for the next while loop */
17600
17601 /*
17602 * Check if the tag matches
17603 */
17604 if ( tiIOReq == taskTag)
17605 {
17606 found = agTRUE;
17607 satIOContext->satToBeAbortedIOContext = satTempIOContext;
17608 TI_DBG1(("satTmAbortTask: found matching tag.\n"));
17609
17610 break;
17611
17612 } /* if matching tag */
17613
17614 } /* while loop */
17615
17616
17617 if (found == agFALSE )
17618 {
17619 TI_DBG1(("satTmAbortTask: *** REJECT *** no match, tiDeviceHandle=%p\n",
17620 tiDeviceHandle ));
17621
17622 /* clean up TD layer's IORequestBody */
17623 ostiFreeMemory(
17624 tiRoot,
17625 TMtdIORequestBody->IOType.InitiatorTMIO.osMemHandle,
17626 sizeof(tdIORequestBody_t)
17627 );
17628
17629 return tiError;
17630 }
17631
17632 /*
17633 * Save tiIORequest, will be returned at device reset completion to return
17634 * the TM completion.
17635 */
17636 satDevData->satTmTaskTag = tiIORequest;
17637
17638 /*
17639 * Set flag to indicate device in recovery mode.
17640 */
17641 satDevData->satDriveState = SAT_DEV_STATE_IN_RECOVERY;
17642
17643
17644 /*
17645 * Issue SATA device reset or check power mode. Set flag to to automatically abort
17646 * at the completion of SATA device reset.
17647 * SAT r09 p25
17648 */
17649 satDevData->satAbortAfterReset = agTRUE;
17650
17651 if ( (satTempIOContext->reqType == AGSA_SATA_PROTOCOL_FPDMA_WRITE) ||
17652 (satTempIOContext->reqType == AGSA_SATA_PROTOCOL_FPDMA_READ)
17653 )
17654 {
17655 TI_DBG1(("satTmAbortTask: calling satStartCheckPowerMode\n"));
17656 /* send check power mode */
17657 satStartCheckPowerMode(
17658 tiRoot,
17659 tiIORequest, /* currentTaskTag */
17660 tiDeviceHandle,
17661 tiScsiRequest,
17662 satIOContext
17663 );
17664 }
17665 else
17666 {
17667 TI_DBG1(("satTmAbortTask: calling satStartResetDevice\n"));
17668 /* send AGSA_SATA_PROTOCOL_SRST_ASSERT */
17669 satStartResetDevice(
17670 tiRoot,
17671 tiIORequest, /* currentTaskTag */
17672 tiDeviceHandle,
17673 tiScsiRequest,
17674 satIOContext
17675 );
17676 }
17677
17678
17679 return tiSuccess;
17680 }
17681
17682 /*****************************************************************************
17683 *! \brief osSatResetCB
17684 *
17685 * This routine is called to notify the completion of SATA device reset
17686 * which was initiated previously through the call to sataLLReset().
17687 * This routine is independent of HW/LL API.
17688 *
17689 * \param tiRoot: Pointer to TISA initiator driver/port instance.
17690 * \param tiDeviceHandle: Pointer to TISA device handle for this I/O.
17691 * \param resetStatus: Reset status either tiSuccess or tiError.
17692 * \param respFis: Pointer to the Register Device-To-Host FIS
17693 * received from the device.
17694 *
17695 * \return: None
17696 *
17697 *****************************************************************************/
17698 osGLOBAL void osSatResetCB(
17699 tiRoot_t *tiRoot,
17700 tiDeviceHandle_t *tiDeviceHandle,
17701 bit32 resetStatus,
17702 void *respFis)
17703 {
17704
17705 agsaRoot_t *agRoot;
17706 tdsaDeviceData_t *tdsaDeviceData;
17707 satDeviceData_t *satDevData;
17708 satIOContext_t *satIOContext;
17709 tdIORequestBody_t *tdIORequestBodyTmp;
17710 tdList_t *elementHdr;
17711 agsaIORequest_t *agAbortIORequest;
17712 tdIORequestBody_t *tdAbortIORequestBody;
17713 bit32 PhysUpper32;
17714 bit32 PhysLower32;
17715 bit32 memAllocStatus;
17716 void *osMemHandle;
17717
17718 tdsaDeviceData = (tdsaDeviceData_t *)tiDeviceHandle->tdData;
17719 agRoot = tdsaDeviceData->agRoot;
17720 satDevData = &tdsaDeviceData->satDevData;
17721
17722 TI_DBG5(("osSatResetCB: tiDeviceHandle=%p resetStatus=0x%x\n",
17723 tiDeviceHandle, resetStatus ));
17724
17725 /* We may need to check FIS to check device operating condition */
17726
17727
17728 /*
17729 * Check if need to abort all pending I/Os
17730 */
17731 if ( satDevData->satAbortAfterReset == agTRUE )
17732 {
17733 /*
17734 * Issue abort to LL layer to all other pending I/Os for the same SATA drive
17735 */
17736 elementHdr = satDevData->satIoLinkList.flink;
17737 while (elementHdr != &satDevData->satIoLinkList)
17738 {
17739 satIOContext = TDLIST_OBJECT_BASE( satIOContext_t,
17740 satIoContextLink,
17741 elementHdr );
17742
17743 tdIORequestBodyTmp = (tdIORequestBody_t *)satIOContext->tiRequestBody;
17744
17745 /*
17746 * Issue abort
17747 */
17748 TI_DBG5(("osSatResetCB: issuing ABORT tiDeviceHandle=%p agIORequest=%p\n",
17749 tiDeviceHandle, &tdIORequestBodyTmp->agIORequest ));
17750
17751 /* allocating agIORequest for abort itself */
17752 memAllocStatus = ostiAllocMemory(
17753 tiRoot,
17754 &osMemHandle,
17755 (void **)&tdAbortIORequestBody,
17756 &PhysUpper32,
17757 &PhysLower32,
17758 8,
17759 sizeof(tdIORequestBody_t),
17760 agTRUE
17761 );
17762
17763 if (memAllocStatus != tiSuccess)
17764 {
17765 /* let os process IO */
17766 TI_DBG1(("osSatResetCB: ostiAllocMemory failed...\n"));
17767 return;
17768 }
17769
17770 if (tdAbortIORequestBody == agNULL)
17771 {
17772 /* let os process IO */
17773 TI_DBG1(("osSatResetCB: ostiAllocMemory returned NULL tdAbortIORequestBody\n"));
17774 return;
17775 }
17776 /* setup task management structure */
17777 tdAbortIORequestBody->IOType.InitiatorTMIO.osMemHandle = osMemHandle;
17778 tdAbortIORequestBody->tiDevHandle = tiDeviceHandle;
17779
17780 /* initialize agIORequest */
17781 agAbortIORequest = &(tdAbortIORequestBody->agIORequest);
17782 agAbortIORequest->osData = (void *) tdAbortIORequestBody;
17783 agAbortIORequest->sdkData = agNULL; /* LL takes care of this */
17784
17785 saSATAAbort( agRoot, agAbortIORequest, 0, agNULL, 0, &(tdIORequestBodyTmp->agIORequest), agNULL );
17786 elementHdr = elementHdr->flink; /* for the next while loop */
17787
17788 } /* while */
17789
17790 /* Reset flag */
17791 satDevData->satAbortAfterReset = agFALSE;
17792
17793 }
17794
17795
17796 /*
17797 * Check if the device reset if the result of TM request.
17798 */
17799 if ( satDevData->satTmTaskTag != agNULL )
17800 {
17801 TI_DBG5(("osSatResetCB: calling TM completion tiDeviceHandle=%p satTmTaskTag=%p\n",
17802 tiDeviceHandle, satDevData->satTmTaskTag ));
17803
17804 ostiInitiatorEvent( tiRoot,
17805 agNULL, /* portalContext not used */
17806 tiDeviceHandle,
17807 tiIntrEventTypeTaskManagement,
17808 tiTMOK,
17809 satDevData->satTmTaskTag);
17810 /*
17811 * Reset flag
17812 */
17813 satDevData->satTmTaskTag = agNULL;
17814 }
17815
17816 }
17817
17818
17819 /*****************************************************************************
17820 *! \brief osSatIOCompleted
17821 *
17822 * This routine is a callback for SATA completion that required FIS status
17823 * translation to SCSI status.
17824 *
17825 * \param tiRoot: Pointer to TISA initiator driver/port instance.
17826 * \param tiIORequest: Pointer to TISA I/O request context for this I/O.
17827 * \param respFis: Pointer to status FIS to read.
17828 * \param respFisLen: Length of response FIS to read.
17829 * \param satIOContext: Pointer to SAT context.
17830 * \param interruptContext: Interrupt context
17831 *
17832 * \return: None
17833 *
17834 *****************************************************************************/
17835 osGLOBAL void osSatIOCompleted(
17836 tiRoot_t *tiRoot,
17837 tiIORequest_t *tiIORequest,
17838 agsaFisHeader_t *agFirstDword,
17839 bit32 respFisLen,
17840 agsaFrameHandle_t agFrameHandle,
17841 satIOContext_t *satIOContext,
17842 bit32 interruptContext)
17843
17844 {
17845 satDeviceData_t *pSatDevData;
17846 scsiRspSense_t *pSense;
17847 #ifdef TD_DEBUG_ENABLE
17848 tiIniScsiCmnd_t *pScsiCmnd;
17849 #endif
17850 agsaFisRegHostToDevice_t *hostToDevFis = agNULL;
17851 bit32 ataStatus = 0;
17852 bit32 ataError;
17853 satInternalIo_t *satIntIo = agNULL;
17854 bit32 status;
17855 tiDeviceHandle_t *tiDeviceHandle;
17856 satIOContext_t *satIOContext2;
17857 tdIORequestBody_t *tdIORequestBody;
17858 agsaFisRegD2HHeader_t *statDevToHostFisHeader = agNULL;
17859 agsaFisSetDevBitsHeader_t *statSetDevBitFisHeader = agNULL;
17860 tiIORequest_t tiIORequestTMP;
17861
17862 pSense = satIOContext->pSense;
17863 pSatDevData = satIOContext->pSatDevData;
17864 #ifdef TD_DEBUG_ENABLE
17865 pScsiCmnd = satIOContext->pScsiCmnd;
17866 #endif
17867 hostToDevFis = satIOContext->pFis;
17868
17869 tiDeviceHandle = &((tdsaDeviceData_t *)(pSatDevData->satSaDeviceData))->tiDeviceHandle;
17870 /*
17871 * Find out the type of response FIS:
17872 * Set Device Bit FIS or Reg Device To Host FIS.
17873 */
17874
17875 /* First assume it is Reg Device to Host FIS */
17876 statDevToHostFisHeader = (agsaFisRegD2HHeader_t *)&(agFirstDword->D2H);
17877 ataStatus = statDevToHostFisHeader->status; /* ATA Status register */
17878 ataError = statDevToHostFisHeader->error; /* ATA Eror register */
17879
17880 /* for debugging */
17881 TI_DBG1(("osSatIOCompleted: H to D command 0x%x\n", hostToDevFis->h.command));
17882 TI_DBG1(("osSatIOCompleted: D to H fistype 0x%x\n", statDevToHostFisHeader->fisType));
17883
17884
17885 if (statDevToHostFisHeader->fisType == SET_DEV_BITS_FIS)
17886 {
17887 /* It is Set Device Bits FIS */
17888 statSetDevBitFisHeader = (agsaFisSetDevBitsHeader_t *)&(agFirstDword->D2H);
17889 /* Get ATA Status register */
17890 ataStatus = (statSetDevBitFisHeader->statusHi_Lo & 0x70); /* bits 4,5,6 */
17891 ataStatus = ataStatus | (statSetDevBitFisHeader->statusHi_Lo & 0x07); /* bits 0,1,2 */
17892
17893 /* ATA Eror register */
17894 ataError = statSetDevBitFisHeader->error;
17895
17896 statDevToHostFisHeader = agNULL;
17897 }
17898
17899 else if (statDevToHostFisHeader->fisType != REG_DEV_TO_HOST_FIS)
17900 {
17901 TI_DBG1(("osSatIOCompleted: *** UNEXPECTED RESP FIS TYPE 0x%x *** tiIORequest=%p\n",
17902 statDevToHostFisHeader->fisType, tiIORequest));
17903
17904 satSetSensePayload( pSense,
17905 SCSI_SNSKEY_HARDWARE_ERROR,
17906 0,
17907 SCSI_SNSCODE_INTERNAL_TARGET_FAILURE,
17908 satIOContext);
17909
17910 ostiInitiatorIOCompleted( tiRoot,
17911 tiIORequest,
17912 tiIOSuccess,
17913 SCSI_STAT_CHECK_CONDITION,
17914 satIOContext->pTiSenseData,
17915 interruptContext );
17916 return;
17917
17918 }
17919
17920 if ( ataStatus & DF_ATA_STATUS_MASK )
17921 {
17922 pSatDevData->satDeviceFaultState = agTRUE;
17923 }
17924 else
17925 {
17926 pSatDevData->satDeviceFaultState = agFALSE;
17927 }
17928
17929 TI_DBG5(("osSatIOCompleted: tiIORequest=%p CDB=0x%x ATA CMD =0x%x\n",
17930 tiIORequest, pScsiCmnd->cdb[0], hostToDevFis->h.command));
17931
17932 /*
17933 * Decide which ATA command is the translation needed
17934 */
17935 switch(hostToDevFis->h.command)
17936 {
17937 case SAT_READ_FPDMA_QUEUED:
17938 case SAT_WRITE_FPDMA_QUEUED:
17939
17940 /************************************************************************
17941 *
17942 * !!!! See Section 13.5.2.4 of SATA 2.5 specs. !!!!
17943 * !!!! If the NCQ error ends up here, it means that the device sent !!!!
17944 * !!!! Set Device Bit FIS (which has SActive register) instead of !!!!
17945 * !!!! Register Device To Host FIS (which does not have SActive !!!!
17946 * !!!! register). The callback ossaSATAEvent() deals with the case !!!!
17947 * !!!! where Register Device To Host FIS was sent by the device. !!!!
17948 *
17949 * For NCQ we need to issue READ LOG EXT command with log page 10h
17950 * to get the error and to allow other I/Os to continue.
17951 *
17952 * Here is the basic flow or sequence of error recovery, note that due
17953 * to the SATA HW assist that we have, this sequence is slighly different
17954 * from the one described in SATA 2.5:
17955 *
17956 * 1. Set SATA device flag to indicate error condition and returning busy
17957 * for all new request.
17958 * return tiSuccess;
17959
17960 * 2. Because the HW/LL layer received Set Device Bit FIS, it can get the
17961 * tag or I/O context for NCQ request, SATL would translate the ATA error
17962 * to SCSI status and return the original NCQ I/O with the appopriate
17963 * SCSI status.
17964 *
17965 * 3. Prepare READ LOG EXT page 10h command. Set flag to indicate that
17966 * the failed I/O has been returned to the OS Layer. Send command.
17967 *
17968 * 4. When the device receives READ LOG EXT page 10h request all other
17969 * pending I/O are implicitly aborted. No completion (aborted) status
17970 * will be sent to the host for these aborted commands.
17971 *
17972 * 5. SATL receives the completion for READ LOG EXT command in
17973 * satReadLogExtCB(). Steps 6,7,8,9 below are the step 1,2,3,4 in
17974 * satReadLogExtCB().
17975 *
17976 * 6. Check flag that indicates whether the failed I/O has been returned
17977 * to the OS Layer. If not, search the I/O context in device data
17978 * looking for a matched tag. Then return the completion of the failed
17979 * NCQ command with the appopriate/trasnlated SCSI status.
17980 *
17981 * 7. Issue abort to LL layer to all other pending I/Os for the same SATA
17982 * drive.
17983 *
17984 * 8. Free resource allocated for the internally generated READ LOG EXT.
17985 *
17986 * 9. At the completion of abort, in the context of ossaSATACompleted(),
17987 * return the I/O with error status to the OS-App Specific layer.
17988 * When all I/O aborts are completed, clear SATA device flag to
17989 * indicate ready to process new request.
17990 *
17991 ***********************************************************************/
17992
17993 TI_DBG1(("osSatIOCompleted: NCQ ERROR tiIORequest=%p ataStatus=0x%x ataError=0x%x\n",
17994 tiIORequest, ataStatus, ataError ));
17995
17996 /* Set flag to indicate we are in recovery */
17997 pSatDevData->satDriveState = SAT_DEV_STATE_IN_RECOVERY;
17998
17999 /* Return the failed NCQ I/O to OS-Apps Specifiic layer */
18000 osSatDefaultTranslation( tiRoot,
18001 tiIORequest,
18002 satIOContext,
18003 pSense,
18004 (bit8)ataStatus,
18005 (bit8)ataError,
18006 interruptContext );
18007
18008 /*
18009 * Allocate resource for READ LOG EXT page 10h
18010 */
18011 satIntIo = satAllocIntIoResource( tiRoot,
18012 &(tiIORequestTMP), /* anything but NULL */
18013 pSatDevData,
18014 sizeof (satReadLogExtPage10h_t),
18015 satIntIo);
18016
18017 if (satIntIo == agNULL)
18018 {
18019 TI_DBG1(("osSatIOCompleted: can't send RLE due to resource lack\n"));
18020
18021 /* Abort I/O after completion of device reset */
18022 pSatDevData->satAbortAfterReset = agTRUE;
18023 #ifdef NOT_YET
18024 /* needs further investigation */
18025 /* no report to OS layer */
18026 satSubTM(tiRoot,
18027 tiDeviceHandle,
18028 TD_INTERNAL_TM_RESET,
18029 agNULL,
18030 agNULL,
18031 agNULL,
18032 agFALSE);
18033 #endif
18034
18035
18036 TI_DBG1(("osSatIOCompleted: calling saSATADeviceReset 1\n"));
18037 return;
18038 }
18039
18040
18041 /*
18042 * Set flag to indicate that the failed I/O has been returned to the
18043 * OS-App specific Layer.
18044 */
18045 satIntIo->satIntFlag = AG_SAT_INT_IO_FLAG_ORG_IO_COMPLETED;
18046
18047 /* compare to satPrepareNewIO() */
18048 /* Send READ LOG EXIT page 10h command */
18049
18050 /*
18051 * Need to initialize all the fields within satIOContext except
18052 * reqType and satCompleteCB which will be set depending on cmd.
18053 */
18054
18055 tdIORequestBody = (tdIORequestBody_t *)satIntIo->satIntRequestBody;
18056 satIOContext2 = &(tdIORequestBody->transport.SATA.satIOContext);
18057
18058 satIOContext2->pSatDevData = pSatDevData;
18059 satIOContext2->pFis = &(tdIORequestBody->transport.SATA.agSATARequestBody.fis.fisRegHostToDev);
18060 satIOContext2->pScsiCmnd = &(satIntIo->satIntTiScsiXchg.scsiCmnd);
18061 satIOContext2->pSense = &(tdIORequestBody->transport.SATA.sensePayload);
18062 satIOContext2->pTiSenseData = &(tdIORequestBody->transport.SATA.tiSenseData);
18063 satIOContext2->pTiSenseData->senseData = satIOContext2->pSense;
18064
18065 satIOContext2->tiRequestBody = satIntIo->satIntRequestBody;
18066 satIOContext2->interruptContext = interruptContext;
18067 satIOContext2->satIntIoContext = satIntIo;
18068
18069 satIOContext2->ptiDeviceHandle = tiDeviceHandle;
18070 satIOContext2->satOrgIOContext = agNULL;
18071 satIOContext2->tiScsiXchg = agNULL;
18072
18073 status = satSendReadLogExt( tiRoot,
18074 &satIntIo->satIntTiIORequest,
18075 tiDeviceHandle,
18076 &satIntIo->satIntTiScsiXchg,
18077 satIOContext2);
18078
18079 if (status != tiSuccess)
18080 {
18081 TI_DBG1(("osSatIOCompleted: can't send RLE due to LL api failure\n"));
18082 satFreeIntIoResource( tiRoot,
18083 pSatDevData,
18084 satIntIo);
18085
18086 /* Abort I/O after completion of device reset */
18087 pSatDevData->satAbortAfterReset = agTRUE;
18088 #ifdef NOT_YET
18089 /* needs further investigation */
18090 /* no report to OS layer */
18091 satSubTM(tiRoot,
18092 tiDeviceHandle,
18093 TD_INTERNAL_TM_RESET,
18094 agNULL,
18095 agNULL,
18096 agNULL,
18097 agFALSE);
18098 #endif
18099
18100 TI_DBG1(("osSatIOCompleted: calling saSATADeviceReset 2\n"));
18101 return;
18102 }
18103
18104 break;
18105
18106 case SAT_READ_DMA_EXT:
18107 /* fall through */
18108 /* Use default status/error translation */
18109
18110 case SAT_READ_DMA:
18111 /* fall through */
18112 /* Use default status/error translation */
18113
18114 default:
18115 osSatDefaultTranslation( tiRoot,
18116 tiIORequest,
18117 satIOContext,
18118 pSense,
18119 (bit8)ataStatus,
18120 (bit8)ataError,
18121 interruptContext );
18122 break;
18123
18124 } /* end switch */
18125 }
18126
18127
18128 /*****************************************************************************/
18129 /*! \brief SAT implementation for SCSI STANDARD INQUIRY.
18130 *
18131 * SAT implementation for SCSI STANDARD INQUIRY.
18132 *
18133 * \param pInquiry: Pointer to Inquiry Data buffer.
18134 * \param pSATAIdData: Pointer to ATA IDENTIFY DEVICE data.
18135 *
18136 * \return None.
18137 */
18138 /*****************************************************************************/
18139 GLOBAL void satInquiryStandard(
18140 bit8 *pInquiry,
18141 agsaSATAIdentifyData_t *pSATAIdData,
18142 tiIniScsiCmnd_t *scsiCmnd
18143 )
18144 {
18145 tiLUN_t *pLun;
18146 pLun = &scsiCmnd->lun;
18147
18148 /*
18149 Assumption: Basic Task Mangement is supported
18150 -> BQUE 1 and CMDQUE 0, SPC-4, Table96, p147
18151 */
18152 /*
18153 See SPC-4, 6.4.2, p 143
18154 and SAT revision 8, 8.1.2, p 28
18155 */
18156
18157 TI_DBG5(("satInquiryStandard: start\n"));
18158
18159 if (pInquiry == agNULL)
18160 {
18161 TI_DBG1(("satInquiryStandard: pInquiry is NULL, wrong\n"));
18162 return;
18163 }
18164 else
18165 {
18166 TI_DBG5(("satInquiryStandard: pInquiry is NOT NULL\n"));
18167 }
18168 /*
18169 * Reject all other LUN other than LUN 0.
18170 */
18171 if ( ((pLun->lun[0] | pLun->lun[1] | pLun->lun[2] | pLun->lun[3] |
18172 pLun->lun[4] | pLun->lun[5] | pLun->lun[6] | pLun->lun[7] ) != 0) )
18173 {
18174 /* SAT Spec Table 8, p27, footnote 'a' */
18175 pInquiry[0] = 0x7F;
18176
18177 }
18178 else
18179 {
18180 pInquiry[0] = 0x00;
18181 }
18182
18183 if (pSATAIdData->rm_ataDevice & ATA_REMOVABLE_MEDIA_DEVICE_MASK )
18184 {
18185 pInquiry[1] = 0x80;
18186 }
18187 else
18188 {
18189 pInquiry[1] = 0x00;
18190 }
18191 pInquiry[2] = 0x05; /* SPC-3 */
18192 pInquiry[3] = 0x12; /* set HiSup 1; resp data format set to 2 */
18193 pInquiry[4] = 0x1F; /* 35 - 4 = 31; Additional length */
18194 pInquiry[5] = 0x00;
18195 /* The following two are for task management. SAT Rev8, p20 */
18196 if (pSATAIdData->sataCapabilities & 0x100)
18197 {
18198 /* NCQ supported; multiple outstanding SCSI IO are supported */
18199 pInquiry[6] = 0x00; /* BQUE bit is not set */
18200 pInquiry[7] = 0x02; /* CMDQUE bit is set */
18201 }
18202 else
18203 {
18204 pInquiry[6] = 0x80; /* BQUE bit is set */
18205 pInquiry[7] = 0x00; /* CMDQUE bit is not set */
18206 }
18207 /*
18208 * Vendor ID.
18209 */
18210 osti_strncpy((char*)&pInquiry[8], AG_SAT_VENDOR_ID_STRING,8); /* 8 bytes */
18211
18212 /*
18213 * Product ID
18214 */
18215 /* when flipped by LL */
18216 pInquiry[16] = pSATAIdData->modelNumber[1];
18217 pInquiry[17] = pSATAIdData->modelNumber[0];
18218 pInquiry[18] = pSATAIdData->modelNumber[3];
18219 pInquiry[19] = pSATAIdData->modelNumber[2];
18220 pInquiry[20] = pSATAIdData->modelNumber[5];
18221 pInquiry[21] = pSATAIdData->modelNumber[4];
18222 pInquiry[22] = pSATAIdData->modelNumber[7];
18223 pInquiry[23] = pSATAIdData->modelNumber[6];
18224 pInquiry[24] = pSATAIdData->modelNumber[9];
18225 pInquiry[25] = pSATAIdData->modelNumber[8];
18226 pInquiry[26] = pSATAIdData->modelNumber[11];
18227 pInquiry[27] = pSATAIdData->modelNumber[10];
18228 pInquiry[28] = pSATAIdData->modelNumber[13];
18229 pInquiry[29] = pSATAIdData->modelNumber[12];
18230 pInquiry[30] = pSATAIdData->modelNumber[15];
18231 pInquiry[31] = pSATAIdData->modelNumber[14];
18232
18233 /* when flipped */
18234 /*
18235 * Product Revision level.
18236 */
18237
18238 /*
18239 * If the IDENTIFY DEVICE data received in words 25 and 26 from the ATA
18240 * device are ASCII spaces (20h), do this translation.
18241 */
18242 if ( (pSATAIdData->firmwareVersion[4] == 0x20 ) &&
18243 (pSATAIdData->firmwareVersion[5] == 0x00 ) &&
18244 (pSATAIdData->firmwareVersion[6] == 0x20 ) &&
18245 (pSATAIdData->firmwareVersion[7] == 0x00 )
18246 )
18247 {
18248 pInquiry[32] = pSATAIdData->firmwareVersion[1];
18249 pInquiry[33] = pSATAIdData->firmwareVersion[0];
18250 pInquiry[34] = pSATAIdData->firmwareVersion[3];
18251 pInquiry[35] = pSATAIdData->firmwareVersion[2];
18252 }
18253 else
18254 {
18255 pInquiry[32] = pSATAIdData->firmwareVersion[5];
18256 pInquiry[33] = pSATAIdData->firmwareVersion[4];
18257 pInquiry[34] = pSATAIdData->firmwareVersion[7];
18258 pInquiry[35] = pSATAIdData->firmwareVersion[6];
18259 }
18260
18261
18262 #ifdef REMOVED
18263 /*
18264 * Product ID
18265 */
18266 /* when flipped by LL */
18267 pInquiry[16] = pSATAIdData->modelNumber[0];
18268 pInquiry[17] = pSATAIdData->modelNumber[1];
18269 pInquiry[18] = pSATAIdData->modelNumber[2];
18270 pInquiry[19] = pSATAIdData->modelNumber[3];
18271 pInquiry[20] = pSATAIdData->modelNumber[4];
18272 pInquiry[21] = pSATAIdData->modelNumber[5];
18273 pInquiry[22] = pSATAIdData->modelNumber[6];
18274 pInquiry[23] = pSATAIdData->modelNumber[7];
18275 pInquiry[24] = pSATAIdData->modelNumber[8];
18276 pInquiry[25] = pSATAIdData->modelNumber[9];
18277 pInquiry[26] = pSATAIdData->modelNumber[10];
18278 pInquiry[27] = pSATAIdData->modelNumber[11];
18279 pInquiry[28] = pSATAIdData->modelNumber[12];
18280 pInquiry[29] = pSATAIdData->modelNumber[13];
18281 pInquiry[30] = pSATAIdData->modelNumber[14];
18282 pInquiry[31] = pSATAIdData->modelNumber[15];
18283
18284 /* when flipped */
18285 /*
18286 * Product Revision level.
18287 */
18288
18289 /*
18290 * If the IDENTIFY DEVICE data received in words 25 and 26 from the ATA
18291 * device are ASCII spaces (20h), do this translation.
18292 */
18293 if ( (pSATAIdData->firmwareVersion[4] == 0x20 ) &&
18294 (pSATAIdData->firmwareVersion[5] == 0x00 ) &&
18295 (pSATAIdData->firmwareVersion[6] == 0x20 ) &&
18296 (pSATAIdData->firmwareVersion[7] == 0x00 )
18297 )
18298 {
18299 pInquiry[32] = pSATAIdData->firmwareVersion[0];
18300 pInquiry[33] = pSATAIdData->firmwareVersion[1];
18301 pInquiry[34] = pSATAIdData->firmwareVersion[2];
18302 pInquiry[35] = pSATAIdData->firmwareVersion[3];
18303 }
18304 else
18305 {
18306 pInquiry[32] = pSATAIdData->firmwareVersion[4];
18307 pInquiry[33] = pSATAIdData->firmwareVersion[5];
18308 pInquiry[34] = pSATAIdData->firmwareVersion[6];
18309 pInquiry[35] = pSATAIdData->firmwareVersion[7];
18310 }
18311 #endif
18312
18313 TI_DBG5(("satInquiryStandard: end\n"));
18314
18315 }
18316
18317
18318 /*****************************************************************************/
18319 /*! \brief SAT implementation for SCSI INQUIRY page 0.
18320 *
18321 * SAT implementation for SCSI INQUIRY page 0.
18322 *
18323 * \param pInquiry: Pointer to Inquiry Data buffer.
18324 * \param pSATAIdData: Pointer to ATA IDENTIFY DEVICE data.
18325 *
18326 * \return None.
18327 */
18328 /*****************************************************************************/
18329 GLOBAL void satInquiryPage0(
18330 bit8 *pInquiry,
18331 agsaSATAIdentifyData_t *pSATAIdData)
18332 {
18333
18334 TI_DBG5(("satInquiryPage0: entry\n"));
18335
18336 /*
18337 See SPC-4, 7.6.9, p 345
18338 and SAT revision 8, 10.3.2, p 77
18339 */
18340 pInquiry[0] = 0x00;
18341 pInquiry[1] = 0x00; /* page code */
18342 pInquiry[2] = 0x00; /* reserved */
18343 pInquiry[3] = 7 - 3; /* last index(in this case, 6) - 3; page length */
18344
18345 /* supported vpd page list */
18346 pInquiry[4] = 0x00; /* page 0x00 supported */
18347 pInquiry[5] = 0x80; /* page 0x80 supported */
18348 pInquiry[6] = 0x83; /* page 0x83 supported */
18349 pInquiry[7] = 0x89; /* page 0x89 supported */
18350
18351 }
18352
18353
18354 /*****************************************************************************/
18355 /*! \brief SAT implementation for SCSI INQUIRY page 83.
18356 *
18357 * SAT implementation for SCSI INQUIRY page 83.
18358 *
18359 * \param pInquiry: Pointer to Inquiry Data buffer.
18360 * \param pSATAIdData: Pointer to ATA IDENTIFY DEVICE data.
18361 *
18362 * \return None.
18363 */
18364 /*****************************************************************************/
18365 GLOBAL void satInquiryPage83(
18366 bit8 *pInquiry,
18367 agsaSATAIdentifyData_t *pSATAIdData,
18368 satDeviceData_t *pSatDevData)
18369 {
18370
18371 satSimpleSATAIdentifyData_t *pSimpleData;
18372
18373 /*
18374 * When translating the fields, in some cases using the simple form of SATA
18375 * Identify Device Data is easier. So we define it here.
18376 * Both pSimpleData and pSATAIdData points to the same data.
18377 */
18378 pSimpleData = ( satSimpleSATAIdentifyData_t *)pSATAIdData;
18379
18380 TI_DBG5(("satInquiryPage83: entry\n"));
18381
18382 pInquiry[0] = 0x00;
18383 pInquiry[1] = 0x83; /* page code */
18384 pInquiry[2] = 0; /* Reserved */
18385
18386 /*
18387 * If the ATA device returns word 87 bit 8 set to one in its IDENTIFY DEVICE
18388 * data indicating that it supports the WORLD WIDE NAME field
18389 * (i.e., words 108-111), the SATL shall include an identification descriptor
18390 * containing a logical unit name.
18391 */
18392 if ( pSatDevData->satWWNSupport)
18393 {
18394 /* Fill in SAT Rev8 Table85 */
18395 /*
18396 * Logical unit name derived from the world wide name.
18397 */
18398 pInquiry[3] = 12; /* 15-3; page length, no addition ID descriptor assumed*/
18399
18400 /*
18401 * Identifier descriptor
18402 */
18403 pInquiry[4] = 0x01; /* Code set: binary codes */
18404 pInquiry[5] = 0x03; /* Identifier type : NAA */
18405 pInquiry[6] = 0x00; /* Reserved */
18406 pInquiry[7] = 0x08; /* Identifier length */
18407
18408 /* Bit 4-7 NAA field, bit 0-3 MSB of IEEE Company ID */
18409 pInquiry[8] = (bit8)((pSATAIdData->namingAuthority) >> 8);
18410 pInquiry[9] = (bit8)((pSATAIdData->namingAuthority) & 0xFF); /* IEEE Company ID */
18411 pInquiry[10] = (bit8)((pSATAIdData->namingAuthority1) >> 8); /* IEEE Company ID */
18412 /* Bit 4-7 LSB of IEEE Company ID, bit 0-3 MSB of Vendor Specific ID */
18413 pInquiry[11] = (bit8)((pSATAIdData->namingAuthority1) & 0xFF);
18414 pInquiry[12] = (bit8)((pSATAIdData->uniqueID_bit16_31) >> 8); /* Vendor Specific ID */
18415 pInquiry[13] = (bit8)((pSATAIdData->uniqueID_bit16_31) & 0xFF); /* Vendor Specific ID */
18416 pInquiry[14] = (bit8)((pSATAIdData->uniqueID_bit0_15) >> 8); /* Vendor Specific ID */
18417 pInquiry[15] = (bit8)((pSATAIdData->uniqueID_bit0_15) & 0xFF); /* Vendor Specific ID */
18418
18419 }
18420 else
18421 {
18422 /* Fill in SAT Rev8 Table86 */
18423 /*
18424 * Logical unit name derived from the model number and serial number.
18425 */
18426 pInquiry[3] = 72; /* 75 - 3; page length */
18427
18428 /*
18429 * Identifier descriptor
18430 */
18431 pInquiry[4] = 0x02; /* Code set: ASCII codes */
18432 pInquiry[5] = 0x01; /* Identifier type : T10 vendor ID based */
18433 pInquiry[6] = 0x00; /* Reserved */
18434 pInquiry[7] = 0x44; /* 0x44, 68 Identifier length */
18435
18436 /* Byte 8 to 15 is the vendor id string 'ATA '. */
18437 osti_strncpy((char *)&pInquiry[8], AG_SAT_VENDOR_ID_STRING, 8);
18438
18439
18440 /*
18441 * Byte 16 to 75 is vendor specific id
18442 */
18443 pInquiry[16] = (bit8)((pSimpleData->word[27]) >> 8);
18444 pInquiry[17] = (bit8)((pSimpleData->word[27]) & 0x00ff);
18445 pInquiry[18] = (bit8)((pSimpleData->word[28]) >> 8);
18446 pInquiry[19] = (bit8)((pSimpleData->word[28]) & 0x00ff);
18447 pInquiry[20] = (bit8)((pSimpleData->word[29]) >> 8);
18448 pInquiry[21] = (bit8)((pSimpleData->word[29]) & 0x00ff);
18449 pInquiry[22] = (bit8)((pSimpleData->word[30]) >> 8);
18450 pInquiry[23] = (bit8)((pSimpleData->word[30]) & 0x00ff);
18451 pInquiry[24] = (bit8)((pSimpleData->word[31]) >> 8);
18452 pInquiry[25] = (bit8)((pSimpleData->word[31]) & 0x00ff);
18453 pInquiry[26] = (bit8)((pSimpleData->word[32]) >> 8);
18454 pInquiry[27] = (bit8)((pSimpleData->word[32]) & 0x00ff);
18455 pInquiry[28] = (bit8)((pSimpleData->word[33]) >> 8);
18456 pInquiry[29] = (bit8)((pSimpleData->word[33]) & 0x00ff);
18457 pInquiry[30] = (bit8)((pSimpleData->word[34]) >> 8);
18458 pInquiry[31] = (bit8)((pSimpleData->word[34]) & 0x00ff);
18459 pInquiry[32] = (bit8)((pSimpleData->word[35]) >> 8);
18460 pInquiry[33] = (bit8)((pSimpleData->word[35]) & 0x00ff);
18461 pInquiry[34] = (bit8)((pSimpleData->word[36]) >> 8);
18462 pInquiry[35] = (bit8)((pSimpleData->word[36]) & 0x00ff);
18463 pInquiry[36] = (bit8)((pSimpleData->word[37]) >> 8);
18464 pInquiry[37] = (bit8)((pSimpleData->word[37]) & 0x00ff);
18465 pInquiry[38] = (bit8)((pSimpleData->word[38]) >> 8);
18466 pInquiry[39] = (bit8)((pSimpleData->word[38]) & 0x00ff);
18467 pInquiry[40] = (bit8)((pSimpleData->word[39]) >> 8);
18468 pInquiry[41] = (bit8)((pSimpleData->word[39]) & 0x00ff);
18469 pInquiry[42] = (bit8)((pSimpleData->word[40]) >> 8);
18470 pInquiry[43] = (bit8)((pSimpleData->word[40]) & 0x00ff);
18471 pInquiry[44] = (bit8)((pSimpleData->word[41]) >> 8);
18472 pInquiry[45] = (bit8)((pSimpleData->word[41]) & 0x00ff);
18473 pInquiry[46] = (bit8)((pSimpleData->word[42]) >> 8);
18474 pInquiry[47] = (bit8)((pSimpleData->word[42]) & 0x00ff);
18475 pInquiry[48] = (bit8)((pSimpleData->word[43]) >> 8);
18476 pInquiry[49] = (bit8)((pSimpleData->word[43]) & 0x00ff);
18477 pInquiry[50] = (bit8)((pSimpleData->word[44]) >> 8);
18478 pInquiry[51] = (bit8)((pSimpleData->word[44]) & 0x00ff);
18479 pInquiry[52] = (bit8)((pSimpleData->word[45]) >> 8);
18480 pInquiry[53] = (bit8)((pSimpleData->word[45]) & 0x00ff);
18481 pInquiry[54] = (bit8)((pSimpleData->word[46]) >> 8);
18482 pInquiry[55] = (bit8)((pSimpleData->word[46]) & 0x00ff);
18483
18484 pInquiry[56] = (bit8)((pSimpleData->word[10]) >> 8);
18485 pInquiry[57] = (bit8)((pSimpleData->word[10]) & 0x00ff);
18486 pInquiry[58] = (bit8)((pSimpleData->word[11]) >> 8);
18487 pInquiry[59] = (bit8)((pSimpleData->word[11]) & 0x00ff);
18488 pInquiry[60] = (bit8)((pSimpleData->word[12]) >> 8);
18489 pInquiry[61] = (bit8)((pSimpleData->word[12]) & 0x00ff);
18490 pInquiry[62] = (bit8)((pSimpleData->word[13]) >> 8);
18491 pInquiry[63] = (bit8)((pSimpleData->word[13]) & 0x00ff);
18492 pInquiry[64] = (bit8)((pSimpleData->word[14]) >> 8);
18493 pInquiry[65] = (bit8)((pSimpleData->word[14]) & 0x00ff);
18494 pInquiry[66] = (bit8)((pSimpleData->word[15]) >> 8);
18495 pInquiry[67] = (bit8)((pSimpleData->word[15]) & 0x00ff);
18496 pInquiry[68] = (bit8)((pSimpleData->word[16]) >> 8);
18497 pInquiry[69] = (bit8)((pSimpleData->word[16]) & 0x00ff);
18498 pInquiry[70] = (bit8)((pSimpleData->word[17]) >> 8);
18499 pInquiry[71] = (bit8)((pSimpleData->word[17]) & 0x00ff);
18500 pInquiry[72] = (bit8)((pSimpleData->word[18]) >> 8);
18501 pInquiry[73] = (bit8)((pSimpleData->word[18]) & 0x00ff);
18502 pInquiry[74] = (bit8)((pSimpleData->word[19]) >> 8);
18503 pInquiry[75] = (bit8)((pSimpleData->word[19]) & 0x00ff);
18504 }
18505
18506 }
18507
18508 /*****************************************************************************/
18509 /*! \brief SAT implementation for SCSI INQUIRY page 89.
18510 *
18511 * SAT implementation for SCSI INQUIRY page 89.
18512 *
18513 * \param pInquiry: Pointer to Inquiry Data buffer.
18514 * \param pSATAIdData: Pointer to ATA IDENTIFY DEVICE data.
18515 * \param pSatDevData Pointer to internal device data structure
18516 *
18517 * \return None.
18518 */
18519 /*****************************************************************************/
18520 GLOBAL void satInquiryPage89(
18521 bit8 *pInquiry,
18522 agsaSATAIdentifyData_t *pSATAIdData,
18523 satDeviceData_t *pSatDevData)
18524 {
18525 /*
18526 SAT revision 8, 10.3.5, p 83
18527 */
18528 satSimpleSATAIdentifyData_t *pSimpleData;
18529
18530 /*
18531 * When translating the fields, in some cases using the simple form of SATA
18532 * Identify Device Data is easier. So we define it here.
18533 * Both pSimpleData and pSATAIdData points to the same data.
18534 */
18535 pSimpleData = ( satSimpleSATAIdentifyData_t *)pSATAIdData;
18536
18537 TI_DBG5(("satInquiryPage89: start\n"));
18538
18539 pInquiry[0] = 0x00; /* Peripheral Qualifier and Peripheral Device Type */
18540 pInquiry[1] = 0x89; /* page code */
18541
18542 /* Page length 0x238 */
18543 pInquiry[2] = 0x02;
18544 pInquiry[3] = 0x38;
18545
18546 pInquiry[4] = 0x0; /* reserved */
18547 pInquiry[5] = 0x0; /* reserved */
18548 pInquiry[6] = 0x0; /* reserved */
18549 pInquiry[7] = 0x0; /* reserved */
18550
18551 /* SAT Vendor Identification */
18552 osti_strncpy((char*)&pInquiry[8], "PMC-SIERRA", 8); /* 8 bytes */
18553
18554 /* SAT Product Idetification */
18555 osti_strncpy((char*)&pInquiry[16], "Tachyon-SPC ", 16); /* 16 bytes */
18556
18557 /* SAT Product Revision Level */
18558 osti_strncpy((char*)&pInquiry[32], "01", 4); /* 4 bytes */
18559
18560 /* Signature, SAT revision8, Table88, p85 */
18561
18562
18563 pInquiry[36] = 0x34; /* FIS type */
18564 if (pSatDevData->satDeviceType == SATA_ATA_DEVICE)
18565 {
18566 /* interrupt assume to be 0 */
18567 pInquiry[37] = (bit8)((pSatDevData->satPMField) >> (4 * 7)); /* first four bits of PM field */
18568 }
18569 else
18570 {
18571 /* interrupt assume to be 1 */
18572 pInquiry[37] = (bit8)(0x40 + (bit8)(((pSatDevData->satPMField) >> (4 * 7)))); /* first four bits of PM field */
18573 }
18574 pInquiry[38] = 0;
18575 pInquiry[39] = 0;
18576
18577 if (pSatDevData->satDeviceType == SATA_ATA_DEVICE)
18578 {
18579 pInquiry[40] = 0x01; /* LBA Low */
18580 pInquiry[41] = 0x00; /* LBA Mid */
18581 pInquiry[42] = 0x00; /* LBA High */
18582 pInquiry[43] = 0x00; /* Device */
18583 pInquiry[44] = 0x00; /* LBA Low Exp */
18584 pInquiry[45] = 0x00; /* LBA Mid Exp */
18585 pInquiry[46] = 0x00; /* LBA High Exp */
18586 pInquiry[47] = 0x00; /* Reserved */
18587 pInquiry[48] = 0x01; /* Sector Count */
18588 pInquiry[49] = 0x00; /* Sector Count Exp */
18589 }
18590 else
18591 {
18592 pInquiry[40] = 0x01; /* LBA Low */
18593 pInquiry[41] = 0x00; /* LBA Mid */
18594 pInquiry[42] = 0x00; /* LBA High */
18595 pInquiry[43] = 0x00; /* Device */
18596 pInquiry[44] = 0x00; /* LBA Low Exp */
18597 pInquiry[45] = 0x00; /* LBA Mid Exp */
18598 pInquiry[46] = 0x00; /* LBA High Exp */
18599 pInquiry[47] = 0x00; /* Reserved */
18600 pInquiry[48] = 0x01; /* Sector Count */
18601 pInquiry[49] = 0x00; /* Sector Count Exp */
18602 }
18603
18604 /* Reserved */
18605 pInquiry[50] = 0x00;
18606 pInquiry[51] = 0x00;
18607 pInquiry[52] = 0x00;
18608 pInquiry[53] = 0x00;
18609 pInquiry[54] = 0x00;
18610 pInquiry[55] = 0x00;
18611
18612 /* Command Code */
18613 if (pSatDevData->satDeviceType == SATA_ATA_DEVICE)
18614 {
18615 pInquiry[56] = 0xEC; /* IDENTIFY DEVICE */
18616 }
18617 else
18618 {
18619 pInquiry[56] = 0xA1; /* IDENTIFY PACKET DEVICE */
18620 }
18621 /* Reserved */
18622 pInquiry[57] = 0x0;
18623 pInquiry[58] = 0x0;
18624 pInquiry[59] = 0x0;
18625
18626 /* Identify Device */
18627 osti_memcpy(&pInquiry[60], pSimpleData, sizeof(satSimpleSATAIdentifyData_t));
18628 return;
18629 }
18630
18631 /*****************************************************************************/
18632 /*! \brief SAT implementation for SCSI INQUIRY page 0.
18633 *
18634 * SAT implementation for SCSI INQUIRY page 0.
18635 *
18636 * \param pInquiry: Pointer to Inquiry Data buffer.
18637 * \param pSATAIdData: Pointer to ATA IDENTIFY DEVICE data.
18638 *
18639 * \return None.
18640 */
18641 /*****************************************************************************/
18642 GLOBAL void satInquiryPage80(
18643 bit8 *pInquiry,
18644 agsaSATAIdentifyData_t *pSATAIdData)
18645 {
18646
18647 TI_DBG5(("satInquiryPage80: entry\n"));
18648
18649 /*
18650 See SPC-4, 7.6.9, p 345
18651 and SAT revision 8, 10.3.3, p 77
18652 */
18653 pInquiry[0] = 0x00;
18654 pInquiry[1] = 0x80; /* page code */
18655 pInquiry[2] = 0x00; /* reserved */
18656 pInquiry[3] = 0x14; /* page length */
18657
18658 /* supported vpd page list */
18659 pInquiry[4] = pSATAIdData->serialNumber[1];
18660 pInquiry[5] = pSATAIdData->serialNumber[0];
18661 pInquiry[6] = pSATAIdData->serialNumber[3];
18662 pInquiry[7] = pSATAIdData->serialNumber[2];
18663 pInquiry[8] = pSATAIdData->serialNumber[5];
18664 pInquiry[9] = pSATAIdData->serialNumber[4];
18665 pInquiry[10] = pSATAIdData->serialNumber[7];
18666 pInquiry[11] = pSATAIdData->serialNumber[6];
18667 pInquiry[12] = pSATAIdData->serialNumber[9];
18668 pInquiry[13] = pSATAIdData->serialNumber[8];
18669 pInquiry[14] = pSATAIdData->serialNumber[11];
18670 pInquiry[15] = pSATAIdData->serialNumber[10];
18671 pInquiry[16] = pSATAIdData->serialNumber[13];
18672 pInquiry[17] = pSATAIdData->serialNumber[12];
18673 pInquiry[18] = pSATAIdData->serialNumber[15];
18674 pInquiry[19] = pSATAIdData->serialNumber[14];
18675 pInquiry[20] = pSATAIdData->serialNumber[17];
18676 pInquiry[21] = pSATAIdData->serialNumber[16];
18677 pInquiry[22] = pSATAIdData->serialNumber[19];
18678 pInquiry[23] = pSATAIdData->serialNumber[18];
18679
18680
18681 }
18682
18683
18684
18685 /*****************************************************************************/
18686 /*! \brief Send READ LOG EXT ATA PAGE 10h command to sata drive.
18687 *
18688 * Send READ LOG EXT ATA command PAGE 10h request to LL layer.
18689 *
18690 * \param tiRoot: Pointer to TISA initiator driver/port instance.
18691 * \param tiIORequest: Pointer to TISA I/O request context for this I/O.
18692 * \param tiDeviceHandle: Pointer to TISA device handle for this I/O.
18693 * \param tiScsiRequest: Pointer to TISA SCSI I/O request and SGL list.
18694 * \param satIOContext_t: Pointer to the SAT IO Context
18695 *
18696 * \return If command is started successfully
18697 * - \e tiSuccess: I/O request successfully initiated.
18698 * - \e tiBusy: No resources available, try again later.
18699 * - \e tiIONoDevice: Invalid device handle.
18700 * - \e tiError: Other errors.
18701 */
18702 /*****************************************************************************/
18703 GLOBAL bit32 satSendReadLogExt(
18704 tiRoot_t *tiRoot,
18705 tiIORequest_t *tiIORequest,
18706 tiDeviceHandle_t *tiDeviceHandle,
18707 tiScsiInitiatorRequest_t *tiScsiRequest,
18708 satIOContext_t *satIOContext)
18709
18710 {
18711
18712 bit32 status;
18713 bit32 agRequestType;
18714 agsaFisRegHostToDevice_t *fis;
18715
18716 fis = satIOContext->pFis;
18717
18718 TI_DBG1(("satSendReadLogExt: tiDeviceHandle=%p tiIORequest=%p\n",
18719 tiDeviceHandle, tiIORequest));
18720
18721 fis->h.fisType = 0x27; /* Reg host to device */
18722 fis->h.c_pmPort = 0x80; /* C Bit is set */
18723 fis->h.command = SAT_READ_LOG_EXT; /* 0x2F */
18724 fis->h.features = 0; /* FIS reserve */
18725 fis->d.lbaLow = 0x10; /* Page number */
18726 fis->d.lbaMid = 0; /* */
18727 fis->d.lbaHigh = 0; /* */
18728 fis->d.device = 0; /* DEV is ignored in SATA */
18729 fis->d.lbaLowExp = 0; /* */
18730 fis->d.lbaMidExp = 0; /* */
18731 fis->d.lbaHighExp = 0; /* */
18732 fis->d.featuresExp = 0; /* FIS reserve */
18733 fis->d.sectorCount = 0x01; /* 1 sector counts*/
18734 fis->d.sectorCountExp = 0x00; /* 1 sector counts */
18735 fis->d.reserved4 = 0;
18736 fis->d.control = 0; /* FIS HOB bit clear */
18737 fis->d.reserved5 = 0;
18738
18739 agRequestType = AGSA_SATA_PROTOCOL_PIO_READ;
18740
18741 /* Initialize CB for SATA completion.
18742 */
18743 satIOContext->satCompleteCB = &satReadLogExtCB;
18744
18745 /*
18746 * Prepare SGL and send FIS to LL layer.
18747 */
18748 satIOContext->reqType = agRequestType; /* Save it */
18749
18750 status = sataLLIOStart( tiRoot,
18751 tiIORequest,
18752 tiDeviceHandle,
18753 tiScsiRequest,
18754 satIOContext);
18755
18756 TI_DBG1(("satSendReadLogExt: end status %d\n", status));
18757
18758 return (status);
18759
18760 }
18761
18762
18763 /*****************************************************************************/
18764 /*! \brief SAT default ATA status and ATA error translation to SCSI.
18765 *
18766 * SSAT default ATA status and ATA error translation to SCSI.
18767 *
18768 * \param tiRoot: Pointer to TISA initiator driver/port instance.
18769 * \param tiIORequest: Pointer to TISA I/O request context for this I/O.
18770 * \param satIOContext: Pointer to the SAT IO Context
18771 * \param pSense: Pointer to scsiRspSense_t
18772 * \param ataStatus: ATA status register
18773 * \param ataError: ATA error register
18774 * \param interruptContext: Interrupt context
18775 *
18776 * \return None
18777 */
18778 /*****************************************************************************/
18779 GLOBAL void osSatDefaultTranslation(
18780 tiRoot_t *tiRoot,
18781 tiIORequest_t *tiIORequest,
18782 satIOContext_t *satIOContext,
18783 scsiRspSense_t *pSense,
18784 bit8 ataStatus,
18785 bit8 ataError,
18786 bit32 interruptContext )
18787 {
18788
18789 /*
18790 * Check for device fault case
18791 */
18792 if ( ataStatus & DF_ATA_STATUS_MASK )
18793 {
18794 satSetSensePayload( pSense,
18795 SCSI_SNSKEY_HARDWARE_ERROR,
18796 0,
18797 SCSI_SNSCODE_INTERNAL_TARGET_FAILURE,
18798 satIOContext);
18799
18800 ostiInitiatorIOCompleted( tiRoot,
18801 tiIORequest,
18802 tiIOSuccess,
18803 SCSI_STAT_CHECK_CONDITION,
18804 satIOContext->pTiSenseData,
18805 interruptContext );
18806 return;
18807 }
18808
18809 /*
18810 * If status error bit it set, need to check the error register
18811 */
18812 if ( ataStatus & ERR_ATA_STATUS_MASK )
18813 {
18814 if ( ataError & NM_ATA_ERROR_MASK )
18815 {
18816 TI_DBG1(("osSatDefaultTranslation: NM_ATA_ERROR ataError= 0x%x, tiIORequest=%p\n",
18817 ataError, tiIORequest));
18818 satSetSensePayload( pSense,
18819 SCSI_SNSKEY_NOT_READY,
18820 0,
18821 SCSI_SNSCODE_MEDIUM_NOT_PRESENT,
18822 satIOContext);
18823 }
18824
18825 else if (ataError & UNC_ATA_ERROR_MASK)
18826 {
18827 TI_DBG1(("osSatDefaultTranslation: UNC_ATA_ERROR ataError= 0x%x, tiIORequest=%p\n",
18828 ataError, tiIORequest));
18829 satSetSensePayload( pSense,
18830 SCSI_SNSKEY_MEDIUM_ERROR,
18831 0,
18832 SCSI_SNSCODE_UNRECOVERED_READ_ERROR,
18833 satIOContext);
18834 }
18835
18836 else if (ataError & IDNF_ATA_ERROR_MASK)
18837 {
18838 TI_DBG1(("osSatDefaultTranslation: IDNF_ATA_ERROR ataError= 0x%x, tiIORequest=%p\n",
18839 ataError, tiIORequest));
18840 satSetSensePayload( pSense,
18841 SCSI_SNSKEY_MEDIUM_ERROR,
18842 0,
18843 SCSI_SNSCODE_RECORD_NOT_FOUND,
18844 satIOContext);
18845 }
18846
18847 else if (ataError & MC_ATA_ERROR_MASK)
18848 {
18849 TI_DBG1(("osSatDefaultTranslation: MC_ATA_ERROR ataError= 0x%x, tiIORequest=%p\n",
18850 ataError, tiIORequest));
18851 satSetSensePayload( pSense,
18852 SCSI_SNSKEY_UNIT_ATTENTION,
18853 0,
18854 SCSI_SNSCODE_NOT_READY_TO_READY_CHANGE,
18855 satIOContext);
18856 }
18857
18858 else if (ataError & MCR_ATA_ERROR_MASK)
18859 {
18860 TI_DBG1(("osSatDefaultTranslation: MCR_ATA_ERROR ataError= 0x%x, tiIORequest=%p\n",
18861 ataError, tiIORequest));
18862 satSetSensePayload( pSense,
18863 SCSI_SNSKEY_UNIT_ATTENTION,
18864 0,
18865 SCSI_SNSCODE_OPERATOR_MEDIUM_REMOVAL_REQUEST,
18866 satIOContext);
18867 }
18868
18869 else if (ataError & ICRC_ATA_ERROR_MASK)
18870 {
18871 TI_DBG1(("osSatDefaultTranslation: ICRC_ATA_ERROR ataError= 0x%x, tiIORequest=%p\n",
18872 ataError, tiIORequest));
18873 satSetSensePayload( pSense,
18874 SCSI_SNSKEY_ABORTED_COMMAND,
18875 0,
18876 SCSI_SNSCODE_INFORMATION_UNIT_CRC_ERROR,
18877 satIOContext);
18878 }
18879
18880 else if (ataError & ABRT_ATA_ERROR_MASK)
18881 {
18882 TI_DBG1(("osSatDefaultTranslation: ABRT_ATA_ERROR ataError= 0x%x, tiIORequest=%p\n",
18883 ataError, tiIORequest));
18884 satSetSensePayload( pSense,
18885 SCSI_SNSKEY_ABORTED_COMMAND,
18886 0,
18887 SCSI_SNSCODE_NO_ADDITIONAL_INFO,
18888 satIOContext);
18889 }
18890
18891 else
18892 {
18893 TI_DBG1(("osSatDefaultTranslation: **** UNEXPECTED ATA_ERROR **** ataError= 0x%x, tiIORequest=%p\n",
18894 ataError, tiIORequest));
18895 satSetSensePayload( pSense,
18896 SCSI_SNSKEY_HARDWARE_ERROR,
18897 0,
18898 SCSI_SNSCODE_INTERNAL_TARGET_FAILURE,
18899 satIOContext);
18900 }
18901
18902 /* Send the completion response now */
18903 ostiInitiatorIOCompleted( tiRoot,
18904 tiIORequest,
18905 tiIOSuccess,
18906 SCSI_STAT_CHECK_CONDITION,
18907 satIOContext->pTiSenseData,
18908 interruptContext );
18909 return;
18910
18911
18912 }
18913
18914 else /* (ataStatus & ERR_ATA_STATUS_MASK ) is false */
18915 {
18916 /* This case should never happen */
18917 TI_DBG1(("osSatDefaultTranslation: *** UNEXPECTED ATA status 0x%x *** tiIORequest=%p\n",
18918 ataStatus, tiIORequest));
18919 satSetSensePayload( pSense,
18920 SCSI_SNSKEY_HARDWARE_ERROR,
18921 0,
18922 SCSI_SNSCODE_INTERNAL_TARGET_FAILURE,
18923 satIOContext);
18924
18925 ostiInitiatorIOCompleted( tiRoot,
18926 tiIORequest,
18927 tiIOSuccess,
18928 SCSI_STAT_CHECK_CONDITION,
18929 satIOContext->pTiSenseData,
18930 interruptContext );
18931 return;
18932
18933 }
18934
18935
18936 }
18937
18938 /*****************************************************************************/
18939 /*! \brief Allocate resource for SAT intervally generated I/O.
18940 *
18941 * Allocate resource for SAT intervally generated I/O.
18942 *
18943 * \param tiRoot: Pointer to TISA driver/port instance.
18944 * \param satDevData: Pointer to SAT specific device data.
18945 * \param allocLength: Length in byte of the DMA mem to allocate, upto
18946 * one page size.
18947 * \param satIntIo: Pointer (output) to context for SAT internally
18948 * generated I/O that is allocated by this routine.
18949 *
18950 * \return If command is started successfully
18951 * - \e tiSuccess: Success.
18952 * - \e tiError: Failed allocating resource.
18953 */
18954 /*****************************************************************************/
18955 GLOBAL satInternalIo_t * satAllocIntIoResource(
18956 tiRoot_t *tiRoot,
18957 tiIORequest_t *tiIORequest,
18958 satDeviceData_t *satDevData,
18959 bit32 dmaAllocLength,
18960 satInternalIo_t *satIntIo)
18961 {
18962 tdList_t *tdList = agNULL;
18963 bit32 memAllocStatus;
18964
18965 TI_DBG1(("satAllocIntIoResource: start\n"));
18966 TI_DBG6(("satAllocIntIoResource: satIntIo %p\n", satIntIo));
18967 if (satDevData == agNULL)
18968 {
18969 TI_DBG1(("satAllocIntIoResource: ***** ASSERT satDevData is null\n"));
18970 return agNULL;
18971 }
18972
18973 tdsaSingleThreadedEnter(tiRoot, TD_SATA_LOCK);
18974 if (!TDLIST_EMPTY(&(satDevData->satFreeIntIoLinkList)))
18975 {
18976 TDLIST_DEQUEUE_FROM_HEAD(&tdList, &(satDevData->satFreeIntIoLinkList));
18977 }
18978 else
18979 {
18980 tdsaSingleThreadedLeave(tiRoot, TD_SATA_LOCK);
18981 TI_DBG1(("satAllocIntIoResource() no more internal free link.\n"));
18982 return agNULL;
18983 }
18984
18985 if (tdList == agNULL)
18986 {
18987 tdsaSingleThreadedLeave(tiRoot, TD_SATA_LOCK);
18988 TI_DBG1(("satAllocIntIoResource() FAIL to alloc satIntIo.\n"));
18989 return agNULL;
18990 }
18991
18992 satIntIo = TDLIST_OBJECT_BASE( satInternalIo_t, satIntIoLink, tdList);
18993 TI_DBG6(("satAllocIntIoResource: satDevData %p satIntIo id %d\n", satDevData, satIntIo->id));
18994
18995 /* Put in active list */
18996 TDLIST_DEQUEUE_THIS (&(satIntIo->satIntIoLink));
18997 TDLIST_ENQUEUE_AT_TAIL (&(satIntIo->satIntIoLink), &(satDevData->satActiveIntIoLinkList));
18998 tdsaSingleThreadedLeave(tiRoot, TD_SATA_LOCK);
18999
19000 #ifdef REMOVED
19001 /* Put in active list */
19002 tdsaSingleThreadedEnter(tiRoot, TD_SATA_LOCK);
19003 TDLIST_DEQUEUE_THIS (tdList);
19004 TDLIST_ENQUEUE_AT_TAIL (tdList, &(satDevData->satActiveIntIoLinkList));
19005 tdsaSingleThreadedLeave(tiRoot, TD_SATA_LOCK);
19006
19007 satIntIo = TDLIST_OBJECT_BASE( satInternalIo_t, satIntIoLink, tdList);
19008 TI_DBG6(("satAllocIntIoResource: satDevData %p satIntIo id %d\n", satDevData, satIntIo->id));
19009 #endif
19010
19011 /*
19012 typedef struct
19013 {
19014 tdList_t satIntIoLink;
19015 tiIORequest_t satIntTiIORequest;
19016 void *satIntRequestBody;
19017 tiScsiInitiatorRequest_t satIntTiScsiXchg;
19018 tiMem_t satIntDmaMem;
19019 tiMem_t satIntReqBodyMem;
19020 bit32 satIntFlag;
19021 } satInternalIo_t;
19022 */
19023
19024 /*
19025 * Allocate mem for Request Body
19026 */
19027 satIntIo->satIntReqBodyMem.totalLength = sizeof(tdIORequestBody_t);
19028
19029 memAllocStatus = ostiAllocMemory( tiRoot,
19030 &satIntIo->satIntReqBodyMem.osHandle,
19031 (void **)&satIntIo->satIntRequestBody,
19032 &satIntIo->satIntReqBodyMem.physAddrUpper,
19033 &satIntIo->satIntReqBodyMem.physAddrLower,
19034 8,
19035 satIntIo->satIntReqBodyMem.totalLength,
19036 agTRUE );
19037
19038 if (memAllocStatus != tiSuccess)
19039 {
19040 TI_DBG1(("satAllocIntIoResource() FAIL to alloc mem for Req Body.\n"));
19041 /*
19042 * Return satIntIo to the free list
19043 */
19044 tdsaSingleThreadedEnter(tiRoot, TD_SATA_LOCK);
19045 TDLIST_DEQUEUE_THIS (&satIntIo->satIntIoLink);
19046 TDLIST_ENQUEUE_AT_HEAD(&satIntIo->satIntIoLink, &satDevData->satFreeIntIoLinkList);
19047 tdsaSingleThreadedLeave(tiRoot, TD_SATA_LOCK);
19048
19049 return agNULL;
19050 }
19051
19052 /*
19053 * Allocate DMA memory if required
19054 */
19055 if (dmaAllocLength != 0)
19056 {
19057 satIntIo->satIntDmaMem.totalLength = dmaAllocLength;
19058
19059 memAllocStatus = ostiAllocMemory( tiRoot,
19060 &satIntIo->satIntDmaMem.osHandle,
19061 (void **)&satIntIo->satIntDmaMem.virtPtr,
19062 &satIntIo->satIntDmaMem.physAddrUpper,
19063 &satIntIo->satIntDmaMem.physAddrLower,
19064 8,
19065 satIntIo->satIntDmaMem.totalLength,
19066 agFALSE);
19067 TI_DBG6(("satAllocIntIoResource: len %d \n", satIntIo->satIntDmaMem.totalLength));
19068 TI_DBG6(("satAllocIntIoResource: pointer %p \n", satIntIo->satIntDmaMem.osHandle));
19069
19070 if (memAllocStatus != tiSuccess)
19071 {
19072 TI_DBG1(("satAllocIntIoResource() FAIL to alloc mem for DMA mem.\n"));
19073 /*
19074 * Return satIntIo to the free list
19075 */
19076 tdsaSingleThreadedEnter(tiRoot, TD_SATA_LOCK);
19077 TDLIST_DEQUEUE_THIS (&satIntIo->satIntIoLink);
19078 TDLIST_ENQUEUE_AT_HEAD(&satIntIo->satIntIoLink, &satDevData->satFreeIntIoLinkList);
19079 tdsaSingleThreadedLeave(tiRoot, TD_SATA_LOCK);
19080
19081 /*
19082 * Free mem allocated for Req body
19083 */
19084 ostiFreeMemory( tiRoot,
19085 satIntIo->satIntReqBodyMem.osHandle,
19086 satIntIo->satIntReqBodyMem.totalLength);
19087
19088 return agNULL;
19089 }
19090 }
19091
19092 /*
19093 typedef struct
19094 {
19095 tdList_t satIntIoLink;
19096 tiIORequest_t satIntTiIORequest;
19097 void *satIntRequestBody;
19098 tiScsiInitiatorRequest_t satIntTiScsiXchg;
19099 tiMem_t satIntDmaMem;
19100 tiMem_t satIntReqBodyMem;
19101 bit32 satIntFlag;
19102 } satInternalIo_t;
19103 */
19104
19105 /*
19106 * Initialize satIntTiIORequest field
19107 */
19108 satIntIo->satIntTiIORequest.osData = agNULL; /* Not used for internal SAT I/O */
19109 satIntIo->satIntTiIORequest.tdData = satIntIo->satIntRequestBody;
19110
19111 /*
19112 * saves the original tiIOrequest
19113 */
19114 satIntIo->satOrgTiIORequest = tiIORequest;
19115 /*
19116 typedef struct tiIniScsiCmnd
19117 {
19118 tiLUN_t lun;
19119 bit32 expDataLength;
19120 bit32 taskAttribute;
19121 bit32 crn;
19122 bit8 cdb[16];
19123 } tiIniScsiCmnd_t;
19124
19125 typedef struct tiScsiInitiatorExchange
19126 {
19127 void *sglVirtualAddr;
19128 tiIniScsiCmnd_t scsiCmnd;
19129 tiSgl_t agSgl1;
19130 tiSgl_t agSgl2;
19131 tiDataDirection_t dataDirection;
19132 } tiScsiInitiatorRequest_t;
19133
19134 */
19135
19136 /*
19137 * Initialize satIntTiScsiXchg. Since the internal SAT request is NOT
19138 * originated from SCSI request, only the following fields are initialized:
19139 * - sglVirtualAddr if DMA transfer is involved
19140 * - agSgl1 if DMA transfer is involved
19141 * - expDataLength in scsiCmnd since this field is read by sataLLIOStart()
19142 */
19143 if (dmaAllocLength != 0)
19144 {
19145 satIntIo->satIntTiScsiXchg.sglVirtualAddr = satIntIo->satIntDmaMem.virtPtr;
19146
19147 OSSA_WRITE_LE_32(agNULL, &satIntIo->satIntTiScsiXchg.agSgl1.len, 0,
19148 satIntIo->satIntDmaMem.totalLength);
19149 satIntIo->satIntTiScsiXchg.agSgl1.lower = satIntIo->satIntDmaMem.physAddrLower;
19150 satIntIo->satIntTiScsiXchg.agSgl1.upper = satIntIo->satIntDmaMem.physAddrUpper;
19151 satIntIo->satIntTiScsiXchg.agSgl1.type = tiSgl;
19152
19153 satIntIo->satIntTiScsiXchg.scsiCmnd.expDataLength = satIntIo->satIntDmaMem.totalLength;
19154 }
19155 else
19156 {
19157 satIntIo->satIntTiScsiXchg.sglVirtualAddr = agNULL;
19158
19159 satIntIo->satIntTiScsiXchg.agSgl1.len = 0;
19160 satIntIo->satIntTiScsiXchg.agSgl1.lower = 0;
19161 satIntIo->satIntTiScsiXchg.agSgl1.upper = 0;
19162 satIntIo->satIntTiScsiXchg.agSgl1.type = tiSgl;
19163
19164 satIntIo->satIntTiScsiXchg.scsiCmnd.expDataLength = 0;
19165 }
19166
19167 TI_DBG5(("satAllocIntIoResource: satIntIo->satIntTiScsiXchg.agSgl1.len %d\n", satIntIo->satIntTiScsiXchg.agSgl1.len));
19168
19169 TI_DBG5(("satAllocIntIoResource: satIntIo->satIntTiScsiXchg.agSgl1.upper %d\n", satIntIo->satIntTiScsiXchg.agSgl1.upper));
19170
19171 TI_DBG5(("satAllocIntIoResource: satIntIo->satIntTiScsiXchg.agSgl1.lower %d\n", satIntIo->satIntTiScsiXchg.agSgl1.lower));
19172
19173 TI_DBG5(("satAllocIntIoResource: satIntIo->satIntTiScsiXchg.agSgl1.type %d\n", satIntIo->satIntTiScsiXchg.agSgl1.type));
19174 TI_DBG5(("satAllocIntIoResource: return satIntIo %p\n", satIntIo));
19175 return satIntIo;
19176
19177 }
19178
19179 /*****************************************************************************/
19180 /*! \brief Free resource for SAT intervally generated I/O.
19181 *
19182 * Free resource for SAT intervally generated I/O that was previously
19183 * allocated in satAllocIntIoResource().
19184 *
19185 * \param tiRoot: Pointer to TISA driver/port instance.
19186 * \param satDevData: Pointer to SAT specific device data.
19187 * \param satIntIo: Pointer to context for SAT internal I/O that was
19188 * previously allocated in satAllocIntIoResource().
19189 *
19190 * \return None
19191 */
19192 /*****************************************************************************/
19193 GLOBAL void satFreeIntIoResource(
19194 tiRoot_t *tiRoot,
19195 satDeviceData_t *satDevData,
19196 satInternalIo_t *satIntIo)
19197 {
19198 TI_DBG6(("satFreeIntIoResource: start\n"));
19199
19200 if (satIntIo == agNULL)
19201 {
19202 TI_DBG6(("satFreeIntIoResource: allowed call\n"));
19203 return;
19204 }
19205
19206 /* sets the original tiIOrequest to agNULL for internally generated ATA cmnd */
19207 satIntIo->satOrgTiIORequest = agNULL;
19208
19209 /*
19210 * Free DMA memory if previosly alocated
19211 */
19212 if (satIntIo->satIntTiScsiXchg.scsiCmnd.expDataLength != 0)
19213 {
19214 TI_DBG1(("satFreeIntIoResource: DMA len %d\n", satIntIo->satIntDmaMem.totalLength));
19215 TI_DBG6(("satFreeIntIoResource: pointer %p\n", satIntIo->satIntDmaMem.osHandle));
19216
19217 ostiFreeMemory( tiRoot,
19218 satIntIo->satIntDmaMem.osHandle,
19219 satIntIo->satIntDmaMem.totalLength);
19220 satIntIo->satIntTiScsiXchg.scsiCmnd.expDataLength = 0;
19221 }
19222
19223 if (satIntIo->satIntReqBodyMem.totalLength != 0)
19224 {
19225 TI_DBG1(("satFreeIntIoResource: req body len %d\n", satIntIo->satIntReqBodyMem.totalLength));
19226 /*
19227 * Free mem allocated for Req body
19228 */
19229 ostiFreeMemory( tiRoot,
19230 satIntIo->satIntReqBodyMem.osHandle,
19231 satIntIo->satIntReqBodyMem.totalLength);
19232
19233 satIntIo->satIntReqBodyMem.totalLength = 0;
19234 }
19235
19236 TI_DBG6(("satFreeIntIoResource: satDevData %p satIntIo id %d\n", satDevData, satIntIo->id));
19237 /*
19238 * Return satIntIo to the free list
19239 */
19240 tdsaSingleThreadedEnter(tiRoot, TD_SATA_LOCK);
19241 TDLIST_DEQUEUE_THIS (&(satIntIo->satIntIoLink));
19242 TDLIST_ENQUEUE_AT_TAIL (&(satIntIo->satIntIoLink), &(satDevData->satFreeIntIoLinkList));
19243 tdsaSingleThreadedLeave(tiRoot, TD_SATA_LOCK);
19244
19245 }
19246
19247
19248 /*****************************************************************************/
19249 /*! \brief SAT implementation for SCSI INQUIRY.
19250 *
19251 * SAT implementation for SCSI INQUIRY.
19252 * This function sends ATA Identify Device data command for SCSI INQUIRY
19253 *
19254 * \param tiRoot: Pointer to TISA initiator driver/port instance.
19255 * \param tiIORequest: Pointer to TISA I/O request context for this I/O.
19256 * \param tiDeviceHandle: Pointer to TISA device handle for this I/O.
19257 * \param tiScsiRequest: Pointer to TISA SCSI I/O request and SGL list.
19258 * \param satIOContext_t: Pointer to the SAT IO Context
19259 *
19260 * \return If command is started successfully
19261 * - \e tiSuccess: I/O request successfully initiated.
19262 * - \e tiBusy: No resources available, try again later.
19263 * - \e tiIONoDevice: Invalid device handle.
19264 * - \e tiError: Other errors.
19265 */
19266 /*****************************************************************************/
19267 GLOBAL bit32 satSendIDDev(
19268 tiRoot_t *tiRoot,
19269 tiIORequest_t *tiIORequest,
19270 tiDeviceHandle_t *tiDeviceHandle,
19271 tiScsiInitiatorRequest_t *tiScsiRequest,
19272 satIOContext_t *satIOContext)
19273
19274 {
19275 bit32 status;
19276 bit32 agRequestType;
19277 satDeviceData_t *pSatDevData;
19278 agsaFisRegHostToDevice_t *fis;
19279 #ifdef TD_DEBUG_ENABLE
19280 satInternalIo_t *satIntIoContext;
19281 tdsaDeviceData_t *oneDeviceData;
19282 tdIORequestBody_t *tdIORequestBody;
19283 #endif
19284
19285 pSatDevData = satIOContext->pSatDevData;
19286 fis = satIOContext->pFis;
19287
19288 TI_DBG5(("satSendIDDev: start\n"));
19289 #ifdef TD_DEBUG_ENABLE
19290 oneDeviceData = (tdsaDeviceData_t *)tiDeviceHandle->tdData;
19291 #endif
19292 TI_DBG5(("satSendIDDev: did %d\n", oneDeviceData->id));
19293
19294
19295 #ifdef TD_DEBUG_ENABLE
19296 satIntIoContext = satIOContext->satIntIoContext;
19297 tdIORequestBody = satIntIoContext->satIntRequestBody;
19298 #endif
19299
19300 TI_DBG5(("satSendIDDev: satIOContext %p tdIORequestBody %p\n", satIOContext, tdIORequestBody));
19301
19302 fis->h.fisType = 0x27; /* Reg host to device */
19303 fis->h.c_pmPort = 0x80; /* C Bit is set */
19304 if (pSatDevData->satDeviceType == SATA_ATAPI_DEVICE)
19305 fis->h.command = SAT_IDENTIFY_PACKET_DEVICE; /* 0x40 */
19306 else
19307 fis->h.command = SAT_IDENTIFY_DEVICE; /* 0xEC */
19308 fis->h.features = 0; /* FIS reserve */
19309 fis->d.lbaLow = 0; /* FIS LBA (7 :0 ) */
19310 fis->d.lbaMid = 0; /* FIS LBA (15:8 ) */
19311 fis->d.lbaHigh = 0; /* FIS LBA (23:16) */
19312 fis->d.device = 0; /* FIS LBA mode */
19313 fis->d.lbaLowExp = 0;
19314 fis->d.lbaMidExp = 0;
19315 fis->d.lbaHighExp = 0;
19316 fis->d.featuresExp = 0;
19317 fis->d.sectorCount = 0; /* FIS sector count (7:0) */
19318 fis->d.sectorCountExp = 0;
19319 fis->d.reserved4 = 0;
19320 fis->d.control = 0; /* FIS HOB bit clear */
19321 fis->d.reserved5 = 0;
19322
19323 agRequestType = AGSA_SATA_PROTOCOL_PIO_READ;
19324
19325 /* Initialize CB for SATA completion.
19326 */
19327 satIOContext->satCompleteCB = &satInquiryCB;
19328
19329 /*
19330 * Prepare SGL and send FIS to LL layer.
19331 */
19332 satIOContext->reqType = agRequestType; /* Save it */
19333
19334 #ifdef TD_INTERNAL_DEBUG
19335 tdhexdump("satSendIDDev", (bit8 *)satIOContext->pFis, sizeof(agsaFisRegHostToDevice_t));
19336 #ifdef TD_DEBUG_ENABLE
19337 tdhexdump("satSendIDDev LL", (bit8 *)&(tdIORequestBody->transport.SATA.agSATARequestBody.fis.fisRegHostToDev), sizeof(agsaFisRegHostToDevice_t));
19338 #endif
19339 #endif
19340
19341 status = sataLLIOStart( tiRoot,
19342 tiIORequest,
19343 tiDeviceHandle,
19344 tiScsiRequest,
19345 satIOContext);
19346
19347 TI_DBG6(("satSendIDDev: end status %d\n", status));
19348 return status;
19349 }
19350
19351
19352 /*****************************************************************************/
19353 /*! \brief SAT implementation for SCSI INQUIRY.
19354 *
19355 * SAT implementation for SCSI INQUIRY.
19356 * This function prepares TD layer internal resource to send ATA
19357 * Identify Device data command for SCSI INQUIRY
19358 *
19359 * \param tiRoot: Pointer to TISA initiator driver/port instance.
19360 * \param tiIORequest: Pointer to TISA I/O request context for this I/O.
19361 * \param tiDeviceHandle: Pointer to TISA device handle for this I/O.
19362 * \param tiScsiRequest: Pointer to TISA SCSI I/O request and SGL list.
19363 * \param satIOContext_t: Pointer to the SAT IO Context
19364 *
19365 * \return If command is started successfully
19366 * - \e tiSuccess: I/O request successfully initiated.
19367 * - \e tiBusy: No resources available, try again later.
19368 * - \e tiIONoDevice: Invalid device handle.
19369 * - \e tiError: Other errors.
19370 */
19371 /*****************************************************************************/
19372 /* prerequsite: tdsaDeviceData and agdevhandle must exist; in other words, LL discovered the device
19373 already */
19374 /*
19375 convert OS generated IO to TD generated IO due to difference in sgl
19376 */
19377 GLOBAL bit32 satStartIDDev(
19378 tiRoot_t *tiRoot,
19379 tiIORequest_t *tiIORequest,
19380 tiDeviceHandle_t *tiDeviceHandle,
19381 tiScsiInitiatorRequest_t *tiScsiRequest,
19382 satIOContext_t *satIOContext
19383 )
19384 {
19385 satInternalIo_t *satIntIo = agNULL;
19386 satDeviceData_t *satDevData = agNULL;
19387 tdIORequestBody_t *tdIORequestBody;
19388 satIOContext_t *satNewIOContext;
19389 bit32 status;
19390
19391 TI_DBG6(("satStartIDDev: start\n"));
19392
19393 satDevData = satIOContext->pSatDevData;
19394
19395 TI_DBG6(("satStartIDDev: before alloc\n"));
19396
19397 /* allocate identify device command */
19398 satIntIo = satAllocIntIoResource( tiRoot,
19399 tiIORequest,
19400 satDevData,
19401 sizeof(agsaSATAIdentifyData_t), /* 512; size of identify device data */
19402 satIntIo);
19403
19404 TI_DBG6(("satStartIDDev: before after\n"));
19405
19406 if (satIntIo == agNULL)
19407 {
19408 TI_DBG1(("satStartIDDev: can't alloacate\n"));
19409
19410 #if 0
19411 ostiInitiatorIOCompleted (
19412 tiRoot,
19413 tiIORequest,
19414 tiIOFailed,
19415 tiDetailOtherError,
19416 agNULL,
19417 satIOContext->interruptContext
19418 );
19419 #endif
19420
19421 return tiError;
19422 }
19423
19424 /* fill in fields */
19425 /* real ttttttthe one worked and the same; 5/21/07/ */
19426 satIntIo->satOrgTiIORequest = tiIORequest; /* changed */
19427 tdIORequestBody = satIntIo->satIntRequestBody;
19428 satNewIOContext = &(tdIORequestBody->transport.SATA.satIOContext);
19429
19430 satNewIOContext->pSatDevData = satDevData;
19431 satNewIOContext->pFis = &(tdIORequestBody->transport.SATA.agSATARequestBody.fis.fisRegHostToDev);
19432 satNewIOContext->pScsiCmnd = &(satIntIo->satIntTiScsiXchg.scsiCmnd);
19433 satNewIOContext->pSense = &(tdIORequestBody->transport.SATA.sensePayload);
19434 satNewIOContext->pTiSenseData = &(tdIORequestBody->transport.SATA.tiSenseData);
19435 satNewIOContext->tiRequestBody = satIntIo->satIntRequestBody; /* key fix */
19436 satNewIOContext->interruptContext = tiInterruptContext;
19437 satNewIOContext->satIntIoContext = satIntIo;
19438
19439 satNewIOContext->ptiDeviceHandle = agNULL;
19440 satNewIOContext->satOrgIOContext = satIOContext; /* changed */
19441
19442 /* this is valid only for TD layer generated (not triggered by OS at all) IO */
19443 satNewIOContext->tiScsiXchg = &(satIntIo->satIntTiScsiXchg);
19444
19445
19446 TI_DBG6(("satStartIDDev: OS satIOContext %p \n", satIOContext));
19447 TI_DBG6(("satStartIDDev: TD satNewIOContext %p \n", satNewIOContext));
19448 TI_DBG6(("satStartIDDev: OS tiScsiXchg %p \n", satIOContext->tiScsiXchg));
19449 TI_DBG6(("satStartIDDev: TD tiScsiXchg %p \n", satNewIOContext->tiScsiXchg));
19450
19451
19452
19453 TI_DBG1(("satStartIDDev: satNewIOContext %p tdIORequestBody %p\n", satNewIOContext, tdIORequestBody));
19454
19455 status = satSendIDDev( tiRoot,
19456 &satIntIo->satIntTiIORequest, /* New tiIORequest */
19457 tiDeviceHandle,
19458 satNewIOContext->tiScsiXchg, /* New tiScsiInitiatorRequest_t *tiScsiRequest, */
19459 satNewIOContext);
19460
19461 if (status != tiSuccess)
19462 {
19463 TI_DBG1(("satStartIDDev: failed in sending\n"));
19464
19465 satFreeIntIoResource( tiRoot,
19466 satDevData,
19467 satIntIo);
19468
19469 #if 0
19470 ostiInitiatorIOCompleted (
19471 tiRoot,
19472 tiIORequest,
19473 tiIOFailed,
19474 tiDetailOtherError,
19475 agNULL,
19476 satIOContext->interruptContext
19477 );
19478 #endif
19479
19480 return tiError;
19481 }
19482
19483
19484 TI_DBG6(("satStartIDDev: end\n"));
19485
19486 return status;
19487
19488
19489 }
19490
19491 /*****************************************************************************/
19492 /*! \brief satComputeCDB10LBA.
19493 *
19494 * This fuctions computes LBA of CDB10.
19495 *
19496 * \param satIOContext_t: Pointer to the SAT IO Context
19497 *
19498 * \return
19499 * - \e LBA
19500 */
19501 /*****************************************************************************/
19502 bit32 satComputeCDB10LBA(satIOContext_t *satIOContext)
19503 {
19504 tiIniScsiCmnd_t *scsiCmnd;
19505 tiScsiInitiatorRequest_t *tiScsiRequest;
19506 bit32 lba = 0;
19507
19508 TI_DBG5(("satComputeCDB10LBA: start\n"));
19509 tiScsiRequest = satIOContext->tiScsiXchg;
19510 scsiCmnd = &(tiScsiRequest->scsiCmnd);
19511
19512 lba = (scsiCmnd->cdb[2] << (8*3)) + (scsiCmnd->cdb[3] << (8*2))
19513 + (scsiCmnd->cdb[4] << 8) + scsiCmnd->cdb[5];
19514
19515 return lba;
19516 }
19517
19518 /*****************************************************************************/
19519 /*! \brief satComputeCDB10TL.
19520 *
19521 * This fuctions computes transfer length of CDB10.
19522 *
19523 * \param satIOContext_t: Pointer to the SAT IO Context
19524 *
19525 * \return
19526 * - \e TL
19527 */
19528 /*****************************************************************************/
19529 bit32 satComputeCDB10TL(satIOContext_t *satIOContext)
19530 {
19531
19532 tiIniScsiCmnd_t *scsiCmnd;
19533 tiScsiInitiatorRequest_t *tiScsiRequest;
19534 bit32 tl = 0;
19535
19536 TI_DBG5(("satComputeCDB10TL: start\n"));
19537 tiScsiRequest = satIOContext->tiScsiXchg;
19538 scsiCmnd = &(tiScsiRequest->scsiCmnd);
19539
19540 tl = (scsiCmnd->cdb[7] << 8) + scsiCmnd->cdb[8];
19541 return tl;
19542 }
19543
19544 /*****************************************************************************/
19545 /*! \brief satComputeCDB12LBA.
19546 *
19547 * This fuctions computes LBA of CDB12.
19548 *
19549 * \param satIOContext_t: Pointer to the SAT IO Context
19550 *
19551 * \return
19552 * - \e LBA
19553 */
19554 /*****************************************************************************/
19555 bit32 satComputeCDB12LBA(satIOContext_t *satIOContext)
19556 {
19557 tiIniScsiCmnd_t *scsiCmnd;
19558 tiScsiInitiatorRequest_t *tiScsiRequest;
19559 bit32 lba = 0;
19560
19561 TI_DBG5(("satComputeCDB10LBA: start\n"));
19562 tiScsiRequest = satIOContext->tiScsiXchg;
19563 scsiCmnd = &(tiScsiRequest->scsiCmnd);
19564
19565 lba = (scsiCmnd->cdb[2] << (8*3)) + (scsiCmnd->cdb[3] << (8*2))
19566 + (scsiCmnd->cdb[4] << 8) + scsiCmnd->cdb[5];
19567
19568 return lba;
19569 }
19570
19571 /*****************************************************************************/
19572 /*! \brief satComputeCDB12TL.
19573 *
19574 * This fuctions computes transfer length of CDB12.
19575 *
19576 * \param satIOContext_t: Pointer to the SAT IO Context
19577 *
19578 * \return
19579 * - \e TL
19580 */
19581 /*****************************************************************************/
19582 bit32 satComputeCDB12TL(satIOContext_t *satIOContext)
19583 {
19584
19585 tiIniScsiCmnd_t *scsiCmnd;
19586 tiScsiInitiatorRequest_t *tiScsiRequest;
19587 bit32 tl = 0;
19588
19589 TI_DBG5(("satComputeCDB10TL: start\n"));
19590 tiScsiRequest = satIOContext->tiScsiXchg;
19591 scsiCmnd = &(tiScsiRequest->scsiCmnd);
19592
19593 tl = (scsiCmnd->cdb[6] << (8*3)) + (scsiCmnd->cdb[7] << (8*2))
19594 + (scsiCmnd->cdb[8] << 8) + scsiCmnd->cdb[9];
19595 return tl;
19596 }
19597
19598
19599 /*****************************************************************************/
19600 /*! \brief satComputeCDB16LBA.
19601 *
19602 * This fuctions computes LBA of CDB16.
19603 *
19604 * \param satIOContext_t: Pointer to the SAT IO Context
19605 *
19606 * \return
19607 * - \e LBA
19608 */
19609 /*****************************************************************************/
19610 /*
19611 CBD16 has bit64 LBA
19612 But it has to be less than (2^28 - 1)
19613 Therefore, use last four bytes to compute LBA is OK
19614 */
19615 bit32 satComputeCDB16LBA(satIOContext_t *satIOContext)
19616 {
19617 tiIniScsiCmnd_t *scsiCmnd;
19618 tiScsiInitiatorRequest_t *tiScsiRequest;
19619 bit32 lba = 0;
19620
19621 TI_DBG5(("satComputeCDB10LBA: start\n"));
19622 tiScsiRequest = satIOContext->tiScsiXchg;
19623 scsiCmnd = &(tiScsiRequest->scsiCmnd);
19624
19625 lba = (scsiCmnd->cdb[6] << (8*3)) + (scsiCmnd->cdb[7] << (8*2))
19626 + (scsiCmnd->cdb[8] << 8) + scsiCmnd->cdb[9];
19627
19628 return lba;
19629 }
19630
19631 /*****************************************************************************/
19632 /*! \brief satComputeCDB16TL.
19633 *
19634 * This fuctions computes transfer length of CDB16.
19635 *
19636 * \param satIOContext_t: Pointer to the SAT IO Context
19637 *
19638 * \return
19639 * - \e TL
19640 */
19641 /*****************************************************************************/
19642 bit32 satComputeCDB16TL(satIOContext_t *satIOContext)
19643 {
19644
19645 tiIniScsiCmnd_t *scsiCmnd;
19646 tiScsiInitiatorRequest_t *tiScsiRequest;
19647 bit32 tl = 0;
19648
19649 TI_DBG5(("satComputeCDB10TL: start\n"));
19650 tiScsiRequest = satIOContext->tiScsiXchg;
19651 scsiCmnd = &(tiScsiRequest->scsiCmnd);
19652
19653 tl = (scsiCmnd->cdb[10] << (8*3)) + (scsiCmnd->cdb[11] << (8*2))
19654 + (scsiCmnd->cdb[12] << 8) + scsiCmnd->cdb[13];
19655 return tl;
19656 }
19657
19658 /*****************************************************************************/
19659 /*! \brief satComputeLoopNum.
19660 *
19661 * This fuctions computes the number of interation needed for a transfer
19662 * length with a specific number.
19663 *
19664 * \param a: a numerator
19665 * \param b: a denominator
19666 *
19667 * \return
19668 * - \e number of interation
19669 */
19670 /*****************************************************************************/
19671 /*
19672 (tl, denom)
19673 tl can be upto bit32 because CDB16 has bit32 tl
19674 Therefore, fine
19675 either (tl, 0xFF) or (tl, 0xFFFF)
19676 */
19677 bit32 satComputeLoopNum(bit32 a, bit32 b)
19678 {
19679
19680 bit32 quo = 0, rem = 0;
19681 bit32 LoopNum = 0;
19682
19683 TI_DBG5(("satComputeLoopNum: start\n"));
19684
19685 quo = a/b;
19686
19687 if (quo == 0)
19688 {
19689 LoopNum = 1;
19690 }
19691 else
19692 {
19693 rem = a % b;
19694 if (rem == 0)
19695 {
19696 LoopNum = quo;
19697 }
19698 else
19699 {
19700 LoopNum = quo + 1;
19701 }
19702 }
19703
19704 return LoopNum;
19705 }
19706
19707 /*****************************************************************************/
19708 /*! \brief satAddNComparebit64.
19709 *
19710 *
19711 *
19712 *
19713 * \param a: lba
19714 * \param b: tl
19715 *
19716 * \return
19717 * - \e TRUE if (lba + tl > SAT_TR_LBA_LIMIT)
19718 * - \e FALSE otherwise
19719 * \note: a and b must be in the same length
19720 */
19721 /*****************************************************************************/
19722 /*
19723 input: bit8 a[8], bit8 b[8] (lba, tl) must be in same length
19724 if (lba + tl > SAT_TR_LBA_LIMIT)
19725 then returns true
19726 else returns false
19727 (LBA,TL)
19728 */
19729 bit32 satAddNComparebit64(bit8 *a, bit8 *b)
19730 {
19731 bit16 ans[8]; // 0 MSB, 8 LSB
19732 bit8 final_ans[9]; // 0 MSB, 9 LSB
19733 bit8 max[9];
19734 int i;
19735
19736 TI_DBG5(("satAddNComparebit64: start\n"));
19737
19738 osti_memset(ans, 0, sizeof(ans));
19739 osti_memset(final_ans, 0, sizeof(final_ans));
19740 osti_memset(max, 0, sizeof(max));
19741
19742 max[0] = 0x1; //max = 0x1 0000 0000 0000 0000
19743
19744 // adding from LSB to MSB
19745 for(i=7;i>=0;i--)
19746 {
19747 ans[i] = (bit16)(a[i] + b[i]);
19748 if (i != 7)
19749 {
19750 ans[i] = (bit16)(ans[i] + ((ans[i+1] & 0xFF00) >> 8));
19751 }
19752 }
19753
19754 /*
19755 filling in the final answer
19756 */
19757 final_ans[0] = (bit8)(((ans[0] & 0xFF00) >> 8));
19758 final_ans[1] = (bit8)(ans[0] & 0xFF);
19759
19760 for(i=2;i<=8;i++)
19761 {
19762 final_ans[i] = (bit8)(ans[i-1] & 0xFF);
19763 }
19764
19765 //compare final_ans to max
19766 for(i=0;i<=8;i++)
19767 {
19768 if (final_ans[i] > max[i])
19769 {
19770 TI_DBG5(("satAddNComparebit64: yes at %d\n", i));
19771 return agTRUE;
19772 }
19773 else if (final_ans[i] < max[i])
19774 {
19775 TI_DBG5(("satAddNComparebit64: no at %d\n", i));
19776 return agFALSE;
19777 }
19778 else
19779 {
19780 continue;
19781 }
19782 }
19783
19784
19785 return agFALSE;
19786 }
19787
19788 /*****************************************************************************/
19789 /*! \brief satAddNComparebit32.
19790 *
19791 *
19792 *
19793 *
19794 * \param a: lba
19795 * \param b: tl
19796 *
19797 * \return
19798 * - \e TRUE if (lba + tl > SAT_TR_LBA_LIMIT)
19799 * - \e FALSE otherwise
19800 * \note: a and b must be in the same length
19801 */
19802 /*****************************************************************************/
19803 /*
19804 input: bit8 a[4], bit8 b[4] (lba, tl) must be in same length
19805 if (lba + tl > SAT_TR_LBA_LIMIT)
19806 then returns true
19807 else returns false
19808 (LBA,TL)
19809 */
19810 bit32 satAddNComparebit32(bit8 *a, bit8 *b)
19811 {
19812 bit16 ans[4]; // 0 MSB, 4 LSB
19813 bit8 final_ans[5]; // 0 MSB, 5 LSB
19814 bit8 max[4];
19815 int i;
19816
19817 TI_DBG5(("satAddNComparebit32: start\n"));
19818
19819 osti_memset(ans, 0, sizeof(ans));
19820 osti_memset(final_ans, 0, sizeof(final_ans));
19821 osti_memset(max, 0, sizeof(max));
19822
19823 max[0] = 0x10; // max =0x1000 0000
19824
19825 // adding from LSB to MSB
19826 for(i=3;i>=0;i--)
19827 {
19828 ans[i] = (bit16)(a[i] + b[i]);
19829 if (i != 3)
19830 {
19831 ans[i] = (bit16)(ans[i] + ((ans[i+1] & 0xFF00) >> 8));
19832 }
19833 }
19834
19835
19836 /*
19837 filling in the final answer
19838 */
19839 final_ans[0] = (bit8)(((ans[0] & 0xFF00) >> 8));
19840 final_ans[1] = (bit8)(ans[0] & 0xFF);
19841
19842 for(i=2;i<=4;i++)
19843 {
19844 final_ans[i] = (bit8)(ans[i-1] & 0xFF);
19845 }
19846
19847 //compare final_ans to max
19848 if (final_ans[0] != 0)
19849 {
19850 TI_DBG5(("satAddNComparebit32: yes bigger and out of range\n"));
19851 return agTRUE;
19852 }
19853 for(i=1;i<=4;i++)
19854 {
19855 if (final_ans[i] > max[i-1])
19856 {
19857 TI_DBG5(("satAddNComparebit32: yes at %d\n", i));
19858 return agTRUE;
19859 }
19860 else if (final_ans[i] < max[i-1])
19861 {
19862 TI_DBG5(("satAddNComparebit32: no at %d\n", i));
19863 return agFALSE;
19864 }
19865 else
19866 {
19867 continue;
19868 }
19869 }
19870
19871
19872 return agFALSE;
19873 }
19874
19875 /*****************************************************************************/
19876 /*! \brief satCompareLBALimitbit.
19877 *
19878 *
19879 *
19880 *
19881 * \param lba: lba
19882 *
19883 * \return
19884 * - \e TRUE if (lba > SAT_TR_LBA_LIMIT - 1)
19885 * - \e FALSE otherwise
19886 * \note: a and b must be in the same length
19887 */
19888 /*****************************************************************************/
19889
19890 /*
19891 lba
19892 */
19893 /*
19894 input: bit8 lba[8]
19895 if (lba > SAT_TR_LBA_LIMIT - 1)
19896 then returns true
19897 else returns false
19898 (LBA,TL)
19899 */
19900 bit32 satCompareLBALimitbit(bit8 *lba)
19901 {
19902 bit32 i;
19903 bit8 limit[8];
19904
19905 /* limit is 0xF FF FF = 2^28 - 1 */
19906 limit[0] = 0x0; /* MSB */
19907 limit[1] = 0x0;
19908 limit[2] = 0x0;
19909 limit[3] = 0x0;
19910 limit[4] = 0xF;
19911 limit[5] = 0xFF;
19912 limit[6] = 0xFF;
19913 limit[7] = 0xFF; /* LSB */
19914
19915 //compare lba to limit
19916 for(i=0;i<8;i++)
19917 {
19918 if (lba[i] > limit[i])
19919 {
19920 TI_DBG5(("satCompareLBALimitbit64: yes at %d\n", i));
19921 return agTRUE;
19922 }
19923 else if (lba[i] < limit[i])
19924 {
19925 TI_DBG5(("satCompareLBALimitbit64: no at %d\n", i));
19926 return agFALSE;
19927 }
19928 else
19929 {
19930 continue;
19931 }
19932 }
19933
19934
19935 return agFALSE;
19936
19937 }
19938 /*****************************************************************************
19939 *! \brief
19940 * Purpose: bitwise set
19941 *
19942 * Parameters:
19943 * data - input output buffer
19944 * index - bit to set
19945 *
19946 * Return:
19947 * none
19948 *
19949 *****************************************************************************/
19950 GLOBAL void
19951 satBitSet(bit8 *data, bit32 index)
19952 {
19953 data[index/8] |= (1 << (index%8));
19954 }
19955
19956 /*****************************************************************************
19957 *! \brief
19958 * Purpose: bitwise clear
19959 *
19960 * Parameters:
19961 * data - input output buffer
19962 * index - bit to clear
19963 *
19964 * Return:
19965 * none
19966 *
19967 *****************************************************************************/
19968 GLOBAL void
19969 satBitClear(bit8 *data, bit32 index)
19970 {
19971 data[index/8] &= ~(1 << (index%8));
19972 }
19973
19974 /*****************************************************************************
19975 *! \brief
19976 * Purpose: bitwise test
19977 *
19978 * Parameters:
19979 * data - input output buffer
19980 * index - bit to test
19981 *
19982 * Return:
19983 * 0 - not set
19984 * 1 - set
19985 *
19986 *****************************************************************************/
19987 GLOBAL agBOOLEAN
19988 satBitTest(bit8 *data, bit32 index)
19989 {
19990 return ( (BOOLEAN)((data[index/8] & (1 << (index%8)) ) ? 1: 0));
19991 }
19992
19993
19994 /******************************************************************************/
19995 /*! \brief allocate an available SATA tag
19996 *
19997 * allocate an available SATA tag
19998 *
19999 * \param tiRoot Pointer to TISA initiator driver/port instance.
20000 * \param pSatDevData
20001 * \param pTag
20002 *
20003 * \return -Success or fail-
20004 */
20005 /*******************************************************************************/
20006 GLOBAL bit32 satTagAlloc(
20007 tiRoot_t *tiRoot,
20008 satDeviceData_t *pSatDevData,
20009 bit8 *pTag
20010 )
20011 {
20012 bit32 retCode = agFALSE;
20013 bit32 i;
20014
20015 tdsaSingleThreadedEnter(tiRoot, TD_SATA_LOCK);
20016 for ( i = 0; i < pSatDevData->satNCQMaxIO; i ++ )
20017 {
20018 if ( 0 == satBitTest((bit8 *)&pSatDevData->freeSATAFDMATagBitmap, i) )
20019 {
20020 satBitSet((bit8*)&pSatDevData->freeSATAFDMATagBitmap, i);
20021 *pTag = (bit8) i;
20022 retCode = agTRUE;
20023 break;
20024 }
20025 }
20026 tdsaSingleThreadedLeave(tiRoot, TD_SATA_LOCK);
20027 return retCode;
20028 }
20029
20030 /******************************************************************************/
20031 /*! \brief release an SATA tag
20032 *
20033 * release an available SATA tag
20034 *
20035 * \param tiRoot Pointer to TISA initiator driver/port instance.
20036 * \param pSatDevData
20037 * \param Tag
20038 *
20039 * \return -the tag-
20040 */
20041 /*******************************************************************************/
20042 GLOBAL bit32 satTagRelease(
20043 tiRoot_t *tiRoot,
20044 satDeviceData_t *pSatDevData,
20045 bit8 tag
20046 )
20047 {
20048 bit32 retCode = agFALSE;
20049
20050 tdsaSingleThreadedEnter(tiRoot, TD_SATA_LOCK);
20051 if ( tag < pSatDevData->satNCQMaxIO )
20052 {
20053 satBitClear( (bit8 *)&pSatDevData->freeSATAFDMATagBitmap, (bit32)tag);
20054 retCode = agTRUE;
20055 }
20056 tdsaSingleThreadedLeave(tiRoot, TD_SATA_LOCK);
20057 return retCode;
20058 }
20059
20060 /*****************************************************************************
20061 *! \brief satSubTM
20062 *
20063 * This routine is called to initiate a TM request to SATL.
20064 * This routine is independent of HW/LL API.
20065 *
20066 * \param tiRoot: Pointer to TISA initiator driver/port instance.
20067 * \param tiDeviceHandle: Pointer to TISA device handle for this I/O.
20068 * \param task: SAM-3 task management request.
20069 * \param lun: Pointer to LUN.
20070 * \param taskTag: Pointer to the associated task where the TM
20071 * command is to be applied.
20072 * \param currentTaskTag: Pointer to tag/context for this TM request.
20073 * \param NotifyOS flag determines whether notify OS layer or not
20074 *
20075 * \return:
20076 *
20077 * \e tiSuccess: I/O request successfully initiated.
20078 * \e tiBusy: No resources available, try again later.
20079 * \e tiIONoDevice: Invalid device handle.
20080 * \e tiError: Other errors that prevent the I/O request to be started.
20081 *
20082 * \note:
20083 * This funcion is triggered bottom up. Not yet in use.
20084 *****************************************************************************/
20085 /* called for bottom up */
20086 osGLOBAL bit32 satSubTM(
20087 tiRoot_t *tiRoot,
20088 tiDeviceHandle_t *tiDeviceHandle,
20089 bit32 task,
20090 tiLUN_t *lun,
20091 tiIORequest_t *taskTag,
20092 tiIORequest_t *currentTaskTag,
20093 bit32 NotifyOS
20094 )
20095 {
20096 void *osMemHandle;
20097 tdIORequestBody_t *TMtdIORequestBody;
20098 bit32 PhysUpper32;
20099 bit32 PhysLower32;
20100 bit32 memAllocStatus;
20101 agsaIORequest_t *agIORequest = agNULL;
20102
20103 TI_DBG6(("satSubTM: start\n"));
20104
20105 /* allocation tdIORequestBody and pass it to satTM() */
20106 memAllocStatus = ostiAllocMemory(
20107 tiRoot,
20108 &osMemHandle,
20109 (void **)&TMtdIORequestBody,
20110 &PhysUpper32,
20111 &PhysLower32,
20112 8,
20113 sizeof(tdIORequestBody_t),
20114 agTRUE
20115 );
20116
20117 if (memAllocStatus != tiSuccess)
20118 {
20119 TI_DBG1(("satSubTM: ostiAllocMemory failed... \n"));
20120 return tiError;
20121 }
20122
20123 if (TMtdIORequestBody == agNULL)
20124 {
20125 TI_DBG1(("satSubTM: ostiAllocMemory returned NULL TMIORequestBody\n"));
20126 return tiError;
20127 }
20128
20129 /* setup task management structure */
20130 TMtdIORequestBody->IOType.InitiatorTMIO.osMemHandle = osMemHandle;
20131 TMtdIORequestBody->IOType.InitiatorTMIO.CurrentTaskTag = agNULL;
20132 TMtdIORequestBody->IOType.InitiatorTMIO.TaskTag = agNULL;
20133
20134 /* initialize tiDevhandle */
20135 TMtdIORequestBody->tiDevHandle = tiDeviceHandle;
20136
20137 /* initialize tiIORequest */
20138 TMtdIORequestBody->tiIORequest = agNULL;
20139
20140 /* initialize agIORequest */
20141 agIORequest = &(TMtdIORequestBody->agIORequest);
20142 agIORequest->osData = (void *) TMtdIORequestBody;
20143 agIORequest->sdkData = agNULL; /* SA takes care of this */
20144 satTM(tiRoot,
20145 tiDeviceHandle,
20146 task, /* TD_INTERNAL_TM_RESET */
20147 agNULL,
20148 agNULL,
20149 agNULL,
20150 TMtdIORequestBody,
20151 agFALSE);
20152
20153 return tiSuccess;
20154 }
20155
20156
20157 /*****************************************************************************/
20158 /*! \brief SAT implementation for satStartResetDevice.
20159 *
20160 * SAT implementation for sending SRT and send FIS request to LL layer.
20161 *
20162 * \param tiRoot: Pointer to TISA initiator driver/port instance.
20163 * \param tiIORequest: Pointer to TISA I/O request context for this I/O.
20164 * \param tiDeviceHandle: Pointer to TISA device handle for this I/O.
20165 * \param tiScsiRequest: Pointer to TISA SCSI I/O request and SGL list.
20166 * \param satIOContext_t: Pointer to the SAT IO Context
20167 *
20168 * \return If command is started successfully
20169 * - \e tiSuccess: I/O request successfully initiated.
20170 * - \e tiBusy: No resources available, try again later.
20171 * - \e tiIONoDevice: Invalid device handle.
20172 * - \e tiError: Other errors.
20173 * \note : triggerred by OS layer or bottom up
20174 */
20175 /*****************************************************************************/
20176 /* OS triggerred or bottom up */
20177 GLOBAL bit32
20178 satStartResetDevice(
20179 tiRoot_t *tiRoot,
20180 tiIORequest_t *tiIORequest, /* currentTaskTag */
20181 tiDeviceHandle_t *tiDeviceHandle,
20182 tiScsiInitiatorRequest_t *tiScsiRequest, /* should be NULL */
20183 satIOContext_t *satIOContext
20184 )
20185 {
20186 satInternalIo_t *satIntIo = agNULL;
20187 satDeviceData_t *satDevData = agNULL;
20188 satIOContext_t *satNewIOContext;
20189 bit32 status;
20190 tiIORequest_t *currentTaskTag = agNULL;
20191
20192 TI_DBG1(("satStartResetDevice: start\n"));
20193
20194 currentTaskTag = tiIORequest;
20195
20196 satDevData = satIOContext->pSatDevData;
20197
20198 TI_DBG6(("satStartResetDevice: before alloc\n"));
20199
20200 /* allocate any fis for seting SRT bit in device control */
20201 satIntIo = satAllocIntIoResource( tiRoot,
20202 tiIORequest,
20203 satDevData,
20204 0,
20205 satIntIo);
20206
20207 TI_DBG6(("satStartResetDevice: before after\n"));
20208
20209 if (satIntIo == agNULL)
20210 {
20211 TI_DBG1(("satStartResetDevice: can't alloacate\n"));
20212 if (satIOContext->NotifyOS)
20213 {
20214 ostiInitiatorEvent( tiRoot,
20215 NULL,
20216 NULL,
20217 tiIntrEventTypeTaskManagement,
20218 tiTMFailed,
20219 currentTaskTag );
20220 }
20221 return tiError;
20222 }
20223
20224 satNewIOContext = satPrepareNewIO(satIntIo,
20225 tiIORequest,
20226 satDevData,
20227 agNULL,
20228 satIOContext);
20229
20230 TI_DBG6(("satStartResetDevice: OS satIOContext %p \n", satIOContext));
20231 TI_DBG6(("satStartResetDevice: TD satNewIOContext %p \n", satNewIOContext));
20232 TI_DBG6(("satStartResetDevice: OS tiScsiXchg %p \n", satIOContext->tiScsiXchg));
20233 TI_DBG6(("satStartResetDevice: TD tiScsiXchg %p \n", satNewIOContext->tiScsiXchg));
20234
20235
20236
20237 TI_DBG6(("satStartResetDevice: satNewIOContext %p \n", satNewIOContext));
20238
20239 if (satDevData->satDeviceType == SATA_ATAPI_DEVICE)
20240 {
20241 status = satDeviceReset(tiRoot,
20242 &satIntIo->satIntTiIORequest, /* New tiIORequest */
20243 tiDeviceHandle,
20244 satNewIOContext->tiScsiXchg, /* New tiScsiInitiatorRequest_t *tiScsiRequest, */
20245 satNewIOContext);
20246 }
20247 else
20248 {
20249 status = satResetDevice(tiRoot,
20250 &satIntIo->satIntTiIORequest, /* New tiIORequest */
20251 tiDeviceHandle,
20252 satNewIOContext->tiScsiXchg, /* New tiScsiInitiatorRequest_t *tiScsiRequest, */
20253 satNewIOContext);
20254 }
20255
20256 if (status != tiSuccess)
20257 {
20258 TI_DBG1(("satStartResetDevice: failed in sending\n"));
20259
20260 satFreeIntIoResource( tiRoot,
20261 satDevData,
20262 satIntIo);
20263 if (satIOContext->NotifyOS)
20264 {
20265 ostiInitiatorEvent( tiRoot,
20266 NULL,
20267 NULL,
20268 tiIntrEventTypeTaskManagement,
20269 tiTMFailed,
20270 currentTaskTag );
20271 }
20272
20273 return tiError;
20274 }
20275
20276
20277 TI_DBG6(("satStartResetDevice: end\n"));
20278
20279 return status;
20280 }
20281
20282 /*****************************************************************************/
20283 /*! \brief SAT implementation for satResetDevice.
20284 *
20285 * SAT implementation for building SRT FIS and sends the request to LL layer.
20286 *
20287 * \param tiRoot: Pointer to TISA initiator driver/port instance.
20288 * \param tiIORequest: Pointer to TISA I/O request context for this I/O.
20289 * \param tiDeviceHandle: Pointer to TISA device handle for this I/O.
20290 * \param tiScsiRequest: Pointer to TISA SCSI I/O request and SGL list.
20291 * \param satIOContext_t: Pointer to the SAT IO Context
20292 *
20293 * \return If command is started successfully
20294 * - \e tiSuccess: I/O request successfully initiated.
20295 * - \e tiBusy: No resources available, try again later.
20296 * - \e tiIONoDevice: Invalid device handle.
20297 * - \e tiError: Other errors.
20298 */
20299 /*****************************************************************************/
20300
20301 /*
20302 create any fis and set SRST bit in device control
20303 */
20304 GLOBAL bit32
20305 satResetDevice(
20306 tiRoot_t *tiRoot,
20307 tiIORequest_t *tiIORequest,
20308 tiDeviceHandle_t *tiDeviceHandle,
20309 tiScsiInitiatorRequest_t *tiScsiRequest,
20310 satIOContext_t *satIOContext
20311 )
20312 {
20313 bit32 status;
20314 bit32 agRequestType;
20315 agsaFisRegHostToDevice_t *fis;
20316 #ifdef TD_DEBUG_ENABLE
20317 tdIORequestBody_t *tdIORequestBody;
20318 satInternalIo_t *satIntIoContext;
20319 #endif
20320
20321 fis = satIOContext->pFis;
20322
20323 TI_DBG2(("satResetDevice: start\n"));
20324
20325 #ifdef TD_DEBUG_ENABLE
20326 satIntIoContext = satIOContext->satIntIoContext;
20327 tdIORequestBody = satIntIoContext->satIntRequestBody;
20328 #endif
20329 TI_DBG5(("satResetDevice: satIOContext %p tdIORequestBody %p\n", satIOContext, tdIORequestBody));
20330 /* any fis should work */
20331 fis->h.fisType = 0x27; /* Reg host to device */
20332 fis->h.c_pmPort = 0; /* C Bit is not set */
20333 fis->h.command = 0; /* any command */
20334 fis->h.features = 0; /* FIS reserve */
20335 fis->d.lbaLow = 0; /* FIS LBA (7 :0 ) */
20336 fis->d.lbaMid = 0; /* FIS LBA (15:8 ) */
20337 fis->d.lbaHigh = 0; /* FIS LBA (23:16) */
20338 fis->d.device = 0; /* FIS LBA mode */
20339 fis->d.lbaLowExp = 0;
20340 fis->d.lbaMidExp = 0;
20341 fis->d.lbaHighExp = 0;
20342 fis->d.featuresExp = 0;
20343 fis->d.sectorCount = 0; /* FIS sector count (7:0) */
20344 fis->d.sectorCountExp = 0;
20345 fis->d.reserved4 = 0;
20346 fis->d.control = 0x4; /* SRST bit is set */
20347 fis->d.reserved5 = 0;
20348
20349 agRequestType = AGSA_SATA_PROTOCOL_SRST_ASSERT;
20350
20351 satIOContext->satCompleteCB = &satResetDeviceCB;
20352
20353 /*
20354 * Prepare SGL and send FIS to LL layer.
20355 */
20356 satIOContext->reqType = agRequestType; /* Save it */
20357
20358 #ifdef TD_INTERNAL_DEBUG
20359 tdhexdump("satResetDevice", (bit8 *)satIOContext->pFis, sizeof(agsaFisRegHostToDevice_t));
20360 #ifdef TD_DEBUG_ENABLE
20361 tdhexdump("satResetDevice LL", (bit8 *)&(tdIORequestBody->transport.SATA.agSATARequestBody.fis.fisRegHostToDev), sizeof(agsaFisRegHostToDevice_t));
20362 #endif
20363 #endif
20364
20365 status = sataLLIOStart( tiRoot,
20366 tiIORequest,
20367 tiDeviceHandle,
20368 tiScsiRequest,
20369 satIOContext);
20370
20371 TI_DBG6(("satResetDevice: end status %d\n", status));
20372 return status;
20373 }
20374
20375 /*****************************************************************************
20376 *! \brief satResetDeviceCB
20377 *
20378 * This routine is a callback function called from ossaSATACompleted().
20379 * This CB routine deals with SRT completion. This function send DSRT
20380 *
20381 * \param agRoot: Handles for this instance of SAS/SATA hardware
20382 * \param agIORequest: Pointer to the LL I/O request context for this I/O.
20383 * \param agIOStatus: Status of completed I/O.
20384 * \param agFirstDword:Pointer to the four bytes of FIS.
20385 * \param agIOInfoLen: Length in bytes of overrun/underrun residual or FIS
20386 * length.
20387 * \param agParam: Additional info based on status.
20388 * \param ioContext: Pointer to satIOContext_t.
20389 *
20390 * \return: none
20391 *
20392 *****************************************************************************/
20393 GLOBAL void satResetDeviceCB(
20394 agsaRoot_t *agRoot,
20395 agsaIORequest_t *agIORequest,
20396 bit32 agIOStatus,
20397 agsaFisHeader_t *agFirstDword,
20398 bit32 agIOInfoLen,
20399 agsaFrameHandle_t agFrameHandle,
20400 void *ioContext
20401 )
20402 {
20403 /* callback for satResetDevice */
20404 tdsaRootOsData_t *osData = (tdsaRootOsData_t *)agRoot->osData;
20405 tiRoot_t *tiRoot = (tiRoot_t *)osData->tiRoot;
20406 tdsaRoot_t *tdsaRoot = (tdsaRoot_t *) tiRoot->tdData;
20407 tdsaContext_t *tdsaAllShared = (tdsaContext_t *)&tdsaRoot->tdsaAllShared;
20408 tdIORequestBody_t *tdIORequestBody;
20409 tdIORequestBody_t *tdOrgIORequestBody;
20410 satIOContext_t *satIOContext;
20411 satIOContext_t *satOrgIOContext;
20412 satIOContext_t *satNewIOContext;
20413 satInternalIo_t *satIntIo;
20414 satInternalIo_t *satNewIntIo = agNULL;
20415 satDeviceData_t *satDevData;
20416 tiIORequest_t *tiOrgIORequest;
20417 #ifdef TD_DEBUG_ENABLE
20418 bit32 ataStatus = 0;
20419 bit32 ataError;
20420 agsaFisPioSetupHeader_t *satPIOSetupHeader = agNULL;
20421 #endif
20422 bit32 status;
20423
20424 TI_DBG1(("satResetDeviceCB: start\n"));
20425 TI_DBG6(("satResetDeviceCB: agIORequest=%p agIOStatus=0x%x agIOInfoLen %d\n", agIORequest, agIOStatus, agIOInfoLen));
20426
20427 tdIORequestBody = (tdIORequestBody_t *)agIORequest->osData;
20428 satIOContext = (satIOContext_t *) ioContext;
20429 satIntIo = satIOContext->satIntIoContext;
20430 satDevData = satIOContext->pSatDevData;
20431 if (satIntIo == agNULL)
20432 {
20433 TI_DBG6(("satResetDeviceCB: External, OS generated\n"));
20434 satOrgIOContext = satIOContext;
20435 tiOrgIORequest = tdIORequestBody->tiIORequest;
20436 }
20437 else
20438 {
20439 TI_DBG6(("satResetDeviceCB: Internal, TD generated\n"));
20440 satOrgIOContext = satIOContext->satOrgIOContext;
20441 if (satOrgIOContext == agNULL)
20442 {
20443 TI_DBG6(("satResetDeviceCB: satOrgIOContext is NULL, wrong\n"));
20444 return;
20445 }
20446 else
20447 {
20448 TI_DBG6(("satResetDeviceCB: satOrgIOContext is NOT NULL\n"));
20449 }
20450 tdOrgIORequestBody = (tdIORequestBody_t *)satOrgIOContext->tiRequestBody;
20451 tiOrgIORequest = (tiIORequest_t *)tdOrgIORequestBody->tiIORequest;
20452 }
20453
20454 tdIORequestBody->ioCompleted = agTRUE;
20455 tdIORequestBody->ioStarted = agFALSE;
20456
20457 if (agFirstDword == agNULL && agIOStatus != OSSA_IO_SUCCESS)
20458 {
20459 TI_DBG1(("satResetDeviceCB: wrong. agFirstDword is NULL when error, status %d\n", agIOStatus));
20460 if (satOrgIOContext->NotifyOS == agTRUE)
20461 {
20462 ostiInitiatorEvent( tiRoot,
20463 NULL,
20464 NULL,
20465 tiIntrEventTypeTaskManagement,
20466 tiTMFailed,
20467 tiOrgIORequest );
20468 }
20469
20470 satDevData->satTmTaskTag = agNULL;
20471
20472 satDecrementPendingIO(tiRoot, tdsaAllShared, satIOContext);
20473
20474 satFreeIntIoResource( tiRoot,
20475 satDevData,
20476 satIntIo);
20477 return;
20478 }
20479
20480 if (agIOStatus == OSSA_IO_OPEN_CNX_ERROR_PROTOCOL_NOT_SUPPORTED ||
20481 agIOStatus == OSSA_IO_OPEN_CNX_ERROR_ZONE_VIOLATION ||
20482 agIOStatus == OSSA_IO_OPEN_CNX_ERROR_BREAK ||
20483 agIOStatus == OSSA_IO_OPEN_CNX_ERROR_IT_NEXUS_LOSS ||
20484 agIOStatus == OSSA_IO_OPEN_CNX_ERROR_BAD_DESTINATION ||
20485 agIOStatus == OSSA_IO_OPEN_CNX_ERROR_CONNECTION_RATE_NOT_SUPPORTED ||
20486 agIOStatus == OSSA_IO_OPEN_CNX_ERROR_WRONG_DESTINATION ||
20487 agIOStatus == OSSA_IO_OPEN_CNX_ERROR_UNKNOWN_ERROR ||
20488 agIOStatus == OSSA_IO_OPEN_CNX_ERROR_STP_RESOURCES_BUSY
20489 )
20490 {
20491 TI_DBG1(("satResetDeviceCB: OSSA_IO_OPEN_CNX_ERROR\n"));
20492
20493 if (satOrgIOContext->NotifyOS == agTRUE)
20494 {
20495 ostiInitiatorEvent( tiRoot,
20496 NULL,
20497 NULL,
20498 tiIntrEventTypeTaskManagement,
20499 tiTMFailed,
20500 tiOrgIORequest );
20501 }
20502
20503 satDevData->satTmTaskTag = agNULL;
20504
20505 satDecrementPendingIO(tiRoot, tdsaAllShared, satIOContext);
20506
20507 satFreeIntIoResource( tiRoot,
20508 satDevData,
20509 satIntIo);
20510 return;
20511 }
20512
20513 if (agIOStatus != OSSA_IO_SUCCESS)
20514 {
20515 #ifdef TD_DEBUG_ENABLE
20516 /* only agsaFisPioSetup_t is expected */
20517 satPIOSetupHeader = (agsaFisPioSetupHeader_t *)&(agFirstDword->PioSetup);
20518 ataStatus = satPIOSetupHeader->status; /* ATA Status register */
20519 ataError = satPIOSetupHeader->error; /* ATA Eror register */
20520 #endif
20521 TI_DBG1(("satResetDeviceCB: ataStatus 0x%x ataError 0x%x\n", ataStatus, ataError));
20522
20523 if (satOrgIOContext->NotifyOS == agTRUE)
20524 {
20525 ostiInitiatorEvent( tiRoot,
20526 NULL,
20527 NULL,
20528 tiIntrEventTypeTaskManagement,
20529 tiTMFailed,
20530 tiOrgIORequest );
20531 }
20532
20533 satDevData->satTmTaskTag = agNULL;
20534
20535 satDecrementPendingIO(tiRoot, tdsaAllShared, satIOContext);
20536
20537 satFreeIntIoResource( tiRoot,
20538 satDevData,
20539 satIntIo);
20540 return;
20541 }
20542
20543 /* success */
20544
20545 satNewIntIo = satAllocIntIoResource( tiRoot,
20546 tiOrgIORequest,
20547 satDevData,
20548 0,
20549 satNewIntIo);
20550 if (satNewIntIo == agNULL)
20551 {
20552 satDevData->satTmTaskTag = agNULL;
20553
20554 satDecrementPendingIO(tiRoot, tdsaAllShared, satIOContext);
20555
20556 /* memory allocation failure */
20557 satFreeIntIoResource( tiRoot,
20558 satDevData,
20559 satNewIntIo);
20560
20561 if (satOrgIOContext->NotifyOS == agTRUE)
20562 {
20563 ostiInitiatorEvent( tiRoot,
20564 NULL,
20565 NULL,
20566 tiIntrEventTypeTaskManagement,
20567 tiTMFailed,
20568 tiOrgIORequest );
20569 }
20570
20571
20572 TI_DBG1(("satResetDeviceCB: momory allocation fails\n"));
20573 return;
20574 } /* end of memory allocation failure */
20575
20576 /*
20577 * Need to initialize all the fields within satIOContext
20578 */
20579
20580 satNewIOContext = satPrepareNewIO(
20581 satNewIntIo,
20582 tiOrgIORequest,
20583 satDevData,
20584 agNULL,
20585 satOrgIOContext
20586 );
20587
20588
20589
20590
20591 /* send AGSA_SATA_PROTOCOL_SRST_DEASSERT */
20592 status = satDeResetDevice(tiRoot,
20593 tiOrgIORequest,
20594 satOrgIOContext->ptiDeviceHandle,
20595 agNULL,
20596 satNewIOContext
20597 );
20598
20599 if (status != tiSuccess)
20600 {
20601 if (satOrgIOContext->NotifyOS == agTRUE)
20602 {
20603 ostiInitiatorEvent( tiRoot,
20604 NULL,
20605 NULL,
20606 tiIntrEventTypeTaskManagement,
20607 tiTMFailed,
20608 tiOrgIORequest );
20609 }
20610
20611 /* sending AGSA_SATA_PROTOCOL_SRST_DEASSERT fails */
20612
20613 satDevData->satTmTaskTag = agNULL;
20614
20615 satDecrementPendingIO(tiRoot, tdsaAllShared, satIOContext);
20616
20617 satFreeIntIoResource( tiRoot,
20618 satDevData,
20619 satNewIntIo);
20620 return;
20621
20622 }
20623
20624 satDevData->satTmTaskTag = agNULL;
20625
20626 satDecrementPendingIO(tiRoot, tdsaAllShared, satIOContext);
20627
20628 satFreeIntIoResource( tiRoot,
20629 satDevData,
20630 satIntIo);
20631 TI_DBG5(("satResetDeviceCB: device %p pending IO %d\n", satDevData, satDevData->satPendingIO));
20632 TI_DBG6(("satResetDeviceCB: end\n"));
20633 return;
20634
20635 }
20636
20637
20638 /*****************************************************************************/
20639 /*! \brief SAT implementation for satDeResetDevice.
20640 *
20641 * SAT implementation for building DSRT FIS and sends the request to LL layer.
20642 *
20643 * \param tiRoot: Pointer to TISA initiator driver/port instance.
20644 * \param tiIORequest: Pointer to TISA I/O request context for this I/O.
20645 * \param tiDeviceHandle: Pointer to TISA device handle for this I/O.
20646 * \param tiScsiRequest: Pointer to TISA SCSI I/O request and SGL list.
20647 * \param satIOContext_t: Pointer to the SAT IO Context
20648 *
20649 * \return If command is started successfully
20650 * - \e tiSuccess: I/O request successfully initiated.
20651 * - \e tiBusy: No resources available, try again later.
20652 * - \e tiIONoDevice: Invalid device handle.
20653 * - \e tiError: Other errors.
20654 */
20655 /*****************************************************************************/
20656 GLOBAL bit32 satDeResetDevice(
20657 tiRoot_t *tiRoot,
20658 tiIORequest_t *tiIORequest,
20659 tiDeviceHandle_t *tiDeviceHandle,
20660 tiScsiInitiatorRequest_t *tiScsiRequest,
20661 satIOContext_t *satIOContext
20662 )
20663 {
20664 bit32 status;
20665 bit32 agRequestType;
20666 agsaFisRegHostToDevice_t *fis;
20667 #ifdef TD_DEBUG_ENABLE
20668 tdIORequestBody_t *tdIORequestBody;
20669 satInternalIo_t *satIntIoContext;
20670 #endif
20671 fis = satIOContext->pFis;
20672
20673 TI_DBG6(("satDeResetDevice: start\n"));
20674
20675 #ifdef TD_DEBUG_ENABLE
20676 satIntIoContext = satIOContext->satIntIoContext;
20677 tdIORequestBody = satIntIoContext->satIntRequestBody;
20678 TI_DBG5(("satDeResetDevice: satIOContext %p tdIORequestBody %p\n", satIOContext, tdIORequestBody));
20679 #endif
20680 /* any fis should work */
20681 fis->h.fisType = 0x27; /* Reg host to device */
20682 fis->h.c_pmPort = 0; /* C Bit is not set */
20683 fis->h.command = 0; /* any command */
20684 fis->h.features = 0; /* FIS reserve */
20685 fis->d.lbaLow = 0; /* FIS LBA (7 :0 ) */
20686 fis->d.lbaMid = 0; /* FIS LBA (15:8 ) */
20687 fis->d.lbaHigh = 0; /* FIS LBA (23:16) */
20688 fis->d.device = 0; /* FIS LBA mode */
20689 fis->d.lbaLowExp = 0;
20690 fis->d.lbaMidExp = 0;
20691 fis->d.lbaHighExp = 0;
20692 fis->d.featuresExp = 0;
20693 fis->d.sectorCount = 0; /* FIS sector count (7:0) */
20694 fis->d.sectorCountExp = 0;
20695 fis->d.reserved4 = 0;
20696 fis->d.control = 0; /* SRST bit is not set */
20697 fis->d.reserved5 = 0;
20698
20699 agRequestType = AGSA_SATA_PROTOCOL_SRST_DEASSERT;
20700
20701 satIOContext->satCompleteCB = &satDeResetDeviceCB;
20702
20703 /*
20704 * Prepare SGL and send FIS to LL layer.
20705 */
20706 satIOContext->reqType = agRequestType; /* Save it */
20707
20708 #ifdef TD_INTERNAL_DEBUG
20709 tdhexdump("satDeResetDevice", (bit8 *)satIOContext->pFis, sizeof(agsaFisRegHostToDevice_t));
20710 #ifdef TD_DEBUG_ENABLE
20711 tdhexdump("satDeResetDevice LL", (bit8 *)&(tdIORequestBody->transport.SATA.agSATARequestBody.fis.fisRegHostToDev), sizeof(agsaFisRegHostToDevice_t));
20712 #endif
20713 #endif
20714
20715 status = sataLLIOStart( tiRoot,
20716 tiIORequest,
20717 tiDeviceHandle,
20718 tiScsiRequest,
20719 satIOContext);
20720
20721 TI_DBG6(("satDeResetDevice: end status %d\n", status));
20722 return status;
20723
20724 }
20725
20726 /*****************************************************************************
20727 *! \brief satDeResetDeviceCB
20728 *
20729 * This routine is a callback function called from ossaSATACompleted().
20730 * This CB routine deals with DSRT completion.
20731 *
20732 * \param agRoot: Handles for this instance of SAS/SATA hardware
20733 * \param agIORequest: Pointer to the LL I/O request context for this I/O.
20734 * \param agIOStatus: Status of completed I/O.
20735 * \param agFirstDword:Pointer to the four bytes of FIS.
20736 * \param agIOInfoLen: Length in bytes of overrun/underrun residual or FIS
20737 * length.
20738 * \param agParam: Additional info based on status.
20739 * \param ioContext: Pointer to satIOContext_t.
20740 *
20741 * \return: none
20742 *
20743 *****************************************************************************/
20744 GLOBAL void satDeResetDeviceCB(
20745 agsaRoot_t *agRoot,
20746 agsaIORequest_t *agIORequest,
20747 bit32 agIOStatus,
20748 agsaFisHeader_t *agFirstDword,
20749 bit32 agIOInfoLen,
20750 agsaFrameHandle_t agFrameHandle,
20751 void *ioContext
20752 )
20753 {
20754 /* callback for satDeResetDevice */
20755 tdsaRootOsData_t *osData = (tdsaRootOsData_t *)agRoot->osData;
20756 tiRoot_t *tiRoot = (tiRoot_t *)osData->tiRoot;
20757 tdsaRoot_t *tdsaRoot = (tdsaRoot_t *) tiRoot->tdData;
20758 tdsaContext_t *tdsaAllShared = (tdsaContext_t *)&tdsaRoot->tdsaAllShared;
20759 tdIORequestBody_t *tdIORequestBody;
20760 tdIORequestBody_t *tdOrgIORequestBody = agNULL;
20761 satIOContext_t *satIOContext;
20762 satIOContext_t *satOrgIOContext;
20763 satInternalIo_t *satIntIo;
20764 satDeviceData_t *satDevData;
20765 tiIORequest_t *tiOrgIORequest;
20766 #ifdef TD_DEBUG_ENABLE
20767 bit32 ataStatus = 0;
20768 bit32 ataError;
20769 agsaFisPioSetupHeader_t *satPIOSetupHeader = agNULL;
20770 #endif
20771 bit32 report = agFALSE;
20772 bit32 AbortTM = agFALSE;
20773
20774 TI_DBG1(("satDeResetDeviceCB: start\n"));
20775 TI_DBG6(("satDeResetDeviceCB: agIORequest=%p agIOStatus=0x%x agIOInfoLen %d\n", agIORequest, agIOStatus, agIOInfoLen));
20776 tdIORequestBody = (tdIORequestBody_t *)agIORequest->osData;
20777 satIOContext = (satIOContext_t *) ioContext;
20778 satIntIo = satIOContext->satIntIoContext;
20779 satDevData = satIOContext->pSatDevData;
20780 if (satIntIo == agNULL)
20781 {
20782 TI_DBG6(("satDeResetDeviceCB: External, OS generated\n"));
20783 satOrgIOContext = satIOContext;
20784 tiOrgIORequest = tdIORequestBody->tiIORequest;
20785 }
20786 else
20787 {
20788 TI_DBG6(("satDeResetDeviceCB: Internal, TD generated\n"));
20789 satOrgIOContext = satIOContext->satOrgIOContext;
20790 if (satOrgIOContext == agNULL)
20791 {
20792 TI_DBG6(("satDeResetDeviceCB: satOrgIOContext is NULL, wrong\n"));
20793 return;
20794 }
20795 else
20796 {
20797 TI_DBG6(("satDeResetDeviceCB: satOrgIOContext is NOT NULL\n"));
20798 }
20799 tdOrgIORequestBody = (tdIORequestBody_t *)satOrgIOContext->tiRequestBody;
20800 tiOrgIORequest = (tiIORequest_t *)tdOrgIORequestBody->tiIORequest;
20801 }
20802
20803 tdIORequestBody->ioCompleted = agTRUE;
20804 tdIORequestBody->ioStarted = agFALSE;
20805
20806 if (agFirstDword == agNULL && agIOStatus != OSSA_IO_SUCCESS)
20807 {
20808 TI_DBG1(("satDeResetDeviceCB: wrong. agFirstDword is NULL when error, status %d\n", agIOStatus));
20809 if (satOrgIOContext->NotifyOS == agTRUE)
20810 {
20811 ostiInitiatorEvent( tiRoot,
20812 NULL,
20813 NULL,
20814 tiIntrEventTypeTaskManagement,
20815 tiTMFailed,
20816 tiOrgIORequest );
20817 }
20818
20819 satDevData->satTmTaskTag = agNULL;
20820 satDecrementPendingIO(tiRoot, tdsaAllShared, satIOContext);
20821
20822 satFreeIntIoResource( tiRoot,
20823 satDevData,
20824 satIntIo);
20825 return;
20826 }
20827
20828 if (agIOStatus == OSSA_IO_OPEN_CNX_ERROR_PROTOCOL_NOT_SUPPORTED ||
20829 agIOStatus == OSSA_IO_OPEN_CNX_ERROR_ZONE_VIOLATION ||
20830 agIOStatus == OSSA_IO_OPEN_CNX_ERROR_BREAK ||
20831 agIOStatus == OSSA_IO_OPEN_CNX_ERROR_IT_NEXUS_LOSS ||
20832 agIOStatus == OSSA_IO_OPEN_CNX_ERROR_BAD_DESTINATION ||
20833 agIOStatus == OSSA_IO_OPEN_CNX_ERROR_CONNECTION_RATE_NOT_SUPPORTED ||
20834 agIOStatus == OSSA_IO_OPEN_CNX_ERROR_WRONG_DESTINATION ||
20835 agIOStatus == OSSA_IO_OPEN_CNX_ERROR_UNKNOWN_ERROR ||
20836 agIOStatus == OSSA_IO_OPEN_CNX_ERROR_STP_RESOURCES_BUSY
20837 )
20838 {
20839 TI_DBG1(("satDeResetDeviceCB: OSSA_IO_OPEN_CNX_ERROR\n"));
20840
20841 if (satOrgIOContext->NotifyOS == agTRUE)
20842 {
20843 ostiInitiatorEvent( tiRoot,
20844 NULL,
20845 NULL,
20846 tiIntrEventTypeTaskManagement,
20847 tiTMFailed,
20848 tiOrgIORequest );
20849 }
20850
20851 satDevData->satTmTaskTag = agNULL;
20852
20853 satDecrementPendingIO(tiRoot, tdsaAllShared, satIOContext);
20854
20855 satFreeIntIoResource( tiRoot,
20856 satDevData,
20857 satIntIo);
20858 return;
20859 }
20860
20861 if (agIOStatus != OSSA_IO_SUCCESS)
20862 {
20863 #ifdef TD_DEBUG_ENABLE
20864 /* only agsaFisPioSetup_t is expected */
20865 satPIOSetupHeader = (agsaFisPioSetupHeader_t *)&(agFirstDword->PioSetup);
20866 ataStatus = satPIOSetupHeader->status; /* ATA Status register */
20867 ataError = satPIOSetupHeader->error; /* ATA Eror register */
20868 #endif
20869 TI_DBG1(("satDeResetDeviceCB: ataStatus 0x%x ataError 0x%x\n", ataStatus, ataError));
20870
20871 if (satOrgIOContext->NotifyOS == agTRUE)
20872 {
20873 ostiInitiatorEvent( tiRoot,
20874 NULL,
20875 NULL,
20876 tiIntrEventTypeTaskManagement,
20877 tiTMFailed,
20878 tiOrgIORequest );
20879 }
20880
20881 satDevData->satTmTaskTag = agNULL;
20882
20883 satDecrementPendingIO(tiRoot, tdsaAllShared, satIOContext);
20884
20885 satFreeIntIoResource( tiRoot,
20886 satDevData,
20887 satIntIo);
20888 return;
20889 }
20890
20891 /* success */
20892 TI_DBG1(("satDeResetDeviceCB: success \n"));
20893 TI_DBG1(("satDeResetDeviceCB: TMF %d\n", satOrgIOContext->TMF));
20894
20895 if (satOrgIOContext->TMF == AG_ABORT_TASK)
20896 {
20897 AbortTM = agTRUE;
20898 }
20899
20900 if (satOrgIOContext->NotifyOS == agTRUE)
20901 {
20902 report = agTRUE;
20903 }
20904
20905 if (AbortTM == agTRUE)
20906 {
20907 TI_DBG1(("satDeResetDeviceCB: calling satAbort\n"));
20908 satAbort(agRoot, satOrgIOContext->satToBeAbortedIOContext);
20909 }
20910 satDevData->satTmTaskTag = agNULL;
20911
20912 satDevData->satDriveState = SAT_DEV_STATE_NORMAL;
20913
20914 satDecrementPendingIO(tiRoot, tdsaAllShared, satIOContext);
20915
20916 TI_DBG1(("satDeResetDeviceCB: satPendingIO %d satNCQMaxIO %d\n", satDevData->satPendingIO, satDevData->satNCQMaxIO ));
20917 TI_DBG1(("satDeResetDeviceCB: satPendingNCQIO %d satPendingNONNCQIO %d\n", satDevData->satPendingNCQIO, satDevData->satPendingNONNCQIO));
20918
20919 satFreeIntIoResource( tiRoot,
20920 satDevData,
20921 satIntIo);
20922
20923 /* clean up TD layer's IORequestBody */
20924 if (tdOrgIORequestBody != agNULL)
20925 {
20926 ostiFreeMemory(
20927 tiRoot,
20928 tdOrgIORequestBody->IOType.InitiatorTMIO.osMemHandle,
20929 sizeof(tdIORequestBody_t)
20930 );
20931 }
20932 else
20933 {
20934 TI_DBG1(("satDeResetDeviceCB: tdOrgIORequestBody is NULL, wrong\n"));
20935 }
20936
20937
20938 if (report)
20939 {
20940 ostiInitiatorEvent( tiRoot,
20941 NULL,
20942 NULL,
20943 tiIntrEventTypeTaskManagement,
20944 tiTMOK,
20945 tiOrgIORequest );
20946 }
20947
20948
20949 TI_DBG5(("satDeResetDeviceCB: device %p pending IO %d\n", satDevData, satDevData->satPendingIO));
20950 TI_DBG6(("satDeResetDeviceCB: end\n"));
20951 return;
20952
20953 }
20954
20955 /*****************************************************************************/
20956 /*! \brief SAT implementation for satStartCheckPowerMode.
20957 *
20958 * SAT implementation for abort task management for non-ncq sata disk.
20959 * This function sends CHECK POWER MODE
20960 *
20961 * \param tiRoot: Pointer to TISA initiator driver/port instance.
20962 * \param tiIORequest: Pointer to TISA I/O request context for this I/O.
20963 * \param tiDeviceHandle: Pointer to TISA device handle for this I/O.
20964 * \param tiScsiRequest: Pointer to TISA SCSI I/O request and SGL list.
20965 * \param satIOContext_t: Pointer to the SAT IO Context
20966 *
20967 * \return If command is started successfully
20968 * - \e tiSuccess: I/O request successfully initiated.
20969 * - \e tiBusy: No resources available, try again later.
20970 * - \e tiIONoDevice: Invalid device handle.
20971 * - \e tiError: Other errors.
20972 */
20973 /*****************************************************************************/
20974 GLOBAL bit32 satStartCheckPowerMode(
20975 tiRoot_t *tiRoot,
20976 tiIORequest_t *tiIORequest,
20977 tiDeviceHandle_t *tiDeviceHandle,
20978 tiScsiInitiatorRequest_t *tiScsiRequest, /* NULL */
20979 satIOContext_t *satIOContext
20980 )
20981 {
20982 satInternalIo_t *satIntIo = agNULL;
20983 satDeviceData_t *satDevData = agNULL;
20984 satIOContext_t *satNewIOContext;
20985 bit32 status;
20986 tiIORequest_t *currentTaskTag = agNULL;
20987
20988 TI_DBG6(("satStartCheckPowerMode: start\n"));
20989
20990 currentTaskTag = tiIORequest;
20991
20992 satDevData = satIOContext->pSatDevData;
20993
20994 TI_DBG6(("satStartCheckPowerMode: before alloc\n"));
20995
20996 /* allocate any fis for seting SRT bit in device control */
20997 satIntIo = satAllocIntIoResource( tiRoot,
20998 tiIORequest,
20999 satDevData,
21000 0,
21001 satIntIo);
21002
21003 TI_DBG6(("satStartCheckPowerMode: before after\n"));
21004
21005 if (satIntIo == agNULL)
21006 {
21007 TI_DBG1(("satStartCheckPowerMode: can't alloacate\n"));
21008 if (satIOContext->NotifyOS)
21009 {
21010 ostiInitiatorEvent( tiRoot,
21011 NULL,
21012 NULL,
21013 tiIntrEventTypeTaskManagement,
21014 tiTMFailed,
21015 currentTaskTag );
21016 }
21017 return tiError;
21018 }
21019
21020 satNewIOContext = satPrepareNewIO(satIntIo,
21021 tiIORequest,
21022 satDevData,
21023 agNULL,
21024 satIOContext);
21025
21026 TI_DBG6(("satStartCheckPowerMode: OS satIOContext %p \n", satIOContext));
21027 TI_DBG6(("satStartCheckPowerMode: TD satNewIOContext %p \n", satNewIOContext));
21028 TI_DBG6(("satStartCheckPowerMode: OS tiScsiXchg %p \n", satIOContext->tiScsiXchg));
21029 TI_DBG6(("satStartCheckPowerMode: TD tiScsiXchg %p \n", satNewIOContext->tiScsiXchg));
21030
21031
21032
21033 TI_DBG1(("satStartCheckPowerMode: satNewIOContext %p \n", satNewIOContext));
21034
21035 status = satCheckPowerMode(tiRoot,
21036 &satIntIo->satIntTiIORequest, /* New tiIORequest */
21037 tiDeviceHandle,
21038 satNewIOContext->tiScsiXchg, /* New tiScsiInitiatorRequest_t *tiScsiRequest, */
21039 satNewIOContext);
21040
21041 if (status != tiSuccess)
21042 {
21043 TI_DBG1(("satStartCheckPowerMode: failed in sending\n"));
21044
21045 satFreeIntIoResource( tiRoot,
21046 satDevData,
21047 satIntIo);
21048 if (satIOContext->NotifyOS)
21049 {
21050 ostiInitiatorEvent( tiRoot,
21051 NULL,
21052 NULL,
21053 tiIntrEventTypeTaskManagement,
21054 tiTMFailed,
21055 currentTaskTag );
21056 }
21057
21058 return tiError;
21059 }
21060
21061
21062 TI_DBG6(("satStartCheckPowerMode: end\n"));
21063
21064 return status;
21065 }
21066
21067 /*****************************************************************************/
21068 /*! \brief SAT implementation for satCheckPowerMode.
21069 *
21070 * This function creates CHECK POWER MODE fis and sends the request to LL layer
21071 *
21072 * \param tiRoot: Pointer to TISA initiator driver/port instance.
21073 * \param tiIORequest: Pointer to TISA I/O request context for this I/O.
21074 * \param tiDeviceHandle: Pointer to TISA device handle for this I/O.
21075 * \param tiScsiRequest: Pointer to TISA SCSI I/O request and SGL list.
21076 * \param satIOContext_t: Pointer to the SAT IO Context
21077 *
21078 * \return If command is started successfully
21079 * - \e tiSuccess: I/O request successfully initiated.
21080 * - \e tiBusy: No resources available, try again later.
21081 * - \e tiIONoDevice: Invalid device handle.
21082 * - \e tiError: Other errors.
21083 */
21084 /*****************************************************************************/
21085 GLOBAL bit32 satCheckPowerMode(
21086 tiRoot_t *tiRoot,
21087 tiIORequest_t *tiIORequest,
21088 tiDeviceHandle_t *tiDeviceHandle,
21089 tiScsiInitiatorRequest_t *tiScsiRequest,
21090 satIOContext_t *satIOContext
21091 )
21092 {
21093 /*
21094 sends SAT_CHECK_POWER_MODE as a part of ABORT TASKMANGEMENT for NCQ commands
21095 internally generated - no directly corresponding scsi
21096 */
21097 bit32 status;
21098 bit32 agRequestType;
21099 agsaFisRegHostToDevice_t *fis;
21100
21101 fis = satIOContext->pFis;
21102 TI_DBG5(("satCheckPowerMode: start\n"));
21103 /*
21104 * Send the ATA CHECK POWER MODE command.
21105 */
21106 fis->h.fisType = 0x27; /* Reg host to device */
21107 fis->h.c_pmPort = 0x80; /* C Bit is set */
21108 fis->h.command = SAT_CHECK_POWER_MODE; /* 0xE5 */
21109 fis->h.features = 0;
21110 fis->d.lbaLow = 0;
21111 fis->d.lbaMid = 0;
21112 fis->d.lbaHigh = 0;
21113 fis->d.device = 0;
21114 fis->d.lbaLowExp = 0;
21115 fis->d.lbaMidExp = 0;
21116 fis->d.lbaHighExp = 0;
21117 fis->d.featuresExp = 0;
21118 fis->d.sectorCount = 0;
21119 fis->d.sectorCountExp = 0;
21120 fis->d.reserved4 = 0;
21121 fis->d.control = 0; /* FIS HOB bit clear */
21122 fis->d.reserved5 = 0;
21123
21124 agRequestType = AGSA_SATA_PROTOCOL_NON_DATA;
21125
21126 /* Initialize CB for SATA completion.
21127 */
21128 satIOContext->satCompleteCB = &satCheckPowerModeCB;
21129
21130 /*
21131 * Prepare SGL and send FIS to LL layer.
21132 */
21133 satIOContext->reqType = agRequestType; /* Save it */
21134
21135 status = sataLLIOStart( tiRoot,
21136 tiIORequest,
21137 tiDeviceHandle,
21138 tiScsiRequest,
21139 satIOContext);
21140
21141 TI_DBG5(("satCheckPowerMode: return\n"));
21142
21143 return status;
21144 }
21145
21146 /*****************************************************************************
21147 *! \brief satCheckPowerModeCB
21148 *
21149 * This routine is a callback function called from ossaSATACompleted().
21150 * This CB routine deals with CHECK POWER MODE completion as abort task
21151 * management.
21152 *
21153 * \param agRoot: Handles for this instance of SAS/SATA hardware
21154 * \param agIORequest: Pointer to the LL I/O request context for this I/O.
21155 * \param agIOStatus: Status of completed I/O.
21156 * \param agFirstDword:Pointer to the four bytes of FIS.
21157 * \param agIOInfoLen: Length in bytes of overrun/underrun residual or FIS
21158 * length.
21159 * \param agParam: Additional info based on status.
21160 * \param ioContext: Pointer to satIOContext_t.
21161 *
21162 * \return: none
21163 *
21164 *****************************************************************************/
21165 GLOBAL void satCheckPowerModeCB(
21166 agsaRoot_t *agRoot,
21167 agsaIORequest_t *agIORequest,
21168 bit32 agIOStatus,
21169 agsaFisHeader_t *agFirstDword,
21170 bit32 agIOInfoLen,
21171 agsaFrameHandle_t agFrameHandle,
21172 void *ioContext
21173 )
21174 {
21175 /* callback for satDeResetDevice */
21176 tdsaRootOsData_t *osData = (tdsaRootOsData_t *)agRoot->osData;
21177 tiRoot_t *tiRoot = (tiRoot_t *)osData->tiRoot;
21178 tdsaRoot_t *tdsaRoot = (tdsaRoot_t *) tiRoot->tdData;
21179 tdsaContext_t *tdsaAllShared = (tdsaContext_t *)&tdsaRoot->tdsaAllShared;
21180 tdIORequestBody_t *tdIORequestBody;
21181 tdIORequestBody_t *tdOrgIORequestBody = agNULL;
21182 satIOContext_t *satIOContext;
21183 satIOContext_t *satOrgIOContext;
21184 satInternalIo_t *satIntIo;
21185 satDeviceData_t *satDevData;
21186
21187 tiIORequest_t *tiOrgIORequest;
21188 #ifdef TD_DEBUG_ENABLE
21189 bit32 ataStatus = 0;
21190 bit32 ataError;
21191 agsaFisPioSetupHeader_t *satPIOSetupHeader = agNULL;
21192 #endif
21193 bit32 report = agFALSE;
21194 bit32 AbortTM = agFALSE;
21195
21196
21197 TI_DBG1(("satCheckPowerModeCB: start\n"));
21198
21199 TI_DBG1(("satCheckPowerModeCB: agIORequest=%p agIOStatus=0x%x agIOInfoLen %d\n", agIORequest, agIOStatus, agIOInfoLen));
21200
21201 tdIORequestBody = (tdIORequestBody_t *)agIORequest->osData;
21202 satIOContext = (satIOContext_t *) ioContext;
21203 satIntIo = satIOContext->satIntIoContext;
21204 satDevData = satIOContext->pSatDevData;
21205 if (satIntIo == agNULL)
21206 {
21207 TI_DBG6(("satCheckPowerModeCB: External, OS generated\n"));
21208 satOrgIOContext = satIOContext;
21209 tiOrgIORequest = tdIORequestBody->tiIORequest;
21210 }
21211 else
21212 {
21213 TI_DBG6(("satCheckPowerModeCB: Internal, TD generated\n"));
21214 satOrgIOContext = satIOContext->satOrgIOContext;
21215 if (satOrgIOContext == agNULL)
21216 {
21217 TI_DBG6(("satCheckPowerModeCB: satOrgIOContext is NULL, wrong\n"));
21218 return;
21219 }
21220 else
21221 {
21222 TI_DBG6(("satCheckPowerModeCB: satOrgIOContext is NOT NULL\n"));
21223 }
21224 tdOrgIORequestBody = (tdIORequestBody_t *)satOrgIOContext->tiRequestBody;
21225 tiOrgIORequest = (tiIORequest_t *)tdOrgIORequestBody->tiIORequest;
21226 }
21227
21228
21229 tdIORequestBody->ioCompleted = agTRUE;
21230 tdIORequestBody->ioStarted = agFALSE;
21231
21232 if (agFirstDword == agNULL && agIOStatus != OSSA_IO_SUCCESS)
21233 {
21234 TI_DBG1(("satCheckPowerModeCB: wrong. agFirstDword is NULL when error, status %d\n", agIOStatus));
21235
21236 if (satOrgIOContext->NotifyOS == agTRUE)
21237 {
21238 ostiInitiatorEvent( tiRoot,
21239 NULL,
21240 NULL,
21241 tiIntrEventTypeTaskManagement,
21242 tiTMFailed,
21243 tiOrgIORequest );
21244 }
21245
21246 satDevData->satTmTaskTag = agNULL;
21247
21248 satDecrementPendingIO(tiRoot, tdsaAllShared, satIOContext);
21249
21250 satFreeIntIoResource( tiRoot,
21251 satDevData,
21252 satIntIo);
21253 return;
21254 }
21255
21256 if (agIOStatus == OSSA_IO_OPEN_CNX_ERROR_PROTOCOL_NOT_SUPPORTED ||
21257 agIOStatus == OSSA_IO_OPEN_CNX_ERROR_ZONE_VIOLATION ||
21258 agIOStatus == OSSA_IO_OPEN_CNX_ERROR_BREAK ||
21259 agIOStatus == OSSA_IO_OPEN_CNX_ERROR_IT_NEXUS_LOSS ||
21260 agIOStatus == OSSA_IO_OPEN_CNX_ERROR_BAD_DESTINATION ||
21261 agIOStatus == OSSA_IO_OPEN_CNX_ERROR_CONNECTION_RATE_NOT_SUPPORTED ||
21262 agIOStatus == OSSA_IO_OPEN_CNX_ERROR_WRONG_DESTINATION ||
21263 agIOStatus == OSSA_IO_OPEN_CNX_ERROR_UNKNOWN_ERROR ||
21264 agIOStatus == OSSA_IO_OPEN_CNX_ERROR_STP_RESOURCES_BUSY
21265 )
21266 {
21267 TI_DBG1(("satCheckPowerModeCB: OSSA_IO_OPEN_CNX_ERROR\n"));
21268
21269 if (satOrgIOContext->NotifyOS == agTRUE)
21270 {
21271 ostiInitiatorEvent( tiRoot,
21272 NULL,
21273 NULL,
21274 tiIntrEventTypeTaskManagement,
21275 tiTMFailed,
21276 tiOrgIORequest );
21277 }
21278
21279 satDevData->satTmTaskTag = agNULL;
21280
21281 satDecrementPendingIO(tiRoot, tdsaAllShared, satIOContext);
21282
21283 satFreeIntIoResource( tiRoot,
21284 satDevData,
21285 satIntIo);
21286 return;
21287 }
21288
21289 if (agIOStatus != OSSA_IO_SUCCESS)
21290 {
21291 #ifdef TD_DEBUG_ENABLE
21292 /* only agsaFisPioSetup_t is expected */
21293 satPIOSetupHeader = (agsaFisPioSetupHeader_t *)&(agFirstDword->PioSetup);
21294 ataStatus = satPIOSetupHeader->status; /* ATA Status register */
21295 ataError = satPIOSetupHeader->error; /* ATA Eror register */
21296 #endif
21297 TI_DBG1(("satCheckPowerModeCB: ataStatus 0x%x ataError 0x%x\n", ataStatus, ataError));
21298
21299 if (satOrgIOContext->NotifyOS == agTRUE)
21300 {
21301 ostiInitiatorEvent( tiRoot,
21302 NULL,
21303 NULL,
21304 tiIntrEventTypeTaskManagement,
21305 tiTMFailed,
21306 tiOrgIORequest );
21307 }
21308
21309 satDevData->satTmTaskTag = agNULL;
21310
21311 satDecrementPendingIO(tiRoot, tdsaAllShared, satIOContext);
21312
21313 satFreeIntIoResource( tiRoot,
21314 satDevData,
21315 satIntIo);
21316 return;
21317 }
21318
21319 /* success */
21320 TI_DBG1(("satCheckPowerModeCB: success\n"));
21321 TI_DBG1(("satCheckPowerModeCB: TMF %d\n", satOrgIOContext->TMF));
21322
21323 if (satOrgIOContext->TMF == AG_ABORT_TASK)
21324 {
21325 AbortTM = agTRUE;
21326 }
21327
21328 if (satOrgIOContext->NotifyOS == agTRUE)
21329 {
21330 report = agTRUE;
21331 }
21332 if (AbortTM == agTRUE)
21333 {
21334 TI_DBG1(("satCheckPowerModeCB: calling satAbort\n"));
21335 satAbort(agRoot, satOrgIOContext->satToBeAbortedIOContext);
21336 }
21337 satDevData->satTmTaskTag = agNULL;
21338
21339 satDevData->satDriveState = SAT_DEV_STATE_NORMAL;
21340
21341 satDecrementPendingIO(tiRoot, tdsaAllShared, satIOContext);
21342
21343 TI_DBG1(("satCheckPowerModeCB: satPendingIO %d satNCQMaxIO %d\n", satDevData->satPendingIO, satDevData->satNCQMaxIO ));
21344 TI_DBG1(("satCheckPowerModeCB: satPendingNCQIO %d satPendingNONNCQIO %d\n", satDevData->satPendingNCQIO, satDevData->satPendingNONNCQIO));
21345
21346 satFreeIntIoResource( tiRoot,
21347 satDevData,
21348 satIntIo);
21349
21350 /* clean up TD layer's IORequestBody */
21351 if (tdOrgIORequestBody != agNULL)
21352 {
21353 ostiFreeMemory(
21354 tiRoot,
21355 tdOrgIORequestBody->IOType.InitiatorTMIO.osMemHandle,
21356 sizeof(tdIORequestBody_t)
21357 );
21358 }
21359 else
21360 {
21361 TI_DBG1(("satCheckPowerModeCB: tdOrgIORequestBody is NULL, wrong\n"));
21362 }
21363 if (report)
21364 {
21365 ostiInitiatorEvent( tiRoot,
21366 NULL,
21367 NULL,
21368 tiIntrEventTypeTaskManagement,
21369 tiTMOK,
21370 tiOrgIORequest );
21371 }
21372
21373 TI_DBG5(("satCheckPowerModeCB: device %p pending IO %d\n", satDevData, satDevData->satPendingIO));
21374 TI_DBG2(("satCheckPowerModeCB: end\n"));
21375 return;
21376
21377 }
21378
21379 /*****************************************************************************/
21380 /*! \brief SAT implementation for satAddSATAStartIDDev.
21381 *
21382 * This function sends identify device data to find out the uniqueness
21383 * of device.
21384 *
21385 * \param tiRoot: Pointer to TISA initiator driver/port instance.
21386 * \param tiIORequest: Pointer to TISA I/O request context for this I/O.
21387 * \param tiDeviceHandle: Pointer to TISA device handle for this I/O.
21388 * \param tiScsiRequest: Pointer to TISA SCSI I/O request and SGL list.
21389 * \param satIOContext_t: Pointer to the SAT IO Context
21390 *
21391 * \return If command is started successfully
21392 * - \e tiSuccess: I/O request successfully initiated.
21393 * - \e tiBusy: No resources available, try again later.
21394 * - \e tiIONoDevice: Invalid device handle.
21395 * - \e tiError: Other errors.
21396 */
21397 /*****************************************************************************/
21398 GLOBAL bit32 satAddSATAStartIDDev(
21399 tiRoot_t *tiRoot,
21400 tiIORequest_t *tiIORequest,
21401 tiDeviceHandle_t *tiDeviceHandle,
21402 tiScsiInitiatorRequest_t *tiScsiRequest, // NULL
21403 satIOContext_t *satIOContext
21404 )
21405 {
21406 satInternalIo_t *satIntIo = agNULL;
21407 satDeviceData_t *satDevData = agNULL;
21408 tdIORequestBody_t *tdIORequestBody;
21409 satIOContext_t *satNewIOContext;
21410 bit32 status;
21411
21412 TI_DBG2(("satAddSATAStartIDDev: start\n"));
21413
21414 satDevData = satIOContext->pSatDevData;
21415
21416 TI_DBG2(("satAddSATAStartIDDev: before alloc\n"));
21417
21418 /* allocate identify device command */
21419 satIntIo = satAllocIntIoResource( tiRoot,
21420 tiIORequest,
21421 satDevData,
21422 sizeof(agsaSATAIdentifyData_t), /* 512; size of identify device data */
21423 satIntIo);
21424
21425 TI_DBG2(("satAddSATAStartIDDev: after alloc\n"));
21426
21427 if (satIntIo == agNULL)
21428 {
21429 TI_DBG1(("satAddSATAStartIDDev: can't alloacate\n"));
21430
21431 return tiError;
21432 }
21433
21434 /* fill in fields */
21435 /* real ttttttthe one worked and the same; 5/21/07/ */
21436 satIntIo->satOrgTiIORequest = tiIORequest; /* changed */
21437 tdIORequestBody = satIntIo->satIntRequestBody;
21438 satNewIOContext = &(tdIORequestBody->transport.SATA.satIOContext);
21439
21440 satNewIOContext->pSatDevData = satDevData;
21441 satNewIOContext->pFis = &(tdIORequestBody->transport.SATA.agSATARequestBody.fis.fisRegHostToDev);
21442 satNewIOContext->pScsiCmnd = &(satIntIo->satIntTiScsiXchg.scsiCmnd);
21443 satNewIOContext->pSense = &(tdIORequestBody->transport.SATA.sensePayload);
21444 satNewIOContext->pTiSenseData = &(tdIORequestBody->transport.SATA.tiSenseData);
21445 satNewIOContext->tiRequestBody = satIntIo->satIntRequestBody; /* key fix */
21446 satNewIOContext->interruptContext = tiInterruptContext;
21447 satNewIOContext->satIntIoContext = satIntIo;
21448
21449 satNewIOContext->ptiDeviceHandle = agNULL;
21450 satNewIOContext->satOrgIOContext = satIOContext; /* changed */
21451
21452 /* this is valid only for TD layer generated (not triggered by OS at all) IO */
21453 satNewIOContext->tiScsiXchg = &(satIntIo->satIntTiScsiXchg);
21454
21455
21456 TI_DBG6(("satAddSATAStartIDDev: OS satIOContext %p \n", satIOContext));
21457 TI_DBG6(("satAddSATAStartIDDev: TD satNewIOContext %p \n", satNewIOContext));
21458 TI_DBG6(("satAddSATAStartIDDev: OS tiScsiXchg %p \n", satIOContext->tiScsiXchg));
21459 TI_DBG6(("satAddSATAStartIDDev: TD tiScsiXchg %p \n", satNewIOContext->tiScsiXchg));
21460
21461
21462
21463 TI_DBG2(("satAddSATAStartIDDev: satNewIOContext %p tdIORequestBody %p\n", satNewIOContext, tdIORequestBody));
21464
21465 status = satAddSATASendIDDev( tiRoot,
21466 &satIntIo->satIntTiIORequest, /* New tiIORequest */
21467 tiDeviceHandle,
21468 satNewIOContext->tiScsiXchg, /* New tiScsiInitiatorRequest_t *tiScsiRequest, */
21469 satNewIOContext);
21470
21471 if (status != tiSuccess)
21472 {
21473 TI_DBG1(("satAddSATAStartIDDev: failed in sending\n"));
21474
21475 satFreeIntIoResource( tiRoot,
21476 satDevData,
21477 satIntIo);
21478
21479 return tiError;
21480 }
21481
21482
21483 TI_DBG6(("satAddSATAStartIDDev: end\n"));
21484
21485 return status;
21486
21487
21488 }
21489
21490 /*****************************************************************************/
21491 /*! \brief SAT implementation for satAddSATASendIDDev.
21492 *
21493 * This function creates identify device data fis and send it to LL
21494 *
21495 * \param tiRoot: Pointer to TISA initiator driver/port instance.
21496 * \param tiIORequest: Pointer to TISA I/O request context for this I/O.
21497 * \param tiDeviceHandle: Pointer to TISA device handle for this I/O.
21498 * \param tiScsiRequest: Pointer to TISA SCSI I/O request and SGL list.
21499 * \param satIOContext_t: Pointer to the SAT IO Context
21500 *
21501 * \return If command is started successfully
21502 * - \e tiSuccess: I/O request successfully initiated.
21503 * - \e tiBusy: No resources available, try again later.
21504 * - \e tiIONoDevice: Invalid device handle.
21505 * - \e tiError: Other errors.
21506 */
21507 /*****************************************************************************/
21508 GLOBAL bit32 satAddSATASendIDDev(
21509 tiRoot_t *tiRoot,
21510 tiIORequest_t *tiIORequest,
21511 tiDeviceHandle_t *tiDeviceHandle,
21512 tiScsiInitiatorRequest_t *tiScsiRequest,
21513 satIOContext_t *satIOContext)
21514 {
21515 bit32 status;
21516 bit32 agRequestType;
21517 satDeviceData_t *pSatDevData;
21518 agsaFisRegHostToDevice_t *fis;
21519 #ifdef TD_DEBUG_ENABLE
21520 tdIORequestBody_t *tdIORequestBody;
21521 satInternalIo_t *satIntIoContext;
21522 #endif
21523
21524 pSatDevData = satIOContext->pSatDevData;
21525 fis = satIOContext->pFis;
21526 TI_DBG2(("satAddSATASendIDDev: start\n"));
21527 #ifdef TD_DEBUG_ENABLE
21528 satIntIoContext = satIOContext->satIntIoContext;
21529 tdIORequestBody = satIntIoContext->satIntRequestBody;
21530 #endif
21531 TI_DBG5(("satAddSATASendIDDev: satIOContext %p tdIORequestBody %p\n", satIOContext, tdIORequestBody));
21532
21533 fis->h.fisType = 0x27; /* Reg host to device */
21534 fis->h.c_pmPort = 0x80; /* C Bit is set */
21535 if (pSatDevData->satDeviceType == SATA_ATAPI_DEVICE)
21536 fis->h.command = SAT_IDENTIFY_PACKET_DEVICE; /* 0x40 */
21537 else
21538 fis->h.command = SAT_IDENTIFY_DEVICE; /* 0xEC */
21539 fis->h.features = 0; /* FIS reserve */
21540 fis->d.lbaLow = 0; /* FIS LBA (7 :0 ) */
21541 fis->d.lbaMid = 0; /* FIS LBA (15:8 ) */
21542 fis->d.lbaHigh = 0; /* FIS LBA (23:16) */
21543 fis->d.device = 0; /* FIS LBA mode */
21544 fis->d.lbaLowExp = 0;
21545 fis->d.lbaMidExp = 0;
21546 fis->d.lbaHighExp = 0;
21547 fis->d.featuresExp = 0;
21548 fis->d.sectorCount = 0; /* FIS sector count (7:0) */
21549 fis->d.sectorCountExp = 0;
21550 fis->d.reserved4 = 0;
21551 fis->d.control = 0; /* FIS HOB bit clear */
21552 fis->d.reserved5 = 0;
21553
21554 agRequestType = AGSA_SATA_PROTOCOL_PIO_READ;
21555
21556 /* Initialize CB for SATA completion.
21557 */
21558 satIOContext->satCompleteCB = &satAddSATAIDDevCB;
21559
21560 /*
21561 * Prepare SGL and send FIS to LL layer.
21562 */
21563 satIOContext->reqType = agRequestType; /* Save it */
21564
21565 #ifdef TD_INTERNAL_DEBUG
21566 tdhexdump("satAddSATASendIDDev", (bit8 *)satIOContext->pFis, sizeof(agsaFisRegHostToDevice_t));
21567 #ifdef TD_DEBUG_ENABLE
21568 tdhexdump("satAddSATASendIDDev LL", (bit8 *)&(tdIORequestBody->transport.SATA.agSATARequestBody.fis.fisRegHostToDev), sizeof(agsaFisRegHostToDevice_t));
21569 #endif
21570 #endif
21571
21572 status = sataLLIOStart( tiRoot,
21573 tiIORequest,
21574 tiDeviceHandle,
21575 tiScsiRequest,
21576 satIOContext);
21577
21578 TI_DBG2(("satAddSATASendIDDev: end status %d\n", status));
21579 return status;
21580 }
21581
21582 /*****************************************************************************
21583 *! \brief satAddSATAIDDevCB
21584 *
21585 * This routine is a callback function for satAddSATASendIDDev()
21586 * Using Identify Device Data, this function finds whether devicedata is
21587 * new or old. If new, add it to the devicelist.
21588 *
21589 * \param agRoot: Handles for this instance of SAS/SATA hardware
21590 * \param agIORequest: Pointer to the LL I/O request context for this I/O.
21591 * \param agIOStatus: Status of completed I/O.
21592 * \param agFirstDword:Pointer to the four bytes of FIS.
21593 * \param agIOInfoLen: Length in bytes of overrun/underrun residual or FIS
21594 * length.
21595 * \param agParam: Additional info based on status.
21596 * \param ioContext: Pointer to satIOContext_t.
21597 *
21598 * \return: none
21599 *
21600 *****************************************************************************/
21601 void satAddSATAIDDevCB(
21602 agsaRoot_t *agRoot,
21603 agsaIORequest_t *agIORequest,
21604 bit32 agIOStatus,
21605 agsaFisHeader_t *agFirstDword,
21606 bit32 agIOInfoLen,
21607 void *agParam,
21608 void *ioContext
21609 )
21610 {
21611
21612 /*
21613 In the process of Inquiry
21614 Process SAT_IDENTIFY_DEVICE
21615 */
21616 tdsaRootOsData_t *osData = (tdsaRootOsData_t *)agRoot->osData;
21617 tiRoot_t *tiRoot = (tiRoot_t *)osData->tiRoot;
21618 tdsaRoot_t *tdsaRoot = (tdsaRoot_t *) tiRoot->tdData;
21619 tdsaContext_t *tdsaAllShared = (tdsaContext_t *)&tdsaRoot->tdsaAllShared;
21620 tdIORequestBody_t *tdIORequestBody;
21621 tdIORequestBody_t *tdOrgIORequestBody;
21622 satIOContext_t *satIOContext;
21623 satIOContext_t *satOrgIOContext;
21624 satIOContext_t *satNewIOContext;
21625 satInternalIo_t *satIntIo;
21626 satInternalIo_t *satNewIntIo = agNULL;
21627 satDeviceData_t *satDevData;
21628 tiIORequest_t *tiOrgIORequest = agNULL;
21629 agsaSATAIdentifyData_t *pSATAIdData;
21630 bit16 *tmpptr, tmpptr_tmp;
21631 bit32 x;
21632 tdsaDeviceData_t *NewOneDeviceData = agNULL;
21633 tdsaDeviceData_t *oneDeviceData = agNULL;
21634 tdList_t *DeviceListList;
21635 int new_device = agTRUE;
21636 bit8 PhyID;
21637 void *sglVirtualAddr;
21638 bit32 retry_status;
21639 agsaContext_t *agContext;
21640 tdsaPortContext_t *onePortContext;
21641 bit32 status = 0;
21642
21643 TI_DBG2(("satAddSATAIDDevCB: start\n"));
21644 TI_DBG6(("satAddSATAIDDevCB: agIORequest=%p agIOStatus=0x%x agIOInfoLen %d\n", agIORequest, agIOStatus, agIOInfoLen));
21645 tdIORequestBody = (tdIORequestBody_t *)agIORequest->osData;
21646 satIOContext = (satIOContext_t *) ioContext;
21647 satIntIo = satIOContext->satIntIoContext;
21648 satDevData = satIOContext->pSatDevData;
21649
21650 NewOneDeviceData = (tdsaDeviceData_t *)tdIORequestBody->tiDevHandle->tdData;
21651 TI_DBG2(("satAddSATAIDDevCB: NewOneDeviceData %p did %d\n", NewOneDeviceData, NewOneDeviceData->id));
21652 PhyID = NewOneDeviceData->phyID;
21653 TI_DBG2(("satAddSATAIDDevCB: phyID %d\n", PhyID));
21654 agContext = &(NewOneDeviceData->agDeviceResetContext);
21655 agContext->osData = agNULL;
21656 if (satIntIo == agNULL)
21657 {
21658 TI_DBG1(("satAddSATAIDDevCB: External, OS generated\n"));
21659 TI_DBG1(("satAddSATAIDDevCB: Not possible case\n"));
21660 satOrgIOContext = satIOContext;
21661 tdOrgIORequestBody = (tdIORequestBody_t *)satOrgIOContext->tiRequestBody;
21662 tdsaAbortAll(tiRoot, agRoot, NewOneDeviceData);
21663
21664 /* put onedevicedata back to free list */
21665 osti_memset(&(NewOneDeviceData->satDevData.satIdentifyData), 0xFF, sizeof(agsaSATAIdentifyData_t));
21666 TDLIST_DEQUEUE_THIS(&(NewOneDeviceData->MainLink));
21667 TDLIST_ENQUEUE_AT_TAIL(&(NewOneDeviceData->FreeLink), &(tdsaAllShared->FreeDeviceList));
21668
21669 satDecrementPendingIO(tiRoot, tdsaAllShared, satIOContext);
21670
21671 satFreeIntIoResource( tiRoot,
21672 satDevData,
21673 satIntIo);
21674 /* clean up TD layer's IORequestBody */
21675 ostiFreeMemory(
21676 tiRoot,
21677 tdOrgIORequestBody->IOType.InitiatorTMIO.osMemHandle,
21678 sizeof(tdIORequestBody_t)
21679 );
21680
21681 /* notifying link up */
21682 ostiPortEvent (
21683 tiRoot,
21684 tiPortLinkUp,
21685 tiSuccess,
21686 (void *)tdsaAllShared->Ports[PhyID].tiPortalContext
21687 );
21688 #ifdef INITIATOR_DRIVER
21689 /* triggers discovery */
21690 ostiPortEvent(
21691 tiRoot,
21692 tiPortDiscoveryReady,
21693 tiSuccess,
21694 (void *) tdsaAllShared->Ports[PhyID].tiPortalContext
21695 );
21696 #endif
21697 return;
21698 }
21699 else
21700 {
21701 TI_DBG1(("satAddSATAIDDevCB: Internal, TD generated\n"));
21702 satOrgIOContext = satIOContext->satOrgIOContext;
21703 if (satOrgIOContext == agNULL)
21704 {
21705 TI_DBG6(("satAddSATAIDDevCB: satOrgIOContext is NULL\n"));
21706 return;
21707 }
21708 else
21709 {
21710 TI_DBG6(("satAddSATAIDDevCB: satOrgIOContext is NOT NULL\n"));
21711 tdOrgIORequestBody = (tdIORequestBody_t *)satOrgIOContext->tiRequestBody;
21712 sglVirtualAddr = satIntIo->satIntTiScsiXchg.sglVirtualAddr;
21713 }
21714 }
21715 tiOrgIORequest = tdIORequestBody->tiIORequest;
21716
21717 tdIORequestBody->ioCompleted = agTRUE;
21718 tdIORequestBody->ioStarted = agFALSE;
21719 TI_DBG2(("satAddSATAIDDevCB: satOrgIOContext->pid %d\n", satOrgIOContext->pid));
21720 /* protect against double completion for old port */
21721 if (satOrgIOContext->pid != tdsaAllShared->Ports[PhyID].portContext->id)
21722 {
21723 TI_DBG2(("satAddSATAIDDevCB: incorrect pid\n"));
21724 TI_DBG2(("satAddSATAIDDevCB: satOrgIOContext->pid %d\n", satOrgIOContext->pid));
21725 TI_DBG2(("satAddSATAIDDevCB: tiPortalContext pid %d\n", tdsaAllShared->Ports[PhyID].portContext->id));
21726 tdsaAbortAll(tiRoot, agRoot, NewOneDeviceData);
21727 /* put onedevicedata back to free list */
21728 osti_memset(&(NewOneDeviceData->satDevData.satIdentifyData), 0xFF, sizeof(agsaSATAIdentifyData_t));
21729 TDLIST_DEQUEUE_THIS(&(NewOneDeviceData->MainLink));
21730 TDLIST_ENQUEUE_AT_TAIL(&(NewOneDeviceData->FreeLink), &(tdsaAllShared->FreeDeviceList));
21731 satDecrementPendingIO(tiRoot, tdsaAllShared, satIOContext);
21732
21733 satFreeIntIoResource( tiRoot,
21734 satDevData,
21735 satIntIo);
21736 /* clean up TD layer's IORequestBody */
21737 ostiFreeMemory(
21738 tiRoot,
21739 tdOrgIORequestBody->IOType.InitiatorTMIO.osMemHandle,
21740 sizeof(tdIORequestBody_t)
21741 );
21742 /* no notification to OS layer */
21743 return;
21744 }
21745 /* completion after portcontext is invalidated */
21746 onePortContext = NewOneDeviceData->tdPortContext;
21747 if (onePortContext != agNULL)
21748 {
21749 if (onePortContext->valid == agFALSE)
21750 {
21751 TI_DBG1(("satAddSATAIDDevCB: portcontext is invalid\n"));
21752 TI_DBG1(("satAddSATAIDDevCB: onePortContext->id pid %d\n", onePortContext->id));
21753 satDecrementPendingIO(tiRoot, tdsaAllShared, satIOContext);
21754
21755 satFreeIntIoResource( tiRoot,
21756 satDevData,
21757 satIntIo);
21758 /* clean up TD layer's IORequestBody */
21759 ostiFreeMemory(
21760 tiRoot,
21761 tdOrgIORequestBody->IOType.InitiatorTMIO.osMemHandle,
21762 sizeof(tdIORequestBody_t)
21763 );
21764 /* no notification to OS layer */
21765 return;
21766 }
21767 }
21768 else
21769 {
21770 TI_DBG1(("satAddSATAIDDevCB: onePortContext is NULL!!!\n"));
21771 return;
21772 }
21773 if (agFirstDword == agNULL && agIOStatus != OSSA_IO_SUCCESS)
21774 {
21775 TI_DBG1(("satAddSATAIDDevCB: wrong. agFirstDword is NULL when error, status %d\n", agIOStatus));
21776 if (tdsaAllShared->ResetInDiscovery != 0 && satDevData->ID_Retries < SATA_ID_DEVICE_DATA_RETRIES)
21777 {
21778 satDevData->satPendingNONNCQIO--;
21779 satDevData->satPendingIO--;
21780 retry_status = sataLLIOStart(tiRoot,
21781 &satIntIo->satIntTiIORequest,
21782 &(NewOneDeviceData->tiDeviceHandle),
21783 satIOContext->tiScsiXchg,
21784 satIOContext);
21785 if (retry_status != tiSuccess)
21786 {
21787 /* simply give up */
21788 satDevData->ID_Retries = 0;
21789 satAddSATAIDDevCBCleanup(agRoot, NewOneDeviceData, satIOContext, tdOrgIORequestBody);
21790 return;
21791 }
21792 satDevData->ID_Retries++;
21793 tdIORequestBody->ioCompleted = agFALSE;
21794 tdIORequestBody->ioStarted = agTRUE;
21795 return;
21796 }
21797 else
21798 {
21799 if (tdsaAllShared->ResetInDiscovery == 0)
21800 {
21801 satAddSATAIDDevCBCleanup(agRoot, NewOneDeviceData, satIOContext, tdOrgIORequestBody);
21802 }
21803 else /* ResetInDiscovery in on */
21804 {
21805 /* RESET only one after ID retries */
21806 if (satDevData->NumOfIDRetries <= 0)
21807 {
21808 satDevData->NumOfIDRetries++;
21809 satDevData->ID_Retries = 0;
21810 satAddSATAIDDevCBReset(agRoot, NewOneDeviceData, satIOContext, tdOrgIORequestBody);
21811 /* send link reset */
21812 saLocalPhyControl(agRoot,
21813 agContext,
21814 tdsaRotateQnumber(tiRoot, NewOneDeviceData),
21815 PhyID,
21816 AGSA_PHY_HARD_RESET,
21817 agNULL);
21818 }
21819 else
21820 {
21821 satDevData->ID_Retries = 0;
21822 satAddSATAIDDevCBCleanup(agRoot, NewOneDeviceData, satIOContext, tdOrgIORequestBody);
21823 }
21824 }
21825 return;
21826 }
21827 }
21828 if (agIOStatus == OSSA_IO_OPEN_CNX_ERROR_PROTOCOL_NOT_SUPPORTED ||
21829 agIOStatus == OSSA_IO_OPEN_CNX_ERROR_ZONE_VIOLATION ||
21830 agIOStatus == OSSA_IO_OPEN_CNX_ERROR_BREAK ||
21831 agIOStatus == OSSA_IO_OPEN_CNX_ERROR_IT_NEXUS_LOSS ||
21832 agIOStatus == OSSA_IO_OPEN_CNX_ERROR_BAD_DESTINATION ||
21833 agIOStatus == OSSA_IO_OPEN_CNX_ERROR_CONNECTION_RATE_NOT_SUPPORTED ||
21834 agIOStatus == OSSA_IO_OPEN_CNX_ERROR_WRONG_DESTINATION ||
21835 agIOStatus == OSSA_IO_OPEN_CNX_ERROR_UNKNOWN_ERROR ||
21836 agIOStatus == OSSA_IO_OPEN_CNX_ERROR_STP_RESOURCES_BUSY
21837 )
21838 {
21839 TI_DBG1(("satAddSATAIDDevCB: OSSA_IO_OPEN_CNX_ERROR\n"));
21840 if (tdsaAllShared->ResetInDiscovery != 0 && satDevData->ID_Retries < SATA_ID_DEVICE_DATA_RETRIES)
21841 {
21842 satDevData->satPendingNONNCQIO--;
21843 satDevData->satPendingIO--;
21844 retry_status = sataLLIOStart(tiRoot,
21845 &satIntIo->satIntTiIORequest,
21846 &(NewOneDeviceData->tiDeviceHandle),
21847 satIOContext->tiScsiXchg,
21848 satIOContext);
21849 if (retry_status != tiSuccess)
21850 {
21851 /* simply give up */
21852 satDevData->ID_Retries = 0;
21853 satAddSATAIDDevCBCleanup(agRoot, NewOneDeviceData, satIOContext, tdOrgIORequestBody);
21854 return;
21855 }
21856 satDevData->ID_Retries++;
21857 tdIORequestBody->ioCompleted = agFALSE;
21858 tdIORequestBody->ioStarted = agTRUE;
21859 return;
21860 }
21861 else
21862 {
21863 if (tdsaAllShared->ResetInDiscovery == 0)
21864 {
21865 satAddSATAIDDevCBCleanup(agRoot, NewOneDeviceData, satIOContext, tdOrgIORequestBody);
21866 }
21867 else /* ResetInDiscovery in on */
21868 {
21869 /* RESET only one after ID retries */
21870 if (satDevData->NumOfIDRetries <= 0)
21871 {
21872 satDevData->NumOfIDRetries++;
21873 satDevData->ID_Retries = 0;
21874 satAddSATAIDDevCBReset(agRoot, NewOneDeviceData, satIOContext, tdOrgIORequestBody);
21875 /* send link reset */
21876 saLocalPhyControl(agRoot,
21877 agContext,
21878 tdsaRotateQnumber(tiRoot, NewOneDeviceData),
21879 PhyID,
21880 AGSA_PHY_HARD_RESET,
21881 agNULL);
21882 }
21883 else
21884 {
21885 satDevData->ID_Retries = 0;
21886 satAddSATAIDDevCBCleanup(agRoot, NewOneDeviceData, satIOContext, tdOrgIORequestBody);
21887 }
21888 }
21889 return;
21890 }
21891 }
21892
21893 if ( agIOStatus != OSSA_IO_SUCCESS ||
21894 (agIOStatus == OSSA_IO_SUCCESS && agFirstDword != agNULL && agIOInfoLen != 0)
21895 )
21896 {
21897 if (tdsaAllShared->ResetInDiscovery != 0 && satDevData->ID_Retries < SATA_ID_DEVICE_DATA_RETRIES)
21898 {
21899 satIOContext->pSatDevData->satPendingNONNCQIO--;
21900 satIOContext->pSatDevData->satPendingIO--;
21901 retry_status = sataLLIOStart(tiRoot,
21902 &satIntIo->satIntTiIORequest,
21903 &(NewOneDeviceData->tiDeviceHandle),
21904 satIOContext->tiScsiXchg,
21905 satIOContext);
21906 if (retry_status != tiSuccess)
21907 {
21908 /* simply give up */
21909 satDevData->ID_Retries = 0;
21910 satAddSATAIDDevCBCleanup(agRoot, NewOneDeviceData, satIOContext, tdOrgIORequestBody);
21911 return;
21912 }
21913 satDevData->ID_Retries++;
21914 tdIORequestBody->ioCompleted = agFALSE;
21915 tdIORequestBody->ioStarted = agTRUE;
21916 return;
21917 }
21918 else
21919 {
21920 if (tdsaAllShared->ResetInDiscovery == 0)
21921 {
21922 satAddSATAIDDevCBCleanup(agRoot, NewOneDeviceData, satIOContext, tdOrgIORequestBody);
21923 }
21924 else /* ResetInDiscovery in on */
21925 {
21926 /* RESET only one after ID retries */
21927 if (satDevData->NumOfIDRetries <= 0)
21928 {
21929 satDevData->NumOfIDRetries++;
21930 satDevData->ID_Retries = 0;
21931 satAddSATAIDDevCBReset(agRoot, NewOneDeviceData, satIOContext, tdOrgIORequestBody);
21932 /* send link reset */
21933 saLocalPhyControl(agRoot,
21934 agContext,
21935 tdsaRotateQnumber(tiRoot, NewOneDeviceData),
21936 PhyID,
21937 AGSA_PHY_HARD_RESET,
21938 agNULL);
21939 }
21940 else
21941 {
21942 satDevData->ID_Retries = 0;
21943 satAddSATAIDDevCBCleanup(agRoot, NewOneDeviceData, satIOContext, tdOrgIORequestBody);
21944 }
21945 }
21946 return;
21947 }
21948 }
21949
21950 /* success */
21951 TI_DBG2(("satAddSATAIDDevCB: Success\n"));
21952 /* Convert to host endian */
21953 tmpptr = (bit16*)sglVirtualAddr;
21954 //tdhexdump("satAddSATAIDDevCB before", (bit8 *)sglVirtualAddr, sizeof(agsaSATAIdentifyData_t));
21955 for (x=0; x < sizeof(agsaSATAIdentifyData_t)/sizeof(bit16); x++)
21956 {
21957 OSSA_READ_LE_16(AGROOT, &tmpptr_tmp, tmpptr, 0);
21958 *tmpptr = tmpptr_tmp;
21959 tmpptr++;
21960 /*Print tmpptr_tmp here for debugging purpose*/
21961 }
21962
21963 pSATAIdData = (agsaSATAIdentifyData_t *)sglVirtualAddr;
21964 //tdhexdump("satAddSATAIDDevCB after", (bit8 *)pSATAIdData, sizeof(agsaSATAIdentifyData_t));
21965
21966 TI_DBG5(("satAddSATAIDDevCB: OS satOrgIOContext %p \n", satOrgIOContext));
21967 TI_DBG5(("satAddSATAIDDevCB: TD satIOContext %p \n", satIOContext));
21968 TI_DBG5(("satAddSATAIDDevCB: OS tiScsiXchg %p \n", satOrgIOContext->tiScsiXchg));
21969 TI_DBG5(("satAddSATAIDDevCB: TD tiScsiXchg %p \n", satIOContext->tiScsiXchg));
21970
21971
21972 /* compare idenitfy device data to the exiting list */
21973 DeviceListList = tdsaAllShared->MainDeviceList.flink;
21974 while (DeviceListList != &(tdsaAllShared->MainDeviceList))
21975 {
21976 oneDeviceData = TDLIST_OBJECT_BASE(tdsaDeviceData_t, MainLink, DeviceListList);
21977 TI_DBG1(("satAddSATAIDDevCB: LOOP oneDeviceData %p did %d\n", oneDeviceData, oneDeviceData->id));
21978 //tdhexdump("satAddSATAIDDevCB LOOP", (bit8 *)&oneDeviceData->satDevData.satIdentifyData, sizeof(agsaSATAIdentifyData_t));
21979
21980 /* what is unique ID for sata device -> response of identify devicedata; not really
21981 Let's compare serial number, firmware version, model number
21982 */
21983 if ( oneDeviceData->DeviceType == TD_SATA_DEVICE &&
21984 (osti_memcmp (oneDeviceData->satDevData.satIdentifyData.serialNumber,
21985 pSATAIdData->serialNumber,
21986 20) == 0) &&
21987 (osti_memcmp (oneDeviceData->satDevData.satIdentifyData.firmwareVersion,
21988 pSATAIdData->firmwareVersion,
21989 8) == 0) &&
21990 (osti_memcmp (oneDeviceData->satDevData.satIdentifyData.modelNumber,
21991 pSATAIdData->modelNumber,
21992 40) == 0)
21993 )
21994 {
21995 TI_DBG2(("satAddSATAIDDevCB: did %d\n", oneDeviceData->id));
21996 new_device = agFALSE;
21997 break;
21998 }
21999 DeviceListList = DeviceListList->flink;
22000 }
22001
22002 if (new_device == agFALSE)
22003 {
22004 TI_DBG2(("satAddSATAIDDevCB: old device data\n"));
22005 oneDeviceData->valid = agTRUE;
22006 oneDeviceData->valid2 = agTRUE;
22007 /* save data field from new device data */
22008 oneDeviceData->agRoot = agRoot;
22009 oneDeviceData->agDevHandle = NewOneDeviceData->agDevHandle;
22010 oneDeviceData->agDevHandle->osData = oneDeviceData; /* TD layer */
22011 oneDeviceData->tdPortContext = NewOneDeviceData->tdPortContext;
22012 oneDeviceData->phyID = NewOneDeviceData->phyID;
22013
22014 /*
22015 one SATA directly attached device per phy;
22016 Therefore, deregister then register
22017 */
22018 saDeregisterDeviceHandle(agRoot, agNULL, NewOneDeviceData->agDevHandle, 0);
22019
22020 if (oneDeviceData->registered == agFALSE)
22021 {
22022 TI_DBG2(("satAddSATAIDDevCB: re-registering old device data\n"));
22023 /* already has old information; just register it again */
22024 saRegisterNewDevice( /* satAddSATAIDDevCB */
22025 agRoot,
22026 &oneDeviceData->agContext,
22027 tdsaRotateQnumber(tiRoot, oneDeviceData),
22028 &oneDeviceData->agDeviceInfo,
22029 oneDeviceData->tdPortContext->agPortContext,
22030 0
22031 );
22032 }
22033
22034 // tdsaAbortAll(tiRoot, agRoot, NewOneDeviceData);
22035 /* put onedevicedata back to free list */
22036 osti_memset(&(NewOneDeviceData->satDevData.satIdentifyData), 0xFF, sizeof(agsaSATAIdentifyData_t));
22037 TDLIST_DEQUEUE_THIS(&(NewOneDeviceData->MainLink));
22038 TDLIST_ENQUEUE_AT_TAIL(&(NewOneDeviceData->FreeLink), &(tdsaAllShared->FreeDeviceList));
22039 satDecrementPendingIO(tiRoot, tdsaAllShared, satIOContext);
22040
22041 satFreeIntIoResource( tiRoot,
22042 satDevData,
22043 satIntIo);
22044
22045 if (satDevData->satDeviceType == SATA_ATAPI_DEVICE)
22046 {
22047 /* send the Set Feature ATA command to ATAPI device for enbling PIO and DMA transfer mode*/
22048 satNewIntIo = satAllocIntIoResource( tiRoot,
22049 tiOrgIORequest,
22050 satDevData,
22051 0,
22052 satNewIntIo);
22053
22054 if (satNewIntIo == agNULL)
22055 {
22056 TI_DBG1(("tdsaDiscoveryStartIDDevCB: momory allocation fails\n"));
22057 /* clean up TD layer's IORequestBody */
22058 ostiFreeMemory(
22059 tiRoot,
22060 tdOrgIORequestBody->IOType.InitiatorTMIO.osMemHandle,
22061 sizeof(tdIORequestBody_t)
22062 );
22063 return;
22064 } /* end memory allocation */
22065
22066 satNewIOContext = satPrepareNewIO(satNewIntIo,
22067 tiOrgIORequest,
22068 satDevData,
22069 agNULL,
22070 satOrgIOContext
22071 );
22072 /* enable PIO mode, then enable Ultra DMA mode in the satSetFeaturesCB callback function*/
22073 status = satSetFeatures(tiRoot,
22074 &satNewIntIo->satIntTiIORequest,
22075 satNewIOContext->ptiDeviceHandle,
22076 &satNewIntIo->satIntTiScsiXchg, /* orginal from OS layer */
22077 satNewIOContext,
22078 agFALSE);
22079 if (status != tiSuccess)
22080 {
22081 satFreeIntIoResource( tiRoot,
22082 satDevData,
22083 satIntIo);
22084 /* clean up TD layer's IORequestBody */
22085 ostiFreeMemory(
22086 tiRoot,
22087 tdOrgIORequestBody->IOType.InitiatorTMIO.osMemHandle,
22088 sizeof(tdIORequestBody_t)
22089 );
22090 }
22091 }
22092 else
22093 {
22094 /* clean up TD layer's IORequestBody */
22095 ostiFreeMemory(
22096 tiRoot,
22097 tdOrgIORequestBody->IOType.InitiatorTMIO.osMemHandle,
22098 sizeof(tdIORequestBody_t)
22099 );
22100 TI_DBG2(("satAddSATAIDDevCB: pid %d\n", tdsaAllShared->Ports[PhyID].portContext->id));
22101 /* notifying link up */
22102 ostiPortEvent(
22103 tiRoot,
22104 tiPortLinkUp,
22105 tiSuccess,
22106 (void *)tdsaAllShared->Ports[PhyID].tiPortalContext
22107 );
22108
22109
22110 #ifdef INITIATOR_DRIVER
22111 /* triggers discovery */
22112 ostiPortEvent(
22113 tiRoot,
22114 tiPortDiscoveryReady,
22115 tiSuccess,
22116 (void *) tdsaAllShared->Ports[PhyID].tiPortalContext
22117 );
22118 #endif
22119 }
22120 return;
22121 }
22122
22123 TI_DBG2(("satAddSATAIDDevCB: new device data\n"));
22124 /* copy ID Dev data to satDevData */
22125 satDevData->satIdentifyData = *pSATAIdData;
22126
22127
22128 satDevData->IDDeviceValid = agTRUE;
22129 #ifdef TD_INTERNAL_DEBUG
22130 tdhexdump("satAddSATAIDDevCB ID Dev data",(bit8 *)pSATAIdData, sizeof(agsaSATAIdentifyData_t));
22131 tdhexdump("satAddSATAIDDevCB Device ID Dev data",(bit8 *)&satDevData->satIdentifyData, sizeof(agsaSATAIdentifyData_t));
22132 #endif
22133
22134 /* set satDevData fields from IndentifyData */
22135 satSetDevInfo(satDevData,pSATAIdData);
22136 satDecrementPendingIO(tiRoot, tdsaAllShared, satIOContext);
22137
22138 satFreeIntIoResource( tiRoot,
22139 satDevData,
22140 satIntIo);
22141
22142 if (satDevData->satDeviceType == SATA_ATAPI_DEVICE)
22143 {
22144 /* send the Set Feature ATA command to ATAPI device for enbling PIO and DMA transfer mode*/
22145 satNewIntIo = satAllocIntIoResource( tiRoot,
22146 tiOrgIORequest,
22147 satDevData,
22148 0,
22149 satNewIntIo);
22150
22151 if (satNewIntIo == agNULL)
22152 {
22153 TI_DBG1(("tdsaDiscoveryStartIDDevCB: momory allocation fails\n"));
22154 /* clean up TD layer's IORequestBody */
22155 ostiFreeMemory(
22156 tiRoot,
22157 tdOrgIORequestBody->IOType.InitiatorTMIO.osMemHandle,
22158 sizeof(tdIORequestBody_t)
22159 );
22160 return;
22161 } /* end memory allocation */
22162
22163 satNewIOContext = satPrepareNewIO(satNewIntIo,
22164 tiOrgIORequest,
22165 satDevData,
22166 agNULL,
22167 satOrgIOContext
22168 );
22169 /* enable PIO mode, then enable Ultra DMA mode in the satSetFeaturesCB callback function*/
22170 status = satSetFeatures(tiRoot,
22171 &satNewIntIo->satIntTiIORequest,
22172 satNewIOContext->ptiDeviceHandle,
22173 &satNewIntIo->satIntTiScsiXchg, /* orginal from OS layer */
22174 satNewIOContext,
22175 agFALSE);
22176 if (status != tiSuccess)
22177 {
22178 satFreeIntIoResource( tiRoot,
22179 satDevData,
22180 satIntIo);
22181 /* clean up TD layer's IORequestBody */
22182 ostiFreeMemory(
22183 tiRoot,
22184 tdOrgIORequestBody->IOType.InitiatorTMIO.osMemHandle,
22185 sizeof(tdIORequestBody_t)
22186 );
22187 }
22188
22189 }
22190 else
22191 {
22192 /* clean up TD layer's IORequestBody */
22193 ostiFreeMemory(
22194 tiRoot,
22195 tdOrgIORequestBody->IOType.InitiatorTMIO.osMemHandle,
22196 sizeof(tdIORequestBody_t)
22197 );
22198
22199 TI_DBG2(("satAddSATAIDDevCB: pid %d\n", tdsaAllShared->Ports[PhyID].portContext->id));
22200 /* notifying link up */
22201 ostiPortEvent (
22202 tiRoot,
22203 tiPortLinkUp,
22204 tiSuccess,
22205 (void *)tdsaAllShared->Ports[PhyID].tiPortalContext
22206 );
22207 #ifdef INITIATOR_DRIVER
22208 /* triggers discovery */
22209 ostiPortEvent(
22210 tiRoot,
22211 tiPortDiscoveryReady,
22212 tiSuccess,
22213 (void *) tdsaAllShared->Ports[PhyID].tiPortalContext
22214 );
22215 #endif
22216 }
22217
22218 TI_DBG2(("satAddSATAIDDevCB: end\n"));
22219 return;
22220
22221 }
22222
22223 /*****************************************************************************
22224 *! \brief satAddSATAIDDevCBReset
22225 *
22226 * This routine cleans up IOs for failed Identify device data
22227 *
22228 * \param agRoot: Handles for this instance of SAS/SATA hardware
22229 * \param oneDeviceData: Pointer to the device data.
22230 * \param ioContext: Pointer to satIOContext_t.
22231 * \param tdIORequestBody: Pointer to the request body
22232 * \param flag: Decrement pending io or not
22233 *
22234 * \return: none
22235 *
22236 *****************************************************************************/
22237 void satAddSATAIDDevCBReset(
22238 agsaRoot_t *agRoot,
22239 tdsaDeviceData_t *oneDeviceData,
22240 satIOContext_t *satIOContext,
22241 tdIORequestBody_t *tdIORequestBody
22242 )
22243 {
22244 tdsaRootOsData_t *osData = (tdsaRootOsData_t *)agRoot->osData;
22245 tiRoot_t *tiRoot = (tiRoot_t *)osData->tiRoot;
22246 tdsaRoot_t *tdsaRoot = (tdsaRoot_t *) tiRoot->tdData;
22247 tdsaContext_t *tdsaAllShared = (tdsaContext_t *)&tdsaRoot->tdsaAllShared;
22248 satInternalIo_t *satIntIo;
22249 satDeviceData_t *satDevData;
22250
22251 TI_DBG2(("satAddSATAIDDevCBReset: start\n"));
22252 satIntIo = satIOContext->satIntIoContext;
22253 satDevData = satIOContext->pSatDevData;
22254 satDecrementPendingIO(tiRoot, tdsaAllShared, satIOContext);
22255
22256 satFreeIntIoResource( tiRoot,
22257 satDevData,
22258 satIntIo);
22259 /* clean up TD layer's IORequestBody */
22260 ostiFreeMemory(
22261 tiRoot,
22262 tdIORequestBody->IOType.InitiatorTMIO.osMemHandle,
22263 sizeof(tdIORequestBody_t)
22264 );
22265 return;
22266 }
22267
22268
22269 /*****************************************************************************
22270 *! \brief satAddSATAIDDevCBCleanup
22271 *
22272 * This routine cleans up IOs for failed Identify device data
22273 *
22274 * \param agRoot: Handles for this instance of SAS/SATA hardware
22275 * \param oneDeviceData: Pointer to the device data.
22276 * \param ioContext: Pointer to satIOContext_t.
22277 * \param tdIORequestBody: Pointer to the request body
22278 *
22279 * \return: none
22280 *
22281 *****************************************************************************/
22282 void satAddSATAIDDevCBCleanup(
22283 agsaRoot_t *agRoot,
22284 tdsaDeviceData_t *oneDeviceData,
22285 satIOContext_t *satIOContext,
22286 tdIORequestBody_t *tdIORequestBody
22287 )
22288 {
22289 tdsaRootOsData_t *osData = (tdsaRootOsData_t *)agRoot->osData;
22290 tiRoot_t *tiRoot = (tiRoot_t *)osData->tiRoot;
22291 tdsaRoot_t *tdsaRoot = (tdsaRoot_t *) tiRoot->tdData;
22292 tdsaContext_t *tdsaAllShared = (tdsaContext_t *)&tdsaRoot->tdsaAllShared;
22293 satInternalIo_t *satIntIo;
22294 satDeviceData_t *satDevData;
22295 bit8 PhyID;
22296
22297 TI_DBG2(("satAddSATAIDDevCBCleanup: start\n"));
22298 satIntIo = satIOContext->satIntIoContext;
22299 satDevData = satIOContext->pSatDevData;
22300 PhyID = oneDeviceData->phyID;
22301 tdsaAbortAll(tiRoot, agRoot, oneDeviceData);
22302 /* put onedevicedata back to free list */
22303 osti_memset(&(oneDeviceData->satDevData.satIdentifyData), 0xFF, sizeof(agsaSATAIdentifyData_t));
22304 TDLIST_DEQUEUE_THIS(&(oneDeviceData->MainLink));
22305 TDLIST_ENQUEUE_AT_TAIL(&(oneDeviceData->FreeLink), &(tdsaAllShared->FreeDeviceList));
22306
22307 satDecrementPendingIO(tiRoot, tdsaAllShared, satIOContext);
22308
22309
22310 satFreeIntIoResource( tiRoot,
22311 satDevData,
22312 satIntIo);
22313
22314 /* clean up TD layer's IORequestBody */
22315 ostiFreeMemory(
22316 tiRoot,
22317 tdIORequestBody->IOType.InitiatorTMIO.osMemHandle,
22318 sizeof(tdIORequestBody_t)
22319 );
22320
22321 /* notifying link up */
22322 ostiPortEvent (
22323 tiRoot,
22324 tiPortLinkUp,
22325 tiSuccess,
22326 (void *)tdsaAllShared->Ports[PhyID].tiPortalContext
22327 );
22328 #ifdef INITIATOR_DRIVER
22329 /* triggers discovery */
22330 ostiPortEvent(
22331 tiRoot,
22332 tiPortDiscoveryReady,
22333 tiSuccess,
22334 (void *) tdsaAllShared->Ports[PhyID].tiPortalContext
22335 );
22336 #endif
22337
22338 return;
22339 }
22340
22341 /*****************************************************************************/
22342 /*! \brief SAT implementation for tdsaDiscoveryStartIDDev.
22343 *
22344 * This function sends identify device data to SATA device in discovery
22345 *
22346 *
22347 * \param tiRoot: Pointer to TISA initiator driver/port instance.
22348 * \param tiIORequest: Pointer to TISA I/O request context for this I/O.
22349 * \param tiDeviceHandle: Pointer to TISA device handle for this I/O.
22350 * \param tiScsiRequest: Pointer to TISA SCSI I/O request and SGL list.
22351 * \param oneDeviceData : Pointer to the device data.
22352 *
22353 * \return If command is started successfully
22354 * - \e tiSuccess: I/O request successfully initiated.
22355 * - \e tiBusy: No resources available, try again later.
22356 * - \e tiIONoDevice: Invalid device handle.
22357 * - \e tiError: Other errors.
22358 */
22359 /*****************************************************************************/
22360 GLOBAL bit32
22361 tdsaDiscoveryStartIDDev(tiRoot_t *tiRoot,
22362 tiIORequest_t *tiIORequest, /* agNULL */
22363 tiDeviceHandle_t *tiDeviceHandle,
22364 tiScsiInitiatorRequest_t *tiScsiRequest, /* agNULL */
22365 tdsaDeviceData_t *oneDeviceData
22366 )
22367 {
22368 void *osMemHandle;
22369 tdIORequestBody_t *tdIORequestBody;
22370 bit32 PhysUpper32;
22371 bit32 PhysLower32;
22372 bit32 memAllocStatus;
22373 agsaIORequest_t *agIORequest = agNULL; /* identify device data itself */
22374 satIOContext_t *satIOContext = agNULL;
22375 bit32 status;
22376
22377 /* allocate tdiorequestbody and call tdsaDiscoveryIntStartIDDev
22378 tdsaDiscoveryIntStartIDDev(tiRoot, agNULL, tiDeviceHandle, satIOContext);
22379
22380 */
22381
22382 TI_DBG3(("tdsaDiscoveryStartIDDev: start\n"));
22383 TI_DBG3(("tdsaDiscoveryStartIDDev: did %d\n", oneDeviceData->id));
22384
22385 /* allocation tdIORequestBody and pass it to satTM() */
22386 memAllocStatus = ostiAllocMemory(
22387 tiRoot,
22388 &osMemHandle,
22389 (void **)&tdIORequestBody,
22390 &PhysUpper32,
22391 &PhysLower32,
22392 8,
22393 sizeof(tdIORequestBody_t),
22394 agTRUE
22395 );
22396
22397 if (memAllocStatus != tiSuccess)
22398 {
22399 TI_DBG1(("tdsaDiscoveryStartIDDev: ostiAllocMemory failed... loc 1\n"));
22400 return tiError;
22401 }
22402 if (tdIORequestBody == agNULL)
22403 {
22404 TI_DBG1(("tdsaDiscoveryStartIDDev: ostiAllocMemory returned NULL tdIORequestBody loc 2\n"));
22405 return tiError;
22406 }
22407
22408 /* setup identify device data IO structure */
22409 tdIORequestBody->IOType.InitiatorTMIO.osMemHandle = osMemHandle;
22410 tdIORequestBody->IOType.InitiatorTMIO.CurrentTaskTag = agNULL;
22411 tdIORequestBody->IOType.InitiatorTMIO.TaskTag = agNULL;
22412
22413 /* initialize tiDevhandle */
22414 tdIORequestBody->tiDevHandle = &(oneDeviceData->tiDeviceHandle);
22415 tdIORequestBody->tiDevHandle->tdData = oneDeviceData;
22416
22417 /* initialize tiIORequest */
22418 tdIORequestBody->tiIORequest = agNULL;
22419
22420 /* initialize agIORequest */
22421 agIORequest = &(tdIORequestBody->agIORequest);
22422 agIORequest->osData = (void *) tdIORequestBody;
22423 agIORequest->sdkData = agNULL; /* SA takes care of this */
22424
22425 /* set up satIOContext */
22426 satIOContext = &(tdIORequestBody->transport.SATA.satIOContext);
22427 satIOContext->pSatDevData = &(oneDeviceData->satDevData);
22428 satIOContext->pFis =
22429 &(tdIORequestBody->transport.SATA.agSATARequestBody.fis.fisRegHostToDev);
22430
22431 satIOContext->tiRequestBody = tdIORequestBody;
22432 satIOContext->ptiDeviceHandle = &(oneDeviceData->tiDeviceHandle);
22433 satIOContext->tiScsiXchg = agNULL;
22434 satIOContext->satIntIoContext = agNULL;
22435 satIOContext->satOrgIOContext = agNULL;
22436 /* followings are used only for internal IO */
22437 satIOContext->currentLBA = 0;
22438 satIOContext->OrgTL = 0;
22439 satIOContext->satToBeAbortedIOContext = agNULL;
22440 satIOContext->NotifyOS = agFALSE;
22441
22442 /* saving port ID just in case of full discovery to full discovery transition */
22443 satIOContext->pid = oneDeviceData->tdPortContext->id;
22444 osti_memset(&(oneDeviceData->satDevData.satIdentifyData), 0x0, sizeof(agsaSATAIdentifyData_t));
22445 status = tdsaDiscoveryIntStartIDDev(tiRoot,
22446 tiIORequest, /* agNULL */
22447 tiDeviceHandle, /* &(oneDeviceData->tiDeviceHandle)*/
22448 agNULL,
22449 satIOContext
22450 );
22451 if (status != tiSuccess)
22452 {
22453 TI_DBG1(("tdsaDiscoveryStartIDDev: failed in sending %d\n", status));
22454 ostiFreeMemory(tiRoot, osMemHandle, sizeof(tdIORequestBody_t));
22455 }
22456 return status;
22457 }
22458
22459 /*****************************************************************************/
22460 /*! \brief SAT implementation for tdsaDiscoveryIntStartIDDev.
22461 *
22462 * This function sends identify device data to SATA device.
22463 *
22464 * \param tiRoot: Pointer to TISA initiator driver/port instance.
22465 * \param tiIORequest: Pointer to TISA I/O request context for this I/O.
22466 * \param tiDeviceHandle: Pointer to TISA device handle for this I/O.
22467 * \param tiScsiRequest: Pointer to TISA SCSI I/O request and SGL list.
22468 * \param satIOContext_t: Pointer to the SAT IO Context
22469 *
22470 * \return If command is started successfully
22471 * - \e tiSuccess: I/O request successfully initiated.
22472 * - \e tiBusy: No resources available, try again later.
22473 * - \e tiIONoDevice: Invalid device handle.
22474 * - \e tiError: Other errors.
22475 */
22476 /*****************************************************************************/
22477 GLOBAL bit32
22478 tdsaDiscoveryIntStartIDDev(tiRoot_t *tiRoot,
22479 tiIORequest_t *tiIORequest, /* agNULL */
22480 tiDeviceHandle_t *tiDeviceHandle,
22481 tiScsiInitiatorRequest_t *tiScsiRequest, /* agNULL */
22482 satIOContext_t *satIOContext
22483 )
22484 {
22485 satInternalIo_t *satIntIo = agNULL;
22486 satDeviceData_t *satDevData = agNULL;
22487 tdIORequestBody_t *tdIORequestBody;
22488 satIOContext_t *satNewIOContext;
22489 bit32 status;
22490
22491 TI_DBG3(("tdsaDiscoveryIntStartIDDev: start\n"));
22492
22493 satDevData = satIOContext->pSatDevData;
22494
22495 /* allocate identify device command */
22496 satIntIo = satAllocIntIoResource( tiRoot,
22497 tiIORequest,
22498 satDevData,
22499 sizeof(agsaSATAIdentifyData_t), /* 512; size of identify device data */
22500 satIntIo);
22501
22502 if (satIntIo == agNULL)
22503 {
22504 TI_DBG2(("tdsaDiscoveryIntStartIDDev: can't alloacate\n"));
22505
22506 return tiError;
22507 }
22508
22509 /* fill in fields */
22510 /* real ttttttthe one worked and the same; 5/21/07/ */
22511 satIntIo->satOrgTiIORequest = tiIORequest; /* changed */
22512 tdIORequestBody = satIntIo->satIntRequestBody;
22513 satNewIOContext = &(tdIORequestBody->transport.SATA.satIOContext);
22514
22515 satNewIOContext->pSatDevData = satDevData;
22516 satNewIOContext->pFis = &(tdIORequestBody->transport.SATA.agSATARequestBody.fis.fisRegHostToDev);
22517 satNewIOContext->pScsiCmnd = &(satIntIo->satIntTiScsiXchg.scsiCmnd);
22518 satNewIOContext->pSense = &(tdIORequestBody->transport.SATA.sensePayload);
22519 satNewIOContext->pTiSenseData = &(tdIORequestBody->transport.SATA.tiSenseData);
22520 satNewIOContext->tiRequestBody = satIntIo->satIntRequestBody; /* key fix */
22521 satNewIOContext->interruptContext = tiInterruptContext;
22522 satNewIOContext->satIntIoContext = satIntIo;
22523
22524 satNewIOContext->ptiDeviceHandle = agNULL;
22525 satNewIOContext->satOrgIOContext = satIOContext; /* changed */
22526
22527 /* this is valid only for TD layer generated (not triggered by OS at all) IO */
22528 satNewIOContext->tiScsiXchg = &(satIntIo->satIntTiScsiXchg);
22529
22530
22531 TI_DBG6(("tdsaDiscoveryIntStartIDDev: OS satIOContext %p \n", satIOContext));
22532 TI_DBG6(("tdsaDiscoveryIntStartIDDev: TD satNewIOContext %p \n", satNewIOContext));
22533 TI_DBG6(("tdsaDiscoveryIntStartIDDev: OS tiScsiXchg %p \n", satIOContext->tiScsiXchg));
22534 TI_DBG6(("tdsaDiscoveryIntStartIDDev: TD tiScsiXchg %p \n", satNewIOContext->tiScsiXchg));
22535
22536
22537
22538 TI_DBG3(("tdsaDiscoveryIntStartIDDev: satNewIOContext %p tdIORequestBody %p\n", satNewIOContext, tdIORequestBody));
22539
22540 status = tdsaDiscoverySendIDDev(tiRoot,
22541 &satIntIo->satIntTiIORequest, /* New tiIORequest */
22542 tiDeviceHandle,
22543 satNewIOContext->tiScsiXchg, /* New tiScsiInitiatorRequest_t *tiScsiRequest, */
22544 satNewIOContext);
22545
22546 if (status != tiSuccess)
22547 {
22548 TI_DBG1(("tdsaDiscoveryIntStartIDDev: failed in sending %d\n", status));
22549
22550 satFreeIntIoResource( tiRoot,
22551 satDevData,
22552 satIntIo);
22553
22554 return tiError;
22555 }
22556
22557
22558 TI_DBG6(("tdsaDiscoveryIntStartIDDev: end\n"));
22559
22560 return status;
22561 }
22562
22563
22564 /*****************************************************************************/
22565 /*! \brief SAT implementation for tdsaDiscoverySendIDDev.
22566 *
22567 * This function prepares identify device data FIS and sends it to SATA device.
22568 *
22569 * \param tiRoot: Pointer to TISA initiator driver/port instance.
22570 * \param tiIORequest: Pointer to TISA I/O request context for this I/O.
22571 * \param tiDeviceHandle: Pointer to TISA device handle for this I/O.
22572 * \param tiScsiRequest: Pointer to TISA SCSI I/O request and SGL list.
22573 * \param satIOContext_t: Pointer to the SAT IO Context
22574 *
22575 * \return If command is started successfully
22576 * - \e tiSuccess: I/O request successfully initiated.
22577 * - \e tiBusy: No resources available, try again later.
22578 * - \e tiIONoDevice: Invalid device handle.
22579 * - \e tiError: Other errors.
22580 */
22581 /*****************************************************************************/
22582 GLOBAL bit32
22583 tdsaDiscoverySendIDDev(tiRoot_t *tiRoot,
22584 tiIORequest_t *tiIORequest,
22585 tiDeviceHandle_t *tiDeviceHandle,
22586 tiScsiInitiatorRequest_t *tiScsiRequest,
22587 satIOContext_t *satIOContext
22588 )
22589 {
22590 bit32 status;
22591 bit32 agRequestType;
22592 satDeviceData_t *pSatDevData;
22593 agsaFisRegHostToDevice_t *fis;
22594 #ifdef TD_DEBUG_ENABLE
22595 tdIORequestBody_t *tdIORequestBody;
22596 satInternalIo_t *satIntIoContext;
22597 #endif
22598
22599 pSatDevData = satIOContext->pSatDevData;
22600 fis = satIOContext->pFis;
22601 TI_DBG3(("tdsaDiscoverySendIDDev: start\n"));
22602 #ifdef TD_DEBUG_ENABLE
22603 satIntIoContext = satIOContext->satIntIoContext;
22604 tdIORequestBody = satIntIoContext->satIntRequestBody;
22605 #endif
22606 TI_DBG5(("tdsaDiscoverySendIDDev: satIOContext %p tdIORequestBody %p\n", satIOContext, tdIORequestBody));
22607
22608 fis->h.fisType = 0x27; /* Reg host to device */
22609 fis->h.c_pmPort = 0x80; /* C Bit is set */
22610 if (pSatDevData->satDeviceType == SATA_ATAPI_DEVICE)
22611 fis->h.command = SAT_IDENTIFY_PACKET_DEVICE; /* 0xA1 */
22612 else
22613 fis->h.command = SAT_IDENTIFY_DEVICE; /* 0xEC */
22614 fis->h.features = 0; /* FIS reserve */
22615 fis->d.lbaLow = 0; /* FIS LBA (7 :0 ) */
22616 fis->d.lbaMid = 0; /* FIS LBA (15:8 ) */
22617 fis->d.lbaHigh = 0; /* FIS LBA (23:16) */
22618 fis->d.device = 0; /* FIS LBA mode */
22619 fis->d.lbaLowExp = 0;
22620 fis->d.lbaMidExp = 0;
22621 fis->d.lbaHighExp = 0;
22622 fis->d.featuresExp = 0;
22623 fis->d.sectorCount = 0; /* FIS sector count (7:0) */
22624 fis->d.sectorCountExp = 0;
22625 fis->d.reserved4 = 0;
22626 fis->d.control = 0; /* FIS HOB bit clear */
22627 fis->d.reserved5 = 0;
22628
22629 agRequestType = AGSA_SATA_PROTOCOL_PIO_READ;
22630
22631 /* Initialize CB for SATA completion.
22632 */
22633 satIOContext->satCompleteCB = &tdsaDiscoveryStartIDDevCB;
22634
22635 /*
22636 * Prepare SGL and send FIS to LL layer.
22637 */
22638 satIOContext->reqType = agRequestType; /* Save it */
22639
22640 #ifdef TD_INTERNAL_DEBUG
22641 tdhexdump("tdsaDiscoverySendIDDev", (bit8 *)satIOContext->pFis, sizeof(agsaFisRegHostToDevice_t));
22642 #ifdef TD_DEBUG_ENABLE
22643 tdhexdump("tdsaDiscoverySendIDDev LL", (bit8 *)&(tdIORequestBody->transport.SATA.agSATARequestBody.fis.fisRegHostToDev), sizeof(agsaFisRegHostToDevice_t));
22644 #endif
22645 #endif
22646 status = sataLLIOStart( tiRoot,
22647 tiIORequest,
22648 tiDeviceHandle,
22649 tiScsiRequest,
22650 satIOContext);
22651 TI_DBG3(("tdsaDiscoverySendIDDev: end status %d\n", status));
22652 return status;
22653 }
22654
22655
22656 /*****************************************************************************
22657 *! \brief tdsaDiscoveryStartIDDevCB
22658 *
22659 * This routine is a callback function for tdsaDiscoverySendIDDev()
22660 * Using Identify Device Data, this function finds whether devicedata is
22661 * new or old. If new, add it to the devicelist. This is done as a part
22662 * of discovery.
22663 *
22664 * \param agRoot: Handles for this instance of SAS/SATA hardware
22665 * \param agIORequest: Pointer to the LL I/O request context for this I/O.
22666 * \param agIOStatus: Status of completed I/O.
22667 * \param agFirstDword:Pointer to the four bytes of FIS.
22668 * \param agIOInfoLen: Length in bytes of overrun/underrun residual or FIS
22669 * length.
22670 * \param agParam: Additional info based on status.
22671 * \param ioContext: Pointer to satIOContext_t.
22672 *
22673 * \return: none
22674 *
22675 *****************************************************************************/
22676 void tdsaDiscoveryStartIDDevCB(
22677 agsaRoot_t *agRoot,
22678 agsaIORequest_t *agIORequest,
22679 bit32 agIOStatus,
22680 agsaFisHeader_t *agFirstDword,
22681 bit32 agIOInfoLen,
22682 void *agParam,
22683 void *ioContext
22684 )
22685 {
22686 /*
22687 In the process of SAT_IDENTIFY_DEVICE during discovery
22688 */
22689 tdsaRootOsData_t *osData = (tdsaRootOsData_t *)agRoot->osData;
22690 tiRoot_t *tiRoot = (tiRoot_t *)osData->tiRoot;
22691 tdsaRoot_t *tdsaRoot = (tdsaRoot_t *) tiRoot->tdData;
22692 tdsaContext_t *tdsaAllShared = (tdsaContext_t *)&tdsaRoot->tdsaAllShared;
22693 tdIORequestBody_t *tdIORequestBody;
22694 tdIORequestBody_t *tdOrgIORequestBody;
22695 satIOContext_t *satIOContext;
22696 satIOContext_t *satOrgIOContext;
22697 satIOContext_t *satNewIOContext;
22698 satInternalIo_t *satIntIo;
22699 satInternalIo_t *satNewIntIo = agNULL;
22700 satDeviceData_t *satDevData;
22701 tiIORequest_t *tiOrgIORequest = agNULL;
22702
22703 #ifdef TD_DEBUG_ENABLE
22704 bit32 ataStatus = 0;
22705 bit32 ataError;
22706 agsaFisPioSetupHeader_t *satPIOSetupHeader = agNULL;
22707 #endif
22708 agsaSATAIdentifyData_t *pSATAIdData;
22709 bit16 *tmpptr, tmpptr_tmp;
22710 bit32 x;
22711 tdsaDeviceData_t *oneDeviceData = agNULL;
22712 void *sglVirtualAddr;
22713 tdsaPortContext_t *onePortContext = agNULL;
22714 tiPortalContext_t *tiPortalContext = agNULL;
22715 bit32 retry_status;
22716
22717 TI_DBG3(("tdsaDiscoveryStartIDDevCB: start\n"));
22718
22719 tdIORequestBody = (tdIORequestBody_t *)agIORequest->osData;
22720 satIOContext = (satIOContext_t *) ioContext;
22721 satIntIo = satIOContext->satIntIoContext;
22722 satDevData = satIOContext->pSatDevData;
22723 oneDeviceData = (tdsaDeviceData_t *)tdIORequestBody->tiDevHandle->tdData;
22724 TI_DBG3(("tdsaDiscoveryStartIDDevCB: did %d\n", oneDeviceData->id));
22725 onePortContext = oneDeviceData->tdPortContext;
22726 if (onePortContext == agNULL)
22727 {
22728 TI_DBG1(("tdsaDiscoveryStartIDDevCB: onePortContext is NULL\n"));
22729 return;
22730 }
22731 tiPortalContext= onePortContext->tiPortalContext;
22732
22733 satDevData->IDDeviceValid = agFALSE;
22734
22735 if (satIntIo == agNULL)
22736 {
22737 TI_DBG1(("tdsaDiscoveryStartIDDevCB: External, OS generated\n"));
22738 TI_DBG1(("tdsaDiscoveryStartIDDevCB: Not possible case\n"));
22739 satOrgIOContext = satIOContext;
22740 tdOrgIORequestBody = (tdIORequestBody_t *)satOrgIOContext->tiRequestBody;
22741
22742 satDecrementPendingIO(tiRoot, tdsaAllShared, satIOContext);
22743
22744 satFreeIntIoResource( tiRoot,
22745 satDevData,
22746 satIntIo);
22747
22748 /* clean up TD layer's IORequestBody */
22749 ostiFreeMemory(
22750 tiRoot,
22751 tdOrgIORequestBody->IOType.InitiatorTMIO.osMemHandle,
22752 sizeof(tdIORequestBody_t)
22753 );
22754 return;
22755 }
22756 else
22757 {
22758 TI_DBG3(("tdsaDiscoveryStartIDDevCB: Internal, TD generated\n"));
22759 satOrgIOContext = satIOContext->satOrgIOContext;
22760 if (satOrgIOContext == agNULL)
22761 {
22762 TI_DBG6(("tdsaDiscoveryStartIDDevCB: satOrgIOContext is NULL\n"));
22763 return;
22764 }
22765 else
22766 {
22767 TI_DBG6(("tdsaDiscoveryStartIDDevCB: satOrgIOContext is NOT NULL\n"));
22768 tdOrgIORequestBody = (tdIORequestBody_t *)satOrgIOContext->tiRequestBody;
22769 sglVirtualAddr = satIntIo->satIntTiScsiXchg.sglVirtualAddr;
22770 }
22771 }
22772
22773 tiOrgIORequest = tdIORequestBody->tiIORequest;
22774 tdIORequestBody->ioCompleted = agTRUE;
22775 tdIORequestBody->ioStarted = agFALSE;
22776
22777 TI_DBG3(("tdsaDiscoveryStartIDDevCB: satOrgIOContext->pid %d\n", satOrgIOContext->pid));
22778
22779 /* protect against double completion for old port */
22780 if (satOrgIOContext->pid != oneDeviceData->tdPortContext->id)
22781 {
22782 TI_DBG3(("tdsaDiscoveryStartIDDevCB: incorrect pid\n"));
22783 TI_DBG3(("tdsaDiscoveryStartIDDevCB: satOrgIOContext->pid %d\n", satOrgIOContext->pid));
22784 TI_DBG3(("tdsaDiscoveryStartIDDevCB: tiPortalContext pid %d\n", oneDeviceData->tdPortContext->id));
22785
22786 satDecrementPendingIO(tiRoot, tdsaAllShared, satIOContext);
22787
22788 satFreeIntIoResource( tiRoot,
22789 satDevData,
22790 satIntIo);
22791
22792 /* clean up TD layer's IORequestBody */
22793 ostiFreeMemory(
22794 tiRoot,
22795 tdOrgIORequestBody->IOType.InitiatorTMIO.osMemHandle,
22796 sizeof(tdIORequestBody_t)
22797 );
22798
22799 return;
22800 }
22801
22802 /* completion after portcontext is invalidated */
22803 if (onePortContext != agNULL)
22804 {
22805 if (onePortContext->valid == agFALSE)
22806 {
22807 TI_DBG1(("tdsaDiscoveryStartIDDevCB: portcontext is invalid\n"));
22808 TI_DBG1(("tdsaDiscoveryStartIDDevCB: onePortContext->id pid %d\n", onePortContext->id));
22809 satDecrementPendingIO(tiRoot, tdsaAllShared, satIOContext);
22810
22811 satFreeIntIoResource( tiRoot,
22812 satDevData,
22813 satIntIo);
22814
22815 /* clean up TD layer's IORequestBody */
22816 ostiFreeMemory(
22817 tiRoot,
22818 tdOrgIORequestBody->IOType.InitiatorTMIO.osMemHandle,
22819 sizeof(tdIORequestBody_t)
22820 );
22821
22822 /* no notification to OS layer */
22823 return;
22824 }
22825 }
22826
22827 if (agFirstDword == agNULL && agIOStatus != OSSA_IO_SUCCESS)
22828 {
22829 TI_DBG1(("tdsaDiscoveryStartIDDevCB: agFirstDword is NULL when error, status %d\n", agIOStatus));
22830 TI_DBG1(("tdsaDiscoveryStartIDDevCB: did %d\n", oneDeviceData->id));
22831
22832 if (tdsaAllShared->ResetInDiscovery != 0 && satDevData->ID_Retries < SATA_ID_DEVICE_DATA_RETRIES)
22833 {
22834 satIOContext->pSatDevData->satPendingNONNCQIO--;
22835 satIOContext->pSatDevData->satPendingIO--;
22836 retry_status = sataLLIOStart(tiRoot,
22837 &satIntIo->satIntTiIORequest,
22838 &(oneDeviceData->tiDeviceHandle),
22839 satIOContext->tiScsiXchg,
22840 satIOContext);
22841 if (retry_status != tiSuccess)
22842 {
22843 /* simply give up */
22844 satDevData->ID_Retries = 0;
22845 satDecrementPendingIO(tiRoot, tdsaAllShared, satIOContext);
22846
22847 satFreeIntIoResource( tiRoot,
22848 satDevData,
22849 satIntIo);
22850
22851 /* clean up TD layer's IORequestBody */
22852 ostiFreeMemory(
22853 tiRoot,
22854 tdOrgIORequestBody->IOType.InitiatorTMIO.osMemHandle,
22855 sizeof(tdIORequestBody_t)
22856 );
22857 return;
22858 }
22859 satDevData->ID_Retries++;
22860 tdIORequestBody->ioCompleted = agFALSE;
22861 tdIORequestBody->ioStarted = agTRUE;
22862 return;
22863 }
22864 else
22865 {
22866 satDecrementPendingIO(tiRoot, tdsaAllShared, satIOContext);
22867 satFreeIntIoResource( tiRoot,
22868 satDevData,
22869 satIntIo);
22870
22871 /* clean up TD layer's IORequestBody */
22872 ostiFreeMemory(
22873 tiRoot,
22874 tdOrgIORequestBody->IOType.InitiatorTMIO.osMemHandle,
22875 sizeof(tdIORequestBody_t)
22876 );
22877 if (tdsaAllShared->ResetInDiscovery != 0)
22878 {
22879 /* ResetInDiscovery in on */
22880 if (satDevData->NumOfIDRetries <= 0)
22881 {
22882 satDevData->NumOfIDRetries++;
22883 satDevData->ID_Retries = 0;
22884 /* send link reset */
22885 tdsaPhyControlSend(tiRoot,
22886 oneDeviceData,
22887 SMP_PHY_CONTROL_HARD_RESET,
22888 agNULL,
22889 tdsaRotateQnumber(tiRoot, oneDeviceData)
22890 );
22891 }
22892 }
22893 return;
22894 }
22895 }
22896
22897 if (agIOStatus == OSSA_IO_ABORTED ||
22898 agIOStatus == OSSA_IO_UNDERFLOW ||
22899 agIOStatus == OSSA_IO_XFER_ERROR_BREAK ||
22900 agIOStatus == OSSA_IO_XFER_ERROR_PHY_NOT_READY ||
22901 agIOStatus == OSSA_IO_OPEN_CNX_ERROR_PROTOCOL_NOT_SUPPORTED ||
22902 agIOStatus == OSSA_IO_OPEN_CNX_ERROR_BREAK ||
22903 agIOStatus == OSSA_IO_OPEN_CNX_ERROR_IT_NEXUS_LOSS ||
22904 agIOStatus == OSSA_IO_OPEN_CNX_ERROR_BAD_DESTINATION ||
22905 agIOStatus == OSSA_IO_OPEN_CNX_ERROR_CONNECTION_RATE_NOT_SUPPORTED ||
22906 agIOStatus == OSSA_IO_OPEN_CNX_ERROR_STP_RESOURCES_BUSY ||
22907 agIOStatus == OSSA_IO_OPEN_CNX_ERROR_WRONG_DESTINATION ||
22908 agIOStatus == OSSA_IO_XFER_ERROR_NAK_RECEIVED ||
22909 agIOStatus == OSSA_IO_XFER_ERROR_DMA ||
22910 agIOStatus == OSSA_IO_XFER_ERROR_SATA_LINK_TIMEOUT ||
22911 agIOStatus == OSSA_IO_XFER_ERROR_REJECTED_NCQ_MODE ||
22912 agIOStatus == OSSA_IO_XFER_OPEN_RETRY_TIMEOUT ||
22913 agIOStatus == OSSA_IO_NO_DEVICE ||
22914 agIOStatus == OSSA_IO_OPEN_CNX_ERROR_ZONE_VIOLATION ||
22915 agIOStatus == OSSA_IO_PORT_IN_RESET ||
22916 agIOStatus == OSSA_IO_DS_NON_OPERATIONAL ||
22917 agIOStatus == OSSA_IO_DS_IN_RECOVERY ||
22918 agIOStatus == OSSA_IO_DS_IN_ERROR
22919 )
22920 {
22921 TI_DBG1(("tdsaDiscoveryStartIDDevCB: OSSA_IO_OPEN_CNX_ERROR 0x%x\n", agIOStatus));
22922 if (tdsaAllShared->ResetInDiscovery != 0 && satDevData->ID_Retries < SATA_ID_DEVICE_DATA_RETRIES)
22923 {
22924 satIOContext->pSatDevData->satPendingNONNCQIO--;
22925 satIOContext->pSatDevData->satPendingIO--;
22926 retry_status = sataLLIOStart(tiRoot,
22927 &satIntIo->satIntTiIORequest,
22928 &(oneDeviceData->tiDeviceHandle),
22929 satIOContext->tiScsiXchg,
22930 satIOContext);
22931 if (retry_status != tiSuccess)
22932 {
22933 /* simply give up */
22934 satDevData->ID_Retries = 0;
22935 satDecrementPendingIO(tiRoot, tdsaAllShared, satIOContext);
22936
22937 satFreeIntIoResource( tiRoot,
22938 satDevData,
22939 satIntIo);
22940
22941 /* clean up TD layer's IORequestBody */
22942 ostiFreeMemory(
22943 tiRoot,
22944 tdOrgIORequestBody->IOType.InitiatorTMIO.osMemHandle,
22945 sizeof(tdIORequestBody_t)
22946 );
22947 return;
22948 }
22949 satDevData->ID_Retries++;
22950 tdIORequestBody->ioCompleted = agFALSE;
22951 tdIORequestBody->ioStarted = agTRUE;
22952 return;
22953 }
22954 else
22955 {
22956 satDecrementPendingIO(tiRoot, tdsaAllShared, satIOContext);
22957 satFreeIntIoResource( tiRoot,
22958 satDevData,
22959 satIntIo);
22960
22961 /* clean up TD layer's IORequestBody */
22962 ostiFreeMemory(
22963 tiRoot,
22964 tdOrgIORequestBody->IOType.InitiatorTMIO.osMemHandle,
22965 sizeof(tdIORequestBody_t)
22966 );
22967 if (tdsaAllShared->ResetInDiscovery != 0)
22968 {
22969 /* ResetInDiscovery in on */
22970 if (satDevData->NumOfIDRetries <= 0)
22971 {
22972 satDevData->NumOfIDRetries++;
22973 satDevData->ID_Retries = 0;
22974 /* send link reset */
22975 tdsaPhyControlSend(tiRoot,
22976 oneDeviceData,
22977 SMP_PHY_CONTROL_HARD_RESET,
22978 agNULL,
22979 tdsaRotateQnumber(tiRoot, oneDeviceData)
22980 );
22981 }
22982 }
22983 return;
22984 }
22985 }
22986
22987 if ( agIOStatus != OSSA_IO_SUCCESS ||
22988 (agIOStatus == OSSA_IO_SUCCESS && agFirstDword != agNULL && agIOInfoLen != 0)
22989 )
22990 {
22991 #ifdef TD_DEBUG_ENABLE
22992 /* only agsaFisPioSetup_t is expected */
22993 satPIOSetupHeader = (agsaFisPioSetupHeader_t *)&(agFirstDword->PioSetup);
22994 ataStatus = satPIOSetupHeader->status; /* ATA Status register */
22995 ataError = satPIOSetupHeader->error; /* ATA Eror register */
22996 #endif
22997 TI_DBG1(("tdsaDiscoveryStartIDDevCB: ataStatus 0x%x ataError 0x%x\n", ataStatus, ataError));
22998
22999 if (tdsaAllShared->ResetInDiscovery != 0 && satDevData->ID_Retries < SATA_ID_DEVICE_DATA_RETRIES)
23000 {
23001 satIOContext->pSatDevData->satPendingNONNCQIO--;
23002 satIOContext->pSatDevData->satPendingIO--;
23003 retry_status = sataLLIOStart(tiRoot,
23004 &satIntIo->satIntTiIORequest,
23005 &(oneDeviceData->tiDeviceHandle),
23006 satIOContext->tiScsiXchg,
23007 satIOContext);
23008 if (retry_status != tiSuccess)
23009 {
23010 /* simply give up */
23011 satDevData->ID_Retries = 0;
23012 satDecrementPendingIO(tiRoot, tdsaAllShared, satIOContext);
23013
23014 satFreeIntIoResource( tiRoot,
23015 satDevData,
23016 satIntIo);
23017
23018 /* clean up TD layer's IORequestBody */
23019 ostiFreeMemory(
23020 tiRoot,
23021 tdOrgIORequestBody->IOType.InitiatorTMIO.osMemHandle,
23022 sizeof(tdIORequestBody_t)
23023 );
23024 return;
23025 }
23026 satDevData->ID_Retries++;
23027 tdIORequestBody->ioCompleted = agFALSE;
23028 tdIORequestBody->ioStarted = agTRUE;
23029 return;
23030 }
23031 else
23032 {
23033 satDecrementPendingIO(tiRoot, tdsaAllShared, satIOContext);
23034 satFreeIntIoResource( tiRoot,
23035 satDevData,
23036 satIntIo);
23037
23038 /* clean up TD layer's IORequestBody */
23039 ostiFreeMemory(
23040 tiRoot,
23041 tdOrgIORequestBody->IOType.InitiatorTMIO.osMemHandle,
23042 sizeof(tdIORequestBody_t)
23043 );
23044 if (tdsaAllShared->ResetInDiscovery != 0)
23045 {
23046 /* ResetInDiscovery in on */
23047 if (satDevData->NumOfIDRetries <= 0)
23048 {
23049 satDevData->NumOfIDRetries++;
23050 satDevData->ID_Retries = 0;
23051 /* send link reset */
23052 tdsaPhyControlSend(tiRoot,
23053 oneDeviceData,
23054 SMP_PHY_CONTROL_HARD_RESET,
23055 agNULL,
23056 tdsaRotateQnumber(tiRoot, oneDeviceData)
23057 );
23058 }
23059 }
23060 return;
23061 }
23062 }
23063
23064
23065 /* success */
23066 TI_DBG3(("tdsaDiscoveryStartIDDevCB: Success\n"));
23067 TI_DBG3(("tdsaDiscoveryStartIDDevCB: Success did %d\n", oneDeviceData->id));
23068
23069 /* Convert to host endian */
23070 tmpptr = (bit16*)sglVirtualAddr;
23071 for (x=0; x < sizeof(agsaSATAIdentifyData_t)/sizeof(bit16); x++)
23072 {
23073 OSSA_READ_LE_16(AGROOT, &tmpptr_tmp, tmpptr, 0);
23074 *tmpptr = tmpptr_tmp;
23075 tmpptr++;
23076 }
23077
23078 pSATAIdData = (agsaSATAIdentifyData_t *)sglVirtualAddr;
23079 //tdhexdump("satAddSATAIDDevCB before", (bit8 *)pSATAIdData, sizeof(agsaSATAIdentifyData_t));
23080
23081 TI_DBG5(("tdsaDiscoveryStartIDDevCB: OS satOrgIOContext %p \n", satOrgIOContext));
23082 TI_DBG5(("tdsaDiscoveryStartIDDevCB: TD satIOContext %p \n", satIOContext));
23083 TI_DBG5(("tdsaDiscoveryStartIDDevCB: OS tiScsiXchg %p \n", satOrgIOContext->tiScsiXchg));
23084 TI_DBG5(("tdsaDiscoveryStartIDDevCB: TD tiScsiXchg %p \n", satIOContext->tiScsiXchg));
23085
23086
23087 /* copy ID Dev data to satDevData */
23088 satDevData->satIdentifyData = *pSATAIdData;
23089 satDevData->IDDeviceValid = agTRUE;
23090
23091 #ifdef TD_INTERNAL_DEBUG
23092 tdhexdump("tdsaDiscoveryStartIDDevCB ID Dev data",(bit8 *)pSATAIdData, sizeof(agsaSATAIdentifyData_t));
23093 tdhexdump("tdsaDiscoveryStartIDDevCB Device ID Dev data",(bit8 *)&satDevData->satIdentifyData, sizeof(agsaSATAIdentifyData_t));
23094 #endif
23095
23096 /* set satDevData fields from IndentifyData */
23097 satSetDevInfo(satDevData,pSATAIdData);
23098 satDecrementPendingIO(tiRoot, tdsaAllShared, satIOContext);
23099
23100 satFreeIntIoResource( tiRoot,
23101 satDevData,
23102 satIntIo);
23103
23104 if (satDevData->satDeviceType == SATA_ATAPI_DEVICE)
23105 {
23106 /* send the Set Feature ATA command to ATAPI device for enbling PIO and DMA transfer mode*/
23107 satNewIntIo = satAllocIntIoResource( tiRoot,
23108 tiOrgIORequest,
23109 satDevData,
23110 0,
23111 satNewIntIo);
23112
23113 if (satNewIntIo == agNULL)
23114 {
23115 TI_DBG1(("tdsaDiscoveryStartIDDevCB: momory allocation fails\n"));
23116 /* clean up TD layer's IORequestBody */
23117 ostiFreeMemory(
23118 tiRoot,
23119 tdOrgIORequestBody->IOType.InitiatorTMIO.osMemHandle,
23120 sizeof(tdIORequestBody_t)
23121 );
23122 return;
23123 } /* end memory allocation */
23124
23125 satNewIOContext = satPrepareNewIO(satNewIntIo,
23126 tiOrgIORequest,
23127 satDevData,
23128 agNULL,
23129 satOrgIOContext
23130 );
23131 /* enable PIO mode, then enable Ultra DMA mode in the satSetFeaturesCB callback function*/
23132 retry_status = satSetFeatures(tiRoot,
23133 &satNewIntIo->satIntTiIORequest,
23134 satNewIOContext->ptiDeviceHandle,
23135 &satNewIntIo->satIntTiScsiXchg, /* orginal from OS layer */
23136 satNewIOContext,
23137 agFALSE);
23138 if (retry_status != tiSuccess)
23139 {
23140 satFreeIntIoResource(tiRoot, satDevData, satIntIo);
23141 /* clean up TD layer's IORequestBody */
23142 ostiFreeMemory(
23143 tiRoot,
23144 tdOrgIORequestBody->IOType.InitiatorTMIO.osMemHandle,
23145 sizeof(tdIORequestBody_t)
23146 );
23147 }
23148 }
23149 else
23150 {
23151 /* clean up TD layer's IORequestBody */
23152 ostiFreeMemory(
23153 tiRoot,
23154 tdOrgIORequestBody->IOType.InitiatorTMIO.osMemHandle,
23155 sizeof(tdIORequestBody_t)
23156 );
23157 if (onePortContext != agNULL)
23158 {
23159 if (onePortContext->DiscoveryState == ITD_DSTATE_COMPLETED)
23160 {
23161 TI_DBG1(("tdsaDiscoveryStartIDDevCB: ID completed after discovery is done; tiDeviceArrival\n"));
23162 /* in case registration is finished after discovery is finished */
23163 ostiInitiatorEvent(
23164 tiRoot,
23165 tiPortalContext,
23166 agNULL,
23167 tiIntrEventTypeDeviceChange,
23168 tiDeviceArrival,
23169 agNULL
23170 );
23171 }
23172 }
23173 else
23174 {
23175 TI_DBG1(("tdsaDiscoveryStartIDDevCB: onePortContext is NULL, wrong\n"));
23176 }
23177 }
23178 TI_DBG3(("tdsaDiscoveryStartIDDevCB: end\n"));
23179 return;
23180 }
23181 /*****************************************************************************
23182 *! \brief satAbort
23183 *
23184 * This routine does local abort for outstanding FIS.
23185 *
23186 * \param agRoot: Handles for this instance of SAS/SATA hardware
23187 * \param satIOContext: Pointer to satIOContext_t.
23188 *
23189 * \return: none
23190 *
23191 *****************************************************************************/
23192 GLOBAL void satAbort(agsaRoot_t *agRoot,
23193 satIOContext_t *satIOContext)
23194 {
23195 tdsaRootOsData_t *osData = (tdsaRootOsData_t *)agRoot->osData;
23196 tiRoot_t *tiRoot = (tiRoot_t *)osData->tiRoot;
23197 tdIORequestBody_t *tdIORequestBody; /* io to be aborted */
23198 tdIORequestBody_t *tdAbortIORequestBody; /* abort io itself */
23199 agsaIORequest_t *agToBeAbortedIORequest; /* io to be aborted */
23200 agsaIORequest_t *agAbortIORequest; /* abort io itself */
23201 bit32 PhysUpper32;
23202 bit32 PhysLower32;
23203 bit32 memAllocStatus;
23204 void *osMemHandle;
23205
23206 TI_DBG1(("satAbort: start\n"));
23207
23208 if (satIOContext == agNULL)
23209 {
23210 TI_DBG1(("satAbort: satIOContext is NULL, wrong\n"));
23211 return;
23212 }
23213 tdIORequestBody = (tdIORequestBody_t *)satIOContext->tiRequestBody;
23214 agToBeAbortedIORequest = (agsaIORequest_t *)&(tdIORequestBody->agIORequest);
23215 /* allocating agIORequest for abort itself */
23216 memAllocStatus = ostiAllocMemory(
23217 tiRoot,
23218 &osMemHandle,
23219 (void **)&tdAbortIORequestBody,
23220 &PhysUpper32,
23221 &PhysLower32,
23222 8,
23223 sizeof(tdIORequestBody_t),
23224 agTRUE
23225 );
23226
23227 if (memAllocStatus != tiSuccess)
23228 {
23229 /* let os process IO */
23230 TI_DBG1(("satAbort: ostiAllocMemory failed...\n"));
23231 return;
23232 }
23233
23234 if (tdAbortIORequestBody == agNULL)
23235 {
23236 /* let os process IO */
23237 TI_DBG1(("satAbort: ostiAllocMemory returned NULL tdAbortIORequestBody\n"));
23238 return;
23239 }
23240 /* setup task management structure */
23241 tdAbortIORequestBody->IOType.InitiatorTMIO.osMemHandle = osMemHandle;
23242 tdAbortIORequestBody->tiDevHandle = tdIORequestBody->tiDevHandle;
23243
23244 /* initialize agIORequest */
23245 agAbortIORequest = &(tdAbortIORequestBody->agIORequest);
23246 agAbortIORequest->osData = (void *) tdAbortIORequestBody;
23247 agAbortIORequest->sdkData = agNULL; /* LL takes care of this */
23248
23249
23250 /*
23251 * Issue abort
23252 */
23253 saSATAAbort( agRoot, agAbortIORequest, 0, agNULL, 0, agToBeAbortedIORequest, agNULL );
23254
23255
23256 TI_DBG1(("satAbort: end\n"));
23257 return;
23258 }
23259
23260 /*****************************************************************************
23261 *! \brief satSATADeviceReset
23262 *
23263 * This routine is called to reset all phys of port which a device belongs to
23264 *
23265 * \param tiRoot: Pointer to TISA initiator driver/port instance.
23266 * \param oneDeviceData: Pointer to the device data.
23267 * \param flag: reset flag
23268 *
23269 * \return:
23270 *
23271 * none
23272 *
23273 *****************************************************************************/
23274 osGLOBAL void
23275 satSATADeviceReset( tiRoot_t *tiRoot,
23276 tdsaDeviceData_t *oneDeviceData,
23277 bit32 flag)
23278 {
23279 agsaRoot_t *agRoot;
23280 tdsaPortContext_t *onePortContext;
23281 bit32 i;
23282
23283 TI_DBG1(("satSATADeviceReset: start\n"));
23284 agRoot = oneDeviceData->agRoot;
23285 onePortContext = oneDeviceData->tdPortContext;
23286
23287 if (agRoot == agNULL)
23288 {
23289 TI_DBG1(("satSATADeviceReset: Error!!! agRoot is NULL\n"));
23290 return;
23291 }
23292 if (onePortContext == agNULL)
23293 {
23294 TI_DBG1(("satSATADeviceReset: Error!!! onePortContext is NULL\n"));
23295 return;
23296 }
23297
23298 for(i=0;i<TD_MAX_NUM_PHYS;i++)
23299 {
23300 if (onePortContext->PhyIDList[i] == agTRUE)
23301 {
23302 saLocalPhyControl(agRoot, agNULL, tdsaRotateQnumber(tiRoot, agNULL), i, flag, agNULL);
23303 }
23304 }
23305
23306 return;
23307 }
23308
23309 #endif /* #ifdef SATA_ENABLE */
Cache object: bc9901e73e76cec866ae0c804b3f2c78
|