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 #include <dev/pms/config.h>
32
33 #include <dev/pms/freebsd/driver/common/osenv.h>
34 #include <dev/pms/freebsd/driver/common/ostypes.h>
35 #include <dev/pms/freebsd/driver/common/osdebug.h>
36
37 #ifdef SATA_ENABLE
38
39 #include <dev/pms/RefTisa/sallsdk/api/sa.h>
40 #include <dev/pms/RefTisa/sallsdk/api/saapi.h>
41 #include <dev/pms/RefTisa/sallsdk/api/saosapi.h>
42
43 #include <dev/pms/RefTisa/tisa/api/titypes.h>
44 #include <dev/pms/RefTisa/tisa/api/ostiapi.h>
45 #include <dev/pms/RefTisa/tisa/api/tiapi.h>
46 #include <dev/pms/RefTisa/tisa/api/tiglobal.h>
47
48 #ifdef FDS_SM
49 #include <dev/pms/RefTisa/sat/api/sm.h>
50 #include <dev/pms/RefTisa/sat/api/smapi.h>
51 #include <dev/pms/RefTisa/sat/api/tdsmapi.h>
52 #endif
53
54 #ifdef FDS_DM
55 #include <dev/pms/RefTisa/discovery/api/dm.h>
56 #include <dev/pms/RefTisa/discovery/api/dmapi.h>
57 #include <dev/pms/RefTisa/discovery/api/tddmapi.h>
58 #endif
59
60 #include <dev/pms/RefTisa/tisa/sassata/sas/common/tdtypes.h>
61 #include <dev/pms/freebsd/driver/common/osstring.h>
62 #include <dev/pms/RefTisa/tisa/sassata/common/tdutil.h>
63
64 #ifdef INITIATOR_DRIVER
65 #include <dev/pms/RefTisa/tisa/sassata/sas/ini/itdtypes.h>
66 #include <dev/pms/RefTisa/tisa/sassata/sas/ini/itddefs.h>
67 #include <dev/pms/RefTisa/tisa/sassata/sas/ini/itdglobl.h>
68 #endif
69
70 #ifdef TARGET_DRIVER
71 #include <dev/pms/RefTisa/tisa/sassata/sas/tgt/ttdglobl.h>
72 #include <dev/pms/RefTisa/tisa/sassata/sas/tgt/ttdxchg.h>
73 #include <dev/pms/RefTisa/tisa/sassata/sas/tgt/ttdtypes.h>
74 #endif
75
76 #include <dev/pms/RefTisa/tisa/sassata/common/tdsatypes.h>
77 #include <dev/pms/RefTisa/tisa/sassata/common/tdproto.h>
78
79 #include <dev/pms/RefTisa/tisa/sassata/sata/host/sat.h>
80 #include <dev/pms/RefTisa/tisa/sassata/sata/host/satproto.h>
81
82 /*****************************************************************************
83 *! \brief satIOStart
84 *
85 * This routine is called to initiate a new SCSI request to SATL.
86 *
87 * \param tiRoot: Pointer to TISA initiator driver/port instance.
88 * \param tiIORequest: Pointer to TISA I/O request context for this I/O.
89 * \param tiDeviceHandle: Pointer to TISA device handle for this I/O.
90 * \param tiScsiRequest: Pointer to TISA SCSI I/O request and SGL list.
91 * \param satIOContext_t: Pointer to the SAT IO Context
92 *
93 * \return:
94 *
95 * \e tiSuccess: I/O request successfully initiated.
96 * \e tiBusy: No resources available, try again later.
97 * \e tiIONoDevice: Invalid device handle.
98 * \e tiError: Other errors that prevent the I/O request to be started.
99 *
100 *
101 *****************************************************************************/
satIOStart(tiRoot_t * tiRoot,tiIORequest_t * tiIORequest,tiDeviceHandle_t * tiDeviceHandle,tiScsiInitiatorRequest_t * tiScsiRequest,satIOContext_t * satIOContext)102 GLOBAL bit32 satIOStart(
103 tiRoot_t *tiRoot,
104 tiIORequest_t *tiIORequest,
105 tiDeviceHandle_t *tiDeviceHandle,
106 tiScsiInitiatorRequest_t *tiScsiRequest,
107 satIOContext_t *satIOContext
108 )
109 {
110
111 bit32 retVal = tiSuccess;
112 satDeviceData_t *pSatDevData;
113 scsiRspSense_t *pSense;
114 tiIniScsiCmnd_t *scsiCmnd;
115 tiLUN_t *pLun;
116 satInternalIo_t *pSatIntIo;
117 #ifdef TD_DEBUG_ENABLE
118 tdsaDeviceData_t *oneDeviceData;
119 #endif
120
121 pSense = satIOContext->pSense;
122 pSatDevData = satIOContext->pSatDevData;
123 scsiCmnd = &tiScsiRequest->scsiCmnd;
124 pLun = &scsiCmnd->lun;
125
126 /*
127 * Reject all other LUN other than LUN 0.
128 */
129 if ( ((pLun->lun[0] | pLun->lun[1] | pLun->lun[2] | pLun->lun[3] |
130 pLun->lun[4] | pLun->lun[5] | pLun->lun[6] | pLun->lun[7] ) != 0) &&
131 (scsiCmnd->cdb[0] != SCSIOPC_INQUIRY)
132 )
133 {
134 TI_DBG1(("satIOStart: *** REJECT *** LUN not zero, cdb[0]=0x%x tiIORequest=%p tiDeviceHandle=%p\n",
135 scsiCmnd->cdb[0], tiIORequest, tiDeviceHandle));
136 satSetSensePayload( pSense,
137 SCSI_SNSKEY_ILLEGAL_REQUEST,
138 0,
139 SCSI_SNSCODE_LOGICAL_NOT_SUPPORTED,
140 satIOContext);
141
142 ostiInitiatorIOCompleted( tiRoot,
143 tiIORequest,
144 tiIOSuccess,
145 SCSI_STAT_CHECK_CONDITION,
146 satIOContext->pTiSenseData,
147 satIOContext->interruptContext );
148 retVal = tiSuccess;
149 goto ext;
150 }
151
152 TI_DBG6(("satIOStart: satPendingIO %d satNCQMaxIO %d\n",pSatDevData->satPendingIO, pSatDevData->satNCQMaxIO ));
153
154 /* this may happen after tiCOMReset until OS sends inquiry */
155 if (pSatDevData->IDDeviceValid == agFALSE && (scsiCmnd->cdb[0] != SCSIOPC_INQUIRY))
156 {
157 #ifdef TD_DEBUG_ENABLE
158 oneDeviceData = (tdsaDeviceData_t *)tiDeviceHandle->tdData;
159 #endif
160 TI_DBG1(("satIOStart: invalid identify device data did %d\n", oneDeviceData->id));
161 retVal = tiIONoDevice;
162 goto ext;
163 }
164 /*
165 * Check if we need to return BUSY, i.e. recovery in progress
166 */
167 if (pSatDevData->satDriveState == SAT_DEV_STATE_IN_RECOVERY)
168 {
169 #ifdef TD_DEBUG_ENABLE
170 oneDeviceData = (tdsaDeviceData_t *)tiDeviceHandle->tdData;
171 #endif
172 TI_DBG1(("satIOStart: IN RECOVERY STATE cdb[0]=0x%x tiIORequest=%p tiDeviceHandle=%p\n",
173 scsiCmnd->cdb[0], tiIORequest, tiDeviceHandle));
174 TI_DBG1(("satIOStart: IN RECOVERY STATE did %d\n", oneDeviceData->id));
175
176 TI_DBG1(("satIOStart: device %p satPendingIO %d satNCQMaxIO %d\n",pSatDevData, pSatDevData->satPendingIO, pSatDevData->satNCQMaxIO ));
177 TI_DBG1(("satIOStart: device %p satPendingNCQIO %d satPendingNONNCQIO %d\n",pSatDevData, pSatDevData->satPendingNCQIO, pSatDevData->satPendingNONNCQIO));
178 retVal = tiError;
179 goto ext;
180 // return tiBusy;
181 }
182
183 if (pSatDevData->satDeviceType == SATA_ATAPI_DEVICE)
184 {
185 if (scsiCmnd->cdb[0] == SCSIOPC_REPORT_LUN)
186 {
187 return satReportLun(tiRoot, tiIORequest, tiDeviceHandle, tiScsiRequest, satIOContext);
188 }
189 else
190 {
191 return satPacket(tiRoot, tiIORequest, tiDeviceHandle, tiScsiRequest, satIOContext);
192 }
193 }
194 else /* pSatDevData->satDeviceType != SATA_ATAPI_DEVICE */
195 {
196 /* Parse CDB */
197 switch(scsiCmnd->cdb[0])
198 {
199 case SCSIOPC_READ_6:
200 retVal = satRead6( tiRoot,
201 tiIORequest,
202 tiDeviceHandle,
203 tiScsiRequest,
204 satIOContext);
205 break;
206
207 case SCSIOPC_READ_10:
208 retVal = satRead10( tiRoot,
209 tiIORequest,
210 tiDeviceHandle,
211 tiScsiRequest,
212 satIOContext);
213 break;
214
215 case SCSIOPC_READ_12:
216 TI_DBG5(("satIOStart: SCSIOPC_READ_12\n"));
217 retVal = satRead12( tiRoot,
218 tiIORequest,
219 tiDeviceHandle,
220 tiScsiRequest,
221 satIOContext);
222 break;
223
224 case SCSIOPC_READ_16:
225 retVal = satRead16( tiRoot,
226 tiIORequest,
227 tiDeviceHandle,
228 tiScsiRequest,
229 satIOContext);
230 break;
231
232 case SCSIOPC_WRITE_6:
233 retVal = satWrite6( tiRoot,
234 tiIORequest,
235 tiDeviceHandle,
236 tiScsiRequest,
237 satIOContext);
238 break;
239
240 case SCSIOPC_WRITE_10:
241 retVal = satWrite10( tiRoot,
242 tiIORequest,
243 tiDeviceHandle,
244 tiScsiRequest,
245 satIOContext);
246 break;
247
248 case SCSIOPC_WRITE_12:
249 TI_DBG5(("satIOStart: SCSIOPC_WRITE_12 \n"));
250 retVal = satWrite12( tiRoot,
251 tiIORequest,
252 tiDeviceHandle,
253 tiScsiRequest,
254 satIOContext);
255
256 break;
257
258 case SCSIOPC_WRITE_16:
259 TI_DBG5(("satIOStart: SCSIOPC_WRITE_16\n"));
260 retVal = satWrite16( tiRoot,
261 tiIORequest,
262 tiDeviceHandle,
263 tiScsiRequest,
264 satIOContext);
265
266 break;
267
268 case SCSIOPC_VERIFY_10:
269 retVal = satVerify10( tiRoot,
270 tiIORequest,
271 tiDeviceHandle,
272 tiScsiRequest,
273 satIOContext);
274 break;
275
276 case SCSIOPC_VERIFY_12:
277 TI_DBG5(("satIOStart: SCSIOPC_VERIFY_12\n"));
278 retVal = satVerify12( tiRoot,
279 tiIORequest,
280 tiDeviceHandle,
281 tiScsiRequest,
282 satIOContext);
283 break;
284
285 case SCSIOPC_VERIFY_16:
286 TI_DBG5(("satIOStart: SCSIOPC_VERIFY_16\n"));
287 retVal = satVerify16( tiRoot,
288 tiIORequest,
289 tiDeviceHandle,
290 tiScsiRequest,
291 satIOContext);
292 break;
293
294 case SCSIOPC_TEST_UNIT_READY:
295 retVal = satTestUnitReady( tiRoot,
296 tiIORequest,
297 tiDeviceHandle,
298 tiScsiRequest,
299 satIOContext);
300 break;
301
302 case SCSIOPC_INQUIRY:
303 retVal = satInquiry( tiRoot,
304 tiIORequest,
305 tiDeviceHandle,
306 tiScsiRequest,
307 satIOContext);
308 break;
309
310 case SCSIOPC_REQUEST_SENSE:
311 retVal = satRequestSense( tiRoot,
312 tiIORequest,
313 tiDeviceHandle,
314 tiScsiRequest,
315 satIOContext);
316 break;
317
318 case SCSIOPC_MODE_SENSE_6:
319 retVal = satModeSense6( tiRoot,
320 tiIORequest,
321 tiDeviceHandle,
322 tiScsiRequest,
323 satIOContext);
324 break;
325
326 case SCSIOPC_MODE_SENSE_10:
327 retVal = satModeSense10( tiRoot,
328 tiIORequest,
329 tiDeviceHandle,
330 tiScsiRequest,
331 satIOContext);
332 break;
333
334
335 case SCSIOPC_READ_CAPACITY_10:
336 retVal = satReadCapacity10( tiRoot,
337 tiIORequest,
338 tiDeviceHandle,
339 tiScsiRequest,
340 satIOContext);
341 break;
342
343 case SCSIOPC_READ_CAPACITY_16:
344 retVal = satReadCapacity16( tiRoot,
345 tiIORequest,
346 tiDeviceHandle,
347 tiScsiRequest,
348 satIOContext);
349 break;
350
351 case SCSIOPC_REPORT_LUN:
352 retVal = satReportLun( tiRoot,
353 tiIORequest,
354 tiDeviceHandle,
355 tiScsiRequest,
356 satIOContext);
357 break;
358
359 case SCSIOPC_FORMAT_UNIT:
360 TI_DBG5(("satIOStart: SCSIOPC_FORMAT_UNIT\n"));
361 retVal = satFormatUnit( tiRoot,
362 tiIORequest,
363 tiDeviceHandle,
364 tiScsiRequest,
365 satIOContext);
366 break;
367 case SCSIOPC_SEND_DIAGNOSTIC: /* Table 28, p40 */
368 TI_DBG5(("satIOStart: SCSIOPC_SEND_DIAGNOSTIC\n"));
369 retVal = satSendDiagnostic( tiRoot,
370 tiIORequest,
371 tiDeviceHandle,
372 tiScsiRequest,
373 satIOContext);
374 break;
375
376 case SCSIOPC_START_STOP_UNIT:
377 TI_DBG5(("satIOStart: SCSIOPC_START_STOP_UNIT\n"));
378 retVal = satStartStopUnit( tiRoot,
379 tiIORequest,
380 tiDeviceHandle,
381 tiScsiRequest,
382 satIOContext);
383 break;
384
385 case SCSIOPC_WRITE_SAME_10: /* sector and LBA; SAT p64 case 3 accessing payload and very
386 inefficient now */
387 TI_DBG5(("satIOStart: SCSIOPC_WRITE_SAME_10\n"));
388 retVal = satWriteSame10( tiRoot,
389 tiIORequest,
390 tiDeviceHandle,
391 tiScsiRequest,
392 satIOContext);
393 break;
394
395 case SCSIOPC_WRITE_SAME_16: /* no support due to transfer length(sector count) */
396 TI_DBG5(("satIOStart: SCSIOPC_WRITE_SAME_16\n"));
397 retVal = satWriteSame16( tiRoot,
398 tiIORequest,
399 tiDeviceHandle,
400 tiScsiRequest,
401 satIOContext);
402 break;
403
404 case SCSIOPC_LOG_SENSE: /* SCT and log parameter(informational exceptions) */
405 TI_DBG5(("satIOStart: SCSIOPC_LOG_SENSE\n"));
406 retVal = satLogSense( tiRoot,
407 tiIORequest,
408 tiDeviceHandle,
409 tiScsiRequest,
410 satIOContext);
411 break;
412
413 case SCSIOPC_MODE_SELECT_6: /*mode layout and AlloLen check */
414 TI_DBG5(("satIOStart: SCSIOPC_MODE_SELECT_6\n"));
415 retVal = satModeSelect6( tiRoot,
416 tiIORequest,
417 tiDeviceHandle,
418 tiScsiRequest,
419 satIOContext);
420 break;
421
422 case SCSIOPC_MODE_SELECT_10: /* mode layout and AlloLen check and sharing CB with satModeSelect6*/
423 TI_DBG5(("satIOStart: SCSIOPC_MODE_SELECT_10\n"));
424 retVal = satModeSelect10( tiRoot,
425 tiIORequest,
426 tiDeviceHandle,
427 tiScsiRequest,
428 satIOContext);
429 break;
430
431 case SCSIOPC_SYNCHRONIZE_CACHE_10: /* on error what to return, sharing CB with
432 satSynchronizeCache16 */
433 TI_DBG5(("satIOStart: SCSIOPC_SYNCHRONIZE_CACHE_10\n"));
434 retVal = satSynchronizeCache10( tiRoot,
435 tiIORequest,
436 tiDeviceHandle,
437 tiScsiRequest,
438 satIOContext);
439 break;
440
441 case SCSIOPC_SYNCHRONIZE_CACHE_16:/* on error what to return, sharing CB with
442 satSynchronizeCache16 */
443
444 TI_DBG5(("satIOStart: SCSIOPC_SYNCHRONIZE_CACHE_16\n"));
445 retVal = satSynchronizeCache16( tiRoot,
446 tiIORequest,
447 tiDeviceHandle,
448 tiScsiRequest,
449 satIOContext);
450 break;
451
452 case SCSIOPC_WRITE_AND_VERIFY_10: /* single write and multiple writes */
453 TI_DBG5(("satIOStart: SCSIOPC_WRITE_AND_VERIFY_10\n"));
454 retVal = satWriteAndVerify10( tiRoot,
455 tiIORequest,
456 tiDeviceHandle,
457 tiScsiRequest,
458 satIOContext);
459 break;
460
461 case SCSIOPC_WRITE_AND_VERIFY_12:
462 TI_DBG5(("satIOStart: SCSIOPC_WRITE_AND_VERIFY_12\n"));
463 retVal = satWriteAndVerify12( tiRoot,
464 tiIORequest,
465 tiDeviceHandle,
466 tiScsiRequest,
467 satIOContext);
468 break;
469
470 case SCSIOPC_WRITE_AND_VERIFY_16:
471 TI_DBG5(("satIOStart: SCSIOPC_WRITE_AND_VERIFY_16\n"));
472 retVal = satWriteAndVerify16( tiRoot,
473 tiIORequest,
474 tiDeviceHandle,
475 tiScsiRequest,
476 satIOContext);
477
478 break;
479
480 case SCSIOPC_READ_MEDIA_SERIAL_NUMBER:
481 TI_DBG5(("satIOStart: SCSIOPC_READ_MEDIA_SERIAL_NUMBER\n"));
482 retVal = satReadMediaSerialNumber( tiRoot,
483 tiIORequest,
484 tiDeviceHandle,
485 tiScsiRequest,
486 satIOContext);
487
488 break;
489
490 case SCSIOPC_READ_BUFFER:
491 TI_DBG5(("satIOStart: SCSIOPC_READ_BUFFER\n"));
492 retVal = satReadBuffer( tiRoot,
493 tiIORequest,
494 tiDeviceHandle,
495 tiScsiRequest,
496 satIOContext);
497
498 break;
499
500 case SCSIOPC_WRITE_BUFFER:
501 TI_DBG5(("satIOStart: SCSIOPC_WRITE_BUFFER\n"));
502 retVal = satWriteBuffer( tiRoot,
503 tiIORequest,
504 tiDeviceHandle,
505 tiScsiRequest,
506 satIOContext);
507
508 break;
509
510 case SCSIOPC_REASSIGN_BLOCKS:
511 TI_DBG5(("satIOStart: SCSIOPC_REASSIGN_BLOCKS\n"));
512 retVal = satReassignBlocks( tiRoot,
513 tiIORequest,
514 tiDeviceHandle,
515 tiScsiRequest,
516 satIOContext);
517
518 break;
519
520 default:
521 /* Not implemented SCSI cmd, set up error response */
522 TI_DBG1(("satIOStart: unsupported SCSI cdb[0]=0x%x tiIORequest=%p tiDeviceHandle=%p\n",
523 scsiCmnd->cdb[0], tiIORequest, tiDeviceHandle));
524
525 satSetSensePayload( pSense,
526 SCSI_SNSKEY_ILLEGAL_REQUEST,
527 0,
528 SCSI_SNSCODE_INVALID_COMMAND,
529 satIOContext);
530
531 ostiInitiatorIOCompleted( tiRoot,
532 tiIORequest,
533 tiIOSuccess,
534 SCSI_STAT_CHECK_CONDITION,
535 satIOContext->pTiSenseData,
536 satIOContext->interruptContext );
537 retVal = tiSuccess;
538
539 break;
540
541 } /* end switch */
542 }
543 if (retVal == tiBusy)
544 {
545 #ifdef TD_DEBUG_ENABLE
546 oneDeviceData = (tdsaDeviceData_t *)tiDeviceHandle->tdData;
547 #endif
548 TI_DBG1(("satIOStart: BUSY did %d\n", oneDeviceData->id));
549 TI_DBG3(("satIOStart: LL is busy or target queue is full\n"));
550 TI_DBG3(("satIOStart: device %p satPendingIO %d satNCQMaxIO %d\n",pSatDevData, pSatDevData->satPendingIO, pSatDevData->satNCQMaxIO ));
551 TI_DBG3(("satIOStart: device %p satPendingNCQIO %d satPendingNONNCQIO %d\n",pSatDevData, pSatDevData->satPendingNCQIO, pSatDevData->satPendingNONNCQIO));
552 pSatIntIo = satIOContext->satIntIoContext;
553
554 /* interal structure free */
555 satFreeIntIoResource( tiRoot,
556 pSatDevData,
557 pSatIntIo);
558 }
559
560 ext:
561 return retVal;
562 }
563
564
565 /*****************************************************************************/
566 /*! \brief Setup up the SCSI Sense response.
567 *
568 * This function is used to setup up the Sense Data payload for
569 * CHECK CONDITION status.
570 *
571 * \param pSense: Pointer to the scsiRspSense_t sense data structure.
572 * \param SnsKey: SCSI Sense Key.
573 * \param SnsInfo: SCSI Sense Info.
574 * \param SnsCode: SCSI Sense Code.
575 *
576 * \return: None
577 */
578 /*****************************************************************************/
satSetSensePayload(scsiRspSense_t * pSense,bit8 SnsKey,bit32 SnsInfo,bit16 SnsCode,satIOContext_t * satIOContext)579 void satSetSensePayload( scsiRspSense_t *pSense,
580 bit8 SnsKey,
581 bit32 SnsInfo,
582 bit16 SnsCode,
583 satIOContext_t *satIOContext
584 )
585 {
586 /* for fixed format sense data, SPC-4, p37 */
587 bit32 i;
588 bit32 senseLength;
589
590 TI_DBG5(("satSetSensePayload: start\n"));
591
592 senseLength = sizeof(scsiRspSense_t);
593
594 /* zero out the data area */
595 for (i=0;i< senseLength;i++)
596 {
597 ((bit8*)pSense)[i] = 0;
598 }
599
600 /*
601 * SCSI Sense Data part of response data
602 */
603 pSense->snsRespCode = 0x70; /* 0xC0 == vendor specific */
604 /* 0x70 == standard current error */
605 pSense->senseKey = SnsKey;
606 /*
607 * Put sense info in scsi order format
608 */
609 pSense->info[0] = (bit8)((SnsInfo >> 24) & 0xff);
610 pSense->info[1] = (bit8)((SnsInfo >> 16) & 0xff);
611 pSense->info[2] = (bit8)((SnsInfo >> 8) & 0xff);
612 pSense->info[3] = (bit8)((SnsInfo) & 0xff);
613 pSense->addSenseLen = 11; /* fixed size of sense data = 18 */
614 pSense->addSenseCode = (bit8)((SnsCode >> 8) & 0xFF);
615 pSense->senseQual = (bit8)(SnsCode & 0xFF);
616 /*
617 * Set pointer in scsi status
618 */
619 switch(SnsKey)
620 {
621 /*
622 * set illegal request sense key specific error in cdb, no bit pointer
623 */
624 case SCSI_SNSKEY_ILLEGAL_REQUEST:
625 pSense->skeySpecific[0] = 0xC8;
626 break;
627
628 default:
629 break;
630 }
631 /* setting sense data length */
632 if (satIOContext != agNULL)
633 {
634 satIOContext->pTiSenseData->senseLen = 18;
635 }
636 else
637 {
638 TI_DBG1(("satSetSensePayload: satIOContext is NULL\n"));
639 }
640 }
641
642 /*****************************************************************************/
643 /*! \brief Setup up the SCSI Sense response.
644 *
645 * This function is used to setup up the Sense Data payload for
646 * CHECK CONDITION status.
647 *
648 * \param pSense: Pointer to the scsiRspSense_t sense data structure.
649 * \param SnsKey: SCSI Sense Key.
650 * \param SnsInfo: SCSI Sense Info.
651 * \param SnsCode: SCSI Sense Code.
652 *
653 * \return: None
654 */
655 /*****************************************************************************/
656
satSetDeferredSensePayload(scsiRspSense_t * pSense,bit8 SnsKey,bit32 SnsInfo,bit16 SnsCode,satIOContext_t * satIOContext)657 void satSetDeferredSensePayload( scsiRspSense_t *pSense,
658 bit8 SnsKey,
659 bit32 SnsInfo,
660 bit16 SnsCode,
661 satIOContext_t *satIOContext
662 )
663 {
664 /* for fixed format sense data, SPC-4, p37 */
665 bit32 i;
666 bit32 senseLength;
667
668 senseLength = sizeof(scsiRspSense_t);
669
670 /* zero out the data area */
671 for (i=0;i< senseLength;i++)
672 {
673 ((bit8*)pSense)[i] = 0;
674 }
675
676 /*
677 * SCSI Sense Data part of response data
678 */
679 pSense->snsRespCode = 0x71; /* 0xC0 == vendor specific */
680 /* 0x70 == standard current error */
681 pSense->senseKey = SnsKey;
682 /*
683 * Put sense info in scsi order format
684 */
685 pSense->info[0] = (bit8)((SnsInfo >> 24) & 0xff);
686 pSense->info[1] = (bit8)((SnsInfo >> 16) & 0xff);
687 pSense->info[2] = (bit8)((SnsInfo >> 8) & 0xff);
688 pSense->info[3] = (bit8)((SnsInfo) & 0xff);
689 pSense->addSenseLen = 11; /* fixed size of sense data = 18 */
690 pSense->addSenseCode = (bit8)((SnsCode >> 8) & 0xFF);
691 pSense->senseQual = (bit8)(SnsCode & 0xFF);
692 /*
693 * Set pointer in scsi status
694 */
695 switch(SnsKey)
696 {
697 /*
698 * set illegal request sense key specific error in cdb, no bit pointer
699 */
700 case SCSI_SNSKEY_ILLEGAL_REQUEST:
701 pSense->skeySpecific[0] = 0xC8;
702 break;
703
704 default:
705 break;
706 }
707
708 /* setting sense data length */
709 if (satIOContext != agNULL)
710 {
711 satIOContext->pTiSenseData->senseLen = 18;
712 }
713 else
714 {
715 TI_DBG1(("satSetDeferredSensePayload: satIOContext is NULL\n"));
716 }
717
718 }
719 /*****************************************************************************/
720 /*! \brief SAT implementation for ATAPI Packet Command.
721 *
722 * SAT implementation for ATAPI Packet and send FIS request to LL layer.
723 *
724 * \param tiRoot: Pointer to TISA initiator driver/port instance.
725 * \param tiIORequest: Pointer to TISA I/O request context for this I/O.
726 * \param tiDeviceHandle: Pointer to TISA device handle for this I/O.
727 * \param tiScsiRequest: Pointer to TISA SCSI I/O request and SGL list.
728 * \param satIOContext_t: Pointer to the SAT IO Context
729 *
730 * \return If command is started successfully
731 * - \e tiSuccess: I/O request successfully initiated.
732 * - \e tiBusy: No resources available, try again later.
733 * - \e tiIONoDevice: Invalid device handle.
734 * - \e tiError: Other errors.
735 */
736 /*****************************************************************************/
satPacket(tiRoot_t * tiRoot,tiIORequest_t * tiIORequest,tiDeviceHandle_t * tiDeviceHandle,tiScsiInitiatorRequest_t * tiScsiRequest,satIOContext_t * satIOContext)737 GLOBAL bit32 satPacket(
738 tiRoot_t *tiRoot,
739 tiIORequest_t *tiIORequest,
740 tiDeviceHandle_t *tiDeviceHandle,
741 tiScsiInitiatorRequest_t *tiScsiRequest,
742 satIOContext_t *satIOContext)
743 {
744 bit32 status;
745 bit32 agRequestType = AGSA_SATA_PROTOCOL_D2H_PKT;
746 satDeviceData_t *pSatDevData;
747 tiIniScsiCmnd_t *scsiCmnd;
748 agsaFisRegHostToDevice_t *fis;
749
750 pSatDevData = satIOContext->pSatDevData;
751 scsiCmnd = &tiScsiRequest->scsiCmnd;
752 fis = satIOContext->pFis;
753
754 TI_DBG3(("satPacket: start, SCSI CDB is 0x%X %X %X %X %X %X %X %X %X %X %X %X\n",
755 scsiCmnd->cdb[0],scsiCmnd->cdb[1],scsiCmnd->cdb[2],scsiCmnd->cdb[3],
756 scsiCmnd->cdb[4],scsiCmnd->cdb[5],scsiCmnd->cdb[6],scsiCmnd->cdb[7],
757 scsiCmnd->cdb[8],scsiCmnd->cdb[9],scsiCmnd->cdb[10],scsiCmnd->cdb[11]));
758
759 fis->h.fisType = 0x27; /* Reg host to device */
760 fis->h.c_pmPort = 0x80; /* C Bit is set 1*/
761 fis->h.command = SAT_PACKET; /* 0xA0 */
762 if (pSatDevData->satDMADIRSupport) /* DMADIR enabled*/
763 {
764 fis->h.features = (tiScsiRequest->dataDirection == tiDirectionIn)? 0x04 : 0; /* 1 for D2H, 0 for H2D */
765 }
766 else
767 {
768 fis->h.features = 0; /* FIS reserve */
769 }
770 /* Byte count low and byte count high */
771 if ( scsiCmnd->expDataLength > 0xFFFF )
772 {
773 fis->d.lbaMid = 0xFF; /* FIS LBA (7 :0 ) */
774 fis->d.lbaHigh = 0xFF; /* FIS LBA (15:8 ) */
775 }
776 else
777 {
778 fis->d.lbaMid = (bit8)scsiCmnd->expDataLength; /* FIS LBA (7 :0 ) */
779 fis->d.lbaHigh = (bit8)(scsiCmnd->expDataLength>>8); /* FIS LBA (15:8 ) */
780 }
781
782 fis->d.lbaLow = 0; /* FIS LBA (7 :0 ) */
783 fis->d.device = 0; /* FIS LBA (27:24) and FIS LBA mode */
784 fis->d.lbaLowExp = 0;
785 fis->d.lbaMidExp = 0;
786 fis->d.lbaHighExp = 0;
787 fis->d.featuresExp = 0;
788 fis->d.sectorCount = 0; /* FIS sector count (7:0) */
789 fis->d.sectorCountExp = 0;
790 fis->d.reserved4 = 0;
791 fis->d.control = 0; /* FIS HOB bit clear */
792 fis->d.reserved5 = 0;
793
794 satIOContext->ATACmd = SAT_PACKET;
795
796 if (tiScsiRequest->dataDirection == tiDirectionIn)
797 {
798 agRequestType = AGSA_SATA_PROTOCOL_D2H_PKT;
799 }
800 else
801 {
802 agRequestType = AGSA_SATA_PROTOCOL_H2D_PKT;
803 }
804
805 if (pSatDevData->satDMASupport == agTRUE && pSatDevData->satDMAEnabled == agTRUE)
806 {
807 /*DMA transfer mode*/
808 fis->h.features |= 0x01;
809 }
810 else
811 {
812 /*PIO transfer mode*/
813 fis->h.features |= 0x0;
814 }
815
816 satIOContext->satCompleteCB = &satPacketCB;
817
818 /*
819 * Prepare SGL and send FIS to LL layer.
820 */
821 satIOContext->reqType = agRequestType; /* Save it */
822
823 status = sataLLIOStart( tiRoot,
824 tiIORequest,
825 tiDeviceHandle,
826 tiScsiRequest,
827 satIOContext);
828
829 TI_DBG5(("satPacket: return\n"));
830 return (status);
831 }
832
833 /*****************************************************************************/
834 /*! \brief SAT implementation for satSetFeatures.
835 *
836 * This function creates SetFeatures fis and sends the request to LL layer
837 *
838 * \param tiRoot: Pointer to TISA initiator driver/port instance.
839 * \param tiIORequest: Pointer to TISA I/O request context for this I/O.
840 * \param tiDeviceHandle: Pointer to TISA device handle for this I/O.
841 * \param tiScsiRequest: Pointer to TISA SCSI I/O request and SGL list.
842 * \param satIOContext_t: Pointer to the SAT IO Context
843 *
844 * \return If command is started successfully
845 * - \e tiSuccess: I/O request successfully initiated.
846 * - \e tiBusy: No resources available, try again later.
847 * - \e tiIONoDevice: Invalid device handle.
848 * - \e tiError: Other errors.
849 */
850 /*****************************************************************************/
satSetFeatures(tiRoot_t * tiRoot,tiIORequest_t * tiIORequest,tiDeviceHandle_t * tiDeviceHandle,tiScsiInitiatorRequest_t * tiScsiRequest,satIOContext_t * satIOContext,bit8 bIsDMAMode)851 GLOBAL bit32 satSetFeatures(
852 tiRoot_t *tiRoot,
853 tiIORequest_t *tiIORequest,
854 tiDeviceHandle_t *tiDeviceHandle,
855 tiScsiInitiatorRequest_t *tiScsiRequest,
856 satIOContext_t *satIOContext,
857 bit8 bIsDMAMode
858 )
859 {
860 bit32 status;
861 bit32 agRequestType;
862 agsaFisRegHostToDevice_t *fis;
863
864 fis = satIOContext->pFis;
865 TI_DBG3(("satSetFeatures: start\n"));
866
867 /*
868 * Send the Set Features command.
869 */
870 fis->h.fisType = 0x27; /* Reg host to device */
871 fis->h.c_pmPort = 0x80; /* C Bit is set */
872 fis->h.command = SAT_SET_FEATURES; /* 0xEF */
873 fis->h.features = 0x03; /* set transfer mode */
874 fis->d.lbaLow = 0;
875 fis->d.lbaMid = 0;
876 fis->d.lbaHigh = 0;
877 fis->d.device = 0;
878 fis->d.lbaLowExp = 0;
879 fis->d.lbaMidExp = 0;
880 fis->d.lbaHighExp = 0;
881 fis->d.featuresExp = 0;
882 fis->d.sectorCountExp = 0;
883 fis->d.reserved4 = 0;
884 fis->d.control = 0; /* FIS HOB bit clear */
885 fis->d.reserved5 = 0;
886
887 agRequestType = AGSA_SATA_PROTOCOL_NON_DATA;
888
889 /* Initialize CB for SATA completion.
890 */
891 if (bIsDMAMode)
892 {
893 fis->d.sectorCount = 0x45;
894 /*satIOContext->satCompleteCB = &satSetFeaturesDMACB;*/
895 }
896 else
897 {
898 fis->d.sectorCount = 0x0C;
899 /*satIOContext->satCompleteCB = &satSetFeaturesPIOCB;*/
900 }
901 satIOContext->satCompleteCB = &satSetFeaturesCB;
902
903 /*
904 * Prepare SGL and send FIS to LL layer.
905 */
906 satIOContext->reqType = agRequestType; /* Save it */
907
908 status = sataLLIOStart( tiRoot,
909 tiIORequest,
910 tiDeviceHandle,
911 tiScsiRequest,
912 satIOContext);
913
914 TI_DBG5(("satSetFeatures: return\n"));
915
916 return status;
917 }
918 /*****************************************************************************/
919 /*! \brief SAT implementation for SCSI REQUEST SENSE to ATAPI device.
920 *
921 * SAT implementation for SCSI REQUEST SENSE.
922 *
923 * \param tiRoot: Pointer to TISA initiator driver/port instance.
924 * \param tiIORequest: Pointer to TISA I/O request context for this I/O.
925 * \param tiDeviceHandle: Pointer to TISA device handle for this I/O.
926 * \param tiScsiRequest: Pointer to TISA SCSI I/O request and SGL list.
927 * \param satIOContext_t: Pointer to the SAT IO Context
928 *
929 * \return If command is started successfully
930 * - \e tiSuccess: I/O request successfully initiated.
931 * - \e tiBusy: No resources available, try again later.
932 * - \e tiIONoDevice: Invalid device handle.
933 * - \e tiError: Other errors.
934 */
935 /*****************************************************************************/
satRequestSenseForATAPI(tiRoot_t * tiRoot,tiIORequest_t * tiIORequest,tiDeviceHandle_t * tiDeviceHandle,tiScsiInitiatorRequest_t * tiScsiRequest,satIOContext_t * satIOContext)936 GLOBAL bit32 satRequestSenseForATAPI(
937 tiRoot_t *tiRoot,
938 tiIORequest_t *tiIORequest,
939 tiDeviceHandle_t *tiDeviceHandle,
940 tiScsiInitiatorRequest_t *tiScsiRequest,
941 satIOContext_t *satIOContext)
942 {
943 bit32 status;
944 bit32 agRequestType = AGSA_SATA_PROTOCOL_D2H_PKT;
945 satDeviceData_t *pSatDevData;
946 tiIniScsiCmnd_t *scsiCmnd;
947 agsaFisRegHostToDevice_t *fis;
948
949 pSatDevData = satIOContext->pSatDevData;
950 scsiCmnd = &tiScsiRequest->scsiCmnd;
951 fis = satIOContext->pFis;
952
953 scsiCmnd->cdb[0] = SCSIOPC_REQUEST_SENSE;
954 scsiCmnd->cdb[1] = 0;
955 scsiCmnd->cdb[2] = 0;
956 scsiCmnd->cdb[3] = 0;
957 scsiCmnd->cdb[4] = SENSE_DATA_LENGTH;
958 scsiCmnd->cdb[5] = 0;
959 TI_DBG3(("satRequestSenseForATAPI: start, SCSI CDB is 0x%X %X %X %X %X %X %X %X %X %X %X %X\n",
960 scsiCmnd->cdb[0],scsiCmnd->cdb[1],scsiCmnd->cdb[2],scsiCmnd->cdb[3],
961 scsiCmnd->cdb[4],scsiCmnd->cdb[5],scsiCmnd->cdb[6],scsiCmnd->cdb[7],
962 scsiCmnd->cdb[8],scsiCmnd->cdb[9],scsiCmnd->cdb[10],scsiCmnd->cdb[11]));
963
964 fis->h.fisType = 0x27; /* Reg host to device */
965 fis->h.c_pmPort = 0x80; /* C Bit is set 1*/
966 fis->h.command = SAT_PACKET; /* 0xA0 */
967 if (pSatDevData->satDMADIRSupport) /* DMADIR enabled*/
968 {
969 fis->h.features = (tiScsiRequest->dataDirection == tiDirectionIn)? 0x04 : 0; /* 1 for D2H, 0 for H2D */
970 }
971 else
972 {
973 fis->h.features = 0; /* FIS reserve */
974 }
975
976 fis->d.lbaLow = 0; /* FIS LBA (7 :0 ) */
977 fis->d.lbaMid = 0; /* FIS LBA (15:8 ) */
978 fis->d.lbaHigh = 0x20; /* FIS LBA (23:16) */
979 fis->d.device = 0; /* FIS LBA (27:24) and FIS LBA mode */
980 fis->d.lbaLowExp = 0;
981 fis->d.lbaMidExp = 0;
982 fis->d.lbaHighExp = 0;
983 fis->d.featuresExp = 0;
984 fis->d.sectorCount = 0; /* FIS sector count (7:0) */
985 fis->d.sectorCountExp = 0;
986 fis->d.reserved4 = 0;
987 fis->d.control = 0; /* FIS HOB bit clear */
988 fis->d.reserved5 = (bit32)(scsiCmnd->cdb[0]|(scsiCmnd->cdb[1]<<8)|(scsiCmnd->cdb[2]<<16)|(scsiCmnd->cdb[3]<<24));
989
990 satIOContext->ATACmd = SAT_PACKET;
991
992 agRequestType = AGSA_SATA_PROTOCOL_D2H_PKT;
993
994 //if (pSatDevData->sat48BitSupport == agTRUE)
995 {
996 if (pSatDevData->satDMASupport == agTRUE && pSatDevData->satDMAEnabled == agTRUE)
997 {
998 fis->h.features |= 0x01;
999 }
1000 else
1001 {
1002 fis->h.features |= 0x0;
1003 }
1004 }
1005
1006 satIOContext->satCompleteCB = &satRequestSenseForATAPICB;
1007
1008 /*
1009 * Prepare SGL and send FIS to LL layer.
1010 */
1011 satIOContext->reqType = agRequestType; /* Save it */
1012
1013 status = sataLLIOStart( tiRoot,
1014 tiIORequest,
1015 tiDeviceHandle,
1016 tiScsiRequest,
1017 satIOContext);
1018
1019 TI_DBG5(("satRequestSenseForATAPI: return\n"));
1020 return (status);
1021 }
1022 /*****************************************************************************/
1023 /*! \brief SAT implementation for satDeviceReset.
1024 *
1025 * This function creates DEVICE RESET fis and sends the request to LL layer
1026 *
1027 * \param tiRoot: Pointer to TISA initiator driver/port instance.
1028 * \param tiIORequest: Pointer to TISA I/O request context for this I/O.
1029 * \param tiDeviceHandle: Pointer to TISA device handle for this I/O.
1030 * \param tiScsiRequest: Pointer to TISA SCSI I/O request and SGL list.
1031 * \param satIOContext_t: Pointer to the SAT IO Context
1032 *
1033 * \return If command is started successfully
1034 * - \e tiSuccess: I/O request successfully initiated.
1035 * - \e tiBusy: No resources available, try again later.
1036 * - \e tiIONoDevice: Invalid device handle.
1037 * - \e tiError: Other errors.
1038 */
1039 /*****************************************************************************/
satDeviceReset(tiRoot_t * tiRoot,tiIORequest_t * tiIORequest,tiDeviceHandle_t * tiDeviceHandle,tiScsiInitiatorRequest_t * tiScsiRequest,satIOContext_t * satIOContext)1040 GLOBAL bit32 satDeviceReset(
1041 tiRoot_t *tiRoot,
1042 tiIORequest_t *tiIORequest,
1043 tiDeviceHandle_t *tiDeviceHandle,
1044 tiScsiInitiatorRequest_t *tiScsiRequest,
1045 satIOContext_t *satIOContext
1046 )
1047 {
1048 bit32 status;
1049 bit32 agRequestType;
1050 agsaFisRegHostToDevice_t *fis;
1051
1052 fis = satIOContext->pFis;
1053
1054 TI_DBG3(("satDeviceReset: start\n"));
1055
1056 /*
1057 * Send the Execute Device Diagnostic command.
1058 */
1059 fis->h.fisType = 0x27; /* Reg host to device */
1060 fis->h.c_pmPort = 0x80; /* C Bit is set */
1061 fis->h.command = SAT_DEVICE_RESET; /* 0x90 */
1062 fis->h.features = 0;
1063 fis->d.lbaLow = 0;
1064 fis->d.lbaMid = 0;
1065 fis->d.lbaHigh = 0;
1066 fis->d.device = 0;
1067 fis->d.lbaLowExp = 0;
1068 fis->d.lbaMidExp = 0;
1069 fis->d.lbaHighExp = 0;
1070 fis->d.featuresExp = 0;
1071 fis->d.sectorCount = 0;
1072 fis->d.sectorCountExp = 0;
1073 fis->d.reserved4 = 0;
1074 fis->d.control = 0; /* FIS HOB bit clear */
1075 fis->d.reserved5 = 0;
1076
1077 agRequestType = AGSA_SATA_PROTOCOL_DEV_RESET;
1078
1079 /* Initialize CB for SATA completion.
1080 */
1081 satIOContext->satCompleteCB = &satDeviceResetCB;
1082
1083 /*
1084 * Prepare SGL and send FIS to LL layer.
1085 */
1086 satIOContext->reqType = agRequestType; /* Save it */
1087
1088 status = sataLLIOStart( tiRoot,
1089 tiIORequest,
1090 tiDeviceHandle,
1091 tiScsiRequest,
1092 satIOContext);
1093
1094 TI_DBG3(("satDeviceReset: return\n"));
1095
1096 return status;
1097 }
1098
1099 /*****************************************************************************/
1100 /*! \brief SAT implementation for saExecuteDeviceDiagnostic.
1101 *
1102 * This function creates Execute Device Diagnostic fis and sends the request to LL layer
1103 *
1104 * \param tiRoot: Pointer to TISA initiator driver/port instance.
1105 * \param tiIORequest: Pointer to TISA I/O request context for this I/O.
1106 * \param tiDeviceHandle: Pointer to TISA device handle for this I/O.
1107 * \param tiScsiRequest: Pointer to TISA SCSI I/O request and SGL list.
1108 * \param satIOContext_t: Pointer to the SAT IO Context
1109 *
1110 * \return If command is started successfully
1111 * - \e tiSuccess: I/O request successfully initiated.
1112 * - \e tiBusy: No resources available, try again later.
1113 * - \e tiIONoDevice: Invalid device handle.
1114 * - \e tiError: Other errors.
1115 */
1116 /*****************************************************************************/
satExecuteDeviceDiagnostic(tiRoot_t * tiRoot,tiIORequest_t * tiIORequest,tiDeviceHandle_t * tiDeviceHandle,tiScsiInitiatorRequest_t * tiScsiRequest,satIOContext_t * satIOContext)1117 GLOBAL bit32 satExecuteDeviceDiagnostic(
1118 tiRoot_t *tiRoot,
1119 tiIORequest_t *tiIORequest,
1120 tiDeviceHandle_t *tiDeviceHandle,
1121 tiScsiInitiatorRequest_t *tiScsiRequest,
1122 satIOContext_t *satIOContext
1123 )
1124 {
1125 bit32 status;
1126 bit32 agRequestType;
1127 agsaFisRegHostToDevice_t *fis;
1128
1129 fis = satIOContext->pFis;
1130
1131 TI_DBG3(("satExecuteDeviceDiagnostic: start\n"));
1132
1133 /*
1134 * Send the Execute Device Diagnostic command.
1135 */
1136 fis->h.fisType = 0x27; /* Reg host to device */
1137 fis->h.c_pmPort = 0x80; /* C Bit is set */
1138 fis->h.command = SAT_EXECUTE_DEVICE_DIAGNOSTIC; /* 0x90 */
1139 fis->h.features = 0;
1140 fis->d.lbaLow = 0;
1141 fis->d.lbaMid = 0;
1142 fis->d.lbaHigh = 0;
1143 fis->d.device = 0;
1144 fis->d.lbaLowExp = 0;
1145 fis->d.lbaMidExp = 0;
1146 fis->d.lbaHighExp = 0;
1147 fis->d.featuresExp = 0;
1148 fis->d.sectorCount = 0;
1149 fis->d.sectorCountExp = 0;
1150 fis->d.reserved4 = 0;
1151 fis->d.control = 0; /* FIS HOB bit clear */
1152 fis->d.reserved5 = 0;
1153
1154 agRequestType = AGSA_SATA_PROTOCOL_NON_DATA;
1155
1156 /* Initialize CB for SATA completion.
1157 */
1158 satIOContext->satCompleteCB = &satExecuteDeviceDiagnosticCB;
1159
1160 /*
1161 * Prepare SGL and send FIS to LL layer.
1162 */
1163 satIOContext->reqType = agRequestType; /* Save it */
1164
1165 status = sataLLIOStart( tiRoot,
1166 tiIORequest,
1167 tiDeviceHandle,
1168 tiScsiRequest,
1169 satIOContext);
1170
1171 TI_DBG5(("satExecuteDeviceDiagnostic: return\n"));
1172
1173 return status;
1174 }
1175
1176
1177 /*****************************************************************************/
1178 /*! \brief SAT implementation for SCSI READ10.
1179 *
1180 * SAT implementation for SCSI READ10 and send FIS request to LL layer.
1181 *
1182 * \param tiRoot: Pointer to TISA initiator driver/port instance.
1183 * \param tiIORequest: Pointer to TISA I/O request context for this I/O.
1184 * \param tiDeviceHandle: Pointer to TISA device handle for this I/O.
1185 * \param tiScsiRequest: Pointer to TISA SCSI I/O request and SGL list.
1186 * \param satIOContext_t: Pointer to the SAT IO Context
1187 *
1188 * \return If command is started successfully
1189 * - \e tiSuccess: I/O request successfully initiated.
1190 * - \e tiBusy: No resources available, try again later.
1191 * - \e tiIONoDevice: Invalid device handle.
1192 * - \e tiError: Other errors.
1193 */
1194 /*****************************************************************************/
satRead10(tiRoot_t * tiRoot,tiIORequest_t * tiIORequest,tiDeviceHandle_t * tiDeviceHandle,tiScsiInitiatorRequest_t * tiScsiRequest,satIOContext_t * satIOContext)1195 GLOBAL bit32 satRead10(
1196 tiRoot_t *tiRoot,
1197 tiIORequest_t *tiIORequest,
1198 tiDeviceHandle_t *tiDeviceHandle,
1199 tiScsiInitiatorRequest_t *tiScsiRequest,
1200 satIOContext_t *satIOContext)
1201 {
1202
1203 bit32 status;
1204 bit32 agRequestType = AGSA_SATA_PROTOCOL_DMA_READ;
1205 satDeviceData_t *pSatDevData;
1206 scsiRspSense_t *pSense;
1207 tiIniScsiCmnd_t *scsiCmnd;
1208 agsaFisRegHostToDevice_t *fis;
1209 bit32 lba = 0;
1210 bit32 tl = 0;
1211 bit32 LoopNum = 1;
1212 bit8 LBA[4];
1213 bit8 TL[4];
1214 bit32 rangeChk = agFALSE; /* lba and tl range check */
1215
1216 pSense = satIOContext->pSense;
1217 pSatDevData = satIOContext->pSatDevData;
1218 scsiCmnd = &tiScsiRequest->scsiCmnd;
1219 fis = satIOContext->pFis;
1220
1221 TI_DBG5(("satRead10: start\n"));
1222 TI_DBG5(("satRead10: pSatDevData=%p\n", pSatDevData));
1223 // tdhexdump("satRead10", (bit8 *)scsiCmnd->cdb, 10);
1224
1225 /* checking FUA_NV */
1226 if (scsiCmnd->cdb[1] & SCSI_FUA_NV_MASK)
1227 {
1228 satSetSensePayload( pSense,
1229 SCSI_SNSKEY_ILLEGAL_REQUEST,
1230 0,
1231 SCSI_SNSCODE_INVALID_FIELD_IN_CDB,
1232 satIOContext);
1233
1234 ostiInitiatorIOCompleted( tiRoot,
1235 tiIORequest,
1236 tiIOSuccess,
1237 SCSI_STAT_CHECK_CONDITION,
1238 satIOContext->pTiSenseData,
1239 satIOContext->interruptContext );
1240
1241 TI_DBG1(("satRead10: return FUA_NV\n"));
1242 return tiSuccess;
1243
1244 }
1245
1246 /* checking CONTROL */
1247 /* NACA == 1 or LINK == 1*/
1248 if ( (scsiCmnd->cdb[9] & SCSI_NACA_MASK) || (scsiCmnd->cdb[9] & SCSI_LINK_MASK) )
1249 {
1250 satSetSensePayload( pSense,
1251 SCSI_SNSKEY_ILLEGAL_REQUEST,
1252 0,
1253 SCSI_SNSCODE_INVALID_FIELD_IN_CDB,
1254 satIOContext);
1255
1256 ostiInitiatorIOCompleted( tiRoot,
1257 tiIORequest,
1258 tiIOSuccess,
1259 SCSI_STAT_CHECK_CONDITION,
1260 satIOContext->pTiSenseData,
1261 satIOContext->interruptContext );
1262
1263 TI_DBG1(("satRead10: return control\n"));
1264 return tiSuccess;
1265 }
1266
1267 osti_memset(LBA, 0, sizeof(LBA));
1268 osti_memset(TL, 0, sizeof(TL));
1269
1270 /* do not use memcpy due to indexing in LBA and TL */
1271 LBA[0] = scsiCmnd->cdb[2]; /* MSB */
1272 LBA[1] = scsiCmnd->cdb[3];
1273 LBA[2] = scsiCmnd->cdb[4];
1274 LBA[3] = scsiCmnd->cdb[5]; /* LSB */
1275
1276 TL[0] = 0;
1277 TL[1] = 0;
1278 TL[2] = scsiCmnd->cdb[7]; /* MSB */
1279 TL[3] = scsiCmnd->cdb[8]; /* LSB */
1280
1281 rangeChk = satAddNComparebit32(LBA, TL);
1282
1283 /* cbd10; computing LBA and transfer length */
1284 lba = (scsiCmnd->cdb[2] << (8*3)) + (scsiCmnd->cdb[3] << (8*2))
1285 + (scsiCmnd->cdb[4] << 8) + scsiCmnd->cdb[5];
1286 tl = (scsiCmnd->cdb[7] << 8) + scsiCmnd->cdb[8];
1287
1288
1289 TI_DBG5(("satRead10: lba %d functioned lba %d\n", lba, satComputeCDB10LBA(satIOContext)));
1290 TI_DBG5(("satRead10: lba 0x%x functioned lba 0x%x\n", lba, satComputeCDB10LBA(satIOContext)));
1291 TI_DBG5(("satRead10: tl %d functioned tl %d\n", tl, satComputeCDB10TL(satIOContext)));
1292
1293 /* Table 34, 9.1, p 46 */
1294 /*
1295 note: As of 2/10/2006, no support for DMA QUEUED
1296 */
1297
1298 /*
1299 Table 34, 9.1, p 46, b
1300 When no 48-bit addressing support or NCQ, if LBA is beyond (2^28 - 1),
1301 return check condition
1302 */
1303
1304 if (pSatDevData->satNCQ != agTRUE &&
1305 pSatDevData->sat48BitSupport != agTRUE
1306 )
1307 {
1308 if (lba > SAT_TR_LBA_LIMIT - 1)
1309 {
1310 TI_DBG1(("satRead10: return LBA out of range, not EXT\n"));
1311 satSetSensePayload( pSense,
1312 SCSI_SNSKEY_ILLEGAL_REQUEST,
1313 0,
1314 SCSI_SNSCODE_LOGICAL_BLOCK_ADDRESS_OUT_OF_RANGE,
1315 satIOContext);
1316
1317 ostiInitiatorIOCompleted( tiRoot,
1318 tiIORequest,
1319 tiIOSuccess,
1320 SCSI_STAT_CHECK_CONDITION,
1321 satIOContext->pTiSenseData,
1322 satIOContext->interruptContext );
1323
1324 return tiSuccess;
1325 }
1326
1327
1328 if (rangeChk) // if (lba + tl > SAT_TR_LBA_LIMIT)
1329 {
1330 TI_DBG1(("satRead10: return LBA+TL out of range, not EXT\n"));
1331 satSetSensePayload( pSense,
1332 SCSI_SNSKEY_ILLEGAL_REQUEST,
1333 0,
1334 SCSI_SNSCODE_LOGICAL_BLOCK_ADDRESS_OUT_OF_RANGE,
1335 satIOContext);
1336
1337 ostiInitiatorIOCompleted( tiRoot,
1338 tiIORequest,
1339 tiIOSuccess,
1340 SCSI_STAT_CHECK_CONDITION,
1341 satIOContext->pTiSenseData,
1342 satIOContext->interruptContext );
1343
1344 return tiSuccess;
1345 }
1346 }
1347
1348 /* case 1 and 2 */
1349 if (!rangeChk) // if (lba + tl <= SAT_TR_LBA_LIMIT)
1350 {
1351 if (pSatDevData->satDMASupport == agTRUE && pSatDevData->satDMAEnabled == agTRUE)
1352 {
1353 /* case 2 */
1354 /* READ DMA*/
1355 /* in case that we can't fit the transfer length,
1356 we need to make it fit by sending multiple ATA cmnds */
1357 TI_DBG5(("satRead10: case 2\n"));
1358
1359
1360 fis->h.fisType = 0x27; /* Reg host to device */
1361 fis->h.c_pmPort = 0x80; /* C Bit is set */
1362 fis->h.command = SAT_READ_DMA; /* 0xC8 */
1363 fis->h.features = 0; /* FIS reserve */
1364 fis->d.lbaLow = scsiCmnd->cdb[5]; /* FIS LBA (7 :0 ) */
1365 fis->d.lbaMid = scsiCmnd->cdb[4]; /* FIS LBA (15:8 ) */
1366 fis->d.lbaHigh = scsiCmnd->cdb[3]; /* FIS LBA (23:16) */
1367 fis->d.device =
1368 (bit8)((0x4 << 4) | (scsiCmnd->cdb[2] & 0xF)); /* FIS LBA (27:24) and FIS LBA mode */
1369 fis->d.lbaLowExp = 0;
1370 fis->d.lbaMidExp = 0;
1371 fis->d.lbaHighExp = 0;
1372 fis->d.featuresExp = 0;
1373 fis->d.sectorCount = scsiCmnd->cdb[8]; /* FIS sector count (7:0) */
1374 fis->d.sectorCountExp = 0;
1375 fis->d.reserved4 = 0;
1376 fis->d.control = 0; /* FIS HOB bit clear */
1377 fis->d.reserved5 = 0;
1378
1379
1380 agRequestType = AGSA_SATA_PROTOCOL_DMA_READ;
1381 satIOContext->ATACmd = SAT_READ_DMA;
1382 }
1383 else
1384 {
1385 /* case 1 */
1386 /* READ MULTIPLE or READ SECTOR(S) */
1387 /* READ SECTORS for easier implemetation */
1388 /* in case that we can't fit the transfer length,
1389 we need to make it fit by sending multiple ATA cmnds */
1390 TI_DBG5(("satRead10: case 1\n"));
1391
1392 fis->h.fisType = 0x27; /* Reg host to device */
1393 fis->h.c_pmPort = 0x80; /* C Bit is set */
1394 fis->h.command = SAT_READ_SECTORS; /* 0x20 */
1395 fis->h.features = 0; /* FIS reserve */
1396 fis->d.lbaLow = scsiCmnd->cdb[5]; /* FIS LBA (7 :0 ) */
1397 fis->d.lbaMid = scsiCmnd->cdb[4]; /* FIS LBA (15:8 ) */
1398 fis->d.lbaHigh = scsiCmnd->cdb[3]; /* FIS LBA (23:16) */
1399 fis->d.device =
1400 (bit8)((0x4 << 4) | (scsiCmnd->cdb[2] & 0xF)); /* FIS LBA (27:24) and FIS LBA mode */
1401 fis->d.lbaLowExp = 0;
1402 fis->d.lbaMidExp = 0;
1403 fis->d.lbaHighExp = 0;
1404 fis->d.featuresExp = 0;
1405 fis->d.sectorCount = scsiCmnd->cdb[8]; /* FIS sector count (7:0) */
1406 fis->d.sectorCountExp = 0;
1407 fis->d.reserved4 = 0;
1408 fis->d.control = 0; /* FIS HOB bit clear */
1409 fis->d.reserved5 = 0;
1410
1411
1412 agRequestType = AGSA_SATA_PROTOCOL_PIO_READ;
1413 satIOContext->ATACmd = SAT_READ_SECTORS;
1414 }
1415 }
1416
1417 /* case 3 and 4 */
1418 if (pSatDevData->sat48BitSupport == agTRUE)
1419 {
1420 if (pSatDevData->satDMASupport == agTRUE && pSatDevData->satDMAEnabled == agTRUE)
1421 {
1422 /* case 3 */
1423 /* READ DMA EXT */
1424 TI_DBG5(("satRead10: case 3\n"));
1425 fis->h.fisType = 0x27; /* Reg host to device */
1426
1427 fis->h.c_pmPort = 0x80; /* C Bit is set */
1428 fis->h.command = SAT_READ_DMA_EXT; /* 0x25 */
1429 fis->h.features = 0; /* FIS reserve */
1430 fis->d.lbaLow = scsiCmnd->cdb[5]; /* FIS LBA (7 :0 ) */
1431 fis->d.lbaMid = scsiCmnd->cdb[4]; /* FIS LBA (15:8 ) */
1432 fis->d.lbaHigh = scsiCmnd->cdb[3]; /* FIS LBA (23:16) */
1433 fis->d.device = 0x40; /* FIS LBA mode set */
1434 fis->d.lbaLowExp = scsiCmnd->cdb[2]; /* FIS LBA (31:24) */
1435 fis->d.lbaMidExp = 0; /* FIS LBA (39:32) */
1436 fis->d.lbaHighExp = 0; /* FIS LBA (47:40) */
1437 fis->d.featuresExp = 0; /* FIS reserve */
1438 fis->d.sectorCount = scsiCmnd->cdb[8]; /* FIS sector count (7:0) */
1439 fis->d.sectorCountExp = scsiCmnd->cdb[7]; /* FIS sector count (15:8) */
1440 fis->d.reserved4 = 0;
1441 fis->d.control = 0; /* FIS HOB bit clear */
1442 fis->d.reserved5 = 0;
1443
1444 agRequestType = AGSA_SATA_PROTOCOL_DMA_READ;
1445 satIOContext->ATACmd = SAT_READ_DMA_EXT;
1446
1447 }
1448 else
1449 {
1450 /* case 4 */
1451 /* READ MULTIPLE EXT or READ SECTOR(S) EXT or READ VERIFY SECTOR(S) EXT*/
1452 /* READ SECTORS EXT for easier implemetation */
1453 TI_DBG5(("satRead10: case 4\n"));
1454 fis->h.fisType = 0x27; /* Reg host to device */
1455 fis->h.c_pmPort = 0x80; /* C Bit is set */
1456
1457 /* Check FUA bit */
1458 if (scsiCmnd->cdb[1] & SCSI_READ10_FUA_MASK)
1459 {
1460
1461 /* for now, no support for FUA */
1462 satSetSensePayload( pSense,
1463 SCSI_SNSKEY_ILLEGAL_REQUEST,
1464 0,
1465 SCSI_SNSCODE_INVALID_FIELD_IN_CDB,
1466 satIOContext);
1467
1468 ostiInitiatorIOCompleted( tiRoot,
1469 tiIORequest,
1470 tiIOSuccess,
1471 SCSI_STAT_CHECK_CONDITION,
1472 satIOContext->pTiSenseData,
1473 satIOContext->interruptContext );
1474 return tiSuccess;
1475 }
1476
1477 fis->h.command = SAT_READ_SECTORS_EXT; /* 0x24 */
1478
1479 fis->h.features = 0; /* FIS reserve */
1480 fis->d.lbaLow = scsiCmnd->cdb[5]; /* FIS LBA (7 :0 ) */
1481 fis->d.lbaMid = scsiCmnd->cdb[4]; /* FIS LBA (15:8 ) */
1482 fis->d.lbaHigh = scsiCmnd->cdb[3]; /* FIS LBA (23:16) */
1483 fis->d.device = 0x40; /* FIS LBA mode set */
1484 fis->d.lbaLowExp = scsiCmnd->cdb[2]; /* FIS LBA (31:24) */
1485 fis->d.lbaMidExp = 0; /* FIS LBA (39:32) */
1486 fis->d.lbaHighExp = 0; /* FIS LBA (47:40) */
1487 fis->d.featuresExp = 0; /* FIS reserve */
1488 fis->d.sectorCount = scsiCmnd->cdb[8]; /* FIS sector count (7:0) */
1489 fis->d.sectorCountExp = scsiCmnd->cdb[7]; /* FIS sector count (15:8) */
1490 fis->d.reserved4 = 0;
1491 fis->d.control = 0; /* FIS HOB bit clear */
1492 fis->d.reserved5 = 0;
1493
1494 agRequestType = AGSA_SATA_PROTOCOL_PIO_READ;
1495 satIOContext->ATACmd = SAT_READ_SECTORS_EXT;
1496 }
1497 }
1498
1499 /* case 5 */
1500 if (pSatDevData->satNCQ == agTRUE)
1501 {
1502 /* READ FPDMA QUEUED */
1503 if (pSatDevData->sat48BitSupport != agTRUE)
1504 {
1505 TI_DBG5(("satRead10: case 5 !!! error NCQ but 28 bit address support \n"));
1506 satSetSensePayload( pSense,
1507 SCSI_SNSKEY_ILLEGAL_REQUEST,
1508 0,
1509 SCSI_SNSCODE_INVALID_FIELD_IN_CDB,
1510 satIOContext);
1511
1512 ostiInitiatorIOCompleted( tiRoot,
1513 tiIORequest,
1514 tiIOSuccess,
1515 SCSI_STAT_CHECK_CONDITION,
1516 satIOContext->pTiSenseData,
1517 satIOContext->interruptContext );
1518 return tiSuccess;
1519 }
1520
1521 TI_DBG6(("satRead10: case 5\n"));
1522
1523 /* Support 48-bit FPDMA addressing, use READ FPDMA QUEUE command */
1524
1525 fis->h.fisType = 0x27; /* Reg host to device */
1526 fis->h.c_pmPort = 0x80; /* C Bit is set */
1527 fis->h.command = SAT_READ_FPDMA_QUEUED; /* 0x60 */
1528 fis->h.features = scsiCmnd->cdb[8]; /* FIS sector count (7:0) */
1529 fis->d.lbaLow = scsiCmnd->cdb[5]; /* FIS LBA (7 :0 ) */
1530 fis->d.lbaMid = scsiCmnd->cdb[4]; /* FIS LBA (15:8 ) */
1531 fis->d.lbaHigh = scsiCmnd->cdb[3]; /* FIS LBA (23:16) */
1532
1533 /* Check FUA bit */
1534 if (scsiCmnd->cdb[1] & SCSI_READ10_FUA_MASK)
1535 fis->d.device = 0xC0; /* FIS FUA set */
1536 else
1537 fis->d.device = 0x40; /* FIS FUA clear */
1538
1539 fis->d.lbaLowExp = scsiCmnd->cdb[2]; /* FIS LBA (31:24) */
1540 fis->d.lbaMidExp = 0; /* FIS LBA (39:32) */
1541 fis->d.lbaHighExp = 0; /* FIS LBA (47:40) */
1542 fis->d.featuresExp = scsiCmnd->cdb[7]; /* FIS sector count (15:8) */
1543 fis->d.sectorCount = 0; /* Tag (7:3) set by LL layer */
1544 fis->d.sectorCountExp = 0;
1545 fis->d.reserved4 = 0;
1546 fis->d.control = 0; /* FIS HOB bit clear */
1547 fis->d.reserved5 = 0;
1548
1549 agRequestType = AGSA_SATA_PROTOCOL_FPDMA_READ;
1550 satIOContext->ATACmd = SAT_READ_FPDMA_QUEUED;
1551 }
1552
1553
1554 // tdhexdump("satRead10 final fis", (bit8 *)fis, sizeof(agsaFisRegHostToDevice_t));
1555
1556 /* saves the current LBA and orginal TL */
1557 satIOContext->currentLBA = lba;
1558 satIOContext->OrgTL = tl;
1559
1560 /*
1561 computing number of loop and remainder for tl
1562 0xFF in case not ext
1563 0xFFFF in case EXT
1564 */
1565 if (fis->h.command == SAT_READ_SECTORS || fis->h.command == SAT_READ_DMA)
1566 {
1567 LoopNum = satComputeLoopNum(tl, 0xFF);
1568 }
1569 else if (fis->h.command == SAT_READ_SECTORS_EXT || fis->h.command == SAT_READ_DMA_EXT)
1570 {
1571 /* SAT_READ_SECTORS_EXT, SAT_READ_DMA_EXT */
1572 LoopNum = satComputeLoopNum(tl, 0xFFFF);
1573 }
1574 else
1575 {
1576 /* SAT_READ_FPDMA_QUEUED */
1577 LoopNum = satComputeLoopNum(tl, 0xFFFF);
1578 }
1579
1580 satIOContext->LoopNum = LoopNum;
1581
1582 /* Initialize CB for SATA completion.
1583 */
1584 if (LoopNum == 1)
1585 {
1586 TI_DBG5(("satRead10: NON CHAINED data\n"));
1587 satIOContext->satCompleteCB = &satNonChainedDataIOCB;
1588 }
1589 else
1590 {
1591 TI_DBG1(("satRead10: CHAINED data\n"));
1592 /* re-setting tl */
1593 if (fis->h.command == SAT_READ_SECTORS || fis->h.command == SAT_READ_DMA)
1594 {
1595 fis->d.sectorCount = 0xFF;
1596 }
1597 else if (fis->h.command == SAT_READ_SECTORS_EXT || fis->h.command == SAT_READ_DMA_EXT)
1598 {
1599 /* SAT_READ_SECTORS_EXT, SAT_READ_DMA_EXT */
1600 fis->d.sectorCount = 0xFF;
1601 fis->d.sectorCountExp = 0xFF;
1602 }
1603 else
1604 {
1605 /* SAT_READ_FPDMA_QUEUED */
1606 fis->h.features = 0xFF;
1607 fis->d.featuresExp = 0xFF;
1608 }
1609
1610 /* chained data */
1611 satIOContext->satCompleteCB = &satChainedDataIOCB;
1612
1613 }
1614
1615 /*
1616 * Prepare SGL and send FIS to LL layer.
1617 */
1618 satIOContext->reqType = agRequestType; /* Save it */
1619
1620 status = sataLLIOStart( tiRoot,
1621 tiIORequest,
1622 tiDeviceHandle,
1623 tiScsiRequest,
1624 satIOContext);
1625
1626 TI_DBG5(("satRead10: return\n"));
1627 return (status);
1628
1629 }
1630
1631
1632 /*****************************************************************************/
1633 /*! \brief SAT implementation for SCSI satRead_1.
1634 *
1635 * SAT implementation for SCSI satRead_1
1636 * Sub function of satRead10
1637 *
1638 * \param tiRoot: Pointer to TISA initiator driver/port instance.
1639 * \param tiIORequest: Pointer to TISA I/O request context for this I/O.
1640 * \param tiDeviceHandle: Pointer to TISA device handle for this I/O.
1641 * \param tiScsiRequest: Pointer to TISA SCSI I/O request and SGL list.
1642 * \param satIOContext_t: Pointer to the SAT IO Context
1643 *
1644 * \return If command is started successfully
1645 * - \e tiSuccess: I/O request successfully initiated.
1646 * - \e tiBusy: No resources available, try again later.
1647 * - \e tiIONoDevice: Invalid device handle.
1648 * - \e tiError: Other errors.
1649 */
1650 /*****************************************************************************/
1651 /*
1652 * as a part of loop for read10
1653 */
satRead_1(tiRoot_t * tiRoot,tiIORequest_t * tiIORequest,tiDeviceHandle_t * tiDeviceHandle,tiScsiInitiatorRequest_t * tiScsiRequest,satIOContext_t * satIOContext)1654 GLOBAL bit32 satRead_1(
1655 tiRoot_t *tiRoot,
1656 tiIORequest_t *tiIORequest,
1657 tiDeviceHandle_t *tiDeviceHandle,
1658 tiScsiInitiatorRequest_t *tiScsiRequest,
1659 satIOContext_t *satIOContext)
1660 {
1661 /*
1662 Assumption: error check on lba and tl has been done in satRead*()
1663 lba = lba + tl;
1664 */
1665 bit32 status;
1666 satIOContext_t *satOrgIOContext = agNULL;
1667 tiIniScsiCmnd_t *scsiCmnd;
1668 agsaFisRegHostToDevice_t *fis;
1669 bit32 agRequestType = AGSA_SATA_PROTOCOL_DMA_READ;
1670 bit32 lba = 0;
1671 bit32 DenomTL = 0xFF;
1672 bit32 Remainder = 0;
1673 bit8 LBA[4]; /* 0 MSB, 3 LSB */
1674
1675 TI_DBG2(("satRead_1: start\n"));
1676
1677 fis = satIOContext->pFis;
1678 satOrgIOContext = satIOContext->satOrgIOContext;
1679 scsiCmnd = satOrgIOContext->pScsiCmnd;
1680
1681 osti_memset(LBA,0, sizeof(LBA));
1682
1683 switch (satOrgIOContext->ATACmd)
1684 {
1685 case SAT_READ_DMA:
1686 DenomTL = 0xFF;
1687 break;
1688 case SAT_READ_SECTORS:
1689 DenomTL = 0xFF;
1690 break;
1691 case SAT_READ_DMA_EXT:
1692 DenomTL = 0xFFFF;
1693 break;
1694 case SAT_READ_SECTORS_EXT:
1695 DenomTL = 0xFFFF;
1696 break;
1697 case SAT_READ_FPDMA_QUEUED:
1698 DenomTL = 0xFFFF;
1699 break;
1700 default:
1701 TI_DBG1(("satRead_1: error incorrect ata command 0x%x\n", satIOContext->ATACmd));
1702 return tiError;
1703 break;
1704 }
1705
1706 Remainder = satOrgIOContext->OrgTL % DenomTL;
1707 satOrgIOContext->currentLBA = satOrgIOContext->currentLBA + DenomTL;
1708 lba = satOrgIOContext->currentLBA;
1709
1710 LBA[0] = (bit8)((lba & 0xF000) >> (8 * 3));
1711 LBA[1] = (bit8)((lba & 0xF00) >> (8 * 2));
1712 LBA[2] = (bit8)((lba & 0xF0) >> 8);
1713 LBA[3] = (bit8)(lba & 0xF);
1714
1715
1716 switch (satOrgIOContext->ATACmd)
1717 {
1718 case SAT_READ_DMA:
1719 fis->h.fisType = 0x27; /* Reg host to device */
1720 fis->h.c_pmPort = 0x80; /* C Bit is set */
1721 fis->h.command = SAT_READ_DMA; /* 0xC8 */
1722 fis->h.features = 0; /* FIS reserve */
1723 fis->d.lbaLow = LBA[3]; /* FIS LBA (7 :0 ) */
1724 fis->d.lbaMid = LBA[2]; /* FIS LBA (15:8 ) */
1725 fis->d.lbaHigh = LBA[1]; /* FIS LBA (23:16) */
1726 fis->d.device =
1727 (bit8)((0x4 << 4) | (LBA[0] & 0xF)); /* FIS LBA (27:24) and FIS LBA mode */
1728 fis->d.lbaLowExp = 0;
1729 fis->d.lbaMidExp = 0;
1730 fis->d.lbaHighExp = 0;
1731 fis->d.featuresExp = 0;
1732
1733 if (satOrgIOContext->LoopNum == 1)
1734 {
1735 /* last loop */
1736 fis->d.sectorCount = (bit8)Remainder; /* FIS sector count (7:0) */
1737 }
1738 else
1739 {
1740 fis->d.sectorCount = 0xFF; /* FIS sector count (7:0) */
1741 }
1742
1743 fis->d.sectorCountExp = 0;
1744 fis->d.reserved4 = 0;
1745 fis->d.control = 0; /* FIS HOB bit clear */
1746 fis->d.reserved5 = 0;
1747
1748 agRequestType = AGSA_SATA_PROTOCOL_DMA_READ;
1749
1750 break;
1751 case SAT_READ_SECTORS:
1752 fis->h.fisType = 0x27; /* Reg host to device */
1753 fis->h.c_pmPort = 0x80; /* C Bit is set */
1754 fis->h.command = SAT_READ_SECTORS; /* 0x20 */
1755 fis->h.features = 0; /* FIS reserve */
1756 fis->d.lbaLow = LBA[3]; /* FIS LBA (7 :0 ) */
1757 fis->d.lbaMid = LBA[2]; /* FIS LBA (15:8 ) */
1758 fis->d.lbaHigh = LBA[1]; /* FIS LBA (23:16) */
1759 fis->d.device =
1760 (bit8)((0x4 << 4) | (LBA[0] & 0xF)); /* FIS LBA (27:24) and FIS LBA mode */
1761 fis->d.lbaLowExp = 0;
1762 fis->d.lbaMidExp = 0;
1763 fis->d.lbaHighExp = 0;
1764 fis->d.featuresExp = 0;
1765 if (satOrgIOContext->LoopNum == 1)
1766 {
1767 /* last loop */
1768 fis->d.sectorCount = (bit8)Remainder; /* FIS sector count (7:0) */
1769 }
1770 else
1771 {
1772 fis->d.sectorCount = 0xFF; /* FIS sector count (7:0) */
1773 }
1774 fis->d.sectorCountExp = 0;
1775 fis->d.reserved4 = 0;
1776 fis->d.control = 0; /* FIS HOB bit clear */
1777 fis->d.reserved5 = 0;
1778
1779 agRequestType = AGSA_SATA_PROTOCOL_PIO_READ;
1780
1781 break;
1782 case SAT_READ_DMA_EXT:
1783 fis->h.fisType = 0x27; /* Reg host to device */
1784 fis->h.c_pmPort = 0x80; /* C Bit is set */
1785 fis->h.command = SAT_READ_DMA_EXT; /* 0x25 */
1786 fis->h.features = 0; /* FIS reserve */
1787 fis->d.lbaLow = LBA[3]; /* FIS LBA (7 :0 ) */
1788 fis->d.lbaMid = LBA[2]; /* FIS LBA (15:8 ) */
1789 fis->d.lbaHigh = LBA[1]; /* FIS LBA (23:16) */
1790 fis->d.device = 0x40; /* FIS LBA mode set */
1791 fis->d.lbaLowExp = LBA[0]; /* FIS LBA (31:24) */
1792 fis->d.lbaMidExp = 0; /* FIS LBA (39:32) */
1793 fis->d.lbaHighExp = 0; /* FIS LBA (47:40) */
1794 fis->d.featuresExp = 0; /* FIS reserve */
1795 if (satOrgIOContext->LoopNum == 1)
1796 {
1797 /* last loop */
1798 fis->d.sectorCount = (bit8)(Remainder & 0xFF); /* FIS sector count (7:0) */
1799 fis->d.sectorCountExp = (bit8)((Remainder & 0xFF00) >> 8); /* FIS sector count (15:8) */
1800
1801 }
1802 else
1803 {
1804 fis->d.sectorCount = 0xFF; /* FIS sector count (7:0) */
1805 fis->d.sectorCountExp = 0xFF; /* FIS sector count (15:8) */
1806 }
1807 fis->d.reserved4 = 0;
1808 fis->d.control = 0; /* FIS HOB bit clear */
1809 fis->d.reserved5 = 0;
1810
1811 agRequestType = AGSA_SATA_PROTOCOL_DMA_READ;
1812
1813 break;
1814 case SAT_READ_SECTORS_EXT:
1815 fis->h.fisType = 0x27; /* Reg host to device */
1816 fis->h.c_pmPort = 0x80; /* C Bit is set */
1817 fis->h.command = SAT_READ_SECTORS_EXT; /* 0x24 */
1818 fis->h.features = 0; /* FIS reserve */
1819 fis->d.lbaLow = LBA[3]; /* FIS LBA (7 :0 ) */
1820 fis->d.lbaMid = LBA[2]; /* FIS LBA (15:8 ) */
1821 fis->d.lbaHigh = LBA[1]; /* FIS LBA (23:16) */
1822 fis->d.device = 0x40; /* FIS LBA mode set */
1823 fis->d.lbaLowExp = LBA[0]; /* FIS LBA (31:24) */
1824 fis->d.lbaMidExp = 0; /* FIS LBA (39:32) */
1825 fis->d.lbaHighExp = 0; /* FIS LBA (47:40) */
1826 fis->d.featuresExp = 0; /* FIS reserve */
1827 if (satOrgIOContext->LoopNum == 1)
1828 {
1829 /* last loop */
1830 fis->d.sectorCount = (bit8)(Remainder & 0xFF); /* FIS sector count (7:0) */
1831 fis->d.sectorCountExp = (bit8)((Remainder & 0xFF00) >> 8); /* FIS sector count (15:8) */
1832 }
1833 else
1834 {
1835 fis->d.sectorCount = 0xFF; /* FIS sector count (7:0) */
1836 fis->d.sectorCountExp = 0xFF; /* FIS sector count (15:8) */
1837 }
1838 fis->d.reserved4 = 0;
1839 fis->d.control = 0; /* FIS HOB bit clear */
1840 fis->d.reserved5 = 0;
1841
1842 agRequestType = AGSA_SATA_PROTOCOL_PIO_READ;
1843 break;
1844 case SAT_READ_FPDMA_QUEUED:
1845 fis->h.fisType = 0x27; /* Reg host to device */
1846 fis->h.c_pmPort = 0x80; /* C Bit is set */
1847 fis->h.command = SAT_READ_FPDMA_QUEUED; /* 0x60 */
1848 fis->d.lbaLow = LBA[3]; /* FIS LBA (7 :0 ) */
1849 fis->d.lbaMid = LBA[2]; /* FIS LBA (15:8 ) */
1850 fis->d.lbaHigh = LBA[1]; /* FIS LBA (23:16) */
1851
1852 /* Check FUA bit */
1853 if (scsiCmnd->cdb[1] & SCSI_READ10_FUA_MASK)
1854 fis->d.device = 0xC0; /* FIS FUA set */
1855 else
1856 fis->d.device = 0x40; /* FIS FUA clear */
1857
1858 fis->d.lbaLowExp = LBA[0]; /* FIS LBA (31:24) */
1859 fis->d.lbaMidExp = 0; /* FIS LBA (39:32) */
1860 fis->d.lbaHighExp = 0; /* FIS LBA (47:40) */
1861 if (satOrgIOContext->LoopNum == 1)
1862 {
1863 /* last loop */
1864 fis->h.features = (bit8)(Remainder & 0xFF); /* FIS sector count (7:0) */
1865 fis->d.featuresExp = (bit8)((Remainder & 0xFF00) >> 8); /* FIS sector count (15:8) */
1866 }
1867 else
1868 {
1869 fis->h.features = 0xFF; /* FIS sector count (7:0) */
1870 fis->d.featuresExp = 0xFF; /* FIS sector count (15:8) */
1871 }
1872 fis->d.sectorCount = 0; /* Tag (7:3) set by LL layer */
1873 fis->d.sectorCountExp = 0;
1874 fis->d.reserved4 = 0;
1875 fis->d.control = 0; /* FIS HOB bit clear */
1876 fis->d.reserved5 = 0;
1877
1878 agRequestType = AGSA_SATA_PROTOCOL_FPDMA_READ;
1879 break;
1880 default:
1881 TI_DBG1(("satRead_1: error incorrect ata command 0x%x\n", satIOContext->ATACmd));
1882 return tiError;
1883 break;
1884 }
1885
1886 /* Initialize CB for SATA completion.
1887 */
1888 /* chained data */
1889 satIOContext->satCompleteCB = &satChainedDataIOCB;
1890
1891
1892 /*
1893 * Prepare SGL and send FIS to LL layer.
1894 */
1895 satIOContext->reqType = agRequestType; /* Save it */
1896
1897 status = sataLLIOStart( tiRoot,
1898 tiIORequest,
1899 tiDeviceHandle,
1900 tiScsiRequest,
1901 satIOContext);
1902
1903 TI_DBG5(("satRead_1: return\n"));
1904 return (status);
1905 }
1906 /*****************************************************************************/
1907 /*! \brief SAT implementation for SCSI READ12.
1908 *
1909 * SAT implementation for SCSI READ12 and send FIS request to LL layer.
1910 *
1911 * \param tiRoot: Pointer to TISA initiator driver/port instance.
1912 * \param tiIORequest: Pointer to TISA I/O request context for this I/O.
1913 * \param tiDeviceHandle: Pointer to TISA device handle for this I/O.
1914 * \param tiScsiRequest: Pointer to TISA SCSI I/O request and SGL list.
1915 * \param satIOContext_t: Pointer to the SAT IO Context
1916 *
1917 * \return If command is started successfully
1918 * - \e tiSuccess: I/O request successfully initiated.
1919 * - \e tiBusy: No resources available, try again later.
1920 * - \e tiIONoDevice: Invalid device handle.
1921 * - \e tiError: Other errors.
1922 */
1923 /*****************************************************************************/
satRead12(tiRoot_t * tiRoot,tiIORequest_t * tiIORequest,tiDeviceHandle_t * tiDeviceHandle,tiScsiInitiatorRequest_t * tiScsiRequest,satIOContext_t * satIOContext)1924 GLOBAL bit32 satRead12(
1925 tiRoot_t *tiRoot,
1926 tiIORequest_t *tiIORequest,
1927 tiDeviceHandle_t *tiDeviceHandle,
1928 tiScsiInitiatorRequest_t *tiScsiRequest,
1929 satIOContext_t *satIOContext)
1930 {
1931 bit32 status;
1932 bit32 agRequestType = AGSA_SATA_PROTOCOL_DMA_READ;
1933 satDeviceData_t *pSatDevData;
1934 scsiRspSense_t *pSense;
1935 tiIniScsiCmnd_t *scsiCmnd;
1936 agsaFisRegHostToDevice_t *fis;
1937 bit32 lba = 0;
1938 bit32 tl = 0;
1939 bit32 LoopNum = 1;
1940 bit8 LBA[4];
1941 bit8 TL[4];
1942 bit32 rangeChk = agFALSE; /* lba and tl range check */
1943
1944 pSense = satIOContext->pSense;
1945 pSatDevData = satIOContext->pSatDevData;
1946 scsiCmnd = &tiScsiRequest->scsiCmnd;
1947 fis = satIOContext->pFis;
1948
1949 TI_DBG5(("satRead12: start\n"));
1950
1951 /* checking FUA_NV */
1952 if (scsiCmnd->cdb[1] & SCSI_FUA_NV_MASK)
1953 {
1954 satSetSensePayload( pSense,
1955 SCSI_SNSKEY_ILLEGAL_REQUEST,
1956 0,
1957 SCSI_SNSCODE_INVALID_FIELD_IN_CDB,
1958 satIOContext);
1959
1960 ostiInitiatorIOCompleted( tiRoot,
1961 tiIORequest,
1962 tiIOSuccess,
1963 SCSI_STAT_CHECK_CONDITION,
1964 satIOContext->pTiSenseData,
1965 satIOContext->interruptContext );
1966
1967 TI_DBG1(("satRead12: return FUA_NV\n"));
1968 return tiSuccess;
1969
1970 }
1971
1972 /* checking CONTROL */
1973 /* NACA == 1 or LINK == 1*/
1974 if ( (scsiCmnd->cdb[11] & SCSI_NACA_MASK) || (scsiCmnd->cdb[11] & SCSI_LINK_MASK) )
1975 {
1976 satSetSensePayload( pSense,
1977 SCSI_SNSKEY_ILLEGAL_REQUEST,
1978 0,
1979 SCSI_SNSCODE_INVALID_FIELD_IN_CDB,
1980 satIOContext);
1981
1982 ostiInitiatorIOCompleted( tiRoot,
1983 tiIORequest,
1984 tiIOSuccess,
1985 SCSI_STAT_CHECK_CONDITION,
1986 satIOContext->pTiSenseData,
1987 satIOContext->interruptContext );
1988
1989 TI_DBG2(("satRead12: return control\n"));
1990 return tiSuccess;
1991 }
1992
1993 osti_memset(LBA, 0, sizeof(LBA));
1994 osti_memset(TL, 0, sizeof(TL));
1995
1996 /* do not use memcpy due to indexing in LBA and TL */
1997 LBA[0] = scsiCmnd->cdb[2]; /* MSB */
1998 LBA[1] = scsiCmnd->cdb[3];
1999 LBA[2] = scsiCmnd->cdb[4];
2000 LBA[3] = scsiCmnd->cdb[5]; /* LSB */
2001
2002 TL[0] = scsiCmnd->cdb[6]; /* MSB */
2003 TL[1] = scsiCmnd->cdb[7];
2004 TL[2] = scsiCmnd->cdb[8];
2005 TL[3] = scsiCmnd->cdb[9]; /* LSB */
2006
2007 rangeChk = satAddNComparebit32(LBA, TL);
2008
2009 lba = satComputeCDB12LBA(satIOContext);
2010 tl = satComputeCDB12TL(satIOContext);
2011
2012 /* Table 34, 9.1, p 46 */
2013 /*
2014 note: As of 2/10/2006, no support for DMA QUEUED
2015 */
2016
2017 /*
2018 Table 34, 9.1, p 46, b
2019 When no 48-bit addressing support or NCQ, if LBA is beyond (2^28 - 1),
2020 return check condition
2021 */
2022 if (pSatDevData->satNCQ != agTRUE &&
2023 pSatDevData->sat48BitSupport != agTRUE
2024 )
2025 {
2026 if (lba > SAT_TR_LBA_LIMIT - 1)
2027 {
2028 TI_DBG1(("satRead12: return LBA out of range, not EXT\n"));
2029 satSetSensePayload( pSense,
2030 SCSI_SNSKEY_ILLEGAL_REQUEST,
2031 0,
2032 SCSI_SNSCODE_LOGICAL_BLOCK_ADDRESS_OUT_OF_RANGE,
2033 satIOContext);
2034
2035 ostiInitiatorIOCompleted( tiRoot,
2036 tiIORequest,
2037 tiIOSuccess,
2038 SCSI_STAT_CHECK_CONDITION,
2039 satIOContext->pTiSenseData,
2040 satIOContext->interruptContext );
2041
2042 return tiSuccess;
2043 }
2044 if (rangeChk) // if (lba + tl > SAT_TR_LBA_LIMIT)
2045 {
2046 TI_DBG1(("satRead12: return LBA+TL out of range, not EXT\n"));
2047 satSetSensePayload( pSense,
2048 SCSI_SNSKEY_ILLEGAL_REQUEST,
2049 0,
2050 SCSI_SNSCODE_LOGICAL_BLOCK_ADDRESS_OUT_OF_RANGE,
2051 satIOContext);
2052
2053 ostiInitiatorIOCompleted( tiRoot,
2054 tiIORequest,
2055 tiIOSuccess,
2056 SCSI_STAT_CHECK_CONDITION,
2057 satIOContext->pTiSenseData,
2058 satIOContext->interruptContext );
2059
2060 return tiSuccess;
2061 }
2062 }
2063
2064 /* case 1 and 2 */
2065 if (!rangeChk) // if (lba + tl <= SAT_TR_LBA_LIMIT)
2066 {
2067 if (pSatDevData->satDMASupport == agTRUE && pSatDevData->satDMAEnabled == agTRUE)
2068 {
2069 /* case 2 */
2070 /* READ DMA*/
2071 /* in case that we can't fit the transfer length,
2072 we need to make it fit by sending multiple ATA cmnds */
2073 TI_DBG5(("satRead12: case 2\n"));
2074
2075
2076 fis->h.fisType = 0x27; /* Reg host to device */
2077 fis->h.c_pmPort = 0x80; /* C Bit is set */
2078 fis->h.command = SAT_READ_DMA; /* 0xC8 */
2079 fis->h.features = 0; /* FIS reserve */
2080 fis->d.lbaLow = scsiCmnd->cdb[5]; /* FIS LBA (7 :0 ) */
2081 fis->d.lbaMid = scsiCmnd->cdb[4]; /* FIS LBA (15:8 ) */
2082 fis->d.lbaHigh = scsiCmnd->cdb[3]; /* FIS LBA (23:16) */
2083 fis->d.device =
2084 (bit8)((0x4 << 4) | (scsiCmnd->cdb[2] & 0xF)); /* FIS LBA (27:24) and FIS LBA mode */
2085 fis->d.lbaLowExp = 0;
2086 fis->d.lbaMidExp = 0;
2087 fis->d.lbaHighExp = 0;
2088 fis->d.featuresExp = 0;
2089 fis->d.sectorCount = scsiCmnd->cdb[9]; /* FIS sector count (7:0) */
2090 fis->d.sectorCountExp = 0;
2091 fis->d.reserved4 = 0;
2092 fis->d.control = 0; /* FIS HOB bit clear */
2093 fis->d.reserved5 = 0;
2094
2095
2096 agRequestType = AGSA_SATA_PROTOCOL_DMA_READ;
2097 satIOContext->ATACmd = SAT_READ_DMA;
2098 }
2099 else
2100 {
2101 /* case 1 */
2102 /* READ MULTIPLE or READ SECTOR(S) */
2103 /* READ SECTORS for easier implemetation */
2104 /* can't fit the transfer length but need to make it fit by sending multiple*/
2105 TI_DBG5(("satRead12: case 1\n"));
2106
2107 fis->h.fisType = 0x27; /* Reg host to device */
2108 fis->h.c_pmPort = 0x80; /* C Bit is set */
2109 fis->h.command = SAT_READ_SECTORS; /* 0x20 */
2110 fis->h.features = 0; /* FIS reserve */
2111 fis->d.lbaLow = scsiCmnd->cdb[5]; /* FIS LBA (7 :0 ) */
2112 fis->d.lbaMid = scsiCmnd->cdb[4]; /* FIS LBA (15:8 ) */
2113 fis->d.lbaHigh = scsiCmnd->cdb[3]; /* FIS LBA (23:16) */
2114 fis->d.device =
2115 (bit8)((0x4 << 4) | (scsiCmnd->cdb[2] & 0xF)); /* FIS LBA (27:24) and FIS LBA mode */
2116 fis->d.lbaLowExp = 0;
2117 fis->d.lbaMidExp = 0;
2118 fis->d.lbaHighExp = 0;
2119 fis->d.featuresExp = 0;
2120 fis->d.sectorCount = scsiCmnd->cdb[9]; /* FIS sector count (7:0) */
2121 fis->d.sectorCountExp = 0;
2122 fis->d.reserved4 = 0;
2123 fis->d.control = 0; /* FIS HOB bit clear */
2124 fis->d.reserved5 = 0;
2125
2126
2127 agRequestType = AGSA_SATA_PROTOCOL_PIO_READ;
2128 satIOContext->ATACmd = SAT_READ_SECTORS;
2129 }
2130 }
2131
2132 /* case 3 and 4 */
2133 if (pSatDevData->sat48BitSupport == agTRUE)
2134 {
2135 if (pSatDevData->satDMASupport == agTRUE && pSatDevData->satDMAEnabled == agTRUE)
2136 {
2137 /* case 3 */
2138 /* READ DMA EXT */
2139 TI_DBG5(("satRead12: case 3\n"));
2140 fis->h.fisType = 0x27; /* Reg host to device */
2141
2142 fis->h.c_pmPort = 0x80; /* C Bit is set */
2143 fis->h.command = SAT_READ_DMA_EXT; /* 0x25 */
2144 fis->h.features = 0; /* FIS reserve */
2145 fis->d.lbaLow = scsiCmnd->cdb[5]; /* FIS LBA (7 :0 ) */
2146 fis->d.lbaMid = scsiCmnd->cdb[4]; /* FIS LBA (15:8 ) */
2147 fis->d.lbaHigh = scsiCmnd->cdb[3]; /* FIS LBA (23:16) */
2148 fis->d.device = 0x40; /* FIS LBA mode set */
2149 fis->d.lbaLowExp = scsiCmnd->cdb[2]; /* FIS LBA (31:24) */
2150 fis->d.lbaMidExp = 0; /* FIS LBA (39:32) */
2151 fis->d.lbaHighExp = 0; /* FIS LBA (47:40) */
2152 fis->d.featuresExp = 0; /* FIS reserve */
2153 fis->d.sectorCount = scsiCmnd->cdb[9]; /* FIS sector count (7:0) */
2154 fis->d.sectorCountExp = scsiCmnd->cdb[8]; /* FIS sector count (15:8) */
2155 fis->d.reserved4 = 0;
2156 fis->d.control = 0; /* FIS HOB bit clear */
2157 fis->d.reserved5 = 0;
2158
2159 agRequestType = AGSA_SATA_PROTOCOL_DMA_READ;
2160 satIOContext->ATACmd = SAT_READ_DMA_EXT;
2161
2162 }
2163 else
2164 {
2165 /* case 4 */
2166 /* READ MULTIPLE EXT or READ SECTOR(S) EXT or READ VERIFY SECTOR(S) EXT*/
2167 /* READ SECTORS EXT for easier implemetation */
2168 TI_DBG5(("satRead12: case 4\n"));
2169 fis->h.fisType = 0x27; /* Reg host to device */
2170 fis->h.c_pmPort = 0x80; /* C Bit is set */
2171
2172 /* Check FUA bit */
2173 if (scsiCmnd->cdb[1] & SCSI_READ12_FUA_MASK)
2174 {
2175 /* for now, no support for FUA */
2176 satSetSensePayload( pSense,
2177 SCSI_SNSKEY_ILLEGAL_REQUEST,
2178 0,
2179 SCSI_SNSCODE_INVALID_FIELD_IN_CDB,
2180 satIOContext);
2181
2182 ostiInitiatorIOCompleted( tiRoot,
2183 tiIORequest,
2184 tiIOSuccess,
2185 SCSI_STAT_CHECK_CONDITION,
2186 satIOContext->pTiSenseData,
2187 satIOContext->interruptContext );
2188 return tiSuccess;
2189 }
2190
2191 fis->h.command = SAT_READ_SECTORS_EXT; /* 0x24 */
2192
2193 fis->h.features = 0; /* FIS reserve */
2194 fis->d.lbaLow = scsiCmnd->cdb[5]; /* FIS LBA (7 :0 ) */
2195 fis->d.lbaMid = scsiCmnd->cdb[4]; /* FIS LBA (15:8 ) */
2196 fis->d.lbaHigh = scsiCmnd->cdb[3]; /* FIS LBA (23:16) */
2197 fis->d.device = 0x40; /* FIS LBA mode set */
2198 fis->d.lbaLowExp = scsiCmnd->cdb[2]; /* FIS LBA (31:24) */
2199 fis->d.lbaMidExp = 0; /* FIS LBA (39:32) */
2200 fis->d.lbaHighExp = 0; /* FIS LBA (47:40) */
2201 fis->d.featuresExp = 0; /* FIS reserve */
2202 fis->d.sectorCount = scsiCmnd->cdb[9]; /* FIS sector count (7:0) */
2203 fis->d.sectorCountExp = scsiCmnd->cdb[8]; /* FIS sector count (15:8) */
2204 fis->d.reserved4 = 0;
2205 fis->d.control = 0; /* FIS HOB bit clear */
2206 fis->d.reserved5 = 0;
2207
2208 agRequestType = AGSA_SATA_PROTOCOL_PIO_READ;
2209 satIOContext->ATACmd = SAT_READ_SECTORS_EXT;
2210 }
2211 }
2212
2213 /* case 5 */
2214 if (pSatDevData->satNCQ == agTRUE)
2215 {
2216 /* READ FPDMA QUEUED */
2217 if (pSatDevData->sat48BitSupport != agTRUE)
2218 {
2219 TI_DBG5(("satRead12: case 5 !!! error NCQ but 28 bit address support \n"));
2220 satSetSensePayload( pSense,
2221 SCSI_SNSKEY_ILLEGAL_REQUEST,
2222 0,
2223 SCSI_SNSCODE_INVALID_FIELD_IN_CDB,
2224 satIOContext);
2225
2226 ostiInitiatorIOCompleted( tiRoot,
2227 tiIORequest,
2228 tiIOSuccess,
2229 SCSI_STAT_CHECK_CONDITION,
2230 satIOContext->pTiSenseData,
2231 satIOContext->interruptContext );
2232 return tiSuccess;
2233 }
2234
2235 TI_DBG6(("satRead12: case 5\n"));
2236
2237 /* Support 48-bit FPDMA addressing, use READ FPDMA QUEUE command */
2238
2239 fis->h.fisType = 0x27; /* Reg host to device */
2240 fis->h.c_pmPort = 0x80; /* C Bit is set */
2241 fis->h.command = SAT_READ_FPDMA_QUEUED; /* 0x60 */
2242 fis->h.features = scsiCmnd->cdb[9]; /* FIS sector count (7:0) */
2243 fis->d.lbaLow = scsiCmnd->cdb[5]; /* FIS LBA (7 :0 ) */
2244 fis->d.lbaMid = scsiCmnd->cdb[4]; /* FIS LBA (15:8 ) */
2245 fis->d.lbaHigh = scsiCmnd->cdb[3]; /* FIS LBA (23:16) */
2246
2247 /* Check FUA bit */
2248 if (scsiCmnd->cdb[1] & SCSI_READ12_FUA_MASK)
2249 fis->d.device = 0xC0; /* FIS FUA set */
2250 else
2251 fis->d.device = 0x40; /* FIS FUA clear */
2252
2253 fis->d.lbaLowExp = scsiCmnd->cdb[2]; /* FIS LBA (31:24) */
2254 fis->d.lbaMidExp = 0; /* FIS LBA (39:32) */
2255 fis->d.lbaHighExp = 0; /* FIS LBA (47:40) */
2256 fis->d.featuresExp = scsiCmnd->cdb[8]; /* FIS sector count (15:8) */
2257 fis->d.sectorCount = 0; /* Tag (7:3) set by LL layer */
2258 fis->d.sectorCountExp = 0;
2259 fis->d.reserved4 = 0;
2260 fis->d.control = 0; /* FIS HOB bit clear */
2261 fis->d.reserved5 = 0;
2262
2263 agRequestType = AGSA_SATA_PROTOCOL_FPDMA_READ;
2264 satIOContext->ATACmd = SAT_READ_FPDMA_QUEUED;
2265 }
2266
2267 /* saves the current LBA and orginal TL */
2268 satIOContext->currentLBA = lba;
2269 satIOContext->OrgTL = tl;
2270
2271 /*
2272 computing number of loop and remainder for tl
2273 0xFF in case not ext
2274 0xFFFF in case EXT
2275 */
2276 if (fis->h.command == SAT_READ_SECTORS || fis->h.command == SAT_READ_DMA)
2277 {
2278 LoopNum = satComputeLoopNum(tl, 0xFF);
2279 }
2280 else if (fis->h.command == SAT_READ_SECTORS_EXT || fis->h.command == SAT_READ_DMA_EXT)
2281 {
2282 /* SAT_READ_SECTORS_EXT, SAT_READ_DMA_EXT */
2283 LoopNum = satComputeLoopNum(tl, 0xFFFF);
2284 }
2285 else
2286 {
2287 /* SAT_READ_FPDMA_QUEUEDK */
2288 LoopNum = satComputeLoopNum(tl, 0xFFFF);
2289 }
2290
2291 satIOContext->LoopNum = LoopNum;
2292
2293 if (LoopNum == 1)
2294 {
2295 TI_DBG5(("satRead12: NON CHAINED data\n"));
2296 satIOContext->satCompleteCB = &satNonChainedDataIOCB;
2297 }
2298 else
2299 {
2300 TI_DBG1(("satRead12: CHAINED data\n"));
2301 /* re-setting tl */
2302 if (fis->h.command == SAT_READ_SECTORS || fis->h.command == SAT_READ_DMA)
2303 {
2304 fis->d.sectorCount = 0xFF;
2305 }
2306 else if (fis->h.command == SAT_READ_SECTORS_EXT || fis->h.command == SAT_READ_DMA_EXT)
2307 {
2308 /* SAT_READ_SECTORS_EXT, SAT_READ_DMA_EXT */
2309 fis->d.sectorCount = 0xFF;
2310 fis->d.sectorCountExp = 0xFF;
2311 }
2312 else
2313 {
2314 /* SAT_READ_FPDMA_QUEUED */
2315 fis->h.features = 0xFF;
2316 fis->d.featuresExp = 0xFF;
2317 }
2318
2319 /* chained data */
2320 satIOContext->satCompleteCB = &satChainedDataIOCB;
2321 }
2322
2323 /*
2324 * Prepare SGL and send FIS to LL layer.
2325 */
2326 satIOContext->reqType = agRequestType; /* Save it */
2327
2328 status = sataLLIOStart( tiRoot,
2329 tiIORequest,
2330 tiDeviceHandle,
2331 tiScsiRequest,
2332 satIOContext);
2333
2334 TI_DBG5(("satRead12: return\n"));
2335 return (status);
2336 }
2337 /*****************************************************************************/
2338 /*! \brief SAT implementation for SCSI READ16.
2339 *
2340 * SAT implementation for SCSI READ16 and send FIS request to LL layer.
2341 *
2342 * \param tiRoot: Pointer to TISA initiator driver/port instance.
2343 * \param tiIORequest: Pointer to TISA I/O request context for this I/O.
2344 * \param tiDeviceHandle: Pointer to TISA device handle for this I/O.
2345 * \param tiScsiRequest: Pointer to TISA SCSI I/O request and SGL list.
2346 * \param satIOContext_t: Pointer to the SAT IO Context
2347 *
2348 * \return If command is started successfully
2349 * - \e tiSuccess: I/O request successfully initiated.
2350 * - \e tiBusy: No resources available, try again later.
2351 * - \e tiIONoDevice: Invalid device handle.
2352 * - \e tiError: Other errors.
2353 */
2354 /*****************************************************************************/
satRead16(tiRoot_t * tiRoot,tiIORequest_t * tiIORequest,tiDeviceHandle_t * tiDeviceHandle,tiScsiInitiatorRequest_t * tiScsiRequest,satIOContext_t * satIOContext)2355 GLOBAL bit32 satRead16(
2356 tiRoot_t *tiRoot,
2357 tiIORequest_t *tiIORequest,
2358 tiDeviceHandle_t *tiDeviceHandle,
2359 tiScsiInitiatorRequest_t *tiScsiRequest,
2360 satIOContext_t *satIOContext)
2361 {
2362 bit32 status;
2363 bit32 agRequestType = AGSA_SATA_PROTOCOL_DMA_READ;
2364 satDeviceData_t *pSatDevData;
2365 scsiRspSense_t *pSense;
2366 tiIniScsiCmnd_t *scsiCmnd;
2367 agsaFisRegHostToDevice_t *fis;
2368 bit32 lba = 0;
2369 bit32 tl = 0;
2370 bit32 LoopNum = 1;
2371 bit8 LBA[8];
2372 bit8 TL[8];
2373 bit32 rangeChk = agFALSE; /* lba and tl range check */
2374 bit32 limitChk = agFALSE; /* lba and tl range check */
2375
2376 pSense = satIOContext->pSense;
2377 pSatDevData = satIOContext->pSatDevData;
2378 scsiCmnd = &tiScsiRequest->scsiCmnd;
2379 fis = satIOContext->pFis;
2380
2381 TI_DBG5(("satRead16: start\n"));
2382
2383 /* checking FUA_NV */
2384 if (scsiCmnd->cdb[1] & SCSI_FUA_NV_MASK)
2385 {
2386 satSetSensePayload( pSense,
2387 SCSI_SNSKEY_ILLEGAL_REQUEST,
2388 0,
2389 SCSI_SNSCODE_INVALID_FIELD_IN_CDB,
2390 satIOContext);
2391
2392 ostiInitiatorIOCompleted( tiRoot,
2393 tiIORequest,
2394 tiIOSuccess,
2395 SCSI_STAT_CHECK_CONDITION,
2396 satIOContext->pTiSenseData,
2397 satIOContext->interruptContext );
2398
2399 TI_DBG1(("satRead16: return FUA_NV\n"));
2400 return tiSuccess;
2401
2402 }
2403
2404 /* checking CONTROL */
2405 /* NACA == 1 or LINK == 1*/
2406 if ( (scsiCmnd->cdb[15] & SCSI_NACA_MASK) || (scsiCmnd->cdb[15] & SCSI_LINK_MASK) )
2407 {
2408 satSetSensePayload( pSense,
2409 SCSI_SNSKEY_ILLEGAL_REQUEST,
2410 0,
2411 SCSI_SNSCODE_INVALID_FIELD_IN_CDB,
2412 satIOContext);
2413
2414 ostiInitiatorIOCompleted( tiRoot,
2415 tiIORequest,
2416 tiIOSuccess,
2417 SCSI_STAT_CHECK_CONDITION,
2418 satIOContext->pTiSenseData,
2419 satIOContext->interruptContext );
2420
2421 TI_DBG1(("satRead16: return control\n"));
2422 return tiSuccess;
2423 }
2424
2425
2426 osti_memset(LBA, 0, sizeof(LBA));
2427 osti_memset(TL, 0, sizeof(TL));
2428
2429
2430 /* do not use memcpy due to indexing in LBA and TL */
2431 LBA[0] = scsiCmnd->cdb[2]; /* MSB */
2432 LBA[1] = scsiCmnd->cdb[3];
2433 LBA[2] = scsiCmnd->cdb[4];
2434 LBA[3] = scsiCmnd->cdb[5];
2435 LBA[4] = scsiCmnd->cdb[6];
2436 LBA[5] = scsiCmnd->cdb[7];
2437 LBA[6] = scsiCmnd->cdb[8];
2438 LBA[7] = scsiCmnd->cdb[9]; /* LSB */
2439
2440 TL[0] = 0;
2441 TL[1] = 0;
2442 TL[2] = 0;
2443 TL[3] = 0;
2444 TL[4] = scsiCmnd->cdb[10]; /* MSB */
2445 TL[5] = scsiCmnd->cdb[11];
2446 TL[6] = scsiCmnd->cdb[12];
2447 TL[7] = scsiCmnd->cdb[13]; /* LSB */
2448
2449 rangeChk = satAddNComparebit64(LBA, TL);
2450
2451 limitChk = satCompareLBALimitbit(LBA);
2452
2453 lba = satComputeCDB16LBA(satIOContext);
2454 tl = satComputeCDB16TL(satIOContext);
2455
2456
2457 /* Table 34, 9.1, p 46 */
2458 /*
2459 note: As of 2/10/2006, no support for DMA QUEUED
2460 */
2461
2462 /*
2463 Table 34, 9.1, p 46, b
2464 When no 48-bit addressing support or NCQ, if LBA is beyond (2^28 - 1),
2465 return check condition
2466 */
2467 if (pSatDevData->satNCQ != agTRUE &&
2468 pSatDevData->sat48BitSupport != agTRUE
2469 )
2470 {
2471 if (limitChk)
2472 {
2473 TI_DBG1(("satRead16: return LBA out of range, not EXT\n"));
2474 satSetSensePayload( pSense,
2475 SCSI_SNSKEY_ILLEGAL_REQUEST,
2476 0,
2477 SCSI_SNSCODE_LOGICAL_BLOCK_ADDRESS_OUT_OF_RANGE,
2478 satIOContext);
2479
2480 ostiInitiatorIOCompleted( tiRoot,
2481 tiIORequest,
2482 tiIOSuccess,
2483 SCSI_STAT_CHECK_CONDITION,
2484 satIOContext->pTiSenseData,
2485 satIOContext->interruptContext );
2486
2487 return tiSuccess;
2488 }
2489 if (rangeChk) // if (lba + tl > SAT_TR_LBA_LIMIT)
2490 {
2491 TI_DBG1(("satRead16: return LBA+TL out of range, not EXT\n"));
2492 satSetSensePayload( pSense,
2493 SCSI_SNSKEY_ILLEGAL_REQUEST,
2494 0,
2495 SCSI_SNSCODE_LOGICAL_BLOCK_ADDRESS_OUT_OF_RANGE,
2496 satIOContext);
2497
2498 ostiInitiatorIOCompleted( tiRoot,
2499 tiIORequest,
2500 tiIOSuccess,
2501 SCSI_STAT_CHECK_CONDITION,
2502 satIOContext->pTiSenseData,
2503 satIOContext->interruptContext );
2504
2505 return tiSuccess;
2506 }
2507 }
2508
2509 /* case 1 and 2 */
2510 if (!rangeChk) // if (lba + tl <= SAT_TR_LBA_LIMIT)
2511 {
2512 if (pSatDevData->satDMASupport == agTRUE && pSatDevData->satDMAEnabled == agTRUE)
2513 {
2514 /* case 2 */
2515 /* READ DMA*/
2516 /* in case that we can't fit the transfer length,
2517 we need to make it fit by sending multiple ATA cmnds */
2518 TI_DBG5(("satRead16: case 2\n"));
2519
2520
2521 fis->h.fisType = 0x27; /* Reg host to device */
2522 fis->h.c_pmPort = 0x80; /* C Bit is set */
2523 fis->h.command = SAT_READ_DMA; /* 0xC8 */
2524 fis->h.features = 0; /* FIS reserve */
2525 fis->d.lbaLow = scsiCmnd->cdb[9]; /* FIS LBA (7 :0 ) */
2526 fis->d.lbaMid = scsiCmnd->cdb[8]; /* FIS LBA (15:8 ) */
2527 fis->d.lbaHigh = scsiCmnd->cdb[7]; /* FIS LBA (23:16) */
2528 fis->d.device =
2529 (bit8)((0x4 << 4) | (scsiCmnd->cdb[6] & 0xF)); /* FIS LBA (27:24) and FIS LBA mode */
2530 fis->d.lbaLowExp = 0;
2531 fis->d.lbaMidExp = 0;
2532 fis->d.lbaHighExp = 0;
2533 fis->d.featuresExp = 0;
2534 fis->d.sectorCount = scsiCmnd->cdb[13]; /* FIS sector count (7:0) */
2535 fis->d.sectorCountExp = 0;
2536 fis->d.reserved4 = 0;
2537 fis->d.control = 0; /* FIS HOB bit clear */
2538 fis->d.reserved5 = 0;
2539
2540
2541 agRequestType = AGSA_SATA_PROTOCOL_DMA_READ;
2542 satIOContext->ATACmd = SAT_READ_DMA;
2543 }
2544 else
2545 {
2546 /* case 1 */
2547 /* READ MULTIPLE or READ SECTOR(S) */
2548 /* READ SECTORS for easier implemetation */
2549 /* can't fit the transfer length but need to make it fit by sending multiple*/
2550 TI_DBG5(("satRead16: case 1\n"));
2551
2552 fis->h.fisType = 0x27; /* Reg host to device */
2553 fis->h.c_pmPort = 0x80; /* C Bit is set */
2554 fis->h.command = SAT_READ_SECTORS; /* 0x20 */
2555 fis->h.features = 0; /* FIS reserve */
2556 fis->d.lbaLow = scsiCmnd->cdb[9]; /* FIS LBA (7 :0 ) */
2557 fis->d.lbaMid = scsiCmnd->cdb[8]; /* FIS LBA (15:8 ) */
2558 fis->d.lbaHigh = scsiCmnd->cdb[7]; /* FIS LBA (23:16) */
2559 fis->d.device =
2560 (bit8)((0x4 << 4) | (scsiCmnd->cdb[6] & 0xF)); /* FIS LBA (27:24) and FIS LBA mode */
2561 fis->d.lbaLowExp = 0;
2562 fis->d.lbaMidExp = 0;
2563 fis->d.lbaHighExp = 0;
2564 fis->d.featuresExp = 0;
2565 fis->d.sectorCount = scsiCmnd->cdb[13]; /* FIS sector count (7:0) */
2566 fis->d.sectorCountExp = 0;
2567 fis->d.reserved4 = 0;
2568 fis->d.control = 0; /* FIS HOB bit clear */
2569 fis->d.reserved5 = 0;
2570
2571
2572 agRequestType = AGSA_SATA_PROTOCOL_PIO_READ;
2573 satIOContext->ATACmd = SAT_READ_SECTORS;
2574 }
2575 }
2576
2577 /* case 3 and 4 */
2578 if (pSatDevData->sat48BitSupport == agTRUE)
2579 {
2580 if (pSatDevData->satDMASupport == agTRUE && pSatDevData->satDMAEnabled == agTRUE)
2581 {
2582 /* case 3 */
2583 /* READ DMA EXT */
2584 TI_DBG5(("satRead16: case 3\n"));
2585 fis->h.fisType = 0x27; /* Reg host to device */
2586
2587 fis->h.c_pmPort = 0x80; /* C Bit is set */
2588 fis->h.command = SAT_READ_DMA_EXT; /* 0x25 */
2589 fis->h.features = 0; /* FIS reserve */
2590 fis->d.lbaLow = scsiCmnd->cdb[9]; /* FIS LBA (7 :0 ) */
2591 fis->d.lbaMid = scsiCmnd->cdb[8]; /* FIS LBA (15:8 ) */
2592 fis->d.lbaHigh = scsiCmnd->cdb[7]; /* FIS LBA (23:16) */
2593 fis->d.device = 0x40; /* FIS LBA mode set */
2594 fis->d.lbaLowExp = scsiCmnd->cdb[6]; /* FIS LBA (31:24) */
2595 fis->d.lbaMidExp = scsiCmnd->cdb[5]; /* FIS LBA (39:32) */
2596 fis->d.lbaHighExp = scsiCmnd->cdb[4]; /* FIS LBA (47:40) */
2597 fis->d.featuresExp = 0; /* FIS reserve */
2598 fis->d.sectorCount = scsiCmnd->cdb[13]; /* FIS sector count (7:0) */
2599 fis->d.sectorCountExp = scsiCmnd->cdb[12]; /* FIS sector count (15:8) */
2600 fis->d.reserved4 = 0;
2601 fis->d.control = 0; /* FIS HOB bit clear */
2602 fis->d.reserved5 = 0;
2603
2604 agRequestType = AGSA_SATA_PROTOCOL_DMA_READ;
2605 satIOContext->ATACmd = SAT_READ_DMA_EXT;
2606
2607 }
2608 else
2609 {
2610 /* case 4 */
2611 /* READ MULTIPLE EXT or READ SECTOR(S) EXT or READ VERIFY SECTOR(S) EXT*/
2612 /* READ SECTORS EXT for easier implemetation */
2613 TI_DBG5(("satRead16: case 4\n"));
2614 fis->h.fisType = 0x27; /* Reg host to device */
2615 fis->h.c_pmPort = 0x80; /* C Bit is set */
2616
2617 /* Check FUA bit */
2618 if (scsiCmnd->cdb[1] & SCSI_READ16_FUA_MASK)
2619 {
2620
2621 /* for now, no support for FUA */
2622 satSetSensePayload( pSense,
2623 SCSI_SNSKEY_ILLEGAL_REQUEST,
2624 0,
2625 SCSI_SNSCODE_INVALID_FIELD_IN_CDB,
2626 satIOContext);
2627
2628 ostiInitiatorIOCompleted( tiRoot,
2629 tiIORequest,
2630 tiIOSuccess,
2631 SCSI_STAT_CHECK_CONDITION,
2632 satIOContext->pTiSenseData,
2633 satIOContext->interruptContext );
2634 return tiSuccess;
2635 }
2636
2637 fis->h.command = SAT_READ_SECTORS_EXT; /* 0x24 */
2638
2639 fis->h.features = 0; /* FIS reserve */
2640 fis->d.lbaLow = scsiCmnd->cdb[9]; /* FIS LBA (7 :0 ) */
2641 fis->d.lbaMid = scsiCmnd->cdb[8]; /* FIS LBA (15:8 ) */
2642 fis->d.lbaHigh = scsiCmnd->cdb[7]; /* FIS LBA (23:16) */
2643 fis->d.device = 0x40; /* FIS LBA mode set */
2644 fis->d.lbaLowExp = scsiCmnd->cdb[6]; /* FIS LBA (31:24) */
2645 fis->d.lbaMidExp = scsiCmnd->cdb[5]; /* FIS LBA (39:32) */
2646 fis->d.lbaHighExp = scsiCmnd->cdb[4]; /* FIS LBA (47:40) */
2647 fis->d.featuresExp = 0; /* FIS reserve */
2648 fis->d.sectorCount = scsiCmnd->cdb[13]; /* FIS sector count (7:0) */
2649 fis->d.sectorCountExp = scsiCmnd->cdb[12]; /* FIS sector count (15:8) */
2650 fis->d.reserved4 = 0;
2651 fis->d.control = 0; /* FIS HOB bit clear */
2652 fis->d.reserved5 = 0;
2653
2654 agRequestType = AGSA_SATA_PROTOCOL_PIO_READ;
2655 satIOContext->ATACmd = SAT_READ_SECTORS_EXT;
2656 }
2657 }
2658
2659
2660 /* case 5 */
2661 if (pSatDevData->satNCQ == agTRUE)
2662 {
2663 /* READ FPDMA QUEUED */
2664 if (pSatDevData->sat48BitSupport != agTRUE)
2665 {
2666 TI_DBG5(("satRead16: case 5 !!! error NCQ but 28 bit address support \n"));
2667 satSetSensePayload( pSense,
2668 SCSI_SNSKEY_ILLEGAL_REQUEST,
2669 0,
2670 SCSI_SNSCODE_INVALID_FIELD_IN_CDB,
2671 satIOContext);
2672
2673 ostiInitiatorIOCompleted( tiRoot,
2674 tiIORequest,
2675 tiIOSuccess,
2676 SCSI_STAT_CHECK_CONDITION,
2677 satIOContext->pTiSenseData,
2678 satIOContext->interruptContext );
2679 return tiSuccess;
2680 }
2681
2682 TI_DBG6(("satRead16: case 5\n"));
2683
2684 /* Support 48-bit FPDMA addressing, use READ FPDMA QUEUE command */
2685
2686 fis->h.fisType = 0x27; /* Reg host to device */
2687 fis->h.c_pmPort = 0x80; /* C Bit is set */
2688 fis->h.command = SAT_READ_FPDMA_QUEUED; /* 0x60 */
2689 fis->h.features = scsiCmnd->cdb[13]; /* FIS sector count (7:0) */
2690 fis->d.lbaLow = scsiCmnd->cdb[9]; /* FIS LBA (7 :0 ) */
2691 fis->d.lbaMid = scsiCmnd->cdb[8]; /* FIS LBA (15:8 ) */
2692 fis->d.lbaHigh = scsiCmnd->cdb[7]; /* FIS LBA (23:16) */
2693
2694 /* Check FUA bit */
2695 if (scsiCmnd->cdb[1] & SCSI_READ16_FUA_MASK)
2696 fis->d.device = 0xC0; /* FIS FUA set */
2697 else
2698 fis->d.device = 0x40; /* FIS FUA clear */
2699
2700 fis->d.lbaLowExp = scsiCmnd->cdb[6]; /* FIS LBA (31:24) */
2701 fis->d.lbaMidExp = scsiCmnd->cdb[5]; /* FIS LBA (39:32) */
2702 fis->d.lbaHighExp = scsiCmnd->cdb[4]; /* FIS LBA (47:40) */
2703 fis->d.featuresExp = scsiCmnd->cdb[12]; /* FIS sector count (15:8) */
2704 fis->d.sectorCount = 0; /* Tag (7:3) set by LL layer */
2705 fis->d.sectorCountExp = 0;
2706 fis->d.reserved4 = 0;
2707 fis->d.control = 0; /* FIS HOB bit clear */
2708 fis->d.reserved5 = 0;
2709
2710 agRequestType = AGSA_SATA_PROTOCOL_FPDMA_READ;
2711 satIOContext->ATACmd = SAT_READ_FPDMA_QUEUED;
2712 }
2713
2714 /* saves the current LBA and orginal TL */
2715 satIOContext->currentLBA = lba;
2716 satIOContext->OrgTL = tl;
2717
2718 /*
2719 computing number of loop and remainder for tl
2720 0xFF in case not ext
2721 0xFFFF in case EXT
2722 */
2723 if (fis->h.command == SAT_READ_SECTORS || fis->h.command == SAT_READ_DMA)
2724 {
2725 LoopNum = satComputeLoopNum(tl, 0xFF);
2726 }
2727 else if (fis->h.command == SAT_READ_SECTORS_EXT || fis->h.command == SAT_READ_DMA_EXT)
2728 {
2729 /* SAT_READ_SECTORS_EXT, SAT_READ_DMA_EXT */
2730 LoopNum = satComputeLoopNum(tl, 0xFFFF);
2731 }
2732 else
2733 {
2734 /* SAT_READ_FPDMA_QUEUEDK */
2735 LoopNum = satComputeLoopNum(tl, 0xFFFF);
2736 }
2737 satIOContext->LoopNum = LoopNum;
2738
2739 if (LoopNum == 1)
2740 {
2741 TI_DBG5(("satRead16: NON CHAINED data\n"));
2742 satIOContext->satCompleteCB = &satNonChainedDataIOCB;
2743 }
2744 else
2745 {
2746 TI_DBG1(("satRead16: CHAINED data\n"));
2747 /* re-setting tl */
2748 if (fis->h.command == SAT_READ_SECTORS || fis->h.command == SAT_READ_DMA)
2749 {
2750 fis->d.sectorCount = 0xFF;
2751 }
2752 else if (fis->h.command == SAT_READ_SECTORS_EXT || fis->h.command == SAT_READ_DMA_EXT)
2753 {
2754 /* SAT_READ_SECTORS_EXT, SAT_READ_DMA_EXT */
2755 fis->d.sectorCount = 0xFF;
2756 fis->d.sectorCountExp = 0xFF;
2757 }
2758 else
2759 {
2760 /* SAT_READ_FPDMA_QUEUED */
2761 fis->h.features = 0xFF;
2762 fis->d.featuresExp = 0xFF;
2763 }
2764
2765 /* chained data */
2766 satIOContext->satCompleteCB = &satChainedDataIOCB;
2767 }
2768
2769 /*
2770 * Prepare SGL and send FIS to LL layer.
2771 */
2772 satIOContext->reqType = agRequestType; /* Save it */
2773
2774 status = sataLLIOStart( tiRoot,
2775 tiIORequest,
2776 tiDeviceHandle,
2777 tiScsiRequest,
2778 satIOContext);
2779
2780 TI_DBG5(("satRead16: return\n"));
2781 return (status);
2782
2783 }
2784
2785 /*****************************************************************************/
2786 /*! \brief SAT implementation for SCSI READ6.
2787 *
2788 * SAT implementation for SCSI READ6 and send FIS request to LL layer.
2789 *
2790 * \param tiRoot: Pointer to TISA initiator driver/port instance.
2791 * \param tiIORequest: Pointer to TISA I/O request context for this I/O.
2792 * \param tiDeviceHandle: Pointer to TISA device handle for this I/O.
2793 * \param tiScsiRequest: Pointer to TISA SCSI I/O request and SGL list.
2794 * \param satIOContext_t: Pointer to the SAT IO Context
2795 *
2796 * \return If command is started successfully
2797 * - \e tiSuccess: I/O request successfully initiated.
2798 * - \e tiBusy: No resources available, try again later.
2799 * - \e tiIONoDevice: Invalid device handle.
2800 * - \e tiError: Other errors.
2801 */
2802 /*****************************************************************************/
satRead6(tiRoot_t * tiRoot,tiIORequest_t * tiIORequest,tiDeviceHandle_t * tiDeviceHandle,tiScsiInitiatorRequest_t * tiScsiRequest,satIOContext_t * satIOContext)2803 GLOBAL bit32 satRead6(
2804 tiRoot_t *tiRoot,
2805 tiIORequest_t *tiIORequest,
2806 tiDeviceHandle_t *tiDeviceHandle,
2807 tiScsiInitiatorRequest_t *tiScsiRequest,
2808 satIOContext_t *satIOContext)
2809 {
2810
2811 bit32 status;
2812 bit32 agRequestType = AGSA_SATA_PROTOCOL_DMA_READ;
2813 satDeviceData_t *pSatDevData;
2814 scsiRspSense_t *pSense;
2815 tiIniScsiCmnd_t *scsiCmnd;
2816 agsaFisRegHostToDevice_t *fis;
2817 bit32 lba = 0;
2818 bit16 tl = 0;
2819
2820 pSense = satIOContext->pSense;
2821 pSatDevData = satIOContext->pSatDevData;
2822 scsiCmnd = &tiScsiRequest->scsiCmnd;
2823 fis = satIOContext->pFis;
2824
2825
2826 TI_DBG5(("satRead6: start\n"));
2827
2828 /* no FUA checking since read6 */
2829
2830
2831 /* checking CONTROL */
2832 /* NACA == 1 or LINK == 1*/
2833 if ( (scsiCmnd->cdb[5] & SCSI_NACA_MASK) || (scsiCmnd->cdb[5] & SCSI_LINK_MASK) )
2834 {
2835 satSetSensePayload( pSense,
2836 SCSI_SNSKEY_ILLEGAL_REQUEST,
2837 0,
2838 SCSI_SNSCODE_INVALID_FIELD_IN_CDB,
2839 satIOContext);
2840
2841 ostiInitiatorIOCompleted( tiRoot,
2842 tiIORequest,
2843 tiIOSuccess,
2844 SCSI_STAT_CHECK_CONDITION,
2845 satIOContext->pTiSenseData,
2846 satIOContext->interruptContext );
2847
2848 TI_DBG2(("satRead6: return control\n"));
2849 return tiSuccess;
2850 }
2851
2852 /* cbd6; computing LBA and transfer length */
2853 lba = (((scsiCmnd->cdb[1]) & 0x1f) << (8*2))
2854 + (scsiCmnd->cdb[2] << 8) + scsiCmnd->cdb[3];
2855 tl = scsiCmnd->cdb[4];
2856
2857
2858 /* Table 34, 9.1, p 46 */
2859 /*
2860 note: As of 2/10/2006, no support for DMA QUEUED
2861 */
2862
2863 /*
2864 Table 34, 9.1, p 46, b
2865 When no 48-bit addressing support or NCQ, if LBA is beyond (2^28 - 1),
2866 return check condition
2867 */
2868 if (pSatDevData->satNCQ != agTRUE &&
2869 pSatDevData->sat48BitSupport != agTRUE
2870 )
2871 {
2872 if (lba > SAT_TR_LBA_LIMIT - 1)
2873 {
2874 satSetSensePayload( pSense,
2875 SCSI_SNSKEY_ILLEGAL_REQUEST,
2876 0,
2877 SCSI_SNSCODE_LOGICAL_BLOCK_ADDRESS_OUT_OF_RANGE,
2878 satIOContext);
2879
2880 ostiInitiatorIOCompleted( tiRoot,
2881 tiIORequest,
2882 tiIOSuccess,
2883 SCSI_STAT_CHECK_CONDITION,
2884 satIOContext->pTiSenseData,
2885 satIOContext->interruptContext );
2886
2887 TI_DBG1(("satRead6: return LBA out of range\n"));
2888 return tiSuccess;
2889 }
2890 }
2891
2892 /* case 1 and 2 */
2893 if (lba + tl <= SAT_TR_LBA_LIMIT)
2894 {
2895 if (pSatDevData->satDMASupport == agTRUE && pSatDevData->satDMAEnabled == agTRUE)
2896 {
2897 /* case 2 */
2898 /* READ DMA*/
2899 TI_DBG5(("satRead6: case 2\n"));
2900
2901
2902 fis->h.fisType = 0x27; /* Reg host to device */
2903 fis->h.c_pmPort = 0x80; /* C Bit is set */
2904 fis->h.command = SAT_READ_DMA; /* 0xC8 */
2905 fis->h.features = 0; /* FIS reserve */
2906 fis->d.lbaLow = scsiCmnd->cdb[3]; /* FIS LBA (7 :0 ) */
2907 fis->d.lbaMid = scsiCmnd->cdb[2]; /* FIS LBA (15:8 ) */
2908 fis->d.lbaHigh = (bit8)((scsiCmnd->cdb[1]) & 0x1f); /* FIS LBA (23:16) */
2909 fis->d.device = 0x40; /* FIS LBA mode */
2910 fis->d.lbaLowExp = 0;
2911 fis->d.lbaMidExp = 0;
2912 fis->d.lbaHighExp = 0;
2913 fis->d.featuresExp = 0;
2914 if (tl == 0)
2915 {
2916 /* temporary fix */
2917 fis->d.sectorCount = 0xff; /* FIS sector count (7:0) */
2918 }
2919 else
2920 {
2921 fis->d.sectorCount = scsiCmnd->cdb[4]; /* FIS sector count (7:0) */
2922 }
2923 fis->d.sectorCountExp = 0;
2924 fis->d.reserved4 = 0;
2925 fis->d.control = 0; /* FIS HOB bit clear */
2926 fis->d.reserved5 = 0;
2927
2928 agRequestType = AGSA_SATA_PROTOCOL_DMA_READ;
2929 }
2930 else
2931 {
2932 /* case 1 */
2933 /* READ SECTORS for easier implemetation */
2934 TI_DBG5(("satRead6: case 1\n"));
2935
2936 fis->h.fisType = 0x27; /* Reg host to device */
2937 fis->h.c_pmPort = 0x80; /* C Bit is set */
2938 fis->h.command = SAT_READ_SECTORS; /* 0x20 */
2939 fis->h.features = 0; /* FIS reserve */
2940 fis->d.lbaLow = scsiCmnd->cdb[3]; /* FIS LBA (7 :0 ) */
2941 fis->d.lbaMid = scsiCmnd->cdb[2]; /* FIS LBA (15:8 ) */
2942 fis->d.lbaHigh = (bit8)((scsiCmnd->cdb[1]) & 0x1f); /* FIS LBA (23:16) */
2943 fis->d.device = 0x40; /* FIS LBA mode */
2944 fis->d.lbaLowExp = 0;
2945 fis->d.lbaMidExp = 0;
2946 fis->d.lbaHighExp = 0;
2947 fis->d.featuresExp = 0;
2948 if (tl == 0)
2949 {
2950 /* temporary fix */
2951 fis->d.sectorCount = 0xff; /* FIS sector count (7:0) */
2952 }
2953 else
2954 {
2955 fis->d.sectorCount = scsiCmnd->cdb[4]; /* FIS sector count (7:0) */
2956 }
2957 fis->d.sectorCountExp = 0;
2958 fis->d.reserved4 = 0;
2959 fis->d.control = 0; /* FIS HOB bit clear */
2960 fis->d.reserved5 = 0;
2961
2962 agRequestType = AGSA_SATA_PROTOCOL_PIO_READ;
2963
2964 }
2965 }
2966
2967 /* case 3 and 4 */
2968 if (pSatDevData->sat48BitSupport == agTRUE)
2969 {
2970 if (pSatDevData->satDMASupport == agTRUE && pSatDevData->satDMAEnabled == agTRUE)
2971 {
2972 /* case 3 */
2973 /* READ DMA EXT only */
2974 TI_DBG5(("satRead6: case 3\n"));
2975 fis->h.fisType = 0x27; /* Reg host to device */
2976 fis->h.c_pmPort = 0x80; /* C Bit is set */
2977 fis->h.command = SAT_READ_DMA_EXT; /* 0x25 */
2978 fis->h.features = 0; /* FIS reserve */
2979 fis->d.lbaLow = scsiCmnd->cdb[3]; /* FIS LBA (7 :0 ) */
2980 fis->d.lbaMid = scsiCmnd->cdb[2]; /* FIS LBA (15:8 ) */
2981 fis->d.lbaHigh = (bit8)((scsiCmnd->cdb[1]) & 0x1f); /* FIS LBA (23:16) */
2982 fis->d.device = 0x40; /* FIS LBA mode set */
2983 fis->d.lbaLowExp = 0; /* FIS LBA (31:24) */
2984 fis->d.lbaMidExp = 0; /* FIS LBA (39:32) */
2985 fis->d.lbaHighExp = 0; /* FIS LBA (47:40) */
2986 fis->d.featuresExp = 0; /* FIS reserve */
2987 if (tl == 0)
2988 {
2989 /* sector count is 256, 0x100*/
2990 fis->d.sectorCount = 0; /* FIS sector count (7:0) */
2991 fis->d.sectorCountExp = 0x01; /* FIS sector count (15:8) */
2992 }
2993 else
2994 {
2995 fis->d.sectorCount = scsiCmnd->cdb[4]; /* FIS sector count (7:0) */
2996 fis->d.sectorCountExp = 0; /* FIS sector count (15:8) */
2997 }
2998 fis->d.reserved4 = 0;
2999 fis->d.control = 0; /* FIS HOB bit clear */
3000 fis->d.reserved5 = 0;
3001
3002 agRequestType = AGSA_SATA_PROTOCOL_DMA_READ;
3003 }
3004 else
3005 {
3006 /* case 4 */
3007 /* READ SECTORS EXT for easier implemetation */
3008 TI_DBG5(("satRead6: case 4\n"));
3009
3010 fis->h.fisType = 0x27; /* Reg host to device */
3011 fis->h.c_pmPort = 0x80; /* C Bit is set */
3012 fis->h.command = SAT_READ_SECTORS_EXT; /* 0x24 */
3013 fis->h.features = 0; /* FIS reserve */
3014 fis->d.lbaLow = scsiCmnd->cdb[3]; /* FIS LBA (7 :0 ) */
3015 fis->d.lbaMid = scsiCmnd->cdb[2]; /* FIS LBA (15:8 ) */
3016 fis->d.lbaHigh = (bit8)((scsiCmnd->cdb[1]) & 0x1f); /* FIS LBA (23:16) */
3017 fis->d.device = 0x40; /* FIS LBA mode set */
3018 fis->d.lbaLowExp = 0; /* FIS LBA (31:24) */
3019 fis->d.lbaMidExp = 0; /* FIS LBA (39:32) */
3020 fis->d.lbaHighExp = 0; /* FIS LBA (47:40) */
3021 fis->d.featuresExp = 0; /* FIS reserve */
3022 if (tl == 0)
3023 {
3024 /* sector count is 256, 0x100*/
3025 fis->d.sectorCount = 0; /* FIS sector count (7:0) */
3026 fis->d.sectorCountExp = 0x01; /* FIS sector count (15:8) */
3027 }
3028 else
3029 {
3030 fis->d.sectorCount = scsiCmnd->cdb[4]; /* FIS sector count (7:0) */
3031 fis->d.sectorCountExp = 0; /* FIS sector count (15:8) */
3032 }
3033 fis->d.reserved4 = 0;
3034 fis->d.control = 0; /* FIS HOB bit clear */
3035 fis->d.reserved5 = 0;
3036
3037 agRequestType = AGSA_SATA_PROTOCOL_PIO_READ;
3038 }
3039 }
3040
3041 /* case 5 */
3042 if (pSatDevData->satNCQ == agTRUE)
3043 {
3044 /* READ FPDMA QUEUED */
3045 if (pSatDevData->sat48BitSupport != agTRUE)
3046 {
3047 /* sanity check */
3048 TI_DBG5(("satRead6: case 5 !!! error NCQ but 28 bit address support \n"));
3049 satSetSensePayload( pSense,
3050 SCSI_SNSKEY_ILLEGAL_REQUEST,
3051 0,
3052 SCSI_SNSCODE_INVALID_FIELD_IN_CDB,
3053 satIOContext);
3054
3055 ostiInitiatorIOCompleted( tiRoot,
3056 tiIORequest,
3057 tiIOSuccess,
3058 SCSI_STAT_CHECK_CONDITION,
3059 satIOContext->pTiSenseData,
3060 satIOContext->interruptContext );
3061 return tiSuccess;
3062 }
3063 TI_DBG5(("satRead6: case 5\n"));
3064
3065 /* Support 48-bit FPDMA addressing, use READ FPDMA QUEUE command */
3066
3067 fis->h.fisType = 0x27; /* Reg host to device */
3068 fis->h.c_pmPort = 0x80; /* C Bit is set */
3069 fis->h.command = SAT_READ_FPDMA_QUEUED; /* 0x60 */
3070 fis->d.lbaLow = scsiCmnd->cdb[3]; /* FIS LBA (7 :0 ) */
3071 fis->d.lbaMid = scsiCmnd->cdb[2]; /* FIS LBA (15:8 ) */
3072 fis->d.lbaHigh = (bit8)((scsiCmnd->cdb[1]) & 0x1f); /* FIS LBA (23:16) */
3073 fis->d.device = 0x40; /* FIS FUA clear */
3074 fis->d.lbaLowExp = 0; /* FIS LBA (31:24) */
3075 fis->d.lbaMidExp = 0; /* FIS LBA (39:32) */
3076 fis->d.lbaHighExp = 0; /* FIS LBA (47:40) */
3077 if (tl == 0)
3078 {
3079 /* sector count is 256, 0x100*/
3080 fis->h.features = 0; /* FIS sector count (7:0) */
3081 fis->d.featuresExp = 0x01; /* FIS sector count (15:8) */
3082 }
3083 else
3084 {
3085 fis->h.features = scsiCmnd->cdb[4]; /* FIS sector count (7:0) */
3086 fis->d.featuresExp = 0; /* FIS sector count (15:8) */
3087 }
3088 fis->d.sectorCount = 0; /* Tag (7:3) set by LL layer */
3089 fis->d.sectorCountExp = 0;
3090 fis->d.reserved4 = 0;
3091 fis->d.control = 0; /* FIS HOB bit clear */
3092 fis->d.reserved5 = 0;
3093
3094 agRequestType = AGSA_SATA_PROTOCOL_FPDMA_READ;
3095 }
3096
3097 /* Initialize CB for SATA completion.
3098 */
3099 satIOContext->satCompleteCB = &satNonChainedDataIOCB;
3100
3101 /*
3102 * Prepare SGL and send FIS to LL layer.
3103 */
3104 satIOContext->reqType = agRequestType; /* Save it */
3105
3106 status = sataLLIOStart( tiRoot,
3107 tiIORequest,
3108 tiDeviceHandle,
3109 tiScsiRequest,
3110 satIOContext);
3111 return (status);
3112
3113 }
3114
3115 /*****************************************************************************/
3116 /*! \brief SAT implementation for SCSI WRITE16.
3117 *
3118 * SAT implementation for SCSI WRITE16 and send FIS request to LL layer.
3119 *
3120 * \param tiRoot: Pointer to TISA initiator driver/port instance.
3121 * \param tiIORequest: Pointer to TISA I/O request context for this I/O.
3122 * \param tiDeviceHandle: Pointer to TISA device handle for this I/O.
3123 * \param tiScsiRequest: Pointer to TISA SCSI I/O request and SGL list.
3124 * \param satIOContext_t: Pointer to the SAT IO Context
3125 *
3126 * \return If command is started successfully
3127 * - \e tiSuccess: I/O request successfully initiated.
3128 * - \e tiBusy: No resources available, try again later.
3129 * - \e tiIONoDevice: Invalid device handle.
3130 * - \e tiError: Other errors.
3131 */
3132 /*****************************************************************************/
satWrite16(tiRoot_t * tiRoot,tiIORequest_t * tiIORequest,tiDeviceHandle_t * tiDeviceHandle,tiScsiInitiatorRequest_t * tiScsiRequest,satIOContext_t * satIOContext)3133 GLOBAL bit32 satWrite16(
3134 tiRoot_t *tiRoot,
3135 tiIORequest_t *tiIORequest,
3136 tiDeviceHandle_t *tiDeviceHandle,
3137 tiScsiInitiatorRequest_t *tiScsiRequest,
3138 satIOContext_t *satIOContext)
3139 {
3140 bit32 status;
3141 bit32 agRequestType = AGSA_SATA_PROTOCOL_DMA_WRITE;
3142 satDeviceData_t *pSatDevData;
3143 scsiRspSense_t *pSense;
3144 tiIniScsiCmnd_t *scsiCmnd;
3145 agsaFisRegHostToDevice_t *fis;
3146 bit32 lba = 0;
3147 bit32 tl = 0;
3148 bit32 LoopNum = 1;
3149 bit8 LBA[8];
3150 bit8 TL[8];
3151 bit32 rangeChk = agFALSE; /* lba and tl range check */
3152 bit32 limitChk = agFALSE; /* lba and tl range check */
3153
3154 pSense = satIOContext->pSense;
3155 pSatDevData = satIOContext->pSatDevData;
3156 scsiCmnd = &tiScsiRequest->scsiCmnd;
3157 fis = satIOContext->pFis;
3158
3159 TI_DBG5(("satWrite16: start\n"));
3160
3161 /* checking FUA_NV */
3162 if (scsiCmnd->cdb[1] & SCSI_FUA_NV_MASK)
3163 {
3164 satSetSensePayload( pSense,
3165 SCSI_SNSKEY_ILLEGAL_REQUEST,
3166 0,
3167 SCSI_SNSCODE_INVALID_FIELD_IN_CDB,
3168 satIOContext);
3169
3170 ostiInitiatorIOCompleted( tiRoot,
3171 tiIORequest,
3172 tiIOSuccess,
3173 SCSI_STAT_CHECK_CONDITION,
3174 satIOContext->pTiSenseData,
3175 satIOContext->interruptContext );
3176
3177 TI_DBG1(("satWrite16: return FUA_NV\n"));
3178 return tiSuccess;
3179
3180 }
3181
3182 /* checking CONTROL */
3183 /* NACA == 1 or LINK == 1*/
3184 if ( (scsiCmnd->cdb[15] & SCSI_NACA_MASK) || (scsiCmnd->cdb[15] & SCSI_LINK_MASK) )
3185 {
3186 satSetSensePayload( pSense,
3187 SCSI_SNSKEY_ILLEGAL_REQUEST,
3188 0,
3189 SCSI_SNSCODE_INVALID_FIELD_IN_CDB,
3190 satIOContext);
3191
3192 ostiInitiatorIOCompleted( tiRoot,
3193 tiIORequest,
3194 tiIOSuccess,
3195 SCSI_STAT_CHECK_CONDITION,
3196 satIOContext->pTiSenseData,
3197 satIOContext->interruptContext );
3198
3199 TI_DBG1(("satWrite16: return control\n"));
3200 return tiSuccess;
3201 }
3202
3203
3204 osti_memset(LBA, 0, sizeof(LBA));
3205 osti_memset(TL, 0, sizeof(TL));
3206
3207
3208 /* do not use memcpy due to indexing in LBA and TL */
3209 LBA[0] = scsiCmnd->cdb[2]; /* MSB */
3210 LBA[1] = scsiCmnd->cdb[3];
3211 LBA[2] = scsiCmnd->cdb[4];
3212 LBA[3] = scsiCmnd->cdb[5];
3213 LBA[4] = scsiCmnd->cdb[6];
3214 LBA[5] = scsiCmnd->cdb[7];
3215 LBA[6] = scsiCmnd->cdb[8];
3216 LBA[7] = scsiCmnd->cdb[9]; /* LSB */
3217
3218 TL[0] = 0;
3219 TL[1] = 0;
3220 TL[2] = 0;
3221 TL[3] = 0;
3222 TL[4] = scsiCmnd->cdb[10]; /* MSB */
3223 TL[5] = scsiCmnd->cdb[11];
3224 TL[6] = scsiCmnd->cdb[12];
3225 TL[7] = scsiCmnd->cdb[13]; /* LSB */
3226
3227 rangeChk = satAddNComparebit64(LBA, TL);
3228
3229 limitChk = satCompareLBALimitbit(LBA);
3230
3231 lba = satComputeCDB16LBA(satIOContext);
3232 tl = satComputeCDB16TL(satIOContext);
3233
3234
3235
3236 /* Table 34, 9.1, p 46 */
3237 /*
3238 note: As of 2/10/2006, no support for DMA QUEUED
3239 */
3240
3241 /*
3242 Table 34, 9.1, p 46, b
3243 When no 48-bit addressing support or NCQ, if LBA is beyond (2^28 - 1),
3244 return check condition
3245 */
3246 if (pSatDevData->satNCQ != agTRUE &&
3247 pSatDevData->sat48BitSupport != agTRUE
3248 )
3249 {
3250 if (limitChk)
3251 {
3252 TI_DBG1(("satWrite16: return LBA out of range, not EXT\n"));
3253 satSetSensePayload( pSense,
3254 SCSI_SNSKEY_ILLEGAL_REQUEST,
3255 0,
3256 SCSI_SNSCODE_LOGICAL_BLOCK_ADDRESS_OUT_OF_RANGE,
3257 satIOContext);
3258
3259 ostiInitiatorIOCompleted( tiRoot,
3260 tiIORequest,
3261 tiIOSuccess,
3262 SCSI_STAT_CHECK_CONDITION,
3263 satIOContext->pTiSenseData,
3264 satIOContext->interruptContext );
3265
3266 return tiSuccess;
3267 }
3268 if (rangeChk) // if (lba + tl > SAT_TR_LBA_LIMIT)
3269 {
3270 TI_DBG1(("satWrite16: return LBA+TL out of range, not EXT\n"));
3271 satSetSensePayload( pSense,
3272 SCSI_SNSKEY_ILLEGAL_REQUEST,
3273 0,
3274 SCSI_SNSCODE_LOGICAL_BLOCK_ADDRESS_OUT_OF_RANGE,
3275 satIOContext);
3276
3277 ostiInitiatorIOCompleted( tiRoot,
3278 tiIORequest,
3279 tiIOSuccess,
3280 SCSI_STAT_CHECK_CONDITION,
3281 satIOContext->pTiSenseData,
3282 satIOContext->interruptContext );
3283
3284 return tiSuccess;
3285 }
3286 }
3287
3288 /* case 1 and 2 */
3289 if (!rangeChk) // if (lba + tl <= SAT_TR_LBA_LIMIT)
3290 {
3291 if (pSatDevData->satDMASupport == agTRUE && pSatDevData->satDMAEnabled == agTRUE)
3292 {
3293 /* case 2 */
3294 /* WRITE DMA*/
3295 /* In case that we can't fit the transfer length, we loop */
3296 TI_DBG5(("satWrite16: case 2\n"));
3297 fis->h.fisType = 0x27; /* Reg host to device */
3298 fis->h.c_pmPort = 0x80; /* C bit is set */
3299 fis->h.command = SAT_WRITE_DMA; /* 0xCA */
3300 fis->h.features = 0; /* FIS reserve */
3301 fis->d.lbaLow = scsiCmnd->cdb[9]; /* FIS LBA (7 :0 ) */
3302 fis->d.lbaMid = scsiCmnd->cdb[8]; /* FIS LBA (15:8 ) */
3303 fis->d.lbaHigh = scsiCmnd->cdb[7]; /* FIS LBA (23:16) */
3304
3305 /* FIS LBA mode set LBA (27:24) */
3306 fis->d.device = (bit8)((0x4 << 4) | (scsiCmnd->cdb[6] & 0xF));
3307
3308 fis->d.lbaLowExp = 0;
3309 fis->d.lbaMidExp = 0;
3310 fis->d.lbaHighExp = 0;
3311 fis->d.featuresExp = 0;
3312 fis->d.sectorCount = scsiCmnd->cdb[13]; /* FIS sector count (7:0) */
3313 fis->d.sectorCountExp = 0;
3314 fis->d.reserved4 = 0;
3315 fis->d.control = 0; /* FIS HOB bit clear */
3316 fis->d.reserved5 = 0;
3317
3318 agRequestType = AGSA_SATA_PROTOCOL_DMA_WRITE;
3319 satIOContext->ATACmd = SAT_WRITE_DMA;
3320 }
3321 else
3322 {
3323 /* case 1 */
3324 /* WRITE MULTIPLE or WRITE SECTOR(S) */
3325 /* WRITE SECTORS for easier implemetation */
3326 /* In case that we can't fit the transfer length, we loop */
3327 TI_DBG5(("satWrite16: case 1\n"));
3328 fis->h.fisType = 0x27; /* Reg host to device */
3329 fis->h.c_pmPort = 0x80; /* C bit is set */
3330 fis->h.command = SAT_WRITE_SECTORS; /* 0x30 */
3331 fis->h.features = 0; /* FIS reserve */
3332 fis->d.lbaLow = scsiCmnd->cdb[9]; /* FIS LBA (7 :0 ) */
3333 fis->d.lbaMid = scsiCmnd->cdb[8]; /* FIS LBA (15:8 ) */
3334 fis->d.lbaHigh = scsiCmnd->cdb[7]; /* FIS LBA (23:16) */
3335
3336 /* FIS LBA mode set LBA (27:24) */
3337 fis->d.device = (bit8)((0x4 << 4) | (scsiCmnd->cdb[6] & 0xF));
3338
3339 fis->d.lbaLowExp = 0;
3340 fis->d.lbaMidExp = 0;
3341 fis->d.lbaHighExp = 0;
3342 fis->d.featuresExp = 0;
3343 fis->d.sectorCount = scsiCmnd->cdb[13]; /* FIS sector count (7:0) */
3344 fis->d.sectorCountExp = 0;
3345 fis->d.reserved4 = 0;
3346 fis->d.control = 0; /* FIS HOB bit clear */
3347 fis->d.reserved5 = 0;
3348
3349 agRequestType = AGSA_SATA_PROTOCOL_PIO_WRITE;
3350 satIOContext->ATACmd = SAT_WRITE_SECTORS;
3351 }
3352 }
3353
3354 /* case 3 and 4 */
3355 if (pSatDevData->sat48BitSupport == agTRUE)
3356 {
3357 if (pSatDevData->satDMASupport == agTRUE && pSatDevData->satDMAEnabled == agTRUE)
3358 {
3359 /* case 3 */
3360 /* WRITE DMA EXT or WRITE DMA FUA EXT */
3361 TI_DBG5(("satWrite16: case 3\n"));
3362 fis->h.fisType = 0x27; /* Reg host to device */
3363 fis->h.c_pmPort = 0x80; /* C Bit is set */
3364
3365 /* SAT_WRITE_DMA_FUA_EXT is optional and we don't support it */
3366 fis->h.command = SAT_WRITE_DMA_EXT; /* 0x35 */
3367
3368 fis->h.features = 0; /* FIS reserve */
3369 fis->d.lbaLow = scsiCmnd->cdb[9]; /* FIS LBA (7 :0 ) */
3370 fis->d.lbaMid = scsiCmnd->cdb[8]; /* FIS LBA (15:8 ) */
3371 fis->d.lbaHigh = scsiCmnd->cdb[7]; /* FIS LBA (23:16) */
3372 fis->d.device = 0x40; /* FIS LBA mode set */
3373 fis->d.lbaLowExp = scsiCmnd->cdb[6]; /* FIS LBA (31:24) */
3374 fis->d.lbaMidExp = scsiCmnd->cdb[5]; /* FIS LBA (39:32) */
3375 fis->d.lbaHighExp = scsiCmnd->cdb[4]; /* FIS LBA (47:40) */
3376 fis->d.featuresExp = 0; /* FIS reserve */
3377 fis->d.sectorCount = scsiCmnd->cdb[13]; /* FIS sector count (7:0) */
3378 fis->d.sectorCountExp = scsiCmnd->cdb[12]; /* FIS sector count (15:8) */
3379 fis->d.reserved4 = 0;
3380 fis->d.control = 0; /* FIS HOB bit clear */
3381 fis->d.reserved5 = 0;
3382
3383 agRequestType = AGSA_SATA_PROTOCOL_DMA_WRITE;
3384 satIOContext->ATACmd = SAT_WRITE_DMA_EXT;
3385 }
3386 else
3387 {
3388 /* case 4 */
3389 /* WRITE MULTIPLE EXT or WRITE MULTIPLE FUA EXT or WRITE SECTOR(S) EXT */
3390 /* WRITE SECTORS EXT for easier implemetation */
3391 TI_DBG5(("satWrite16: case 4\n"));
3392 fis->h.fisType = 0x27; /* Reg host to device */
3393 fis->h.c_pmPort = 0x80; /* C Bit is set */
3394 fis->h.command = SAT_WRITE_SECTORS_EXT; /* 0x34 */
3395
3396 fis->h.features = 0; /* FIS reserve */
3397 fis->d.lbaLow = scsiCmnd->cdb[9]; /* FIS LBA (7 :0 ) */
3398 fis->d.lbaMid = scsiCmnd->cdb[8]; /* FIS LBA (15:8 ) */
3399 fis->d.lbaHigh = scsiCmnd->cdb[7]; /* FIS LBA (23:16) */
3400 fis->d.device = 0x40; /* FIS LBA mode set */
3401 fis->d.lbaLowExp = scsiCmnd->cdb[6]; /* FIS LBA (31:24) */
3402 fis->d.lbaMidExp = scsiCmnd->cdb[5]; /* FIS LBA (39:32) */
3403 fis->d.lbaHighExp = scsiCmnd->cdb[4]; /* FIS LBA (47:40) */
3404 fis->d.featuresExp = 0; /* FIS reserve */
3405 fis->d.sectorCount = scsiCmnd->cdb[13]; /* FIS sector count (7:0) */
3406 fis->d.sectorCountExp = scsiCmnd->cdb[12]; /* FIS sector count (15:8) */
3407 fis->d.reserved4 = 0;
3408 fis->d.control = 0; /* FIS HOB bit clear */
3409 fis->d.reserved5 = 0;
3410
3411 agRequestType = AGSA_SATA_PROTOCOL_PIO_WRITE;
3412 satIOContext->ATACmd = SAT_WRITE_SECTORS_EXT;
3413 }
3414 }
3415
3416 /* case 5 */
3417 if (pSatDevData->satNCQ == agTRUE)
3418 {
3419 /* WRITE FPDMA QUEUED */
3420 if (pSatDevData->sat48BitSupport != agTRUE)
3421 {
3422 TI_DBG5(("satWrite16: case 5 !!! error NCQ but 28 bit address support \n"));
3423 satSetSensePayload( pSense,
3424 SCSI_SNSKEY_ILLEGAL_REQUEST,
3425 0,
3426 SCSI_SNSCODE_INVALID_FIELD_IN_CDB,
3427 satIOContext);
3428
3429 ostiInitiatorIOCompleted( tiRoot,
3430 tiIORequest,
3431 tiIOSuccess,
3432 SCSI_STAT_CHECK_CONDITION,
3433 satIOContext->pTiSenseData,
3434 satIOContext->interruptContext );
3435 return tiSuccess;
3436 }
3437 TI_DBG6(("satWrite16: case 5\n"));
3438
3439 /* Support 48-bit FPDMA addressing, use WRITE FPDMA QUEUE command */
3440
3441 fis->h.fisType = 0x27; /* Reg host to device */
3442 fis->h.c_pmPort = 0x80; /* C Bit is set */
3443 fis->h.command = SAT_WRITE_FPDMA_QUEUED; /* 0x61 */
3444 fis->h.features = scsiCmnd->cdb[13]; /* FIS sector count (7:0) */
3445 fis->d.lbaLow = scsiCmnd->cdb[9]; /* FIS LBA (7 :0 ) */
3446 fis->d.lbaMid = scsiCmnd->cdb[8]; /* FIS LBA (15:8 ) */
3447 fis->d.lbaHigh = scsiCmnd->cdb[7]; /* FIS LBA (23:16) */
3448
3449 /* Check FUA bit */
3450 if (scsiCmnd->cdb[1] & SCSI_WRITE16_FUA_MASK)
3451 fis->d.device = 0xC0; /* FIS FUA set */
3452 else
3453 fis->d.device = 0x40; /* FIS FUA clear */
3454
3455 fis->d.lbaLowExp = scsiCmnd->cdb[6]; /* FIS LBA (31:24) */
3456 fis->d.lbaMidExp = scsiCmnd->cdb[5]; /* FIS LBA (39:32) */
3457 fis->d.lbaHighExp = scsiCmnd->cdb[4]; /* FIS LBA (47:40) */
3458 fis->d.featuresExp = scsiCmnd->cdb[12]; /* FIS sector count (15:8) */
3459 fis->d.sectorCount = 0; /* Tag (7:3) set by LL layer */
3460 fis->d.sectorCountExp = 0;
3461 fis->d.reserved4 = 0;
3462 fis->d.control = 0; /* FIS HOB bit clear */
3463 fis->d.reserved5 = 0;
3464
3465 agRequestType = AGSA_SATA_PROTOCOL_FPDMA_WRITE;
3466 satIOContext->ATACmd = SAT_WRITE_FPDMA_QUEUED;
3467 }
3468
3469 satIOContext->currentLBA = lba;
3470 satIOContext->OrgTL = tl;
3471
3472 /*
3473 computing number of loop and remainder for tl
3474 0xFF in case not ext
3475 0xFFFF in case EXT
3476 */
3477 if (fis->h.command == SAT_WRITE_SECTORS || fis->h.command == SAT_WRITE_DMA)
3478 {
3479 LoopNum = satComputeLoopNum(tl, 0xFF);
3480 }
3481 else if (fis->h.command == SAT_WRITE_SECTORS_EXT ||
3482 fis->h.command == SAT_WRITE_DMA_EXT ||
3483 fis->h.command == SAT_WRITE_DMA_FUA_EXT
3484 )
3485 {
3486 /* SAT_READ_SECTORS_EXT, SAT_READ_DMA_EXT */
3487 LoopNum = satComputeLoopNum(tl, 0xFFFF);
3488 }
3489 else
3490 {
3491 /* SAT_WRITE_FPDMA_QUEUEDK */
3492 LoopNum = satComputeLoopNum(tl, 0xFFFF);
3493 }
3494
3495 satIOContext->LoopNum = LoopNum;
3496
3497
3498 if (LoopNum == 1)
3499 {
3500 TI_DBG5(("satWrite16: NON CHAINED data\n"));
3501 /* Initialize CB for SATA completion.
3502 */
3503 satIOContext->satCompleteCB = &satNonChainedDataIOCB;
3504 }
3505 else
3506 {
3507 TI_DBG1(("satWrite16: CHAINED data\n"));
3508 /* re-setting tl */
3509 if (fis->h.command == SAT_WRITE_SECTORS || fis->h.command == SAT_WRITE_DMA)
3510 {
3511 fis->d.sectorCount = 0xFF;
3512 }
3513 else if (fis->h.command == SAT_WRITE_SECTORS_EXT ||
3514 fis->h.command == SAT_WRITE_DMA_EXT ||
3515 fis->h.command == SAT_WRITE_DMA_FUA_EXT
3516 )
3517 {
3518 fis->d.sectorCount = 0xFF;
3519 fis->d.sectorCountExp = 0xFF;
3520 }
3521 else
3522 {
3523 /* SAT_WRITE_FPDMA_QUEUED */
3524 fis->h.features = 0xFF;
3525 fis->d.featuresExp = 0xFF;
3526 }
3527
3528 /* Initialize CB for SATA completion.
3529 */
3530 satIOContext->satCompleteCB = &satChainedDataIOCB;
3531 }
3532
3533
3534 /*
3535 * Prepare SGL and send FIS to LL layer.
3536 */
3537 satIOContext->reqType = agRequestType; /* Save it */
3538
3539 status = sataLLIOStart( tiRoot,
3540 tiIORequest,
3541 tiDeviceHandle,
3542 tiScsiRequest,
3543 satIOContext);
3544 return (status);
3545 }
3546
3547 /*****************************************************************************/
3548 /*! \brief SAT implementation for SCSI WRITE12.
3549 *
3550 * SAT implementation for SCSI WRITE12 and send FIS request to LL layer.
3551 *
3552 * \param tiRoot: Pointer to TISA initiator driver/port instance.
3553 * \param tiIORequest: Pointer to TISA I/O request context for this I/O.
3554 * \param tiDeviceHandle: Pointer to TISA device handle for this I/O.
3555 * \param tiScsiRequest: Pointer to TISA SCSI I/O request and SGL list.
3556 * \param satIOContext_t: Pointer to the SAT IO Context
3557 *
3558 * \return If command is started successfully
3559 * - \e tiSuccess: I/O request successfully initiated.
3560 * - \e tiBusy: No resources available, try again later.
3561 * - \e tiIONoDevice: Invalid device handle.
3562 * - \e tiError: Other errors.
3563 */
3564 /*****************************************************************************/
satWrite12(tiRoot_t * tiRoot,tiIORequest_t * tiIORequest,tiDeviceHandle_t * tiDeviceHandle,tiScsiInitiatorRequest_t * tiScsiRequest,satIOContext_t * satIOContext)3565 GLOBAL bit32 satWrite12(
3566 tiRoot_t *tiRoot,
3567 tiIORequest_t *tiIORequest,
3568 tiDeviceHandle_t *tiDeviceHandle,
3569 tiScsiInitiatorRequest_t *tiScsiRequest,
3570 satIOContext_t *satIOContext)
3571 {
3572 bit32 status;
3573 bit32 agRequestType = AGSA_SATA_PROTOCOL_DMA_WRITE;
3574 satDeviceData_t *pSatDevData;
3575 scsiRspSense_t *pSense;
3576 tiIniScsiCmnd_t *scsiCmnd;
3577 agsaFisRegHostToDevice_t *fis;
3578 bit32 lba = 0;
3579 bit32 tl = 0;
3580 bit32 LoopNum = 1;
3581 bit8 LBA[4];
3582 bit8 TL[4];
3583 bit32 rangeChk = agFALSE; /* lba and tl range check */
3584
3585 pSense = satIOContext->pSense;
3586 pSatDevData = satIOContext->pSatDevData;
3587 scsiCmnd = &tiScsiRequest->scsiCmnd;
3588 fis = satIOContext->pFis;
3589
3590 TI_DBG5(("satWrite12: start\n"));
3591
3592 /* checking FUA_NV */
3593 if (scsiCmnd->cdb[1] & SCSI_FUA_NV_MASK)
3594 {
3595 satSetSensePayload( pSense,
3596 SCSI_SNSKEY_ILLEGAL_REQUEST,
3597 0,
3598 SCSI_SNSCODE_INVALID_FIELD_IN_CDB,
3599 satIOContext);
3600
3601 ostiInitiatorIOCompleted( tiRoot,
3602 tiIORequest,
3603 tiIOSuccess,
3604 SCSI_STAT_CHECK_CONDITION,
3605 satIOContext->pTiSenseData,
3606 satIOContext->interruptContext );
3607
3608 TI_DBG1(("satWrite12: return FUA_NV\n"));
3609 return tiSuccess;
3610
3611 }
3612
3613
3614 /* checking CONTROL */
3615 /* NACA == 1 or LINK == 1*/
3616 if ( (scsiCmnd->cdb[11] & SCSI_NACA_MASK) || (scsiCmnd->cdb[11] & SCSI_LINK_MASK) )
3617 {
3618 satSetSensePayload( pSense,
3619 SCSI_SNSKEY_ILLEGAL_REQUEST,
3620 0,
3621 SCSI_SNSCODE_INVALID_FIELD_IN_CDB,
3622 satIOContext);
3623
3624 ostiInitiatorIOCompleted( tiRoot,
3625 tiIORequest,
3626 tiIOSuccess,
3627 SCSI_STAT_CHECK_CONDITION,
3628 satIOContext->pTiSenseData,
3629 satIOContext->interruptContext );
3630
3631 TI_DBG1(("satWrite12: return control\n"));
3632 return tiSuccess;
3633 }
3634
3635
3636 osti_memset(LBA, 0, sizeof(LBA));
3637 osti_memset(TL, 0, sizeof(TL));
3638
3639 /* do not use memcpy due to indexing in LBA and TL */
3640 LBA[0] = scsiCmnd->cdb[2]; /* MSB */
3641 LBA[1] = scsiCmnd->cdb[3];
3642 LBA[2] = scsiCmnd->cdb[4];
3643 LBA[3] = scsiCmnd->cdb[5]; /* LSB */
3644
3645 TL[0] = scsiCmnd->cdb[6]; /* MSB */
3646 TL[1] = scsiCmnd->cdb[7];
3647 TL[2] = scsiCmnd->cdb[8];
3648 TL[3] = scsiCmnd->cdb[9]; /* LSB */
3649
3650 rangeChk = satAddNComparebit32(LBA, TL);
3651
3652 lba = satComputeCDB12LBA(satIOContext);
3653 tl = satComputeCDB12TL(satIOContext);
3654
3655
3656 /* Table 34, 9.1, p 46 */
3657 /*
3658 note: As of 2/10/2006, no support for DMA QUEUED
3659 */
3660
3661 /*
3662 Table 34, 9.1, p 46, b
3663 When no 48-bit addressing support or NCQ, if LBA is beyond (2^28 - 1),
3664 return check condition
3665 */
3666 if (pSatDevData->satNCQ != agTRUE &&
3667 pSatDevData->sat48BitSupport != agTRUE
3668 )
3669 {
3670 if (lba > SAT_TR_LBA_LIMIT - 1)
3671 {
3672 satSetSensePayload( pSense,
3673 SCSI_SNSKEY_ILLEGAL_REQUEST,
3674 0,
3675 SCSI_SNSCODE_LOGICAL_BLOCK_ADDRESS_OUT_OF_RANGE,
3676 satIOContext);
3677
3678 ostiInitiatorIOCompleted( tiRoot,
3679 tiIORequest,
3680 tiIOSuccess,
3681 SCSI_STAT_CHECK_CONDITION,
3682 satIOContext->pTiSenseData,
3683 satIOContext->interruptContext );
3684
3685 TI_DBG1(("satWrite12: return LBA out of range, not EXT\n"));
3686 return tiSuccess;
3687 }
3688
3689 if (rangeChk) // if (lba + tl > SAT_TR_LBA_LIMIT)
3690 {
3691 TI_DBG1(("satWrite12: return LBA+TL out of range, not EXT\n"));
3692 satSetSensePayload( pSense,
3693 SCSI_SNSKEY_ILLEGAL_REQUEST,
3694 0,
3695 SCSI_SNSCODE_LOGICAL_BLOCK_ADDRESS_OUT_OF_RANGE,
3696 satIOContext);
3697
3698 ostiInitiatorIOCompleted( tiRoot,
3699 tiIORequest,
3700 tiIOSuccess,
3701 SCSI_STAT_CHECK_CONDITION,
3702 satIOContext->pTiSenseData,
3703 satIOContext->interruptContext );
3704
3705 return tiSuccess;
3706 }
3707 }
3708
3709
3710 /* case 1 and 2 */
3711 if (!rangeChk) // if (lba + tl <= SAT_TR_LBA_LIMIT)
3712 {
3713 if (pSatDevData->satDMASupport == agTRUE && pSatDevData->satDMAEnabled == agTRUE)
3714 {
3715 /* case 2 */
3716 /* WRITE DMA*/
3717 /* In case that we can't fit the transfer length, we loop */
3718 TI_DBG5(("satWrite12: case 2\n"));
3719 fis->h.fisType = 0x27; /* Reg host to device */
3720 fis->h.c_pmPort = 0x80; /* C bit is set */
3721 fis->h.command = SAT_WRITE_DMA; /* 0xCA */
3722 fis->h.features = 0; /* FIS reserve */
3723 fis->d.lbaLow = scsiCmnd->cdb[5]; /* FIS LBA (7 :0 ) */
3724 fis->d.lbaMid = scsiCmnd->cdb[4]; /* FIS LBA (15:8 ) */
3725 fis->d.lbaHigh = scsiCmnd->cdb[3]; /* FIS LBA (23:16) */
3726
3727 /* FIS LBA mode set LBA (27:24) */
3728 fis->d.device = (bit8)((0x4 << 4) | (scsiCmnd->cdb[2] & 0xF));
3729
3730 fis->d.lbaLowExp = 0;
3731 fis->d.lbaMidExp = 0;
3732 fis->d.lbaHighExp = 0;
3733 fis->d.featuresExp = 0;
3734 fis->d.sectorCount = scsiCmnd->cdb[9]; /* FIS sector count (7:0) */
3735 fis->d.sectorCountExp = 0;
3736 fis->d.reserved4 = 0;
3737 fis->d.control = 0; /* FIS HOB bit clear */
3738 fis->d.reserved5 = 0;
3739
3740 agRequestType = AGSA_SATA_PROTOCOL_DMA_WRITE;
3741 satIOContext->ATACmd = SAT_WRITE_DMA;
3742 }
3743 else
3744 {
3745 /* case 1 */
3746 /* WRITE MULTIPLE or WRITE SECTOR(S) */
3747 /* WRITE SECTORS for easier implemetation */
3748 /* In case that we can't fit the transfer length, we loop */
3749 TI_DBG5(("satWrite12: case 1\n"));
3750 fis->h.fisType = 0x27; /* Reg host to device */
3751 fis->h.c_pmPort = 0x80; /* C bit is set */
3752 fis->h.command = SAT_WRITE_SECTORS; /* 0x30 */
3753 fis->h.features = 0; /* FIS reserve */
3754 fis->d.lbaLow = scsiCmnd->cdb[5]; /* FIS LBA (7 :0 ) */
3755 fis->d.lbaMid = scsiCmnd->cdb[4]; /* FIS LBA (15:8 ) */
3756 fis->d.lbaHigh = scsiCmnd->cdb[3]; /* FIS LBA (23:16) */
3757
3758 /* FIS LBA mode set LBA (27:24) */
3759 fis->d.device = (bit8)((0x4 << 4) | (scsiCmnd->cdb[2] & 0xF));
3760
3761 fis->d.lbaLowExp = 0;
3762 fis->d.lbaMidExp = 0;
3763 fis->d.lbaHighExp = 0;
3764 fis->d.featuresExp = 0;
3765 fis->d.sectorCount = scsiCmnd->cdb[9]; /* FIS sector count (7:0) */
3766 fis->d.sectorCountExp = 0;
3767 fis->d.reserved4 = 0;
3768 fis->d.control = 0; /* FIS HOB bit clear */
3769 fis->d.reserved5 = 0;
3770
3771 agRequestType = AGSA_SATA_PROTOCOL_PIO_WRITE;
3772 satIOContext->ATACmd = SAT_WRITE_SECTORS;
3773 }
3774 }
3775
3776 /* case 3 and 4 */
3777 if (pSatDevData->sat48BitSupport == agTRUE)
3778 {
3779 if (pSatDevData->satDMASupport == agTRUE && pSatDevData->satDMAEnabled == agTRUE)
3780 {
3781 /* case 3 */
3782 /* WRITE DMA EXT or WRITE DMA FUA EXT */
3783 TI_DBG5(("satWrite12: case 3\n"));
3784 fis->h.fisType = 0x27; /* Reg host to device */
3785 fis->h.c_pmPort = 0x80; /* C Bit is set */
3786
3787 /* SAT_WRITE_DMA_FUA_EXT is optional and we don't support it */
3788 fis->h.command = SAT_WRITE_DMA_EXT; /* 0x35 */
3789
3790 fis->h.features = 0; /* FIS reserve */
3791 fis->d.lbaLow = scsiCmnd->cdb[5]; /* FIS LBA (7 :0 ) */
3792 fis->d.lbaMid = scsiCmnd->cdb[4]; /* FIS LBA (15:8 ) */
3793 fis->d.lbaHigh = scsiCmnd->cdb[3]; /* FIS LBA (23:16) */
3794 fis->d.device = 0x40; /* FIS LBA mode set */
3795 fis->d.lbaLowExp = scsiCmnd->cdb[2]; /* FIS LBA (31:24) */
3796 fis->d.lbaMidExp = 0; /* FIS LBA (39:32) */
3797 fis->d.lbaHighExp = 0; /* FIS LBA (47:40) */
3798 fis->d.featuresExp = 0; /* FIS reserve */
3799 fis->d.sectorCount = scsiCmnd->cdb[9]; /* FIS sector count (7:0) */
3800 fis->d.sectorCountExp = scsiCmnd->cdb[8]; /* FIS sector count (15:8) */
3801 fis->d.reserved4 = 0;
3802 fis->d.control = 0; /* FIS HOB bit clear */
3803 fis->d.reserved5 = 0;
3804
3805 agRequestType = AGSA_SATA_PROTOCOL_DMA_WRITE;
3806 satIOContext->ATACmd = SAT_WRITE_DMA_EXT;
3807 }
3808 else
3809 {
3810 /* case 4 */
3811 /* WRITE MULTIPLE EXT or WRITE MULTIPLE FUA EXT or WRITE SECTOR(S) EXT */
3812 /* WRITE SECTORS EXT for easier implemetation */
3813 TI_DBG5(("satWrite12: case 4\n"));
3814 fis->h.fisType = 0x27; /* Reg host to device */
3815 fis->h.c_pmPort = 0x80; /* C Bit is set */
3816 fis->h.command = SAT_WRITE_SECTORS_EXT; /* 0x34 */
3817
3818 fis->h.features = 0; /* FIS reserve */
3819 fis->d.lbaLow = scsiCmnd->cdb[5]; /* FIS LBA (7 :0 ) */
3820 fis->d.lbaMid = scsiCmnd->cdb[4]; /* FIS LBA (15:8 ) */
3821 fis->d.lbaHigh = scsiCmnd->cdb[3]; /* FIS LBA (23:16) */
3822 fis->d.device = 0x40; /* FIS LBA mode set */
3823 fis->d.lbaLowExp = scsiCmnd->cdb[2]; /* FIS LBA (31:24) */
3824 fis->d.lbaMidExp = 0; /* FIS LBA (39:32) */
3825 fis->d.lbaHighExp = 0; /* FIS LBA (47:40) */
3826 fis->d.featuresExp = 0; /* FIS reserve */
3827 fis->d.sectorCount = scsiCmnd->cdb[9]; /* FIS sector count (7:0) */
3828 fis->d.sectorCountExp = scsiCmnd->cdb[8]; /* FIS sector count (15:8) */
3829 fis->d.reserved4 = 0;
3830 fis->d.control = 0; /* FIS HOB bit clear */
3831 fis->d.reserved5 = 0;
3832
3833 agRequestType = AGSA_SATA_PROTOCOL_PIO_WRITE;
3834 satIOContext->ATACmd = SAT_WRITE_SECTORS_EXT;
3835 }
3836 }
3837
3838 /* case 5 */
3839 if (pSatDevData->satNCQ == agTRUE)
3840 {
3841 /* WRITE FPDMA QUEUED */
3842 if (pSatDevData->sat48BitSupport != agTRUE)
3843 {
3844 TI_DBG5(("satWrite12: case 5 !!! error NCQ but 28 bit address support \n"));
3845 satSetSensePayload( pSense,
3846 SCSI_SNSKEY_ILLEGAL_REQUEST,
3847 0,
3848 SCSI_SNSCODE_INVALID_FIELD_IN_CDB,
3849 satIOContext);
3850
3851 ostiInitiatorIOCompleted( tiRoot,
3852 tiIORequest,
3853 tiIOSuccess,
3854 SCSI_STAT_CHECK_CONDITION,
3855 satIOContext->pTiSenseData,
3856 satIOContext->interruptContext );
3857 return tiSuccess;
3858 }
3859 TI_DBG6(("satWrite12: case 5\n"));
3860
3861 /* Support 48-bit FPDMA addressing, use WRITE FPDMA QUEUE command */
3862
3863 fis->h.fisType = 0x27; /* Reg host to device */
3864 fis->h.c_pmPort = 0x80; /* C Bit is set */
3865 fis->h.command = SAT_WRITE_FPDMA_QUEUED; /* 0x61 */
3866 fis->h.features = scsiCmnd->cdb[9]; /* FIS sector count (7:0) */
3867 fis->d.lbaLow = scsiCmnd->cdb[5]; /* FIS LBA (7 :0 ) */
3868 fis->d.lbaMid = scsiCmnd->cdb[4]; /* FIS LBA (15:8 ) */
3869 fis->d.lbaHigh = scsiCmnd->cdb[3]; /* FIS LBA (23:16) */
3870
3871 /* Check FUA bit */
3872 if (scsiCmnd->cdb[1] & SCSI_WRITE12_FUA_MASK)
3873 fis->d.device = 0xC0; /* FIS FUA set */
3874 else
3875 fis->d.device = 0x40; /* FIS FUA clear */
3876
3877 fis->d.lbaLowExp = scsiCmnd->cdb[2]; /* FIS LBA (31:24) */
3878 fis->d.lbaMidExp = 0; /* FIS LBA (39:32) */
3879 fis->d.lbaHighExp = 0; /* FIS LBA (47:40) */
3880 fis->d.featuresExp = scsiCmnd->cdb[8]; /* FIS sector count (15:8) */
3881 fis->d.sectorCount = 0; /* Tag (7:3) set by LL layer */
3882 fis->d.sectorCountExp = 0;
3883 fis->d.reserved4 = 0;
3884 fis->d.control = 0; /* FIS HOB bit clear */
3885 fis->d.reserved5 = 0;
3886
3887 agRequestType = AGSA_SATA_PROTOCOL_FPDMA_WRITE;
3888 satIOContext->ATACmd = SAT_WRITE_FPDMA_QUEUED;
3889 }
3890
3891 satIOContext->currentLBA = lba;
3892 satIOContext->OrgTL = tl;
3893
3894 /*
3895 computing number of loop and remainder for tl
3896 0xFF in case not ext
3897 0xFFFF in case EXT
3898 */
3899 if (fis->h.command == SAT_WRITE_SECTORS || fis->h.command == SAT_WRITE_DMA)
3900 {
3901 LoopNum = satComputeLoopNum(tl, 0xFF);
3902 }
3903 else if (fis->h.command == SAT_WRITE_SECTORS_EXT ||
3904 fis->h.command == SAT_WRITE_DMA_EXT ||
3905 fis->h.command == SAT_WRITE_DMA_FUA_EXT
3906 )
3907 {
3908 /* SAT_READ_SECTORS_EXT, SAT_READ_DMA_EXT */
3909 LoopNum = satComputeLoopNum(tl, 0xFFFF);
3910 }
3911 else
3912 {
3913 /* SAT_WRITE_FPDMA_QUEUEDK */
3914 LoopNum = satComputeLoopNum(tl, 0xFFFF);
3915 }
3916
3917 satIOContext->LoopNum = LoopNum;
3918
3919
3920 if (LoopNum == 1)
3921 {
3922 TI_DBG5(("satWrite12: NON CHAINED data\n"));
3923 /* Initialize CB for SATA completion.
3924 */
3925 satIOContext->satCompleteCB = &satNonChainedDataIOCB;
3926 }
3927 else
3928 {
3929 TI_DBG1(("satWrite12: CHAINED data\n"));
3930 /* re-setting tl */
3931 if (fis->h.command == SAT_WRITE_SECTORS || fis->h.command == SAT_WRITE_DMA)
3932 {
3933 fis->d.sectorCount = 0xFF;
3934 }
3935 else if (fis->h.command == SAT_WRITE_SECTORS_EXT ||
3936 fis->h.command == SAT_WRITE_DMA_EXT ||
3937 fis->h.command == SAT_WRITE_DMA_FUA_EXT
3938 )
3939 {
3940 fis->d.sectorCount = 0xFF;
3941 fis->d.sectorCountExp = 0xFF;
3942 }
3943 else
3944 {
3945 /* SAT_WRITE_FPDMA_QUEUED */
3946 fis->h.features = 0xFF;
3947 fis->d.featuresExp = 0xFF;
3948 }
3949
3950 /* Initialize CB for SATA completion.
3951 */
3952 satIOContext->satCompleteCB = &satChainedDataIOCB;
3953 }
3954
3955
3956 /*
3957 * Prepare SGL and send FIS to LL layer.
3958 */
3959 satIOContext->reqType = agRequestType; /* Save it */
3960
3961 status = sataLLIOStart( tiRoot,
3962 tiIORequest,
3963 tiDeviceHandle,
3964 tiScsiRequest,
3965 satIOContext);
3966 return (status);
3967 }
3968
3969 /*****************************************************************************/
3970 /*! \brief SAT implementation for SCSI WRITE10.
3971 *
3972 * SAT implementation for SCSI WRITE10 and send FIS request to LL layer.
3973 *
3974 * \param tiRoot: Pointer to TISA initiator driver/port instance.
3975 * \param tiIORequest: Pointer to TISA I/O request context for this I/O.
3976 * \param tiDeviceHandle: Pointer to TISA device handle for this I/O.
3977 * \param tiScsiRequest: Pointer to TISA SCSI I/O request and SGL list.
3978 * \param satIOContext_t: Pointer to the SAT IO Context
3979 *
3980 * \return If command is started successfully
3981 * - \e tiSuccess: I/O request successfully initiated.
3982 * - \e tiBusy: No resources available, try again later.
3983 * - \e tiIONoDevice: Invalid device handle.
3984 * - \e tiError: Other errors.
3985 */
3986 /*****************************************************************************/
satWrite10(tiRoot_t * tiRoot,tiIORequest_t * tiIORequest,tiDeviceHandle_t * tiDeviceHandle,tiScsiInitiatorRequest_t * tiScsiRequest,satIOContext_t * satIOContext)3987 GLOBAL bit32 satWrite10(
3988 tiRoot_t *tiRoot,
3989 tiIORequest_t *tiIORequest,
3990 tiDeviceHandle_t *tiDeviceHandle,
3991 tiScsiInitiatorRequest_t *tiScsiRequest,
3992 satIOContext_t *satIOContext)
3993 {
3994
3995 bit32 status;
3996 bit32 agRequestType = AGSA_SATA_PROTOCOL_DMA_WRITE;
3997 satDeviceData_t *pSatDevData;
3998 scsiRspSense_t *pSense;
3999 tiIniScsiCmnd_t *scsiCmnd;
4000 agsaFisRegHostToDevice_t *fis;
4001 bit32 lba = 0;
4002 bit32 tl = 0;
4003 bit32 LoopNum = 1;
4004 bit8 LBA[4];
4005 bit8 TL[4];
4006 bit32 rangeChk = agFALSE; /* lba and tl range check */
4007
4008 pSense = satIOContext->pSense;
4009 pSatDevData = satIOContext->pSatDevData;
4010 scsiCmnd = &tiScsiRequest->scsiCmnd;
4011 fis = satIOContext->pFis;
4012
4013 TI_DBG5(("satWrite10: start\n"));
4014
4015 /* checking FUA_NV */
4016 if (scsiCmnd->cdb[1] & SCSI_FUA_NV_MASK)
4017 {
4018 satSetSensePayload( pSense,
4019 SCSI_SNSKEY_ILLEGAL_REQUEST,
4020 0,
4021 SCSI_SNSCODE_INVALID_FIELD_IN_CDB,
4022 satIOContext);
4023
4024 ostiInitiatorIOCompleted( tiRoot,
4025 tiIORequest,
4026 tiIOSuccess,
4027 SCSI_STAT_CHECK_CONDITION,
4028 satIOContext->pTiSenseData,
4029 satIOContext->interruptContext );
4030
4031 TI_DBG1(("satWrite10: return FUA_NV\n"));
4032 return tiSuccess;
4033
4034 }
4035
4036 /* checking CONTROL */
4037 /* NACA == 1 or LINK == 1*/
4038 if ( (scsiCmnd->cdb[9] & SCSI_NACA_MASK) || (scsiCmnd->cdb[9] & SCSI_LINK_MASK) )
4039 {
4040 satSetSensePayload( pSense,
4041 SCSI_SNSKEY_ILLEGAL_REQUEST,
4042 0,
4043 SCSI_SNSCODE_INVALID_FIELD_IN_CDB,
4044 satIOContext);
4045
4046 ostiInitiatorIOCompleted( tiRoot,
4047 tiIORequest,
4048 tiIOSuccess,
4049 SCSI_STAT_CHECK_CONDITION,
4050 satIOContext->pTiSenseData,
4051 satIOContext->interruptContext );
4052
4053 TI_DBG1(("satWrite10: return control\n"));
4054 return tiSuccess;
4055 }
4056
4057 osti_memset(LBA, 0, sizeof(LBA));
4058 osti_memset(TL, 0, sizeof(TL));
4059
4060 /* do not use memcpy due to indexing in LBA and TL */
4061 LBA[0] = scsiCmnd->cdb[2]; /* MSB */
4062 LBA[1] = scsiCmnd->cdb[3];
4063 LBA[2] = scsiCmnd->cdb[4];
4064 LBA[3] = scsiCmnd->cdb[5]; /* LSB */
4065
4066 TL[0] = 0;
4067 TL[1] = 0;
4068 TL[2] = scsiCmnd->cdb[7]; /* MSB */
4069 TL[3] = scsiCmnd->cdb[8]; /* LSB */
4070
4071 rangeChk = satAddNComparebit32(LBA, TL);
4072
4073
4074 /* cbd10; computing LBA and transfer length */
4075 lba = (scsiCmnd->cdb[2] << (8*3)) + (scsiCmnd->cdb[3] << (8*2))
4076 + (scsiCmnd->cdb[4] << 8) + scsiCmnd->cdb[5];
4077 tl = (scsiCmnd->cdb[7] << 8) + scsiCmnd->cdb[8];
4078
4079 TI_DBG5(("satWrite10: lba %d functioned lba %d\n", lba, satComputeCDB10LBA(satIOContext)));
4080 TI_DBG5(("satWrite10: tl %d functioned tl %d\n", tl, satComputeCDB10TL(satIOContext)));
4081
4082 /* Table 34, 9.1, p 46 */
4083 /*
4084 note: As of 2/10/2006, no support for DMA QUEUED
4085 */
4086
4087 /*
4088 Table 34, 9.1, p 46, b
4089 When no 48-bit addressing support or NCQ, if LBA is beyond (2^28 - 1),
4090 return check condition
4091 */
4092 if (pSatDevData->satNCQ != agTRUE &&
4093 pSatDevData->sat48BitSupport != agTRUE
4094 )
4095 {
4096 if (lba > SAT_TR_LBA_LIMIT - 1)
4097 {
4098 satSetSensePayload( pSense,
4099 SCSI_SNSKEY_ILLEGAL_REQUEST,
4100 0,
4101 SCSI_SNSCODE_LOGICAL_BLOCK_ADDRESS_OUT_OF_RANGE,
4102 satIOContext);
4103
4104 ostiInitiatorIOCompleted( tiRoot,
4105 tiIORequest,
4106 tiIOSuccess,
4107 SCSI_STAT_CHECK_CONDITION,
4108 satIOContext->pTiSenseData,
4109 satIOContext->interruptContext );
4110
4111 TI_DBG1(("satWrite10: return LBA out of range, not EXT\n"));
4112 TI_DBG1(("satWrite10: cdb 0x%x 0x%x 0x%x 0x%x\n",scsiCmnd->cdb[2], scsiCmnd->cdb[3],
4113 scsiCmnd->cdb[4], scsiCmnd->cdb[5]));
4114 TI_DBG1(("satWrite10: lba 0x%x SAT_TR_LBA_LIMIT 0x%x\n", lba, SAT_TR_LBA_LIMIT));
4115 return tiSuccess;
4116 }
4117
4118 if (rangeChk) // if (lba + tl > SAT_TR_LBA_LIMIT)
4119 {
4120 TI_DBG1(("satWrite10: return LBA+TL out of range, not EXT\n"));
4121 satSetSensePayload( pSense,
4122 SCSI_SNSKEY_ILLEGAL_REQUEST,
4123 0,
4124 SCSI_SNSCODE_LOGICAL_BLOCK_ADDRESS_OUT_OF_RANGE,
4125 satIOContext);
4126
4127 ostiInitiatorIOCompleted( tiRoot,
4128 tiIORequest,
4129 tiIOSuccess,
4130 SCSI_STAT_CHECK_CONDITION,
4131 satIOContext->pTiSenseData,
4132 satIOContext->interruptContext );
4133
4134 return tiSuccess;
4135 }
4136
4137 }
4138
4139
4140 /* case 1 and 2 */
4141 if (!rangeChk) // if (lba + tl <= SAT_TR_LBA_LIMIT)
4142 {
4143 if (pSatDevData->satDMASupport == agTRUE && pSatDevData->satDMAEnabled == agTRUE)
4144 {
4145 /* case 2 */
4146 /* WRITE DMA*/
4147 /* can't fit the transfer length */
4148 TI_DBG5(("satWrite10: case 2\n"));
4149 fis->h.fisType = 0x27; /* Reg host to device */
4150 fis->h.c_pmPort = 0x80; /* C bit is set */
4151 fis->h.command = SAT_WRITE_DMA; /* 0xCA */
4152 fis->h.features = 0; /* FIS reserve */
4153 fis->d.lbaLow = scsiCmnd->cdb[5]; /* FIS LBA (7 :0 ) */
4154 fis->d.lbaMid = scsiCmnd->cdb[4]; /* FIS LBA (15:8 ) */
4155 fis->d.lbaHigh = scsiCmnd->cdb[3]; /* FIS LBA (23:16) */
4156
4157 /* FIS LBA mode set LBA (27:24) */
4158 fis->d.device = (bit8)((0x4 << 4) | (scsiCmnd->cdb[2] & 0xF));
4159
4160 fis->d.lbaLowExp = 0;
4161 fis->d.lbaMidExp = 0;
4162 fis->d.lbaHighExp = 0;
4163 fis->d.featuresExp = 0;
4164 fis->d.sectorCount = scsiCmnd->cdb[8]; /* FIS sector count (7:0) */
4165 fis->d.sectorCountExp = 0;
4166 fis->d.reserved4 = 0;
4167 fis->d.control = 0; /* FIS HOB bit clear */
4168 fis->d.reserved5 = 0;
4169
4170 agRequestType = AGSA_SATA_PROTOCOL_DMA_WRITE;
4171 satIOContext->ATACmd = SAT_WRITE_DMA;
4172 }
4173 else
4174 {
4175 /* case 1 */
4176 /* WRITE MULTIPLE or WRITE SECTOR(S) */
4177 /* WRITE SECTORS for easier implemetation */
4178 /* can't fit the transfer length */
4179 TI_DBG5(("satWrite10: case 1\n"));
4180 fis->h.fisType = 0x27; /* Reg host to device */
4181 fis->h.c_pmPort = 0x80; /* C bit is set */
4182 fis->h.command = SAT_WRITE_SECTORS; /* 0x30 */
4183 fis->h.features = 0; /* FIS reserve */
4184 fis->d.lbaLow = scsiCmnd->cdb[5]; /* FIS LBA (7 :0 ) */
4185 fis->d.lbaMid = scsiCmnd->cdb[4]; /* FIS LBA (15:8 ) */
4186 fis->d.lbaHigh = scsiCmnd->cdb[3]; /* FIS LBA (23:16) */
4187
4188 /* FIS LBA mode set LBA (27:24) */
4189 fis->d.device = (bit8)((0x4 << 4) | (scsiCmnd->cdb[2] & 0xF));
4190
4191 fis->d.lbaLowExp = 0;
4192 fis->d.lbaMidExp = 0;
4193 fis->d.lbaHighExp = 0;
4194 fis->d.featuresExp = 0;
4195 fis->d.sectorCount = scsiCmnd->cdb[8]; /* FIS sector count (7:0) */
4196 fis->d.sectorCountExp = 0;
4197 fis->d.reserved4 = 0;
4198 fis->d.control = 0; /* FIS HOB bit clear */
4199 fis->d.reserved5 = 0;
4200
4201 agRequestType = AGSA_SATA_PROTOCOL_PIO_WRITE;
4202 satIOContext->ATACmd = SAT_WRITE_SECTORS;
4203 }
4204 }
4205 /* case 3 and 4 */
4206 if (pSatDevData->sat48BitSupport == agTRUE)
4207 {
4208 if (pSatDevData->satDMASupport == agTRUE && pSatDevData->satDMAEnabled == agTRUE)
4209 {
4210 /* case 3 */
4211 /* WRITE DMA EXT or WRITE DMA FUA EXT */
4212 TI_DBG5(("satWrite10: case 3\n"));
4213 fis->h.fisType = 0x27; /* Reg host to device */
4214 fis->h.c_pmPort = 0x80; /* C Bit is set */
4215
4216 /* SAT_WRITE_DMA_FUA_EXT is optional and we don't support it */
4217 fis->h.command = SAT_WRITE_DMA_EXT; /* 0x35 */
4218 satIOContext->ATACmd = SAT_WRITE_DMA_EXT;
4219
4220 fis->h.features = 0; /* FIS reserve */
4221 fis->d.lbaLow = scsiCmnd->cdb[5]; /* FIS LBA (7 :0 ) */
4222 fis->d.lbaMid = scsiCmnd->cdb[4]; /* FIS LBA (15:8 ) */
4223 fis->d.lbaHigh = scsiCmnd->cdb[3]; /* FIS LBA (23:16) */
4224 fis->d.device = 0x40; /* FIS LBA mode set */
4225 fis->d.lbaLowExp = scsiCmnd->cdb[2]; /* FIS LBA (31:24) */
4226 fis->d.lbaMidExp = 0; /* FIS LBA (39:32) */
4227 fis->d.lbaHighExp = 0; /* FIS LBA (47:40) */
4228 fis->d.featuresExp = 0; /* FIS reserve */
4229 fis->d.sectorCount = scsiCmnd->cdb[8]; /* FIS sector count (7:0) */
4230 fis->d.sectorCountExp = scsiCmnd->cdb[7]; /* FIS sector count (15:8) */
4231 fis->d.reserved4 = 0;
4232 fis->d.control = 0; /* FIS HOB bit clear */
4233 fis->d.reserved5 = 0;
4234
4235 agRequestType = AGSA_SATA_PROTOCOL_DMA_WRITE;
4236 }
4237 else
4238 {
4239 /* case 4 */
4240 /* WRITE MULTIPLE EXT or WRITE MULTIPLE FUA EXT or WRITE SECTOR(S) EXT */
4241 /* WRITE SECTORS EXT for easier implemetation */
4242 TI_DBG5(("satWrite10: case 4\n"));
4243 fis->h.fisType = 0x27; /* Reg host to device */
4244 fis->h.c_pmPort = 0x80; /* C Bit is set */
4245 fis->h.command = SAT_WRITE_SECTORS_EXT; /* 0x34 */
4246
4247 fis->h.features = 0; /* FIS reserve */
4248 fis->d.lbaLow = scsiCmnd->cdb[5]; /* FIS LBA (7 :0 ) */
4249 fis->d.lbaMid = scsiCmnd->cdb[4]; /* FIS LBA (15:8 ) */
4250 fis->d.lbaHigh = scsiCmnd->cdb[3]; /* FIS LBA (23:16) */
4251 fis->d.device = 0x40; /* FIS LBA mode set */
4252 fis->d.lbaLowExp = scsiCmnd->cdb[2]; /* FIS LBA (31:24) */
4253 fis->d.lbaMidExp = 0; /* FIS LBA (39:32) */
4254 fis->d.lbaHighExp = 0; /* FIS LBA (47:40) */
4255 fis->d.featuresExp = 0; /* FIS reserve */
4256 fis->d.sectorCount = scsiCmnd->cdb[8]; /* FIS sector count (7:0) */
4257 fis->d.sectorCountExp = scsiCmnd->cdb[7]; /* FIS sector count (15:8) */
4258 fis->d.reserved4 = 0;
4259 fis->d.control = 0; /* FIS HOB bit clear */
4260 fis->d.reserved5 = 0;
4261
4262 agRequestType = AGSA_SATA_PROTOCOL_PIO_WRITE;
4263 satIOContext->ATACmd = SAT_WRITE_SECTORS_EXT;
4264 }
4265 }
4266 /* case 5 */
4267 if (pSatDevData->satNCQ == agTRUE)
4268 {
4269 /* WRITE FPDMA QUEUED */
4270 if (pSatDevData->sat48BitSupport != agTRUE)
4271 {
4272 TI_DBG5(("satWrite10: case 5 !!! error NCQ but 28 bit address support \n"));
4273 satSetSensePayload( pSense,
4274 SCSI_SNSKEY_ILLEGAL_REQUEST,
4275 0,
4276 SCSI_SNSCODE_INVALID_FIELD_IN_CDB,
4277 satIOContext);
4278
4279 ostiInitiatorIOCompleted( tiRoot,
4280 tiIORequest,
4281 tiIOSuccess,
4282 SCSI_STAT_CHECK_CONDITION,
4283 satIOContext->pTiSenseData,
4284 satIOContext->interruptContext );
4285 return tiSuccess;
4286 }
4287 TI_DBG6(("satWrite10: case 5\n"));
4288
4289 /* Support 48-bit FPDMA addressing, use WRITE FPDMA QUEUE command */
4290
4291 fis->h.fisType = 0x27; /* Reg host to device */
4292 fis->h.c_pmPort = 0x80; /* C Bit is set */
4293 fis->h.command = SAT_WRITE_FPDMA_QUEUED; /* 0x61 */
4294 fis->h.features = scsiCmnd->cdb[8]; /* FIS sector count (7:0) */
4295 fis->d.lbaLow = scsiCmnd->cdb[5]; /* FIS LBA (7 :0 ) */
4296 fis->d.lbaMid = scsiCmnd->cdb[4]; /* FIS LBA (15:8 ) */
4297 fis->d.lbaHigh = scsiCmnd->cdb[3]; /* FIS LBA (23:16) */
4298
4299 /* Check FUA bit */
4300 if (scsiCmnd->cdb[1] & SCSI_WRITE10_FUA_MASK)
4301 fis->d.device = 0xC0; /* FIS FUA set */
4302 else
4303 fis->d.device = 0x40; /* FIS FUA clear */
4304
4305 fis->d.lbaLowExp = scsiCmnd->cdb[2]; /* FIS LBA (31:24) */
4306 fis->d.lbaMidExp = 0; /* FIS LBA (39:32) */
4307 fis->d.lbaHighExp = 0; /* FIS LBA (47:40) */
4308 fis->d.featuresExp = scsiCmnd->cdb[7]; /* FIS sector count (15:8) */
4309 fis->d.sectorCount = 0; /* Tag (7:3) set by LL layer */
4310 fis->d.sectorCountExp = 0;
4311 fis->d.reserved4 = 0;
4312 fis->d.control = 0; /* FIS HOB bit clear */
4313 fis->d.reserved5 = 0;
4314
4315 agRequestType = AGSA_SATA_PROTOCOL_FPDMA_WRITE;
4316 satIOContext->ATACmd = SAT_WRITE_FPDMA_QUEUED;
4317 }
4318
4319 // tdhexdump("satWrite10 final fis", (bit8 *)fis, sizeof(agsaFisRegHostToDevice_t));
4320
4321 satIOContext->currentLBA = lba;
4322 satIOContext->OrgTL = tl;
4323
4324 /*
4325 computing number of loop and remainder for tl
4326 0xFF in case not ext
4327 0xFFFF in case EXT
4328 */
4329 if (fis->h.command == SAT_WRITE_SECTORS || fis->h.command == SAT_WRITE_DMA)
4330 {
4331 LoopNum = satComputeLoopNum(tl, 0xFF);
4332 }
4333 else if (fis->h.command == SAT_WRITE_SECTORS_EXT ||
4334 fis->h.command == SAT_WRITE_DMA_EXT ||
4335 fis->h.command == SAT_WRITE_DMA_FUA_EXT
4336 )
4337 {
4338 /* SAT_READ_SECTORS_EXT, SAT_READ_DMA_EXT */
4339 LoopNum = satComputeLoopNum(tl, 0xFFFF);
4340 }
4341 else
4342 {
4343 /* SAT_WRITE_FPDMA_QUEUEDK */
4344 LoopNum = satComputeLoopNum(tl, 0xFFFF);
4345 }
4346
4347 satIOContext->LoopNum = LoopNum;
4348
4349
4350 if (LoopNum == 1)
4351 {
4352 TI_DBG5(("satWrite10: NON CHAINED data\n"));
4353 /* Initialize CB for SATA completion.
4354 */
4355 satIOContext->satCompleteCB = &satNonChainedDataIOCB;
4356 }
4357 else
4358 {
4359 TI_DBG1(("satWrite10: CHAINED data\n"));
4360 /* re-setting tl */
4361 if (fis->h.command == SAT_WRITE_SECTORS || fis->h.command == SAT_WRITE_DMA)
4362 {
4363 fis->d.sectorCount = 0xFF;
4364 }
4365 else if (fis->h.command == SAT_WRITE_SECTORS_EXT ||
4366 fis->h.command == SAT_WRITE_DMA_EXT ||
4367 fis->h.command == SAT_WRITE_DMA_FUA_EXT
4368 )
4369 {
4370 fis->d.sectorCount = 0xFF;
4371 fis->d.sectorCountExp = 0xFF;
4372 }
4373 else
4374 {
4375 /* SAT_WRITE_FPDMA_QUEUED */
4376 fis->h.features = 0xFF;
4377 fis->d.featuresExp = 0xFF;
4378 }
4379
4380 /* Initialize CB for SATA completion.
4381 */
4382 satIOContext->satCompleteCB = &satChainedDataIOCB;
4383 }
4384
4385
4386 /*
4387 * Prepare SGL and send FIS to LL layer.
4388 */
4389 satIOContext->reqType = agRequestType; /* Save it */
4390
4391 status = sataLLIOStart( tiRoot,
4392 tiIORequest,
4393 tiDeviceHandle,
4394 tiScsiRequest,
4395 satIOContext);
4396 return (status);
4397 }
4398
4399 /*****************************************************************************/
4400 /*! \brief SAT implementation for SCSI satWrite_1.
4401 *
4402 * SAT implementation for SCSI WRITE10 and send FIS request to LL layer.
4403 * This is used when WRITE10 is divided into multiple ATA commands
4404 *
4405 * \param tiRoot: Pointer to TISA initiator driver/port instance.
4406 * \param tiIORequest: Pointer to TISA I/O request context for this I/O.
4407 * \param tiDeviceHandle: Pointer to TISA device handle for this I/O.
4408 * \param tiScsiRequest: Pointer to TISA SCSI I/O request and SGL list.
4409 * \param satIOContext_t: Pointer to the SAT IO Context
4410 *
4411 * \return If command is started successfully
4412 * - \e tiSuccess: I/O request successfully initiated.
4413 * - \e tiBusy: No resources available, try again later.
4414 * - \e tiIONoDevice: Invalid device handle.
4415 * - \e tiError: Other errors.
4416 */
4417 /*****************************************************************************/
satWrite_1(tiRoot_t * tiRoot,tiIORequest_t * tiIORequest,tiDeviceHandle_t * tiDeviceHandle,tiScsiInitiatorRequest_t * tiScsiRequest,satIOContext_t * satIOContext)4418 GLOBAL bit32 satWrite_1(
4419 tiRoot_t *tiRoot,
4420 tiIORequest_t *tiIORequest,
4421 tiDeviceHandle_t *tiDeviceHandle,
4422 tiScsiInitiatorRequest_t *tiScsiRequest,
4423 satIOContext_t *satIOContext)
4424 {
4425 /*
4426 Assumption: error check on lba and tl has been done in satWrite*()
4427 lba = lba + tl;
4428 */
4429 bit32 status;
4430 satIOContext_t *satOrgIOContext = agNULL;
4431 tiIniScsiCmnd_t *scsiCmnd;
4432 agsaFisRegHostToDevice_t *fis;
4433 bit32 agRequestType = AGSA_SATA_PROTOCOL_DMA_WRITE;
4434 bit32 lba = 0;
4435 bit32 DenomTL = 0xFF;
4436 bit32 Remainder = 0;
4437 bit8 LBA[4]; /* 0 MSB, 3 LSB */
4438
4439 TI_DBG2(("satWrite_1: start\n"));
4440
4441 fis = satIOContext->pFis;
4442 satOrgIOContext = satIOContext->satOrgIOContext;
4443 scsiCmnd = satOrgIOContext->pScsiCmnd;
4444
4445 osti_memset(LBA,0, sizeof(LBA));
4446
4447 switch (satOrgIOContext->ATACmd)
4448 {
4449 case SAT_WRITE_DMA:
4450 DenomTL = 0xFF;
4451 break;
4452 case SAT_WRITE_SECTORS:
4453 DenomTL = 0xFF;
4454 break;
4455 case SAT_WRITE_DMA_EXT:
4456 DenomTL = 0xFFFF;
4457 break;
4458 case SAT_WRITE_DMA_FUA_EXT:
4459 DenomTL = 0xFFFF;
4460 break;
4461 case SAT_WRITE_SECTORS_EXT:
4462 DenomTL = 0xFFFF;
4463 break;
4464 case SAT_WRITE_FPDMA_QUEUED:
4465 DenomTL = 0xFFFF;
4466 break;
4467 default:
4468 TI_DBG1(("satWrite_1: error incorrect ata command 0x%x\n", satIOContext->ATACmd));
4469 return tiError;
4470 break;
4471 }
4472
4473 Remainder = satOrgIOContext->OrgTL % DenomTL;
4474 satOrgIOContext->currentLBA = satOrgIOContext->currentLBA + DenomTL;
4475 lba = satOrgIOContext->currentLBA;
4476
4477 LBA[0] = (bit8)((lba & 0xF000) >> (8 * 3)); /* MSB */
4478 LBA[1] = (bit8)((lba & 0xF00) >> (8 * 2));
4479 LBA[2] = (bit8)((lba & 0xF0) >> 8);
4480 LBA[3] = (bit8)(lba & 0xF); /* LSB */
4481
4482 switch (satOrgIOContext->ATACmd)
4483 {
4484 case SAT_WRITE_DMA:
4485 fis->h.fisType = 0x27; /* Reg host to device */
4486 fis->h.c_pmPort = 0x80; /* C bit is set */
4487 fis->h.command = SAT_WRITE_DMA; /* 0xCA */
4488 fis->h.features = 0; /* FIS reserve */
4489 fis->d.lbaLow = LBA[3]; /* FIS LBA (7 :0 ) */
4490 fis->d.lbaMid = LBA[2]; /* FIS LBA (15:8 ) */
4491 fis->d.lbaHigh = LBA[1]; /* FIS LBA (23:16) */
4492
4493 /* FIS LBA mode set LBA (27:24) */
4494 fis->d.device = (bit8)((0x4 << 4) | (LBA[0] & 0xF));
4495
4496 fis->d.lbaLowExp = 0;
4497 fis->d.lbaMidExp = 0;
4498 fis->d.lbaHighExp = 0;
4499 fis->d.featuresExp = 0;
4500 if (satOrgIOContext->LoopNum == 1)
4501 {
4502 /* last loop */
4503 fis->d.sectorCount = (bit8)Remainder; /* FIS sector count (7:0) */
4504 }
4505 else
4506 {
4507 fis->d.sectorCount = 0xFF; /* FIS sector count (7:0) */
4508 }
4509 fis->d.sectorCountExp = 0;
4510 fis->d.reserved4 = 0;
4511 fis->d.control = 0; /* FIS HOB bit clear */
4512 fis->d.reserved5 = 0;
4513
4514 agRequestType = AGSA_SATA_PROTOCOL_DMA_WRITE;
4515
4516 break;
4517 case SAT_WRITE_SECTORS:
4518 fis->h.fisType = 0x27; /* Reg host to device */
4519 fis->h.c_pmPort = 0x80; /* C bit is set */
4520 fis->h.command = SAT_WRITE_SECTORS; /* 0x30 */
4521 fis->h.features = 0; /* FIS reserve */
4522 fis->d.lbaLow = LBA[3]; /* FIS LBA (7 :0 ) */
4523 fis->d.lbaMid = LBA[2]; /* FIS LBA (15:8 ) */
4524 fis->d.lbaHigh = LBA[1]; /* FIS LBA (23:16) */
4525
4526 /* FIS LBA mode set LBA (27:24) */
4527 fis->d.device = (bit8)((0x4 << 4) | (LBA[0] & 0xF));
4528
4529 fis->d.lbaLowExp = 0;
4530 fis->d.lbaMidExp = 0;
4531 fis->d.lbaHighExp = 0;
4532 fis->d.featuresExp = 0;
4533 if (satOrgIOContext->LoopNum == 1)
4534 {
4535 /* last loop */
4536 fis->d.sectorCount = (bit8)Remainder; /* FIS sector count (7:0) */
4537 }
4538 else
4539 {
4540 fis->d.sectorCount = 0xFF; /* FIS sector count (7:0) */
4541 }
4542 fis->d.sectorCountExp = 0;
4543 fis->d.reserved4 = 0;
4544 fis->d.control = 0; /* FIS HOB bit clear */
4545 fis->d.reserved5 = 0;
4546
4547 agRequestType = AGSA_SATA_PROTOCOL_PIO_WRITE;
4548
4549 break;
4550 case SAT_WRITE_DMA_EXT:
4551 fis->h.fisType = 0x27; /* Reg host to device */
4552 fis->h.c_pmPort = 0x80; /* C Bit is set */
4553 fis->h.command = SAT_WRITE_DMA_EXT; /* 0x3D */
4554 fis->h.features = 0; /* FIS reserve */
4555 fis->d.lbaLow = LBA[3]; /* FIS LBA (7 :0 ) */
4556 fis->d.lbaMid = LBA[2]; /* FIS LBA (15:8 ) */
4557 fis->d.lbaHigh = LBA[1]; /* FIS LBA (23:16) */
4558 fis->d.device = 0x40; /* FIS LBA mode set */
4559 fis->d.lbaLowExp = LBA[0]; /* FIS LBA (31:24) */
4560 fis->d.lbaMidExp = 0; /* FIS LBA (39:32) */
4561 fis->d.lbaHighExp = 0; /* FIS LBA (47:40) */
4562 fis->d.featuresExp = 0; /* FIS reserve */
4563 if (satOrgIOContext->LoopNum == 1)
4564 {
4565 /* last loop */
4566 fis->d.sectorCount = (bit8)(Remainder & 0xFF); /* FIS sector count (7:0) */
4567 fis->d.sectorCountExp = (bit8)((Remainder & 0xFF00) >> 8); /* FIS sector count (15:8) */
4568 }
4569 else
4570 {
4571 fis->d.sectorCount = 0xFF; /* FIS sector count (7:0) */
4572 fis->d.sectorCountExp = 0xFF; /* FIS sector count (15:8) */
4573 }
4574 fis->d.reserved4 = 0;
4575 fis->d.control = 0; /* FIS HOB bit clear */
4576 fis->d.reserved5 = 0;
4577
4578 agRequestType = AGSA_SATA_PROTOCOL_DMA_WRITE;
4579
4580 break;
4581 case SAT_WRITE_SECTORS_EXT:
4582 fis->h.fisType = 0x27; /* Reg host to device */
4583 fis->h.c_pmPort = 0x80; /* C Bit is set */
4584 fis->h.command = SAT_WRITE_SECTORS_EXT; /* 0x34 */
4585
4586 fis->h.features = 0; /* FIS reserve */
4587 fis->d.lbaLow = LBA[3]; /* FIS LBA (7 :0 ) */
4588 fis->d.lbaMid = LBA[2]; /* FIS LBA (15:8 ) */
4589 fis->d.lbaHigh = LBA[1]; /* FIS LBA (23:16) */
4590 fis->d.device = 0x40; /* FIS LBA mode set */
4591 fis->d.lbaLowExp = LBA[0]; /* FIS LBA (31:24) */
4592 fis->d.lbaMidExp = 0; /* FIS LBA (39:32) */
4593 fis->d.lbaHighExp = 0; /* FIS LBA (47:40) */
4594 fis->d.featuresExp = 0; /* FIS reserve */
4595 if (satOrgIOContext->LoopNum == 1)
4596 {
4597 /* last loop */
4598 fis->d.sectorCount = (bit8)(Remainder & 0xFF); /* FIS sector count (7:0) */
4599 fis->d.sectorCountExp = (bit8)((Remainder & 0xFF00) >> 8); /* FIS sector count (15:8) */
4600 }
4601 else
4602 {
4603 fis->d.sectorCount = 0xFF; /* FIS sector count (7:0) */
4604 fis->d.sectorCountExp = 0xFF; /* FIS sector count (15:8) */
4605 }
4606 fis->d.reserved4 = 0;
4607 fis->d.control = 0; /* FIS HOB bit clear */
4608 fis->d.reserved5 = 0;
4609
4610 agRequestType = AGSA_SATA_PROTOCOL_PIO_WRITE;
4611
4612 break;
4613 case SAT_WRITE_FPDMA_QUEUED:
4614 fis->h.fisType = 0x27; /* Reg host to device */
4615 fis->h.c_pmPort = 0x80; /* C Bit is set */
4616 fis->h.command = SAT_WRITE_FPDMA_QUEUED; /* 0x61 */
4617 fis->d.lbaLow = LBA[3]; /* FIS LBA (7 :0 ) */
4618 fis->d.lbaMid = LBA[2]; /* FIS LBA (15:8 ) */
4619 fis->d.lbaHigh = LBA[1]; /* FIS LBA (23:16) */
4620
4621 /* Check FUA bit */
4622 if (scsiCmnd->cdb[1] & SCSI_WRITE10_FUA_MASK)
4623 fis->d.device = 0xC0; /* FIS FUA set */
4624 else
4625 fis->d.device = 0x40; /* FIS FUA clear */
4626
4627 fis->d.lbaLowExp = LBA[0];; /* FIS LBA (31:24) */
4628 fis->d.lbaMidExp = 0; /* FIS LBA (39:32) */
4629 fis->d.lbaHighExp = 0; /* FIS LBA (47:40) */
4630 if (satOrgIOContext->LoopNum == 1)
4631 {
4632 /* last loop */
4633 fis->h.features = (bit8)(Remainder & 0xFF); /* FIS sector count (7:0) */
4634 fis->d.featuresExp = (bit8)((Remainder & 0xFF00) >> 8); /* FIS sector count (15:8) */
4635 }
4636 else
4637 {
4638 fis->h.features = 0xFF; /* FIS sector count (7:0) */
4639 fis->d.featuresExp = 0xFF; /* FIS sector count (15:8) */
4640 }
4641 fis->d.sectorCount = 0; /* Tag (7:3) set by LL layer */
4642 fis->d.sectorCountExp = 0;
4643 fis->d.reserved4 = 0;
4644 fis->d.control = 0; /* FIS HOB bit clear */
4645 fis->d.reserved5 = 0;
4646
4647 agRequestType = AGSA_SATA_PROTOCOL_FPDMA_WRITE;
4648 break;
4649
4650 default:
4651 TI_DBG1(("satWrite_1: error incorrect ata command 0x%x\n", satIOContext->ATACmd));
4652 return tiError;
4653 break;
4654 }
4655
4656 /* Initialize CB for SATA completion.
4657 */
4658 /* chained data */
4659 satIOContext->satCompleteCB = &satChainedDataIOCB;
4660
4661
4662 /*
4663 * Prepare SGL and send FIS to LL layer.
4664 */
4665 satIOContext->reqType = agRequestType; /* Save it */
4666
4667 status = sataLLIOStart( tiRoot,
4668 tiIORequest,
4669 tiDeviceHandle,
4670 tiScsiRequest,
4671 satIOContext);
4672
4673 TI_DBG5(("satWrite_1: return\n"));
4674 return (status);
4675 }
4676
4677 /*****************************************************************************/
4678 /*! \brief SAT implementation for SCSI WRITE6.
4679 *
4680 * SAT implementation for SCSI WRITE6 and send FIS request to LL layer.
4681 *
4682 * \param tiRoot: Pointer to TISA initiator driver/port instance.
4683 * \param tiIORequest: Pointer to TISA I/O request context for this I/O.
4684 * \param tiDeviceHandle: Pointer to TISA device handle for this I/O.
4685 * \param tiScsiRequest: Pointer to TISA SCSI I/O request and SGL list.
4686 * \param satIOContext_t: Pointer to the SAT IO Context
4687 *
4688 * \return If command is started successfully
4689 * - \e tiSuccess: I/O request successfully initiated.
4690 * - \e tiBusy: No resources available, try again later.
4691 * - \e tiIONoDevice: Invalid device handle.
4692 * - \e tiError: Other errors.
4693 */
4694 /*****************************************************************************/
satWrite6(tiRoot_t * tiRoot,tiIORequest_t * tiIORequest,tiDeviceHandle_t * tiDeviceHandle,tiScsiInitiatorRequest_t * tiScsiRequest,satIOContext_t * satIOContext)4695 GLOBAL bit32 satWrite6(
4696 tiRoot_t *tiRoot,
4697 tiIORequest_t *tiIORequest,
4698 tiDeviceHandle_t *tiDeviceHandle,
4699 tiScsiInitiatorRequest_t *tiScsiRequest,
4700 satIOContext_t *satIOContext)
4701 {
4702
4703 bit32 status;
4704 bit32 agRequestType = AGSA_SATA_PROTOCOL_DMA_WRITE;
4705 satDeviceData_t *pSatDevData;
4706 scsiRspSense_t *pSense;
4707 tiIniScsiCmnd_t *scsiCmnd;
4708 agsaFisRegHostToDevice_t *fis;
4709 bit32 lba = 0;
4710 bit16 tl = 0;
4711
4712 pSense = satIOContext->pSense;
4713 pSatDevData = satIOContext->pSatDevData;
4714 scsiCmnd = &tiScsiRequest->scsiCmnd;
4715 fis = satIOContext->pFis;
4716
4717 TI_DBG5(("satWrite6: start\n"));
4718
4719 /* checking CONTROL */
4720 /* NACA == 1 or LINK == 1*/
4721 if ( (scsiCmnd->cdb[5] & SCSI_NACA_MASK) || (scsiCmnd->cdb[5] & SCSI_LINK_MASK) )
4722 {
4723 satSetSensePayload( pSense,
4724 SCSI_SNSKEY_ILLEGAL_REQUEST,
4725 0,
4726 SCSI_SNSCODE_INVALID_FIELD_IN_CDB,
4727 satIOContext);
4728
4729 ostiInitiatorIOCompleted( tiRoot,
4730 tiIORequest,
4731 tiIOSuccess,
4732 SCSI_STAT_CHECK_CONDITION,
4733 satIOContext->pTiSenseData,
4734 satIOContext->interruptContext );
4735
4736 TI_DBG1(("satWrite6: return control\n"));
4737 return tiSuccess;
4738 }
4739
4740
4741 /* cbd6; computing LBA and transfer length */
4742 lba = (((scsiCmnd->cdb[1]) & 0x1f) << (8*2))
4743 + (scsiCmnd->cdb[2] << 8) + scsiCmnd->cdb[3];
4744 tl = scsiCmnd->cdb[4];
4745
4746
4747 /* Table 34, 9.1, p 46 */
4748 /*
4749 note: As of 2/10/2006, no support for DMA QUEUED
4750 */
4751
4752 /*
4753 Table 34, 9.1, p 46, b
4754 When no 48-bit addressing support or NCQ, if LBA is beyond (2^28 - 1),
4755 return check condition
4756 */
4757 if (pSatDevData->satNCQ != agTRUE &&
4758 pSatDevData->sat48BitSupport != agTRUE
4759 )
4760 {
4761 if (lba > SAT_TR_LBA_LIMIT - 1)
4762 {
4763 satSetSensePayload( pSense,
4764 SCSI_SNSKEY_ILLEGAL_REQUEST,
4765 0,
4766 SCSI_SNSCODE_LOGICAL_BLOCK_ADDRESS_OUT_OF_RANGE,
4767 satIOContext);
4768
4769 ostiInitiatorIOCompleted( tiRoot,
4770 tiIORequest,
4771 tiIOSuccess,
4772 SCSI_STAT_CHECK_CONDITION,
4773 satIOContext->pTiSenseData,
4774 satIOContext->interruptContext );
4775
4776 TI_DBG1(("satWrite6: return LBA out of range\n"));
4777 return tiSuccess;
4778 }
4779 }
4780
4781 /* case 1 and 2 */
4782 if (lba + tl <= SAT_TR_LBA_LIMIT)
4783 {
4784 if (pSatDevData->satDMASupport == agTRUE && pSatDevData->satDMAEnabled == agTRUE)
4785 {
4786 /* case 2 */
4787 /* WRITE DMA*/
4788 TI_DBG5(("satWrite6: case 2\n"));
4789
4790
4791 fis->h.fisType = 0x27; /* Reg host to device */
4792 fis->h.c_pmPort = 0x80; /* C Bit is set */
4793 fis->h.command = SAT_WRITE_DMA; /* 0xCA */
4794 fis->h.features = 0; /* FIS reserve */
4795 fis->d.lbaLow = scsiCmnd->cdb[3]; /* FIS LBA (7 :0 ) */
4796 fis->d.lbaMid = scsiCmnd->cdb[2]; /* FIS LBA (15:8 ) */
4797 fis->d.lbaHigh = (bit8)((scsiCmnd->cdb[1]) & 0x1f); /* FIS LBA (23:16) */
4798 fis->d.device = 0x40; /* FIS LBA mode */
4799 fis->d.lbaLowExp = 0;
4800 fis->d.lbaMidExp = 0;
4801 fis->d.lbaHighExp = 0;
4802 fis->d.featuresExp = 0;
4803 if (tl == 0)
4804 {
4805 /* temporary fix */
4806 fis->d.sectorCount = 0xff; /* FIS sector count (7:0) */
4807 }
4808 else
4809 {
4810 fis->d.sectorCount = scsiCmnd->cdb[4]; /* FIS sector count (7:0) */
4811 }
4812 fis->d.sectorCountExp = 0;
4813 fis->d.reserved4 = 0;
4814 fis->d.control = 0; /* FIS HOB bit clear */
4815 fis->d.reserved5 = 0;
4816
4817 agRequestType = AGSA_SATA_PROTOCOL_DMA_WRITE;
4818 }
4819 else
4820 {
4821 /* case 1 */
4822 /* WRITE SECTORS for easier implemetation */
4823 TI_DBG5(("satWrite6: case 1\n"));
4824
4825 fis->h.fisType = 0x27; /* Reg host to device */
4826 fis->h.c_pmPort = 0x80; /* C Bit is set */
4827 fis->h.command = SAT_WRITE_SECTORS; /* 0xCA */
4828 fis->h.features = 0; /* FIS reserve */
4829 fis->d.lbaLow = scsiCmnd->cdb[3]; /* FIS LBA (7 :0 ) */
4830 fis->d.lbaMid = scsiCmnd->cdb[2]; /* FIS LBA (15:8 ) */
4831 fis->d.lbaHigh = (bit8)((scsiCmnd->cdb[1]) & 0x1f); /* FIS LBA (23:16) */
4832 fis->d.device = 0x40; /* FIS LBA mode */
4833 fis->d.lbaLowExp = 0;
4834 fis->d.lbaMidExp = 0;
4835 fis->d.lbaHighExp = 0;
4836 fis->d.featuresExp = 0;
4837 if (tl == 0)
4838 {
4839 /* temporary fix */
4840 fis->d.sectorCount = 0xff; /* FIS sector count (7:0) */
4841 }
4842 else
4843 {
4844 fis->d.sectorCount = scsiCmnd->cdb[4]; /* FIS sector count (7:0) */
4845 }
4846 fis->d.sectorCountExp = 0;
4847 fis->d.reserved4 = 0;
4848 fis->d.control = 0; /* FIS HOB bit clear */
4849 fis->d.reserved5 = 0;
4850
4851 agRequestType = AGSA_SATA_PROTOCOL_PIO_WRITE;
4852
4853 }
4854 }
4855
4856 /* case 3 and 4 */
4857 if (pSatDevData->sat48BitSupport == agTRUE)
4858 {
4859 if (pSatDevData->satDMASupport == agTRUE && pSatDevData->satDMAEnabled == agTRUE)
4860 {
4861 /* case 3 */
4862 /* WRITE DMA EXT only */
4863 TI_DBG5(("satWrite6: case 3\n"));
4864 fis->h.fisType = 0x27; /* Reg host to device */
4865 fis->h.c_pmPort = 0x80; /* C Bit is set */
4866 fis->h.command = SAT_WRITE_DMA_EXT; /* 0x35 */
4867 fis->h.features = 0; /* FIS reserve */
4868 fis->d.lbaLow = scsiCmnd->cdb[3]; /* FIS LBA (7 :0 ) */
4869 fis->d.lbaMid = scsiCmnd->cdb[2]; /* FIS LBA (15:8 ) */
4870 fis->d.lbaHigh = (bit8)((scsiCmnd->cdb[1]) & 0x1f); /* FIS LBA (23:16) */
4871 fis->d.device = 0x40; /* FIS LBA mode set */
4872 fis->d.lbaLowExp = 0; /* FIS LBA (31:24) */
4873 fis->d.lbaMidExp = 0; /* FIS LBA (39:32) */
4874 fis->d.lbaHighExp = 0; /* FIS LBA (47:40) */
4875 fis->d.featuresExp = 0; /* FIS reserve */
4876 if (tl == 0)
4877 {
4878 /* sector count is 256, 0x100*/
4879 fis->d.sectorCount = 0; /* FIS sector count (7:0) */
4880 fis->d.sectorCountExp = 0x01; /* FIS sector count (15:8) */
4881 }
4882 else
4883 {
4884 fis->d.sectorCount = scsiCmnd->cdb[4]; /* FIS sector count (7:0) */
4885 fis->d.sectorCountExp = 0; /* FIS sector count (15:8) */
4886 }
4887 fis->d.reserved4 = 0;
4888 fis->d.control = 0; /* FIS HOB bit clear */
4889 fis->d.reserved5 = 0;
4890
4891 agRequestType = AGSA_SATA_PROTOCOL_DMA_WRITE;
4892 }
4893 else
4894 {
4895 /* case 4 */
4896 /* WRITE SECTORS EXT for easier implemetation */
4897 TI_DBG5(("satWrite6: case 4\n"));
4898
4899 fis->h.fisType = 0x27; /* Reg host to device */
4900 fis->h.c_pmPort = 0x80; /* C Bit is set */
4901 fis->h.command = SAT_WRITE_SECTORS_EXT; /* 0x34 */
4902 fis->h.features = 0; /* FIS reserve */
4903 fis->d.lbaLow = scsiCmnd->cdb[3]; /* FIS LBA (7 :0 ) */
4904 fis->d.lbaMid = scsiCmnd->cdb[2]; /* FIS LBA (15:8 ) */
4905 fis->d.lbaHigh = (bit8)((scsiCmnd->cdb[1]) & 0x1f); /* FIS LBA (23:16) */
4906 fis->d.device = 0x40; /* FIS LBA mode set */
4907 fis->d.lbaLowExp = 0; /* FIS LBA (31:24) */
4908 fis->d.lbaMidExp = 0; /* FIS LBA (39:32) */
4909 fis->d.lbaHighExp = 0; /* FIS LBA (47:40) */
4910 fis->d.featuresExp = 0; /* FIS reserve */
4911 if (tl == 0)
4912 {
4913 /* sector count is 256, 0x100*/
4914 fis->d.sectorCount = 0; /* FIS sector count (7:0) */
4915 fis->d.sectorCountExp = 0x01; /* FIS sector count (15:8) */
4916 }
4917 else
4918 {
4919 fis->d.sectorCount = scsiCmnd->cdb[4]; /* FIS sector count (7:0) */
4920 fis->d.sectorCountExp = 0; /* FIS sector count (15:8) */
4921 }
4922 fis->d.reserved4 = 0;
4923 fis->d.control = 0; /* FIS HOB bit clear */
4924 fis->d.reserved5 = 0;
4925
4926 agRequestType = AGSA_SATA_PROTOCOL_PIO_WRITE;
4927 }
4928 }
4929
4930 /* case 5 */
4931 if (pSatDevData->satNCQ == agTRUE)
4932 {
4933 /* WRITE FPDMA QUEUED */
4934 if (pSatDevData->sat48BitSupport != agTRUE)
4935 {
4936 /* sanity check */
4937 TI_DBG5(("satWrite6: case 5 !!! error NCQ but 28 bit address support \n"));
4938 satSetSensePayload( pSense,
4939 SCSI_SNSKEY_ILLEGAL_REQUEST,
4940 0,
4941 SCSI_SNSCODE_INVALID_FIELD_IN_CDB,
4942 satIOContext);
4943
4944 ostiInitiatorIOCompleted( tiRoot,
4945 tiIORequest,
4946 tiIOSuccess,
4947 SCSI_STAT_CHECK_CONDITION,
4948 satIOContext->pTiSenseData,
4949 satIOContext->interruptContext );
4950 return tiSuccess;
4951 }
4952 TI_DBG5(("satWrite6: case 5\n"));
4953
4954 /* Support 48-bit FPDMA addressing, use WRITE FPDMA QUEUE command */
4955
4956 fis->h.fisType = 0x27; /* Reg host to device */
4957 fis->h.c_pmPort = 0x80; /* C Bit is set */
4958 fis->h.command = SAT_WRITE_FPDMA_QUEUED; /* 0x61 */
4959 fis->d.lbaLow = scsiCmnd->cdb[3]; /* FIS LBA (7 :0 ) */
4960 fis->d.lbaMid = scsiCmnd->cdb[2]; /* FIS LBA (15:8 ) */
4961 fis->d.lbaHigh = (bit8)((scsiCmnd->cdb[1]) & 0x1f); /* FIS LBA (23:16) */
4962 fis->d.device = 0x40; /* FIS FUA clear */
4963 fis->d.lbaLowExp = 0; /* FIS LBA (31:24) */
4964 fis->d.lbaMidExp = 0; /* FIS LBA (39:32) */
4965 fis->d.lbaHighExp = 0; /* FIS LBA (47:40) */
4966 if (tl == 0)
4967 {
4968 /* sector count is 256, 0x100*/
4969 fis->h.features = 0; /* FIS sector count (7:0) */
4970 fis->d.featuresExp = 0x01; /* FIS sector count (15:8) */
4971 }
4972 else
4973 {
4974 fis->h.features = scsiCmnd->cdb[4]; /* FIS sector count (7:0) */
4975 fis->d.featuresExp = 0; /* FIS sector count (15:8) */
4976 }
4977 fis->d.sectorCount = 0; /* Tag (7:3) set by LL layer */
4978 fis->d.sectorCountExp = 0;
4979 fis->d.reserved4 = 0;
4980 fis->d.control = 0; /* FIS HOB bit clear */
4981 fis->d.reserved5 = 0;
4982
4983 agRequestType = AGSA_SATA_PROTOCOL_FPDMA_WRITE;
4984 }
4985
4986 /* Initialize CB for SATA completion.
4987 */
4988 satIOContext->satCompleteCB = &satNonChainedDataIOCB;
4989
4990 /*
4991 * Prepare SGL and send FIS to LL layer.
4992 */
4993 satIOContext->reqType = agRequestType; /* Save it */
4994
4995 status = sataLLIOStart( tiRoot,
4996 tiIORequest,
4997 tiDeviceHandle,
4998 tiScsiRequest,
4999 satIOContext);
5000 return (status);
5001 }
5002
5003
5004 /*****************************************************************************/
5005 /*! \brief SAT implementation for SCSI TEST UNIT READY.
5006 *
5007 * SAT implementation for SCSI TUR and send FIS request to LL layer.
5008 *
5009 * \param tiRoot: Pointer to TISA initiator driver/port instance.
5010 * \param tiIORequest: Pointer to TISA I/O request context for this I/O.
5011 * \param tiDeviceHandle: Pointer to TISA device handle for this I/O.
5012 * \param tiScsiRequest: Pointer to TISA SCSI I/O request and SGL list.
5013 * \param satIOContext_t: Pointer to the SAT IO Context
5014 *
5015 * \return If command is started successfully
5016 * - \e tiSuccess: I/O request successfully initiated.
5017 * - \e tiBusy: No resources available, try again later.
5018 * - \e tiIONoDevice: Invalid device handle.
5019 * - \e tiError: Other errors.
5020 */
5021 /*****************************************************************************/
satTestUnitReady(tiRoot_t * tiRoot,tiIORequest_t * tiIORequest,tiDeviceHandle_t * tiDeviceHandle,tiScsiInitiatorRequest_t * tiScsiRequest,satIOContext_t * satIOContext)5022 GLOBAL bit32 satTestUnitReady(
5023 tiRoot_t *tiRoot,
5024 tiIORequest_t *tiIORequest,
5025 tiDeviceHandle_t *tiDeviceHandle,
5026 tiScsiInitiatorRequest_t *tiScsiRequest,
5027 satIOContext_t *satIOContext)
5028 {
5029
5030 bit32 status;
5031 bit32 agRequestType;
5032 satDeviceData_t *pSatDevData;
5033 scsiRspSense_t *pSense;
5034 tiIniScsiCmnd_t *scsiCmnd;
5035 agsaFisRegHostToDevice_t *fis;
5036
5037 pSense = satIOContext->pSense;
5038 pSatDevData = satIOContext->pSatDevData;
5039 scsiCmnd = &tiScsiRequest->scsiCmnd;
5040 fis = satIOContext->pFis;
5041
5042 TI_DBG6(("satTestUnitReady: entry tiDeviceHandle=%p tiIORequest=%p\n",
5043 tiDeviceHandle, tiIORequest));
5044
5045 /* checking CONTROL */
5046 /* NACA == 1 or LINK == 1*/
5047 if ( (scsiCmnd->cdb[5] & SCSI_NACA_MASK) || (scsiCmnd->cdb[5] & SCSI_LINK_MASK) )
5048 {
5049 satSetSensePayload( pSense,
5050 SCSI_SNSKEY_ILLEGAL_REQUEST,
5051 0,
5052 SCSI_SNSCODE_INVALID_FIELD_IN_CDB,
5053 satIOContext);
5054
5055 ostiInitiatorIOCompleted( tiRoot,
5056 tiIORequest,
5057 tiIOSuccess,
5058 SCSI_STAT_CHECK_CONDITION,
5059 satIOContext->pTiSenseData,
5060 satIOContext->interruptContext );
5061
5062 TI_DBG1(("satTestUnitReady: return control\n"));
5063 return tiSuccess;
5064 }
5065
5066 /* SAT revision 8, 8.11.2, p42*/
5067 if (pSatDevData->satStopState == agTRUE)
5068 {
5069 satSetSensePayload( pSense,
5070 SCSI_SNSKEY_NOT_READY,
5071 0,
5072 SCSI_SNSCODE_LOGICAL_UNIT_NOT_READY_INITIALIZING_COMMAND_REQUIRED,
5073 satIOContext);
5074
5075 ostiInitiatorIOCompleted( tiRoot,
5076 tiIORequest,
5077 tiIOSuccess,
5078 SCSI_STAT_CHECK_CONDITION,
5079 satIOContext->pTiSenseData,
5080 satIOContext->interruptContext );
5081 TI_DBG1(("satTestUnitReady: stop state\n"));
5082 return tiSuccess;
5083 }
5084
5085 /*
5086 * Check if format is in progress
5087 */
5088
5089 if (pSatDevData->satDriveState == SAT_DEV_STATE_FORMAT_IN_PROGRESS)
5090 {
5091 TI_DBG1(("satTestUnitReady() FORMAT_IN_PROGRESS tiDeviceHandle=%p tiIORequest=%p\n",
5092 tiDeviceHandle, tiIORequest));
5093
5094 satSetSensePayload( pSense,
5095 SCSI_SNSKEY_NOT_READY,
5096 0,
5097 SCSI_SNSCODE_LOGICAL_UNIT_NOT_READY_FORMAT_IN_PROGRESS,
5098 satIOContext);
5099
5100 ostiInitiatorIOCompleted( tiRoot,
5101 tiIORequest,
5102 tiIOSuccess,
5103 SCSI_STAT_CHECK_CONDITION,
5104 satIOContext->pTiSenseData,
5105 satIOContext->interruptContext );
5106 TI_DBG1(("satTestUnitReady: format in progress\n"));
5107 return tiSuccess;
5108 }
5109
5110 /*
5111 check previously issued ATA command
5112 */
5113 if (pSatDevData->satPendingIO != 0)
5114 {
5115 if (pSatDevData->satDeviceFaultState == agTRUE)
5116 {
5117 satSetSensePayload( pSense,
5118 SCSI_SNSKEY_HARDWARE_ERROR,
5119 0,
5120 SCSI_SNSCODE_LOGICAL_UNIT_FAILURE,
5121 satIOContext);
5122
5123 ostiInitiatorIOCompleted( tiRoot,
5124 tiIORequest,
5125 tiIOSuccess,
5126 SCSI_STAT_CHECK_CONDITION,
5127 satIOContext->pTiSenseData,
5128 satIOContext->interruptContext );
5129 TI_DBG1(("satTestUnitReady: previous command ended in error\n"));
5130 return tiSuccess;
5131 }
5132 }
5133 /*
5134 check removalbe media feature set
5135 */
5136 if(pSatDevData->satRemovableMedia && pSatDevData->satRemovableMediaEnabled)
5137 {
5138 TI_DBG5(("satTestUnitReady: sending get media status cmnd\n"));
5139 /* send GET MEDIA STATUS command */
5140 fis->h.fisType = 0x27; /* Reg host to device */
5141 fis->h.c_pmPort = 0x80; /* C Bit is set */
5142 fis->h.command = SAT_GET_MEDIA_STATUS; /* 0xDA */
5143 fis->h.features = 0; /* FIS features NA */
5144 fis->d.lbaLow = 0; /* FIS LBA (7 :0 ) */
5145 fis->d.lbaMid = 0; /* FIS LBA (15:8 ) */
5146 fis->d.lbaHigh = 0; /* FIS LBA (23:16) */
5147 fis->d.device = 0; /* FIS DEV is discared in SATA */
5148 fis->d.lbaLowExp = 0;
5149 fis->d.lbaMidExp = 0;
5150 fis->d.lbaHighExp = 0;
5151 fis->d.featuresExp = 0;
5152 fis->d.sectorCount = 0; /* FIS sector count (7:0) */
5153 fis->d.sectorCountExp = 0;
5154 fis->d.reserved4 = 0;
5155 fis->d.control = 0; /* FIS HOB bit clear */
5156 fis->d.reserved5 = 0;
5157 agRequestType = AGSA_SATA_PROTOCOL_NON_DATA;
5158
5159 /* Initialize CB for SATA completion.
5160 */
5161 satIOContext->satCompleteCB = &satTestUnitReadyCB;
5162
5163 /*
5164 * Prepare SGL and send FIS to LL layer.
5165 */
5166 satIOContext->reqType = agRequestType; /* Save it */
5167
5168 status = sataLLIOStart( tiRoot,
5169 tiIORequest,
5170 tiDeviceHandle,
5171 tiScsiRequest,
5172 satIOContext);
5173
5174 return (status);
5175 }
5176 /*
5177 number 6) in SAT p42
5178 send ATA CHECK POWER MODE
5179 */
5180 TI_DBG5(("satTestUnitReady: sending check power mode cmnd\n"));
5181 status = satTestUnitReady_1( tiRoot,
5182 tiIORequest,
5183 tiDeviceHandle,
5184 tiScsiRequest,
5185 satIOContext);
5186 return (status);
5187 }
5188
5189
5190 /*****************************************************************************/
5191 /*! \brief SAT implementation for SCSI satTestUnitReady_1.
5192 *
5193 * SAT implementation for SCSI satTestUnitReady_1.
5194 *
5195 * \param tiRoot: Pointer to TISA initiator driver/port instance.
5196 * \param tiIORequest: Pointer to TISA I/O request context for this I/O.
5197 * \param tiDeviceHandle: Pointer to TISA device handle for this I/O.
5198 * \param tiScsiRequest: Pointer to TISA SCSI I/O request and SGL list.
5199 * \param satIOContext_t: Pointer to the SAT IO Context
5200 *
5201 * \return If command is started successfully
5202 * - \e tiSuccess: I/O request successfully initiated.
5203 * - \e tiBusy: No resources available, try again later.
5204 * - \e tiIONoDevice: Invalid device handle.
5205 * - \e tiError: Other errors.
5206 */
5207 /*****************************************************************************/
satTestUnitReady_1(tiRoot_t * tiRoot,tiIORequest_t * tiIORequest,tiDeviceHandle_t * tiDeviceHandle,tiScsiInitiatorRequest_t * tiScsiRequest,satIOContext_t * satIOContext)5208 GLOBAL bit32 satTestUnitReady_1(
5209 tiRoot_t *tiRoot,
5210 tiIORequest_t *tiIORequest,
5211 tiDeviceHandle_t *tiDeviceHandle,
5212 tiScsiInitiatorRequest_t *tiScsiRequest,
5213 satIOContext_t *satIOContext)
5214 {
5215 /*
5216 sends SAT_CHECK_POWER_MODE as a part of TESTUNITREADY
5217 internally generated - no directly corresponding scsi
5218 called in satIOCompleted as a part of satTestUnitReady(), SAT, revision8, 8.11.2, p42
5219 */
5220 bit32 status;
5221 bit32 agRequestType;
5222 agsaFisRegHostToDevice_t *fis;
5223
5224 fis = satIOContext->pFis;
5225
5226 TI_DBG5(("satTestUnitReady_1: start\n"));
5227
5228 /*
5229 * Send the ATA CHECK POWER MODE command.
5230 */
5231 fis->h.fisType = 0x27; /* Reg host to device */
5232 fis->h.c_pmPort = 0x80; /* C Bit is set */
5233 fis->h.command = SAT_CHECK_POWER_MODE; /* 0xE5 */
5234 fis->h.features = 0;
5235 fis->d.lbaLow = 0;
5236 fis->d.lbaMid = 0;
5237 fis->d.lbaHigh = 0;
5238 fis->d.device = 0;
5239 fis->d.lbaLowExp = 0;
5240 fis->d.lbaMidExp = 0;
5241 fis->d.lbaHighExp = 0;
5242 fis->d.featuresExp = 0;
5243 fis->d.sectorCount = 0;
5244 fis->d.sectorCountExp = 0;
5245 fis->d.reserved4 = 0;
5246 fis->d.control = 0; /* FIS HOB bit clear */
5247 fis->d.reserved5 = 0;
5248
5249 agRequestType = AGSA_SATA_PROTOCOL_NON_DATA;
5250
5251 /* Initialize CB for SATA completion.
5252 */
5253 satIOContext->satCompleteCB = &satTestUnitReadyCB;
5254
5255 /*
5256 * Prepare SGL and send FIS to LL layer.
5257 */
5258 satIOContext->reqType = agRequestType; /* Save it */
5259
5260 status = sataLLIOStart( tiRoot,
5261 tiIORequest,
5262 tiDeviceHandle,
5263 tiScsiRequest,
5264 satIOContext);
5265
5266 TI_DBG5(("satTestUnitReady_1: return\n"));
5267
5268 return status;
5269 }
5270
5271
5272 /*****************************************************************************/
5273 /*! \brief SAT implementation for SCSI satReportLun.
5274 *
5275 * SAT implementation for SCSI satReportLun. Only LUN0 is reported.
5276 *
5277 * \param tiRoot: Pointer to TISA initiator driver/port instance.
5278 * \param tiIORequest: Pointer to TISA I/O request context for this I/O.
5279 * \param tiDeviceHandle: Pointer to TISA device handle for this I/O.
5280 * \param tiScsiRequest: Pointer to TISA SCSI I/O request and SGL list.
5281 * \param satIOContext_t: Pointer to the SAT IO Context
5282 *
5283 * \return If command is started successfully
5284 * - \e tiSuccess: I/O request successfully initiated.
5285 * - \e tiBusy: No resources available, try again later.
5286 * - \e tiIONoDevice: Invalid device handle.
5287 * - \e tiError: Other errors.
5288 */
5289 /*****************************************************************************/
satReportLun(tiRoot_t * tiRoot,tiIORequest_t * tiIORequest,tiDeviceHandle_t * tiDeviceHandle,tiScsiInitiatorRequest_t * tiScsiRequest,satIOContext_t * satIOContext)5290 GLOBAL bit32 satReportLun(
5291 tiRoot_t *tiRoot,
5292 tiIORequest_t *tiIORequest,
5293 tiDeviceHandle_t *tiDeviceHandle,
5294 tiScsiInitiatorRequest_t *tiScsiRequest,
5295 satIOContext_t *satIOContext)
5296 {
5297 scsiRspSense_t *pSense;
5298 bit32 allocationLen;
5299 bit32 reportLunLen;
5300 scsiReportLun_t *pReportLun;
5301 tiIniScsiCmnd_t *scsiCmnd;
5302
5303 TI_DBG5(("satReportLun entry: tiDeviceHandle=%p tiIORequest=%p\n",
5304 tiDeviceHandle, tiIORequest));
5305
5306 pSense = satIOContext->pSense;
5307 pReportLun = (scsiReportLun_t *) tiScsiRequest->sglVirtualAddr;
5308 scsiCmnd = &tiScsiRequest->scsiCmnd;
5309
5310 // tdhexdump("satReportLun cdb", (bit8 *)scsiCmnd, 16);
5311
5312 /* Find the buffer size allocated by Initiator */
5313 allocationLen = (((bit32)scsiCmnd->cdb[6]) << 24) |
5314 (((bit32)scsiCmnd->cdb[7]) << 16) |
5315 (((bit32)scsiCmnd->cdb[8]) << 8 ) |
5316 (((bit32)scsiCmnd->cdb[9]) );
5317
5318 reportLunLen = 16; /* 8 byte header and 8 bytes of LUN0 */
5319
5320 if (allocationLen < reportLunLen)
5321 {
5322 TI_DBG1(("satReportLun *** ERROR *** insufficient len=0x%x tiDeviceHandle=%p tiIORequest=%p\n",
5323 reportLunLen, tiDeviceHandle, tiIORequest));
5324
5325 satSetSensePayload( pSense,
5326 SCSI_SNSKEY_ILLEGAL_REQUEST,
5327 0,
5328 SCSI_SNSCODE_INVALID_FIELD_IN_CDB,
5329 satIOContext);
5330
5331 ostiInitiatorIOCompleted( tiRoot,
5332 tiIORequest,
5333 tiIOSuccess,
5334 SCSI_STAT_CHECK_CONDITION,
5335 satIOContext->pTiSenseData,
5336 satIOContext->interruptContext );
5337 return tiSuccess;
5338
5339 }
5340
5341 /* Set length to one entry */
5342 pReportLun->len[0] = 0;
5343 pReportLun->len[1] = 0;
5344 pReportLun->len[2] = 0;
5345 pReportLun->len[3] = sizeof (tiLUN_t);
5346
5347 pReportLun->reserved = 0;
5348
5349 /* Set to LUN 0:
5350 * - address method to 0x00: Peripheral device addressing method,
5351 * - bus identifier to 0
5352 */
5353 pReportLun->lunList[0].lun[0] = 0;
5354 pReportLun->lunList[0].lun[1] = 0;
5355 pReportLun->lunList[0].lun[2] = 0;
5356 pReportLun->lunList[0].lun[3] = 0;
5357 pReportLun->lunList[0].lun[4] = 0;
5358 pReportLun->lunList[0].lun[5] = 0;
5359 pReportLun->lunList[0].lun[6] = 0;
5360 pReportLun->lunList[0].lun[7] = 0;
5361
5362 if (allocationLen > reportLunLen)
5363 {
5364 /* underrun */
5365 TI_DBG1(("satReportLun reporting underrun reportLunLen=0x%x allocationLen=0x%x \n", reportLunLen, allocationLen));
5366
5367 ostiInitiatorIOCompleted( tiRoot,
5368 tiIORequest,
5369 tiIOUnderRun,
5370 allocationLen - reportLunLen,
5371 agNULL,
5372 satIOContext->interruptContext );
5373
5374
5375 }
5376 else
5377 {
5378 ostiInitiatorIOCompleted( tiRoot,
5379 tiIORequest,
5380 tiIOSuccess,
5381 SCSI_STAT_GOOD,
5382 agNULL,
5383 satIOContext->interruptContext);
5384 }
5385 return tiSuccess;
5386 }
5387
5388
5389 /*****************************************************************************/
5390 /*! \brief SAT implementation for SCSI REQUEST SENSE.
5391 *
5392 * SAT implementation for SCSI REQUEST SENSE.
5393 *
5394 * \param tiRoot: Pointer to TISA initiator driver/port instance.
5395 * \param tiIORequest: Pointer to TISA I/O request context for this I/O.
5396 * \param tiDeviceHandle: Pointer to TISA device handle for this I/O.
5397 * \param tiScsiRequest: Pointer to TISA SCSI I/O request and SGL list.
5398 * \param satIOContext_t: Pointer to the SAT IO Context
5399 *
5400 * \return If command is started successfully
5401 * - \e tiSuccess: I/O request successfully initiated.
5402 * - \e tiBusy: No resources available, try again later.
5403 * - \e tiIONoDevice: Invalid device handle.
5404 * - \e tiError: Other errors.
5405 */
5406 /*****************************************************************************/
satRequestSense(tiRoot_t * tiRoot,tiIORequest_t * tiIORequest,tiDeviceHandle_t * tiDeviceHandle,tiScsiInitiatorRequest_t * tiScsiRequest,satIOContext_t * satIOContext)5407 GLOBAL bit32 satRequestSense(
5408 tiRoot_t *tiRoot,
5409 tiIORequest_t *tiIORequest,
5410 tiDeviceHandle_t *tiDeviceHandle,
5411 tiScsiInitiatorRequest_t *tiScsiRequest,
5412 satIOContext_t *satIOContext)
5413 {
5414 /*
5415 SAT Rev 8 p38, Table25
5416 sending SMART RETURN STATUS
5417 Checking SMART Treshold Exceeded Condition is done in satRequestSenseCB()
5418 Only fixed format sense data is support. In other words, we don't support DESC bit is set
5419 in Request Sense
5420 */
5421 bit32 status;
5422 bit32 agRequestType;
5423 scsiRspSense_t *pSense;
5424 satDeviceData_t *pSatDevData;
5425 tiIniScsiCmnd_t *scsiCmnd;
5426 agsaFisRegHostToDevice_t *fis;
5427 tdIORequestBody_t *tdIORequestBody;
5428 satInternalIo_t *satIntIo = agNULL;
5429 satIOContext_t *satIOContext2;
5430
5431 TI_DBG4(("satRequestSense entry: tiDeviceHandle=%p tiIORequest=%p\n",
5432 tiDeviceHandle, tiIORequest));
5433
5434 pSense = (scsiRspSense_t *) tiScsiRequest->sglVirtualAddr;
5435 pSatDevData = satIOContext->pSatDevData;
5436 scsiCmnd = &tiScsiRequest->scsiCmnd;
5437 fis = satIOContext->pFis;
5438
5439 TI_DBG4(("satRequestSense: pSatDevData=%p\n", pSatDevData));
5440
5441 /* checking CONTROL */
5442 /* NACA == 1 or LINK == 1*/
5443 if ( (scsiCmnd->cdb[5] & SCSI_NACA_MASK) || (scsiCmnd->cdb[5] & SCSI_LINK_MASK) )
5444 {
5445 satSetSensePayload( pSense,
5446 SCSI_SNSKEY_ILLEGAL_REQUEST,
5447 0,
5448 SCSI_SNSCODE_INVALID_FIELD_IN_CDB,
5449 satIOContext);
5450
5451 ostiInitiatorIOCompleted( tiRoot,
5452 tiIORequest,
5453 tiIOSuccess,
5454 SCSI_STAT_CHECK_CONDITION,
5455 satIOContext->pTiSenseData,
5456 satIOContext->interruptContext );
5457
5458 TI_DBG1(("satRequestSense: return control\n"));
5459 return tiSuccess;
5460 }
5461
5462 /*
5463 Only fixed format sense data is support. In other words, we don't support DESC bit is set
5464 in Request Sense
5465 */
5466 if ( scsiCmnd->cdb[1] & ATA_REMOVABLE_MEDIA_DEVICE_MASK )
5467 {
5468 satSetSensePayload( pSense,
5469 SCSI_SNSKEY_ILLEGAL_REQUEST,
5470 0,
5471 SCSI_SNSCODE_INVALID_FIELD_IN_CDB,
5472 satIOContext);
5473
5474 ostiInitiatorIOCompleted( tiRoot,
5475 tiIORequest,
5476 tiIOSuccess,
5477 SCSI_STAT_CHECK_CONDITION,
5478 satIOContext->pTiSenseData,
5479 satIOContext->interruptContext );
5480
5481 TI_DBG1(("satRequestSense: DESC bit is set, which we don't support\n"));
5482 return tiSuccess;
5483 }
5484
5485
5486 if (pSatDevData->satSMARTEnabled == agTRUE)
5487 {
5488 /* sends SMART RETURN STATUS */
5489 fis->h.fisType = 0x27; /* Reg host to device */
5490 fis->h.c_pmPort = 0x80; /* C Bit is set */
5491
5492 fis->h.command = SAT_SMART_RETURN_STATUS; /* 0xB0 */
5493 fis->h.features = 0xDA; /* FIS features */
5494 fis->d.featuresExp = 0; /* FIS reserve */
5495 fis->d.sectorCount = 0; /* FIS sector count (7:0) */
5496 fis->d.sectorCountExp = 0; /* FIS sector count (15:8) */
5497 fis->d.lbaLow = 0; /* FIS LBA (7 :0 ) */
5498 fis->d.lbaLowExp = 0; /* FIS LBA (31:24) */
5499 fis->d.lbaMid = 0x4F; /* FIS LBA (15:8 ) */
5500 fis->d.lbaMidExp = 0; /* FIS LBA (39:32) */
5501 fis->d.lbaHigh = 0xC2; /* FIS LBA (23:16) */
5502 fis->d.lbaHighExp = 0; /* FIS LBA (47:40) */
5503 fis->d.device = 0; /* FIS DEV is discared in SATA */
5504 fis->d.control = 0; /* FIS HOB bit clear */
5505 fis->d.reserved4 = 0;
5506 fis->d.reserved5 = 0;
5507
5508 agRequestType = AGSA_SATA_PROTOCOL_NON_DATA;
5509 /* Initialize CB for SATA completion.
5510 */
5511 satIOContext->satCompleteCB = &satRequestSenseCB;
5512
5513 /*
5514 * Prepare SGL and send FIS to LL layer.
5515 */
5516 satIOContext->reqType = agRequestType; /* Save it */
5517
5518 status = sataLLIOStart( tiRoot,
5519 tiIORequest,
5520 tiDeviceHandle,
5521 tiScsiRequest,
5522 satIOContext);
5523
5524 TI_DBG4(("satRequestSense: if return, status %d\n", status));
5525 return (status);
5526 }
5527 else
5528 {
5529 /*allocate iocontext for xmitting xmit SAT_CHECK_POWER_MODE
5530 then call satRequestSense2 */
5531
5532 TI_DBG4(("satRequestSense: before satIntIo %p\n", satIntIo));
5533 /* allocate iocontext */
5534 satIntIo = satAllocIntIoResource( tiRoot,
5535 tiIORequest, /* original request */
5536 pSatDevData,
5537 tiScsiRequest->scsiCmnd.expDataLength,
5538 satIntIo);
5539
5540 TI_DBG4(("satRequestSense: after satIntIo %p\n", satIntIo));
5541
5542 if (satIntIo == agNULL)
5543 {
5544 /* memory allocation failure */
5545 satFreeIntIoResource( tiRoot,
5546 pSatDevData,
5547 satIntIo);
5548
5549 /* failed during sending SMART RETURN STATUS */
5550 satSetSensePayload( pSense,
5551 SCSI_SNSKEY_NO_SENSE,
5552 0,
5553 SCSI_SNSCODE_HARDWARE_IMPENDING_FAILURE,
5554 satIOContext);
5555
5556 ostiInitiatorIOCompleted( tiRoot,
5557 tiIORequest,
5558 tiIOSuccess,
5559 SCSI_STAT_GOOD,
5560 agNULL,
5561 satIOContext->interruptContext );
5562
5563 TI_DBG4(("satRequestSense: else fail 1\n"));
5564 return tiSuccess;
5565 } /* end of memory allocation failure */
5566
5567
5568 /*
5569 * Need to initialize all the fields within satIOContext except
5570 * reqType and satCompleteCB which will be set depending on cmd.
5571 */
5572
5573 if (satIntIo == agNULL)
5574 {
5575 TI_DBG4(("satRequestSense: satIntIo is NULL\n"));
5576 }
5577 else
5578 {
5579 TI_DBG4(("satRequestSense: satIntIo is NOT NULL\n"));
5580 }
5581 /* use this --- tttttthe one the same */
5582
5583
5584 satIntIo->satOrgTiIORequest = tiIORequest;
5585 tdIORequestBody = (tdIORequestBody_t *)satIntIo->satIntRequestBody;
5586 satIOContext2 = &(tdIORequestBody->transport.SATA.satIOContext);
5587
5588 satIOContext2->pSatDevData = pSatDevData;
5589 satIOContext2->pFis = &(tdIORequestBody->transport.SATA.agSATARequestBody.fis.fisRegHostToDev);
5590 satIOContext2->pScsiCmnd = &(satIntIo->satIntTiScsiXchg.scsiCmnd);
5591 satIOContext2->pSense = &(tdIORequestBody->transport.SATA.sensePayload);
5592 satIOContext2->pTiSenseData = &(tdIORequestBody->transport.SATA.tiSenseData);
5593 satIOContext2->pTiSenseData->senseData = satIOContext2->pSense;
5594 satIOContext2->tiRequestBody = satIntIo->satIntRequestBody;
5595 satIOContext2->interruptContext = satIOContext->interruptContext;
5596 satIOContext2->satIntIoContext = satIntIo;
5597 satIOContext2->ptiDeviceHandle = tiDeviceHandle;
5598 satIOContext2->satOrgIOContext = satIOContext;
5599
5600 TI_DBG4(("satRequestSense: satIntIo->satIntTiScsiXchg.agSgl1.len %d\n", satIntIo->satIntTiScsiXchg.agSgl1.len));
5601
5602 TI_DBG4(("satRequestSense: satIntIo->satIntTiScsiXchg.agSgl1.upper %d\n", satIntIo->satIntTiScsiXchg.agSgl1.upper));
5603
5604 TI_DBG4(("satRequestSense: satIntIo->satIntTiScsiXchg.agSgl1.lower %d\n", satIntIo->satIntTiScsiXchg.agSgl1.lower));
5605
5606 TI_DBG4(("satRequestSense: satIntIo->satIntTiScsiXchg.agSgl1.type %d\n", satIntIo->satIntTiScsiXchg.agSgl1.type));
5607
5608 status = satRequestSense_1( tiRoot,
5609 &(satIntIo->satIntTiIORequest),
5610 tiDeviceHandle,
5611 &(satIntIo->satIntTiScsiXchg),
5612 satIOContext2);
5613
5614 if (status != tiSuccess)
5615 {
5616 satFreeIntIoResource( tiRoot,
5617 pSatDevData,
5618 satIntIo);
5619
5620 /* failed during sending SMART RETURN STATUS */
5621 satSetSensePayload( pSense,
5622 SCSI_SNSKEY_NO_SENSE,
5623 0,
5624 SCSI_SNSCODE_HARDWARE_IMPENDING_FAILURE,
5625 satIOContext);
5626
5627 ostiInitiatorIOCompleted( tiRoot,
5628 tiIORequest,
5629 tiIOSuccess,
5630 SCSI_STAT_CHECK_CONDITION,
5631 agNULL,
5632 satIOContext->interruptContext );
5633
5634 TI_DBG1(("satRequestSense: else fail 2\n"));
5635 return tiSuccess;
5636 }
5637 TI_DBG4(("satRequestSense: else return success\n"));
5638 return tiSuccess;
5639 }
5640 }
5641
5642
5643 /*****************************************************************************/
5644 /*! \brief SAT implementation for SCSI REQUEST SENSE.
5645 *
5646 * SAT implementation for SCSI REQUEST SENSE.
5647 * Sub function of satRequestSense
5648 *
5649 * \param tiRoot: Pointer to TISA initiator driver/port instance.
5650 * \param tiIORequest: Pointer to TISA I/O request context for this I/O.
5651 * \param tiDeviceHandle: Pointer to TISA device handle for this I/O.
5652 * \param tiScsiRequest: Pointer to TISA SCSI I/O request and SGL list.
5653 * \param satIOContext_t: Pointer to the SAT IO Context
5654 *
5655 * \return If command is started successfully
5656 * - \e tiSuccess: I/O request successfully initiated.
5657 * - \e tiBusy: No resources available, try again later.
5658 * - \e tiIONoDevice: Invalid device handle.
5659 * - \e tiError: Other errors.
5660 */
5661 /*****************************************************************************/
satRequestSense_1(tiRoot_t * tiRoot,tiIORequest_t * tiIORequest,tiDeviceHandle_t * tiDeviceHandle,tiScsiInitiatorRequest_t * tiScsiRequest,satIOContext_t * satIOContext)5662 GLOBAL bit32 satRequestSense_1(
5663 tiRoot_t *tiRoot,
5664 tiIORequest_t *tiIORequest,
5665 tiDeviceHandle_t *tiDeviceHandle,
5666 tiScsiInitiatorRequest_t *tiScsiRequest,
5667 satIOContext_t *satIOContext)
5668 {
5669 /*
5670 sends SAT_CHECK_POWER_MODE
5671 */
5672 bit32 status;
5673 bit32 agRequestType;
5674 agsaFisRegHostToDevice_t *fis;
5675
5676 TI_DBG4(("satRequestSense_1 entry: tiDeviceHandle=%p tiIORequest=%p\n",
5677 tiDeviceHandle, tiIORequest));
5678
5679 fis = satIOContext->pFis;
5680 /*
5681 * Send the ATA CHECK POWER MODE command.
5682 */
5683 fis->h.fisType = 0x27; /* Reg host to device */
5684 fis->h.c_pmPort = 0x80; /* C Bit is set */
5685
5686 fis->h.command = SAT_CHECK_POWER_MODE; /* 0xE5 */
5687 fis->h.features = 0;
5688 fis->d.lbaLow = 0;
5689 fis->d.lbaMid = 0;
5690 fis->d.lbaHigh = 0;
5691 fis->d.device = 0;
5692 fis->d.lbaLowExp = 0;
5693 fis->d.lbaMidExp = 0;
5694 fis->d.lbaHighExp = 0;
5695 fis->d.featuresExp = 0;
5696 fis->d.sectorCount = 0;
5697 fis->d.sectorCountExp = 0;
5698 fis->d.reserved4 = 0;
5699 fis->d.control = 0; /* FIS HOB bit clear */
5700 fis->d.reserved5 = 0;
5701
5702 agRequestType = AGSA_SATA_PROTOCOL_NON_DATA;
5703
5704 /* Initialize CB for SATA completion.
5705 */
5706 satIOContext->satCompleteCB = &satRequestSenseCB;
5707
5708 /*
5709 * Prepare SGL and send FIS to LL layer.
5710 */
5711 satIOContext->reqType = agRequestType; /* Save it */
5712
5713
5714 TI_DBG4(("satRequestSense_1: agSgl1.len %d\n", tiScsiRequest->agSgl1.len));
5715
5716 TI_DBG4(("satRequestSense_1: agSgl1.upper %d\n", tiScsiRequest->agSgl1.upper));
5717
5718 TI_DBG4(("satRequestSense_1: agSgl1.lower %d\n", tiScsiRequest->agSgl1.lower));
5719
5720 TI_DBG4(("satRequestSense_1: agSgl1.type %d\n", tiScsiRequest->agSgl1.type));
5721
5722 // tdhexdump("satRequestSense_1", (bit8 *)fis, sizeof(agsaFisRegHostToDevice_t));
5723
5724 status = sataLLIOStart( tiRoot,
5725 tiIORequest,
5726 tiDeviceHandle,
5727 tiScsiRequest,
5728 satIOContext);
5729
5730
5731
5732 return status;
5733 }
5734
5735
5736 /*****************************************************************************/
5737 /*! \brief SAT implementation for SCSI INQUIRY.
5738 *
5739 * SAT implementation for SCSI INQUIRY.
5740 *
5741 * \param tiRoot: Pointer to TISA initiator driver/port instance.
5742 * \param tiIORequest: Pointer to TISA I/O request context for this I/O.
5743 * \param tiDeviceHandle: Pointer to TISA device handle for this I/O.
5744 * \param tiScsiRequest: Pointer to TISA SCSI I/O request and SGL list.
5745 * \param satIOContext_t: Pointer to the SAT IO Context
5746 *
5747 * \return If command is started successfully
5748 * - \e tiSuccess: I/O request successfully initiated.
5749 * - \e tiBusy: No resources available, try again later.
5750 * - \e tiIONoDevice: Invalid device handle.
5751 * - \e tiError: Other errors.
5752 */
5753 /*****************************************************************************/
satInquiry(tiRoot_t * tiRoot,tiIORequest_t * tiIORequest,tiDeviceHandle_t * tiDeviceHandle,tiScsiInitiatorRequest_t * tiScsiRequest,satIOContext_t * satIOContext)5754 GLOBAL bit32 satInquiry(
5755 tiRoot_t *tiRoot,
5756 tiIORequest_t *tiIORequest,
5757 tiDeviceHandle_t *tiDeviceHandle,
5758 tiScsiInitiatorRequest_t *tiScsiRequest,
5759 satIOContext_t *satIOContext)
5760 {
5761 /*
5762 CMDDT bit is obsolete in SPC-3 and this is assumed in SAT revision 8
5763 */
5764 scsiRspSense_t *pSense;
5765 tiIniScsiCmnd_t *scsiCmnd;
5766 satDeviceData_t *pSatDevData;
5767 bit32 status;
5768
5769 TI_DBG5(("satInquiry: start\n"));
5770 TI_DBG5(("satInquiry entry: tiDeviceHandle=%p tiIORequest=%p\n",
5771 tiDeviceHandle, tiIORequest));
5772 pSense = satIOContext->pSense;
5773 scsiCmnd = &tiScsiRequest->scsiCmnd;
5774 pSatDevData = satIOContext->pSatDevData;
5775 TI_DBG5(("satInquiry: pSatDevData=%p\n", pSatDevData));
5776 //tdhexdump("satInquiry", (bit8 *)scsiCmnd->cdb, 6);
5777 /* checking CONTROL */
5778 /* NACA == 1 or LINK == 1*/
5779 if ( (scsiCmnd->cdb[5] & SCSI_NACA_MASK) || (scsiCmnd->cdb[5] & SCSI_LINK_MASK) )
5780 {
5781 satSetSensePayload( pSense,
5782 SCSI_SNSKEY_ILLEGAL_REQUEST,
5783 0,
5784 SCSI_SNSCODE_INVALID_FIELD_IN_CDB,
5785 satIOContext);
5786 ostiInitiatorIOCompleted( tiRoot,
5787 tiIORequest,
5788 tiIOSuccess,
5789 SCSI_STAT_CHECK_CONDITION,
5790 satIOContext->pTiSenseData,
5791 satIOContext->interruptContext );
5792 TI_DBG2(("satInquiry: return control\n"));
5793 return tiSuccess;
5794 }
5795
5796 /* checking EVPD and Allocation Length */
5797 /* SPC-4 spec 6.4 p141 */
5798 /* EVPD bit == 0 && PAGE CODE != 0 */
5799 if ( !(scsiCmnd->cdb[1] & SCSI_EVPD_MASK) &&
5800 (scsiCmnd->cdb[2] != 0)
5801 )
5802 {
5803 satSetSensePayload( pSense,
5804 SCSI_SNSKEY_ILLEGAL_REQUEST,
5805 0,
5806 SCSI_SNSCODE_INVALID_FIELD_IN_CDB,
5807 satIOContext);
5808 ostiInitiatorIOCompleted( tiRoot,
5809 tiIORequest,
5810 tiIOSuccess,
5811 SCSI_STAT_CHECK_CONDITION,
5812 satIOContext->pTiSenseData,
5813 satIOContext->interruptContext );
5814 TI_DBG1(("satInquiry: return EVPD and PAGE CODE\n"));
5815 return tiSuccess;
5816 }
5817 TI_DBG6(("satInquiry: allocation length 0x%x %d\n", ((scsiCmnd->cdb[3]) << 8) + scsiCmnd->cdb[4], ((scsiCmnd->cdb[3]) << 8) + scsiCmnd->cdb[4]));
5818
5819 /* convert OS IO to TD internal IO */
5820 if ( pSatDevData->IDDeviceValid == agFALSE)
5821 {
5822 status = satStartIDDev(
5823 tiRoot,
5824 tiIORequest,
5825 tiDeviceHandle,
5826 tiScsiRequest,
5827 satIOContext
5828 );
5829 TI_DBG6(("satInquiry: end status %d\n", status));
5830 return status;
5831 }
5832 else
5833 {
5834 TI_DBG6(("satInquiry: calling satInquiryIntCB\n"));
5835 satInquiryIntCB(
5836 tiRoot,
5837 tiIORequest,
5838 tiDeviceHandle,
5839 tiScsiRequest,
5840 satIOContext
5841 );
5842
5843 return tiSuccess;
5844 }
5845
5846 }
5847
5848
5849 /*****************************************************************************/
5850 /*! \brief SAT implementation for SCSI satReadCapacity10.
5851 *
5852 * SAT implementation for SCSI satReadCapacity10.
5853 *
5854 * \param tiRoot: Pointer to TISA initiator driver/port instance.
5855 * \param tiIORequest: Pointer to TISA I/O request context for this I/O.
5856 * \param tiDeviceHandle: Pointer to TISA device handle for this I/O.
5857 * \param tiScsiRequest: Pointer to TISA SCSI I/O request and SGL list.
5858 * \param satIOContext_t: Pointer to the SAT IO Context
5859 *
5860 * \return If command is started successfully
5861 * - \e tiSuccess: I/O request successfully initiated.
5862 * - \e tiBusy: No resources available, try again later.
5863 * - \e tiIONoDevice: Invalid device handle.
5864 * - \e tiError: Other errors.
5865 */
5866 /*****************************************************************************/
satReadCapacity10(tiRoot_t * tiRoot,tiIORequest_t * tiIORequest,tiDeviceHandle_t * tiDeviceHandle,tiScsiInitiatorRequest_t * tiScsiRequest,satIOContext_t * satIOContext)5867 GLOBAL bit32 satReadCapacity10(
5868 tiRoot_t *tiRoot,
5869 tiIORequest_t *tiIORequest,
5870 tiDeviceHandle_t *tiDeviceHandle,
5871 tiScsiInitiatorRequest_t *tiScsiRequest,
5872 satIOContext_t *satIOContext)
5873 {
5874 scsiRspSense_t *pSense;
5875 tiIniScsiCmnd_t *scsiCmnd;
5876 bit8 *pVirtAddr;
5877 satDeviceData_t *pSatDevData;
5878 agsaSATAIdentifyData_t *pSATAIdData;
5879 bit32 lastLba;
5880 bit32 word117_118;
5881 bit32 word117;
5882 bit32 word118;
5883 TI_DBG5(("satReadCapacity10: start: tiDeviceHandle=%p tiIORequest=%p\n",
5884 tiDeviceHandle, tiIORequest));
5885
5886 pSense = satIOContext->pSense;
5887 pVirtAddr = (bit8 *) tiScsiRequest->sglVirtualAddr;
5888 scsiCmnd = &tiScsiRequest->scsiCmnd;
5889 pSatDevData = satIOContext->pSatDevData;
5890 pSATAIdData = &pSatDevData->satIdentifyData;
5891
5892
5893 /* checking CONTROL */
5894 /* NACA == 1 or LINK == 1*/
5895 if ( (scsiCmnd->cdb[9] & SCSI_NACA_MASK) || (scsiCmnd->cdb[9] & SCSI_LINK_MASK) )
5896 {
5897 satSetSensePayload( pSense,
5898 SCSI_SNSKEY_ILLEGAL_REQUEST,
5899 0,
5900 SCSI_SNSCODE_INVALID_FIELD_IN_CDB,
5901 satIOContext);
5902
5903 ostiInitiatorIOCompleted( tiRoot,
5904 tiIORequest,
5905 tiIOSuccess,
5906 SCSI_STAT_CHECK_CONDITION,
5907 satIOContext->pTiSenseData,
5908 satIOContext->interruptContext );
5909
5910 TI_DBG1(("satReadCapacity10: return control\n"));
5911 return tiSuccess;
5912 }
5913
5914
5915 /*
5916 * If Logical block address is not set to zero, return error
5917 */
5918 if ((scsiCmnd->cdb[2] || scsiCmnd->cdb[3] || scsiCmnd->cdb[4] || scsiCmnd->cdb[5]))
5919 {
5920 TI_DBG1(("satReadCapacity10 *** ERROR *** logical address non zero, tiDeviceHandle=%p tiIORequest=%p\n",
5921 tiDeviceHandle, tiIORequest));
5922
5923 satSetSensePayload( pSense,
5924 SCSI_SNSKEY_ILLEGAL_REQUEST,
5925 0,
5926 SCSI_SNSCODE_INVALID_FIELD_IN_CDB,
5927 satIOContext);
5928
5929 ostiInitiatorIOCompleted( tiRoot,
5930 tiIORequest,
5931 tiIOSuccess,
5932 SCSI_STAT_CHECK_CONDITION,
5933 satIOContext->pTiSenseData,
5934 satIOContext->interruptContext );
5935 return tiSuccess;
5936
5937 }
5938
5939 /*
5940 * If PMI bit is not zero, return error
5941 */
5942 if ( ((scsiCmnd->cdb[8]) & SCSI_READ_CAPACITY10_PMI_MASK) != 0 )
5943 {
5944 TI_DBG1(("satReadCapacity10 *** ERROR *** PMI is not zero, tiDeviceHandle=%p tiIORequest=%p\n",
5945 tiDeviceHandle, tiIORequest));
5946
5947 satSetSensePayload( pSense,
5948 SCSI_SNSKEY_ILLEGAL_REQUEST,
5949 0,
5950 SCSI_SNSCODE_INVALID_FIELD_IN_CDB,
5951 satIOContext);
5952
5953 ostiInitiatorIOCompleted( tiRoot,
5954 tiIORequest,
5955 tiIOSuccess,
5956 SCSI_STAT_CHECK_CONDITION,
5957 satIOContext->pTiSenseData,
5958 satIOContext->interruptContext );
5959 return tiSuccess;
5960
5961 }
5962
5963 /*
5964 filling in Read Capacity parameter data
5965 saved identify device has been already flipped
5966 See ATA spec p125 and p136 and SBC spec p54
5967 */
5968 /*
5969 * If 48-bit addressing is supported, set capacity information from Identify
5970 * Device Word 100-103.
5971 */
5972 if (pSatDevData->sat48BitSupport == agTRUE)
5973 {
5974 /*
5975 * Setting RETURNED LOGICAL BLOCK ADDRESS in READ CAPACITY(10) response data:
5976 * SBC-2 specifies that if the capacity exceeded the 4-byte RETURNED LOGICAL
5977 * BLOCK ADDRESS in READ CAPACITY(10) parameter data, the RETURNED LOGICAL
5978 * BLOCK ADDRESS should be set to 0xFFFFFFFF so the application client would
5979 * then issue a READ CAPACITY(16) command.
5980 */
5981 /* ATA Identify Device information word 100 - 103 */
5982 if ( (pSATAIdData->maxLBA32_47 != 0 ) || (pSATAIdData->maxLBA48_63 != 0))
5983 {
5984 pVirtAddr[0] = 0xFF; /* MSB number of block */
5985 pVirtAddr[1] = 0xFF;
5986 pVirtAddr[2] = 0xFF;
5987 pVirtAddr[3] = 0xFF; /* LSB number of block */
5988 TI_DBG1(("satReadCapacity10: returns 0xFFFFFFFF\n"));
5989 }
5990 else /* Fit the Readcapacity10 4-bytes response length */
5991 {
5992 lastLba = (((pSATAIdData->maxLBA16_31) << 16) ) |
5993 (pSATAIdData->maxLBA0_15);
5994 lastLba = lastLba - 1; /* LBA starts from zero */
5995
5996 /*
5997 for testing
5998 lastLba = lastLba - (512*10) - 1;
5999 */
6000
6001
6002 pVirtAddr[0] = (bit8)((lastLba >> 24) & 0xFF); /* MSB */
6003 pVirtAddr[1] = (bit8)((lastLba >> 16) & 0xFF);
6004 pVirtAddr[2] = (bit8)((lastLba >> 8) & 0xFF);
6005 pVirtAddr[3] = (bit8)((lastLba ) & 0xFF); /* LSB */
6006
6007 TI_DBG3(("satReadCapacity10: lastLba is 0x%x %d\n", lastLba, lastLba));
6008 TI_DBG3(("satReadCapacity10: LBA 0 is 0x%x %d\n", pVirtAddr[0], pVirtAddr[0]));
6009 TI_DBG3(("satReadCapacity10: LBA 1 is 0x%x %d\n", pVirtAddr[1], pVirtAddr[1]));
6010 TI_DBG3(("satReadCapacity10: LBA 2 is 0x%x %d\n", pVirtAddr[2], pVirtAddr[2]));
6011 TI_DBG3(("satReadCapacity10: LBA 3 is 0x%x %d\n", pVirtAddr[3], pVirtAddr[3]));
6012
6013 }
6014 }
6015
6016 /*
6017 * For 28-bit addressing, set capacity information from Identify
6018 * Device Word 60-61.
6019 */
6020 else
6021 {
6022 /* ATA Identify Device information word 60 - 61 */
6023 lastLba = (((pSATAIdData->numOfUserAddressableSectorsHi) << 16) ) |
6024 (pSATAIdData->numOfUserAddressableSectorsLo);
6025 lastLba = lastLba - 1; /* LBA starts from zero */
6026
6027 pVirtAddr[0] = (bit8)((lastLba >> 24) & 0xFF); /* MSB */
6028 pVirtAddr[1] = (bit8)((lastLba >> 16) & 0xFF);
6029 pVirtAddr[2] = (bit8)((lastLba >> 8) & 0xFF);
6030 pVirtAddr[3] = (bit8)((lastLba ) & 0xFF); /* LSB */
6031 }
6032 /* SAT Rev 8d */
6033 if (((pSATAIdData->word104_107[2]) & 0x1000) == 0)
6034 {
6035 TI_DBG5(("satReadCapacity10: Default Block Length is 512\n"));
6036 /*
6037 * Set the block size, fixed at 512 bytes.
6038 */
6039 pVirtAddr[4] = 0x00; /* MSB block size in bytes */
6040 pVirtAddr[5] = 0x00;
6041 pVirtAddr[6] = 0x02;
6042 pVirtAddr[7] = 0x00; /* LSB block size in bytes */
6043 }
6044 else
6045 {
6046 word118 = pSATAIdData->word112_126[6];
6047 word117 = pSATAIdData->word112_126[5];
6048
6049 word117_118 = (word118 << 16) + word117;
6050 word117_118 = word117_118 * 2;
6051 pVirtAddr[4] = (bit8)((word117_118 >> 24) & 0xFF); /* MSB block size in bytes */
6052 pVirtAddr[5] = (bit8)((word117_118 >> 16) & 0xFF);
6053 pVirtAddr[6] = (bit8)((word117_118 >> 8) & 0xFF);
6054 pVirtAddr[7] = (bit8)(word117_118 & 0xFF); /* LSB block size in bytes */
6055
6056 TI_DBG1(("satReadCapacity10: Nondefault word118 %d 0x%x \n", word118, word118));
6057 TI_DBG1(("satReadCapacity10: Nondefault word117 %d 0x%x \n", word117, word117));
6058 TI_DBG1(("satReadCapacity10: Nondefault Block Length is %d 0x%x \n",word117_118, word117_118));
6059
6060 }
6061
6062 /* fill in MAX LBA, which is used in satSendDiagnostic_1() */
6063 pSatDevData->satMaxLBA[0] = 0; /* MSB */
6064 pSatDevData->satMaxLBA[1] = 0;
6065 pSatDevData->satMaxLBA[2] = 0;
6066 pSatDevData->satMaxLBA[3] = 0;
6067 pSatDevData->satMaxLBA[4] = pVirtAddr[0];
6068 pSatDevData->satMaxLBA[5] = pVirtAddr[1];
6069 pSatDevData->satMaxLBA[6] = pVirtAddr[2];
6070 pSatDevData->satMaxLBA[7] = pVirtAddr[3]; /* LSB */
6071
6072
6073 TI_DBG4(("satReadCapacity10 0x%x 0x%x 0x%x 0x%x 0x%x 0x%x 0x%x 0x%x , tiDeviceHandle=%p tiIORequest=%p\n",
6074 pVirtAddr[0], pVirtAddr[1], pVirtAddr[2], pVirtAddr[3],
6075 pVirtAddr[4], pVirtAddr[5], pVirtAddr[6], pVirtAddr[7],
6076 tiDeviceHandle, tiIORequest));
6077
6078
6079 /*
6080 * Send the completion response now.
6081 */
6082 ostiInitiatorIOCompleted( tiRoot,
6083 tiIORequest,
6084 tiIOSuccess,
6085 SCSI_STAT_GOOD,
6086 agNULL,
6087 satIOContext->interruptContext);
6088 return tiSuccess;
6089 }
6090
6091
6092 /*****************************************************************************/
6093 /*! \brief SAT implementation for SCSI satReadCapacity16.
6094 *
6095 * SAT implementation for SCSI satReadCapacity16.
6096 *
6097 * \param tiRoot: Pointer to TISA initiator driver/port instance.
6098 * \param tiIORequest: Pointer to TISA I/O request context for this I/O.
6099 * \param tiDeviceHandle: Pointer to TISA device handle for this I/O.
6100 * \param tiScsiRequest: Pointer to TISA SCSI I/O request and SGL list.
6101 * \param satIOContext_t: Pointer to the SAT IO Context
6102 *
6103 * \return If command is started successfully
6104 * - \e tiSuccess: I/O request successfully initiated.
6105 * - \e tiBusy: No resources available, try again later.
6106 * - \e tiIONoDevice: Invalid device handle.
6107 * - \e tiError: Other errors.
6108 */
6109 /*****************************************************************************/
satReadCapacity16(tiRoot_t * tiRoot,tiIORequest_t * tiIORequest,tiDeviceHandle_t * tiDeviceHandle,tiScsiInitiatorRequest_t * tiScsiRequest,satIOContext_t * satIOContext)6110 GLOBAL bit32 satReadCapacity16(
6111 tiRoot_t *tiRoot,
6112 tiIORequest_t *tiIORequest,
6113 tiDeviceHandle_t *tiDeviceHandle,
6114 tiScsiInitiatorRequest_t *tiScsiRequest,
6115 satIOContext_t *satIOContext)
6116 {
6117
6118 scsiRspSense_t *pSense;
6119 tiIniScsiCmnd_t *scsiCmnd;
6120 bit8 *pVirtAddr;
6121 satDeviceData_t *pSatDevData;
6122 agsaSATAIdentifyData_t *pSATAIdData;
6123 bit32 lastLbaLo;
6124 bit32 allocationLen;
6125 bit32 readCapacityLen = 32;
6126 bit32 i = 0;
6127 TI_DBG5(("satReadCapacity16 start: tiDeviceHandle=%p tiIORequest=%p\n",
6128 tiDeviceHandle, tiIORequest));
6129
6130 pSense = satIOContext->pSense;
6131 pVirtAddr = (bit8 *) tiScsiRequest->sglVirtualAddr;
6132 scsiCmnd = &tiScsiRequest->scsiCmnd;
6133 pSatDevData = satIOContext->pSatDevData;
6134 pSATAIdData = &pSatDevData->satIdentifyData;
6135
6136 /* Find the buffer size allocated by Initiator */
6137 allocationLen = (((bit32)scsiCmnd->cdb[10]) << 24) |
6138 (((bit32)scsiCmnd->cdb[11]) << 16) |
6139 (((bit32)scsiCmnd->cdb[12]) << 8 ) |
6140 (((bit32)scsiCmnd->cdb[13]) );
6141
6142
6143 if (allocationLen < readCapacityLen)
6144 {
6145 TI_DBG1(("satReadCapacity16 *** ERROR *** insufficient len=0x%x readCapacityLen=0x%x\n", allocationLen, readCapacityLen));
6146
6147 satSetSensePayload( pSense,
6148 SCSI_SNSKEY_ILLEGAL_REQUEST,
6149 0,
6150 SCSI_SNSCODE_INVALID_FIELD_IN_CDB,
6151 satIOContext);
6152
6153 ostiInitiatorIOCompleted( tiRoot,
6154 tiIORequest,
6155 tiIOSuccess,
6156 SCSI_STAT_CHECK_CONDITION,
6157 satIOContext->pTiSenseData,
6158 satIOContext->interruptContext );
6159 return tiSuccess;
6160
6161 }
6162
6163 /* checking CONTROL */
6164 /* NACA == 1 or LINK == 1*/
6165 if ( (scsiCmnd->cdb[15] & SCSI_NACA_MASK) || (scsiCmnd->cdb[15] & SCSI_LINK_MASK) )
6166 {
6167 satSetSensePayload( pSense,
6168 SCSI_SNSKEY_ILLEGAL_REQUEST,
6169 0,
6170 SCSI_SNSCODE_INVALID_FIELD_IN_CDB,
6171 satIOContext);
6172
6173 ostiInitiatorIOCompleted( tiRoot,
6174 tiIORequest,
6175 tiIOSuccess,
6176 SCSI_STAT_CHECK_CONDITION,
6177 satIOContext->pTiSenseData,
6178 satIOContext->interruptContext );
6179
6180 TI_DBG1(("satReadCapacity16: return control\n"));
6181 return tiSuccess;
6182 }
6183
6184 /*
6185 * If Logical blcok address is not set to zero, return error
6186 */
6187 if ((scsiCmnd->cdb[2] || scsiCmnd->cdb[3] || scsiCmnd->cdb[4] || scsiCmnd->cdb[5]) ||
6188 (scsiCmnd->cdb[6] || scsiCmnd->cdb[7] || scsiCmnd->cdb[8] || scsiCmnd->cdb[9]) )
6189 {
6190 TI_DBG1(("satReadCapacity16 *** ERROR *** logical address non zero, tiDeviceHandle=%p tiIORequest=%p\n",
6191 tiDeviceHandle, tiIORequest));
6192
6193 satSetSensePayload( pSense,
6194 SCSI_SNSKEY_ILLEGAL_REQUEST,
6195 0,
6196 SCSI_SNSCODE_INVALID_FIELD_IN_CDB,
6197 satIOContext);
6198
6199 ostiInitiatorIOCompleted( tiRoot,
6200 tiIORequest,
6201 tiIOSuccess,
6202 SCSI_STAT_CHECK_CONDITION,
6203 satIOContext->pTiSenseData,
6204 satIOContext->interruptContext );
6205 return tiSuccess;
6206
6207 }
6208
6209 /*
6210 * If PMI bit is not zero, return error
6211 */
6212 if ( ((scsiCmnd->cdb[14]) & SCSI_READ_CAPACITY16_PMI_MASK) != 0 )
6213 {
6214 TI_DBG1(("satReadCapacity16 *** ERROR *** PMI is not zero, tiDeviceHandle=%p tiIORequest=%p\n",
6215 tiDeviceHandle, tiIORequest));
6216
6217 satSetSensePayload( pSense,
6218 SCSI_SNSKEY_ILLEGAL_REQUEST,
6219 0,
6220 SCSI_SNSCODE_INVALID_FIELD_IN_CDB,
6221 satIOContext);
6222
6223 ostiInitiatorIOCompleted( tiRoot,
6224 tiIORequest,
6225 tiIOSuccess,
6226 SCSI_STAT_CHECK_CONDITION,
6227 satIOContext->pTiSenseData,
6228 satIOContext->interruptContext );
6229 return tiSuccess;
6230
6231 }
6232
6233 /*
6234 filling in Read Capacity parameter data
6235 */
6236
6237 /*
6238 * If 48-bit addressing is supported, set capacity information from Identify
6239 * Device Word 100-103.
6240 */
6241 if (pSatDevData->sat48BitSupport == agTRUE)
6242 {
6243 pVirtAddr[0] = (bit8)(((pSATAIdData->maxLBA48_63) >> 8) & 0xff); /* MSB */
6244 pVirtAddr[1] = (bit8)((pSATAIdData->maxLBA48_63) & 0xff);
6245 pVirtAddr[2] = (bit8)(((pSATAIdData->maxLBA32_47) >> 8) & 0xff);
6246 pVirtAddr[3] = (bit8)((pSATAIdData->maxLBA32_47) & 0xff);
6247
6248 lastLbaLo = (((pSATAIdData->maxLBA16_31) << 16) ) | (pSATAIdData->maxLBA0_15);
6249 lastLbaLo = lastLbaLo - 1; /* LBA starts from zero */
6250
6251 pVirtAddr[4] = (bit8)((lastLbaLo >> 24) & 0xFF);
6252 pVirtAddr[5] = (bit8)((lastLbaLo >> 16) & 0xFF);
6253 pVirtAddr[6] = (bit8)((lastLbaLo >> 8) & 0xFF);
6254 pVirtAddr[7] = (bit8)((lastLbaLo ) & 0xFF); /* LSB */
6255
6256 }
6257
6258 /*
6259 * For 28-bit addressing, set capacity information from Identify
6260 * Device Word 60-61.
6261 */
6262 else
6263 {
6264 pVirtAddr[0] = 0; /* MSB */
6265 pVirtAddr[1] = 0;
6266 pVirtAddr[2] = 0;
6267 pVirtAddr[3] = 0;
6268
6269 lastLbaLo = (((pSATAIdData->numOfUserAddressableSectorsHi) << 16) ) |
6270 (pSATAIdData->numOfUserAddressableSectorsLo);
6271 lastLbaLo = lastLbaLo - 1; /* LBA starts from zero */
6272
6273 pVirtAddr[4] = (bit8)((lastLbaLo >> 24) & 0xFF);
6274 pVirtAddr[5] = (bit8)((lastLbaLo >> 16) & 0xFF);
6275 pVirtAddr[6] = (bit8)((lastLbaLo >> 8) & 0xFF);
6276 pVirtAddr[7] = (bit8)((lastLbaLo ) & 0xFF); /* LSB */
6277
6278 }
6279
6280 /*
6281 * Set the block size, fixed at 512 bytes.
6282 */
6283 pVirtAddr[8] = 0x00; /* MSB block size in bytes */
6284 pVirtAddr[9] = 0x00;
6285 pVirtAddr[10] = 0x02;
6286 pVirtAddr[11] = 0x00; /* LSB block size in bytes */
6287
6288
6289 /* fill in MAX LBA, which is used in satSendDiagnostic_1() */
6290 pSatDevData->satMaxLBA[0] = pVirtAddr[0]; /* MSB */
6291 pSatDevData->satMaxLBA[1] = pVirtAddr[1];
6292 pSatDevData->satMaxLBA[2] = pVirtAddr[2];
6293 pSatDevData->satMaxLBA[3] = pVirtAddr[3];
6294 pSatDevData->satMaxLBA[4] = pVirtAddr[4];
6295 pSatDevData->satMaxLBA[5] = pVirtAddr[5];
6296 pSatDevData->satMaxLBA[6] = pVirtAddr[6];
6297 pSatDevData->satMaxLBA[7] = pVirtAddr[7]; /* LSB */
6298
6299 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",
6300 pVirtAddr[0], pVirtAddr[1], pVirtAddr[2], pVirtAddr[3],
6301 pVirtAddr[4], pVirtAddr[5], pVirtAddr[6], pVirtAddr[7],
6302 pVirtAddr[8], pVirtAddr[9], pVirtAddr[10], pVirtAddr[11],
6303 tiDeviceHandle, tiIORequest));
6304
6305 for(i=12;i<=31;i++)
6306 {
6307 pVirtAddr[i] = 0x00;
6308 }
6309
6310 /*
6311 * Send the completion response now.
6312 */
6313 if (allocationLen > readCapacityLen)
6314 {
6315 /* underrun */
6316 TI_DBG1(("satReadCapacity16 reporting underrun readCapacityLen=0x%x allocationLen=0x%x \n", readCapacityLen, allocationLen));
6317
6318 ostiInitiatorIOCompleted( tiRoot,
6319 tiIORequest,
6320 tiIOUnderRun,
6321 allocationLen - readCapacityLen,
6322 agNULL,
6323 satIOContext->interruptContext );
6324
6325
6326 }
6327 else
6328 {
6329 ostiInitiatorIOCompleted( tiRoot,
6330 tiIORequest,
6331 tiIOSuccess,
6332 SCSI_STAT_GOOD,
6333 agNULL,
6334 satIOContext->interruptContext);
6335 }
6336 return tiSuccess;
6337
6338 }
6339
6340
6341 /*****************************************************************************/
6342 /*! \brief SAT implementation for SCSI MODE SENSE (6).
6343 *
6344 * SAT implementation for SCSI MODE SENSE (6).
6345 *
6346 * \param tiRoot: Pointer to TISA initiator driver/port instance.
6347 * \param tiIORequest: Pointer to TISA I/O request context for this I/O.
6348 * \param tiDeviceHandle: Pointer to TISA device handle for this I/O.
6349 * \param tiScsiRequest: Pointer to TISA SCSI I/O request and SGL list.
6350 * \param satIOContext_t: Pointer to the SAT IO Context
6351 *
6352 * \return If command is started successfully
6353 * - \e tiSuccess: I/O request successfully initiated.
6354 * - \e tiBusy: No resources available, try again later.
6355 * - \e tiIONoDevice: Invalid device handle.
6356 * - \e tiError: Other errors.
6357 */
6358 /*****************************************************************************/
satModeSense6(tiRoot_t * tiRoot,tiIORequest_t * tiIORequest,tiDeviceHandle_t * tiDeviceHandle,tiScsiInitiatorRequest_t * tiScsiRequest,satIOContext_t * satIOContext)6359 GLOBAL bit32 satModeSense6(
6360 tiRoot_t *tiRoot,
6361 tiIORequest_t *tiIORequest,
6362 tiDeviceHandle_t *tiDeviceHandle,
6363 tiScsiInitiatorRequest_t *tiScsiRequest,
6364 satIOContext_t *satIOContext)
6365 {
6366
6367 scsiRspSense_t *pSense;
6368 bit32 requestLen;
6369 tiIniScsiCmnd_t *scsiCmnd;
6370 bit32 pageSupported;
6371 bit8 page;
6372 bit8 *pModeSense; /* Mode Sense data buffer */
6373 satDeviceData_t *pSatDevData;
6374 bit8 PC;
6375 bit8 AllPages[MODE_SENSE6_RETURN_ALL_PAGES_LEN];
6376 bit8 Control[MODE_SENSE6_CONTROL_PAGE_LEN];
6377 bit8 RWErrorRecovery[MODE_SENSE6_READ_WRITE_ERROR_RECOVERY_PAGE_LEN];
6378 bit8 Caching[MODE_SENSE6_CACHING_LEN];
6379 bit8 InfoExceptionCtrl[MODE_SENSE6_INFORMATION_EXCEPTION_CONTROL_PAGE_LEN];
6380 bit8 lenRead = 0;
6381
6382
6383 TI_DBG5(("satModeSense6 entry: tiDeviceHandle=%p tiIORequest=%p\n",
6384 tiDeviceHandle, tiIORequest));
6385
6386 pSense = satIOContext->pSense;
6387 scsiCmnd = &tiScsiRequest->scsiCmnd;
6388 pModeSense = (bit8 *) tiScsiRequest->sglVirtualAddr;
6389 pSatDevData = satIOContext->pSatDevData;
6390
6391 //tdhexdump("satModeSense6", (bit8 *)scsiCmnd->cdb, 6);
6392 /* checking CONTROL */
6393 /* NACA == 1 or LINK == 1*/
6394 if ( (scsiCmnd->cdb[5] & SCSI_NACA_MASK) || (scsiCmnd->cdb[5] & SCSI_LINK_MASK) )
6395 {
6396 satSetSensePayload( pSense,
6397 SCSI_SNSKEY_ILLEGAL_REQUEST,
6398 0,
6399 SCSI_SNSCODE_INVALID_FIELD_IN_CDB,
6400 satIOContext);
6401
6402 ostiInitiatorIOCompleted( tiRoot,
6403 tiIORequest,
6404 tiIOSuccess,
6405 SCSI_STAT_CHECK_CONDITION,
6406 satIOContext->pTiSenseData,
6407 satIOContext->interruptContext );
6408
6409 TI_DBG2(("satModeSense6: return control\n"));
6410 return tiSuccess;
6411 }
6412
6413 /* checking PC(Page Control)
6414 SAT revion 8, 8.5.3 p33 and 10.1.2, p66
6415 */
6416 PC = (bit8)((scsiCmnd->cdb[2]) & SCSI_MODE_SENSE6_PC_MASK);
6417 if (PC != 0)
6418 {
6419 satSetSensePayload( pSense,
6420 SCSI_SNSKEY_ILLEGAL_REQUEST,
6421 0,
6422 SCSI_SNSCODE_INVALID_FIELD_IN_CDB,
6423 satIOContext);
6424
6425 ostiInitiatorIOCompleted( tiRoot,
6426 tiIORequest,
6427 tiIOSuccess,
6428 SCSI_STAT_CHECK_CONDITION,
6429 satIOContext->pTiSenseData,
6430 satIOContext->interruptContext );
6431
6432 TI_DBG1(("satModeSense6: return due to PC value pc 0x%x\n", PC >> 6));
6433 return tiSuccess;
6434 }
6435
6436 /* reading PAGE CODE */
6437 page = (bit8)((scsiCmnd->cdb[2]) & SCSI_MODE_SENSE6_PAGE_CODE_MASK);
6438
6439
6440 TI_DBG5(("satModeSense6: page=0x%x, tiDeviceHandle=%p tiIORequest=%p\n",
6441 page, tiDeviceHandle, tiIORequest));
6442
6443 requestLen = scsiCmnd->cdb[4];
6444
6445 /*
6446 Based on page code value, returns a corresponding mode page
6447 note: no support for subpage
6448 */
6449
6450 switch(page)
6451 {
6452 case MODESENSE_RETURN_ALL_PAGES:
6453 case MODESENSE_CONTROL_PAGE: /* control */
6454 case MODESENSE_READ_WRITE_ERROR_RECOVERY_PAGE: /* Read-Write Error Recovery */
6455 case MODESENSE_CACHING: /* caching */
6456 case MODESENSE_INFORMATION_EXCEPTION_CONTROL_PAGE: /* informational exceptions control*/
6457 pageSupported = agTRUE;
6458 break;
6459 case MODESENSE_VENDOR_SPECIFIC_PAGE: /* vendor specific */
6460 default:
6461 pageSupported = agFALSE;
6462 break;
6463 }
6464
6465 if (pageSupported == agFALSE)
6466 {
6467
6468 TI_DBG1(("satModeSense6 *** ERROR *** not supported page 0x%x tiDeviceHandle=%p tiIORequest=%p\n",
6469 page, tiDeviceHandle, tiIORequest));
6470
6471 satSetSensePayload( pSense,
6472 SCSI_SNSKEY_ILLEGAL_REQUEST,
6473 0,
6474 SCSI_SNSCODE_INVALID_COMMAND,
6475 satIOContext);
6476
6477 ostiInitiatorIOCompleted( tiRoot,
6478 tiIORequest,
6479 tiIOSuccess,
6480 SCSI_STAT_CHECK_CONDITION,
6481 satIOContext->pTiSenseData,
6482 satIOContext->interruptContext );
6483 return tiSuccess;
6484 }
6485
6486 switch(page)
6487 {
6488 case MODESENSE_RETURN_ALL_PAGES:
6489 lenRead = (bit8)MIN(requestLen, MODE_SENSE6_RETURN_ALL_PAGES_LEN);
6490 break;
6491 case MODESENSE_CONTROL_PAGE: /* control */
6492 lenRead = (bit8)MIN(requestLen, MODE_SENSE6_CONTROL_PAGE_LEN);
6493 break;
6494 case MODESENSE_READ_WRITE_ERROR_RECOVERY_PAGE: /* Read-Write Error Recovery */
6495 lenRead = (bit8)MIN(requestLen, MODE_SENSE6_READ_WRITE_ERROR_RECOVERY_PAGE_LEN);
6496 break;
6497 case MODESENSE_CACHING: /* caching */
6498 lenRead = (bit8)MIN(requestLen, MODE_SENSE6_CACHING_LEN);
6499 break;
6500 case MODESENSE_INFORMATION_EXCEPTION_CONTROL_PAGE: /* informational exceptions control*/
6501 lenRead = (bit8)MIN(requestLen, MODE_SENSE6_INFORMATION_EXCEPTION_CONTROL_PAGE_LEN);
6502 break;
6503 default:
6504 TI_DBG1(("satModeSense6: default error page %d\n", page));
6505 break;
6506 }
6507
6508 if (page == MODESENSE_RETURN_ALL_PAGES)
6509 {
6510 TI_DBG5(("satModeSense6: MODESENSE_RETURN_ALL_PAGES\n"));
6511 AllPages[0] = (bit8)(lenRead - 1);
6512 AllPages[1] = 0x00; /* default medium type (currently mounted medium type) */
6513 AllPages[2] = 0x00; /* no write-protect, no support for DPO-FUA */
6514 AllPages[3] = 0x08; /* block descriptor length */
6515
6516 /*
6517 * Fill-up direct-access device block-descriptor, SAT, Table 19
6518 */
6519
6520 /* density code */
6521 AllPages[4] = 0x04; /* density-code : reserved for direct-access */
6522 /* number of blocks */
6523 AllPages[5] = 0x00; /* unspecified */
6524 AllPages[6] = 0x00; /* unspecified */
6525 AllPages[7] = 0x00; /* unspecified */
6526 /* reserved */
6527 AllPages[8] = 0x00; /* reserved */
6528 /* Block size */
6529 AllPages[9] = 0x00;
6530 AllPages[10] = 0x02; /* Block size is always 512 bytes */
6531 AllPages[11] = 0x00;
6532
6533 /* MODESENSE_READ_WRITE_ERROR_RECOVERY_PAGE */
6534 AllPages[12] = 0x01; /* page code */
6535 AllPages[13] = 0x0A; /* page length */
6536 AllPages[14] = 0x40; /* ARRE is set */
6537 AllPages[15] = 0x00;
6538 AllPages[16] = 0x00;
6539 AllPages[17] = 0x00;
6540 AllPages[18] = 0x00;
6541 AllPages[19] = 0x00;
6542 AllPages[20] = 0x00;
6543 AllPages[21] = 0x00;
6544 AllPages[22] = 0x00;
6545 AllPages[23] = 0x00;
6546 /* MODESENSE_CACHING */
6547 AllPages[24] = 0x08; /* page code */
6548 AllPages[25] = 0x12; /* page length */
6549 #ifdef NOT_YET
6550 if (pSatDevData->satWriteCacheEnabled == agTRUE)
6551 {
6552 AllPages[26] = 0x04;/* WCE bit is set */
6553 }
6554 else
6555 {
6556 AllPages[26] = 0x00;/* WCE bit is NOT set */
6557 }
6558 #endif
6559 AllPages[26] = 0x00;/* WCE bit is NOT set */
6560
6561 AllPages[27] = 0x00;
6562 AllPages[28] = 0x00;
6563 AllPages[29] = 0x00;
6564 AllPages[30] = 0x00;
6565 AllPages[31] = 0x00;
6566 AllPages[32] = 0x00;
6567 AllPages[33] = 0x00;
6568 AllPages[34] = 0x00;
6569 AllPages[35] = 0x00;
6570 if (pSatDevData->satLookAheadEnabled == agTRUE)
6571 {
6572 AllPages[36] = 0x00;/* DRA bit is NOT set */
6573 }
6574 else
6575 {
6576 AllPages[36] = 0x20;/* DRA bit is set */
6577 }
6578 AllPages[37] = 0x00;
6579 AllPages[38] = 0x00;
6580 AllPages[39] = 0x00;
6581 AllPages[40] = 0x00;
6582 AllPages[41] = 0x00;
6583 AllPages[42] = 0x00;
6584 AllPages[43] = 0x00;
6585 /* MODESENSE_CONTROL_PAGE */
6586 AllPages[44] = 0x0A; /* page code */
6587 AllPages[45] = 0x0A; /* page length */
6588 AllPages[46] = 0x02; /* only GLTSD bit is set */
6589 if (pSatDevData->satNCQ == agTRUE)
6590 {
6591 AllPages[47] = 0x12; /* Queue Alogorithm modifier 1b and QErr 01b*/
6592 }
6593 else
6594 {
6595 AllPages[47] = 0x02; /* Queue Alogorithm modifier 0b and QErr 01b */
6596 }
6597 AllPages[48] = 0x00;
6598 AllPages[49] = 0x00;
6599 AllPages[50] = 0x00; /* obsolete */
6600 AllPages[51] = 0x00; /* obsolete */
6601 AllPages[52] = 0xFF; /* Busy Timeout Period */
6602 AllPages[53] = 0xFF; /* Busy Timeout Period */
6603 AllPages[54] = 0x00; /* we don't support non-000b value for the self-test code */
6604 AllPages[55] = 0x00; /* we don't support non-000b value for the self-test code */
6605 /* MODESENSE_INFORMATION_EXCEPTION_CONTROL_PAGE */
6606 AllPages[56] = 0x1C; /* page code */
6607 AllPages[57] = 0x0A; /* page length */
6608 if (pSatDevData->satSMARTEnabled == agTRUE)
6609 {
6610 AllPages[58] = 0x00;/* DEXCPT bit is NOT set */
6611 }
6612 else
6613 {
6614 AllPages[58] = 0x08;/* DEXCPT bit is set */
6615 }
6616 AllPages[59] = 0x00; /* We don't support MRIE */
6617 AllPages[60] = 0x00; /* Interval timer vendor-specific */
6618 AllPages[61] = 0x00;
6619 AllPages[62] = 0x00;
6620 AllPages[63] = 0x00;
6621 AllPages[64] = 0x00; /* REPORT-COUNT */
6622 AllPages[65] = 0x00;
6623 AllPages[66] = 0x00;
6624 AllPages[67] = 0x00;
6625
6626 osti_memcpy(pModeSense, &AllPages, lenRead);
6627 }
6628 else if (page == MODESENSE_CONTROL_PAGE)
6629 {
6630 TI_DBG5(("satModeSense6: MODESENSE_CONTROL_PAGE\n"));
6631 Control[0] = MODE_SENSE6_CONTROL_PAGE_LEN - 1;
6632 Control[1] = 0x00; /* default medium type (currently mounted medium type) */
6633 Control[2] = 0x00; /* no write-protect, no support for DPO-FUA */
6634 Control[3] = 0x08; /* block descriptor length */
6635 /*
6636 * Fill-up direct-access device block-descriptor, SAT, Table 19
6637 */
6638
6639 /* density code */
6640 Control[4] = 0x04; /* density-code : reserved for direct-access */
6641 /* number of blocks */
6642 Control[5] = 0x00; /* unspecified */
6643 Control[6] = 0x00; /* unspecified */
6644 Control[7] = 0x00; /* unspecified */
6645 /* reserved */
6646 Control[8] = 0x00; /* reserved */
6647 /* Block size */
6648 Control[9] = 0x00;
6649 Control[10] = 0x02; /* Block size is always 512 bytes */
6650 Control[11] = 0x00;
6651 /*
6652 * Fill-up control mode page, SAT, Table 65
6653 */
6654 Control[12] = 0x0A; /* page code */
6655 Control[13] = 0x0A; /* page length */
6656 Control[14] = 0x02; /* only GLTSD bit is set */
6657 if (pSatDevData->satNCQ == agTRUE)
6658 {
6659 Control[15] = 0x12; /* Queue Alogorithm modifier 1b and QErr 01b*/
6660 }
6661 else
6662 {
6663 Control[15] = 0x02; /* Queue Alogorithm modifier 0b and QErr 01b */
6664 }
6665 Control[16] = 0x00;
6666 Control[17] = 0x00;
6667 Control[18] = 0x00; /* obsolete */
6668 Control[19] = 0x00; /* obsolete */
6669 Control[20] = 0xFF; /* Busy Timeout Period */
6670 Control[21] = 0xFF; /* Busy Timeout Period */
6671 Control[22] = 0x00; /* we don't support non-000b value for the self-test code */
6672 Control[23] = 0x00; /* we don't support non-000b value for the self-test code */
6673
6674 osti_memcpy(pModeSense, &Control, lenRead);
6675
6676 }
6677 else if (page == MODESENSE_READ_WRITE_ERROR_RECOVERY_PAGE)
6678 {
6679 TI_DBG5(("satModeSense6: MODESENSE_READ_WRITE_ERROR_RECOVERY_PAGE\n"));
6680 RWErrorRecovery[0] = MODE_SENSE6_READ_WRITE_ERROR_RECOVERY_PAGE_LEN - 1;
6681 RWErrorRecovery[1] = 0x00; /* default medium type (currently mounted medium type) */
6682 RWErrorRecovery[2] = 0x00; /* no write-protect, no support for DPO-FUA */
6683 RWErrorRecovery[3] = 0x08; /* block descriptor length */
6684 /*
6685 * Fill-up direct-access device block-descriptor, SAT, Table 19
6686 */
6687
6688 /* density code */
6689 RWErrorRecovery[4] = 0x04; /* density-code : reserved for direct-access */
6690 /* number of blocks */
6691 RWErrorRecovery[5] = 0x00; /* unspecified */
6692 RWErrorRecovery[6] = 0x00; /* unspecified */
6693 RWErrorRecovery[7] = 0x00; /* unspecified */
6694 /* reserved */
6695 RWErrorRecovery[8] = 0x00; /* reserved */
6696 /* Block size */
6697 RWErrorRecovery[9] = 0x00;
6698 RWErrorRecovery[10] = 0x02; /* Block size is always 512 bytes */
6699 RWErrorRecovery[11] = 0x00;
6700 /*
6701 * Fill-up Read-Write Error Recovery mode page, SAT, Table 66
6702 */
6703 RWErrorRecovery[12] = 0x01; /* page code */
6704 RWErrorRecovery[13] = 0x0A; /* page length */
6705 RWErrorRecovery[14] = 0x40; /* ARRE is set */
6706 RWErrorRecovery[15] = 0x00;
6707 RWErrorRecovery[16] = 0x00;
6708 RWErrorRecovery[17] = 0x00;
6709 RWErrorRecovery[18] = 0x00;
6710 RWErrorRecovery[19] = 0x00;
6711 RWErrorRecovery[20] = 0x00;
6712 RWErrorRecovery[21] = 0x00;
6713 RWErrorRecovery[22] = 0x00;
6714 RWErrorRecovery[23] = 0x00;
6715
6716 osti_memcpy(pModeSense, &RWErrorRecovery, lenRead);
6717
6718 }
6719 else if (page == MODESENSE_CACHING)
6720 {
6721 TI_DBG5(("satModeSense6: MODESENSE_CACHING\n"));
6722 /* special case */
6723 if (requestLen == 4 && page == MODESENSE_CACHING)
6724 {
6725 TI_DBG5(("satModeSense6: linux 2.6.8.24 support\n"));
6726
6727 pModeSense[0] = 0x20 - 1; /* 32 - 1 */
6728 pModeSense[1] = 0x00; /* default medium type (currently mounted medium type) */
6729 pModeSense[2] = 0x00; /* no write-protect, no support for DPO-FUA */
6730 pModeSense[3] = 0x08; /* block descriptor length */
6731 ostiInitiatorIOCompleted( tiRoot,
6732 tiIORequest,
6733 tiIOSuccess,
6734 SCSI_STAT_GOOD,
6735 agNULL,
6736 satIOContext->interruptContext);
6737 return tiSuccess;
6738 }
6739 Caching[0] = MODE_SENSE6_CACHING_LEN - 1;
6740 Caching[1] = 0x00; /* default medium type (currently mounted medium type) */
6741 Caching[2] = 0x00; /* no write-protect, no support for DPO-FUA */
6742 Caching[3] = 0x08; /* block descriptor length */
6743 /*
6744 * Fill-up direct-access device block-descriptor, SAT, Table 19
6745 */
6746
6747 /* density code */
6748 Caching[4] = 0x04; /* density-code : reserved for direct-access */
6749 /* number of blocks */
6750 Caching[5] = 0x00; /* unspecified */
6751 Caching[6] = 0x00; /* unspecified */
6752 Caching[7] = 0x00; /* unspecified */
6753 /* reserved */
6754 Caching[8] = 0x00; /* reserved */
6755 /* Block size */
6756 Caching[9] = 0x00;
6757 Caching[10] = 0x02; /* Block size is always 512 bytes */
6758 Caching[11] = 0x00;
6759 /*
6760 * Fill-up Caching mode page, SAT, Table 67
6761 */
6762 /* length 20 */
6763 Caching[12] = 0x08; /* page code */
6764 Caching[13] = 0x12; /* page length */
6765 #ifdef NOT_YET
6766 if (pSatDevData->satWriteCacheEnabled == agTRUE)
6767 {
6768 Caching[14] = 0x04;/* WCE bit is set */
6769 }
6770 else
6771 {
6772 Caching[14] = 0x00;/* WCE bit is NOT set */
6773 }
6774 #endif
6775 Caching[14] = 0x00;/* WCE bit is NOT set */
6776
6777 Caching[15] = 0x00;
6778 Caching[16] = 0x00;
6779 Caching[17] = 0x00;
6780 Caching[18] = 0x00;
6781 Caching[19] = 0x00;
6782 Caching[20] = 0x00;
6783 Caching[21] = 0x00;
6784 Caching[22] = 0x00;
6785 Caching[23] = 0x00;
6786 if (pSatDevData->satLookAheadEnabled == agTRUE)
6787 {
6788 Caching[24] = 0x00;/* DRA bit is NOT set */
6789 }
6790 else
6791 {
6792 Caching[24] = 0x20;/* DRA bit is set */
6793 }
6794 Caching[25] = 0x00;
6795 Caching[26] = 0x00;
6796 Caching[27] = 0x00;
6797 Caching[28] = 0x00;
6798 Caching[29] = 0x00;
6799 Caching[30] = 0x00;
6800 Caching[31] = 0x00;
6801
6802 osti_memcpy(pModeSense, &Caching, lenRead);
6803
6804 }
6805 else if (page == MODESENSE_INFORMATION_EXCEPTION_CONTROL_PAGE)
6806 {
6807 TI_DBG5(("satModeSense6: MODESENSE_INFORMATION_EXCEPTION_CONTROL_PAGE\n"));
6808 InfoExceptionCtrl[0] = MODE_SENSE6_INFORMATION_EXCEPTION_CONTROL_PAGE_LEN - 1;
6809 InfoExceptionCtrl[1] = 0x00; /* default medium type (currently mounted medium type) */
6810 InfoExceptionCtrl[2] = 0x00; /* no write-protect, no support for DPO-FUA */
6811 InfoExceptionCtrl[3] = 0x08; /* block descriptor length */
6812 /*
6813 * Fill-up direct-access device block-descriptor, SAT, Table 19
6814 */
6815
6816 /* density code */
6817 InfoExceptionCtrl[4] = 0x04; /* density-code : reserved for direct-access */
6818 /* number of blocks */
6819 InfoExceptionCtrl[5] = 0x00; /* unspecified */
6820 InfoExceptionCtrl[6] = 0x00; /* unspecified */
6821 InfoExceptionCtrl[7] = 0x00; /* unspecified */
6822 /* reserved */
6823 InfoExceptionCtrl[8] = 0x00; /* reserved */
6824 /* Block size */
6825 InfoExceptionCtrl[9] = 0x00;
6826 InfoExceptionCtrl[10] = 0x02; /* Block size is always 512 bytes */
6827 InfoExceptionCtrl[11] = 0x00;
6828 /*
6829 * Fill-up informational-exceptions control mode page, SAT, Table 68
6830 */
6831 InfoExceptionCtrl[12] = 0x1C; /* page code */
6832 InfoExceptionCtrl[13] = 0x0A; /* page length */
6833 if (pSatDevData->satSMARTEnabled == agTRUE)
6834 {
6835 InfoExceptionCtrl[14] = 0x00;/* DEXCPT bit is NOT set */
6836 }
6837 else
6838 {
6839 InfoExceptionCtrl[14] = 0x08;/* DEXCPT bit is set */
6840 }
6841 InfoExceptionCtrl[15] = 0x00; /* We don't support MRIE */
6842 InfoExceptionCtrl[16] = 0x00; /* Interval timer vendor-specific */
6843 InfoExceptionCtrl[17] = 0x00;
6844 InfoExceptionCtrl[18] = 0x00;
6845 InfoExceptionCtrl[19] = 0x00;
6846 InfoExceptionCtrl[20] = 0x00; /* REPORT-COUNT */
6847 InfoExceptionCtrl[21] = 0x00;
6848 InfoExceptionCtrl[22] = 0x00;
6849 InfoExceptionCtrl[23] = 0x00;
6850 osti_memcpy(pModeSense, &InfoExceptionCtrl, lenRead);
6851
6852 }
6853 else
6854 {
6855 /* Error */
6856 TI_DBG1(("satModeSense6: Error page %d\n", page));
6857 satSetSensePayload( pSense,
6858 SCSI_SNSKEY_ILLEGAL_REQUEST,
6859 0,
6860 SCSI_SNSCODE_INVALID_COMMAND,
6861 satIOContext);
6862
6863 ostiInitiatorIOCompleted( tiRoot,
6864 tiIORequest,
6865 tiIOSuccess,
6866 SCSI_STAT_CHECK_CONDITION,
6867 satIOContext->pTiSenseData,
6868 satIOContext->interruptContext );
6869 return tiSuccess;
6870 }
6871
6872 /* there can be only underrun not overrun in error case */
6873 if (requestLen > lenRead)
6874 {
6875 TI_DBG6(("satModeSense6 reporting underrun lenRead=0x%x requestLen=0x%x tiIORequest=%p\n", lenRead, requestLen, tiIORequest));
6876
6877 ostiInitiatorIOCompleted( tiRoot,
6878 tiIORequest,
6879 tiIOUnderRun,
6880 requestLen - lenRead,
6881 agNULL,
6882 satIOContext->interruptContext );
6883
6884
6885 }
6886 else
6887 {
6888 ostiInitiatorIOCompleted( tiRoot,
6889 tiIORequest,
6890 tiIOSuccess,
6891 SCSI_STAT_GOOD,
6892 agNULL,
6893 satIOContext->interruptContext);
6894 }
6895
6896 return tiSuccess;
6897
6898 }
6899
6900 /*****************************************************************************/
6901 /*! \brief SAT implementation for SCSI MODE SENSE (10).
6902 *
6903 * SAT implementation for SCSI MODE SENSE (10).
6904 *
6905 * \param tiRoot: Pointer to TISA initiator driver/port instance.
6906 * \param tiIORequest: Pointer to TISA I/O request context for this I/O.
6907 * \param tiDeviceHandle: Pointer to TISA device handle for this I/O.
6908 * \param tiScsiRequest: Pointer to TISA SCSI I/O request and SGL list.
6909 * \param satIOContext_t: Pointer to the SAT IO Context
6910 *
6911 * \return If command is started successfully
6912 * - \e tiSuccess: I/O request successfully initiated.
6913 * - \e tiBusy: No resources available, try again later.
6914 * - \e tiIONoDevice: Invalid device handle.
6915 * - \e tiError: Other errors.
6916 */
6917 /*****************************************************************************/
satModeSense10(tiRoot_t * tiRoot,tiIORequest_t * tiIORequest,tiDeviceHandle_t * tiDeviceHandle,tiScsiInitiatorRequest_t * tiScsiRequest,satIOContext_t * satIOContext)6918 GLOBAL bit32 satModeSense10(
6919 tiRoot_t *tiRoot,
6920 tiIORequest_t *tiIORequest,
6921 tiDeviceHandle_t *tiDeviceHandle,
6922 tiScsiInitiatorRequest_t *tiScsiRequest,
6923 satIOContext_t *satIOContext)
6924 {
6925
6926 scsiRspSense_t *pSense;
6927 bit32 requestLen;
6928 tiIniScsiCmnd_t *scsiCmnd;
6929 bit32 pageSupported;
6930 bit8 page;
6931 bit8 *pModeSense; /* Mode Sense data buffer */
6932 satDeviceData_t *pSatDevData;
6933 bit8 PC; /* page control */
6934 bit8 LLBAA; /* Long LBA Accepted */
6935 bit32 index;
6936 bit8 AllPages[MODE_SENSE10_RETURN_ALL_PAGES_LLBAA_LEN];
6937 bit8 Control[MODE_SENSE10_CONTROL_PAGE_LLBAA_LEN];
6938 bit8 RWErrorRecovery[MODE_SENSE10_READ_WRITE_ERROR_RECOVERY_PAGE_LLBAA_LEN];
6939 bit8 Caching[MODE_SENSE10_CACHING_LLBAA_LEN];
6940 bit8 InfoExceptionCtrl[MODE_SENSE10_INFORMATION_EXCEPTION_CONTROL_PAGE_LLBAA_LEN];
6941 bit8 lenRead = 0;
6942
6943 TI_DBG5(("satModeSense10 entry: tiDeviceHandle=%p tiIORequest=%p\n",
6944 tiDeviceHandle, tiIORequest));
6945
6946 pSense = satIOContext->pSense;
6947 scsiCmnd = &tiScsiRequest->scsiCmnd;
6948 pModeSense = (bit8 *) tiScsiRequest->sglVirtualAddr;
6949 pSatDevData = satIOContext->pSatDevData;
6950
6951 /* checking CONTROL */
6952 /* NACA == 1 or LINK == 1*/
6953 if ( (scsiCmnd->cdb[9] & SCSI_NACA_MASK) || (scsiCmnd->cdb[9] & SCSI_LINK_MASK) )
6954 {
6955 satSetSensePayload( pSense,
6956 SCSI_SNSKEY_ILLEGAL_REQUEST,
6957 0,
6958 SCSI_SNSCODE_INVALID_FIELD_IN_CDB,
6959 satIOContext);
6960
6961 ostiInitiatorIOCompleted( tiRoot,
6962 tiIORequest,
6963 tiIOSuccess,
6964 SCSI_STAT_CHECK_CONDITION,
6965 satIOContext->pTiSenseData,
6966 satIOContext->interruptContext );
6967
6968 TI_DBG2(("satModeSense10: return control\n"));
6969 return tiSuccess;
6970 }
6971
6972 /* checking PC(Page Control)
6973 SAT revion 8, 8.5.3 p33 and 10.1.2, p66
6974 */
6975 PC = (bit8)((scsiCmnd->cdb[2]) & SCSI_MODE_SENSE10_PC_MASK);
6976 if (PC != 0)
6977 {
6978 satSetSensePayload( pSense,
6979 SCSI_SNSKEY_ILLEGAL_REQUEST,
6980 0,
6981 SCSI_SNSCODE_INVALID_FIELD_IN_CDB,
6982 satIOContext);
6983
6984 ostiInitiatorIOCompleted( tiRoot,
6985 tiIORequest,
6986 tiIOSuccess,
6987 SCSI_STAT_CHECK_CONDITION,
6988 satIOContext->pTiSenseData,
6989 satIOContext->interruptContext );
6990
6991 TI_DBG1(("satModeSense10: return due to PC value pc 0x%x\n", PC));
6992 return tiSuccess;
6993 }
6994 /* finding LLBAA bit */
6995 LLBAA = (bit8)((scsiCmnd->cdb[1]) & SCSI_MODE_SENSE10_LLBAA_MASK);
6996 /* reading PAGE CODE */
6997 page = (bit8)((scsiCmnd->cdb[2]) & SCSI_MODE_SENSE10_PAGE_CODE_MASK);
6998
6999 TI_DBG5(("satModeSense10: page=0x%x, tiDeviceHandle=%p tiIORequest=%p\n",
7000 page, tiDeviceHandle, tiIORequest));
7001 requestLen = (scsiCmnd->cdb[7] << 8) + scsiCmnd->cdb[8];
7002
7003 /*
7004 Based on page code value, returns a corresponding mode page
7005 note: no support for subpage
7006 */
7007 switch(page)
7008 {
7009 case MODESENSE_RETURN_ALL_PAGES: /* return all pages */
7010 case MODESENSE_CONTROL_PAGE: /* control */
7011 case MODESENSE_READ_WRITE_ERROR_RECOVERY_PAGE: /* Read-Write Error Recovery */
7012 case MODESENSE_CACHING: /* caching */
7013 case MODESENSE_INFORMATION_EXCEPTION_CONTROL_PAGE: /* informational exceptions control*/
7014 pageSupported = agTRUE;
7015 break;
7016 case MODESENSE_VENDOR_SPECIFIC_PAGE: /* vendor specific */
7017 default:
7018 pageSupported = agFALSE;
7019 break;
7020 }
7021
7022 if (pageSupported == agFALSE)
7023 {
7024
7025 TI_DBG1(("satModeSense10 *** ERROR *** not supported page 0x%x tiDeviceHandle=%p tiIORequest=%p\n",
7026 page, tiDeviceHandle, tiIORequest));
7027
7028 satSetSensePayload( pSense,
7029 SCSI_SNSKEY_ILLEGAL_REQUEST,
7030 0,
7031 SCSI_SNSCODE_INVALID_COMMAND,
7032 satIOContext);
7033
7034 ostiInitiatorIOCompleted( tiRoot,
7035 tiIORequest,
7036 tiIOSuccess,
7037 SCSI_STAT_CHECK_CONDITION,
7038 satIOContext->pTiSenseData,
7039 satIOContext->interruptContext );
7040 return tiSuccess;
7041 }
7042
7043 switch(page)
7044 {
7045 case MODESENSE_RETURN_ALL_PAGES:
7046 if (LLBAA)
7047 {
7048 lenRead = (bit8)MIN(requestLen, MODE_SENSE10_RETURN_ALL_PAGES_LLBAA_LEN);
7049 }
7050 else
7051 {
7052 lenRead = (bit8)MIN(requestLen, MODE_SENSE10_RETURN_ALL_PAGES_LEN);
7053 }
7054 break;
7055 case MODESENSE_CONTROL_PAGE: /* control */
7056 if (LLBAA)
7057 {
7058 lenRead = (bit8)MIN(requestLen, MODE_SENSE10_CONTROL_PAGE_LLBAA_LEN);
7059 }
7060 else
7061 {
7062 lenRead = (bit8)MIN(requestLen, MODE_SENSE10_CONTROL_PAGE_LEN);
7063 }
7064 break;
7065 case MODESENSE_READ_WRITE_ERROR_RECOVERY_PAGE: /* Read-Write Error Recovery */
7066 if (LLBAA)
7067 {
7068 lenRead = (bit8)MIN(requestLen, MODE_SENSE10_READ_WRITE_ERROR_RECOVERY_PAGE_LLBAA_LEN);
7069 }
7070 else
7071 {
7072 lenRead = (bit8)MIN(requestLen, MODE_SENSE10_READ_WRITE_ERROR_RECOVERY_PAGE_LEN);
7073 }
7074 break;
7075 case MODESENSE_CACHING: /* caching */
7076 if (LLBAA)
7077 {
7078 lenRead = (bit8)MIN(requestLen, MODE_SENSE10_CACHING_LLBAA_LEN);
7079 }
7080 else
7081 {
7082 lenRead = (bit8)MIN(requestLen, MODE_SENSE10_CACHING_LEN);
7083 }
7084 break;
7085 case MODESENSE_INFORMATION_EXCEPTION_CONTROL_PAGE: /* informational exceptions control*/
7086 if (LLBAA)
7087 {
7088 lenRead = (bit8)MIN(requestLen, MODE_SENSE10_INFORMATION_EXCEPTION_CONTROL_PAGE_LLBAA_LEN);
7089 }
7090 else
7091 {
7092 lenRead = (bit8)MIN(requestLen, MODE_SENSE10_INFORMATION_EXCEPTION_CONTROL_PAGE_LEN);
7093 }
7094 break;
7095 default:
7096 TI_DBG1(("satModeSense10: default error page %d\n", page));
7097 break;
7098 }
7099
7100 if (page == MODESENSE_RETURN_ALL_PAGES)
7101 {
7102 TI_DBG5(("satModeSense10: MODESENSE_RETURN_ALL_PAGES\n"));
7103 AllPages[0] = 0;
7104 AllPages[1] = (bit8)(lenRead - 2);
7105 AllPages[2] = 0x00; /* medium type: default medium type (currently mounted medium type) */
7106 AllPages[3] = 0x00; /* device-specific param: no write-protect, no support for DPO-FUA */
7107 if (LLBAA)
7108 {
7109 AllPages[4] = 0x00; /* reserved and LONGLBA */
7110 AllPages[4] = (bit8)(AllPages[4] | 0x1); /* LONGLBA is set */
7111 }
7112 else
7113 {
7114 AllPages[4] = 0x00; /* reserved and LONGLBA: LONGLBA is not set */
7115 }
7116 AllPages[5] = 0x00; /* reserved */
7117 AllPages[6] = 0x00; /* block descriptot length */
7118 if (LLBAA)
7119 {
7120 AllPages[7] = 0x10; /* block descriptor length: LONGLBA is set. So, length is 16 */
7121 }
7122 else
7123 {
7124 AllPages[7] = 0x08; /* block descriptor length: LONGLBA is NOT set. So, length is 8 */
7125 }
7126
7127 /*
7128 * Fill-up direct-access device block-descriptor, SAT, Table 19
7129 */
7130
7131 if (LLBAA)
7132 {
7133 /* density code */
7134 AllPages[8] = 0x04; /* density-code : reserved for direct-access */
7135 /* number of blocks */
7136 AllPages[9] = 0x00; /* unspecified */
7137 AllPages[10] = 0x00; /* unspecified */
7138 AllPages[11] = 0x00; /* unspecified */
7139 AllPages[12] = 0x00; /* unspecified */
7140 AllPages[13] = 0x00; /* unspecified */
7141 AllPages[14] = 0x00; /* unspecified */
7142 AllPages[15] = 0x00; /* unspecified */
7143 /* reserved */
7144 AllPages[16] = 0x00; /* reserved */
7145 AllPages[17] = 0x00; /* reserved */
7146 AllPages[18] = 0x00; /* reserved */
7147 AllPages[19] = 0x00; /* reserved */
7148 /* Block size */
7149 AllPages[20] = 0x00;
7150 AllPages[21] = 0x00;
7151 AllPages[22] = 0x02; /* Block size is always 512 bytes */
7152 AllPages[23] = 0x00;
7153 }
7154 else
7155 {
7156 /* density code */
7157 AllPages[8] = 0x04; /* density-code : reserved for direct-access */
7158 /* number of blocks */
7159 AllPages[9] = 0x00; /* unspecified */
7160 AllPages[10] = 0x00; /* unspecified */
7161 AllPages[11] = 0x00; /* unspecified */
7162 /* reserved */
7163 AllPages[12] = 0x00; /* reserved */
7164 /* Block size */
7165 AllPages[13] = 0x00;
7166 AllPages[14] = 0x02; /* Block size is always 512 bytes */
7167 AllPages[15] = 0x00;
7168 }
7169
7170 if (LLBAA)
7171 {
7172 index = 24;
7173 }
7174 else
7175 {
7176 index = 16;
7177 }
7178 /* MODESENSE_READ_WRITE_ERROR_RECOVERY_PAGE */
7179 AllPages[index+0] = 0x01; /* page code */
7180 AllPages[index+1] = 0x0A; /* page length */
7181 AllPages[index+2] = 0x40; /* ARRE is set */
7182 AllPages[index+3] = 0x00;
7183 AllPages[index+4] = 0x00;
7184 AllPages[index+5] = 0x00;
7185 AllPages[index+6] = 0x00;
7186 AllPages[index+7] = 0x00;
7187 AllPages[index+8] = 0x00;
7188 AllPages[index+9] = 0x00;
7189 AllPages[index+10] = 0x00;
7190 AllPages[index+11] = 0x00;
7191
7192 /* MODESENSE_CACHING */
7193 /*
7194 * Fill-up Caching mode page, SAT, Table 67
7195 */
7196 /* length 20 */
7197 AllPages[index+12] = 0x08; /* page code */
7198 AllPages[index+13] = 0x12; /* page length */
7199 #ifdef NOT_YET
7200 if (pSatDevData->satWriteCacheEnabled == agTRUE)
7201 {
7202 AllPages[index+14] = 0x04;/* WCE bit is set */
7203 }
7204 else
7205 {
7206 AllPages[index+14] = 0x00;/* WCE bit is NOT set */
7207 }
7208 #endif
7209 AllPages[index+14] = 0x00;/* WCE bit is NOT set */
7210 AllPages[index+15] = 0x00;
7211 AllPages[index+16] = 0x00;
7212 AllPages[index+17] = 0x00;
7213 AllPages[index+18] = 0x00;
7214 AllPages[index+19] = 0x00;
7215 AllPages[index+20] = 0x00;
7216 AllPages[index+21] = 0x00;
7217 AllPages[index+22] = 0x00;
7218 AllPages[index+23] = 0x00;
7219 if (pSatDevData->satLookAheadEnabled == agTRUE)
7220 {
7221 AllPages[index+24] = 0x00;/* DRA bit is NOT set */
7222 }
7223 else
7224 {
7225 AllPages[index+24] = 0x20;/* DRA bit is set */
7226 }
7227 AllPages[index+25] = 0x00;
7228 AllPages[index+26] = 0x00;
7229 AllPages[index+27] = 0x00;
7230 AllPages[index+28] = 0x00;
7231 AllPages[index+29] = 0x00;
7232 AllPages[index+30] = 0x00;
7233 AllPages[index+31] = 0x00;
7234
7235 /* MODESENSE_CONTROL_PAGE */
7236 /*
7237 * Fill-up control mode page, SAT, Table 65
7238 */
7239 AllPages[index+32] = 0x0A; /* page code */
7240 AllPages[index+33] = 0x0A; /* page length */
7241 AllPages[index+34] = 0x02; /* only GLTSD bit is set */
7242 if (pSatDevData->satNCQ == agTRUE)
7243 {
7244 AllPages[index+35] = 0x12; /* Queue Alogorithm modifier 1b and QErr 01b*/
7245 }
7246 else
7247 {
7248 AllPages[index+35] = 0x02; /* Queue Alogorithm modifier 0b and QErr 01b */
7249 }
7250 AllPages[index+36] = 0x00;
7251 AllPages[index+37] = 0x00;
7252 AllPages[index+38] = 0x00; /* obsolete */
7253 AllPages[index+39] = 0x00; /* obsolete */
7254 AllPages[index+40] = 0xFF; /* Busy Timeout Period */
7255 AllPages[index+41] = 0xFF; /* Busy Timeout Period */
7256 AllPages[index+42] = 0x00; /* we don't support non-000b value for the self-test code */
7257 AllPages[index+43] = 0x00; /* we don't support non-000b value for the self-test code */
7258
7259 /* MODESENSE_INFORMATION_EXCEPTION_CONTROL_PAGE */
7260 /*
7261 * Fill-up informational-exceptions control mode page, SAT, Table 68
7262 */
7263 AllPages[index+44] = 0x1C; /* page code */
7264 AllPages[index+45] = 0x0A; /* page length */
7265 if (pSatDevData->satSMARTEnabled == agTRUE)
7266 {
7267 AllPages[index+46] = 0x00;/* DEXCPT bit is NOT set */
7268 }
7269 else
7270 {
7271 AllPages[index+46] = 0x08;/* DEXCPT bit is set */
7272 }
7273 AllPages[index+47] = 0x00; /* We don't support MRIE */
7274 AllPages[index+48] = 0x00; /* Interval timer vendor-specific */
7275 AllPages[index+49] = 0x00;
7276 AllPages[index+50] = 0x00;
7277 AllPages[index+51] = 0x00;
7278 AllPages[index+52] = 0x00; /* REPORT-COUNT */
7279 AllPages[index+53] = 0x00;
7280 AllPages[index+54] = 0x00;
7281 AllPages[index+55] = 0x00;
7282
7283 osti_memcpy(pModeSense, &AllPages, lenRead);
7284 }
7285 else if (page == MODESENSE_CONTROL_PAGE)
7286 {
7287 TI_DBG5(("satModeSense10: MODESENSE_CONTROL_PAGE\n"));
7288 Control[0] = 0;
7289 Control[1] = (bit8)(lenRead - 2);
7290 Control[2] = 0x00; /* medium type: default medium type (currently mounted medium type) */
7291 Control[3] = 0x00; /* device-specific param: no write-protect, no support for DPO-FUA */
7292 if (LLBAA)
7293 {
7294 Control[4] = 0x00; /* reserved and LONGLBA */
7295 Control[4] = (bit8)(Control[4] | 0x1); /* LONGLBA is set */
7296 }
7297 else
7298 {
7299 Control[4] = 0x00; /* reserved and LONGLBA: LONGLBA is not set */
7300 }
7301 Control[5] = 0x00; /* reserved */
7302 Control[6] = 0x00; /* block descriptot length */
7303 if (LLBAA)
7304 {
7305 Control[7] = 0x10; /* block descriptor length: LONGLBA is set. So, length is 16 */
7306 }
7307 else
7308 {
7309 Control[7] = 0x08; /* block descriptor length: LONGLBA is NOT set. So, length is 8 */
7310 }
7311
7312 /*
7313 * Fill-up direct-access device block-descriptor, SAT, Table 19
7314 */
7315
7316 if (LLBAA)
7317 {
7318 /* density code */
7319 Control[8] = 0x04; /* density-code : reserved for direct-access */
7320 /* number of blocks */
7321 Control[9] = 0x00; /* unspecified */
7322 Control[10] = 0x00; /* unspecified */
7323 Control[11] = 0x00; /* unspecified */
7324 Control[12] = 0x00; /* unspecified */
7325 Control[13] = 0x00; /* unspecified */
7326 Control[14] = 0x00; /* unspecified */
7327 Control[15] = 0x00; /* unspecified */
7328 /* reserved */
7329 Control[16] = 0x00; /* reserved */
7330 Control[17] = 0x00; /* reserved */
7331 Control[18] = 0x00; /* reserved */
7332 Control[19] = 0x00; /* reserved */
7333 /* Block size */
7334 Control[20] = 0x00;
7335 Control[21] = 0x00;
7336 Control[22] = 0x02; /* Block size is always 512 bytes */
7337 Control[23] = 0x00;
7338 }
7339 else
7340 {
7341 /* density code */
7342 Control[8] = 0x04; /* density-code : reserved for direct-access */
7343 /* number of blocks */
7344 Control[9] = 0x00; /* unspecified */
7345 Control[10] = 0x00; /* unspecified */
7346 Control[11] = 0x00; /* unspecified */
7347 /* reserved */
7348 Control[12] = 0x00; /* reserved */
7349 /* Block size */
7350 Control[13] = 0x00;
7351 Control[14] = 0x02; /* Block size is always 512 bytes */
7352 Control[15] = 0x00;
7353 }
7354
7355 if (LLBAA)
7356 {
7357 index = 24;
7358 }
7359 else
7360 {
7361 index = 16;
7362 }
7363 /*
7364 * Fill-up control mode page, SAT, Table 65
7365 */
7366 Control[index+0] = 0x0A; /* page code */
7367 Control[index+1] = 0x0A; /* page length */
7368 Control[index+2] = 0x02; /* only GLTSD bit is set */
7369 if (pSatDevData->satNCQ == agTRUE)
7370 {
7371 Control[index+3] = 0x12; /* Queue Alogorithm modifier 1b and QErr 01b*/
7372 }
7373 else
7374 {
7375 Control[index+3] = 0x02; /* Queue Alogorithm modifier 0b and QErr 01b */
7376 }
7377 Control[index+4] = 0x00;
7378 Control[index+5] = 0x00;
7379 Control[index+6] = 0x00; /* obsolete */
7380 Control[index+7] = 0x00; /* obsolete */
7381 Control[index+8] = 0xFF; /* Busy Timeout Period */
7382 Control[index+9] = 0xFF; /* Busy Timeout Period */
7383 Control[index+10] = 0x00; /* we don't support non-000b value for the self-test code */
7384 Control[index+11] = 0x00; /* we don't support non-000b value for the self-test code */
7385
7386 osti_memcpy(pModeSense, &Control, lenRead);
7387 }
7388 else if (page == MODESENSE_READ_WRITE_ERROR_RECOVERY_PAGE)
7389 {
7390 TI_DBG5(("satModeSense10: MODESENSE_READ_WRITE_ERROR_RECOVERY_PAGE\n"));
7391 RWErrorRecovery[0] = 0;
7392 RWErrorRecovery[1] = (bit8)(lenRead - 2);
7393 RWErrorRecovery[2] = 0x00; /* medium type: default medium type (currently mounted medium type) */
7394 RWErrorRecovery[3] = 0x00; /* device-specific param: no write-protect, no support for DPO-FUA */
7395 if (LLBAA)
7396 {
7397 RWErrorRecovery[4] = 0x00; /* reserved and LONGLBA */
7398 RWErrorRecovery[4] = (bit8)(RWErrorRecovery[4] | 0x1); /* LONGLBA is set */
7399 }
7400 else
7401 {
7402 RWErrorRecovery[4] = 0x00; /* reserved and LONGLBA: LONGLBA is not set */
7403 }
7404 RWErrorRecovery[5] = 0x00; /* reserved */
7405 RWErrorRecovery[6] = 0x00; /* block descriptot length */
7406 if (LLBAA)
7407 {
7408 RWErrorRecovery[7] = 0x10; /* block descriptor length: LONGLBA is set. So, length is 16 */
7409 }
7410 else
7411 {
7412 RWErrorRecovery[7] = 0x08; /* block descriptor length: LONGLBA is NOT set. So, length is 8 */
7413 }
7414
7415 /*
7416 * Fill-up direct-access device block-descriptor, SAT, Table 19
7417 */
7418
7419 if (LLBAA)
7420 {
7421 /* density code */
7422 RWErrorRecovery[8] = 0x04; /* density-code : reserved for direct-access */
7423 /* number of blocks */
7424 RWErrorRecovery[9] = 0x00; /* unspecified */
7425 RWErrorRecovery[10] = 0x00; /* unspecified */
7426 RWErrorRecovery[11] = 0x00; /* unspecified */
7427 RWErrorRecovery[12] = 0x00; /* unspecified */
7428 RWErrorRecovery[13] = 0x00; /* unspecified */
7429 RWErrorRecovery[14] = 0x00; /* unspecified */
7430 RWErrorRecovery[15] = 0x00; /* unspecified */
7431 /* reserved */
7432 RWErrorRecovery[16] = 0x00; /* reserved */
7433 RWErrorRecovery[17] = 0x00; /* reserved */
7434 RWErrorRecovery[18] = 0x00; /* reserved */
7435 RWErrorRecovery[19] = 0x00; /* reserved */
7436 /* Block size */
7437 RWErrorRecovery[20] = 0x00;
7438 RWErrorRecovery[21] = 0x00;
7439 RWErrorRecovery[22] = 0x02; /* Block size is always 512 bytes */
7440 RWErrorRecovery[23] = 0x00;
7441 }
7442 else
7443 {
7444 /* density code */
7445 RWErrorRecovery[8] = 0x04; /* density-code : reserved for direct-access */
7446 /* number of blocks */
7447 RWErrorRecovery[9] = 0x00; /* unspecified */
7448 RWErrorRecovery[10] = 0x00; /* unspecified */
7449 RWErrorRecovery[11] = 0x00; /* unspecified */
7450 /* reserved */
7451 RWErrorRecovery[12] = 0x00; /* reserved */
7452 /* Block size */
7453 RWErrorRecovery[13] = 0x00;
7454 RWErrorRecovery[14] = 0x02; /* Block size is always 512 bytes */
7455 RWErrorRecovery[15] = 0x00;
7456 }
7457
7458 if (LLBAA)
7459 {
7460 index = 24;
7461 }
7462 else
7463 {
7464 index = 16;
7465 }
7466 /*
7467 * Fill-up Read-Write Error Recovery mode page, SAT, Table 66
7468 */
7469 RWErrorRecovery[index+0] = 0x01; /* page code */
7470 RWErrorRecovery[index+1] = 0x0A; /* page length */
7471 RWErrorRecovery[index+2] = 0x40; /* ARRE is set */
7472 RWErrorRecovery[index+3] = 0x00;
7473 RWErrorRecovery[index+4] = 0x00;
7474 RWErrorRecovery[index+5] = 0x00;
7475 RWErrorRecovery[index+6] = 0x00;
7476 RWErrorRecovery[index+7] = 0x00;
7477 RWErrorRecovery[index+8] = 0x00;
7478 RWErrorRecovery[index+9] = 0x00;
7479 RWErrorRecovery[index+10] = 0x00;
7480 RWErrorRecovery[index+11] = 0x00;
7481
7482 osti_memcpy(pModeSense, &RWErrorRecovery, lenRead);
7483 }
7484 else if (page == MODESENSE_CACHING)
7485 {
7486 TI_DBG5(("satModeSense10: MODESENSE_CACHING\n"));
7487 Caching[0] = 0;
7488 Caching[1] = (bit8)(lenRead - 2);
7489 Caching[2] = 0x00; /* medium type: default medium type (currently mounted medium type) */
7490 Caching[3] = 0x00; /* device-specific param: no write-protect, no support for DPO-FUA */
7491 if (LLBAA)
7492 {
7493 Caching[4] = 0x00; /* reserved and LONGLBA */
7494 Caching[4] = (bit8)(Caching[4] | 0x1); /* LONGLBA is set */
7495 }
7496 else
7497 {
7498 Caching[4] = 0x00; /* reserved and LONGLBA: LONGLBA is not set */
7499 }
7500 Caching[5] = 0x00; /* reserved */
7501 Caching[6] = 0x00; /* block descriptot length */
7502 if (LLBAA)
7503 {
7504 Caching[7] = 0x10; /* block descriptor length: LONGLBA is set. So, length is 16 */
7505 }
7506 else
7507 {
7508 Caching[7] = 0x08; /* block descriptor length: LONGLBA is NOT set. So, length is 8 */
7509 }
7510
7511 /*
7512 * Fill-up direct-access device block-descriptor, SAT, Table 19
7513 */
7514
7515 if (LLBAA)
7516 {
7517 /* density code */
7518 Caching[8] = 0x04; /* density-code : reserved for direct-access */
7519 /* number of blocks */
7520 Caching[9] = 0x00; /* unspecified */
7521 Caching[10] = 0x00; /* unspecified */
7522 Caching[11] = 0x00; /* unspecified */
7523 Caching[12] = 0x00; /* unspecified */
7524 Caching[13] = 0x00; /* unspecified */
7525 Caching[14] = 0x00; /* unspecified */
7526 Caching[15] = 0x00; /* unspecified */
7527 /* reserved */
7528 Caching[16] = 0x00; /* reserved */
7529 Caching[17] = 0x00; /* reserved */
7530 Caching[18] = 0x00; /* reserved */
7531 Caching[19] = 0x00; /* reserved */
7532 /* Block size */
7533 Caching[20] = 0x00;
7534 Caching[21] = 0x00;
7535 Caching[22] = 0x02; /* Block size is always 512 bytes */
7536 Caching[23] = 0x00;
7537 }
7538 else
7539 {
7540 /* density code */
7541 Caching[8] = 0x04; /* density-code : reserved for direct-access */
7542 /* number of blocks */
7543 Caching[9] = 0x00; /* unspecified */
7544 Caching[10] = 0x00; /* unspecified */
7545 Caching[11] = 0x00; /* unspecified */
7546 /* reserved */
7547 Caching[12] = 0x00; /* reserved */
7548 /* Block size */
7549 Caching[13] = 0x00;
7550 Caching[14] = 0x02; /* Block size is always 512 bytes */
7551 Caching[15] = 0x00;
7552 }
7553
7554 if (LLBAA)
7555 {
7556 index = 24;
7557 }
7558 else
7559 {
7560 index = 16;
7561 }
7562 /*
7563 * Fill-up Caching mode page, SAT, Table 67
7564 */
7565 /* length 20 */
7566 Caching[index+0] = 0x08; /* page code */
7567 Caching[index+1] = 0x12; /* page length */
7568 #ifdef NOT_YET
7569 if (pSatDevData->satWriteCacheEnabled == agTRUE)
7570 {
7571 Caching[index+2] = 0x04;/* WCE bit is set */
7572 }
7573 else
7574 {
7575 Caching[index+2] = 0x00;/* WCE bit is NOT set */
7576 }
7577 #endif
7578 Caching[index+2] = 0x00;/* WCE bit is NOT set */
7579 Caching[index+3] = 0x00;
7580 Caching[index+4] = 0x00;
7581 Caching[index+5] = 0x00;
7582 Caching[index+6] = 0x00;
7583 Caching[index+7] = 0x00;
7584 Caching[index+8] = 0x00;
7585 Caching[index+9] = 0x00;
7586 Caching[index+10] = 0x00;
7587 Caching[index+11] = 0x00;
7588 if (pSatDevData->satLookAheadEnabled == agTRUE)
7589 {
7590 Caching[index+12] = 0x00;/* DRA bit is NOT set */
7591 }
7592 else
7593 {
7594 Caching[index+12] = 0x20;/* DRA bit is set */
7595 }
7596 Caching[index+13] = 0x00;
7597 Caching[index+14] = 0x00;
7598 Caching[index+15] = 0x00;
7599 Caching[index+16] = 0x00;
7600 Caching[index+17] = 0x00;
7601 Caching[index+18] = 0x00;
7602 Caching[index+19] = 0x00;
7603 osti_memcpy(pModeSense, &Caching, lenRead);
7604
7605 }
7606 else if (page == MODESENSE_INFORMATION_EXCEPTION_CONTROL_PAGE)
7607 {
7608 TI_DBG5(("satModeSense10: MODESENSE_INFORMATION_EXCEPTION_CONTROL_PAGE\n"));
7609 InfoExceptionCtrl[0] = 0;
7610 InfoExceptionCtrl[1] = (bit8)(lenRead - 2);
7611 InfoExceptionCtrl[2] = 0x00; /* medium type: default medium type (currently mounted medium type) */
7612 InfoExceptionCtrl[3] = 0x00; /* device-specific param: no write-protect, no support for DPO-FUA */
7613 if (LLBAA)
7614 {
7615 InfoExceptionCtrl[4] = 0x00; /* reserved and LONGLBA */
7616 InfoExceptionCtrl[4] = (bit8)(InfoExceptionCtrl[4] | 0x1); /* LONGLBA is set */
7617 }
7618 else
7619 {
7620 InfoExceptionCtrl[4] = 0x00; /* reserved and LONGLBA: LONGLBA is not set */
7621 }
7622 InfoExceptionCtrl[5] = 0x00; /* reserved */
7623 InfoExceptionCtrl[6] = 0x00; /* block descriptot length */
7624 if (LLBAA)
7625 {
7626 InfoExceptionCtrl[7] = 0x10; /* block descriptor length: LONGLBA is set. So, length is 16 */
7627 }
7628 else
7629 {
7630 InfoExceptionCtrl[7] = 0x08; /* block descriptor length: LONGLBA is NOT set. So, length is 8 */
7631 }
7632
7633 /*
7634 * Fill-up direct-access device block-descriptor, SAT, Table 19
7635 */
7636
7637 if (LLBAA)
7638 {
7639 /* density code */
7640 InfoExceptionCtrl[8] = 0x04; /* density-code : reserved for direct-access */
7641 /* number of blocks */
7642 InfoExceptionCtrl[9] = 0x00; /* unspecified */
7643 InfoExceptionCtrl[10] = 0x00; /* unspecified */
7644 InfoExceptionCtrl[11] = 0x00; /* unspecified */
7645 InfoExceptionCtrl[12] = 0x00; /* unspecified */
7646 InfoExceptionCtrl[13] = 0x00; /* unspecified */
7647 InfoExceptionCtrl[14] = 0x00; /* unspecified */
7648 InfoExceptionCtrl[15] = 0x00; /* unspecified */
7649 /* reserved */
7650 InfoExceptionCtrl[16] = 0x00; /* reserved */
7651 InfoExceptionCtrl[17] = 0x00; /* reserved */
7652 InfoExceptionCtrl[18] = 0x00; /* reserved */
7653 InfoExceptionCtrl[19] = 0x00; /* reserved */
7654 /* Block size */
7655 InfoExceptionCtrl[20] = 0x00;
7656 InfoExceptionCtrl[21] = 0x00;
7657 InfoExceptionCtrl[22] = 0x02; /* Block size is always 512 bytes */
7658 InfoExceptionCtrl[23] = 0x00;
7659 }
7660 else
7661 {
7662 /* density code */
7663 InfoExceptionCtrl[8] = 0x04; /* density-code : reserved for direct-access */
7664 /* number of blocks */
7665 InfoExceptionCtrl[9] = 0x00; /* unspecified */
7666 InfoExceptionCtrl[10] = 0x00; /* unspecified */
7667 InfoExceptionCtrl[11] = 0x00; /* unspecified */
7668 /* reserved */
7669 InfoExceptionCtrl[12] = 0x00; /* reserved */
7670 /* Block size */
7671 InfoExceptionCtrl[13] = 0x00;
7672 InfoExceptionCtrl[14] = 0x02; /* Block size is always 512 bytes */
7673 InfoExceptionCtrl[15] = 0x00;
7674 }
7675
7676 if (LLBAA)
7677 {
7678 index = 24;
7679 }
7680 else
7681 {
7682 index = 16;
7683 }
7684 /*
7685 * Fill-up informational-exceptions control mode page, SAT, Table 68
7686 */
7687 InfoExceptionCtrl[index+0] = 0x1C; /* page code */
7688 InfoExceptionCtrl[index+1] = 0x0A; /* page length */
7689 if (pSatDevData->satSMARTEnabled == agTRUE)
7690 {
7691 InfoExceptionCtrl[index+2] = 0x00;/* DEXCPT bit is NOT set */
7692 }
7693 else
7694 {
7695 InfoExceptionCtrl[index+2] = 0x08;/* DEXCPT bit is set */
7696 }
7697 InfoExceptionCtrl[index+3] = 0x00; /* We don't support MRIE */
7698 InfoExceptionCtrl[index+4] = 0x00; /* Interval timer vendor-specific */
7699 InfoExceptionCtrl[index+5] = 0x00;
7700 InfoExceptionCtrl[index+6] = 0x00;
7701 InfoExceptionCtrl[index+7] = 0x00;
7702 InfoExceptionCtrl[index+8] = 0x00; /* REPORT-COUNT */
7703 InfoExceptionCtrl[index+9] = 0x00;
7704 InfoExceptionCtrl[index+10] = 0x00;
7705 InfoExceptionCtrl[index+11] = 0x00;
7706 osti_memcpy(pModeSense, &InfoExceptionCtrl, lenRead);
7707
7708 }
7709 else
7710 {
7711 /* Error */
7712 TI_DBG1(("satModeSense10: Error page %d\n", page));
7713 satSetSensePayload( pSense,
7714 SCSI_SNSKEY_ILLEGAL_REQUEST,
7715 0,
7716 SCSI_SNSCODE_INVALID_COMMAND,
7717 satIOContext);
7718
7719 ostiInitiatorIOCompleted( tiRoot,
7720 tiIORequest,
7721 tiIOSuccess,
7722 SCSI_STAT_CHECK_CONDITION,
7723 satIOContext->pTiSenseData,
7724 satIOContext->interruptContext );
7725 return tiSuccess;
7726 }
7727
7728 if (requestLen > lenRead)
7729 {
7730 TI_DBG1(("satModeSense10 reporting underrun lenRead=0x%x requestLen=0x%x tiIORequest=%p\n", lenRead, requestLen, tiIORequest));
7731
7732 ostiInitiatorIOCompleted( tiRoot,
7733 tiIORequest,
7734 tiIOUnderRun,
7735 requestLen - lenRead,
7736 agNULL,
7737 satIOContext->interruptContext );
7738
7739
7740 }
7741 else
7742 {
7743 ostiInitiatorIOCompleted( tiRoot,
7744 tiIORequest,
7745 tiIOSuccess,
7746 SCSI_STAT_GOOD,
7747 agNULL,
7748 satIOContext->interruptContext);
7749 }
7750
7751 return tiSuccess;
7752 }
7753
7754
7755 /*****************************************************************************/
7756 /*! \brief SAT implementation for SCSI VERIFY (10).
7757 *
7758 * SAT implementation for SCSI VERIFY (10).
7759 *
7760 * \param tiRoot: Pointer to TISA initiator driver/port instance.
7761 * \param tiIORequest: Pointer to TISA I/O request context for this I/O.
7762 * \param tiDeviceHandle: Pointer to TISA device handle for this I/O.
7763 * \param tiScsiRequest: Pointer to TISA SCSI I/O request and SGL list.
7764 * \param satIOContext_t: Pointer to the SAT IO Context
7765 *
7766 * \return If command is started successfully
7767 * - \e tiSuccess: I/O request successfully initiated.
7768 * - \e tiBusy: No resources available, try again later.
7769 * - \e tiIONoDevice: Invalid device handle.
7770 * - \e tiError: Other errors.
7771 */
7772 /*****************************************************************************/
satVerify10(tiRoot_t * tiRoot,tiIORequest_t * tiIORequest,tiDeviceHandle_t * tiDeviceHandle,tiScsiInitiatorRequest_t * tiScsiRequest,satIOContext_t * satIOContext)7773 GLOBAL bit32 satVerify10(
7774 tiRoot_t *tiRoot,
7775 tiIORequest_t *tiIORequest,
7776 tiDeviceHandle_t *tiDeviceHandle,
7777 tiScsiInitiatorRequest_t *tiScsiRequest,
7778 satIOContext_t *satIOContext)
7779 {
7780 /*
7781 For simple implementation,
7782 no byte comparison supported as of 4/5/06
7783 */
7784 scsiRspSense_t *pSense;
7785 tiIniScsiCmnd_t *scsiCmnd;
7786 satDeviceData_t *pSatDevData;
7787 agsaFisRegHostToDevice_t *fis;
7788 bit32 status;
7789 bit32 agRequestType = AGSA_SATA_PROTOCOL_NON_DATA;
7790 bit32 lba = 0;
7791 bit32 tl = 0;
7792 bit32 LoopNum = 1;
7793 bit8 LBA[4];
7794 bit8 TL[4];
7795 bit32 rangeChk = agFALSE; /* lba and tl range check */
7796
7797
7798 TI_DBG5(("satVerify10 entry: tiDeviceHandle=%p tiIORequest=%p\n",
7799 tiDeviceHandle, tiIORequest));
7800
7801 pSense = satIOContext->pSense;
7802 scsiCmnd = &tiScsiRequest->scsiCmnd;
7803 pSatDevData = satIOContext->pSatDevData;
7804 fis = satIOContext->pFis;
7805
7806 /* checking BYTCHK */
7807 if (scsiCmnd->cdb[1] & SCSI_VERIFY_BYTCHK_MASK)
7808 {
7809 /*
7810 should do the byte check
7811 but not supported in this version
7812 */
7813 satSetSensePayload( pSense,
7814 SCSI_SNSKEY_ILLEGAL_REQUEST,
7815 0,
7816 SCSI_SNSCODE_INVALID_FIELD_IN_CDB,
7817 satIOContext);
7818
7819 ostiInitiatorIOCompleted( tiRoot,
7820 tiIORequest,
7821 tiIOSuccess,
7822 SCSI_STAT_CHECK_CONDITION,
7823 satIOContext->pTiSenseData,
7824 satIOContext->interruptContext );
7825
7826 TI_DBG1(("satVerify10: no byte checking \n"));
7827 return tiSuccess;
7828 }
7829
7830 /* checking CONTROL */
7831 /* NACA == 1 or LINK == 1*/
7832 if ( (scsiCmnd->cdb[9] & SCSI_NACA_MASK) || (scsiCmnd->cdb[9] & SCSI_LINK_MASK) )
7833 {
7834 satSetSensePayload( pSense,
7835 SCSI_SNSKEY_ILLEGAL_REQUEST,
7836 0,
7837 SCSI_SNSCODE_INVALID_FIELD_IN_CDB,
7838 satIOContext);
7839
7840 ostiInitiatorIOCompleted( tiRoot,
7841 tiIORequest,
7842 tiIOSuccess,
7843 SCSI_STAT_CHECK_CONDITION,
7844 satIOContext->pTiSenseData,
7845 satIOContext->interruptContext );
7846
7847 TI_DBG2(("satVerify10: return control\n"));
7848 return tiSuccess;
7849 }
7850
7851 osti_memset(LBA, 0, sizeof(LBA));
7852 osti_memset(TL, 0, sizeof(TL));
7853
7854 /* do not use memcpy due to indexing in LBA and TL */
7855 LBA[0] = scsiCmnd->cdb[2]; /* MSB */
7856 LBA[1] = scsiCmnd->cdb[3];
7857 LBA[2] = scsiCmnd->cdb[4];
7858 LBA[3] = scsiCmnd->cdb[5]; /* LSB */
7859
7860 TL[0] = 0;
7861 TL[1] = 0;
7862 TL[2] = scsiCmnd->cdb[7]; /* MSB */
7863 TL[3] = scsiCmnd->cdb[8]; /* LSB */
7864
7865 rangeChk = satAddNComparebit32(LBA, TL);
7866
7867 /* cbd10; computing LBA and transfer length */
7868 lba = (scsiCmnd->cdb[2] << (8*3)) + (scsiCmnd->cdb[3] << (8*2))
7869 + (scsiCmnd->cdb[4] << 8) + scsiCmnd->cdb[5];
7870 tl = (scsiCmnd->cdb[7] << 8) + scsiCmnd->cdb[8];
7871
7872 if (pSatDevData->satNCQ != agTRUE &&
7873 pSatDevData->sat48BitSupport != agTRUE
7874 )
7875 {
7876 if (lba > SAT_TR_LBA_LIMIT - 1)
7877 {
7878 satSetSensePayload( pSense,
7879 SCSI_SNSKEY_ILLEGAL_REQUEST,
7880 0,
7881 SCSI_SNSCODE_LOGICAL_BLOCK_ADDRESS_OUT_OF_RANGE,
7882 satIOContext);
7883
7884 ostiInitiatorIOCompleted( tiRoot,
7885 tiIORequest,
7886 tiIOSuccess,
7887 SCSI_STAT_CHECK_CONDITION,
7888 satIOContext->pTiSenseData,
7889 satIOContext->interruptContext );
7890
7891 TI_DBG1(("satVerify10: return LBA out of range, not EXT\n"));
7892 TI_DBG1(("satVerify10: cdb 0x%x 0x%x 0x%x 0x%x\n",scsiCmnd->cdb[2], scsiCmnd->cdb[3],
7893 scsiCmnd->cdb[4], scsiCmnd->cdb[5]));
7894 TI_DBG1(("satVerify10: lba 0x%x SAT_TR_LBA_LIMIT 0x%x\n", lba, SAT_TR_LBA_LIMIT));
7895 return tiSuccess;
7896 }
7897
7898 if (rangeChk) // if (lba + tl > SAT_TR_LBA_LIMIT)
7899 {
7900 TI_DBG1(("satVerify10: return LBA+TL out of range, not EXT\n"));
7901 satSetSensePayload( pSense,
7902 SCSI_SNSKEY_ILLEGAL_REQUEST,
7903 0,
7904 SCSI_SNSCODE_LOGICAL_BLOCK_ADDRESS_OUT_OF_RANGE,
7905 satIOContext);
7906
7907 ostiInitiatorIOCompleted( tiRoot,
7908 tiIORequest,
7909 tiIOSuccess,
7910 SCSI_STAT_CHECK_CONDITION,
7911 satIOContext->pTiSenseData,
7912 satIOContext->interruptContext );
7913
7914 return tiSuccess;
7915 }
7916 }
7917
7918 if (pSatDevData->sat48BitSupport == agTRUE)
7919 {
7920 TI_DBG5(("satVerify10: SAT_READ_VERIFY_SECTORS_EXT\n"));
7921 fis->h.fisType = 0x27; /* Reg host to device */
7922 fis->h.c_pmPort = 0x80; /* C Bit is set */
7923
7924 fis->h.command = SAT_READ_VERIFY_SECTORS_EXT;/* 0x42 */
7925 fis->h.features = 0; /* FIS reserve */
7926 fis->d.lbaLow = scsiCmnd->cdb[5]; /* FIS LBA (7 :0 ) */
7927 fis->d.lbaMid = scsiCmnd->cdb[4]; /* FIS LBA (15:8 ) */
7928 fis->d.lbaHigh = scsiCmnd->cdb[3]; /* FIS LBA (23:16) */
7929 fis->d.device = 0x40; /* FIS LBA mode set 01000000 */
7930 fis->d.lbaLowExp = scsiCmnd->cdb[2]; /* FIS LBA (31:24) */
7931 fis->d.lbaMidExp = 0; /* FIS LBA (39:32) */
7932 fis->d.lbaHighExp = 0; /* FIS LBA (47:40) */
7933 fis->d.featuresExp = 0; /* FIS reserve */
7934 fis->d.sectorCount = scsiCmnd->cdb[8]; /* FIS sector count (7:0) */
7935 fis->d.sectorCountExp = scsiCmnd->cdb[7]; /* FIS sector count (15:8) */
7936
7937 fis->d.reserved4 = 0;
7938 fis->d.control = 0; /* FIS HOB bit clear */
7939 fis->d.reserved5 = 0;
7940
7941 agRequestType = AGSA_SATA_PROTOCOL_NON_DATA;
7942 satIOContext->ATACmd = SAT_READ_VERIFY_SECTORS_EXT;
7943 }
7944 else
7945 {
7946 TI_DBG5(("satVerify10: SAT_READ_VERIFY_SECTORS\n"));
7947 fis->h.fisType = 0x27; /* Reg host to device */
7948 fis->h.c_pmPort = 0x80; /* C bit is set */
7949 fis->h.command = SAT_READ_VERIFY_SECTORS; /* 0x40 */
7950 fis->h.features = 0; /* FIS reserve */
7951 fis->d.lbaLow = scsiCmnd->cdb[5]; /* FIS LBA (7 :0 ) */
7952 fis->d.lbaMid = scsiCmnd->cdb[4]; /* FIS LBA (15:8 ) */
7953 fis->d.lbaHigh = scsiCmnd->cdb[3]; /* FIS LBA (23:16) */
7954 /* FIS LBA mode set LBA (27:24) */
7955 fis->d.device = (bit8)((0x4 << 4) | (scsiCmnd->cdb[2] & 0xF));
7956 fis->d.lbaLowExp = 0;
7957 fis->d.lbaMidExp = 0;
7958 fis->d.lbaHighExp = 0;
7959 fis->d.featuresExp = 0;
7960 fis->d.sectorCount = scsiCmnd->cdb[8]; /* FIS sector count (7:0) */
7961 fis->d.sectorCountExp = 0;
7962 fis->d.reserved4 = 0;
7963 fis->d.control = 0; /* FIS HOB bit clear */
7964 fis->d.reserved5 = 0;
7965
7966 agRequestType = AGSA_SATA_PROTOCOL_NON_DATA;
7967 satIOContext->ATACmd = SAT_READ_VERIFY_SECTORS;
7968
7969 }
7970
7971 satIOContext->currentLBA = lba;
7972 satIOContext->OrgTL = tl;
7973
7974 /*
7975 computing number of loop and remainder for tl
7976 0xFF in case not ext
7977 0xFFFF in case EXT
7978 */
7979 if (fis->h.command == SAT_READ_VERIFY_SECTORS)
7980 {
7981 LoopNum = satComputeLoopNum(tl, 0xFF);
7982 }
7983 else if (fis->h.command == SAT_READ_VERIFY_SECTORS_EXT)
7984 {
7985 /* SAT_READ_SECTORS_EXT, SAT_READ_DMA_EXT */
7986 LoopNum = satComputeLoopNum(tl, 0xFFFF);
7987 }
7988 else
7989 {
7990 TI_DBG1(("satVerify10: error case 1!!!\n"));
7991 LoopNum = 1;
7992 }
7993
7994 satIOContext->LoopNum = LoopNum;
7995
7996 if (LoopNum == 1)
7997 {
7998 TI_DBG5(("satVerify10: NON CHAINED data\n"));
7999 /* Initialize CB for SATA completion.
8000 */
8001 satIOContext->satCompleteCB = &satNonChainedVerifyCB;
8002 }
8003 else
8004 {
8005 TI_DBG1(("satVerify10: CHAINED data\n"));
8006 /* re-setting tl */
8007 if (fis->h.command == SAT_READ_VERIFY_SECTORS)
8008 {
8009 fis->d.sectorCount = 0xFF;
8010 }
8011 else if (fis->h.command == SAT_READ_VERIFY_SECTORS_EXT)
8012 {
8013 fis->d.sectorCount = 0xFF;
8014 fis->d.sectorCountExp = 0xFF;
8015 }
8016 else
8017 {
8018 TI_DBG1(("satVerify10: error case 2!!!\n"));
8019 }
8020
8021 /* Initialize CB for SATA completion.
8022 */
8023 satIOContext->satCompleteCB = &satChainedVerifyCB;
8024 }
8025
8026
8027 /*
8028 * Prepare SGL and send FIS to LL layer.
8029 */
8030 satIOContext->reqType = agRequestType; /* Save it */
8031
8032 status = sataLLIOStart( tiRoot,
8033 tiIORequest,
8034 tiDeviceHandle,
8035 tiScsiRequest,
8036 satIOContext);
8037 return (status);
8038 }
8039
satChainedVerify(tiRoot_t * tiRoot,tiIORequest_t * tiIORequest,tiDeviceHandle_t * tiDeviceHandle,tiScsiInitiatorRequest_t * tiScsiRequest,satIOContext_t * satIOContext)8040 GLOBAL bit32 satChainedVerify(
8041 tiRoot_t *tiRoot,
8042 tiIORequest_t *tiIORequest,
8043 tiDeviceHandle_t *tiDeviceHandle,
8044 tiScsiInitiatorRequest_t *tiScsiRequest,
8045 satIOContext_t *satIOContext)
8046 {
8047 bit32 status;
8048 satIOContext_t *satOrgIOContext = agNULL;
8049 agsaFisRegHostToDevice_t *fis;
8050 bit32 agRequestType = AGSA_SATA_PROTOCOL_NON_DATA;
8051 bit32 lba = 0;
8052 bit32 DenomTL = 0xFF;
8053 bit32 Remainder = 0;
8054 bit8 LBA[4]; /* 0 MSB, 3 LSB */
8055
8056 TI_DBG2(("satChainedVerify: start\n"));
8057
8058 fis = satIOContext->pFis;
8059 satOrgIOContext = satIOContext->satOrgIOContext;
8060 osti_memset(LBA,0, sizeof(LBA));
8061
8062 switch (satOrgIOContext->ATACmd)
8063 {
8064 case SAT_READ_VERIFY_SECTORS:
8065 DenomTL = 0xFF;
8066 break;
8067 case SAT_READ_VERIFY_SECTORS_EXT:
8068 DenomTL = 0xFFFF;
8069 break;
8070 default:
8071 TI_DBG1(("satChainedVerify: error incorrect ata command 0x%x\n", satIOContext->ATACmd));
8072 return tiError;
8073 break;
8074 }
8075
8076 Remainder = satOrgIOContext->OrgTL % DenomTL;
8077 satOrgIOContext->currentLBA = satOrgIOContext->currentLBA + DenomTL;
8078 lba = satOrgIOContext->currentLBA;
8079
8080 LBA[0] = (bit8)((lba & 0xF000) >> (8 * 3)); /* MSB */
8081 LBA[1] = (bit8)((lba & 0xF00) >> (8 * 2));
8082 LBA[2] = (bit8)((lba & 0xF0) >> 8);
8083 LBA[3] = (bit8)(lba & 0xF); /* LSB */
8084
8085 switch (satOrgIOContext->ATACmd)
8086 {
8087 case SAT_READ_VERIFY_SECTORS:
8088 fis->h.fisType = 0x27; /* Reg host to device */
8089 fis->h.c_pmPort = 0x80; /* C bit is set */
8090 fis->h.command = SAT_READ_VERIFY_SECTORS; /* 0x40 */
8091 fis->h.features = 0; /* FIS reserve */
8092 fis->d.lbaLow = LBA[3]; /* FIS LBA (7 :0 ) */
8093 fis->d.lbaMid = LBA[2]; /* FIS LBA (15:8 ) */
8094 fis->d.lbaHigh = LBA[1]; /* FIS LBA (23:16) */
8095
8096 /* FIS LBA mode set LBA (27:24) */
8097 fis->d.device = (bit8)((0x4 << 4) | (LBA[0] & 0xF));
8098
8099 fis->d.lbaLowExp = 0;
8100 fis->d.lbaMidExp = 0;
8101 fis->d.lbaHighExp = 0;
8102 fis->d.featuresExp = 0;
8103 if (satOrgIOContext->LoopNum == 1)
8104 {
8105 /* last loop */
8106 fis->d.sectorCount = (bit8)Remainder; /* FIS sector count (7:0) */
8107 }
8108 else
8109 {
8110 fis->d.sectorCount = 0xFF; /* FIS sector count (7:0) */
8111 }
8112 fis->d.sectorCountExp = 0;
8113 fis->d.reserved4 = 0;
8114 fis->d.control = 0; /* FIS HOB bit clear */
8115 fis->d.reserved5 = 0;
8116
8117 agRequestType = AGSA_SATA_PROTOCOL_NON_DATA;
8118
8119 break;
8120 case SAT_READ_VERIFY_SECTORS_EXT:
8121 fis->h.fisType = 0x27; /* Reg host to device */
8122 fis->h.c_pmPort = 0x80; /* C Bit is set */
8123 fis->h.command = SAT_READ_VERIFY_SECTORS_EXT; /* 0x42 */
8124 fis->h.features = 0; /* FIS reserve */
8125 fis->d.lbaLow = LBA[3]; /* FIS LBA (7 :0 ) */
8126 fis->d.lbaMid = LBA[2]; /* FIS LBA (15:8 ) */
8127 fis->d.lbaHigh = LBA[1]; /* FIS LBA (23:16) */
8128 fis->d.device = 0x40; /* FIS LBA mode set */
8129 fis->d.lbaLowExp = LBA[0]; /* FIS LBA (31:24) */
8130 fis->d.lbaMidExp = 0; /* FIS LBA (39:32) */
8131 fis->d.lbaHighExp = 0; /* FIS LBA (47:40) */
8132 fis->d.featuresExp = 0; /* FIS reserve */
8133 if (satOrgIOContext->LoopNum == 1)
8134 {
8135 /* last loop */
8136 fis->d.sectorCount = (bit8)(Remainder & 0xFF); /* FIS sector count (7:0) */
8137 fis->d.sectorCountExp = (bit8)((Remainder & 0xFF00) >> 8); /* FIS sector count (15:8) */
8138 }
8139 else
8140 {
8141 fis->d.sectorCount = 0xFF; /* FIS sector count (7:0) */
8142 fis->d.sectorCountExp = 0xFF; /* FIS sector count (15:8) */
8143 }
8144 fis->d.reserved4 = 0;
8145 fis->d.control = 0; /* FIS HOB bit clear */
8146 fis->d.reserved5 = 0;
8147
8148 agRequestType = AGSA_SATA_PROTOCOL_NON_DATA;
8149
8150 break;
8151
8152 default:
8153 TI_DBG1(("satChainedVerify: error incorrect ata command 0x%x\n", satIOContext->ATACmd));
8154 return tiError;
8155 break;
8156 }
8157
8158 /* Initialize CB for SATA completion.
8159 */
8160 /* chained data */
8161 satIOContext->satCompleteCB = &satChainedVerifyCB;
8162
8163
8164 /*
8165 * Prepare SGL and send FIS to LL layer.
8166 */
8167 satIOContext->reqType = agRequestType; /* Save it */
8168
8169 status = sataLLIOStart( tiRoot,
8170 tiIORequest,
8171 tiDeviceHandle,
8172 tiScsiRequest,
8173 satIOContext);
8174
8175 TI_DBG5(("satChainedVerify: return\n"));
8176 return (status);
8177
8178 }
8179
8180
8181 /*****************************************************************************/
8182 /*! \brief SAT implementation for SCSI VERIFY (12).
8183 *
8184 * SAT implementation for SCSI VERIFY (12).
8185 *
8186 * \param tiRoot: Pointer to TISA initiator driver/port instance.
8187 * \param tiIORequest: Pointer to TISA I/O request context for this I/O.
8188 * \param tiDeviceHandle: Pointer to TISA device handle for this I/O.
8189 * \param tiScsiRequest: Pointer to TISA SCSI I/O request and SGL list.
8190 * \param satIOContext_t: Pointer to the SAT IO Context
8191 *
8192 * \return If command is started successfully
8193 * - \e tiSuccess: I/O request successfully initiated.
8194 * - \e tiBusy: No resources available, try again later.
8195 * - \e tiIONoDevice: Invalid device handle.
8196 * - \e tiError: Other errors.
8197 */
8198 /*****************************************************************************/
satVerify12(tiRoot_t * tiRoot,tiIORequest_t * tiIORequest,tiDeviceHandle_t * tiDeviceHandle,tiScsiInitiatorRequest_t * tiScsiRequest,satIOContext_t * satIOContext)8199 GLOBAL bit32 satVerify12(
8200 tiRoot_t *tiRoot,
8201 tiIORequest_t *tiIORequest,
8202 tiDeviceHandle_t *tiDeviceHandle,
8203 tiScsiInitiatorRequest_t *tiScsiRequest,
8204 satIOContext_t *satIOContext)
8205 {
8206 /*
8207 For simple implementation,
8208 no byte comparison supported as of 4/5/06
8209 */
8210 scsiRspSense_t *pSense;
8211 tiIniScsiCmnd_t *scsiCmnd;
8212 satDeviceData_t *pSatDevData;
8213 agsaFisRegHostToDevice_t *fis;
8214 bit32 status;
8215 bit32 agRequestType = AGSA_SATA_PROTOCOL_NON_DATA;
8216 bit32 lba = 0;
8217 bit32 tl = 0;
8218 bit32 LoopNum = 1;
8219 bit8 LBA[4];
8220 bit8 TL[4];
8221 bit32 rangeChk = agFALSE; /* lba and tl range check */
8222
8223 TI_DBG5(("satVerify12 entry: tiDeviceHandle=%p tiIORequest=%p\n",
8224 tiDeviceHandle, tiIORequest));
8225
8226 pSense = satIOContext->pSense;
8227 scsiCmnd = &tiScsiRequest->scsiCmnd;
8228 pSatDevData = satIOContext->pSatDevData;
8229 fis = satIOContext->pFis;
8230
8231
8232 /* checking BYTCHK */
8233 if (scsiCmnd->cdb[1] & SCSI_VERIFY_BYTCHK_MASK)
8234 {
8235 /*
8236 should do the byte check
8237 but not supported in this version
8238 */
8239 satSetSensePayload( pSense,
8240 SCSI_SNSKEY_ILLEGAL_REQUEST,
8241 0,
8242 SCSI_SNSCODE_INVALID_FIELD_IN_CDB,
8243 satIOContext);
8244
8245 ostiInitiatorIOCompleted( tiRoot,
8246 tiIORequest,
8247 tiIOSuccess,
8248 SCSI_STAT_CHECK_CONDITION,
8249 satIOContext->pTiSenseData,
8250 satIOContext->interruptContext );
8251
8252 TI_DBG1(("satVerify12: no byte checking \n"));
8253 return tiSuccess;
8254 }
8255
8256 /* checking CONTROL */
8257 /* NACA == 1 or LINK == 1*/
8258 if ( (scsiCmnd->cdb[11] & SCSI_NACA_MASK) || (scsiCmnd->cdb[11] & SCSI_LINK_MASK) )
8259 {
8260 satSetSensePayload( pSense,
8261 SCSI_SNSKEY_ILLEGAL_REQUEST,
8262 0,
8263 SCSI_SNSCODE_INVALID_FIELD_IN_CDB,
8264 satIOContext);
8265
8266 ostiInitiatorIOCompleted( tiRoot,
8267 tiIORequest,
8268 tiIOSuccess,
8269 SCSI_STAT_CHECK_CONDITION,
8270 satIOContext->pTiSenseData,
8271 satIOContext->interruptContext );
8272
8273 TI_DBG1(("satVerify12: return control\n"));
8274 return tiSuccess;
8275 }
8276
8277 osti_memset(LBA, 0, sizeof(LBA));
8278 osti_memset(TL, 0, sizeof(TL));
8279
8280 /* do not use memcpy due to indexing in LBA and TL */
8281 LBA[0] = scsiCmnd->cdb[2]; /* MSB */
8282 LBA[1] = scsiCmnd->cdb[3];
8283 LBA[2] = scsiCmnd->cdb[4];
8284 LBA[3] = scsiCmnd->cdb[5]; /* LSB */
8285
8286 TL[0] = scsiCmnd->cdb[6]; /* MSB */
8287 TL[1] = scsiCmnd->cdb[7];
8288 TL[2] = scsiCmnd->cdb[7];
8289 TL[3] = scsiCmnd->cdb[8]; /* LSB */
8290
8291 rangeChk = satAddNComparebit32(LBA, TL);
8292
8293 lba = satComputeCDB12LBA(satIOContext);
8294 tl = satComputeCDB12TL(satIOContext);
8295
8296 if (pSatDevData->satNCQ != agTRUE &&
8297 pSatDevData->sat48BitSupport != agTRUE
8298 )
8299 {
8300 if (lba > SAT_TR_LBA_LIMIT - 1)
8301 {
8302 satSetSensePayload( pSense,
8303 SCSI_SNSKEY_ILLEGAL_REQUEST,
8304 0,
8305 SCSI_SNSCODE_LOGICAL_BLOCK_ADDRESS_OUT_OF_RANGE,
8306 satIOContext);
8307
8308 ostiInitiatorIOCompleted( tiRoot,
8309 tiIORequest,
8310 tiIOSuccess,
8311 SCSI_STAT_CHECK_CONDITION,
8312 satIOContext->pTiSenseData,
8313 satIOContext->interruptContext );
8314
8315 TI_DBG1(("satVerify12: return LBA out of range, not EXT\n"));
8316 TI_DBG1(("satVerify12: cdb 0x%x 0x%x 0x%x 0x%x\n",scsiCmnd->cdb[2], scsiCmnd->cdb[3],
8317 scsiCmnd->cdb[4], scsiCmnd->cdb[5]));
8318 TI_DBG1(("satVerify12: lba 0x%x SAT_TR_LBA_LIMIT 0x%x\n", lba, SAT_TR_LBA_LIMIT));
8319 return tiSuccess;
8320 }
8321
8322 if (rangeChk) // if (lba + tl > SAT_TR_LBA_LIMIT)
8323 {
8324 TI_DBG1(("satVerify12: return LBA+TL out of range, not EXT\n"));
8325 satSetSensePayload( pSense,
8326 SCSI_SNSKEY_ILLEGAL_REQUEST,
8327 0,
8328 SCSI_SNSCODE_LOGICAL_BLOCK_ADDRESS_OUT_OF_RANGE,
8329 satIOContext);
8330
8331 ostiInitiatorIOCompleted( tiRoot,
8332 tiIORequest,
8333 tiIOSuccess,
8334 SCSI_STAT_CHECK_CONDITION,
8335 satIOContext->pTiSenseData,
8336 satIOContext->interruptContext );
8337
8338 return tiSuccess;
8339 }
8340 }
8341
8342 if (pSatDevData->sat48BitSupport == agTRUE)
8343 {
8344 TI_DBG5(("satVerify12: SAT_READ_VERIFY_SECTORS_EXT\n"));
8345 fis->h.fisType = 0x27; /* Reg host to device */
8346 fis->h.c_pmPort = 0x80; /* C Bit is set */
8347
8348 fis->h.command = SAT_READ_VERIFY_SECTORS_EXT;/* 0x42 */
8349 fis->h.features = 0; /* FIS reserve */
8350 fis->d.lbaLow = scsiCmnd->cdb[5]; /* FIS LBA (7 :0 ) */
8351 fis->d.lbaMid = scsiCmnd->cdb[4]; /* FIS LBA (15:8 ) */
8352 fis->d.lbaHigh = scsiCmnd->cdb[3]; /* FIS LBA (23:16) */
8353 fis->d.device = 0x40; /* FIS LBA mode set 01000000 */
8354 fis->d.lbaLowExp = scsiCmnd->cdb[2]; /* FIS LBA (31:24) */
8355 fis->d.lbaMidExp = 0; /* FIS LBA (39:32) */
8356 fis->d.lbaHighExp = 0; /* FIS LBA (47:40) */
8357 fis->d.featuresExp = 0; /* FIS reserve */
8358 fis->d.sectorCount = scsiCmnd->cdb[9]; /* FIS sector count (7:0) */
8359 fis->d.sectorCountExp = scsiCmnd->cdb[8]; /* FIS sector count (15:8) */
8360
8361 fis->d.reserved4 = 0;
8362 fis->d.control = 0; /* FIS HOB bit clear */
8363 fis->d.reserved5 = 0;
8364
8365 agRequestType = AGSA_SATA_PROTOCOL_NON_DATA;
8366 satIOContext->ATACmd = SAT_READ_VERIFY_SECTORS_EXT;
8367 }
8368 else
8369 {
8370 TI_DBG5(("satVerify12: SAT_READ_VERIFY_SECTORS\n"));
8371 fis->h.fisType = 0x27; /* Reg host to device */
8372 fis->h.c_pmPort = 0x80; /* C bit is set */
8373 fis->h.command = SAT_READ_VERIFY_SECTORS; /* 0x40 */
8374 fis->h.features = 0; /* FIS reserve */
8375 fis->d.lbaLow = scsiCmnd->cdb[5]; /* FIS LBA (7 :0 ) */
8376 fis->d.lbaMid = scsiCmnd->cdb[4]; /* FIS LBA (15:8 ) */
8377 fis->d.lbaHigh = scsiCmnd->cdb[3]; /* FIS LBA (23:16) */
8378 /* FIS LBA mode set LBA (27:24) */
8379 fis->d.device = (bit8)((0x4 << 4) | (scsiCmnd->cdb[2] & 0xF));
8380 fis->d.lbaLowExp = 0;
8381 fis->d.lbaMidExp = 0;
8382 fis->d.lbaHighExp = 0;
8383 fis->d.featuresExp = 0;
8384 fis->d.sectorCount = scsiCmnd->cdb[9]; /* FIS sector count (7:0) */
8385 fis->d.sectorCountExp = 0;
8386 fis->d.reserved4 = 0;
8387 fis->d.control = 0; /* FIS HOB bit clear */
8388 fis->d.reserved5 = 0;
8389
8390 agRequestType = AGSA_SATA_PROTOCOL_NON_DATA;
8391 satIOContext->ATACmd = SAT_READ_VERIFY_SECTORS;
8392
8393 }
8394
8395 satIOContext->currentLBA = lba;
8396 satIOContext->OrgTL = tl;
8397
8398 /*
8399 computing number of loop and remainder for tl
8400 0xFF in case not ext
8401 0xFFFF in case EXT
8402 */
8403 if (fis->h.command == SAT_READ_VERIFY_SECTORS)
8404 {
8405 LoopNum = satComputeLoopNum(tl, 0xFF);
8406 }
8407 else if (fis->h.command == SAT_READ_VERIFY_SECTORS_EXT)
8408 {
8409 /* SAT_READ_SECTORS_EXT, SAT_READ_DMA_EXT */
8410 LoopNum = satComputeLoopNum(tl, 0xFFFF);
8411 }
8412 else
8413 {
8414 TI_DBG1(("satVerify12: error case 1!!!\n"));
8415 LoopNum = 1;
8416 }
8417
8418 satIOContext->LoopNum = LoopNum;
8419
8420 if (LoopNum == 1)
8421 {
8422 TI_DBG5(("satVerify12: NON CHAINED data\n"));
8423 /* Initialize CB for SATA completion.
8424 */
8425 satIOContext->satCompleteCB = &satNonChainedVerifyCB;
8426 }
8427 else
8428 {
8429 TI_DBG1(("satVerify12: CHAINED data\n"));
8430 /* re-setting tl */
8431 if (fis->h.command == SAT_READ_VERIFY_SECTORS)
8432 {
8433 fis->d.sectorCount = 0xFF;
8434 }
8435 else if (fis->h.command == SAT_READ_VERIFY_SECTORS_EXT)
8436 {
8437 fis->d.sectorCount = 0xFF;
8438 fis->d.sectorCountExp = 0xFF;
8439 }
8440 else
8441 {
8442 TI_DBG1(("satVerify10: error case 2!!!\n"));
8443 }
8444
8445 /* Initialize CB for SATA completion.
8446 */
8447 satIOContext->satCompleteCB = &satChainedVerifyCB;
8448 }
8449
8450
8451 /*
8452 * Prepare SGL and send FIS to LL layer.
8453 */
8454 satIOContext->reqType = agRequestType; /* Save it */
8455
8456 status = sataLLIOStart( tiRoot,
8457 tiIORequest,
8458 tiDeviceHandle,
8459 tiScsiRequest,
8460 satIOContext);
8461 return (status);
8462 }
8463 /*****************************************************************************/
8464 /*! \brief SAT implementation for SCSI VERIFY (16).
8465 *
8466 * SAT implementation for SCSI VERIFY (16).
8467 *
8468 * \param tiRoot: Pointer to TISA initiator driver/port instance.
8469 * \param tiIORequest: Pointer to TISA I/O request context for this I/O.
8470 * \param tiDeviceHandle: Pointer to TISA device handle for this I/O.
8471 * \param tiScsiRequest: Pointer to TISA SCSI I/O request and SGL list.
8472 * \param satIOContext_t: Pointer to the SAT IO Context
8473 *
8474 * \return If command is started successfully
8475 * - \e tiSuccess: I/O request successfully initiated.
8476 * - \e tiBusy: No resources available, try again later.
8477 * - \e tiIONoDevice: Invalid device handle.
8478 * - \e tiError: Other errors.
8479 */
8480 /*****************************************************************************/
satVerify16(tiRoot_t * tiRoot,tiIORequest_t * tiIORequest,tiDeviceHandle_t * tiDeviceHandle,tiScsiInitiatorRequest_t * tiScsiRequest,satIOContext_t * satIOContext)8481 GLOBAL bit32 satVerify16(
8482 tiRoot_t *tiRoot,
8483 tiIORequest_t *tiIORequest,
8484 tiDeviceHandle_t *tiDeviceHandle,
8485 tiScsiInitiatorRequest_t *tiScsiRequest,
8486 satIOContext_t *satIOContext)
8487 {
8488 /*
8489 For simple implementation,
8490 no byte comparison supported as of 4/5/06
8491 */
8492 scsiRspSense_t *pSense;
8493 tiIniScsiCmnd_t *scsiCmnd;
8494 satDeviceData_t *pSatDevData;
8495 agsaFisRegHostToDevice_t *fis;
8496 bit32 status;
8497 bit32 agRequestType = AGSA_SATA_PROTOCOL_NON_DATA;
8498 bit32 lba = 0;
8499 bit32 tl = 0;
8500 bit32 LoopNum = 1;
8501 bit8 LBA[8];
8502 bit8 TL[8];
8503 bit32 rangeChk = agFALSE; /* lba and tl range check */
8504 bit32 limitChk = agFALSE; /* lba and tl range check */
8505
8506 TI_DBG5(("satVerify16 entry: tiDeviceHandle=%p tiIORequest=%p\n",
8507 tiDeviceHandle, tiIORequest));
8508
8509 pSense = satIOContext->pSense;
8510 scsiCmnd = &tiScsiRequest->scsiCmnd;
8511 pSatDevData = satIOContext->pSatDevData;
8512 fis = satIOContext->pFis;
8513
8514 /* checking BYTCHK */
8515 if (scsiCmnd->cdb[1] & SCSI_VERIFY_BYTCHK_MASK)
8516 {
8517 /*
8518 should do the byte check
8519 but not supported in this version
8520 */
8521 satSetSensePayload( pSense,
8522 SCSI_SNSKEY_ILLEGAL_REQUEST,
8523 0,
8524 SCSI_SNSCODE_INVALID_FIELD_IN_CDB,
8525 satIOContext);
8526
8527 ostiInitiatorIOCompleted( tiRoot,
8528 tiIORequest,
8529 tiIOSuccess,
8530 SCSI_STAT_CHECK_CONDITION,
8531 satIOContext->pTiSenseData,
8532 satIOContext->interruptContext );
8533
8534 TI_DBG1(("satVerify16: no byte checking \n"));
8535 return tiSuccess;
8536 }
8537
8538 /* checking CONTROL */
8539 /* NACA == 1 or LINK == 1*/
8540 if ( (scsiCmnd->cdb[15] & SCSI_NACA_MASK) || (scsiCmnd->cdb[15] & SCSI_LINK_MASK) )
8541 {
8542 satSetSensePayload( pSense,
8543 SCSI_SNSKEY_ILLEGAL_REQUEST,
8544 0,
8545 SCSI_SNSCODE_INVALID_FIELD_IN_CDB,
8546 satIOContext);
8547
8548 ostiInitiatorIOCompleted( tiRoot,
8549 tiIORequest,
8550 tiIOSuccess,
8551 SCSI_STAT_CHECK_CONDITION,
8552 satIOContext->pTiSenseData,
8553 satIOContext->interruptContext );
8554
8555 TI_DBG2(("satVerify16: return control\n"));
8556 return tiSuccess;
8557 }
8558
8559 osti_memset(LBA, 0, sizeof(LBA));
8560 osti_memset(TL, 0, sizeof(TL));
8561
8562
8563 /* do not use memcpy due to indexing in LBA and TL */
8564 LBA[0] = scsiCmnd->cdb[2]; /* MSB */
8565 LBA[1] = scsiCmnd->cdb[3];
8566 LBA[2] = scsiCmnd->cdb[4];
8567 LBA[3] = scsiCmnd->cdb[5];
8568 LBA[4] = scsiCmnd->cdb[6];
8569 LBA[5] = scsiCmnd->cdb[7];
8570 LBA[6] = scsiCmnd->cdb[8];
8571 LBA[7] = scsiCmnd->cdb[9]; /* LSB */
8572
8573 TL[0] = 0;
8574 TL[1] = 0;
8575 TL[2] = 0;
8576 TL[3] = 0;
8577 TL[4] = scsiCmnd->cdb[10]; /* MSB */
8578 TL[5] = scsiCmnd->cdb[11];
8579 TL[6] = scsiCmnd->cdb[12];
8580 TL[7] = scsiCmnd->cdb[13]; /* LSB */
8581
8582 rangeChk = satAddNComparebit64(LBA, TL);
8583
8584 limitChk = satCompareLBALimitbit(LBA);
8585
8586 lba = satComputeCDB16LBA(satIOContext);
8587 tl = satComputeCDB16TL(satIOContext);
8588
8589 if (pSatDevData->satNCQ != agTRUE &&
8590 pSatDevData->sat48BitSupport != agTRUE
8591 )
8592 {
8593 if (limitChk)
8594 {
8595 TI_DBG1(("satVerify16: return LBA out of range, not EXT\n"));
8596 satSetSensePayload( pSense,
8597 SCSI_SNSKEY_ILLEGAL_REQUEST,
8598 0,
8599 SCSI_SNSCODE_LOGICAL_BLOCK_ADDRESS_OUT_OF_RANGE,
8600 satIOContext);
8601
8602 ostiInitiatorIOCompleted( tiRoot,
8603 tiIORequest,
8604 tiIOSuccess,
8605 SCSI_STAT_CHECK_CONDITION,
8606 satIOContext->pTiSenseData,
8607 satIOContext->interruptContext );
8608
8609 return tiSuccess;
8610 }
8611 if (rangeChk) // if (lba + tl > SAT_TR_LBA_LIMIT)
8612 {
8613 TI_DBG1(("satVerify16: return LBA+TL out of range, not EXT\n"));
8614 satSetSensePayload( pSense,
8615 SCSI_SNSKEY_ILLEGAL_REQUEST,
8616 0,
8617 SCSI_SNSCODE_LOGICAL_BLOCK_ADDRESS_OUT_OF_RANGE,
8618 satIOContext);
8619
8620 ostiInitiatorIOCompleted( tiRoot,
8621 tiIORequest,
8622 tiIOSuccess,
8623 SCSI_STAT_CHECK_CONDITION,
8624 satIOContext->pTiSenseData,
8625 satIOContext->interruptContext );
8626
8627 return tiSuccess;
8628 }
8629 }
8630
8631 if (pSatDevData->sat48BitSupport == agTRUE)
8632 {
8633 TI_DBG5(("satVerify16: SAT_READ_VERIFY_SECTORS_EXT\n"));
8634 fis->h.fisType = 0x27; /* Reg host to device */
8635 fis->h.c_pmPort = 0x80; /* C Bit is set */
8636
8637 fis->h.command = SAT_READ_VERIFY_SECTORS_EXT;/* 0x42 */
8638 fis->h.features = 0; /* FIS reserve */
8639 fis->d.lbaLow = scsiCmnd->cdb[9]; /* FIS LBA (7 :0 ) */
8640 fis->d.lbaMid = scsiCmnd->cdb[8]; /* FIS LBA (15:8 ) */
8641 fis->d.lbaHigh = scsiCmnd->cdb[7]; /* FIS LBA (23:16) */
8642 fis->d.device = 0x40; /* FIS LBA mode set 01000000 */
8643 fis->d.lbaLowExp = scsiCmnd->cdb[6]; /* FIS LBA (31:24) */
8644 fis->d.lbaMidExp = scsiCmnd->cdb[5]; /* FIS LBA (39:32) */
8645 fis->d.lbaHighExp = scsiCmnd->cdb[4]; /* FIS LBA (47:40) */
8646 fis->d.featuresExp = 0; /* FIS reserve */
8647 fis->d.sectorCount = scsiCmnd->cdb[13]; /* FIS sector count (7:0) */
8648 fis->d.sectorCountExp = scsiCmnd->cdb[12]; /* FIS sector count (15:8) */
8649
8650 fis->d.reserved4 = 0;
8651 fis->d.control = 0; /* FIS HOB bit clear */
8652 fis->d.reserved5 = 0;
8653
8654 agRequestType = AGSA_SATA_PROTOCOL_NON_DATA;
8655 satIOContext->ATACmd = SAT_READ_VERIFY_SECTORS_EXT;
8656 }
8657 else
8658 {
8659 TI_DBG5(("satVerify12: SAT_READ_VERIFY_SECTORS\n"));
8660 fis->h.fisType = 0x27; /* Reg host to device */
8661 fis->h.c_pmPort = 0x80; /* C bit is set */
8662 fis->h.command = SAT_READ_VERIFY_SECTORS; /* 0x40 */
8663 fis->h.features = 0; /* FIS reserve */
8664 fis->d.lbaLow = scsiCmnd->cdb[9]; /* FIS LBA (7 :0 ) */
8665 fis->d.lbaMid = scsiCmnd->cdb[8]; /* FIS LBA (15:8 ) */
8666 fis->d.lbaHigh = scsiCmnd->cdb[7]; /* FIS LBA (23:16) */
8667 /* FIS LBA mode set LBA (27:24) */
8668 fis->d.device = (bit8)((0x4 << 4) | (scsiCmnd->cdb[6] & 0xF));
8669 fis->d.lbaLowExp = 0;
8670 fis->d.lbaMidExp = 0;
8671 fis->d.lbaHighExp = 0;
8672 fis->d.featuresExp = 0;
8673 fis->d.sectorCount = scsiCmnd->cdb[13]; /* FIS sector count (7:0) */
8674 fis->d.sectorCountExp = 0;
8675 fis->d.reserved4 = 0;
8676 fis->d.control = 0; /* FIS HOB bit clear */
8677 fis->d.reserved5 = 0;
8678
8679 agRequestType = AGSA_SATA_PROTOCOL_NON_DATA;
8680 satIOContext->ATACmd = SAT_READ_VERIFY_SECTORS;
8681
8682 }
8683
8684 satIOContext->currentLBA = lba;
8685 satIOContext->OrgTL = tl;
8686
8687 /*
8688 computing number of loop and remainder for tl
8689 0xFF in case not ext
8690 0xFFFF in case EXT
8691 */
8692 if (fis->h.command == SAT_READ_VERIFY_SECTORS)
8693 {
8694 LoopNum = satComputeLoopNum(tl, 0xFF);
8695 }
8696 else if (fis->h.command == SAT_READ_VERIFY_SECTORS_EXT)
8697 {
8698 /* SAT_READ_SECTORS_EXT, SAT_READ_DMA_EXT */
8699 LoopNum = satComputeLoopNum(tl, 0xFFFF);
8700 }
8701 else
8702 {
8703 TI_DBG1(("satVerify12: error case 1!!!\n"));
8704 LoopNum = 1;
8705 }
8706
8707 satIOContext->LoopNum = LoopNum;
8708
8709 if (LoopNum == 1)
8710 {
8711 TI_DBG5(("satVerify12: NON CHAINED data\n"));
8712 /* Initialize CB for SATA completion.
8713 */
8714 satIOContext->satCompleteCB = &satNonChainedVerifyCB;
8715 }
8716 else
8717 {
8718 TI_DBG1(("satVerify12: CHAINED data\n"));
8719 /* re-setting tl */
8720 if (fis->h.command == SAT_READ_VERIFY_SECTORS)
8721 {
8722 fis->d.sectorCount = 0xFF;
8723 }
8724 else if (fis->h.command == SAT_READ_VERIFY_SECTORS_EXT)
8725 {
8726 fis->d.sectorCount = 0xFF;
8727 fis->d.sectorCountExp = 0xFF;
8728 }
8729 else
8730 {
8731 TI_DBG1(("satVerify10: error case 2!!!\n"));
8732 }
8733
8734 /* Initialize CB for SATA completion.
8735 */
8736 satIOContext->satCompleteCB = &satChainedVerifyCB;
8737 }
8738
8739
8740 /*
8741 * Prepare SGL and send FIS to LL layer.
8742 */
8743 satIOContext->reqType = agRequestType; /* Save it */
8744
8745 status = sataLLIOStart( tiRoot,
8746 tiIORequest,
8747 tiDeviceHandle,
8748 tiScsiRequest,
8749 satIOContext);
8750 return (status);
8751 }
8752 /*****************************************************************************/
8753 /*! \brief SAT implementation for SCSI satFormatUnit.
8754 *
8755 * SAT implementation for SCSI satFormatUnit.
8756 *
8757 * \param tiRoot: Pointer to TISA initiator driver/port instance.
8758 * \param tiIORequest: Pointer to TISA I/O request context for this I/O.
8759 * \param tiDeviceHandle: Pointer to TISA device handle for this I/O.
8760 * \param tiScsiRequest: Pointer to TISA SCSI I/O request and SGL list.
8761 * \param satIOContext_t: Pointer to the SAT IO Context
8762 *
8763 * \return If command is started successfully
8764 * - \e tiSuccess: I/O request successfully initiated.
8765 * - \e tiBusy: No resources available, try again later.
8766 * - \e tiIONoDevice: Invalid device handle.
8767 * - \e tiError: Other errors.
8768 */
8769 /*****************************************************************************/
satFormatUnit(tiRoot_t * tiRoot,tiIORequest_t * tiIORequest,tiDeviceHandle_t * tiDeviceHandle,tiScsiInitiatorRequest_t * tiScsiRequest,satIOContext_t * satIOContext)8770 GLOBAL bit32 satFormatUnit(
8771 tiRoot_t *tiRoot,
8772 tiIORequest_t *tiIORequest,
8773 tiDeviceHandle_t *tiDeviceHandle,
8774 tiScsiInitiatorRequest_t *tiScsiRequest,
8775 satIOContext_t *satIOContext)
8776 {
8777 /*
8778 note: we don't support media certification in this version and IP bit
8779 satDevData->satFormatState will be agFalse since SAT does not actually sends
8780 any ATA command
8781 */
8782
8783 scsiRspSense_t *pSense;
8784 tiIniScsiCmnd_t *scsiCmnd;
8785 bit32 index = 0;
8786
8787 pSense = satIOContext->pSense;
8788 scsiCmnd = &tiScsiRequest->scsiCmnd;
8789
8790 TI_DBG5(("satFormatUnit:start\n"));
8791
8792 /*
8793 checking opcode
8794 1. FMTDATA bit == 0(no defect list header)
8795 2. FMTDATA bit == 1 and DCRT bit == 1(defect list header is provided
8796 with DCRT bit set)
8797 */
8798 if ( ((scsiCmnd->cdb[1] & SCSI_FORMAT_UNIT_FMTDATA_MASK) == 0) ||
8799 ((scsiCmnd->cdb[1] & SCSI_FORMAT_UNIT_FMTDATA_MASK) &&
8800 (scsiCmnd->cdb[7] & SCSI_FORMAT_UNIT_DCRT_MASK))
8801 )
8802 {
8803 ostiInitiatorIOCompleted( tiRoot,
8804 tiIORequest,
8805 tiIOSuccess,
8806 SCSI_STAT_GOOD,
8807 agNULL,
8808 satIOContext->interruptContext);
8809
8810 TI_DBG2(("satFormatUnit: return opcode\n"));
8811 return tiSuccess;
8812 }
8813
8814 /*
8815 checking DEFECT LIST FORMAT and defect list length
8816 */
8817 if ( (((scsiCmnd->cdb[1] & SCSI_FORMAT_UNIT_DEFECT_LIST_FORMAT_MASK) == 0x00) ||
8818 ((scsiCmnd->cdb[1] & SCSI_FORMAT_UNIT_DEFECT_LIST_FORMAT_MASK) == 0x06)) )
8819 {
8820 /* short parameter header */
8821 if ((scsiCmnd->cdb[2] & SCSI_FORMAT_UNIT_LONGLIST_MASK) == 0x00)
8822 {
8823 index = 8;
8824 }
8825 /* long parameter header */
8826 if ((scsiCmnd->cdb[2] & SCSI_FORMAT_UNIT_LONGLIST_MASK) == 0x01)
8827 {
8828 index = 10;
8829 }
8830 /* defect list length */
8831 if ((scsiCmnd->cdb[index] != 0) || (scsiCmnd->cdb[index+1] != 0))
8832 {
8833 satSetSensePayload( pSense,
8834 SCSI_SNSKEY_ILLEGAL_REQUEST,
8835 0,
8836 SCSI_SNSCODE_INVALID_FIELD_IN_CDB,
8837 satIOContext);
8838
8839 ostiInitiatorIOCompleted( tiRoot,
8840 tiIORequest,
8841 tiIOSuccess,
8842 SCSI_STAT_CHECK_CONDITION,
8843 satIOContext->pTiSenseData,
8844 satIOContext->interruptContext );
8845
8846 TI_DBG1(("satFormatUnit: return defect list format\n"));
8847 return tiSuccess;
8848 }
8849 }
8850
8851 /* FMTDATA == 1 && CMPLIST == 1*/
8852 if ( (scsiCmnd->cdb[1] & SCSI_FORMAT_UNIT_FMTDATA_MASK) &&
8853 (scsiCmnd->cdb[1] & SCSI_FORMAT_UNIT_CMPLIST_MASK) )
8854 {
8855 satSetSensePayload( pSense,
8856 SCSI_SNSKEY_ILLEGAL_REQUEST,
8857 0,
8858 SCSI_SNSCODE_INVALID_FIELD_IN_CDB,
8859 satIOContext);
8860
8861 ostiInitiatorIOCompleted( tiRoot,
8862 tiIORequest,
8863 tiIOSuccess,
8864 SCSI_STAT_CHECK_CONDITION,
8865 satIOContext->pTiSenseData,
8866 satIOContext->interruptContext );
8867
8868 TI_DBG1(("satFormatUnit: return cmplist\n"));
8869 return tiSuccess;
8870
8871 }
8872
8873 if ( (scsiCmnd->cdb[5] & SCSI_NACA_MASK) || (scsiCmnd->cdb[5] & SCSI_LINK_MASK) )
8874 {
8875 satSetSensePayload( pSense,
8876 SCSI_SNSKEY_ILLEGAL_REQUEST,
8877 0,
8878 SCSI_SNSCODE_INVALID_FIELD_IN_CDB,
8879 satIOContext);
8880
8881 ostiInitiatorIOCompleted( tiRoot,
8882 tiIORequest,
8883 tiIOSuccess,
8884 SCSI_STAT_CHECK_CONDITION,
8885 satIOContext->pTiSenseData,
8886 satIOContext->interruptContext );
8887
8888 TI_DBG1(("satFormatUnit: return control\n"));
8889 return tiSuccess;
8890 }
8891
8892 /* defect list header filed, if exists, SAT rev8, Table 37, p48 */
8893 if (scsiCmnd->cdb[1] & SCSI_FORMAT_UNIT_FMTDATA_MASK)
8894 {
8895 /* case 1,2,3 */
8896 /* IMMED 1; FOV 0; FOV 1, DCRT 1, IP 0 */
8897 if ( (scsiCmnd->cdb[7] & SCSI_FORMAT_UNIT_IMMED_MASK) ||
8898 ( !(scsiCmnd->cdb[7] & SCSI_FORMAT_UNIT_FOV_MASK)) ||
8899 ( (scsiCmnd->cdb[7] & SCSI_FORMAT_UNIT_FOV_MASK) &&
8900 (scsiCmnd->cdb[7] & SCSI_FORMAT_UNIT_DCRT_MASK) &&
8901 !(scsiCmnd->cdb[7] & SCSI_FORMAT_UNIT_IP_MASK))
8902 )
8903 {
8904 ostiInitiatorIOCompleted( tiRoot,
8905 tiIORequest,
8906 tiIOSuccess,
8907 SCSI_STAT_GOOD,
8908 agNULL,
8909 satIOContext->interruptContext);
8910
8911 TI_DBG5(("satFormatUnit: return defect list case 1\n"));
8912 return tiSuccess;
8913 }
8914 /* case 4,5,6 */
8915 /*
8916 1. IMMED 0, FOV 1, DCRT 0, IP 0
8917 2. IMMED 0, FOV 1, DCRT 0, IP 1
8918 3. IMMED 0, FOV 1, DCRT 1, IP 1
8919 */
8920
8921 if ( ( !(scsiCmnd->cdb[7] & SCSI_FORMAT_UNIT_IMMED_MASK) &&
8922 (scsiCmnd->cdb[7] & SCSI_FORMAT_UNIT_FOV_MASK) &&
8923 !(scsiCmnd->cdb[7] & SCSI_FORMAT_UNIT_DCRT_MASK) &&
8924 !(scsiCmnd->cdb[7] & SCSI_FORMAT_UNIT_IP_MASK) )
8925 ||
8926 ( !(scsiCmnd->cdb[7] & SCSI_FORMAT_UNIT_IMMED_MASK) &&
8927 (scsiCmnd->cdb[7] & SCSI_FORMAT_UNIT_FOV_MASK) &&
8928 !(scsiCmnd->cdb[7] & SCSI_FORMAT_UNIT_DCRT_MASK) &&
8929 (scsiCmnd->cdb[7] & SCSI_FORMAT_UNIT_IP_MASK) )
8930 ||
8931 ( !(scsiCmnd->cdb[7] & SCSI_FORMAT_UNIT_IMMED_MASK) &&
8932 (scsiCmnd->cdb[7] & SCSI_FORMAT_UNIT_FOV_MASK) &&
8933 (scsiCmnd->cdb[7] & SCSI_FORMAT_UNIT_DCRT_MASK) &&
8934 (scsiCmnd->cdb[7] & SCSI_FORMAT_UNIT_IP_MASK) )
8935 )
8936 {
8937
8938 satSetSensePayload( pSense,
8939 SCSI_SNSKEY_ILLEGAL_REQUEST,
8940 0,
8941 SCSI_SNSCODE_INVALID_FIELD_PARAMETER_LIST,
8942 satIOContext);
8943
8944 ostiInitiatorIOCompleted( tiRoot,
8945 tiIORequest,
8946 tiIOSuccess,
8947 SCSI_STAT_CHECK_CONDITION,
8948 satIOContext->pTiSenseData,
8949 satIOContext->interruptContext );
8950
8951 TI_DBG5(("satFormatUnit: return defect list case 2\n"));
8952 return tiSuccess;
8953
8954 }
8955 }
8956
8957
8958 /*
8959 * Send the completion response now.
8960 */
8961 ostiInitiatorIOCompleted( tiRoot,
8962 tiIORequest,
8963 tiIOSuccess,
8964 SCSI_STAT_GOOD,
8965 agNULL,
8966 satIOContext->interruptContext);
8967
8968 TI_DBG5(("satFormatUnit: return last\n"));
8969 return tiSuccess;
8970 }
8971
8972
8973 /*****************************************************************************/
8974 /*! \brief SAT implementation for SCSI satSendDiagnostic.
8975 *
8976 * SAT implementation for SCSI satSendDiagnostic.
8977 *
8978 * \param tiRoot: Pointer to TISA initiator driver/port instance.
8979 * \param tiIORequest: Pointer to TISA I/O request context for this I/O.
8980 * \param tiDeviceHandle: Pointer to TISA device handle for this I/O.
8981 * \param tiScsiRequest: Pointer to TISA SCSI I/O request and SGL list.
8982 * \param satIOContext_t: Pointer to the SAT IO Context
8983 *
8984 * \return If command is started successfully
8985 * - \e tiSuccess: I/O request successfully initiated.
8986 * - \e tiBusy: No resources available, try again later.
8987 * - \e tiIONoDevice: Invalid device handle.
8988 * - \e tiError: Other errors.
8989 */
8990 /*****************************************************************************/
satSendDiagnostic(tiRoot_t * tiRoot,tiIORequest_t * tiIORequest,tiDeviceHandle_t * tiDeviceHandle,tiScsiInitiatorRequest_t * tiScsiRequest,satIOContext_t * satIOContext)8991 GLOBAL bit32 satSendDiagnostic(
8992 tiRoot_t *tiRoot,
8993 tiIORequest_t *tiIORequest,
8994 tiDeviceHandle_t *tiDeviceHandle,
8995 tiScsiInitiatorRequest_t *tiScsiRequest,
8996 satIOContext_t *satIOContext)
8997 {
8998 bit32 status;
8999 bit32 agRequestType;
9000 satDeviceData_t *pSatDevData;
9001 scsiRspSense_t *pSense;
9002 tiIniScsiCmnd_t *scsiCmnd;
9003 agsaFisRegHostToDevice_t *fis;
9004 bit32 parmLen;
9005
9006 pSense = satIOContext->pSense;
9007 pSatDevData = satIOContext->pSatDevData;
9008 scsiCmnd = &tiScsiRequest->scsiCmnd;
9009 fis = satIOContext->pFis;
9010
9011 TI_DBG5(("satSendDiagnostic:start\n"));
9012
9013 /* reset satVerifyState */
9014 pSatDevData->satVerifyState = 0;
9015 /* no pending diagnostic in background */
9016 pSatDevData->satBGPendingDiag = agFALSE;
9017
9018 /* table 27, 8.10 p39 SAT Rev8 */
9019 /*
9020 1. checking PF == 1
9021 2. checking DEVOFFL == 1
9022 3. checking UNITOFFL == 1
9023 4. checking PARAMETER LIST LENGTH != 0
9024
9025 */
9026 if ( (scsiCmnd->cdb[1] & SCSI_PF_MASK) ||
9027 (scsiCmnd->cdb[1] & SCSI_DEVOFFL_MASK) ||
9028 (scsiCmnd->cdb[1] & SCSI_UNITOFFL_MASK) ||
9029 ( (scsiCmnd->cdb[3] != 0) || (scsiCmnd->cdb[4] != 0) )
9030 )
9031 {
9032 satSetSensePayload( pSense,
9033 SCSI_SNSKEY_ILLEGAL_REQUEST,
9034 0,
9035 SCSI_SNSCODE_INVALID_FIELD_IN_CDB,
9036 satIOContext);
9037
9038 ostiInitiatorIOCompleted( tiRoot,
9039 tiIORequest,
9040 tiIOSuccess,
9041 SCSI_STAT_CHECK_CONDITION,
9042 satIOContext->pTiSenseData,
9043 satIOContext->interruptContext );
9044
9045 TI_DBG1(("satSendDiagnostic: return PF, DEVOFFL, UNITOFFL, PARAM LIST\n"));
9046 return tiSuccess;
9047 }
9048
9049 /* checking CONTROL */
9050 /* NACA == 1 or LINK == 1*/
9051 if ( (scsiCmnd->cdb[5] & SCSI_NACA_MASK) || (scsiCmnd->cdb[5] & SCSI_LINK_MASK) )
9052 {
9053 satSetSensePayload( pSense,
9054 SCSI_SNSKEY_ILLEGAL_REQUEST,
9055 0,
9056 SCSI_SNSCODE_INVALID_FIELD_IN_CDB,
9057 satIOContext);
9058
9059 ostiInitiatorIOCompleted( tiRoot,
9060 tiIORequest,
9061 tiIOSuccess,
9062 SCSI_STAT_CHECK_CONDITION,
9063 satIOContext->pTiSenseData,
9064 satIOContext->interruptContext );
9065
9066 TI_DBG2(("satSendDiagnostic: return control\n"));
9067 return tiSuccess;
9068 }
9069
9070 parmLen = (scsiCmnd->cdb[3] << 8) + scsiCmnd->cdb[4];
9071
9072 /* checking SELFTEST bit*/
9073 /* table 29, 8.10.3, p41 SAT Rev8 */
9074 /* case 1 */
9075 if ( !(scsiCmnd->cdb[1] & SCSI_SEND_DIAGNOSTIC_SELFTEST_MASK) &&
9076 (pSatDevData->satSMARTSelfTest == agFALSE)
9077 )
9078 {
9079 satSetSensePayload( pSense,
9080 SCSI_SNSKEY_ILLEGAL_REQUEST,
9081 0,
9082 SCSI_SNSCODE_INVALID_FIELD_IN_CDB,
9083 satIOContext);
9084
9085 ostiInitiatorIOCompleted( tiRoot,
9086 tiIORequest,
9087 tiIOSuccess,
9088 SCSI_STAT_CHECK_CONDITION,
9089 satIOContext->pTiSenseData,
9090 satIOContext->interruptContext );
9091
9092 TI_DBG1(("satSendDiagnostic: return Table 29 case 1\n"));
9093 return tiSuccess;
9094 }
9095
9096 /* case 2 */
9097 if ( !(scsiCmnd->cdb[1] & SCSI_SEND_DIAGNOSTIC_SELFTEST_MASK) &&
9098 (pSatDevData->satSMARTSelfTest == agTRUE) &&
9099 (pSatDevData->satSMARTEnabled == agFALSE)
9100 )
9101 {
9102 satSetSensePayload( pSense,
9103 SCSI_SNSKEY_ABORTED_COMMAND,
9104 0,
9105 SCSI_SNSCODE_ATA_DEVICE_FEATURE_NOT_ENABLED,
9106 satIOContext);
9107
9108 ostiInitiatorIOCompleted( tiRoot,
9109 tiIORequest,
9110 tiIOSuccess,
9111 SCSI_STAT_CHECK_CONDITION,
9112 satIOContext->pTiSenseData,
9113 satIOContext->interruptContext );
9114
9115 TI_DBG5(("satSendDiagnostic: return Table 29 case 2\n"));
9116 return tiSuccess;
9117 }
9118 /*
9119 case 3
9120 see SELF TEST CODE later
9121 */
9122
9123
9124
9125 /* case 4 */
9126
9127 /*
9128 sends three ATA verify commands
9129
9130 */
9131 if ( ((scsiCmnd->cdb[1] & SCSI_SEND_DIAGNOSTIC_SELFTEST_MASK) &&
9132 (pSatDevData->satSMARTSelfTest == agFALSE))
9133 ||
9134 ((scsiCmnd->cdb[1] & SCSI_SEND_DIAGNOSTIC_SELFTEST_MASK) &&
9135 (pSatDevData->satSMARTSelfTest == agTRUE) &&
9136 (pSatDevData->satSMARTEnabled == agFALSE))
9137 )
9138 {
9139 /*
9140 sector count 1, LBA 0
9141 sector count 1, LBA MAX
9142 sector count 1, LBA random
9143 */
9144 if (pSatDevData->sat48BitSupport == agTRUE)
9145 {
9146 /* sends READ VERIFY SECTOR(S) EXT*/
9147 fis->h.fisType = 0x27; /* Reg host to device */
9148 fis->h.c_pmPort = 0x80; /* C Bit is set */
9149 fis->h.command = SAT_READ_VERIFY_SECTORS_EXT;/* 0x42 */
9150 fis->h.features = 0; /* FIS reserve */
9151 fis->d.lbaLow = 0; /* FIS LBA (7 :0 ) */
9152 fis->d.lbaMid = 0; /* FIS LBA (15:8 ) */
9153 fis->d.lbaHigh = 0; /* FIS LBA (23:16) */
9154 fis->d.lbaLowExp = 0; /* FIS LBA (31:24) */
9155 fis->d.lbaMidExp = 0; /* FIS LBA (39:32) */
9156 fis->d.lbaHighExp = 0; /* FIS LBA (47:40) */
9157 fis->d.featuresExp = 0; /* FIS reserve */
9158 fis->d.sectorCount = 1; /* FIS sector count (7:0) */
9159 fis->d.sectorCountExp = 0; /* FIS sector count (15:8) */
9160 fis->d.reserved4 = 0;
9161 fis->d.device = 0x40; /* 01000000 */
9162 fis->d.control = 0; /* FIS HOB bit clear */
9163 fis->d.reserved5 = 0;
9164
9165 agRequestType = AGSA_SATA_PROTOCOL_NON_DATA;
9166 }
9167 else
9168 {
9169 /* READ VERIFY SECTOR(S)*/
9170 fis->h.fisType = 0x27; /* Reg host to device */
9171 fis->h.c_pmPort = 0x80; /* C Bit is set */
9172 fis->h.command = SAT_READ_VERIFY_SECTORS;/* 0x40 */
9173 fis->h.features = 0; /* FIS features NA */
9174 fis->d.lbaLow = 0; /* FIS LBA (7 :0 ) */
9175 fis->d.lbaMid = 0; /* FIS LBA (15:8 ) */
9176 fis->d.lbaHigh = 0; /* FIS LBA (23:16) */
9177 fis->d.lbaLowExp = 0;
9178 fis->d.lbaMidExp = 0;
9179 fis->d.lbaHighExp = 0;
9180 fis->d.featuresExp = 0;
9181 fis->d.sectorCount = 1; /* FIS sector count (7:0) */
9182 fis->d.sectorCountExp = 0;
9183 fis->d.reserved4 = 0;
9184 fis->d.device = 0x40; /* 01000000 */
9185 fis->d.control = 0; /* FIS HOB bit clear */
9186 fis->d.reserved5 = 0;
9187
9188 agRequestType = AGSA_SATA_PROTOCOL_NON_DATA;
9189 }
9190
9191 /* Initialize CB for SATA completion.
9192 */
9193 satIOContext->satCompleteCB = &satSendDiagnosticCB;
9194
9195 /*
9196 * Prepare SGL and send FIS to LL layer.
9197 */
9198 satIOContext->reqType = agRequestType; /* Save it */
9199
9200 status = sataLLIOStart( tiRoot,
9201 tiIORequest,
9202 tiDeviceHandle,
9203 tiScsiRequest,
9204 satIOContext);
9205
9206
9207 TI_DBG5(("satSendDiagnostic: return Table 29 case 4\n"));
9208 return (status);
9209 }
9210 /* case 5 */
9211 if ( (scsiCmnd->cdb[1] & SCSI_SEND_DIAGNOSTIC_SELFTEST_MASK) &&
9212 (pSatDevData->satSMARTSelfTest == agTRUE) &&
9213 (pSatDevData->satSMARTEnabled == agTRUE)
9214 )
9215 {
9216 /* sends SMART EXECUTE OFF-LINE IMMEDIATE */
9217 fis->h.fisType = 0x27; /* Reg host to device */
9218 fis->h.c_pmPort = 0x80; /* C Bit is set */
9219 fis->h.command = SAT_SMART_EXEUTE_OFF_LINE_IMMEDIATE;/* 0xB0 */
9220 fis->h.features = 0xD4; /* FIS features NA */
9221 fis->d.lbaLow = 0x81; /* FIS LBA (7 :0 ) */
9222 fis->d.lbaMid = 0x4F; /* FIS LBA (15:8 ) */
9223 fis->d.lbaHigh = 0xC2; /* FIS LBA (23:16) */
9224 fis->d.lbaLowExp = 0;
9225 fis->d.lbaMidExp = 0;
9226 fis->d.lbaHighExp = 0;
9227 fis->d.featuresExp = 0;
9228 fis->d.sectorCount = 0; /* FIS sector count (7:0) */
9229 fis->d.sectorCountExp = 0;
9230 fis->d.reserved4 = 0;
9231 fis->d.device = 0; /* FIS DEV is discared in SATA */
9232 fis->d.control = 0; /* FIS HOB bit clear */
9233 fis->d.reserved5 = 0;
9234
9235 agRequestType = AGSA_SATA_PROTOCOL_NON_DATA;
9236
9237 /* Initialize CB for SATA completion.
9238 */
9239 satIOContext->satCompleteCB = &satSendDiagnosticCB;
9240
9241 /*
9242 * Prepare SGL and send FIS to LL layer.
9243 */
9244 satIOContext->reqType = agRequestType; /* Save it */
9245
9246 status = sataLLIOStart( tiRoot,
9247 tiIORequest,
9248 tiDeviceHandle,
9249 tiScsiRequest,
9250 satIOContext);
9251
9252
9253 TI_DBG5(("satSendDiagnostic: return Table 29 case 5\n"));
9254 return (status);
9255 }
9256
9257
9258
9259
9260 /* SAT rev8 Table29 p41 case 3*/
9261 /* checking SELF TEST CODE*/
9262 if ( !(scsiCmnd->cdb[1] & SCSI_SEND_DIAGNOSTIC_SELFTEST_MASK) &&
9263 (pSatDevData->satSMARTSelfTest == agTRUE) &&
9264 (pSatDevData->satSMARTEnabled == agTRUE)
9265 )
9266 {
9267 /* SAT rev8 Table28 p40 */
9268 /* finding self-test code */
9269 switch ((scsiCmnd->cdb[1] & SCSI_SEND_DIAGNOSTIC_TEST_CODE_MASK) >> 5)
9270 {
9271 case 1:
9272 pSatDevData->satBGPendingDiag = agTRUE;
9273
9274 ostiInitiatorIOCompleted( tiRoot,
9275 tiIORequest,
9276 tiIOSuccess,
9277 SCSI_STAT_GOOD,
9278 agNULL,
9279 satIOContext->interruptContext );
9280 /* sends SMART EXECUTE OFF-LINE IMMEDIATE */
9281 fis->h.fisType = 0x27; /* Reg host to device */
9282 fis->h.c_pmPort = 0x80; /* C Bit is set */
9283 fis->h.command = SAT_SMART_EXEUTE_OFF_LINE_IMMEDIATE;/* 0x40 */
9284 fis->h.features = 0xD4; /* FIS features NA */
9285 fis->d.lbaLow = 0x01; /* FIS LBA (7 :0 ) */
9286 fis->d.lbaMid = 0x4F; /* FIS LBA (15:8 ) */
9287 fis->d.lbaHigh = 0xC2; /* FIS LBA (23:16) */
9288
9289 fis->d.lbaLowExp = 0;
9290 fis->d.lbaMidExp = 0;
9291 fis->d.lbaHighExp = 0;
9292 fis->d.featuresExp = 0;
9293 fis->d.sectorCount = 0; /* FIS sector count (7:0) */
9294 fis->d.sectorCountExp = 0;
9295 fis->d.reserved4 = 0;
9296 fis->d.device = 0; /* FIS DEV is discared in SATA */
9297 fis->d.control = 0; /* FIS HOB bit clear */
9298 fis->d.reserved5 = 0;
9299
9300 agRequestType = AGSA_SATA_PROTOCOL_NON_DATA;
9301
9302 /* Initialize CB for SATA completion.
9303 */
9304 satIOContext->satCompleteCB = &satSendDiagnosticCB;
9305
9306 /*
9307 * Prepare SGL and send FIS to LL layer.
9308 */
9309 satIOContext->reqType = agRequestType; /* Save it */
9310
9311 status = sataLLIOStart( tiRoot,
9312 tiIORequest,
9313 tiDeviceHandle,
9314 tiScsiRequest,
9315 satIOContext);
9316
9317
9318 TI_DBG5(("satSendDiagnostic: return Table 28 case 1\n"));
9319 return (status);
9320 case 2:
9321 pSatDevData->satBGPendingDiag = agTRUE;
9322
9323 ostiInitiatorIOCompleted( tiRoot,
9324 tiIORequest,
9325 tiIOSuccess,
9326 SCSI_STAT_GOOD,
9327 agNULL,
9328 satIOContext->interruptContext );
9329
9330
9331 /* issuing SMART EXECUTE OFF-LINE IMMEDIATE */
9332 fis->h.fisType = 0x27; /* Reg host to device */
9333 fis->h.c_pmPort = 0x80; /* C Bit is set */
9334 fis->h.command = SAT_SMART_EXEUTE_OFF_LINE_IMMEDIATE;/* 0x40 */
9335 fis->h.features = 0xD4; /* FIS features NA */
9336 fis->d.lbaLow = 0x02; /* FIS LBA (7 :0 ) */
9337 fis->d.lbaMid = 0x4F; /* FIS LBA (15:8 ) */
9338 fis->d.lbaHigh = 0xC2; /* FIS LBA (23:16) */
9339 fis->d.lbaLowExp = 0;
9340 fis->d.lbaMidExp = 0;
9341 fis->d.lbaHighExp = 0;
9342 fis->d.featuresExp = 0;
9343 fis->d.sectorCount = 0; /* FIS sector count (7:0) */
9344 fis->d.sectorCountExp = 0;
9345 fis->d.reserved4 = 0;
9346 fis->d.device = 0; /* FIS DEV is discared in SATA */
9347 fis->d.control = 0; /* FIS HOB bit clear */
9348 fis->d.reserved5 = 0;
9349
9350 agRequestType = AGSA_SATA_PROTOCOL_NON_DATA;
9351
9352 /* Initialize CB for SATA completion.
9353 */
9354 satIOContext->satCompleteCB = &satSendDiagnosticCB;
9355
9356 /*
9357 * Prepare SGL and send FIS to LL layer.
9358 */
9359 satIOContext->reqType = agRequestType; /* Save it */
9360
9361 status = sataLLIOStart( tiRoot,
9362 tiIORequest,
9363 tiDeviceHandle,
9364 tiScsiRequest,
9365 satIOContext);
9366
9367
9368 TI_DBG5(("satSendDiagnostic: return Table 28 case 2\n"));
9369 return (status);
9370 case 4:
9371 /* For simplicity, no abort is supported
9372 Returns good status
9373 need a flag in device data for previously sent background Send Diagnostic
9374 */
9375 if (parmLen != 0)
9376 {
9377 /* check condition */
9378 satSetSensePayload( pSense,
9379 SCSI_SNSKEY_ILLEGAL_REQUEST,
9380 0,
9381 SCSI_SNSCODE_INVALID_FIELD_IN_CDB,
9382 satIOContext);
9383
9384 ostiInitiatorIOCompleted( tiRoot,
9385 tiIORequest,
9386 tiIOSuccess,
9387 SCSI_STAT_CHECK_CONDITION,
9388 satIOContext->pTiSenseData,
9389 satIOContext->interruptContext );
9390
9391 TI_DBG1(("satSendDiagnostic: case 4, non zero ParmLen %d\n", parmLen));
9392 return tiSuccess;
9393 }
9394 if (pSatDevData->satBGPendingDiag == agTRUE)
9395 {
9396 /* sends SMART EXECUTE OFF-LINE IMMEDIATE abort */
9397 fis->h.fisType = 0x27; /* Reg host to device */
9398 fis->h.c_pmPort = 0x80; /* C Bit is set */
9399 fis->h.command = SAT_SMART_EXEUTE_OFF_LINE_IMMEDIATE;/* 0x40 */
9400 fis->h.features = 0xD4; /* FIS features NA */
9401 fis->d.lbaLow = 0x7F; /* FIS LBA (7 :0 ) */
9402 fis->d.lbaMid = 0x4F; /* FIS LBA (15:8 ) */
9403 fis->d.lbaHigh = 0xC2; /* FIS LBA (23:16) */
9404
9405 fis->d.lbaLowExp = 0;
9406 fis->d.lbaMidExp = 0;
9407 fis->d.lbaHighExp = 0;
9408 fis->d.featuresExp = 0;
9409 fis->d.sectorCount = 0; /* FIS sector count (7:0) */
9410 fis->d.sectorCountExp = 0;
9411 fis->d.reserved4 = 0;
9412 fis->d.device = 0; /* FIS DEV is discared in SATA */
9413 fis->d.control = 0; /* FIS HOB bit clear */
9414 fis->d.reserved5 = 0;
9415
9416 agRequestType = AGSA_SATA_PROTOCOL_NON_DATA;
9417
9418 /* Initialize CB for SATA completion.
9419 */
9420 satIOContext->satCompleteCB = &satSendDiagnosticCB;
9421
9422 /*
9423 * Prepare SGL and send FIS to LL layer.
9424 */
9425 satIOContext->reqType = agRequestType; /* Save it */
9426
9427 status = sataLLIOStart( tiRoot,
9428 tiIORequest,
9429 tiDeviceHandle,
9430 tiScsiRequest,
9431 satIOContext);
9432
9433
9434 TI_DBG5(("satSendDiagnostic: send SAT_SMART_EXEUTE_OFF_LINE_IMMEDIATE case 3\n"));
9435 TI_DBG5(("satSendDiagnostic: Table 28 case 4\n"));
9436 return (status);
9437 }
9438 else
9439 {
9440 /* check condition */
9441 satSetSensePayload( pSense,
9442 SCSI_SNSKEY_ILLEGAL_REQUEST,
9443 0,
9444 SCSI_SNSCODE_INVALID_FIELD_IN_CDB,
9445 satIOContext);
9446
9447 ostiInitiatorIOCompleted( tiRoot,
9448 tiIORequest,
9449 tiIOSuccess,
9450 SCSI_STAT_CHECK_CONDITION,
9451 satIOContext->pTiSenseData,
9452 satIOContext->interruptContext );
9453
9454 TI_DBG1(("satSendDiagnostic: case 4, no pending diagnostic in background\n"));
9455 TI_DBG5(("satSendDiagnostic: Table 28 case 4\n"));
9456 return tiSuccess;
9457 }
9458 break;
9459 case 5:
9460 /* issuing SMART EXECUTE OFF-LINE IMMEDIATE */
9461 fis->h.fisType = 0x27; /* Reg host to device */
9462 fis->h.c_pmPort = 0x80; /* C Bit is set */
9463 fis->h.command = SAT_SMART_EXEUTE_OFF_LINE_IMMEDIATE;/* 0x40 */
9464 fis->h.features = 0xD4; /* FIS features NA */
9465 fis->d.lbaLow = 0x81; /* FIS LBA (7 :0 ) */
9466 fis->d.lbaMid = 0x4F; /* FIS LBA (15:8 ) */
9467 fis->d.lbaHigh = 0xC2; /* FIS LBA (23:16) */
9468 fis->d.lbaLowExp = 0;
9469 fis->d.lbaMidExp = 0;
9470 fis->d.lbaHighExp = 0;
9471 fis->d.featuresExp = 0;
9472 fis->d.sectorCount = 0; /* FIS sector count (7:0) */
9473 fis->d.sectorCountExp = 0;
9474 fis->d.reserved4 = 0;
9475 fis->d.device = 0; /* FIS DEV is discared in SATA */
9476 fis->d.control = 0; /* FIS HOB bit clear */
9477 fis->d.reserved5 = 0;
9478
9479 agRequestType = AGSA_SATA_PROTOCOL_NON_DATA;
9480
9481 /* Initialize CB for SATA completion.
9482 */
9483 satIOContext->satCompleteCB = &satSendDiagnosticCB;
9484
9485 /*
9486 * Prepare SGL and send FIS to LL layer.
9487 */
9488 satIOContext->reqType = agRequestType; /* Save it */
9489
9490 status = sataLLIOStart( tiRoot,
9491 tiIORequest,
9492 tiDeviceHandle,
9493 tiScsiRequest,
9494 satIOContext);
9495
9496
9497 TI_DBG5(("satSendDiagnostic: return Table 28 case 5\n"));
9498 return (status);
9499 case 6:
9500 /* issuing SMART EXECUTE OFF-LINE IMMEDIATE */
9501 fis->h.fisType = 0x27; /* Reg host to device */
9502 fis->h.c_pmPort = 0x80; /* C Bit is set */
9503 fis->h.command = SAT_SMART_EXEUTE_OFF_LINE_IMMEDIATE;/* 0x40 */
9504 fis->h.features = 0xD4; /* FIS features NA */
9505 fis->d.lbaLow = 0x82; /* FIS LBA (7 :0 ) */
9506 fis->d.lbaMid = 0x4F; /* FIS LBA (15:8 ) */
9507 fis->d.lbaHigh = 0xC2; /* FIS LBA (23:16) */
9508 fis->d.lbaLowExp = 0;
9509 fis->d.lbaMidExp = 0;
9510 fis->d.lbaHighExp = 0;
9511 fis->d.featuresExp = 0;
9512 fis->d.sectorCount = 0; /* FIS sector count (7:0) */
9513 fis->d.sectorCountExp = 0;
9514 fis->d.reserved4 = 0;
9515 fis->d.device = 0; /* FIS DEV is discared in SATA */
9516 fis->d.control = 0; /* FIS HOB bit clear */
9517 fis->d.reserved5 = 0;
9518
9519 agRequestType = AGSA_SATA_PROTOCOL_NON_DATA;
9520
9521 /* Initialize CB for SATA completion.
9522 */
9523 satIOContext->satCompleteCB = &satSendDiagnosticCB;
9524
9525 /*
9526 * Prepare SGL and send FIS to LL layer.
9527 */
9528 satIOContext->reqType = agRequestType; /* Save it */
9529
9530 status = sataLLIOStart( tiRoot,
9531 tiIORequest,
9532 tiDeviceHandle,
9533 tiScsiRequest,
9534 satIOContext);
9535
9536
9537 TI_DBG5(("satSendDiagnostic: return Table 28 case 6\n"));
9538 return (status);
9539 case 0:
9540 case 3: /* fall through */
9541 case 7: /* fall through */
9542 default:
9543 break;
9544 }/* switch */
9545
9546 /* returns the results of default self-testing, which is good */
9547 ostiInitiatorIOCompleted( tiRoot,
9548 tiIORequest,
9549 tiIOSuccess,
9550 SCSI_STAT_GOOD,
9551 agNULL,
9552 satIOContext->interruptContext );
9553
9554 TI_DBG5(("satSendDiagnostic: return Table 28 case 0,3,7 and default\n"));
9555 return tiSuccess;
9556 }
9557
9558
9559 ostiInitiatorIOCompleted( tiRoot,
9560 tiIORequest,
9561 tiIOSuccess,
9562 SCSI_STAT_GOOD,
9563 agNULL,
9564 satIOContext->interruptContext );
9565
9566
9567 TI_DBG5(("satSendDiagnostic: return last\n"));
9568 return tiSuccess;
9569 }
9570
9571 /*****************************************************************************/
9572 /*! \brief SAT implementation for SCSI satSendDiagnostic_1.
9573 *
9574 * SAT implementation for SCSI satSendDiagnostic_1.
9575 * Sub function of satSendDiagnostic.
9576 *
9577 * \param tiRoot: Pointer to TISA initiator driver/port instance.
9578 * \param tiIORequest: Pointer to TISA I/O request context for this I/O.
9579 * \param tiDeviceHandle: Pointer to TISA device handle for this I/O.
9580 * \param tiScsiRequest: Pointer to TISA SCSI I/O request and SGL list.
9581 * \param satIOContext_t: Pointer to the SAT IO Context
9582 *
9583 * \return If command is started successfully
9584 * - \e tiSuccess: I/O request successfully initiated.
9585 * - \e tiBusy: No resources available, try again later.
9586 * - \e tiIONoDevice: Invalid device handle.
9587 * - \e tiError: Other errors.
9588 */
9589 /*****************************************************************************/
satSendDiagnostic_1(tiRoot_t * tiRoot,tiIORequest_t * tiIORequest,tiDeviceHandle_t * tiDeviceHandle,tiScsiInitiatorRequest_t * tiScsiRequest,satIOContext_t * satIOContext)9590 GLOBAL bit32 satSendDiagnostic_1(
9591 tiRoot_t *tiRoot,
9592 tiIORequest_t *tiIORequest,
9593 tiDeviceHandle_t *tiDeviceHandle,
9594 tiScsiInitiatorRequest_t *tiScsiRequest,
9595 satIOContext_t *satIOContext)
9596 {
9597 /*
9598 SAT Rev9, Table29, p41
9599 send 2nd SAT_READ_VERIFY_SECTORS(_EXT)
9600 */
9601 bit32 status;
9602 bit32 agRequestType;
9603 satDeviceData_t *pSatDevData;
9604 agsaFisRegHostToDevice_t *fis;
9605
9606 TI_DBG5(("satSendDiagnostic_1 entry: tiDeviceHandle=%p tiIORequest=%p\n",
9607 tiDeviceHandle, tiIORequest));
9608
9609 pSatDevData = satIOContext->pSatDevData;
9610 fis = satIOContext->pFis;
9611
9612 /*
9613 sector count 1, LBA MAX
9614 */
9615 if (pSatDevData->sat48BitSupport == agTRUE)
9616 {
9617 /* sends READ VERIFY SECTOR(S) EXT*/
9618 fis->h.fisType = 0x27; /* Reg host to device */
9619 fis->h.c_pmPort = 0x80; /* C Bit is set */
9620 fis->h.command = SAT_READ_VERIFY_SECTORS_EXT;/* 0x42 */
9621 fis->h.features = 0; /* FIS reserve */
9622 fis->d.lbaLow = pSatDevData->satMaxLBA[7]; /* FIS LBA (7 :0 ) */
9623 fis->d.lbaMid = pSatDevData->satMaxLBA[6]; /* FIS LBA (15:8 ) */
9624 fis->d.lbaHigh = pSatDevData->satMaxLBA[5]; /* FIS LBA (23:16) */
9625 fis->d.lbaLowExp = pSatDevData->satMaxLBA[4]; /* FIS LBA (31:24) */
9626 fis->d.lbaMidExp = pSatDevData->satMaxLBA[3]; /* FIS LBA (39:32) */
9627 fis->d.lbaHighExp = pSatDevData->satMaxLBA[2]; /* FIS LBA (47:40) */
9628 fis->d.featuresExp = 0; /* FIS reserve */
9629 fis->d.sectorCount = 1; /* FIS sector count (7:0) */
9630 fis->d.sectorCountExp = 0; /* FIS sector count (15:8) */
9631 fis->d.reserved4 = 0;
9632 fis->d.device = 0x40; /* 01000000 */
9633 fis->d.control = 0; /* FIS HOB bit clear */
9634 fis->d.reserved5 = 0;
9635
9636 }
9637 else
9638 {
9639 /* READ VERIFY SECTOR(S)*/
9640 fis->h.fisType = 0x27; /* Reg host to device */
9641 fis->h.c_pmPort = 0x80; /* C Bit is set */
9642 fis->h.command = SAT_READ_VERIFY_SECTORS;/* 0x40 */
9643 fis->h.features = 0; /* FIS features NA */
9644 fis->d.lbaLow = pSatDevData->satMaxLBA[7]; /* FIS LBA (7 :0 ) */
9645 fis->d.lbaMid = pSatDevData->satMaxLBA[6]; /* FIS LBA (15:8 ) */
9646 fis->d.lbaHigh = pSatDevData->satMaxLBA[5]; /* FIS LBA (23:16) */
9647 fis->d.lbaLowExp = 0;
9648 fis->d.lbaMidExp = 0;
9649 fis->d.lbaHighExp = 0;
9650 fis->d.featuresExp = 0;
9651 fis->d.sectorCount = 1; /* FIS sector count (7:0) */
9652 fis->d.sectorCountExp = 0;
9653 fis->d.reserved4 = 0;
9654 fis->d.device = (bit8)((0x4 << 4) | (pSatDevData->satMaxLBA[4] & 0xF));
9655 /* DEV and LBA 27:24 */
9656 fis->d.control = 0; /* FIS HOB bit clear */
9657 fis->d.reserved5 = 0;
9658
9659 }
9660
9661 agRequestType = AGSA_SATA_PROTOCOL_NON_DATA;
9662
9663 /* Initialize CB for SATA completion.
9664 */
9665 satIOContext->satCompleteCB = &satSendDiagnosticCB;
9666
9667 /*
9668 * Prepare SGL and send FIS to LL layer.
9669 */
9670 satIOContext->reqType = agRequestType; /* Save it */
9671
9672 status = sataLLIOStart( tiRoot,
9673 tiIORequest,
9674 tiDeviceHandle,
9675 tiScsiRequest,
9676 satIOContext);
9677
9678
9679 return status;
9680 }
9681
9682 /*****************************************************************************/
9683 /*! \brief SAT implementation for SCSI satSendDiagnostic_2.
9684 *
9685 * SAT implementation for SCSI satSendDiagnostic_2.
9686 * Sub function of satSendDiagnostic.
9687 *
9688 * \param tiRoot: Pointer to TISA initiator driver/port instance.
9689 * \param tiIORequest: Pointer to TISA I/O request context for this I/O.
9690 * \param tiDeviceHandle: Pointer to TISA device handle for this I/O.
9691 * \param tiScsiRequest: Pointer to TISA SCSI I/O request and SGL list.
9692 * \param satIOContext_t: Pointer to the SAT IO Context
9693 *
9694 * \return If command is started successfully
9695 * - \e tiSuccess: I/O request successfully initiated.
9696 * - \e tiBusy: No resources available, try again later.
9697 * - \e tiIONoDevice: Invalid device handle.
9698 * - \e tiError: Other errors.
9699 */
9700 /*****************************************************************************/
satSendDiagnostic_2(tiRoot_t * tiRoot,tiIORequest_t * tiIORequest,tiDeviceHandle_t * tiDeviceHandle,tiScsiInitiatorRequest_t * tiScsiRequest,satIOContext_t * satIOContext)9701 GLOBAL bit32 satSendDiagnostic_2(
9702 tiRoot_t *tiRoot,
9703 tiIORequest_t *tiIORequest,
9704 tiDeviceHandle_t *tiDeviceHandle,
9705 tiScsiInitiatorRequest_t *tiScsiRequest,
9706 satIOContext_t *satIOContext)
9707 {
9708 /*
9709 SAT Rev9, Table29, p41
9710 send 3rd SAT_READ_VERIFY_SECTORS(_EXT)
9711 */
9712 bit32 status;
9713 bit32 agRequestType;
9714 satDeviceData_t *pSatDevData;
9715 agsaFisRegHostToDevice_t *fis;
9716
9717 TI_DBG5(("satSendDiagnostic_2 entry: tiDeviceHandle=%p tiIORequest=%p\n",
9718 tiDeviceHandle, tiIORequest));
9719
9720 pSatDevData = satIOContext->pSatDevData;
9721 fis = satIOContext->pFis;
9722
9723 /*
9724 sector count 1, LBA Random
9725 */
9726 if (pSatDevData->sat48BitSupport == agTRUE)
9727 {
9728 /* sends READ VERIFY SECTOR(S) EXT*/
9729 fis->h.fisType = 0x27; /* Reg host to device */
9730 fis->h.c_pmPort = 0x80; /* C Bit is set */
9731 fis->h.command = SAT_READ_VERIFY_SECTORS_EXT;/* 0x42 */
9732 fis->h.features = 0; /* FIS reserve */
9733 fis->d.lbaLow = 0x7F; /* FIS LBA (7 :0 ) */
9734 fis->d.lbaMid = 0; /* FIS LBA (15:8 ) */
9735 fis->d.lbaHigh = 0; /* FIS LBA (23:16) */
9736 fis->d.lbaLowExp = 0; /* FIS LBA (31:24) */
9737 fis->d.lbaMidExp = 0; /* FIS LBA (39:32) */
9738 fis->d.lbaHighExp = 0; /* FIS LBA (47:40) */
9739 fis->d.featuresExp = 0; /* FIS reserve */
9740 fis->d.sectorCount = 1; /* FIS sector count (7:0) */
9741 fis->d.sectorCountExp = 0; /* FIS sector count (15:8) */
9742 fis->d.reserved4 = 0;
9743 fis->d.device = 0x40; /* 01000000 */
9744 fis->d.control = 0; /* FIS HOB bit clear */
9745 fis->d.reserved5 = 0;
9746
9747 }
9748 else
9749 {
9750 /* READ VERIFY SECTOR(S)*/
9751 fis->h.fisType = 0x27; /* Reg host to device */
9752 fis->h.c_pmPort = 0x80; /* C Bit is set */
9753 fis->h.command = SAT_READ_VERIFY_SECTORS;/* 0x40 */
9754 fis->h.features = 0; /* FIS features NA */
9755 fis->d.lbaLow = 0x7F; /* FIS LBA (7 :0 ) */
9756 fis->d.lbaMid = 0; /* FIS LBA (15:8 ) */
9757 fis->d.lbaHigh = 0; /* FIS LBA (23:16) */
9758 fis->d.lbaLowExp = 0;
9759 fis->d.lbaMidExp = 0;
9760 fis->d.lbaHighExp = 0;
9761 fis->d.featuresExp = 0;
9762 fis->d.sectorCount = 1; /* FIS sector count (7:0) */
9763 fis->d.sectorCountExp = 0;
9764 fis->d.reserved4 = 0;
9765 fis->d.device = 0x40; /* FIS LBA mode set 01000000 */
9766 fis->d.control = 0; /* FIS HOB bit clear */
9767 fis->d.reserved5 = 0;
9768
9769 }
9770
9771 agRequestType = AGSA_SATA_PROTOCOL_NON_DATA;
9772
9773 /* Initialize CB for SATA completion.
9774 */
9775 satIOContext->satCompleteCB = &satSendDiagnosticCB;
9776
9777 /*
9778 * Prepare SGL and send FIS to LL layer.
9779 */
9780 satIOContext->reqType = agRequestType; /* Save it */
9781
9782 status = sataLLIOStart( tiRoot,
9783 tiIORequest,
9784 tiDeviceHandle,
9785 tiScsiRequest,
9786 satIOContext);
9787
9788
9789 return status;
9790 }
9791 /*****************************************************************************/
9792 /*! \brief SAT implementation for SCSI satStartStopUnit.
9793 *
9794 * SAT implementation for SCSI satStartStopUnit.
9795 *
9796 * \param tiRoot: Pointer to TISA initiator driver/port instance.
9797 * \param tiIORequest: Pointer to TISA I/O request context for this I/O.
9798 * \param tiDeviceHandle: Pointer to TISA device handle for this I/O.
9799 * \param tiScsiRequest: Pointer to TISA SCSI I/O request and SGL list.
9800 * \param satIOContext_t: Pointer to the SAT IO Context
9801 *
9802 * \return If command is started successfully
9803 * - \e tiSuccess: I/O request successfully initiated.
9804 * - \e tiBusy: No resources available, try again later.
9805 * - \e tiIONoDevice: Invalid device handle.
9806 * - \e tiError: Other errors.
9807 */
9808 /*****************************************************************************/
satStartStopUnit(tiRoot_t * tiRoot,tiIORequest_t * tiIORequest,tiDeviceHandle_t * tiDeviceHandle,tiScsiInitiatorRequest_t * tiScsiRequest,satIOContext_t * satIOContext)9809 GLOBAL bit32 satStartStopUnit(
9810 tiRoot_t *tiRoot,
9811 tiIORequest_t *tiIORequest,
9812 tiDeviceHandle_t *tiDeviceHandle,
9813 tiScsiInitiatorRequest_t *tiScsiRequest,
9814 satIOContext_t *satIOContext)
9815 {
9816 bit32 status;
9817 bit32 agRequestType;
9818 satDeviceData_t *pSatDevData;
9819 scsiRspSense_t *pSense;
9820 tiIniScsiCmnd_t *scsiCmnd;
9821 agsaFisRegHostToDevice_t *fis;
9822
9823 pSense = satIOContext->pSense;
9824 pSatDevData = satIOContext->pSatDevData;
9825 scsiCmnd = &tiScsiRequest->scsiCmnd;
9826 fis = satIOContext->pFis;
9827
9828 TI_DBG5(("satStartStopUnit:start\n"));
9829
9830 /* checking CONTROL */
9831 /* NACA == 1 or LINK == 1*/
9832 if ( (scsiCmnd->cdb[5] & SCSI_NACA_MASK) || (scsiCmnd->cdb[5] & SCSI_LINK_MASK) )
9833 {
9834 satSetSensePayload( pSense,
9835 SCSI_SNSKEY_ILLEGAL_REQUEST,
9836 0,
9837 SCSI_SNSCODE_INVALID_FIELD_IN_CDB,
9838 satIOContext);
9839
9840 ostiInitiatorIOCompleted( tiRoot,
9841 tiIORequest,
9842 tiIOSuccess,
9843 SCSI_STAT_CHECK_CONDITION,
9844 satIOContext->pTiSenseData,
9845 satIOContext->interruptContext );
9846
9847 TI_DBG1(("satStartStopUnit: return control\n"));
9848 return tiSuccess;
9849 }
9850
9851 /* Spec p55, Table 48 checking START and LOEJ bit */
9852 /* case 1 */
9853 if ( !(scsiCmnd->cdb[4] & SCSI_START_MASK) && !(scsiCmnd->cdb[4] & SCSI_LOEJ_MASK) )
9854 {
9855 if ( (scsiCmnd->cdb[1] & SCSI_IMMED_MASK) )
9856 {
9857 /* immed bit , SAT rev 8, 9.11.2.1 p 54*/
9858 ostiInitiatorIOCompleted( tiRoot,
9859 tiIORequest,
9860 tiIOSuccess,
9861 SCSI_STAT_GOOD,
9862 agNULL,
9863 satIOContext->interruptContext );
9864 TI_DBG5(("satStartStopUnit: return table48 case 1-1\n"));
9865 return tiSuccess;
9866 }
9867 /* sends FLUSH CACHE or FLUSH CACHE EXT */
9868 if (pSatDevData->sat48BitSupport == agTRUE)
9869 {
9870 /* FLUSH CACHE EXT */
9871 fis->h.fisType = 0x27; /* Reg host to device */
9872 fis->h.c_pmPort = 0x80; /* C Bit is set */
9873
9874 fis->h.command = SAT_FLUSH_CACHE_EXT; /* 0xEA */
9875 fis->h.features = 0; /* FIS reserve */
9876 fis->d.featuresExp = 0; /* FIS reserve */
9877 fis->d.sectorCount = 0; /* FIS sector count (7:0) */
9878 fis->d.sectorCountExp = 0; /* FIS sector count (15:8) */
9879 fis->d.lbaLow = 0; /* FIS LBA (7 :0 ) */
9880 fis->d.lbaLowExp = 0; /* FIS LBA (31:24) */
9881 fis->d.lbaMid = 0; /* FIS LBA (15:8 ) */
9882 fis->d.lbaMidExp = 0; /* FIS LBA (39:32) */
9883 fis->d.lbaHigh = 0; /* FIS LBA (23:16) */
9884 fis->d.lbaHighExp = 0; /* FIS LBA (47:40) */
9885 fis->d.device = 0; /* FIS DEV is discared in SATA */
9886 fis->d.control = 0; /* FIS HOB bit clear */
9887 fis->d.reserved4 = 0;
9888 fis->d.reserved5 = 0;
9889
9890 agRequestType = AGSA_SATA_PROTOCOL_NON_DATA;
9891 }
9892 else
9893 {
9894 /* FLUSH CACHE */
9895 fis->h.fisType = 0x27; /* Reg host to device */
9896 fis->h.c_pmPort = 0x80; /* C Bit is set */
9897
9898 fis->h.command = SAT_FLUSH_CACHE; /* 0xE7 */
9899 fis->h.features = 0; /* FIS features NA */
9900 fis->d.lbaLow = 0; /* FIS LBA (7 :0 ) */
9901 fis->d.lbaMid = 0; /* FIS LBA (15:8 ) */
9902 fis->d.lbaHigh = 0; /* FIS LBA (23:16) */
9903 fis->d.lbaLowExp = 0;
9904 fis->d.lbaMidExp = 0;
9905 fis->d.lbaHighExp = 0;
9906 fis->d.featuresExp = 0;
9907 fis->d.sectorCount = 0; /* FIS sector count (7:0) */
9908 fis->d.sectorCountExp = 0;
9909 fis->d.device = 0; /* FIS DEV is discared in SATA */
9910 fis->d.control = 0; /* FIS HOB bit clear */
9911 fis->d.reserved4 = 0;
9912 fis->d.reserved5 = 0;
9913
9914 agRequestType = AGSA_SATA_PROTOCOL_NON_DATA;
9915 }
9916
9917 /* Initialize CB for SATA completion.
9918 */
9919 satIOContext->satCompleteCB = &satStartStopUnitCB;
9920
9921 /*
9922 * Prepare SGL and send FIS to LL layer.
9923 */
9924 satIOContext->reqType = agRequestType; /* Save it */
9925
9926 status = sataLLIOStart( tiRoot,
9927 tiIORequest,
9928 tiDeviceHandle,
9929 tiScsiRequest,
9930 satIOContext);
9931
9932
9933 TI_DBG5(("satStartStopUnit: return table48 case 1\n"));
9934 return (status);
9935 }
9936 /* case 2 */
9937 else if ( (scsiCmnd->cdb[4] & SCSI_START_MASK) && !(scsiCmnd->cdb[4] & SCSI_LOEJ_MASK) )
9938 {
9939 /* immed bit , SAT rev 8, 9.11.2.1 p 54*/
9940 if ( (scsiCmnd->cdb[1] & SCSI_IMMED_MASK) )
9941 {
9942 ostiInitiatorIOCompleted( tiRoot,
9943 tiIORequest,
9944 tiIOSuccess,
9945 SCSI_STAT_GOOD,
9946 agNULL,
9947 satIOContext->interruptContext );
9948
9949 TI_DBG5(("satStartStopUnit: return table48 case 2 1\n"));
9950 return tiSuccess;
9951 }
9952 /*
9953 sends READ_VERIFY_SECTORS(_EXT)
9954 sector count 1, any LBA between zero to Maximum
9955 */
9956 if (pSatDevData->sat48BitSupport == agTRUE)
9957 {
9958 /* READ VERIFY SECTOR(S) EXT*/
9959 fis->h.fisType = 0x27; /* Reg host to device */
9960 fis->h.c_pmPort = 0x80; /* C Bit is set */
9961
9962 fis->h.command = SAT_READ_VERIFY_SECTORS_EXT;/* 0x42 */
9963 fis->h.features = 0; /* FIS reserve */
9964 fis->d.lbaLow = 0x01; /* FIS LBA (7 :0 ) */
9965 fis->d.lbaMid = 0x00; /* FIS LBA (15:8 ) */
9966 fis->d.lbaHigh = 0x00; /* FIS LBA (23:16) */
9967 fis->d.lbaLowExp = 0x00; /* FIS LBA (31:24) */
9968 fis->d.lbaMidExp = 0x00; /* FIS LBA (39:32) */
9969 fis->d.lbaHighExp = 0x00; /* FIS LBA (47:40) */
9970 fis->d.featuresExp = 0; /* FIS reserve */
9971 fis->d.sectorCount = 1; /* FIS sector count (7:0) */
9972 fis->d.sectorCountExp = 0; /* FIS sector count (15:8) */
9973 fis->d.reserved4 = 0;
9974 fis->d.device = 0x40; /* 01000000 */
9975 fis->d.control = 0; /* FIS HOB bit clear */
9976 fis->d.reserved5 = 0;
9977
9978 }
9979 else
9980 {
9981 /* READ VERIFY SECTOR(S)*/
9982 fis->h.fisType = 0x27; /* Reg host to device */
9983 fis->h.c_pmPort = 0x80; /* C Bit is set */
9984
9985 fis->h.command = SAT_READ_VERIFY_SECTORS;/* 0x40 */
9986 fis->h.features = 0; /* FIS features NA */
9987 fis->d.lbaLow = 0x01; /* FIS LBA (7 :0 ) */
9988 fis->d.lbaMid = 0x00; /* FIS LBA (15:8 ) */
9989 fis->d.lbaHigh = 0x00; /* FIS LBA (23:16) */
9990 fis->d.lbaLowExp = 0;
9991 fis->d.lbaMidExp = 0;
9992 fis->d.lbaHighExp = 0;
9993 fis->d.featuresExp = 0;
9994 fis->d.sectorCount = 1; /* FIS sector count (7:0) */
9995 fis->d.sectorCountExp = 0;
9996 fis->d.reserved4 = 0;
9997 fis->d.device = 0x40; /* 01000000 */
9998 fis->d.control = 0; /* FIS HOB bit clear */
9999 fis->d.reserved5 = 0;
10000
10001 }
10002
10003 agRequestType = AGSA_SATA_PROTOCOL_NON_DATA;
10004
10005 /* Initialize CB for SATA completion.
10006 */
10007 satIOContext->satCompleteCB = &satStartStopUnitCB;
10008
10009 /*
10010 * Prepare SGL and send FIS to LL layer.
10011 */
10012 satIOContext->reqType = agRequestType; /* Save it */
10013
10014 status = sataLLIOStart( tiRoot,
10015 tiIORequest,
10016 tiDeviceHandle,
10017 tiScsiRequest,
10018 satIOContext);
10019
10020 TI_DBG5(("satStartStopUnit: return table48 case 2 2\n"));
10021 return status;
10022 }
10023 /* case 3 */
10024 else if ( !(scsiCmnd->cdb[4] & SCSI_START_MASK) && (scsiCmnd->cdb[4] & SCSI_LOEJ_MASK) )
10025 {
10026 if(pSatDevData->satRemovableMedia && pSatDevData->satRemovableMediaEnabled)
10027 {
10028 /* support for removal media */
10029 /* immed bit , SAT rev 8, 9.11.2.1 p 54*/
10030 if ( (scsiCmnd->cdb[1] & SCSI_IMMED_MASK) )
10031 {
10032 ostiInitiatorIOCompleted( tiRoot,
10033 tiIORequest,
10034 tiIOSuccess,
10035 SCSI_STAT_GOOD,
10036 agNULL,
10037 satIOContext->interruptContext );
10038
10039 TI_DBG5(("satStartStopUnit: return table48 case 3 1\n"));
10040 return tiSuccess;
10041 }
10042 /*
10043 sends MEDIA EJECT
10044 */
10045 /* Media Eject fis */
10046 fis->h.fisType = 0x27; /* Reg host to device */
10047 fis->h.c_pmPort = 0x80; /* C Bit is set */
10048
10049 fis->h.command = SAT_MEDIA_EJECT; /* 0xED */
10050 fis->h.features = 0; /* FIS features NA */
10051 fis->d.lbaLow = 0; /* FIS LBA (7 :0 ) */
10052 fis->d.lbaMid = 0; /* FIS LBA (15:8 ) */
10053 fis->d.lbaHigh = 0; /* FIS LBA (23:16) */
10054 fis->d.lbaLowExp = 0;
10055 fis->d.lbaMidExp = 0;
10056 fis->d.lbaHighExp = 0;
10057 fis->d.featuresExp = 0;
10058 /* sector count zero */
10059 fis->d.sectorCount = 0; /* FIS sector count (7:0) */
10060 fis->d.sectorCountExp = 0;
10061 fis->d.device = 0; /* FIS DEV is discared in SATA */
10062 fis->d.control = 0; /* FIS HOB bit clear */
10063 fis->d.reserved4 = 0;
10064 fis->d.reserved5 = 0;
10065
10066 agRequestType = AGSA_SATA_PROTOCOL_NON_DATA;
10067
10068 /* Initialize CB for SATA completion.
10069 */
10070 satIOContext->satCompleteCB = &satStartStopUnitCB;
10071
10072 /*
10073 * Prepare SGL and send FIS to LL layer.
10074 */
10075 satIOContext->reqType = agRequestType; /* Save it */
10076
10077 status = sataLLIOStart( tiRoot,
10078 tiIORequest,
10079 tiDeviceHandle,
10080 tiScsiRequest,
10081 satIOContext);
10082
10083 return status;
10084 }
10085 else
10086 {
10087 /* no support for removal media */
10088 satSetSensePayload( pSense,
10089 SCSI_SNSKEY_ILLEGAL_REQUEST,
10090 0,
10091 SCSI_SNSCODE_INVALID_FIELD_IN_CDB,
10092 satIOContext);
10093
10094 ostiInitiatorIOCompleted( tiRoot,
10095 tiIORequest,
10096 tiIOSuccess,
10097 SCSI_STAT_CHECK_CONDITION,
10098 satIOContext->pTiSenseData,
10099 satIOContext->interruptContext );
10100
10101 TI_DBG5(("satStartStopUnit: return Table 29 case 3 2\n"));
10102 return tiSuccess;
10103 }
10104
10105 }
10106 /* case 4 */
10107 else /* ( (scsiCmnd->cdb[4] & SCSI_START_MASK) && (scsiCmnd->cdb[4] & SCSI_LOEJ_MASK) ) */
10108 {
10109 satSetSensePayload( pSense,
10110 SCSI_SNSKEY_ILLEGAL_REQUEST,
10111 0,
10112 SCSI_SNSCODE_INVALID_FIELD_IN_CDB,
10113 satIOContext);
10114
10115 ostiInitiatorIOCompleted( tiRoot,
10116 tiIORequest,
10117 tiIOSuccess,
10118 SCSI_STAT_CHECK_CONDITION,
10119 satIOContext->pTiSenseData,
10120 satIOContext->interruptContext );
10121
10122 TI_DBG5(("satStartStopUnit: return Table 29 case 4\n"));
10123 return tiSuccess;
10124 }
10125
10126
10127 }
10128
10129
10130 /*****************************************************************************/
10131 /*! \brief SAT implementation for SCSI satStartStopUnit_1.
10132 *
10133 * SAT implementation for SCSI satStartStopUnit_1.
10134 * Sub function of satStartStopUnit
10135 *
10136 * \param tiRoot: Pointer to TISA initiator driver/port instance.
10137 * \param tiIORequest: Pointer to TISA I/O request context for this I/O.
10138 * \param tiDeviceHandle: Pointer to TISA device handle for this I/O.
10139 * \param tiScsiRequest: Pointer to TISA SCSI I/O request and SGL list.
10140 * \param satIOContext_t: Pointer to the SAT IO Context
10141 *
10142 * \return If command is started successfully
10143 * - \e tiSuccess: I/O request successfully initiated.
10144 * - \e tiBusy: No resources available, try again later.
10145 * - \e tiIONoDevice: Invalid device handle.
10146 * - \e tiError: Other errors.
10147 */
10148 /*****************************************************************************/
satStartStopUnit_1(tiRoot_t * tiRoot,tiIORequest_t * tiIORequest,tiDeviceHandle_t * tiDeviceHandle,tiScsiInitiatorRequest_t * tiScsiRequest,satIOContext_t * satIOContext)10149 GLOBAL bit32 satStartStopUnit_1(
10150 tiRoot_t *tiRoot,
10151 tiIORequest_t *tiIORequest,
10152 tiDeviceHandle_t *tiDeviceHandle,
10153 tiScsiInitiatorRequest_t *tiScsiRequest,
10154 satIOContext_t *satIOContext)
10155 {
10156 /*
10157 SAT Rev 8, Table 48, 9.11.3 p55
10158 sends STANDBY
10159 */
10160 bit32 status;
10161 bit32 agRequestType;
10162 agsaFisRegHostToDevice_t *fis;
10163
10164 TI_DBG5(("satStartStopUnit_1 entry: tiDeviceHandle=%p tiIORequest=%p\n",
10165 tiDeviceHandle, tiIORequest));
10166
10167 fis = satIOContext->pFis;
10168
10169 /* STANDBY */
10170 fis->h.fisType = 0x27; /* Reg host to device */
10171 fis->h.c_pmPort = 0x80; /* C Bit is set */
10172
10173 fis->h.command = SAT_STANDBY; /* 0xE2 */
10174 fis->h.features = 0; /* FIS features NA */
10175 fis->d.lbaLow = 0; /* FIS LBA (7 :0 ) */
10176 fis->d.lbaMid = 0; /* FIS LBA (15:8 ) */
10177 fis->d.lbaHigh = 0; /* FIS LBA (23:16) */
10178 fis->d.lbaLowExp = 0;
10179 fis->d.lbaMidExp = 0;
10180 fis->d.lbaHighExp = 0;
10181 fis->d.featuresExp = 0;
10182 fis->d.sectorCount = 0; /* FIS sector count (7:0) */
10183 fis->d.sectorCountExp = 0;
10184 fis->d.reserved4 = 0;
10185 fis->d.device = 0; /* 0 */
10186 fis->d.control = 0; /* FIS HOB bit clear */
10187 fis->d.reserved5 = 0;
10188
10189 agRequestType = AGSA_SATA_PROTOCOL_NON_DATA;
10190
10191 /* Initialize CB for SATA completion.
10192 */
10193 satIOContext->satCompleteCB = &satStartStopUnitCB;
10194
10195 /*
10196 * Prepare SGL and send FIS to LL layer.
10197 */
10198 satIOContext->reqType = agRequestType; /* Save it */
10199
10200 status = sataLLIOStart( tiRoot,
10201 tiIORequest,
10202 tiDeviceHandle,
10203 tiScsiRequest,
10204 satIOContext);
10205
10206 TI_DBG5(("satStartStopUnit_1 return status %d\n", status));
10207 return status;
10208 }
10209
10210 /*****************************************************************************/
10211 /*! \brief SAT implementation for SCSI satRead10_2.
10212 *
10213 * SAT implementation for SCSI satRead10_2
10214 * Sub function of satRead10
10215 *
10216 * \param tiRoot: Pointer to TISA initiator driver/port instance.
10217 * \param tiIORequest: Pointer to TISA I/O request context for this I/O.
10218 * \param tiDeviceHandle: Pointer to TISA device handle for this I/O.
10219 * \param tiScsiRequest: Pointer to TISA SCSI I/O request and SGL list.
10220 * \param satIOContext_t: Pointer to the SAT IO Context
10221 *
10222 * \return If command is started successfully
10223 * - \e tiSuccess: I/O request successfully initiated.
10224 * - \e tiBusy: No resources available, try again later.
10225 * - \e tiIONoDevice: Invalid device handle.
10226 * - \e tiError: Other errors.
10227 */
10228 /*****************************************************************************/
satRead10_2(tiRoot_t * tiRoot,tiIORequest_t * tiIORequest,tiDeviceHandle_t * tiDeviceHandle,tiScsiInitiatorRequest_t * tiScsiRequest,satIOContext_t * satIOContext)10229 GLOBAL bit32 satRead10_2(
10230 tiRoot_t *tiRoot,
10231 tiIORequest_t *tiIORequest,
10232 tiDeviceHandle_t *tiDeviceHandle,
10233 tiScsiInitiatorRequest_t *tiScsiRequest,
10234 satIOContext_t *satIOContext)
10235 {
10236 /*
10237 externally generated ATA cmd, there is corresponding scsi cmnd
10238 called by satStartStopUnit() or maybe satRead10()
10239 */
10240
10241 bit32 status;
10242 bit32 agRequestType;
10243 satDeviceData_t *pSatDevData;
10244 agsaFisRegHostToDevice_t *fis;
10245
10246 pSatDevData = satIOContext->pSatDevData;
10247 fis = satIOContext->pFis;
10248
10249 TI_DBG5(("satReadVerifySectorsNoChain: start\n"));
10250
10251 /* specifying ReadVerifySectors has no chain */
10252 pSatDevData->satVerifyState = 0xFFFFFFFF;
10253
10254 if (pSatDevData->sat48BitSupport == agTRUE)
10255 {
10256 /* READ VERIFY SECTOR(S) EXT*/
10257 fis->h.fisType = 0x27; /* Reg host to device */
10258 fis->h.c_pmPort = 0x80; /* C Bit is set */
10259 fis->h.command = SAT_READ_VERIFY_SECTORS_EXT;/* 0x42 */
10260 fis->h.features = 0; /* FIS reserve */
10261 fis->d.lbaLow = 0x7F; /* FIS LBA (7 :0 ) */
10262 fis->d.lbaMid = 0x4F; /* FIS LBA (15:8 ) */
10263 fis->d.lbaHigh = 0x00; /* FIS LBA (23:16) */
10264 fis->d.lbaLowExp = 0xF1; /* FIS LBA (31:24) */
10265 fis->d.lbaMidExp = 0x5F; /* FIS LBA (39:32) */
10266 fis->d.lbaHighExp = 0xFF; /* FIS LBA (47:40) */
10267 fis->d.featuresExp = 0; /* FIS reserve */
10268 fis->d.sectorCount = 1; /* FIS sector count (7:0) */
10269 fis->d.sectorCountExp = 0; /* FIS sector count (15:8) */
10270 fis->d.reserved4 = 0;
10271 fis->d.device = 0x4E; /* 01001110 */
10272 fis->d.control = 0; /* FIS HOB bit clear */
10273 fis->d.reserved5 = 0;
10274
10275 agRequestType = AGSA_SATA_PROTOCOL_NON_DATA;
10276 }
10277 else
10278 {
10279 /* READ VERIFY SECTOR(S)*/
10280 fis->h.fisType = 0x27; /* Reg host to device */
10281 fis->h.c_pmPort = 0x80; /* C Bit is set */
10282 fis->h.command = SAT_READ_VERIFY_SECTORS;/* 0x40 */
10283 fis->h.features = 0; /* FIS features NA */
10284 fis->d.lbaLow = 0x7F; /* FIS LBA (7 :0 ) */
10285 fis->d.lbaMid = 0x4F; /* FIS LBA (15:8 ) */
10286 fis->d.lbaHigh = 0x00; /* FIS LBA (23:16) */
10287 fis->d.lbaLowExp = 0;
10288 fis->d.lbaMidExp = 0;
10289 fis->d.lbaHighExp = 0;
10290 fis->d.featuresExp = 0;
10291 fis->d.sectorCount = 1; /* FIS sector count (7:0) */
10292 fis->d.sectorCountExp = 0;
10293 fis->d.reserved4 = 0;
10294 fis->d.device = 0x4E; /* 01001110 */
10295 fis->d.control = 0; /* FIS HOB bit clear */
10296 fis->d.reserved5 = 0;
10297
10298 agRequestType = AGSA_SATA_PROTOCOL_NON_DATA;
10299 }
10300
10301 /* Initialize CB for SATA completion.
10302 */
10303 satIOContext->satCompleteCB = &satNonDataIOCB;
10304
10305 /*
10306 * Prepare SGL and send FIS to LL layer.
10307 */
10308 satIOContext->reqType = agRequestType; /* Save it */
10309
10310 status = sataLLIOStart( tiRoot,
10311 tiIORequest,
10312 tiDeviceHandle,
10313 tiScsiRequest,
10314 satIOContext);
10315
10316 TI_DBG5(("satReadVerifySectorsNoChain: return last\n"));
10317
10318 return status;
10319 }
10320
10321
10322 /*****************************************************************************/
10323 /*! \brief SAT implementation for SCSI satWriteSame10.
10324 *
10325 * SAT implementation for SCSI satWriteSame10.
10326 *
10327 * \param tiRoot: Pointer to TISA initiator driver/port instance.
10328 * \param tiIORequest: Pointer to TISA I/O request context for this I/O.
10329 * \param tiDeviceHandle: Pointer to TISA device handle for this I/O.
10330 * \param tiScsiRequest: Pointer to TISA SCSI I/O request and SGL list.
10331 * \param satIOContext_t: Pointer to the SAT IO Context
10332 *
10333 * \return If command is started successfully
10334 * - \e tiSuccess: I/O request successfully initiated.
10335 * - \e tiBusy: No resources available, try again later.
10336 * - \e tiIONoDevice: Invalid device handle.
10337 * - \e tiError: Other errors.
10338 */
10339 /*****************************************************************************/
satWriteSame10(tiRoot_t * tiRoot,tiIORequest_t * tiIORequest,tiDeviceHandle_t * tiDeviceHandle,tiScsiInitiatorRequest_t * tiScsiRequest,satIOContext_t * satIOContext)10340 GLOBAL bit32 satWriteSame10(
10341 tiRoot_t *tiRoot,
10342 tiIORequest_t *tiIORequest,
10343 tiDeviceHandle_t *tiDeviceHandle,
10344 tiScsiInitiatorRequest_t *tiScsiRequest,
10345 satIOContext_t *satIOContext)
10346 {
10347 bit32 status;
10348 bit32 agRequestType = AGSA_SATA_PROTOCOL_DMA_WRITE;
10349 satDeviceData_t *pSatDevData;
10350 scsiRspSense_t *pSense;
10351 tiIniScsiCmnd_t *scsiCmnd;
10352 agsaFisRegHostToDevice_t *fis;
10353 bit32 lba = 0;
10354 bit32 tl = 0;
10355
10356 pSense = satIOContext->pSense;
10357 pSatDevData = satIOContext->pSatDevData;
10358 scsiCmnd = &tiScsiRequest->scsiCmnd;
10359 fis = satIOContext->pFis;
10360
10361 TI_DBG5(("satWriteSame10: start\n"));
10362
10363 /* checking CONTROL */
10364 /* NACA == 1 or LINK == 1*/
10365 if ( (scsiCmnd->cdb[9] & SCSI_NACA_MASK) || (scsiCmnd->cdb[9] & SCSI_LINK_MASK) )
10366 {
10367 satSetSensePayload( pSense,
10368 SCSI_SNSKEY_ILLEGAL_REQUEST,
10369 0,
10370 SCSI_SNSCODE_INVALID_FIELD_IN_CDB,
10371 satIOContext);
10372
10373 ostiInitiatorIOCompleted( tiRoot,
10374 tiIORequest,
10375 tiIOSuccess,
10376 SCSI_STAT_CHECK_CONDITION,
10377 satIOContext->pTiSenseData,
10378 satIOContext->interruptContext );
10379
10380 TI_DBG1(("satWriteSame10: return control\n"));
10381 return tiSuccess;
10382 }
10383
10384
10385 /* checking LBDATA and PBDATA */
10386 /* case 1 */
10387 if ( !(scsiCmnd->cdb[1] & SCSI_WRITE_SAME_LBDATA_MASK) &&
10388 !(scsiCmnd->cdb[1] & SCSI_WRITE_SAME_PBDATA_MASK))
10389 {
10390 TI_DBG5(("satWriteSame10: case 1\n"));
10391 /* spec 9.26.2, Table 62, p64, case 1*/
10392 /*
10393 normal case
10394 just like write in 9.17.1
10395 */
10396
10397 if ( pSatDevData->sat48BitSupport != agTRUE )
10398 {
10399 /*
10400 writeSame10 but no support for 48 bit addressing
10401 -> problem in transfer length. Therefore, return check condition
10402 */
10403 satSetSensePayload( pSense,
10404 SCSI_SNSKEY_ILLEGAL_REQUEST,
10405 0,
10406 SCSI_SNSCODE_INVALID_FIELD_IN_CDB,
10407 satIOContext);
10408
10409 ostiInitiatorIOCompleted( tiRoot,
10410 tiIORequest,
10411 tiIOSuccess,
10412 SCSI_STAT_CHECK_CONDITION,
10413 satIOContext->pTiSenseData,
10414 satIOContext->interruptContext );
10415
10416 TI_DBG1(("satWriteSame10: return internal checking\n"));
10417 return tiSuccess;
10418 }
10419
10420 /* cdb10; computing LBA and transfer length */
10421 lba = (scsiCmnd->cdb[2] << (8*3)) + (scsiCmnd->cdb[3] << (8*2))
10422 + (scsiCmnd->cdb[4] << 8) + scsiCmnd->cdb[5];
10423 tl = (scsiCmnd->cdb[7] << 8) + scsiCmnd->cdb[8];
10424
10425
10426 /* Table 34, 9.1, p 46 */
10427 /*
10428 note: As of 2/10/2006, no support for DMA QUEUED
10429 */
10430
10431 /*
10432 Table 34, 9.1, p 46, b (footnote)
10433 When no 48-bit addressing support or NCQ, if LBA is beyond (2^28 - 1),
10434 return check condition
10435 */
10436 if (pSatDevData->satNCQ != agTRUE &&
10437 pSatDevData->sat48BitSupport != agTRUE
10438 )
10439 {
10440 if (lba > SAT_TR_LBA_LIMIT - 1) /* SAT_TR_LBA_LIMIT is 2^28, 0x10000000 */
10441 {
10442 satSetSensePayload( pSense,
10443 SCSI_SNSKEY_ILLEGAL_REQUEST,
10444 0,
10445 SCSI_SNSCODE_LOGICAL_BLOCK_ADDRESS_OUT_OF_RANGE,
10446 satIOContext);
10447
10448 ostiInitiatorIOCompleted( tiRoot,
10449 tiIORequest,
10450 tiIOSuccess,
10451 SCSI_STAT_CHECK_CONDITION,
10452 satIOContext->pTiSenseData,
10453 satIOContext->interruptContext );
10454
10455 TI_DBG1(("satWriteSame10: return LBA out of range\n"));
10456 return tiSuccess;
10457 }
10458 }
10459
10460 if (lba + tl <= SAT_TR_LBA_LIMIT)
10461 {
10462 if (pSatDevData->satDMASupport == agTRUE && pSatDevData->satDMAEnabled == agTRUE)
10463 {
10464 /* case 2 */
10465 /* WRITE DMA */
10466 /* can't fit the transfer length since WRITE DMA has 1 byte for sector count */
10467 TI_DBG5(("satWriteSame10: case 1-2 !!! error due to writeSame10\n"));
10468 satSetSensePayload( pSense,
10469 SCSI_SNSKEY_ILLEGAL_REQUEST,
10470 0,
10471 SCSI_SNSCODE_INVALID_FIELD_IN_CDB,
10472 satIOContext);
10473
10474 ostiInitiatorIOCompleted( tiRoot,
10475 tiIORequest,
10476 tiIOSuccess,
10477 SCSI_STAT_CHECK_CONDITION,
10478 satIOContext->pTiSenseData,
10479 satIOContext->interruptContext );
10480 return tiSuccess;
10481 }
10482 else
10483 {
10484 /* case 1 */
10485 /* WRITE MULTIPLE or WRITE SECTOR(S) */
10486 /* WRITE SECTORS is chosen for easier implemetation */
10487 /* can't fit the transfer length since WRITE DMA has 1 byte for sector count */
10488 TI_DBG5(("satWriteSame10: case 1-1 !!! error due to writesame10\n"));
10489 satSetSensePayload( pSense,
10490 SCSI_SNSKEY_ILLEGAL_REQUEST,
10491 0,
10492 SCSI_SNSCODE_INVALID_FIELD_IN_CDB,
10493 satIOContext);
10494
10495 ostiInitiatorIOCompleted( tiRoot,
10496 tiIORequest,
10497 tiIOSuccess,
10498 SCSI_STAT_CHECK_CONDITION,
10499 satIOContext->pTiSenseData,
10500 satIOContext->interruptContext );
10501 return tiSuccess;
10502 }
10503 } /* end of case 1 and 2 */
10504
10505 /* case 3 and 4 */
10506 if (pSatDevData->sat48BitSupport == agTRUE)
10507 {
10508 if (pSatDevData->satDMASupport == agTRUE && pSatDevData->satDMAEnabled == agTRUE)
10509 {
10510 /* case 3 */
10511 /* WRITE DMA EXT or WRITE DMA FUA EXT */
10512 /* WRITE DMA EXT is chosen since WRITE SAME does not have FUA bit */
10513 TI_DBG5(("satWriteSame10: case 1-3\n"));
10514 fis->h.fisType = 0x27; /* Reg host to device */
10515 fis->h.c_pmPort = 0x80; /* C Bit is set */
10516
10517 fis->h.command = SAT_WRITE_DMA_EXT; /* 0x35 */
10518
10519 fis->h.features = 0; /* FIS reserve */
10520 fis->d.lbaLow = scsiCmnd->cdb[5]; /* FIS LBA (7 :0 ) */
10521 fis->d.lbaMid = scsiCmnd->cdb[4]; /* FIS LBA (15:8 ) */
10522 fis->d.lbaHigh = scsiCmnd->cdb[3]; /* FIS LBA (23:16) */
10523 fis->d.device = 0x40; /* FIS LBA mode set */
10524 fis->d.lbaLowExp = scsiCmnd->cdb[2]; /* FIS LBA (31:24) */
10525 fis->d.lbaMidExp = 0; /* FIS LBA (39:32) */
10526 fis->d.lbaHighExp = 0; /* FIS LBA (47:40) */
10527 fis->d.featuresExp = 0; /* FIS reserve */
10528 if (tl == 0)
10529 {
10530 /* error check
10531 ATA spec, p125, 6.17.29
10532 pSatDevData->satMaxUserAddrSectors should be 0x0FFFFFFF
10533 and allowed value is 0x0FFFFFFF - 1
10534 */
10535 if (pSatDevData->satMaxUserAddrSectors > 0x0FFFFFFF)
10536 {
10537 TI_DBG5(("satWriteSame10: case 3 !!! warning can't fit sectors\n"));
10538 satSetSensePayload( pSense,
10539 SCSI_SNSKEY_ILLEGAL_REQUEST,
10540 0,
10541 SCSI_SNSCODE_INVALID_FIELD_IN_CDB,
10542 satIOContext);
10543
10544 ostiInitiatorIOCompleted( tiRoot,
10545 tiIORequest,
10546 tiIOSuccess,
10547 SCSI_STAT_CHECK_CONDITION,
10548 satIOContext->pTiSenseData,
10549 satIOContext->interruptContext );
10550 return tiSuccess;
10551 }
10552 }
10553 /* one sector at a time */
10554 fis->d.sectorCount = 1; /* FIS sector count (7:0) */
10555 fis->d.sectorCountExp = 0; /* FIS sector count (15:8) */
10556 fis->d.reserved4 = 0;
10557 fis->d.control = 0; /* FIS HOB bit clear */
10558 fis->d.reserved5 = 0;
10559
10560 agRequestType = AGSA_SATA_PROTOCOL_DMA_WRITE;
10561 }
10562 else
10563 {
10564 /* case 4 */
10565 /* WRITE MULTIPLE EXT or WRITE MULTIPLE FUA EXT or WRITE SECTOR(S) EXT */
10566 /* WRITE SECTORS EXT is chosen for easier implemetation */
10567 TI_DBG5(("satWriteSame10: case 1-4\n"));
10568 fis->h.fisType = 0x27; /* Reg host to device */
10569 fis->h.c_pmPort = 0x80; /* C Bit is set */
10570
10571 fis->h.command = SAT_WRITE_SECTORS_EXT; /* 0x34 */
10572 fis->h.features = 0; /* FIS reserve */
10573 fis->d.lbaLow = scsiCmnd->cdb[5]; /* FIS LBA (7 :0 ) */
10574 fis->d.lbaMid = scsiCmnd->cdb[4]; /* FIS LBA (15:8 ) */
10575 fis->d.lbaHigh = scsiCmnd->cdb[3]; /* FIS LBA (23:16) */
10576 fis->d.device = 0x40; /* FIS LBA mode set */
10577 fis->d.lbaLowExp = scsiCmnd->cdb[2]; /* FIS LBA (31:24) */
10578 fis->d.lbaMidExp = 0; /* FIS LBA (39:32) */
10579 fis->d.lbaHighExp = 0; /* FIS LBA (47:40) */
10580 fis->d.featuresExp = 0; /* FIS reserve */
10581 if (tl == 0)
10582 {
10583 /* error check
10584 ATA spec, p125, 6.17.29
10585 pSatDevData->satMaxUserAddrSectors should be 0x0FFFFFFF
10586 and allowed value is 0x0FFFFFFF - 1
10587 */
10588 if (pSatDevData->satMaxUserAddrSectors > 0x0FFFFFFF)
10589 {
10590 TI_DBG5(("satWriteSame10: case 4 !!! warning can't fit sectors\n"));
10591 satSetSensePayload( pSense,
10592 SCSI_SNSKEY_ILLEGAL_REQUEST,
10593 0,
10594 SCSI_SNSCODE_INVALID_FIELD_IN_CDB,
10595 satIOContext);
10596
10597 ostiInitiatorIOCompleted( tiRoot,
10598 tiIORequest,
10599 tiIOSuccess,
10600 SCSI_STAT_CHECK_CONDITION,
10601 satIOContext->pTiSenseData,
10602 satIOContext->interruptContext );
10603 return tiSuccess;
10604 }
10605 }
10606 /* one sector at a time */
10607 fis->d.sectorCount = 1; /* FIS sector count (7:0) */
10608 fis->d.sectorCountExp = 0; /* FIS sector count (15:8) */
10609 fis->d.reserved4 = 0;
10610 fis->d.control = 0; /* FIS HOB bit clear */
10611 fis->d.reserved5 = 0;
10612
10613 agRequestType = AGSA_SATA_PROTOCOL_PIO_WRITE;
10614 }
10615 }
10616
10617 /* case 5 */
10618 if (pSatDevData->satNCQ == agTRUE)
10619 {
10620 /* WRITE FPDMA QUEUED */
10621 if (pSatDevData->sat48BitSupport != agTRUE)
10622 {
10623 TI_DBG5(("satWriteSame10: case 1-5 !!! error NCQ but 28 bit address support \n"));
10624 satSetSensePayload( pSense,
10625 SCSI_SNSKEY_ILLEGAL_REQUEST,
10626 0,
10627 SCSI_SNSCODE_INVALID_FIELD_IN_CDB,
10628 satIOContext);
10629
10630 ostiInitiatorIOCompleted( tiRoot,
10631 tiIORequest,
10632 tiIOSuccess,
10633 SCSI_STAT_CHECK_CONDITION,
10634 satIOContext->pTiSenseData,
10635 satIOContext->interruptContext );
10636 return tiSuccess;
10637 }
10638 TI_DBG5(("satWriteSame10: case 1-5\n"));
10639
10640 /* Support 48-bit FPDMA addressing, use WRITE FPDMA QUEUE command */
10641
10642 fis->h.fisType = 0x27; /* Reg host to device */
10643 fis->h.c_pmPort = 0x80; /* C Bit is set */
10644 fis->h.command = SAT_WRITE_FPDMA_QUEUED; /* 0x61 */
10645
10646 if (tl == 0)
10647 {
10648 /* error check
10649 ATA spec, p125, 6.17.29
10650 pSatDevData->satMaxUserAddrSectors should be 0x0FFFFFFF
10651 and allowed value is 0x0FFFFFFF - 1
10652 */
10653 if (pSatDevData->satMaxUserAddrSectors > 0x0FFFFFFF)
10654 {
10655 TI_DBG5(("satWriteSame10: case 4 !!! warning can't fit sectors\n"));
10656 satSetSensePayload( pSense,
10657 SCSI_SNSKEY_ILLEGAL_REQUEST,
10658 0,
10659 SCSI_SNSCODE_INVALID_FIELD_IN_CDB,
10660 satIOContext);
10661
10662 ostiInitiatorIOCompleted( tiRoot,
10663 tiIORequest,
10664 tiIOSuccess,
10665 SCSI_STAT_CHECK_CONDITION,
10666 satIOContext->pTiSenseData,
10667 satIOContext->interruptContext );
10668 return tiSuccess;
10669 }
10670 }
10671 /* one sector at a time */
10672 fis->h.features = 1; /* FIS sector count (7:0) */
10673 fis->d.featuresExp = 0; /* FIS sector count (15:8) */
10674
10675
10676 fis->d.lbaLow = scsiCmnd->cdb[5]; /* FIS LBA (7 :0 ) */
10677 fis->d.lbaMid = scsiCmnd->cdb[4]; /* FIS LBA (15:8 ) */
10678 fis->d.lbaHigh = scsiCmnd->cdb[3]; /* FIS LBA (23:16) */
10679
10680 /* NO FUA bit in the WRITE SAME 10 */
10681 fis->d.device = 0x40; /* FIS FUA clear */
10682
10683 fis->d.lbaLowExp = scsiCmnd->cdb[2]; /* FIS LBA (31:24) */
10684 fis->d.lbaMidExp = 0; /* FIS LBA (39:32) */
10685 fis->d.lbaHighExp = 0; /* FIS LBA (47:40) */
10686 fis->d.sectorCount = 0; /* Tag (7:3) set by LL layer */
10687 fis->d.sectorCountExp = 0;
10688 fis->d.reserved4 = 0;
10689 fis->d.control = 0; /* FIS HOB bit clear */
10690 fis->d.reserved5 = 0;
10691
10692 agRequestType = AGSA_SATA_PROTOCOL_FPDMA_WRITE;
10693 }
10694 /* Initialize CB for SATA completion.
10695 */
10696 satIOContext->satCompleteCB = &satWriteSame10CB;
10697
10698 /*
10699 * Prepare SGL and send FIS to LL layer.
10700 */
10701 satIOContext->reqType = agRequestType; /* Save it */
10702
10703 status = sataLLIOStart( tiRoot,
10704 tiIORequest,
10705 tiDeviceHandle,
10706 tiScsiRequest,
10707 satIOContext);
10708 return (status);
10709
10710
10711 } /* end of case 1 */
10712 else if ( !(scsiCmnd->cdb[1] & SCSI_WRITE_SAME_LBDATA_MASK) &&
10713 (scsiCmnd->cdb[1] & SCSI_WRITE_SAME_PBDATA_MASK))
10714 {
10715 /* spec 9.26.2, Table 62, p64, case 2*/
10716 satSetSensePayload( pSense,
10717 SCSI_SNSKEY_ILLEGAL_REQUEST,
10718 0,
10719 SCSI_SNSCODE_INVALID_FIELD_IN_CDB,
10720 satIOContext);
10721
10722 ostiInitiatorIOCompleted( tiRoot,
10723 tiIORequest,
10724 tiIOSuccess,
10725 SCSI_STAT_CHECK_CONDITION,
10726 satIOContext->pTiSenseData,
10727 satIOContext->interruptContext );
10728
10729 TI_DBG5(("satWriteSame10: return Table 62 case 2\n"));
10730 return tiSuccess;
10731 }
10732 else if ( (scsiCmnd->cdb[1] & SCSI_WRITE_SAME_LBDATA_MASK) &&
10733 !(scsiCmnd->cdb[1] & SCSI_WRITE_SAME_PBDATA_MASK))
10734 {
10735 TI_DBG5(("satWriteSame10: Table 62 case 3\n"));
10736
10737 }
10738 else /* ( (scsiCmnd->cdb[1] & SCSI_WRITE_SAME_LBDATA_MASK) &&
10739 (scsiCmnd->cdb[1] & SCSI_WRITE_SAME_PBDATA_MASK)) */
10740 {
10741
10742 /* spec 9.26.2, Table 62, p64, case 4*/
10743 satSetSensePayload( pSense,
10744 SCSI_SNSKEY_ILLEGAL_REQUEST,
10745 0,
10746 SCSI_SNSCODE_INVALID_FIELD_IN_CDB,
10747 satIOContext);
10748
10749 ostiInitiatorIOCompleted( tiRoot,
10750 tiIORequest,
10751 tiIOSuccess,
10752 SCSI_STAT_CHECK_CONDITION,
10753 satIOContext->pTiSenseData,
10754 satIOContext->interruptContext );
10755
10756 TI_DBG5(("satWriteSame10: return Table 62 case 4\n"));
10757 return tiSuccess;
10758 }
10759
10760
10761 return tiSuccess;
10762 }
10763
10764 /*****************************************************************************/
10765 /*! \brief SAT implementation for SCSI satWriteSame10_1.
10766 *
10767 * SAT implementation for SCSI WRITESANE10 and send FIS request to LL layer.
10768 * This is used when WRITESAME10 is divided into multiple ATA commands
10769 *
10770 * \param tiRoot: Pointer to TISA initiator driver/port instance.
10771 * \param tiIORequest: Pointer to TISA I/O request context for this I/O.
10772 * \param tiDeviceHandle: Pointer to TISA device handle for this I/O.
10773 * \param tiScsiRequest: Pointer to TISA SCSI I/O request and SGL list.
10774 * \param satIOContext_t: Pointer to the SAT IO Context
10775 * \param lba: LBA
10776 *
10777 * \return If command is started successfully
10778 * - \e tiSuccess: I/O request successfully initiated.
10779 * - \e tiBusy: No resources available, try again later.
10780 * - \e tiIONoDevice: Invalid device handle.
10781 * - \e tiError: Other errors.
10782 */
10783 /*****************************************************************************/
satWriteSame10_1(tiRoot_t * tiRoot,tiIORequest_t * tiIORequest,tiDeviceHandle_t * tiDeviceHandle,tiScsiInitiatorRequest_t * tiScsiRequest,satIOContext_t * satIOContext,bit32 lba)10784 GLOBAL bit32 satWriteSame10_1(
10785 tiRoot_t *tiRoot,
10786 tiIORequest_t *tiIORequest,
10787 tiDeviceHandle_t *tiDeviceHandle,
10788 tiScsiInitiatorRequest_t *tiScsiRequest,
10789 satIOContext_t *satIOContext,
10790 bit32 lba
10791 )
10792 {
10793 /*
10794 sends SAT_WRITE_DMA_EXT
10795 */
10796
10797 bit32 status;
10798 bit32 agRequestType;
10799 agsaFisRegHostToDevice_t *fis;
10800 bit8 lba1, lba2 ,lba3, lba4;
10801
10802 TI_DBG5(("satWriteSame10_1 entry: tiDeviceHandle=%p tiIORequest=%p\n",
10803 tiDeviceHandle, tiIORequest));
10804
10805 fis = satIOContext->pFis;
10806
10807 /* MSB */
10808 lba1 = (bit8)((lba & 0xFF000000) >> (8*3));
10809 lba2 = (bit8)((lba & 0x00FF0000) >> (8*2));
10810 lba3 = (bit8)((lba & 0x0000FF00) >> (8*1));
10811 /* LSB */
10812 lba4 = (bit8)(lba & 0x000000FF);
10813
10814 /* SAT_WRITE_DMA_EXT */
10815 fis->h.fisType = 0x27; /* Reg host to device */
10816 fis->h.c_pmPort = 0x80; /* C Bit is set */
10817
10818 fis->h.command = SAT_WRITE_DMA_EXT; /* 0x35 */
10819
10820 fis->h.features = 0; /* FIS reserve */
10821 fis->d.lbaLow = lba4; /* FIS LBA (7 :0 ) */
10822 fis->d.lbaMid = lba3; /* FIS LBA (15:8 ) */
10823 fis->d.lbaHigh = lba2; /* FIS LBA (23:16) */
10824 fis->d.device = 0x40; /* FIS LBA mode set */
10825 fis->d.lbaLowExp = lba1; /* FIS LBA (31:24) */
10826 fis->d.lbaMidExp = 0; /* FIS LBA (39:32) */
10827 fis->d.lbaHighExp = 0; /* FIS LBA (47:40) */
10828 fis->d.featuresExp = 0; /* FIS reserve */
10829 /* one sector at a time */
10830 fis->d.sectorCount = 1; /* FIS sector count (7:0) */
10831 fis->d.sectorCountExp = 0; /* FIS sector count (15:8) */
10832
10833 fis->d.reserved4 = 0;
10834 fis->d.control = 0; /* FIS HOB bit clear */
10835 fis->d.reserved5 = 0;
10836
10837
10838 agRequestType = AGSA_SATA_PROTOCOL_DMA_WRITE;
10839
10840 /* Initialize CB for SATA completion.
10841 */
10842 satIOContext->satCompleteCB = &satWriteSame10CB;
10843
10844 /*
10845 * Prepare SGL and send FIS to LL layer.
10846 */
10847 satIOContext->reqType = agRequestType; /* Save it */
10848
10849 status = sataLLIOStart( tiRoot,
10850 tiIORequest,
10851 tiDeviceHandle,
10852 tiScsiRequest,
10853 satIOContext);
10854
10855 TI_DBG5(("satWriteSame10_1 return status %d\n", status));
10856 return status;
10857 }
10858
10859 /*****************************************************************************/
10860 /*! \brief SAT implementation for SCSI satWriteSame10_2.
10861 *
10862 * SAT implementation for SCSI WRITESANE10 and send FIS request to LL layer.
10863 * This is used when WRITESAME10 is divided into multiple ATA commands
10864 *
10865 * \param tiRoot: Pointer to TISA initiator driver/port instance.
10866 * \param tiIORequest: Pointer to TISA I/O request context for this I/O.
10867 * \param tiDeviceHandle: Pointer to TISA device handle for this I/O.
10868 * \param tiScsiRequest: Pointer to TISA SCSI I/O request and SGL list.
10869 * \param satIOContext_t: Pointer to the SAT IO Context
10870 * \param lba: LBA
10871 *
10872 * \return If command is started successfully
10873 * - \e tiSuccess: I/O request successfully initiated.
10874 * - \e tiBusy: No resources available, try again later.
10875 * - \e tiIONoDevice: Invalid device handle.
10876 * - \e tiError: Other errors.
10877 */
10878 /*****************************************************************************/
satWriteSame10_2(tiRoot_t * tiRoot,tiIORequest_t * tiIORequest,tiDeviceHandle_t * tiDeviceHandle,tiScsiInitiatorRequest_t * tiScsiRequest,satIOContext_t * satIOContext,bit32 lba)10879 GLOBAL bit32 satWriteSame10_2(
10880 tiRoot_t *tiRoot,
10881 tiIORequest_t *tiIORequest,
10882 tiDeviceHandle_t *tiDeviceHandle,
10883 tiScsiInitiatorRequest_t *tiScsiRequest,
10884 satIOContext_t *satIOContext,
10885 bit32 lba
10886 )
10887 {
10888 /*
10889 sends SAT_WRITE_SECTORS_EXT
10890 */
10891
10892 bit32 status;
10893 bit32 agRequestType;
10894 agsaFisRegHostToDevice_t *fis;
10895 bit8 lba1, lba2 ,lba3, lba4;
10896
10897 TI_DBG5(("satWriteSame10_2 entry: tiDeviceHandle=%p tiIORequest=%p\n",
10898 tiDeviceHandle, tiIORequest));
10899
10900 fis = satIOContext->pFis;
10901
10902 /* MSB */
10903 lba1 = (bit8)((lba & 0xFF000000) >> (8*3));
10904 lba2 = (bit8)((lba & 0x00FF0000) >> (8*2));
10905 lba3 = (bit8)((lba & 0x0000FF00) >> (8*1));
10906 /* LSB */
10907 lba4 = (bit8)(lba & 0x000000FF);
10908
10909
10910 /* SAT_WRITE_SECTORS_EXT */
10911 fis->h.fisType = 0x27; /* Reg host to device */
10912 fis->h.c_pmPort = 0x80; /* C Bit is set */
10913
10914 fis->h.command = SAT_WRITE_SECTORS_EXT; /* 0x34 */
10915 fis->h.features = 0; /* FIS reserve */
10916 fis->d.lbaLow = lba4; /* FIS LBA (7 :0 ) */
10917 fis->d.lbaMid = lba3; /* FIS LBA (15:8 ) */
10918 fis->d.lbaHigh = lba2; /* FIS LBA (23:16) */
10919 fis->d.device = 0x40; /* FIS LBA mode set */
10920 fis->d.lbaLowExp = lba1; /* FIS LBA (31:24) */
10921 fis->d.lbaMidExp = 0; /* FIS LBA (39:32) */
10922 fis->d.lbaHighExp = 0; /* FIS LBA (47:40) */
10923 fis->d.featuresExp = 0; /* FIS reserve */
10924 /* one sector at a time */
10925 fis->d.sectorCount = 1; /* FIS sector count (7:0) */
10926 fis->d.sectorCountExp = 0; /* FIS sector count (15:8) */
10927
10928 fis->d.reserved4 = 0;
10929 fis->d.control = 0; /* FIS HOB bit clear */
10930 fis->d.reserved5 = 0;
10931
10932
10933 agRequestType = AGSA_SATA_PROTOCOL_PIO_WRITE;
10934
10935 /* Initialize CB for SATA completion.
10936 */
10937 satIOContext->satCompleteCB = &satWriteSame10CB;
10938
10939 /*
10940 * Prepare SGL and send FIS to LL layer.
10941 */
10942 satIOContext->reqType = agRequestType; /* Save it */
10943
10944 status = sataLLIOStart( tiRoot,
10945 tiIORequest,
10946 tiDeviceHandle,
10947 tiScsiRequest,
10948 satIOContext);
10949
10950 TI_DBG5(("satWriteSame10_2 return status %d\n", status));
10951 return status;
10952 }
10953
10954 /*****************************************************************************/
10955 /*! \brief SAT implementation for SCSI satWriteSame10_3.
10956 *
10957 * SAT implementation for SCSI WRITESANE10 and send FIS request to LL layer.
10958 * This is used when WRITESAME10 is divided into multiple ATA commands
10959 *
10960 * \param tiRoot: Pointer to TISA initiator driver/port instance.
10961 * \param tiIORequest: Pointer to TISA I/O request context for this I/O.
10962 * \param tiDeviceHandle: Pointer to TISA device handle for this I/O.
10963 * \param tiScsiRequest: Pointer to TISA SCSI I/O request and SGL list.
10964 * \param satIOContext_t: Pointer to the SAT IO Context
10965 * \param lba: LBA
10966 *
10967 * \return If command is started successfully
10968 * - \e tiSuccess: I/O request successfully initiated.
10969 * - \e tiBusy: No resources available, try again later.
10970 * - \e tiIONoDevice: Invalid device handle.
10971 * - \e tiError: Other errors.
10972 */
10973 /*****************************************************************************/
satWriteSame10_3(tiRoot_t * tiRoot,tiIORequest_t * tiIORequest,tiDeviceHandle_t * tiDeviceHandle,tiScsiInitiatorRequest_t * tiScsiRequest,satIOContext_t * satIOContext,bit32 lba)10974 GLOBAL bit32 satWriteSame10_3(
10975 tiRoot_t *tiRoot,
10976 tiIORequest_t *tiIORequest,
10977 tiDeviceHandle_t *tiDeviceHandle,
10978 tiScsiInitiatorRequest_t *tiScsiRequest,
10979 satIOContext_t *satIOContext,
10980 bit32 lba
10981 )
10982 {
10983 /*
10984 sends SAT_WRITE_FPDMA_QUEUED
10985 */
10986
10987 bit32 status;
10988 bit32 agRequestType;
10989 agsaFisRegHostToDevice_t *fis;
10990 bit8 lba1, lba2 ,lba3, lba4;
10991
10992 TI_DBG5(("satWriteSame10_3 entry: tiDeviceHandle=%p tiIORequest=%p\n",
10993 tiDeviceHandle, tiIORequest));
10994
10995 fis = satIOContext->pFis;
10996
10997 /* MSB */
10998 lba1 = (bit8)((lba & 0xFF000000) >> (8*3));
10999 lba2 = (bit8)((lba & 0x00FF0000) >> (8*2));
11000 lba3 = (bit8)((lba & 0x0000FF00) >> (8*1));
11001 /* LSB */
11002 lba4 = (bit8)(lba & 0x000000FF);
11003
11004 /* SAT_WRITE_FPDMA_QUEUED */
11005 fis->h.fisType = 0x27; /* Reg host to device */
11006 fis->h.c_pmPort = 0x80; /* C Bit is set */
11007 fis->h.command = SAT_WRITE_FPDMA_QUEUED; /* 0x61 */
11008
11009
11010 /* one sector at a time */
11011 fis->h.features = 1; /* FIS sector count (7:0) */
11012 fis->d.featuresExp = 0; /* FIS sector count (15:8) */
11013
11014
11015 fis->d.lbaLow = lba4; /* FIS LBA (7 :0 ) */
11016 fis->d.lbaMid = lba3; /* FIS LBA (15:8 ) */
11017 fis->d.lbaHigh = lba2; /* FIS LBA (23:16) */
11018
11019 /* NO FUA bit in the WRITE SAME 10 */
11020 fis->d.device = 0x40; /* FIS FUA clear */
11021
11022 fis->d.lbaLowExp = lba1; /* FIS LBA (31:24) */
11023 fis->d.lbaMidExp = 0; /* FIS LBA (39:32) */
11024 fis->d.lbaHighExp = 0; /* FIS LBA (47:40) */
11025 fis->d.sectorCount = 0; /* Tag (7:3) set by LL layer */
11026 fis->d.sectorCountExp = 0;
11027 fis->d.reserved4 = 0;
11028 fis->d.control = 0; /* FIS HOB bit clear */
11029 fis->d.reserved5 = 0;
11030
11031 agRequestType = AGSA_SATA_PROTOCOL_FPDMA_WRITE;
11032
11033 /* Initialize CB for SATA completion.
11034 */
11035 satIOContext->satCompleteCB = &satWriteSame10CB;
11036
11037 /*
11038 * Prepare SGL and send FIS to LL layer.
11039 */
11040 satIOContext->reqType = agRequestType; /* Save it */
11041
11042 status = sataLLIOStart( tiRoot,
11043 tiIORequest,
11044 tiDeviceHandle,
11045 tiScsiRequest,
11046 satIOContext);
11047
11048 TI_DBG5(("satWriteSame10_2 return status %d\n", status));
11049 return status;
11050 }
11051 /*****************************************************************************/
11052 /*! \brief SAT implementation for SCSI satWriteSame16.
11053 *
11054 * SAT implementation for SCSI satWriteSame16.
11055 *
11056 * \param tiRoot: Pointer to TISA initiator driver/port instance.
11057 * \param tiIORequest: Pointer to TISA I/O request context for this I/O.
11058 * \param tiDeviceHandle: Pointer to TISA device handle for this I/O.
11059 * \param tiScsiRequest: Pointer to TISA SCSI I/O request and SGL list.
11060 * \param satIOContext_t: Pointer to the SAT IO Context
11061 *
11062 * \return If command is started successfully
11063 * - \e tiSuccess: I/O request successfully initiated.
11064 * - \e tiBusy: No resources available, try again later.
11065 * - \e tiIONoDevice: Invalid device handle.
11066 * - \e tiError: Other errors.
11067 */
11068 /*****************************************************************************/
satWriteSame16(tiRoot_t * tiRoot,tiIORequest_t * tiIORequest,tiDeviceHandle_t * tiDeviceHandle,tiScsiInitiatorRequest_t * tiScsiRequest,satIOContext_t * satIOContext)11069 GLOBAL bit32 satWriteSame16(
11070 tiRoot_t *tiRoot,
11071 tiIORequest_t *tiIORequest,
11072 tiDeviceHandle_t *tiDeviceHandle,
11073 tiScsiInitiatorRequest_t *tiScsiRequest,
11074 satIOContext_t *satIOContext)
11075 {
11076 scsiRspSense_t *pSense;
11077
11078 pSense = satIOContext->pSense;
11079
11080 TI_DBG5(("satWriteSame16:start\n"));
11081
11082
11083 satSetSensePayload( pSense,
11084 SCSI_SNSKEY_NO_SENSE,
11085 0,
11086 SCSI_SNSCODE_NO_ADDITIONAL_INFO,
11087 satIOContext);
11088
11089 ostiInitiatorIOCompleted( tiRoot,
11090 tiIORequest, /* == &satIntIo->satOrgTiIORequest */
11091 tiIOSuccess,
11092 SCSI_STAT_CHECK_CONDITION,
11093 satIOContext->pTiSenseData,
11094 satIOContext->interruptContext );
11095 TI_DBG5(("satWriteSame16: return internal checking\n"));
11096 return tiSuccess;
11097 }
11098
11099 /*****************************************************************************/
11100 /*! \brief SAT implementation for SCSI satLogSense_1.
11101 *
11102 * Part of SAT implementation for SCSI satLogSense.
11103 *
11104 * \param tiRoot: Pointer to TISA initiator driver/port instance.
11105 * \param tiIORequest: Pointer to TISA I/O request context for this I/O.
11106 * \param tiDeviceHandle: Pointer to TISA device handle for this I/O.
11107 * \param tiScsiRequest: Pointer to TISA SCSI I/O request and SGL list.
11108 * \param satIOContext_t: Pointer to the SAT IO Context
11109 *
11110 * \return If command is started successfully
11111 * - \e tiSuccess: I/O request successfully initiated.
11112 * - \e tiBusy: No resources available, try again later.
11113 * - \e tiIONoDevice: Invalid device handle.
11114 * - \e tiError: Other errors.
11115 */
11116 /*****************************************************************************/
satLogSense_1(tiRoot_t * tiRoot,tiIORequest_t * tiIORequest,tiDeviceHandle_t * tiDeviceHandle,tiScsiInitiatorRequest_t * tiScsiRequest,satIOContext_t * satIOContext)11117 GLOBAL bit32 satLogSense_1(
11118 tiRoot_t *tiRoot,
11119 tiIORequest_t *tiIORequest,
11120 tiDeviceHandle_t *tiDeviceHandle,
11121 tiScsiInitiatorRequest_t *tiScsiRequest,
11122 satIOContext_t *satIOContext)
11123 {
11124 bit32 status;
11125 bit32 agRequestType;
11126 satDeviceData_t *pSatDevData;
11127 agsaFisRegHostToDevice_t *fis;
11128
11129 pSatDevData = satIOContext->pSatDevData;
11130 fis = satIOContext->pFis;
11131
11132 TI_DBG5(("satLogSense_1: start\n"));
11133
11134
11135 /* SAT Rev 8, 10.2.4 p74 */
11136 if ( pSatDevData->sat48BitSupport == agTRUE )
11137 {
11138 TI_DBG5(("satLogSense_1: case 2-1 sends READ LOG EXT\n"));
11139 /* sends READ LOG EXT */
11140 fis->h.fisType = 0x27; /* Reg host to device */
11141 fis->h.c_pmPort = 0x80; /* C Bit is set */
11142
11143 fis->h.command = SAT_READ_LOG_EXT; /* 0x2F */
11144 fis->h.features = 0; /* FIS reserve */
11145 fis->d.lbaLow = 0x07; /* 0x07 */
11146 fis->d.lbaMid = 0; /* */
11147 fis->d.lbaHigh = 0; /* */
11148 fis->d.device = 0; /* */
11149 fis->d.lbaLowExp = 0; /* */
11150 fis->d.lbaMidExp = 0; /* */
11151 fis->d.lbaHighExp = 0; /* */
11152 fis->d.featuresExp = 0; /* FIS reserve */
11153 fis->d.sectorCount = 0x01; /* 1 sector counts */
11154 fis->d.sectorCountExp = 0x00; /* 1 sector counts */
11155 fis->d.reserved4 = 0;
11156 fis->d.control = 0; /* FIS HOB bit clear */
11157 fis->d.reserved5 = 0;
11158
11159 agRequestType = AGSA_SATA_PROTOCOL_PIO_READ;
11160
11161 /* Initialize CB for SATA completion.
11162 */
11163 satIOContext->satCompleteCB = &satLogSenseCB;
11164
11165 /*
11166 * Prepare SGL and send FIS to LL layer.
11167 */
11168 satIOContext->reqType = agRequestType; /* Save it */
11169
11170 status = sataLLIOStart( tiRoot,
11171 tiIORequest,
11172 tiDeviceHandle,
11173 tiScsiRequest,
11174 satIOContext);
11175 return status;
11176
11177 }
11178 else
11179 {
11180 TI_DBG5(("satLogSense_1: case 2-2 sends SMART READ LOG\n"));
11181 /* sends SMART READ LOG */
11182 fis->h.fisType = 0x27; /* Reg host to device */
11183 fis->h.c_pmPort = 0x80; /* C Bit is set */
11184
11185 fis->h.command = SAT_SMART_READ_LOG; /* 0x2F */
11186 fis->h.features = 0x00; /* 0xd5 */
11187 fis->d.lbaLow = 0x06; /* 0x06 */
11188 fis->d.lbaMid = 0x00; /* 0x4f */
11189 fis->d.lbaHigh = 0x00; /* 0xc2 */
11190 fis->d.device = 0; /* */
11191 fis->d.lbaLowExp = 0; /* */
11192 fis->d.lbaMidExp = 0; /* */
11193 fis->d.lbaHighExp = 0; /* */
11194 fis->d.featuresExp = 0; /* FIS reserve */
11195 fis->d.sectorCount = 0x01; /* */
11196 fis->d.sectorCountExp = 0x00; /* */
11197 fis->d.reserved4 = 0;
11198 fis->d.control = 0; /* FIS HOB bit clear */
11199 fis->d.reserved5 = 0;
11200
11201 agRequestType = AGSA_SATA_PROTOCOL_PIO_READ;
11202
11203 /* Initialize CB for SATA completion.
11204 */
11205 satIOContext->satCompleteCB = &satLogSenseCB;
11206
11207 /*
11208 * Prepare SGL and send FIS to LL layer.
11209 */
11210 satIOContext->reqType = agRequestType; /* Save it */
11211
11212 status = sataLLIOStart( tiRoot,
11213 tiIORequest,
11214 tiDeviceHandle,
11215 tiScsiRequest,
11216 satIOContext);
11217 return status;
11218
11219 }
11220 }
11221
11222 /*****************************************************************************/
11223 /*! \brief SAT implementation for SCSI satSMARTEnable.
11224 *
11225 * Part of SAT implementation for SCSI satLogSense.
11226 *
11227 * \param tiRoot: Pointer to TISA initiator driver/port instance.
11228 * \param tiIORequest: Pointer to TISA I/O request context for this I/O.
11229 * \param tiDeviceHandle: Pointer to TISA device handle for this I/O.
11230 * \param tiScsiRequest: Pointer to TISA SCSI I/O request and SGL list.
11231 * \param satIOContext_t: Pointer to the SAT IO Context
11232 *
11233 * \return If command is started successfully
11234 * - \e tiSuccess: I/O request successfully initiated.
11235 * - \e tiBusy: No resources available, try again later.
11236 * - \e tiIONoDevice: Invalid device handle.
11237 * - \e tiError: Other errors.
11238 */
11239 /*****************************************************************************/
satSMARTEnable(tiRoot_t * tiRoot,tiIORequest_t * tiIORequest,tiDeviceHandle_t * tiDeviceHandle,tiScsiInitiatorRequest_t * tiScsiRequest,satIOContext_t * satIOContext)11240 GLOBAL bit32 satSMARTEnable(
11241 tiRoot_t *tiRoot,
11242 tiIORequest_t *tiIORequest,
11243 tiDeviceHandle_t *tiDeviceHandle,
11244 tiScsiInitiatorRequest_t *tiScsiRequest,
11245 satIOContext_t *satIOContext)
11246 {
11247 bit32 status;
11248 bit32 agRequestType;
11249 agsaFisRegHostToDevice_t *fis;
11250
11251 TI_DBG4(("satSMARTEnable entry: tiDeviceHandle=%p tiIORequest=%p\n",
11252 tiDeviceHandle, tiIORequest));
11253
11254 fis = satIOContext->pFis;
11255
11256 /*
11257 * Send the SAT_SMART_ENABLE_OPERATIONS command.
11258 */
11259 fis->h.fisType = 0x27; /* Reg host to device */
11260 fis->h.c_pmPort = 0x80; /* C Bit is set */
11261
11262 fis->h.command = SAT_SMART_ENABLE_OPERATIONS; /* 0xB0 */
11263 fis->h.features = 0xD8;
11264 fis->d.lbaLow = 0;
11265 fis->d.lbaMid = 0x4F;
11266 fis->d.lbaHigh = 0xC2;
11267 fis->d.device = 0;
11268 fis->d.lbaLowExp = 0;
11269 fis->d.lbaMidExp = 0;
11270 fis->d.lbaHighExp = 0;
11271 fis->d.featuresExp = 0;
11272 fis->d.sectorCount = 0;
11273 fis->d.sectorCountExp = 0;
11274 fis->d.reserved4 = 0;
11275 fis->d.control = 0; /* FIS HOB bit clear */
11276 fis->d.reserved5 = 0;
11277
11278 agRequestType = AGSA_SATA_PROTOCOL_NON_DATA;
11279
11280 /* Initialize CB for SATA completion.
11281 */
11282 satIOContext->satCompleteCB = &satSMARTEnableCB;
11283
11284 /*
11285 * Prepare SGL and send FIS to LL layer.
11286 */
11287 satIOContext->reqType = agRequestType; /* Save it */
11288
11289 status = sataLLIOStart( tiRoot,
11290 tiIORequest,
11291 tiDeviceHandle,
11292 tiScsiRequest,
11293 satIOContext);
11294
11295
11296 return status;
11297 }
11298
11299 /*****************************************************************************/
11300 /*! \brief SAT implementation for SCSI satLogSense_3.
11301 *
11302 * Part of SAT implementation for SCSI satLogSense.
11303 *
11304 * \param tiRoot: Pointer to TISA initiator driver/port instance.
11305 * \param tiIORequest: Pointer to TISA I/O request context for this I/O.
11306 * \param tiDeviceHandle: Pointer to TISA device handle for this I/O.
11307 * \param tiScsiRequest: Pointer to TISA SCSI I/O request and SGL list.
11308 * \param satIOContext_t: Pointer to the SAT IO Context
11309 *
11310 * \return If command is started successfully
11311 * - \e tiSuccess: I/O request successfully initiated.
11312 * - \e tiBusy: No resources available, try again later.
11313 * - \e tiIONoDevice: Invalid device handle.
11314 * - \e tiError: Other errors.
11315 */
11316 /*****************************************************************************/
satLogSense_3(tiRoot_t * tiRoot,tiIORequest_t * tiIORequest,tiDeviceHandle_t * tiDeviceHandle,tiScsiInitiatorRequest_t * tiScsiRequest,satIOContext_t * satIOContext)11317 GLOBAL bit32 satLogSense_3(
11318 tiRoot_t *tiRoot,
11319 tiIORequest_t *tiIORequest,
11320 tiDeviceHandle_t *tiDeviceHandle,
11321 tiScsiInitiatorRequest_t *tiScsiRequest,
11322 satIOContext_t *satIOContext)
11323 {
11324 bit32 status;
11325 bit32 agRequestType;
11326 agsaFisRegHostToDevice_t *fis;
11327
11328 TI_DBG4(("satLogSense_3 entry: tiDeviceHandle=%p tiIORequest=%p\n",
11329 tiDeviceHandle, tiIORequest));
11330
11331 fis = satIOContext->pFis;
11332 /* sends READ LOG EXT */
11333 fis->h.fisType = 0x27; /* Reg host to device */
11334 fis->h.c_pmPort = 0x80; /* C Bit is set */
11335
11336 fis->h.command = SAT_SMART_READ_LOG; /* 0x2F */
11337 fis->h.features = 0xD5; /* 0xd5 */
11338 fis->d.lbaLow = 0x06; /* 0x06 */
11339 fis->d.lbaMid = 0x4F; /* 0x4f */
11340 fis->d.lbaHigh = 0xC2; /* 0xc2 */
11341 fis->d.device = 0; /* */
11342 fis->d.lbaLowExp = 0; /* */
11343 fis->d.lbaMidExp = 0; /* */
11344 fis->d.lbaHighExp = 0; /* */
11345 fis->d.featuresExp = 0; /* FIS reserve */
11346 fis->d.sectorCount = 0x01; /* 1 sector counts */
11347 fis->d.sectorCountExp = 0x00; /* 1 sector counts */
11348 fis->d.reserved4 = 0;
11349 fis->d.control = 0; /* FIS HOB bit clear */
11350 fis->d.reserved5 = 0;
11351
11352 agRequestType = AGSA_SATA_PROTOCOL_PIO_READ;
11353
11354 /* Initialize CB for SATA completion.
11355 */
11356 satIOContext->satCompleteCB = &satLogSenseCB;
11357
11358 /*
11359 * Prepare SGL and send FIS to LL layer.
11360 */
11361 satIOContext->reqType = agRequestType; /* Save it */
11362
11363 status = sataLLIOStart( tiRoot,
11364 tiIORequest,
11365 tiDeviceHandle,
11366 tiScsiRequest,
11367 satIOContext);
11368 return status;
11369 }
11370
11371 /*****************************************************************************/
11372 /*! \brief SAT implementation for SCSI satLogSense_2.
11373 *
11374 * Part of SAT implementation for SCSI satLogSense.
11375 *
11376 * \param tiRoot: Pointer to TISA initiator driver/port instance.
11377 * \param tiIORequest: Pointer to TISA I/O request context for this I/O.
11378 * \param tiDeviceHandle: Pointer to TISA device handle for this I/O.
11379 * \param tiScsiRequest: Pointer to TISA SCSI I/O request and SGL list.
11380 * \param satIOContext_t: Pointer to the SAT IO Context
11381 *
11382 * \return If command is started successfully
11383 * - \e tiSuccess: I/O request successfully initiated.
11384 * - \e tiBusy: No resources available, try again later.
11385 * - \e tiIONoDevice: Invalid device handle.
11386 * - \e tiError: Other errors.
11387 */
11388 /*****************************************************************************/
satLogSense_2(tiRoot_t * tiRoot,tiIORequest_t * tiIORequest,tiDeviceHandle_t * tiDeviceHandle,tiScsiInitiatorRequest_t * tiScsiRequest,satIOContext_t * satIOContext)11389 GLOBAL bit32 satLogSense_2(
11390 tiRoot_t *tiRoot,
11391 tiIORequest_t *tiIORequest,
11392 tiDeviceHandle_t *tiDeviceHandle,
11393 tiScsiInitiatorRequest_t *tiScsiRequest,
11394 satIOContext_t *satIOContext)
11395 {
11396 bit32 status;
11397 bit32 agRequestType;
11398 agsaFisRegHostToDevice_t *fis;
11399
11400 TI_DBG4(("satLogSense_2 entry: tiDeviceHandle=%p tiIORequest=%p\n",
11401 tiDeviceHandle, tiIORequest));
11402
11403 fis = satIOContext->pFis;
11404 /* sends READ LOG EXT */
11405 fis->h.fisType = 0x27; /* Reg host to device */
11406 fis->h.c_pmPort = 0x80; /* C Bit is set */
11407
11408 fis->h.command = SAT_READ_LOG_EXT; /* 0x2F */
11409 fis->h.features = 0; /* FIS reserve */
11410 fis->d.lbaLow = 0x07; /* 0x07 */
11411 fis->d.lbaMid = 0; /* */
11412 fis->d.lbaHigh = 0; /* */
11413 fis->d.device = 0; /* */
11414 fis->d.lbaLowExp = 0; /* */
11415 fis->d.lbaMidExp = 0; /* */
11416 fis->d.lbaHighExp = 0; /* */
11417 fis->d.featuresExp = 0; /* FIS reserve */
11418 fis->d.sectorCount = 0x01; /* 1 sector counts */
11419 fis->d.sectorCountExp = 0x00; /* 1 sector counts */
11420 fis->d.reserved4 = 0;
11421 fis->d.control = 0; /* FIS HOB bit clear */
11422 fis->d.reserved5 = 0;
11423
11424 agRequestType = AGSA_SATA_PROTOCOL_PIO_READ;
11425
11426 /* Initialize CB for SATA completion.
11427 */
11428 satIOContext->satCompleteCB = &satLogSenseCB;
11429
11430 /*
11431 * Prepare SGL and send FIS to LL layer.
11432 */
11433 satIOContext->reqType = agRequestType; /* Save it */
11434
11435 status = sataLLIOStart( tiRoot,
11436 tiIORequest,
11437 tiDeviceHandle,
11438 tiScsiRequest,
11439 satIOContext);
11440 return status;
11441 }
11442
11443 /*****************************************************************************/
11444 /*! \brief SAT implementation for SCSI satLogSenseAllocate.
11445 *
11446 * Part of SAT implementation for SCSI satLogSense.
11447 *
11448 * \param tiRoot: Pointer to TISA initiator driver/port instance.
11449 * \param tiIORequest: Pointer to TISA I/O request context for this I/O.
11450 * \param tiDeviceHandle: Pointer to TISA device handle for this I/O.
11451 * \param tiScsiRequest: Pointer to TISA SCSI I/O request and SGL list.
11452 * \param satIOContext_t: Pointer to the SAT IO Context
11453 * \param payloadSize: size of payload to be allocated.
11454 * \param flag: flag value
11455 *
11456 * \return If command is started successfully
11457 * - \e tiSuccess: I/O request successfully initiated.
11458 * - \e tiBusy: No resources available, try again later.
11459 * - \e tiIONoDevice: Invalid device handle.
11460 * - \e tiError: Other errors.
11461 * \note
11462 * - flag values: LOG_SENSE_0, LOG_SENSE_1, LOG_SENSE_2
11463 */
11464 /*****************************************************************************/
satLogSenseAllocate(tiRoot_t * tiRoot,tiIORequest_t * tiIORequest,tiDeviceHandle_t * tiDeviceHandle,tiScsiInitiatorRequest_t * tiScsiRequest,satIOContext_t * satIOContext,bit32 payloadSize,bit32 flag)11465 GLOBAL bit32 satLogSenseAllocate(
11466 tiRoot_t *tiRoot,
11467 tiIORequest_t *tiIORequest,
11468 tiDeviceHandle_t *tiDeviceHandle,
11469 tiScsiInitiatorRequest_t *tiScsiRequest,
11470 satIOContext_t *satIOContext,
11471 bit32 payloadSize,
11472 bit32 flag
11473 )
11474 {
11475 satDeviceData_t *pSatDevData;
11476 tdIORequestBody_t *tdIORequestBody;
11477 satInternalIo_t *satIntIo = agNULL;
11478 satIOContext_t *satIOContext2;
11479 bit32 status;
11480
11481 TI_DBG4(("satLogSense_2 entry: tiDeviceHandle=%p tiIORequest=%p\n",
11482 tiDeviceHandle, tiIORequest));
11483
11484 pSatDevData = satIOContext->pSatDevData;
11485
11486 /* create internal satIOContext */
11487 satIntIo = satAllocIntIoResource( tiRoot,
11488 tiIORequest, /* original request */
11489 pSatDevData,
11490 payloadSize,
11491 satIntIo);
11492
11493 if (satIntIo == agNULL)
11494 {
11495 /* memory allocation failure */
11496 satFreeIntIoResource( tiRoot,
11497 pSatDevData,
11498 satIntIo);
11499
11500 ostiInitiatorIOCompleted( tiRoot,
11501 tiIORequest,
11502 tiIOFailed,
11503 tiDetailOtherError,
11504 agNULL,
11505 satIOContext->interruptContext );
11506
11507 TI_DBG4(("satLogSense_2: fail in allocation\n"));
11508 return tiSuccess;
11509 } /* end of memory allocation failure */
11510
11511 satIntIo->satOrgTiIORequest = tiIORequest;
11512 tdIORequestBody = (tdIORequestBody_t *)satIntIo->satIntRequestBody;
11513 satIOContext2 = &(tdIORequestBody->transport.SATA.satIOContext);
11514
11515 satIOContext2->pSatDevData = pSatDevData;
11516 satIOContext2->pFis = &(tdIORequestBody->transport.SATA.agSATARequestBody.fis.fisRegHostToDev);
11517 satIOContext2->pScsiCmnd = &(satIntIo->satIntTiScsiXchg.scsiCmnd);
11518 satIOContext2->pSense = &(tdIORequestBody->transport.SATA.sensePayload);
11519 satIOContext2->pTiSenseData = &(tdIORequestBody->transport.SATA.tiSenseData);
11520 satIOContext2->pTiSenseData->senseData = satIOContext2->pSense;
11521 satIOContext2->tiRequestBody = satIntIo->satIntRequestBody;
11522 satIOContext2->interruptContext = satIOContext->interruptContext;
11523 satIOContext2->satIntIoContext = satIntIo;
11524 satIOContext2->ptiDeviceHandle = tiDeviceHandle;
11525 satIOContext2->satOrgIOContext = satIOContext;
11526
11527 if (flag == LOG_SENSE_0)
11528 {
11529 /* SAT_SMART_ENABLE_OPERATIONS */
11530 status = satSMARTEnable( tiRoot,
11531 &(satIntIo->satIntTiIORequest),
11532 tiDeviceHandle,
11533 &(satIntIo->satIntTiScsiXchg),
11534 satIOContext2);
11535 }
11536 else if (flag == LOG_SENSE_1)
11537 {
11538 /* SAT_READ_LOG_EXT */
11539 status = satLogSense_2( tiRoot,
11540 &(satIntIo->satIntTiIORequest),
11541 tiDeviceHandle,
11542 &(satIntIo->satIntTiScsiXchg),
11543 satIOContext2);
11544 }
11545 else
11546 {
11547 /* SAT_SMART_READ_LOG */
11548 /* SAT_READ_LOG_EXT */
11549 status = satLogSense_3( tiRoot,
11550 &(satIntIo->satIntTiIORequest),
11551 tiDeviceHandle,
11552 &(satIntIo->satIntTiScsiXchg),
11553 satIOContext2);
11554
11555 }
11556 if (status != tiSuccess)
11557 {
11558 satFreeIntIoResource( tiRoot,
11559 pSatDevData,
11560 satIntIo);
11561
11562 ostiInitiatorIOCompleted( tiRoot,
11563 tiIORequest,
11564 tiIOFailed,
11565 tiDetailOtherError,
11566 agNULL,
11567 satIOContext->interruptContext );
11568 return tiSuccess;
11569 }
11570
11571
11572 return tiSuccess;
11573 }
11574
11575
11576 /*****************************************************************************/
11577 /*! \brief SAT implementation for SCSI satLogSense.
11578 *
11579 * SAT implementation for SCSI satLogSense.
11580 *
11581 * \param tiRoot: Pointer to TISA initiator driver/port instance.
11582 * \param tiIORequest: Pointer to TISA I/O request context for this I/O.
11583 * \param tiDeviceHandle: Pointer to TISA device handle for this I/O.
11584 * \param tiScsiRequest: Pointer to TISA SCSI I/O request and SGL list.
11585 * \param satIOContext_t: Pointer to the SAT IO Context
11586 *
11587 * \return If command is started successfully
11588 * - \e tiSuccess: I/O request successfully initiated.
11589 * - \e tiBusy: No resources available, try again later.
11590 * - \e tiIONoDevice: Invalid device handle.
11591 * - \e tiError: Other errors.
11592 */
11593 /*****************************************************************************/
satLogSense(tiRoot_t * tiRoot,tiIORequest_t * tiIORequest,tiDeviceHandle_t * tiDeviceHandle,tiScsiInitiatorRequest_t * tiScsiRequest,satIOContext_t * satIOContext)11594 GLOBAL bit32 satLogSense(
11595 tiRoot_t *tiRoot,
11596 tiIORequest_t *tiIORequest,
11597 tiDeviceHandle_t *tiDeviceHandle,
11598 tiScsiInitiatorRequest_t *tiScsiRequest,
11599 satIOContext_t *satIOContext)
11600 {
11601 bit32 status;
11602 bit32 agRequestType;
11603 satDeviceData_t *pSatDevData;
11604 scsiRspSense_t *pSense;
11605 tiIniScsiCmnd_t *scsiCmnd;
11606 agsaFisRegHostToDevice_t *fis;
11607 bit8 *pLogPage; /* Log Page data buffer */
11608 bit32 flag = 0;
11609 bit16 AllocLen = 0; /* allocation length */
11610 bit8 AllLogPages[8];
11611 bit16 lenRead = 0;
11612
11613 pSense = satIOContext->pSense;
11614 pSatDevData = satIOContext->pSatDevData;
11615 scsiCmnd = &tiScsiRequest->scsiCmnd;
11616 fis = satIOContext->pFis;
11617 pLogPage = (bit8 *) tiScsiRequest->sglVirtualAddr;
11618
11619 TI_DBG5(("satLogSense: start\n"));
11620
11621 osti_memset(&AllLogPages, 0, 8);
11622 /* checking CONTROL */
11623 /* NACA == 1 or LINK == 1*/
11624 if ( (scsiCmnd->cdb[9] & SCSI_NACA_MASK) || (scsiCmnd->cdb[9] & SCSI_LINK_MASK) )
11625 {
11626 satSetSensePayload( pSense,
11627 SCSI_SNSKEY_ILLEGAL_REQUEST,
11628 0,
11629 SCSI_SNSCODE_INVALID_FIELD_IN_CDB,
11630 satIOContext);
11631
11632 ostiInitiatorIOCompleted( tiRoot,
11633 tiIORequest,
11634 tiIOSuccess,
11635 SCSI_STAT_CHECK_CONDITION,
11636 satIOContext->pTiSenseData,
11637 satIOContext->interruptContext );
11638
11639 TI_DBG2(("satLogSense: return control\n"));
11640 return tiSuccess;
11641 }
11642
11643
11644 AllocLen = (bit8)((scsiCmnd->cdb[7] << 8) + scsiCmnd->cdb[8]);
11645
11646 /* checking PC (Page Control) */
11647 /* nothing */
11648
11649 /* special cases */
11650 if (AllocLen == 4)
11651 {
11652 TI_DBG1(("satLogSense: AllocLen is 4\n"));
11653 switch (scsiCmnd->cdb[2] & SCSI_LOG_SENSE_PAGE_CODE_MASK)
11654 {
11655 case LOGSENSE_SUPPORTED_LOG_PAGES:
11656 TI_DBG5(("satLogSense: case LOGSENSE_SUPPORTED_LOG_PAGES\n"));
11657
11658 /* SAT Rev 8, 10.2.5 p76 */
11659 if (pSatDevData->satSMARTFeatureSet == agTRUE)
11660 {
11661 /* add informational exception log */
11662 flag = 1;
11663 if (pSatDevData->satSMARTSelfTest == agTRUE)
11664 {
11665 /* add Self-Test results log page */
11666 flag = 2;
11667 }
11668 }
11669 else
11670 {
11671 /* only supported, no informational exception log, no Self-Test results log page */
11672 flag = 0;
11673 }
11674 lenRead = 4;
11675 AllLogPages[0] = LOGSENSE_SUPPORTED_LOG_PAGES; /* page code */
11676 AllLogPages[1] = 0; /* reserved */
11677 switch (flag)
11678 {
11679 case 0:
11680 /* only supported */
11681 AllLogPages[2] = 0; /* page length */
11682 AllLogPages[3] = 1; /* page length */
11683 break;
11684 case 1:
11685 /* supported and informational exception log */
11686 AllLogPages[2] = 0; /* page length */
11687 AllLogPages[3] = 2; /* page length */
11688 break;
11689 case 2:
11690 /* supported and informational exception log */
11691 AllLogPages[2] = 0; /* page length */
11692 AllLogPages[3] = 3; /* page length */
11693 break;
11694 default:
11695 TI_DBG1(("satLogSense: error unallowed flag value %d\n", flag));
11696 break;
11697 }
11698 osti_memcpy(pLogPage, &AllLogPages, lenRead);
11699 break;
11700 case LOGSENSE_SELFTEST_RESULTS_PAGE:
11701 TI_DBG5(("satLogSense: case LOGSENSE_SUPPORTED_LOG_PAGES\n"));
11702 lenRead = 4;
11703 AllLogPages[0] = LOGSENSE_SELFTEST_RESULTS_PAGE; /* page code */
11704 AllLogPages[1] = 0; /* reserved */
11705 /* page length = SELFTEST_RESULTS_LOG_PAGE_LENGTH - 1 - 3 = 400 = 0x190 */
11706 AllLogPages[2] = 0x01;
11707 AllLogPages[3] = 0x90; /* page length */
11708 osti_memcpy(pLogPage, &AllLogPages, lenRead);
11709
11710 break;
11711 case LOGSENSE_INFORMATION_EXCEPTIONS_PAGE:
11712 TI_DBG5(("satLogSense: case LOGSENSE_SUPPORTED_LOG_PAGES\n"));
11713 lenRead = 4;
11714 AllLogPages[0] = LOGSENSE_INFORMATION_EXCEPTIONS_PAGE; /* page code */
11715 AllLogPages[1] = 0; /* reserved */
11716 AllLogPages[2] = 0; /* page length */
11717 AllLogPages[3] = INFORMATION_EXCEPTIONS_LOG_PAGE_LENGTH - 1 - 3; /* page length */
11718 osti_memcpy(pLogPage, &AllLogPages, lenRead);
11719 break;
11720 default:
11721 TI_DBG1(("satLogSense: default Page Code 0x%x\n", scsiCmnd->cdb[2] & SCSI_LOG_SENSE_PAGE_CODE_MASK));
11722 satSetSensePayload( pSense,
11723 SCSI_SNSKEY_ILLEGAL_REQUEST,
11724 0,
11725 SCSI_SNSCODE_INVALID_FIELD_IN_CDB,
11726 satIOContext);
11727
11728 ostiInitiatorIOCompleted( tiRoot,
11729 tiIORequest,
11730 tiIOSuccess,
11731 SCSI_STAT_CHECK_CONDITION,
11732 satIOContext->pTiSenseData,
11733 satIOContext->interruptContext );
11734 return tiSuccess;
11735 }
11736 ostiInitiatorIOCompleted( tiRoot,
11737 tiIORequest,
11738 tiIOSuccess,
11739 SCSI_STAT_GOOD,
11740 agNULL,
11741 satIOContext->interruptContext);
11742 return tiSuccess;
11743
11744 } /* if */
11745
11746 /* SAT rev8 Table 11 p30*/
11747 /* checking Page Code */
11748 switch (scsiCmnd->cdb[2] & SCSI_LOG_SENSE_PAGE_CODE_MASK)
11749 {
11750 case LOGSENSE_SUPPORTED_LOG_PAGES:
11751 TI_DBG5(("satLogSense: case 1\n"));
11752
11753 /* SAT Rev 8, 10.2.5 p76 */
11754
11755 if (pSatDevData->satSMARTFeatureSet == agTRUE)
11756 {
11757 /* add informational exception log */
11758 flag = 1;
11759 if (pSatDevData->satSMARTSelfTest == agTRUE)
11760 {
11761 /* add Self-Test results log page */
11762 flag = 2;
11763 }
11764 }
11765 else
11766 {
11767 /* only supported, no informational exception log, no Self-Test results log page */
11768 flag = 0;
11769 }
11770 AllLogPages[0] = 0; /* page code */
11771 AllLogPages[1] = 0; /* reserved */
11772 switch (flag)
11773 {
11774 case 0:
11775 /* only supported */
11776 AllLogPages[2] = 0; /* page length */
11777 AllLogPages[3] = 1; /* page length */
11778 AllLogPages[4] = 0x00; /* supported page list */
11779 lenRead = (bit8)(MIN(AllocLen, 5));
11780 break;
11781 case 1:
11782 /* supported and informational exception log */
11783 AllLogPages[2] = 0; /* page length */
11784 AllLogPages[3] = 2; /* page length */
11785 AllLogPages[4] = 0x00; /* supported page list */
11786 AllLogPages[5] = 0x10; /* supported page list */
11787 lenRead = (bit8)(MIN(AllocLen, 6));
11788 break;
11789 case 2:
11790 /* supported and informational exception log */
11791 AllLogPages[2] = 0; /* page length */
11792 AllLogPages[3] = 3; /* page length */
11793 AllLogPages[4] = 0x00; /* supported page list */
11794 AllLogPages[5] = 0x10; /* supported page list */
11795 AllLogPages[6] = 0x2F; /* supported page list */
11796 lenRead = (bit8)(MIN(AllocLen, 7));
11797 break;
11798 default:
11799 TI_DBG1(("satLogSense: error unallowed flag value %d\n", flag));
11800 break;
11801 }
11802
11803 osti_memcpy(pLogPage, &AllLogPages, lenRead);
11804 /* comparing allocation length to Log Page byte size */
11805 /* SPC-4, 4.3.4.6, p28 */
11806 if (AllocLen > lenRead )
11807 {
11808 TI_DBG1(("satLogSense reporting underrun lenRead=0x%x AllocLen=0x%x tiIORequest=%p\n", lenRead, AllocLen, tiIORequest));
11809 ostiInitiatorIOCompleted( tiRoot,
11810 tiIORequest,
11811 tiIOUnderRun,
11812 AllocLen - lenRead,
11813 agNULL,
11814 satIOContext->interruptContext );
11815 }
11816 else
11817 {
11818 ostiInitiatorIOCompleted( tiRoot,
11819 tiIORequest,
11820 tiIOSuccess,
11821 SCSI_STAT_GOOD,
11822 agNULL,
11823 satIOContext->interruptContext);
11824 }
11825 break;
11826 case LOGSENSE_SELFTEST_RESULTS_PAGE:
11827 TI_DBG5(("satLogSense: case 2\n"));
11828 /* checking SMART self-test */
11829 if (pSatDevData->satSMARTSelfTest == agFALSE)
11830 {
11831 TI_DBG5(("satLogSense: case 2 no SMART Self Test\n"));
11832 satSetSensePayload( pSense,
11833 SCSI_SNSKEY_ILLEGAL_REQUEST,
11834 0,
11835 SCSI_SNSCODE_INVALID_FIELD_IN_CDB,
11836 satIOContext);
11837
11838 ostiInitiatorIOCompleted( tiRoot,
11839 tiIORequest,
11840 tiIOSuccess,
11841 SCSI_STAT_CHECK_CONDITION,
11842 satIOContext->pTiSenseData,
11843 satIOContext->interruptContext );
11844 }
11845 else
11846 {
11847 /* if satSMARTEnabled is false, send SMART_ENABLE_OPERATIONS */
11848 if (pSatDevData->satSMARTEnabled == agFALSE)
11849 {
11850 TI_DBG5(("satLogSense: case 2 calling satSMARTEnable\n"));
11851 status = satLogSenseAllocate(tiRoot,
11852 tiIORequest,
11853 tiDeviceHandle,
11854 tiScsiRequest,
11855 satIOContext,
11856 0,
11857 LOG_SENSE_0
11858 );
11859
11860 return status;
11861
11862 }
11863 else
11864 {
11865 /* SAT Rev 8, 10.2.4 p74 */
11866 if ( pSatDevData->sat48BitSupport == agTRUE )
11867 {
11868 TI_DBG5(("satLogSense: case 2-1 sends READ LOG EXT\n"));
11869 status = satLogSenseAllocate(tiRoot,
11870 tiIORequest,
11871 tiDeviceHandle,
11872 tiScsiRequest,
11873 satIOContext,
11874 512,
11875 LOG_SENSE_1
11876 );
11877
11878 return status;
11879 }
11880 else
11881 {
11882 TI_DBG5(("satLogSense: case 2-2 sends SMART READ LOG\n"));
11883 status = satLogSenseAllocate(tiRoot,
11884 tiIORequest,
11885 tiDeviceHandle,
11886 tiScsiRequest,
11887 satIOContext,
11888 512,
11889 LOG_SENSE_2
11890 );
11891
11892 return status;
11893 }
11894 }
11895 }
11896 break;
11897 case LOGSENSE_INFORMATION_EXCEPTIONS_PAGE:
11898 TI_DBG5(("satLogSense: case 3\n"));
11899 /* checking SMART feature set */
11900 if (pSatDevData->satSMARTFeatureSet == agFALSE)
11901 {
11902 satSetSensePayload( pSense,
11903 SCSI_SNSKEY_ILLEGAL_REQUEST,
11904 0,
11905 SCSI_SNSCODE_INVALID_FIELD_IN_CDB,
11906 satIOContext);
11907
11908 ostiInitiatorIOCompleted( tiRoot,
11909 tiIORequest,
11910 tiIOSuccess,
11911 SCSI_STAT_CHECK_CONDITION,
11912 satIOContext->pTiSenseData,
11913 satIOContext->interruptContext );
11914 }
11915 else
11916 {
11917 /* checking SMART feature enabled */
11918 if (pSatDevData->satSMARTEnabled == agFALSE)
11919 {
11920 satSetSensePayload( pSense,
11921 SCSI_SNSKEY_ABORTED_COMMAND,
11922 0,
11923 SCSI_SNSCODE_ATA_DEVICE_FEATURE_NOT_ENABLED,
11924 satIOContext);
11925
11926 ostiInitiatorIOCompleted( tiRoot,
11927 tiIORequest,
11928 tiIOSuccess,
11929 SCSI_STAT_CHECK_CONDITION,
11930 satIOContext->pTiSenseData,
11931 satIOContext->interruptContext );
11932 }
11933 else
11934 {
11935 /* SAT Rev 8, 10.2.3 p72 */
11936 TI_DBG5(("satLogSense: case 3 sends SMART RETURN STATUS\n"));
11937
11938 /* sends SMART RETURN STATUS */
11939 fis->h.fisType = 0x27; /* Reg host to device */
11940 fis->h.c_pmPort = 0x80; /* C Bit is set */
11941
11942 fis->h.command = SAT_SMART_RETURN_STATUS;/* 0xB0 */
11943 fis->h.features = 0xDA; /* FIS features */
11944 fis->d.featuresExp = 0; /* FIS reserve */
11945 fis->d.sectorCount = 0; /* FIS sector count (7:0) */
11946 fis->d.sectorCountExp = 0; /* FIS sector count (15:8) */
11947 fis->d.lbaLow = 0; /* FIS LBA (7 :0 ) */
11948 fis->d.lbaLowExp = 0; /* FIS LBA (31:24) */
11949 fis->d.lbaMid = 0x4F; /* FIS LBA (15:8 ) */
11950 fis->d.lbaMidExp = 0; /* FIS LBA (39:32) */
11951 fis->d.lbaHigh = 0xC2; /* FIS LBA (23:16) */
11952 fis->d.lbaHighExp = 0; /* FIS LBA (47:40) */
11953 fis->d.device = 0; /* FIS DEV is discared in SATA */
11954 fis->d.control = 0; /* FIS HOB bit clear */
11955 fis->d.reserved4 = 0;
11956 fis->d.reserved5 = 0;
11957
11958 agRequestType = AGSA_SATA_PROTOCOL_NON_DATA;
11959 /* Initialize CB for SATA completion.
11960 */
11961 satIOContext->satCompleteCB = &satLogSenseCB;
11962
11963 /*
11964 * Prepare SGL and send FIS to LL layer.
11965 */
11966 satIOContext->reqType = agRequestType; /* Save it */
11967
11968 status = sataLLIOStart( tiRoot,
11969 tiIORequest,
11970 tiDeviceHandle,
11971 tiScsiRequest,
11972 satIOContext);
11973
11974
11975 return status;
11976 }
11977 }
11978 break;
11979 default:
11980 TI_DBG1(("satLogSense: default Page Code 0x%x\n", scsiCmnd->cdb[2] & SCSI_LOG_SENSE_PAGE_CODE_MASK));
11981 satSetSensePayload( pSense,
11982 SCSI_SNSKEY_ILLEGAL_REQUEST,
11983 0,
11984 SCSI_SNSCODE_INVALID_FIELD_IN_CDB,
11985 satIOContext);
11986
11987 ostiInitiatorIOCompleted( tiRoot,
11988 tiIORequest,
11989 tiIOSuccess,
11990 SCSI_STAT_CHECK_CONDITION,
11991 satIOContext->pTiSenseData,
11992 satIOContext->interruptContext );
11993
11994 break;
11995 } /* end switch */
11996
11997 return tiSuccess;
11998
11999
12000 }
12001
12002 /*****************************************************************************/
12003 /*! \brief SAT implementation for SCSI satModeSelect6.
12004 *
12005 * SAT implementation for SCSI satModeSelect6.
12006 *
12007 * \param tiRoot: Pointer to TISA initiator driver/port instance.
12008 * \param tiIORequest: Pointer to TISA I/O request context for this I/O.
12009 * \param tiDeviceHandle: Pointer to TISA device handle for this I/O.
12010 * \param tiScsiRequest: Pointer to TISA SCSI I/O request and SGL list.
12011 * \param satIOContext_t: Pointer to the SAT IO Context
12012 *
12013 * \return If command is started successfully
12014 * - \e tiSuccess: I/O request successfully initiated.
12015 * - \e tiBusy: No resources available, try again later.
12016 * - \e tiIONoDevice: Invalid device handle.
12017 * - \e tiError: Other errors.
12018 */
12019 /*****************************************************************************/
satModeSelect6(tiRoot_t * tiRoot,tiIORequest_t * tiIORequest,tiDeviceHandle_t * tiDeviceHandle,tiScsiInitiatorRequest_t * tiScsiRequest,satIOContext_t * satIOContext)12020 GLOBAL bit32 satModeSelect6(
12021 tiRoot_t *tiRoot,
12022 tiIORequest_t *tiIORequest,
12023 tiDeviceHandle_t *tiDeviceHandle,
12024 tiScsiInitiatorRequest_t *tiScsiRequest,
12025 satIOContext_t *satIOContext)
12026 {
12027 bit32 status;
12028 bit32 agRequestType;
12029 satDeviceData_t *pSatDevData;
12030 scsiRspSense_t *pSense;
12031 tiIniScsiCmnd_t *scsiCmnd;
12032 agsaFisRegHostToDevice_t *fis;
12033 bit8 *pLogPage; /* Log Page data buffer */
12034 bit32 StartingIndex = 0;
12035 bit8 PageCode = 0;
12036 bit32 chkCnd = agFALSE;
12037
12038 pSense = satIOContext->pSense;
12039 pSatDevData = satIOContext->pSatDevData;
12040 scsiCmnd = &tiScsiRequest->scsiCmnd;
12041 fis = satIOContext->pFis;
12042 pLogPage = (bit8 *) tiScsiRequest->sglVirtualAddr;
12043
12044 TI_DBG5(("satModeSelect6: start\n"));
12045
12046 /* checking CONTROL */
12047 /* NACA == 1 or LINK == 1*/
12048 if ( (scsiCmnd->cdb[5] & SCSI_NACA_MASK) || (scsiCmnd->cdb[5] & SCSI_LINK_MASK) )
12049 {
12050 satSetSensePayload( pSense,
12051 SCSI_SNSKEY_ILLEGAL_REQUEST,
12052 0,
12053 SCSI_SNSCODE_INVALID_FIELD_IN_CDB,
12054 satIOContext);
12055
12056 ostiInitiatorIOCompleted( tiRoot,
12057 tiIORequest,
12058 tiIOSuccess,
12059 SCSI_STAT_CHECK_CONDITION,
12060 satIOContext->pTiSenseData,
12061 satIOContext->interruptContext );
12062
12063 TI_DBG2(("satModeSelect6: return control\n"));
12064 return tiSuccess;
12065 }
12066
12067 /* checking PF bit */
12068 if ( !(scsiCmnd->cdb[1] & SCSI_MODE_SELECT6_PF_MASK))
12069 {
12070 satSetSensePayload( pSense,
12071 SCSI_SNSKEY_ILLEGAL_REQUEST,
12072 0,
12073 SCSI_SNSCODE_INVALID_FIELD_IN_CDB,
12074 satIOContext);
12075
12076 ostiInitiatorIOCompleted( tiRoot,
12077 tiIORequest,
12078 tiIOSuccess,
12079 SCSI_STAT_CHECK_CONDITION,
12080 satIOContext->pTiSenseData,
12081 satIOContext->interruptContext );
12082
12083 TI_DBG1(("satModeSelect6: PF bit check \n"));
12084 return tiSuccess;
12085
12086 }
12087
12088 /* checking Block Descriptor Length on Mode parameter header(6)*/
12089 if (pLogPage[3] == 8)
12090 {
12091 /* mode parameter block descriptor exists */
12092 PageCode = (bit8)(pLogPage[12] & 0x3F); /* page code and index is 4 + 8 */
12093 StartingIndex = 12;
12094 }
12095 else if (pLogPage[3] == 0)
12096 {
12097 /* mode parameter block descriptor does not exist */
12098 PageCode = (bit8)(pLogPage[4] & 0x3F); /* page code and index is 4 + 0 */
12099 StartingIndex = 4;
12100 ostiInitiatorIOCompleted( tiRoot,
12101 tiIORequest,
12102 tiIOSuccess,
12103 SCSI_STAT_GOOD,
12104 agNULL,
12105 satIOContext->interruptContext);
12106 return tiSuccess;
12107 }
12108 else
12109 {
12110 TI_DBG1(("satModeSelect6: return mode parameter block descriptor 0x%x\n", pLogPage[3]));
12111 /* no more than one mode parameter block descriptor shall be supported */
12112 satSetSensePayload( pSense,
12113 SCSI_SNSKEY_NO_SENSE,
12114 0,
12115 SCSI_SNSCODE_NO_ADDITIONAL_INFO,
12116 satIOContext);
12117
12118 ostiInitiatorIOCompleted( tiRoot,
12119 tiIORequest,
12120 tiIOSuccess,
12121 SCSI_STAT_CHECK_CONDITION,
12122 satIOContext->pTiSenseData,
12123 satIOContext->interruptContext );
12124 return tiSuccess;
12125 }
12126
12127
12128
12129 switch (PageCode) /* page code */
12130 {
12131 case MODESELECT_CONTROL_PAGE:
12132 TI_DBG1(("satModeSelect6: Control mode page\n"));
12133 /*
12134 compare pLogPage to expected value (SAT Table 65, p67)
12135 If not match, return check condition
12136 */
12137 if ( pLogPage[StartingIndex+1] != 0x0A ||
12138 pLogPage[StartingIndex+2] != 0x02 ||
12139 (pSatDevData->satNCQ == agTRUE && pLogPage[StartingIndex+3] != 0x12) ||
12140 (pSatDevData->satNCQ == agFALSE && pLogPage[StartingIndex+3] != 0x02) ||
12141 (pLogPage[StartingIndex+4] & BIT3_MASK) != 0x00 || /* SWP bit */
12142 (pLogPage[StartingIndex+4] & BIT4_MASK) != 0x00 || /* UA_INTLCK_CTRL */
12143 (pLogPage[StartingIndex+4] & BIT5_MASK) != 0x00 || /* UA_INTLCK_CTRL */
12144
12145 (pLogPage[StartingIndex+5] & BIT0_MASK) != 0x00 || /* AUTOLOAD MODE */
12146 (pLogPage[StartingIndex+5] & BIT1_MASK) != 0x00 || /* AUTOLOAD MODE */
12147 (pLogPage[StartingIndex+5] & BIT2_MASK) != 0x00 || /* AUTOLOAD MODE */
12148 (pLogPage[StartingIndex+5] & BIT6_MASK) != 0x00 || /* TAS bit */
12149
12150 pLogPage[StartingIndex+8] != 0xFF ||
12151 pLogPage[StartingIndex+9] != 0xFF ||
12152 pLogPage[StartingIndex+10] != 0x00 ||
12153 pLogPage[StartingIndex+11] != 0x00
12154 )
12155 {
12156 chkCnd = agTRUE;
12157 }
12158 if (chkCnd == agTRUE)
12159 {
12160 satSetSensePayload( pSense,
12161 SCSI_SNSKEY_ILLEGAL_REQUEST,
12162 0,
12163 SCSI_SNSCODE_INVALID_FIELD_IN_CDB,
12164 satIOContext);
12165
12166 ostiInitiatorIOCompleted( tiRoot,
12167 tiIORequest,
12168 tiIOSuccess,
12169 SCSI_STAT_CHECK_CONDITION,
12170 satIOContext->pTiSenseData,
12171 satIOContext->interruptContext );
12172
12173 TI_DBG1(("satModeSelect10: unexpected values\n"));
12174 }
12175 else
12176 {
12177 ostiInitiatorIOCompleted( tiRoot,
12178 tiIORequest,
12179 tiIOSuccess,
12180 SCSI_STAT_GOOD,
12181 agNULL,
12182 satIOContext->interruptContext);
12183 }
12184 return tiSuccess;
12185 break;
12186 case MODESELECT_READ_WRITE_ERROR_RECOVERY_PAGE:
12187 TI_DBG1(("satModeSelect6: Read-Write Error Recovery mode page\n"));
12188
12189 if ( (pLogPage[StartingIndex + 2] & SCSI_MODE_SELECT6_AWRE_MASK) ||
12190 (pLogPage[StartingIndex + 2] & SCSI_MODE_SELECT6_RC_MASK) ||
12191 (pLogPage[StartingIndex + 2] & SCSI_MODE_SELECT6_EER_MASK) ||
12192 (pLogPage[StartingIndex + 2] & SCSI_MODE_SELECT6_PER_MASK) ||
12193 (pLogPage[StartingIndex + 2] & SCSI_MODE_SELECT6_DTE_MASK) ||
12194 (pLogPage[StartingIndex + 2] & SCSI_MODE_SELECT6_DCR_MASK) ||
12195 (pLogPage[StartingIndex + 10]) ||
12196 (pLogPage[StartingIndex + 11])
12197 )
12198 {
12199 TI_DBG5(("satModeSelect6: return check condition \n"));
12200
12201 satSetSensePayload( pSense,
12202 SCSI_SNSKEY_ILLEGAL_REQUEST,
12203 0,
12204 SCSI_SNSCODE_INVALID_FIELD_PARAMETER_LIST,
12205 satIOContext);
12206
12207 ostiInitiatorIOCompleted( tiRoot,
12208 tiIORequest,
12209 tiIOSuccess,
12210 SCSI_STAT_CHECK_CONDITION,
12211 satIOContext->pTiSenseData,
12212 satIOContext->interruptContext );
12213 return tiSuccess;
12214 }
12215 else
12216 {
12217 TI_DBG5(("satModeSelect6: return GOOD \n"));
12218 ostiInitiatorIOCompleted( tiRoot,
12219 tiIORequest,
12220 tiIOSuccess,
12221 SCSI_STAT_GOOD,
12222 agNULL,
12223 satIOContext->interruptContext);
12224 return tiSuccess;
12225 }
12226
12227 break;
12228 case MODESELECT_CACHING:
12229 /* SAT rev8 Table67, p69*/
12230 TI_DBG5(("satModeSelect6: Caching mode page\n"));
12231 if ( (pLogPage[StartingIndex + 2] & 0xFB) || /* 1111 1011 */
12232 (pLogPage[StartingIndex + 3]) ||
12233 (pLogPage[StartingIndex + 4]) ||
12234 (pLogPage[StartingIndex + 5]) ||
12235 (pLogPage[StartingIndex + 6]) ||
12236 (pLogPage[StartingIndex + 7]) ||
12237 (pLogPage[StartingIndex + 8]) ||
12238 (pLogPage[StartingIndex + 9]) ||
12239 (pLogPage[StartingIndex + 10]) ||
12240 (pLogPage[StartingIndex + 11]) ||
12241
12242 (pLogPage[StartingIndex + 12] & 0xC1) || /* 1100 0001 */
12243 (pLogPage[StartingIndex + 13]) ||
12244 (pLogPage[StartingIndex + 14]) ||
12245 (pLogPage[StartingIndex + 15])
12246 )
12247 {
12248 TI_DBG1(("satModeSelect6: return check condition \n"));
12249
12250 satSetSensePayload( pSense,
12251 SCSI_SNSKEY_ILLEGAL_REQUEST,
12252 0,
12253 SCSI_SNSCODE_INVALID_FIELD_PARAMETER_LIST,
12254 satIOContext);
12255
12256 ostiInitiatorIOCompleted( tiRoot,
12257 tiIORequest,
12258 tiIOSuccess,
12259 SCSI_STAT_CHECK_CONDITION,
12260 satIOContext->pTiSenseData,
12261 satIOContext->interruptContext );
12262 return tiSuccess;
12263
12264 }
12265 else
12266 {
12267 /* sends ATA SET FEATURES based on WCE bit */
12268 if ( !(pLogPage[StartingIndex + 2] & SCSI_MODE_SELECT6_WCE_MASK) )
12269 {
12270 TI_DBG5(("satModeSelect6: disable write cache\n"));
12271 /* sends SET FEATURES */
12272 fis->h.fisType = 0x27; /* Reg host to device */
12273 fis->h.c_pmPort = 0x80; /* C Bit is set */
12274
12275 fis->h.command = SAT_SET_FEATURES; /* 0xEF */
12276 fis->h.features = 0x82; /* disable write cache */
12277 fis->d.lbaLow = 0; /* */
12278 fis->d.lbaMid = 0; /* */
12279 fis->d.lbaHigh = 0; /* */
12280 fis->d.device = 0; /* */
12281 fis->d.lbaLowExp = 0; /* */
12282 fis->d.lbaMidExp = 0; /* */
12283 fis->d.lbaHighExp = 0; /* */
12284 fis->d.featuresExp = 0; /* */
12285 fis->d.sectorCount = 0; /* */
12286 fis->d.sectorCountExp = 0; /* */
12287 fis->d.reserved4 = 0;
12288 fis->d.control = 0; /* FIS HOB bit clear */
12289 fis->d.reserved5 = 0;
12290
12291 agRequestType = AGSA_SATA_PROTOCOL_NON_DATA;
12292
12293 /* Initialize CB for SATA completion.
12294 */
12295 satIOContext->satCompleteCB = &satModeSelect6n10CB;
12296
12297 /*
12298 * Prepare SGL and send FIS to LL layer.
12299 */
12300 satIOContext->reqType = agRequestType; /* Save it */
12301
12302 status = sataLLIOStart( tiRoot,
12303 tiIORequest,
12304 tiDeviceHandle,
12305 tiScsiRequest,
12306 satIOContext);
12307 return status;
12308 }
12309 else
12310 {
12311 TI_DBG5(("satModeSelect6: enable write cache\n"));
12312 /* sends SET FEATURES */
12313 fis->h.fisType = 0x27; /* Reg host to device */
12314 fis->h.c_pmPort = 0x80; /* C Bit is set */
12315
12316 fis->h.command = SAT_SET_FEATURES; /* 0xEF */
12317 fis->h.features = 0x02; /* enable write cache */
12318 fis->d.lbaLow = 0; /* */
12319 fis->d.lbaMid = 0; /* */
12320 fis->d.lbaHigh = 0; /* */
12321 fis->d.device = 0; /* */
12322 fis->d.lbaLowExp = 0; /* */
12323 fis->d.lbaMidExp = 0; /* */
12324 fis->d.lbaHighExp = 0; /* */
12325 fis->d.featuresExp = 0; /* */
12326 fis->d.sectorCount = 0; /* */
12327 fis->d.sectorCountExp = 0; /* */
12328 fis->d.reserved4 = 0;
12329 fis->d.control = 0; /* FIS HOB bit clear */
12330 fis->d.reserved5 = 0;
12331
12332 agRequestType = AGSA_SATA_PROTOCOL_NON_DATA;
12333
12334 /* Initialize CB for SATA completion.
12335 */
12336 satIOContext->satCompleteCB = &satModeSelect6n10CB;
12337
12338 /*
12339 * Prepare SGL and send FIS to LL layer.
12340 */
12341 satIOContext->reqType = agRequestType; /* Save it */
12342
12343 status = sataLLIOStart( tiRoot,
12344 tiIORequest,
12345 tiDeviceHandle,
12346 tiScsiRequest,
12347 satIOContext);
12348 return status;
12349
12350 }
12351 }
12352 break;
12353 case MODESELECT_INFORMATION_EXCEPTION_CONTROL_PAGE:
12354 TI_DBG5(("satModeSelect6: Informational Exception Control mode page\n"));
12355 if ( (pLogPage[StartingIndex + 2] & SCSI_MODE_SELECT6_PERF_MASK) ||
12356 (pLogPage[StartingIndex + 2] & SCSI_MODE_SELECT6_TEST_MASK)
12357 )
12358 {
12359 TI_DBG1(("satModeSelect6: return check condition \n"));
12360
12361 satSetSensePayload( pSense,
12362 SCSI_SNSKEY_ILLEGAL_REQUEST,
12363 0,
12364 SCSI_SNSCODE_INVALID_FIELD_PARAMETER_LIST,
12365 satIOContext);
12366
12367 ostiInitiatorIOCompleted( tiRoot,
12368 tiIORequest,
12369 tiIOSuccess,
12370 SCSI_STAT_CHECK_CONDITION,
12371 satIOContext->pTiSenseData,
12372 satIOContext->interruptContext );
12373 return tiSuccess;
12374 }
12375 else
12376 {
12377 /* sends either ATA SMART ENABLE/DISABLE OPERATIONS based on DEXCPT bit */
12378 if ( !(pLogPage[StartingIndex + 2] & 0x08) )
12379 {
12380 TI_DBG5(("satModeSelect6: enable information exceptions reporting\n"));
12381 /* sends SMART ENABLE OPERATIONS */
12382 fis->h.fisType = 0x27; /* Reg host to device */
12383 fis->h.c_pmPort = 0x80; /* C Bit is set */
12384
12385 fis->h.command = SAT_SMART_ENABLE_OPERATIONS; /* 0xB0 */
12386 fis->h.features = 0xD8; /* enable */
12387 fis->d.lbaLow = 0; /* */
12388 fis->d.lbaMid = 0x4F; /* 0x4F */
12389 fis->d.lbaHigh = 0xC2; /* 0xC2 */
12390 fis->d.device = 0; /* */
12391 fis->d.lbaLowExp = 0; /* */
12392 fis->d.lbaMidExp = 0; /* */
12393 fis->d.lbaHighExp = 0; /* */
12394 fis->d.featuresExp = 0; /* */
12395 fis->d.sectorCount = 0; /* */
12396 fis->d.sectorCountExp = 0; /* */
12397 fis->d.reserved4 = 0;
12398 fis->d.control = 0; /* FIS HOB bit clear */
12399 fis->d.reserved5 = 0;
12400
12401 agRequestType = AGSA_SATA_PROTOCOL_NON_DATA;
12402
12403 /* Initialize CB for SATA completion.
12404 */
12405 satIOContext->satCompleteCB = &satModeSelect6n10CB;
12406
12407 /*
12408 * Prepare SGL and send FIS to LL layer.
12409 */
12410 satIOContext->reqType = agRequestType; /* Save it */
12411
12412 status = sataLLIOStart( tiRoot,
12413 tiIORequest,
12414 tiDeviceHandle,
12415 tiScsiRequest,
12416 satIOContext);
12417 return status;
12418 }
12419 else
12420 {
12421 TI_DBG5(("satModeSelect6: disable information exceptions reporting\n"));
12422 /* sends SMART DISABLE OPERATIONS */
12423 fis->h.fisType = 0x27; /* Reg host to device */
12424 fis->h.c_pmPort = 0x80; /* C Bit is set */
12425
12426 fis->h.command = SAT_SMART_DISABLE_OPERATIONS; /* 0xB0 */
12427 fis->h.features = 0xD9; /* disable */
12428 fis->d.lbaLow = 0; /* */
12429 fis->d.lbaMid = 0x4F; /* 0x4F */
12430 fis->d.lbaHigh = 0xC2; /* 0xC2 */
12431 fis->d.device = 0; /* */
12432 fis->d.lbaLowExp = 0; /* */
12433 fis->d.lbaMidExp = 0; /* */
12434 fis->d.lbaHighExp = 0; /* */
12435 fis->d.featuresExp = 0; /* */
12436 fis->d.sectorCount = 0; /* */
12437 fis->d.sectorCountExp = 0; /* */
12438 fis->d.reserved4 = 0;
12439 fis->d.control = 0; /* FIS HOB bit clear */
12440 fis->d.reserved5 = 0;
12441
12442 agRequestType = AGSA_SATA_PROTOCOL_NON_DATA;
12443
12444 /* Initialize CB for SATA completion.
12445 */
12446 satIOContext->satCompleteCB = &satModeSelect6n10CB;
12447
12448 /*
12449 * Prepare SGL and send FIS to LL layer.
12450 */
12451 satIOContext->reqType = agRequestType; /* Save it */
12452
12453 status = sataLLIOStart( tiRoot,
12454 tiIORequest,
12455 tiDeviceHandle,
12456 tiScsiRequest,
12457 satIOContext);
12458 return status;
12459
12460 }
12461 }
12462 break;
12463 default:
12464 TI_DBG1(("satModeSelect6: Error unknown page code 0x%x\n", pLogPage[12]));
12465 satSetSensePayload( pSense,
12466 SCSI_SNSKEY_NO_SENSE,
12467 0,
12468 SCSI_SNSCODE_NO_ADDITIONAL_INFO,
12469 satIOContext);
12470
12471 ostiInitiatorIOCompleted( tiRoot,
12472 tiIORequest,
12473 tiIOSuccess,
12474 SCSI_STAT_CHECK_CONDITION,
12475 satIOContext->pTiSenseData,
12476 satIOContext->interruptContext );
12477 return tiSuccess;
12478 }
12479
12480 }
12481
12482 /*****************************************************************************/
12483 /*! \brief SAT implementation for SCSI satModeSelect6n10_1.
12484 *
12485 * This function is part of implementation of ModeSelect6 and ModeSelect10.
12486 * When ModeSelect6 or ModeSelect10 is coverted into multiple ATA commands,
12487 * this function is used.
12488 *
12489 * \param tiRoot: Pointer to TISA initiator driver/port instance.
12490 * \param tiIORequest: Pointer to TISA I/O request context for this I/O.
12491 * \param tiDeviceHandle: Pointer to TISA device handle for this I/O.
12492 * \param tiScsiRequest: Pointer to TISA SCSI I/O request and SGL list.
12493 * \param satIOContext_t: Pointer to the SAT IO Context
12494 *
12495 * \return If command is started successfully
12496 * - \e tiSuccess: I/O request successfully initiated.
12497 * - \e tiBusy: No resources available, try again later.
12498 * - \e tiIONoDevice: Invalid device handle.
12499 * - \e tiError: Other errors.
12500 */
12501 /*****************************************************************************/
satModeSelect6n10_1(tiRoot_t * tiRoot,tiIORequest_t * tiIORequest,tiDeviceHandle_t * tiDeviceHandle,tiScsiInitiatorRequest_t * tiScsiRequest,satIOContext_t * satIOContext)12502 GLOBAL bit32 satModeSelect6n10_1(
12503 tiRoot_t *tiRoot,
12504 tiIORequest_t *tiIORequest,
12505 tiDeviceHandle_t *tiDeviceHandle,
12506 tiScsiInitiatorRequest_t *tiScsiRequest,
12507 satIOContext_t *satIOContext)
12508 {
12509 /* sends either ATA SET FEATURES based on DRA bit */
12510 bit32 status;
12511 bit32 agRequestType;
12512 agsaFisRegHostToDevice_t *fis;
12513 bit8 *pLogPage; /* Log Page data buffer */
12514 bit32 StartingIndex = 0;
12515
12516 fis = satIOContext->pFis;
12517 pLogPage = (bit8 *) tiScsiRequest->sglVirtualAddr;
12518 TI_DBG5(("satModeSelect6_1: start\n"));
12519 /* checking Block Descriptor Length on Mode parameter header(6)*/
12520 if (pLogPage[3] == 8)
12521 {
12522 /* mode parameter block descriptor exists */
12523 StartingIndex = 12;
12524 }
12525 else
12526 {
12527 /* mode parameter block descriptor does not exist */
12528 StartingIndex = 4;
12529 }
12530
12531 /* sends ATA SET FEATURES based on DRA bit */
12532 if ( !(pLogPage[StartingIndex + 12] & SCSI_MODE_SELECT6_DRA_MASK) )
12533 {
12534 TI_DBG5(("satModeSelect6_1: enable read look-ahead feature\n"));
12535 /* sends SET FEATURES */
12536 fis->h.fisType = 0x27; /* Reg host to device */
12537 fis->h.c_pmPort = 0x80; /* C Bit is set */
12538
12539 fis->h.command = SAT_SET_FEATURES; /* 0xEF */
12540 fis->h.features = 0xAA; /* enable read look-ahead */
12541 fis->d.lbaLow = 0; /* */
12542 fis->d.lbaMid = 0; /* */
12543 fis->d.lbaHigh = 0; /* */
12544 fis->d.device = 0; /* */
12545 fis->d.lbaLowExp = 0; /* */
12546 fis->d.lbaMidExp = 0; /* */
12547 fis->d.lbaHighExp = 0; /* */
12548 fis->d.featuresExp = 0; /* */
12549 fis->d.sectorCount = 0; /* */
12550 fis->d.sectorCountExp = 0; /* */
12551 fis->d.reserved4 = 0;
12552 fis->d.control = 0; /* FIS HOB bit clear */
12553 fis->d.reserved5 = 0;
12554
12555 agRequestType = AGSA_SATA_PROTOCOL_NON_DATA;
12556
12557 /* Initialize CB for SATA completion.
12558 */
12559 satIOContext->satCompleteCB = &satModeSelect6n10CB;
12560
12561 /*
12562 * Prepare SGL and send FIS to LL layer.
12563 */
12564 satIOContext->reqType = agRequestType; /* Save it */
12565
12566 status = sataLLIOStart( tiRoot,
12567 tiIORequest,
12568 tiDeviceHandle,
12569 tiScsiRequest,
12570 satIOContext);
12571 return status;
12572 }
12573 else
12574 {
12575 TI_DBG5(("satModeSelect6_1: disable read look-ahead feature\n"));
12576 /* sends SET FEATURES */
12577 fis->h.fisType = 0x27; /* Reg host to device */
12578 fis->h.c_pmPort = 0x80; /* C Bit is set */
12579
12580 fis->h.command = SAT_SET_FEATURES; /* 0xEF */
12581 fis->h.features = 0x55; /* disable read look-ahead */
12582 fis->d.lbaLow = 0; /* */
12583 fis->d.lbaMid = 0; /* */
12584 fis->d.lbaHigh = 0; /* */
12585 fis->d.device = 0; /* */
12586 fis->d.lbaLowExp = 0; /* */
12587 fis->d.lbaMidExp = 0; /* */
12588 fis->d.lbaHighExp = 0; /* */
12589 fis->d.featuresExp = 0; /* */
12590 fis->d.sectorCount = 0; /* */
12591 fis->d.sectorCountExp = 0; /* */
12592 fis->d.reserved4 = 0;
12593 fis->d.control = 0; /* FIS HOB bit clear */
12594 fis->d.reserved5 = 0;
12595
12596 agRequestType = AGSA_SATA_PROTOCOL_NON_DATA;
12597
12598 /* Initialize CB for SATA completion.
12599 */
12600 satIOContext->satCompleteCB = &satModeSelect6n10CB;
12601
12602 /*
12603 * Prepare SGL and send FIS to LL layer.
12604 */
12605 satIOContext->reqType = agRequestType; /* Save it */
12606
12607 status = sataLLIOStart( tiRoot,
12608 tiIORequest,
12609 tiDeviceHandle,
12610 tiScsiRequest,
12611 satIOContext);
12612 return status;
12613 }
12614
12615 }
12616
12617
12618 /*****************************************************************************/
12619 /*! \brief SAT implementation for SCSI satModeSelect10.
12620 *
12621 * SAT implementation for SCSI satModeSelect10.
12622 *
12623 * \param tiRoot: Pointer to TISA initiator driver/port instance.
12624 * \param tiIORequest: Pointer to TISA I/O request context for this I/O.
12625 * \param tiDeviceHandle: Pointer to TISA device handle for this I/O.
12626 * \param tiScsiRequest: Pointer to TISA SCSI I/O request and SGL list.
12627 * \param satIOContext_t: Pointer to the SAT IO Context
12628 *
12629 * \return If command is started successfully
12630 * - \e tiSuccess: I/O request successfully initiated.
12631 * - \e tiBusy: No resources available, try again later.
12632 * - \e tiIONoDevice: Invalid device handle.
12633 * - \e tiError: Other errors.
12634 */
12635 /*****************************************************************************/
satModeSelect10(tiRoot_t * tiRoot,tiIORequest_t * tiIORequest,tiDeviceHandle_t * tiDeviceHandle,tiScsiInitiatorRequest_t * tiScsiRequest,satIOContext_t * satIOContext)12636 GLOBAL bit32 satModeSelect10(
12637 tiRoot_t *tiRoot,
12638 tiIORequest_t *tiIORequest,
12639 tiDeviceHandle_t *tiDeviceHandle,
12640 tiScsiInitiatorRequest_t *tiScsiRequest,
12641 satIOContext_t *satIOContext)
12642 {
12643 bit32 status;
12644 bit32 agRequestType;
12645 satDeviceData_t *pSatDevData;
12646 scsiRspSense_t *pSense;
12647 tiIniScsiCmnd_t *scsiCmnd;
12648 agsaFisRegHostToDevice_t *fis;
12649 bit8 *pLogPage; /* Log Page data buffer */
12650 bit16 BlkDescLen = 0; /* Block Descriptor Length */
12651 bit32 StartingIndex = 0;
12652 bit8 PageCode = 0;
12653 bit32 chkCnd = agFALSE;
12654
12655 pSense = satIOContext->pSense;
12656 pSatDevData = satIOContext->pSatDevData;
12657 scsiCmnd = &tiScsiRequest->scsiCmnd;
12658 fis = satIOContext->pFis;
12659 pLogPage = (bit8 *) tiScsiRequest->sglVirtualAddr;
12660
12661 TI_DBG5(("satModeSelect10: start\n"));
12662
12663 /* checking CONTROL */
12664 /* NACA == 1 or LINK == 1*/
12665 if ( (scsiCmnd->cdb[9] & SCSI_NACA_MASK) || (scsiCmnd->cdb[9] & SCSI_LINK_MASK) )
12666 {
12667 satSetSensePayload( pSense,
12668 SCSI_SNSKEY_ILLEGAL_REQUEST,
12669 0,
12670 SCSI_SNSCODE_INVALID_FIELD_IN_CDB,
12671 satIOContext);
12672
12673 ostiInitiatorIOCompleted( tiRoot,
12674 tiIORequest,
12675 tiIOSuccess,
12676 SCSI_STAT_CHECK_CONDITION,
12677 satIOContext->pTiSenseData,
12678 satIOContext->interruptContext );
12679
12680 TI_DBG2(("satModeSelect10: return control\n"));
12681 return tiSuccess;
12682 }
12683
12684 /* checking PF bit */
12685 if ( !(scsiCmnd->cdb[1] & SCSI_MODE_SELECT10_PF_MASK))
12686 {
12687 satSetSensePayload( pSense,
12688 SCSI_SNSKEY_ILLEGAL_REQUEST,
12689 0,
12690 SCSI_SNSCODE_INVALID_FIELD_IN_CDB,
12691 satIOContext);
12692
12693 ostiInitiatorIOCompleted( tiRoot,
12694 tiIORequest,
12695 tiIOSuccess,
12696 SCSI_STAT_CHECK_CONDITION,
12697 satIOContext->pTiSenseData,
12698 satIOContext->interruptContext );
12699
12700 TI_DBG1(("satModeSelect10: PF bit check \n"));
12701 return tiSuccess;
12702
12703 }
12704
12705 BlkDescLen = (bit8)((pLogPage[6] << 8) + pLogPage[7]);
12706
12707 /* checking Block Descriptor Length on Mode parameter header(10) and LONGLBA bit*/
12708 if ( (BlkDescLen == 8) && !(pLogPage[4] & SCSI_MODE_SELECT10_LONGLBA_MASK) )
12709 {
12710 /* mode parameter block descriptor exists and length is 8 byte */
12711 PageCode = (bit8)(pLogPage[16] & 0x3F); /* page code and index is 8 + 8 */
12712 StartingIndex = 16;
12713 }
12714 else if ( (BlkDescLen == 16) && (pLogPage[4] & SCSI_MODE_SELECT10_LONGLBA_MASK) )
12715 {
12716 /* mode parameter block descriptor exists and length is 16 byte */
12717 PageCode = (bit8)(pLogPage[24] & 0x3F); /* page code and index is 8 + 16 */
12718 StartingIndex = 24;
12719 }
12720 else if (BlkDescLen == 0)
12721 {
12722 /*
12723 mode parameter block descriptor does not exist
12724 */
12725 PageCode = (bit8)(pLogPage[8] & 0x3F); /* page code and index is 8 + 0 */
12726 StartingIndex = 8;
12727 ostiInitiatorIOCompleted( tiRoot,
12728 tiIORequest,
12729 tiIOSuccess,
12730 SCSI_STAT_GOOD,
12731 agNULL,
12732 satIOContext->interruptContext);
12733 return tiSuccess;
12734 }
12735 else
12736 {
12737 TI_DBG1(("satModeSelect10: return mode parameter block descriptor 0x%x\n", BlkDescLen));
12738 /* no more than one mode parameter block descriptor shall be supported */
12739 satSetSensePayload( pSense,
12740 SCSI_SNSKEY_NO_SENSE,
12741 0,
12742 SCSI_SNSCODE_NO_ADDITIONAL_INFO,
12743 satIOContext);
12744
12745 ostiInitiatorIOCompleted( tiRoot,
12746 tiIORequest,
12747 tiIOSuccess,
12748 SCSI_STAT_CHECK_CONDITION,
12749 satIOContext->pTiSenseData,
12750 satIOContext->interruptContext );
12751 return tiSuccess;
12752 }
12753 /*
12754 for debugging only
12755 */
12756 if (StartingIndex == 8)
12757 {
12758 tdhexdump("startingindex 8", (bit8 *)pLogPage, 8);
12759 }
12760 else if(StartingIndex == 16)
12761 {
12762 if (PageCode == MODESELECT_CACHING)
12763 {
12764 tdhexdump("startingindex 16", (bit8 *)pLogPage, 16+20);
12765 }
12766 else
12767 {
12768 tdhexdump("startingindex 16", (bit8 *)pLogPage, 16+12);
12769 }
12770 }
12771 else
12772 {
12773 if (PageCode == MODESELECT_CACHING)
12774 {
12775 tdhexdump("startingindex 24", (bit8 *)pLogPage, 24+20);
12776 }
12777 else
12778 {
12779 tdhexdump("startingindex 24", (bit8 *)pLogPage, 24+12);
12780 }
12781 }
12782 switch (PageCode) /* page code */
12783 {
12784 case MODESELECT_CONTROL_PAGE:
12785 TI_DBG5(("satModeSelect10: Control mode page\n"));
12786 /*
12787 compare pLogPage to expected value (SAT Table 65, p67)
12788 If not match, return check condition
12789 */
12790 if ( pLogPage[StartingIndex+1] != 0x0A ||
12791 pLogPage[StartingIndex+2] != 0x02 ||
12792 (pSatDevData->satNCQ == agTRUE && pLogPage[StartingIndex+3] != 0x12) ||
12793 (pSatDevData->satNCQ == agFALSE && pLogPage[StartingIndex+3] != 0x02) ||
12794 (pLogPage[StartingIndex+4] & BIT3_MASK) != 0x00 || /* SWP bit */
12795 (pLogPage[StartingIndex+4] & BIT4_MASK) != 0x00 || /* UA_INTLCK_CTRL */
12796 (pLogPage[StartingIndex+4] & BIT5_MASK) != 0x00 || /* UA_INTLCK_CTRL */
12797
12798 (pLogPage[StartingIndex+5] & BIT0_MASK) != 0x00 || /* AUTOLOAD MODE */
12799 (pLogPage[StartingIndex+5] & BIT1_MASK) != 0x00 || /* AUTOLOAD MODE */
12800 (pLogPage[StartingIndex+5] & BIT2_MASK) != 0x00 || /* AUTOLOAD MODE */
12801 (pLogPage[StartingIndex+5] & BIT6_MASK) != 0x00 || /* TAS bit */
12802
12803 pLogPage[StartingIndex+8] != 0xFF ||
12804 pLogPage[StartingIndex+9] != 0xFF ||
12805 pLogPage[StartingIndex+10] != 0x00 ||
12806 pLogPage[StartingIndex+11] != 0x00
12807 )
12808 {
12809 chkCnd = agTRUE;
12810 }
12811 if (chkCnd == agTRUE)
12812 {
12813 satSetSensePayload( pSense,
12814 SCSI_SNSKEY_ILLEGAL_REQUEST,
12815 0,
12816 SCSI_SNSCODE_INVALID_FIELD_IN_CDB,
12817 satIOContext);
12818
12819 ostiInitiatorIOCompleted( tiRoot,
12820 tiIORequest,
12821 tiIOSuccess,
12822 SCSI_STAT_CHECK_CONDITION,
12823 satIOContext->pTiSenseData,
12824 satIOContext->interruptContext );
12825
12826 TI_DBG1(("satModeSelect10: unexpected values\n"));
12827 }
12828 else
12829 {
12830 ostiInitiatorIOCompleted( tiRoot,
12831 tiIORequest,
12832 tiIOSuccess,
12833 SCSI_STAT_GOOD,
12834 agNULL,
12835 satIOContext->interruptContext);
12836 }
12837 return tiSuccess;
12838 break;
12839 case MODESELECT_READ_WRITE_ERROR_RECOVERY_PAGE:
12840 TI_DBG5(("satModeSelect10: Read-Write Error Recovery mode page\n"));
12841 if ( (pLogPage[StartingIndex + 2] & SCSI_MODE_SELECT10_AWRE_MASK) ||
12842 (pLogPage[StartingIndex + 2] & SCSI_MODE_SELECT10_RC_MASK) ||
12843 (pLogPage[StartingIndex + 2] & SCSI_MODE_SELECT10_EER_MASK) ||
12844 (pLogPage[StartingIndex + 2] & SCSI_MODE_SELECT10_PER_MASK) ||
12845 (pLogPage[StartingIndex + 2] & SCSI_MODE_SELECT10_DTE_MASK) ||
12846 (pLogPage[StartingIndex + 2] & SCSI_MODE_SELECT10_DCR_MASK) ||
12847 (pLogPage[StartingIndex + 10]) ||
12848 (pLogPage[StartingIndex + 11])
12849 )
12850 {
12851 TI_DBG1(("satModeSelect10: return check condition \n"));
12852
12853 satSetSensePayload( pSense,
12854 SCSI_SNSKEY_ILLEGAL_REQUEST,
12855 0,
12856 SCSI_SNSCODE_INVALID_FIELD_PARAMETER_LIST,
12857 satIOContext);
12858
12859 ostiInitiatorIOCompleted( tiRoot,
12860 tiIORequest,
12861 tiIOSuccess,
12862 SCSI_STAT_CHECK_CONDITION,
12863 satIOContext->pTiSenseData,
12864 satIOContext->interruptContext );
12865 return tiSuccess;
12866 }
12867 else
12868 {
12869 TI_DBG2(("satModeSelect10: return GOOD \n"));
12870 ostiInitiatorIOCompleted( tiRoot,
12871 tiIORequest,
12872 tiIOSuccess,
12873 SCSI_STAT_GOOD,
12874 agNULL,
12875 satIOContext->interruptContext);
12876 return tiSuccess;
12877 }
12878
12879 break;
12880 case MODESELECT_CACHING:
12881 /* SAT rev8 Table67, p69*/
12882 TI_DBG5(("satModeSelect10: Caching mode page\n"));
12883 if ( (pLogPage[StartingIndex + 2] & 0xFB) || /* 1111 1011 */
12884 (pLogPage[StartingIndex + 3]) ||
12885 (pLogPage[StartingIndex + 4]) ||
12886 (pLogPage[StartingIndex + 5]) ||
12887 (pLogPage[StartingIndex + 6]) ||
12888 (pLogPage[StartingIndex + 7]) ||
12889 (pLogPage[StartingIndex + 8]) ||
12890 (pLogPage[StartingIndex + 9]) ||
12891 (pLogPage[StartingIndex + 10]) ||
12892 (pLogPage[StartingIndex + 11]) ||
12893
12894 (pLogPage[StartingIndex + 12] & 0xC1) || /* 1100 0001 */
12895 (pLogPage[StartingIndex + 13]) ||
12896 (pLogPage[StartingIndex + 14]) ||
12897 (pLogPage[StartingIndex + 15])
12898 )
12899 {
12900 TI_DBG1(("satModeSelect10: return check condition \n"));
12901
12902 satSetSensePayload( pSense,
12903 SCSI_SNSKEY_ILLEGAL_REQUEST,
12904 0,
12905 SCSI_SNSCODE_INVALID_FIELD_PARAMETER_LIST,
12906 satIOContext);
12907
12908 ostiInitiatorIOCompleted( tiRoot,
12909 tiIORequest,
12910 tiIOSuccess,
12911 SCSI_STAT_CHECK_CONDITION,
12912 satIOContext->pTiSenseData,
12913 satIOContext->interruptContext );
12914 return tiSuccess;
12915
12916 }
12917 else
12918 {
12919 /* sends ATA SET FEATURES based on WCE bit */
12920 if ( !(pLogPage[StartingIndex + 2] & SCSI_MODE_SELECT10_WCE_MASK) )
12921 {
12922 TI_DBG5(("satModeSelect10: disable write cache\n"));
12923 /* sends SET FEATURES */
12924 fis->h.fisType = 0x27; /* Reg host to device */
12925 fis->h.c_pmPort = 0x80; /* C Bit is set */
12926
12927 fis->h.command = SAT_SET_FEATURES; /* 0xEF */
12928 fis->h.features = 0x82; /* disable write cache */
12929 fis->d.lbaLow = 0; /* */
12930 fis->d.lbaMid = 0; /* */
12931 fis->d.lbaHigh = 0; /* */
12932 fis->d.device = 0; /* */
12933 fis->d.lbaLowExp = 0; /* */
12934 fis->d.lbaMidExp = 0; /* */
12935 fis->d.lbaHighExp = 0; /* */
12936 fis->d.featuresExp = 0; /* */
12937 fis->d.sectorCount = 0; /* */
12938 fis->d.sectorCountExp = 0; /* */
12939 fis->d.reserved4 = 0;
12940 fis->d.control = 0; /* FIS HOB bit clear */
12941 fis->d.reserved5 = 0;
12942
12943 agRequestType = AGSA_SATA_PROTOCOL_NON_DATA;
12944
12945 /* Initialize CB for SATA completion.
12946 */
12947 satIOContext->satCompleteCB = &satModeSelect6n10CB;
12948
12949 /*
12950 * Prepare SGL and send FIS to LL layer.
12951 */
12952 satIOContext->reqType = agRequestType; /* Save it */
12953
12954 status = sataLLIOStart( tiRoot,
12955 tiIORequest,
12956 tiDeviceHandle,
12957 tiScsiRequest,
12958 satIOContext);
12959 return status;
12960 }
12961 else
12962 {
12963 TI_DBG5(("satModeSelect10: enable write cache\n"));
12964 /* sends SET FEATURES */
12965 fis->h.fisType = 0x27; /* Reg host to device */
12966 fis->h.c_pmPort = 0x80; /* C Bit is set */
12967
12968 fis->h.command = SAT_SET_FEATURES; /* 0xEF */
12969 fis->h.features = 0x02; /* enable write cache */
12970 fis->d.lbaLow = 0; /* */
12971 fis->d.lbaMid = 0; /* */
12972 fis->d.lbaHigh = 0; /* */
12973 fis->d.device = 0; /* */
12974 fis->d.lbaLowExp = 0; /* */
12975 fis->d.lbaMidExp = 0; /* */
12976 fis->d.lbaHighExp = 0; /* */
12977 fis->d.featuresExp = 0; /* */
12978 fis->d.sectorCount = 0; /* */
12979 fis->d.sectorCountExp = 0; /* */
12980 fis->d.reserved4 = 0;
12981 fis->d.control = 0; /* FIS HOB bit clear */
12982 fis->d.reserved5 = 0;
12983
12984 agRequestType = AGSA_SATA_PROTOCOL_NON_DATA;
12985
12986 /* Initialize CB for SATA completion.
12987 */
12988 satIOContext->satCompleteCB = &satModeSelect6n10CB;
12989
12990 /*
12991 * Prepare SGL and send FIS to LL layer.
12992 */
12993 satIOContext->reqType = agRequestType; /* Save it */
12994
12995 status = sataLLIOStart( tiRoot,
12996 tiIORequest,
12997 tiDeviceHandle,
12998 tiScsiRequest,
12999 satIOContext);
13000 return status;
13001
13002 }
13003 }
13004 break;
13005 case MODESELECT_INFORMATION_EXCEPTION_CONTROL_PAGE:
13006 TI_DBG5(("satModeSelect10: Informational Exception Control mode page\n"));
13007
13008 if ( (pLogPage[StartingIndex + 2] & SCSI_MODE_SELECT10_PERF_MASK) ||
13009 (pLogPage[StartingIndex + 2] & SCSI_MODE_SELECT10_TEST_MASK)
13010 )
13011 {
13012 TI_DBG1(("satModeSelect10: return check condition \n"));
13013
13014 satSetSensePayload( pSense,
13015 SCSI_SNSKEY_ILLEGAL_REQUEST,
13016 0,
13017 SCSI_SNSCODE_INVALID_FIELD_PARAMETER_LIST,
13018 satIOContext);
13019
13020 ostiInitiatorIOCompleted( tiRoot,
13021 tiIORequest,
13022 tiIOSuccess,
13023 SCSI_STAT_CHECK_CONDITION,
13024 satIOContext->pTiSenseData,
13025 satIOContext->interruptContext );
13026 return tiSuccess;
13027 }
13028 else
13029 {
13030 /* sends either ATA SMART ENABLE/DISABLE OPERATIONS based on DEXCPT bit */
13031 if ( !(pLogPage[StartingIndex + 2] & SCSI_MODE_SELECT10_DEXCPT_MASK) )
13032 {
13033 TI_DBG5(("satModeSelect10: enable information exceptions reporting\n"));
13034 /* sends SMART ENABLE OPERATIONS */
13035 fis->h.fisType = 0x27; /* Reg host to device */
13036 fis->h.c_pmPort = 0x80; /* C Bit is set */
13037
13038 fis->h.command = SAT_SMART_ENABLE_OPERATIONS; /* 0xB0 */
13039 fis->h.features = 0xD8; /* enable */
13040 fis->d.lbaLow = 0; /* */
13041 fis->d.lbaMid = 0x4F; /* 0x4F */
13042 fis->d.lbaHigh = 0xC2; /* 0xC2 */
13043 fis->d.device = 0; /* */
13044 fis->d.lbaLowExp = 0; /* */
13045 fis->d.lbaMidExp = 0; /* */
13046 fis->d.lbaHighExp = 0; /* */
13047 fis->d.featuresExp = 0; /* */
13048 fis->d.sectorCount = 0; /* */
13049 fis->d.sectorCountExp = 0; /* */
13050 fis->d.reserved4 = 0;
13051 fis->d.control = 0; /* FIS HOB bit clear */
13052 fis->d.reserved5 = 0;
13053
13054 agRequestType = AGSA_SATA_PROTOCOL_NON_DATA;
13055
13056 /* Initialize CB for SATA completion.
13057 */
13058 satIOContext->satCompleteCB = &satModeSelect6n10CB;
13059
13060 /*
13061 * Prepare SGL and send FIS to LL layer.
13062 */
13063 satIOContext->reqType = agRequestType; /* Save it */
13064
13065 status = sataLLIOStart( tiRoot,
13066 tiIORequest,
13067 tiDeviceHandle,
13068 tiScsiRequest,
13069 satIOContext);
13070 return status;
13071 }
13072 else
13073 {
13074 TI_DBG5(("satModeSelect10: disable information exceptions reporting\n"));
13075 /* sends SMART DISABLE OPERATIONS */
13076 fis->h.fisType = 0x27; /* Reg host to device */
13077 fis->h.c_pmPort = 0x80; /* C Bit is set */
13078
13079 fis->h.command = SAT_SMART_DISABLE_OPERATIONS; /* 0xB0 */
13080 fis->h.features = 0xD9; /* disable */
13081 fis->d.lbaLow = 0; /* */
13082 fis->d.lbaMid = 0x4F; /* 0x4F */
13083 fis->d.lbaHigh = 0xC2; /* 0xC2 */
13084 fis->d.device = 0; /* */
13085 fis->d.lbaLowExp = 0; /* */
13086 fis->d.lbaMidExp = 0; /* */
13087 fis->d.lbaHighExp = 0; /* */
13088 fis->d.featuresExp = 0; /* */
13089 fis->d.sectorCount = 0; /* */
13090 fis->d.sectorCountExp = 0; /* */
13091 fis->d.reserved4 = 0;
13092 fis->d.control = 0; /* FIS HOB bit clear */
13093 fis->d.reserved5 = 0;
13094
13095 agRequestType = AGSA_SATA_PROTOCOL_NON_DATA;
13096
13097 /* Initialize CB for SATA completion.
13098 */
13099 satIOContext->satCompleteCB = &satModeSelect6n10CB;
13100
13101 /*
13102 * Prepare SGL and send FIS to LL layer.
13103 */
13104 satIOContext->reqType = agRequestType; /* Save it */
13105
13106 status = sataLLIOStart( tiRoot,
13107 tiIORequest,
13108 tiDeviceHandle,
13109 tiScsiRequest,
13110 satIOContext);
13111 return status;
13112
13113 }
13114 }
13115 break;
13116 default:
13117 TI_DBG1(("satModeSelect10: Error unknown page code 0x%x\n", pLogPage[12]));
13118 satSetSensePayload( pSense,
13119 SCSI_SNSKEY_NO_SENSE,
13120 0,
13121 SCSI_SNSCODE_NO_ADDITIONAL_INFO,
13122 satIOContext);
13123
13124 ostiInitiatorIOCompleted( tiRoot,
13125 tiIORequest,
13126 tiIOSuccess,
13127 SCSI_STAT_CHECK_CONDITION,
13128 satIOContext->pTiSenseData,
13129 satIOContext->interruptContext );
13130 return tiSuccess;
13131 }
13132
13133 }
13134
13135
13136 /*****************************************************************************/
13137 /*! \brief SAT implementation for SCSI satSynchronizeCache10.
13138 *
13139 * SAT implementation for SCSI satSynchronizeCache10.
13140 *
13141 * \param tiRoot: Pointer to TISA initiator driver/port instance.
13142 * \param tiIORequest: Pointer to TISA I/O request context for this I/O.
13143 * \param tiDeviceHandle: Pointer to TISA device handle for this I/O.
13144 * \param tiScsiRequest: Pointer to TISA SCSI I/O request and SGL list.
13145 * \param satIOContext_t: Pointer to the SAT IO Context
13146 *
13147 * \return If command is started successfully
13148 * - \e tiSuccess: I/O request successfully initiated.
13149 * - \e tiBusy: No resources available, try again later.
13150 * - \e tiIONoDevice: Invalid device handle.
13151 * - \e tiError: Other errors.
13152 */
13153 /*****************************************************************************/
satSynchronizeCache10(tiRoot_t * tiRoot,tiIORequest_t * tiIORequest,tiDeviceHandle_t * tiDeviceHandle,tiScsiInitiatorRequest_t * tiScsiRequest,satIOContext_t * satIOContext)13154 GLOBAL bit32 satSynchronizeCache10(
13155 tiRoot_t *tiRoot,
13156 tiIORequest_t *tiIORequest,
13157 tiDeviceHandle_t *tiDeviceHandle,
13158 tiScsiInitiatorRequest_t *tiScsiRequest,
13159 satIOContext_t *satIOContext)
13160 {
13161 bit32 status;
13162 bit32 agRequestType;
13163 satDeviceData_t *pSatDevData;
13164 scsiRspSense_t *pSense;
13165 tiIniScsiCmnd_t *scsiCmnd;
13166 agsaFisRegHostToDevice_t *fis;
13167
13168 pSense = satIOContext->pSense;
13169 pSatDevData = satIOContext->pSatDevData;
13170 scsiCmnd = &tiScsiRequest->scsiCmnd;
13171 fis = satIOContext->pFis;
13172
13173 TI_DBG5(("satSynchronizeCache10: start\n"));
13174
13175 /* checking CONTROL */
13176 /* NACA == 1 or LINK == 1*/
13177 if ( (scsiCmnd->cdb[9] & SCSI_NACA_MASK) || (scsiCmnd->cdb[9] & SCSI_LINK_MASK) )
13178 {
13179 satSetSensePayload( pSense,
13180 SCSI_SNSKEY_ILLEGAL_REQUEST,
13181 0,
13182 SCSI_SNSCODE_INVALID_FIELD_IN_CDB,
13183 satIOContext);
13184
13185 ostiInitiatorIOCompleted( tiRoot,
13186 tiIORequest,
13187 tiIOSuccess,
13188 SCSI_STAT_CHECK_CONDITION,
13189 satIOContext->pTiSenseData,
13190 satIOContext->interruptContext );
13191
13192 TI_DBG2(("satSynchronizeCache10: return control\n"));
13193 return tiSuccess;
13194 }
13195
13196 /* checking IMMED bit */
13197 if (scsiCmnd->cdb[1] & SCSI_SYNC_CACHE_IMMED_MASK)
13198 {
13199 TI_DBG1(("satSynchronizeCache10: GOOD status due to IMMED bit\n"));
13200
13201 /* return GOOD status first here */
13202 ostiInitiatorIOCompleted( tiRoot,
13203 tiIORequest,
13204 tiIOSuccess,
13205 SCSI_STAT_GOOD,
13206 agNULL,
13207 satIOContext->interruptContext);
13208 }
13209
13210 /* sends FLUSH CACHE or FLUSH CACHE EXT */
13211 if (pSatDevData->sat48BitSupport == agTRUE)
13212 {
13213 TI_DBG5(("satSynchronizeCache10: sends FLUSH CACHE EXT\n"));
13214 /* FLUSH CACHE EXT */
13215 fis->h.fisType = 0x27; /* Reg host to device */
13216 fis->h.c_pmPort = 0x80; /* C Bit is set */
13217
13218 fis->h.command = SAT_FLUSH_CACHE_EXT; /* 0xEA */
13219 fis->h.features = 0; /* FIS reserve */
13220 fis->d.featuresExp = 0; /* FIS reserve */
13221 fis->d.sectorCount = 0; /* FIS sector count (7:0) */
13222 fis->d.sectorCountExp = 0; /* FIS sector count (15:8) */
13223 fis->d.lbaLow = 0; /* FIS LBA (7 :0 ) */
13224 fis->d.lbaLowExp = 0; /* FIS LBA (31:24) */
13225 fis->d.lbaMid = 0; /* FIS LBA (15:8 ) */
13226 fis->d.lbaMidExp = 0; /* FIS LBA (39:32) */
13227 fis->d.lbaHigh = 0; /* FIS LBA (23:16) */
13228 fis->d.lbaHighExp = 0; /* FIS LBA (47:40) */
13229 fis->d.device = 0; /* FIS DEV is discared in SATA */
13230 fis->d.control = 0; /* FIS HOB bit clear */
13231 fis->d.reserved4 = 0;
13232 fis->d.reserved5 = 0;
13233
13234 }
13235 else
13236 {
13237 TI_DBG5(("satSynchronizeCache10: sends FLUSH CACHE\n"));
13238 /* FLUSH CACHE */
13239 fis->h.fisType = 0x27; /* Reg host to device */
13240 fis->h.c_pmPort = 0x80; /* C Bit is set */
13241
13242 fis->h.command = SAT_FLUSH_CACHE; /* 0xE7 */
13243 fis->h.features = 0; /* FIS features NA */
13244 fis->d.lbaLow = 0; /* FIS LBA (7 :0 ) */
13245 fis->d.lbaMid = 0; /* FIS LBA (15:8 ) */
13246 fis->d.lbaHigh = 0; /* FIS LBA (23:16) */
13247 fis->d.lbaLowExp = 0;
13248 fis->d.lbaMidExp = 0;
13249 fis->d.lbaHighExp = 0;
13250 fis->d.featuresExp = 0;
13251 fis->d.sectorCount = 0; /* FIS sector count (7:0) */
13252 fis->d.sectorCountExp = 0;
13253 fis->d.device = 0; /* FIS DEV is discared in SATA */
13254 fis->d.control = 0; /* FIS HOB bit clear */
13255 fis->d.reserved4 = 0;
13256 fis->d.reserved5 = 0;
13257
13258 }
13259
13260 agRequestType = AGSA_SATA_PROTOCOL_NON_DATA;
13261
13262 /* Initialize CB for SATA completion.
13263 */
13264 satIOContext->satCompleteCB = &satSynchronizeCache10n16CB;
13265
13266 /*
13267 * Prepare SGL and send FIS to LL layer.
13268 */
13269 satIOContext->reqType = agRequestType; /* Save it */
13270
13271 status = sataLLIOStart( tiRoot,
13272 tiIORequest,
13273 tiDeviceHandle,
13274 tiScsiRequest,
13275 satIOContext);
13276
13277
13278 return (status);
13279 }
13280
13281 /*****************************************************************************/
13282 /*! \brief SAT implementation for SCSI satSynchronizeCache16.
13283 *
13284 * SAT implementation for SCSI satSynchronizeCache16.
13285 *
13286 * \param tiRoot: Pointer to TISA initiator driver/port instance.
13287 * \param tiIORequest: Pointer to TISA I/O request context for this I/O.
13288 * \param tiDeviceHandle: Pointer to TISA device handle for this I/O.
13289 * \param tiScsiRequest: Pointer to TISA SCSI I/O request and SGL list.
13290 * \param satIOContext_t: Pointer to the SAT IO Context
13291 *
13292 * \return If command is started successfully
13293 * - \e tiSuccess: I/O request successfully initiated.
13294 * - \e tiBusy: No resources available, try again later.
13295 * - \e tiIONoDevice: Invalid device handle.
13296 * - \e tiError: Other errors.
13297 */
13298 /*****************************************************************************/
satSynchronizeCache16(tiRoot_t * tiRoot,tiIORequest_t * tiIORequest,tiDeviceHandle_t * tiDeviceHandle,tiScsiInitiatorRequest_t * tiScsiRequest,satIOContext_t * satIOContext)13299 GLOBAL bit32 satSynchronizeCache16(
13300 tiRoot_t *tiRoot,
13301 tiIORequest_t *tiIORequest,
13302 tiDeviceHandle_t *tiDeviceHandle,
13303 tiScsiInitiatorRequest_t *tiScsiRequest,
13304 satIOContext_t *satIOContext)
13305 {
13306 bit32 status;
13307 bit32 agRequestType;
13308 satDeviceData_t *pSatDevData;
13309 scsiRspSense_t *pSense;
13310 tiIniScsiCmnd_t *scsiCmnd;
13311 agsaFisRegHostToDevice_t *fis;
13312
13313 pSense = satIOContext->pSense;
13314 pSatDevData = satIOContext->pSatDevData;
13315 scsiCmnd = &tiScsiRequest->scsiCmnd;
13316 fis = satIOContext->pFis;
13317
13318 TI_DBG5(("satSynchronizeCache16: start\n"));
13319
13320 /* checking CONTROL */
13321 /* NACA == 1 or LINK == 1*/
13322 if ( (scsiCmnd->cdb[15] & SCSI_NACA_MASK) || (scsiCmnd->cdb[15] & SCSI_LINK_MASK) )
13323 {
13324 satSetSensePayload( pSense,
13325 SCSI_SNSKEY_ILLEGAL_REQUEST,
13326 0,
13327 SCSI_SNSCODE_INVALID_FIELD_IN_CDB,
13328 satIOContext);
13329
13330 ostiInitiatorIOCompleted( tiRoot,
13331 tiIORequest,
13332 tiIOSuccess,
13333 SCSI_STAT_CHECK_CONDITION,
13334 satIOContext->pTiSenseData,
13335 satIOContext->interruptContext );
13336
13337 TI_DBG1(("satSynchronizeCache16: return control\n"));
13338 return tiSuccess;
13339 }
13340
13341
13342 /* checking IMMED bit */
13343 if (scsiCmnd->cdb[1] & SCSI_SYNC_CACHE_IMMED_MASK)
13344 {
13345 TI_DBG1(("satSynchronizeCache16: GOOD status due to IMMED bit\n"));
13346
13347 /* return GOOD status first here */
13348 ostiInitiatorIOCompleted( tiRoot,
13349 tiIORequest,
13350 tiIOSuccess,
13351 SCSI_STAT_GOOD,
13352 agNULL,
13353 satIOContext->interruptContext);
13354 }
13355
13356 /* sends FLUSH CACHE or FLUSH CACHE EXT */
13357 if (pSatDevData->sat48BitSupport == agTRUE)
13358 {
13359 TI_DBG5(("satSynchronizeCache16: sends FLUSH CACHE EXT\n"));
13360 /* FLUSH CACHE EXT */
13361 fis->h.fisType = 0x27; /* Reg host to device */
13362 fis->h.c_pmPort = 0x80; /* C Bit is set */
13363
13364 fis->h.command = SAT_FLUSH_CACHE_EXT; /* 0xEA */
13365 fis->h.features = 0; /* FIS reserve */
13366 fis->d.featuresExp = 0; /* FIS reserve */
13367 fis->d.sectorCount = 0; /* FIS sector count (7:0) */
13368 fis->d.sectorCountExp = 0; /* FIS sector count (15:8) */
13369 fis->d.lbaLow = 0; /* FIS LBA (7 :0 ) */
13370 fis->d.lbaLowExp = 0; /* FIS LBA (31:24) */
13371 fis->d.lbaMid = 0; /* FIS LBA (15:8 ) */
13372 fis->d.lbaMidExp = 0; /* FIS LBA (39:32) */
13373 fis->d.lbaHigh = 0; /* FIS LBA (23:16) */
13374 fis->d.lbaHighExp = 0; /* FIS LBA (47:40) */
13375 fis->d.device = 0; /* FIS DEV is discared in SATA */
13376 fis->d.control = 0; /* FIS HOB bit clear */
13377 fis->d.reserved4 = 0;
13378 fis->d.reserved5 = 0;
13379
13380 }
13381 else
13382 {
13383 TI_DBG5(("satSynchronizeCache16: sends FLUSH CACHE\n"));
13384 /* FLUSH CACHE */
13385 fis->h.fisType = 0x27; /* Reg host to device */
13386 fis->h.c_pmPort = 0x80; /* C Bit is set */
13387
13388 fis->h.command = SAT_FLUSH_CACHE; /* 0xE7 */
13389 fis->h.features = 0; /* FIS features NA */
13390 fis->d.lbaLow = 0; /* FIS LBA (7 :0 ) */
13391 fis->d.lbaMid = 0; /* FIS LBA (15:8 ) */
13392 fis->d.lbaHigh = 0; /* FIS LBA (23:16) */
13393 fis->d.lbaLowExp = 0;
13394 fis->d.lbaMidExp = 0;
13395 fis->d.lbaHighExp = 0;
13396 fis->d.featuresExp = 0;
13397 fis->d.sectorCount = 0; /* FIS sector count (7:0) */
13398 fis->d.sectorCountExp = 0;
13399 fis->d.device = 0; /* FIS DEV is discared in SATA */
13400 fis->d.control = 0; /* FIS HOB bit clear */
13401 fis->d.reserved4 = 0;
13402 fis->d.reserved5 = 0;
13403
13404 }
13405
13406 agRequestType = AGSA_SATA_PROTOCOL_NON_DATA;
13407
13408 /* Initialize CB for SATA completion.
13409 */
13410 satIOContext->satCompleteCB = &satSynchronizeCache10n16CB;
13411
13412 /*
13413 * Prepare SGL and send FIS to LL layer.
13414 */
13415 satIOContext->reqType = agRequestType; /* Save it */
13416
13417 status = sataLLIOStart( tiRoot,
13418 tiIORequest,
13419 tiDeviceHandle,
13420 tiScsiRequest,
13421 satIOContext);
13422
13423
13424 return (status);
13425 }
13426
13427
13428 /*****************************************************************************/
13429 /*! \brief SAT implementation for SCSI satWriteAndVerify10.
13430 *
13431 * SAT implementation for SCSI satWriteAndVerify10.
13432 *
13433 * \param tiRoot: Pointer to TISA initiator driver/port instance.
13434 * \param tiIORequest: Pointer to TISA I/O request context for this I/O.
13435 * \param tiDeviceHandle: Pointer to TISA device handle for this I/O.
13436 * \param tiScsiRequest: Pointer to TISA SCSI I/O request and SGL list.
13437 * \param satIOContext_t: Pointer to the SAT IO Context
13438 *
13439 * \return If command is started successfully
13440 * - \e tiSuccess: I/O request successfully initiated.
13441 * - \e tiBusy: No resources available, try again later.
13442 * - \e tiIONoDevice: Invalid device handle.
13443 * - \e tiError: Other errors.
13444 */
13445 /*****************************************************************************/
satWriteAndVerify10(tiRoot_t * tiRoot,tiIORequest_t * tiIORequest,tiDeviceHandle_t * tiDeviceHandle,tiScsiInitiatorRequest_t * tiScsiRequest,satIOContext_t * satIOContext)13446 GLOBAL bit32 satWriteAndVerify10(
13447 tiRoot_t *tiRoot,
13448 tiIORequest_t *tiIORequest,
13449 tiDeviceHandle_t *tiDeviceHandle,
13450 tiScsiInitiatorRequest_t *tiScsiRequest,
13451 satIOContext_t *satIOContext)
13452 {
13453 /*
13454 combination of write10 and verify10
13455 */
13456
13457 bit32 status;
13458 bit32 agRequestType = AGSA_SATA_PROTOCOL_DMA_WRITE;
13459 satDeviceData_t *pSatDevData;
13460 scsiRspSense_t *pSense;
13461 tiIniScsiCmnd_t *scsiCmnd;
13462 agsaFisRegHostToDevice_t *fis;
13463 bit32 lba = 0;
13464 bit32 tl = 0;
13465 bit32 LoopNum = 1;
13466 bit8 LBA[4];
13467 bit8 TL[4];
13468 bit32 rangeChk = agFALSE; /* lba and tl range check */
13469
13470 pSense = satIOContext->pSense;
13471 pSatDevData = satIOContext->pSatDevData;
13472 scsiCmnd = &tiScsiRequest->scsiCmnd;
13473 fis = satIOContext->pFis;
13474
13475 TI_DBG5(("satWriteAndVerify10: start\n"));
13476
13477
13478 /* checking BYTCHK bit */
13479 if (scsiCmnd->cdb[1] & SCSI_WRITE_N_VERIFY_BYTCHK_MASK)
13480 {
13481 satSetSensePayload( pSense,
13482 SCSI_SNSKEY_ILLEGAL_REQUEST,
13483 0,
13484 SCSI_SNSCODE_INVALID_FIELD_IN_CDB,
13485 satIOContext);
13486
13487 ostiInitiatorIOCompleted( tiRoot,
13488 tiIORequest,
13489 tiIOSuccess,
13490 SCSI_STAT_CHECK_CONDITION,
13491 satIOContext->pTiSenseData,
13492 satIOContext->interruptContext );
13493
13494 TI_DBG1(("satWriteAndVerify10: BYTCHK bit checking \n"));
13495 return tiSuccess;
13496 }
13497
13498
13499 /* checking CONTROL */
13500 /* NACA == 1 or LINK == 1*/
13501 if ( (scsiCmnd->cdb[9] & SCSI_NACA_MASK) || (scsiCmnd->cdb[9] & SCSI_LINK_MASK) )
13502 {
13503 satSetSensePayload( pSense,
13504 SCSI_SNSKEY_ILLEGAL_REQUEST,
13505 0,
13506 SCSI_SNSCODE_INVALID_FIELD_IN_CDB,
13507 satIOContext);
13508
13509 ostiInitiatorIOCompleted( tiRoot,
13510 tiIORequest,
13511 tiIOSuccess,
13512 SCSI_STAT_CHECK_CONDITION,
13513 satIOContext->pTiSenseData,
13514 satIOContext->interruptContext );
13515
13516 TI_DBG1(("satWriteAndVerify10: return control\n"));
13517 return tiSuccess;
13518 }
13519
13520 osti_memset(LBA, 0, sizeof(LBA));
13521 osti_memset(TL, 0, sizeof(TL));
13522
13523 /* do not use memcpy due to indexing in LBA and TL */
13524 LBA[0] = scsiCmnd->cdb[2]; /* MSB */
13525 LBA[1] = scsiCmnd->cdb[3];
13526 LBA[2] = scsiCmnd->cdb[4];
13527 LBA[3] = scsiCmnd->cdb[5]; /* LSB */
13528
13529 TL[0] = 0;
13530 TL[1] = 0;
13531 TL[2] = scsiCmnd->cdb[7]; /* MSB */
13532 TL[3] = scsiCmnd->cdb[8]; /* LSB */
13533
13534 rangeChk = satAddNComparebit32(LBA, TL);
13535
13536 /* cbd10; computing LBA and transfer length */
13537 lba = (scsiCmnd->cdb[2] << (8*3)) + (scsiCmnd->cdb[3] << (8*2))
13538 + (scsiCmnd->cdb[4] << 8) + scsiCmnd->cdb[5];
13539 tl = (scsiCmnd->cdb[7] << 8) + scsiCmnd->cdb[8];
13540
13541
13542 /* Table 34, 9.1, p 46 */
13543 /*
13544 note: As of 2/10/2006, no support for DMA QUEUED
13545 */
13546
13547 /*
13548 Table 34, 9.1, p 46, b
13549 When no 48-bit addressing support or NCQ, if LBA is beyond (2^28 - 1),
13550 return check condition
13551 */
13552 if (pSatDevData->satNCQ != agTRUE &&
13553 pSatDevData->sat48BitSupport != agTRUE
13554 )
13555 {
13556 if (lba > SAT_TR_LBA_LIMIT - 1)
13557 {
13558 satSetSensePayload( pSense,
13559 SCSI_SNSKEY_ILLEGAL_REQUEST,
13560 0,
13561 SCSI_SNSCODE_LOGICAL_BLOCK_ADDRESS_OUT_OF_RANGE,
13562 satIOContext);
13563
13564 ostiInitiatorIOCompleted( tiRoot,
13565 tiIORequest,
13566 tiIOSuccess,
13567 SCSI_STAT_CHECK_CONDITION,
13568 satIOContext->pTiSenseData,
13569 satIOContext->interruptContext );
13570
13571 TI_DBG1(("satWriteAndVerify10: return LBA out of range\n"));
13572 return tiSuccess;
13573 }
13574
13575 if (rangeChk) // if (lba + tl > SAT_TR_LBA_LIMIT)
13576 {
13577 TI_DBG1(("satWrite10: return LBA+TL out of range, not EXT\n"));
13578 satSetSensePayload( pSense,
13579 SCSI_SNSKEY_ILLEGAL_REQUEST,
13580 0,
13581 SCSI_SNSCODE_LOGICAL_BLOCK_ADDRESS_OUT_OF_RANGE,
13582 satIOContext);
13583
13584 ostiInitiatorIOCompleted( tiRoot,
13585 tiIORequest,
13586 tiIOSuccess,
13587 SCSI_STAT_CHECK_CONDITION,
13588 satIOContext->pTiSenseData,
13589 satIOContext->interruptContext );
13590
13591 return tiSuccess;
13592 }
13593 }
13594
13595
13596 /* case 1 and 2 */
13597 if (!rangeChk) // if (lba + tl <= SAT_TR_LBA_LIMIT)
13598 {
13599 if (pSatDevData->satDMASupport == agTRUE && pSatDevData->satDMAEnabled == agTRUE)
13600 {
13601 /* case 2 */
13602 /* WRITE DMA*/
13603 /* can't fit the transfer length */
13604 TI_DBG5(("satWriteAndVerify10: case 2 !!!\n"));
13605 fis->h.fisType = 0x27; /* Reg host to device */
13606 fis->h.c_pmPort = 0x80; /* C bit is set */
13607 fis->h.command = SAT_WRITE_DMA; /* 0xCA */
13608 fis->h.features = 0; /* FIS reserve */
13609 fis->d.lbaLow = scsiCmnd->cdb[5]; /* FIS LBA (7 :0 ) */
13610 fis->d.lbaMid = scsiCmnd->cdb[4]; /* FIS LBA (15:8 ) */
13611 fis->d.lbaHigh = scsiCmnd->cdb[3]; /* FIS LBA (23:16) */
13612
13613 /* FIS LBA mode set LBA (27:24) */
13614 fis->d.device = (bit8)((0x4 << 4) | (scsiCmnd->cdb[2] & 0xF));
13615
13616 fis->d.lbaLowExp = 0;
13617 fis->d.lbaMidExp = 0;
13618 fis->d.lbaHighExp = 0;
13619 fis->d.featuresExp = 0;
13620 fis->d.sectorCount = scsiCmnd->cdb[8]; /* FIS sector count (7:0) */
13621 fis->d.sectorCountExp = 0;
13622 fis->d.reserved4 = 0;
13623 fis->d.control = 0; /* FIS HOB bit clear */
13624 fis->d.reserved5 = 0;
13625
13626 agRequestType = AGSA_SATA_PROTOCOL_DMA_WRITE;
13627 satIOContext->ATACmd = SAT_WRITE_DMA;
13628 }
13629 else
13630 {
13631 /* case 1 */
13632 /* WRITE MULTIPLE or WRITE SECTOR(S) */
13633 /* WRITE SECTORS for easier implemetation */
13634 /* can't fit the transfer length */
13635 TI_DBG5(("satWriteAndVerify10: case 1 !!!\n"));
13636 fis->h.fisType = 0x27; /* Reg host to device */
13637 fis->h.c_pmPort = 0x80; /* C bit is set */
13638 fis->h.command = SAT_WRITE_SECTORS; /* 0x30 */
13639 fis->h.features = 0; /* FIS reserve */
13640 fis->d.lbaLow = scsiCmnd->cdb[5]; /* FIS LBA (7 :0 ) */
13641 fis->d.lbaMid = scsiCmnd->cdb[4]; /* FIS LBA (15:8 ) */
13642 fis->d.lbaHigh = scsiCmnd->cdb[3]; /* FIS LBA (23:16) */
13643
13644 /* FIS LBA mode set LBA (27:24) */
13645 fis->d.device = (bit8)((0x4 << 4) | (scsiCmnd->cdb[2] & 0xF));
13646
13647 fis->d.lbaLowExp = 0;
13648 fis->d.lbaMidExp = 0;
13649 fis->d.lbaHighExp = 0;
13650 fis->d.featuresExp = 0;
13651 fis->d.sectorCount = scsiCmnd->cdb[8]; /* FIS sector count (7:0) */
13652 fis->d.sectorCountExp = 0;
13653 fis->d.reserved4 = 0;
13654 fis->d.control = 0; /* FIS HOB bit clear */
13655 fis->d.reserved5 = 0;
13656
13657 agRequestType = AGSA_SATA_PROTOCOL_PIO_WRITE;
13658 satIOContext->ATACmd = SAT_WRITE_SECTORS;
13659
13660 }
13661 }
13662
13663 /* case 3 and 4 */
13664 if (pSatDevData->sat48BitSupport == agTRUE)
13665 {
13666 if (pSatDevData->satDMASupport == agTRUE && pSatDevData->satDMAEnabled == agTRUE)
13667 {
13668 /* case 3 */
13669 /* WRITE DMA EXT or WRITE DMA FUA EXT */
13670 TI_DBG5(("satWriteAndVerify10: case 3\n"));
13671 fis->h.fisType = 0x27; /* Reg host to device */
13672 fis->h.c_pmPort = 0x80; /* C Bit is set */
13673
13674 /* SAT_WRITE_DMA_FUA_EXT is optional and we don't support it */
13675 fis->h.command = SAT_WRITE_DMA_EXT; /* 0x35 */
13676
13677 fis->h.features = 0; /* FIS reserve */
13678 fis->d.lbaLow = scsiCmnd->cdb[5]; /* FIS LBA (7 :0 ) */
13679 fis->d.lbaMid = scsiCmnd->cdb[4]; /* FIS LBA (15:8 ) */
13680 fis->d.lbaHigh = scsiCmnd->cdb[3]; /* FIS LBA (23:16) */
13681 fis->d.device = 0x40; /* FIS LBA mode set */
13682 fis->d.lbaLowExp = scsiCmnd->cdb[2]; /* FIS LBA (31:24) */
13683 fis->d.lbaMidExp = 0; /* FIS LBA (39:32) */
13684 fis->d.lbaHighExp = 0; /* FIS LBA (47:40) */
13685 fis->d.featuresExp = 0; /* FIS reserve */
13686 fis->d.sectorCount = scsiCmnd->cdb[8]; /* FIS sector count (7:0) */
13687 fis->d.sectorCountExp = scsiCmnd->cdb[7]; /* FIS sector count (15:8) */
13688 fis->d.reserved4 = 0;
13689 fis->d.control = 0; /* FIS HOB bit clear */
13690 fis->d.reserved5 = 0;
13691
13692 agRequestType = AGSA_SATA_PROTOCOL_DMA_WRITE;
13693 satIOContext->ATACmd = SAT_WRITE_DMA_EXT;
13694 }
13695 else
13696 {
13697 /* case 4 */
13698 /* WRITE MULTIPLE EXT or WRITE MULTIPLE FUA EXT or WRITE SECTOR(S) EXT */
13699 /* WRITE SECTORS EXT for easier implemetation */
13700 TI_DBG5(("satWriteAndVerify10: case 4\n"));
13701 fis->h.fisType = 0x27; /* Reg host to device */
13702 fis->h.c_pmPort = 0x80; /* C Bit is set */
13703 fis->h.command = SAT_WRITE_SECTORS_EXT; /* 0x34 */
13704
13705 fis->h.features = 0; /* FIS reserve */
13706 fis->d.lbaLow = scsiCmnd->cdb[5]; /* FIS LBA (7 :0 ) */
13707 fis->d.lbaMid = scsiCmnd->cdb[4]; /* FIS LBA (15:8 ) */
13708 fis->d.lbaHigh = scsiCmnd->cdb[3]; /* FIS LBA (23:16) */
13709 fis->d.device = 0x40; /* FIS LBA mode set */
13710 fis->d.lbaLowExp = scsiCmnd->cdb[2]; /* FIS LBA (31:24) */
13711 fis->d.lbaMidExp = 0; /* FIS LBA (39:32) */
13712 fis->d.lbaHighExp = 0; /* FIS LBA (47:40) */
13713 fis->d.featuresExp = 0; /* FIS reserve */
13714 fis->d.sectorCount = scsiCmnd->cdb[8]; /* FIS sector count (7:0) */
13715 fis->d.sectorCountExp = scsiCmnd->cdb[7]; /* FIS sector count (15:8) */
13716 fis->d.reserved4 = 0;
13717 fis->d.control = 0; /* FIS HOB bit clear */
13718 fis->d.reserved5 = 0;
13719
13720 agRequestType = AGSA_SATA_PROTOCOL_PIO_WRITE;
13721 satIOContext->ATACmd = SAT_WRITE_SECTORS_EXT;
13722 }
13723 }
13724 /* case 5 */
13725 if (pSatDevData->satNCQ == agTRUE)
13726 {
13727 /* WRITE FPDMA QUEUED */
13728 if (pSatDevData->sat48BitSupport != agTRUE)
13729 {
13730 TI_DBG5(("satWriteAndVerify10: case 5 !!! error NCQ but 28 bit address support \n"));
13731 satSetSensePayload( pSense,
13732 SCSI_SNSKEY_ILLEGAL_REQUEST,
13733 0,
13734 SCSI_SNSCODE_INVALID_FIELD_IN_CDB,
13735 satIOContext);
13736
13737 ostiInitiatorIOCompleted( tiRoot,
13738 tiIORequest,
13739 tiIOSuccess,
13740 SCSI_STAT_CHECK_CONDITION,
13741 satIOContext->pTiSenseData,
13742 satIOContext->interruptContext );
13743 return tiSuccess;
13744 }
13745 TI_DBG5(("satWriteAndVerify10: case 5\n"));
13746
13747 /* Support 48-bit FPDMA addressing, use WRITE FPDMA QUEUE command */
13748
13749 fis->h.fisType = 0x27; /* Reg host to device */
13750 fis->h.c_pmPort = 0x80; /* C Bit is set */
13751 fis->h.command = SAT_WRITE_FPDMA_QUEUED; /* 0x61 */
13752 fis->h.features = scsiCmnd->cdb[8]; /* FIS sector count (7:0) */
13753 fis->d.lbaLow = scsiCmnd->cdb[5]; /* FIS LBA (7 :0 ) */
13754 fis->d.lbaMid = scsiCmnd->cdb[4]; /* FIS LBA (15:8 ) */
13755 fis->d.lbaHigh = scsiCmnd->cdb[3]; /* FIS LBA (23:16) */
13756
13757 /* Check FUA bit */
13758 if (scsiCmnd->cdb[1] & SCSI_WRITE_N_VERIFY10_FUA_MASK)
13759 fis->d.device = 0xC0; /* FIS FUA set */
13760 else
13761 fis->d.device = 0x40; /* FIS FUA clear */
13762
13763 fis->d.lbaLowExp = scsiCmnd->cdb[2]; /* FIS LBA (31:24) */
13764 fis->d.lbaMidExp = 0; /* FIS LBA (39:32) */
13765 fis->d.lbaHighExp = 0; /* FIS LBA (47:40) */
13766 fis->d.featuresExp = scsiCmnd->cdb[7]; /* FIS sector count (15:8) */
13767 fis->d.sectorCount = 0; /* Tag (7:3) set by LL layer */
13768 fis->d.sectorCountExp = 0;
13769 fis->d.reserved4 = 0;
13770 fis->d.control = 0; /* FIS HOB bit clear */
13771 fis->d.reserved5 = 0;
13772
13773 agRequestType = AGSA_SATA_PROTOCOL_FPDMA_WRITE;
13774 satIOContext->ATACmd = SAT_WRITE_FPDMA_QUEUED;
13775 }
13776
13777 satIOContext->currentLBA = lba;
13778 satIOContext->OrgTL = tl;
13779
13780 /*
13781 computing number of loop and remainder for tl
13782 0xFF in case not ext
13783 0xFFFF in case EXT
13784 */
13785 if (fis->h.command == SAT_WRITE_SECTORS || fis->h.command == SAT_WRITE_DMA)
13786 {
13787 LoopNum = satComputeLoopNum(tl, 0xFF);
13788 }
13789 else if (fis->h.command == SAT_WRITE_SECTORS_EXT ||
13790 fis->h.command == SAT_WRITE_DMA_EXT ||
13791 fis->h.command == SAT_WRITE_DMA_FUA_EXT
13792 )
13793 {
13794 /* SAT_READ_SECTORS_EXT, SAT_READ_DMA_EXT */
13795 LoopNum = satComputeLoopNum(tl, 0xFFFF);
13796 }
13797 else
13798 {
13799 /* SAT_WRITE_FPDMA_QUEUED */
13800 LoopNum = satComputeLoopNum(tl, 0xFFFF);
13801 }
13802
13803 satIOContext->LoopNum = LoopNum;
13804
13805
13806 if (LoopNum == 1)
13807 {
13808 TI_DBG5(("satWriteAndVerify10: NON CHAINED data\n"));
13809 /* Initialize CB for SATA completion.
13810 */
13811 satIOContext->satCompleteCB = &satNonChainedWriteNVerifyCB;
13812 }
13813 else
13814 {
13815 TI_DBG1(("satWriteAndVerify10: CHAINED data\n"));
13816 /* re-setting tl */
13817 if (fis->h.command == SAT_WRITE_SECTORS || fis->h.command == SAT_WRITE_DMA)
13818 {
13819 fis->d.sectorCount = 0xFF;
13820 }
13821 else if (fis->h.command == SAT_WRITE_SECTORS_EXT ||
13822 fis->h.command == SAT_WRITE_DMA_EXT ||
13823 fis->h.command == SAT_WRITE_DMA_FUA_EXT
13824 )
13825 {
13826 fis->d.sectorCount = 0xFF;
13827 fis->d.sectorCountExp = 0xFF;
13828 }
13829 else
13830 {
13831 /* SAT_WRITE_FPDMA_QUEUED */
13832 fis->h.features = 0xFF;
13833 fis->d.featuresExp = 0xFF;
13834 }
13835
13836 /* Initialize CB for SATA completion.
13837 */
13838 satIOContext->satCompleteCB = &satChainedWriteNVerifyCB;
13839 }
13840
13841
13842 /*
13843 * Prepare SGL and send FIS to LL layer.
13844 */
13845 satIOContext->reqType = agRequestType; /* Save it */
13846
13847 status = sataLLIOStart( tiRoot,
13848 tiIORequest,
13849 tiDeviceHandle,
13850 tiScsiRequest,
13851 satIOContext);
13852 return (status);
13853
13854 }
13855
13856
13857
13858
13859
13860
13861 #ifdef REMOVED
satWriteAndVerify10(tiRoot_t * tiRoot,tiIORequest_t * tiIORequest,tiDeviceHandle_t * tiDeviceHandle,tiScsiInitiatorRequest_t * tiScsiRequest,satIOContext_t * satIOContext)13862 GLOBAL bit32 satWriteAndVerify10(
13863 tiRoot_t *tiRoot,
13864 tiIORequest_t *tiIORequest,
13865 tiDeviceHandle_t *tiDeviceHandle,
13866 tiScsiInitiatorRequest_t *tiScsiRequest,
13867 satIOContext_t *satIOContext)
13868 {
13869 /*
13870 combination of write10 and verify10
13871 */
13872
13873 bit32 status;
13874 bit32 agRequestType = AGSA_SATA_PROTOCOL_DMA_WRITE;
13875 satDeviceData_t *pSatDevData;
13876 scsiRspSense_t *pSense;
13877 tiIniScsiCmnd_t *scsiCmnd;
13878 agsaFisRegHostToDevice_t *fis;
13879 bit32 lba = 0;
13880 bit32 tl = 0;
13881
13882 pSense = satIOContext->pSense;
13883 pSatDevData = satIOContext->pSatDevData;
13884 scsiCmnd = &tiScsiRequest->scsiCmnd;
13885 fis = satIOContext->pFis;
13886
13887 TI_DBG5(("satWriteAndVerify10: start\n"));
13888
13889
13890 /* checking BYTCHK bit */
13891 if (scsiCmnd->cdb[1] & SCSI_WRITE_N_VERIFY_BYTCHK_MASK)
13892 {
13893 satSetSensePayload( pSense,
13894 SCSI_SNSKEY_ILLEGAL_REQUEST,
13895 0,
13896 SCSI_SNSCODE_INVALID_FIELD_IN_CDB,
13897 satIOContext);
13898
13899 ostiInitiatorIOCompleted( tiRoot,
13900 tiIORequest,
13901 tiIOSuccess,
13902 SCSI_STAT_CHECK_CONDITION,
13903 satIOContext->pTiSenseData,
13904 satIOContext->interruptContext );
13905
13906 TI_DBG1(("satWriteAndVerify10: BYTCHK bit checking \n"));
13907 return tiSuccess;
13908 }
13909
13910
13911 /* checking CONTROL */
13912 /* NACA == 1 or LINK == 1*/
13913 if ( (scsiCmnd->cdb[9] & SCSI_NACA_MASK) || (scsiCmnd->cdb[9] & SCSI_LINK_MASK) )
13914 {
13915 satSetSensePayload( pSense,
13916 SCSI_SNSKEY_ILLEGAL_REQUEST,
13917 0,
13918 SCSI_SNSCODE_INVALID_FIELD_IN_CDB,
13919 satIOContext);
13920
13921 ostiInitiatorIOCompleted( tiRoot,
13922 tiIORequest,
13923 tiIOSuccess,
13924 SCSI_STAT_CHECK_CONDITION,
13925 satIOContext->pTiSenseData,
13926 satIOContext->interruptContext );
13927
13928 TI_DBG2(("satWriteAndVerify10: return control\n"));
13929 return tiSuccess;
13930 }
13931
13932 /* let's do write10 */
13933 if ( pSatDevData->sat48BitSupport != agTRUE )
13934 {
13935 /*
13936 writeandverify10 but no support for 48 bit addressing -> problem in transfer
13937 length(sector count)
13938 */
13939 satSetSensePayload( pSense,
13940 SCSI_SNSKEY_ILLEGAL_REQUEST,
13941 0,
13942 SCSI_SNSCODE_INVALID_FIELD_IN_CDB,
13943 satIOContext);
13944
13945 ostiInitiatorIOCompleted( tiRoot,
13946 tiIORequest,
13947 tiIOSuccess,
13948 SCSI_STAT_CHECK_CONDITION,
13949 satIOContext->pTiSenseData,
13950 satIOContext->interruptContext );
13951
13952 TI_DBG1(("satWriteAndVerify10: return internal checking\n"));
13953 return tiSuccess;
13954 }
13955
13956 /* cbd10; computing LBA and transfer length */
13957 lba = (scsiCmnd->cdb[2] << (8*3)) + (scsiCmnd->cdb[3] << (8*2))
13958 + (scsiCmnd->cdb[4] << 8) + scsiCmnd->cdb[5];
13959 tl = (scsiCmnd->cdb[7] << 8) + scsiCmnd->cdb[8];
13960
13961
13962 /* Table 34, 9.1, p 46 */
13963 /*
13964 note: As of 2/10/2006, no support for DMA QUEUED
13965 */
13966
13967 /*
13968 Table 34, 9.1, p 46, b
13969 When no 48-bit addressing support or NCQ, if LBA is beyond (2^28 - 1),
13970 return check condition
13971 */
13972 if (pSatDevData->satNCQ != agTRUE &&
13973 pSatDevData->sat48BitSupport != agTRUE
13974 )
13975 {
13976 if (lba > SAT_TR_LBA_LIMIT - 1)
13977 {
13978 satSetSensePayload( pSense,
13979 SCSI_SNSKEY_ILLEGAL_REQUEST,
13980 0,
13981 SCSI_SNSCODE_LOGICAL_BLOCK_ADDRESS_OUT_OF_RANGE,
13982 satIOContext);
13983
13984 ostiInitiatorIOCompleted( tiRoot,
13985 tiIORequest,
13986 tiIOSuccess,
13987 SCSI_STAT_CHECK_CONDITION,
13988 satIOContext->pTiSenseData,
13989 satIOContext->interruptContext );
13990
13991 TI_DBG1(("satWriteAndVerify10: return LBA out of range\n"));
13992 return tiSuccess;
13993 }
13994 }
13995
13996
13997 /* case 1 and 2 */
13998 if (lba + tl <= SAT_TR_LBA_LIMIT)
13999 {
14000 if (pSatDevData->satDMASupport == agTRUE && pSatDevData->satDMAEnabled == agTRUE)
14001 {
14002 /* case 2 */
14003 /* WRITE DMA*/
14004 /* can't fit the transfer length */
14005 TI_DBG5(("satWriteAndVerify10: case 2 !!!\n"));
14006 fis->h.fisType = 0x27; /* Reg host to device */
14007 fis->h.c_pmPort = 0x80; /* C bit is set */
14008 fis->h.command = SAT_WRITE_DMA; /* 0xCA */
14009 fis->h.features = 0; /* FIS reserve */
14010 fis->d.lbaLow = scsiCmnd->cdb[5]; /* FIS LBA (7 :0 ) */
14011 fis->d.lbaMid = scsiCmnd->cdb[4]; /* FIS LBA (15:8 ) */
14012 fis->d.lbaHigh = scsiCmnd->cdb[3]; /* FIS LBA (23:16) */
14013
14014 /* FIS LBA mode set LBA (27:24) */
14015 fis->d.device = (0x4 << 4) | (scsiCmnd->cdb[2] & 0xF);
14016
14017 fis->d.lbaLowExp = 0;
14018 fis->d.lbaMidExp = 0;
14019 fis->d.lbaHighExp = 0;
14020 fis->d.featuresExp = 0;
14021 fis->d.sectorCount = scsiCmnd->cdb[8]; /* FIS sector count (7:0) */
14022 fis->d.sectorCountExp = 0;
14023 fis->d.reserved4 = 0;
14024 fis->d.control = 0; /* FIS HOB bit clear */
14025 fis->d.reserved5 = 0;
14026
14027 agRequestType = AGSA_SATA_PROTOCOL_DMA_WRITE;
14028 satIOContext->ATACmd = SAT_WRITE_DMA;
14029 }
14030 else
14031 {
14032 /* case 1 */
14033 /* WRITE MULTIPLE or WRITE SECTOR(S) */
14034 /* WRITE SECTORS for easier implemetation */
14035 /* can't fit the transfer length */
14036 TI_DBG5(("satWriteAndVerify10: case 1 !!!\n"));
14037 fis->h.fisType = 0x27; /* Reg host to device */
14038 fis->h.c_pmPort = 0x80; /* C bit is set */
14039 fis->h.command = SAT_WRITE_SECTORS; /* 0x30 */
14040 fis->h.features = 0; /* FIS reserve */
14041 fis->d.lbaLow = scsiCmnd->cdb[5]; /* FIS LBA (7 :0 ) */
14042 fis->d.lbaMid = scsiCmnd->cdb[4]; /* FIS LBA (15:8 ) */
14043 fis->d.lbaHigh = scsiCmnd->cdb[3]; /* FIS LBA (23:16) */
14044
14045 /* FIS LBA mode set LBA (27:24) */
14046 fis->d.device = (0x4 << 4) | (scsiCmnd->cdb[2] & 0xF);
14047
14048 fis->d.lbaLowExp = 0;
14049 fis->d.lbaMidExp = 0;
14050 fis->d.lbaHighExp = 0;
14051 fis->d.featuresExp = 0;
14052 fis->d.sectorCount = scsiCmnd->cdb[8]; /* FIS sector count (7:0) */
14053 fis->d.sectorCountExp = 0;
14054 fis->d.reserved4 = 0;
14055 fis->d.control = 0; /* FIS HOB bit clear */
14056 fis->d.reserved5 = 0;
14057
14058 agRequestType = AGSA_SATA_PROTOCOL_PIO_WRITE;
14059 satIOContext->ATACmd = SAT_WRITE_SECTORS;
14060
14061 }
14062 }
14063
14064 /* case 3 and 4 */
14065 if (pSatDevData->sat48BitSupport == agTRUE)
14066 {
14067 if (pSatDevData->satDMASupport == agTRUE && pSatDevData->satDMAEnabled == agTRUE)
14068 {
14069 /* case 3 */
14070 /* WRITE DMA EXT or WRITE DMA FUA EXT */
14071 TI_DBG5(("satWriteAndVerify10: case 3\n"));
14072 fis->h.fisType = 0x27; /* Reg host to device */
14073 fis->h.c_pmPort = 0x80; /* C Bit is set */
14074
14075 /* SAT_WRITE_DMA_FUA_EXT is optional and we don't support it */
14076 fis->h.command = SAT_WRITE_DMA_EXT; /* 0x35 */
14077
14078 fis->h.features = 0; /* FIS reserve */
14079 fis->d.lbaLow = scsiCmnd->cdb[5]; /* FIS LBA (7 :0 ) */
14080 fis->d.lbaMid = scsiCmnd->cdb[4]; /* FIS LBA (15:8 ) */
14081 fis->d.lbaHigh = scsiCmnd->cdb[3]; /* FIS LBA (23:16) */
14082 fis->d.device = 0x40; /* FIS LBA mode set */
14083 fis->d.lbaLowExp = scsiCmnd->cdb[2]; /* FIS LBA (31:24) */
14084 fis->d.lbaMidExp = 0; /* FIS LBA (39:32) */
14085 fis->d.lbaHighExp = 0; /* FIS LBA (47:40) */
14086 fis->d.featuresExp = 0; /* FIS reserve */
14087 fis->d.sectorCount = scsiCmnd->cdb[8]; /* FIS sector count (7:0) */
14088 fis->d.sectorCountExp = scsiCmnd->cdb[7]; /* FIS sector count (15:8) */
14089 fis->d.reserved4 = 0;
14090 fis->d.control = 0; /* FIS HOB bit clear */
14091 fis->d.reserved5 = 0;
14092
14093 agRequestType = AGSA_SATA_PROTOCOL_DMA_WRITE;
14094 }
14095 else
14096 {
14097 /* case 4 */
14098 /* WRITE MULTIPLE EXT or WRITE MULTIPLE FUA EXT or WRITE SECTOR(S) EXT */
14099 /* WRITE SECTORS EXT for easier implemetation */
14100 TI_DBG5(("satWriteAndVerify10: case 4\n"));
14101 fis->h.fisType = 0x27; /* Reg host to device */
14102 fis->h.c_pmPort = 0x80; /* C Bit is set */
14103 fis->h.command = SAT_WRITE_SECTORS_EXT; /* 0x34 */
14104
14105 fis->h.features = 0; /* FIS reserve */
14106 fis->d.lbaLow = scsiCmnd->cdb[5]; /* FIS LBA (7 :0 ) */
14107 fis->d.lbaMid = scsiCmnd->cdb[4]; /* FIS LBA (15:8 ) */
14108 fis->d.lbaHigh = scsiCmnd->cdb[3]; /* FIS LBA (23:16) */
14109 fis->d.device = 0x40; /* FIS LBA mode set */
14110 fis->d.lbaLowExp = scsiCmnd->cdb[2]; /* FIS LBA (31:24) */
14111 fis->d.lbaMidExp = 0; /* FIS LBA (39:32) */
14112 fis->d.lbaHighExp = 0; /* FIS LBA (47:40) */
14113 fis->d.featuresExp = 0; /* FIS reserve */
14114 fis->d.sectorCount = scsiCmnd->cdb[8]; /* FIS sector count (7:0) */
14115 fis->d.sectorCountExp = scsiCmnd->cdb[7]; /* FIS sector count (15:8) */
14116 fis->d.reserved4 = 0;
14117 fis->d.control = 0; /* FIS HOB bit clear */
14118 fis->d.reserved5 = 0;
14119
14120 agRequestType = AGSA_SATA_PROTOCOL_PIO_WRITE;
14121 }
14122 }
14123 /* case 5 */
14124 if (pSatDevData->satNCQ == agTRUE)
14125 {
14126 /* WRITE FPDMA QUEUED */
14127 if (pSatDevData->sat48BitSupport != agTRUE)
14128 {
14129 TI_DBG5(("satWriteAndVerify10: case 5 !!! error NCQ but 28 bit address support \n"));
14130 satSetSensePayload( pSense,
14131 SCSI_SNSKEY_ILLEGAL_REQUEST,
14132 0,
14133 SCSI_SNSCODE_INVALID_FIELD_IN_CDB,
14134 satIOContext);
14135
14136 ostiInitiatorIOCompleted( tiRoot,
14137 tiIORequest,
14138 tiIOSuccess,
14139 SCSI_STAT_CHECK_CONDITION,
14140 satIOContext->pTiSenseData,
14141 satIOContext->interruptContext );
14142 return tiSuccess;
14143 }
14144 TI_DBG5(("satWriteAndVerify10: case 5\n"));
14145
14146 /* Support 48-bit FPDMA addressing, use WRITE FPDMA QUEUE command */
14147
14148 fis->h.fisType = 0x27; /* Reg host to device */
14149 fis->h.c_pmPort = 0x80; /* C Bit is set */
14150 fis->h.command = SAT_WRITE_FPDMA_QUEUED; /* 0x61 */
14151 fis->h.features = scsiCmnd->cdb[8]; /* FIS sector count (7:0) */
14152 fis->d.lbaLow = scsiCmnd->cdb[5]; /* FIS LBA (7 :0 ) */
14153 fis->d.lbaMid = scsiCmnd->cdb[4]; /* FIS LBA (15:8 ) */
14154 fis->d.lbaHigh = scsiCmnd->cdb[3]; /* FIS LBA (23:16) */
14155
14156 /* Check FUA bit */
14157 if (scsiCmnd->cdb[1] & SCSI_WRITE_N_VERIFY10_FUA_MASK)
14158 fis->d.device = 0xC0; /* FIS FUA set */
14159 else
14160 fis->d.device = 0x40; /* FIS FUA clear */
14161
14162 fis->d.lbaLowExp = scsiCmnd->cdb[2]; /* FIS LBA (31:24) */
14163 fis->d.lbaMidExp = 0; /* FIS LBA (39:32) */
14164 fis->d.lbaHighExp = 0; /* FIS LBA (47:40) */
14165 fis->d.featuresExp = scsiCmnd->cdb[7]; /* FIS sector count (15:8) */
14166 fis->d.sectorCount = 0; /* Tag (7:3) set by LL layer */
14167 fis->d.sectorCountExp = 0;
14168 fis->d.reserved4 = 0;
14169 fis->d.control = 0; /* FIS HOB bit clear */
14170 fis->d.reserved5 = 0;
14171
14172 agRequestType = AGSA_SATA_PROTOCOL_FPDMA_WRITE;
14173 }
14174
14175 /* Initialize CB for SATA completion.
14176 */
14177 satIOContext->satCompleteCB = &satWriteAndVerify10CB;
14178
14179 /*
14180 * Prepare SGL and send FIS to LL layer.
14181 */
14182 satIOContext->reqType = agRequestType; /* Save it */
14183
14184 status = sataLLIOStart( tiRoot,
14185 tiIORequest,
14186 tiDeviceHandle,
14187 tiScsiRequest,
14188 satIOContext);
14189 return (status);
14190
14191 }
14192 #endif /* REMOVED */
14193
14194 #ifdef REMOVED
14195 /*****************************************************************************/
14196 /*! \brief SAT implementation for SCSI satWriteAndVerify10_1.
14197 *
14198 * SAT implementation for SCSI satWriteAndVerify10_1.
14199 * Sub function of satWriteAndVerify10
14200 *
14201 * \param tiRoot: Pointer to TISA initiator driver/port instance.
14202 * \param tiIORequest: Pointer to TISA I/O request context for this I/O.
14203 * \param tiDeviceHandle: Pointer to TISA device handle for this I/O.
14204 * \param tiScsiRequest: Pointer to TISA SCSI I/O request and SGL list.
14205 * \param satIOContext_t: Pointer to the SAT IO Context
14206 *
14207 * \return If command is started successfully
14208 * - \e tiSuccess: I/O request successfully initiated.
14209 * - \e tiBusy: No resources available, try again later.
14210 * - \e tiIONoDevice: Invalid device handle.
14211 * - \e tiError: Other errors.
14212 */
14213 /*****************************************************************************/
satWriteAndVerify10_1(tiRoot_t * tiRoot,tiIORequest_t * tiIORequest,tiDeviceHandle_t * tiDeviceHandle,tiScsiInitiatorRequest_t * tiScsiRequest,satIOContext_t * satIOContext)14214 GLOBAL bit32 satWriteAndVerify10_1(
14215 tiRoot_t *tiRoot,
14216 tiIORequest_t *tiIORequest,
14217 tiDeviceHandle_t *tiDeviceHandle,
14218 tiScsiInitiatorRequest_t *tiScsiRequest,
14219 satIOContext_t *satIOContext)
14220 {
14221 bit32 status;
14222 bit32 agRequestType = AGSA_SATA_PROTOCOL_DMA_WRITE;
14223 satDeviceData_t *pSatDevData;
14224 scsiRspSense_t *pSense;
14225 tiIniScsiCmnd_t *scsiCmnd;
14226 agsaFisRegHostToDevice_t *fis;
14227
14228 pSense = satIOContext->pSense;
14229 pSatDevData = satIOContext->pSatDevData;
14230 scsiCmnd = &tiScsiRequest->scsiCmnd;
14231 fis = satIOContext->pFis;
14232
14233 TI_DBG5(("satWriteAndVerify10_1: start\n"));
14234
14235 if (pSatDevData->sat48BitSupport == agTRUE)
14236 {
14237 fis->h.fisType = 0x27; /* Reg host to device */
14238 fis->h.c_pmPort = 0x80; /* C Bit is set */
14239
14240 fis->h.command = SAT_READ_VERIFY_SECTORS_EXT;/* 0x42 */
14241 fis->h.features = 0; /* FIS reserve */
14242 fis->d.lbaLow = scsiCmnd->cdb[5]; /* FIS LBA (7 :0 ) */
14243 fis->d.lbaMid = scsiCmnd->cdb[4]; /* FIS LBA (15:8 ) */
14244 fis->d.lbaHigh = scsiCmnd->cdb[3]; /* FIS LBA (23:16) */
14245 fis->d.device = 0x40; /* FIS LBA mode set 01000000 */
14246 fis->d.lbaLowExp = scsiCmnd->cdb[2]; /* FIS LBA (31:24) */
14247 fis->d.lbaMidExp = 0; /* FIS LBA (39:32) */
14248 fis->d.lbaHighExp = 0; /* FIS LBA (47:40) */
14249 fis->d.featuresExp = 0; /* FIS reserve */
14250 fis->d.sectorCount = scsiCmnd->cdb[8]; /* FIS sector count (7:0) */
14251 fis->d.sectorCountExp = scsiCmnd->cdb[7]; /* FIS sector count (15:8) */
14252
14253 fis->d.reserved4 = 0;
14254 fis->d.control = 0; /* FIS HOB bit clear */
14255 fis->d.reserved5 = 0;
14256
14257 agRequestType = AGSA_SATA_PROTOCOL_NON_DATA;
14258
14259 /* Initialize CB for SATA completion.
14260 */
14261 satIOContext->satCompleteCB = &satWriteAndVerify10CB;
14262
14263 /*
14264 * Prepare SGL and send FIS to LL layer.
14265 */
14266 satIOContext->reqType = agRequestType; /* Save it */
14267
14268 status = sataLLIOStart( tiRoot,
14269 tiIORequest,
14270 tiDeviceHandle,
14271 tiScsiRequest,
14272 satIOContext);
14273
14274
14275 TI_DBG1(("satWriteAndVerify10_1: return status %d\n", status));
14276 return (status);
14277 }
14278 else
14279 {
14280 /* can't fit in SAT_READ_VERIFY_SECTORS becasue of Sector Count and LBA */
14281 TI_DBG1(("satWriteAndVerify10_1: can't fit in SAT_READ_VERIFY_SECTORS\n"));
14282 return tiError;
14283 }
14284
14285
14286 return tiSuccess;
14287 }
14288 #endif /* REMOVED */
14289
14290 /*****************************************************************************/
14291 /*! \brief SAT implementation for SCSI satWriteAndVerify12.
14292 *
14293 * SAT implementation for SCSI satWriteAndVerify12.
14294 *
14295 * \param tiRoot: Pointer to TISA initiator driver/port instance.
14296 * \param tiIORequest: Pointer to TISA I/O request context for this I/O.
14297 * \param tiDeviceHandle: Pointer to TISA device handle for this I/O.
14298 * \param tiScsiRequest: Pointer to TISA SCSI I/O request and SGL list.
14299 * \param satIOContext_t: Pointer to the SAT IO Context
14300 *
14301 * \return If command is started successfully
14302 * - \e tiSuccess: I/O request successfully initiated.
14303 * - \e tiBusy: No resources available, try again later.
14304 * - \e tiIONoDevice: Invalid device handle.
14305 * - \e tiError: Other errors.
14306 */
14307 /*****************************************************************************/
satWriteAndVerify12(tiRoot_t * tiRoot,tiIORequest_t * tiIORequest,tiDeviceHandle_t * tiDeviceHandle,tiScsiInitiatorRequest_t * tiScsiRequest,satIOContext_t * satIOContext)14308 GLOBAL bit32 satWriteAndVerify12(
14309 tiRoot_t *tiRoot,
14310 tiIORequest_t *tiIORequest,
14311 tiDeviceHandle_t *tiDeviceHandle,
14312 tiScsiInitiatorRequest_t *tiScsiRequest,
14313 satIOContext_t *satIOContext)
14314 {
14315 /*
14316 combination of write12 and verify12
14317 temp: since write12 is not support (due to internal checking), no support
14318 */
14319 bit32 status;
14320 bit32 agRequestType = AGSA_SATA_PROTOCOL_DMA_WRITE;
14321 satDeviceData_t *pSatDevData;
14322 scsiRspSense_t *pSense;
14323 tiIniScsiCmnd_t *scsiCmnd;
14324 agsaFisRegHostToDevice_t *fis;
14325 bit32 lba = 0;
14326 bit32 tl = 0;
14327 bit32 LoopNum = 1;
14328 bit8 LBA[4];
14329 bit8 TL[4];
14330 bit32 rangeChk = agFALSE; /* lba and tl range check */
14331
14332 pSense = satIOContext->pSense;
14333 pSatDevData = satIOContext->pSatDevData;
14334 scsiCmnd = &tiScsiRequest->scsiCmnd;
14335 fis = satIOContext->pFis;
14336
14337 TI_DBG5(("satWriteAndVerify12: start\n"));
14338
14339 /* checking BYTCHK bit */
14340 if (scsiCmnd->cdb[1] & SCSI_WRITE_N_VERIFY_BYTCHK_MASK)
14341 {
14342 satSetSensePayload( pSense,
14343 SCSI_SNSKEY_ILLEGAL_REQUEST,
14344 0,
14345 SCSI_SNSCODE_INVALID_FIELD_IN_CDB,
14346 satIOContext);
14347
14348 ostiInitiatorIOCompleted( tiRoot,
14349 tiIORequest,
14350 tiIOSuccess,
14351 SCSI_STAT_CHECK_CONDITION,
14352 satIOContext->pTiSenseData,
14353 satIOContext->interruptContext );
14354
14355 TI_DBG1(("satWriteAndVerify12: BYTCHK bit checking \n"));
14356 return tiSuccess;
14357 }
14358
14359 /* checking CONTROL */
14360 /* NACA == 1 or LINK == 1*/
14361 if ( (scsiCmnd->cdb[11] & SCSI_NACA_MASK) || (scsiCmnd->cdb[11] & SCSI_LINK_MASK) )
14362 {
14363 satSetSensePayload( pSense,
14364 SCSI_SNSKEY_ILLEGAL_REQUEST,
14365 0,
14366 SCSI_SNSCODE_INVALID_FIELD_IN_CDB,
14367 satIOContext);
14368
14369 ostiInitiatorIOCompleted( tiRoot,
14370 tiIORequest,
14371 tiIOSuccess,
14372 SCSI_STAT_CHECK_CONDITION,
14373 satIOContext->pTiSenseData,
14374 satIOContext->interruptContext );
14375
14376 TI_DBG2(("satWriteAndVerify12: return control\n"));
14377 return tiSuccess;
14378 }
14379
14380 osti_memset(LBA, 0, sizeof(LBA));
14381 osti_memset(TL, 0, sizeof(TL));
14382
14383 /* do not use memcpy due to indexing in LBA and TL */
14384 LBA[0] = scsiCmnd->cdb[2]; /* MSB */
14385 LBA[1] = scsiCmnd->cdb[3];
14386 LBA[2] = scsiCmnd->cdb[4];
14387 LBA[3] = scsiCmnd->cdb[5]; /* LSB */
14388
14389 TL[0] = scsiCmnd->cdb[6]; /* MSB */
14390 TL[1] = scsiCmnd->cdb[7];
14391 TL[2] = scsiCmnd->cdb[7];
14392 TL[3] = scsiCmnd->cdb[8]; /* LSB */
14393
14394 rangeChk = satAddNComparebit32(LBA, TL);
14395
14396 lba = satComputeCDB12LBA(satIOContext);
14397 tl = satComputeCDB12TL(satIOContext);
14398
14399
14400 /* Table 34, 9.1, p 46 */
14401 /*
14402 note: As of 2/10/2006, no support for DMA QUEUED
14403 */
14404
14405 /*
14406 Table 34, 9.1, p 46, b
14407 When no 48-bit addressing support or NCQ, if LBA is beyond (2^28 - 1),
14408 return check condition
14409 */
14410 if (pSatDevData->satNCQ != agTRUE &&
14411 pSatDevData->sat48BitSupport != agTRUE
14412 )
14413 {
14414 if (lba > SAT_TR_LBA_LIMIT - 1)
14415 {
14416 satSetSensePayload( pSense,
14417 SCSI_SNSKEY_ILLEGAL_REQUEST,
14418 0,
14419 SCSI_SNSCODE_LOGICAL_BLOCK_ADDRESS_OUT_OF_RANGE,
14420 satIOContext);
14421
14422 ostiInitiatorIOCompleted( tiRoot,
14423 tiIORequest,
14424 tiIOSuccess,
14425 SCSI_STAT_CHECK_CONDITION,
14426 satIOContext->pTiSenseData,
14427 satIOContext->interruptContext );
14428
14429 TI_DBG1(("satWriteAndVerify12: return LBA out of range, not EXT\n"));
14430 return tiSuccess;
14431 }
14432
14433 if (rangeChk) // if (lba + tl > SAT_TR_LBA_LIMIT)
14434 {
14435 TI_DBG1(("satWriteAndVerify12: return LBA+TL out of range, not EXT\n"));
14436 satSetSensePayload( pSense,
14437 SCSI_SNSKEY_ILLEGAL_REQUEST,
14438 0,
14439 SCSI_SNSCODE_LOGICAL_BLOCK_ADDRESS_OUT_OF_RANGE,
14440 satIOContext);
14441
14442 ostiInitiatorIOCompleted( tiRoot,
14443 tiIORequest,
14444 tiIOSuccess,
14445 SCSI_STAT_CHECK_CONDITION,
14446 satIOContext->pTiSenseData,
14447 satIOContext->interruptContext );
14448
14449 return tiSuccess;
14450 }
14451 }
14452
14453 /* case 1 and 2 */
14454 if (!rangeChk) // if (lba + tl <= SAT_TR_LBA_LIMIT)
14455 {
14456 if (pSatDevData->satDMASupport == agTRUE && pSatDevData->satDMAEnabled == agTRUE)
14457 {
14458 /* case 2 */
14459 /* WRITE DMA*/
14460 /* In case that we can't fit the transfer length, we loop */
14461 TI_DBG5(("satWriteAndVerify12: case 2\n"));
14462 fis->h.fisType = 0x27; /* Reg host to device */
14463 fis->h.c_pmPort = 0x80; /* C bit is set */
14464 fis->h.command = SAT_WRITE_DMA; /* 0xCA */
14465 fis->h.features = 0; /* FIS reserve */
14466 fis->d.lbaLow = scsiCmnd->cdb[5]; /* FIS LBA (7 :0 ) */
14467 fis->d.lbaMid = scsiCmnd->cdb[4]; /* FIS LBA (15:8 ) */
14468 fis->d.lbaHigh = scsiCmnd->cdb[3]; /* FIS LBA (23:16) */
14469
14470 /* FIS LBA mode set LBA (27:24) */
14471 fis->d.device = (bit8)((0x4 << 4) | (scsiCmnd->cdb[2] & 0xF));
14472
14473 fis->d.lbaLowExp = 0;
14474 fis->d.lbaMidExp = 0;
14475 fis->d.lbaHighExp = 0;
14476 fis->d.featuresExp = 0;
14477 fis->d.sectorCount = scsiCmnd->cdb[9]; /* FIS sector count (7:0) */
14478 fis->d.sectorCountExp = 0;
14479 fis->d.reserved4 = 0;
14480 fis->d.control = 0; /* FIS HOB bit clear */
14481 fis->d.reserved5 = 0;
14482
14483 agRequestType = AGSA_SATA_PROTOCOL_DMA_WRITE;
14484 satIOContext->ATACmd = SAT_WRITE_DMA;
14485 }
14486 else
14487 {
14488 /* case 1 */
14489 /* WRITE MULTIPLE or WRITE SECTOR(S) */
14490 /* WRITE SECTORS for easier implemetation */
14491 /* In case that we can't fit the transfer length, we loop */
14492 TI_DBG5(("satWriteAndVerify12: case 1\n"));
14493 fis->h.fisType = 0x27; /* Reg host to device */
14494 fis->h.c_pmPort = 0x80; /* C bit is set */
14495 fis->h.command = SAT_WRITE_SECTORS; /* 0x30 */
14496 fis->h.features = 0; /* FIS reserve */
14497 fis->d.lbaLow = scsiCmnd->cdb[5]; /* FIS LBA (7 :0 ) */
14498 fis->d.lbaMid = scsiCmnd->cdb[4]; /* FIS LBA (15:8 ) */
14499 fis->d.lbaHigh = scsiCmnd->cdb[3]; /* FIS LBA (23:16) */
14500
14501 /* FIS LBA mode set LBA (27:24) */
14502 fis->d.device = (bit8)((0x4 << 4) | (scsiCmnd->cdb[2] & 0xF));
14503
14504 fis->d.lbaLowExp = 0;
14505 fis->d.lbaMidExp = 0;
14506 fis->d.lbaHighExp = 0;
14507 fis->d.featuresExp = 0;
14508 fis->d.sectorCount = scsiCmnd->cdb[9]; /* FIS sector count (7:0) */
14509 fis->d.sectorCountExp = 0;
14510 fis->d.reserved4 = 0;
14511 fis->d.control = 0; /* FIS HOB bit clear */
14512 fis->d.reserved5 = 0;
14513
14514 agRequestType = AGSA_SATA_PROTOCOL_PIO_WRITE;
14515 satIOContext->ATACmd = SAT_WRITE_SECTORS;
14516 }
14517 }
14518
14519 /* case 3 and 4 */
14520 if (pSatDevData->sat48BitSupport == agTRUE)
14521 {
14522 if (pSatDevData->satDMASupport == agTRUE && pSatDevData->satDMAEnabled == agTRUE)
14523 {
14524 /* case 3 */
14525 /* WRITE DMA EXT or WRITE DMA FUA EXT */
14526 TI_DBG5(("satWriteAndVerify12: case 3\n"));
14527 fis->h.fisType = 0x27; /* Reg host to device */
14528 fis->h.c_pmPort = 0x80; /* C Bit is set */
14529
14530 /* SAT_WRITE_DMA_FUA_EXT is optional and we don't support it */
14531 fis->h.command = SAT_WRITE_DMA_EXT; /* 0x35 */
14532
14533 fis->h.features = 0; /* FIS reserve */
14534 fis->d.lbaLow = scsiCmnd->cdb[5]; /* FIS LBA (7 :0 ) */
14535 fis->d.lbaMid = scsiCmnd->cdb[4]; /* FIS LBA (15:8 ) */
14536 fis->d.lbaHigh = scsiCmnd->cdb[3]; /* FIS LBA (23:16) */
14537 fis->d.device = 0x40; /* FIS LBA mode set */
14538 fis->d.lbaLowExp = scsiCmnd->cdb[2]; /* FIS LBA (31:24) */
14539 fis->d.lbaMidExp = 0; /* FIS LBA (39:32) */
14540 fis->d.lbaHighExp = 0; /* FIS LBA (47:40) */
14541 fis->d.featuresExp = 0; /* FIS reserve */
14542 fis->d.sectorCount = scsiCmnd->cdb[9]; /* FIS sector count (7:0) */
14543 fis->d.sectorCountExp = scsiCmnd->cdb[8]; /* FIS sector count (15:8) */
14544 fis->d.reserved4 = 0;
14545 fis->d.control = 0; /* FIS HOB bit clear */
14546 fis->d.reserved5 = 0;
14547
14548 agRequestType = AGSA_SATA_PROTOCOL_DMA_WRITE;
14549 satIOContext->ATACmd = SAT_WRITE_DMA_EXT;
14550 }
14551 else
14552 {
14553 /* case 4 */
14554 /* WRITE MULTIPLE EXT or WRITE MULTIPLE FUA EXT or WRITE SECTOR(S) EXT */
14555 /* WRITE SECTORS EXT for easier implemetation */
14556 TI_DBG5(("satWriteAndVerify12: case 4\n"));
14557 fis->h.fisType = 0x27; /* Reg host to device */
14558 fis->h.c_pmPort = 0x80; /* C Bit is set */
14559 fis->h.command = SAT_WRITE_SECTORS_EXT; /* 0x34 */
14560
14561 fis->h.features = 0; /* FIS reserve */
14562 fis->d.lbaLow = scsiCmnd->cdb[5]; /* FIS LBA (7 :0 ) */
14563 fis->d.lbaMid = scsiCmnd->cdb[4]; /* FIS LBA (15:8 ) */
14564 fis->d.lbaHigh = scsiCmnd->cdb[3]; /* FIS LBA (23:16) */
14565 fis->d.device = 0x40; /* FIS LBA mode set */
14566 fis->d.lbaLowExp = scsiCmnd->cdb[2]; /* FIS LBA (31:24) */
14567 fis->d.lbaMidExp = 0; /* FIS LBA (39:32) */
14568 fis->d.lbaHighExp = 0; /* FIS LBA (47:40) */
14569 fis->d.featuresExp = 0; /* FIS reserve */
14570 fis->d.sectorCount = scsiCmnd->cdb[9]; /* FIS sector count (7:0) */
14571 fis->d.sectorCountExp = scsiCmnd->cdb[8]; /* FIS sector count (15:8) */
14572 fis->d.reserved4 = 0;
14573 fis->d.control = 0; /* FIS HOB bit clear */
14574 fis->d.reserved5 = 0;
14575
14576 agRequestType = AGSA_SATA_PROTOCOL_PIO_WRITE;
14577 satIOContext->ATACmd = SAT_WRITE_SECTORS_EXT;
14578 }
14579 }
14580
14581 /* case 5 */
14582 if (pSatDevData->satNCQ == agTRUE)
14583 {
14584 /* WRITE FPDMA QUEUED */
14585 if (pSatDevData->sat48BitSupport != agTRUE)
14586 {
14587 TI_DBG5(("satWriteAndVerify12: case 5 !!! error NCQ but 28 bit address support \n"));
14588 satSetSensePayload( pSense,
14589 SCSI_SNSKEY_ILLEGAL_REQUEST,
14590 0,
14591 SCSI_SNSCODE_INVALID_FIELD_IN_CDB,
14592 satIOContext);
14593
14594 ostiInitiatorIOCompleted( tiRoot,
14595 tiIORequest,
14596 tiIOSuccess,
14597 SCSI_STAT_CHECK_CONDITION,
14598 satIOContext->pTiSenseData,
14599 satIOContext->interruptContext );
14600 return tiSuccess;
14601 }
14602 TI_DBG6(("satWriteAndVerify12: case 5\n"));
14603
14604 /* Support 48-bit FPDMA addressing, use WRITE FPDMA QUEUE command */
14605
14606 fis->h.fisType = 0x27; /* Reg host to device */
14607 fis->h.c_pmPort = 0x80; /* C Bit is set */
14608 fis->h.command = SAT_WRITE_FPDMA_QUEUED; /* 0x61 */
14609 fis->h.features = scsiCmnd->cdb[9]; /* FIS sector count (7:0) */
14610 fis->d.lbaLow = scsiCmnd->cdb[5]; /* FIS LBA (7 :0 ) */
14611 fis->d.lbaMid = scsiCmnd->cdb[4]; /* FIS LBA (15:8 ) */
14612 fis->d.lbaHigh = scsiCmnd->cdb[3]; /* FIS LBA (23:16) */
14613
14614 /* Check FUA bit */
14615 if (scsiCmnd->cdb[1] & SCSI_WRITE12_FUA_MASK)
14616 fis->d.device = 0xC0; /* FIS FUA set */
14617 else
14618 fis->d.device = 0x40; /* FIS FUA clear */
14619
14620 fis->d.lbaLowExp = scsiCmnd->cdb[2]; /* FIS LBA (31:24) */
14621 fis->d.lbaMidExp = 0; /* FIS LBA (39:32) */
14622 fis->d.lbaHighExp = 0; /* FIS LBA (47:40) */
14623 fis->d.featuresExp = scsiCmnd->cdb[8]; /* FIS sector count (15:8) */
14624 fis->d.sectorCount = 0; /* Tag (7:3) set by LL layer */
14625 fis->d.sectorCountExp = 0;
14626 fis->d.reserved4 = 0;
14627 fis->d.control = 0; /* FIS HOB bit clear */
14628 fis->d.reserved5 = 0;
14629
14630 agRequestType = AGSA_SATA_PROTOCOL_FPDMA_WRITE;
14631 satIOContext->ATACmd = SAT_WRITE_FPDMA_QUEUED;
14632 }
14633
14634 satIOContext->currentLBA = lba;
14635 // satIOContext->OrgLBA = lba;
14636 satIOContext->OrgTL = tl;
14637
14638 /*
14639 computing number of loop and remainder for tl
14640 0xFF in case not ext
14641 0xFFFF in case EXT
14642 */
14643 if (fis->h.command == SAT_WRITE_SECTORS || fis->h.command == SAT_WRITE_DMA)
14644 {
14645 LoopNum = satComputeLoopNum(tl, 0xFF);
14646 }
14647 else if (fis->h.command == SAT_WRITE_SECTORS_EXT ||
14648 fis->h.command == SAT_WRITE_DMA_EXT ||
14649 fis->h.command == SAT_WRITE_DMA_FUA_EXT
14650 )
14651 {
14652 /* SAT_READ_SECTORS_EXT, SAT_READ_DMA_EXT */
14653 LoopNum = satComputeLoopNum(tl, 0xFFFF);
14654 }
14655 else
14656 {
14657 /* SAT_WRITE_FPDMA_QUEUEDK */
14658 LoopNum = satComputeLoopNum(tl, 0xFFFF);
14659 }
14660
14661 satIOContext->LoopNum = LoopNum;
14662 satIOContext->LoopNum2 = LoopNum;
14663
14664
14665 if (LoopNum == 1)
14666 {
14667 TI_DBG5(("satWriteAndVerify12: NON CHAINED data\n"));
14668 /* Initialize CB for SATA completion.
14669 */
14670 satIOContext->satCompleteCB = &satNonChainedWriteNVerifyCB;
14671 }
14672 else
14673 {
14674 TI_DBG1(("satWriteAndVerify12: CHAINED data\n"));
14675 /* re-setting tl */
14676 if (fis->h.command == SAT_WRITE_SECTORS || fis->h.command == SAT_WRITE_DMA)
14677 {
14678 fis->d.sectorCount = 0xFF;
14679 }
14680 else if (fis->h.command == SAT_WRITE_SECTORS_EXT ||
14681 fis->h.command == SAT_WRITE_DMA_EXT ||
14682 fis->h.command == SAT_WRITE_DMA_FUA_EXT
14683 )
14684 {
14685 fis->d.sectorCount = 0xFF;
14686 fis->d.sectorCountExp = 0xFF;
14687 }
14688 else
14689 {
14690 /* SAT_WRITE_FPDMA_QUEUED */
14691 fis->h.features = 0xFF;
14692 fis->d.featuresExp = 0xFF;
14693 }
14694
14695 /* Initialize CB for SATA completion.
14696 */
14697 satIOContext->satCompleteCB = &satChainedWriteNVerifyCB;
14698 }
14699
14700
14701 /*
14702 * Prepare SGL and send FIS to LL layer.
14703 */
14704 satIOContext->reqType = agRequestType; /* Save it */
14705
14706 status = sataLLIOStart( tiRoot,
14707 tiIORequest,
14708 tiDeviceHandle,
14709 tiScsiRequest,
14710 satIOContext);
14711 return (status);
14712 }
14713
satNonChainedWriteNVerify_Verify(tiRoot_t * tiRoot,tiIORequest_t * tiIORequest,tiDeviceHandle_t * tiDeviceHandle,tiScsiInitiatorRequest_t * tiScsiRequest,satIOContext_t * satIOContext)14714 GLOBAL bit32 satNonChainedWriteNVerify_Verify(
14715 tiRoot_t *tiRoot,
14716 tiIORequest_t *tiIORequest,
14717 tiDeviceHandle_t *tiDeviceHandle,
14718 tiScsiInitiatorRequest_t *tiScsiRequest,
14719 satIOContext_t *satIOContext)
14720 {
14721 bit32 status;
14722 bit32 agRequestType = AGSA_SATA_PROTOCOL_DMA_WRITE;
14723 satDeviceData_t *pSatDevData;
14724 tiIniScsiCmnd_t *scsiCmnd;
14725 agsaFisRegHostToDevice_t *fis;
14726
14727 pSatDevData = satIOContext->pSatDevData;
14728 scsiCmnd = &tiScsiRequest->scsiCmnd;
14729 fis = satIOContext->pFis;
14730
14731 TI_DBG5(("satNonChainedWriteNVerify_Verify: start\n"));
14732
14733 if (pSatDevData->sat48BitSupport == agTRUE)
14734 {
14735 fis->h.fisType = 0x27; /* Reg host to device */
14736 fis->h.c_pmPort = 0x80; /* C Bit is set */
14737
14738 fis->h.command = SAT_READ_VERIFY_SECTORS_EXT;/* 0x42 */
14739 fis->h.features = 0; /* FIS reserve */
14740 fis->d.lbaLow = scsiCmnd->cdb[5]; /* FIS LBA (7 :0 ) */
14741 fis->d.lbaMid = scsiCmnd->cdb[4]; /* FIS LBA (15:8 ) */
14742 fis->d.lbaHigh = scsiCmnd->cdb[3]; /* FIS LBA (23:16) */
14743 fis->d.device = 0x40; /* FIS LBA mode set 01000000 */
14744 fis->d.lbaLowExp = scsiCmnd->cdb[2]; /* FIS LBA (31:24) */
14745 fis->d.lbaMidExp = 0; /* FIS LBA (39:32) */
14746 fis->d.lbaHighExp = 0; /* FIS LBA (47:40) */
14747 fis->d.featuresExp = 0; /* FIS reserve */
14748 fis->d.sectorCount = scsiCmnd->cdb[8]; /* FIS sector count (7:0) */
14749 fis->d.sectorCountExp = scsiCmnd->cdb[7]; /* FIS sector count (15:8) */
14750
14751 fis->d.reserved4 = 0;
14752 fis->d.control = 0; /* FIS HOB bit clear */
14753 fis->d.reserved5 = 0;
14754
14755 agRequestType = AGSA_SATA_PROTOCOL_NON_DATA;
14756
14757 /* Initialize CB for SATA completion.
14758 */
14759 satIOContext->satCompleteCB = &satNonChainedWriteNVerifyCB;
14760
14761 /*
14762 * Prepare SGL and send FIS to LL layer.
14763 */
14764 satIOContext->reqType = agRequestType; /* Save it */
14765
14766 status = sataLLIOStart( tiRoot,
14767 tiIORequest,
14768 tiDeviceHandle,
14769 tiScsiRequest,
14770 satIOContext);
14771
14772
14773 TI_DBG1(("satNonChainedWriteNVerify_Verify: return status %d\n", status));
14774 return (status);
14775 }
14776 else
14777 {
14778 /* can't fit in SAT_READ_VERIFY_SECTORS becasue of Sector Count and LBA */
14779 TI_DBG1(("satNonChainedWriteNVerify_Verify: can't fit in SAT_READ_VERIFY_SECTORS\n"));
14780 return tiError;
14781 }
14782
14783 }
14784
satChainedWriteNVerify_Write(tiRoot_t * tiRoot,tiIORequest_t * tiIORequest,tiDeviceHandle_t * tiDeviceHandle,tiScsiInitiatorRequest_t * tiScsiRequest,satIOContext_t * satIOContext)14785 GLOBAL bit32 satChainedWriteNVerify_Write(
14786 tiRoot_t *tiRoot,
14787 tiIORequest_t *tiIORequest,
14788 tiDeviceHandle_t *tiDeviceHandle,
14789 tiScsiInitiatorRequest_t *tiScsiRequest,
14790 satIOContext_t *satIOContext)
14791 {
14792 /*
14793 Assumption: error check on lba and tl has been done in satWrite*()
14794 lba = lba + tl;
14795 */
14796 bit32 status;
14797 satIOContext_t *satOrgIOContext = agNULL;
14798 tiIniScsiCmnd_t *scsiCmnd;
14799 agsaFisRegHostToDevice_t *fis;
14800 bit32 agRequestType = AGSA_SATA_PROTOCOL_DMA_WRITE;
14801 bit32 lba = 0;
14802 bit32 DenomTL = 0xFF;
14803 bit32 Remainder = 0;
14804 bit8 LBA[4]; /* 0 MSB, 3 LSB */
14805
14806 TI_DBG1(("satChainedWriteNVerify_Write: start\n"));
14807
14808 fis = satIOContext->pFis;
14809 satOrgIOContext = satIOContext->satOrgIOContext;
14810 scsiCmnd = satOrgIOContext->pScsiCmnd;
14811
14812 osti_memset(LBA,0, sizeof(LBA));
14813
14814 switch (satOrgIOContext->ATACmd)
14815 {
14816 case SAT_WRITE_DMA:
14817 DenomTL = 0xFF;
14818 break;
14819 case SAT_WRITE_SECTORS:
14820 DenomTL = 0xFF;
14821 break;
14822 case SAT_WRITE_DMA_EXT:
14823 DenomTL = 0xFFFF;
14824 break;
14825 case SAT_WRITE_DMA_FUA_EXT:
14826 DenomTL = 0xFFFF;
14827 break;
14828 case SAT_WRITE_SECTORS_EXT:
14829 DenomTL = 0xFFFF;
14830 break;
14831 case SAT_WRITE_FPDMA_QUEUED:
14832 DenomTL = 0xFFFF;
14833 break;
14834 default:
14835 TI_DBG1(("satChainedWriteNVerify_Write: error incorrect ata command 0x%x\n", satIOContext->ATACmd));
14836 return tiError;
14837 break;
14838 }
14839
14840 Remainder = satOrgIOContext->OrgTL % DenomTL;
14841 satOrgIOContext->currentLBA = satOrgIOContext->currentLBA + DenomTL;
14842 lba = satOrgIOContext->currentLBA;
14843
14844 LBA[0] = (bit8)((lba & 0xF000) >> (8 * 3)); /* MSB */
14845 LBA[1] = (bit8)((lba & 0xF00) >> (8 * 2));
14846 LBA[2] = (bit8)((lba & 0xF0) >> 8);
14847 LBA[3] = (bit8)(lba & 0xF); /* LSB */
14848
14849 switch (satOrgIOContext->ATACmd)
14850 {
14851 case SAT_WRITE_DMA:
14852 fis->h.fisType = 0x27; /* Reg host to device */
14853 fis->h.c_pmPort = 0x80; /* C bit is set */
14854 fis->h.command = SAT_WRITE_DMA; /* 0xCA */
14855 fis->h.features = 0; /* FIS reserve */
14856 fis->d.lbaLow = LBA[3]; /* FIS LBA (7 :0 ) */
14857 fis->d.lbaMid = LBA[2]; /* FIS LBA (15:8 ) */
14858 fis->d.lbaHigh = LBA[1]; /* FIS LBA (23:16) */
14859
14860 /* FIS LBA mode set LBA (27:24) */
14861 fis->d.device = (bit8)((0x4 << 4) | (LBA[0] & 0xF));
14862
14863 fis->d.lbaLowExp = 0;
14864 fis->d.lbaMidExp = 0;
14865 fis->d.lbaHighExp = 0;
14866 fis->d.featuresExp = 0;
14867 if (satOrgIOContext->LoopNum == 1)
14868 {
14869 /* last loop */
14870 fis->d.sectorCount = (bit8)Remainder; /* FIS sector count (7:0) */
14871 }
14872 else
14873 {
14874 fis->d.sectorCount = 0xFF; /* FIS sector count (7:0) */
14875 }
14876 fis->d.sectorCountExp = 0;
14877 fis->d.reserved4 = 0;
14878 fis->d.control = 0; /* FIS HOB bit clear */
14879 fis->d.reserved5 = 0;
14880
14881 agRequestType = AGSA_SATA_PROTOCOL_DMA_WRITE;
14882
14883 break;
14884 case SAT_WRITE_SECTORS:
14885 fis->h.fisType = 0x27; /* Reg host to device */
14886 fis->h.c_pmPort = 0x80; /* C bit is set */
14887 fis->h.command = SAT_WRITE_SECTORS; /* 0x30 */
14888 fis->h.features = 0; /* FIS reserve */
14889 fis->d.lbaLow = LBA[3]; /* FIS LBA (7 :0 ) */
14890 fis->d.lbaMid = LBA[2]; /* FIS LBA (15:8 ) */
14891 fis->d.lbaHigh = LBA[1]; /* FIS LBA (23:16) */
14892
14893 /* FIS LBA mode set LBA (27:24) */
14894 fis->d.device = (bit8)((0x4 << 4) | (LBA[0] & 0xF));
14895
14896 fis->d.lbaLowExp = 0;
14897 fis->d.lbaMidExp = 0;
14898 fis->d.lbaHighExp = 0;
14899 fis->d.featuresExp = 0;
14900 if (satOrgIOContext->LoopNum == 1)
14901 {
14902 /* last loop */
14903 fis->d.sectorCount = (bit8)Remainder; /* FIS sector count (7:0) */
14904 }
14905 else
14906 {
14907 fis->d.sectorCount = 0xFF; /* FIS sector count (7:0) */
14908 }
14909 fis->d.sectorCountExp = 0;
14910 fis->d.reserved4 = 0;
14911 fis->d.control = 0; /* FIS HOB bit clear */
14912 fis->d.reserved5 = 0;
14913
14914 agRequestType = AGSA_SATA_PROTOCOL_PIO_WRITE;
14915
14916 break;
14917 case SAT_WRITE_DMA_EXT:
14918 fis->h.fisType = 0x27; /* Reg host to device */
14919 fis->h.c_pmPort = 0x80; /* C Bit is set */
14920 fis->h.command = SAT_WRITE_DMA_EXT; /* 0x3D */
14921 fis->h.features = 0; /* FIS reserve */
14922 fis->d.lbaLow = LBA[3]; /* FIS LBA (7 :0 ) */
14923 fis->d.lbaMid = LBA[2]; /* FIS LBA (15:8 ) */
14924 fis->d.lbaHigh = LBA[1]; /* FIS LBA (23:16) */
14925 fis->d.device = 0x40; /* FIS LBA mode set */
14926 fis->d.lbaLowExp = LBA[0]; /* FIS LBA (31:24) */
14927 fis->d.lbaMidExp = 0; /* FIS LBA (39:32) */
14928 fis->d.lbaHighExp = 0; /* FIS LBA (47:40) */
14929 fis->d.featuresExp = 0; /* FIS reserve */
14930 if (satOrgIOContext->LoopNum == 1)
14931 {
14932 /* last loop */
14933 fis->d.sectorCount = (bit8)(Remainder & 0xFF); /* FIS sector count (7:0) */
14934 fis->d.sectorCountExp = (bit8)((Remainder & 0xFF00) >> 8); /* FIS sector count (15:8) */
14935 }
14936 else
14937 {
14938 fis->d.sectorCount = 0xFF; /* FIS sector count (7:0) */
14939 fis->d.sectorCountExp = 0xFF; /* FIS sector count (15:8) */
14940 }
14941 fis->d.reserved4 = 0;
14942 fis->d.control = 0; /* FIS HOB bit clear */
14943 fis->d.reserved5 = 0;
14944
14945 agRequestType = AGSA_SATA_PROTOCOL_DMA_WRITE;
14946
14947 break;
14948 case SAT_WRITE_SECTORS_EXT:
14949 fis->h.fisType = 0x27; /* Reg host to device */
14950 fis->h.c_pmPort = 0x80; /* C Bit is set */
14951 fis->h.command = SAT_WRITE_SECTORS_EXT; /* 0x34 */
14952
14953 fis->h.features = 0; /* FIS reserve */
14954 fis->d.lbaLow = LBA[3]; /* FIS LBA (7 :0 ) */
14955 fis->d.lbaMid = LBA[2]; /* FIS LBA (15:8 ) */
14956 fis->d.lbaHigh = LBA[1]; /* FIS LBA (23:16) */
14957 fis->d.device = 0x40; /* FIS LBA mode set */
14958 fis->d.lbaLowExp = LBA[0]; /* FIS LBA (31:24) */
14959 fis->d.lbaMidExp = 0; /* FIS LBA (39:32) */
14960 fis->d.lbaHighExp = 0; /* FIS LBA (47:40) */
14961 fis->d.featuresExp = 0; /* FIS reserve */
14962 if (satOrgIOContext->LoopNum == 1)
14963 {
14964 /* last loop */
14965 fis->d.sectorCount = (bit8)(Remainder & 0xFF); /* FIS sector count (7:0) */
14966 fis->d.sectorCountExp = (bit8)((Remainder & 0xFF00) >> 8); /* FIS sector count (15:8) */
14967 }
14968 else
14969 {
14970 fis->d.sectorCount = 0xFF; /* FIS sector count (7:0) */
14971 fis->d.sectorCountExp = 0xFF; /* FIS sector count (15:8) */
14972 }
14973 fis->d.reserved4 = 0;
14974 fis->d.control = 0; /* FIS HOB bit clear */
14975 fis->d.reserved5 = 0;
14976
14977 agRequestType = AGSA_SATA_PROTOCOL_PIO_WRITE;
14978
14979 break;
14980 case SAT_WRITE_FPDMA_QUEUED:
14981 fis->h.fisType = 0x27; /* Reg host to device */
14982 fis->h.c_pmPort = 0x80; /* C Bit is set */
14983 fis->h.command = SAT_WRITE_FPDMA_QUEUED; /* 0x61 */
14984 fis->d.lbaLow = LBA[3]; /* FIS LBA (7 :0 ) */
14985 fis->d.lbaMid = LBA[2]; /* FIS LBA (15:8 ) */
14986 fis->d.lbaHigh = LBA[1]; /* FIS LBA (23:16) */
14987
14988 /* Check FUA bit */
14989 if (scsiCmnd->cdb[1] & SCSI_WRITE10_FUA_MASK)
14990 fis->d.device = 0xC0; /* FIS FUA set */
14991 else
14992 fis->d.device = 0x40; /* FIS FUA clear */
14993
14994 fis->d.lbaLowExp = LBA[0];; /* FIS LBA (31:24) */
14995 fis->d.lbaMidExp = 0; /* FIS LBA (39:32) */
14996 fis->d.lbaHighExp = 0; /* FIS LBA (47:40) */
14997 if (satOrgIOContext->LoopNum == 1)
14998 {
14999 /* last loop */
15000 fis->h.features = (bit8)(Remainder & 0xFF); /* FIS sector count (7:0) */
15001 fis->d.featuresExp = (bit8)((Remainder & 0xFF00) >> 8); /* FIS sector count (15:8) */
15002 }
15003 else
15004 {
15005 fis->h.features = 0xFF; /* FIS sector count (7:0) */
15006 fis->d.featuresExp = 0xFF; /* FIS sector count (15:8) */
15007 }
15008 fis->d.sectorCount = 0; /* Tag (7:3) set by LL layer */
15009 fis->d.sectorCountExp = 0;
15010 fis->d.reserved4 = 0;
15011 fis->d.control = 0; /* FIS HOB bit clear */
15012 fis->d.reserved5 = 0;
15013
15014 agRequestType = AGSA_SATA_PROTOCOL_FPDMA_WRITE;
15015 break;
15016
15017 default:
15018 TI_DBG1(("satChainedWriteNVerify_Write: error incorrect ata command 0x%x\n", satIOContext->ATACmd));
15019 return tiError;
15020 break;
15021 }
15022
15023 /* Initialize CB for SATA completion.
15024 */
15025 /* chained data */
15026 satIOContext->satCompleteCB = &satChainedWriteNVerifyCB;
15027
15028
15029 /*
15030 * Prepare SGL and send FIS to LL layer.
15031 */
15032 satIOContext->reqType = agRequestType; /* Save it */
15033
15034 status = sataLLIOStart( tiRoot,
15035 tiIORequest,
15036 tiDeviceHandle,
15037 tiScsiRequest,
15038 satIOContext);
15039
15040 TI_DBG5(("satChainedWriteNVerify_Write: return\n"));
15041 return (status);
15042
15043 }
15044
15045 /*
15046 similar to write12 and verify10;
15047 this will be similar to verify12
15048 */
satChainedWriteNVerify_Start_Verify(tiRoot_t * tiRoot,tiIORequest_t * tiIORequest,tiDeviceHandle_t * tiDeviceHandle,tiScsiInitiatorRequest_t * tiScsiRequest,satIOContext_t * satIOContext)15049 GLOBAL bit32 satChainedWriteNVerify_Start_Verify(
15050 tiRoot_t *tiRoot,
15051 tiIORequest_t *tiIORequest,
15052 tiDeviceHandle_t *tiDeviceHandle,
15053 tiScsiInitiatorRequest_t *tiScsiRequest,
15054 satIOContext_t *satIOContext)
15055 {
15056 /*
15057 deal with transfer length; others have been handled previously at this point;
15058 no LBA check; no range check;
15059 */
15060 bit32 status;
15061 bit32 agRequestType = AGSA_SATA_PROTOCOL_NON_DATA;
15062 satDeviceData_t *pSatDevData;
15063 tiIniScsiCmnd_t *scsiCmnd;
15064 agsaFisRegHostToDevice_t *fis;
15065 bit32 lba = 0;
15066 bit32 tl = 0;
15067 bit32 LoopNum = 1;
15068 bit8 LBA[4];
15069 bit8 TL[4];
15070
15071 pSatDevData = satIOContext->pSatDevData;
15072 scsiCmnd = &tiScsiRequest->scsiCmnd;
15073 fis = satIOContext->pFis;
15074
15075 TI_DBG5(("satChainedWriteNVerify_Start_Verify: start\n"));
15076
15077 osti_memset(LBA, 0, sizeof(LBA));
15078 osti_memset(TL, 0, sizeof(TL));
15079
15080 /* do not use memcpy due to indexing in LBA and TL */
15081 LBA[0] = scsiCmnd->cdb[2]; /* MSB */
15082 LBA[1] = scsiCmnd->cdb[3];
15083 LBA[2] = scsiCmnd->cdb[4];
15084 LBA[3] = scsiCmnd->cdb[5]; /* LSB */
15085
15086 TL[0] = scsiCmnd->cdb[6]; /* MSB */
15087 TL[1] = scsiCmnd->cdb[7];
15088 TL[2] = scsiCmnd->cdb[7];
15089 TL[3] = scsiCmnd->cdb[8]; /* LSB */
15090
15091 lba = satComputeCDB12LBA(satIOContext);
15092 tl = satComputeCDB12TL(satIOContext);
15093
15094 if (pSatDevData->sat48BitSupport == agTRUE)
15095 {
15096 TI_DBG5(("satChainedWriteNVerify_Start_Verify: SAT_READ_VERIFY_SECTORS_EXT\n"));
15097 fis->h.fisType = 0x27; /* Reg host to device */
15098 fis->h.c_pmPort = 0x80; /* C Bit is set */
15099
15100 fis->h.command = SAT_READ_VERIFY_SECTORS_EXT;/* 0x42 */
15101 fis->h.features = 0; /* FIS reserve */
15102 fis->d.lbaLow = scsiCmnd->cdb[5]; /* FIS LBA (7 :0 ) */
15103 fis->d.lbaMid = scsiCmnd->cdb[4]; /* FIS LBA (15:8 ) */
15104 fis->d.lbaHigh = scsiCmnd->cdb[3]; /* FIS LBA (23:16) */
15105 fis->d.device = 0x40; /* FIS LBA mode set 01000000 */
15106 fis->d.lbaLowExp = scsiCmnd->cdb[2]; /* FIS LBA (31:24) */
15107 fis->d.lbaMidExp = 0; /* FIS LBA (39:32) */
15108 fis->d.lbaHighExp = 0; /* FIS LBA (47:40) */
15109 fis->d.featuresExp = 0; /* FIS reserve */
15110 fis->d.sectorCount = scsiCmnd->cdb[8]; /* FIS sector count (7:0) */
15111 fis->d.sectorCountExp = scsiCmnd->cdb[7]; /* FIS sector count (15:8) */
15112
15113 fis->d.reserved4 = 0;
15114 fis->d.control = 0; /* FIS HOB bit clear */
15115 fis->d.reserved5 = 0;
15116
15117 agRequestType = AGSA_SATA_PROTOCOL_NON_DATA;
15118 satIOContext->ATACmd = SAT_READ_VERIFY_SECTORS_EXT;
15119 }
15120 else
15121 {
15122 TI_DBG5(("satChainedWriteNVerify_Start_Verify: SAT_READ_VERIFY_SECTORS\n"));
15123 fis->h.fisType = 0x27; /* Reg host to device */
15124 fis->h.c_pmPort = 0x80; /* C bit is set */
15125 fis->h.command = SAT_READ_VERIFY_SECTORS; /* 0x40 */
15126 fis->h.features = 0; /* FIS reserve */
15127 fis->d.lbaLow = scsiCmnd->cdb[5]; /* FIS LBA (7 :0 ) */
15128 fis->d.lbaMid = scsiCmnd->cdb[4]; /* FIS LBA (15:8 ) */
15129 fis->d.lbaHigh = scsiCmnd->cdb[3]; /* FIS LBA (23:16) */
15130 /* FIS LBA mode set LBA (27:24) */
15131 fis->d.device = (bit8)((0x4 << 4) | (scsiCmnd->cdb[2] & 0xF));
15132 fis->d.lbaLowExp = 0;
15133 fis->d.lbaMidExp = 0;
15134 fis->d.lbaHighExp = 0;
15135 fis->d.featuresExp = 0;
15136 fis->d.sectorCount = scsiCmnd->cdb[8]; /* FIS sector count (7:0) */
15137 fis->d.sectorCountExp = 0;
15138 fis->d.reserved4 = 0;
15139 fis->d.control = 0; /* FIS HOB bit clear */
15140 fis->d.reserved5 = 0;
15141
15142 agRequestType = AGSA_SATA_PROTOCOL_NON_DATA;
15143 satIOContext->ATACmd = SAT_READ_VERIFY_SECTORS;
15144
15145 }
15146
15147 satIOContext->currentLBA = lba;
15148 satIOContext->OrgTL = tl;
15149
15150 /*
15151 computing number of loop and remainder for tl
15152 0xFF in case not ext
15153 0xFFFF in case EXT
15154 */
15155 if (fis->h.command == SAT_READ_VERIFY_SECTORS)
15156 {
15157 LoopNum = satComputeLoopNum(tl, 0xFF);
15158 }
15159 else if (fis->h.command == SAT_READ_VERIFY_SECTORS_EXT)
15160 {
15161 /* SAT_READ_SECTORS_EXT, SAT_READ_DMA_EXT */
15162 LoopNum = satComputeLoopNum(tl, 0xFFFF);
15163 }
15164 else
15165 {
15166 TI_DBG1(("satChainedWriteNVerify_Start_Verify: error case 1!!!\n"));
15167 LoopNum = 1;
15168 }
15169
15170 satIOContext->LoopNum = LoopNum;
15171
15172 if (LoopNum == 1)
15173 {
15174 TI_DBG5(("satChainedWriteNVerify_Start_Verify: NON CHAINED data\n"));
15175 /* Initialize CB for SATA completion.
15176 */
15177 satIOContext->satCompleteCB = &satNonChainedWriteNVerifyCB;
15178 }
15179 else
15180 {
15181 TI_DBG1(("satChainedWriteNVerify_Start_Verify: CHAINED data\n"));
15182 /* re-setting tl */
15183 if (fis->h.command == SAT_READ_VERIFY_SECTORS)
15184 {
15185 fis->d.sectorCount = 0xFF;
15186 }
15187 else if (fis->h.command == SAT_READ_VERIFY_SECTORS_EXT)
15188 {
15189 fis->d.sectorCount = 0xFF;
15190 fis->d.sectorCountExp = 0xFF;
15191 }
15192 else
15193 {
15194 TI_DBG1(("satChainedWriteNVerify_Start_Verify: error case 2!!!\n"));
15195 }
15196
15197 /* Initialize CB for SATA completion.
15198 */
15199 satIOContext->satCompleteCB = &satChainedWriteNVerifyCB;
15200 }
15201
15202
15203 /*
15204 * Prepare SGL and send FIS to LL layer.
15205 */
15206 satIOContext->reqType = agRequestType; /* Save it */
15207
15208 status = sataLLIOStart( tiRoot,
15209 tiIORequest,
15210 tiDeviceHandle,
15211 tiScsiRequest,
15212 satIOContext);
15213 return (status);
15214 }
15215
satChainedWriteNVerify_Verify(tiRoot_t * tiRoot,tiIORequest_t * tiIORequest,tiDeviceHandle_t * tiDeviceHandle,tiScsiInitiatorRequest_t * tiScsiRequest,satIOContext_t * satIOContext)15216 GLOBAL bit32 satChainedWriteNVerify_Verify(
15217 tiRoot_t *tiRoot,
15218 tiIORequest_t *tiIORequest,
15219 tiDeviceHandle_t *tiDeviceHandle,
15220 tiScsiInitiatorRequest_t *tiScsiRequest,
15221 satIOContext_t *satIOContext)
15222 {
15223 bit32 status;
15224 satIOContext_t *satOrgIOContext = agNULL;
15225 agsaFisRegHostToDevice_t *fis;
15226 bit32 agRequestType = AGSA_SATA_PROTOCOL_NON_DATA;
15227 bit32 lba = 0;
15228 bit32 DenomTL = 0xFF;
15229 bit32 Remainder = 0;
15230 bit8 LBA[4]; /* 0 MSB, 3 LSB */
15231
15232 TI_DBG2(("satChainedWriteNVerify_Verify: start\n"));
15233
15234 fis = satIOContext->pFis;
15235 satOrgIOContext = satIOContext->satOrgIOContext;
15236
15237 osti_memset(LBA,0, sizeof(LBA));
15238
15239 switch (satOrgIOContext->ATACmd)
15240 {
15241 case SAT_READ_VERIFY_SECTORS:
15242 DenomTL = 0xFF;
15243 break;
15244 case SAT_READ_VERIFY_SECTORS_EXT:
15245 DenomTL = 0xFFFF;
15246 break;
15247 default:
15248 TI_DBG1(("satChainedWriteNVerify_Verify: error incorrect ata command 0x%x\n", satIOContext->ATACmd));
15249 return tiError;
15250 break;
15251 }
15252
15253 Remainder = satOrgIOContext->OrgTL % DenomTL;
15254 satOrgIOContext->currentLBA = satOrgIOContext->currentLBA + DenomTL;
15255 lba = satOrgIOContext->currentLBA;
15256
15257 LBA[0] = (bit8)((lba & 0xF000) >> (8 * 3)); /* MSB */
15258 LBA[1] = (bit8)((lba & 0xF00) >> (8 * 2));
15259 LBA[2] = (bit8)((lba & 0xF0) >> 8);
15260 LBA[3] = (bit8)(lba & 0xF); /* LSB */
15261
15262 switch (satOrgIOContext->ATACmd)
15263 {
15264 case SAT_READ_VERIFY_SECTORS:
15265 fis->h.fisType = 0x27; /* Reg host to device */
15266 fis->h.c_pmPort = 0x80; /* C bit is set */
15267 fis->h.command = SAT_READ_VERIFY_SECTORS; /* 0x40 */
15268 fis->h.features = 0; /* FIS reserve */
15269 fis->d.lbaLow = LBA[3]; /* FIS LBA (7 :0 ) */
15270 fis->d.lbaMid = LBA[2]; /* FIS LBA (15:8 ) */
15271 fis->d.lbaHigh = LBA[1]; /* FIS LBA (23:16) */
15272
15273 /* FIS LBA mode set LBA (27:24) */
15274 fis->d.device = (bit8)((0x4 << 4) | (LBA[0] & 0xF));
15275
15276 fis->d.lbaLowExp = 0;
15277 fis->d.lbaMidExp = 0;
15278 fis->d.lbaHighExp = 0;
15279 fis->d.featuresExp = 0;
15280 if (satOrgIOContext->LoopNum == 1)
15281 {
15282 /* last loop */
15283 fis->d.sectorCount = (bit8)Remainder; /* FIS sector count (7:0) */
15284 }
15285 else
15286 {
15287 fis->d.sectorCount = 0xFF; /* FIS sector count (7:0) */
15288 }
15289 fis->d.sectorCountExp = 0;
15290 fis->d.reserved4 = 0;
15291 fis->d.control = 0; /* FIS HOB bit clear */
15292 fis->d.reserved5 = 0;
15293
15294 agRequestType = AGSA_SATA_PROTOCOL_NON_DATA;
15295
15296 break;
15297 case SAT_READ_VERIFY_SECTORS_EXT:
15298 fis->h.fisType = 0x27; /* Reg host to device */
15299 fis->h.c_pmPort = 0x80; /* C Bit is set */
15300 fis->h.command = SAT_READ_VERIFY_SECTORS_EXT; /* 0x42 */
15301 fis->h.features = 0; /* FIS reserve */
15302 fis->d.lbaLow = LBA[3]; /* FIS LBA (7 :0 ) */
15303 fis->d.lbaMid = LBA[2]; /* FIS LBA (15:8 ) */
15304 fis->d.lbaHigh = LBA[1]; /* FIS LBA (23:16) */
15305 fis->d.device = 0x40; /* FIS LBA mode set */
15306 fis->d.lbaLowExp = LBA[0]; /* FIS LBA (31:24) */
15307 fis->d.lbaMidExp = 0; /* FIS LBA (39:32) */
15308 fis->d.lbaHighExp = 0; /* FIS LBA (47:40) */
15309 fis->d.featuresExp = 0; /* FIS reserve */
15310 if (satOrgIOContext->LoopNum == 1)
15311 {
15312 /* last loop */
15313 fis->d.sectorCount = (bit8)(Remainder & 0xFF); /* FIS sector count (7:0) */
15314 fis->d.sectorCountExp = (bit8)((Remainder & 0xFF00) >> 8); /* FIS sector count (15:8) */
15315 }
15316 else
15317 {
15318 fis->d.sectorCount = 0xFF; /* FIS sector count (7:0) */
15319 fis->d.sectorCountExp = 0xFF; /* FIS sector count (15:8) */
15320 }
15321 fis->d.reserved4 = 0;
15322 fis->d.control = 0; /* FIS HOB bit clear */
15323 fis->d.reserved5 = 0;
15324
15325 agRequestType = AGSA_SATA_PROTOCOL_NON_DATA;
15326
15327 break;
15328
15329 default:
15330 TI_DBG1(("satChainedWriteNVerify_Verify: error incorrect ata command 0x%x\n", satIOContext->ATACmd));
15331 return tiError;
15332 break;
15333 }
15334
15335 /* Initialize CB for SATA completion.
15336 */
15337 /* chained data */
15338 satIOContext->satCompleteCB = &satChainedWriteNVerifyCB;
15339
15340
15341 /*
15342 * Prepare SGL and send FIS to LL layer.
15343 */
15344 satIOContext->reqType = agRequestType; /* Save it */
15345
15346 status = sataLLIOStart( tiRoot,
15347 tiIORequest,
15348 tiDeviceHandle,
15349 tiScsiRequest,
15350 satIOContext);
15351
15352 TI_DBG5(("satChainedWriteNVerify_Verify: return\n"));
15353 return (status);
15354
15355 }
15356
15357
15358 /*****************************************************************************/
15359 /*! \brief SAT implementation for SCSI satWriteAndVerify16.
15360 *
15361 * SAT implementation for SCSI satWriteAndVerify16.
15362 *
15363 * \param tiRoot: Pointer to TISA initiator driver/port instance.
15364 * \param tiIORequest: Pointer to TISA I/O request context for this I/O.
15365 * \param tiDeviceHandle: Pointer to TISA device handle for this I/O.
15366 * \param tiScsiRequest: Pointer to TISA SCSI I/O request and SGL list.
15367 * \param satIOContext_t: Pointer to the SAT IO Context
15368 *
15369 * \return If command is started successfully
15370 * - \e tiSuccess: I/O request successfully initiated.
15371 * - \e tiBusy: No resources available, try again later.
15372 * - \e tiIONoDevice: Invalid device handle.
15373 * - \e tiError: Other errors.
15374 */
15375 /*****************************************************************************/
satWriteAndVerify16(tiRoot_t * tiRoot,tiIORequest_t * tiIORequest,tiDeviceHandle_t * tiDeviceHandle,tiScsiInitiatorRequest_t * tiScsiRequest,satIOContext_t * satIOContext)15376 GLOBAL bit32 satWriteAndVerify16(
15377 tiRoot_t *tiRoot,
15378 tiIORequest_t *tiIORequest,
15379 tiDeviceHandle_t *tiDeviceHandle,
15380 tiScsiInitiatorRequest_t *tiScsiRequest,
15381 satIOContext_t *satIOContext)
15382 {
15383 /*
15384 combination of write16 and verify16
15385 since write16 has 8 bytes LBA -> problem ATA LBA(upto 6 bytes), no support
15386 */
15387 bit32 status;
15388 bit32 agRequestType = AGSA_SATA_PROTOCOL_DMA_WRITE;
15389 satDeviceData_t *pSatDevData;
15390 scsiRspSense_t *pSense;
15391 tiIniScsiCmnd_t *scsiCmnd;
15392 agsaFisRegHostToDevice_t *fis;
15393 bit32 lba = 0;
15394 bit32 tl = 0;
15395 bit32 LoopNum = 1;
15396 bit8 LBA[8];
15397 bit8 TL[8];
15398 bit32 rangeChk = agFALSE; /* lba and tl range check */
15399 bit32 limitChk = agFALSE; /* lba and tl range check */
15400
15401 pSense = satIOContext->pSense;
15402 pSatDevData = satIOContext->pSatDevData;
15403 scsiCmnd = &tiScsiRequest->scsiCmnd;
15404 fis = satIOContext->pFis;
15405 TI_DBG5(("satWriteAndVerify16:start\n"));
15406
15407 /* checking BYTCHK bit */
15408 if (scsiCmnd->cdb[1] & SCSI_WRITE_N_VERIFY_BYTCHK_MASK)
15409 {
15410 satSetSensePayload( pSense,
15411 SCSI_SNSKEY_ILLEGAL_REQUEST,
15412 0,
15413 SCSI_SNSCODE_INVALID_FIELD_IN_CDB,
15414 satIOContext);
15415
15416 ostiInitiatorIOCompleted( tiRoot,
15417 tiIORequest,
15418 tiIOSuccess,
15419 SCSI_STAT_CHECK_CONDITION,
15420 satIOContext->pTiSenseData,
15421 satIOContext->interruptContext );
15422
15423 TI_DBG1(("satWriteAndVerify16: BYTCHK bit checking \n"));
15424 return tiSuccess;
15425 }
15426
15427
15428 /* checking CONTROL */
15429 /* NACA == 1 or LINK == 1*/
15430 if ( (scsiCmnd->cdb[15] & SCSI_NACA_MASK) || (scsiCmnd->cdb[15] & SCSI_LINK_MASK) )
15431 {
15432 satSetSensePayload( pSense,
15433 SCSI_SNSKEY_ILLEGAL_REQUEST,
15434 0,
15435 SCSI_SNSCODE_INVALID_FIELD_IN_CDB,
15436 satIOContext);
15437
15438 ostiInitiatorIOCompleted( tiRoot,
15439 tiIORequest,
15440 tiIOSuccess,
15441 SCSI_STAT_CHECK_CONDITION,
15442 satIOContext->pTiSenseData,
15443 satIOContext->interruptContext );
15444
15445 TI_DBG2(("satWriteAndVerify16: return control\n"));
15446 return tiSuccess;
15447 }
15448
15449 osti_memset(LBA, 0, sizeof(LBA));
15450 osti_memset(TL, 0, sizeof(TL));
15451
15452
15453 /* do not use memcpy due to indexing in LBA and TL */
15454 LBA[0] = scsiCmnd->cdb[2]; /* MSB */
15455 LBA[1] = scsiCmnd->cdb[3];
15456 LBA[2] = scsiCmnd->cdb[4];
15457 LBA[3] = scsiCmnd->cdb[5];
15458 LBA[4] = scsiCmnd->cdb[6];
15459 LBA[5] = scsiCmnd->cdb[7];
15460 LBA[6] = scsiCmnd->cdb[8];
15461 LBA[7] = scsiCmnd->cdb[9]; /* LSB */
15462
15463 TL[0] = 0;
15464 TL[1] = 0;
15465 TL[2] = 0;
15466 TL[3] = 0;
15467 TL[4] = scsiCmnd->cdb[10]; /* MSB */
15468 TL[5] = scsiCmnd->cdb[11];
15469 TL[6] = scsiCmnd->cdb[12];
15470 TL[7] = scsiCmnd->cdb[13]; /* LSB */
15471
15472 rangeChk = satAddNComparebit64(LBA, TL);
15473
15474 limitChk = satCompareLBALimitbit(LBA);
15475
15476 lba = satComputeCDB16LBA(satIOContext);
15477 tl = satComputeCDB16TL(satIOContext);
15478
15479
15480 /* Table 34, 9.1, p 46 */
15481 /*
15482 note: As of 2/10/2006, no support for DMA QUEUED
15483 */
15484
15485 /*
15486 Table 34, 9.1, p 46, b
15487 When no 48-bit addressing support or NCQ, if LBA is beyond (2^28 - 1),
15488 return check condition
15489 */
15490 if (pSatDevData->satNCQ != agTRUE &&
15491 pSatDevData->sat48BitSupport != agTRUE
15492 )
15493 {
15494 if (limitChk)
15495 {
15496 TI_DBG1(("satWriteAndVerify16: return LBA out of range, not EXT\n"));
15497 satSetSensePayload( pSense,
15498 SCSI_SNSKEY_ILLEGAL_REQUEST,
15499 0,
15500 SCSI_SNSCODE_LOGICAL_BLOCK_ADDRESS_OUT_OF_RANGE,
15501 satIOContext);
15502
15503 ostiInitiatorIOCompleted( tiRoot,
15504 tiIORequest,
15505 tiIOSuccess,
15506 SCSI_STAT_CHECK_CONDITION,
15507 satIOContext->pTiSenseData,
15508 satIOContext->interruptContext );
15509
15510 return tiSuccess;
15511 }
15512 if (rangeChk) // if (lba + tl > SAT_TR_LBA_LIMIT)
15513 {
15514 TI_DBG1(("satWriteAndVerify16: return LBA+TL out of range, not EXT\n"));
15515 satSetSensePayload( pSense,
15516 SCSI_SNSKEY_ILLEGAL_REQUEST,
15517 0,
15518 SCSI_SNSCODE_LOGICAL_BLOCK_ADDRESS_OUT_OF_RANGE,
15519 satIOContext);
15520
15521 ostiInitiatorIOCompleted( tiRoot,
15522 tiIORequest,
15523 tiIOSuccess,
15524 SCSI_STAT_CHECK_CONDITION,
15525 satIOContext->pTiSenseData,
15526 satIOContext->interruptContext );
15527
15528 return tiSuccess;
15529 }
15530 }
15531
15532
15533 /* case 1 and 2 */
15534 if (!rangeChk) // if (lba + tl <= SAT_TR_LBA_LIMIT)
15535 {
15536 if (pSatDevData->satDMASupport == agTRUE && pSatDevData->satDMAEnabled == agTRUE)
15537 {
15538 /* case 2 */
15539 /* WRITE DMA*/
15540 /* In case that we can't fit the transfer length, we loop */
15541 TI_DBG5(("satWriteAndVerify16: case 2\n"));
15542 fis->h.fisType = 0x27; /* Reg host to device */
15543 fis->h.c_pmPort = 0x80; /* C bit is set */
15544 fis->h.command = SAT_WRITE_DMA; /* 0xCA */
15545 fis->h.features = 0; /* FIS reserve */
15546 fis->d.lbaLow = scsiCmnd->cdb[9]; /* FIS LBA (7 :0 ) */
15547 fis->d.lbaMid = scsiCmnd->cdb[8]; /* FIS LBA (15:8 ) */
15548 fis->d.lbaHigh = scsiCmnd->cdb[7]; /* FIS LBA (23:16) */
15549
15550 /* FIS LBA mode set LBA (27:24) */
15551 fis->d.device = (bit8)((0x4 << 4) | (scsiCmnd->cdb[6] & 0xF));
15552
15553 fis->d.lbaLowExp = 0;
15554 fis->d.lbaMidExp = 0;
15555 fis->d.lbaHighExp = 0;
15556 fis->d.featuresExp = 0;
15557 fis->d.sectorCount = scsiCmnd->cdb[13]; /* FIS sector count (7:0) */
15558 fis->d.sectorCountExp = 0;
15559 fis->d.reserved4 = 0;
15560 fis->d.control = 0; /* FIS HOB bit clear */
15561 fis->d.reserved5 = 0;
15562
15563 agRequestType = AGSA_SATA_PROTOCOL_DMA_WRITE;
15564 satIOContext->ATACmd = SAT_WRITE_DMA;
15565 }
15566 else
15567 {
15568 /* case 1 */
15569 /* WRITE MULTIPLE or WRITE SECTOR(S) */
15570 /* WRITE SECTORS for easier implemetation */
15571 /* In case that we can't fit the transfer length, we loop */
15572 TI_DBG5(("satWriteAndVerify16: case 1\n"));
15573 fis->h.fisType = 0x27; /* Reg host to device */
15574 fis->h.c_pmPort = 0x80; /* C bit is set */
15575 fis->h.command = SAT_WRITE_SECTORS; /* 0x30 */
15576 fis->h.features = 0; /* FIS reserve */
15577 fis->d.lbaLow = scsiCmnd->cdb[9]; /* FIS LBA (7 :0 ) */
15578 fis->d.lbaMid = scsiCmnd->cdb[8]; /* FIS LBA (15:8 ) */
15579 fis->d.lbaHigh = scsiCmnd->cdb[7]; /* FIS LBA (23:16) */
15580
15581 /* FIS LBA mode set LBA (27:24) */
15582 fis->d.device = (bit8)((0x4 << 4) | (scsiCmnd->cdb[6] & 0xF));
15583
15584 fis->d.lbaLowExp = 0;
15585 fis->d.lbaMidExp = 0;
15586 fis->d.lbaHighExp = 0;
15587 fis->d.featuresExp = 0;
15588 fis->d.sectorCount = scsiCmnd->cdb[13]; /* FIS sector count (7:0) */
15589 fis->d.sectorCountExp = 0;
15590 fis->d.reserved4 = 0;
15591 fis->d.control = 0; /* FIS HOB bit clear */
15592 fis->d.reserved5 = 0;
15593
15594 agRequestType = AGSA_SATA_PROTOCOL_PIO_WRITE;
15595 satIOContext->ATACmd = SAT_WRITE_SECTORS;
15596 }
15597 }
15598
15599 /* case 3 and 4 */
15600 if (pSatDevData->sat48BitSupport == agTRUE)
15601 {
15602 if (pSatDevData->satDMASupport == agTRUE && pSatDevData->satDMAEnabled == agTRUE)
15603 {
15604 /* case 3 */
15605 /* WRITE DMA EXT or WRITE DMA FUA EXT */
15606 TI_DBG5(("satWriteAndVerify16: case 3\n"));
15607 fis->h.fisType = 0x27; /* Reg host to device */
15608 fis->h.c_pmPort = 0x80; /* C Bit is set */
15609
15610 /* SAT_WRITE_DMA_FUA_EXT is optional and we don't support it */
15611 fis->h.command = SAT_WRITE_DMA_EXT; /* 0x35 */
15612
15613 fis->h.features = 0; /* FIS reserve */
15614 fis->d.lbaLow = scsiCmnd->cdb[9]; /* FIS LBA (7 :0 ) */
15615 fis->d.lbaMid = scsiCmnd->cdb[8]; /* FIS LBA (15:8 ) */
15616 fis->d.lbaHigh = scsiCmnd->cdb[7]; /* FIS LBA (23:16) */
15617 fis->d.device = 0x40; /* FIS LBA mode set */
15618 fis->d.lbaLowExp = scsiCmnd->cdb[6]; /* FIS LBA (31:24) */
15619 fis->d.lbaMidExp = scsiCmnd->cdb[5]; /* FIS LBA (39:32) */
15620 fis->d.lbaHighExp = scsiCmnd->cdb[4]; /* FIS LBA (47:40) */
15621 fis->d.featuresExp = 0; /* FIS reserve */
15622 fis->d.sectorCount = scsiCmnd->cdb[13]; /* FIS sector count (7:0) */
15623 fis->d.sectorCountExp = scsiCmnd->cdb[12]; /* FIS sector count (15:8) */
15624 fis->d.reserved4 = 0;
15625 fis->d.control = 0; /* FIS HOB bit clear */
15626 fis->d.reserved5 = 0;
15627
15628 agRequestType = AGSA_SATA_PROTOCOL_DMA_WRITE;
15629 satIOContext->ATACmd = SAT_WRITE_DMA_EXT;
15630 }
15631 else
15632 {
15633 /* case 4 */
15634 /* WRITE MULTIPLE EXT or WRITE MULTIPLE FUA EXT or WRITE SECTOR(S) EXT */
15635 /* WRITE SECTORS EXT for easier implemetation */
15636 TI_DBG5(("satWriteAndVerify16: case 4\n"));
15637 fis->h.fisType = 0x27; /* Reg host to device */
15638 fis->h.c_pmPort = 0x80; /* C Bit is set */
15639 fis->h.command = SAT_WRITE_SECTORS_EXT; /* 0x34 */
15640
15641 fis->h.features = 0; /* FIS reserve */
15642 fis->d.lbaLow = scsiCmnd->cdb[9]; /* FIS LBA (7 :0 ) */
15643 fis->d.lbaMid = scsiCmnd->cdb[8]; /* FIS LBA (15:8 ) */
15644 fis->d.lbaHigh = scsiCmnd->cdb[7]; /* FIS LBA (23:16) */
15645 fis->d.device = 0x40; /* FIS LBA mode set */
15646 fis->d.lbaLowExp = scsiCmnd->cdb[6]; /* FIS LBA (31:24) */
15647 fis->d.lbaMidExp = scsiCmnd->cdb[5]; /* FIS LBA (39:32) */
15648 fis->d.lbaHighExp = scsiCmnd->cdb[4]; /* FIS LBA (47:40) */
15649 fis->d.featuresExp = 0; /* FIS reserve */
15650 fis->d.sectorCount = scsiCmnd->cdb[13]; /* FIS sector count (7:0) */
15651 fis->d.sectorCountExp = scsiCmnd->cdb[12]; /* FIS sector count (15:8) */
15652 fis->d.reserved4 = 0;
15653 fis->d.control = 0; /* FIS HOB bit clear */
15654 fis->d.reserved5 = 0;
15655
15656 agRequestType = AGSA_SATA_PROTOCOL_PIO_WRITE;
15657 satIOContext->ATACmd = SAT_WRITE_SECTORS_EXT;
15658 }
15659 }
15660
15661 /* case 5 */
15662 if (pSatDevData->satNCQ == agTRUE)
15663 {
15664 /* WRITE FPDMA QUEUED */
15665 if (pSatDevData->sat48BitSupport != agTRUE)
15666 {
15667 TI_DBG5(("satWriteAndVerify16: case 5 !!! error NCQ but 28 bit address support \n"));
15668 satSetSensePayload( pSense,
15669 SCSI_SNSKEY_ILLEGAL_REQUEST,
15670 0,
15671 SCSI_SNSCODE_INVALID_FIELD_IN_CDB,
15672 satIOContext);
15673
15674 ostiInitiatorIOCompleted( tiRoot,
15675 tiIORequest,
15676 tiIOSuccess,
15677 SCSI_STAT_CHECK_CONDITION,
15678 satIOContext->pTiSenseData,
15679 satIOContext->interruptContext );
15680 return tiSuccess;
15681 }
15682 TI_DBG6(("satWriteAndVerify16: case 5\n"));
15683
15684 /* Support 48-bit FPDMA addressing, use WRITE FPDMA QUEUE command */
15685
15686 fis->h.fisType = 0x27; /* Reg host to device */
15687 fis->h.c_pmPort = 0x80; /* C Bit is set */
15688 fis->h.command = SAT_WRITE_FPDMA_QUEUED; /* 0x61 */
15689 fis->h.features = scsiCmnd->cdb[13]; /* FIS sector count (7:0) */
15690 fis->d.lbaLow = scsiCmnd->cdb[9]; /* FIS LBA (7 :0 ) */
15691 fis->d.lbaMid = scsiCmnd->cdb[8]; /* FIS LBA (15:8 ) */
15692 fis->d.lbaHigh = scsiCmnd->cdb[7]; /* FIS LBA (23:16) */
15693
15694 /* Check FUA bit */
15695 if (scsiCmnd->cdb[1] & SCSI_WRITE16_FUA_MASK)
15696 fis->d.device = 0xC0; /* FIS FUA set */
15697 else
15698 fis->d.device = 0x40; /* FIS FUA clear */
15699
15700 fis->d.lbaLowExp = scsiCmnd->cdb[6]; /* FIS LBA (31:24) */
15701 fis->d.lbaMidExp = scsiCmnd->cdb[5]; /* FIS LBA (39:32) */
15702 fis->d.lbaHighExp = scsiCmnd->cdb[4]; /* FIS LBA (47:40) */
15703 fis->d.featuresExp = scsiCmnd->cdb[12]; /* FIS sector count (15:8) */
15704 fis->d.sectorCount = 0; /* Tag (7:3) set by LL layer */
15705 fis->d.sectorCountExp = 0;
15706 fis->d.reserved4 = 0;
15707 fis->d.control = 0; /* FIS HOB bit clear */
15708 fis->d.reserved5 = 0;
15709
15710 agRequestType = AGSA_SATA_PROTOCOL_FPDMA_WRITE;
15711 satIOContext->ATACmd = SAT_WRITE_FPDMA_QUEUED;
15712 }
15713
15714 satIOContext->currentLBA = lba;
15715 satIOContext->OrgTL = tl;
15716
15717 /*
15718 computing number of loop and remainder for tl
15719 0xFF in case not ext
15720 0xFFFF in case EXT
15721 */
15722 if (fis->h.command == SAT_WRITE_SECTORS || fis->h.command == SAT_WRITE_DMA)
15723 {
15724 LoopNum = satComputeLoopNum(tl, 0xFF);
15725 }
15726 else if (fis->h.command == SAT_WRITE_SECTORS_EXT ||
15727 fis->h.command == SAT_WRITE_DMA_EXT ||
15728 fis->h.command == SAT_WRITE_DMA_FUA_EXT
15729 )
15730 {
15731 /* SAT_READ_SECTORS_EXT, SAT_READ_DMA_EXT */
15732 LoopNum = satComputeLoopNum(tl, 0xFFFF);
15733 }
15734 else
15735 {
15736 /* SAT_WRITE_FPDMA_QUEUEDK */
15737 LoopNum = satComputeLoopNum(tl, 0xFFFF);
15738 }
15739
15740 satIOContext->LoopNum = LoopNum;
15741
15742
15743 if (LoopNum == 1)
15744 {
15745 TI_DBG5(("satWriteAndVerify16: NON CHAINED data\n"));
15746 /* Initialize CB for SATA completion.
15747 */
15748 satIOContext->satCompleteCB = &satNonChainedWriteNVerifyCB;
15749 }
15750 else
15751 {
15752 TI_DBG1(("satWriteAndVerify16: CHAINED data\n"));
15753 /* re-setting tl */
15754 if (fis->h.command == SAT_WRITE_SECTORS || fis->h.command == SAT_WRITE_DMA)
15755 {
15756 fis->d.sectorCount = 0xFF;
15757 }
15758 else if (fis->h.command == SAT_WRITE_SECTORS_EXT ||
15759 fis->h.command == SAT_WRITE_DMA_EXT ||
15760 fis->h.command == SAT_WRITE_DMA_FUA_EXT
15761 )
15762 {
15763 fis->d.sectorCount = 0xFF;
15764 fis->d.sectorCountExp = 0xFF;
15765 }
15766 else
15767 {
15768 /* SAT_WRITE_FPDMA_QUEUED */
15769 fis->h.features = 0xFF;
15770 fis->d.featuresExp = 0xFF;
15771 }
15772
15773 /* Initialize CB for SATA completion.
15774 */
15775 satIOContext->satCompleteCB = &satChainedWriteNVerifyCB;
15776 }
15777
15778
15779 /*
15780 * Prepare SGL and send FIS to LL layer.
15781 */
15782 satIOContext->reqType = agRequestType; /* Save it */
15783
15784 status = sataLLIOStart( tiRoot,
15785 tiIORequest,
15786 tiDeviceHandle,
15787 tiScsiRequest,
15788 satIOContext);
15789 return (status);
15790 }
15791
15792 /*****************************************************************************/
15793 /*! \brief SAT implementation for SCSI satReadMediaSerialNumber.
15794 *
15795 * SAT implementation for SCSI Read Media Serial Number.
15796 *
15797 * \param tiRoot: Pointer to TISA initiator driver/port instance.
15798 * \param tiIORequest: Pointer to TISA I/O request context for this I/O.
15799 * \param tiDeviceHandle: Pointer to TISA device handle for this I/O.
15800 * \param tiScsiRequest: Pointer to TISA SCSI I/O request and SGL list.
15801 * \param satIOContext_t: Pointer to the SAT IO Context
15802 *
15803 * \return If command is started successfully
15804 * - \e tiSuccess: I/O request successfully initiated.
15805 * - \e tiBusy: No resources available, try again later.
15806 * - \e tiIONoDevice: Invalid device handle.
15807 * - \e tiError: Other errors.
15808 */
15809 /*****************************************************************************/
satReadMediaSerialNumber(tiRoot_t * tiRoot,tiIORequest_t * tiIORequest,tiDeviceHandle_t * tiDeviceHandle,tiScsiInitiatorRequest_t * tiScsiRequest,satIOContext_t * satIOContext)15810 GLOBAL bit32 satReadMediaSerialNumber(
15811 tiRoot_t *tiRoot,
15812 tiIORequest_t *tiIORequest,
15813 tiDeviceHandle_t *tiDeviceHandle,
15814 tiScsiInitiatorRequest_t *tiScsiRequest,
15815 satIOContext_t *satIOContext)
15816 {
15817 bit32 status;
15818 bit32 agRequestType = AGSA_SATA_PROTOCOL_PIO_READ;
15819 satDeviceData_t *pSatDevData;
15820 scsiRspSense_t *pSense;
15821 tiIniScsiCmnd_t *scsiCmnd;
15822 agsaFisRegHostToDevice_t *fis;
15823 agsaSATAIdentifyData_t *pSATAIdData;
15824 bit8 *pSerialNumber;
15825
15826 pSense = satIOContext->pSense;
15827 pSatDevData = satIOContext->pSatDevData;
15828 scsiCmnd = &tiScsiRequest->scsiCmnd;
15829 fis = satIOContext->pFis;
15830 pSATAIdData = &(pSatDevData->satIdentifyData);
15831 pSerialNumber = (bit8 *) tiScsiRequest->sglVirtualAddr;
15832
15833
15834 TI_DBG1(("satReadMediaSerialNumber: start\n"));
15835
15836 /* checking CONTROL */
15837 /* NACA == 1 or LINK == 1*/
15838 if ( (scsiCmnd->cdb[11] & SCSI_NACA_MASK) || (scsiCmnd->cdb[11] & SCSI_LINK_MASK) )
15839 {
15840 satSetSensePayload( pSense,
15841 SCSI_SNSKEY_ILLEGAL_REQUEST,
15842 0,
15843 SCSI_SNSCODE_INVALID_FIELD_IN_CDB,
15844 satIOContext);
15845
15846 ostiInitiatorIOCompleted( tiRoot,
15847 tiIORequest,
15848 tiIOSuccess,
15849 SCSI_STAT_CHECK_CONDITION,
15850 satIOContext->pTiSenseData,
15851 satIOContext->interruptContext );
15852
15853 TI_DBG1(("satReadMediaSerialNumber: return control\n"));
15854 return tiSuccess;
15855 }
15856
15857 if (tiScsiRequest->scsiCmnd.expDataLength == 4)
15858 {
15859 if (pSATAIdData->commandSetFeatureDefault & 0x4)
15860 {
15861 TI_DBG1(("satReadMediaSerialNumber: Media serial number returning only length\n"));
15862 /* SPC-3 6.16 p192; filling in length */
15863 pSerialNumber[0] = 0;
15864 pSerialNumber[1] = 0;
15865 pSerialNumber[2] = 0;
15866 pSerialNumber[3] = 0x3C;
15867 }
15868 else
15869 {
15870 /* 1 sector - 4 = 512 - 4 to avoid underflow; 0x1fc*/
15871 pSerialNumber[0] = 0;
15872 pSerialNumber[1] = 0;
15873 pSerialNumber[2] = 0x1;
15874 pSerialNumber[3] = 0xfc;
15875 }
15876
15877 ostiInitiatorIOCompleted( tiRoot,
15878 tiIORequest,
15879 tiIOSuccess,
15880 SCSI_STAT_GOOD,
15881 agNULL,
15882 satIOContext->interruptContext);
15883
15884 return tiSuccess;
15885 }
15886
15887 if ( pSatDevData->IDDeviceValid == agTRUE)
15888 {
15889 if (pSATAIdData->commandSetFeatureDefault & 0x4)
15890 {
15891 /* word87 bit2 Media serial number is valid */
15892 /* read word 176 to 205; length is 2*30 = 60 = 0x3C*/
15893 tdhexdump("ID satReadMediaSerialNumber", (bit8*)pSATAIdData->currentMediaSerialNumber, 2*30);
15894 /* SPC-3 6.16 p192; filling in length */
15895 pSerialNumber[0] = 0;
15896 pSerialNumber[1] = 0;
15897 pSerialNumber[2] = 0;
15898 pSerialNumber[3] = 0x3C;
15899 osti_memcpy(&pSerialNumber[4], (void *)pSATAIdData->currentMediaSerialNumber, 60);
15900 tdhexdump("satReadMediaSerialNumber", (bit8*)pSerialNumber, 2*30 + 4);
15901
15902 ostiInitiatorIOCompleted( tiRoot,
15903 tiIORequest,
15904 tiIOSuccess,
15905 SCSI_STAT_GOOD,
15906 agNULL,
15907 satIOContext->interruptContext);
15908 return tiSuccess;
15909
15910
15911 }
15912 else
15913 {
15914 /* word87 bit2 Media serial number is NOT valid */
15915 TI_DBG1(("satReadMediaSerialNumber: Media serial number is NOT valid \n"));
15916
15917 if (pSatDevData->sat48BitSupport == agTRUE)
15918 {
15919 /* READ VERIFY SECTORS EXT */
15920 fis->h.fisType = 0x27; /* Reg host to device */
15921 fis->h.c_pmPort = 0x80; /* C Bit is set */
15922 fis->h.command = SAT_READ_SECTORS_EXT; /* 0x24 */
15923
15924 fis->h.features = 0; /* FIS reserve */
15925 fis->d.lbaLow = 0; /* FIS LBA (7 :0 ) */
15926 fis->d.lbaMid = 0; /* FIS LBA (15:8 ) */
15927 fis->d.lbaHigh = 0; /* FIS LBA (23:16) */
15928 fis->d.device = 0x40; /* FIS LBA mode set */
15929 fis->d.lbaLowExp = 0; /* FIS LBA (31:24) */
15930 fis->d.lbaMidExp = 0; /* FIS LBA (39:32) */
15931 fis->d.lbaHighExp = 0; /* FIS LBA (47:40) */
15932 fis->d.featuresExp = 0; /* FIS reserve */
15933 fis->d.sectorCount = 1; /* FIS sector count (7:0) */
15934 fis->d.sectorCountExp = 0; /* FIS sector count (15:8) */
15935 fis->d.reserved4 = 0;
15936 fis->d.control = 0; /* FIS HOB bit clear */
15937 fis->d.reserved5 = 0;
15938
15939 agRequestType = AGSA_SATA_PROTOCOL_PIO_READ;
15940 }
15941 else
15942 {
15943 /* READ VERIFY SECTORS */
15944 fis->h.fisType = 0x27; /* Reg host to device */
15945 fis->h.c_pmPort = 0x80; /* C Bit is set */
15946 fis->h.command = SAT_READ_SECTORS; /* 0x20 */
15947 fis->h.features = 0; /* FIS reserve */
15948 fis->d.lbaLow = 0; /* FIS LBA (7 :0 ) */
15949 fis->d.lbaMid = 0; /* FIS LBA (15:8 ) */
15950 fis->d.lbaHigh = 0; /* FIS LBA (23:16) */
15951 fis->d.device = 0x40; /* FIS LBA (27:24) and FIS LBA mode */
15952 fis->d.lbaLowExp = 0;
15953 fis->d.lbaMidExp = 0;
15954 fis->d.lbaHighExp = 0;
15955 fis->d.featuresExp = 0;
15956 fis->d.sectorCount = 1; /* FIS sector count (7:0) */
15957 fis->d.sectorCountExp = 0;
15958 fis->d.reserved4 = 0;
15959 fis->d.control = 0; /* FIS HOB bit clear */
15960 fis->d.reserved5 = 0;
15961
15962
15963 agRequestType = AGSA_SATA_PROTOCOL_PIO_READ;
15964 }
15965 satIOContext->satCompleteCB = &satReadMediaSerialNumberCB;
15966 satIOContext->reqType = agRequestType; /* Save it */
15967 status = sataLLIOStart( tiRoot,
15968 tiIORequest,
15969 tiDeviceHandle,
15970 tiScsiRequest,
15971 satIOContext);
15972
15973 return status;
15974 }
15975 }
15976 else
15977 {
15978 /* temporary failure */
15979 ostiInitiatorIOCompleted( tiRoot,
15980 tiIORequest,
15981 tiIOFailed,
15982 tiDetailOtherError,
15983 agNULL,
15984 satIOContext->interruptContext);
15985
15986 return tiSuccess;
15987
15988 }
15989
15990 }
15991
15992 /*****************************************************************************/
15993 /*! \brief SAT implementation for SCSI satReadBuffer.
15994 *
15995 * SAT implementation for SCSI Read Buffer.
15996 *
15997 * \param tiRoot: Pointer to TISA initiator driver/port instance.
15998 * \param tiIORequest: Pointer to TISA I/O request context for this I/O.
15999 * \param tiDeviceHandle: Pointer to TISA device handle for this I/O.
16000 * \param tiScsiRequest: Pointer to TISA SCSI I/O request and SGL list.
16001 * \param satIOContext_t: Pointer to the SAT IO Context
16002 *
16003 * \return If command is started successfully
16004 * - \e tiSuccess: I/O request successfully initiated.
16005 * - \e tiBusy: No resources available, try again later.
16006 * - \e tiIONoDevice: Invalid device handle.
16007 * - \e tiError: Other errors.
16008 */
16009 /*****************************************************************************/
16010 /* SAT-2, Revision 00*/
satReadBuffer(tiRoot_t * tiRoot,tiIORequest_t * tiIORequest,tiDeviceHandle_t * tiDeviceHandle,tiScsiInitiatorRequest_t * tiScsiRequest,satIOContext_t * satIOContext)16011 GLOBAL bit32 satReadBuffer(
16012 tiRoot_t *tiRoot,
16013 tiIORequest_t *tiIORequest,
16014 tiDeviceHandle_t *tiDeviceHandle,
16015 tiScsiInitiatorRequest_t *tiScsiRequest,
16016 satIOContext_t *satIOContext)
16017 {
16018 bit32 status = tiSuccess;
16019 bit32 agRequestType = AGSA_SATA_PROTOCOL_PIO_READ;
16020 scsiRspSense_t *pSense;
16021 tiIniScsiCmnd_t *scsiCmnd;
16022 agsaFisRegHostToDevice_t *fis;
16023 bit32 bufferOffset;
16024 bit32 tl;
16025 bit8 mode;
16026 bit8 bufferID;
16027 bit8 *pBuff;
16028
16029 pSense = satIOContext->pSense;
16030 scsiCmnd = &tiScsiRequest->scsiCmnd;
16031 fis = satIOContext->pFis;
16032 pBuff = (bit8 *) tiScsiRequest->sglVirtualAddr;
16033
16034 TI_DBG2(("satReadBuffer: start\n"));
16035 /* checking CONTROL */
16036 /* NACA == 1 or LINK == 1*/
16037 if ( (scsiCmnd->cdb[9] & SCSI_NACA_MASK) || (scsiCmnd->cdb[9] & SCSI_LINK_MASK) )
16038 {
16039 satSetSensePayload( pSense,
16040 SCSI_SNSKEY_ILLEGAL_REQUEST,
16041 0,
16042 SCSI_SNSCODE_INVALID_FIELD_IN_CDB,
16043 satIOContext);
16044 ostiInitiatorIOCompleted( tiRoot,
16045 tiIORequest,
16046 tiIOSuccess,
16047 SCSI_STAT_CHECK_CONDITION,
16048 satIOContext->pTiSenseData,
16049 satIOContext->interruptContext );
16050 TI_DBG1(("satReadBuffer: return control\n"));
16051 return tiSuccess;
16052 }
16053
16054 bufferOffset = (scsiCmnd->cdb[3] << (8*2)) + (scsiCmnd->cdb[4] << 8) + scsiCmnd->cdb[5];
16055 tl = (scsiCmnd->cdb[6] << (8*2)) + (scsiCmnd->cdb[7] << 8) + scsiCmnd->cdb[8];
16056
16057 mode = (bit8)(scsiCmnd->cdb[1] & SCSI_READ_BUFFER_MODE_MASK);
16058 bufferID = scsiCmnd->cdb[2];
16059
16060 if (mode == READ_BUFFER_DATA_MODE) /* 2 */
16061 {
16062 if (bufferID == 0 && bufferOffset == 0 && tl == 512)
16063 {
16064 /* send ATA READ BUFFER */
16065 fis->h.fisType = 0x27; /* Reg host to device */
16066 fis->h.c_pmPort = 0x80; /* C Bit is set */
16067 fis->h.command = SAT_READ_BUFFER; /* 0xE4 */
16068 fis->h.features = 0; /* FIS reserve */
16069 fis->d.lbaLow = 0; /* FIS LBA (7 :0 ) */
16070 fis->d.lbaMid = 0; /* FIS LBA (15:8 ) */
16071 fis->d.lbaHigh = 0; /* FIS LBA (23:16) */
16072 fis->d.device = 0x40; /* FIS LBA (27:24) and FIS LBA mode */
16073 fis->d.lbaLowExp = 0;
16074 fis->d.lbaMidExp = 0;
16075 fis->d.lbaHighExp = 0;
16076 fis->d.featuresExp = 0;
16077 fis->d.sectorCount = 0; /* FIS sector count (7:0) */
16078 fis->d.sectorCountExp = 0;
16079 fis->d.reserved4 = 0;
16080 fis->d.control = 0; /* FIS HOB bit clear */
16081 fis->d.reserved5 = 0;
16082
16083 agRequestType = AGSA_SATA_PROTOCOL_PIO_READ;
16084 satIOContext->satCompleteCB = &satReadBufferCB;
16085 satIOContext->reqType = agRequestType; /* Save it */
16086
16087 status = sataLLIOStart( tiRoot,
16088 tiIORequest,
16089 tiDeviceHandle,
16090 tiScsiRequest,
16091 satIOContext);
16092 return status;
16093 }
16094 if (bufferID == 0 && bufferOffset == 0 && tl != 512)
16095 {
16096 satSetSensePayload( pSense,
16097 SCSI_SNSKEY_ILLEGAL_REQUEST,
16098 0,
16099 SCSI_SNSCODE_INVALID_FIELD_IN_CDB,
16100 satIOContext);
16101 ostiInitiatorIOCompleted( tiRoot,
16102 tiIORequest,
16103 tiIOSuccess,
16104 SCSI_STAT_CHECK_CONDITION,
16105 satIOContext->pTiSenseData,
16106 satIOContext->interruptContext );
16107 TI_DBG1(("satReadBuffer: allocation length is not 512; it is %d\n", tl));
16108 return tiSuccess;
16109 }
16110 if (bufferID == 0 && bufferOffset != 0)
16111 {
16112 satSetSensePayload( pSense,
16113 SCSI_SNSKEY_ILLEGAL_REQUEST,
16114 0,
16115 SCSI_SNSCODE_INVALID_FIELD_IN_CDB,
16116 satIOContext);
16117 ostiInitiatorIOCompleted( tiRoot,
16118 tiIORequest,
16119 tiIOSuccess,
16120 SCSI_STAT_CHECK_CONDITION,
16121 satIOContext->pTiSenseData,
16122 satIOContext->interruptContext );
16123 TI_DBG1(("satReadBuffer: buffer offset is not 0; it is %d\n", bufferOffset));
16124 return tiSuccess;
16125 }
16126 /* all other cases unsupported */
16127 TI_DBG1(("satReadBuffer: unsupported case 1\n"));
16128 satSetSensePayload( pSense,
16129 SCSI_SNSKEY_ILLEGAL_REQUEST,
16130 0,
16131 SCSI_SNSCODE_INVALID_COMMAND,
16132 satIOContext);
16133
16134 ostiInitiatorIOCompleted( tiRoot,
16135 tiIORequest,
16136 tiIOSuccess,
16137 SCSI_STAT_CHECK_CONDITION,
16138 satIOContext->pTiSenseData,
16139 satIOContext->interruptContext );
16140 return tiSuccess;
16141 }
16142 else if (mode == READ_BUFFER_DESCRIPTOR_MODE) /* 3 */
16143 {
16144 if (tl < READ_BUFFER_DESCRIPTOR_MODE_DATA_LEN) /* 4 */
16145 {
16146 satSetSensePayload( pSense,
16147 SCSI_SNSKEY_ILLEGAL_REQUEST,
16148 0,
16149 SCSI_SNSCODE_INVALID_FIELD_IN_CDB,
16150 satIOContext);
16151 ostiInitiatorIOCompleted( tiRoot,
16152 tiIORequest,
16153 tiIOSuccess,
16154 SCSI_STAT_CHECK_CONDITION,
16155 satIOContext->pTiSenseData,
16156 satIOContext->interruptContext );
16157 TI_DBG1(("satReadBuffer: tl < 4; tl is %d\n", tl));
16158 return tiSuccess;
16159 }
16160 if (bufferID == 0)
16161 {
16162 /* SPC-4, 6.15.5, p189; SAT-2 Rev00, 8.7.2.3, p41*/
16163 pBuff[0] = 0xFF;
16164 pBuff[1] = 0x00;
16165 pBuff[2] = 0x02;
16166 pBuff[3] = 0x00;
16167 if (READ_BUFFER_DESCRIPTOR_MODE_DATA_LEN < tl)
16168 {
16169 /* underrrun */
16170 TI_DBG1(("satReadBuffer: underrun tl %d data %d\n", tl, READ_BUFFER_DESCRIPTOR_MODE_DATA_LEN));
16171 ostiInitiatorIOCompleted( tiRoot,
16172 tiIORequest,
16173 tiIOUnderRun,
16174 tl - READ_BUFFER_DESCRIPTOR_MODE_DATA_LEN,
16175 agNULL,
16176 satIOContext->interruptContext );
16177 return tiSuccess;
16178 }
16179 else
16180 {
16181 ostiInitiatorIOCompleted( tiRoot,
16182 tiIORequest,
16183 tiIOSuccess,
16184 SCSI_STAT_GOOD,
16185 agNULL,
16186 satIOContext->interruptContext);
16187 return tiSuccess;
16188 }
16189 }
16190 else
16191 {
16192 /* We don't support other than bufferID 0 */
16193 satSetSensePayload( pSense,
16194 SCSI_SNSKEY_ILLEGAL_REQUEST,
16195 0,
16196 SCSI_SNSCODE_INVALID_COMMAND,
16197 satIOContext);
16198
16199 ostiInitiatorIOCompleted( tiRoot,
16200 tiIORequest,
16201 tiIOSuccess,
16202 SCSI_STAT_CHECK_CONDITION,
16203 satIOContext->pTiSenseData,
16204 satIOContext->interruptContext );
16205 return tiSuccess;
16206 }
16207 }
16208 else
16209 {
16210 /* We don't support any other mode */
16211 TI_DBG1(("satReadBuffer: unsupported mode %d\n", mode));
16212 satSetSensePayload( pSense,
16213 SCSI_SNSKEY_ILLEGAL_REQUEST,
16214 0,
16215 SCSI_SNSCODE_INVALID_COMMAND,
16216 satIOContext);
16217
16218 ostiInitiatorIOCompleted( tiRoot,
16219 tiIORequest,
16220 tiIOSuccess,
16221 SCSI_STAT_CHECK_CONDITION,
16222 satIOContext->pTiSenseData,
16223 satIOContext->interruptContext );
16224 return tiSuccess;
16225 }
16226 }
16227
16228 /*****************************************************************************/
16229 /*! \brief SAT implementation for SCSI satWriteBuffer.
16230 *
16231 * SAT implementation for SCSI Write Buffer.
16232 *
16233 * \param tiRoot: Pointer to TISA initiator driver/port instance.
16234 * \param tiIORequest: Pointer to TISA I/O request context for this I/O.
16235 * \param tiDeviceHandle: Pointer to TISA device handle for this I/O.
16236 * \param tiScsiRequest: Pointer to TISA SCSI I/O request and SGL list.
16237 * \param satIOContext_t: Pointer to the SAT IO Context
16238 *
16239 * \return If command is started successfully
16240 * - \e tiSuccess: I/O request successfully initiated.
16241 * - \e tiBusy: No resources available, try again later.
16242 * - \e tiIONoDevice: Invalid device handle.
16243 * - \e tiError: Other errors.
16244 */
16245 /*****************************************************************************/
16246 /* SAT-2, Revision 00*/
satWriteBuffer(tiRoot_t * tiRoot,tiIORequest_t * tiIORequest,tiDeviceHandle_t * tiDeviceHandle,tiScsiInitiatorRequest_t * tiScsiRequest,satIOContext_t * satIOContext)16247 GLOBAL bit32 satWriteBuffer(
16248 tiRoot_t *tiRoot,
16249 tiIORequest_t *tiIORequest,
16250 tiDeviceHandle_t *tiDeviceHandle,
16251 tiScsiInitiatorRequest_t *tiScsiRequest,
16252 satIOContext_t *satIOContext)
16253 {
16254 #ifdef NOT_YET
16255 bit32 agRequestType = AGSA_SATA_PROTOCOL_PIO_READ;
16256 #endif
16257 scsiRspSense_t *pSense;
16258 tiIniScsiCmnd_t *scsiCmnd;
16259 bit32 bufferOffset;
16260 bit32 parmLen;
16261 bit8 mode;
16262 bit8 bufferID;
16263 bit8 *pBuff;
16264
16265 pSense = satIOContext->pSense;
16266 scsiCmnd = &tiScsiRequest->scsiCmnd;
16267 pBuff = (bit8 *) tiScsiRequest->sglVirtualAddr;
16268
16269 TI_DBG2(("satWriteBuffer: start\n"));
16270
16271 /* checking CONTROL */
16272 /* NACA == 1 or LINK == 1*/
16273 if ( (scsiCmnd->cdb[9] & SCSI_NACA_MASK) || (scsiCmnd->cdb[9] & SCSI_LINK_MASK) )
16274 {
16275 satSetSensePayload( pSense,
16276 SCSI_SNSKEY_ILLEGAL_REQUEST,
16277 0,
16278 SCSI_SNSCODE_INVALID_FIELD_IN_CDB,
16279 satIOContext);
16280
16281 ostiInitiatorIOCompleted( tiRoot,
16282 tiIORequest,
16283 tiIOSuccess,
16284 SCSI_STAT_CHECK_CONDITION,
16285 satIOContext->pTiSenseData,
16286 satIOContext->interruptContext );
16287
16288 TI_DBG1(("satWriteBuffer: return control\n"));
16289 return tiSuccess;
16290 }
16291
16292 bufferOffset = (scsiCmnd->cdb[3] << (8*2)) + (scsiCmnd->cdb[4] << 8) + scsiCmnd->cdb[5];
16293 parmLen = (scsiCmnd->cdb[6] << (8*2)) + (scsiCmnd->cdb[7] << 8) + scsiCmnd->cdb[8];
16294
16295 mode = (bit8)(scsiCmnd->cdb[1] & SCSI_READ_BUFFER_MODE_MASK);
16296 bufferID = scsiCmnd->cdb[2];
16297
16298 /* for debugging only */
16299 tdhexdump("satWriteBuffer pBuff", (bit8 *)pBuff, 24);
16300
16301 if (mode == WRITE_BUFFER_DATA_MODE) /* 2 */
16302 {
16303 if (bufferID == 0 && bufferOffset == 0 && parmLen == 512)
16304 {
16305 TI_DBG1(("satWriteBuffer: sending ATA WRITE BUFFER\n"));
16306 /* send ATA WRITE BUFFER */
16307 #ifdef NOT_YET
16308 fis->h.fisType = 0x27; /* Reg host to device */
16309 fis->h.c_pmPort = 0x80; /* C Bit is set */
16310 fis->h.command = SAT_WRITE_BUFFER; /* 0xE8 */
16311 fis->h.features = 0; /* FIS reserve */
16312 fis->d.lbaLow = 0; /* FIS LBA (7 :0 ) */
16313 fis->d.lbaMid = 0; /* FIS LBA (15:8 ) */
16314 fis->d.lbaHigh = 0; /* FIS LBA (23:16) */
16315 fis->d.device = 0x40; /* FIS LBA (27:24) and FIS LBA mode */
16316 fis->d.lbaLowExp = 0;
16317 fis->d.lbaMidExp = 0;
16318 fis->d.lbaHighExp = 0;
16319 fis->d.featuresExp = 0;
16320 fis->d.sectorCount = 0; /* FIS sector count (7:0) */
16321 fis->d.sectorCountExp = 0;
16322 fis->d.reserved4 = 0;
16323 fis->d.control = 0; /* FIS HOB bit clear */
16324 fis->d.reserved5 = 0;
16325
16326
16327 agRequestType = AGSA_SATA_PROTOCOL_PIO_WRITE;
16328
16329 satIOContext->satCompleteCB = &satWriteBufferCB;
16330
16331 satIOContext->reqType = agRequestType; /* Save it */
16332
16333 status = sataLLIOStart( tiRoot,
16334 tiIORequest,
16335 tiDeviceHandle,
16336 tiScsiRequest,
16337 satIOContext);
16338 return status;
16339 #endif
16340 /* temp */
16341 ostiInitiatorIOCompleted( tiRoot,
16342 tiIORequest,
16343 tiIOSuccess,
16344 SCSI_STAT_GOOD,
16345 agNULL,
16346 satIOContext->interruptContext);
16347 return tiSuccess;
16348 }
16349 if ( (bufferID == 0 && bufferOffset != 0) ||
16350 (bufferID == 0 && parmLen != 512)
16351 )
16352 {
16353 satSetSensePayload( pSense,
16354 SCSI_SNSKEY_ILLEGAL_REQUEST,
16355 0,
16356 SCSI_SNSCODE_INVALID_FIELD_IN_CDB,
16357 satIOContext);
16358
16359 ostiInitiatorIOCompleted( tiRoot,
16360 tiIORequest,
16361 tiIOSuccess,
16362 SCSI_STAT_CHECK_CONDITION,
16363 satIOContext->pTiSenseData,
16364 satIOContext->interruptContext );
16365
16366 TI_DBG1(("satWriteBuffer: wrong buffer offset %d or parameter length parmLen %d\n", bufferOffset, parmLen));
16367 return tiSuccess;
16368 }
16369
16370 /* all other cases unsupported */
16371 TI_DBG1(("satWriteBuffer: unsupported case 1\n"));
16372 satSetSensePayload( pSense,
16373 SCSI_SNSKEY_ILLEGAL_REQUEST,
16374 0,
16375 SCSI_SNSCODE_INVALID_COMMAND,
16376 satIOContext);
16377
16378 ostiInitiatorIOCompleted( tiRoot,
16379 tiIORequest,
16380 tiIOSuccess,
16381 SCSI_STAT_CHECK_CONDITION,
16382 satIOContext->pTiSenseData,
16383 satIOContext->interruptContext );
16384
16385 return tiSuccess;
16386
16387 }
16388 else if (mode == WRITE_BUFFER_DL_MICROCODE_SAVE_MODE) /* 5 */
16389 {
16390 TI_DBG1(("satWriteBuffer: not yet supported mode %d\n", mode));
16391 satSetSensePayload( pSense,
16392 SCSI_SNSKEY_ILLEGAL_REQUEST,
16393 0,
16394 SCSI_SNSCODE_INVALID_COMMAND,
16395 satIOContext);
16396
16397 ostiInitiatorIOCompleted( tiRoot,
16398 tiIORequest,
16399 tiIOSuccess,
16400 SCSI_STAT_CHECK_CONDITION,
16401 satIOContext->pTiSenseData,
16402 satIOContext->interruptContext );
16403
16404 return tiSuccess;
16405 }
16406 else
16407 {
16408 /* We don't support any other mode */
16409 TI_DBG1(("satWriteBuffer: unsupported mode %d\n", mode));
16410 satSetSensePayload( pSense,
16411 SCSI_SNSKEY_ILLEGAL_REQUEST,
16412 0,
16413 SCSI_SNSCODE_INVALID_COMMAND,
16414 satIOContext);
16415
16416 ostiInitiatorIOCompleted( tiRoot,
16417 tiIORequest,
16418 tiIOSuccess,
16419 SCSI_STAT_CHECK_CONDITION,
16420 satIOContext->pTiSenseData,
16421 satIOContext->interruptContext );
16422
16423 return tiSuccess;
16424 }
16425
16426 }
16427
16428 /*****************************************************************************/
16429 /*! \brief SAT implementation for SCSI satReassignBlocks.
16430 *
16431 * SAT implementation for SCSI Reassign Blocks.
16432 *
16433 * \param tiRoot: Pointer to TISA initiator driver/port instance.
16434 * \param tiIORequest: Pointer to TISA I/O request context for this I/O.
16435 * \param tiDeviceHandle: Pointer to TISA device handle for this I/O.
16436 * \param tiScsiRequest: Pointer to TISA SCSI I/O request and SGL list.
16437 * \param satIOContext_t: Pointer to the SAT IO Context
16438 *
16439 * \return If command is started successfully
16440 * - \e tiSuccess: I/O request successfully initiated.
16441 * - \e tiBusy: No resources available, try again later.
16442 * - \e tiIONoDevice: Invalid device handle.
16443 * - \e tiError: Other errors.
16444 */
16445 /*****************************************************************************/
satReassignBlocks(tiRoot_t * tiRoot,tiIORequest_t * tiIORequest,tiDeviceHandle_t * tiDeviceHandle,tiScsiInitiatorRequest_t * tiScsiRequest,satIOContext_t * satIOContext)16446 GLOBAL bit32 satReassignBlocks(
16447 tiRoot_t *tiRoot,
16448 tiIORequest_t *tiIORequest,
16449 tiDeviceHandle_t *tiDeviceHandle,
16450 tiScsiInitiatorRequest_t *tiScsiRequest,
16451 satIOContext_t *satIOContext)
16452 {
16453 /*
16454 assumes all LBA fits in ATA command; no boundary condition is checked here yet
16455 */
16456 bit32 status;
16457 bit32 agRequestType;
16458 satDeviceData_t *pSatDevData;
16459 scsiRspSense_t *pSense;
16460 tiIniScsiCmnd_t *scsiCmnd;
16461 agsaFisRegHostToDevice_t *fis;
16462 bit8 *pParmList; /* Log Page data buffer */
16463 bit8 LongLBA;
16464 bit8 LongList;
16465 bit32 defectListLen;
16466 bit8 LBA[8];
16467 bit32 startingIndex;
16468
16469 pSense = satIOContext->pSense;
16470 pSatDevData = satIOContext->pSatDevData;
16471 scsiCmnd = &tiScsiRequest->scsiCmnd;
16472 fis = satIOContext->pFis;
16473 pParmList = (bit8 *) tiScsiRequest->sglVirtualAddr;
16474
16475 TI_DBG5(("satReassignBlocks: start\n"));
16476
16477 /* checking CONTROL */
16478 /* NACA == 1 or LINK == 1*/
16479 if ( (scsiCmnd->cdb[5] & SCSI_NACA_MASK) || (scsiCmnd->cdb[5] & SCSI_LINK_MASK) )
16480 {
16481 satSetSensePayload( pSense,
16482 SCSI_SNSKEY_ILLEGAL_REQUEST,
16483 0,
16484 SCSI_SNSCODE_INVALID_FIELD_IN_CDB,
16485 satIOContext);
16486
16487 ostiInitiatorIOCompleted( tiRoot,
16488 tiIORequest,
16489 tiIOSuccess,
16490 SCSI_STAT_CHECK_CONDITION,
16491 satIOContext->pTiSenseData,
16492 satIOContext->interruptContext );
16493
16494 TI_DBG1(("satReassignBlocks: return control\n"));
16495 return tiSuccess;
16496 }
16497
16498 osti_memset(satIOContext->LBA, 0, 8);
16499 satIOContext->ParmIndex = 0;
16500 satIOContext->ParmLen = 0;
16501
16502 LongList = (bit8)(scsiCmnd->cdb[1] & SCSI_REASSIGN_BLOCKS_LONGLIST_MASK);
16503 LongLBA = (bit8)(scsiCmnd->cdb[1] & SCSI_REASSIGN_BLOCKS_LONGLBA_MASK);
16504 osti_memset(LBA, 0, sizeof(LBA));
16505
16506 if (LongList == 0)
16507 {
16508 defectListLen = (pParmList[2] << 8) + pParmList[3];
16509 }
16510 else
16511 {
16512 defectListLen = (pParmList[0] << (8*3)) + (pParmList[1] << (8*2))
16513 + (pParmList[2] << 8) + pParmList[3];
16514 }
16515 /* SBC 5.16.2, p61*/
16516 satIOContext->ParmLen = defectListLen + 4 /* header size */;
16517
16518 startingIndex = 4;
16519
16520 if (LongLBA == 0)
16521 {
16522 LBA[4] = pParmList[startingIndex]; /* MSB */
16523 LBA[5] = pParmList[startingIndex+1];
16524 LBA[6] = pParmList[startingIndex+2];
16525 LBA[7] = pParmList[startingIndex+3]; /* LSB */
16526 startingIndex = startingIndex + 4;
16527 }
16528 else
16529 {
16530 LBA[0] = pParmList[startingIndex]; /* MSB */
16531 LBA[1] = pParmList[startingIndex+1];
16532 LBA[2] = pParmList[startingIndex+2];
16533 LBA[3] = pParmList[startingIndex+3];
16534 LBA[4] = pParmList[startingIndex+4];
16535 LBA[5] = pParmList[startingIndex+5];
16536 LBA[6] = pParmList[startingIndex+6];
16537 LBA[7] = pParmList[startingIndex+7]; /* LSB */
16538 startingIndex = startingIndex + 8;
16539 }
16540
16541 tdhexdump("satReassignBlocks Parameter list", (bit8 *)pParmList, 4 + defectListLen);
16542
16543 if (pSatDevData->sat48BitSupport == agTRUE)
16544 {
16545 /* sends READ VERIFY SECTOR(S) EXT*/
16546 fis->h.fisType = 0x27; /* Reg host to device */
16547 fis->h.c_pmPort = 0x80; /* C Bit is set */
16548 fis->h.command = SAT_READ_VERIFY_SECTORS_EXT;/* 0x42 */
16549 fis->h.features = 0; /* FIS reserve */
16550 fis->d.lbaLow = LBA[7]; /* FIS LBA (7 :0 ) */
16551 fis->d.lbaMid = LBA[6]; /* FIS LBA (15:8 ) */
16552 fis->d.lbaHigh = LBA[5]; /* FIS LBA (23:16) */
16553 fis->d.lbaLowExp = LBA[4]; /* FIS LBA (31:24) */
16554 fis->d.lbaMidExp = LBA[3]; /* FIS LBA (39:32) */
16555 fis->d.lbaHighExp = LBA[2]; /* FIS LBA (47:40) */
16556 fis->d.featuresExp = 0; /* FIS reserve */
16557 fis->d.sectorCount = 1; /* FIS sector count (7:0) */
16558 fis->d.sectorCountExp = 0; /* FIS sector count (15:8) */
16559 fis->d.reserved4 = 0;
16560 fis->d.device = 0x40; /* 01000000 */
16561 fis->d.control = 0; /* FIS HOB bit clear */
16562 fis->d.reserved5 = 0;
16563 }
16564 else
16565 {
16566 /* READ VERIFY SECTOR(S)*/
16567 fis->h.fisType = 0x27; /* Reg host to device */
16568 fis->h.c_pmPort = 0x80; /* C Bit is set */
16569 fis->h.command = SAT_READ_VERIFY_SECTORS;/* 0x40 */
16570 fis->h.features = 0; /* FIS features NA */
16571 fis->d.lbaLow = LBA[7]; /* FIS LBA (7 :0 ) */
16572 fis->d.lbaMid = LBA[6]; /* FIS LBA (15:8 ) */
16573 fis->d.lbaHigh = LBA[5]; /* FIS LBA (23:16) */
16574 fis->d.lbaLowExp = 0;
16575 fis->d.lbaMidExp = 0;
16576 fis->d.lbaHighExp = 0;
16577 fis->d.featuresExp = 0;
16578 fis->d.sectorCount = 1; /* FIS sector count (7:0) */
16579 fis->d.sectorCountExp = 0;
16580 fis->d.reserved4 = 0;
16581 fis->d.device = (bit8)((0x4 << 4) | (LBA[4] & 0xF));
16582 /* DEV and LBA 27:24 */
16583 fis->d.control = 0; /* FIS HOB bit clear */
16584 fis->d.reserved5 = 0;
16585 }
16586
16587 osti_memcpy(satIOContext->LBA, LBA, 8);
16588 satIOContext->ParmIndex = startingIndex;
16589
16590 agRequestType = AGSA_SATA_PROTOCOL_NON_DATA;
16591
16592 /* Initialize CB for SATA completion.
16593 */
16594 satIOContext->satCompleteCB = &satReassignBlocksCB;
16595
16596 /*
16597 * Prepare SGL and send FIS to LL layer.
16598 */
16599 satIOContext->reqType = agRequestType; /* Save it */
16600
16601 status = sataLLIOStart( tiRoot,
16602 tiIORequest,
16603 tiDeviceHandle,
16604 tiScsiRequest,
16605 satIOContext);
16606
16607 return status;
16608 }
16609
16610 /*****************************************************************************/
16611 /*! \brief SAT implementation for SCSI satReassignBlocks_1.
16612 *
16613 * SAT implementation for SCSI Reassign Blocks. This is helper function for
16614 * satReassignBlocks and satReassignBlocksCB. This sends ATA verify command.
16615 *
16616 * \param tiRoot: Pointer to TISA initiator driver/port instance.
16617 * \param tiIORequest: Pointer to TISA I/O request context for this I/O.
16618 * \param tiDeviceHandle: Pointer to TISA device handle for this I/O.
16619 * \param tiScsiRequest: Pointer to TISA SCSI I/O request and SGL list.
16620 * \param satIOContext_t: Pointer to the SAT IO Context
16621 *
16622 * \return If command is started successfully
16623 * - \e tiSuccess: I/O request successfully initiated.
16624 * - \e tiBusy: No resources available, try again later.
16625 * - \e tiIONoDevice: Invalid device handle.
16626 * - \e tiError: Other errors.
16627 */
16628 /*****************************************************************************/
16629 /* next LBA; sends READ VERIFY SECTOR; update LBA and ParmIdx */
satReassignBlocks_1(tiRoot_t * tiRoot,tiIORequest_t * tiIORequest,tiDeviceHandle_t * tiDeviceHandle,tiScsiInitiatorRequest_t * tiScsiRequest,satIOContext_t * satIOContext,satIOContext_t * satOrgIOContext)16630 GLOBAL bit32 satReassignBlocks_1(
16631 tiRoot_t *tiRoot,
16632 tiIORequest_t *tiIORequest,
16633 tiDeviceHandle_t *tiDeviceHandle,
16634 tiScsiInitiatorRequest_t *tiScsiRequest,
16635 satIOContext_t *satIOContext,
16636 satIOContext_t *satOrgIOContext
16637 )
16638 {
16639 /*
16640 assumes all LBA fits in ATA command; no boundary condition is checked here yet
16641 tiScsiRequest is OS generated; needs for accessing parameter list
16642 */
16643 bit32 agRequestType;
16644 satDeviceData_t *pSatDevData;
16645 tiIniScsiCmnd_t *scsiCmnd;
16646 agsaFisRegHostToDevice_t *fis;
16647 bit8 *pParmList; /* Log Page data buffer */
16648 bit8 LongLBA;
16649 bit8 LBA[8];
16650 bit32 startingIndex;
16651
16652 pSatDevData = satIOContext->pSatDevData;
16653 scsiCmnd = &tiScsiRequest->scsiCmnd;
16654 fis = satIOContext->pFis;
16655 pParmList = (bit8 *) tiScsiRequest->sglVirtualAddr;
16656
16657 TI_DBG5(("satReassignBlocks_1: start\n"));
16658
16659 LongLBA = (bit8)(scsiCmnd->cdb[1] & SCSI_REASSIGN_BLOCKS_LONGLBA_MASK);
16660 osti_memset(LBA, 0, sizeof(LBA));
16661
16662 startingIndex = satOrgIOContext->ParmIndex;
16663
16664 if (LongLBA == 0)
16665 {
16666 LBA[4] = pParmList[startingIndex];
16667 LBA[5] = pParmList[startingIndex+1];
16668 LBA[6] = pParmList[startingIndex+2];
16669 LBA[7] = pParmList[startingIndex+3];
16670 startingIndex = startingIndex + 4;
16671 }
16672 else
16673 {
16674 LBA[0] = pParmList[startingIndex];
16675 LBA[1] = pParmList[startingIndex+1];
16676 LBA[2] = pParmList[startingIndex+2];
16677 LBA[3] = pParmList[startingIndex+3];
16678 LBA[4] = pParmList[startingIndex+4];
16679 LBA[5] = pParmList[startingIndex+5];
16680 LBA[6] = pParmList[startingIndex+6];
16681 LBA[7] = pParmList[startingIndex+7];
16682 startingIndex = startingIndex + 8;
16683 }
16684
16685 if (pSatDevData->sat48BitSupport == agTRUE)
16686 {
16687 /* sends READ VERIFY SECTOR(S) EXT*/
16688 fis->h.fisType = 0x27; /* Reg host to device */
16689 fis->h.c_pmPort = 0x80; /* C Bit is set */
16690 fis->h.command = SAT_READ_VERIFY_SECTORS_EXT;/* 0x42 */
16691 fis->h.features = 0; /* FIS reserve */
16692 fis->d.lbaLow = LBA[7]; /* FIS LBA (7 :0 ) */
16693 fis->d.lbaMid = LBA[6]; /* FIS LBA (15:8 ) */
16694 fis->d.lbaHigh = LBA[5]; /* FIS LBA (23:16) */
16695 fis->d.lbaLowExp = LBA[4]; /* FIS LBA (31:24) */
16696 fis->d.lbaMidExp = LBA[3]; /* FIS LBA (39:32) */
16697 fis->d.lbaHighExp = LBA[2]; /* FIS LBA (47:40) */
16698 fis->d.featuresExp = 0; /* FIS reserve */
16699 fis->d.sectorCount = 1; /* FIS sector count (7:0) */
16700 fis->d.sectorCountExp = 0; /* FIS sector count (15:8) */
16701 fis->d.reserved4 = 0;
16702 fis->d.device = 0x40; /* 01000000 */
16703 fis->d.control = 0; /* FIS HOB bit clear */
16704 fis->d.reserved5 = 0;
16705 }
16706 else
16707 {
16708 /* READ VERIFY SECTOR(S)*/
16709 fis->h.fisType = 0x27; /* Reg host to device */
16710 fis->h.c_pmPort = 0x80; /* C Bit is set */
16711 fis->h.command = SAT_READ_VERIFY_SECTORS;/* 0x40 */
16712 fis->h.features = 0; /* FIS features NA */
16713 fis->d.lbaLow = LBA[7]; /* FIS LBA (7 :0 ) */
16714 fis->d.lbaMid = LBA[6]; /* FIS LBA (15:8 ) */
16715 fis->d.lbaHigh = LBA[5]; /* FIS LBA (23:16) */
16716 fis->d.lbaLowExp = 0;
16717 fis->d.lbaMidExp = 0;
16718 fis->d.lbaHighExp = 0;
16719 fis->d.featuresExp = 0;
16720 fis->d.sectorCount = 1; /* FIS sector count (7:0) */
16721 fis->d.sectorCountExp = 0;
16722 fis->d.reserved4 = 0;
16723 fis->d.device = (bit8)((0x4 << 4) | (LBA[4] & 0xF));
16724 /* DEV and LBA 27:24 */
16725 fis->d.control = 0; /* FIS HOB bit clear */
16726 fis->d.reserved5 = 0;
16727 }
16728 osti_memcpy(satOrgIOContext->LBA, LBA, 8);
16729 satOrgIOContext->ParmIndex = startingIndex;
16730 agRequestType = AGSA_SATA_PROTOCOL_NON_DATA;
16731 /* Initialize CB for SATA completion.
16732 */
16733 satIOContext->satCompleteCB = &satReassignBlocksCB;
16734 /*
16735 * Prepare SGL and send FIS to LL layer.
16736 */
16737 satIOContext->reqType = agRequestType; /* Save it */
16738
16739 sataLLIOStart( tiRoot,
16740 tiIORequest,
16741 tiDeviceHandle,
16742 tiScsiRequest,
16743 satIOContext );
16744 return tiSuccess;
16745 }
16746
16747 /*****************************************************************************/
16748 /*! \brief SAT implementation for SCSI satReassignBlocks_2.
16749 *
16750 * SAT implementation for SCSI Reassign Blocks. This is helper function for
16751 * satReassignBlocks and satReassignBlocksCB. This sends ATA write command.
16752 *
16753 * \param tiRoot: Pointer to TISA initiator driver/port instance.
16754 * \param tiIORequest: Pointer to TISA I/O request context for this I/O.
16755 * \param tiDeviceHandle: Pointer to TISA device handle for this I/O.
16756 * \param tiScsiRequest: Pointer to TISA SCSI I/O request and SGL list.
16757 * \param satIOContext_t: Pointer to the SAT IO Context
16758 * \param LBA: Pointer to the LBA to be processed
16759 *
16760 * \return If command is started successfully
16761 * - \e tiSuccess: I/O request successfully initiated.
16762 * - \e tiBusy: No resources available, try again later.
16763 * - \e tiIONoDevice: Invalid device handle.
16764 * - \e tiError: Other errors.
16765 */
16766 /*****************************************************************************/
16767 /* current LBA; sends WRITE */
satReassignBlocks_2(tiRoot_t * tiRoot,tiIORequest_t * tiIORequest,tiDeviceHandle_t * tiDeviceHandle,tiScsiInitiatorRequest_t * tiScsiRequest,satIOContext_t * satIOContext,bit8 * LBA)16768 GLOBAL bit32 satReassignBlocks_2(
16769 tiRoot_t *tiRoot,
16770 tiIORequest_t *tiIORequest,
16771 tiDeviceHandle_t *tiDeviceHandle,
16772 tiScsiInitiatorRequest_t *tiScsiRequest,
16773 satIOContext_t *satIOContext,
16774 bit8 *LBA
16775 )
16776 {
16777 /*
16778 assumes all LBA fits in ATA command; no boundary condition is checked here yet
16779 tiScsiRequest is TD generated for writing
16780 */
16781 bit32 status;
16782 bit32 agRequestType;
16783 satDeviceData_t *pSatDevData;
16784 scsiRspSense_t *pSense;
16785 agsaFisRegHostToDevice_t *fis;
16786
16787 pSense = satIOContext->pSense;
16788 pSatDevData = satIOContext->pSatDevData;
16789 fis = satIOContext->pFis;
16790
16791 if (pSatDevData->satDMASupport == agTRUE && pSatDevData->satDMAEnabled == agTRUE)
16792 {
16793 /* case 2 */
16794 /* WRITE DMA*/
16795 /* can't fit the transfer length */
16796 TI_DBG5(("satReassignBlocks_2: case 2\n"));
16797 fis->h.fisType = 0x27; /* Reg host to device */
16798 fis->h.c_pmPort = 0x80; /* C bit is set */
16799 fis->h.command = SAT_WRITE_DMA; /* 0xCA */
16800 fis->h.features = 0; /* FIS reserve */
16801 fis->d.lbaLow = LBA[7]; /* FIS LBA (7 :0 ) */
16802 fis->d.lbaMid = LBA[6]; /* FIS LBA (15:8 ) */
16803 fis->d.lbaHigh = LBA[5]; /* FIS LBA (23:16) */
16804
16805 /* FIS LBA mode set LBA (27:24) */
16806 fis->d.device = (bit8)((0x4 << 4) | (LBA[4] & 0xF));
16807
16808 fis->d.lbaLowExp = 0;
16809 fis->d.lbaMidExp = 0;
16810 fis->d.lbaHighExp = 0;
16811 fis->d.featuresExp = 0;
16812 fis->d.sectorCount = 1; /* FIS sector count (7:0) */
16813 fis->d.sectorCountExp = 0;
16814 fis->d.reserved4 = 0;
16815 fis->d.control = 0; /* FIS HOB bit clear */
16816 fis->d.reserved5 = 0;
16817
16818 agRequestType = AGSA_SATA_PROTOCOL_DMA_WRITE;
16819 satIOContext->ATACmd = SAT_WRITE_DMA;
16820 }
16821 else
16822 {
16823 /* case 1 */
16824 /* WRITE MULTIPLE or WRITE SECTOR(S) */
16825 /* WRITE SECTORS for easier implemetation */
16826 /* can't fit the transfer length */
16827 TI_DBG5(("satReassignBlocks_2: case 1\n"));
16828 fis->h.fisType = 0x27; /* Reg host to device */
16829 fis->h.c_pmPort = 0x80; /* C bit is set */
16830 fis->h.command = SAT_WRITE_SECTORS; /* 0x30 */
16831 fis->h.features = 0; /* FIS reserve */
16832 fis->d.lbaLow = LBA[7]; /* FIS LBA (7 :0 ) */
16833 fis->d.lbaMid = LBA[6]; /* FIS LBA (15:8 ) */
16834 fis->d.lbaHigh = LBA[7]; /* FIS LBA (23:16) */
16835
16836 /* FIS LBA mode set LBA (27:24) */
16837 fis->d.device = (bit8)((0x4 << 4) | (LBA[4] & 0xF));
16838
16839 fis->d.lbaLowExp = 0;
16840 fis->d.lbaMidExp = 0;
16841 fis->d.lbaHighExp = 0;
16842 fis->d.featuresExp = 0;
16843 fis->d.sectorCount = 1; /* FIS sector count (7:0) */
16844 fis->d.sectorCountExp = 0;
16845 fis->d.reserved4 = 0;
16846 fis->d.control = 0; /* FIS HOB bit clear */
16847 fis->d.reserved5 = 0;
16848
16849 agRequestType = AGSA_SATA_PROTOCOL_PIO_WRITE;
16850 satIOContext->ATACmd = SAT_WRITE_SECTORS;
16851 }
16852
16853 /* case 3 and 4 */
16854 if (pSatDevData->sat48BitSupport == agTRUE)
16855 {
16856 if (pSatDevData->satDMASupport == agTRUE && pSatDevData->satDMAEnabled == agTRUE)
16857 {
16858 /* case 3 */
16859 /* WRITE DMA EXT or WRITE DMA FUA EXT */
16860 TI_DBG5(("satReassignBlocks_2: case 3\n"));
16861 fis->h.fisType = 0x27; /* Reg host to device */
16862 fis->h.c_pmPort = 0x80; /* C Bit is set */
16863
16864 /* SAT_WRITE_DMA_FUA_EXT is optional and we don't support it */
16865 fis->h.command = SAT_WRITE_DMA_EXT; /* 0x35 */
16866 satIOContext->ATACmd = SAT_WRITE_DMA_EXT;
16867
16868 fis->h.features = 0; /* FIS reserve */
16869 fis->d.lbaLow = LBA[7]; /* FIS LBA (7 :0 ) */
16870 fis->d.lbaMid = LBA[6]; /* FIS LBA (15:8 ) */
16871 fis->d.lbaHigh = LBA[5]; /* FIS LBA (23:16) */
16872 fis->d.device = 0x40; /* FIS LBA mode set */
16873 fis->d.lbaLowExp = LBA[4]; /* FIS LBA (31:24) */
16874 fis->d.lbaMidExp = LBA[3]; /* FIS LBA (39:32) */
16875 fis->d.lbaHighExp = LBA[2]; /* FIS LBA (47:40) */
16876 fis->d.featuresExp = 0; /* FIS reserve */
16877 fis->d.sectorCount = 1; /* FIS sector count (7:0) */
16878 fis->d.sectorCountExp = 0; /* FIS sector count (15:8) */
16879 fis->d.reserved4 = 0;
16880 fis->d.control = 0; /* FIS HOB bit clear */
16881 fis->d.reserved5 = 0;
16882
16883 agRequestType = AGSA_SATA_PROTOCOL_DMA_WRITE;
16884 }
16885 else
16886 {
16887 /* case 4 */
16888 /* WRITE MULTIPLE EXT or WRITE MULTIPLE FUA EXT or WRITE SECTOR(S) EXT */
16889 /* WRITE SECTORS EXT for easier implemetation */
16890 TI_DBG5(("satReassignBlocks_2: case 4\n"));
16891 fis->h.fisType = 0x27; /* Reg host to device */
16892 fis->h.c_pmPort = 0x80; /* C Bit is set */
16893 fis->h.command = SAT_WRITE_SECTORS_EXT; /* 0x34 */
16894
16895 fis->h.features = 0; /* FIS reserve */
16896 fis->d.lbaLow = LBA[7]; /* FIS LBA (7 :0 ) */
16897 fis->d.lbaMid = LBA[6]; /* FIS LBA (15:8 ) */
16898 fis->d.lbaHigh = LBA[5]; /* FIS LBA (23:16) */
16899 fis->d.device = 0x40; /* FIS LBA mode set */
16900 fis->d.lbaLowExp = LBA[4]; /* FIS LBA (31:24) */
16901 fis->d.lbaMidExp = LBA[3]; /* FIS LBA (39:32) */
16902 fis->d.lbaHighExp = LBA[2]; /* FIS LBA (47:40) */
16903 fis->d.featuresExp = 0; /* FIS reserve */
16904 fis->d.sectorCount = 1; /* FIS sector count (7:0) */
16905 fis->d.sectorCountExp = 0; /* FIS sector count (15:8) */
16906 fis->d.reserved4 = 0;
16907 fis->d.control = 0; /* FIS HOB bit clear */
16908 fis->d.reserved5 = 0;
16909
16910 agRequestType = AGSA_SATA_PROTOCOL_PIO_WRITE;
16911 satIOContext->ATACmd = SAT_WRITE_SECTORS_EXT;
16912 }
16913 }
16914 /* case 5 */
16915 if (pSatDevData->satNCQ == agTRUE)
16916 {
16917 /* WRITE FPDMA QUEUED */
16918 if (pSatDevData->sat48BitSupport != agTRUE)
16919 {
16920 TI_DBG5(("satReassignBlocks_2: case 5 !!! error NCQ but 28 bit address support \n"));
16921 satSetSensePayload( pSense,
16922 SCSI_SNSKEY_HARDWARE_ERROR,
16923 0,
16924 SCSI_SNSCODE_WRITE_ERROR_AUTO_REALLOCATION_FAILED,
16925 satIOContext);
16926
16927 ostiInitiatorIOCompleted( tiRoot,
16928 tiIORequest,
16929 tiIOSuccess,
16930 SCSI_STAT_CHECK_CONDITION,
16931 satIOContext->pTiSenseData,
16932 satIOContext->interruptContext );
16933 return tiSuccess;
16934 }
16935 TI_DBG6(("satWrite10: case 5\n"));
16936
16937 /* Support 48-bit FPDMA addressing, use WRITE FPDMA QUEUE command */
16938
16939 fis->h.fisType = 0x27; /* Reg host to device */
16940 fis->h.c_pmPort = 0x80; /* C Bit is set */
16941 fis->h.command = SAT_WRITE_FPDMA_QUEUED; /* 0x61 */
16942 fis->h.features = 1; /* FIS sector count (7:0) */
16943 fis->d.lbaLow = LBA[7]; /* FIS LBA (7 :0 ) */
16944 fis->d.lbaMid = LBA[6]; /* FIS LBA (15:8 ) */
16945 fis->d.lbaHigh = LBA[5]; /* FIS LBA (23:16) */
16946
16947 /* Check FUA bit */
16948 fis->d.device = 0x40; /* FIS FUA clear */
16949
16950 fis->d.lbaLowExp = LBA[4]; /* FIS LBA (31:24) */
16951 fis->d.lbaMidExp = LBA[3]; /* FIS LBA (39:32) */
16952 fis->d.lbaHighExp = LBA[2]; /* FIS LBA (47:40) */
16953 fis->d.featuresExp = 0; /* FIS sector count (15:8) */
16954 fis->d.sectorCount = 0; /* Tag (7:3) set by LL layer */
16955 fis->d.sectorCountExp = 0;
16956 fis->d.reserved4 = 0;
16957 fis->d.control = 0; /* FIS HOB bit clear */
16958 fis->d.reserved5 = 0;
16959
16960 agRequestType = AGSA_SATA_PROTOCOL_FPDMA_WRITE;
16961 satIOContext->ATACmd = SAT_WRITE_FPDMA_QUEUED;
16962 }
16963
16964 satIOContext->satCompleteCB = &satReassignBlocksCB;
16965
16966 /*
16967 * Prepare SGL and send FIS to LL layer.
16968 */
16969 satIOContext->reqType = agRequestType; /* Save it */
16970
16971 status = sataLLIOStart( tiRoot,
16972 tiIORequest,
16973 tiDeviceHandle,
16974 /* not the original, should be the TD generated one */
16975 tiScsiRequest,
16976 satIOContext);
16977 return (status);
16978 }
16979
16980
16981 /*****************************************************************************/
16982 /*! \brief SAT implementation for SCSI satPrepareNewIO.
16983 *
16984 * This function fills in the fields of internal IO generated by TD layer.
16985 * This is mostly used in the callback functions.
16986 *
16987 * \param satNewIntIo: Pointer to the internal IO structure.
16988 * \param tiOrgIORequest: Pointer to the original tiIOrequest sent by OS layer
16989 * \param satDevData: Pointer to the device data.
16990 * \param scsiCmnd: Pointer to SCSI command.
16991 * \param satOrgIOContext: Pointer to the original SAT IO Context
16992 *
16993 * \return
16994 * - \e Pointer to the new SAT IO Context
16995 */
16996 /*****************************************************************************/
satPrepareNewIO(satInternalIo_t * satNewIntIo,tiIORequest_t * tiOrgIORequest,satDeviceData_t * satDevData,tiIniScsiCmnd_t * scsiCmnd,satIOContext_t * satOrgIOContext)16997 GLOBAL satIOContext_t *satPrepareNewIO(
16998 satInternalIo_t *satNewIntIo,
16999 tiIORequest_t *tiOrgIORequest,
17000 satDeviceData_t *satDevData,
17001 tiIniScsiCmnd_t *scsiCmnd,
17002 satIOContext_t *satOrgIOContext
17003 )
17004 {
17005 satIOContext_t *satNewIOContext;
17006 tdIORequestBody_t *tdNewIORequestBody;
17007
17008 TI_DBG2(("satPrepareNewIO: start\n"));
17009
17010 /* the one to be used; good 8/2/07 */
17011 satNewIntIo->satOrgTiIORequest = tiOrgIORequest; /* this is already done in
17012 satAllocIntIoResource() */
17013
17014 tdNewIORequestBody = (tdIORequestBody_t *)satNewIntIo->satIntRequestBody;
17015 satNewIOContext = &(tdNewIORequestBody->transport.SATA.satIOContext);
17016
17017 satNewIOContext->pSatDevData = satDevData;
17018 satNewIOContext->pFis = &(tdNewIORequestBody->transport.SATA.agSATARequestBody.fis.fisRegHostToDev);
17019 satNewIOContext->pScsiCmnd = &(satNewIntIo->satIntTiScsiXchg.scsiCmnd);
17020 if (scsiCmnd != agNULL)
17021 {
17022 /* saves only CBD; not scsi command for LBA and number of blocks */
17023 osti_memcpy(satNewIOContext->pScsiCmnd->cdb, scsiCmnd->cdb, 16);
17024 }
17025 satNewIOContext->pSense = &(tdNewIORequestBody->transport.SATA.sensePayload);
17026 satNewIOContext->pTiSenseData = &(tdNewIORequestBody->transport.SATA.tiSenseData);
17027 satNewIOContext->pTiSenseData->senseData = satNewIOContext->pSense;
17028 satNewIOContext->tiRequestBody = satNewIntIo->satIntRequestBody;
17029 satNewIOContext->interruptContext = satNewIOContext->interruptContext;
17030 satNewIOContext->satIntIoContext = satNewIntIo;
17031 satNewIOContext->ptiDeviceHandle = satOrgIOContext->ptiDeviceHandle;
17032 satNewIOContext->satOrgIOContext = satOrgIOContext;
17033 /* saves tiScsiXchg; only for writesame10() */
17034 satNewIOContext->tiScsiXchg = satOrgIOContext->tiScsiXchg;
17035
17036 return satNewIOContext;
17037 }
17038 /*****************************************************************************
17039 *! \brief satIOAbort
17040 *
17041 * This routine is called to initiate a I/O abort to SATL.
17042 * This routine is independent of HW/LL API.
17043 *
17044 * \param tiRoot: Pointer to TISA initiator driver/port instance.
17045 * \param taskTag: Pointer to TISA I/O request context/tag to be aborted.
17046 *
17047 * \return:
17048 *
17049 * \e tiSuccess: I/O request successfully initiated.
17050 * \e tiBusy: No resources available, try again later.
17051 * \e tiError: Other errors that prevent the I/O request to be started.
17052 *
17053 *
17054 *****************************************************************************/
satIOAbort(tiRoot_t * tiRoot,tiIORequest_t * taskTag)17055 GLOBAL bit32 satIOAbort(
17056 tiRoot_t *tiRoot,
17057 tiIORequest_t *taskTag )
17058 {
17059
17060 tdsaRoot_t *tdsaRoot = (tdsaRoot_t *) tiRoot->tdData;
17061 tdsaContext_t *tdsaAllShared = (tdsaContext_t *)&tdsaRoot->tdsaAllShared;
17062 agsaRoot_t *agRoot;
17063 tdIORequestBody_t *tdIORequestBody;
17064 tdIORequestBody_t *tdIONewRequestBody;
17065 agsaIORequest_t *agIORequest;
17066 bit32 status;
17067 agsaIORequest_t *agAbortIORequest;
17068 tdIORequestBody_t *tdAbortIORequestBody;
17069 bit32 PhysUpper32;
17070 bit32 PhysLower32;
17071 bit32 memAllocStatus;
17072 void *osMemHandle;
17073 satIOContext_t *satIOContext;
17074 satInternalIo_t *satIntIo;
17075
17076 TI_DBG2(("satIOAbort: start\n"));
17077
17078 agRoot = &(tdsaAllShared->agRootNonInt);
17079 tdIORequestBody = (tdIORequestBody_t *)taskTag->tdData;
17080
17081 /* needs to distinguish internally generated or externally generated */
17082 satIOContext = &(tdIORequestBody->transport.SATA.satIOContext);
17083 satIntIo = satIOContext->satIntIoContext;
17084 if (satIntIo == agNULL)
17085 {
17086 TI_DBG1(("satIOAbort: External, OS generated\n"));
17087 agIORequest = &(tdIORequestBody->agIORequest);
17088 }
17089 else
17090 {
17091 TI_DBG1(("satIOAbort: Internal, TD generated\n"));
17092 tdIONewRequestBody = (tdIORequestBody_t *)satIntIo->satIntRequestBody;
17093 agIORequest = &(tdIONewRequestBody->agIORequest);
17094 }
17095
17096 /* allocating agIORequest for abort itself */
17097 memAllocStatus = ostiAllocMemory(
17098 tiRoot,
17099 &osMemHandle,
17100 (void **)&tdAbortIORequestBody,
17101 &PhysUpper32,
17102 &PhysLower32,
17103 8,
17104 sizeof(tdIORequestBody_t),
17105 agTRUE
17106 );
17107 if (memAllocStatus != tiSuccess)
17108 {
17109 /* let os process IO */
17110 TI_DBG1(("satIOAbort: ostiAllocMemory failed...\n"));
17111 return tiError;
17112 }
17113
17114 if (tdAbortIORequestBody == agNULL)
17115 {
17116 /* let os process IO */
17117 TI_DBG1(("satIOAbort: ostiAllocMemory returned NULL tdAbortIORequestBody\n"));
17118 return tiError;
17119 }
17120
17121 /* setup task management structure */
17122 tdAbortIORequestBody->IOType.InitiatorTMIO.osMemHandle = osMemHandle;
17123 tdAbortIORequestBody->tiDevHandle = tdIORequestBody->tiDevHandle;
17124
17125 /* initialize agIORequest */
17126 agAbortIORequest = &(tdAbortIORequestBody->agIORequest);
17127 agAbortIORequest->osData = (void *) tdAbortIORequestBody;
17128 agAbortIORequest->sdkData = agNULL; /* LL takes care of this */
17129
17130 /* remember IO to be aborted */
17131 tdAbortIORequestBody->tiIOToBeAbortedRequest = taskTag;
17132
17133 status = saSATAAbort( agRoot, agAbortIORequest, 0, agNULL, 0, agIORequest, agNULL );
17134
17135 TI_DBG5(("satIOAbort: return status=0x%x\n", status));
17136
17137 if (status == AGSA_RC_SUCCESS)
17138 return tiSuccess;
17139 else
17140 return tiError;
17141
17142 }
17143
17144
17145 /*****************************************************************************
17146 *! \brief satTM
17147 *
17148 * This routine is called to initiate a TM request to SATL.
17149 * This routine is independent of HW/LL API.
17150 *
17151 * \param tiRoot: Pointer to TISA initiator driver/port instance.
17152 * \param tiDeviceHandle: Pointer to TISA device handle for this I/O.
17153 * \param task: SAM-3 task management request.
17154 * \param lun: Pointer to LUN.
17155 * \param taskTag: Pointer to the associated task where the TM
17156 * command is to be applied.
17157 * \param currentTaskTag: Pointer to tag/context for this TM request.
17158 *
17159 * \return:
17160 *
17161 * \e tiSuccess: I/O request successfully initiated.
17162 * \e tiBusy: No resources available, try again later.
17163 * \e tiIONoDevice: Invalid device handle.
17164 * \e tiError: Other errors that prevent the I/O request to be started.
17165 *
17166 *
17167 *****************************************************************************/
17168 /* save task in satIOContext */
satTM(tiRoot_t * tiRoot,tiDeviceHandle_t * tiDeviceHandle,bit32 task,tiLUN_t * lun,tiIORequest_t * taskTag,tiIORequest_t * currentTaskTag,tdIORequestBody_t * tiRequestBody,bit32 NotifyOS)17169 osGLOBAL bit32 satTM(
17170 tiRoot_t *tiRoot,
17171 tiDeviceHandle_t *tiDeviceHandle,
17172 bit32 task,
17173 tiLUN_t *lun,
17174 tiIORequest_t *taskTag,
17175 tiIORequest_t *currentTaskTag,
17176 tdIORequestBody_t *tiRequestBody,
17177 bit32 NotifyOS
17178 )
17179 {
17180 tdIORequestBody_t *tdIORequestBody = agNULL;
17181 satIOContext_t *satIOContext = agNULL;
17182 tdsaDeviceData_t *oneDeviceData = agNULL;
17183 bit32 status;
17184
17185 TI_DBG3(("satTM: tiDeviceHandle=%p task=0x%x\n", tiDeviceHandle, task ));
17186
17187 /* set satIOContext fields and etc */
17188 oneDeviceData = (tdsaDeviceData_t *)tiDeviceHandle->tdData;
17189
17190
17191 tdIORequestBody = (tdIORequestBody_t *)tiRequestBody;
17192 satIOContext = &(tdIORequestBody->transport.SATA.satIOContext);
17193
17194 satIOContext->pSatDevData = &oneDeviceData->satDevData;
17195 satIOContext->pFis =
17196 &tdIORequestBody->transport.SATA.agSATARequestBody.fis.fisRegHostToDev;
17197
17198
17199 satIOContext->tiRequestBody = tiRequestBody;
17200 satIOContext->ptiDeviceHandle = tiDeviceHandle;
17201 satIOContext->satIntIoContext = agNULL;
17202 satIOContext->satOrgIOContext = agNULL;
17203
17204 /* followings are used only for internal IO */
17205 satIOContext->currentLBA = 0;
17206 satIOContext->OrgTL = 0;
17207
17208 /* saving task in satIOContext */
17209 satIOContext->TMF = task;
17210
17211 satIOContext->satToBeAbortedIOContext = agNULL;
17212
17213 if (NotifyOS == agTRUE)
17214 {
17215 satIOContext->NotifyOS = agTRUE;
17216 }
17217 else
17218 {
17219 satIOContext->NotifyOS = agFALSE;
17220 }
17221 /*
17222 * Our SAT supports RESET LUN and partially support ABORT TASK (only if there
17223 * is no more than one I/O pending on the drive.
17224 */
17225
17226 if (task == AG_LOGICAL_UNIT_RESET)
17227 {
17228 status = satTmResetLUN( tiRoot,
17229 currentTaskTag,
17230 tiDeviceHandle,
17231 agNULL,
17232 satIOContext,
17233 lun);
17234 return status;
17235 }
17236 #ifdef TO_BE_REMOVED
17237 else if (task == AG_TARGET_WARM_RESET)
17238 {
17239 status = satTmWarmReset( tiRoot,
17240 currentTaskTag,
17241 tiDeviceHandle,
17242 agNULL,
17243 satIOContext);
17244
17245 return status;
17246 }
17247 #endif
17248 else if (task == AG_ABORT_TASK)
17249 {
17250 status = satTmAbortTask( tiRoot,
17251 currentTaskTag,
17252 tiDeviceHandle,
17253 agNULL,
17254 satIOContext,
17255 taskTag);
17256
17257 return status;
17258 }
17259 else if (task == TD_INTERNAL_TM_RESET)
17260 {
17261 status = satTDInternalTmReset( tiRoot,
17262 currentTaskTag,
17263 tiDeviceHandle,
17264 agNULL,
17265 satIOContext);
17266 return status;
17267 }
17268 else
17269 {
17270 TI_DBG1(("satTM: tiDeviceHandle=%p UNSUPPORTED TM task=0x%x\n",
17271 tiDeviceHandle, task ));
17272
17273 /* clean up TD layer's IORequestBody */
17274 ostiFreeMemory(
17275 tiRoot,
17276 tiRequestBody->IOType.InitiatorTMIO.osMemHandle,
17277 sizeof(tdIORequestBody_t)
17278 );
17279 return tiError;
17280 }
17281
17282 }
17283
17284
17285 /*****************************************************************************
17286 *! \brief satTmResetLUN
17287 *
17288 * This routine is called to initiate a TM RESET LUN request to SATL.
17289 * This routine is independent of HW/LL API.
17290 *
17291 * \param tiRoot: Pointer to TISA initiator driver/port instance.
17292 * \param tiDeviceHandle: Pointer to TISA device handle for this I/O.
17293 * \param lun: Pointer to LUN.
17294 * \param currentTaskTag: Pointer to tag/context for this TM request.
17295 *
17296 * \return:
17297 *
17298 * \e tiSuccess: I/O request successfully initiated.
17299 * \e tiBusy: No resources available, try again later.
17300 * \e tiIONoDevice: Invalid device handle.
17301 * \e tiError: Other errors that prevent the I/O request to be started.
17302 *
17303 *
17304 *****************************************************************************/
satTmResetLUN(tiRoot_t * tiRoot,tiIORequest_t * tiIORequest,tiDeviceHandle_t * tiDeviceHandle,tiScsiInitiatorRequest_t * tiScsiRequest,satIOContext_t * satIOContext,tiLUN_t * lun)17305 osGLOBAL bit32 satTmResetLUN(
17306 tiRoot_t *tiRoot,
17307 tiIORequest_t *tiIORequest, /* current task tag */
17308 tiDeviceHandle_t *tiDeviceHandle,
17309 tiScsiInitiatorRequest_t *tiScsiRequest,
17310 satIOContext_t *satIOContext,
17311 tiLUN_t *lun)
17312 {
17313
17314 tdsaDeviceData_t *tdsaDeviceData;
17315 satDeviceData_t *satDevData;
17316
17317 tdsaDeviceData = (tdsaDeviceData_t *)tiDeviceHandle->tdData;
17318 satDevData = &tdsaDeviceData->satDevData;
17319
17320 TI_DBG1(("satTmResetLUN: tiDeviceHandle=%p.\n", tiDeviceHandle ));
17321
17322 /*
17323 * Only support LUN 0
17324 */
17325 if ( (lun->lun[0] | lun->lun[1] | lun->lun[2] | lun->lun[3] |
17326 lun->lun[4] | lun->lun[5] | lun->lun[6] | lun->lun[7] ) != 0 )
17327 {
17328 TI_DBG1(("satTmResetLUN: *** REJECT *** LUN not zero, tiDeviceHandle=%p\n",
17329 tiDeviceHandle));
17330 return tiError;
17331 }
17332
17333 /*
17334 * Check if there is other TM request pending
17335 */
17336 if (satDevData->satTmTaskTag != agNULL)
17337 {
17338 TI_DBG1(("satTmResetLUN: *** REJECT *** other TM pending, tiDeviceHandle=%p\n",
17339 tiDeviceHandle));
17340 return tiError;
17341 }
17342
17343 /*
17344 * Save tiIORequest, will be returned at device reset completion to return
17345 * the TM completion.
17346 */
17347 satDevData->satTmTaskTag = tiIORequest;
17348
17349 /*
17350 * Set flag to indicate device in recovery mode.
17351 */
17352 satDevData->satDriveState = SAT_DEV_STATE_IN_RECOVERY;
17353
17354 /*
17355 * Issue SATA device reset. Set flag to indicate NOT to automatically abort
17356 * at the completion of SATA device reset.
17357 */
17358 satDevData->satAbortAfterReset = agFALSE;
17359
17360 /* SAT rev8 6.3.6 p22 */
17361 satStartResetDevice(
17362 tiRoot,
17363 tiIORequest, /* currentTaskTag */
17364 tiDeviceHandle,
17365 tiScsiRequest,
17366 satIOContext
17367 );
17368
17369
17370 return tiSuccess;
17371
17372 }
17373
17374 /*****************************************************************************
17375 *! \brief satTmWarmReset
17376 *
17377 * This routine is called to initiate a TM warm RESET request to SATL.
17378 * This routine is independent of HW/LL API.
17379 *
17380 * \param tiRoot: Pointer to TISA initiator driver/port instance.
17381 * \param tiDeviceHandle: Pointer to TISA device handle for this I/O.
17382 * \param currentTaskTag: Pointer to tag/context for this TM request.
17383 *
17384 * \return:
17385 *
17386 * \e tiSuccess: I/O request successfully initiated.
17387 * \e tiBusy: No resources available, try again later.
17388 * \e tiIONoDevice: Invalid device handle.
17389 * \e tiError: Other errors that prevent the I/O request to be started.
17390 *
17391 *
17392 *****************************************************************************/
satTmWarmReset(tiRoot_t * tiRoot,tiIORequest_t * tiIORequest,tiDeviceHandle_t * tiDeviceHandle,tiScsiInitiatorRequest_t * tiScsiRequest,satIOContext_t * satIOContext)17393 osGLOBAL bit32 satTmWarmReset(
17394 tiRoot_t *tiRoot,
17395 tiIORequest_t *tiIORequest, /* current task tag */
17396 tiDeviceHandle_t *tiDeviceHandle,
17397 tiScsiInitiatorRequest_t *tiScsiRequest,
17398 satIOContext_t *satIOContext)
17399 {
17400
17401 tdsaDeviceData_t *tdsaDeviceData;
17402 satDeviceData_t *satDevData;
17403
17404 tdsaDeviceData = (tdsaDeviceData_t *)tiDeviceHandle->tdData;
17405 satDevData = &tdsaDeviceData->satDevData;
17406
17407 TI_DBG1(("satTmWarmReset: tiDeviceHandle=%p.\n", tiDeviceHandle ));
17408
17409 /*
17410 * Check if there is other TM request pending
17411 */
17412 if (satDevData->satTmTaskTag != agNULL)
17413 {
17414 TI_DBG1(("satTmWarmReset: *** REJECT *** other TM pending, tiDeviceHandle=%p\n",
17415 tiDeviceHandle));
17416 return tiError;
17417 }
17418
17419 /*
17420 * Save tiIORequest, will be returned at device reset completion to return
17421 * the TM completion.
17422 */
17423 satDevData->satTmTaskTag = tiIORequest;
17424
17425 /*
17426 * Set flag to indicate device in recovery mode.
17427 */
17428 satDevData->satDriveState = SAT_DEV_STATE_IN_RECOVERY;
17429
17430 /*
17431 * Issue SATA device reset. Set flag to indicate NOT to automatically abort
17432 * at the completion of SATA device reset.
17433 */
17434 satDevData->satAbortAfterReset = agFALSE;
17435
17436 /* SAT rev8 6.3.6 p22 */
17437 satStartResetDevice(
17438 tiRoot,
17439 tiIORequest, /* currentTaskTag */
17440 tiDeviceHandle,
17441 tiScsiRequest,
17442 satIOContext
17443 );
17444
17445 return tiSuccess;
17446
17447 }
17448
satTDInternalTmReset(tiRoot_t * tiRoot,tiIORequest_t * tiIORequest,tiDeviceHandle_t * tiDeviceHandle,tiScsiInitiatorRequest_t * tiScsiRequest,satIOContext_t * satIOContext)17449 osGLOBAL bit32 satTDInternalTmReset(
17450 tiRoot_t *tiRoot,
17451 tiIORequest_t *tiIORequest, /* current task tag */
17452 tiDeviceHandle_t *tiDeviceHandle,
17453 tiScsiInitiatorRequest_t *tiScsiRequest,
17454 satIOContext_t *satIOContext)
17455 {
17456
17457 tdsaDeviceData_t *tdsaDeviceData;
17458 satDeviceData_t *satDevData;
17459
17460 tdsaDeviceData = (tdsaDeviceData_t *)tiDeviceHandle->tdData;
17461 satDevData = &tdsaDeviceData->satDevData;
17462
17463 TI_DBG1(("satTmWarmReset: tiDeviceHandle=%p.\n", tiDeviceHandle ));
17464
17465 /*
17466 * Check if there is other TM request pending
17467 */
17468 if (satDevData->satTmTaskTag != agNULL)
17469 {
17470 TI_DBG1(("satTmWarmReset: *** REJECT *** other TM pending, tiDeviceHandle=%p\n",
17471 tiDeviceHandle));
17472 return tiError;
17473 }
17474
17475 /*
17476 * Save tiIORequest, will be returned at device reset completion to return
17477 * the TM completion.
17478 */
17479 satDevData->satTmTaskTag = tiIORequest;
17480
17481 /*
17482 * Set flag to indicate device in recovery mode.
17483 */
17484 satDevData->satDriveState = SAT_DEV_STATE_IN_RECOVERY;
17485
17486 /*
17487 * Issue SATA device reset. Set flag to indicate NOT to automatically abort
17488 * at the completion of SATA device reset.
17489 */
17490 satDevData->satAbortAfterReset = agFALSE;
17491
17492 /* SAT rev8 6.3.6 p22 */
17493 satStartResetDevice(
17494 tiRoot,
17495 tiIORequest, /* currentTaskTag */
17496 tiDeviceHandle,
17497 tiScsiRequest,
17498 satIOContext
17499 );
17500
17501 return tiSuccess;
17502
17503 }
17504
17505 /*****************************************************************************
17506 *! \brief satTmAbortTask
17507 *
17508 * This routine is called to initiate a TM ABORT TASK request to SATL.
17509 * This routine is independent of HW/LL API.
17510 *
17511 * \param tiRoot: Pointer to TISA initiator driver/port instance.
17512 * \param tiDeviceHandle: Pointer to TISA device handle for this I/O.
17513 * \param taskTag: Pointer to the associated task where the TM
17514 * command is to be applied.
17515 * \param currentTaskTag: Pointer to tag/context for this TM request.
17516 *
17517 * \return:
17518 *
17519 * \e tiSuccess: I/O request successfully initiated.
17520 * \e tiBusy: No resources available, try again later.
17521 * \e tiIONoDevice: Invalid device handle.
17522 * \e tiError: Other errors that prevent the I/O request to be started.
17523 *
17524 *
17525 *****************************************************************************/
satTmAbortTask(tiRoot_t * tiRoot,tiIORequest_t * tiIORequest,tiDeviceHandle_t * tiDeviceHandle,tiScsiInitiatorRequest_t * tiScsiRequest,satIOContext_t * satIOContext,tiIORequest_t * taskTag)17526 osGLOBAL bit32 satTmAbortTask(
17527 tiRoot_t *tiRoot,
17528 tiIORequest_t *tiIORequest, /* current task tag */
17529 tiDeviceHandle_t *tiDeviceHandle,
17530 tiScsiInitiatorRequest_t *tiScsiRequest, /* NULL */
17531 satIOContext_t *satIOContext,
17532 tiIORequest_t *taskTag)
17533 {
17534
17535 tdsaDeviceData_t *tdsaDeviceData;
17536 satDeviceData_t *satDevData;
17537 satIOContext_t *satTempIOContext = agNULL;
17538 tdIORequestBody_t *tdIORequestBody;
17539 tdIORequestBody_t *TMtdIORequestBody;
17540 tdList_t *elementHdr;
17541 bit32 found = agFALSE;
17542 tiIORequest_t *tiIOReq;
17543
17544 tdsaDeviceData = (tdsaDeviceData_t *)tiDeviceHandle->tdData;
17545 satDevData = &tdsaDeviceData->satDevData;
17546 TMtdIORequestBody = (tdIORequestBody_t *)tiIORequest->tdData;
17547
17548 TI_DBG1(("satTmAbortTask: tiDeviceHandle=%p taskTag=%p.\n", tiDeviceHandle, taskTag ));
17549 /*
17550 * Check if there is other TM request pending
17551 */
17552 if (satDevData->satTmTaskTag != agNULL)
17553 {
17554 TI_DBG1(("satTmAbortTask: REJECT other TM pending, tiDeviceHandle=%p\n",
17555 tiDeviceHandle));
17556 /* clean up TD layer's IORequestBody */
17557 ostiFreeMemory(
17558 tiRoot,
17559 TMtdIORequestBody->IOType.InitiatorTMIO.osMemHandle,
17560 sizeof(tdIORequestBody_t)
17561 );
17562 return tiError;
17563 }
17564
17565 #ifdef REMOVED
17566 /*
17567 * Check if there is only one I/O pending.
17568 */
17569 if (satDevData->satPendingIO > 0)
17570 {
17571 TI_DBG1(("satTmAbortTask: REJECT num pending I/O, tiDeviceHandle=%p, satPendingIO=0x%x\n",
17572 tiDeviceHandle, satDevData->satPendingIO));
17573 /* clean up TD layer's IORequestBody */
17574 ostiFreeMemory(
17575 tiRoot,
17576 TMtdIORequestBody->IOType.InitiatorTMIO.osMemHandle,
17577 sizeof(tdIORequestBody_t)
17578 );
17579
17580 return tiError;
17581 }
17582 #endif
17583
17584 /*
17585 * Check that the only pending I/O matches taskTag. If not return tiError.
17586 */
17587 elementHdr = satDevData->satIoLinkList.flink;
17588
17589 while (elementHdr != &satDevData->satIoLinkList)
17590 {
17591 satTempIOContext = TDLIST_OBJECT_BASE( satIOContext_t,
17592 satIoContextLink,
17593 elementHdr );
17594
17595 tdIORequestBody = (tdIORequestBody_t *) satTempIOContext->tiRequestBody;
17596 tiIOReq = tdIORequestBody->tiIORequest;
17597
17598 elementHdr = elementHdr->flink; /* for the next while loop */
17599
17600 /*
17601 * Check if the tag matches
17602 */
17603 if ( tiIOReq == taskTag)
17604 {
17605 found = agTRUE;
17606 satIOContext->satToBeAbortedIOContext = satTempIOContext;
17607 TI_DBG1(("satTmAbortTask: found matching tag.\n"));
17608
17609 break;
17610
17611 } /* if matching tag */
17612
17613 } /* while loop */
17614
17615
17616 if (found == agFALSE )
17617 {
17618 TI_DBG1(("satTmAbortTask: *** REJECT *** no match, tiDeviceHandle=%p\n",
17619 tiDeviceHandle ));
17620
17621 /* clean up TD layer's IORequestBody */
17622 ostiFreeMemory(
17623 tiRoot,
17624 TMtdIORequestBody->IOType.InitiatorTMIO.osMemHandle,
17625 sizeof(tdIORequestBody_t)
17626 );
17627
17628 return tiError;
17629 }
17630
17631 /*
17632 * Save tiIORequest, will be returned at device reset completion to return
17633 * the TM completion.
17634 */
17635 satDevData->satTmTaskTag = tiIORequest;
17636
17637 /*
17638 * Set flag to indicate device in recovery mode.
17639 */
17640 satDevData->satDriveState = SAT_DEV_STATE_IN_RECOVERY;
17641
17642
17643 /*
17644 * Issue SATA device reset or check power mode. Set flag to to automatically abort
17645 * at the completion of SATA device reset.
17646 * SAT r09 p25
17647 */
17648 satDevData->satAbortAfterReset = agTRUE;
17649
17650 if ( (satTempIOContext->reqType == AGSA_SATA_PROTOCOL_FPDMA_WRITE) ||
17651 (satTempIOContext->reqType == AGSA_SATA_PROTOCOL_FPDMA_READ)
17652 )
17653 {
17654 TI_DBG1(("satTmAbortTask: calling satStartCheckPowerMode\n"));
17655 /* send check power mode */
17656 satStartCheckPowerMode(
17657 tiRoot,
17658 tiIORequest, /* currentTaskTag */
17659 tiDeviceHandle,
17660 tiScsiRequest,
17661 satIOContext
17662 );
17663 }
17664 else
17665 {
17666 TI_DBG1(("satTmAbortTask: calling satStartResetDevice\n"));
17667 /* send AGSA_SATA_PROTOCOL_SRST_ASSERT */
17668 satStartResetDevice(
17669 tiRoot,
17670 tiIORequest, /* currentTaskTag */
17671 tiDeviceHandle,
17672 tiScsiRequest,
17673 satIOContext
17674 );
17675 }
17676
17677
17678 return tiSuccess;
17679 }
17680
17681 /*****************************************************************************
17682 *! \brief osSatResetCB
17683 *
17684 * This routine is called to notify the completion of SATA device reset
17685 * which was initiated previously through the call to sataLLReset().
17686 * This routine is independent of HW/LL API.
17687 *
17688 * \param tiRoot: Pointer to TISA initiator driver/port instance.
17689 * \param tiDeviceHandle: Pointer to TISA device handle for this I/O.
17690 * \param resetStatus: Reset status either tiSuccess or tiError.
17691 * \param respFis: Pointer to the Register Device-To-Host FIS
17692 * received from the device.
17693 *
17694 * \return: None
17695 *
17696 *****************************************************************************/
osSatResetCB(tiRoot_t * tiRoot,tiDeviceHandle_t * tiDeviceHandle,bit32 resetStatus,void * respFis)17697 osGLOBAL void osSatResetCB(
17698 tiRoot_t *tiRoot,
17699 tiDeviceHandle_t *tiDeviceHandle,
17700 bit32 resetStatus,
17701 void *respFis)
17702 {
17703
17704 agsaRoot_t *agRoot;
17705 tdsaDeviceData_t *tdsaDeviceData;
17706 satDeviceData_t *satDevData;
17707 satIOContext_t *satIOContext;
17708 tdIORequestBody_t *tdIORequestBodyTmp;
17709 tdList_t *elementHdr;
17710 agsaIORequest_t *agAbortIORequest;
17711 tdIORequestBody_t *tdAbortIORequestBody;
17712 bit32 PhysUpper32;
17713 bit32 PhysLower32;
17714 bit32 memAllocStatus;
17715 void *osMemHandle;
17716
17717 tdsaDeviceData = (tdsaDeviceData_t *)tiDeviceHandle->tdData;
17718 agRoot = tdsaDeviceData->agRoot;
17719 satDevData = &tdsaDeviceData->satDevData;
17720
17721 TI_DBG5(("osSatResetCB: tiDeviceHandle=%p resetStatus=0x%x\n",
17722 tiDeviceHandle, resetStatus ));
17723
17724 /* We may need to check FIS to check device operating condition */
17725
17726
17727 /*
17728 * Check if need to abort all pending I/Os
17729 */
17730 if ( satDevData->satAbortAfterReset == agTRUE )
17731 {
17732 /*
17733 * Issue abort to LL layer to all other pending I/Os for the same SATA drive
17734 */
17735 elementHdr = satDevData->satIoLinkList.flink;
17736 while (elementHdr != &satDevData->satIoLinkList)
17737 {
17738 satIOContext = TDLIST_OBJECT_BASE( satIOContext_t,
17739 satIoContextLink,
17740 elementHdr );
17741
17742 tdIORequestBodyTmp = (tdIORequestBody_t *)satIOContext->tiRequestBody;
17743
17744 /*
17745 * Issue abort
17746 */
17747 TI_DBG5(("osSatResetCB: issuing ABORT tiDeviceHandle=%p agIORequest=%p\n",
17748 tiDeviceHandle, &tdIORequestBodyTmp->agIORequest ));
17749
17750 /* allocating agIORequest for abort itself */
17751 memAllocStatus = ostiAllocMemory(
17752 tiRoot,
17753 &osMemHandle,
17754 (void **)&tdAbortIORequestBody,
17755 &PhysUpper32,
17756 &PhysLower32,
17757 8,
17758 sizeof(tdIORequestBody_t),
17759 agTRUE
17760 );
17761
17762 if (memAllocStatus != tiSuccess)
17763 {
17764 /* let os process IO */
17765 TI_DBG1(("osSatResetCB: ostiAllocMemory failed...\n"));
17766 return;
17767 }
17768
17769 if (tdAbortIORequestBody == agNULL)
17770 {
17771 /* let os process IO */
17772 TI_DBG1(("osSatResetCB: ostiAllocMemory returned NULL tdAbortIORequestBody\n"));
17773 return;
17774 }
17775 /* setup task management structure */
17776 tdAbortIORequestBody->IOType.InitiatorTMIO.osMemHandle = osMemHandle;
17777 tdAbortIORequestBody->tiDevHandle = tiDeviceHandle;
17778
17779 /* initialize agIORequest */
17780 agAbortIORequest = &(tdAbortIORequestBody->agIORequest);
17781 agAbortIORequest->osData = (void *) tdAbortIORequestBody;
17782 agAbortIORequest->sdkData = agNULL; /* LL takes care of this */
17783
17784 saSATAAbort( agRoot, agAbortIORequest, 0, agNULL, 0, &(tdIORequestBodyTmp->agIORequest), agNULL );
17785 elementHdr = elementHdr->flink; /* for the next while loop */
17786
17787 } /* while */
17788
17789 /* Reset flag */
17790 satDevData->satAbortAfterReset = agFALSE;
17791
17792 }
17793
17794
17795 /*
17796 * Check if the device reset if the result of TM request.
17797 */
17798 if ( satDevData->satTmTaskTag != agNULL )
17799 {
17800 TI_DBG5(("osSatResetCB: calling TM completion tiDeviceHandle=%p satTmTaskTag=%p\n",
17801 tiDeviceHandle, satDevData->satTmTaskTag ));
17802
17803 ostiInitiatorEvent( tiRoot,
17804 agNULL, /* portalContext not used */
17805 tiDeviceHandle,
17806 tiIntrEventTypeTaskManagement,
17807 tiTMOK,
17808 satDevData->satTmTaskTag);
17809 /*
17810 * Reset flag
17811 */
17812 satDevData->satTmTaskTag = agNULL;
17813 }
17814
17815 }
17816
17817
17818 /*****************************************************************************
17819 *! \brief osSatIOCompleted
17820 *
17821 * This routine is a callback for SATA completion that required FIS status
17822 * translation to SCSI status.
17823 *
17824 * \param tiRoot: Pointer to TISA initiator driver/port instance.
17825 * \param tiIORequest: Pointer to TISA I/O request context for this I/O.
17826 * \param respFis: Pointer to status FIS to read.
17827 * \param respFisLen: Length of response FIS to read.
17828 * \param satIOContext: Pointer to SAT context.
17829 * \param interruptContext: Interrupt context
17830 *
17831 * \return: None
17832 *
17833 *****************************************************************************/
osSatIOCompleted(tiRoot_t * tiRoot,tiIORequest_t * tiIORequest,agsaFisHeader_t * agFirstDword,bit32 respFisLen,agsaFrameHandle_t agFrameHandle,satIOContext_t * satIOContext,bit32 interruptContext)17834 osGLOBAL void osSatIOCompleted(
17835 tiRoot_t *tiRoot,
17836 tiIORequest_t *tiIORequest,
17837 agsaFisHeader_t *agFirstDword,
17838 bit32 respFisLen,
17839 agsaFrameHandle_t agFrameHandle,
17840 satIOContext_t *satIOContext,
17841 bit32 interruptContext)
17842
17843 {
17844 satDeviceData_t *pSatDevData;
17845 scsiRspSense_t *pSense;
17846 #ifdef TD_DEBUG_ENABLE
17847 tiIniScsiCmnd_t *pScsiCmnd;
17848 #endif
17849 agsaFisRegHostToDevice_t *hostToDevFis = agNULL;
17850 bit32 ataStatus = 0;
17851 bit32 ataError;
17852 satInternalIo_t *satIntIo = agNULL;
17853 bit32 status;
17854 tiDeviceHandle_t *tiDeviceHandle;
17855 satIOContext_t *satIOContext2;
17856 tdIORequestBody_t *tdIORequestBody;
17857 agsaFisRegD2HHeader_t *statDevToHostFisHeader = agNULL;
17858 agsaFisSetDevBitsHeader_t *statSetDevBitFisHeader = agNULL;
17859 tiIORequest_t tiIORequestTMP;
17860
17861 pSense = satIOContext->pSense;
17862 pSatDevData = satIOContext->pSatDevData;
17863 #ifdef TD_DEBUG_ENABLE
17864 pScsiCmnd = satIOContext->pScsiCmnd;
17865 #endif
17866 hostToDevFis = satIOContext->pFis;
17867
17868 tiDeviceHandle = &((tdsaDeviceData_t *)(pSatDevData->satSaDeviceData))->tiDeviceHandle;
17869 /*
17870 * Find out the type of response FIS:
17871 * Set Device Bit FIS or Reg Device To Host FIS.
17872 */
17873
17874 /* First assume it is Reg Device to Host FIS */
17875 statDevToHostFisHeader = (agsaFisRegD2HHeader_t *)&(agFirstDword->D2H);
17876 ataStatus = statDevToHostFisHeader->status; /* ATA Status register */
17877 ataError = statDevToHostFisHeader->error; /* ATA Eror register */
17878
17879 /* for debugging */
17880 TI_DBG1(("osSatIOCompleted: H to D command 0x%x\n", hostToDevFis->h.command));
17881 TI_DBG1(("osSatIOCompleted: D to H fistype 0x%x\n", statDevToHostFisHeader->fisType));
17882
17883
17884 if (statDevToHostFisHeader->fisType == SET_DEV_BITS_FIS)
17885 {
17886 /* It is Set Device Bits FIS */
17887 statSetDevBitFisHeader = (agsaFisSetDevBitsHeader_t *)&(agFirstDword->D2H);
17888 /* Get ATA Status register */
17889 ataStatus = (statSetDevBitFisHeader->statusHi_Lo & 0x70); /* bits 4,5,6 */
17890 ataStatus = ataStatus | (statSetDevBitFisHeader->statusHi_Lo & 0x07); /* bits 0,1,2 */
17891
17892 /* ATA Eror register */
17893 ataError = statSetDevBitFisHeader->error;
17894
17895 statDevToHostFisHeader = agNULL;
17896 }
17897
17898 else if (statDevToHostFisHeader->fisType != REG_DEV_TO_HOST_FIS)
17899 {
17900 TI_DBG1(("osSatIOCompleted: *** UNEXPECTED RESP FIS TYPE 0x%x *** tiIORequest=%p\n",
17901 statDevToHostFisHeader->fisType, tiIORequest));
17902
17903 satSetSensePayload( pSense,
17904 SCSI_SNSKEY_HARDWARE_ERROR,
17905 0,
17906 SCSI_SNSCODE_INTERNAL_TARGET_FAILURE,
17907 satIOContext);
17908
17909 ostiInitiatorIOCompleted( tiRoot,
17910 tiIORequest,
17911 tiIOSuccess,
17912 SCSI_STAT_CHECK_CONDITION,
17913 satIOContext->pTiSenseData,
17914 interruptContext );
17915 return;
17916
17917 }
17918
17919 if ( ataStatus & DF_ATA_STATUS_MASK )
17920 {
17921 pSatDevData->satDeviceFaultState = agTRUE;
17922 }
17923 else
17924 {
17925 pSatDevData->satDeviceFaultState = agFALSE;
17926 }
17927
17928 TI_DBG5(("osSatIOCompleted: tiIORequest=%p CDB=0x%x ATA CMD =0x%x\n",
17929 tiIORequest, pScsiCmnd->cdb[0], hostToDevFis->h.command));
17930
17931 /*
17932 * Decide which ATA command is the translation needed
17933 */
17934 switch(hostToDevFis->h.command)
17935 {
17936 case SAT_READ_FPDMA_QUEUED:
17937 case SAT_WRITE_FPDMA_QUEUED:
17938
17939 /************************************************************************
17940 *
17941 * !!!! See Section 13.5.2.4 of SATA 2.5 specs. !!!!
17942 * !!!! If the NCQ error ends up here, it means that the device sent !!!!
17943 * !!!! Set Device Bit FIS (which has SActive register) instead of !!!!
17944 * !!!! Register Device To Host FIS (which does not have SActive !!!!
17945 * !!!! register). The callback ossaSATAEvent() deals with the case !!!!
17946 * !!!! where Register Device To Host FIS was sent by the device. !!!!
17947 *
17948 * For NCQ we need to issue READ LOG EXT command with log page 10h
17949 * to get the error and to allow other I/Os to continue.
17950 *
17951 * Here is the basic flow or sequence of error recovery, note that due
17952 * to the SATA HW assist that we have, this sequence is slighly different
17953 * from the one described in SATA 2.5:
17954 *
17955 * 1. Set SATA device flag to indicate error condition and returning busy
17956 * for all new request.
17957 * return tiSuccess;
17958
17959 * 2. Because the HW/LL layer received Set Device Bit FIS, it can get the
17960 * tag or I/O context for NCQ request, SATL would translate the ATA error
17961 * to SCSI status and return the original NCQ I/O with the appopriate
17962 * SCSI status.
17963 *
17964 * 3. Prepare READ LOG EXT page 10h command. Set flag to indicate that
17965 * the failed I/O has been returned to the OS Layer. Send command.
17966 *
17967 * 4. When the device receives READ LOG EXT page 10h request all other
17968 * pending I/O are implicitly aborted. No completion (aborted) status
17969 * will be sent to the host for these aborted commands.
17970 *
17971 * 5. SATL receives the completion for READ LOG EXT command in
17972 * satReadLogExtCB(). Steps 6,7,8,9 below are the step 1,2,3,4 in
17973 * satReadLogExtCB().
17974 *
17975 * 6. Check flag that indicates whether the failed I/O has been returned
17976 * to the OS Layer. If not, search the I/O context in device data
17977 * looking for a matched tag. Then return the completion of the failed
17978 * NCQ command with the appopriate/trasnlated SCSI status.
17979 *
17980 * 7. Issue abort to LL layer to all other pending I/Os for the same SATA
17981 * drive.
17982 *
17983 * 8. Free resource allocated for the internally generated READ LOG EXT.
17984 *
17985 * 9. At the completion of abort, in the context of ossaSATACompleted(),
17986 * return the I/O with error status to the OS-App Specific layer.
17987 * When all I/O aborts are completed, clear SATA device flag to
17988 * indicate ready to process new request.
17989 *
17990 ***********************************************************************/
17991
17992 TI_DBG1(("osSatIOCompleted: NCQ ERROR tiIORequest=%p ataStatus=0x%x ataError=0x%x\n",
17993 tiIORequest, ataStatus, ataError ));
17994
17995 /* Set flag to indicate we are in recovery */
17996 pSatDevData->satDriveState = SAT_DEV_STATE_IN_RECOVERY;
17997
17998 /* Return the failed NCQ I/O to OS-Apps Specifiic layer */
17999 osSatDefaultTranslation( tiRoot,
18000 tiIORequest,
18001 satIOContext,
18002 pSense,
18003 (bit8)ataStatus,
18004 (bit8)ataError,
18005 interruptContext );
18006
18007 /*
18008 * Allocate resource for READ LOG EXT page 10h
18009 */
18010 satIntIo = satAllocIntIoResource( tiRoot,
18011 &(tiIORequestTMP), /* anything but NULL */
18012 pSatDevData,
18013 sizeof (satReadLogExtPage10h_t),
18014 satIntIo);
18015
18016 if (satIntIo == agNULL)
18017 {
18018 TI_DBG1(("osSatIOCompleted: can't send RLE due to resource lack\n"));
18019
18020 /* Abort I/O after completion of device reset */
18021 pSatDevData->satAbortAfterReset = agTRUE;
18022 #ifdef NOT_YET
18023 /* needs further investigation */
18024 /* no report to OS layer */
18025 satSubTM(tiRoot,
18026 tiDeviceHandle,
18027 TD_INTERNAL_TM_RESET,
18028 agNULL,
18029 agNULL,
18030 agNULL,
18031 agFALSE);
18032 #endif
18033
18034
18035 TI_DBG1(("osSatIOCompleted: calling saSATADeviceReset 1\n"));
18036 return;
18037 }
18038
18039
18040 /*
18041 * Set flag to indicate that the failed I/O has been returned to the
18042 * OS-App specific Layer.
18043 */
18044 satIntIo->satIntFlag = AG_SAT_INT_IO_FLAG_ORG_IO_COMPLETED;
18045
18046 /* compare to satPrepareNewIO() */
18047 /* Send READ LOG EXIT page 10h command */
18048
18049 /*
18050 * Need to initialize all the fields within satIOContext except
18051 * reqType and satCompleteCB which will be set depending on cmd.
18052 */
18053
18054 tdIORequestBody = (tdIORequestBody_t *)satIntIo->satIntRequestBody;
18055 satIOContext2 = &(tdIORequestBody->transport.SATA.satIOContext);
18056
18057 satIOContext2->pSatDevData = pSatDevData;
18058 satIOContext2->pFis = &(tdIORequestBody->transport.SATA.agSATARequestBody.fis.fisRegHostToDev);
18059 satIOContext2->pScsiCmnd = &(satIntIo->satIntTiScsiXchg.scsiCmnd);
18060 satIOContext2->pSense = &(tdIORequestBody->transport.SATA.sensePayload);
18061 satIOContext2->pTiSenseData = &(tdIORequestBody->transport.SATA.tiSenseData);
18062 satIOContext2->pTiSenseData->senseData = satIOContext2->pSense;
18063
18064 satIOContext2->tiRequestBody = satIntIo->satIntRequestBody;
18065 satIOContext2->interruptContext = interruptContext;
18066 satIOContext2->satIntIoContext = satIntIo;
18067
18068 satIOContext2->ptiDeviceHandle = tiDeviceHandle;
18069 satIOContext2->satOrgIOContext = agNULL;
18070 satIOContext2->tiScsiXchg = agNULL;
18071
18072 status = satSendReadLogExt( tiRoot,
18073 &satIntIo->satIntTiIORequest,
18074 tiDeviceHandle,
18075 &satIntIo->satIntTiScsiXchg,
18076 satIOContext2);
18077
18078 if (status != tiSuccess)
18079 {
18080 TI_DBG1(("osSatIOCompleted: can't send RLE due to LL api failure\n"));
18081 satFreeIntIoResource( tiRoot,
18082 pSatDevData,
18083 satIntIo);
18084
18085 /* Abort I/O after completion of device reset */
18086 pSatDevData->satAbortAfterReset = agTRUE;
18087 #ifdef NOT_YET
18088 /* needs further investigation */
18089 /* no report to OS layer */
18090 satSubTM(tiRoot,
18091 tiDeviceHandle,
18092 TD_INTERNAL_TM_RESET,
18093 agNULL,
18094 agNULL,
18095 agNULL,
18096 agFALSE);
18097 #endif
18098
18099 TI_DBG1(("osSatIOCompleted: calling saSATADeviceReset 2\n"));
18100 return;
18101 }
18102
18103 break;
18104
18105 case SAT_READ_DMA_EXT:
18106 /* fall through */
18107 /* Use default status/error translation */
18108
18109 case SAT_READ_DMA:
18110 /* fall through */
18111 /* Use default status/error translation */
18112
18113 default:
18114 osSatDefaultTranslation( tiRoot,
18115 tiIORequest,
18116 satIOContext,
18117 pSense,
18118 (bit8)ataStatus,
18119 (bit8)ataError,
18120 interruptContext );
18121 break;
18122
18123 } /* end switch */
18124 }
18125
18126
18127 /*****************************************************************************/
18128 /*! \brief SAT implementation for SCSI STANDARD INQUIRY.
18129 *
18130 * SAT implementation for SCSI STANDARD INQUIRY.
18131 *
18132 * \param pInquiry: Pointer to Inquiry Data buffer.
18133 * \param pSATAIdData: Pointer to ATA IDENTIFY DEVICE data.
18134 *
18135 * \return None.
18136 */
18137 /*****************************************************************************/
satInquiryStandard(bit8 * pInquiry,agsaSATAIdentifyData_t * pSATAIdData,tiIniScsiCmnd_t * scsiCmnd)18138 GLOBAL void satInquiryStandard(
18139 bit8 *pInquiry,
18140 agsaSATAIdentifyData_t *pSATAIdData,
18141 tiIniScsiCmnd_t *scsiCmnd
18142 )
18143 {
18144 tiLUN_t *pLun;
18145 pLun = &scsiCmnd->lun;
18146
18147 /*
18148 Assumption: Basic Task Mangement is supported
18149 -> BQUE 1 and CMDQUE 0, SPC-4, Table96, p147
18150 */
18151 /*
18152 See SPC-4, 6.4.2, p 143
18153 and SAT revision 8, 8.1.2, p 28
18154 */
18155
18156 TI_DBG5(("satInquiryStandard: start\n"));
18157
18158 if (pInquiry == agNULL)
18159 {
18160 TI_DBG1(("satInquiryStandard: pInquiry is NULL, wrong\n"));
18161 return;
18162 }
18163 else
18164 {
18165 TI_DBG5(("satInquiryStandard: pInquiry is NOT NULL\n"));
18166 }
18167 /*
18168 * Reject all other LUN other than LUN 0.
18169 */
18170 if ( ((pLun->lun[0] | pLun->lun[1] | pLun->lun[2] | pLun->lun[3] |
18171 pLun->lun[4] | pLun->lun[5] | pLun->lun[6] | pLun->lun[7] ) != 0) )
18172 {
18173 /* SAT Spec Table 8, p27, footnote 'a' */
18174 pInquiry[0] = 0x7F;
18175
18176 }
18177 else
18178 {
18179 pInquiry[0] = 0x00;
18180 }
18181
18182 if (pSATAIdData->rm_ataDevice & ATA_REMOVABLE_MEDIA_DEVICE_MASK )
18183 {
18184 pInquiry[1] = 0x80;
18185 }
18186 else
18187 {
18188 pInquiry[1] = 0x00;
18189 }
18190 pInquiry[2] = 0x05; /* SPC-3 */
18191 pInquiry[3] = 0x12; /* set HiSup 1; resp data format set to 2 */
18192 pInquiry[4] = 0x1F; /* 35 - 4 = 31; Additional length */
18193 pInquiry[5] = 0x00;
18194 /* The following two are for task management. SAT Rev8, p20 */
18195 if (pSATAIdData->sataCapabilities & 0x100)
18196 {
18197 /* NCQ supported; multiple outstanding SCSI IO are supported */
18198 pInquiry[6] = 0x00; /* BQUE bit is not set */
18199 pInquiry[7] = 0x02; /* CMDQUE bit is set */
18200 }
18201 else
18202 {
18203 pInquiry[6] = 0x80; /* BQUE bit is set */
18204 pInquiry[7] = 0x00; /* CMDQUE bit is not set */
18205 }
18206 /*
18207 * Vendor ID.
18208 */
18209 osti_strncpy((char*)&pInquiry[8], AG_SAT_VENDOR_ID_STRING,8); /* 8 bytes */
18210
18211 /*
18212 * Product ID
18213 */
18214 /* when flipped by LL */
18215 pInquiry[16] = pSATAIdData->modelNumber[1];
18216 pInquiry[17] = pSATAIdData->modelNumber[0];
18217 pInquiry[18] = pSATAIdData->modelNumber[3];
18218 pInquiry[19] = pSATAIdData->modelNumber[2];
18219 pInquiry[20] = pSATAIdData->modelNumber[5];
18220 pInquiry[21] = pSATAIdData->modelNumber[4];
18221 pInquiry[22] = pSATAIdData->modelNumber[7];
18222 pInquiry[23] = pSATAIdData->modelNumber[6];
18223 pInquiry[24] = pSATAIdData->modelNumber[9];
18224 pInquiry[25] = pSATAIdData->modelNumber[8];
18225 pInquiry[26] = pSATAIdData->modelNumber[11];
18226 pInquiry[27] = pSATAIdData->modelNumber[10];
18227 pInquiry[28] = pSATAIdData->modelNumber[13];
18228 pInquiry[29] = pSATAIdData->modelNumber[12];
18229 pInquiry[30] = pSATAIdData->modelNumber[15];
18230 pInquiry[31] = pSATAIdData->modelNumber[14];
18231
18232 /* when flipped */
18233 /*
18234 * Product Revision level.
18235 */
18236
18237 /*
18238 * If the IDENTIFY DEVICE data received in words 25 and 26 from the ATA
18239 * device are ASCII spaces (20h), do this translation.
18240 */
18241 if ( (pSATAIdData->firmwareVersion[4] == 0x20 ) &&
18242 (pSATAIdData->firmwareVersion[5] == 0x00 ) &&
18243 (pSATAIdData->firmwareVersion[6] == 0x20 ) &&
18244 (pSATAIdData->firmwareVersion[7] == 0x00 )
18245 )
18246 {
18247 pInquiry[32] = pSATAIdData->firmwareVersion[1];
18248 pInquiry[33] = pSATAIdData->firmwareVersion[0];
18249 pInquiry[34] = pSATAIdData->firmwareVersion[3];
18250 pInquiry[35] = pSATAIdData->firmwareVersion[2];
18251 }
18252 else
18253 {
18254 pInquiry[32] = pSATAIdData->firmwareVersion[5];
18255 pInquiry[33] = pSATAIdData->firmwareVersion[4];
18256 pInquiry[34] = pSATAIdData->firmwareVersion[7];
18257 pInquiry[35] = pSATAIdData->firmwareVersion[6];
18258 }
18259
18260
18261 #ifdef REMOVED
18262 /*
18263 * Product ID
18264 */
18265 /* when flipped by LL */
18266 pInquiry[16] = pSATAIdData->modelNumber[0];
18267 pInquiry[17] = pSATAIdData->modelNumber[1];
18268 pInquiry[18] = pSATAIdData->modelNumber[2];
18269 pInquiry[19] = pSATAIdData->modelNumber[3];
18270 pInquiry[20] = pSATAIdData->modelNumber[4];
18271 pInquiry[21] = pSATAIdData->modelNumber[5];
18272 pInquiry[22] = pSATAIdData->modelNumber[6];
18273 pInquiry[23] = pSATAIdData->modelNumber[7];
18274 pInquiry[24] = pSATAIdData->modelNumber[8];
18275 pInquiry[25] = pSATAIdData->modelNumber[9];
18276 pInquiry[26] = pSATAIdData->modelNumber[10];
18277 pInquiry[27] = pSATAIdData->modelNumber[11];
18278 pInquiry[28] = pSATAIdData->modelNumber[12];
18279 pInquiry[29] = pSATAIdData->modelNumber[13];
18280 pInquiry[30] = pSATAIdData->modelNumber[14];
18281 pInquiry[31] = pSATAIdData->modelNumber[15];
18282
18283 /* when flipped */
18284 /*
18285 * Product Revision level.
18286 */
18287
18288 /*
18289 * If the IDENTIFY DEVICE data received in words 25 and 26 from the ATA
18290 * device are ASCII spaces (20h), do this translation.
18291 */
18292 if ( (pSATAIdData->firmwareVersion[4] == 0x20 ) &&
18293 (pSATAIdData->firmwareVersion[5] == 0x00 ) &&
18294 (pSATAIdData->firmwareVersion[6] == 0x20 ) &&
18295 (pSATAIdData->firmwareVersion[7] == 0x00 )
18296 )
18297 {
18298 pInquiry[32] = pSATAIdData->firmwareVersion[0];
18299 pInquiry[33] = pSATAIdData->firmwareVersion[1];
18300 pInquiry[34] = pSATAIdData->firmwareVersion[2];
18301 pInquiry[35] = pSATAIdData->firmwareVersion[3];
18302 }
18303 else
18304 {
18305 pInquiry[32] = pSATAIdData->firmwareVersion[4];
18306 pInquiry[33] = pSATAIdData->firmwareVersion[5];
18307 pInquiry[34] = pSATAIdData->firmwareVersion[6];
18308 pInquiry[35] = pSATAIdData->firmwareVersion[7];
18309 }
18310 #endif
18311
18312 TI_DBG5(("satInquiryStandard: end\n"));
18313
18314 }
18315
18316
18317 /*****************************************************************************/
18318 /*! \brief SAT implementation for SCSI INQUIRY page 0.
18319 *
18320 * SAT implementation for SCSI INQUIRY page 0.
18321 *
18322 * \param pInquiry: Pointer to Inquiry Data buffer.
18323 * \param pSATAIdData: Pointer to ATA IDENTIFY DEVICE data.
18324 *
18325 * \return None.
18326 */
18327 /*****************************************************************************/
satInquiryPage0(bit8 * pInquiry,agsaSATAIdentifyData_t * pSATAIdData)18328 GLOBAL void satInquiryPage0(
18329 bit8 *pInquiry,
18330 agsaSATAIdentifyData_t *pSATAIdData)
18331 {
18332
18333 TI_DBG5(("satInquiryPage0: entry\n"));
18334
18335 /*
18336 See SPC-4, 7.6.9, p 345
18337 and SAT revision 8, 10.3.2, p 77
18338 */
18339 pInquiry[0] = 0x00;
18340 pInquiry[1] = 0x00; /* page code */
18341 pInquiry[2] = 0x00; /* reserved */
18342 pInquiry[3] = 7 - 3; /* last index(in this case, 6) - 3; page length */
18343
18344 /* supported vpd page list */
18345 pInquiry[4] = 0x00; /* page 0x00 supported */
18346 pInquiry[5] = 0x80; /* page 0x80 supported */
18347 pInquiry[6] = 0x83; /* page 0x83 supported */
18348 pInquiry[7] = 0x89; /* page 0x89 supported */
18349
18350 }
18351
18352
18353 /*****************************************************************************/
18354 /*! \brief SAT implementation for SCSI INQUIRY page 83.
18355 *
18356 * SAT implementation for SCSI INQUIRY page 83.
18357 *
18358 * \param pInquiry: Pointer to Inquiry Data buffer.
18359 * \param pSATAIdData: Pointer to ATA IDENTIFY DEVICE data.
18360 *
18361 * \return None.
18362 */
18363 /*****************************************************************************/
satInquiryPage83(bit8 * pInquiry,agsaSATAIdentifyData_t * pSATAIdData,satDeviceData_t * pSatDevData)18364 GLOBAL void satInquiryPage83(
18365 bit8 *pInquiry,
18366 agsaSATAIdentifyData_t *pSATAIdData,
18367 satDeviceData_t *pSatDevData)
18368 {
18369
18370 satSimpleSATAIdentifyData_t *pSimpleData;
18371
18372 /*
18373 * When translating the fields, in some cases using the simple form of SATA
18374 * Identify Device Data is easier. So we define it here.
18375 * Both pSimpleData and pSATAIdData points to the same data.
18376 */
18377 pSimpleData = ( satSimpleSATAIdentifyData_t *)pSATAIdData;
18378
18379 TI_DBG5(("satInquiryPage83: entry\n"));
18380
18381 pInquiry[0] = 0x00;
18382 pInquiry[1] = 0x83; /* page code */
18383 pInquiry[2] = 0; /* Reserved */
18384
18385 /*
18386 * If the ATA device returns word 87 bit 8 set to one in its IDENTIFY DEVICE
18387 * data indicating that it supports the WORLD WIDE NAME field
18388 * (i.e., words 108-111), the SATL shall include an identification descriptor
18389 * containing a logical unit name.
18390 */
18391 if ( pSatDevData->satWWNSupport)
18392 {
18393 /* Fill in SAT Rev8 Table85 */
18394 /*
18395 * Logical unit name derived from the world wide name.
18396 */
18397 pInquiry[3] = 12; /* 15-3; page length, no addition ID descriptor assumed*/
18398
18399 /*
18400 * Identifier descriptor
18401 */
18402 pInquiry[4] = 0x01; /* Code set: binary codes */
18403 pInquiry[5] = 0x03; /* Identifier type : NAA */
18404 pInquiry[6] = 0x00; /* Reserved */
18405 pInquiry[7] = 0x08; /* Identifier length */
18406
18407 /* Bit 4-7 NAA field, bit 0-3 MSB of IEEE Company ID */
18408 pInquiry[8] = (bit8)((pSATAIdData->namingAuthority) >> 8);
18409 pInquiry[9] = (bit8)((pSATAIdData->namingAuthority) & 0xFF); /* IEEE Company ID */
18410 pInquiry[10] = (bit8)((pSATAIdData->namingAuthority1) >> 8); /* IEEE Company ID */
18411 /* Bit 4-7 LSB of IEEE Company ID, bit 0-3 MSB of Vendor Specific ID */
18412 pInquiry[11] = (bit8)((pSATAIdData->namingAuthority1) & 0xFF);
18413 pInquiry[12] = (bit8)((pSATAIdData->uniqueID_bit16_31) >> 8); /* Vendor Specific ID */
18414 pInquiry[13] = (bit8)((pSATAIdData->uniqueID_bit16_31) & 0xFF); /* Vendor Specific ID */
18415 pInquiry[14] = (bit8)((pSATAIdData->uniqueID_bit0_15) >> 8); /* Vendor Specific ID */
18416 pInquiry[15] = (bit8)((pSATAIdData->uniqueID_bit0_15) & 0xFF); /* Vendor Specific ID */
18417
18418 }
18419 else
18420 {
18421 /* Fill in SAT Rev8 Table86 */
18422 /*
18423 * Logical unit name derived from the model number and serial number.
18424 */
18425 pInquiry[3] = 72; /* 75 - 3; page length */
18426
18427 /*
18428 * Identifier descriptor
18429 */
18430 pInquiry[4] = 0x02; /* Code set: ASCII codes */
18431 pInquiry[5] = 0x01; /* Identifier type : T10 vendor ID based */
18432 pInquiry[6] = 0x00; /* Reserved */
18433 pInquiry[7] = 0x44; /* 0x44, 68 Identifier length */
18434
18435 /* Byte 8 to 15 is the vendor id string 'ATA '. */
18436 osti_strncpy((char *)&pInquiry[8], AG_SAT_VENDOR_ID_STRING, 8);
18437
18438
18439 /*
18440 * Byte 16 to 75 is vendor specific id
18441 */
18442 pInquiry[16] = (bit8)((pSimpleData->word[27]) >> 8);
18443 pInquiry[17] = (bit8)((pSimpleData->word[27]) & 0x00ff);
18444 pInquiry[18] = (bit8)((pSimpleData->word[28]) >> 8);
18445 pInquiry[19] = (bit8)((pSimpleData->word[28]) & 0x00ff);
18446 pInquiry[20] = (bit8)((pSimpleData->word[29]) >> 8);
18447 pInquiry[21] = (bit8)((pSimpleData->word[29]) & 0x00ff);
18448 pInquiry[22] = (bit8)((pSimpleData->word[30]) >> 8);
18449 pInquiry[23] = (bit8)((pSimpleData->word[30]) & 0x00ff);
18450 pInquiry[24] = (bit8)((pSimpleData->word[31]) >> 8);
18451 pInquiry[25] = (bit8)((pSimpleData->word[31]) & 0x00ff);
18452 pInquiry[26] = (bit8)((pSimpleData->word[32]) >> 8);
18453 pInquiry[27] = (bit8)((pSimpleData->word[32]) & 0x00ff);
18454 pInquiry[28] = (bit8)((pSimpleData->word[33]) >> 8);
18455 pInquiry[29] = (bit8)((pSimpleData->word[33]) & 0x00ff);
18456 pInquiry[30] = (bit8)((pSimpleData->word[34]) >> 8);
18457 pInquiry[31] = (bit8)((pSimpleData->word[34]) & 0x00ff);
18458 pInquiry[32] = (bit8)((pSimpleData->word[35]) >> 8);
18459 pInquiry[33] = (bit8)((pSimpleData->word[35]) & 0x00ff);
18460 pInquiry[34] = (bit8)((pSimpleData->word[36]) >> 8);
18461 pInquiry[35] = (bit8)((pSimpleData->word[36]) & 0x00ff);
18462 pInquiry[36] = (bit8)((pSimpleData->word[37]) >> 8);
18463 pInquiry[37] = (bit8)((pSimpleData->word[37]) & 0x00ff);
18464 pInquiry[38] = (bit8)((pSimpleData->word[38]) >> 8);
18465 pInquiry[39] = (bit8)((pSimpleData->word[38]) & 0x00ff);
18466 pInquiry[40] = (bit8)((pSimpleData->word[39]) >> 8);
18467 pInquiry[41] = (bit8)((pSimpleData->word[39]) & 0x00ff);
18468 pInquiry[42] = (bit8)((pSimpleData->word[40]) >> 8);
18469 pInquiry[43] = (bit8)((pSimpleData->word[40]) & 0x00ff);
18470 pInquiry[44] = (bit8)((pSimpleData->word[41]) >> 8);
18471 pInquiry[45] = (bit8)((pSimpleData->word[41]) & 0x00ff);
18472 pInquiry[46] = (bit8)((pSimpleData->word[42]) >> 8);
18473 pInquiry[47] = (bit8)((pSimpleData->word[42]) & 0x00ff);
18474 pInquiry[48] = (bit8)((pSimpleData->word[43]) >> 8);
18475 pInquiry[49] = (bit8)((pSimpleData->word[43]) & 0x00ff);
18476 pInquiry[50] = (bit8)((pSimpleData->word[44]) >> 8);
18477 pInquiry[51] = (bit8)((pSimpleData->word[44]) & 0x00ff);
18478 pInquiry[52] = (bit8)((pSimpleData->word[45]) >> 8);
18479 pInquiry[53] = (bit8)((pSimpleData->word[45]) & 0x00ff);
18480 pInquiry[54] = (bit8)((pSimpleData->word[46]) >> 8);
18481 pInquiry[55] = (bit8)((pSimpleData->word[46]) & 0x00ff);
18482
18483 pInquiry[56] = (bit8)((pSimpleData->word[10]) >> 8);
18484 pInquiry[57] = (bit8)((pSimpleData->word[10]) & 0x00ff);
18485 pInquiry[58] = (bit8)((pSimpleData->word[11]) >> 8);
18486 pInquiry[59] = (bit8)((pSimpleData->word[11]) & 0x00ff);
18487 pInquiry[60] = (bit8)((pSimpleData->word[12]) >> 8);
18488 pInquiry[61] = (bit8)((pSimpleData->word[12]) & 0x00ff);
18489 pInquiry[62] = (bit8)((pSimpleData->word[13]) >> 8);
18490 pInquiry[63] = (bit8)((pSimpleData->word[13]) & 0x00ff);
18491 pInquiry[64] = (bit8)((pSimpleData->word[14]) >> 8);
18492 pInquiry[65] = (bit8)((pSimpleData->word[14]) & 0x00ff);
18493 pInquiry[66] = (bit8)((pSimpleData->word[15]) >> 8);
18494 pInquiry[67] = (bit8)((pSimpleData->word[15]) & 0x00ff);
18495 pInquiry[68] = (bit8)((pSimpleData->word[16]) >> 8);
18496 pInquiry[69] = (bit8)((pSimpleData->word[16]) & 0x00ff);
18497 pInquiry[70] = (bit8)((pSimpleData->word[17]) >> 8);
18498 pInquiry[71] = (bit8)((pSimpleData->word[17]) & 0x00ff);
18499 pInquiry[72] = (bit8)((pSimpleData->word[18]) >> 8);
18500 pInquiry[73] = (bit8)((pSimpleData->word[18]) & 0x00ff);
18501 pInquiry[74] = (bit8)((pSimpleData->word[19]) >> 8);
18502 pInquiry[75] = (bit8)((pSimpleData->word[19]) & 0x00ff);
18503 }
18504
18505 }
18506
18507 /*****************************************************************************/
18508 /*! \brief SAT implementation for SCSI INQUIRY page 89.
18509 *
18510 * SAT implementation for SCSI INQUIRY page 89.
18511 *
18512 * \param pInquiry: Pointer to Inquiry Data buffer.
18513 * \param pSATAIdData: Pointer to ATA IDENTIFY DEVICE data.
18514 * \param pSatDevData Pointer to internal device data structure
18515 *
18516 * \return None.
18517 */
18518 /*****************************************************************************/
satInquiryPage89(bit8 * pInquiry,agsaSATAIdentifyData_t * pSATAIdData,satDeviceData_t * pSatDevData)18519 GLOBAL void satInquiryPage89(
18520 bit8 *pInquiry,
18521 agsaSATAIdentifyData_t *pSATAIdData,
18522 satDeviceData_t *pSatDevData)
18523 {
18524 /*
18525 SAT revision 8, 10.3.5, p 83
18526 */
18527 satSimpleSATAIdentifyData_t *pSimpleData;
18528
18529 /*
18530 * When translating the fields, in some cases using the simple form of SATA
18531 * Identify Device Data is easier. So we define it here.
18532 * Both pSimpleData and pSATAIdData points to the same data.
18533 */
18534 pSimpleData = ( satSimpleSATAIdentifyData_t *)pSATAIdData;
18535
18536 TI_DBG5(("satInquiryPage89: start\n"));
18537
18538 pInquiry[0] = 0x00; /* Peripheral Qualifier and Peripheral Device Type */
18539 pInquiry[1] = 0x89; /* page code */
18540
18541 /* Page length 0x238 */
18542 pInquiry[2] = 0x02;
18543 pInquiry[3] = 0x38;
18544
18545 pInquiry[4] = 0x0; /* reserved */
18546 pInquiry[5] = 0x0; /* reserved */
18547 pInquiry[6] = 0x0; /* reserved */
18548 pInquiry[7] = 0x0; /* reserved */
18549
18550 /* SAT Vendor Identification */
18551 osti_strncpy((char*)&pInquiry[8], "PMC-SIERRA", 8); /* 8 bytes */
18552
18553 /* SAT Product Idetification */
18554 osti_strncpy((char*)&pInquiry[16], "Tachyon-SPC ", 16); /* 16 bytes */
18555
18556 /* SAT Product Revision Level */
18557 osti_strncpy((char*)&pInquiry[32], "01", 4); /* 4 bytes */
18558
18559 /* Signature, SAT revision8, Table88, p85 */
18560
18561
18562 pInquiry[36] = 0x34; /* FIS type */
18563 if (pSatDevData->satDeviceType == SATA_ATA_DEVICE)
18564 {
18565 /* interrupt assume to be 0 */
18566 pInquiry[37] = (bit8)((pSatDevData->satPMField) >> (4 * 7)); /* first four bits of PM field */
18567 }
18568 else
18569 {
18570 /* interrupt assume to be 1 */
18571 pInquiry[37] = (bit8)(0x40 + (bit8)(((pSatDevData->satPMField) >> (4 * 7)))); /* first four bits of PM field */
18572 }
18573 pInquiry[38] = 0;
18574 pInquiry[39] = 0;
18575
18576 if (pSatDevData->satDeviceType == SATA_ATA_DEVICE)
18577 {
18578 pInquiry[40] = 0x01; /* LBA Low */
18579 pInquiry[41] = 0x00; /* LBA Mid */
18580 pInquiry[42] = 0x00; /* LBA High */
18581 pInquiry[43] = 0x00; /* Device */
18582 pInquiry[44] = 0x00; /* LBA Low Exp */
18583 pInquiry[45] = 0x00; /* LBA Mid Exp */
18584 pInquiry[46] = 0x00; /* LBA High Exp */
18585 pInquiry[47] = 0x00; /* Reserved */
18586 pInquiry[48] = 0x01; /* Sector Count */
18587 pInquiry[49] = 0x00; /* Sector Count Exp */
18588 }
18589 else
18590 {
18591 pInquiry[40] = 0x01; /* LBA Low */
18592 pInquiry[41] = 0x00; /* LBA Mid */
18593 pInquiry[42] = 0x00; /* LBA High */
18594 pInquiry[43] = 0x00; /* Device */
18595 pInquiry[44] = 0x00; /* LBA Low Exp */
18596 pInquiry[45] = 0x00; /* LBA Mid Exp */
18597 pInquiry[46] = 0x00; /* LBA High Exp */
18598 pInquiry[47] = 0x00; /* Reserved */
18599 pInquiry[48] = 0x01; /* Sector Count */
18600 pInquiry[49] = 0x00; /* Sector Count Exp */
18601 }
18602
18603 /* Reserved */
18604 pInquiry[50] = 0x00;
18605 pInquiry[51] = 0x00;
18606 pInquiry[52] = 0x00;
18607 pInquiry[53] = 0x00;
18608 pInquiry[54] = 0x00;
18609 pInquiry[55] = 0x00;
18610
18611 /* Command Code */
18612 if (pSatDevData->satDeviceType == SATA_ATA_DEVICE)
18613 {
18614 pInquiry[56] = 0xEC; /* IDENTIFY DEVICE */
18615 }
18616 else
18617 {
18618 pInquiry[56] = 0xA1; /* IDENTIFY PACKET DEVICE */
18619 }
18620 /* Reserved */
18621 pInquiry[57] = 0x0;
18622 pInquiry[58] = 0x0;
18623 pInquiry[59] = 0x0;
18624
18625 /* Identify Device */
18626 osti_memcpy(&pInquiry[60], pSimpleData, sizeof(satSimpleSATAIdentifyData_t));
18627 return;
18628 }
18629
18630 /*****************************************************************************/
18631 /*! \brief SAT implementation for SCSI INQUIRY page 0.
18632 *
18633 * SAT implementation for SCSI INQUIRY page 0.
18634 *
18635 * \param pInquiry: Pointer to Inquiry Data buffer.
18636 * \param pSATAIdData: Pointer to ATA IDENTIFY DEVICE data.
18637 *
18638 * \return None.
18639 */
18640 /*****************************************************************************/
satInquiryPage80(bit8 * pInquiry,agsaSATAIdentifyData_t * pSATAIdData)18641 GLOBAL void satInquiryPage80(
18642 bit8 *pInquiry,
18643 agsaSATAIdentifyData_t *pSATAIdData)
18644 {
18645
18646 TI_DBG5(("satInquiryPage80: entry\n"));
18647
18648 /*
18649 See SPC-4, 7.6.9, p 345
18650 and SAT revision 8, 10.3.3, p 77
18651 */
18652 pInquiry[0] = 0x00;
18653 pInquiry[1] = 0x80; /* page code */
18654 pInquiry[2] = 0x00; /* reserved */
18655 pInquiry[3] = 0x14; /* page length */
18656
18657 /* supported vpd page list */
18658 pInquiry[4] = pSATAIdData->serialNumber[1];
18659 pInquiry[5] = pSATAIdData->serialNumber[0];
18660 pInquiry[6] = pSATAIdData->serialNumber[3];
18661 pInquiry[7] = pSATAIdData->serialNumber[2];
18662 pInquiry[8] = pSATAIdData->serialNumber[5];
18663 pInquiry[9] = pSATAIdData->serialNumber[4];
18664 pInquiry[10] = pSATAIdData->serialNumber[7];
18665 pInquiry[11] = pSATAIdData->serialNumber[6];
18666 pInquiry[12] = pSATAIdData->serialNumber[9];
18667 pInquiry[13] = pSATAIdData->serialNumber[8];
18668 pInquiry[14] = pSATAIdData->serialNumber[11];
18669 pInquiry[15] = pSATAIdData->serialNumber[10];
18670 pInquiry[16] = pSATAIdData->serialNumber[13];
18671 pInquiry[17] = pSATAIdData->serialNumber[12];
18672 pInquiry[18] = pSATAIdData->serialNumber[15];
18673 pInquiry[19] = pSATAIdData->serialNumber[14];
18674 pInquiry[20] = pSATAIdData->serialNumber[17];
18675 pInquiry[21] = pSATAIdData->serialNumber[16];
18676 pInquiry[22] = pSATAIdData->serialNumber[19];
18677 pInquiry[23] = pSATAIdData->serialNumber[18];
18678
18679
18680 }
18681
18682
18683
18684 /*****************************************************************************/
18685 /*! \brief Send READ LOG EXT ATA PAGE 10h command to sata drive.
18686 *
18687 * Send READ LOG EXT ATA command PAGE 10h request to LL layer.
18688 *
18689 * \param tiRoot: Pointer to TISA initiator driver/port instance.
18690 * \param tiIORequest: Pointer to TISA I/O request context for this I/O.
18691 * \param tiDeviceHandle: Pointer to TISA device handle for this I/O.
18692 * \param tiScsiRequest: Pointer to TISA SCSI I/O request and SGL list.
18693 * \param satIOContext_t: Pointer to the SAT IO Context
18694 *
18695 * \return If command is started successfully
18696 * - \e tiSuccess: I/O request successfully initiated.
18697 * - \e tiBusy: No resources available, try again later.
18698 * - \e tiIONoDevice: Invalid device handle.
18699 * - \e tiError: Other errors.
18700 */
18701 /*****************************************************************************/
satSendReadLogExt(tiRoot_t * tiRoot,tiIORequest_t * tiIORequest,tiDeviceHandle_t * tiDeviceHandle,tiScsiInitiatorRequest_t * tiScsiRequest,satIOContext_t * satIOContext)18702 GLOBAL bit32 satSendReadLogExt(
18703 tiRoot_t *tiRoot,
18704 tiIORequest_t *tiIORequest,
18705 tiDeviceHandle_t *tiDeviceHandle,
18706 tiScsiInitiatorRequest_t *tiScsiRequest,
18707 satIOContext_t *satIOContext)
18708
18709 {
18710
18711 bit32 status;
18712 bit32 agRequestType;
18713 agsaFisRegHostToDevice_t *fis;
18714
18715 fis = satIOContext->pFis;
18716
18717 TI_DBG1(("satSendReadLogExt: tiDeviceHandle=%p tiIORequest=%p\n",
18718 tiDeviceHandle, tiIORequest));
18719
18720 fis->h.fisType = 0x27; /* Reg host to device */
18721 fis->h.c_pmPort = 0x80; /* C Bit is set */
18722 fis->h.command = SAT_READ_LOG_EXT; /* 0x2F */
18723 fis->h.features = 0; /* FIS reserve */
18724 fis->d.lbaLow = 0x10; /* Page number */
18725 fis->d.lbaMid = 0; /* */
18726 fis->d.lbaHigh = 0; /* */
18727 fis->d.device = 0; /* DEV is ignored in SATA */
18728 fis->d.lbaLowExp = 0; /* */
18729 fis->d.lbaMidExp = 0; /* */
18730 fis->d.lbaHighExp = 0; /* */
18731 fis->d.featuresExp = 0; /* FIS reserve */
18732 fis->d.sectorCount = 0x01; /* 1 sector counts*/
18733 fis->d.sectorCountExp = 0x00; /* 1 sector counts */
18734 fis->d.reserved4 = 0;
18735 fis->d.control = 0; /* FIS HOB bit clear */
18736 fis->d.reserved5 = 0;
18737
18738 agRequestType = AGSA_SATA_PROTOCOL_PIO_READ;
18739
18740 /* Initialize CB for SATA completion.
18741 */
18742 satIOContext->satCompleteCB = &satReadLogExtCB;
18743
18744 /*
18745 * Prepare SGL and send FIS to LL layer.
18746 */
18747 satIOContext->reqType = agRequestType; /* Save it */
18748
18749 status = sataLLIOStart( tiRoot,
18750 tiIORequest,
18751 tiDeviceHandle,
18752 tiScsiRequest,
18753 satIOContext);
18754
18755 TI_DBG1(("satSendReadLogExt: end status %d\n", status));
18756
18757 return (status);
18758
18759 }
18760
18761
18762 /*****************************************************************************/
18763 /*! \brief SAT default ATA status and ATA error translation to SCSI.
18764 *
18765 * SSAT default ATA status and ATA error translation to SCSI.
18766 *
18767 * \param tiRoot: Pointer to TISA initiator driver/port instance.
18768 * \param tiIORequest: Pointer to TISA I/O request context for this I/O.
18769 * \param satIOContext: Pointer to the SAT IO Context
18770 * \param pSense: Pointer to scsiRspSense_t
18771 * \param ataStatus: ATA status register
18772 * \param ataError: ATA error register
18773 * \param interruptContext: Interrupt context
18774 *
18775 * \return None
18776 */
18777 /*****************************************************************************/
osSatDefaultTranslation(tiRoot_t * tiRoot,tiIORequest_t * tiIORequest,satIOContext_t * satIOContext,scsiRspSense_t * pSense,bit8 ataStatus,bit8 ataError,bit32 interruptContext)18778 GLOBAL void osSatDefaultTranslation(
18779 tiRoot_t *tiRoot,
18780 tiIORequest_t *tiIORequest,
18781 satIOContext_t *satIOContext,
18782 scsiRspSense_t *pSense,
18783 bit8 ataStatus,
18784 bit8 ataError,
18785 bit32 interruptContext )
18786 {
18787
18788 /*
18789 * Check for device fault case
18790 */
18791 if ( ataStatus & DF_ATA_STATUS_MASK )
18792 {
18793 satSetSensePayload( pSense,
18794 SCSI_SNSKEY_HARDWARE_ERROR,
18795 0,
18796 SCSI_SNSCODE_INTERNAL_TARGET_FAILURE,
18797 satIOContext);
18798
18799 ostiInitiatorIOCompleted( tiRoot,
18800 tiIORequest,
18801 tiIOSuccess,
18802 SCSI_STAT_CHECK_CONDITION,
18803 satIOContext->pTiSenseData,
18804 interruptContext );
18805 return;
18806 }
18807
18808 /*
18809 * If status error bit it set, need to check the error register
18810 */
18811 if ( ataStatus & ERR_ATA_STATUS_MASK )
18812 {
18813 if ( ataError & NM_ATA_ERROR_MASK )
18814 {
18815 TI_DBG1(("osSatDefaultTranslation: NM_ATA_ERROR ataError= 0x%x, tiIORequest=%p\n",
18816 ataError, tiIORequest));
18817 satSetSensePayload( pSense,
18818 SCSI_SNSKEY_NOT_READY,
18819 0,
18820 SCSI_SNSCODE_MEDIUM_NOT_PRESENT,
18821 satIOContext);
18822 }
18823
18824 else if (ataError & UNC_ATA_ERROR_MASK)
18825 {
18826 TI_DBG1(("osSatDefaultTranslation: UNC_ATA_ERROR ataError= 0x%x, tiIORequest=%p\n",
18827 ataError, tiIORequest));
18828 satSetSensePayload( pSense,
18829 SCSI_SNSKEY_MEDIUM_ERROR,
18830 0,
18831 SCSI_SNSCODE_UNRECOVERED_READ_ERROR,
18832 satIOContext);
18833 }
18834
18835 else if (ataError & IDNF_ATA_ERROR_MASK)
18836 {
18837 TI_DBG1(("osSatDefaultTranslation: IDNF_ATA_ERROR ataError= 0x%x, tiIORequest=%p\n",
18838 ataError, tiIORequest));
18839 satSetSensePayload( pSense,
18840 SCSI_SNSKEY_MEDIUM_ERROR,
18841 0,
18842 SCSI_SNSCODE_RECORD_NOT_FOUND,
18843 satIOContext);
18844 }
18845
18846 else if (ataError & MC_ATA_ERROR_MASK)
18847 {
18848 TI_DBG1(("osSatDefaultTranslation: MC_ATA_ERROR ataError= 0x%x, tiIORequest=%p\n",
18849 ataError, tiIORequest));
18850 satSetSensePayload( pSense,
18851 SCSI_SNSKEY_UNIT_ATTENTION,
18852 0,
18853 SCSI_SNSCODE_NOT_READY_TO_READY_CHANGE,
18854 satIOContext);
18855 }
18856
18857 else if (ataError & MCR_ATA_ERROR_MASK)
18858 {
18859 TI_DBG1(("osSatDefaultTranslation: MCR_ATA_ERROR ataError= 0x%x, tiIORequest=%p\n",
18860 ataError, tiIORequest));
18861 satSetSensePayload( pSense,
18862 SCSI_SNSKEY_UNIT_ATTENTION,
18863 0,
18864 SCSI_SNSCODE_OPERATOR_MEDIUM_REMOVAL_REQUEST,
18865 satIOContext);
18866 }
18867
18868 else if (ataError & ICRC_ATA_ERROR_MASK)
18869 {
18870 TI_DBG1(("osSatDefaultTranslation: ICRC_ATA_ERROR ataError= 0x%x, tiIORequest=%p\n",
18871 ataError, tiIORequest));
18872 satSetSensePayload( pSense,
18873 SCSI_SNSKEY_ABORTED_COMMAND,
18874 0,
18875 SCSI_SNSCODE_INFORMATION_UNIT_CRC_ERROR,
18876 satIOContext);
18877 }
18878
18879 else if (ataError & ABRT_ATA_ERROR_MASK)
18880 {
18881 TI_DBG1(("osSatDefaultTranslation: ABRT_ATA_ERROR ataError= 0x%x, tiIORequest=%p\n",
18882 ataError, tiIORequest));
18883 satSetSensePayload( pSense,
18884 SCSI_SNSKEY_ABORTED_COMMAND,
18885 0,
18886 SCSI_SNSCODE_NO_ADDITIONAL_INFO,
18887 satIOContext);
18888 }
18889
18890 else
18891 {
18892 TI_DBG1(("osSatDefaultTranslation: **** UNEXPECTED ATA_ERROR **** ataError= 0x%x, tiIORequest=%p\n",
18893 ataError, tiIORequest));
18894 satSetSensePayload( pSense,
18895 SCSI_SNSKEY_HARDWARE_ERROR,
18896 0,
18897 SCSI_SNSCODE_INTERNAL_TARGET_FAILURE,
18898 satIOContext);
18899 }
18900
18901 /* Send the completion response now */
18902 ostiInitiatorIOCompleted( tiRoot,
18903 tiIORequest,
18904 tiIOSuccess,
18905 SCSI_STAT_CHECK_CONDITION,
18906 satIOContext->pTiSenseData,
18907 interruptContext );
18908 return;
18909
18910
18911 }
18912
18913 else /* (ataStatus & ERR_ATA_STATUS_MASK ) is false */
18914 {
18915 /* This case should never happen */
18916 TI_DBG1(("osSatDefaultTranslation: *** UNEXPECTED ATA status 0x%x *** tiIORequest=%p\n",
18917 ataStatus, tiIORequest));
18918 satSetSensePayload( pSense,
18919 SCSI_SNSKEY_HARDWARE_ERROR,
18920 0,
18921 SCSI_SNSCODE_INTERNAL_TARGET_FAILURE,
18922 satIOContext);
18923
18924 ostiInitiatorIOCompleted( tiRoot,
18925 tiIORequest,
18926 tiIOSuccess,
18927 SCSI_STAT_CHECK_CONDITION,
18928 satIOContext->pTiSenseData,
18929 interruptContext );
18930 return;
18931
18932 }
18933
18934
18935 }
18936
18937 /*****************************************************************************/
18938 /*! \brief Allocate resource for SAT intervally generated I/O.
18939 *
18940 * Allocate resource for SAT intervally generated I/O.
18941 *
18942 * \param tiRoot: Pointer to TISA driver/port instance.
18943 * \param satDevData: Pointer to SAT specific device data.
18944 * \param allocLength: Length in byte of the DMA mem to allocate, upto
18945 * one page size.
18946 * \param satIntIo: Pointer (output) to context for SAT internally
18947 * generated I/O that is allocated by this routine.
18948 *
18949 * \return If command is started successfully
18950 * - \e tiSuccess: Success.
18951 * - \e tiError: Failed allocating resource.
18952 */
18953 /*****************************************************************************/
satAllocIntIoResource(tiRoot_t * tiRoot,tiIORequest_t * tiIORequest,satDeviceData_t * satDevData,bit32 dmaAllocLength,satInternalIo_t * satIntIo)18954 GLOBAL satInternalIo_t * satAllocIntIoResource(
18955 tiRoot_t *tiRoot,
18956 tiIORequest_t *tiIORequest,
18957 satDeviceData_t *satDevData,
18958 bit32 dmaAllocLength,
18959 satInternalIo_t *satIntIo)
18960 {
18961 tdList_t *tdList = agNULL;
18962 bit32 memAllocStatus;
18963
18964 TI_DBG1(("satAllocIntIoResource: start\n"));
18965 TI_DBG6(("satAllocIntIoResource: satIntIo %p\n", satIntIo));
18966 if (satDevData == agNULL)
18967 {
18968 TI_DBG1(("satAllocIntIoResource: ***** ASSERT satDevData is null\n"));
18969 return agNULL;
18970 }
18971
18972 tdsaSingleThreadedEnter(tiRoot, TD_SATA_LOCK);
18973 if (!TDLIST_EMPTY(&(satDevData->satFreeIntIoLinkList)))
18974 {
18975 TDLIST_DEQUEUE_FROM_HEAD(&tdList, &(satDevData->satFreeIntIoLinkList));
18976 }
18977 else
18978 {
18979 tdsaSingleThreadedLeave(tiRoot, TD_SATA_LOCK);
18980 TI_DBG1(("satAllocIntIoResource() no more internal free link.\n"));
18981 return agNULL;
18982 }
18983
18984 if (tdList == agNULL)
18985 {
18986 tdsaSingleThreadedLeave(tiRoot, TD_SATA_LOCK);
18987 TI_DBG1(("satAllocIntIoResource() FAIL to alloc satIntIo.\n"));
18988 return agNULL;
18989 }
18990
18991 satIntIo = TDLIST_OBJECT_BASE( satInternalIo_t, satIntIoLink, tdList);
18992 TI_DBG6(("satAllocIntIoResource: satDevData %p satIntIo id %d\n", satDevData, satIntIo->id));
18993
18994 /* Put in active list */
18995 TDLIST_DEQUEUE_THIS (&(satIntIo->satIntIoLink));
18996 TDLIST_ENQUEUE_AT_TAIL (&(satIntIo->satIntIoLink), &(satDevData->satActiveIntIoLinkList));
18997 tdsaSingleThreadedLeave(tiRoot, TD_SATA_LOCK);
18998
18999 #ifdef REMOVED
19000 /* Put in active list */
19001 tdsaSingleThreadedEnter(tiRoot, TD_SATA_LOCK);
19002 TDLIST_DEQUEUE_THIS (tdList);
19003 TDLIST_ENQUEUE_AT_TAIL (tdList, &(satDevData->satActiveIntIoLinkList));
19004 tdsaSingleThreadedLeave(tiRoot, TD_SATA_LOCK);
19005
19006 satIntIo = TDLIST_OBJECT_BASE( satInternalIo_t, satIntIoLink, tdList);
19007 TI_DBG6(("satAllocIntIoResource: satDevData %p satIntIo id %d\n", satDevData, satIntIo->id));
19008 #endif
19009
19010 /*
19011 typedef struct
19012 {
19013 tdList_t satIntIoLink;
19014 tiIORequest_t satIntTiIORequest;
19015 void *satIntRequestBody;
19016 tiScsiInitiatorRequest_t satIntTiScsiXchg;
19017 tiMem_t satIntDmaMem;
19018 tiMem_t satIntReqBodyMem;
19019 bit32 satIntFlag;
19020 } satInternalIo_t;
19021 */
19022
19023 /*
19024 * Allocate mem for Request Body
19025 */
19026 satIntIo->satIntReqBodyMem.totalLength = sizeof(tdIORequestBody_t);
19027
19028 memAllocStatus = ostiAllocMemory( tiRoot,
19029 &satIntIo->satIntReqBodyMem.osHandle,
19030 (void **)&satIntIo->satIntRequestBody,
19031 &satIntIo->satIntReqBodyMem.physAddrUpper,
19032 &satIntIo->satIntReqBodyMem.physAddrLower,
19033 8,
19034 satIntIo->satIntReqBodyMem.totalLength,
19035 agTRUE );
19036
19037 if (memAllocStatus != tiSuccess)
19038 {
19039 TI_DBG1(("satAllocIntIoResource() FAIL to alloc mem for Req Body.\n"));
19040 /*
19041 * Return satIntIo to the free list
19042 */
19043 tdsaSingleThreadedEnter(tiRoot, TD_SATA_LOCK);
19044 TDLIST_DEQUEUE_THIS (&satIntIo->satIntIoLink);
19045 TDLIST_ENQUEUE_AT_HEAD(&satIntIo->satIntIoLink, &satDevData->satFreeIntIoLinkList);
19046 tdsaSingleThreadedLeave(tiRoot, TD_SATA_LOCK);
19047
19048 return agNULL;
19049 }
19050
19051 /*
19052 * Allocate DMA memory if required
19053 */
19054 if (dmaAllocLength != 0)
19055 {
19056 satIntIo->satIntDmaMem.totalLength = dmaAllocLength;
19057
19058 memAllocStatus = ostiAllocMemory( tiRoot,
19059 &satIntIo->satIntDmaMem.osHandle,
19060 (void **)&satIntIo->satIntDmaMem.virtPtr,
19061 &satIntIo->satIntDmaMem.physAddrUpper,
19062 &satIntIo->satIntDmaMem.physAddrLower,
19063 8,
19064 satIntIo->satIntDmaMem.totalLength,
19065 agFALSE);
19066 TI_DBG6(("satAllocIntIoResource: len %d \n", satIntIo->satIntDmaMem.totalLength));
19067 TI_DBG6(("satAllocIntIoResource: pointer %p \n", satIntIo->satIntDmaMem.osHandle));
19068
19069 if (memAllocStatus != tiSuccess)
19070 {
19071 TI_DBG1(("satAllocIntIoResource() FAIL to alloc mem for DMA mem.\n"));
19072 /*
19073 * Return satIntIo to the free list
19074 */
19075 tdsaSingleThreadedEnter(tiRoot, TD_SATA_LOCK);
19076 TDLIST_DEQUEUE_THIS (&satIntIo->satIntIoLink);
19077 TDLIST_ENQUEUE_AT_HEAD(&satIntIo->satIntIoLink, &satDevData->satFreeIntIoLinkList);
19078 tdsaSingleThreadedLeave(tiRoot, TD_SATA_LOCK);
19079
19080 /*
19081 * Free mem allocated for Req body
19082 */
19083 ostiFreeMemory( tiRoot,
19084 satIntIo->satIntReqBodyMem.osHandle,
19085 satIntIo->satIntReqBodyMem.totalLength);
19086
19087 return agNULL;
19088 }
19089 }
19090
19091 /*
19092 typedef struct
19093 {
19094 tdList_t satIntIoLink;
19095 tiIORequest_t satIntTiIORequest;
19096 void *satIntRequestBody;
19097 tiScsiInitiatorRequest_t satIntTiScsiXchg;
19098 tiMem_t satIntDmaMem;
19099 tiMem_t satIntReqBodyMem;
19100 bit32 satIntFlag;
19101 } satInternalIo_t;
19102 */
19103
19104 /*
19105 * Initialize satIntTiIORequest field
19106 */
19107 satIntIo->satIntTiIORequest.osData = agNULL; /* Not used for internal SAT I/O */
19108 satIntIo->satIntTiIORequest.tdData = satIntIo->satIntRequestBody;
19109
19110 /*
19111 * saves the original tiIOrequest
19112 */
19113 satIntIo->satOrgTiIORequest = tiIORequest;
19114 /*
19115 typedef struct tiIniScsiCmnd
19116 {
19117 tiLUN_t lun;
19118 bit32 expDataLength;
19119 bit32 taskAttribute;
19120 bit32 crn;
19121 bit8 cdb[16];
19122 } tiIniScsiCmnd_t;
19123
19124 typedef struct tiScsiInitiatorExchange
19125 {
19126 void *sglVirtualAddr;
19127 tiIniScsiCmnd_t scsiCmnd;
19128 tiSgl_t agSgl1;
19129 tiSgl_t agSgl2;
19130 tiDataDirection_t dataDirection;
19131 } tiScsiInitiatorRequest_t;
19132
19133 */
19134
19135 /*
19136 * Initialize satIntTiScsiXchg. Since the internal SAT request is NOT
19137 * originated from SCSI request, only the following fields are initialized:
19138 * - sglVirtualAddr if DMA transfer is involved
19139 * - agSgl1 if DMA transfer is involved
19140 * - expDataLength in scsiCmnd since this field is read by sataLLIOStart()
19141 */
19142 if (dmaAllocLength != 0)
19143 {
19144 satIntIo->satIntTiScsiXchg.sglVirtualAddr = satIntIo->satIntDmaMem.virtPtr;
19145
19146 OSSA_WRITE_LE_32(agNULL, &satIntIo->satIntTiScsiXchg.agSgl1.len, 0,
19147 satIntIo->satIntDmaMem.totalLength);
19148 satIntIo->satIntTiScsiXchg.agSgl1.lower = satIntIo->satIntDmaMem.physAddrLower;
19149 satIntIo->satIntTiScsiXchg.agSgl1.upper = satIntIo->satIntDmaMem.physAddrUpper;
19150 satIntIo->satIntTiScsiXchg.agSgl1.type = tiSgl;
19151
19152 satIntIo->satIntTiScsiXchg.scsiCmnd.expDataLength = satIntIo->satIntDmaMem.totalLength;
19153 }
19154 else
19155 {
19156 satIntIo->satIntTiScsiXchg.sglVirtualAddr = agNULL;
19157
19158 satIntIo->satIntTiScsiXchg.agSgl1.len = 0;
19159 satIntIo->satIntTiScsiXchg.agSgl1.lower = 0;
19160 satIntIo->satIntTiScsiXchg.agSgl1.upper = 0;
19161 satIntIo->satIntTiScsiXchg.agSgl1.type = tiSgl;
19162
19163 satIntIo->satIntTiScsiXchg.scsiCmnd.expDataLength = 0;
19164 }
19165
19166 TI_DBG5(("satAllocIntIoResource: satIntIo->satIntTiScsiXchg.agSgl1.len %d\n", satIntIo->satIntTiScsiXchg.agSgl1.len));
19167
19168 TI_DBG5(("satAllocIntIoResource: satIntIo->satIntTiScsiXchg.agSgl1.upper %d\n", satIntIo->satIntTiScsiXchg.agSgl1.upper));
19169
19170 TI_DBG5(("satAllocIntIoResource: satIntIo->satIntTiScsiXchg.agSgl1.lower %d\n", satIntIo->satIntTiScsiXchg.agSgl1.lower));
19171
19172 TI_DBG5(("satAllocIntIoResource: satIntIo->satIntTiScsiXchg.agSgl1.type %d\n", satIntIo->satIntTiScsiXchg.agSgl1.type));
19173 TI_DBG5(("satAllocIntIoResource: return satIntIo %p\n", satIntIo));
19174 return satIntIo;
19175
19176 }
19177
19178 /*****************************************************************************/
19179 /*! \brief Free resource for SAT intervally generated I/O.
19180 *
19181 * Free resource for SAT intervally generated I/O that was previously
19182 * allocated in satAllocIntIoResource().
19183 *
19184 * \param tiRoot: Pointer to TISA driver/port instance.
19185 * \param satDevData: Pointer to SAT specific device data.
19186 * \param satIntIo: Pointer to context for SAT internal I/O that was
19187 * previously allocated in satAllocIntIoResource().
19188 *
19189 * \return None
19190 */
19191 /*****************************************************************************/
satFreeIntIoResource(tiRoot_t * tiRoot,satDeviceData_t * satDevData,satInternalIo_t * satIntIo)19192 GLOBAL void satFreeIntIoResource(
19193 tiRoot_t *tiRoot,
19194 satDeviceData_t *satDevData,
19195 satInternalIo_t *satIntIo)
19196 {
19197 TI_DBG6(("satFreeIntIoResource: start\n"));
19198
19199 if (satIntIo == agNULL)
19200 {
19201 TI_DBG6(("satFreeIntIoResource: allowed call\n"));
19202 return;
19203 }
19204
19205 /* sets the original tiIOrequest to agNULL for internally generated ATA cmnd */
19206 satIntIo->satOrgTiIORequest = agNULL;
19207
19208 /*
19209 * Free DMA memory if previosly alocated
19210 */
19211 if (satIntIo->satIntTiScsiXchg.scsiCmnd.expDataLength != 0)
19212 {
19213 TI_DBG1(("satFreeIntIoResource: DMA len %d\n", satIntIo->satIntDmaMem.totalLength));
19214 TI_DBG6(("satFreeIntIoResource: pointer %p\n", satIntIo->satIntDmaMem.osHandle));
19215
19216 ostiFreeMemory( tiRoot,
19217 satIntIo->satIntDmaMem.osHandle,
19218 satIntIo->satIntDmaMem.totalLength);
19219 satIntIo->satIntTiScsiXchg.scsiCmnd.expDataLength = 0;
19220 }
19221
19222 if (satIntIo->satIntReqBodyMem.totalLength != 0)
19223 {
19224 TI_DBG1(("satFreeIntIoResource: req body len %d\n", satIntIo->satIntReqBodyMem.totalLength));
19225 /*
19226 * Free mem allocated for Req body
19227 */
19228 ostiFreeMemory( tiRoot,
19229 satIntIo->satIntReqBodyMem.osHandle,
19230 satIntIo->satIntReqBodyMem.totalLength);
19231
19232 satIntIo->satIntReqBodyMem.totalLength = 0;
19233 }
19234
19235 TI_DBG6(("satFreeIntIoResource: satDevData %p satIntIo id %d\n", satDevData, satIntIo->id));
19236 /*
19237 * Return satIntIo to the free list
19238 */
19239 tdsaSingleThreadedEnter(tiRoot, TD_SATA_LOCK);
19240 TDLIST_DEQUEUE_THIS (&(satIntIo->satIntIoLink));
19241 TDLIST_ENQUEUE_AT_TAIL (&(satIntIo->satIntIoLink), &(satDevData->satFreeIntIoLinkList));
19242 tdsaSingleThreadedLeave(tiRoot, TD_SATA_LOCK);
19243
19244 }
19245
19246
19247 /*****************************************************************************/
19248 /*! \brief SAT implementation for SCSI INQUIRY.
19249 *
19250 * SAT implementation for SCSI INQUIRY.
19251 * This function sends ATA Identify Device data command for SCSI INQUIRY
19252 *
19253 * \param tiRoot: Pointer to TISA initiator driver/port instance.
19254 * \param tiIORequest: Pointer to TISA I/O request context for this I/O.
19255 * \param tiDeviceHandle: Pointer to TISA device handle for this I/O.
19256 * \param tiScsiRequest: Pointer to TISA SCSI I/O request and SGL list.
19257 * \param satIOContext_t: Pointer to the SAT IO Context
19258 *
19259 * \return If command is started successfully
19260 * - \e tiSuccess: I/O request successfully initiated.
19261 * - \e tiBusy: No resources available, try again later.
19262 * - \e tiIONoDevice: Invalid device handle.
19263 * - \e tiError: Other errors.
19264 */
19265 /*****************************************************************************/
satSendIDDev(tiRoot_t * tiRoot,tiIORequest_t * tiIORequest,tiDeviceHandle_t * tiDeviceHandle,tiScsiInitiatorRequest_t * tiScsiRequest,satIOContext_t * satIOContext)19266 GLOBAL bit32 satSendIDDev(
19267 tiRoot_t *tiRoot,
19268 tiIORequest_t *tiIORequest,
19269 tiDeviceHandle_t *tiDeviceHandle,
19270 tiScsiInitiatorRequest_t *tiScsiRequest,
19271 satIOContext_t *satIOContext)
19272
19273 {
19274 bit32 status;
19275 bit32 agRequestType;
19276 satDeviceData_t *pSatDevData;
19277 agsaFisRegHostToDevice_t *fis;
19278 #ifdef TD_DEBUG_ENABLE
19279 satInternalIo_t *satIntIoContext;
19280 tdsaDeviceData_t *oneDeviceData;
19281 tdIORequestBody_t *tdIORequestBody;
19282 #endif
19283
19284 pSatDevData = satIOContext->pSatDevData;
19285 fis = satIOContext->pFis;
19286
19287 TI_DBG5(("satSendIDDev: start\n"));
19288 #ifdef TD_DEBUG_ENABLE
19289 oneDeviceData = (tdsaDeviceData_t *)tiDeviceHandle->tdData;
19290 #endif
19291 TI_DBG5(("satSendIDDev: did %d\n", oneDeviceData->id));
19292
19293
19294 #ifdef TD_DEBUG_ENABLE
19295 satIntIoContext = satIOContext->satIntIoContext;
19296 tdIORequestBody = satIntIoContext->satIntRequestBody;
19297 #endif
19298
19299 TI_DBG5(("satSendIDDev: satIOContext %p tdIORequestBody %p\n", satIOContext, tdIORequestBody));
19300
19301 fis->h.fisType = 0x27; /* Reg host to device */
19302 fis->h.c_pmPort = 0x80; /* C Bit is set */
19303 if (pSatDevData->satDeviceType == SATA_ATAPI_DEVICE)
19304 fis->h.command = SAT_IDENTIFY_PACKET_DEVICE; /* 0x40 */
19305 else
19306 fis->h.command = SAT_IDENTIFY_DEVICE; /* 0xEC */
19307 fis->h.features = 0; /* FIS reserve */
19308 fis->d.lbaLow = 0; /* FIS LBA (7 :0 ) */
19309 fis->d.lbaMid = 0; /* FIS LBA (15:8 ) */
19310 fis->d.lbaHigh = 0; /* FIS LBA (23:16) */
19311 fis->d.device = 0; /* FIS LBA mode */
19312 fis->d.lbaLowExp = 0;
19313 fis->d.lbaMidExp = 0;
19314 fis->d.lbaHighExp = 0;
19315 fis->d.featuresExp = 0;
19316 fis->d.sectorCount = 0; /* FIS sector count (7:0) */
19317 fis->d.sectorCountExp = 0;
19318 fis->d.reserved4 = 0;
19319 fis->d.control = 0; /* FIS HOB bit clear */
19320 fis->d.reserved5 = 0;
19321
19322 agRequestType = AGSA_SATA_PROTOCOL_PIO_READ;
19323
19324 /* Initialize CB for SATA completion.
19325 */
19326 satIOContext->satCompleteCB = &satInquiryCB;
19327
19328 /*
19329 * Prepare SGL and send FIS to LL layer.
19330 */
19331 satIOContext->reqType = agRequestType; /* Save it */
19332
19333 #ifdef TD_INTERNAL_DEBUG
19334 tdhexdump("satSendIDDev", (bit8 *)satIOContext->pFis, sizeof(agsaFisRegHostToDevice_t));
19335 #ifdef TD_DEBUG_ENABLE
19336 tdhexdump("satSendIDDev LL", (bit8 *)&(tdIORequestBody->transport.SATA.agSATARequestBody.fis.fisRegHostToDev), sizeof(agsaFisRegHostToDevice_t));
19337 #endif
19338 #endif
19339
19340 status = sataLLIOStart( tiRoot,
19341 tiIORequest,
19342 tiDeviceHandle,
19343 tiScsiRequest,
19344 satIOContext);
19345
19346 TI_DBG6(("satSendIDDev: end status %d\n", status));
19347 return status;
19348 }
19349
19350
19351 /*****************************************************************************/
19352 /*! \brief SAT implementation for SCSI INQUIRY.
19353 *
19354 * SAT implementation for SCSI INQUIRY.
19355 * This function prepares TD layer internal resource to send ATA
19356 * Identify Device data command for SCSI INQUIRY
19357 *
19358 * \param tiRoot: Pointer to TISA initiator driver/port instance.
19359 * \param tiIORequest: Pointer to TISA I/O request context for this I/O.
19360 * \param tiDeviceHandle: Pointer to TISA device handle for this I/O.
19361 * \param tiScsiRequest: Pointer to TISA SCSI I/O request and SGL list.
19362 * \param satIOContext_t: Pointer to the SAT IO Context
19363 *
19364 * \return If command is started successfully
19365 * - \e tiSuccess: I/O request successfully initiated.
19366 * - \e tiBusy: No resources available, try again later.
19367 * - \e tiIONoDevice: Invalid device handle.
19368 * - \e tiError: Other errors.
19369 */
19370 /*****************************************************************************/
19371 /* prerequsite: tdsaDeviceData and agdevhandle must exist; in other words, LL discovered the device
19372 already */
19373 /*
19374 convert OS generated IO to TD generated IO due to difference in sgl
19375 */
satStartIDDev(tiRoot_t * tiRoot,tiIORequest_t * tiIORequest,tiDeviceHandle_t * tiDeviceHandle,tiScsiInitiatorRequest_t * tiScsiRequest,satIOContext_t * satIOContext)19376 GLOBAL bit32 satStartIDDev(
19377 tiRoot_t *tiRoot,
19378 tiIORequest_t *tiIORequest,
19379 tiDeviceHandle_t *tiDeviceHandle,
19380 tiScsiInitiatorRequest_t *tiScsiRequest,
19381 satIOContext_t *satIOContext
19382 )
19383 {
19384 satInternalIo_t *satIntIo = agNULL;
19385 satDeviceData_t *satDevData = agNULL;
19386 tdIORequestBody_t *tdIORequestBody;
19387 satIOContext_t *satNewIOContext;
19388 bit32 status;
19389
19390 TI_DBG6(("satStartIDDev: start\n"));
19391
19392 satDevData = satIOContext->pSatDevData;
19393
19394 TI_DBG6(("satStartIDDev: before alloc\n"));
19395
19396 /* allocate identify device command */
19397 satIntIo = satAllocIntIoResource( tiRoot,
19398 tiIORequest,
19399 satDevData,
19400 sizeof(agsaSATAIdentifyData_t), /* 512; size of identify device data */
19401 satIntIo);
19402
19403 TI_DBG6(("satStartIDDev: before after\n"));
19404
19405 if (satIntIo == agNULL)
19406 {
19407 TI_DBG1(("satStartIDDev: can't alloacate\n"));
19408
19409 #if 0
19410 ostiInitiatorIOCompleted (
19411 tiRoot,
19412 tiIORequest,
19413 tiIOFailed,
19414 tiDetailOtherError,
19415 agNULL,
19416 satIOContext->interruptContext
19417 );
19418 #endif
19419
19420 return tiError;
19421 }
19422
19423 /* fill in fields */
19424 /* real ttttttthe one worked and the same; 5/21/07/ */
19425 satIntIo->satOrgTiIORequest = tiIORequest; /* changed */
19426 tdIORequestBody = satIntIo->satIntRequestBody;
19427 satNewIOContext = &(tdIORequestBody->transport.SATA.satIOContext);
19428
19429 satNewIOContext->pSatDevData = satDevData;
19430 satNewIOContext->pFis = &(tdIORequestBody->transport.SATA.agSATARequestBody.fis.fisRegHostToDev);
19431 satNewIOContext->pScsiCmnd = &(satIntIo->satIntTiScsiXchg.scsiCmnd);
19432 satNewIOContext->pSense = &(tdIORequestBody->transport.SATA.sensePayload);
19433 satNewIOContext->pTiSenseData = &(tdIORequestBody->transport.SATA.tiSenseData);
19434 satNewIOContext->tiRequestBody = satIntIo->satIntRequestBody; /* key fix */
19435 satNewIOContext->interruptContext = tiInterruptContext;
19436 satNewIOContext->satIntIoContext = satIntIo;
19437
19438 satNewIOContext->ptiDeviceHandle = agNULL;
19439 satNewIOContext->satOrgIOContext = satIOContext; /* changed */
19440
19441 /* this is valid only for TD layer generated (not triggered by OS at all) IO */
19442 satNewIOContext->tiScsiXchg = &(satIntIo->satIntTiScsiXchg);
19443
19444
19445 TI_DBG6(("satStartIDDev: OS satIOContext %p \n", satIOContext));
19446 TI_DBG6(("satStartIDDev: TD satNewIOContext %p \n", satNewIOContext));
19447 TI_DBG6(("satStartIDDev: OS tiScsiXchg %p \n", satIOContext->tiScsiXchg));
19448 TI_DBG6(("satStartIDDev: TD tiScsiXchg %p \n", satNewIOContext->tiScsiXchg));
19449
19450
19451
19452 TI_DBG1(("satStartIDDev: satNewIOContext %p tdIORequestBody %p\n", satNewIOContext, tdIORequestBody));
19453
19454 status = satSendIDDev( tiRoot,
19455 &satIntIo->satIntTiIORequest, /* New tiIORequest */
19456 tiDeviceHandle,
19457 satNewIOContext->tiScsiXchg, /* New tiScsiInitiatorRequest_t *tiScsiRequest, */
19458 satNewIOContext);
19459
19460 if (status != tiSuccess)
19461 {
19462 TI_DBG1(("satStartIDDev: failed in sending\n"));
19463
19464 satFreeIntIoResource( tiRoot,
19465 satDevData,
19466 satIntIo);
19467
19468 #if 0
19469 ostiInitiatorIOCompleted (
19470 tiRoot,
19471 tiIORequest,
19472 tiIOFailed,
19473 tiDetailOtherError,
19474 agNULL,
19475 satIOContext->interruptContext
19476 );
19477 #endif
19478
19479 return tiError;
19480 }
19481
19482
19483 TI_DBG6(("satStartIDDev: end\n"));
19484
19485 return status;
19486
19487
19488 }
19489
19490 /*****************************************************************************/
19491 /*! \brief satComputeCDB10LBA.
19492 *
19493 * This fuctions computes LBA of CDB10.
19494 *
19495 * \param satIOContext_t: Pointer to the SAT IO Context
19496 *
19497 * \return
19498 * - \e LBA
19499 */
19500 /*****************************************************************************/
satComputeCDB10LBA(satIOContext_t * satIOContext)19501 bit32 satComputeCDB10LBA(satIOContext_t *satIOContext)
19502 {
19503 tiIniScsiCmnd_t *scsiCmnd;
19504 tiScsiInitiatorRequest_t *tiScsiRequest;
19505 bit32 lba = 0;
19506
19507 TI_DBG5(("satComputeCDB10LBA: start\n"));
19508 tiScsiRequest = satIOContext->tiScsiXchg;
19509 scsiCmnd = &(tiScsiRequest->scsiCmnd);
19510
19511 lba = (scsiCmnd->cdb[2] << (8*3)) + (scsiCmnd->cdb[3] << (8*2))
19512 + (scsiCmnd->cdb[4] << 8) + scsiCmnd->cdb[5];
19513
19514 return lba;
19515 }
19516
19517 /*****************************************************************************/
19518 /*! \brief satComputeCDB10TL.
19519 *
19520 * This fuctions computes transfer length of CDB10.
19521 *
19522 * \param satIOContext_t: Pointer to the SAT IO Context
19523 *
19524 * \return
19525 * - \e TL
19526 */
19527 /*****************************************************************************/
satComputeCDB10TL(satIOContext_t * satIOContext)19528 bit32 satComputeCDB10TL(satIOContext_t *satIOContext)
19529 {
19530
19531 tiIniScsiCmnd_t *scsiCmnd;
19532 tiScsiInitiatorRequest_t *tiScsiRequest;
19533 bit32 tl = 0;
19534
19535 TI_DBG5(("satComputeCDB10TL: start\n"));
19536 tiScsiRequest = satIOContext->tiScsiXchg;
19537 scsiCmnd = &(tiScsiRequest->scsiCmnd);
19538
19539 tl = (scsiCmnd->cdb[7] << 8) + scsiCmnd->cdb[8];
19540 return tl;
19541 }
19542
19543 /*****************************************************************************/
19544 /*! \brief satComputeCDB12LBA.
19545 *
19546 * This fuctions computes LBA of CDB12.
19547 *
19548 * \param satIOContext_t: Pointer to the SAT IO Context
19549 *
19550 * \return
19551 * - \e LBA
19552 */
19553 /*****************************************************************************/
satComputeCDB12LBA(satIOContext_t * satIOContext)19554 bit32 satComputeCDB12LBA(satIOContext_t *satIOContext)
19555 {
19556 tiIniScsiCmnd_t *scsiCmnd;
19557 tiScsiInitiatorRequest_t *tiScsiRequest;
19558 bit32 lba = 0;
19559
19560 TI_DBG5(("satComputeCDB10LBA: start\n"));
19561 tiScsiRequest = satIOContext->tiScsiXchg;
19562 scsiCmnd = &(tiScsiRequest->scsiCmnd);
19563
19564 lba = (scsiCmnd->cdb[2] << (8*3)) + (scsiCmnd->cdb[3] << (8*2))
19565 + (scsiCmnd->cdb[4] << 8) + scsiCmnd->cdb[5];
19566
19567 return lba;
19568 }
19569
19570 /*****************************************************************************/
19571 /*! \brief satComputeCDB12TL.
19572 *
19573 * This fuctions computes transfer length of CDB12.
19574 *
19575 * \param satIOContext_t: Pointer to the SAT IO Context
19576 *
19577 * \return
19578 * - \e TL
19579 */
19580 /*****************************************************************************/
satComputeCDB12TL(satIOContext_t * satIOContext)19581 bit32 satComputeCDB12TL(satIOContext_t *satIOContext)
19582 {
19583
19584 tiIniScsiCmnd_t *scsiCmnd;
19585 tiScsiInitiatorRequest_t *tiScsiRequest;
19586 bit32 tl = 0;
19587
19588 TI_DBG5(("satComputeCDB10TL: start\n"));
19589 tiScsiRequest = satIOContext->tiScsiXchg;
19590 scsiCmnd = &(tiScsiRequest->scsiCmnd);
19591
19592 tl = (scsiCmnd->cdb[6] << (8*3)) + (scsiCmnd->cdb[7] << (8*2))
19593 + (scsiCmnd->cdb[8] << 8) + scsiCmnd->cdb[9];
19594 return tl;
19595 }
19596
19597
19598 /*****************************************************************************/
19599 /*! \brief satComputeCDB16LBA.
19600 *
19601 * This fuctions computes LBA of CDB16.
19602 *
19603 * \param satIOContext_t: Pointer to the SAT IO Context
19604 *
19605 * \return
19606 * - \e LBA
19607 */
19608 /*****************************************************************************/
19609 /*
19610 CBD16 has bit64 LBA
19611 But it has to be less than (2^28 - 1)
19612 Therefore, use last four bytes to compute LBA is OK
19613 */
satComputeCDB16LBA(satIOContext_t * satIOContext)19614 bit32 satComputeCDB16LBA(satIOContext_t *satIOContext)
19615 {
19616 tiIniScsiCmnd_t *scsiCmnd;
19617 tiScsiInitiatorRequest_t *tiScsiRequest;
19618 bit32 lba = 0;
19619
19620 TI_DBG5(("satComputeCDB10LBA: start\n"));
19621 tiScsiRequest = satIOContext->tiScsiXchg;
19622 scsiCmnd = &(tiScsiRequest->scsiCmnd);
19623
19624 lba = (scsiCmnd->cdb[6] << (8*3)) + (scsiCmnd->cdb[7] << (8*2))
19625 + (scsiCmnd->cdb[8] << 8) + scsiCmnd->cdb[9];
19626
19627 return lba;
19628 }
19629
19630 /*****************************************************************************/
19631 /*! \brief satComputeCDB16TL.
19632 *
19633 * This fuctions computes transfer length of CDB16.
19634 *
19635 * \param satIOContext_t: Pointer to the SAT IO Context
19636 *
19637 * \return
19638 * - \e TL
19639 */
19640 /*****************************************************************************/
satComputeCDB16TL(satIOContext_t * satIOContext)19641 bit32 satComputeCDB16TL(satIOContext_t *satIOContext)
19642 {
19643
19644 tiIniScsiCmnd_t *scsiCmnd;
19645 tiScsiInitiatorRequest_t *tiScsiRequest;
19646 bit32 tl = 0;
19647
19648 TI_DBG5(("satComputeCDB10TL: start\n"));
19649 tiScsiRequest = satIOContext->tiScsiXchg;
19650 scsiCmnd = &(tiScsiRequest->scsiCmnd);
19651
19652 tl = (scsiCmnd->cdb[10] << (8*3)) + (scsiCmnd->cdb[11] << (8*2))
19653 + (scsiCmnd->cdb[12] << 8) + scsiCmnd->cdb[13];
19654 return tl;
19655 }
19656
19657 /*****************************************************************************/
19658 /*! \brief satComputeLoopNum.
19659 *
19660 * This fuctions computes the number of interation needed for a transfer
19661 * length with a specific number.
19662 *
19663 * \param a: a numerator
19664 * \param b: a denominator
19665 *
19666 * \return
19667 * - \e number of interation
19668 */
19669 /*****************************************************************************/
19670 /*
19671 (tl, denom)
19672 tl can be upto bit32 because CDB16 has bit32 tl
19673 Therefore, fine
19674 either (tl, 0xFF) or (tl, 0xFFFF)
19675 */
satComputeLoopNum(bit32 a,bit32 b)19676 bit32 satComputeLoopNum(bit32 a, bit32 b)
19677 {
19678
19679 bit32 quo = 0, rem = 0;
19680 bit32 LoopNum = 0;
19681
19682 TI_DBG5(("satComputeLoopNum: start\n"));
19683
19684 quo = a/b;
19685
19686 if (quo == 0)
19687 {
19688 LoopNum = 1;
19689 }
19690 else
19691 {
19692 rem = a % b;
19693 if (rem == 0)
19694 {
19695 LoopNum = quo;
19696 }
19697 else
19698 {
19699 LoopNum = quo + 1;
19700 }
19701 }
19702
19703 return LoopNum;
19704 }
19705
19706 /*****************************************************************************/
19707 /*! \brief satAddNComparebit64.
19708 *
19709 *
19710 *
19711 *
19712 * \param a: lba
19713 * \param b: tl
19714 *
19715 * \return
19716 * - \e TRUE if (lba + tl > SAT_TR_LBA_LIMIT)
19717 * - \e FALSE otherwise
19718 * \note: a and b must be in the same length
19719 */
19720 /*****************************************************************************/
19721 /*
19722 input: bit8 a[8], bit8 b[8] (lba, tl) must be in same length
19723 if (lba + tl > SAT_TR_LBA_LIMIT)
19724 then returns true
19725 else returns false
19726 (LBA,TL)
19727 */
satAddNComparebit64(bit8 * a,bit8 * b)19728 bit32 satAddNComparebit64(bit8 *a, bit8 *b)
19729 {
19730 bit16 ans[8]; // 0 MSB, 8 LSB
19731 bit8 final_ans[9]; // 0 MSB, 9 LSB
19732 bit8 max[9];
19733 int i;
19734
19735 TI_DBG5(("satAddNComparebit64: start\n"));
19736
19737 osti_memset(ans, 0, sizeof(ans));
19738 osti_memset(final_ans, 0, sizeof(final_ans));
19739 osti_memset(max, 0, sizeof(max));
19740
19741 max[0] = 0x1; //max = 0x1 0000 0000 0000 0000
19742
19743 // adding from LSB to MSB
19744 for(i=7;i>=0;i--)
19745 {
19746 ans[i] = (bit16)(a[i] + b[i]);
19747 if (i != 7)
19748 {
19749 ans[i] = (bit16)(ans[i] + ((ans[i+1] & 0xFF00) >> 8));
19750 }
19751 }
19752
19753 /*
19754 filling in the final answer
19755 */
19756 final_ans[0] = (bit8)(((ans[0] & 0xFF00) >> 8));
19757 final_ans[1] = (bit8)(ans[0] & 0xFF);
19758
19759 for(i=2;i<=8;i++)
19760 {
19761 final_ans[i] = (bit8)(ans[i-1] & 0xFF);
19762 }
19763
19764 //compare final_ans to max
19765 for(i=0;i<=8;i++)
19766 {
19767 if (final_ans[i] > max[i])
19768 {
19769 TI_DBG5(("satAddNComparebit64: yes at %d\n", i));
19770 return agTRUE;
19771 }
19772 else if (final_ans[i] < max[i])
19773 {
19774 TI_DBG5(("satAddNComparebit64: no at %d\n", i));
19775 return agFALSE;
19776 }
19777 else
19778 {
19779 continue;
19780 }
19781 }
19782
19783
19784 return agFALSE;
19785 }
19786
19787 /*****************************************************************************/
19788 /*! \brief satAddNComparebit32.
19789 *
19790 *
19791 *
19792 *
19793 * \param a: lba
19794 * \param b: tl
19795 *
19796 * \return
19797 * - \e TRUE if (lba + tl > SAT_TR_LBA_LIMIT)
19798 * - \e FALSE otherwise
19799 * \note: a and b must be in the same length
19800 */
19801 /*****************************************************************************/
19802 /*
19803 input: bit8 a[4], bit8 b[4] (lba, tl) must be in same length
19804 if (lba + tl > SAT_TR_LBA_LIMIT)
19805 then returns true
19806 else returns false
19807 (LBA,TL)
19808 */
satAddNComparebit32(bit8 * a,bit8 * b)19809 bit32 satAddNComparebit32(bit8 *a, bit8 *b)
19810 {
19811 bit16 ans[4]; // 0 MSB, 4 LSB
19812 bit8 final_ans[5]; // 0 MSB, 5 LSB
19813 bit8 max[4];
19814 int i;
19815
19816 TI_DBG5(("satAddNComparebit32: start\n"));
19817
19818 osti_memset(ans, 0, sizeof(ans));
19819 osti_memset(final_ans, 0, sizeof(final_ans));
19820 osti_memset(max, 0, sizeof(max));
19821
19822 max[0] = 0x10; // max =0x1000 0000
19823
19824 // adding from LSB to MSB
19825 for(i=3;i>=0;i--)
19826 {
19827 ans[i] = (bit16)(a[i] + b[i]);
19828 if (i != 3)
19829 {
19830 ans[i] = (bit16)(ans[i] + ((ans[i+1] & 0xFF00) >> 8));
19831 }
19832 }
19833
19834
19835 /*
19836 filling in the final answer
19837 */
19838 final_ans[0] = (bit8)(((ans[0] & 0xFF00) >> 8));
19839 final_ans[1] = (bit8)(ans[0] & 0xFF);
19840
19841 for(i=2;i<=4;i++)
19842 {
19843 final_ans[i] = (bit8)(ans[i-1] & 0xFF);
19844 }
19845
19846 //compare final_ans to max
19847 if (final_ans[0] != 0)
19848 {
19849 TI_DBG5(("satAddNComparebit32: yes bigger and out of range\n"));
19850 return agTRUE;
19851 }
19852 for(i=1;i<=4;i++)
19853 {
19854 if (final_ans[i] > max[i-1])
19855 {
19856 TI_DBG5(("satAddNComparebit32: yes at %d\n", i));
19857 return agTRUE;
19858 }
19859 else if (final_ans[i] < max[i-1])
19860 {
19861 TI_DBG5(("satAddNComparebit32: no at %d\n", i));
19862 return agFALSE;
19863 }
19864 else
19865 {
19866 continue;
19867 }
19868 }
19869
19870
19871 return agFALSE;
19872 }
19873
19874 /*****************************************************************************/
19875 /*! \brief satCompareLBALimitbit.
19876 *
19877 *
19878 *
19879 *
19880 * \param lba: lba
19881 *
19882 * \return
19883 * - \e TRUE if (lba > SAT_TR_LBA_LIMIT - 1)
19884 * - \e FALSE otherwise
19885 * \note: a and b must be in the same length
19886 */
19887 /*****************************************************************************/
19888
19889 /*
19890 lba
19891 */
19892 /*
19893 input: bit8 lba[8]
19894 if (lba > SAT_TR_LBA_LIMIT - 1)
19895 then returns true
19896 else returns false
19897 (LBA,TL)
19898 */
satCompareLBALimitbit(bit8 * lba)19899 bit32 satCompareLBALimitbit(bit8 *lba)
19900 {
19901 bit32 i;
19902 bit8 limit[8];
19903
19904 /* limit is 0xF FF FF = 2^28 - 1 */
19905 limit[0] = 0x0; /* MSB */
19906 limit[1] = 0x0;
19907 limit[2] = 0x0;
19908 limit[3] = 0x0;
19909 limit[4] = 0xF;
19910 limit[5] = 0xFF;
19911 limit[6] = 0xFF;
19912 limit[7] = 0xFF; /* LSB */
19913
19914 //compare lba to limit
19915 for(i=0;i<8;i++)
19916 {
19917 if (lba[i] > limit[i])
19918 {
19919 TI_DBG5(("satCompareLBALimitbit64: yes at %d\n", i));
19920 return agTRUE;
19921 }
19922 else if (lba[i] < limit[i])
19923 {
19924 TI_DBG5(("satCompareLBALimitbit64: no at %d\n", i));
19925 return agFALSE;
19926 }
19927 else
19928 {
19929 continue;
19930 }
19931 }
19932
19933
19934 return agFALSE;
19935
19936 }
19937 /*****************************************************************************
19938 *! \brief
19939 * Purpose: bitwise set
19940 *
19941 * Parameters:
19942 * data - input output buffer
19943 * index - bit to set
19944 *
19945 * Return:
19946 * none
19947 *
19948 *****************************************************************************/
19949 GLOBAL void
satBitSet(bit8 * data,bit32 index)19950 satBitSet(bit8 *data, bit32 index)
19951 {
19952 data[index/8] |= (1 << (index%8));
19953 }
19954
19955 /*****************************************************************************
19956 *! \brief
19957 * Purpose: bitwise clear
19958 *
19959 * Parameters:
19960 * data - input output buffer
19961 * index - bit to clear
19962 *
19963 * Return:
19964 * none
19965 *
19966 *****************************************************************************/
19967 GLOBAL void
satBitClear(bit8 * data,bit32 index)19968 satBitClear(bit8 *data, bit32 index)
19969 {
19970 data[index/8] &= ~(1 << (index%8));
19971 }
19972
19973 /*****************************************************************************
19974 *! \brief
19975 * Purpose: bitwise test
19976 *
19977 * Parameters:
19978 * data - input output buffer
19979 * index - bit to test
19980 *
19981 * Return:
19982 * 0 - not set
19983 * 1 - set
19984 *
19985 *****************************************************************************/
19986 GLOBAL agBOOLEAN
satBitTest(bit8 * data,bit32 index)19987 satBitTest(bit8 *data, bit32 index)
19988 {
19989 return ( (BOOLEAN)((data[index/8] & (1 << (index%8)) ) ? 1: 0));
19990 }
19991
19992
19993 /******************************************************************************/
19994 /*! \brief allocate an available SATA tag
19995 *
19996 * allocate an available SATA tag
19997 *
19998 * \param tiRoot Pointer to TISA initiator driver/port instance.
19999 * \param pSatDevData
20000 * \param pTag
20001 *
20002 * \return -Success or fail-
20003 */
20004 /*******************************************************************************/
satTagAlloc(tiRoot_t * tiRoot,satDeviceData_t * pSatDevData,bit8 * pTag)20005 GLOBAL bit32 satTagAlloc(
20006 tiRoot_t *tiRoot,
20007 satDeviceData_t *pSatDevData,
20008 bit8 *pTag
20009 )
20010 {
20011 bit32 retCode = agFALSE;
20012 bit32 i;
20013
20014 tdsaSingleThreadedEnter(tiRoot, TD_SATA_LOCK);
20015 for ( i = 0; i < pSatDevData->satNCQMaxIO; i ++ )
20016 {
20017 if ( 0 == satBitTest((bit8 *)&pSatDevData->freeSATAFDMATagBitmap, i) )
20018 {
20019 satBitSet((bit8*)&pSatDevData->freeSATAFDMATagBitmap, i);
20020 *pTag = (bit8) i;
20021 retCode = agTRUE;
20022 break;
20023 }
20024 }
20025 tdsaSingleThreadedLeave(tiRoot, TD_SATA_LOCK);
20026 return retCode;
20027 }
20028
20029 /******************************************************************************/
20030 /*! \brief release an SATA tag
20031 *
20032 * release an available SATA tag
20033 *
20034 * \param tiRoot Pointer to TISA initiator driver/port instance.
20035 * \param pSatDevData
20036 * \param Tag
20037 *
20038 * \return -the tag-
20039 */
20040 /*******************************************************************************/
satTagRelease(tiRoot_t * tiRoot,satDeviceData_t * pSatDevData,bit8 tag)20041 GLOBAL bit32 satTagRelease(
20042 tiRoot_t *tiRoot,
20043 satDeviceData_t *pSatDevData,
20044 bit8 tag
20045 )
20046 {
20047 bit32 retCode = agFALSE;
20048
20049 tdsaSingleThreadedEnter(tiRoot, TD_SATA_LOCK);
20050 if ( tag < pSatDevData->satNCQMaxIO )
20051 {
20052 satBitClear( (bit8 *)&pSatDevData->freeSATAFDMATagBitmap, (bit32)tag);
20053 retCode = agTRUE;
20054 }
20055 tdsaSingleThreadedLeave(tiRoot, TD_SATA_LOCK);
20056 return retCode;
20057 }
20058
20059 /*****************************************************************************
20060 *! \brief satSubTM
20061 *
20062 * This routine is called to initiate a TM request to SATL.
20063 * This routine is independent of HW/LL API.
20064 *
20065 * \param tiRoot: Pointer to TISA initiator driver/port instance.
20066 * \param tiDeviceHandle: Pointer to TISA device handle for this I/O.
20067 * \param task: SAM-3 task management request.
20068 * \param lun: Pointer to LUN.
20069 * \param taskTag: Pointer to the associated task where the TM
20070 * command is to be applied.
20071 * \param currentTaskTag: Pointer to tag/context for this TM request.
20072 * \param NotifyOS flag determines whether notify OS layer or not
20073 *
20074 * \return:
20075 *
20076 * \e tiSuccess: I/O request successfully initiated.
20077 * \e tiBusy: No resources available, try again later.
20078 * \e tiIONoDevice: Invalid device handle.
20079 * \e tiError: Other errors that prevent the I/O request to be started.
20080 *
20081 * \note:
20082 * This funcion is triggered bottom up. Not yet in use.
20083 *****************************************************************************/
20084 /* called for bottom up */
satSubTM(tiRoot_t * tiRoot,tiDeviceHandle_t * tiDeviceHandle,bit32 task,tiLUN_t * lun,tiIORequest_t * taskTag,tiIORequest_t * currentTaskTag,bit32 NotifyOS)20085 osGLOBAL bit32 satSubTM(
20086 tiRoot_t *tiRoot,
20087 tiDeviceHandle_t *tiDeviceHandle,
20088 bit32 task,
20089 tiLUN_t *lun,
20090 tiIORequest_t *taskTag,
20091 tiIORequest_t *currentTaskTag,
20092 bit32 NotifyOS
20093 )
20094 {
20095 void *osMemHandle;
20096 tdIORequestBody_t *TMtdIORequestBody;
20097 bit32 PhysUpper32;
20098 bit32 PhysLower32;
20099 bit32 memAllocStatus;
20100 agsaIORequest_t *agIORequest = agNULL;
20101
20102 TI_DBG6(("satSubTM: start\n"));
20103
20104 /* allocation tdIORequestBody and pass it to satTM() */
20105 memAllocStatus = ostiAllocMemory(
20106 tiRoot,
20107 &osMemHandle,
20108 (void **)&TMtdIORequestBody,
20109 &PhysUpper32,
20110 &PhysLower32,
20111 8,
20112 sizeof(tdIORequestBody_t),
20113 agTRUE
20114 );
20115
20116 if (memAllocStatus != tiSuccess)
20117 {
20118 TI_DBG1(("satSubTM: ostiAllocMemory failed... \n"));
20119 return tiError;
20120 }
20121
20122 if (TMtdIORequestBody == agNULL)
20123 {
20124 TI_DBG1(("satSubTM: ostiAllocMemory returned NULL TMIORequestBody\n"));
20125 return tiError;
20126 }
20127
20128 /* setup task management structure */
20129 TMtdIORequestBody->IOType.InitiatorTMIO.osMemHandle = osMemHandle;
20130 TMtdIORequestBody->IOType.InitiatorTMIO.CurrentTaskTag = agNULL;
20131 TMtdIORequestBody->IOType.InitiatorTMIO.TaskTag = agNULL;
20132
20133 /* initialize tiDevhandle */
20134 TMtdIORequestBody->tiDevHandle = tiDeviceHandle;
20135
20136 /* initialize tiIORequest */
20137 TMtdIORequestBody->tiIORequest = agNULL;
20138
20139 /* initialize agIORequest */
20140 agIORequest = &(TMtdIORequestBody->agIORequest);
20141 agIORequest->osData = (void *) TMtdIORequestBody;
20142 agIORequest->sdkData = agNULL; /* SA takes care of this */
20143 satTM(tiRoot,
20144 tiDeviceHandle,
20145 task, /* TD_INTERNAL_TM_RESET */
20146 agNULL,
20147 agNULL,
20148 agNULL,
20149 TMtdIORequestBody,
20150 agFALSE);
20151
20152 return tiSuccess;
20153 }
20154
20155
20156 /*****************************************************************************/
20157 /*! \brief SAT implementation for satStartResetDevice.
20158 *
20159 * SAT implementation for sending SRT and send FIS request to LL layer.
20160 *
20161 * \param tiRoot: Pointer to TISA initiator driver/port instance.
20162 * \param tiIORequest: Pointer to TISA I/O request context for this I/O.
20163 * \param tiDeviceHandle: Pointer to TISA device handle for this I/O.
20164 * \param tiScsiRequest: Pointer to TISA SCSI I/O request and SGL list.
20165 * \param satIOContext_t: Pointer to the SAT IO Context
20166 *
20167 * \return If command is started successfully
20168 * - \e tiSuccess: I/O request successfully initiated.
20169 * - \e tiBusy: No resources available, try again later.
20170 * - \e tiIONoDevice: Invalid device handle.
20171 * - \e tiError: Other errors.
20172 * \note : triggerred by OS layer or bottom up
20173 */
20174 /*****************************************************************************/
20175 /* OS triggerred or bottom up */
20176 GLOBAL bit32
satStartResetDevice(tiRoot_t * tiRoot,tiIORequest_t * tiIORequest,tiDeviceHandle_t * tiDeviceHandle,tiScsiInitiatorRequest_t * tiScsiRequest,satIOContext_t * satIOContext)20177 satStartResetDevice(
20178 tiRoot_t *tiRoot,
20179 tiIORequest_t *tiIORequest, /* currentTaskTag */
20180 tiDeviceHandle_t *tiDeviceHandle,
20181 tiScsiInitiatorRequest_t *tiScsiRequest, /* should be NULL */
20182 satIOContext_t *satIOContext
20183 )
20184 {
20185 satInternalIo_t *satIntIo = agNULL;
20186 satDeviceData_t *satDevData = agNULL;
20187 satIOContext_t *satNewIOContext;
20188 bit32 status;
20189 tiIORequest_t *currentTaskTag = agNULL;
20190
20191 TI_DBG1(("satStartResetDevice: start\n"));
20192
20193 currentTaskTag = tiIORequest;
20194
20195 satDevData = satIOContext->pSatDevData;
20196
20197 TI_DBG6(("satStartResetDevice: before alloc\n"));
20198
20199 /* allocate any fis for seting SRT bit in device control */
20200 satIntIo = satAllocIntIoResource( tiRoot,
20201 tiIORequest,
20202 satDevData,
20203 0,
20204 satIntIo);
20205
20206 TI_DBG6(("satStartResetDevice: before after\n"));
20207
20208 if (satIntIo == agNULL)
20209 {
20210 TI_DBG1(("satStartResetDevice: can't alloacate\n"));
20211 if (satIOContext->NotifyOS)
20212 {
20213 ostiInitiatorEvent( tiRoot,
20214 NULL,
20215 NULL,
20216 tiIntrEventTypeTaskManagement,
20217 tiTMFailed,
20218 currentTaskTag );
20219 }
20220 return tiError;
20221 }
20222
20223 satNewIOContext = satPrepareNewIO(satIntIo,
20224 tiIORequest,
20225 satDevData,
20226 agNULL,
20227 satIOContext);
20228
20229 TI_DBG6(("satStartResetDevice: OS satIOContext %p \n", satIOContext));
20230 TI_DBG6(("satStartResetDevice: TD satNewIOContext %p \n", satNewIOContext));
20231 TI_DBG6(("satStartResetDevice: OS tiScsiXchg %p \n", satIOContext->tiScsiXchg));
20232 TI_DBG6(("satStartResetDevice: TD tiScsiXchg %p \n", satNewIOContext->tiScsiXchg));
20233
20234
20235
20236 TI_DBG6(("satStartResetDevice: satNewIOContext %p \n", satNewIOContext));
20237
20238 if (satDevData->satDeviceType == SATA_ATAPI_DEVICE)
20239 {
20240 status = satDeviceReset(tiRoot,
20241 &satIntIo->satIntTiIORequest, /* New tiIORequest */
20242 tiDeviceHandle,
20243 satNewIOContext->tiScsiXchg, /* New tiScsiInitiatorRequest_t *tiScsiRequest, */
20244 satNewIOContext);
20245 }
20246 else
20247 {
20248 status = satResetDevice(tiRoot,
20249 &satIntIo->satIntTiIORequest, /* New tiIORequest */
20250 tiDeviceHandle,
20251 satNewIOContext->tiScsiXchg, /* New tiScsiInitiatorRequest_t *tiScsiRequest, */
20252 satNewIOContext);
20253 }
20254
20255 if (status != tiSuccess)
20256 {
20257 TI_DBG1(("satStartResetDevice: failed in sending\n"));
20258
20259 satFreeIntIoResource( tiRoot,
20260 satDevData,
20261 satIntIo);
20262 if (satIOContext->NotifyOS)
20263 {
20264 ostiInitiatorEvent( tiRoot,
20265 NULL,
20266 NULL,
20267 tiIntrEventTypeTaskManagement,
20268 tiTMFailed,
20269 currentTaskTag );
20270 }
20271
20272 return tiError;
20273 }
20274
20275
20276 TI_DBG6(("satStartResetDevice: end\n"));
20277
20278 return status;
20279 }
20280
20281 /*****************************************************************************/
20282 /*! \brief SAT implementation for satResetDevice.
20283 *
20284 * SAT implementation for building SRT FIS and sends the request to LL layer.
20285 *
20286 * \param tiRoot: Pointer to TISA initiator driver/port instance.
20287 * \param tiIORequest: Pointer to TISA I/O request context for this I/O.
20288 * \param tiDeviceHandle: Pointer to TISA device handle for this I/O.
20289 * \param tiScsiRequest: Pointer to TISA SCSI I/O request and SGL list.
20290 * \param satIOContext_t: Pointer to the SAT IO Context
20291 *
20292 * \return If command is started successfully
20293 * - \e tiSuccess: I/O request successfully initiated.
20294 * - \e tiBusy: No resources available, try again later.
20295 * - \e tiIONoDevice: Invalid device handle.
20296 * - \e tiError: Other errors.
20297 */
20298 /*****************************************************************************/
20299
20300 /*
20301 create any fis and set SRST bit in device control
20302 */
20303 GLOBAL bit32
satResetDevice(tiRoot_t * tiRoot,tiIORequest_t * tiIORequest,tiDeviceHandle_t * tiDeviceHandle,tiScsiInitiatorRequest_t * tiScsiRequest,satIOContext_t * satIOContext)20304 satResetDevice(
20305 tiRoot_t *tiRoot,
20306 tiIORequest_t *tiIORequest,
20307 tiDeviceHandle_t *tiDeviceHandle,
20308 tiScsiInitiatorRequest_t *tiScsiRequest,
20309 satIOContext_t *satIOContext
20310 )
20311 {
20312 bit32 status;
20313 bit32 agRequestType;
20314 agsaFisRegHostToDevice_t *fis;
20315 #ifdef TD_DEBUG_ENABLE
20316 tdIORequestBody_t *tdIORequestBody;
20317 satInternalIo_t *satIntIoContext;
20318 #endif
20319
20320 fis = satIOContext->pFis;
20321
20322 TI_DBG2(("satResetDevice: start\n"));
20323
20324 #ifdef TD_DEBUG_ENABLE
20325 satIntIoContext = satIOContext->satIntIoContext;
20326 tdIORequestBody = satIntIoContext->satIntRequestBody;
20327 #endif
20328 TI_DBG5(("satResetDevice: satIOContext %p tdIORequestBody %p\n", satIOContext, tdIORequestBody));
20329 /* any fis should work */
20330 fis->h.fisType = 0x27; /* Reg host to device */
20331 fis->h.c_pmPort = 0; /* C Bit is not set */
20332 fis->h.command = 0; /* any command */
20333 fis->h.features = 0; /* FIS reserve */
20334 fis->d.lbaLow = 0; /* FIS LBA (7 :0 ) */
20335 fis->d.lbaMid = 0; /* FIS LBA (15:8 ) */
20336 fis->d.lbaHigh = 0; /* FIS LBA (23:16) */
20337 fis->d.device = 0; /* FIS LBA mode */
20338 fis->d.lbaLowExp = 0;
20339 fis->d.lbaMidExp = 0;
20340 fis->d.lbaHighExp = 0;
20341 fis->d.featuresExp = 0;
20342 fis->d.sectorCount = 0; /* FIS sector count (7:0) */
20343 fis->d.sectorCountExp = 0;
20344 fis->d.reserved4 = 0;
20345 fis->d.control = 0x4; /* SRST bit is set */
20346 fis->d.reserved5 = 0;
20347
20348 agRequestType = AGSA_SATA_PROTOCOL_SRST_ASSERT;
20349
20350 satIOContext->satCompleteCB = &satResetDeviceCB;
20351
20352 /*
20353 * Prepare SGL and send FIS to LL layer.
20354 */
20355 satIOContext->reqType = agRequestType; /* Save it */
20356
20357 #ifdef TD_INTERNAL_DEBUG
20358 tdhexdump("satResetDevice", (bit8 *)satIOContext->pFis, sizeof(agsaFisRegHostToDevice_t));
20359 #ifdef TD_DEBUG_ENABLE
20360 tdhexdump("satResetDevice LL", (bit8 *)&(tdIORequestBody->transport.SATA.agSATARequestBody.fis.fisRegHostToDev), sizeof(agsaFisRegHostToDevice_t));
20361 #endif
20362 #endif
20363
20364 status = sataLLIOStart( tiRoot,
20365 tiIORequest,
20366 tiDeviceHandle,
20367 tiScsiRequest,
20368 satIOContext);
20369
20370 TI_DBG6(("satResetDevice: end status %d\n", status));
20371 return status;
20372 }
20373
20374 /*****************************************************************************
20375 *! \brief satResetDeviceCB
20376 *
20377 * This routine is a callback function called from ossaSATACompleted().
20378 * This CB routine deals with SRT completion. This function send DSRT
20379 *
20380 * \param agRoot: Handles for this instance of SAS/SATA hardware
20381 * \param agIORequest: Pointer to the LL I/O request context for this I/O.
20382 * \param agIOStatus: Status of completed I/O.
20383 * \param agFirstDword:Pointer to the four bytes of FIS.
20384 * \param agIOInfoLen: Length in bytes of overrun/underrun residual or FIS
20385 * length.
20386 * \param agParam: Additional info based on status.
20387 * \param ioContext: Pointer to satIOContext_t.
20388 *
20389 * \return: none
20390 *
20391 *****************************************************************************/
satResetDeviceCB(agsaRoot_t * agRoot,agsaIORequest_t * agIORequest,bit32 agIOStatus,agsaFisHeader_t * agFirstDword,bit32 agIOInfoLen,agsaFrameHandle_t agFrameHandle,void * ioContext)20392 GLOBAL void satResetDeviceCB(
20393 agsaRoot_t *agRoot,
20394 agsaIORequest_t *agIORequest,
20395 bit32 agIOStatus,
20396 agsaFisHeader_t *agFirstDword,
20397 bit32 agIOInfoLen,
20398 agsaFrameHandle_t agFrameHandle,
20399 void *ioContext
20400 )
20401 {
20402 /* callback for satResetDevice */
20403 tdsaRootOsData_t *osData = (tdsaRootOsData_t *)agRoot->osData;
20404 tiRoot_t *tiRoot = (tiRoot_t *)osData->tiRoot;
20405 tdsaRoot_t *tdsaRoot = (tdsaRoot_t *) tiRoot->tdData;
20406 tdsaContext_t *tdsaAllShared = (tdsaContext_t *)&tdsaRoot->tdsaAllShared;
20407 tdIORequestBody_t *tdIORequestBody;
20408 tdIORequestBody_t *tdOrgIORequestBody;
20409 satIOContext_t *satIOContext;
20410 satIOContext_t *satOrgIOContext;
20411 satIOContext_t *satNewIOContext;
20412 satInternalIo_t *satIntIo;
20413 satInternalIo_t *satNewIntIo = agNULL;
20414 satDeviceData_t *satDevData;
20415 tiIORequest_t *tiOrgIORequest;
20416 #ifdef TD_DEBUG_ENABLE
20417 bit32 ataStatus = 0;
20418 bit32 ataError;
20419 agsaFisPioSetupHeader_t *satPIOSetupHeader = agNULL;
20420 #endif
20421 bit32 status;
20422
20423 TI_DBG1(("satResetDeviceCB: start\n"));
20424 TI_DBG6(("satResetDeviceCB: agIORequest=%p agIOStatus=0x%x agIOInfoLen %d\n", agIORequest, agIOStatus, agIOInfoLen));
20425
20426 tdIORequestBody = (tdIORequestBody_t *)agIORequest->osData;
20427 satIOContext = (satIOContext_t *) ioContext;
20428 satIntIo = satIOContext->satIntIoContext;
20429 satDevData = satIOContext->pSatDevData;
20430 if (satIntIo == agNULL)
20431 {
20432 TI_DBG6(("satResetDeviceCB: External, OS generated\n"));
20433 satOrgIOContext = satIOContext;
20434 tiOrgIORequest = tdIORequestBody->tiIORequest;
20435 }
20436 else
20437 {
20438 TI_DBG6(("satResetDeviceCB: Internal, TD generated\n"));
20439 satOrgIOContext = satIOContext->satOrgIOContext;
20440 if (satOrgIOContext == agNULL)
20441 {
20442 TI_DBG6(("satResetDeviceCB: satOrgIOContext is NULL, wrong\n"));
20443 return;
20444 }
20445 else
20446 {
20447 TI_DBG6(("satResetDeviceCB: satOrgIOContext is NOT NULL\n"));
20448 }
20449 tdOrgIORequestBody = (tdIORequestBody_t *)satOrgIOContext->tiRequestBody;
20450 tiOrgIORequest = (tiIORequest_t *)tdOrgIORequestBody->tiIORequest;
20451 }
20452
20453 tdIORequestBody->ioCompleted = agTRUE;
20454 tdIORequestBody->ioStarted = agFALSE;
20455
20456 if (agFirstDword == agNULL && agIOStatus != OSSA_IO_SUCCESS)
20457 {
20458 TI_DBG1(("satResetDeviceCB: wrong. agFirstDword is NULL when error, status %d\n", agIOStatus));
20459 if (satOrgIOContext->NotifyOS == agTRUE)
20460 {
20461 ostiInitiatorEvent( tiRoot,
20462 NULL,
20463 NULL,
20464 tiIntrEventTypeTaskManagement,
20465 tiTMFailed,
20466 tiOrgIORequest );
20467 }
20468
20469 satDevData->satTmTaskTag = agNULL;
20470
20471 satDecrementPendingIO(tiRoot, tdsaAllShared, satIOContext);
20472
20473 satFreeIntIoResource( tiRoot,
20474 satDevData,
20475 satIntIo);
20476 return;
20477 }
20478
20479 if (agIOStatus == OSSA_IO_OPEN_CNX_ERROR_PROTOCOL_NOT_SUPPORTED ||
20480 agIOStatus == OSSA_IO_OPEN_CNX_ERROR_ZONE_VIOLATION ||
20481 agIOStatus == OSSA_IO_OPEN_CNX_ERROR_BREAK ||
20482 agIOStatus == OSSA_IO_OPEN_CNX_ERROR_IT_NEXUS_LOSS ||
20483 agIOStatus == OSSA_IO_OPEN_CNX_ERROR_BAD_DESTINATION ||
20484 agIOStatus == OSSA_IO_OPEN_CNX_ERROR_CONNECTION_RATE_NOT_SUPPORTED ||
20485 agIOStatus == OSSA_IO_OPEN_CNX_ERROR_WRONG_DESTINATION ||
20486 agIOStatus == OSSA_IO_OPEN_CNX_ERROR_UNKNOWN_ERROR ||
20487 agIOStatus == OSSA_IO_OPEN_CNX_ERROR_STP_RESOURCES_BUSY
20488 )
20489 {
20490 TI_DBG1(("satResetDeviceCB: OSSA_IO_OPEN_CNX_ERROR\n"));
20491
20492 if (satOrgIOContext->NotifyOS == agTRUE)
20493 {
20494 ostiInitiatorEvent( tiRoot,
20495 NULL,
20496 NULL,
20497 tiIntrEventTypeTaskManagement,
20498 tiTMFailed,
20499 tiOrgIORequest );
20500 }
20501
20502 satDevData->satTmTaskTag = agNULL;
20503
20504 satDecrementPendingIO(tiRoot, tdsaAllShared, satIOContext);
20505
20506 satFreeIntIoResource( tiRoot,
20507 satDevData,
20508 satIntIo);
20509 return;
20510 }
20511
20512 if (agIOStatus != OSSA_IO_SUCCESS)
20513 {
20514 #ifdef TD_DEBUG_ENABLE
20515 /* only agsaFisPioSetup_t is expected */
20516 satPIOSetupHeader = (agsaFisPioSetupHeader_t *)&(agFirstDword->PioSetup);
20517 ataStatus = satPIOSetupHeader->status; /* ATA Status register */
20518 ataError = satPIOSetupHeader->error; /* ATA Eror register */
20519 #endif
20520 TI_DBG1(("satResetDeviceCB: ataStatus 0x%x ataError 0x%x\n", ataStatus, ataError));
20521
20522 if (satOrgIOContext->NotifyOS == agTRUE)
20523 {
20524 ostiInitiatorEvent( tiRoot,
20525 NULL,
20526 NULL,
20527 tiIntrEventTypeTaskManagement,
20528 tiTMFailed,
20529 tiOrgIORequest );
20530 }
20531
20532 satDevData->satTmTaskTag = agNULL;
20533
20534 satDecrementPendingIO(tiRoot, tdsaAllShared, satIOContext);
20535
20536 satFreeIntIoResource( tiRoot,
20537 satDevData,
20538 satIntIo);
20539 return;
20540 }
20541
20542 /* success */
20543
20544 satNewIntIo = satAllocIntIoResource( tiRoot,
20545 tiOrgIORequest,
20546 satDevData,
20547 0,
20548 satNewIntIo);
20549 if (satNewIntIo == agNULL)
20550 {
20551 satDevData->satTmTaskTag = agNULL;
20552
20553 satDecrementPendingIO(tiRoot, tdsaAllShared, satIOContext);
20554
20555 /* memory allocation failure */
20556 satFreeIntIoResource( tiRoot,
20557 satDevData,
20558 satNewIntIo);
20559
20560 if (satOrgIOContext->NotifyOS == agTRUE)
20561 {
20562 ostiInitiatorEvent( tiRoot,
20563 NULL,
20564 NULL,
20565 tiIntrEventTypeTaskManagement,
20566 tiTMFailed,
20567 tiOrgIORequest );
20568 }
20569
20570
20571 TI_DBG1(("satResetDeviceCB: momory allocation fails\n"));
20572 return;
20573 } /* end of memory allocation failure */
20574
20575 /*
20576 * Need to initialize all the fields within satIOContext
20577 */
20578
20579 satNewIOContext = satPrepareNewIO(
20580 satNewIntIo,
20581 tiOrgIORequest,
20582 satDevData,
20583 agNULL,
20584 satOrgIOContext
20585 );
20586
20587
20588
20589
20590 /* send AGSA_SATA_PROTOCOL_SRST_DEASSERT */
20591 status = satDeResetDevice(tiRoot,
20592 tiOrgIORequest,
20593 satOrgIOContext->ptiDeviceHandle,
20594 agNULL,
20595 satNewIOContext
20596 );
20597
20598 if (status != tiSuccess)
20599 {
20600 if (satOrgIOContext->NotifyOS == agTRUE)
20601 {
20602 ostiInitiatorEvent( tiRoot,
20603 NULL,
20604 NULL,
20605 tiIntrEventTypeTaskManagement,
20606 tiTMFailed,
20607 tiOrgIORequest );
20608 }
20609
20610 /* sending AGSA_SATA_PROTOCOL_SRST_DEASSERT fails */
20611
20612 satDevData->satTmTaskTag = agNULL;
20613
20614 satDecrementPendingIO(tiRoot, tdsaAllShared, satIOContext);
20615
20616 satFreeIntIoResource( tiRoot,
20617 satDevData,
20618 satNewIntIo);
20619 return;
20620
20621 }
20622
20623 satDevData->satTmTaskTag = agNULL;
20624
20625 satDecrementPendingIO(tiRoot, tdsaAllShared, satIOContext);
20626
20627 satFreeIntIoResource( tiRoot,
20628 satDevData,
20629 satIntIo);
20630 TI_DBG5(("satResetDeviceCB: device %p pending IO %d\n", satDevData, satDevData->satPendingIO));
20631 TI_DBG6(("satResetDeviceCB: end\n"));
20632 return;
20633
20634 }
20635
20636
20637 /*****************************************************************************/
20638 /*! \brief SAT implementation for satDeResetDevice.
20639 *
20640 * SAT implementation for building DSRT FIS and sends the request to LL layer.
20641 *
20642 * \param tiRoot: Pointer to TISA initiator driver/port instance.
20643 * \param tiIORequest: Pointer to TISA I/O request context for this I/O.
20644 * \param tiDeviceHandle: Pointer to TISA device handle for this I/O.
20645 * \param tiScsiRequest: Pointer to TISA SCSI I/O request and SGL list.
20646 * \param satIOContext_t: Pointer to the SAT IO Context
20647 *
20648 * \return If command is started successfully
20649 * - \e tiSuccess: I/O request successfully initiated.
20650 * - \e tiBusy: No resources available, try again later.
20651 * - \e tiIONoDevice: Invalid device handle.
20652 * - \e tiError: Other errors.
20653 */
20654 /*****************************************************************************/
satDeResetDevice(tiRoot_t * tiRoot,tiIORequest_t * tiIORequest,tiDeviceHandle_t * tiDeviceHandle,tiScsiInitiatorRequest_t * tiScsiRequest,satIOContext_t * satIOContext)20655 GLOBAL bit32 satDeResetDevice(
20656 tiRoot_t *tiRoot,
20657 tiIORequest_t *tiIORequest,
20658 tiDeviceHandle_t *tiDeviceHandle,
20659 tiScsiInitiatorRequest_t *tiScsiRequest,
20660 satIOContext_t *satIOContext
20661 )
20662 {
20663 bit32 status;
20664 bit32 agRequestType;
20665 agsaFisRegHostToDevice_t *fis;
20666 #ifdef TD_DEBUG_ENABLE
20667 tdIORequestBody_t *tdIORequestBody;
20668 satInternalIo_t *satIntIoContext;
20669 #endif
20670 fis = satIOContext->pFis;
20671
20672 TI_DBG6(("satDeResetDevice: start\n"));
20673
20674 #ifdef TD_DEBUG_ENABLE
20675 satIntIoContext = satIOContext->satIntIoContext;
20676 tdIORequestBody = satIntIoContext->satIntRequestBody;
20677 TI_DBG5(("satDeResetDevice: satIOContext %p tdIORequestBody %p\n", satIOContext, tdIORequestBody));
20678 #endif
20679 /* any fis should work */
20680 fis->h.fisType = 0x27; /* Reg host to device */
20681 fis->h.c_pmPort = 0; /* C Bit is not set */
20682 fis->h.command = 0; /* any command */
20683 fis->h.features = 0; /* FIS reserve */
20684 fis->d.lbaLow = 0; /* FIS LBA (7 :0 ) */
20685 fis->d.lbaMid = 0; /* FIS LBA (15:8 ) */
20686 fis->d.lbaHigh = 0; /* FIS LBA (23:16) */
20687 fis->d.device = 0; /* FIS LBA mode */
20688 fis->d.lbaLowExp = 0;
20689 fis->d.lbaMidExp = 0;
20690 fis->d.lbaHighExp = 0;
20691 fis->d.featuresExp = 0;
20692 fis->d.sectorCount = 0; /* FIS sector count (7:0) */
20693 fis->d.sectorCountExp = 0;
20694 fis->d.reserved4 = 0;
20695 fis->d.control = 0; /* SRST bit is not set */
20696 fis->d.reserved5 = 0;
20697
20698 agRequestType = AGSA_SATA_PROTOCOL_SRST_DEASSERT;
20699
20700 satIOContext->satCompleteCB = &satDeResetDeviceCB;
20701
20702 /*
20703 * Prepare SGL and send FIS to LL layer.
20704 */
20705 satIOContext->reqType = agRequestType; /* Save it */
20706
20707 #ifdef TD_INTERNAL_DEBUG
20708 tdhexdump("satDeResetDevice", (bit8 *)satIOContext->pFis, sizeof(agsaFisRegHostToDevice_t));
20709 #ifdef TD_DEBUG_ENABLE
20710 tdhexdump("satDeResetDevice LL", (bit8 *)&(tdIORequestBody->transport.SATA.agSATARequestBody.fis.fisRegHostToDev), sizeof(agsaFisRegHostToDevice_t));
20711 #endif
20712 #endif
20713
20714 status = sataLLIOStart( tiRoot,
20715 tiIORequest,
20716 tiDeviceHandle,
20717 tiScsiRequest,
20718 satIOContext);
20719
20720 TI_DBG6(("satDeResetDevice: end status %d\n", status));
20721 return status;
20722
20723 }
20724
20725 /*****************************************************************************
20726 *! \brief satDeResetDeviceCB
20727 *
20728 * This routine is a callback function called from ossaSATACompleted().
20729 * This CB routine deals with DSRT completion.
20730 *
20731 * \param agRoot: Handles for this instance of SAS/SATA hardware
20732 * \param agIORequest: Pointer to the LL I/O request context for this I/O.
20733 * \param agIOStatus: Status of completed I/O.
20734 * \param agFirstDword:Pointer to the four bytes of FIS.
20735 * \param agIOInfoLen: Length in bytes of overrun/underrun residual or FIS
20736 * length.
20737 * \param agParam: Additional info based on status.
20738 * \param ioContext: Pointer to satIOContext_t.
20739 *
20740 * \return: none
20741 *
20742 *****************************************************************************/
satDeResetDeviceCB(agsaRoot_t * agRoot,agsaIORequest_t * agIORequest,bit32 agIOStatus,agsaFisHeader_t * agFirstDword,bit32 agIOInfoLen,agsaFrameHandle_t agFrameHandle,void * ioContext)20743 GLOBAL void satDeResetDeviceCB(
20744 agsaRoot_t *agRoot,
20745 agsaIORequest_t *agIORequest,
20746 bit32 agIOStatus,
20747 agsaFisHeader_t *agFirstDword,
20748 bit32 agIOInfoLen,
20749 agsaFrameHandle_t agFrameHandle,
20750 void *ioContext
20751 )
20752 {
20753 /* callback for satDeResetDevice */
20754 tdsaRootOsData_t *osData = (tdsaRootOsData_t *)agRoot->osData;
20755 tiRoot_t *tiRoot = (tiRoot_t *)osData->tiRoot;
20756 tdsaRoot_t *tdsaRoot = (tdsaRoot_t *) tiRoot->tdData;
20757 tdsaContext_t *tdsaAllShared = (tdsaContext_t *)&tdsaRoot->tdsaAllShared;
20758 tdIORequestBody_t *tdIORequestBody;
20759 tdIORequestBody_t *tdOrgIORequestBody = agNULL;
20760 satIOContext_t *satIOContext;
20761 satIOContext_t *satOrgIOContext;
20762 satInternalIo_t *satIntIo;
20763 satDeviceData_t *satDevData;
20764 tiIORequest_t *tiOrgIORequest;
20765 #ifdef TD_DEBUG_ENABLE
20766 bit32 ataStatus = 0;
20767 bit32 ataError;
20768 agsaFisPioSetupHeader_t *satPIOSetupHeader = agNULL;
20769 #endif
20770 bit32 report = agFALSE;
20771 bit32 AbortTM = agFALSE;
20772
20773 TI_DBG1(("satDeResetDeviceCB: start\n"));
20774 TI_DBG6(("satDeResetDeviceCB: agIORequest=%p agIOStatus=0x%x agIOInfoLen %d\n", agIORequest, agIOStatus, agIOInfoLen));
20775 tdIORequestBody = (tdIORequestBody_t *)agIORequest->osData;
20776 satIOContext = (satIOContext_t *) ioContext;
20777 satIntIo = satIOContext->satIntIoContext;
20778 satDevData = satIOContext->pSatDevData;
20779 if (satIntIo == agNULL)
20780 {
20781 TI_DBG6(("satDeResetDeviceCB: External, OS generated\n"));
20782 satOrgIOContext = satIOContext;
20783 tiOrgIORequest = tdIORequestBody->tiIORequest;
20784 }
20785 else
20786 {
20787 TI_DBG6(("satDeResetDeviceCB: Internal, TD generated\n"));
20788 satOrgIOContext = satIOContext->satOrgIOContext;
20789 if (satOrgIOContext == agNULL)
20790 {
20791 TI_DBG6(("satDeResetDeviceCB: satOrgIOContext is NULL, wrong\n"));
20792 return;
20793 }
20794 else
20795 {
20796 TI_DBG6(("satDeResetDeviceCB: satOrgIOContext is NOT NULL\n"));
20797 }
20798 tdOrgIORequestBody = (tdIORequestBody_t *)satOrgIOContext->tiRequestBody;
20799 tiOrgIORequest = (tiIORequest_t *)tdOrgIORequestBody->tiIORequest;
20800 }
20801
20802 tdIORequestBody->ioCompleted = agTRUE;
20803 tdIORequestBody->ioStarted = agFALSE;
20804
20805 if (agFirstDword == agNULL && agIOStatus != OSSA_IO_SUCCESS)
20806 {
20807 TI_DBG1(("satDeResetDeviceCB: wrong. agFirstDword is NULL when error, status %d\n", agIOStatus));
20808 if (satOrgIOContext->NotifyOS == agTRUE)
20809 {
20810 ostiInitiatorEvent( tiRoot,
20811 NULL,
20812 NULL,
20813 tiIntrEventTypeTaskManagement,
20814 tiTMFailed,
20815 tiOrgIORequest );
20816 }
20817
20818 satDevData->satTmTaskTag = agNULL;
20819 satDecrementPendingIO(tiRoot, tdsaAllShared, satIOContext);
20820
20821 satFreeIntIoResource( tiRoot,
20822 satDevData,
20823 satIntIo);
20824 return;
20825 }
20826
20827 if (agIOStatus == OSSA_IO_OPEN_CNX_ERROR_PROTOCOL_NOT_SUPPORTED ||
20828 agIOStatus == OSSA_IO_OPEN_CNX_ERROR_ZONE_VIOLATION ||
20829 agIOStatus == OSSA_IO_OPEN_CNX_ERROR_BREAK ||
20830 agIOStatus == OSSA_IO_OPEN_CNX_ERROR_IT_NEXUS_LOSS ||
20831 agIOStatus == OSSA_IO_OPEN_CNX_ERROR_BAD_DESTINATION ||
20832 agIOStatus == OSSA_IO_OPEN_CNX_ERROR_CONNECTION_RATE_NOT_SUPPORTED ||
20833 agIOStatus == OSSA_IO_OPEN_CNX_ERROR_WRONG_DESTINATION ||
20834 agIOStatus == OSSA_IO_OPEN_CNX_ERROR_UNKNOWN_ERROR ||
20835 agIOStatus == OSSA_IO_OPEN_CNX_ERROR_STP_RESOURCES_BUSY
20836 )
20837 {
20838 TI_DBG1(("satDeResetDeviceCB: OSSA_IO_OPEN_CNX_ERROR\n"));
20839
20840 if (satOrgIOContext->NotifyOS == agTRUE)
20841 {
20842 ostiInitiatorEvent( tiRoot,
20843 NULL,
20844 NULL,
20845 tiIntrEventTypeTaskManagement,
20846 tiTMFailed,
20847 tiOrgIORequest );
20848 }
20849
20850 satDevData->satTmTaskTag = agNULL;
20851
20852 satDecrementPendingIO(tiRoot, tdsaAllShared, satIOContext);
20853
20854 satFreeIntIoResource( tiRoot,
20855 satDevData,
20856 satIntIo);
20857 return;
20858 }
20859
20860 if (agIOStatus != OSSA_IO_SUCCESS)
20861 {
20862 #ifdef TD_DEBUG_ENABLE
20863 /* only agsaFisPioSetup_t is expected */
20864 satPIOSetupHeader = (agsaFisPioSetupHeader_t *)&(agFirstDword->PioSetup);
20865 ataStatus = satPIOSetupHeader->status; /* ATA Status register */
20866 ataError = satPIOSetupHeader->error; /* ATA Eror register */
20867 #endif
20868 TI_DBG1(("satDeResetDeviceCB: ataStatus 0x%x ataError 0x%x\n", ataStatus, ataError));
20869
20870 if (satOrgIOContext->NotifyOS == agTRUE)
20871 {
20872 ostiInitiatorEvent( tiRoot,
20873 NULL,
20874 NULL,
20875 tiIntrEventTypeTaskManagement,
20876 tiTMFailed,
20877 tiOrgIORequest );
20878 }
20879
20880 satDevData->satTmTaskTag = agNULL;
20881
20882 satDecrementPendingIO(tiRoot, tdsaAllShared, satIOContext);
20883
20884 satFreeIntIoResource( tiRoot,
20885 satDevData,
20886 satIntIo);
20887 return;
20888 }
20889
20890 /* success */
20891 TI_DBG1(("satDeResetDeviceCB: success \n"));
20892 TI_DBG1(("satDeResetDeviceCB: TMF %d\n", satOrgIOContext->TMF));
20893
20894 if (satOrgIOContext->TMF == AG_ABORT_TASK)
20895 {
20896 AbortTM = agTRUE;
20897 }
20898
20899 if (satOrgIOContext->NotifyOS == agTRUE)
20900 {
20901 report = agTRUE;
20902 }
20903
20904 if (AbortTM == agTRUE)
20905 {
20906 TI_DBG1(("satDeResetDeviceCB: calling satAbort\n"));
20907 satAbort(agRoot, satOrgIOContext->satToBeAbortedIOContext);
20908 }
20909 satDevData->satTmTaskTag = agNULL;
20910
20911 satDevData->satDriveState = SAT_DEV_STATE_NORMAL;
20912
20913 satDecrementPendingIO(tiRoot, tdsaAllShared, satIOContext);
20914
20915 TI_DBG1(("satDeResetDeviceCB: satPendingIO %d satNCQMaxIO %d\n", satDevData->satPendingIO, satDevData->satNCQMaxIO ));
20916 TI_DBG1(("satDeResetDeviceCB: satPendingNCQIO %d satPendingNONNCQIO %d\n", satDevData->satPendingNCQIO, satDevData->satPendingNONNCQIO));
20917
20918 satFreeIntIoResource( tiRoot,
20919 satDevData,
20920 satIntIo);
20921
20922 /* clean up TD layer's IORequestBody */
20923 if (tdOrgIORequestBody != agNULL)
20924 {
20925 ostiFreeMemory(
20926 tiRoot,
20927 tdOrgIORequestBody->IOType.InitiatorTMIO.osMemHandle,
20928 sizeof(tdIORequestBody_t)
20929 );
20930 }
20931 else
20932 {
20933 TI_DBG1(("satDeResetDeviceCB: tdOrgIORequestBody is NULL, wrong\n"));
20934 }
20935
20936
20937 if (report)
20938 {
20939 ostiInitiatorEvent( tiRoot,
20940 NULL,
20941 NULL,
20942 tiIntrEventTypeTaskManagement,
20943 tiTMOK,
20944 tiOrgIORequest );
20945 }
20946
20947
20948 TI_DBG5(("satDeResetDeviceCB: device %p pending IO %d\n", satDevData, satDevData->satPendingIO));
20949 TI_DBG6(("satDeResetDeviceCB: end\n"));
20950 return;
20951
20952 }
20953
20954 /*****************************************************************************/
20955 /*! \brief SAT implementation for satStartCheckPowerMode.
20956 *
20957 * SAT implementation for abort task management for non-ncq sata disk.
20958 * This function sends CHECK POWER MODE
20959 *
20960 * \param tiRoot: Pointer to TISA initiator driver/port instance.
20961 * \param tiIORequest: Pointer to TISA I/O request context for this I/O.
20962 * \param tiDeviceHandle: Pointer to TISA device handle for this I/O.
20963 * \param tiScsiRequest: Pointer to TISA SCSI I/O request and SGL list.
20964 * \param satIOContext_t: Pointer to the SAT IO Context
20965 *
20966 * \return If command is started successfully
20967 * - \e tiSuccess: I/O request successfully initiated.
20968 * - \e tiBusy: No resources available, try again later.
20969 * - \e tiIONoDevice: Invalid device handle.
20970 * - \e tiError: Other errors.
20971 */
20972 /*****************************************************************************/
satStartCheckPowerMode(tiRoot_t * tiRoot,tiIORequest_t * tiIORequest,tiDeviceHandle_t * tiDeviceHandle,tiScsiInitiatorRequest_t * tiScsiRequest,satIOContext_t * satIOContext)20973 GLOBAL bit32 satStartCheckPowerMode(
20974 tiRoot_t *tiRoot,
20975 tiIORequest_t *tiIORequest,
20976 tiDeviceHandle_t *tiDeviceHandle,
20977 tiScsiInitiatorRequest_t *tiScsiRequest, /* NULL */
20978 satIOContext_t *satIOContext
20979 )
20980 {
20981 satInternalIo_t *satIntIo = agNULL;
20982 satDeviceData_t *satDevData = agNULL;
20983 satIOContext_t *satNewIOContext;
20984 bit32 status;
20985 tiIORequest_t *currentTaskTag = agNULL;
20986
20987 TI_DBG6(("satStartCheckPowerMode: start\n"));
20988
20989 currentTaskTag = tiIORequest;
20990
20991 satDevData = satIOContext->pSatDevData;
20992
20993 TI_DBG6(("satStartCheckPowerMode: before alloc\n"));
20994
20995 /* allocate any fis for seting SRT bit in device control */
20996 satIntIo = satAllocIntIoResource( tiRoot,
20997 tiIORequest,
20998 satDevData,
20999 0,
21000 satIntIo);
21001
21002 TI_DBG6(("satStartCheckPowerMode: before after\n"));
21003
21004 if (satIntIo == agNULL)
21005 {
21006 TI_DBG1(("satStartCheckPowerMode: can't alloacate\n"));
21007 if (satIOContext->NotifyOS)
21008 {
21009 ostiInitiatorEvent( tiRoot,
21010 NULL,
21011 NULL,
21012 tiIntrEventTypeTaskManagement,
21013 tiTMFailed,
21014 currentTaskTag );
21015 }
21016 return tiError;
21017 }
21018
21019 satNewIOContext = satPrepareNewIO(satIntIo,
21020 tiIORequest,
21021 satDevData,
21022 agNULL,
21023 satIOContext);
21024
21025 TI_DBG6(("satStartCheckPowerMode: OS satIOContext %p \n", satIOContext));
21026 TI_DBG6(("satStartCheckPowerMode: TD satNewIOContext %p \n", satNewIOContext));
21027 TI_DBG6(("satStartCheckPowerMode: OS tiScsiXchg %p \n", satIOContext->tiScsiXchg));
21028 TI_DBG6(("satStartCheckPowerMode: TD tiScsiXchg %p \n", satNewIOContext->tiScsiXchg));
21029
21030
21031
21032 TI_DBG1(("satStartCheckPowerMode: satNewIOContext %p \n", satNewIOContext));
21033
21034 status = satCheckPowerMode(tiRoot,
21035 &satIntIo->satIntTiIORequest, /* New tiIORequest */
21036 tiDeviceHandle,
21037 satNewIOContext->tiScsiXchg, /* New tiScsiInitiatorRequest_t *tiScsiRequest, */
21038 satNewIOContext);
21039
21040 if (status != tiSuccess)
21041 {
21042 TI_DBG1(("satStartCheckPowerMode: failed in sending\n"));
21043
21044 satFreeIntIoResource( tiRoot,
21045 satDevData,
21046 satIntIo);
21047 if (satIOContext->NotifyOS)
21048 {
21049 ostiInitiatorEvent( tiRoot,
21050 NULL,
21051 NULL,
21052 tiIntrEventTypeTaskManagement,
21053 tiTMFailed,
21054 currentTaskTag );
21055 }
21056
21057 return tiError;
21058 }
21059
21060
21061 TI_DBG6(("satStartCheckPowerMode: end\n"));
21062
21063 return status;
21064 }
21065
21066 /*****************************************************************************/
21067 /*! \brief SAT implementation for satCheckPowerMode.
21068 *
21069 * This function creates CHECK POWER MODE fis and sends the request to LL layer
21070 *
21071 * \param tiRoot: Pointer to TISA initiator driver/port instance.
21072 * \param tiIORequest: Pointer to TISA I/O request context for this I/O.
21073 * \param tiDeviceHandle: Pointer to TISA device handle for this I/O.
21074 * \param tiScsiRequest: Pointer to TISA SCSI I/O request and SGL list.
21075 * \param satIOContext_t: Pointer to the SAT IO Context
21076 *
21077 * \return If command is started successfully
21078 * - \e tiSuccess: I/O request successfully initiated.
21079 * - \e tiBusy: No resources available, try again later.
21080 * - \e tiIONoDevice: Invalid device handle.
21081 * - \e tiError: Other errors.
21082 */
21083 /*****************************************************************************/
satCheckPowerMode(tiRoot_t * tiRoot,tiIORequest_t * tiIORequest,tiDeviceHandle_t * tiDeviceHandle,tiScsiInitiatorRequest_t * tiScsiRequest,satIOContext_t * satIOContext)21084 GLOBAL bit32 satCheckPowerMode(
21085 tiRoot_t *tiRoot,
21086 tiIORequest_t *tiIORequest,
21087 tiDeviceHandle_t *tiDeviceHandle,
21088 tiScsiInitiatorRequest_t *tiScsiRequest,
21089 satIOContext_t *satIOContext
21090 )
21091 {
21092 /*
21093 sends SAT_CHECK_POWER_MODE as a part of ABORT TASKMANGEMENT for NCQ commands
21094 internally generated - no directly corresponding scsi
21095 */
21096 bit32 status;
21097 bit32 agRequestType;
21098 agsaFisRegHostToDevice_t *fis;
21099
21100 fis = satIOContext->pFis;
21101 TI_DBG5(("satCheckPowerMode: start\n"));
21102 /*
21103 * Send the ATA CHECK POWER MODE command.
21104 */
21105 fis->h.fisType = 0x27; /* Reg host to device */
21106 fis->h.c_pmPort = 0x80; /* C Bit is set */
21107 fis->h.command = SAT_CHECK_POWER_MODE; /* 0xE5 */
21108 fis->h.features = 0;
21109 fis->d.lbaLow = 0;
21110 fis->d.lbaMid = 0;
21111 fis->d.lbaHigh = 0;
21112 fis->d.device = 0;
21113 fis->d.lbaLowExp = 0;
21114 fis->d.lbaMidExp = 0;
21115 fis->d.lbaHighExp = 0;
21116 fis->d.featuresExp = 0;
21117 fis->d.sectorCount = 0;
21118 fis->d.sectorCountExp = 0;
21119 fis->d.reserved4 = 0;
21120 fis->d.control = 0; /* FIS HOB bit clear */
21121 fis->d.reserved5 = 0;
21122
21123 agRequestType = AGSA_SATA_PROTOCOL_NON_DATA;
21124
21125 /* Initialize CB for SATA completion.
21126 */
21127 satIOContext->satCompleteCB = &satCheckPowerModeCB;
21128
21129 /*
21130 * Prepare SGL and send FIS to LL layer.
21131 */
21132 satIOContext->reqType = agRequestType; /* Save it */
21133
21134 status = sataLLIOStart( tiRoot,
21135 tiIORequest,
21136 tiDeviceHandle,
21137 tiScsiRequest,
21138 satIOContext);
21139
21140 TI_DBG5(("satCheckPowerMode: return\n"));
21141
21142 return status;
21143 }
21144
21145 /*****************************************************************************
21146 *! \brief satCheckPowerModeCB
21147 *
21148 * This routine is a callback function called from ossaSATACompleted().
21149 * This CB routine deals with CHECK POWER MODE completion as abort task
21150 * management.
21151 *
21152 * \param agRoot: Handles for this instance of SAS/SATA hardware
21153 * \param agIORequest: Pointer to the LL I/O request context for this I/O.
21154 * \param agIOStatus: Status of completed I/O.
21155 * \param agFirstDword:Pointer to the four bytes of FIS.
21156 * \param agIOInfoLen: Length in bytes of overrun/underrun residual or FIS
21157 * length.
21158 * \param agParam: Additional info based on status.
21159 * \param ioContext: Pointer to satIOContext_t.
21160 *
21161 * \return: none
21162 *
21163 *****************************************************************************/
satCheckPowerModeCB(agsaRoot_t * agRoot,agsaIORequest_t * agIORequest,bit32 agIOStatus,agsaFisHeader_t * agFirstDword,bit32 agIOInfoLen,agsaFrameHandle_t agFrameHandle,void * ioContext)21164 GLOBAL void satCheckPowerModeCB(
21165 agsaRoot_t *agRoot,
21166 agsaIORequest_t *agIORequest,
21167 bit32 agIOStatus,
21168 agsaFisHeader_t *agFirstDword,
21169 bit32 agIOInfoLen,
21170 agsaFrameHandle_t agFrameHandle,
21171 void *ioContext
21172 )
21173 {
21174 /* callback for satDeResetDevice */
21175 tdsaRootOsData_t *osData = (tdsaRootOsData_t *)agRoot->osData;
21176 tiRoot_t *tiRoot = (tiRoot_t *)osData->tiRoot;
21177 tdsaRoot_t *tdsaRoot = (tdsaRoot_t *) tiRoot->tdData;
21178 tdsaContext_t *tdsaAllShared = (tdsaContext_t *)&tdsaRoot->tdsaAllShared;
21179 tdIORequestBody_t *tdIORequestBody;
21180 tdIORequestBody_t *tdOrgIORequestBody = agNULL;
21181 satIOContext_t *satIOContext;
21182 satIOContext_t *satOrgIOContext;
21183 satInternalIo_t *satIntIo;
21184 satDeviceData_t *satDevData;
21185
21186 tiIORequest_t *tiOrgIORequest;
21187 #ifdef TD_DEBUG_ENABLE
21188 bit32 ataStatus = 0;
21189 bit32 ataError;
21190 agsaFisPioSetupHeader_t *satPIOSetupHeader = agNULL;
21191 #endif
21192 bit32 report = agFALSE;
21193 bit32 AbortTM = agFALSE;
21194
21195
21196 TI_DBG1(("satCheckPowerModeCB: start\n"));
21197
21198 TI_DBG1(("satCheckPowerModeCB: agIORequest=%p agIOStatus=0x%x agIOInfoLen %d\n", agIORequest, agIOStatus, agIOInfoLen));
21199
21200 tdIORequestBody = (tdIORequestBody_t *)agIORequest->osData;
21201 satIOContext = (satIOContext_t *) ioContext;
21202 satIntIo = satIOContext->satIntIoContext;
21203 satDevData = satIOContext->pSatDevData;
21204 if (satIntIo == agNULL)
21205 {
21206 TI_DBG6(("satCheckPowerModeCB: External, OS generated\n"));
21207 satOrgIOContext = satIOContext;
21208 tiOrgIORequest = tdIORequestBody->tiIORequest;
21209 }
21210 else
21211 {
21212 TI_DBG6(("satCheckPowerModeCB: Internal, TD generated\n"));
21213 satOrgIOContext = satIOContext->satOrgIOContext;
21214 if (satOrgIOContext == agNULL)
21215 {
21216 TI_DBG6(("satCheckPowerModeCB: satOrgIOContext is NULL, wrong\n"));
21217 return;
21218 }
21219 else
21220 {
21221 TI_DBG6(("satCheckPowerModeCB: satOrgIOContext is NOT NULL\n"));
21222 }
21223 tdOrgIORequestBody = (tdIORequestBody_t *)satOrgIOContext->tiRequestBody;
21224 tiOrgIORequest = (tiIORequest_t *)tdOrgIORequestBody->tiIORequest;
21225 }
21226
21227
21228 tdIORequestBody->ioCompleted = agTRUE;
21229 tdIORequestBody->ioStarted = agFALSE;
21230
21231 if (agFirstDword == agNULL && agIOStatus != OSSA_IO_SUCCESS)
21232 {
21233 TI_DBG1(("satCheckPowerModeCB: wrong. agFirstDword is NULL when error, status %d\n", agIOStatus));
21234
21235 if (satOrgIOContext->NotifyOS == agTRUE)
21236 {
21237 ostiInitiatorEvent( tiRoot,
21238 NULL,
21239 NULL,
21240 tiIntrEventTypeTaskManagement,
21241 tiTMFailed,
21242 tiOrgIORequest );
21243 }
21244
21245 satDevData->satTmTaskTag = agNULL;
21246
21247 satDecrementPendingIO(tiRoot, tdsaAllShared, satIOContext);
21248
21249 satFreeIntIoResource( tiRoot,
21250 satDevData,
21251 satIntIo);
21252 return;
21253 }
21254
21255 if (agIOStatus == OSSA_IO_OPEN_CNX_ERROR_PROTOCOL_NOT_SUPPORTED ||
21256 agIOStatus == OSSA_IO_OPEN_CNX_ERROR_ZONE_VIOLATION ||
21257 agIOStatus == OSSA_IO_OPEN_CNX_ERROR_BREAK ||
21258 agIOStatus == OSSA_IO_OPEN_CNX_ERROR_IT_NEXUS_LOSS ||
21259 agIOStatus == OSSA_IO_OPEN_CNX_ERROR_BAD_DESTINATION ||
21260 agIOStatus == OSSA_IO_OPEN_CNX_ERROR_CONNECTION_RATE_NOT_SUPPORTED ||
21261 agIOStatus == OSSA_IO_OPEN_CNX_ERROR_WRONG_DESTINATION ||
21262 agIOStatus == OSSA_IO_OPEN_CNX_ERROR_UNKNOWN_ERROR ||
21263 agIOStatus == OSSA_IO_OPEN_CNX_ERROR_STP_RESOURCES_BUSY
21264 )
21265 {
21266 TI_DBG1(("satCheckPowerModeCB: OSSA_IO_OPEN_CNX_ERROR\n"));
21267
21268 if (satOrgIOContext->NotifyOS == agTRUE)
21269 {
21270 ostiInitiatorEvent( tiRoot,
21271 NULL,
21272 NULL,
21273 tiIntrEventTypeTaskManagement,
21274 tiTMFailed,
21275 tiOrgIORequest );
21276 }
21277
21278 satDevData->satTmTaskTag = agNULL;
21279
21280 satDecrementPendingIO(tiRoot, tdsaAllShared, satIOContext);
21281
21282 satFreeIntIoResource( tiRoot,
21283 satDevData,
21284 satIntIo);
21285 return;
21286 }
21287
21288 if (agIOStatus != OSSA_IO_SUCCESS)
21289 {
21290 #ifdef TD_DEBUG_ENABLE
21291 /* only agsaFisPioSetup_t is expected */
21292 satPIOSetupHeader = (agsaFisPioSetupHeader_t *)&(agFirstDword->PioSetup);
21293 ataStatus = satPIOSetupHeader->status; /* ATA Status register */
21294 ataError = satPIOSetupHeader->error; /* ATA Eror register */
21295 #endif
21296 TI_DBG1(("satCheckPowerModeCB: ataStatus 0x%x ataError 0x%x\n", ataStatus, ataError));
21297
21298 if (satOrgIOContext->NotifyOS == agTRUE)
21299 {
21300 ostiInitiatorEvent( tiRoot,
21301 NULL,
21302 NULL,
21303 tiIntrEventTypeTaskManagement,
21304 tiTMFailed,
21305 tiOrgIORequest );
21306 }
21307
21308 satDevData->satTmTaskTag = agNULL;
21309
21310 satDecrementPendingIO(tiRoot, tdsaAllShared, satIOContext);
21311
21312 satFreeIntIoResource( tiRoot,
21313 satDevData,
21314 satIntIo);
21315 return;
21316 }
21317
21318 /* success */
21319 TI_DBG1(("satCheckPowerModeCB: success\n"));
21320 TI_DBG1(("satCheckPowerModeCB: TMF %d\n", satOrgIOContext->TMF));
21321
21322 if (satOrgIOContext->TMF == AG_ABORT_TASK)
21323 {
21324 AbortTM = agTRUE;
21325 }
21326
21327 if (satOrgIOContext->NotifyOS == agTRUE)
21328 {
21329 report = agTRUE;
21330 }
21331 if (AbortTM == agTRUE)
21332 {
21333 TI_DBG1(("satCheckPowerModeCB: calling satAbort\n"));
21334 satAbort(agRoot, satOrgIOContext->satToBeAbortedIOContext);
21335 }
21336 satDevData->satTmTaskTag = agNULL;
21337
21338 satDevData->satDriveState = SAT_DEV_STATE_NORMAL;
21339
21340 satDecrementPendingIO(tiRoot, tdsaAllShared, satIOContext);
21341
21342 TI_DBG1(("satCheckPowerModeCB: satPendingIO %d satNCQMaxIO %d\n", satDevData->satPendingIO, satDevData->satNCQMaxIO ));
21343 TI_DBG1(("satCheckPowerModeCB: satPendingNCQIO %d satPendingNONNCQIO %d\n", satDevData->satPendingNCQIO, satDevData->satPendingNONNCQIO));
21344
21345 satFreeIntIoResource( tiRoot,
21346 satDevData,
21347 satIntIo);
21348
21349 /* clean up TD layer's IORequestBody */
21350 if (tdOrgIORequestBody != agNULL)
21351 {
21352 ostiFreeMemory(
21353 tiRoot,
21354 tdOrgIORequestBody->IOType.InitiatorTMIO.osMemHandle,
21355 sizeof(tdIORequestBody_t)
21356 );
21357 }
21358 else
21359 {
21360 TI_DBG1(("satCheckPowerModeCB: tdOrgIORequestBody is NULL, wrong\n"));
21361 }
21362 if (report)
21363 {
21364 ostiInitiatorEvent( tiRoot,
21365 NULL,
21366 NULL,
21367 tiIntrEventTypeTaskManagement,
21368 tiTMOK,
21369 tiOrgIORequest );
21370 }
21371
21372 TI_DBG5(("satCheckPowerModeCB: device %p pending IO %d\n", satDevData, satDevData->satPendingIO));
21373 TI_DBG2(("satCheckPowerModeCB: end\n"));
21374 return;
21375
21376 }
21377
21378 /*****************************************************************************/
21379 /*! \brief SAT implementation for satAddSATAStartIDDev.
21380 *
21381 * This function sends identify device data to find out the uniqueness
21382 * of device.
21383 *
21384 * \param tiRoot: Pointer to TISA initiator driver/port instance.
21385 * \param tiIORequest: Pointer to TISA I/O request context for this I/O.
21386 * \param tiDeviceHandle: Pointer to TISA device handle for this I/O.
21387 * \param tiScsiRequest: Pointer to TISA SCSI I/O request and SGL list.
21388 * \param satIOContext_t: Pointer to the SAT IO Context
21389 *
21390 * \return If command is started successfully
21391 * - \e tiSuccess: I/O request successfully initiated.
21392 * - \e tiBusy: No resources available, try again later.
21393 * - \e tiIONoDevice: Invalid device handle.
21394 * - \e tiError: Other errors.
21395 */
21396 /*****************************************************************************/
satAddSATAStartIDDev(tiRoot_t * tiRoot,tiIORequest_t * tiIORequest,tiDeviceHandle_t * tiDeviceHandle,tiScsiInitiatorRequest_t * tiScsiRequest,satIOContext_t * satIOContext)21397 GLOBAL bit32 satAddSATAStartIDDev(
21398 tiRoot_t *tiRoot,
21399 tiIORequest_t *tiIORequest,
21400 tiDeviceHandle_t *tiDeviceHandle,
21401 tiScsiInitiatorRequest_t *tiScsiRequest, // NULL
21402 satIOContext_t *satIOContext
21403 )
21404 {
21405 satInternalIo_t *satIntIo = agNULL;
21406 satDeviceData_t *satDevData = agNULL;
21407 tdIORequestBody_t *tdIORequestBody;
21408 satIOContext_t *satNewIOContext;
21409 bit32 status;
21410
21411 TI_DBG2(("satAddSATAStartIDDev: start\n"));
21412
21413 satDevData = satIOContext->pSatDevData;
21414
21415 TI_DBG2(("satAddSATAStartIDDev: before alloc\n"));
21416
21417 /* allocate identify device command */
21418 satIntIo = satAllocIntIoResource( tiRoot,
21419 tiIORequest,
21420 satDevData,
21421 sizeof(agsaSATAIdentifyData_t), /* 512; size of identify device data */
21422 satIntIo);
21423
21424 TI_DBG2(("satAddSATAStartIDDev: after alloc\n"));
21425
21426 if (satIntIo == agNULL)
21427 {
21428 TI_DBG1(("satAddSATAStartIDDev: can't alloacate\n"));
21429
21430 return tiError;
21431 }
21432
21433 /* fill in fields */
21434 /* real ttttttthe one worked and the same; 5/21/07/ */
21435 satIntIo->satOrgTiIORequest = tiIORequest; /* changed */
21436 tdIORequestBody = satIntIo->satIntRequestBody;
21437 satNewIOContext = &(tdIORequestBody->transport.SATA.satIOContext);
21438
21439 satNewIOContext->pSatDevData = satDevData;
21440 satNewIOContext->pFis = &(tdIORequestBody->transport.SATA.agSATARequestBody.fis.fisRegHostToDev);
21441 satNewIOContext->pScsiCmnd = &(satIntIo->satIntTiScsiXchg.scsiCmnd);
21442 satNewIOContext->pSense = &(tdIORequestBody->transport.SATA.sensePayload);
21443 satNewIOContext->pTiSenseData = &(tdIORequestBody->transport.SATA.tiSenseData);
21444 satNewIOContext->tiRequestBody = satIntIo->satIntRequestBody; /* key fix */
21445 satNewIOContext->interruptContext = tiInterruptContext;
21446 satNewIOContext->satIntIoContext = satIntIo;
21447
21448 satNewIOContext->ptiDeviceHandle = agNULL;
21449 satNewIOContext->satOrgIOContext = satIOContext; /* changed */
21450
21451 /* this is valid only for TD layer generated (not triggered by OS at all) IO */
21452 satNewIOContext->tiScsiXchg = &(satIntIo->satIntTiScsiXchg);
21453
21454
21455 TI_DBG6(("satAddSATAStartIDDev: OS satIOContext %p \n", satIOContext));
21456 TI_DBG6(("satAddSATAStartIDDev: TD satNewIOContext %p \n", satNewIOContext));
21457 TI_DBG6(("satAddSATAStartIDDev: OS tiScsiXchg %p \n", satIOContext->tiScsiXchg));
21458 TI_DBG6(("satAddSATAStartIDDev: TD tiScsiXchg %p \n", satNewIOContext->tiScsiXchg));
21459
21460
21461
21462 TI_DBG2(("satAddSATAStartIDDev: satNewIOContext %p tdIORequestBody %p\n", satNewIOContext, tdIORequestBody));
21463
21464 status = satAddSATASendIDDev( tiRoot,
21465 &satIntIo->satIntTiIORequest, /* New tiIORequest */
21466 tiDeviceHandle,
21467 satNewIOContext->tiScsiXchg, /* New tiScsiInitiatorRequest_t *tiScsiRequest, */
21468 satNewIOContext);
21469
21470 if (status != tiSuccess)
21471 {
21472 TI_DBG1(("satAddSATAStartIDDev: failed in sending\n"));
21473
21474 satFreeIntIoResource( tiRoot,
21475 satDevData,
21476 satIntIo);
21477
21478 return tiError;
21479 }
21480
21481
21482 TI_DBG6(("satAddSATAStartIDDev: end\n"));
21483
21484 return status;
21485
21486
21487 }
21488
21489 /*****************************************************************************/
21490 /*! \brief SAT implementation for satAddSATASendIDDev.
21491 *
21492 * This function creates identify device data fis and send it to LL
21493 *
21494 * \param tiRoot: Pointer to TISA initiator driver/port instance.
21495 * \param tiIORequest: Pointer to TISA I/O request context for this I/O.
21496 * \param tiDeviceHandle: Pointer to TISA device handle for this I/O.
21497 * \param tiScsiRequest: Pointer to TISA SCSI I/O request and SGL list.
21498 * \param satIOContext_t: Pointer to the SAT IO Context
21499 *
21500 * \return If command is started successfully
21501 * - \e tiSuccess: I/O request successfully initiated.
21502 * - \e tiBusy: No resources available, try again later.
21503 * - \e tiIONoDevice: Invalid device handle.
21504 * - \e tiError: Other errors.
21505 */
21506 /*****************************************************************************/
satAddSATASendIDDev(tiRoot_t * tiRoot,tiIORequest_t * tiIORequest,tiDeviceHandle_t * tiDeviceHandle,tiScsiInitiatorRequest_t * tiScsiRequest,satIOContext_t * satIOContext)21507 GLOBAL bit32 satAddSATASendIDDev(
21508 tiRoot_t *tiRoot,
21509 tiIORequest_t *tiIORequest,
21510 tiDeviceHandle_t *tiDeviceHandle,
21511 tiScsiInitiatorRequest_t *tiScsiRequest,
21512 satIOContext_t *satIOContext)
21513 {
21514 bit32 status;
21515 bit32 agRequestType;
21516 satDeviceData_t *pSatDevData;
21517 agsaFisRegHostToDevice_t *fis;
21518 #ifdef TD_DEBUG_ENABLE
21519 tdIORequestBody_t *tdIORequestBody;
21520 satInternalIo_t *satIntIoContext;
21521 #endif
21522
21523 pSatDevData = satIOContext->pSatDevData;
21524 fis = satIOContext->pFis;
21525 TI_DBG2(("satAddSATASendIDDev: start\n"));
21526 #ifdef TD_DEBUG_ENABLE
21527 satIntIoContext = satIOContext->satIntIoContext;
21528 tdIORequestBody = satIntIoContext->satIntRequestBody;
21529 #endif
21530 TI_DBG5(("satAddSATASendIDDev: satIOContext %p tdIORequestBody %p\n", satIOContext, tdIORequestBody));
21531
21532 fis->h.fisType = 0x27; /* Reg host to device */
21533 fis->h.c_pmPort = 0x80; /* C Bit is set */
21534 if (pSatDevData->satDeviceType == SATA_ATAPI_DEVICE)
21535 fis->h.command = SAT_IDENTIFY_PACKET_DEVICE; /* 0x40 */
21536 else
21537 fis->h.command = SAT_IDENTIFY_DEVICE; /* 0xEC */
21538 fis->h.features = 0; /* FIS reserve */
21539 fis->d.lbaLow = 0; /* FIS LBA (7 :0 ) */
21540 fis->d.lbaMid = 0; /* FIS LBA (15:8 ) */
21541 fis->d.lbaHigh = 0; /* FIS LBA (23:16) */
21542 fis->d.device = 0; /* FIS LBA mode */
21543 fis->d.lbaLowExp = 0;
21544 fis->d.lbaMidExp = 0;
21545 fis->d.lbaHighExp = 0;
21546 fis->d.featuresExp = 0;
21547 fis->d.sectorCount = 0; /* FIS sector count (7:0) */
21548 fis->d.sectorCountExp = 0;
21549 fis->d.reserved4 = 0;
21550 fis->d.control = 0; /* FIS HOB bit clear */
21551 fis->d.reserved5 = 0;
21552
21553 agRequestType = AGSA_SATA_PROTOCOL_PIO_READ;
21554
21555 /* Initialize CB for SATA completion.
21556 */
21557 satIOContext->satCompleteCB = &satAddSATAIDDevCB;
21558
21559 /*
21560 * Prepare SGL and send FIS to LL layer.
21561 */
21562 satIOContext->reqType = agRequestType; /* Save it */
21563
21564 #ifdef TD_INTERNAL_DEBUG
21565 tdhexdump("satAddSATASendIDDev", (bit8 *)satIOContext->pFis, sizeof(agsaFisRegHostToDevice_t));
21566 #ifdef TD_DEBUG_ENABLE
21567 tdhexdump("satAddSATASendIDDev LL", (bit8 *)&(tdIORequestBody->transport.SATA.agSATARequestBody.fis.fisRegHostToDev), sizeof(agsaFisRegHostToDevice_t));
21568 #endif
21569 #endif
21570
21571 status = sataLLIOStart( tiRoot,
21572 tiIORequest,
21573 tiDeviceHandle,
21574 tiScsiRequest,
21575 satIOContext);
21576
21577 TI_DBG2(("satAddSATASendIDDev: end status %d\n", status));
21578 return status;
21579 }
21580
21581 /*****************************************************************************
21582 *! \brief satAddSATAIDDevCB
21583 *
21584 * This routine is a callback function for satAddSATASendIDDev()
21585 * Using Identify Device Data, this function finds whether devicedata is
21586 * new or old. If new, add it to the devicelist.
21587 *
21588 * \param agRoot: Handles for this instance of SAS/SATA hardware
21589 * \param agIORequest: Pointer to the LL I/O request context for this I/O.
21590 * \param agIOStatus: Status of completed I/O.
21591 * \param agFirstDword:Pointer to the four bytes of FIS.
21592 * \param agIOInfoLen: Length in bytes of overrun/underrun residual or FIS
21593 * length.
21594 * \param agParam: Additional info based on status.
21595 * \param ioContext: Pointer to satIOContext_t.
21596 *
21597 * \return: none
21598 *
21599 *****************************************************************************/
satAddSATAIDDevCB(agsaRoot_t * agRoot,agsaIORequest_t * agIORequest,bit32 agIOStatus,agsaFisHeader_t * agFirstDword,bit32 agIOInfoLen,void * agParam,void * ioContext)21600 void satAddSATAIDDevCB(
21601 agsaRoot_t *agRoot,
21602 agsaIORequest_t *agIORequest,
21603 bit32 agIOStatus,
21604 agsaFisHeader_t *agFirstDword,
21605 bit32 agIOInfoLen,
21606 void *agParam,
21607 void *ioContext
21608 )
21609 {
21610
21611 /*
21612 In the process of Inquiry
21613 Process SAT_IDENTIFY_DEVICE
21614 */
21615 tdsaRootOsData_t *osData = (tdsaRootOsData_t *)agRoot->osData;
21616 tiRoot_t *tiRoot = (tiRoot_t *)osData->tiRoot;
21617 tdsaRoot_t *tdsaRoot = (tdsaRoot_t *) tiRoot->tdData;
21618 tdsaContext_t *tdsaAllShared = (tdsaContext_t *)&tdsaRoot->tdsaAllShared;
21619 tdIORequestBody_t *tdIORequestBody;
21620 tdIORequestBody_t *tdOrgIORequestBody;
21621 satIOContext_t *satIOContext;
21622 satIOContext_t *satOrgIOContext;
21623 satIOContext_t *satNewIOContext;
21624 satInternalIo_t *satIntIo;
21625 satInternalIo_t *satNewIntIo = agNULL;
21626 satDeviceData_t *satDevData;
21627 tiIORequest_t *tiOrgIORequest = agNULL;
21628 agsaSATAIdentifyData_t *pSATAIdData;
21629 bit16 *tmpptr, tmpptr_tmp;
21630 bit32 x;
21631 tdsaDeviceData_t *NewOneDeviceData = agNULL;
21632 tdsaDeviceData_t *oneDeviceData = agNULL;
21633 tdList_t *DeviceListList;
21634 int new_device = agTRUE;
21635 bit8 PhyID;
21636 void *sglVirtualAddr;
21637 bit32 retry_status;
21638 agsaContext_t *agContext;
21639 tdsaPortContext_t *onePortContext;
21640 bit32 status = 0;
21641
21642 TI_DBG2(("satAddSATAIDDevCB: start\n"));
21643 TI_DBG6(("satAddSATAIDDevCB: agIORequest=%p agIOStatus=0x%x agIOInfoLen %d\n", agIORequest, agIOStatus, agIOInfoLen));
21644 tdIORequestBody = (tdIORequestBody_t *)agIORequest->osData;
21645 satIOContext = (satIOContext_t *) ioContext;
21646 satIntIo = satIOContext->satIntIoContext;
21647 satDevData = satIOContext->pSatDevData;
21648
21649 NewOneDeviceData = (tdsaDeviceData_t *)tdIORequestBody->tiDevHandle->tdData;
21650 TI_DBG2(("satAddSATAIDDevCB: NewOneDeviceData %p did %d\n", NewOneDeviceData, NewOneDeviceData->id));
21651 PhyID = NewOneDeviceData->phyID;
21652 TI_DBG2(("satAddSATAIDDevCB: phyID %d\n", PhyID));
21653 agContext = &(NewOneDeviceData->agDeviceResetContext);
21654 agContext->osData = agNULL;
21655 if (satIntIo == agNULL)
21656 {
21657 TI_DBG1(("satAddSATAIDDevCB: External, OS generated\n"));
21658 TI_DBG1(("satAddSATAIDDevCB: Not possible case\n"));
21659 satOrgIOContext = satIOContext;
21660 tdOrgIORequestBody = (tdIORequestBody_t *)satOrgIOContext->tiRequestBody;
21661 tdsaAbortAll(tiRoot, agRoot, NewOneDeviceData);
21662
21663 /* put onedevicedata back to free list */
21664 osti_memset(&(NewOneDeviceData->satDevData.satIdentifyData), 0xFF, sizeof(agsaSATAIdentifyData_t));
21665 TDLIST_DEQUEUE_THIS(&(NewOneDeviceData->MainLink));
21666 TDLIST_ENQUEUE_AT_TAIL(&(NewOneDeviceData->FreeLink), &(tdsaAllShared->FreeDeviceList));
21667
21668 satDecrementPendingIO(tiRoot, tdsaAllShared, satIOContext);
21669
21670 satFreeIntIoResource( tiRoot,
21671 satDevData,
21672 satIntIo);
21673 /* clean up TD layer's IORequestBody */
21674 ostiFreeMemory(
21675 tiRoot,
21676 tdOrgIORequestBody->IOType.InitiatorTMIO.osMemHandle,
21677 sizeof(tdIORequestBody_t)
21678 );
21679
21680 /* notifying link up */
21681 ostiPortEvent (
21682 tiRoot,
21683 tiPortLinkUp,
21684 tiSuccess,
21685 (void *)tdsaAllShared->Ports[PhyID].tiPortalContext
21686 );
21687 #ifdef INITIATOR_DRIVER
21688 /* triggers discovery */
21689 ostiPortEvent(
21690 tiRoot,
21691 tiPortDiscoveryReady,
21692 tiSuccess,
21693 (void *) tdsaAllShared->Ports[PhyID].tiPortalContext
21694 );
21695 #endif
21696 return;
21697 }
21698 else
21699 {
21700 TI_DBG1(("satAddSATAIDDevCB: Internal, TD generated\n"));
21701 satOrgIOContext = satIOContext->satOrgIOContext;
21702 if (satOrgIOContext == agNULL)
21703 {
21704 TI_DBG6(("satAddSATAIDDevCB: satOrgIOContext is NULL\n"));
21705 return;
21706 }
21707 else
21708 {
21709 TI_DBG6(("satAddSATAIDDevCB: satOrgIOContext is NOT NULL\n"));
21710 tdOrgIORequestBody = (tdIORequestBody_t *)satOrgIOContext->tiRequestBody;
21711 sglVirtualAddr = satIntIo->satIntTiScsiXchg.sglVirtualAddr;
21712 }
21713 }
21714 tiOrgIORequest = tdIORequestBody->tiIORequest;
21715
21716 tdIORequestBody->ioCompleted = agTRUE;
21717 tdIORequestBody->ioStarted = agFALSE;
21718 TI_DBG2(("satAddSATAIDDevCB: satOrgIOContext->pid %d\n", satOrgIOContext->pid));
21719 /* protect against double completion for old port */
21720 if (satOrgIOContext->pid != tdsaAllShared->Ports[PhyID].portContext->id)
21721 {
21722 TI_DBG2(("satAddSATAIDDevCB: incorrect pid\n"));
21723 TI_DBG2(("satAddSATAIDDevCB: satOrgIOContext->pid %d\n", satOrgIOContext->pid));
21724 TI_DBG2(("satAddSATAIDDevCB: tiPortalContext pid %d\n", tdsaAllShared->Ports[PhyID].portContext->id));
21725 tdsaAbortAll(tiRoot, agRoot, NewOneDeviceData);
21726 /* put onedevicedata back to free list */
21727 osti_memset(&(NewOneDeviceData->satDevData.satIdentifyData), 0xFF, sizeof(agsaSATAIdentifyData_t));
21728 TDLIST_DEQUEUE_THIS(&(NewOneDeviceData->MainLink));
21729 TDLIST_ENQUEUE_AT_TAIL(&(NewOneDeviceData->FreeLink), &(tdsaAllShared->FreeDeviceList));
21730 satDecrementPendingIO(tiRoot, tdsaAllShared, satIOContext);
21731
21732 satFreeIntIoResource( tiRoot,
21733 satDevData,
21734 satIntIo);
21735 /* clean up TD layer's IORequestBody */
21736 ostiFreeMemory(
21737 tiRoot,
21738 tdOrgIORequestBody->IOType.InitiatorTMIO.osMemHandle,
21739 sizeof(tdIORequestBody_t)
21740 );
21741 /* no notification to OS layer */
21742 return;
21743 }
21744 /* completion after portcontext is invalidated */
21745 onePortContext = NewOneDeviceData->tdPortContext;
21746 if (onePortContext != agNULL)
21747 {
21748 if (onePortContext->valid == agFALSE)
21749 {
21750 TI_DBG1(("satAddSATAIDDevCB: portcontext is invalid\n"));
21751 TI_DBG1(("satAddSATAIDDevCB: onePortContext->id pid %d\n", onePortContext->id));
21752 satDecrementPendingIO(tiRoot, tdsaAllShared, satIOContext);
21753
21754 satFreeIntIoResource( tiRoot,
21755 satDevData,
21756 satIntIo);
21757 /* clean up TD layer's IORequestBody */
21758 ostiFreeMemory(
21759 tiRoot,
21760 tdOrgIORequestBody->IOType.InitiatorTMIO.osMemHandle,
21761 sizeof(tdIORequestBody_t)
21762 );
21763 /* no notification to OS layer */
21764 return;
21765 }
21766 }
21767 else
21768 {
21769 TI_DBG1(("satAddSATAIDDevCB: onePortContext is NULL!!!\n"));
21770 return;
21771 }
21772 if (agFirstDword == agNULL && agIOStatus != OSSA_IO_SUCCESS)
21773 {
21774 TI_DBG1(("satAddSATAIDDevCB: wrong. agFirstDword is NULL when error, status %d\n", agIOStatus));
21775 if (tdsaAllShared->ResetInDiscovery != 0 && satDevData->ID_Retries < SATA_ID_DEVICE_DATA_RETRIES)
21776 {
21777 satDevData->satPendingNONNCQIO--;
21778 satDevData->satPendingIO--;
21779 retry_status = sataLLIOStart(tiRoot,
21780 &satIntIo->satIntTiIORequest,
21781 &(NewOneDeviceData->tiDeviceHandle),
21782 satIOContext->tiScsiXchg,
21783 satIOContext);
21784 if (retry_status != tiSuccess)
21785 {
21786 /* simply give up */
21787 satDevData->ID_Retries = 0;
21788 satAddSATAIDDevCBCleanup(agRoot, NewOneDeviceData, satIOContext, tdOrgIORequestBody);
21789 return;
21790 }
21791 satDevData->ID_Retries++;
21792 tdIORequestBody->ioCompleted = agFALSE;
21793 tdIORequestBody->ioStarted = agTRUE;
21794 return;
21795 }
21796 else
21797 {
21798 if (tdsaAllShared->ResetInDiscovery == 0)
21799 {
21800 satAddSATAIDDevCBCleanup(agRoot, NewOneDeviceData, satIOContext, tdOrgIORequestBody);
21801 }
21802 else /* ResetInDiscovery in on */
21803 {
21804 /* RESET only one after ID retries */
21805 if (satDevData->NumOfIDRetries <= 0)
21806 {
21807 satDevData->NumOfIDRetries++;
21808 satDevData->ID_Retries = 0;
21809 satAddSATAIDDevCBReset(agRoot, NewOneDeviceData, satIOContext, tdOrgIORequestBody);
21810 /* send link reset */
21811 saLocalPhyControl(agRoot,
21812 agContext,
21813 tdsaRotateQnumber(tiRoot, NewOneDeviceData),
21814 PhyID,
21815 AGSA_PHY_HARD_RESET,
21816 agNULL);
21817 }
21818 else
21819 {
21820 satDevData->ID_Retries = 0;
21821 satAddSATAIDDevCBCleanup(agRoot, NewOneDeviceData, satIOContext, tdOrgIORequestBody);
21822 }
21823 }
21824 return;
21825 }
21826 }
21827 if (agIOStatus == OSSA_IO_OPEN_CNX_ERROR_PROTOCOL_NOT_SUPPORTED ||
21828 agIOStatus == OSSA_IO_OPEN_CNX_ERROR_ZONE_VIOLATION ||
21829 agIOStatus == OSSA_IO_OPEN_CNX_ERROR_BREAK ||
21830 agIOStatus == OSSA_IO_OPEN_CNX_ERROR_IT_NEXUS_LOSS ||
21831 agIOStatus == OSSA_IO_OPEN_CNX_ERROR_BAD_DESTINATION ||
21832 agIOStatus == OSSA_IO_OPEN_CNX_ERROR_CONNECTION_RATE_NOT_SUPPORTED ||
21833 agIOStatus == OSSA_IO_OPEN_CNX_ERROR_WRONG_DESTINATION ||
21834 agIOStatus == OSSA_IO_OPEN_CNX_ERROR_UNKNOWN_ERROR ||
21835 agIOStatus == OSSA_IO_OPEN_CNX_ERROR_STP_RESOURCES_BUSY
21836 )
21837 {
21838 TI_DBG1(("satAddSATAIDDevCB: OSSA_IO_OPEN_CNX_ERROR\n"));
21839 if (tdsaAllShared->ResetInDiscovery != 0 && satDevData->ID_Retries < SATA_ID_DEVICE_DATA_RETRIES)
21840 {
21841 satDevData->satPendingNONNCQIO--;
21842 satDevData->satPendingIO--;
21843 retry_status = sataLLIOStart(tiRoot,
21844 &satIntIo->satIntTiIORequest,
21845 &(NewOneDeviceData->tiDeviceHandle),
21846 satIOContext->tiScsiXchg,
21847 satIOContext);
21848 if (retry_status != tiSuccess)
21849 {
21850 /* simply give up */
21851 satDevData->ID_Retries = 0;
21852 satAddSATAIDDevCBCleanup(agRoot, NewOneDeviceData, satIOContext, tdOrgIORequestBody);
21853 return;
21854 }
21855 satDevData->ID_Retries++;
21856 tdIORequestBody->ioCompleted = agFALSE;
21857 tdIORequestBody->ioStarted = agTRUE;
21858 return;
21859 }
21860 else
21861 {
21862 if (tdsaAllShared->ResetInDiscovery == 0)
21863 {
21864 satAddSATAIDDevCBCleanup(agRoot, NewOneDeviceData, satIOContext, tdOrgIORequestBody);
21865 }
21866 else /* ResetInDiscovery in on */
21867 {
21868 /* RESET only one after ID retries */
21869 if (satDevData->NumOfIDRetries <= 0)
21870 {
21871 satDevData->NumOfIDRetries++;
21872 satDevData->ID_Retries = 0;
21873 satAddSATAIDDevCBReset(agRoot, NewOneDeviceData, satIOContext, tdOrgIORequestBody);
21874 /* send link reset */
21875 saLocalPhyControl(agRoot,
21876 agContext,
21877 tdsaRotateQnumber(tiRoot, NewOneDeviceData),
21878 PhyID,
21879 AGSA_PHY_HARD_RESET,
21880 agNULL);
21881 }
21882 else
21883 {
21884 satDevData->ID_Retries = 0;
21885 satAddSATAIDDevCBCleanup(agRoot, NewOneDeviceData, satIOContext, tdOrgIORequestBody);
21886 }
21887 }
21888 return;
21889 }
21890 }
21891
21892 if ( agIOStatus != OSSA_IO_SUCCESS ||
21893 (agIOStatus == OSSA_IO_SUCCESS && agFirstDword != agNULL && agIOInfoLen != 0)
21894 )
21895 {
21896 if (tdsaAllShared->ResetInDiscovery != 0 && satDevData->ID_Retries < SATA_ID_DEVICE_DATA_RETRIES)
21897 {
21898 satIOContext->pSatDevData->satPendingNONNCQIO--;
21899 satIOContext->pSatDevData->satPendingIO--;
21900 retry_status = sataLLIOStart(tiRoot,
21901 &satIntIo->satIntTiIORequest,
21902 &(NewOneDeviceData->tiDeviceHandle),
21903 satIOContext->tiScsiXchg,
21904 satIOContext);
21905 if (retry_status != tiSuccess)
21906 {
21907 /* simply give up */
21908 satDevData->ID_Retries = 0;
21909 satAddSATAIDDevCBCleanup(agRoot, NewOneDeviceData, satIOContext, tdOrgIORequestBody);
21910 return;
21911 }
21912 satDevData->ID_Retries++;
21913 tdIORequestBody->ioCompleted = agFALSE;
21914 tdIORequestBody->ioStarted = agTRUE;
21915 return;
21916 }
21917 else
21918 {
21919 if (tdsaAllShared->ResetInDiscovery == 0)
21920 {
21921 satAddSATAIDDevCBCleanup(agRoot, NewOneDeviceData, satIOContext, tdOrgIORequestBody);
21922 }
21923 else /* ResetInDiscovery in on */
21924 {
21925 /* RESET only one after ID retries */
21926 if (satDevData->NumOfIDRetries <= 0)
21927 {
21928 satDevData->NumOfIDRetries++;
21929 satDevData->ID_Retries = 0;
21930 satAddSATAIDDevCBReset(agRoot, NewOneDeviceData, satIOContext, tdOrgIORequestBody);
21931 /* send link reset */
21932 saLocalPhyControl(agRoot,
21933 agContext,
21934 tdsaRotateQnumber(tiRoot, NewOneDeviceData),
21935 PhyID,
21936 AGSA_PHY_HARD_RESET,
21937 agNULL);
21938 }
21939 else
21940 {
21941 satDevData->ID_Retries = 0;
21942 satAddSATAIDDevCBCleanup(agRoot, NewOneDeviceData, satIOContext, tdOrgIORequestBody);
21943 }
21944 }
21945 return;
21946 }
21947 }
21948
21949 /* success */
21950 TI_DBG2(("satAddSATAIDDevCB: Success\n"));
21951 /* Convert to host endian */
21952 tmpptr = (bit16*)sglVirtualAddr;
21953 //tdhexdump("satAddSATAIDDevCB before", (bit8 *)sglVirtualAddr, sizeof(agsaSATAIdentifyData_t));
21954 for (x=0; x < sizeof(agsaSATAIdentifyData_t)/sizeof(bit16); x++)
21955 {
21956 OSSA_READ_LE_16(AGROOT, &tmpptr_tmp, tmpptr, 0);
21957 *tmpptr = tmpptr_tmp;
21958 tmpptr++;
21959 /*Print tmpptr_tmp here for debugging purpose*/
21960 }
21961
21962 pSATAIdData = (agsaSATAIdentifyData_t *)sglVirtualAddr;
21963 //tdhexdump("satAddSATAIDDevCB after", (bit8 *)pSATAIdData, sizeof(agsaSATAIdentifyData_t));
21964
21965 TI_DBG5(("satAddSATAIDDevCB: OS satOrgIOContext %p \n", satOrgIOContext));
21966 TI_DBG5(("satAddSATAIDDevCB: TD satIOContext %p \n", satIOContext));
21967 TI_DBG5(("satAddSATAIDDevCB: OS tiScsiXchg %p \n", satOrgIOContext->tiScsiXchg));
21968 TI_DBG5(("satAddSATAIDDevCB: TD tiScsiXchg %p \n", satIOContext->tiScsiXchg));
21969
21970
21971 /* compare idenitfy device data to the exiting list */
21972 DeviceListList = tdsaAllShared->MainDeviceList.flink;
21973 while (DeviceListList != &(tdsaAllShared->MainDeviceList))
21974 {
21975 oneDeviceData = TDLIST_OBJECT_BASE(tdsaDeviceData_t, MainLink, DeviceListList);
21976 TI_DBG1(("satAddSATAIDDevCB: LOOP oneDeviceData %p did %d\n", oneDeviceData, oneDeviceData->id));
21977 //tdhexdump("satAddSATAIDDevCB LOOP", (bit8 *)&oneDeviceData->satDevData.satIdentifyData, sizeof(agsaSATAIdentifyData_t));
21978
21979 /* what is unique ID for sata device -> response of identify devicedata; not really
21980 Let's compare serial number, firmware version, model number
21981 */
21982 if ( oneDeviceData->DeviceType == TD_SATA_DEVICE &&
21983 (osti_memcmp (oneDeviceData->satDevData.satIdentifyData.serialNumber,
21984 pSATAIdData->serialNumber,
21985 20) == 0) &&
21986 (osti_memcmp (oneDeviceData->satDevData.satIdentifyData.firmwareVersion,
21987 pSATAIdData->firmwareVersion,
21988 8) == 0) &&
21989 (osti_memcmp (oneDeviceData->satDevData.satIdentifyData.modelNumber,
21990 pSATAIdData->modelNumber,
21991 40) == 0)
21992 )
21993 {
21994 TI_DBG2(("satAddSATAIDDevCB: did %d\n", oneDeviceData->id));
21995 new_device = agFALSE;
21996 break;
21997 }
21998 DeviceListList = DeviceListList->flink;
21999 }
22000
22001 if (new_device == agFALSE)
22002 {
22003 TI_DBG2(("satAddSATAIDDevCB: old device data\n"));
22004 oneDeviceData->valid = agTRUE;
22005 oneDeviceData->valid2 = agTRUE;
22006 /* save data field from new device data */
22007 oneDeviceData->agRoot = agRoot;
22008 oneDeviceData->agDevHandle = NewOneDeviceData->agDevHandle;
22009 oneDeviceData->agDevHandle->osData = oneDeviceData; /* TD layer */
22010 oneDeviceData->tdPortContext = NewOneDeviceData->tdPortContext;
22011 oneDeviceData->phyID = NewOneDeviceData->phyID;
22012
22013 /*
22014 one SATA directly attached device per phy;
22015 Therefore, deregister then register
22016 */
22017 saDeregisterDeviceHandle(agRoot, agNULL, NewOneDeviceData->agDevHandle, 0);
22018
22019 if (oneDeviceData->registered == agFALSE)
22020 {
22021 TI_DBG2(("satAddSATAIDDevCB: re-registering old device data\n"));
22022 /* already has old information; just register it again */
22023 saRegisterNewDevice( /* satAddSATAIDDevCB */
22024 agRoot,
22025 &oneDeviceData->agContext,
22026 tdsaRotateQnumber(tiRoot, oneDeviceData),
22027 &oneDeviceData->agDeviceInfo,
22028 oneDeviceData->tdPortContext->agPortContext,
22029 0
22030 );
22031 }
22032
22033 // tdsaAbortAll(tiRoot, agRoot, NewOneDeviceData);
22034 /* put onedevicedata back to free list */
22035 osti_memset(&(NewOneDeviceData->satDevData.satIdentifyData), 0xFF, sizeof(agsaSATAIdentifyData_t));
22036 TDLIST_DEQUEUE_THIS(&(NewOneDeviceData->MainLink));
22037 TDLIST_ENQUEUE_AT_TAIL(&(NewOneDeviceData->FreeLink), &(tdsaAllShared->FreeDeviceList));
22038 satDecrementPendingIO(tiRoot, tdsaAllShared, satIOContext);
22039
22040 satFreeIntIoResource( tiRoot,
22041 satDevData,
22042 satIntIo);
22043
22044 if (satDevData->satDeviceType == SATA_ATAPI_DEVICE)
22045 {
22046 /* send the Set Feature ATA command to ATAPI device for enbling PIO and DMA transfer mode*/
22047 satNewIntIo = satAllocIntIoResource( tiRoot,
22048 tiOrgIORequest,
22049 satDevData,
22050 0,
22051 satNewIntIo);
22052
22053 if (satNewIntIo == agNULL)
22054 {
22055 TI_DBG1(("tdsaDiscoveryStartIDDevCB: momory allocation fails\n"));
22056 /* clean up TD layer's IORequestBody */
22057 ostiFreeMemory(
22058 tiRoot,
22059 tdOrgIORequestBody->IOType.InitiatorTMIO.osMemHandle,
22060 sizeof(tdIORequestBody_t)
22061 );
22062 return;
22063 } /* end memory allocation */
22064
22065 satNewIOContext = satPrepareNewIO(satNewIntIo,
22066 tiOrgIORequest,
22067 satDevData,
22068 agNULL,
22069 satOrgIOContext
22070 );
22071 /* enable PIO mode, then enable Ultra DMA mode in the satSetFeaturesCB callback function*/
22072 status = satSetFeatures(tiRoot,
22073 &satNewIntIo->satIntTiIORequest,
22074 satNewIOContext->ptiDeviceHandle,
22075 &satNewIntIo->satIntTiScsiXchg, /* orginal from OS layer */
22076 satNewIOContext,
22077 agFALSE);
22078 if (status != tiSuccess)
22079 {
22080 satFreeIntIoResource( tiRoot,
22081 satDevData,
22082 satIntIo);
22083 /* clean up TD layer's IORequestBody */
22084 ostiFreeMemory(
22085 tiRoot,
22086 tdOrgIORequestBody->IOType.InitiatorTMIO.osMemHandle,
22087 sizeof(tdIORequestBody_t)
22088 );
22089 }
22090 }
22091 else
22092 {
22093 /* clean up TD layer's IORequestBody */
22094 ostiFreeMemory(
22095 tiRoot,
22096 tdOrgIORequestBody->IOType.InitiatorTMIO.osMemHandle,
22097 sizeof(tdIORequestBody_t)
22098 );
22099 TI_DBG2(("satAddSATAIDDevCB: pid %d\n", tdsaAllShared->Ports[PhyID].portContext->id));
22100 /* notifying link up */
22101 ostiPortEvent(
22102 tiRoot,
22103 tiPortLinkUp,
22104 tiSuccess,
22105 (void *)tdsaAllShared->Ports[PhyID].tiPortalContext
22106 );
22107
22108
22109 #ifdef INITIATOR_DRIVER
22110 /* triggers discovery */
22111 ostiPortEvent(
22112 tiRoot,
22113 tiPortDiscoveryReady,
22114 tiSuccess,
22115 (void *) tdsaAllShared->Ports[PhyID].tiPortalContext
22116 );
22117 #endif
22118 }
22119 return;
22120 }
22121
22122 TI_DBG2(("satAddSATAIDDevCB: new device data\n"));
22123 /* copy ID Dev data to satDevData */
22124 satDevData->satIdentifyData = *pSATAIdData;
22125
22126
22127 satDevData->IDDeviceValid = agTRUE;
22128 #ifdef TD_INTERNAL_DEBUG
22129 tdhexdump("satAddSATAIDDevCB ID Dev data",(bit8 *)pSATAIdData, sizeof(agsaSATAIdentifyData_t));
22130 tdhexdump("satAddSATAIDDevCB Device ID Dev data",(bit8 *)&satDevData->satIdentifyData, sizeof(agsaSATAIdentifyData_t));
22131 #endif
22132
22133 /* set satDevData fields from IndentifyData */
22134 satSetDevInfo(satDevData,pSATAIdData);
22135 satDecrementPendingIO(tiRoot, tdsaAllShared, satIOContext);
22136
22137 satFreeIntIoResource( tiRoot,
22138 satDevData,
22139 satIntIo);
22140
22141 if (satDevData->satDeviceType == SATA_ATAPI_DEVICE)
22142 {
22143 /* send the Set Feature ATA command to ATAPI device for enbling PIO and DMA transfer mode*/
22144 satNewIntIo = satAllocIntIoResource( tiRoot,
22145 tiOrgIORequest,
22146 satDevData,
22147 0,
22148 satNewIntIo);
22149
22150 if (satNewIntIo == agNULL)
22151 {
22152 TI_DBG1(("tdsaDiscoveryStartIDDevCB: momory allocation fails\n"));
22153 /* clean up TD layer's IORequestBody */
22154 ostiFreeMemory(
22155 tiRoot,
22156 tdOrgIORequestBody->IOType.InitiatorTMIO.osMemHandle,
22157 sizeof(tdIORequestBody_t)
22158 );
22159 return;
22160 } /* end memory allocation */
22161
22162 satNewIOContext = satPrepareNewIO(satNewIntIo,
22163 tiOrgIORequest,
22164 satDevData,
22165 agNULL,
22166 satOrgIOContext
22167 );
22168 /* enable PIO mode, then enable Ultra DMA mode in the satSetFeaturesCB callback function*/
22169 status = satSetFeatures(tiRoot,
22170 &satNewIntIo->satIntTiIORequest,
22171 satNewIOContext->ptiDeviceHandle,
22172 &satNewIntIo->satIntTiScsiXchg, /* orginal from OS layer */
22173 satNewIOContext,
22174 agFALSE);
22175 if (status != tiSuccess)
22176 {
22177 satFreeIntIoResource( tiRoot,
22178 satDevData,
22179 satIntIo);
22180 /* clean up TD layer's IORequestBody */
22181 ostiFreeMemory(
22182 tiRoot,
22183 tdOrgIORequestBody->IOType.InitiatorTMIO.osMemHandle,
22184 sizeof(tdIORequestBody_t)
22185 );
22186 }
22187
22188 }
22189 else
22190 {
22191 /* clean up TD layer's IORequestBody */
22192 ostiFreeMemory(
22193 tiRoot,
22194 tdOrgIORequestBody->IOType.InitiatorTMIO.osMemHandle,
22195 sizeof(tdIORequestBody_t)
22196 );
22197
22198 TI_DBG2(("satAddSATAIDDevCB: pid %d\n", tdsaAllShared->Ports[PhyID].portContext->id));
22199 /* notifying link up */
22200 ostiPortEvent (
22201 tiRoot,
22202 tiPortLinkUp,
22203 tiSuccess,
22204 (void *)tdsaAllShared->Ports[PhyID].tiPortalContext
22205 );
22206 #ifdef INITIATOR_DRIVER
22207 /* triggers discovery */
22208 ostiPortEvent(
22209 tiRoot,
22210 tiPortDiscoveryReady,
22211 tiSuccess,
22212 (void *) tdsaAllShared->Ports[PhyID].tiPortalContext
22213 );
22214 #endif
22215 }
22216
22217 TI_DBG2(("satAddSATAIDDevCB: end\n"));
22218 return;
22219
22220 }
22221
22222 /*****************************************************************************
22223 *! \brief satAddSATAIDDevCBReset
22224 *
22225 * This routine cleans up IOs for failed Identify device data
22226 *
22227 * \param agRoot: Handles for this instance of SAS/SATA hardware
22228 * \param oneDeviceData: Pointer to the device data.
22229 * \param ioContext: Pointer to satIOContext_t.
22230 * \param tdIORequestBody: Pointer to the request body
22231 * \param flag: Decrement pending io or not
22232 *
22233 * \return: none
22234 *
22235 *****************************************************************************/
satAddSATAIDDevCBReset(agsaRoot_t * agRoot,tdsaDeviceData_t * oneDeviceData,satIOContext_t * satIOContext,tdIORequestBody_t * tdIORequestBody)22236 void satAddSATAIDDevCBReset(
22237 agsaRoot_t *agRoot,
22238 tdsaDeviceData_t *oneDeviceData,
22239 satIOContext_t *satIOContext,
22240 tdIORequestBody_t *tdIORequestBody
22241 )
22242 {
22243 tdsaRootOsData_t *osData = (tdsaRootOsData_t *)agRoot->osData;
22244 tiRoot_t *tiRoot = (tiRoot_t *)osData->tiRoot;
22245 tdsaRoot_t *tdsaRoot = (tdsaRoot_t *) tiRoot->tdData;
22246 tdsaContext_t *tdsaAllShared = (tdsaContext_t *)&tdsaRoot->tdsaAllShared;
22247 satInternalIo_t *satIntIo;
22248 satDeviceData_t *satDevData;
22249
22250 TI_DBG2(("satAddSATAIDDevCBReset: start\n"));
22251 satIntIo = satIOContext->satIntIoContext;
22252 satDevData = satIOContext->pSatDevData;
22253 satDecrementPendingIO(tiRoot, tdsaAllShared, satIOContext);
22254
22255 satFreeIntIoResource( tiRoot,
22256 satDevData,
22257 satIntIo);
22258 /* clean up TD layer's IORequestBody */
22259 ostiFreeMemory(
22260 tiRoot,
22261 tdIORequestBody->IOType.InitiatorTMIO.osMemHandle,
22262 sizeof(tdIORequestBody_t)
22263 );
22264 return;
22265 }
22266
22267
22268 /*****************************************************************************
22269 *! \brief satAddSATAIDDevCBCleanup
22270 *
22271 * This routine cleans up IOs for failed Identify device data
22272 *
22273 * \param agRoot: Handles for this instance of SAS/SATA hardware
22274 * \param oneDeviceData: Pointer to the device data.
22275 * \param ioContext: Pointer to satIOContext_t.
22276 * \param tdIORequestBody: Pointer to the request body
22277 *
22278 * \return: none
22279 *
22280 *****************************************************************************/
satAddSATAIDDevCBCleanup(agsaRoot_t * agRoot,tdsaDeviceData_t * oneDeviceData,satIOContext_t * satIOContext,tdIORequestBody_t * tdIORequestBody)22281 void satAddSATAIDDevCBCleanup(
22282 agsaRoot_t *agRoot,
22283 tdsaDeviceData_t *oneDeviceData,
22284 satIOContext_t *satIOContext,
22285 tdIORequestBody_t *tdIORequestBody
22286 )
22287 {
22288 tdsaRootOsData_t *osData = (tdsaRootOsData_t *)agRoot->osData;
22289 tiRoot_t *tiRoot = (tiRoot_t *)osData->tiRoot;
22290 tdsaRoot_t *tdsaRoot = (tdsaRoot_t *) tiRoot->tdData;
22291 tdsaContext_t *tdsaAllShared = (tdsaContext_t *)&tdsaRoot->tdsaAllShared;
22292 satInternalIo_t *satIntIo;
22293 satDeviceData_t *satDevData;
22294 bit8 PhyID;
22295
22296 TI_DBG2(("satAddSATAIDDevCBCleanup: start\n"));
22297 satIntIo = satIOContext->satIntIoContext;
22298 satDevData = satIOContext->pSatDevData;
22299 PhyID = oneDeviceData->phyID;
22300 tdsaAbortAll(tiRoot, agRoot, oneDeviceData);
22301 /* put onedevicedata back to free list */
22302 osti_memset(&(oneDeviceData->satDevData.satIdentifyData), 0xFF, sizeof(agsaSATAIdentifyData_t));
22303 TDLIST_DEQUEUE_THIS(&(oneDeviceData->MainLink));
22304 TDLIST_ENQUEUE_AT_TAIL(&(oneDeviceData->FreeLink), &(tdsaAllShared->FreeDeviceList));
22305
22306 satDecrementPendingIO(tiRoot, tdsaAllShared, satIOContext);
22307
22308
22309 satFreeIntIoResource( tiRoot,
22310 satDevData,
22311 satIntIo);
22312
22313 /* clean up TD layer's IORequestBody */
22314 ostiFreeMemory(
22315 tiRoot,
22316 tdIORequestBody->IOType.InitiatorTMIO.osMemHandle,
22317 sizeof(tdIORequestBody_t)
22318 );
22319
22320 /* notifying link up */
22321 ostiPortEvent (
22322 tiRoot,
22323 tiPortLinkUp,
22324 tiSuccess,
22325 (void *)tdsaAllShared->Ports[PhyID].tiPortalContext
22326 );
22327 #ifdef INITIATOR_DRIVER
22328 /* triggers discovery */
22329 ostiPortEvent(
22330 tiRoot,
22331 tiPortDiscoveryReady,
22332 tiSuccess,
22333 (void *) tdsaAllShared->Ports[PhyID].tiPortalContext
22334 );
22335 #endif
22336
22337 return;
22338 }
22339
22340 /*****************************************************************************/
22341 /*! \brief SAT implementation for tdsaDiscoveryStartIDDev.
22342 *
22343 * This function sends identify device data to SATA device in discovery
22344 *
22345 *
22346 * \param tiRoot: Pointer to TISA initiator driver/port instance.
22347 * \param tiIORequest: Pointer to TISA I/O request context for this I/O.
22348 * \param tiDeviceHandle: Pointer to TISA device handle for this I/O.
22349 * \param tiScsiRequest: Pointer to TISA SCSI I/O request and SGL list.
22350 * \param oneDeviceData : Pointer to the device data.
22351 *
22352 * \return If command is started successfully
22353 * - \e tiSuccess: I/O request successfully initiated.
22354 * - \e tiBusy: No resources available, try again later.
22355 * - \e tiIONoDevice: Invalid device handle.
22356 * - \e tiError: Other errors.
22357 */
22358 /*****************************************************************************/
22359 GLOBAL bit32
tdsaDiscoveryStartIDDev(tiRoot_t * tiRoot,tiIORequest_t * tiIORequest,tiDeviceHandle_t * tiDeviceHandle,tiScsiInitiatorRequest_t * tiScsiRequest,tdsaDeviceData_t * oneDeviceData)22360 tdsaDiscoveryStartIDDev(tiRoot_t *tiRoot,
22361 tiIORequest_t *tiIORequest, /* agNULL */
22362 tiDeviceHandle_t *tiDeviceHandle,
22363 tiScsiInitiatorRequest_t *tiScsiRequest, /* agNULL */
22364 tdsaDeviceData_t *oneDeviceData
22365 )
22366 {
22367 void *osMemHandle;
22368 tdIORequestBody_t *tdIORequestBody;
22369 bit32 PhysUpper32;
22370 bit32 PhysLower32;
22371 bit32 memAllocStatus;
22372 agsaIORequest_t *agIORequest = agNULL; /* identify device data itself */
22373 satIOContext_t *satIOContext = agNULL;
22374 bit32 status;
22375
22376 /* allocate tdiorequestbody and call tdsaDiscoveryIntStartIDDev
22377 tdsaDiscoveryIntStartIDDev(tiRoot, agNULL, tiDeviceHandle, satIOContext);
22378
22379 */
22380
22381 TI_DBG3(("tdsaDiscoveryStartIDDev: start\n"));
22382 TI_DBG3(("tdsaDiscoveryStartIDDev: did %d\n", oneDeviceData->id));
22383
22384 /* allocation tdIORequestBody and pass it to satTM() */
22385 memAllocStatus = ostiAllocMemory(
22386 tiRoot,
22387 &osMemHandle,
22388 (void **)&tdIORequestBody,
22389 &PhysUpper32,
22390 &PhysLower32,
22391 8,
22392 sizeof(tdIORequestBody_t),
22393 agTRUE
22394 );
22395
22396 if (memAllocStatus != tiSuccess)
22397 {
22398 TI_DBG1(("tdsaDiscoveryStartIDDev: ostiAllocMemory failed... loc 1\n"));
22399 return tiError;
22400 }
22401 if (tdIORequestBody == agNULL)
22402 {
22403 TI_DBG1(("tdsaDiscoveryStartIDDev: ostiAllocMemory returned NULL tdIORequestBody loc 2\n"));
22404 return tiError;
22405 }
22406
22407 /* setup identify device data IO structure */
22408 tdIORequestBody->IOType.InitiatorTMIO.osMemHandle = osMemHandle;
22409 tdIORequestBody->IOType.InitiatorTMIO.CurrentTaskTag = agNULL;
22410 tdIORequestBody->IOType.InitiatorTMIO.TaskTag = agNULL;
22411
22412 /* initialize tiDevhandle */
22413 tdIORequestBody->tiDevHandle = &(oneDeviceData->tiDeviceHandle);
22414 tdIORequestBody->tiDevHandle->tdData = oneDeviceData;
22415
22416 /* initialize tiIORequest */
22417 tdIORequestBody->tiIORequest = agNULL;
22418
22419 /* initialize agIORequest */
22420 agIORequest = &(tdIORequestBody->agIORequest);
22421 agIORequest->osData = (void *) tdIORequestBody;
22422 agIORequest->sdkData = agNULL; /* SA takes care of this */
22423
22424 /* set up satIOContext */
22425 satIOContext = &(tdIORequestBody->transport.SATA.satIOContext);
22426 satIOContext->pSatDevData = &(oneDeviceData->satDevData);
22427 satIOContext->pFis =
22428 &(tdIORequestBody->transport.SATA.agSATARequestBody.fis.fisRegHostToDev);
22429
22430 satIOContext->tiRequestBody = tdIORequestBody;
22431 satIOContext->ptiDeviceHandle = &(oneDeviceData->tiDeviceHandle);
22432 satIOContext->tiScsiXchg = agNULL;
22433 satIOContext->satIntIoContext = agNULL;
22434 satIOContext->satOrgIOContext = agNULL;
22435 /* followings are used only for internal IO */
22436 satIOContext->currentLBA = 0;
22437 satIOContext->OrgTL = 0;
22438 satIOContext->satToBeAbortedIOContext = agNULL;
22439 satIOContext->NotifyOS = agFALSE;
22440
22441 /* saving port ID just in case of full discovery to full discovery transition */
22442 satIOContext->pid = oneDeviceData->tdPortContext->id;
22443 osti_memset(&(oneDeviceData->satDevData.satIdentifyData), 0x0, sizeof(agsaSATAIdentifyData_t));
22444 status = tdsaDiscoveryIntStartIDDev(tiRoot,
22445 tiIORequest, /* agNULL */
22446 tiDeviceHandle, /* &(oneDeviceData->tiDeviceHandle)*/
22447 agNULL,
22448 satIOContext
22449 );
22450 if (status != tiSuccess)
22451 {
22452 TI_DBG1(("tdsaDiscoveryStartIDDev: failed in sending %d\n", status));
22453 ostiFreeMemory(tiRoot, osMemHandle, sizeof(tdIORequestBody_t));
22454 }
22455 return status;
22456 }
22457
22458 /*****************************************************************************/
22459 /*! \brief SAT implementation for tdsaDiscoveryIntStartIDDev.
22460 *
22461 * This function sends identify device data to SATA device.
22462 *
22463 * \param tiRoot: Pointer to TISA initiator driver/port instance.
22464 * \param tiIORequest: Pointer to TISA I/O request context for this I/O.
22465 * \param tiDeviceHandle: Pointer to TISA device handle for this I/O.
22466 * \param tiScsiRequest: Pointer to TISA SCSI I/O request and SGL list.
22467 * \param satIOContext_t: Pointer to the SAT IO Context
22468 *
22469 * \return If command is started successfully
22470 * - \e tiSuccess: I/O request successfully initiated.
22471 * - \e tiBusy: No resources available, try again later.
22472 * - \e tiIONoDevice: Invalid device handle.
22473 * - \e tiError: Other errors.
22474 */
22475 /*****************************************************************************/
22476 GLOBAL bit32
tdsaDiscoveryIntStartIDDev(tiRoot_t * tiRoot,tiIORequest_t * tiIORequest,tiDeviceHandle_t * tiDeviceHandle,tiScsiInitiatorRequest_t * tiScsiRequest,satIOContext_t * satIOContext)22477 tdsaDiscoveryIntStartIDDev(tiRoot_t *tiRoot,
22478 tiIORequest_t *tiIORequest, /* agNULL */
22479 tiDeviceHandle_t *tiDeviceHandle,
22480 tiScsiInitiatorRequest_t *tiScsiRequest, /* agNULL */
22481 satIOContext_t *satIOContext
22482 )
22483 {
22484 satInternalIo_t *satIntIo = agNULL;
22485 satDeviceData_t *satDevData = agNULL;
22486 tdIORequestBody_t *tdIORequestBody;
22487 satIOContext_t *satNewIOContext;
22488 bit32 status;
22489
22490 TI_DBG3(("tdsaDiscoveryIntStartIDDev: start\n"));
22491
22492 satDevData = satIOContext->pSatDevData;
22493
22494 /* allocate identify device command */
22495 satIntIo = satAllocIntIoResource( tiRoot,
22496 tiIORequest,
22497 satDevData,
22498 sizeof(agsaSATAIdentifyData_t), /* 512; size of identify device data */
22499 satIntIo);
22500
22501 if (satIntIo == agNULL)
22502 {
22503 TI_DBG2(("tdsaDiscoveryIntStartIDDev: can't alloacate\n"));
22504
22505 return tiError;
22506 }
22507
22508 /* fill in fields */
22509 /* real ttttttthe one worked and the same; 5/21/07/ */
22510 satIntIo->satOrgTiIORequest = tiIORequest; /* changed */
22511 tdIORequestBody = satIntIo->satIntRequestBody;
22512 satNewIOContext = &(tdIORequestBody->transport.SATA.satIOContext);
22513
22514 satNewIOContext->pSatDevData = satDevData;
22515 satNewIOContext->pFis = &(tdIORequestBody->transport.SATA.agSATARequestBody.fis.fisRegHostToDev);
22516 satNewIOContext->pScsiCmnd = &(satIntIo->satIntTiScsiXchg.scsiCmnd);
22517 satNewIOContext->pSense = &(tdIORequestBody->transport.SATA.sensePayload);
22518 satNewIOContext->pTiSenseData = &(tdIORequestBody->transport.SATA.tiSenseData);
22519 satNewIOContext->tiRequestBody = satIntIo->satIntRequestBody; /* key fix */
22520 satNewIOContext->interruptContext = tiInterruptContext;
22521 satNewIOContext->satIntIoContext = satIntIo;
22522
22523 satNewIOContext->ptiDeviceHandle = agNULL;
22524 satNewIOContext->satOrgIOContext = satIOContext; /* changed */
22525
22526 /* this is valid only for TD layer generated (not triggered by OS at all) IO */
22527 satNewIOContext->tiScsiXchg = &(satIntIo->satIntTiScsiXchg);
22528
22529
22530 TI_DBG6(("tdsaDiscoveryIntStartIDDev: OS satIOContext %p \n", satIOContext));
22531 TI_DBG6(("tdsaDiscoveryIntStartIDDev: TD satNewIOContext %p \n", satNewIOContext));
22532 TI_DBG6(("tdsaDiscoveryIntStartIDDev: OS tiScsiXchg %p \n", satIOContext->tiScsiXchg));
22533 TI_DBG6(("tdsaDiscoveryIntStartIDDev: TD tiScsiXchg %p \n", satNewIOContext->tiScsiXchg));
22534
22535
22536
22537 TI_DBG3(("tdsaDiscoveryIntStartIDDev: satNewIOContext %p tdIORequestBody %p\n", satNewIOContext, tdIORequestBody));
22538
22539 status = tdsaDiscoverySendIDDev(tiRoot,
22540 &satIntIo->satIntTiIORequest, /* New tiIORequest */
22541 tiDeviceHandle,
22542 satNewIOContext->tiScsiXchg, /* New tiScsiInitiatorRequest_t *tiScsiRequest, */
22543 satNewIOContext);
22544
22545 if (status != tiSuccess)
22546 {
22547 TI_DBG1(("tdsaDiscoveryIntStartIDDev: failed in sending %d\n", status));
22548
22549 satFreeIntIoResource( tiRoot,
22550 satDevData,
22551 satIntIo);
22552
22553 return tiError;
22554 }
22555
22556
22557 TI_DBG6(("tdsaDiscoveryIntStartIDDev: end\n"));
22558
22559 return status;
22560 }
22561
22562
22563 /*****************************************************************************/
22564 /*! \brief SAT implementation for tdsaDiscoverySendIDDev.
22565 *
22566 * This function prepares identify device data FIS and sends it to SATA device.
22567 *
22568 * \param tiRoot: Pointer to TISA initiator driver/port instance.
22569 * \param tiIORequest: Pointer to TISA I/O request context for this I/O.
22570 * \param tiDeviceHandle: Pointer to TISA device handle for this I/O.
22571 * \param tiScsiRequest: Pointer to TISA SCSI I/O request and SGL list.
22572 * \param satIOContext_t: Pointer to the SAT IO Context
22573 *
22574 * \return If command is started successfully
22575 * - \e tiSuccess: I/O request successfully initiated.
22576 * - \e tiBusy: No resources available, try again later.
22577 * - \e tiIONoDevice: Invalid device handle.
22578 * - \e tiError: Other errors.
22579 */
22580 /*****************************************************************************/
22581 GLOBAL bit32
tdsaDiscoverySendIDDev(tiRoot_t * tiRoot,tiIORequest_t * tiIORequest,tiDeviceHandle_t * tiDeviceHandle,tiScsiInitiatorRequest_t * tiScsiRequest,satIOContext_t * satIOContext)22582 tdsaDiscoverySendIDDev(tiRoot_t *tiRoot,
22583 tiIORequest_t *tiIORequest,
22584 tiDeviceHandle_t *tiDeviceHandle,
22585 tiScsiInitiatorRequest_t *tiScsiRequest,
22586 satIOContext_t *satIOContext
22587 )
22588 {
22589 bit32 status;
22590 bit32 agRequestType;
22591 satDeviceData_t *pSatDevData;
22592 agsaFisRegHostToDevice_t *fis;
22593 #ifdef TD_DEBUG_ENABLE
22594 tdIORequestBody_t *tdIORequestBody;
22595 satInternalIo_t *satIntIoContext;
22596 #endif
22597
22598 pSatDevData = satIOContext->pSatDevData;
22599 fis = satIOContext->pFis;
22600 TI_DBG3(("tdsaDiscoverySendIDDev: start\n"));
22601 #ifdef TD_DEBUG_ENABLE
22602 satIntIoContext = satIOContext->satIntIoContext;
22603 tdIORequestBody = satIntIoContext->satIntRequestBody;
22604 #endif
22605 TI_DBG5(("tdsaDiscoverySendIDDev: satIOContext %p tdIORequestBody %p\n", satIOContext, tdIORequestBody));
22606
22607 fis->h.fisType = 0x27; /* Reg host to device */
22608 fis->h.c_pmPort = 0x80; /* C Bit is set */
22609 if (pSatDevData->satDeviceType == SATA_ATAPI_DEVICE)
22610 fis->h.command = SAT_IDENTIFY_PACKET_DEVICE; /* 0xA1 */
22611 else
22612 fis->h.command = SAT_IDENTIFY_DEVICE; /* 0xEC */
22613 fis->h.features = 0; /* FIS reserve */
22614 fis->d.lbaLow = 0; /* FIS LBA (7 :0 ) */
22615 fis->d.lbaMid = 0; /* FIS LBA (15:8 ) */
22616 fis->d.lbaHigh = 0; /* FIS LBA (23:16) */
22617 fis->d.device = 0; /* FIS LBA mode */
22618 fis->d.lbaLowExp = 0;
22619 fis->d.lbaMidExp = 0;
22620 fis->d.lbaHighExp = 0;
22621 fis->d.featuresExp = 0;
22622 fis->d.sectorCount = 0; /* FIS sector count (7:0) */
22623 fis->d.sectorCountExp = 0;
22624 fis->d.reserved4 = 0;
22625 fis->d.control = 0; /* FIS HOB bit clear */
22626 fis->d.reserved5 = 0;
22627
22628 agRequestType = AGSA_SATA_PROTOCOL_PIO_READ;
22629
22630 /* Initialize CB for SATA completion.
22631 */
22632 satIOContext->satCompleteCB = &tdsaDiscoveryStartIDDevCB;
22633
22634 /*
22635 * Prepare SGL and send FIS to LL layer.
22636 */
22637 satIOContext->reqType = agRequestType; /* Save it */
22638
22639 #ifdef TD_INTERNAL_DEBUG
22640 tdhexdump("tdsaDiscoverySendIDDev", (bit8 *)satIOContext->pFis, sizeof(agsaFisRegHostToDevice_t));
22641 #ifdef TD_DEBUG_ENABLE
22642 tdhexdump("tdsaDiscoverySendIDDev LL", (bit8 *)&(tdIORequestBody->transport.SATA.agSATARequestBody.fis.fisRegHostToDev), sizeof(agsaFisRegHostToDevice_t));
22643 #endif
22644 #endif
22645 status = sataLLIOStart( tiRoot,
22646 tiIORequest,
22647 tiDeviceHandle,
22648 tiScsiRequest,
22649 satIOContext);
22650 TI_DBG3(("tdsaDiscoverySendIDDev: end status %d\n", status));
22651 return status;
22652 }
22653
22654
22655 /*****************************************************************************
22656 *! \brief tdsaDiscoveryStartIDDevCB
22657 *
22658 * This routine is a callback function for tdsaDiscoverySendIDDev()
22659 * Using Identify Device Data, this function finds whether devicedata is
22660 * new or old. If new, add it to the devicelist. This is done as a part
22661 * of discovery.
22662 *
22663 * \param agRoot: Handles for this instance of SAS/SATA hardware
22664 * \param agIORequest: Pointer to the LL I/O request context for this I/O.
22665 * \param agIOStatus: Status of completed I/O.
22666 * \param agFirstDword:Pointer to the four bytes of FIS.
22667 * \param agIOInfoLen: Length in bytes of overrun/underrun residual or FIS
22668 * length.
22669 * \param agParam: Additional info based on status.
22670 * \param ioContext: Pointer to satIOContext_t.
22671 *
22672 * \return: none
22673 *
22674 *****************************************************************************/
tdsaDiscoveryStartIDDevCB(agsaRoot_t * agRoot,agsaIORequest_t * agIORequest,bit32 agIOStatus,agsaFisHeader_t * agFirstDword,bit32 agIOInfoLen,void * agParam,void * ioContext)22675 void tdsaDiscoveryStartIDDevCB(
22676 agsaRoot_t *agRoot,
22677 agsaIORequest_t *agIORequest,
22678 bit32 agIOStatus,
22679 agsaFisHeader_t *agFirstDword,
22680 bit32 agIOInfoLen,
22681 void *agParam,
22682 void *ioContext
22683 )
22684 {
22685 /*
22686 In the process of SAT_IDENTIFY_DEVICE during discovery
22687 */
22688 tdsaRootOsData_t *osData = (tdsaRootOsData_t *)agRoot->osData;
22689 tiRoot_t *tiRoot = (tiRoot_t *)osData->tiRoot;
22690 tdsaRoot_t *tdsaRoot = (tdsaRoot_t *) tiRoot->tdData;
22691 tdsaContext_t *tdsaAllShared = (tdsaContext_t *)&tdsaRoot->tdsaAllShared;
22692 tdIORequestBody_t *tdIORequestBody;
22693 tdIORequestBody_t *tdOrgIORequestBody;
22694 satIOContext_t *satIOContext;
22695 satIOContext_t *satOrgIOContext;
22696 satIOContext_t *satNewIOContext;
22697 satInternalIo_t *satIntIo;
22698 satInternalIo_t *satNewIntIo = agNULL;
22699 satDeviceData_t *satDevData;
22700 tiIORequest_t *tiOrgIORequest = agNULL;
22701
22702 #ifdef TD_DEBUG_ENABLE
22703 bit32 ataStatus = 0;
22704 bit32 ataError;
22705 agsaFisPioSetupHeader_t *satPIOSetupHeader = agNULL;
22706 #endif
22707 agsaSATAIdentifyData_t *pSATAIdData;
22708 bit16 *tmpptr, tmpptr_tmp;
22709 bit32 x;
22710 tdsaDeviceData_t *oneDeviceData = agNULL;
22711 void *sglVirtualAddr;
22712 tdsaPortContext_t *onePortContext = agNULL;
22713 tiPortalContext_t *tiPortalContext = agNULL;
22714 bit32 retry_status;
22715
22716 TI_DBG3(("tdsaDiscoveryStartIDDevCB: start\n"));
22717
22718 tdIORequestBody = (tdIORequestBody_t *)agIORequest->osData;
22719 satIOContext = (satIOContext_t *) ioContext;
22720 satIntIo = satIOContext->satIntIoContext;
22721 satDevData = satIOContext->pSatDevData;
22722 oneDeviceData = (tdsaDeviceData_t *)tdIORequestBody->tiDevHandle->tdData;
22723 TI_DBG3(("tdsaDiscoveryStartIDDevCB: did %d\n", oneDeviceData->id));
22724 onePortContext = oneDeviceData->tdPortContext;
22725 if (onePortContext == agNULL)
22726 {
22727 TI_DBG1(("tdsaDiscoveryStartIDDevCB: onePortContext is NULL\n"));
22728 return;
22729 }
22730 tiPortalContext= onePortContext->tiPortalContext;
22731
22732 satDevData->IDDeviceValid = agFALSE;
22733
22734 if (satIntIo == agNULL)
22735 {
22736 TI_DBG1(("tdsaDiscoveryStartIDDevCB: External, OS generated\n"));
22737 TI_DBG1(("tdsaDiscoveryStartIDDevCB: Not possible case\n"));
22738 satOrgIOContext = satIOContext;
22739 tdOrgIORequestBody = (tdIORequestBody_t *)satOrgIOContext->tiRequestBody;
22740
22741 satDecrementPendingIO(tiRoot, tdsaAllShared, satIOContext);
22742
22743 satFreeIntIoResource( tiRoot,
22744 satDevData,
22745 satIntIo);
22746
22747 /* clean up TD layer's IORequestBody */
22748 ostiFreeMemory(
22749 tiRoot,
22750 tdOrgIORequestBody->IOType.InitiatorTMIO.osMemHandle,
22751 sizeof(tdIORequestBody_t)
22752 );
22753 return;
22754 }
22755 else
22756 {
22757 TI_DBG3(("tdsaDiscoveryStartIDDevCB: Internal, TD generated\n"));
22758 satOrgIOContext = satIOContext->satOrgIOContext;
22759 if (satOrgIOContext == agNULL)
22760 {
22761 TI_DBG6(("tdsaDiscoveryStartIDDevCB: satOrgIOContext is NULL\n"));
22762 return;
22763 }
22764 else
22765 {
22766 TI_DBG6(("tdsaDiscoveryStartIDDevCB: satOrgIOContext is NOT NULL\n"));
22767 tdOrgIORequestBody = (tdIORequestBody_t *)satOrgIOContext->tiRequestBody;
22768 sglVirtualAddr = satIntIo->satIntTiScsiXchg.sglVirtualAddr;
22769 }
22770 }
22771
22772 tiOrgIORequest = tdIORequestBody->tiIORequest;
22773 tdIORequestBody->ioCompleted = agTRUE;
22774 tdIORequestBody->ioStarted = agFALSE;
22775
22776 TI_DBG3(("tdsaDiscoveryStartIDDevCB: satOrgIOContext->pid %d\n", satOrgIOContext->pid));
22777
22778 /* protect against double completion for old port */
22779 if (satOrgIOContext->pid != oneDeviceData->tdPortContext->id)
22780 {
22781 TI_DBG3(("tdsaDiscoveryStartIDDevCB: incorrect pid\n"));
22782 TI_DBG3(("tdsaDiscoveryStartIDDevCB: satOrgIOContext->pid %d\n", satOrgIOContext->pid));
22783 TI_DBG3(("tdsaDiscoveryStartIDDevCB: tiPortalContext pid %d\n", oneDeviceData->tdPortContext->id));
22784
22785 satDecrementPendingIO(tiRoot, tdsaAllShared, satIOContext);
22786
22787 satFreeIntIoResource( tiRoot,
22788 satDevData,
22789 satIntIo);
22790
22791 /* clean up TD layer's IORequestBody */
22792 ostiFreeMemory(
22793 tiRoot,
22794 tdOrgIORequestBody->IOType.InitiatorTMIO.osMemHandle,
22795 sizeof(tdIORequestBody_t)
22796 );
22797
22798 return;
22799 }
22800
22801 /* completion after portcontext is invalidated */
22802 if (onePortContext != agNULL)
22803 {
22804 if (onePortContext->valid == agFALSE)
22805 {
22806 TI_DBG1(("tdsaDiscoveryStartIDDevCB: portcontext is invalid\n"));
22807 TI_DBG1(("tdsaDiscoveryStartIDDevCB: onePortContext->id pid %d\n", onePortContext->id));
22808 satDecrementPendingIO(tiRoot, tdsaAllShared, satIOContext);
22809
22810 satFreeIntIoResource( tiRoot,
22811 satDevData,
22812 satIntIo);
22813
22814 /* clean up TD layer's IORequestBody */
22815 ostiFreeMemory(
22816 tiRoot,
22817 tdOrgIORequestBody->IOType.InitiatorTMIO.osMemHandle,
22818 sizeof(tdIORequestBody_t)
22819 );
22820
22821 /* no notification to OS layer */
22822 return;
22823 }
22824 }
22825
22826 if (agFirstDword == agNULL && agIOStatus != OSSA_IO_SUCCESS)
22827 {
22828 TI_DBG1(("tdsaDiscoveryStartIDDevCB: agFirstDword is NULL when error, status %d\n", agIOStatus));
22829 TI_DBG1(("tdsaDiscoveryStartIDDevCB: did %d\n", oneDeviceData->id));
22830
22831 if (tdsaAllShared->ResetInDiscovery != 0 && satDevData->ID_Retries < SATA_ID_DEVICE_DATA_RETRIES)
22832 {
22833 satIOContext->pSatDevData->satPendingNONNCQIO--;
22834 satIOContext->pSatDevData->satPendingIO--;
22835 retry_status = sataLLIOStart(tiRoot,
22836 &satIntIo->satIntTiIORequest,
22837 &(oneDeviceData->tiDeviceHandle),
22838 satIOContext->tiScsiXchg,
22839 satIOContext);
22840 if (retry_status != tiSuccess)
22841 {
22842 /* simply give up */
22843 satDevData->ID_Retries = 0;
22844 satDecrementPendingIO(tiRoot, tdsaAllShared, satIOContext);
22845
22846 satFreeIntIoResource( tiRoot,
22847 satDevData,
22848 satIntIo);
22849
22850 /* clean up TD layer's IORequestBody */
22851 ostiFreeMemory(
22852 tiRoot,
22853 tdOrgIORequestBody->IOType.InitiatorTMIO.osMemHandle,
22854 sizeof(tdIORequestBody_t)
22855 );
22856 return;
22857 }
22858 satDevData->ID_Retries++;
22859 tdIORequestBody->ioCompleted = agFALSE;
22860 tdIORequestBody->ioStarted = agTRUE;
22861 return;
22862 }
22863 else
22864 {
22865 satDecrementPendingIO(tiRoot, tdsaAllShared, satIOContext);
22866 satFreeIntIoResource( tiRoot,
22867 satDevData,
22868 satIntIo);
22869
22870 /* clean up TD layer's IORequestBody */
22871 ostiFreeMemory(
22872 tiRoot,
22873 tdOrgIORequestBody->IOType.InitiatorTMIO.osMemHandle,
22874 sizeof(tdIORequestBody_t)
22875 );
22876 if (tdsaAllShared->ResetInDiscovery != 0)
22877 {
22878 /* ResetInDiscovery in on */
22879 if (satDevData->NumOfIDRetries <= 0)
22880 {
22881 satDevData->NumOfIDRetries++;
22882 satDevData->ID_Retries = 0;
22883 /* send link reset */
22884 tdsaPhyControlSend(tiRoot,
22885 oneDeviceData,
22886 SMP_PHY_CONTROL_HARD_RESET,
22887 agNULL,
22888 tdsaRotateQnumber(tiRoot, oneDeviceData)
22889 );
22890 }
22891 }
22892 return;
22893 }
22894 }
22895
22896 if (agIOStatus == OSSA_IO_ABORTED ||
22897 agIOStatus == OSSA_IO_UNDERFLOW ||
22898 agIOStatus == OSSA_IO_XFER_ERROR_BREAK ||
22899 agIOStatus == OSSA_IO_XFER_ERROR_PHY_NOT_READY ||
22900 agIOStatus == OSSA_IO_OPEN_CNX_ERROR_PROTOCOL_NOT_SUPPORTED ||
22901 agIOStatus == OSSA_IO_OPEN_CNX_ERROR_BREAK ||
22902 agIOStatus == OSSA_IO_OPEN_CNX_ERROR_IT_NEXUS_LOSS ||
22903 agIOStatus == OSSA_IO_OPEN_CNX_ERROR_BAD_DESTINATION ||
22904 agIOStatus == OSSA_IO_OPEN_CNX_ERROR_CONNECTION_RATE_NOT_SUPPORTED ||
22905 agIOStatus == OSSA_IO_OPEN_CNX_ERROR_STP_RESOURCES_BUSY ||
22906 agIOStatus == OSSA_IO_OPEN_CNX_ERROR_WRONG_DESTINATION ||
22907 agIOStatus == OSSA_IO_XFER_ERROR_NAK_RECEIVED ||
22908 agIOStatus == OSSA_IO_XFER_ERROR_DMA ||
22909 agIOStatus == OSSA_IO_XFER_ERROR_SATA_LINK_TIMEOUT ||
22910 agIOStatus == OSSA_IO_XFER_ERROR_REJECTED_NCQ_MODE ||
22911 agIOStatus == OSSA_IO_XFER_OPEN_RETRY_TIMEOUT ||
22912 agIOStatus == OSSA_IO_NO_DEVICE ||
22913 agIOStatus == OSSA_IO_OPEN_CNX_ERROR_ZONE_VIOLATION ||
22914 agIOStatus == OSSA_IO_PORT_IN_RESET ||
22915 agIOStatus == OSSA_IO_DS_NON_OPERATIONAL ||
22916 agIOStatus == OSSA_IO_DS_IN_RECOVERY ||
22917 agIOStatus == OSSA_IO_DS_IN_ERROR
22918 )
22919 {
22920 TI_DBG1(("tdsaDiscoveryStartIDDevCB: OSSA_IO_OPEN_CNX_ERROR 0x%x\n", agIOStatus));
22921 if (tdsaAllShared->ResetInDiscovery != 0 && satDevData->ID_Retries < SATA_ID_DEVICE_DATA_RETRIES)
22922 {
22923 satIOContext->pSatDevData->satPendingNONNCQIO--;
22924 satIOContext->pSatDevData->satPendingIO--;
22925 retry_status = sataLLIOStart(tiRoot,
22926 &satIntIo->satIntTiIORequest,
22927 &(oneDeviceData->tiDeviceHandle),
22928 satIOContext->tiScsiXchg,
22929 satIOContext);
22930 if (retry_status != tiSuccess)
22931 {
22932 /* simply give up */
22933 satDevData->ID_Retries = 0;
22934 satDecrementPendingIO(tiRoot, tdsaAllShared, satIOContext);
22935
22936 satFreeIntIoResource( tiRoot,
22937 satDevData,
22938 satIntIo);
22939
22940 /* clean up TD layer's IORequestBody */
22941 ostiFreeMemory(
22942 tiRoot,
22943 tdOrgIORequestBody->IOType.InitiatorTMIO.osMemHandle,
22944 sizeof(tdIORequestBody_t)
22945 );
22946 return;
22947 }
22948 satDevData->ID_Retries++;
22949 tdIORequestBody->ioCompleted = agFALSE;
22950 tdIORequestBody->ioStarted = agTRUE;
22951 return;
22952 }
22953 else
22954 {
22955 satDecrementPendingIO(tiRoot, tdsaAllShared, satIOContext);
22956 satFreeIntIoResource( tiRoot,
22957 satDevData,
22958 satIntIo);
22959
22960 /* clean up TD layer's IORequestBody */
22961 ostiFreeMemory(
22962 tiRoot,
22963 tdOrgIORequestBody->IOType.InitiatorTMIO.osMemHandle,
22964 sizeof(tdIORequestBody_t)
22965 );
22966 if (tdsaAllShared->ResetInDiscovery != 0)
22967 {
22968 /* ResetInDiscovery in on */
22969 if (satDevData->NumOfIDRetries <= 0)
22970 {
22971 satDevData->NumOfIDRetries++;
22972 satDevData->ID_Retries = 0;
22973 /* send link reset */
22974 tdsaPhyControlSend(tiRoot,
22975 oneDeviceData,
22976 SMP_PHY_CONTROL_HARD_RESET,
22977 agNULL,
22978 tdsaRotateQnumber(tiRoot, oneDeviceData)
22979 );
22980 }
22981 }
22982 return;
22983 }
22984 }
22985
22986 if ( agIOStatus != OSSA_IO_SUCCESS ||
22987 (agIOStatus == OSSA_IO_SUCCESS && agFirstDword != agNULL && agIOInfoLen != 0)
22988 )
22989 {
22990 #ifdef TD_DEBUG_ENABLE
22991 /* only agsaFisPioSetup_t is expected */
22992 satPIOSetupHeader = (agsaFisPioSetupHeader_t *)&(agFirstDword->PioSetup);
22993 ataStatus = satPIOSetupHeader->status; /* ATA Status register */
22994 ataError = satPIOSetupHeader->error; /* ATA Eror register */
22995 #endif
22996 TI_DBG1(("tdsaDiscoveryStartIDDevCB: ataStatus 0x%x ataError 0x%x\n", ataStatus, ataError));
22997
22998 if (tdsaAllShared->ResetInDiscovery != 0 && satDevData->ID_Retries < SATA_ID_DEVICE_DATA_RETRIES)
22999 {
23000 satIOContext->pSatDevData->satPendingNONNCQIO--;
23001 satIOContext->pSatDevData->satPendingIO--;
23002 retry_status = sataLLIOStart(tiRoot,
23003 &satIntIo->satIntTiIORequest,
23004 &(oneDeviceData->tiDeviceHandle),
23005 satIOContext->tiScsiXchg,
23006 satIOContext);
23007 if (retry_status != tiSuccess)
23008 {
23009 /* simply give up */
23010 satDevData->ID_Retries = 0;
23011 satDecrementPendingIO(tiRoot, tdsaAllShared, satIOContext);
23012
23013 satFreeIntIoResource( tiRoot,
23014 satDevData,
23015 satIntIo);
23016
23017 /* clean up TD layer's IORequestBody */
23018 ostiFreeMemory(
23019 tiRoot,
23020 tdOrgIORequestBody->IOType.InitiatorTMIO.osMemHandle,
23021 sizeof(tdIORequestBody_t)
23022 );
23023 return;
23024 }
23025 satDevData->ID_Retries++;
23026 tdIORequestBody->ioCompleted = agFALSE;
23027 tdIORequestBody->ioStarted = agTRUE;
23028 return;
23029 }
23030 else
23031 {
23032 satDecrementPendingIO(tiRoot, tdsaAllShared, satIOContext);
23033 satFreeIntIoResource( tiRoot,
23034 satDevData,
23035 satIntIo);
23036
23037 /* clean up TD layer's IORequestBody */
23038 ostiFreeMemory(
23039 tiRoot,
23040 tdOrgIORequestBody->IOType.InitiatorTMIO.osMemHandle,
23041 sizeof(tdIORequestBody_t)
23042 );
23043 if (tdsaAllShared->ResetInDiscovery != 0)
23044 {
23045 /* ResetInDiscovery in on */
23046 if (satDevData->NumOfIDRetries <= 0)
23047 {
23048 satDevData->NumOfIDRetries++;
23049 satDevData->ID_Retries = 0;
23050 /* send link reset */
23051 tdsaPhyControlSend(tiRoot,
23052 oneDeviceData,
23053 SMP_PHY_CONTROL_HARD_RESET,
23054 agNULL,
23055 tdsaRotateQnumber(tiRoot, oneDeviceData)
23056 );
23057 }
23058 }
23059 return;
23060 }
23061 }
23062
23063
23064 /* success */
23065 TI_DBG3(("tdsaDiscoveryStartIDDevCB: Success\n"));
23066 TI_DBG3(("tdsaDiscoveryStartIDDevCB: Success did %d\n", oneDeviceData->id));
23067
23068 /* Convert to host endian */
23069 tmpptr = (bit16*)sglVirtualAddr;
23070 for (x=0; x < sizeof(agsaSATAIdentifyData_t)/sizeof(bit16); x++)
23071 {
23072 OSSA_READ_LE_16(AGROOT, &tmpptr_tmp, tmpptr, 0);
23073 *tmpptr = tmpptr_tmp;
23074 tmpptr++;
23075 }
23076
23077 pSATAIdData = (agsaSATAIdentifyData_t *)sglVirtualAddr;
23078 //tdhexdump("satAddSATAIDDevCB before", (bit8 *)pSATAIdData, sizeof(agsaSATAIdentifyData_t));
23079
23080 TI_DBG5(("tdsaDiscoveryStartIDDevCB: OS satOrgIOContext %p \n", satOrgIOContext));
23081 TI_DBG5(("tdsaDiscoveryStartIDDevCB: TD satIOContext %p \n", satIOContext));
23082 TI_DBG5(("tdsaDiscoveryStartIDDevCB: OS tiScsiXchg %p \n", satOrgIOContext->tiScsiXchg));
23083 TI_DBG5(("tdsaDiscoveryStartIDDevCB: TD tiScsiXchg %p \n", satIOContext->tiScsiXchg));
23084
23085
23086 /* copy ID Dev data to satDevData */
23087 satDevData->satIdentifyData = *pSATAIdData;
23088 satDevData->IDDeviceValid = agTRUE;
23089
23090 #ifdef TD_INTERNAL_DEBUG
23091 tdhexdump("tdsaDiscoveryStartIDDevCB ID Dev data",(bit8 *)pSATAIdData, sizeof(agsaSATAIdentifyData_t));
23092 tdhexdump("tdsaDiscoveryStartIDDevCB Device ID Dev data",(bit8 *)&satDevData->satIdentifyData, sizeof(agsaSATAIdentifyData_t));
23093 #endif
23094
23095 /* set satDevData fields from IndentifyData */
23096 satSetDevInfo(satDevData,pSATAIdData);
23097 satDecrementPendingIO(tiRoot, tdsaAllShared, satIOContext);
23098
23099 satFreeIntIoResource( tiRoot,
23100 satDevData,
23101 satIntIo);
23102
23103 if (satDevData->satDeviceType == SATA_ATAPI_DEVICE)
23104 {
23105 /* send the Set Feature ATA command to ATAPI device for enbling PIO and DMA transfer mode*/
23106 satNewIntIo = satAllocIntIoResource( tiRoot,
23107 tiOrgIORequest,
23108 satDevData,
23109 0,
23110 satNewIntIo);
23111
23112 if (satNewIntIo == agNULL)
23113 {
23114 TI_DBG1(("tdsaDiscoveryStartIDDevCB: momory allocation fails\n"));
23115 /* clean up TD layer's IORequestBody */
23116 ostiFreeMemory(
23117 tiRoot,
23118 tdOrgIORequestBody->IOType.InitiatorTMIO.osMemHandle,
23119 sizeof(tdIORequestBody_t)
23120 );
23121 return;
23122 } /* end memory allocation */
23123
23124 satNewIOContext = satPrepareNewIO(satNewIntIo,
23125 tiOrgIORequest,
23126 satDevData,
23127 agNULL,
23128 satOrgIOContext
23129 );
23130 /* enable PIO mode, then enable Ultra DMA mode in the satSetFeaturesCB callback function*/
23131 retry_status = satSetFeatures(tiRoot,
23132 &satNewIntIo->satIntTiIORequest,
23133 satNewIOContext->ptiDeviceHandle,
23134 &satNewIntIo->satIntTiScsiXchg, /* orginal from OS layer */
23135 satNewIOContext,
23136 agFALSE);
23137 if (retry_status != tiSuccess)
23138 {
23139 satFreeIntIoResource(tiRoot, satDevData, satIntIo);
23140 /* clean up TD layer's IORequestBody */
23141 ostiFreeMemory(
23142 tiRoot,
23143 tdOrgIORequestBody->IOType.InitiatorTMIO.osMemHandle,
23144 sizeof(tdIORequestBody_t)
23145 );
23146 }
23147 }
23148 else
23149 {
23150 /* clean up TD layer's IORequestBody */
23151 ostiFreeMemory(
23152 tiRoot,
23153 tdOrgIORequestBody->IOType.InitiatorTMIO.osMemHandle,
23154 sizeof(tdIORequestBody_t)
23155 );
23156 if (onePortContext != agNULL)
23157 {
23158 if (onePortContext->DiscoveryState == ITD_DSTATE_COMPLETED)
23159 {
23160 TI_DBG1(("tdsaDiscoveryStartIDDevCB: ID completed after discovery is done; tiDeviceArrival\n"));
23161 /* in case registration is finished after discovery is finished */
23162 ostiInitiatorEvent(
23163 tiRoot,
23164 tiPortalContext,
23165 agNULL,
23166 tiIntrEventTypeDeviceChange,
23167 tiDeviceArrival,
23168 agNULL
23169 );
23170 }
23171 }
23172 else
23173 {
23174 TI_DBG1(("tdsaDiscoveryStartIDDevCB: onePortContext is NULL, wrong\n"));
23175 }
23176 }
23177 TI_DBG3(("tdsaDiscoveryStartIDDevCB: end\n"));
23178 return;
23179 }
23180 /*****************************************************************************
23181 *! \brief satAbort
23182 *
23183 * This routine does local abort for outstanding FIS.
23184 *
23185 * \param agRoot: Handles for this instance of SAS/SATA hardware
23186 * \param satIOContext: Pointer to satIOContext_t.
23187 *
23188 * \return: none
23189 *
23190 *****************************************************************************/
satAbort(agsaRoot_t * agRoot,satIOContext_t * satIOContext)23191 GLOBAL void satAbort(agsaRoot_t *agRoot,
23192 satIOContext_t *satIOContext)
23193 {
23194 tdsaRootOsData_t *osData = (tdsaRootOsData_t *)agRoot->osData;
23195 tiRoot_t *tiRoot = (tiRoot_t *)osData->tiRoot;
23196 tdIORequestBody_t *tdIORequestBody; /* io to be aborted */
23197 tdIORequestBody_t *tdAbortIORequestBody; /* abort io itself */
23198 agsaIORequest_t *agToBeAbortedIORequest; /* io to be aborted */
23199 agsaIORequest_t *agAbortIORequest; /* abort io itself */
23200 bit32 PhysUpper32;
23201 bit32 PhysLower32;
23202 bit32 memAllocStatus;
23203 void *osMemHandle;
23204
23205 TI_DBG1(("satAbort: start\n"));
23206
23207 if (satIOContext == agNULL)
23208 {
23209 TI_DBG1(("satAbort: satIOContext is NULL, wrong\n"));
23210 return;
23211 }
23212 tdIORequestBody = (tdIORequestBody_t *)satIOContext->tiRequestBody;
23213 agToBeAbortedIORequest = (agsaIORequest_t *)&(tdIORequestBody->agIORequest);
23214 /* allocating agIORequest for abort itself */
23215 memAllocStatus = ostiAllocMemory(
23216 tiRoot,
23217 &osMemHandle,
23218 (void **)&tdAbortIORequestBody,
23219 &PhysUpper32,
23220 &PhysLower32,
23221 8,
23222 sizeof(tdIORequestBody_t),
23223 agTRUE
23224 );
23225
23226 if (memAllocStatus != tiSuccess)
23227 {
23228 /* let os process IO */
23229 TI_DBG1(("satAbort: ostiAllocMemory failed...\n"));
23230 return;
23231 }
23232
23233 if (tdAbortIORequestBody == agNULL)
23234 {
23235 /* let os process IO */
23236 TI_DBG1(("satAbort: ostiAllocMemory returned NULL tdAbortIORequestBody\n"));
23237 return;
23238 }
23239 /* setup task management structure */
23240 tdAbortIORequestBody->IOType.InitiatorTMIO.osMemHandle = osMemHandle;
23241 tdAbortIORequestBody->tiDevHandle = tdIORequestBody->tiDevHandle;
23242
23243 /* initialize agIORequest */
23244 agAbortIORequest = &(tdAbortIORequestBody->agIORequest);
23245 agAbortIORequest->osData = (void *) tdAbortIORequestBody;
23246 agAbortIORequest->sdkData = agNULL; /* LL takes care of this */
23247
23248
23249 /*
23250 * Issue abort
23251 */
23252 saSATAAbort( agRoot, agAbortIORequest, 0, agNULL, 0, agToBeAbortedIORequest, agNULL );
23253
23254
23255 TI_DBG1(("satAbort: end\n"));
23256 return;
23257 }
23258
23259 /*****************************************************************************
23260 *! \brief satSATADeviceReset
23261 *
23262 * This routine is called to reset all phys of port which a device belongs to
23263 *
23264 * \param tiRoot: Pointer to TISA initiator driver/port instance.
23265 * \param oneDeviceData: Pointer to the device data.
23266 * \param flag: reset flag
23267 *
23268 * \return:
23269 *
23270 * none
23271 *
23272 *****************************************************************************/
23273 osGLOBAL void
satSATADeviceReset(tiRoot_t * tiRoot,tdsaDeviceData_t * oneDeviceData,bit32 flag)23274 satSATADeviceReset( tiRoot_t *tiRoot,
23275 tdsaDeviceData_t *oneDeviceData,
23276 bit32 flag)
23277 {
23278 agsaRoot_t *agRoot;
23279 tdsaPortContext_t *onePortContext;
23280 bit32 i;
23281
23282 TI_DBG1(("satSATADeviceReset: start\n"));
23283 agRoot = oneDeviceData->agRoot;
23284 onePortContext = oneDeviceData->tdPortContext;
23285
23286 if (agRoot == agNULL)
23287 {
23288 TI_DBG1(("satSATADeviceReset: Error!!! agRoot is NULL\n"));
23289 return;
23290 }
23291 if (onePortContext == agNULL)
23292 {
23293 TI_DBG1(("satSATADeviceReset: Error!!! onePortContext is NULL\n"));
23294 return;
23295 }
23296
23297 for(i=0;i<TD_MAX_NUM_PHYS;i++)
23298 {
23299 if (onePortContext->PhyIDList[i] == agTRUE)
23300 {
23301 saLocalPhyControl(agRoot, agNULL, tdsaRotateQnumber(tiRoot, agNULL), i, flag, agNULL);
23302 }
23303 }
23304
23305 return;
23306 }
23307
23308 #endif /* #ifdef SATA_ENABLE */
23309